home *** CD-ROM | disk | FTP | other *** search
- ;
- ; THIS IS THE PROCESSOR TECHNOLOGY SELF CONTAINED SYSTEM
- ; (ALSO CALLED SOFTWARE PACKAGE NO. 1)
- ;
- ; THIS ROUTINE INITILALIZES THE FILE AREA FOR SUBSEQUENT PROCESSING
- ;
- ORG 100H
- INITA:
- MVI A,3
- OUT 20Q
- MVI A,21Q
- OUT 20Q ;SET UP ACIA
- LXI H,FILE0
- MVI C,MAXFIL*FELEN
- XRA A
- INIT2: MOV M,A
- INX H
- DCR C
- JNZ INIT2
- ;
- ; THIS IS THE STARTING POINT OF THE SELF CONTAINED SYSTEM ONCE
- ; THE SYSTEM HAS BEEN INITIALIZED. COMMANDS ARE READ FROM THE USER,
- ; EXECUTED, AND CONTROL RETURNS BACK TO THIS POINT TO READ ANOTHER
- ; USER COMMAND.
- ;
- SYS8: LXI SP,AREA+18
- CALL READ ;READ INPUT LINE
- INX H
- MOV A,M ;FETCH FIRST CHARACTER
- CPI '9'+1 ;COMMAND OR LINE NUMBER
- JC LINE ;JUMP IF LINE FOR FILE
- CALL VALC ;GET COMMAND VALUES
- CALL COMM ;CHECK LEGAL COMMANDS
- EOR: CALL CRLF ;GET HERE WHEN ROUTINE IS DONE
- JMP SYS8
- ;
- ;
- ; THIS ROUTINE READS IN A LINE FROM THE TTY AND PLACES IT IN AN
- ; INPUT BUFFER
- ; THE FOLLOWING ARE SPECIAL CHARACTERS
- ; CR - TERMINATES READ ROUTINE
- ; LF - NOT RECOGNIZED BY ROUTINE
- ; CONTROL X - DELETE CURRENT LINE
- ; DEL - DELETE CHARACTER
- ; ALL DISPLAYABLE CHARACTERS BETWEEN BLANK-Z AND THE ABOVE
- ; ARE RECOGNIZED BY THE READ ROUTINE. ALL OTHERS ARE SKIPPED
- ; THE ROUTINE WILL NOT ACCEPT MORE CHARACTERS THAN THE INPUT
- ; BUFFER WILL HOLD.
- ;
- READ: LXI H,IBUF ;SET INPUT BUFFER ADDRESS
- SHLD ADDS ;SAVE ADDRESS
- MVI E,2 ;INITIALIZE CHAR COUNT
- NEXT: CALL IN8 ;READ A LINE
- MOV A,B
- CPI 24 ;CHECK FOR CONTROL X
- JNZ CR
- CALL CRLF ;OUTPUT A CRLF
- JMP READ
- CR: CPI ASCR ;GET AN ASCII CR
- JNZ DEL
- MOV A,L
- CPI IBUF AND 0FFH
- JZ READ
- MVI M,ASCR ;PLACE CR AT END OF LINE
- INX H
- MVI M,1 ;PLACE OEF INDICATOR IN LINE
- INX H
- MVI A,IBUF+83
- CALL CLER ;CLEAR REMAINING BUFFER
- LXI H,IBUF-1
- MOV M,E ;SAVE CHAR COUNT
- RET
- DEL: CPI 127 ;CHECK FOR DELETE CHAR
- JNZ CHAR
- MVI A,IBUF
- CMP L ;IS THIS FIRST CHAR
- JZ NEXT
- DCX H ;DECR POINTER
- DCR E ;DECR COUNT
- BSPA: MVI B,5FH
- CALL OUT8
- JMP NEXT
- CHAR: CPI ' ' ;CHECK FOR LEGAL CHAR
- JC NEXT
- CPI 'Z'+1
- JNC NEXT
- MOV B,A
- CALL OUT8 ;ECHO CHAR
- MOV M,A
- MVI A,IBUF+81
- CMP L ;CHECK FOR END OF LINE
- JZ BSPA
- INX H
- INR E ;INCR CHAR COUNT
- JMP NEXT
- ;
- ;
- ; THIS ROUTINE IS USED TO BLANK OUT A PORTION OF MEMORY
- ;
- CLER: CMP L
- RZ
- MVI M,' '
- INX H
- JMP CLER
- ;
- ; THIS ROUTINE IS USED TO READ BYTE OF DATA FROM THE UART
- ;
- IN8:
- IN 20Q ;GET STATUS
- RRC ;MOVE INTO CARRY
- JNC IN8
- IN 21Q ;GET THE DATA
- ANI 7FH ;MASK OFF PARITY BIT
- MOV B,A
- RET
- ;
- ; THIS ROUTINE OUTPUTS A BYTE OF DATA TO THE UART
- ;
- OUT8:
- IN 20Q ;GET STATUS
- RRC
- RRC
- JNC OUT8
- OK: MOV A,B
- OUT 21Q ;SEND OUT THE DATA
- RET
- ;
- ; THIS ROUTINE WILL OUTPUT A CARRIAGE RETURN AND LINE FEED
- ; FOLLOWED BY TWO DELETE CHARACTERS WHICH PROVIDE TIME FOR A
- ; PRINT HEAD TO RETURN
- ;
- CRLF: MVI B,13 ;CR
- CALL OUT8
- LF: MVI B,10 ;LF
- CALL OUT8
- MVI B,127
- CALL OUT8
- CALL OUT8
- RET
- ;
- ; THIS ROUTINE JUMPS TO A LOCATION IN MEMORY GIVEN BY THE
- ; INPUT COMMAND
- ;
- EXEC: CALL VCHK ;CHECK FOR PARAMETER
- CALL CRLF
- LHLD BBUF ;FETCH ADDRESS
- PCHL ;JUMP TO PROGRAM
- ;
- ; THIS ROUTINES CHECKS THE INPUT COMMAND AGAINST ALL LEGAL COMMANDS
- ; STORED IN A TABLE. IF A LEGAL COMMAND IS FOUND A JUMP IS
- ; MADE TO THAT ROUTINE; OTHERWISE AN ERROR MESSAGE IS OUTPUT
- ; TO THE USER
- ;
- COMM: LXI D,CTAB ;COMMAND TABLE ADDRESS
- MVI B,NCOM ;NUMBER OF COMMANDS
- MVI A,4 ;LENGTH OF COMMAND
- STA NCHR ;SAVE
- CALL COMS ;SEARCH TABLE
- JNZ WHAT ;JUMP IF ILLEGAL COMMAND
- PCHL ;JUMP TO ROUTINE
- ;
- ; THIS ROUTINE CHECKS IF A BASE CHARACTER STRING IS EQUAL TO
- ; ANY OF THE STRINGS CONTAINED IN A TABLE POINTED TO BY
- ; D,E. THE LENGTH OF THE STRINGS ARE <256. ON RETURN IF THE
- ; ZERO FLAG IS SET A MATCH WAS FOUND; IF THE ZERO FLAG IS CLEAR,
- ; NO MATCH WAS FOUND. REGISTER B CONTAINS THE NUMBER OF
- ; STRINGS TO COMPARE.
- ; THE TABLE CONSISTS OF ANY NUMBER OF CHARS, WITH 2 BYTES CONTAINING
- ; VALUES ASSOCIATED WITH IT. IT CAN BE USED TO SEARCH THROUGH
- ; A COMMAND TABLE OR SYMBOL TABLE.
- ; ON RETURN D,E POINT TO THE LAST BYTE ASSOCIATED WITH THE CHARACTER
- ; STRING IF A MATCH WAS FOUND. IF NO MATCH WAS FOUND, D,E POINT TO
- ; THE NEXT LOCATION AFTER THE END OF THE TABLE.
- ;
- COMS: LHLD ADDS ;FETCH COMPARE ADDRESS
- LDA NCHR ;GET LENGTH OF STRING
- MOV C,A
- CALL SEAR ;COMPARE STRINGS
- LDAX D
- MOV L,A
- INX D
- LDAX D ;FETCH VALUE
- MOV H,A
- RZ
- INX D ;SET TO NEXT STRING
- DCR B ;DECR COUNT
- JNZ COMS
- INR B ;CLEAR ZERO FLAG
- RET
- ;
- ; THIS ROUTINE CHECKS IF TWO CHARACTER STRINGS CONTAINED IN MEMORY
- ; ARE EQUAL. THE STRINGS ARE POINTED TO BY H,L AND D,E.
- ; ON RETURN, THE ZERO FLAG SET INDICATES A MATCH. REGISTER C
- ; INDICATES THE LENGTH OF THE STRINGS. ON RETURN, THE POINTERS
- ; POINT TO THE NEXT ADDRESS AFTER THE CHARACTER STRINGS
- ;
- SEAR: LDAX D ;FETCH CHAR
- CMP M ;COMPARE STRINGS
- JNZ INCA
- INX H
- INX D
- DCR C ;DECR CHAR COUNT
- JNZ SEAR
- RET
- INCA: INX D
- DCR C
- JNZ INCA
- INR C ;CLEAR ZERO FLAG
- RET
- ;
- ; THIS ROUTINE ZEROS OUT A BUFFER IN MEMORY WHICH IS THEN
- ; USED BY OTHER SCANNING ROUTINES
- ;
- ZBUF: XRA A ;GET A ZERO
- LXI D,ABUF+12 ;BUFFER ADDRESS
- MVI B,12 ;BUFFER LENGTH
- ZBU1: DCX D ;DECR ADDR
- STAX D ;ZERO BUFFER
- DCR B
- JNZ ZBU1
- RET
- ;
- ; THIS ROUTINE CALLS ETRA TO OBTAIN THE INPUT PARAMETER VALUES
- ; AND CALLS AN ERROR ROUTINE IF AN ERROR OCCURS
- ;
- VALC: CALL ETRA ;GET INPUT PARAMETERS
- JC WHAT ;JUMP IF ERROR
- RET
- ;
- ; THIS ROUTINE EXTRACTS THE VALUES ASSOCIATED WITH A COMMAND
- ; FROM THE INPUT STREAM AND PLACES THEM IN THE ASCII BUFFER (ABUF)
- ; IT ALSO CALLS A ROUTINE TO CONVERT THE ASCII HEXADECIMAL TO BINARY
- ; AND STORES THEM IN THE BINARY BUFFER (BBUF)
- ; ON RETURN, CARRY SET INDICATES AN ERROR IN INPUT PARAMETERS
- ;
- ETRA: LXI H,0 ;GET A ZERO
- SHLD BBUF+2 ;ZERO VALUE
- SHLD FBUF ;SET NO FILE NAME
- CALL ZBUF ;ZERO BUFFER
- LXI H,IBUF-1 ;INPUT BUFFER ADDRESS
- VAL1: INX H
- MOV A,M ;FETCH INPUT CHAR
- CPI ' ' ;LOOK FOR FIRST BLANK
- CMC
- RNC
- JNZ VAL1 ;JUMP IF NO BLANK
- SHLD PNTR ;SAVE POINTER
- CALL SBLK ;SCAN TO FIRST PARAMETER
- CMC
- RNC ;RETURN IF CR
- CPI '/'
- JNZ VAL5 ;NO FILE NAME
- LXI D,FBUF ;NAME FOLLOWS PUT IN FBUF
- MVI C,NMLEN
- VAL2: INX H
- MOV A,M
- CPI '/'
- JZ VAL3
- DCR C
- JM WHAT
- STAX D ;STORE FILE NAME
- NOP
- INX D
- JMP VAL2
- VAL3: MVI A,' ' ;GET AN ASCII SPACE
- VAL4: DCR C
- JM DONE
- STAX D ;FILL IN WITH SPACES
- INX D
- JMP VAL4
- DONE: CALL SBL2
- CMC
- RNC
- VAL5: LXI D,ABUF
- CALL ALPS ;PLACE PARAMETER IN BUFFER
- MOV A,B ;GET DIGIT COUNT
- CPI 5 ;CHECK NUMBER OF DIGITS
- CMC
- RC ;RETURN IF TOO MANY DIGITS
- LXI B,ABUF
- CALL AHEX ;CONVERT VALUE
- RC ;ILLEGAL CHAR
- SHLD BBUF ;SAVE IN BINARY BUFFER
- LXI H,ABUF
- CALL NORM ;NORMALIZE ASCII VALUE
- CALL SBLK ;SCAN TO NEXT PARAMETER
- CMC
- RNC ;RETURN IF CR
- LXI D,ABUF+4
- CALL ALPS ;PLACR PARAMETER IN BUFFER
- MOV A,B
- CPI 5 ;CHECK NUMBER OF DIGITS
- CMC
- RC ;RETURN IF TOO MANY DIGITS
- LXI B,ABUF+4
- CALL AHEX ;CONVERT VALUE
- RC ;ILLEGAL CHAR
- SHLD BBUF+2 ;SAVE IN BINARY BUFFER
- LXI H,ABUF+4
- CALL NORM ;NORMALIZE ASCII VALUE
- ORA A ;CLEAR CARRY
- RET
- ;
- ; THIS ROUTINE FETCHES DIGITS FROM THE BUFFER ADDRESSED BY
- ; REGISTERS B,C AND CONVERST THE ASCII DECIMAL DIGITS INTO
- ; BINARY. UP TO A 16 BIT VALUE CAN BE CONVERTED. THE SCAN
- ; STOPS WHEN A BINARY ZERO IS FOUND IN THE BUFFER
- ;
- ADEC: LXI H,0 ;GET A 16 BIT ZERO
- ADE1: LDAX B ;FETCH ASCII DIGIT
- ORA A ;SET ZERO FLAG
- RZ ;RETURN IF FINISHED
- MOV D,H ;SAVE CURRENT VALUE
- MOV E,L ;SAVE CURRENT VALUE
- DAD H ;TIMES TWO
- DAD H ;TIMES TWO
- DAD D ;ADD IN ORIGINAL VALUE
- DAD H ;TIMES TWO
- SUI '0' ;ASCII BIAS
- CPI 10 ;CHECK FOR LEGAL VALUE
- CMC
- RC ;RETURN IF ERROR
- MOV E,A
- MVI D,0
- DAD D ;ADD IN NEXT DIGIT
- INX B ;INCREMENT POINTER
- JMP ADE1
- ;
- ; THIS ROUTINE FETCHES DIGITS FROM THE BUFFER ADDRESSED BY
- ; REGISTERS B,C AND CONVERTS THE ASCII HEXADECIMAL DIGITS INTO
- ; BINARY. UP TO A 16 BIT VALUE CAN BE CONVERTED. THE SCAN STOPS
- ; WHEN A BINARY ZERO IS FOUND IN THE BUFFER
- ;
- AHEX: LXI H,0 ;GET A 16 BIT ZERO
- AHE1: LDAX B ;FETCH ASCII DIGIT
- ORA A
- RZ ;RETURN IF ZERO
- DAD H ;LEFT SHIFT
- DAD H
- DAD H
- DAD H
- CALL AHS1 ;CONVERT TO BINARY
- CPI 10H ;CHECK FOR LEGAL VALUE
- CMC
- RC ;RETURN IF ERROR
- ADD L
- MOV L,A
- INX B ;INCR POINTER
- JMP AHE1
- ;
- ; THIS ROUTINE CONVERTS ASCII HEX DIGITS INTO BINARY
- ;
- AHS1: SUI '0' ;ASCII BIAS
- CPI 10 ;DIGIT 0-10
- RC
- SUI 7 ;ALPHA BIAS
- RET
- ;
- ; THIS ROUTINE CONVERTS A BINARY VALUE TO ASCII HEXADECIMAL
- ; AND OUTPUTS THE CHARACTERS TO THE TTY
- ;
- HOUT: CALL BINH ;CONVERT VALUE
- LXI H,HCON ;CONVERSION AREA
- CHOT: MOV B,M ;FETCH OUTPUT CHARACTER
- CALL OUT8 ;OUTPUT CHAR
- INX H
- MOV B,M ;FETCH CHAR
- CALL OUT8 ;OUTPUT CHAR
- RET
- ;
- ; THIS ROUTINE DOES THE SAME AS ABOVE BUT OUTPUTS A BLANK
- ; AFTER THE LAST CHAR
- ;
- HOTB: CALL HOUT ;CONVERT AND OUTPUT
- CALL BLK1 ;OUTPUT A BLANK
- RET
- ;
- ; THIS ROUTINE CONVERTS A BINARY VALUE TO ASCII DECIMAL
- ; DIGITS AND OUTPUTS THE CHARACTERS TO THE TTY
- ;
- DOUT: CALL BIND ;CONVERT VALUE
- CALL HOUT+3 ;OUTPUT VALUE (2 DIGITS)
- INX H
- MOV B,M ;GET LAST DIGIT
- CALL OUT8 ;OUTPUT
- RET
- ;
- ; THIS ROUTINE OUTPUTS A BLANK
- ;
- BLK1: MVI B,' '
- CALL OUT8
- RET
- ;
- ; THIS ROUTINE IS USED BY OTHER ROUTINES TO INCREMENT THE
- ; STARTING ADDRESS IN A COMMAND AND COMPARE IT WITH THE FINAL
- ; ADDRESS IN THE COMMAND. ON RETURN THE CARRY FLAG SET
- ; INDICATES THAT THE FINAL ADDRESS HAS BEEN REACHED
- ;
- ACHK: LHLD BBUF ;FETCH START ADDRESS
- LDA BBUF+3 ;STOP ADDRESS (HIGH)
- CMP H ;COMPARE
- JNZ ACH1
- LDA BBUF+2 ;STOP ADDRESS (LOW)
- CMP L ;COMPARE
- JNZ ACH1
- STC ;SET CARRY IF EQUAL
- ACH1: INX H ;INCREMENT START ADDRESS
- SHLD BBUF ;STORE START ADDRESS
- RET
- ;
- ; THIS ROUTINE OUTPUTS CHARACTERS FROM A CHARACTER STRING UNTIL
- ; A CARRIAGE RETURN IS FOUND
- ;
- SCRN: MOV B,M ;FETCH CHAR
- MVI A,13 ;CARRIAGE RETURN
- CMP B ;CHAR = CR
- RZ
- CALL OUT8 ;OUTPUT CHAR
- INX H ;INCREMENT ADDRESS
- JMP SCRN
- ;
- ; THIS ROUTINE CONVERTS THE BINARY VALUE IN REG A INTO
- ; ASCII HEXADECIMAL DIGITS AND STORES THEM IN MEMORY
- ;
- BINH: LXI H,HCON ;CONVERSION ADDRESS
- MOV B,A ;SAVE VALUE
- RAR
- RAR
- RAR
- RAR
- CALL BIN1
- MOV M,A
- INX H
- MOV A,B
- CALL BIN1 ;CONVERT TO ASCII
- MOV M,A
- RET
- ;
- ; THIS ROUTINE CONVERTS A VALUE TO HEXADECIMAL
- ;
- BIN1: ANI 0FH ;LOW FOUR DIGITS
- ADI '0' ;MODIFY FOR ASCII
- CPI '0'+10 ;DIGIT 0-9
- RC
- ADI 7 ;MODIFY FOR A-F
- RET
- ;
- ; THIS ROUTINE CONVERTS THE BINARY VALUE IN THE A REG
- ; TO ASCII DECIMAL DIGITS AND STORES THEM IN MEMORY
- ;
- BIND: LXI H,HCON ;CONVERSION ADDRESS
- MVI B,100
- CALL BID1 ;CONVERT HUNDREDS DIGIT
- MVI B,10
- CALL BID1 ;CONVERT TENS DIGIT
- ADI '0' ;GET UNITS DIGIT
- MOV M,A ;STORE IN MEMORY
- RET
- ;
- ; THIS ROUTINE CONVERTS A VALUE TO DECIMAL
- ;
- BID1: MVI M,'0'-1 ;INITIALIZE DIGIT COUNT
- INR M
- SUB B ;CHECK DIGIT
- JNC BID1+2
- ADD B ;RESTORE VALUE
- INX H
- RET
- ;
- ; LEGAL COMMAND TABLE
- ;
- CTAB: DB 'DUMP' ;DUMP COMMAND
- DW DUMP
- DB 'EXEC'
- DW EXEC
- DB 'ENTR'
- DW ENTR
- DB 'FILE'
- DW FILE
- DB 'LIST'
- DW LIST
- DB 'DELT'
- DW DELL
- DB 'ASSM'
- DW ASSM
- DB 'PAGE'
- DW PAGE
- DB 'PROM'
- DW PROM
- DB 'CUST'
- DW 0E000H
- ;
- ; THIS ROUTINE CHECKS IF ANY PARAMETERS WERE ENTERED
- ; WITH THE COMMAND; IF NOT, AN ERROR MESSAGE IS ISSUED
- ;
- VCHK: LDA ABUF ;FETCH PARAMETER BYTE
- ORA A ;SET FLAGS
- JZ WHAT ;NO PARAMETER
- RET
- ;
- ; THIS ROUTINE DUMPS THE CONTENTS OF MEMORY FROM
- ; THE START TO FINAL ADDRESSES GIVEN IN THE COMMAND
- ;
- DUMP: CALL VCHK ;CHECK FOR PARAMETERS
- MVI A,16 ;LOCATIONS PER LINE
- STA SCNT ;DUMP COUNTER
- DUMS: CALL CRLF ;START NEW LINE
- LDA BBUF+1 ;FETCH ADDRESS
- CALL HOUT ;OUTPUT ADDRESS
- LDA BBUF
- CALL HOTB ;OUTPUT ADDRESS
- LDA SCNT ;FETCH LINE COUNTER
- DUM1: STA DCNT
- LHLD BBUF ;FETCH MEMORY ADDRESS
- MOV A,L ;GET LOW ORDER ADDRESS
- OUT PADO ;SET PROM ADDRESS
- MOV A,H
- CPI 0EFH
- MOV A,M
- JNZ DUM2
- IN PDAI ;READ PROM DATA
- DUM2: CALL HOTB ;OUTPUT VALUE
- CALL ACHK ;CHECK ADDRESS
- RC ;RETURN IF FINISHED
- LDA DCNT ;FETCH COUNTER
- DCR A ;DECR COUNTER
- JNZ DUM1
- JMP DUMS
- ;
- ; THIS ROUTINE WILL MOVE 1 PAGE (256 BYTES) FROM 1ST ADDRESS GIVEN
- ; IN COMMAND TO 2ND ADDRESS IN COMMAND
- ;
- PAGE: CALL VCHK ;CHECK FOR PARAMETER
- LDA ABUF+4 ;FETCH 2ND PARAMETER
- ORA A ;DOES 2ND PARAMETER EXIST?
- JZ WHAT
- LHLD BBUF ;FETCH MOVE FROM ADDRESS
- XCHG
- LHLD BBUF+2 ;FETCH MOVE TO ADDRESS
- MVI B,0 ;SET COUNTER
- PAG1: MOV A,E
- OUT PADO ;SET PROM ADDRESS
- MOV A,D
- CPI 0FFH ;CHECK FOR PROM ADDRESS
- LDAX D ;GET DATA
- JNZ PAG2
- IN PDAI ;READ PROM DATA
- PAG2: MOV M,A
- INX H
- INX D
- DCR B ;DECR COUNT
- JNZ PAG1
- RET
- ;
- ; THIS ROUTINE INITIALIZES THE BEGINNING OF FILE ADDRESS
- ; AND END OF FILE ADDRESS AS WELL AS THE FILE AREA
- ; WHEN THE FILE COMMAND IS USED
- ;
- FILE: CALL CRLF
- ;CHECK FOR FILE PARAMETERS
- LDA FBUF
- ORA A
- JZ FOUT ;NO GO LIST
- CALL FSEA ;LOOK UP FILE
- XCHG ;PNTR IN DE
- JNZ TEST ;IF FOUND
- ;NO ENTRY
- LDA ABUF ;CHECK FOR PARAM
- ORA A
- JZ WHA1 ;NO?? - GIVE EM HELL
- ;CHECK FOR ROOM IN DIRECTORY
- LDA FEF
- ORA A
- JNZ ROOM
- LXI H,EMES1
- JMP MESS
- ;ENTRY FOUND ARE THESE PARAMETERS
- TEST: LDA ABUF
- ORA A
- JZ SWAPS
- LHLD BBUF
- MOV A,H
- ORA L
- JZ SWAPS
- LXI H,EMES2 ;NO-NO CAN'T DO
- JMP MESS
- ;MOVE FILE NAME TO BLOCK POINTED TO BY FREAD
- ROOM: LHLD FREAD
- XCHG ;DIRECT POINTER IN D,E
- LXI H,FBUF ;FILE NAME POINTER IN H,L
- PUSH D
- MVI C,NMLEN ;NAME LENGTH COUNT
- MOV23: MOV A,M
- STAX D
- INX D
- INX H
- DCR C ;TEST COUNT
- JNZ MOV23
- POP D ;RESTORE ENTRY PTR, MAKE CURRENT
- ;MAKE FILE POINTED TO BY D,E CURRENT
- SWAPS: LXI H,FILE0
- MVI C,FELEN ;ENTRY LENGTH
- SWAP: LDAX D
- MOV B,M
- MOV M,A
- MOV A,B
- STAX D
- INX D ;BUMP POINTERS
- INX H
- DCR C ;TEST COUNT
- JNZ SWAP
- ;CHECK FOR 2ND PARAMETER, => INITIALIZE NEW
- LDA ABUF
- ORA A
- JZ FOOT ;NO SECOND PARAMETER
- ;PROCESS SECOND PARAMETER
- LHLD BBUF ;GET ADDRESS
- SHLD BOFP ;SET BEGIN
- SHLD EOFP ;SET END
- MOV A,L ;IS ADDRESS ZERO?
- ORA H
- JZ FIL35 ;YES
- FIL30: MVI M,1 ;NON-ZERO - SET EOF
- FIL35: XRA A
- STA MAXL ;AND MAX LINE #
- JMP FOOT ;OUTPUT PARAMETERS
- FOUT: LDA IBUF+4
- CPI 'S' ;IS COMMAND FILES
- MVI C,MAXFIL
- JZ FOUL
- FOOT: MVI C,1
- ;OUTPUT THE # OF ENTRIES IN C
- FOUL: LXI H,FILE0
- MOV A,C
- FINE: STA FOCNT ;SAVE COUNT
- PUSH H
- LXI D,NMLEN
- DAD D
- MOV A,M
- ORA A
- JNZ FOOD ;NON-ZERO, OK TO OUTPUT
- INX H
- ADD M
- INX H
- JNZ FOOD
- INX SP
- INX SP
- INX H
- INX H
- JMP FEET
- ;HAVE AN ENTRY TO OUTPUT
- FOOD: POP H ;PTR
- MVI C,NMLEN
- FAST: MOV B,M ;LOAD CHAR TO B
- CALL OUT8 ;OUTPUT
- DCR C
- INX H
- JNZ FAST ;DO THE REST
- ;NOW OUTPUT BEGIN-END PTRS
- CALL FOOL ;OUTPUT BEGIN
- CALL FOOL ;OUTPUT END
- CALL CRLF ;AND CR
- ;TEST COUNT, H,L POINTS PAST EOFP
- FEET: LXI D,FELEN-NMLEN-4
- DAD D ;MOVE TO NEXT ENTRY
- LDA FOCNT
- DCR A ;TEST COUNT
- JNZ FINE ;MORE TO DO
- RET
- ;OUTPUT NUMBER POINTED TO BY H,L
- ;ON RET, H,L POINT 2 WORDS LATER
- FOOL: CALL BLK1 ;SPACE
- INX H
- MOV A,M
- DCX H
- PUSH H
- CALL HOUT ;OUTPUT
- POP H
- MOV A,M
- INX H
- INX H
- PUSH H
- CALL HOTB ;OUTPUT
- POP H ;RESTORE H,L
- RET
- ;
- ; SEARCH THE FILE DIRECTORY FOR THE FILE
- ; WHOSE NAME IS IN FBUF.
- ; RETURN IF FOUND, ZERO IS OFF, H,L POINT TO
- ; ENTRY WHILE SEARCHING. ON ENTRY FOUND WITH ADDR
- ; ZERO, SET FEF TO > 0 AND FREAD TO THE ADDR OF ENTRY
- ;
- FSEA: XRA A
- STA FEF ;CLAIM NO FREE ENTRIES
- MVI B,MAXFIL ;COUNT OF ENTRIES
- LXI D,FILE0 ;TABLE ADDRESS
- FSE10: LXI H,FBUF
- MVI C,NMLEN
- CALL SEAR ;TEST STRINGS
- PUSH PSW ;SAVE FLAG
- PUSH D
- LDAX D ;GET BOFP
- ORA A ;EMPTY ENTRY?
- JNZ FSE20
- INX D ;TEST OTHER WORD
- LDAX D
- ORA A
- JNZ FSE20 ;NOPE-GO TEST FOR MATCH
- XCHG ;H,L GET MIDDLE OF FREE ENTRY
- LXI D,-NMLEN-1
- DAD D ;MOVE TO BEGINNING
- SHLD FREAD ;SAVE ADDR
- MOV A,D
- STA FEF ;SET FREE ENTRY FOUND
- POP H ;RESTORE INTERIM POINTER
- POP PSW ;UNJUNK STACK
- ; MOVE TO NEXT ENTRY
- FSE15: LXI D,FELEN-NMLEN
- DAD D
- XCHG ;NEXT ENTRY ADDR IN DE
- DCR B ;TEST COUNT
- RZ ;DONE?
- JMP FSE10 ;TRY NEXT
- ; ENTRY WASN'T FREE, TEST FOR MATCH
- FSE20: POP H
- POP PSW
- JNZ FSE15 ;IF ZERO CLEAR, NO MATCH
- ; ENTRY FOUND
- LXI D,-NMLEN ;BACKUP
- DAD D ;H,L POINTS TO ENTRY
- MOV A,D
- ORA A ;CLEAR ZERO
- RET ;THAT'S ALL
- ;
- ; OUTPUT ERROR MESSAGE FOR ILLEGAL COMMAND
- ;
- WHAT: CALL CRLF ;OUTPUT CRLF
- WHA1: LXI H,EMES ;MESSAGE ADDRESS
- MESS: CALL SCRN
- JMP EOR
- ;
- EMES: DB 'WHAT?',13
- EMES1: DB 'FULL',13
- EMES2: DB 'NO NO',13
- ;
- ; CALL ROUTINE TO ENTER DATA INTO MEMORY
- ; AND CHECK FOR ERROR ON RETURN
- ;
- ; THIS ROUTINE IS USED TO ENTER DATA VALUES INTO MEMORY.
- ; EACH VALUE IS ONE BYTE AND IS WRITTEN IN HEXADECIMAL
- ; VALUES GREATER THAN 255 WILL CAUSE CARRY TO BE SET
- ; AND RETURN MADE TO CALLING PROGRAM
- ;
- ENTR: CALL VCHK ;CHECK FOR PARAMETERS
- CALL ENTS
- JC WHAT
- CALL CRLF
- RET
- ;
- EEND EQU '/' ;TERMINATION CHAR
- ENTS: CALL CRLF
- CALL READ ;READ INPUT DATA
- LXI H,IBUF ;SET LINE POINTER
- SHLD PNTR ;SAVE POINTER
- ENT1: CALL ZBUF ;CLEAR BUFFER
- CALL SBLK ;SCAN TO FIRST VALUE
- JC ENTS ;JUMP IF CR FOUND
- CPI EEND
- RZ ;CARRY IS ZERO
- CALL ALPS ;PLACE VALUE IN BUFFER
- MOV A,B ;GET DIGIT COUNT
- CPI 3 ;CHECK NUMBER OF DIGITS
- CMC
- RC ;RETURN IF MORE THAN 2 DIGITS
- LXI B,ABUF ;CONVERSION ADDRESS
- CALL AHEX ;CONVERT VALUE
- RC ;ERROR IN HEX CHARACTER
- MOV A,L
- LHLD BBUF ;FETCH MEMORY ADDRESS
- MOV M,A ;PUT IN MEMORY
- CALL ACH1 ;INCREMENT MEMORY LOCATION
- JMP ENT1
- ;
- ; THIS ROUTINE IS USED TO ENTER LINES INTO THE FILE
- ; AREA. THE LINE NUMBER IS FIRST CHECKED TO SEE IF IT IS
- ; A VALID NUMBER (0000-9999). NEXT IT IS CHECKED TO SEE IF IT IS
- ; GREATER THAN THE MAXIMUM CURRENT LINE NUMBER. IF IT IS, THE NEW
- ; LINE IS INSERTED AT THE END OF THE CURRENT FILE AND THE MAXIMUM
- ; LINE NUMBER IS UPDATED AS WELL AS THE END OF FILE POSITION
- ; LINE NUMBERS THAT ALREADY EXIST ARE INSERTED INTO THE FILE AREA
- ; AT THE APPROPRIATE PLACE AND ANY EXTRA CHARACTERS IN THE OLD
- ; LINE ARE DELETED
- ;
- LINE: MVI C,4 ;NO OF DIGITS TO CHECK
- LXI H,IBUF-1 ;INITIALIZE ADDRESS
- LICK: INX H
- MOV A,M ;FETCH LINE DIGIT
- CPI '0' ;CHECK FOR VALID NUMBER
- JC WHAT
- CPI '9'+1
- JNC WHAT
- DCR C
- JNZ LICK
- SHLD ADDS ;FIND ADDRESS
- LXI D,MAXL+3 ;SET ADDRESS
- CALL COM0
- JNC INSR
- ; GET HERE IF NEW LINE IS GREATER THAN MAXIMUM CURRENT LINE #
- INX H
- CALL LODM ;GET NEW LINE NUMBER
- LXI H,MAXL+3
- CALL STOM ;MAKE IT MAXIMUM LINE NUMBER
- LXI D,IBUF-1
- LHLD EOFP ;END OF FILE POSITION
- MVI C,1
- CALL LMOV ;PLACE LINE IN FILE
- SEOF: MVI M,1 ;END OF FILE INDICATOR
- SHLD EOFP ;END OF FILE ADDRESS
- JMP EOR
- ; GET HERE IF NEW LINE MUST BE INSERTED INTO ALREADY EXISTING
- ; FILE AREA
- INSR: CALL FIN1 ;FIND LINE IN FILE
- MVI C,2
- JZ EQUL
- DCR C ;NEW LN NOT EQUAL TO SOME OLD LINE
- EQUL: MOV B,M
- DCX H
- MVI M,2 ;MOVE LINE INDICATOR
- SHLD INSP ;INSERT LINE POSITION
- LDA IBUF-1 ;NEW LINE COUNT
- DCR C
- JZ LT ;NEW LINE NOT = OLD LINE
- SUB B ;COUNT DIFFERENCE
- JZ ZERO ;LINE LENGTHS EQUAL
- JC GT
- ; GET HERE IF NO OF CHARS IN OLD LINE > NO OF CHARS IN NEW LINE
- ; OR NEW LINE NUMBER WAS NOT EQUAL TO SOME OLD LINE NUMBER
- LT: LHLD EOFP ;END OF FILE ADDRESS
- MOV D,H
- MOV E,L
- CALL ADR ;MOVE TO ADDRESS
- SHLD EOFP ;NEW END OF FILE ADDRESS
- MVI C,2
- CALL RMOV ;OPEN UP FILE AREA
- JMP ZERO
- ; GET HERE IF NO OF CHARS IN OLD LINE < NO OF CHARS IN NEW LINE
- GT: CMA
- INR A ;COUNT DIFFERENCE
- MOV D,H
- MOV E,L
- CALL ADR
- XCHG
- CALL LMOV ;DELETE EXCESS CHARS IN FILE
- MVI M,1 ;EOF INDICATOR
- SHLD EOFP ;EOF ADDRESS
- ; GET HERE TO INSERT CURRENT LINE INTO FILE AREA
- ZERO: LHLD INSP ;INSERT ADDRESS
- MVI M,ASCR
- INX H
- LXI D,IBUF-1 ;NEW LINE ADDRESS
- MVI C,1 ;CHECK VALUE
- CALL LMOV ;PLACE LINE IN FILE
- JMP EOR
- ;
- ; THIS ROUTINE IS USED TO FIND A LINE IN THE FILE AREA
- ; WHICH IS GREATER THAN OR EQUAL TO THE CURRENT LINE NUMBER
- ;
- FIND: LXI H,ABUF+3 ;BUFFER ADDRESS
- SHLD ADDS ;SAVE ADDRESS
- FIN1: LHLD BOFP ;BEGIN FILE ADDRESS
- FI1: CALL EO1 ;CHECK FOR END OF FILE
- XCHG
- LHLD ADDS ;FETCH FIND ADDRESS
- XCHG
- MVI A,4
- CALL ADR ;LINE ADDRESS
- CALL COM0 ;COMPARE LINE NUMBER
- RC
- RZ
- FI2: MOV A,M
- CALL ADR ;NEXT LINE ADDRESS
- JMP FI1
- ;
- ; THIS ROUTINE CHECKS IF THE CURRENT ADDRESS
- ; IS THE END OF FILE
- ;
- EOF: INX H
- EO1: MVI A,1 ;EOF INDICATOR
- CMP M
- RNZ
- JMP EOR
- ;
- ; THIS ROUTINE IS USED TO ADD A VALUE TO AN ADDRESS
- ; CONTAINED IN REGISTER H,L
- ;
- ADR: ADD L
- MOV L,A
- RNC
- INR H
- RET
- ;
- ; THIS ROUTINE WILL MOVE CHARACTER STRINGS FROM ONE LOCATION
- ; OF MEMORY TO ANOTHER
- ; CHARACTERS ARE MOVED FROM LOCATION ADDRESSED BY D,E TO LOCATION
- ; ADDRESSED BY H,L. ADDITIONAL CHARACTERS ARE MOVED BY
- ; INCREMENTING MEMORY UNTIL THE CHARACTER IN REGISTER C IS FETCHED
- ;
- LMOV: LDAX D ;FETCH CHAR
- INX D
- CMP C ;TERMINATION CHAR
- RZ
- MOV M,A
- INX H
- JMP LMOV
- ;
- ; THIS ROUTINE IS SIMILAR TO THE ABOVE EXCEPT THAT THE CHARACTER
- ; ADDRESS IS DECREMENTED AFTER EACH FETCH AND STORE
- ;
- RMOV: LDAX D ;FETCH CHAR
- DCX D
- CMP C ;TERMINATION CHAR
- RZ
- MOV M,A ;STORE CHAR
- DCX H ;DECR STORE ADDRESS
- JMP RMOV
- ;
- ; THIS ROUTINE IS USED TO LOAD FOUR CHARACTERS FROM
- ; MEMORY INTO REGISTERS
- ;
- LODM: MOV B,M ;FETCH CHAR
- INX H
- MOV C,M
- INX H
- MOV D,M
- INX H
- MOV E,M
- RET
- ;
- ; THIS ROUTINE STORES FOUR CHARACTERS FROM REGISTERS INTO MEMORY
- ;
- STOM: MOV M,E
- DCX H
- MOV M,D
- DCX H
- MOV M,C
- DCX H
- MOV M,B
- RET
- ;
- ; THIS ROUTINE IS USED TO COMPARE TWO CHARACTER STRINGS
- ; OF LENGTH 4. ON RETURN ZERO FLAG SET MEANS BOTH
- ; STRINGS ARE EQUAL. CARRY FLAG = 0 MEANS STRING ADDRESSED
- ; BY D,E WAS GREATER THAN OR EQUAL TO CHARACTER STRING
- ; ADDRESSED BY H,L
- ;
- COM0: MVI B,1 ;EQUAL COUNTER
- MVI C,4 ;STRING LENGTH
- ORA A ;CLEAR CARRY
- CO1: LDAX D ;FETCH CHARACTER
- SBB M ;COMPARE CHAR
- JZ CO2
- INR B ;INCREMENT EQUAL COUNTER
- CO2: DCX D
- DCX H
- DCR C
- JNZ CO1
- DCR B
- RET
- ;
- ; THIS ROUTINE IS SIMILAR TO THE ABOVE EXCEPT ON RETURN, CARRY = 0
- ; MEANS THAT THE CHAR STRING ADDRESSED BY D,E IS STRICTLY GREATER
- ; THAN STRING ADDRESSED BY H,L
- ;
- COM1: MVI C,4 ;STRING LENGTH
- LDAX D ;FETCH CHAR
- SUI 1
- JMP CO1+1
- ;
- ; THIS ROUTINE WILL TAKE ASCII CHARS AND ADD ANY
- ; NECESSARY ASCII ZEROES SO THE RESULT IS A 4 CHARACTER
- ; ASCII VALUE
- ;
- NORM: CALL LODM ;LOAD ZEROES
- XRA A
- CMP B
- RZ
- NOR1: CMP E
- CNZ STOM ;STORE VALUES
- RNZ
- MOV E,D
- MOV D,C
- MOV C,B
- MVI B,'0'
- JMP NOR1
- ;
- ; THIS ROUTINE IS USED TO LIST THE CONTENTS OF THE FILE
- ; AREA STARTING AT THE LINE NUMBER GIVEN IN THE COMMAND
- ;
- LIST: CALL CRLF
- CALL FIND ;FIND STARTING LINE
- INX H
- LIS1: CALL SCRN ;OUTPUT LINE
- CALL CRLF
- CALL EOF ;END OF FILE
- IN SWCH ;READ SWITCHES
- ANI 80H
- RNZ
- INX H
- JMP LIS1
- ;
- ; THIS ROUTINE IS USED TO PROGRAM A 1702A PROM
- ;
- PROM: CALL VCHK ;CHECK FOR PARAMETER
- PRO1: CALL CRLF
- LDA BBUF ;GET ADDRESS (LOW)
- CALL HOTB ;OUTPUT ADDRESS
- MVI D,3 ;NUMBER OF ATTEMPTS
- LHLD BBUF ;GET ADDRESS
- PRO2: MOV A,L
- OUT PADO
- MOV A,M ;GET DATA
- OUT PDAO ;OUTPUT TO PROM
- MVI A,2
- OUT PCTO ;ENABLE PROGRAMMER
- CALL DLAY ;500 MSEC DELAY
- XRA A
- OUT PCTO ;DISABLE PROGRAMMER
- IN PDAI ;READ DATA
- CMP M ;COMPARE DATA
- JZ PRO3
- MVI B,'?'
- CALL OUT8
- DCR D ;NUMBER OF ATTEMPTS
- JNZ PRO2 ;TRY AGAIN
- RET
- PRO3: CALL ACHK ;FINAL ADDRESS
- RC ;RETURN IF FINISHED
- JMP PRO1 ;NEXT LOCATION
- ;
- DLAY: MVI E,150
- DLA1: XRA A ;GET A ZERO (256)
- DLA2: DCR A
- JNZ DLA2
- DCR E
- JNZ DLA1
- RET
- ;
- ; THIS ROUTINE IS UDED TO DELAETE LINES FROM THE FILE AREA
- ; THE REMAINING FILE AREA IS THEN MOVED IN MEMORY SO THAT
- ; THERE IS NO EXCESS SPACE IN MEMORY
- ;
- DELL: CALL VCHK ;CHECK FOR PARAMETER
- CALL FIND ;FIND LINE IN FILE AREA
- SHLD DELP ;SAVE DELETE POSITION
- LXI H,ABUF+7
- MOV A,M ;CHECK FOR 2ND PARAMETER
- ORA A ;SET FLAGS
- JNZ DEL1
- LXI H,ABUF+3 ;USE FIRST PARAMETER
- DEL1: SHLD ADDS ;SAVE FIND ADDRESS
- XCHG
- LXI H,MAXL+3
- CALL COM0 ;COMPARE LINE NO
- LHLD DELP ;LOAD DELETE POSITION
- JC NOVR
- ; GET HERE IF DELETION INVOLVES END OF FILE
- SHLD EOFP ;CHANGE EOF POSITION
- MVI M,1 ;SET EOF INDICATOR
- XCHG
- LHLD BOFP ;GET BEGIN FILE ADDRESS
- XCHG
- MVI B,13 ;SET SCAN SWITCH
- DCX H ;DECREMENT FILE ADDRESS
- DEL2: MOV A,L ;CHECK FOR BOF
- SUB E
- MOV A,H
- SBB D
- MVI A,ASCR ;LOOK FOR CR
- JC DEL4
- DCR B
- DCX H
- CMP M ;FIND NEW MAX LINE NO
- JNZ DEL2
- DCX H
- MOV A,L
- SUB E
- MOV A,H
- SBB D
- JC DEL5
- CMP M ;END OF PREVIOUS LINE
- INX H
- INX H
- JZ DEL3
- INX H
- DEL3: CALL LODM ;LOAD NEW MAX LINE NO
- LXI H,MAXL+3 ;SET ADDRESS
- CALL STOM ;STORE NEW MAX LINE NO
- RET
- DEL4: CMP B ;CHECK SWITCH
- DEL5: XCHG
- JNZ DEL3-1
- STA MAXL ;MAKE MAX LINE NO A SMALL NUMBER
- RET
- ; GET HERE IF DELETION IS IN MIDDLE OF FILE AREA
- NOVR: CALL FI1 ;FIND END OF FILE AREA
- CZ FI2 ;NEXT LINE IF THIS LINE NO IS EQUAL
- NOV1: XCHG
- LHLD DELP ;CHAR MOVE TO POSITION
- MVI C,1 ;MOVE TERMINATION
- CALL LMOV ;COMPACT FILE AREA
- SHLD EOFP ;SET EOF POSITION
- MVI M,1 ;SET EOF INDICATOR
- RET
- ;
- ; STARTING HERE IS THE SELF ASSEMBLER PROGRAM
- ; THIS PROGRAM ASSEMBLES PROGRAMS WHICH ARE
- ; IN THE FILE AREA
- ;
- ASSM: CALL VCHK ;CHECK FOR PARAMETER
- LDA ABUF+4 ;GET 2ND PARAMETER
- ORA A ;CHECK FOR PARAMETERS
- JNZ ASM4
- LHLD BBUF ;FETCH 1ST PARAMETER
- SHLD BBUF+2 ;STORE INTO 2ND PARAMETER
- ASM4: LDA IBUF+4 ;FETCH INPUT CHAR
- CPI 'E' ;ERROR ONLY INDICATOR
- JNZ ASM5
- XRA A ;SET FOR ONLY ERRORS
- ASM5: STA AERR ;SET ERROR SWITCH
- XRA A ;GET A ZERO
- STA NOLA ;INITIALIZE LABEL COUNT
- ASM3: STA PASI ;SET PASS INDICATOR
- LHLD BBUF ;FETCH ORIGIN
- SHLD ASPC ;INITIALIZE PC
- LHLD BOFP ;GET START OF FILE
- SHLD APNT ;SAVE ADDRESS
- ASM1: LHLD APNT ;FETCH LINE POINTER
- LXI SP,AREA+18
- MOV A,M ;FETCH CHAR
- CPI 1 ;END OF FILE
- JZ EASS ;JUMP IF END OF FILE
- XCHG
- INX D ;INCREMENT ADDRESS
- LXI H,OBUF ;BLANK START ADDRESS
- MVI A,IBUF-5 ;BLANK END ADDRESS
- CALL CLER ;BLANK OUT BUFFER
- MVI C,ASCR ;STOP CHAR
- CALL LMOV ;MOVE LINE INTO BUFFER
- MOV M,C ;PLACE CR IN BUFFER
- XCHG
- SHLD APNT ;SAVE ADDRESS
- LDA PASI ;FETCH PASS INDICATOR
- ORA A ;SET FLAGS
- JNZ ASM2 ;JUMP IF PASS 2
- CALL PAS1
- JMP ASM1
- ASM2: CALL PAS2
- LXI H,OBUF ;OUTPUT BUFFER ADDRESS
- CALL AOUT ;OUTPUT LINE
- JMP ASM1
- ;
- ; THIS ROUTINE IS USED TO OUTPUT THE LISTING FOR AN ASSEMBLY
- ; IT CHECKS WHETHER ALL LINES ARE PRINTED OR ONLY THOSE
- ; WITH ERRORS DEPENDING UPON THE ERROR SWITCH
- ;
- AOUT: LDA AERR ;FETCH ERROR SWITCH
- ORA A ;SET FLAGS
- JNZ AOU1 ;OUTPUT ALL LINES
- AOU2: LDA OBUF+18 ;FETCH ERROR INDICATOR
- CPI ' ' ;CHECK FOR AN ERROR
- RZ ;RETURN IF NO ERROR
- AOU1: LXI H,OBUF ;OUTPUT BUFFER ADDRESS
- CALL CRLF
- CALL SCRN ;OUTPUT LINE
- 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 CHAR
- CPI ' ' ;CHECK FOR A BLANK
- JZ OPC ;JUMP IF NO LABEL
- CPI ';' ;CHECK FOR COMMENT
- RZ ;RETURN IF COMMENT
- ;
- ; PROCESS LABEL
- ;
- CALL SLAB ;GET AND CHECK LABEL
- JC OP5 ;ERROR IN LABEL
- JZ ERRD ;DUPLICATE LABEL
- CALL LCHK ;CHECK CHAR AFTER LABEL
- JNZ OP5 ;ERROR IF NO BLANK
- MVI C,LLAB ;LENGTH OF LABELS
- LXI H,ABUF ;SET BUFFER ADDRESS
- MLAB: MOV A,M ;FETCH NEXT CHAR
- STAX D ;STORE IN SYMBOL TABLE
- INX D
- INX H
- DCR C ;DECR COUNT
- JNZ MLAB
- XCHG
- SHLD TABA ;SAVE TABLE ADDRESS FOR EQU
- LDA ASPC ;FETCH PC (LOW)
- MOV M,A ;STORE IN TABLE
- INX H
- LDA ASPC+1 ;FETCH PC (HIGH)
- MOV M,A ;STORE IN TABLE
- LXI H,NOLA
- INR M ;INCR NUMBER OF LABELS
- ;
- ; PROCESS OPCODE
- ;
- OPC: CALL ZBUF ;ZERO WORKING BUFFER
- CALL SBLK ;SCAN TO OPCODE
- JC OERR ;FOUND CARRIAGE RETURN
- 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
- ;
- ; THIS ROUTINE CHECKS THE CHAR AFTER A LABEL FOR A BLANK
- ; OR A COLON
- ;
- LCHK: LHLD PNTR
- MOV A,M ;GET CHAR 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 ;SET FLAGS
- JZ ORG1 ;ORG OPCODE
- JM DAT1 ;DATA STATEMENT
- JPO EQU1 ;EQU OP
- CPI 5
- JC RES1 ;RES OPCODE
- JNZ EASS ;JUMP IF END
- ; DO DW PSEUDO OP
- ACO1: MVI C,2 ;2 BYTE INSTRUCTION
- XRA A ;GET A ZERO
- JMP OCN1 ;ADD VALUE TO PROGRAM COUNTER
- ; DO ORG PSEUDO OP
- ORG1: CALL ASCN ;GET OPERAND
- LDA OBUF+18 ;FETCH ERROR INDICATOR
- CPI ' ' ;CHECK FOR AN ERROR
- RNZ ;IF ERROR DON'T CHANGE PC
- SHLD ASPC ;STORE NEW ORIGIN
- LDA IBUF ;GET FIRST CHAR
- CPI ' ' ;CHECK FOR LABEL
- RZ ;NO LABEL
- JMP EQUS ;CHANGE LABEL VALUE
- ; DO EQU PSEUDO OP
- EQU1: CALL ASCN ;GET OPERAND
- LDA IBUF ;FETCH 1ST CHAR
- CPI ' ' ;CHECK FOR LABEL
- JZ ERRM ;MISSING LABEL
- EQUS: XCHG
- LHLD TABA ;SYMBOL TABLE ADDRESS
- MOV M,E ;STORE LABEL VALUE
- INX H
- MOV M,D
- JMP AOU2 ;OUTPUT IF ERROR
- ; DO DS PSEUDO OP
- RES1: CALL ASCN ;GET OPERAND
- MOV B,H
- MOV C,L
- JMP RES21 ;ADD VALUE TO PROGRAM COUNTER
- ; DO DB PSEUDO OP
- DAT1: JMP DAT1X
- ;
- ; PERFORM PASS 2 OF THE ASSEMBLER
- ;
- PAS2: LXI H,OBUF ;SET OUTPUT BUFFER ADDRESS
- LDA ASPC+1 ;FETCH PC (HIGH)
- CALL BINH+3 ;CONVERT FOR OUTPUT
- INX H
- LDA ASPC ;FETCH PC(LOW)
- CALL BINH+3 ;CONVERT FOR OUTPUT
- SHLD OIND ;SAVE OUTPUT ADDRESS
- CALL ZBUF ;CLEAR BUFFER
- LXI H,IBUF ;INITIALIZE LINE POINTER
- PABL: SHLD PNTR ;SAVE POINTER
- MOV A,M ;FETCH FIRST CHAR
- CPI ' ' ;CHECK FOR LABEL
- JZ OPC ;GET OPCODE
- CPI ';' ;CHECK FOR COMMENT
- RZ ;RETURN IF COMMENT
- CALL SLAB ;SCAN OFF LABEL
- JC ERRL ;ERROR IN LABEL
- CALL LCHK ;CHECK FOR A BLANK OR COLON
- JNZ ERRL ;ERROR IF NOT A BLANK
- JMP OPC
- ;
- ; PROCESS PSEUDO OPS FOR PASS 2
- ;
- PSU2: LDAX D
- ORA A ;SET FLAGS
- JZ ORG2 ;ORG OPCODE
- JM DAT2 ;DATA OPCODE
- RPO ;RETURN IF EQU
- CPI 5
- JC RES2 ;RES OPCODE
- JNZ EASS ;END OPCODE
- ; DO DW PSEUDO OP
- ACO2: CALL TYS6 ;GET VALUE
- JMP ACO1
- ; DO DS PSEUDO OP
- RES2: CALL ASBL ;GET OPERAND
- MOV B,H
- MOV C,L
- LHLD BBUF+2 ;FETCH STORAGE COUNTER
- DAD B ;ADD VALUE
- SHLD BBUF+2 ;GET A ZERO
- RES21: XRA A
- JMP OCN2
- ; DO DB PSEUDO OP
- DAT2: CALL TYS5 ;GET OPERAND
- DAT1X: XRA A ;GET A ZERO
- MVI C,1 ;BYTE COUNT
- JMP OCN1
- ; DO ORG PSEUDO OP
- ORG2: CALL ASBL ;GET NEW ORIGIN
- LDA OBUF+18 ;GET ERROR INDICATOR
- CPI ' ' ;CHECK FOR AN ERROR
- RNZ
- XCHG
- LHLD ASPC ;FETCH PC
- XCHG
- SHLD ASPC ;STORE NEW PC
- MOV A,L
- SUB E ;FORM DIFFERENCE OF ORIGINS
- MOV E,A
- MOV A,H
- SBB D
- MOV D,A
- LHLD BBUF+2 ;FETCH STORAGE POINTER
- DAD D ;MODIFY
- SHLD BBUF+2 ;SAVE
- RET
- ;
- ; PROCESS 1 BYTE INSTRUCTIONS WITHOUT OPERANDS
- ;
- TYP1: CALL ASTO ;STORE VALUE IN MEMORY
- RET
- ;
- ; PROCESS STAX AND LDAX
- ;
- TYP2: CALL ASBL ;FETCH OPERAND
- CNZ ERRR ;ILLEGAL REGISTER
- MOV A,L ;GET LOW ORDER OPERAND
- ORA A
- 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 TYP1
- ;
- ; PROCESS ACCUMULATOR, INR,DCR,MOV,RST INSTRUCTION
- ;
- 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 MOV INSTRUCTION
- JZ TY41
- CPI 199
- MOV A,L
- JZ TY31 ;RST INST
- JM TY32 ;ACCUMULATOR INST
- 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 ;INCR 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: CPI 6 ;CHECK FOR MVI INST
- CZ TY56
- CALL ASTO ;STORE OBJECT CODE BYTE
- TYS5: CALL ASBL ;GET IMMEDIATE ARGUMENT
- INR A
- CPI 2 ;CHECK OPERAND FOR RANGE
- CNC ERRV ;OPERAND OUT OF RANGE
- MOV A,L
- JMP TYP1
- ;
- ; FETCH 1ST ARGUMENT FOR MVI AND LXI INSTRUCTIONS
- ;
- TY56: CALL ASBL ;FETCH ARG
- 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
- MOV A,M ;FETCH CHARACTER
- CPI ',' ;CHECK FOR COMMA
- INX H ;INCR POINTER
- SHLD PNTR
- JNZ ERRS ;SYNTAX ERROR IN NO COMMA
- MOV A,E ;GET OBJECT BYTE
- RET
- ;
- ; PROCESS 3 BYTE INSTRUCTIONS
- ; LXI IS A SPECIAL CASE
- ;
- TYP6: CPI 1 ;CHECK FOR LXI
- JNZ TY6 ;JUMP IF NOT LXI
- CALL TY56 ;GET REGISTER
- ANI 8 ;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 ASBL ;FETCH OPERAND
- MOV A,L
- MOV D,H
- CALL ASTO ;STORE 2ND BYTE
- MOV A,D
- JMP TYP1
- RET
- ;
- ; THIS ROUTINE IS USED TO STORE OBJECT CODE PRODUCED
- ; BY THE ASSEMBLER DURING PASS 2 INTO MEMORY
- ;
- ASTO: LHLD BBUF+2 ;FETCH STORAGE ADDRESS
- MOV M,A ;STORE OBJECT BYTE
- INX H
- SHLD BBUF+2
- LHLD OIND ;FETCH OUTPUT ADDRESS
- INX H
- INX H
- CALL BINH+3 ;CONVERT OBJECT BYTE
- SHLD OIND
- RET
- ;
- ; GET HERE WHEN END PSEUDO OP IS FOUND OR WHEN END OF FILE
- ; OCCURS IN SOURCE STATEMENTS. CONTROL IS SET FOR EITHER PASS 2
- ; OR ASSEMBLY TERMINATES IF FINISHED.
- ;
- EASS: LDA PASI ;FETCH PASS INDICATOR
- ORA A ;SET FLAGS
- JNZ EOR ;JUMP IF FINISHED
- CALL CRLF
- MVI A,1 ;PASS INDICATOR FOR PASS 2
- JMP ASM3 ;DO 2ND PASS
- ;
- ; THIS ROUTINE SCANS THROUGH A CHARACTER STRING UNTIL
- ; THE FIRST NON-BLANK CHARACTER IS FOUND
- ;
- ; ON RETURN CARRY = 1 INDICATES A CR AS FIRST NON BLANK CHARACTER
- ;
- SBLK: LHLD PNTR ;FETCH ADDRESS
- SBL1: MOV A,M ;FETCH CHAR
- CPI ' ' ;CHECK FOR A BLANK
- RNZ ;RETURN IF NOT BLANK
- SBL2: INX H
- SHLD PNTR ;SAVE POINTER
- JMP SBL1
- ;
- ; THIS ROUTINE IS USED TO CHECK THE CONDITION CODE MNEMONICS
- ; FOR CONDITIONAL JUMPS, CALLS, AND RETURN.
- ;
- COND: LXI H,ABUF+1
- SHLD ADDS
- MVI B,2 ;2 CHARACTERS
- CALL COPC
- RET
- ;
- ; THE FOLLOWING IS THE OPCODE TABLE
- ;
- OTAB: DB 'ORG',0,0
- DB 'EQU',0,1
- DB 'DB',0,0,-1
- DB 'DS',0,0,3
- DB 'DW',0,0,5
- DB 'END',0,6,0
- DB 'HLT',76H
- DB 'RLC',7
- DB 'RRC',0FH
- DB 'RAL',17H
- DB 'RAR',1FH
- DB 'RET',0C9H
- DB 'CMA',2FH
- DB 'STC',37H
- DB 'DAA',27H
- DB 'CMC',3FH
- DB 'EI',0,0FBH
- DB 'DI',0,0F3H
- DB 'NOP',0,0
- DB 'XCHG',0EBH
- DB 'XTHL',0E3H
- DB 'SPHL',0F9H
- DB 'PCHL',0E9H,0
- DB 'STAX',2
- DB 'LDAX',0AH,0
- DB 'PUSH',0C5H
- DB 'POP',0,0C1H
- DB 'INX',0,3
- DB 'DCX',0,0BH
- DB 'DAD',0,9,0
- DB 'INR',4
- DB 'DCR',5
- DB 'MOV',40H
- DB 'ADD',80H
- DB 'ADC',88H
- DB 'SUB',90H
- DB 'SBB',98H
- DB 'ANA',0A0H
- DB 'XRA',0A8H
- DB 'ORA',0B0H
- DB 'CMP',0B8H
- DB 'RST',0C7H,0
- DB 'ADI',0C6H
- DB 'ACI',0CEH
- DB 'SUI',0D6H
- DB 'SBI',0DEH
- DB 'ANI',0E6H
- DB 'XRI',0EEH
- DB 'ORI',0F6H
- DB 'CPI',0FEH
- DB 'IN',0,0DBH
- DB 'OUT',0D3H
- DB 'MVI',6,0
- DB 'JMP',0,0C3H
- DB 'CALL',0CDH
- DB 'LXI',0,1
- DB 'LDA',0,3AH
- DB 'STA',0,32H
- DB 'SHLD',22H
- DB 'LHLD',2AH,0
- ; CONDITION CODE TABLE
- DB 'NZ',0
- DB 'Z',0,8
- DB 'NC',10H
- DB 'C',0,18H
- DB 'PO',20H
- DB 'PE',28H
- DB 'P',0,30H
- DB 'M',0,38H,0
- ;
- ; THIS ROUTINE IS USED TO CHECK A GIVEN OPCODE AGAINST TO LEGAL
- ; OPCODES CONTAINED IN THE OPCODE TABLE
- ;
- COPC: LHLD ADDS
- LDAX D ;FETCH CHAR
- ORA A
- JZ COP1 ;JUMP IF TERMINATION CHAR
- 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 ;INCR ADDRESS
- RET
- ;
- ; THIS ROUTINE CHACKS 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
- ; PASS 2
- ;
- OPCD: LXI H,ABUF ;SET ADDRESS
- SHLD ADDS
- LXI D,OTAB ;OPCODE TABLE ADDRESS
- MVI B,4 ;CHAR COUNT
- CALL COPC ;CHECK OPCODES
- JZ PSEU ;JUMP IF A PSEUDO OP
- DCR B ;3 CHAR OPCODES
- CALL COPC
- JZ OP1
- INR B ;4 CHAR OPCODES
- CALL COPC
- OP1: LXI H,TYP1 ;TYPE 1 INST
- OP2: MVI C,1 ;1 BYTE INST
- JZ OCNT
- ;
- OPC2: CALL COPC ;CHECK FOR STAX, LDAX
- LXI H,TYP2
- JZ OP2
- CALL COPC ;CHECK FOR PUSH,POP,INX,DCX,DAD
- LXI H,TYP3
- JZ OP2
- DCR B ;3 CHAR OPCODES
- CALL COPC ;ACCUMULATOR INST'S,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 0C0H ;ADD BASE VALUE OF RETURN
- MOV D,A
- MVI B,3 ;3 CHAR OPCODES
- LDA ABUF ;FETCH FIRST CHAR
- MOV C,A ;SAVE CHAR
- 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 ;LOAD BUFFER ADDRESS
- ADD B ;ADD LENGTH OF OPCODE
- MOV E,A
- MVI A,ABUF SHR 8 ;LOAD BUFFER ADDRESS
- ACI 0 ;GET HIGH ORDER PART
- MOV D,A
- LDAX D ;FETCH CHAR AFTER OPCODE
- ORA A ;IS 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
- ;
- PSEU: LXI H,ABUF+4 ;SET BUFFER ADDRESS
- MOV A,M ;FETCH CHAR 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 CHAR
- RC ;RETURN IF ILLEGAL CHAR
- CPI 'Z'+1
- CMC
- RC ;RETURN IF ILLEGAL CHAR
- CALL ALPS ;PLACE SYMBOL IN BUFFER
- LXI H,ABUF ;SET BUFFER ADDRESS
- SHLD ADDS ;SAVE ADDRESS
- DCR B ;CHECK IF ONE CHAR
- 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)
- JMP SLA2
- SLA1: LDA NOLA ;FETCH SYMBOL COUNT
- MOV B,A
- LXI D,SYMT ;SET SYMBOL TABLE ADDRESS
- ORA A ;ARE THERE ANY LABELS
- JZ SLA3 ;JUMP IF NO LABELS
- MVI A,LLAB ;FETCH LENGTH OF TABLE
- STA NCHR
- CALL COMS ;CHECK TABLE
- SLA2: STC
- CMC ;CLEAR CARRY
- RET
- SLA3: INR A ;CLEAR ZERO FLAG
- ORA A ;CLEAR CARRY
- 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 CHAR IN BUFFER
- INR B ;INCR COUNT
- MOV A,B ;FETCH COUNT
- CPI 11 ;MAX BUFFER SIZE
- RNC ;RETURN IF BUFFER FILLED
- INX D ;INCR BUFFER
- INX H ;INCR INPUT ADDRESS
- SHLD PNTR ;SAVE LINE POINTER
- MOV A,M ;FETCH CHAR
- CPI '0' ;CHECK FOR LEGAL CHAR
- RC
- CPI '9'+1
- JC ALP1
- 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: LXI H,0 ;GET A ZERO
- SHLD OPRD ;INITIALIZE OPERAND
- INR H
- SHLD OPRI-1 ;INITIALIZE OPERAND INDICATOR
- NXT1: LHLD PNTR ;FETCH SCAN POINTER
- DCX H
- CALL ZBUF ;CLEAR BUFFER
- STA SIGN ;ZERO SIGN INDICATOR
- NXT2: INX H ;INCR POINTER
- MOV A,M ;FETCH NEXT CHAR
- CPI ' '+1
- JC SEND ;JUMP IF CR OR BLANK
- CPI ',' ;FIELD SEPARATOR
- JZ SEND
- ; CHECK FOR OPERATORS
- CPI '+' ;CHECK FOR PLUS
- JZ ASCI
- CPI '-' ;CHECK FOR MINUS
- JNZ ASC2
- STA SIGN
- ASCI: 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
- ASC2: MOV C,A ;SAVE CHAR
- LDA OPRI ;GET INDICATOR
- ORA A ;CHECK FOR TWO OPERANDS
- JZ ERRS ;SYNTAX ERROR
- MOV A,C
- CPI '$' ;LC EXPRESSION
- JNZ ASC3
- INX H
- SHLD PNTR ;SAVE POINTER
- LHLD ASPC ;FETCH LOCATION COUNTER
- JMP AVAL
- ; CHECK FOR ASCII CHARS
- ASC3: CPI 2 TABLE END ADDRESS
- ASPC: DS 2 ;ASSEMBLER PROGRAM COUNTER
- PASI: DS 1 ;PASS INDICATOR
- NCHR: DS 1 ;LENGTH OF STRING FOR COMPARE
- PNTR: DS 2 ;LINE POINTER STORAGE
- NOLA: DS 1 ;NUMBER OF LABELS
- SIGN: DS 1 ;SIGN STORAGE FOR SCAN
- OPRD: DS 2 ;OPERAND STORAGE
- OPRI: DS 1 ;OPERAND FOUND INDICATOR
- TEMP: DS 1
- APNT EQU INSP ;ASSEMBLER LINE POINTER
- AERR EQU SCNT ;ASSEMBLER ERROR PRINT SWITCH
- OIND: DS 2 ;OUTPUT ADDRESS
- LLAB EQU 5 ;LENGTH OF LABELS
- AREA: DS 18
- OBUF: DS 25 ;OUTPUT BUFFER AREA
- DS 5: CPI '0' ;CHECK FOR NUMERIC
- JC ERRA ;ILLEGAL CHAR
- 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
- ORA A ;SET FLAGS
- JNZ ASUB
- 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
- ALAB: CALL SLAB
- JZ AVAL
- JC ERRA ;ILLEGAL SYMBOL
- JMP ERRU ;UNDEFINEσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσR ADDRESS
- CPI 'H' ;IS IT HEX
- JZ NUM2
- CPI 'D' ;IS IT DECIMAL
- JNZ NUM1
- XRA A ;GET A ZERO
- STAX D ;CLEAR D FROM BUFFER
- NUM1: CALL ADEC ;CONVERT DECIMAL VALUE
- RET
- NUM2: XRA A
- STAX D ;CLEAR H FROM BUFFER
- CALL AHEX ;CONVERT HEX
- RET
- ; PROCESS REGISTER ERROR
- ERRR: MVI A,'R' ;GET INDICATOR
- LXI H,0
- STA OBUF+18 ;SET IN OUTPUT BUFFER
- RET
- ; PROCESS SYNTAX ERROR
- ERRS: MVI A,'S'
- STA OBUF+18
- LXI H,0
- RET
- ; PROCESS UNDEFINED SYMBOL ERROR
- ERRU: MVI A,'U'
- JMP ERRS+2
- ; PROCESS VALUE ERROR
- ERRV: MVI A,'V'
- JMP ERRR+2
- ; PROCESS MISSING LABEL ERROR
- ERRM: MVI A,'M'
- STA OBUF+18
- CALL AOU1
- RET
- ; PROCESS ARGUMENT ERROR
- ERRA: MVI A,'A'
- JMP ERRS+2
- ; PROCESS OPCODE ERROR
- ; STORE 3 BYTES OF ZERO IN OBJECT CODE TO PROVIDE FOR PATCH
- ERRO: MVI A,'O'
- STA OBUF+18
- LDA PASI ;FETCH PASS INDICATOR
- ORA A
- RZ ;RETURN IF PASS 1
- MVI C,3 ;NEED 3 BYTES
- ERO1: XRA A ;GET A ZERO
- CALL ASTO ;PUT IN LISTING AND MEMORY
- DCR C
- JNZ ERO1
- RET
- ; PROCESS LABEL ERROR
- ERRL: MVI A,'L'
- JMP ERRO+2
- ; PROCESS DUPLICATE LABEL ERROR
- ERRD: MVI A,'D'
- STA OBUF+18
- CALL AOUT
- JMP OPC
- ;
- ;
- ; DEFINE INPUT AND OUTPUT PORTS
- ;
- USTA EQU 0 ;UART STATUS
- UDAI EQU 1 ;DATA IN
- UDAO EQU 1 ;DATA OUT
- PDAI EQU 6 ;PROM DATA IN
- PADO EQU 7 ;PROM ADDRESS OUT
- PDAO EQU 8 ;PROM DATA OUT
- PCTO EQU 9 ;PROM CONTROL OUT
- SWCH EQU 0FFH
- ;
- ; FILE AREA PARAMETERS
- ;
- MAXFIL EQU 6 ;MAX # OF FILES
- NMLEN EQU 5 ;NAME LENGTH
- FELEN EQU NMLEN+8 ;DIRECTORY ENTRY LENGTH
- FILE0: DS NMLEN
- BOFP: DS 2
- EOFP: DS 2
- MAXL: DS 4
- FILTB: DS (MAXFIL-1)*FELEN
- INSP: DS 2 ;INSERT LINE POSITION
- DELP EQU INSP ;DELETE LINE POSITION
- ASCR EQU 13 ;ASCII CARRIAGE RETURN VALUE
- HCON: DS 2
- ADDS EQU HCON ;FIND ADDRESS
- FBUF: DS NMLEN ;FILE NAME BUFFER
- FREAD: DS 2 ;FREE ADDRESS IN DIRECTORY
- FEF: DS 1 ;FREE ENTRY FOUND FLAG
- FOCNT EQU FEF ;OUTPUT COUNTER
- ABUF: DS 12 ;ASCII BUFFER
- BBUF: DS 4 ;BINARY BUFFER
- SCNT: DS 1
- DCNT: DS 1 ;DUMP ROUTINE COUNTER
- NCOM EQU 10 ;NUMBER OF COMMANDS
- TABA: DS 2 ;SYMBOL TABLE END ADDRESS
- ASPC: DS 2 ;ASSEMBLER PROGRAM COUNTER
- PASI: DS 1 ;PASS INDICATOR
- NCHR: DS 1 ;LENGTH OF STRING FOR COMPARE
- PNTR: DS 2 ;LINE POINTER STORAGE
- NOLA: DS 1 ;NUMBER OF LABELS
- SIGN: DS 1 ;SIGN STORAGE FOR SCAN
- OPRD: DS 2 ;OPERAND STORAGE
- OPRI: DS 1 ;OPERAND FOUND INDICATOR
- TEMP: DS 1
- APNT EQU INSP ;ASSEMBLER LINE POINTER
- AERR EQU SCNT ;ASSEMBLER ERROR PRINT SWITCH
- OIND: DS 2 ;OUTPUT ADDRESS
- LLAB EQU 5 ;LENGTH OF LABELS
- AREA: DS 18
- OBUF: DS 25 ;OUTPUT BUFFER AREA
- DS 5
- IBUF: DS 83
- SYMT EQU $ ;START OF SYMBOL TABLE
- END