JMP COPC * * * THE FOLLOWING IS THE OPCODE TABLE * * OTAB DB 'O','R','G',0,0 DB 'E','Q','U',0,1 DB 'D','B',0,0,-1 DB 'D','S',0,0,2 DB 'D','W',0,0,3 DB 'E','N','D',0,4 DB 'C','O','M',0,5 DB 'L','S','T',0,6 DB 'N','L','S','T',7 DB 'A','S','C',0,8 DB 0 DB 'H','L','T',118 DB 'R','L','C',7 DB 'R','R','C',15 DB 'R','A','L',23 DB 'R','A','R',31 DB 'R','E','T',201 DB 'C','M','A',47 DB 'S','T','C',55 DB 'D','A','A',39 DB 'C','M','C',63 DB 'E','I',0,251 DB 'D','I',0,243 DB 'N','O','P',0 DB 0 DB 'X','C','H','G',235 DB 'X','T','H','L',227 DB 'S','P','H','L',249 DB 'P','C','H','L',233 DB 0 DB 'S','T','A','X',2 DB 'L','D','A','X',10 DB 0 DB 'P','U','S','H',197 DB 'P','O','P',0,193 DB 'I','N','X',0,3 DB 'D','C','X',0,11 DB 'D','A','D',0,9 DB 0 DB 'I','N','R',4 DB 'D','C','R',5 DB 'M','O','V',64 DB 'A','D','D',128 DB 'A','D','C',136 DB 'S','U','B',144 DB 'S','B','B',152 DB 'A','N','A',160 DB 'X','R','A',168 DB 'O','R','A',176 DB 'C','M','P',184 DB 'R','S','T',199 DB 0 DB 'A','D','I',198 DB 'A','C','I',206 DB 'S','U','I',214 DB 'S','B','I',222 DB 'A','N','I',230 DB 'X','R','I',238 DB 'O','R','I',246 DB 'C','P','I',254 DB 'I','N',0,219 DB 'O','U','T',211 DB 'M','V','I',6 DB 0 DB 'J','M','P',0,195 DB 'C','A','L','L',205 DB 'L','X','I',0,1 DB 'L','D','A',0,58 DB 'S','T','A',0,50 DB 'S','H','L','D',34 DB 'L','H','L','D',42 DB 0 * CONDITION CODE TABLE DB 'N','Z',0 DB 'Z',0,8 DB 'N','C',16 DB 'C',0,24 DB 'P','O',32 DB 'P','E',40 DB 'P',0,48 DB 'M',0,56 DB 0 * * THIS ROUTINE IS USED TO CHECK A GIVEN OPCODE AGAINST THE LEGAL * OPCODES CONTAINED IN THE OPCODE TABLE * COPC LHLD ADDS LDAX D FETCH CHARACTER ORA A SET FLAGS JZ COP1 JUMP IF TERMINATION CHARACTER MOV C,B CALL SEAR COMPARE STRINGS LDAX D RZ RETURN IF MATCH INX D NEXT STRING JMP COPC CONTINUE SEARCH COP1 INR A CLEAR ZERO FLAG INX D INCREMENT ADDRESS RET * * * THIS ROUTINE CHECKS THE LEGAL OPCODES IN BOTH PASS 1 AND * PASS 2. IN PASS 1 THE PROGRAM COUNTER IS INCREMENTED BY THE * CORRECT NUMBER OF BYTES. AN ADDRESS IS ALSO SET SO THAT * AN INDEXED JUMP CAN BE MADE TO PROCESS THE OPCODE FOR * PASS2. * * OPCD LXI H,ABUF SET ADDRESS SHLD ADDS LXI D,OTAB OPCODE TABLE ADDRESS MVI B,4 CHARACTER COUNT CALL COPC CHECK OPCODES JZ PSEU JUMP IF A PSEUDO-OP DCR B 3 CHARACTER OPCODES CALL COPC JZ OP1 INR B 4 CHAR OPCODES CALL COPC OP1 LXI H,ASTO OP2 MVI C,1 1 BYTE INSTRUCTION JZ OCNT * OPC2 CALL COPC CHECK FOR STAX,LDAX LXI H,TYP2 JZ OP2 CALL COPC CHECK FOR PUSH,POP,INX * DCX AND DAD LXI H,TYP3 JZ OP2 DCR B 3 CHAR OPCODES CALL COPC ACCUMULATOR INSTRUCTIONS, * INR,DCR,MOV,RST LXI H,TYP4 JZ OP2 * OPC3 CALL COPC IMMEDIATE INSTRUCTIONS LXI H,TYP5 MVI C,2 2 BYTE INSTRUCTIONS JZ OCNT INR B 4 CHAR OPCODES CALL COPC JMP,CALL,LXI,LDA,STA, * LHLD,SHLD OPCODES JZ OP4 CALL COND CONDITIONAL INSTRUCTIONS JNZ OERR ILLEGAL OPCODE ADI 192 ADD BASE VALUE OF RETURN MOV D,A MVI B,3 3 CHARACTER OPCODES LDA ABUF FETCH FIRST CHARACTER MOV C,A SAVE CHARACTER CPI 'R' CONDITIONAL RETURN MOV A,D JZ OP1 MOV A,C INR D FORM CONDITIONAL JUMP INR D CPI 'J' CONDITIONAL JUMP JZ OPAD CPI 'C' CONDITIONAL CALL JNZ OERR ILLEGAL OPCODE INR D FORM CONDITIONAL CALL INR D OPAD MOV A,D GET OPCODE OP4 LXI H,TYP6 OP5 MVI C,3 3 BYTE INSTRUCTION OCNT STA TEMP SAVE OPCODE * CHECK FOR OPCODE ONLY CONTAINING THE CORRECT NUMBER OF CHARACTERS * THUS SAY ADDQ WOULD GIVE AN ERROR MVI A,ABUF-ABUFP ADD B ADD LENGTH OF OPCODE MOV E,A MVI A,ABUF/256 ACI 0 GET HIGH ORDER ADDRESS MOV D,A LDAX D FETCH CHARACTER AFTER OPCODE ORA A IT SHOULD BE ZERO JNZ OERR OPCODE ERROR LDA PASI FETCH PASS INDICATOR OCN1 MVI B,0 XCHG OCN2 LHLD ASPC FETCH PROGRAM COUNTER DAD B ADD IN BYTE COUNT SHLD ASPC STORE PC ORA A WHICH PASS RZ RETURN IF PASS 1 LDA TEMP FETCH OPCODE XCHG PCHL * OERR LXI H,ERRO SET ERROR ADDRESS MVI C,3 LEAVE 3 BYTES FOR PATCH JMP OCN1-3 * LERR LXI H,ERRL JMP OERR+3 * PSEU LXI H,ABUF+4 SET BUFFER ADDRESS MOV A,M FETCH CHARACTER AFTER OPCODE ORA A SHOULD BE A ZERO JNZ OERR LDA PASI FETCH PASS INDICATOR ORA A JZ PSU1 JMP PSU2 * * * THIS ROUTINE IS USED TO PROCESS LABELS * IT CHECKS WHETHER A LABEL IS IN THE SYMBOL TABLE OR NOT * ON RETURN Z=1 MEANS A MATCH WAS FOUND AND H,L CONTAIN THE VALUE * ASSOCIATED WITH THE LABEL. OTHERWISE D,E POINT TO THE NEXT AVAILABLE * LOCATION IN THE TABLE. THE REGISTER NAMES A,B,C,D,E,H,L,M * ARE PREDEFINED BY THE SYSTEM AND NEED NOT BE ENTERED BY THE USER * ON RETURN C=1 INDICATES A LABEL ERROR SLAB CPI 'A' CHECK FOR LEGAL CHARACTER RC RETURN IF ILLEGAL CHARACTER CPI 'Z'+1 CHECK FOR ILLEGAL CHARACTER CMC RC RETURN IF ILLEGAL CHARACTER CALL ALPS PLACE SYMBOL IN BUFFER LXI H,ABUF SET BUFFER ADDRESS LDA PASI GET PASS INDICATOR CPI 2 INR A RNC SHLD ADDS SAVE ADDRESS DCR B CHECK IF ONE CHARACTER JNZ SLA1 * CHECK IF PREDEFINED REGISTER NAME INR B SET B=1 LXI D,RTAB REGISTER TABLE ADDRESS CALL COPC CHECK NAME OF REGISTER JNZ SLA1 NOT A PREDEFINED REGISTER MOV L,A MVI H,0 SET VALUE (HIGH) SLA2 STC SET CARRY CMC CLEAR CARRY RET SLA1 LHLD SYMADD GET SYMBOL TABLE ADDRESS XCHG MVI B,LLAB GET LABEL SIZE CALL COMS CHECK TABLE RET * * PREDEFINE REGISTER VALUES IN THIS TABLE * RTAB DB 'A',7 DB 'B',0 DB 'C',1 DB 'D',2 DB 'E',3 DB 'H',4 DB 'L',5 DB 'M',6 DB 0 END OF TABLE INDICATOR * * * THIS ROUTINE SCANS THE INPUT LINE AND PLACES THE OPCODES AND * LABELS IN THE BUFFER. THE SCAN TERMINATES WHEN A CHARACTER * OTHER THAN 0-9 OR A-Z IS FOUND * ALPS MVI B,0 SET COUNT ALP1 STAX D STORE CHARACTER IN BUFFER INR B INCREMENT COUNT MOV A,B FETCH COUNT CPI 15 MAXIMUM BUFFER SI E RNC RETURN IF BUFFER FILLED INX D INCREMENT BUFFER INX H INCREMENT INPUT ADDRESS SHLD PNTR SAVE LINE POINTER MOV A,M FETCH CHARACTER CPI '0' CHECK FOR LEGAL CHARACTERS RC CPI '9'+1 JC ALP1 ALP2 CPI 'A' RC CPI 'Z'+1 JC ALP1 RET * * * THIS ROUTINE IS USED TO SCAN THROUGH THE INPUT LINE TO * FETCH THE VALUE OF THE OPERAND FIELD. ON RETURN THE VALUE OF THE * OPERAND IS CONTAINED IN REGISTERS H,L. * ASBL CALL SBLK GET FIRST ARGUMENT ASCN LHLD PNTR GET LINE POINTER MOV A,M GET FIRST CHARACTER LXI H,0 SHLD OPRD INITIALIZE OPERAND INR L MOV H,A SHLD OPRI NXT1 LHLD PNTR FETCH SCAN POINTER DCX H CALL ZBUF CLEAR BUFFER STA SIGN ZERO SIGN INDICATOR NXT2 INX H INCREMENT POINTER MOV A,M FETCH NEXT CHARACTER CPI ' '+1 JC SEND JUMP IF CR OR BLANK CPI ',' FIELD SEPARATOR JZ SEND * CHECK FOR OPERATORS CPI '+' JZ NXT3 INR B CPI '-' CHECK FOR MINUS JZ NXT3 INR B CPI '*' JZ NXT3 INR B CPI '/' JNZ NXT4 NXT3 MOV A,B STA SIGN LDA OPRI FETCH OPERAND INDICATOR CPI 2 CHECK FOR TWO OPERATORS JZ ERRS SYNTAX ERROR MVI A,2 STA OPRI SET INDICATOR JMP NXT2 * CHECK FOR OPERANDS NXT4 MOV C,A SAVE CHARACTER LDA OPRI GET INDICATOR ORA A CHECK FOR TWO OPERANDS JZ ERRS SYNTAX ERROR MOV A,C CPI '$' LC EXPRESSION JNZ ASC3 INX H INCREMENT POINTER SHLD PNTR SAVE POINTER LHLD ASPC FETCH LOCATION COUNTER JMP AVAL * CHECK FOR ASCII CHARACTERS ASC3 CPI '''' CHECK FOR SINGLE QUOTE JNZ ASC5 JUMP IF NOT QUOTE LXI D,0 GET A ZERO MVI C,3 CHARACTER COUNT ASC4 INX H INCREMENT POINTER SHLD PNTR SAVE MOV A,M FETCH NEXT CHARACTER CPI ASCR IS IT A CR JZ ERRA ARGUMENT ERROR CPI '''' IS IT A QUOTE JNZ SSTR INX H INCREMENT POINTER SHLD PNTR SAVE MOV A,M FETCH NEXT CHARACTER CPI '''' CHECK FOR 2 QUOTES IN A ROW JNZ AVAL+1 TERMINAL QUOTE SSTR DCR C CHECK COUNT JZ ERRA TOO MANY CHARACTERS MOV D,E MOV E,A SET CHARACTER IN BUFFER JMP ASC4 ASC5 CPI '0' CHECK FOR NUMERIC JC ERRA ILLEGAL CHARACTER CPI '9'+1 JNC ALAB CALL NUMS GET NUMERIC VALUE JC ERRA ARGUMENT ERROR AVAL XCHG LHLD OPRD FETCH OPERAND XRA A GET A ZERO STA OPRI STORE IN OPERAND INDICATOR LDA SIGN GET SIGN INDICATOR CPI 1 JZ ASUB JNC AMULT DAD D FORM RESULT ASC7 SHLD OPRD SAVE RESULT JMP NXT1 ASUB MOV A,L SUB E MOV L,A MOV A,H SBB D MOV H,A JMP ASC7 AMULT MOV B,D MOV C,E XCHG LXI H,0 CPI 3 JZ ADIV CALL MULT JMP ASC7 MULT MVI A,16 MULT1 DAD H XCHG DAD H XCHG JNC MULT2 DAD B MULT2 DCR A JNZ MULT1 RET ADIV MOV A,B ORA C JZ ASC7 DIVIDE BY ZERO CALL DIV XCHG JMP ASC7 DIV MVI A,16 SET BIT COUNT DIV1 STA SCNT DAD H ROTATE BUFFER XCHG DAD H ROTATE DIVIDEND XCHG JNC DIV2 INX H DIV2 MOV A,L SUB C SUBTRACT DIVISOR MOV L,A MOV A,H SBB B MOV H,A INX D ASSUMED 1 IN QUOTIENT JNC DIV3 DAD B RESTORE DIVIDEND DCX D DIV3 LDA SCNT GET BIT COUNT DCR A JNZ DIV1 RET ALAB CALL SLAB JZ AVAL JC ERRA ILLEGAL SYMBOL LDA PASI CPI 2 JNC SLA3 LXI D,SYSYM SET SYMTEM TABLE CALL COMS JZ AVAL JMP ERRU UNDEFINED SYMBOL * * SLA3 XCHG LHLD SYMSAV ADDRESS OF NEXT SYMBOL MVI C,LLAB CALL SEAR CHECK FOR REFERENCE JNZ SLA6 LXI H,SCNT GET LINE COUNT INR M MOV A,M CPI 12 LINE FILLED JC SLA4 MVI M,1 INITIALIZE COUNT