**************************************************************** * * * * * *** *** *** * * * * * * * * * * ** ** * * * * * * * * * * * ***** *** *** * * * * * * * * * * * * * * * * * * * * * * * * *** *** * * * * * * * * 8080 DISK ASSEMBLER * * * * ASSM 1.1 (MOD 0) * * OCTOBER 9, 1978 * * * * COPYRIGHT (C) 1977 * * PROCESSOR TECHNOLOGY CORPORATION * * * * * **************************************************************** * * * * * FORMAT: * * * * ,,,,,S=options * * * * WHERE: ALL BUT ARE OPTIONAL * * AND ANY IS OF THE FORM: * * filename,filename/unit, OR filenumber * * * * = disk SOURCE FILE name * * = disk LIST FILE name * * = disk OBJECT FILE name * * = disk ERROR FILE name * * = disk SYMBOL FILE name, or '=' * * which will cause it to be the * * same file as * * options = ANY COMBINATION OF: form,A,L,#,P,X * * * * options: * * A: INFILE IS IN ALS8 FORMAT * * L: INFILE HAS LINE NUMBERS * * #: GENERATE NEW LINE NUMBERS FOR LISTFILE * * P: PAGAGNATE LISTFILE * * X: PRODUCE A CROSS REFERENCE LISTING * * form: FORMAT OF LISTFILE (0-3) (SEE BELOW) * * * * A - X MAY BE PROCEEDED BY A + OR - TO TURN THE * * OPTION ON OR OFF. IF NEITHER, + IS ASSUMED * * DEFAULT: +#, +P, -X; A AND L ARE DETERMINED * * BY SCANNING FIRST FEW LINES OF CODE * * * * FORMAT: 0 no format * * 1 minimum (72) * * 2 nominal (80) * * 3 maximum (132) * * * * * **************************************************************** TITL DISK ASSEMBLER"ASSM 1.1 (MOD 0) * * EQUATES * COPY NPTDEFS PTDOS DEFINITIONS TMARG EQU 5 TOP MARGIN FOR PAGNATION BMARG EQU 62 BOTTOM MARGIN FOR PAGNATION CR EQU 13 ASCII CARRIAGE RETURN LF EQU 10 ASCII LINEFEED LLAB EQU 5 IBFLN EQU 120 INPUT BUFFERS (IBUF) LENGTH TRUE EQU 0FFH * ///// DIRECT REFERENCE TO SYSTEM ///// GLOBG EQU 5*34 SIZE OF GARBAGE AT START OF "SYSGLOBL" ///// DNAMP EQU GLOBG+GLNAM OFFSET INTO "SYSGLOBL" OF DISK NAME * * ASCF 0 IFLS ORG 100H XEQ ASSMD * **************************************************************** * * INITIALIZE * ASSMD LXI D,NBUF+10 ZERO NAME BUFFER MVI B,8 XRA A CALL ZBU1 LXI D,IBUF+IBFLN MVI B,IBFLN MVI A,' ' CALL ZBU1 * LHLD SYSGLO LXI D,GLCIF DAD D MOV A,M CIFILE STA CIUNT SAVE INTERNAL LHLD SYSGLO LXI D,GLCOF DAD D MOV A,M STA CONIT SAVE COFILE INTERNAL FOR LATER ADDITIONS * LHLD SYSGLO LXI D,GLFLG GET ADDRESS OF CHARACTER FLAG DAD D SHLD CHARFL * * SET DOS ERROR TRAP FOR RETURN TO HERE * LHLD SYSGLO LXI D,GLERM DAD D SHLD ERMPT MOV E,M MVI M,-1 INX H MOV D,M MVI M,-1 XCHG . GET BACK ORGINAL DOS ERROR TRAP SHLD ERSWC SAVE DOS ERROR SWITCHES * CALL GARGS READ ARGUMENTS FROM CIFILE * **************************************** * * * * ASSEMBLER CODE * LXI D,STMSG PRINT START MESSAGE LDA HOFLG DOES USER WANT US TO PRINT IT? CPI '-' CNZ PRINT YEP XRA A STA SYMA1 START SYMBOL TABLE LXI H,COBUF SHLD LADDR * ASM3 LXI H,100H DEFAULT ORG ADDRESS SHLD ASPC SHLD BBUF SHLD BADDR LXI H,0 SHLD BCOUNT * ASM0 LXI SP,AREA+18 SET STACK POINTER LDA PASI ON PASS 1? ORA A JNZ ASM2 NO-PASS 2 OR 3 * ASM1 CALL GTLIN GET LINE FROM INFILE CALL PAS1 JMP ASM1 * * ASM2 CALL GTLIN GET LINE FROM INFILE CALL PAS2 CALL LOUT OUTPUT LINE TO LISFILE (&ERRFILE IF ERR) JMP ASM2 * **************************************** * * * GET LINE FROM IN-FILE(OR COPY FILE) TO IBUF * GTLIN LDA EOFLG END OF FILE ON LAST CALL? ORA A JNZ INEOF YES-DONE READING THIS FILE LXI H,OBUF CLEAR OBUF MVI A,>IBUF CALL CLER LXI H,IBUF PUT CR AT IBUF IN CASE OF SHORT LINE MVI M,CR * CALL PAUSE PAUSE/EXIT ON SPACEBAR/MODE SELECT * LHLD RLINE READ INTO MEMORY AT RLINE XCHG . LXI B,IBFLN * GTLI1 MVI L,CR UNTILL A CR IS READ LDA CPYSS GET CURRENT COPY FILE CPI 0FFH IS THERE ANY? JNZ GTLI2 YES-USE IT LDA INUM NO-USE IN-FILE * GTLI2 MOV H,A CALL SYS DB DRDOP CALL EOFTS MOV A,C GET BYTES READ COUNT CPI IBFLN WERE ANY READ JZ INEOF NO-HIT EOF ORA A WAS MAX READ COUNT HIT? CZ GTLI7 YES-CHECK FOR LINE LONGER THAN IBFLN LDA AOFLG ALS8 FORMAT? CPI '+' JNZ GENUM NO-DONE READING LINE, CHECK # OPTION * GTLI6 LHLD RLINE XCHG . LDAX D GET ALS8 BYTE COUNT CPI 1 JNZ GTLI9 NOT=1, SKIP AHEAD MOV A,C ALS8 BYTE COUNT=1,SHIFT IBUF LEFT CPI IBFLN-1 ONLY ONE BYTE READ? JZ INEOF YES-DONE READING HIT EOF CALL GTLI4 GO DO THE SHIFTING JMP GTLI6 GO TEST LINE AGAIN * * GTLI9 CPI CR ONLY ONE BYTE READ (ALS8 COUNT=CR)? JZ GTLI3 * GTLI8 ADD C ADD IBFLN-(BYTES READ) TO ALS8 COUNT CPI IBFLN IS IT IBFLN? (ALS8 COUNT=BYTES READ?) CNZ ERR8 IF BYTES READ <> ALS8 BYTE COUNT-ERROR LHLD RLINE MVI M,' ' BLANK OUT ALS8 BYTE COUNT JMP GENUM DONE READING LINE, CHECK # OPTION * * * READ REST OF LINE IF 1ST BYTE WAS CR * GTLI3 MOV A,C GET BYTES READ COUNT CPI IBFLN-1 ONLY 1? INX D DON'T WANT TO WRITE OVER BYTE COUNT JZ GTLI1 YES-GO READ REST OF LINE MVI A,13 NO-HAS ALREADY BEEN HERE, LINE IS READ IN JMP GTLI8 RESTORE BYTE COUNT TO A AND RECHECK LINE * * * SHIFT IBUF LEFT ONE * GTLI4 INR C UPDATE READ COUNT SINCE DELETING 1ST BYTE LHLD RLINE INX H GTLI5 MOV A,M GET NEXT BYTE STAX D MOVE IT TO ONE LOCATION EARLIER CPI CR RZ . DONE SHIFT IF CR INX D INX H JMP GTLI5 * * * HANDLE LINES LONGER THAN IBFLN * GTLI7 DCX D LDAX D GET LAST BYTE READ CPI CR WAS IT A CR? INX D RZ . YES-JUST FITS, SO OK MOV A,H NO-SPACE OVER GARBAGE TILL CR PUSH B LXI B,0FFFFH MVI D,1 MVI L,CR CALL SYS DB SPAOP CALL EOFTS POP B RET ******************* * * * GENERATE LINE NUMBERS (IN DECIMAL) * GENUM LDA NOFLG LINE NUMBER GENERATION WANTED? CPI '+' RNZ . NOPE LHLD LINO PUT NEW LINE NUMBERS IN IN/OUT BUFFER SHLD IBUF-5 LHLD LINO+2 SHLD IBUF-5+2 LXI H,LINO+3 INCREMENT LINE NUMBER IN LINO MVI E,4 * GENU1 MOV A,M CPI '9' INR M RC . MVI M,'0' DCX H DCR E JNZ GENU1 RET . * ********** * * INEOF XRA A RESET EOFLG STA EOFLG LDA CPYSS IS THERE A CURRENT COPY FILE? CPI 0FFH JZ EASS0 NO-END OF A PASS CALL CLOSE CLOSE CURRENT COPY FILE CALL CPYPO POP OUT NEW COPY FILE JMP GTLIN * ******************** * * PAUSE/EXIT ON SPACEBAR/MODE SELECT * PAUSE CALL CONTST IS KEY PRESSED? RZ . NO CALL CONIN GET CHARACTER ORA A JZ DONE1 IF MODE SELECT, DONE CPI ' ' JNZ PAUS1 IF NOT BLANK RETURN IT TO CI PAUS2 CALL CONIN PAUSE TILL ANOTHER KEY HIT ORA A JZ DONE1 IF MODE SELECT, DONE CPI ' ' RZ . IF BLANK, STOP PAUSING CPI '0' JC PAUS2 IF NON-DIGIT, IGNORE CPI '9'+1 JNC PAUS2 LIKEWISE PAUS1 LHLD CHARFL MOV M,A RET . * **************************************** * * * OUTPUT LINE TO LIST FILE IF THERE IS ONE * OUTPUT ERROR LINE TO ERROR FILE IF THERE IS ONE * LOUT LDA PASI CPI 2 PASS 3? RNC . YES CALL EOUT OUTPUT TO ENUM IF ERROR LDA LNUM IS THERE A LIST FILE? INR A RZ . NO-RETURN LDA OBUF+18 IS THERE AN ERROR? CPI ' ' JNZ LOUT2 YES-SKIP NLST FLAG CHECK LDA ALST IS NLST FLAG SET? ORA A RNZ . YES-RETURN * LOUT2 CALL FORMT FORMAT OUTPUT LDA POFLG PAGINATION WANTED? CPI '+' LDA LNUM CZ PAGE YES CALL PAGEUP BUMP COUNT OF LINES ON PAGE (MOD 66) LDA LNUM OUTPUT TO LIST FILE * LOUT1 LXI B,255 LXI D,OBUF MVI L,CR CALL SYS WRITE TILL CR DB DWROP CALL ERR0 MVI B,LF FOLLOW WITH LINEFEED CALL WB CALL ERRWB RET . * * * OUTPUT LINE TO EFILE IF THERE IS ONE * EOUT CALL FORMT FORMAT OUTPUT LDA OBUF+18 IS THERE AN ERROR? CPI ' ' RZ . NO-RETURN LDA ENUM IS THERE AN ERROR FILE? CPI 0FFH RZ . NO-RETURN JMP LOUT1 * * * OUTPUT LINE TO SYMBOL FILE * SOUT PUSH D LHLD SBPTR GET SBUF LINE POINTER MVI M,CR PLACE A MARKER THERE INX H MVI M,LF LDA POFLG PAGNATION WANTED? CPI '+' LDA SNUM CZ PAGE YES CALL PAGEUP BUMP COUNT OF LINES ON PAGE (MOD 66) LXI H,SBUF POINT TO START OF SBUF SHLD SBPTR RESET SBPTR THERE LDA SNUM LXI B,134 XCHG . MVI L,LF CALL SYS DB DWROP CALL ERR0 POP D RET . * * * CHECK FOR AND SKIP OVER PAGE BOUNDRIES * PAGE MOV C,A SAVE FILE NUMBER LDA PGCNT UPDATE COUNT OF LINES ON PAGE CPI TMARG ABOVE TOP MARGIN? JC PAGEABOVE YES CPI BMARG+1 BELOW BOTTOM MARGIN? RC . NO-WITHIN MARGINS * SUI 66 PAGEABOVE CMA A INR A ADI TMARG CALL PAGEMOVE * MVI A,TMARG SET LINE NUMBER STA PGCNT CALL PGHEAD OUTPUT PAGE HEADER RET . * * PAGEMOVE DCR A OUTPUT A CRLF'S TO FILE #C RM . CALL PAGECR JMP PAGEMOVE * * PAGECR MOV B,A PUSH B MOV A,C LXI B,2 LXI D,CRLF CALL SYS DB WBLOP CALL ERR0 POP B MOV A,B RET . * * NEWPAGE MOV C,A MOVE TO NEW PAGE INR A RZ . FILE NOT OPEN LDA POFLG CPI '+' RNZ . PAGINATION NOT WANTED MVI A,67 LXI H,PGCNT SUB M CPI 66 RZ . ALREADY AT TOP OF PAGE CALL PAGEMOVE MVI A,1 STA PGCNT RET . * * PAGEUP LDA PGCNT INCREMENT COUNT OF LINES ON PAGE (MOD 66) INR A STA PGCNT CPI 67 RC . SUI 66 STA PGCNT RET . * **************************************** * * * PASS 1 OF ASSEMBLER. USED TO FORM SYMBOL TABLE * PAS1 CALL ZBUF CLEAR BUFFER STA PASI SET FOR PASS 1 LXI H,IBUF INITIALIZE LINE POINTER SHLD PNTR SAVE ADDRESS MOV A,M FETCH CHARACTER CPI ' ' CHECK FOR A BLANK JZ OPC JUMP IF NO LABEL CPI '*' CHECK FOR COMMENT RZ . RETURN IF COMMENT CPI ';' SAME THING RZ . CPI CR SAME THING RZ . * * PROCESS LABEL * CALL SLAB GET AND CHECK LABEL JC LERR ERROR IN LABEL PUSH PSW LDA IFFLG ORA A JZ LPRC1 POP PSW JMP OPC * * LPRC1 CALL LCHK CHECK CHARACTER AFTER LABEL JZ LPRC2 POP PSW JMP LERR ERROR IN LABEL LPRC2 POP PSW JZ ERRD DUPLICATE LABEL * CALL MLAB1 STORE LABEL XCHG SHLD TABA SAVE TABLE ADDRESS FOR EQU LDA ASPC+1 FETCH PC (HIGH) MOV M,A STORE IN TABLE INX H LDA ASPC FETCH PC (LOW) MOV M,A STORE IN TABLE INX H MVI M,0 SET TABLE TERMINATION SHLD STEND SAVE SYMTAB'S ENDING ADDRESS LXI H,LBCNT+3 BUMP COUNT OF SYMBOLS (IN ASCII-DECIMAL) MVI E,4 CALL GENU1 * * PROCESS OPCODE * OPC CALL ZBUF ZERO WORKING BUFFER CALL SBLK SCAN TO OPCODE JC OPCCR FOUND CARRIAGE RETURN LXI D,ABUF CALL ALPS PLACE OPCODE IN BUFFER CPI ' ' CHECK FOR BLANK AFTER OPCODE JC OPCD CR AFTER OPCODE JNZ OERR ERROR IF NO BLANK JMP OPCD CHECK OPCODE * OPCCR LXI H,IBUF FOUND CR BEFORE OPCODE, CHECK FOR LABLE MOV A,M CPI ' ' JNZ OERR FOUND LABLEP-SO OPCODE ERROR LDA PASI CHECK PASS ORA A RZ . ON PASS 1 JUST IGNORE LINE JMP COMNT ON PASS2 TREAT AS COMMENT * * MLAB1 MVI C,LLAB LABEL LENGTH LXI H,ABUF SET BUFFER ADDRESS MLAB MOV A,M FETCH NEXT CHARACTER STAX D STORE IN SYMBOL TABLE INX D INX H DCR C DECREMENT COUNT JNZ MLAB RET * * * THIS ROUTINE CHECKS THE CHARACTER AFTER A LABEL FOR A * BLANK OR A COLON. * LCHK LHLD PNTR MOV A,M GET CHARACTER AFTER LABEL CPI ' ' CHECK FOR A BLANK RZ . RETURN IF A BLANK CPI ':' CHECK FOR A COLON RNZ INX H SHLD PNTR SAVE POINTER RET * * * PROCESS ANY PSEUDO OPS THAT NEED TO BE IN PASS 1 * PSU1 CALL SBLK SCAN TO OPERAND LDAX D FETCH VALUE ORA A JZ ORG1 ORG OPCODE JM DAT21 DATA STATEMENT CPI 2 JC EQU1 JZ RES1 CPI 8 JZ ASC1 CPI 17 JZ ASCZ1 CPI 9 JZ ASM0 CPI 12 JZ ACO1 DDB SAME AS DW IN PASS ONE CPI 13 JZ CPY "COPY" CPI 14 JZ IFPRC CPI 4 JZ EASS "END" RNC . IGNORE ALL OVER 4 * * DO DW PSEUDO/OP * ACO1 MVI C,2 2 BYTE INSTRUCTION ACO11 MVI B,0 ACO12 LHLD ASPC UPDATE PC DAD B SHLD ASPC RET . * * * PROCESS TITLE * TITLP LDA PASI IGNORE ON PASS 3 CPI 2 JZ ASM0 CALL SBLK SCAN TO TITLE XCHG . LXI H,TITLBUF POINT TO TITLE BUFFER TITL1 LDAX D GET CHARACTER CPI CR INX D JZ TDON1 CPI '"' FIRST DELIMITER? JZ TITL2 MOV M,A INX H JMP TITL1 * * TITL2 MVI M,0 STORE DELIMITER INX H TITL3 LDAX D CPI '"' JZ TDON1 CPI CR JZ TDON1 MOV M,A INX H INX D JMP TITL3 * * TDON1 MVI M,0 INX H MVI M,0 JMP ASM0 * * * DO ORG PSEUDO-OP * ORG1 CALL ASCN GET OPERAND LDA OBUF+18 FETCH ERROR INDICATOR CPI ' ' CHECK FOR AN ERROR JNZ LOUT ERROR DON'T CHANGE PC SHLD ASPC STORE NEW ORIGIN LDA IBUF GET FIRST CHARACTER CPI ' ' CHECK FOR LABEL RZ JMP EQUS CHANGE LABEL VALUE * * * DO EQU PSEUDO-OP * EQU1 CALL ASCN GET OPERAND LDA IBUF FETCH 1ST CHARACTER CPI ' ' CHECK FOR LABEL JZ ERRM MISSING LABEL * EQUS XCHG LHLD TABA SYMBOL TABLE ADDRESS MOV M,D STORE LABEL VALUE INX H MOV M,E LDA OBUF+18 OUTPUT TO ERROR FILE IF OBUF+18 HAS ERROR CPI ' ' JNZ LOUT RET . * * * PROCESS IF STATEMENT * IFPRC LDA IFFLG ORA A JNZ IFALS CALL ASBL LDA OBUF+18 CPI ' ' JNZ LOUT IF ERROR OUTPUT IT MOV A,H ORA L JZ IFALS XRA A * IFPRI STA IFFLG JMP IFLTS * IFALS LDA IFFLG INR A JMP IFPRI * * ENDIF LDA IFFLG DCR A JP IFPRI XRA A JMP IFPRI * * IFLST XRA A INR A STA ILFLG JMP ASM0 * * * DO DS PSEUDO-OP * RES1 CALL ASCN GET OPERAND MOV B,H MOV C,L LDA OBUF+18 CPI ' ' ERROR? JNZ LOUT JMP RES21 ADD VALUE TO PROGRAM COUNTER * * * DO ASCZ PSEUDO-OP * ASCZ1 MOV A,M GET FIRST CHARACTER CPI CR CARRIAGE RETURN RZ . MOV D,A SAVE AS DELIMITER LXI B,1 SET BYTE COUNT TO 1 JMP ASC11 * * * DO ASC PSEUDO-OP * ASC1 MOV A,M GET FIRST CHARACTER CPI CR CARRIAGE RETURN RZ MOV D,A SAVE AS DELIMITER LXI B,0 SET BYTE COUNT TO 0 * ASC11 INX H MOV A,M GET NEXT CHARACTER CPI CR CARRIAGE RETURN JZ RES21 UPDATE PC CMP D FOUND DELIMITER JZ RES21 INX B JMP ASC11 * ******************* * * * PERFORM PASS 2 OF THE ASSEMBLER * PAS2 LXI H,OBUF SET OUTPUT BUFFER ADDRESS LDA ASPC+1 FETCH PC (HIGH) CALL BINH0 CONVERT FOR OUTPUT INX H LDA ASPC FETCH PC (LOW) CALL BINH0 CONVERT FOR OUTPUT SHLD OIND SAVE OUTPUT ADDRESS CALL ZBUF CLEAR BUFFER LXI H,IBUF INITIALIZE LINE POINTER * SHLD PNTR SAVE POINTER MOV A,M FETCH FIRST CHARACTER CPI ' ' CHECK FOR LABEL JZ OPC GET OPCODE CPI '*' CHECK FOR COMMENT JZ COMNT PROCESS COMMENT LINE CPI ';' ANOTHER COMMENT JZ COMNT CPI CR ANOTHER COMMENT JZ COMNT CALL SLAB SCAN OFF LABEL JC LERR ERROR IN LABEL CALL LCHK CHECK FOR A BLANK OR COLON JNZ LERR ERROR IF NOT A BLANK JMP OPC * * COMNT LDA IFFLG IS IF FLAG SET? ORA A JZ COMT2 NO-PRINT AS NORMAL COMMENT * IFLTS LDA ILFLG IS IF LIST FLAG SET? ORA A JZ ASM0 NO-DON'T PRINT;YES-PRINT AS COMMENT * COMT2 LXI H,2020H SHLD OBUF BLANK OUT ADDRESSES ON COMMENT LINES SHLD OBUF+2 RET * * * PROCESS PSEUDO OPS FOR PASS 2 * PSU2 LDAX D ORA A JZ ORG2 ORG OPCODE JM DAT2 DATA OPCODE CPI 2 JC EQU2 EQUATE OPCODE JZ RES2 CPI 5 JZ FRMFEED CPI 8 JZ ASC2 CPI 17 JZ ASCZ2 CPI 9 JZ TITLP CPI 10 JZ XEQP PROCESS XEQ ADDRESS CPI 11 JZ ASCFP PROCESS ASCII FLAG CPI 12 JZ DDBP DOUBLE BYTE PROCESS CPI 14 JZ IFPRC CPI 16 JZ IFLST CPI 13 JZ CPY "COPY" CPI 4 JZ END2 "END" JNC LST MUST BE "LST" OR "NLST" JMP ACO2 MUST BE DW * * * DO DW PSEUDO-OP * ACO2 CALL SBLK SCAN TO ARGUMENT CALL TYS6 GET VALUE JMP ACO1 * * GET VALUE OF EQUATE FOR LISTING * EQU2 CALL ASBL GET VALUE EQU3 XCHG . TO DE CALL COMNT LHLD OIND INX H INX H MOV A,D CALL BINH0 CONVERT D TO LISTING INX H MOV A,E JMP BINH0 * * * DEFINE DOUBLE BYTE * DDBP CALL ASBL MOV A,H GET HIGH MOV D,L CALL TYS6A JMP ACO1 * * * DO DS PSEUDO-OP * RES2 CALL ASBL GET OPERAND MOV B,H MOV C,L LHLD BBUF FETCH STORAGE COUNTER DAD B ADD VALUE PUSH B CALL ORG3 UPDATE BINARY FILE POP B RES21 JMP ACO12 * * * DO DB PSEUDO-OP * DAT2 CALL SBLK SCAN TO FIRST ARGUMENT LHLD PNTR COPY LINE INTO INTO SPARE BUFFER LXI D,BUFR DAT24 MOV A,M STAX D INX D INX H CPI CR JNZ DAT24 LXI H,BUFR SHLD PNTR MVI A,4 ONLY WANT 4 DB VALUES PER LINE STA DBCNT DA2TA CALL ASCN GET ARGUMENT INR A CPI 2 CHECK ARGUMENT FOR RANGE CNC ERRV OPERAND OUT OF RANGE MOV A,L CALL ASTO OUTPUT BYTE TO LIST AND BIN FILES CALL DAT22 UPDATE PC AND CHECK FOR MORE ARGS PUSH PSW SAVE FLAGS LDA DBCNT UPDATE DBCNT DCR A STA DBCNT CZ DAT25 4 DB VALUES ON LINE, SO OUTPUT IT POP PSW RESTORE FLAGS JZ DA2TA IF MORE ARGS, PROCESS THEM LDA OBUF+6 DOES LAST LINE HAVE ANY VALUES ON IT? CPI ' ' CNZ DAT25 YES-OUTPUT LAST LINE JMP ASM0 NOTHING LEFT TO LIST * DAT22 MVI C,1 CALL ACO11 UPDATE PC BY C LHLD PNTR CHECK NEXT CHARACTER MOV A,M CPI ',' RNZ . INX H SHLD PNTR IF ',' MOVE PNTR OVER IT RET . * DAT21 CALL SBLK SCAN TO FIRST ARGUMENT DAT2A CALL ASCN GET ARGUMENT CALL DAT22 UPDATE PC AND CHECK FOR MORE ARGS JZ DAT2A IF MORE, PROCESS THEM RET . * DAT25 LDA OBUF IS THIS FIRST LINE? CPI ' ' JZ DAT26 NO-SKIP AHEAD CALL LOUT YES-OUTPUT IT JMP DAT28 DAT26 LDA ASFLG ORA A JZ DAT27 IF ASFLG NOT SET, SKIP AHEAD CALL LOUT JMP DAT28 DAT27 LDA OBUF+18 CPI ' ' JZ DAT28 IF NO ERRORS, SKIP AHEAD CALL LOUT DAT28 MVI A,4 RESET DBCNT STA DBCNT MVI A,' ' LXI D,OBUF+20 MVI B,20 CALL ZBU1 FILL OBUF WITH BLANKS MVI A,CR PLACE CR AT END OF OBUF STA OBUF+20 LXI H,OBUF+3 SHLD OIND SET BUFFER POINTER RET . * * * DO XEQ PSEUDO-OP * XEQP CALL ASBL LDA OBUF+18 CPI ' ' CHECK FOR ERROR RNZ . IF ERROR STA XQFLG SHLD XQADR JMP EQU3 * * * DO ORG PSEUDO-OP * ORG2 CALL ASBL GET NEW ORIGIN LDA OBUF+18 GET ERROR INDICATOR CPI ' ' CHECK FOR AN ERROR RNZ . DON'T MODIFY PC IF ERROR SHLD ASPC STORE NEW PC MOV A,H LXI H,OBUF CALL BINH0 INX H LDA ASPC CALL BINH0 LHLD ASPC * ORG3 SHLD BBUF CALL UPDATE LHLD BBUF SHLD BADDR NEW BUFFER ADDRESS RET * * * DO PAGE PSEUDO-OP * FRMFEED LDA PASI IGNORE ON PASS 3 CPI 2 JZ ASM2 LDA LNUM CALL NEWPAGE JMP ASM2 * * SET ASCII OUTPUT FLAG * ASCFP CALL ASBL MOV A,L STA ASFLG STORE NEW ASCII FLAG JMP ASM0 * * * PROCESS LST AND NLST PSEUDO-OPS * LST SUI 6 STA ALST SET LIST SWITCH JMP ASM0 * * * DO ASCZ PSEUDO-OP * ASCZ2 CALL SBLK SCAN TO OPERAND JC ERRA FOUND CR MOV C,A SAVE DELIMITER INX H MOV A,M GET NEXT CHARACTER CPI CR JZ ERRA CMP C FOUND DELIMITER JZ ERRA MVI B,-7 LXI D,BUFR POINT TO SPARE BUFFER * ASCZST STAX D STORE CHARACTER INX H INX D MOV A,M CPI CR JZ ASCZDN CMP C JNZ ASCZST * ASCZDN XRA A STORE THE EXTRA ZERO BYTE AT END OF SPARE BUFFER STAX D INX D MOV A,C JMP ASCDN * * * DO ASC PSEUDO-OP * ASC2 CALL SBLK SCAN TO OPERAND JC ERRA FOUND CR MOV C,A SAVE DELIMITER INX H MOV A,M GET NEXT CHARACTER CPI CR JZ ERRA CMP C FOUND DELIMITER JZ ERRA MVI B,-7 LXI D,BUFR POINT TO SPARE BUFFER * ASCST STAX D STORE CHARACTER INX H INX D MOV A,M CPI CR JZ ASCDN CMP C DELIMITER? JNZ ASCST KEEP STORING * ASCDN STAX D SAVE DELIMITER LXI H,BUFR RESET POINTER ASC21 MOV A,M GET NEXT CHARACTER CPI CR JZ ASC23 CMP C FOUND DELIMITER JZ ASC23 SHLD PNTR LHLD ASPC INX H INCREMENT PROGRAM COUNTER SHLD ASPC SAVE PC INR B PUSH B CALL ASTO STORE OBJECT BYTE LHLD OIND GET POINTER INTO OBUF MOV A,L CPI >OBUF+15 JNZ ASC22 * OUTPUT LINE IF APPROPRIATE POP B PUSH B MOV A,B ORA A JM ASOUT FIRST TIME THROUGH LDA ASFLG GET OUTPUT SWITCH ORA A JZ ASC2A NO OUTPUT * ASOUT CALL LOUT ASC2A POP B MVI B,0 PUSH B CALL COMNT ASCII BLANKS MVI A,CR STA OBUF+16 PUT CR IN BUFFER LXI H,OBUF+3 SHLD OIND SET BUFFER POINTER * ASC22 LHLD PNTR POP B INX H JMP ASC21 * * GET HERE AT END OF SCAN * ASC23 MOV A,B ORA A ANYTHING ON LINE RM LDA ASFLG GET ASCII LISTING FLAG ORA A JZ ASM0 THE FLAG SAYS NO MOV A,B ORA A JZ ASM0 NOTHING TO LIST * LHLD OIND GET LAST CHARACTER ON LINE INX H MVI M,CR PUT IN A CR RET * * * DO END PSEDO-OP FOR PASS 2 * END2 CALL COMNT CALL LOUT PRINT OUT THE LINE JMP EASS * * * * PROCESS 1 BYTE INSTRUCTIONS WITHOUT OPERANDS * * * PROCESS STAX AND LDAX INSTRUCTIONS * TYP2 CALL ASBL FETCH OPERAND CNZ ERRR ILLEGAL REGISTER MOV A,L GET LOW ORDER OPERAND ORA A SET FLAGS JZ TY31 OPERAND = 0 CPI 2 OPERAND = 2 CNZ ERRR ILLEGAL REGISTER JMP TY31 * * * PROCESS PUSH,POP,INX,DCX,DAD INSTRUCTIONS * TYP3 CALL ASBL FETCH OPERAND CNZ ERRR ILLEGAL REGISTER MOV A,L GET LOW ORDER OPERAND RRC . CHECK LOW ORDER BIT CC ERRR ILLEGAL REGISTER RAL . RESTORE OPERAND CPI 8 CNC ERRR ILLEGAL REGISTER * TY31 RLC . MULTIPLY BY 8 RAL RAL TY32 MOV B,A LDAX D FETCH OPCODE BASE ADD B FORM OPCODE CPI 118 CHECK FOR MOV M,M CZ ERRR ILLEGAL REGISTER JMP ASTO0 * * * PROCESS ACCUMULATOR, INR,DCR,MOV,RST INSTRUCTIONS * TYP4 CALL ASBL FETCH OPERAND CNZ ERRR ILLEGAL REGISTER MOV A,L GET LOW ORDER OPERAND CPI 8 CNC ERRR ILLEGAL REGISTER LDAX D FETCH OPCODE BASE CPI 64 CHECK FOR MOV INSTRUCTION JZ TY41 CPI 199 MOV A,L JZ TY31 RST INSTRUCTION JM TY32 ACCUMULATOR INSTRUCTION JMP TY31 INR,DCR * * * PROCESS MOV INSTRUCTION * TY41 DAD H MULTIPLY OPERAND BY 8 DAD H DAD H ADD L FORM OPCODE STAX D SAVE OPCODE CALL MPNT INCREMENT POINTER CALL ASCN GET NEXT OPERAND CNZ ERRR ILLEGAL REGISTER MOV A,L FETCH LOW ORDER OPERAND CPI 8 CNC ERRR ILLEGAL REGISTER JMP TY32 * * * PROCESS IMMEDIATE INSTRUCTIONS * IMMEDIATE BYTE CAN BE BETWEEN -256 AND +255 * MVI INSTRUCTION IS A SPECIAL CASE AND CONTAINS 2 * ARGUMENTS IN OPERAND * TYP5 PUSH PSW SAVE INSTRUCTION CALL SBLK SCAN TO ARGUMENT POP PSW RESTORE INSTRUCTION CPI 6 CHECK FOR MVI INSTRUCTION CZ TY56 CALL ASTO STORE OBJECT BYTE * CALL ASCN GET IMMEDIATE ARGUMENT INR A CPI 2 CHECK OPERAND FOR RANGE CNC ERRV OPERAND OUT OF RANGE MOV A,L JMP ASTO0 * * * FETCH 1ST ARGUMENT FOR MVI AND LXI INSTRUCTIONS * TY56 CALL ASCN FETCH ARGUMENT CNZ ERRR ILLEGAL REGISTER MOV A,L GET LOW ORDER ARGUMENT CPI 8 CNC ERRR ILLEGAL REGISTER DAD H MULTIPLY BY 8 DAD H DAD H LDAX D FETCH OPCODE BASE ADD L FORM OPCODE MOV E,A SAVE OBJECT BYTE * MPNT LHLD PNTR FETCH POINTER INX H INCREMENT POINTER SHLD PNTR MOV A,E GET OBJECT BYTE RET * * * PROCESS 3 BYTE INSTRUCTIONS * * LXI INSTRUCTION IS A SPECIAL CASE * TYP6 PUSH PSW SAVE INSTRUCTION CALL SBLK SCAN TO ARGUMENT POP PSW RESTORE INSTRUCTION CPI 1 CHECK FOR LXI INSTRUCTION JNZ TY6 JUMP IF NOT LXI CALL SBLK SCAN TO FIRST ARGUMENT CALL TY56 GET REGISTER ANI 08H CHECK FOR ILLEGAL REGISTER CNZ ERRR REGISTER ERROR MOV A,E GET OPCODE ANI 0F7H CLEAR BIT IN ERROR TY6 CALL ASTO STORE OBJECT BYTE * TYS6 CALL ASCN FETCH OPERAND MOV A,L MOV D,H TYS6A CALL ASTO0 STORE 2ND BYTE MOV A,D * * STORE OBJECT CODE TO LIST FILE * ASTO0 MOV B,A SAVE OBJECT BYTE LHLD PNTR MOV A,M CPI ',' ARE THERE MORE ARGUMENTS ON LINE? MOV A,B RESTORE OBJECT BYTE JNZ ASTO NO-OK CALL ERRS YES-SYNTAX ERROR * ASTO MOV B,A SAVE OPCODE LDA PASI CPI 2 PASS 3? RNC . YES LHLD OIND OUTPUT TO OBUF FOR LISTING INX H INX H MOV A,B CALL BINH0 CONVERT TO ASCII SHLD OIND * * STORE OBJECT CODE TO BINARY FILE * LDA BNUM IS THERE AND OBJECT FILE? INR A RZ . NO-THEN RETURN * LHLD LADDR GET LINE ADDRESS MOV M,B INX H SHLD LADDR NEW LINE ADDRESS LHLD BBUF GET CODE ADDRESS INX H SHLD BBUF * * IS BINARY FILE UPDATE NEEDED? * LDA BCOUNT BUMP LINE COUNT INR A STA BCOUNT CPI 100 AT THE END? RC * * UPDATE BINARY FILE & ZERO RECORD & LINE * UPDATE LDA BCOUNT ORA A RZ . NO UPDATE IF ZERO * PUSH H PUSH D PUSH B LXI H,BCOUNT POINT TO COUNT MOV A,M GET IT INX H MVI B,0 MOV M,B MAKE SURE IT'S ZERO DCX H XCHG . DE HAVE POINTER ADI 4 BUMP LENGTH MOV C,A LDA BNUM OBJECT FILE CALL SYS DB WBLOP WRITE IT OUT * CALL ERR0 XRA A STA BCOUNT LXI H,COBUF SHLD LADDR LHLD BBUF SHLD BADDR POP B POP D POP H RET * *