home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-10-25 | 22.4 KB | 1,459 lines |
- ; ***************************************************************
- ; * *
- ; * Z80MACRO.LIB Macro Library for CP/M System Routines *
- ; * *
- ; * Ref: "Mastering CP/M" by Alan R. Miller *
- ; * Modified and adapted to Z80MR by Rich Brewster *
- ; * R.D.1 Brackney, PA 18812 (717) 663-2408 *
- ; * *
- ; ***************************************************************
-
- ; Z80MACRO.LIB Table of Contents 06/23 10:15.24
-
- ; MACRO PARAMETERS FLAG EMBEDDED MACROS
-
- ; AMBIG UFNFCB,AFNFCB AMFLAG
- ; CLOSE FCB,ERRJMP CLFLAG SYSF
- ; CMPBLK ADDR1,ADDR2,SIZE CMFLAG
- ; CMPDAT ADDR,SIZE CMFLAG
- ; CPABLK ADDR1,ADDR2,SIZE CPFLAG
- ; CPATXT TEXT,ADDR CPFLAG
- ; CPMVER
- ; CRLF CRFLAG PCHAR
- ; DELETE FCB,ERRJMP DEFLAG CRLF GCHAR PFNAME PRINT SYSF UCASE UNPROT
- ; DIVIDE TWOS DVFLAG
- ; DRIVE DRFLAG SYSF
- ; ENTER
- ; EXIT BOOT
- ; FILL ADDR,SIZE,VAL FLFLAG
- ; GCHAR CIFLAG SYSF
- ; GFNAME FCB FNFLAG CRLF PCHAR PRINT READB UCASE
- ; HEXHL HXFLAG UCASE
- ; HLDEC HLFLAG PCHAR
- ; LCHAR LOFLAG SYSF
- ; MAKE FCB,ERRJMP MKFLAG SYSF
- ; MOVBLK FROM,TO,SIZE
- ; MOVDAT TO,SIZE
- ; MULT TWOS MLFLAG
- ; OPEN FCB,ERRJMP OPFLAG SYSF
- ; OUTBIN BNFLAG PCHAR
- ; OUTHEX REG CXFLAG PCHAR
- ; OUTHL OUTHEX
- ; PCHAR COFLAG SYSF
- ; PFNAME FCB PFFLAG PCHAR PRINTB
- ; PRINT TEXT PRFLAG PCHAR
- ; PRINTB ADDR,SIZE PRFLAG PCHAR
- ; PROTEC FCB PTFLAG SYSF
- ; READB RBFLAG
- ; READS FCB,ERRJMP RSFLAG SYSF
- ; RENAME FCB RNFLAG CRLF PFNAME PRINT SYSF UNPROT
- ; SCAN CHAR,JMP
- ; SETDMA DMFLAG SYSF
- ; SYSF FUNC,AE
- ; UCASE
- ; UNPROT FCB PTFLAG SYSF
- ; UPPER
- ; VERSN TEXT
- ; WRITES FCB,ERRJMP WSFLAG SYSF
-
- ; *INCLUDE MRFLAGS.H in .AZM files for flag initialization.
- ; See MRFLAGS.DOC for MACRO/FLAG/GLOBAL cross listing.
-
- ; DEFINED CHARACTERS
-
- BEL EQU 07 ; ^G Console Beep
- TAB EQU 09 ; ^I Horizontal Tab
- LF EQU 0AH ; ^J Line Feed
- FF EQU 0CH ; ^L Form Feed
- CR EQU 0DH ; ^M Carriage Return
- EOF EQU 1AH ; ^Z End of File
- ESC EQU 1BH ; ^[ Escape
- BLANK EQU 20H ; Space
-
- ; CP/M CONVENTIONS
-
- BOOT EQU 0 ; Warm Boot entry vector
- BDOS EQU 5 ; BDOS entry vector
- FCB1 EQU 5CH ; Input file control block
- FCB2 EQU 6CH ; Second command line parameter
- DBUFF EQU 80H ; Default disk sector buffer
- TPA EQU 100H ; Transient program area
-
-
- ; MACRO OPTIONS
-
- STKSIZ EQU 32 ; EXIT macro user stack size
- BUFSIZ EQU 16 ; READB macro console input buffer size
-
- ; FLAG SETTINGS
-
- FALSE EQU 0
- TRUE EQU .NOT.FALSE
-
- ; MACROS
-
- AMBIG MACRO #UFNFCB,#AFNFCB
- ;
- ; Inline macro to change an ambiguous filename at address #AFNFCB
- ; to match an unambiguous filename at address #UFNFCB.
- ;
- ; e.g. AMBIG FCB1,FCB2
- ;
- LOCAL #AROUND
- PUSH HL
- PUSH DE
- PUSH BC
- LD HL,#AFNFCB+1
- LD DE,#UFNFCB+1
- LD B,11 ; number of characters in a filename
- CALL AMBI2?
- POP BC
- POP DE
- POP HL
- ;
- IF .NOT.AMFLAG
- JP #AROUND
- AMBI2?:
- LD A,'?'
- CP (HL)
- JR NZ,AMBI3?
- LD A,(DE) ; get UFN
- LD (HL),A ; put AFN
- AMBI3?:
- INC HL
- INC DE
- DJNZ AMBI2?
- RET
- ;
- AMFLAG DEFL TRUE
- #AROUND:
- ENDIF
- ; AMBIG
- ENDM
-
-
- CLOSE MACRO #FCB,#ERRJMP
- ;
- ; Inline macro to close a file using FCB at address #FCB.
- ; Jumps to #ERRJMP if the filename is not in the disk directory.
- ;
- ; e.g. CLOSE DFCB,NOFILE
- ;
- LOCAL #AROUND
- LD DE,#FCB
- CALL CLOS2?
- INC A ; A returns 0FFH if name not in directory
- JP Z,#ERRJMP
- ;
- IF .NOT.CLFLAG
- JP #AROUND
- CLOS2?:
- SYSF 16,0 ; Close File
- CLFLAG DEFL TRUE
- #AROUND:
- ENDIF ; CLOSE
-
- ENDM
-
-
- CMPBLK MACRO #ADDR1,#ADDR2,#SIZE
- ;
- ; Inline macro to compare two memory blocks of length
- ; #SIZE bytes at addresses #ADDR1 and #ADDR2.
- ; Z flag is set if the blocks are identical.
- ;
- ; e.g. CMPBLK FCB1,FCB2,12
- ;
- LOCAL #AROUND
- PUSH HL
- PUSH DE
- PUSH BC
- LD BC,#SIZE
- LD HL,#ADDR1
- LD DE,#ADDR2
- CALL COMP2?
- POP BC
- POP DE
- POP HL
- ;
- IF .NOT.CMFLAG
- JP #AROUND
- COMP2?:
- LD A,(DE)
- CPI
- RET NZ
- INC DE
- JP PE,COMP2?
- RET
- ;
- CMFLAG DEFL TRUE
- #AROUND:
- ENDIF
- ; CMPBLK
- ENDM
-
-
- CMPDAT MACRO #ADDR,#SIZE
- ;
- ; Inline macro to compare immediately following data
- ; of length #SIZE bytes with a memory block at #ADDR.
- ; Z flag is set if the data are identical.
- ;
- ; e.g. CMPDAT FCB1+9,5
- ; DB '???',2,10H
- ;
- LOCAL #DATA
- PUSH HL
- PUSH DE
- PUSH BC
- LD BC,#SIZE
- LD HL,#DATA
- LD DE,#ADDR
- CALL COMP2?
- POP BC
- POP DE
- POP HL
- JP #DATA+#SIZE
- ;
- IF .NOT.CMFLAG
- COMP2?:
- LD A,(DE)
- CPI
- RET NZ
- INC DE
- JP PE,COMP2?
- RET
- ;
- CMFLAG DEFL TRUE
- ENDIF
- #DATA:
- ; CMPDAT - DB here
- ENDM
-
-
- CPABLK MACRO #ADDR1,#ADDR2,#SIZE
- ;
- ; Inline macro to compare two memory blocks at #ADDR1 and #ADDR2
- ; of length #SIZE bytes, 256 bytes max.
- ; 7-bit ASCII compare, Z flag is set if the blocks are identical.
- ;
- ; e.g. CPABLK FCB1+1,FCB2+1,11
- ;
- LOCAL #AROUND
- PUSH HL
- PUSH DE
- PUSH BC
- LD B,#SIZE
- LD HL,#ADDR1
- LD DE,#ADDR2
- CALL CPAS2?
- POP BC
- POP DE
- POP HL
- ;
- IF .NOT.CPFLAG
- JP #AROUND
- CPAS2?:
- LD A,(DE)
- RES 7,A
- LD C,A
- LD A,(HL)
- RES 7,A
- CP C
- RET NZ
- INC HL
- INC DE
- DJNZ CPAS2?
- RET
- ;
- CPFLAG DEFL TRUE
- #AROUND:
- ENDIF
- ; CPABLK
- ENDM
-
-
- CPATXT MACRO #TEXT,#ADDR
- ;
- ; Inline macro to compare #TEXT string with a memory block at #ADDR.
- ; 7-bit ASCII compare, Z flag is set if the strings are identical.
- ;
- ; e.g. CPATXT 'COM',FCB1+9
- ;
- LOCAL #AROUND,#STRING
- PUSH HL
- PUSH DE
- PUSH BC
- LD B,#AROUND-#STRING
- LD HL,#STRING
- LD DE,#ADDR
- CALL CPAS2?
- POP BC
- POP DE
- POP HL
- JP #AROUND
- ;
- IF .NOT.CPFLAG
- CPAS2?:
- LD A,(DE)
- RES 7,A
- LD C,A
- LD A,(HL)
- RES 7,A
- CP C
- RET NZ
- INC HL
- INC DE
- DJNZ CPAS2?
- RET
- ;
- CPFLAG DEFL TRUE
- ENDIF
- #STRING:
- DB '#TEXT'
- #AROUND:
- ; CPATXT
- ENDM
-
-
- CPMVER MACRO
- ;
- ; Inline macro to determine the CP/M version number.
- ; Returns version number in A, in BCD times 10.
- ;
- PUSH HL
- PUSH DE
- PUSH BC
- LD C,12 ; BDOS function 12
- CALL BDOS
- POP BC
- POP DE
- POP HL
- ; CPMVER
- ENDM
-
-
- CRLF MACRO
- ;
- ; Inline macro to send carriage return and line feed to console.
- ;
- LOCAL #AROUND
- CALL CRLF2?
- ;
- IF .NOT.CRFLAG
- JP #AROUND
- CRLF2?:
- PUSH AF
- LD A,CR ; carriage return
- PCHAR
- LD A,LF ; line feed
- PCHAR
- POP AF
- RET
- ;
- CRFLAG DEFL TRUE
- #AROUND:
- ENDIF
- ; CRLF
- ENDM
-
-
- DELETE MACRO #FCB,#ERRJMP
- ;
- ; Inline macro to delete an existing disk file using the FCB
- ; at address #FCB.
- ; Prompts user if file is R/O, and gives option to abort.
- ; If aborting the deletion of a R/O file, jumps to #ERRJMP.
- ;
- ; e.g. DELETE FCB1,CONT
- ;
- LOCAL #AROUND,#DEL
- LD DE,#FCB
- LD A,(#FCB+9) ;first char of file type
- BIT 7,A ;R/O?
- JP Z,#DEL
- CRLF
- PFNAME #FCB
- PRINT ' is R/O, delete?'
- GCHAR
- UCASE
- CP 'Y'
- JP NZ,#ERRJMP
- UNPROT #FCB
- #DEL:
- CALL DELE2?
- ;
- IF .NOT.DEFLAG
- JP #AROUND
- DELE2?:
- SYSF 19,0 ; Delete File
- DEFLAG DEFL TRUE
- #AROUND:
- ENDIF
- ; DELETE
- ENDM
-
-
- DIVIDE MACRO #TWOS
- ;
- ; Inline macro to divide HL by #TWOS.
- ; #TWOS must be a power of 2.
- ; HL unchanged if #TWOS is 0 or 1.
- ;
- ; e.g. DIVIDE 4
- ;
- LOCAL #AROUND
- PUSH BC
- LD B,#TWOS
- CALL DIVI2?
- POP BC
- ;
- IF .NOT.DVFLAG
- JP #AROUND
- DIVI2?:
- LD A,B
- OR A
- RET Z ; by zero
- RRA
- RET C ; by one
- LD B,A
- DIVI3?:
- CALL DIVI4?
- LD A,B ; get divisor
- RRA
- LD B,A
- JR NC,DIVI3?
- RET
- DIVI4?:
- XOR A ; clear carry
- LD A,H
- RRA
- LD H,A
- LD A,L
- RRA
- LD L,A
- RET
- ;
- DVFLAG DEFL TRUE
- #AROUND:
- ENDIF
- ; DIVIDE
- ENDM
-
-
- DRIVE MACRO
- ;
- ; Inline macro to return current drive in A.
- ; A:=1, B:=2, etc.
- ;
- LOCAL #AROUND
- CALL DRIV2?
- INC A ; func 25 returns 0 for A:
- ;
- IF .NOT.DRFLAG
- JP #AROUND
- DRIV2?:
- SYSF 25,0 ; Return Current Disk
- DRFLAG DEFL TRUE
- #AROUND:
- ENDIF
- ; DRIVE
- ENDM
-
-
- ENTER MACRO
- ;
- ; Inline macro to save incoming stack.
- ;
- LD (OLDSTK),SP
- LD SP,STACK
- ; ENTER
- ENDM
-
-
- EXIT MACRO #BOOT
- ;
- ; Inline macro to restore the stack.
- ; If #BOOT is 0 then warm boot on exit.
- ;
- LD SP,(OLDSTK)
- ;
- IF #BOOT
- RET
- ELSE
- LD C,0 ; warm boot
- CALL BDOS
- ENDIF
- ;
- OLDSTK: DS 2 ; incoming SP saved here
- DS STKSIZ ; user stack
- STACK EQU $ ; stack top here
- ; EXIT
- ENDM
-
-
- FILL MACRO #ADDR,#SIZE,#VAL
- ;
- ; Inline macro to fill memory with byte #VAL,
- ; starting at #ADDR, continuing for #SIZE locations.
- ;
- ; e.g. FILL FCB1+1,8,BLANK
- ;
- LOCAL #AROUND
- PUSH HL
- PUSH BC
- LD HL,#ADDR
- LD BC,#SIZE
- LD A,#VAL
- CALL FILL2?
- POP BC
- POP HL
- ;
- IF .NOT.FLFLAG
- JP #AROUND
- FILL2?:
- PUSH DE
- LD D,A
- FILL3?:
- LD (HL),D
- INC HL
- DEC BC
- LD A,C
- OR B
- JR NZ,FILL3?
- POP DE
- RET
- ;
- FLFLAG DEFL TRUE
- #AROUND:
- ENDIF
- ; FILL
- ENDM
-
-
- GCHAR MACRO
- ;
- ; Inline macro to read one character from console.
- ; Suspends program execution and waits for character.
- ; Character is returned in A.
- ;
- LOCAL #AROUND
- CALL GCHA2?
- ;
- IF .NOT.CIFLAG
- JP #AROUND
- GCHA2?:
- SYSF 1,0 ; Console Input
- CIFLAG DEFL TRUE
- #AROUND:
- ENDIF
- ; GCHAR
- ENDM
-
-
- GFNAME MACRO #FCB
- ;
- ; Inline macro to get a filename from the
- ; console and place it in a memory FCB at address #FCB.
- ;
- ; e.g. GFNAME FCB1
- ;
- LOCAL #AROUND
- PUSH HL
- PUSH DE
- PUSH BC
- LD HL,#FCB
- LD (?FCBAD),HL ; save FCB address
- CALL GNAM2?
- POP BC
- POP DE
- POP HL
- ;
- IF .NOT.FNFLAG
- JP #AROUND
- ?FCBAD: DS 2 ; FCB address saved here
- GNAM2?:
- CRLF
- GNAM3?:
- PRINT ' '
- LD A,CR
- PCHAR
- PRINT 'Enter file name: '
- LD HL,(?FCBAD)
- PUSH HL
- XOR A ; 0 = default drive
- LD (HL),A ; initialize to default drive
- LD B,11 ; chars in name
- LD A,BLANK
- ZNAME?: ; initialize name to blanks
- INC HL
- LD (HL),A
- DJNZ ZNAME?
- POP DE ; FCB address
- INC DE ; point to first char of name
- READB
- CALL GETCH? ; char returns in A
- JP C,GNAM3? ; nothing entered, so start again
- CP BLANK
- JP Z,GNAM3? ; leading space entered, so start again
- UCASE
- LD (DE),A ; store first char of name
- CALL GETCH? ; char returns in A
- RET C ; done: short name
- CP BLANK ; same, with trailing space
- RET Z
- LD B,7 ; 7 characters to go
- UCASE
- CP '.'
- JP Z,ENAME? ; end of name
- CP ':'
- JP NZ,PNAME? ; no drive specification
- LD A,(DE) ; get the drive spec
- SUB 40H ; make it binary
- DEC DE ; point to 1st FCB location
- LD (DE),A ; put binary drive spec
- CALL GETCH? ; start filename
- JP C,GNAM3? ; only drive spec entered, so start again
- UCASE
- INC B ; 8 characters to go
- PNAME?:
- INC DE
- LD (DE),A
- CALL GETCH?
- RET C
- CP BLANK
- RET Z
- UCASE
- CP '.'
- JP Z,ENAME?
- DJNZ PNAME?
- JP GNAM3? ; if 9 characters
- ENAME?:
- LD HL,(?FCBAD) ; get FCB
- LD DE,9 ; extent offset
- ADD HL,DE
- EX DE,HL
- LD B,3
- ENAM2?:
- CALL GETCH?
- RET C
- CP BLANK
- RET Z
- UCASE
- LD (DE),A
- INC DE
- DJNZ ENAM2?
- RET
- ;
- FNFLAG DEFL TRUE
- #AROUND:
- ENDIF
- ; GFNAME
- ENDM
-
-
- HEXHL MACRO
- ;
- ; Inline macro to convert ASCII characters in the console
- ; buffer of READB into a 16-bit binary number in HL.
- ; Carry flag is set if invalid hex character found.
- ;
- ; e.g. READB
- ; HEXHL
- ;
- LOCAL #AROUND
- CALL RDHL2?
- ;
- IF .NOT.HXFLAG
- JP #AROUND
- RDHL2?:
- LD HL,0 ; clear HL
- RDHL3?:
- CALL GETCH?
- CCF ; check for last character
- RET NC
- UCASE
- CALL RDHL4? ; convert to binary
- RET C ; error of input
- ADD HL,HL ; multiply previous digit by 16
- ADD HL,HL
- ADD HL,HL
- ADD HL,HL
- OR L ; combine new
- LD L,A ; put back into L
- JR RDHL3? ; next
- RDHL4?:
- SUB 30H ; ASCII bias
- RET C ; < 0
- CP 17H
- CCF
- RET C ; > F
- CP 10
- CCF
- RET NC ; 0-9
- SUB 7
- CP 10 ; A-F or error
- RET
- ;
- HXFLAG DEFL TRUE
- #AROUND:
- ENDIF
- ; HEXHL
- ENDM
-
-
- HLDEC MACRO
- ;
- ; Inline macro to print HL as a decimal string.
- ;
- LOCAL #AROUND
- CALL HLDC2?
- ;
- IF .NOT.HLFLAG
- JP #AROUND
- HLDC2?:
- PUSH HL
- PUSH DE
- PUSH BC
- LD B,0 ; leading-zero flag
- LD DE,-10000 ; two's complement
- CALL HLDC3? ; ten thousands
- LD DE,-1000
- CALL HLDC3? ; thousands
- LD DE,-100
- CALL HLDC3? ; hundreds
- LD DE,-10
- CALL HLDC3? ; tens
- LD A,L
- ADD A,'0' ; make ASCII
- PCHAR
- POP BC
- POP DE
- POP HL
- RET
- HLDC3?:
- LD C,'0'-1
- HLDC4?:
- INC C
- ADD HL,DE ; add neg until result negative
- JP C,HLDC4?
- ;
- OR A
- SBC HL,DE ; get back last value
- LD A,C ; decimal ASCII digit
- CP '1'
- JP NC,HLDC5?
- LD A,B ; check zero flag
- OR A
- LD A,C
- RET Z ; don't print if leading zero
- ;
- PCHAR ; print a non-leading zero
- RET
- HLDC5?:
- LD B,0FFH ; print all zeros from now on
- PCHAR ; first non-zero digit
- RET
- ;
- HLFLAG DEFL TRUE
- #AROUND:
- ENDIF
- ;HLDEC
- ENDM
-
-
- LCHAR MACRO
- ;
- ; Inline macro to send char in A to printer.
- ;
- ; e.g. LD A,CR
- ; LCHAR
- ;
- LOCAL #AROUND
- CALL LOCH2?
- ;
- IF .NOT.LOFLAG
- JP #AROUND
- LOCH2?:
- SYSF 5,1 ; List Output
- LOFLAG DEFL TRUE
- #AROUND:
- ENDIF
- ; LCHAR
- ENDM
-
-
- MAKE MACRO #FCB,#ERRJMP
- ;
- ; Inline macro to create a new disk file
- ; using FCB at address #FCB.
- ; Jumps to #ERRJMP if disk directory is full.
- ;
- ; e.g. MAKE FCB1,FULDIR
- ;
- LOCAL #AROUND
- LD DE,#FCB
- XOR A ; zero
- LD (#FCB+12),A ; ex
- LD (#FCB+32),A ; cr
- CALL MAKE2?
- INC A ; A returns 0FFH if no directory space left
- JP Z,#ERRJMP
- ;
- IF .NOT.MKFLAG
- JP #AROUND
- MAKE2?:
- SYSF 22,0 ; Make File
- MKFLAG DEFL TRUE
- #AROUND:
- ENDIF
- ; MAKE
- ENDM
-
-
- MOVBLK MACRO #FROM,#TO,#SIZE
- ;
- ; Inline macro to move a block of length #SIZE bytes
- ; from address #FROM to address #TO.
- ;
- ; e.g. MOVBLK FCB1,4000H,0FH
- ;
- PUSH HL
- PUSH DE
- PUSH BC
- LD HL,#FROM
- LD DE,#TO
- LD BC,#SIZE
- LDIR
- POP BC
- POP DE
- POP HL
- ; MOVBLK
- ENDM
-
-
- MOVDAT MACRO #TO,#SIZE
- ;
- ; Inline macro to move immediately following data
- ; of length #SIZE bytes to address #TO.
- ;
- ; e.g. MOVDAT NEWBUF,7
- ; DB 30H,CR,LF,'TEST'
- ;
- LOCAL #DATA
- PUSH HL
- PUSH DE
- PUSH BC
- LD BC,#SIZE
- LD DE,#TO
- LD HL,#DATA
- LDIR
- POP BC
- POP DE
- POP HL
- JP #DATA+#SIZE
- #DATA:
- ; MOVDAT - DB here
- ENDM
-
-
- MULT MACRO #TWOS
- ;
- ; Inline macro to multiply HL by #TWOS.
- ; #TWOS must be 0, 1, or a power of 2.
- ; If #TWOS is 0, A is presumed loaded with multiplier.
- ;
- ; e.g. MULT 8
- ;
- LOCAL #AROUND
- PUSH BC
- ;
- IF #TWOS
- LD B,#TWOS
- ELSE
- LD B,A
- ENDIF
- ;
- CALL MULT2?
- POP BC
- ;
- IF .NOT.MLFLAG
- JP #AROUND
- MULT2?:
- LD A,B
- OR A ; times 0
- JR NZ,MULT3?
- LD L,A
- LD H,A
- RET
- MULT3?:
- RRA
- RET C ; times 1
- LD B,A
- MULT4?:
- ADD HL,HL ; shift left
- LD A,B
- RRA
- LD B,A
- JR NC,MULT4?
- RET
- ;
- MLFLAG DEFL TRUE
- #AROUND:
- ENDIF
- ; MULT
- ENDM
-
-
- OPEN MACRO #FCB,#ERRJMP
- ;
- ; Inline macro to open an existing disk file
- ; using the FCB at address #FCB.
- ; Jumps to #ERRJMP if no file is found.
- ;
- ; e.g. OPEN FCB1,NOFILE
- ;
- LOCAL #AROUND
- LD DE,#FCB
- XOR A ; zero accumulator
- LD (#FCB+12),A ; extent
- LD (#FCB+32),A ; current record
- CALL OPEN2?
- INC A ; A returns 0FFH if no file
- JP Z,#ERRJMP
- ;
- IF .NOT.OPFLAG
- JP #AROUND
- OPEN2?:
- SYSF 15,0 ; Open File
- OPFLAG DEFL TRUE
- #AROUND:
- ENDIF
- ; OPEN
- ENDM
-
-
- OUTBIN MACRO
- ;
- ; Inline macro to print A as a binary string.
- ;
- LOCAL #AROUND
- CALL BINB2?
- ;
- IF .NOT.BNFLAG
- JP #AROUND
- BINB2?:
- PUSH BC
- LD C,A
- LD B,8
- BINB3?:
- LD A,C
- ADD A,A ; left shift into carry
- LD C,A
- LD A,'0'/2
- ADC A,A ; yields ASCII '0' or '1'
- PCHAR
- DEC B
- JP NZ,BINB3?
- POP BC
- RET
- ;
- BNFLAG DEFL TRUE
- #AROUND:
- ENDIF
- ; OUTBIN
- ENDM
-
-
- OUTHEX MACRO #REG
- ;
- ; Inline macro to convert binary number in register #REG
- ; to two hex ASCII characters, and print them.
- ; Original number is left in A.
- ;
- ; e.g. OUTHEX A
- ;
- LOCAL #AROUND
- LD A,#REG
- CALL OTHX2?
- ;
- IF .NOT.CXFLAG
- JP #AROUND
- OTHX2?:
- PUSH BC
- LD C,A ; save number in C
- RRA ; shift high nybble to low
- RRA
- RRA
- RRA
- CALL OTHX3? ; high byte
- LD A,C ; retrieve number
- CALL OTHX3? ; low byte
- LD A,C ; retrieve again
- POP BC
- RET
- OTHX3?:
- AND 0FH ; zero upper nybble
- ADD A,90H ; ASCII conversion
- DAA
- ADC A,40H
- DAA
- PCHAR ; send it
- RET
- ;
- CXFLAG DEFL TRUE
- #AROUND:
- ENDIF
- ; OUTHEX
- ENDM
-
-
- OUTHL MACRO
- ;
- ; Inline macro to print HL as a hexadecimal string.
- ;
- LOCAL #OVER
- LD A,H
- OR A ; is H zero?
- JP Z,#OVER
- OUTHEX H
- #OVER:
- OUTHEX L
- ; OUTHL
- ENDM
-
-
- PCHAR MACRO
- ;
- ; Inline macro to send char in A to console.
- ;
- ; e.g. LD A,(HL)
- ; PCHAR
- ;
- LOCAL #AROUND
- CALL PCHR2?
- ;
- IF .NOT.COFLAG
- JP #AROUND
- PCHR2?:
- SYSF 2,1 ; Console Output
- COFLAG DEFL TRUE
- #AROUND:
- ENDIF
- ; PCHAR
- ENDM
-
-
- PFNAME MACRO #FCB
- ;
- ; Inline macro to print file name in FCB at address #FCB.
- ;
- ; e.g. PFNAME FCB1
- ;
- LOCAL #AROUND
- PUSH HL
- PUSH BC
- LD B,8 ; length of primary name
- LD HL,#FCB+1
- CALL PFNA2?
- POP BC
- POP HL
- PRINTB #FCB+9,3 ; the file type
- ;
- IF .NOT.PFFLAG
- JP #AROUND
- PFNA2?:
- LD A,(HL) ; get char
- CP BLANK
- JP Z,PFNA3?
- RES 7,A ; make printable if 8th bit options used
- PCHAR
- INC HL
- DEC B
- JP NZ,PFNA2?
- PFNA3?:
- LD A,'.'
- PCHAR
- RET
- ;
- PFFLAG DEFL TRUE
- #AROUND:
- ENDIF
- ; PFNAME
- ENDM
-
-
- PRINT MACRO #TEXT
- ;
- ; Inline macro to print a string literal to the console.
- ;
- ; e.g. PRINT 'Message '
- ;
- LOCAL #AROUND,#MESG
- PUSH HL
- PUSH BC
- LD C,#AROUND-#MESG
- LD HL,#MESG
- CALL PBUF2?
- POP BC
- POP HL
- JP #AROUND
- ;
- IF .NOT.PRFLAG
- PBUF2?:
- LD A,(HL)
- PCHAR
- INC HL
- DEC C
- JP NZ,PBUF2?
- RET
- ;
- PRFLAG DEFL TRUE
- ENDIF
- ;
- #MESG: DB '#TEXT'
- #AROUND:
- ; PRINT
- ENDM
-
-
- PRINTB MACRO #ADDR,#SIZE
- ;
- ; Inline macro to print a string at address #ADDR
- ; of length #SIZE bytes, 256 max.
- ;
- ; e.g. PRINTB FCB1+1,11
- ;
- LOCAL #AROUND
- PUSH HL
- PUSH BC
- LD C,#SIZE
- LD HL,#ADDR
- CALL PBUF2?
- POP BC
- POP HL
- ;
- IF .NOT.PRFLAG
- JP #AROUND
- PBUF2?:
- LD A,(HL)
- PCHAR
- INC HL
- DEC C
- JP NZ,PBUF2?
- RET
- ;
- PRFLAG DEFL TRUE
- #AROUND:
- ENDIF
- ; PRINTB
- ENDM
-
-
- PROTEC MACRO #FCB
- ;
- ; Inline macro to set file attribute to R/O,
- ; using FCB at address #FCB.
- ;
- ; e.g. PROTEC FCB1
- ;
- LOCAL #AROUND
- LD DE,#FCB
- LD A,(#FCB+9) ; get t1' bit
- SET 7,A ; set for R/O
- LD (#FCB+9),A ; put it back
- CALL PROT2?
- ;
- IF .NOT.PTFLAG
- JP #AROUND
- PROT2?:
- SYSF 30,0 ; Set File Attributes
- PTFLAG DEFL TRUE
- #AROUND:
- ENDIF
- ; PROTEC
- ENDM
-
-
- READB MACRO
- ;
- ; Inline macro to read a line from the console into a buffer.
- ; Buffer size is set by BUFSIZ.
- ; GETCH? subroutine retrieves characters from the buffer.
- ;
- ; e.g. READB
- ;
- LOCAL #AROUND
- CALL RDBF2?
- ;
- IF .NOT.RBFLAG
- JP #AROUND
- RDBF2?:
- PUSH HL
- PUSH DE
- PUSH BC
- LD DE,?MBUFF ; address of max length
- LD C,10 ; BDOS function 10
- CALL BDOS
- LD HL,?RBUFF ; start of buffer
- LD (?BUFFP),HL ; initialize buffer pointer
- POP BC
- POP DE
- POP HL
- RET
- GETCH?:
- LD A,(?CBUFF) ; get character count
- SUB 1 ; decrement with carry
- RET C ; no more characters
- LD (?CBUFF),A ; update the count
- PUSH HL
- LD HL,(?BUFFP) ; get buffer pointer
- LD A,(HL) ; get the character
- INC HL ; increment pointer
- LD (?BUFFP),HL ; update the pointer
- POP HL
- RET
- ;
- RBFLAG DEFL TRUE
- ;
- ?BUFFP: DW ?RBUFF ; buffer pointer is here
- ?MBUFF: DB BUFSIZ ; max buffer length
- ?CBUFF: DS 1 ; character count placed here by BDOS call
- ?RBUFF: DS BUFSIZ ; buffer is here
- ;
- #AROUND:
- ENDIF
- ; READB
- ENDM
-
-
- READS MACRO #FCB,#ERRJMP
- ;
- ; Inline macro to read a disk sector into the DMA buffer,
- ; using FCB at address #FCB.
- ; Jumps to address #ERRJMP if EOF is read.
- ;
- ; e.g. READS FCB1,EOFILE
- ;
- LOCAL #AROUND
- LD DE,#FCB
- CALL READ2?
- OR A ; set flags
- JP NZ,#ERRJMP ; EOF read
- ;
- IF .NOT.RSFLAG
- JP #AROUND
- READ2?:
- SYSF 20,0 ; Read Sequential
- RSFLAG DEFL TRUE
- #AROUND:
- ENDIF
- ; READS
- ENDM
-
-
- RENAME MACRO #FCB
- ;
- ; Inline macro to rename an existing disk file.
- ; #FCB is FCB address holding original name.
- ; New name must exist at #FCB + 10H.
- ;
- ; e.g. RENAME FCB1
- ;
- LOCAL #AROUND
- UNPROT #FCB ; make it R/W
- CALL RENA2?
- CRLF
- PFNAME #FCB
- PRINT ' renamed to '
- PFNAME #FCB+10H
- ;
- IF .NOT.RNFLAG
- JP #AROUND
- RENA2?:
- SYSF 23,0 ; Rename File
- RNFLAG DEFL TRUE
- #AROUND:
- ENDIF
- ; RENAME
- ENDM
-
-
- SCAN MACRO #CHAR,#JMP
- ;
- ; Inline macro which generates a jump to #JMP if
- ; the console key #CHAR has been pressed.
- ;
- ; e.g. SCAN 3,BOOT ; Warm boot if ^C pressed
- ;
- LOCAL #OVER
- PUSH HL
- PUSH DE
- PUSH BC
- LD C,11 ; Get Console Status
- CALL BDOS
- POP BC
- POP DE
- POP HL
- RRCA ; 0FFH returned if char ready
- JP NC,#OVER ; no char
- GCHAR
- CP #CHAR
- JP Z,#JMP
- #OVER:
- ; SCAN
- ENDM
-
-
- SETDMA MACRO
- ;
- ; Inline macro to set the DMA address.
- ; DE must be loaded with the DMA address prior to SETDMA.
- ;
- ; e.g. SETDMA BUFFP
- ;
- LOCAL #AROUND
- CALL SDMA2?
- ;
- IF .NOT.DMFLAG
- JP #AROUND
- SDMA2?:
- SYSF 26,0 ; Set DMA Address
- DMFLAG DEFL TRUE
- #AROUND:
- ENDIF
- ; SETDMA
- ENDM
-
-
- SYSF MACRO #FUNC,#AE
- ;
- ; Macro to generate BDOS call #FUNC.
- ; NOT AN INLINE MACRO: needs branch around instructions.
- ; Referenced only by other macros in Z80MACRO.LIB
- ; If BDOS function is 2,5,8,or 14, then #AE=1; otherwise #AE = 0.
- ;
- ; e.g. SYSF 9,0 ; Print String
- ; SYSF 2,1 ; Console Output
- ;
- PUSH HL
- PUSH DE
- PUSH BC
- LD C,#FUNC
- ;
- IF #AE
- LD E,A
- PUSH AF
- CALL BDOS
- POP AF
- ELSE
- CALL BDOS
- ENDIF
- ;
- POP BC
- POP DE
- POP HL
- RET
- ; SYSF
- ENDM
-
-
- UCASE MACRO
- ;
- ; Inline macro to convert ASCII char in A to uppercase.
- ; Will not alter values other than ASCII lower case.
- ;
- ; e.g. UCASE
- ;
- LOCAL #SKIP
- CP 61H
- JP C,#SKIP
- CP 7BH
- JP NC,#SKIP
- AND 5FH ; make uppercase
- #SKIP:
- ; UCASE
- ENDM
-
-
- UNPROT MACRO #FCB
- ;
- ; Inline macro to convert R/O file to R/W
- ; using FCB at address #FCB.
- ;
- ; e.g. UNPROT FCB1
- ;
- LOCAL #AROUND
- LD DE,#FCB
- LD A,(#FCB+9) ; get t1' bit
- RES 7,A ; reset for R/W
- LD (#FCB+9),A ; put it back
- CALL PROT2?
- ;
- IF .NOT.PTFLAG ; PROT2? shared with PROTEC macro
- JP #AROUND
- PROT2?:
- SYSF 30,0 ; Set File Attributes
- PTFLAG DEFL TRUE
- #AROUND:
- ENDIF
- ; UNPROT
- ENDM
-
-
- UPPER MACRO
- ;
- ; Inline macro to isolate upper digit of packed BCD in A
- ; and shift it to lower place.
- ;
- ; e.g. UPPER
- ;
- RRA
- RRA
- RRA
- RRA
- AND 0FH ; zero upper nybble
- ; UPPER
- ENDM
-
-
- VERSN MACRO #TEXT
- ;
- ; Inline macro to embed the version number.
- ;
- ; e.g. VERSN 'dd.mm.yy.NAME'
- ;
- LOCAL #AROUND
- JP #AROUND
- DB 'Ver ','#TEXT'
- #AROUND:
- ; VERSN
- ENDM
-
-
- WRITES MACRO #FCB,#ERRJMP
- ;
- ; Inline macro to write a sector to disk,
- ; using the FCB address at #FCB.
- ; Jumps to #ERRJMP if disk is full.
- ;
- ; e.g. WRITES FCB1,FULL
- ;
- LOCAL #AROUND
- LD DE,#FCB
- CALL WRIT2?
- OR A ; A is 0 if successful
- JP NZ,#ERRJMP ; disk is full
- ;
- IF .NOT.WSFLAG
- JP #AROUND
- WRIT2?:
- SYSF 21,0 ; Write Sequential
- WSFLAG DEFL TRUE
- #AROUND:
- ENDIF
- ; WRITES
- ENDM
-
-