***************************************************
*   
*   LOGICAL OPERATIONS, RETURNING A BOOLEAN RESULT
*   
****************************************************
*   
*** ZIOR
*   
*  LOGICAL OR
*   
ZIOR  DCX  D
  LDAX  D
  DCX  D
  DCX  D
  MOV  L,A
  LDAX  D
  ORA  L
  STAX  D
  INX  D
  JMP  FETCH
*   
*** ZAND
*   
*  LOGICAL AND
*   
ZAND  DCX  D
  LDAX  D
  DCX  D
  DCX  D
  MOV  L,A
  LDAX  D
  ANA  L
  STAX  D
  INX  D
  JMP  FETCH
*   
*** ZNOT
*   
*  LOGICAL NOT
*   
ZNOT  DCX  D
  LDAX  D
  XRI  TRUE
  STAX  D
  INX  D
  JMP  FETCH
*   
*** ZODD ***
*   
*  ODD FUNCTION, INTEGER ARGUMENT, BOOLEAN RESULT
*   
ZODD  DCX  D
  LDAX  D
  ANI  001H
  STAX  D
  XRA  A
  DCX  D
  STAX  D
  INX  D
  INX  D
  JMP  FETCH  ,
*   
*   
********************************************
*   
*  COMPARE AND LOGICAL OPERATIONS
*   
********************************************
*   
*   
*** COMMON CODE FOR COMPARISON INSTRUCTIONS
*   
*  THIS ROUTINE SUBTRACTS TOP_OF_STACK FROM 2ND_TOP LEAVING
*        THE
*  RESULT IN 'AE' REGS. FLAGS ARE SET ACCORDING TO THE VALUE
*        IN 'A'.
*  'BC' UNCAHNGED, 'DE' DESTROYED, 'HL' POINTS TO 2ND_TOP
*  AND (HL) SET TO 'TRUE'
*   
*  'HL' <-- 'DE'-4
*  'AE' <-- (DE-4,DE-3) - (DE-2,DE-1) ;
*  (HL,HL+1) <-- 0,TRUE
*   
CMPSUB  XCHG  ,
  DCX  H
  MOV  E,M
  DCX  H
  MOV  D,M
  DCX  H
  MOV  A,M
  DCX  H
  SUB  E
  MOV  E,A
  MOV  A,M
  MVI  M,0
  INX  H
  SBB  D
  MVI  M,TRUE
  RET  ,
*   
CMPFLS  MVI  M,FALSE
*   
CMPTRU  INX  H
  XCHG  ,
  JMP  FETCH
*   
*** ZLES
*   
*  2ND_TOP_OF_P_STACK < TOP  ?
*   
ZLES  CALL  CMPSUB
  JM  CMPTRU
  JMP  CMPFLS
*   
*** ZGEQ
*   
*   2ND_TOP >= TOP  ?
*   
ZGEQ  CALL  CMPSUB
  JP  CMPTRU
  JMP  CMPFLS
*   
*** ZEQU
*   
*  2ND_TOP == TOP  ?     (THE MOST FREQUENT COMPARISON)
*   
ZEQU  CALL  CMPSUB
  ORA  E
  JZ  CMPTRU
  JMP  CMPFLS
*   
*** ZNEQ
*   
*  2ND_TOP <> TOP  ?
*   
ZNEQ  CALL  CMPSUB
  ORA  E
  JNZ  CMPTRU
  JMP  CMPFLS
*   
*** ZLEQ
*   
*  END_TOP <= TOP  ?
*   
ZLEQ  CALL  CMPSUB
  JM  CMPTRU
  ORA  E
  JNZ  CMPFLS
  JMP  CMPTRU
*   
*** ZGRT
*   
*  2ND_TOP > TOP  ?
*   
ZGRT  CALL  CMPSUB
  JM  CMPFLS
  ORA  E
  JNZ  CMPTRU
  JMP  CMPFLS
*   
*** CMPM ***
*   
*** COMPARE INSTRUCTIONS  (STRING AND SET OPERANDS)
*   
ZCMPM  INX  B
  LDAX  B
  CPI  6
  JP  CM05
  INX  B  COMPARE MEMORY
  LDAX  B  PICK UP THE COUNT
  PUSH  B
  XCHG  ,
  DCX  H
  MOV  C,M
  DCX  H
  MOV  B,M  BC <-- 2ND OPERAND'S ADDRESS
  DCX  H
  MOV  E,M
  DCX  H
  MOV  D,M
  XCHG  ,  HL <-- FIRST OPERAND'S ADDRESS
  PUSH  D
  MOV  E,A  E <-- WORD COUNT
