home *** CD-ROM | disk | FTP | other *** search
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;
- ; PROCSELF.ASM
- ;
- ; THIS IS THE PROCESSOR TECHNOLOGY SELF-CONTAINED SYSTEM
- ; (ALSO CALLED SOFTWARE PACKAGE NO. 1)
- ;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;
- ; TO ASSEMBLE, LOAD AND EXECUTE THIS PROGRAM, USE DIGITAL RESEARCH'S
- ; ASM.COM, LOAD.COM AS FOLLOWS:
- ;
- ; A>ASM PROCSELF.AAX
- ; A>LOAD PROCSELF
- ; A>PROCSELF
- ;
-
- RCONF EQU 1 ; READ CON: FUNCTION
- WCONF EQU 2 ; WRITE CON: FUNCTION
- BDOS EQU 5 ; SYSTEM CALL ENTRY
- PSTRF EQU 9 ; PRINT STRING FUNCTION
-
- ORG 100H
-
- LXI D,VERMSG
- MVI C,PSTRF
- CALL BDOS
- LXI D,ASKMSG
- MVI C,PSTRF
- CALL BDOS
- CALL IN8
- CPI 'Y'
- JZ SUGHLP
-
- LXI H,FILE0
- MVI C,MAXFIL*FELEN
- XRA A
- INIT2: MOV M,A
- INX H
- DCR C
- JNZ INIT2
-
- SUGHLP: LXI D,HLPMSG
- MVI C,PSTRF
- CALL BDOS
- JMP WARM
-
- VERMSG: DB 0DH,0AH,'PROCSELF.COM (05/26/85)',0DH,0AH,'$'
- HLPMSG: DB 0DH,0AH,'TYPE HELP FOR ASSISTANCE',0DH,0AH,'$'
-
- ASKMSG: DB 0DH,0AH,'DO YOU WANT TO BYPASS FILE INITIALIZATION'
- DB 0DH,0AH,'AND WORK WITH PREVIOUSLY SAVED FILES (Y/N)? '
- DB '$'
-
- EXTMSG: DB 0DH,0AH
- DB 0DH,0AH,'TO SAVE A NEW COPY OF THIS PROGRAM WHICH',0DH,0AH
- DB 'CONTAINS THE FILES YOU HAVE BEEN WORKING WITH, TYPE',0DH,0AH
- DB 0DH,0AH
- DB 'A>SAVE 64 PROCSELF.COM',0DH,0AH,'$'
-
- EXIT: LXI D,EXTMSG
- MVI C,PSTRF
- CALL BDOS
- JMP 0
-
- HELP: LXI D,HLPMSG1
- MVI C,PSTRF
- CALL BDOS
- CALL PAUSE
- LXI D,HLPMSG2
- MVI C,PSTRF
- CALL BDOS
- CALL PAUSE
- LXI D,HLPMSG3
- MVI C,PSTRF
- CALL BDOS
- CALL PAUSE
- LXI D,HLPMSG4
- MVI C,PSTRF
- CALL BDOS
- CALL PAUSE
- LXI D,HLPMSG5
- MVI C,PSTRF
- CALL BDOS
- CALL PAUSE
- RET
-
- PAUSE: LXI D,PSBMSG
- MVI C,PSTRF
- CALL BDOS
- PAUSE1: CALL IN8
- CPI 20H
- RZ
- JMP PAUSE1
-
- PSBMSG: DB 0DH,0AH,'PRESS (SPACE BAR) TO CONTINUE','$'
-
- HLPMSG1: DB 1AH,0DH,0AH
-
- DB 'I USED THIS GEM OF A PROGRAM IN THE MID ',27H,'70',27H,'S',0DH,0AH
- DB 'AND I LIKED IT SO MUCH I GOT IT FROM THE CPMUG LIBRARY,',0DH,0AH
- DB 'TUNED IT UP A LITTLE AND GOT IT TO WORK FOR THE KAYPRO.',0DH,0AH
- DB 0DH,0AH
- DB 'PROCSELF.COM IS A SMALL MONITOR CONTAINING AN EDITOR, ASSEMBLER',0DH,0AH
- DB 'AND MEMORY MANAGER.',0DH,0AH,'$'
-
- HLPMSG2: DB 0DH,0AH,0DH,0AH
-
-
- DB 'HERE IS A BRIEF EXAMPLE OF THE COMMANDS.',0DH,0AH
- DB 0DH,0AH
- DB 'YOU MUST FIRST ESTABLISH A FILE TO EDIT. UP TO 6 FILES CAN',0DH,0AH
- DB 'BE EDITED AT A TIME. HERE',27H,'S THE COMMAND TO ESTABLISH A ',0DH,0AH
- DB 'FILE NAMED TEST. THE SOURCE WILL BE STORED STARTING AT HEX 2000',0DH,0AH
- DB ' ',0DH,0AH
- DB 'FILE /TEST/ 2000',0DH,0AH
- DB ' ',0DH,0AH
- DB 'NEXT, YOU TYPE IN AN 8080 ASSEMBLY LANGUAGE PROGRAM.',0DH,0AH
- DB 'USE 4 DECIMAL DIGIT LINE NUMBERS IN FRONT OF EACH LINE.',0DH,0AH
- DB 'HERE',27H,'S AN EXAMPLE OF WHAT YOU MIGHT TYPE IN.',0DH,0AH,'$'
-
- HLPMSG3: DB 1AH
-
- DB 0DH,0AH
- DB '0001 ; THIS WILL LOOP TIL YOU TYPE AN EXCLAMATION MARK (!)',0DH,0AH
- DB '0005 BEGIN: DS 0 ',0DH,0AH
- DB '0010 CALL INKEY',0DH,0AH
- DB '0015 CPI 21H ; ASCII FOR !',0DH,0AH
- DB '0017 JZ DONE',0DH,0AH
- DB '0020 JMP BEGIN',0DH,0AH
- DB '0023 DONE: JMP WARM ; MONITOR WARM RE-ENTRY',0DH,0AH
- DB '0050 INKEY: IN 7 ; GET STATUS (KAYPRO VALUE)',0DH,0AH
- DB '0055 RRC ',0DH,0AH
- DB '0060 JNC INKEY',0DH,0AH
- DB '0065 IN 5 ; GET THE DATA (KAYPRO VALUE)',0DH,0AH
- DB '0070 ANI 7FH ; MASK OFF THE PARITY BIT',0DH,0AH
- DB '0077 RET ',0DH,0AH
- DB '0089 WARM EQU 0D00H',0DH,0AH
- DB '0002 ; IT IS USED TO ILLUSTRATE PROCSELF.COM',0DH,0AH
- DB '0003 ; THESE TWO LINES WILL BE INSERTED BETWEEN LINES 1 AND 5',0DH,0AH
- DB '0004 ; AND THEN SOME LINES WILL BE DELETED',0DH,0AH,'$'
-
- HLPMSG4: DB 1AH,0DH,0AH
-
- DB 'THE FOLLOWING PAGE WILL SHOW YOU HOW TO LIST THE SOURCE, ',0DH,0AH
- DB 'DELETE LINES, AND ASSEMBLE THE PROGRAM AT 3000 HEX. THE DUMP ',0DH,0AH
- DB 'COMMAND WOULD DUMP THE HEX CODE TO THE CRT. THE EXEC ',0DH,0AH
- DB 'COMMAND WOULD RUN THE PROGRAM, WHICH LOOPS TIL AN "!" IS TYPED.',0DH,0AH
- DB 'TYPING "!" WOULD GET YOU BACK TO THE MONITOR. MODIFYING MEMORY',0DH,0AH
- DB 'IS DONE BY THE ENTR COMMAND. THE EXAMPLE CHANGES THE ASCII CODE',0DH,0AH
- DB 'WHICH CORRESPONDS TO THE "!" (21 HEX) TO 2F HEX WHICH IS A "/".',0DH,0AH
- DB 'THE "/" FOLLOWING THE 2F (NO RELATION) SIGNALS THAT YOU ARE DONE',0DH,0AH
- DB 'MODIFYING MEMORY BYTES. YOU MAY MODIFY CONSECUTIVE BYTES BY',0DH,0AH
- DB 'SIMPLY TYPING THEM ONE AFTER ANOTHER. PUT A SPACE BETWEEN THE ',0DH,0AH
- DB 'BYTES. IE. 2F 20 43 A5 / ',0DH,0AH
- DB 'THE REMAINING COMMANDS RE-EXECUTE THE PROGRAM, SHOW YOU THE ',0DH,0AH
- DB 'FILES CURRENTLY OPEN, AND FINALLY, EXIT TO GOOD OL',27H,' CP/M.',0DH,0AH
- DB ' ',0DH,0AH,'$'
-
- HLPMSG5: DB 1AH,0DH,0AH
- DB 0DH,0AH
- DB 'LIST',0DH,0AH
- DB 'DELT 0003 0004',0DH,0AH
- DB 'LIST',0DH,0AH
- DB 'ASSM 3000',0DH,0AH
- DB 'DUMP 3000 30FF',0DH,0AH
- DB 'EXEC 3000',0DH,0AH
- DB 'ENTR 3004',0DH,0AH
- DB '2F /',0DH,0AH
- DB 'EXEC 3000',0DH,0AH
- DB 'FILES',0DH,0AH
- DB 'EXIT',0DH,0AH
- DB 0DH,0AH
- DB 'THIS PROGRAM HAS NO PROMPT, SO THE NEXT TIME YOU HIT THE ',0DH,0AH
- DB '(SPACE BAR), YUR ON YUR OWN.'
- DB 0DH,0AH
- DB 0DH,0AH
- DB 'LEE R. BRADLEY MOUSE HOUSE SOFTWARE NEWINGTON, CT 06111',0DH,0AH,'$'
-
- ; 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.
- ;
-
- ORG 0D00H
- WARM:
- SYS8: LXI SP,AREA+18
- CALL READ ;READ LINE FROM KEYBOARD
- 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,BACK SPACE - DELETE CHARACTER TO LEFT OF CURSOR AND
- ; POSITION CURSOR AT DELETED SPOT
- ; 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 EOF INDICATOR IN LINE
- INX H
- MVI A,IBUF+83 AND 00FFH ; LRB TO SATISFY DR
- CALL CLER ;CLEAR REMAINING BUFFER
- LXI H,IBUF-1
- MOV M,E ;SAVE CHAR COUNT
- RET
- DEL: CPI 127 ;CHECK FOR DELETE CHAR
- JZ DELC
- CPI 08H ;CHECK FOR BACK SPACE
- JNZ CHAR
- DELC: MOV B,A ;SAVE DEL OR BS
- MVI A,IBUF AND 00FFH ; LRB TO SATISFY DR
- CMP L ;IS THIS FIRST CHAR
- JZ NEXT
- DCX H ;DECR POINTER
- DCR E ;DECR COUNT
- BSPA: MOV A,B ;RESTORE DEL OR BS
- CPI 127 ;DEL?
- JNZ WASBS ;NO, WAS BS
- MVI B,08H ;BACK TWO POSITIONS
- CALL OUT8
- CALL OUT8
- MVI B,' ' ;SPACE TWO POSITIONS OUT
- CALL OUT8
- CALL OUT8
- MVI B,08H ;BACK TWO POSITIONS
- CALL OUT8
- CALL OUT8
- JMP NEXT
- WASBS: MVI B,' ' ;SPACE ONE POSITION
- CALL OUT8
- MVI B,08H ;BACK ONE POSITION
- CALL OUT8
- JMP NEXT
- CHAR: CPI ' ' ;CHECK FOR LEGAL CHAR
- JC NEXT
- CPI 'Z'+1
- JNC NEXT
- MOV B,A
- MOV M,B
- MVI A,IBUF+81 AND 00FFH ; LRB TO SATISFY DR
- 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
- ;
- ; 03/17/85 LRB CHANGED TO BDOS CALL
- ;
- IN8:
- PUSH B ;SAVE REGISTERS
- PUSH D
- PUSH H
- MVI C,RCONF ; READ FUNCTION
- CALL BDOS
- ANI 7FH ;MASK OFF PARITY BIT
- POP H
- POP D
- POP B ; RESTORE REGISTERS
- MOV B,A
- RET
- ;
- ; THIS ROUTINE OUTPUTS A BYTE OF DATA TO THE UART
- ;
- ; 03/17/85 LRB CHANGED TO BDOS CALL
- ;
- OUT8:
- PUSH B
- PUSH D
- PUSH H
- MVI C,WCONF
- MOV E,B
- CALL BDOS
- POP H
- POP D
- POP B
- RET
- ;
- ; THIS ROUTINE WILL OUTPUT A CARRIAGE RETURN AND LINE FEED
- ;
- CRLF: MVI B,13 ;CR
- CALL OUT8
- LF: MVI B,10 ;LF
- 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 ROUTINE 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 'EXIT'
- DW EXIT
- DB 'HELP'
- DW HELP
-
- ;
- ; 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 USED TO DELETE 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 AND 00FFH ;BLANK END ADDRESS ; LRB FOR DR
- 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,0FFH ; LRB TO SATISFY DR
- 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 AND 00FFH ;LOAD BUFFER ADDRESS ; LRB FOR DR
- 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 27H ;CHECK FOR SINGLE QUOTE
- JNZ ASC5 ;JUMP IF NOT QUOTE
- LXI D,0 ;GET A ZERO
- MVI C,3 ;CHAR COUNT
- ASC4: INX H ;INCR POINTER
- SHLD PNTR ;SAVE
- MOV A,M ;FETCH NEXT CHAR
- CPI ASCR ;IS IT CR?
- JZ ERRA ;ARGUMENT ERROR
- CPI 27H ;IS IT A QUOTE?
- JNZ SSTR
- INX H
- SHLD PNTR ;SAVE POINTER
- MOV A,M ;FETCH NEXT CHAR
- CPI 27H ;CHECK FOR 2 QUOTES IN A ROW
- JNZ AVAL+1 ;TERMINAL QUOTE
- SSTR: DCR C ;CHECK COUNT
- JZ ERRA ;TOO MANY CHARS
- MOV D,E
- MOV E,A ;SET CHAR IN BUFFER
- JMP ASC4
- ASC5: 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 ;UNDEFINED SYMBOL
- ;
- ; GET HERE WHEN TERMINATION CHARACTER IS FOUND. BLANK, COMMA, CR.
- ; CHECK FOR LEADING FIELD SEPARATOR
- ;
- SEND: LDA OPRI ;FETCH OPERAND INDICATOR
- ORA A ;SET FLAGS
- JNZ ERRS ;SYNTAX ERROR
- LHLD OPRD
- SEN1: MOV A,H ;GET HIGH ORDER BYTE
- LXI D,TEMP ;SET ADDRESS
- ORA A ;SET FLAGS
- RET
- ;
- ; GET A NUMERIC VALUE WHICH IS EITHER HEXADECIMAL OR DECIMAL
- ; ON RETURN CARRY SET INDICATES AN ERROR
- ;
- NUMS: CALL ALPS ;GET NUMERIC
- DCX D
- LDAX D ;GET LAST CHAR
- LXI B,ABUF ;SET BUFFER 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 11 ;NUMBER OF COMMANDS (HELP ADDED)
- 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
-
- LINE POSITION
- DELP EQU INSP ;DELETE LINE POSITION
- ASCR EQU 13 ;ASCII CARRIAGE RETURN VALUE
- HCON: DS 2
- ADDS EQU HCON ;F