home *** CD-ROM | disk | FTP | other *** search
- ;-----------------------------------------------;
- ; Z80 RESIDENT ASSEMBLER ;
- ;-----------------------------------------------;
- ; ;
- ;(C) 1977 LEHMAN CONSULTING SERVICES ;
- ; ALL RIGHTS RESERVED ;
- ; ;
- ;-----------------------------------------------;
- ; ;
- ; SUBROUTINE PACKAGE ;
- ; ;
- ;-----------------------------------------------;
- ; ;
- ; REV 0 14-JULY-77 MGL ;
- ; ;
- ;-----------------------------------------------;
- ;
- ; EJECT
- ;-----------------------------------------------;
- ; ;
- ; CPMUTIL COMMUNICATIONS AREA ;
- ; ;
- ;-----------------------------------------------;
- ;
- ORG 103H
- ;
- ; JUMP TABLE EQUATES
- ;
- WLINE DS 3 ;WRITE PRINTER LINE
- WMSG DS 3 ;WRITE CONSOLE MSG
- DSKSEL DS 3 ;SELECT DISK
- OPNFIL DS 3 ;OPEN FILE
- CLSFIL DS 3 ;CLOSE FILE
- DELFIL DS 3 ;DELETE FILE
- DREAD DS 3 ;DISK READ
- DWRITE DS 3 ;DISK WRITE
- CREFIL DS 3 ;CREATE FILE
- DMASET DS 3 ;SET DMA ADDRESS
- MOVE DS 3 ;MOVE BYTES
- CMPCHR DS 3 ;COMPARE CHARACTERS
- CMPHD DS 3 ;COMPARE HL:DE
- MUL16 DS 3 ;HL <= HL * DE
- GNB DS 3 ;GET NEXT BYTE (1K BLOCKING)
- WNB DS 3 ;WRITE NEXT BYTE
- GNB2 DS 3 ;GET NEXT BYTE (FCB2)
- WNB2 DS 3 ;WRITE NEXT BYTE (FCB2)
- CNV2HX DS 3 ;CONVERT TO HEX - BUF => HL REG
- ;
- ;
- FCB1 DS 33
- FCB2 DS 33
- IBP DS 2
- IBP2 DS 1
- OBP DS 1
- OBP2 DS 1
- IBUF DS 2
- OBUF DS 2
- IBUF2 DS 2
- OBUF2 DS 2
- INBUF DS 1024
- OUTBUF DS 128
- INBUF2 DS 128
- OUTBF2 DS 128
- ;
- ; EJECT
- ;-----------------------------------------------;
- ; COMMON DATA AREA (CDA) ;
- ;-----------------------------------------------;
- ;
- ORG 980H ;LEAVE SPACE FOR CPMUTIL
- ;
- HDRBUF DS 16 ;MUST FOLLOW ORG
- REC DS 80 ;MUST FOLLOW HDRBUF
- PC DS 2 ;CURRENT PROGRAM COUNTER
- OBJ DS 32 ;OBJECT CODE BUFFER
- OBJCNT DS 1 ;LEN OF DATA IN OBJ
- LEN DS 1 ;LEN OF CURRENT INSTRUCTION
- VAL DS 2 ;RETURN FROM EVAL ROUTINE
- INST DS 80 ;CURRENT INSTRUCTION (OR DATA FROM DB)
- EOM DB 0 ;END OF BUFFER CHARACTER (FOR WLINE)
- PTR1 DS 2 ;POINTS TO NEXT CHAR IN REC
- PASSNO DS 1 ;CURRENT PASS =0 PASS1 =FF PASS2
- IDBUF DS 16 ;CURRENT ID
- INTBUF DS 2 ;RETURNED VALUE FROM INT ROUTINE
- CURLNE DS 1 ;CURRENT LINE NUMBER FOR PAGING OUTPUT
- LEN2 DS 2 ;FOR DEFS
- LBLADR DS 2 ;LAST LBL ADDR IN SYM (FOR EQU)
- EQUFLG DS 1 ;IF NON-ZERO EQUVAL IS USED INSTEAD OF PC FOR PRINT
- EQUVAL DS 2 ;VALUE OF LAST EQU
- ENDADR DS 2 ;EXPRESSION VALUE ON END STATEMENT
- EFLG DS 1 ;END OF PROGRAM FLAG (TO ALLOW PRINTING OF END STMT)
- OPCODE DS 2 ;CURRENT OPCODE FROM SYMBOL TABLE
- SAVVAL DS 2 ;SAVED CONTENTS OF VAL
- LFLAG DS 1 ;LISTING FLAG =N NO LISTING, =' ' OR 'Y' LISTING
- HFLAG DS 1 ;HEX OBJ FLAG =N NO HEX OBJ, =' ' OR 'Y' HEX OBJ OUTPUT
- ERRFLG DS 1 ;ERROR CHARACTER FOR THIS LINE
- TEMP DS 2 ;TEMP 2 BYTE AREA
- MULT DS 2 ;BASE OF NUMBER IN INT CONVERT LOOP
- SYMPTR DS 2 ;ADDRESS OF NEXT SYMBOL TABLE ENTRY
- SYMPT DS 2 ;ADDRESS OF BEGINING OF SYMBOL TABLE
- UFLAG DS 1 ;UNDEFINED FLAG FROM EVAL, =0 ALL OK, =1 >1 UNDEFINED
- EVFLGS DS 1 ;FLAG FIELD FROM LAST SYMLUK
- ;
- ; EJECT
- ;
- ; JUMP TABLE FOR ROUTINES IN THIS ASSEMBLY
- ;
- JMP EVAL
- JMP ID
- JMP INT
- JMP SETUP ;INIT FILES FOR ASSEMBLER
- JMP SYMENT
- JMP SYMLUK
- JMP GNR ;GET NEXT RECORD
- JMP GNC ;GET NEXT CHARACTER
- JMP BACKUP ;BACKUP TO LAST CHARACTER
- ;
- ; EJECT
- ;
- ;
- ; EXPRESSION EVALUATOR
- ;
- ; VALID OPERATORS ARE: +, - AND *
- ;
- ; VALID ELEMENTS ARE: ID'S, NUMBERS, AND '$' FOR PC
- ;
- ;
- EVAL EQU $
- MVI A,0 ! STA OP ! STA UFLAG ;DEFAULT OP TO +, UFLAG=0
- STA EVFLGS ;RESET FLAGS FROM LAST SEARCH
- LXI H,0 ! SHLD VAL ;SET VAL TO 0000
- EVAL1 EQU $
- CALL GNC ;GET NEXT ELEMENT OR OPERATOR
- CPI '0' ! JC EVAL3 ! CPI '9'+1 ! JC EVAL9 ;BRANCH IF NUMBER
- EVAL3 EQU $
- CPI '$' ! JZ EVAL11 ;BRANCH IF PC REF
- CPI 'A' ! JC EVAL5 ! CPI 'Z'+1 ! JC EVAL13 ;BRANCH IF ID
- EVAL5 EQU $
- CPI '+' ! JZ EVAL22
- CPI '-' ! JZ EVAL24
- CPI '*' ! JZ EVAL26
- CPI 27H ! JZ EVAL29 ;PROCESS SINGLE BYTE QUOTED STRING
- RET ;GET OUT OF HERE WE ARE DONE
- ;
- ; PROCESS NUMBER
- ;
- EVAL9 EQU $
- CALL BACKUP ! CALL INT ! JMP EVAL28
- ;
- ;
- ; PROCESS '$' REF
- ;
- EVAL11 EQU $
- LHLD PC ! SHLD INTBUF ! JMP EVAL28
- ;
- ;
- ; PROCESS ID
- ;
- ;
- EVAL13 EQU $
- CALL BACKUP ! CALL ID
- CALL BACKUP ;BACKUP SO AS TO NOT IGNORE OPERATOR OR COMMA
- LXI H,IDBUF ! CALL SYMLUK ! JNZ EVAL19 ;BRANCH IF UNDEFINED
- MOV A,M ! STA INTBUF ! INX H ! MOV A,M ! STA INTBUF+1 ! JMP EVAL28
- EVAL19 EQU $ ;PROCESS UNDEFINED ID
- LXI H,0 ! SHLD INTBUF ;SET VALUE TO 0000
- LDA UFLAG ! ORI 1 ! STA UFLAG ;SET UNDEFINED FLAG
- JMP EVAL28
- ;
- ; PROCESS OPERATORS
- ;
- EVAL22 EQU $
- MVI A,0 ! JMP EVAL27
- ;
- EVAL24 EQU $
- MVI A,1 ! JMP EVAL27
- ;
- EVAL26 EQU $
- MVI A,2
- EVAL27 EQU $
- STA OP
- JMP EVAL1
- ;
- ;
- ; PROCESS VALUE USING CURRENT OPERATOR
- ;
- ;
- EVAL28 EQU $ ;VAL = VAL OP INTBUF
- LDA OP
- CPI 1 ! JZ EVAL28A ;BRANCH IF SUBTRACT
- CPI 2 ! JZ EVAL28B ;BRANCH IF MULTIPLY
- LHLD VAL ! XCHG ! LHLD INTBUF ! DAD D ! SHLD VAL ;+
- JMP EVAL1
- ;
- EVAL28A EQU $ ;SUBTRACT
- LHLD VAL ! XCHG ! LHLD INTBUF
- MOV A,E ! SUB L ! MOV L,A ! MOV A,D ! SBB H ! MOV H,A ! SHLD VAL
- JMP EVAL1
- ;
- EVAL28B EQU $ ;MULTIPLY
- LHLD VAL ! XCHG ! LHLD INTBUF ! CALL MUL16 ! SHLD VAL
- JMP EVAL1
- ;
- ;
- ; PROCESS SINGLE BYTE IN QUOTES
- ;
- EVAL29 EQU $
- CALL GNC ;GET CHARACTER
- STA INTBUF ! XRA A ! STA INTBUF+1 ;FAKE 2 BYTE VALUE
- CALL GNC ;BYPASS TRAILING QUOTE
- JMP EVAL28 ;AND GO PROCESS VALUE NORMALLY
- ;
- ;
- OP DS 1 ;CURRENT OPERATOR FOR EVAL
- ;
- ; EJECT
- ;
- ;
- ; ID - COLLECT ID AND PLACE IN IDBUF
- ;
- ID EQU $
- PUSH H ! PUSH D ! PUSH B ;SAVE REGS
- MVI A,' ' ! STA IDBUF
- LXI H,IDBUF+1 ! LXI D,IDBUF ! LXI B,15 ! CALL MOVE ;BLANK IDBUF
- LXI H,IDBUF
- CALL GNC
- ID2 EQU $
- CPI 'A' ! JC ID1 ! CPI 'Z'+1 ! JNC ID1 ;IF NOT A LETTER THEN BRANCH
- ID3 MOV M,A ! INX H
- PUSH H ! LHLD PTR1 ! MOV A,M ! INX H ! SHLD PTR1 ! POP H
- JMP ID2
- ;
- ID1 CPI '.' ! JZ ID3 ; ALLLOW LABELS WITH '.' IN THEM (E.G. LAB.01)
- CPI '$' ! JZ ID2 ; ALLOW $ FILLERS (E.G. SQR$ROOT)
- CPI '0' ! JC ID4 ! CPI '9'+1 ! JC ID3 ;ALLOW DIGITS
- ID4 POP B ! POP D ! POP H
- RET
- ;
- ; EJECT
- ;
- ;
- ; INT - CONVERT CHARACTERS TO BINARY
- ;
- ; ALLOW TRAILING 'H' FOR HEX AND 'B' FOR BINARY
- ; DEFAULT TYPE IS DECIMAL (BASE 10)
- ;
- INT EQU $
- LHLD PTR1 ! SHLD TEMP ;SAVE POINTER
- LXI H,10 ! SHLD MULT ;SET DEFAULT BASE TO 10
- MVI B,0 ;SET UP LENGTH COUNTER
- CALL GNC ;SKIP BLANKS
- INT1 EQU $
- CPI '+' ! JZ INT1A ;BRANCH IF A TERMINATOR
- CPI '-' ! JZ INT1A
- CPI '*' ! JZ INT1A
- CPI 0DH ! JZ INT1A
- CPI ';' ! JZ INT1A
- CPI ')' ! JZ INT1A
- CPI ',' ! JZ INT1A
- CPI 20H ! JZ INT1A
- LHLD PTR1 ! MOV A,M ! INX H ! SHLD PTR1 ;GET NEXT CHARACTER
- INR B ! JMP INT1 ;INCREMENT COUNTER AND CONTINUE LOOP
- INT1A EQU $
- DCX H ! SHLD PTR1 ! DCX H ! MOV A,M
- INT2 CPI 'H' ! JNZ INT3 ;BRANCH IF NOT HEX
- DCR B ;DECREMENT COUNTER
- LXI H,16 ! SHLD MULT ;SET UP BASE 16
- JMP INT4
- ;
- INT3 CPI 'B' ! JNZ INT4 ;BRANCH IF NOT BINARY
- DCR B ;DECREMENT COUNTER
- LXI H,2 ! SHLD MULT ;SET UP BASE 2
- INT4 LHLD PTR1 ! XCHG ! LHLD TEMP ! SHLD PTR1 ! XCHG ! SHLD TEMP ;SAVE PTR
- LXI D,0 ;SET UP ACCUMULATOR
- CALL GNC ! CALL BACKUP
- INT5 EQU $
- LHLD PTR1 ! MOV A,M
- INX H ! SHLD PTR1
- CPI 'A' ! JC $+5 ! ADI 9 ;FOR A-F
- ANI 0FH ! PUSH PSW ;GET BINARY VALUE OF THIS DIGIT
- PUSH B ;SAVE COUNTER
- LHLD MULT ! CALL MUL16
- POP B ;RESTORE COUNTER
- POP PSW ! MOV E,A ! MVI D,0 ! DAD D ;ADD IN NEW DIGIT
- XCHG ! DCR B ! JNZ INT5 ;GO BACK IF MORE TO DO
- INT6 LHLD TEMP ! SHLD PTR1
- XCHG ! SHLD INTBUF ;SAVE VALUE
- RET
- ;
- ; EJECT
- ;
- ; SETUP - SET UP FILES FOR Z80ASM
- ;
- ; INPUT FROM CONSOLE IS FILENAME.AB
- ;
- ; A= Y OR N FOR LISTING
- ; B= Y OR N FOR HEX FILE
- ;
- SETUP EQU $
- LXI H,FCB1 ! LXI D,5CH ! LXI B,33 ! CALL MOVE ;GET DEFAULT FCB
- LXI H,FCB1+9 ! LXI D,ASMEXT ! LXI B,3 ! CALL MOVE ;SET UP EXTENSION
- LXI H,FCB2 ! LXI D,5CH ! LXI B,33 ! CALL MOVE ;GET DEFAULT FCB
- LXI H,FCB2+9 ! LXI D,HEXEXT ! LXI B,3 ! CALL MOVE ;SET UP EXTENSION
- LDA 5CH+9 ! STA LFLAG ;SET UP LISTING FLAG
- LDA 5CH+10 ! STA HFLAG ;SET UP HEX FLAG
- LXI D,FCB1 ! CALL OPNFIL ! JZ SETER1 ;BRANCH IF SOURCE FILE NOT FOUND
- LDA HFLAG ! CPI 'N' ! JZ SETUP1 ;BRANCH IF NO HEX FILE SETUP
- LXI D,FCB2 ! CALL DELFIL ;DELETE FILE
- LXI D,FCB2 ! CALL CREFIL ! JZ SETER2 ;BRANCH IF UNABLE TO CREATE
- LXI D,FCB2 ! CALL OPNFIL ! JZ SETER2 ;BRANCH IF UNABLE TO OPEN
- SETUP1 EQU $
- LXI H,INBUF+1024 ! SHLD IBP ! XRA A ! STA OBP2 ;SET UP POINTERS
- RET ;AND GET OUT OF HERE
- ;
- SETER1 LXI D,SM1 ! CALL WMSG ! JMP 0 ;MSG AND REBOOT
- ;
- SETER2 LXI D,SM2 ! CALL WMSG ! JMP 0 ;MSG AND REBOOT
- ;
- SM1 DB 13,10,'SOURCE (.ASM) FILE NOT FOUND',13,10,'$'
- ;
- SM2 DB 13,10,'UNABLE TO CREATE/OPEN OBJECT (.HEX) FILE',13,10,'$'
- ;
- ASMEXT DB 'ASM'
- HEXEXT DB 'HEX'
- ;
- ; EJECT
- ;
- ; SYMENT - ENTER A SYMBOL INTO THE SYMBOL TABLE
- ;
- ; UPON ENTRY HL POINTS TO NEW ENTRY
- ;
- ; ENTRY FORMAT: FLAGS/LENGTH (EACH 4 BITS)
- ; N A M E ... (UP TO 11 BYTES)
- ; VALUE LOW (1 BYTE)
- ; VALUE HIGH (1 BYTE)
- ; TYPE BYTE (1 BYTE)
- ;
- ; ON RETURN HL POINTS TO VALUE LOW BYTE IN NEW ENTRY FOR POSSIBLE
- ; FURTHER UPDATE (USED BY EQU PSEUDO OPERATOR)
- ;
- ;
- SYMENT EQU $
- MOV A,M ! PUSH B ! XCHG ! ANI 0FH ! MOV C,A ! MVI B,0 ;GET LEN
- LHLD SYMPTR ! CALL MOVE ;MOVE INTO SYMBOL TABLE
- SHLD SYMPTR ! MVI M,0 ; SET UP NEW POINTER AND NEW END MARKER
- DCX H ! DCX H ! DCX H ;BACKUP TO POINT TO VALUE LOW FIELD
- POP B
- RET
- ;
- ; EJECT
- ;
- ;
- ; SYMLUK - LOOK UP SYMBOLS IN TABLE
- ;
- ; ON RETURN Z=0 MEANS SYMBOL NOT FOUND.
- ; Z=1 SYMBOL FOUND, HL POINTS TO VALUE LOW BYTE IN TABLE ENTRY
- ;
- ;
- SYMLUK EQU $
- XCHG
- LHLD SYMPT ;GET POINTER TO BEGINING OF TABLE
- XCHG
- SYML1 LDAX D ! CPI 0 ! JZ SYMNF ;BRANCH IF END OF TABLE
- STA EVFLGS ;SAVE FOR MAIN PROCESSOR
- ANI 0FH ! SUI 4 ! MOV B,A ! INX D ;SET UP FOR COMPARE
- CALL CMPCHR ! JZ SYML2 ;BRANCH IF MATCH
- DCX D ;BACK UP LENGTH BYTE AGAIN
- SYML3 EQU $
- LDAX D ! ANI 0FH ! MOV C,A ! MVI B,0 ! XCHG ! DAD B ! XCHG
- JMP SYML1 ;ADVANCE POINTER AND CONTINUE TO LOOP
- ;
- SYML2 EQU $ ;NOW SEE IF EXACT MATCH
- DCX D ! LDAX D ! ANI 0FH ! SUI 4 ;GET LENGTH
- PUSH H ! MOV C,A ! MVI B,0 ! DAD B ! MOV A,M
- CPI ' ' ! POP H ! JNZ SYML3 ;IF NXT CHR NOT BLANK THEN NOT EXACT MATCH
- LDAX D ! ANI 0FH ! DCR A ! DCR A ! DCR A ! MOV C,A ! MVI B,0
- XCHG ! DAD B ! XRA A ! RET ;POINT TO VALUE LOW AND EXIT
- ;
- SYMNF XRA A ! INR A ! RET ;SET Z=0 AND RETURN
- ;
- ; EJECT
- ;
- ; GNR - GET NEXT RECORD - FILL REC UNTIL 0AH OR 1AH (CTRL/Z) IS FOUND
- ;
- GNR LXI H,REC ! SHLD PTR1 ;RESET POINTER
- MVI M,' ' ! XCHG ! LXI H,REC+1 ! LXI B,79 ! CALL MOVE ;BLNK BUFFER
- LXI H,REC ;GET ADDRESS OF RECORD BACK AGAIN
- GNR1 CALL GNB ! CPI 1AH ! RZ ;RETURN IF EOF MARKER (CTRL/Z) IF FOUND
- CPI 09H ! JZ GNR2 ;BRANCH IF TAB CHARACTER
- MOV M,A ! INX H ! CPI 0AH ! JNZ GNR1 ;BRANCH IF NOT LF
- RET
- GNR2 EQU $ ;PROCESS TAB
- LXI D,8 ! DAD D ! MOV A,L ! ANI 0F8H ! MOV L,A ;PROCESS TAB STOP
- JMP GNR1
- ;
- ; EJECT
- ;
- ;
- ; GNC - GET NEXT CHARACTER
- ; USE PTR1 TO INDEX INTO REC, SKIP BLANKS
- ;
- GNC EQU $
- PUSH H ! LHLD PTR1
- MOV A,M ! CPI ' ' ! INX H ! JZ $-4 ;SKIP BLANKS
- CPI 09H ! JZ $-9 ;BRANCH IF TAB CHARACTER
- SHLD PTR1 ! POP H
- RET
- ;
- ;
- ; BACKUP - BACKUP PTR1 AND RETURN CHARACTER
- ;
- ;
- BACKUP PUSH H ! LHLD PTR1
- DCX H ! MOV A,M
- SHLD PTR1 ! POP H
- RET
- ;
- ; EJECT