CM06  LDAX  B
  CMP  M  COMP ONE BYTE
  JNZ  CM07
  INX  B
  INX  H
  LDAX  B
  CMP  M  COMP NEXT BYTE
  JNZ  CM07
  INX  B
  INX  H
  DCR  E
  JNZ  CM06  NEXT WORD
CM07  POP  D
  POP  B
  MVI  A,1
  PUSH  PSW  SAVE COMP RESULT
  XRA  A
  STAX  D  HI BYTE OF BOOL
  INX  D
  STAX  D
  DCX  B  GET CODE BACK
  LDAX  B
  INX  B  PASS COUNT
  CPI  1
  JM  CM08  CODE 0  '='
  JZ  CM09  CODE 1  '<>'
  CPI  3
  JM  CM10  CODE 2  '<='
  JZ  CM11  CODE 3  '< '
  CPI  5
  JM  CM12  CODE 4  '>='
  POP  PSW  CODE 5  '> '
  JP  CM13
CM14  STAX  D
CM13  INX  D
  JMP  FETCH
CM12  POP  PSW
  JM  CM14
  JZ  CM14
  JMP  CM13
CM11  POP  PSW
  JM  CM13
  JZ  CM13
  JMP  CM14
CM10  POP  PSW
  JM  CM13
  JMP  CM14
CM09  POP  PSW
  JNZ  CM14
  JMP  CM13
CM08  POP  PSW
  JNZ  CM13
  JMP  CM14
CM05  CPI  10
  JP  ERROR
  LXI  H,-16  COMPARE SETS
  DAD  D
  PUSH  H
  LXI  H,-8
  DCX  D
  DAD  D
  PUSH  B
  MVI  C,8
  CMP  C
  JM  CM15  CODE 6, 7  ('= ', '<>')
  JZ  CM16  CODE 8  ('<=')
  XCHG  ,  CODE 9  ('>=')
CM16  LDAX  D
  XRA  M
  ANA  M
  JNZ  CM17
  DCX  H
  DCX  D
  DCR  C
  JNZ  CM16
CM17  POP  B
  POP  D
  MVI  A,0
  STAX  D
  INX  D
  JNZ  CM18
  INR  A
CM18  STAX  D
  INX  D
  JMP  FETCH
CM15  LDAX  D
  CMP  M
  JNZ  CM19
  DCX  H
  DCX  D
  DCR  C
  JNZ  CM15
CM19  POP  B
  POP  D
  MVI  A,0
  MOV  L,A
  STAX  D
  INX  D
  JNZ  CM20
  INR  L
CM20  LDAX  B
  ANI  1
  XRA  L
  STAX  D
  INX  D
  JMP  FETCH
*   
**************************************************
*   
*        SET RELATED OPERATIONS
*   
**************************************************
*   
*   
*** ZINT ZDIF & ZUNI ***
*   
ZINT  PUSH  B
  LXI  H,-8
  MOV  C,L
  DAD  D
IT1  DCX  D
  DCX  H
  LDAX  D
  ANA  M
  MOV  M,A
  INR  C
  JNZ  IT1
  POP  B
  JMP  FETCH
ZDIF  PUSH  B
  LXI  H,-8
  MOV  C,L
  DAD  D
IT2  DCX  D
  DCX  H
  LDAX  D
  XRA  M
  ANA  M
  MOV  M,A
  INR  C
  JNZ  IT2
  POP  B
  JMP  FETCH
ZUNI  PUSH  B
  LXI  H,-8
  MOV  C,L
  DAD  D
IT3  DCX  D
  DCX  H
  LDAX  D
  ORA  M
  MOV  M,A
  INR  C
  JNZ  IT3
  POP  B
  JMP  FETCH
*   
*** ZINN & ZSGS ***
*   
* FIRST, A SUBROUTINE TO CONVERT I TO S
*   
ITOS  DCX  D
  LDAX  D
**  
  CPI  64
  JC  IT31
  SUB A  A <-- 0
  MOV  H,A
  MOV  L,A
  RET  ,
**  
IT31  RRC  ,
  RRC  ,
  RRC  ,
  MVI  H,7
  ANA  H
  XRA  H
  MOV  L,A
  LDAX  D
  ANA  H
  MOV  H,A
  INR  H
  MVI  A,1
IT4  DCR  H
  RZ  ,
  RLC  ,
  JMP  IT4
*   
ZSGS  CALL  ITOS
  DCX  D
  DAD  D
  XCHG  ,
  PUSH  B
  MVI  C,8
IT5  MVI  M,0
  INX  H
  DCR  C
  JNZ  IT5
  XCHG  ,
  MOV  M,A
  POP  B
  JMP  FETCH
ZINN  LXI  H,-8
  DAD  D
  XCHG  ,
  CALL  ITOS
  DAD  D
  INX  H
  ANA  M
  MVI  A,0
  DCX  D
  STAX  D
  INX  D
  JZ  IT6
  INR  A
IT6  STAX  D
  INX  D
  JMP  FETCH
*   
********************************************
*   
*  BRANCH AND CONTROL INSTRUCTIONS
*   
********************************************
*   
*** ZUJP ***
*   
*  UNCONDITIONAL JUMP
*   
ZUJP  LDAX  B
  ANI  00FH
  MOV  H,A
  INX  B
  LDAX  B
  MOV  B,H
  MOV  C,A
  LHLD  BASE
  DAD  B
  MOV  B,H
  MOV  C,L
  JMP  FET1
*   
*** ZFJP ***
*   
*  JUMP IF FALSE
*   
ZFJP  DCX  D
  LDAX  D
  DCX  D
  ORA  A
  JZ  ZUJP
  INX  B
  JMP  FETCH
*   
*** ZXJP ***
*   
*  INDEXED JUMP,  FIRST CHECK THE TOP OF STACK TO BE IN RANGE.
*   
ZXJP  INX  B
  DCX  D
  LDAX  D  CHECK THE INDEX VALUE FIRST
  MOV  L,A
  DCX  D
  LDAX  D
  ORA  A  IS IT SMALL POSITIVE VALUE ?
  JNZ  XJ08
  LDAX  B  A <-- UPPER BOUND ON RANGE
  CMP  L
  JC  XJ08  IF INDEX TOO LARGE, EXIT THE 'CASE'
  MOV  A,L
  LHLD  BASE
  ADD  A  MULTIPLY INDEX VALUE BY TWO.
  JNC  XJ02
  INR  H
XJ02  ADD  L
  JNC  XJ03  ADD INDEX TO PROCBASE
  INR  H
XJ03  MOV  L,A
  INX  B
  LDAX  B  ADD THE BRANCH TABLE ADDRESS
  ADD  H
  MOV  H,A
  INX  B
  LDAX  B
  ADD  L
  JNC  XJ04
  INR  H
XJ04  MOV  B,H
  MOV  C,A
  JMP  FET1
*   
*        BRANCH INDEX OUT OF RANGE, EXIT THE CASE STATEMENT
*   
XJ08  INX  B
  INX  B
  INX  B  POINT TO 'CASE' EXIT ADDRESS
  LHLD  BASE
  LDAX  B
  ADD  H
  MOV  H,A
  INX  B
  LDAX  B
  ADD  L  ADD PROC. BASE ADDRESS TO CASE EXIT ADDR
  JNC  XJ09
  INR  H
XJ09  MOV  B,H
  MOV  C,A
  JMP  FET1
*   
*** ZMST ***
*   
*        ZMST, MARK STACK BEFORE A PROCEDURE CALL
*   
ZMST  LHLD  MP
  PUSH  H  SAVE CURRENT 'MP'
  PUSH  D  SAVE (TEMPORARY) NEW 'MP'
  JMP  FETCH
*   
*** ZMSTF ***
*   
*        ZMSTF, MARK STACK PRIOR TO A FUNCTION CALL
*   
ZMST8  MVI  A,8  SIZE OF THE FUNCTION RESULT
  JMP  MS02
*   
ZMSTF  MVI  A,2
MS02  LHLD  MP
  PUSH  H
  PUSH  D
  MVI  H,0
  MOV  L,A
  DAD  D
  XCHG  ,
  JMP  FETCH
*   
