home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The C Users' Group Library 1994 August
/
wc-cdrom-cusersgrouplibrary-1994-08.iso
/
vol_100
/
109_01
/
xsdmac.lib
< prev
next >
Wrap
Text File
|
1985-03-10
|
19KB
|
954 lines
;
; note: BDOS should be defined by the user as the
; entry to CP/M (5 for normal systems 1009H for ADDS)
;
; also BOOT as the entry to warmboot
; (0 in normal systems 1000H in ADDS)
;
; -- NEW MACRO LIBRARY --
;
; SAVE MACRO SAVE SPECIFIED REGISTERS
;
; SAVE R1,R2,R3,R4
;
; R1-R4 MAY BE B,D,H OR PSW SAVED IN ORDER SPECIFIED
; IF REGS ARE OMITTED SAVE B,D AND H
;
SAVE MACRO R1,R2,R3,R4
IF NOT NUL R1&R2&R3&R4
IRP R,<<R1>,<R2>,<R3>,<R4>>
IF NUL R
EXITM
ENDIF
PUSH R
ENDM
ELSE
IRPC REG,BDH
PUSH REG
ENDM
ENDIF
ENDM
;
; . . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
; RESTORE MACRO RESTORE REGISTERS (INVERSE OF SAVE)
;
; RESTORE R1,R2,R3,R4
;
; R1-R4 MAY BE B,D,H OR PSW RESTORED IN ORDER SPECIFIED
; IF REGS OMITTED RESTORE H,D AND B
;
RESTORE MACRO R1,R2,R3,R4
IF NOT NUL R1&R2&R3&R4
IRP R,<<R1>,<R2>,<R3>,<R4>>
IF NUL R
EXITM
ENDIF
POP R
ENDM
ELSE
IRPC REG,HDB
POP REG
ENDM
ENDIF
ENDM
;
;
; . . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
; CHARIN MACRO CONSOLE INPUT TO A
;
; CHARIN ADDR
;
CHARIN MACRO ADDR
MVI C,1 ;;CONSOLE INPUT
CALL BDOS ;;CALL BDOS
IF NOT NUL ADDR
STA ADDR
ENDIF
ENDM
;
;
; . . . . . . . . . . . . . . ... ... . .. . . . . . . . .
;
; CHAROUT MACRO CONSOLE OUTPUT FROM A
;
; CHAROUT ADDR
;
CHAROUT MACRO ADDR
IF NOT NUL ADDR
LDA ADDR
ENDIF
MVI C,2 ;;CONOUT
MOV E,A ;;CHAR TO E
CALL BDOS ;;CALL BDOS
ENDM
;
; . . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
; CHARSTAT MACRO CHECK CONSOLE STATUS
;
; RETURN TRUE (FF) IF CHAR READY FALSE (0) IF NOT
;
CHARSTAT MACRO
LOCAL EXIT
MVI C,11
CALL BDOS
ORA A
JZ EXIT
MVI A,0FFH
EXIT: ENDM
;
; . . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
; INPUT MACRO INPUT CHARACTER STRING FROM CONSOLE
;
; INPUT ADDR,BUFLEN
;
; ADDR START OF TEXT BUFFER
; BUFLEN LENGTH OF BUFFER (DEFAULT IS 127)
;
INPUT MACRO ADDR,BUFLEN
MVI C,10
IF NOT NUL ADDR
LXI D,ADDR ;;SET BUFFER ADDRESS
ENDIF
IF NOT NUL BUFLEN
MVI A,BUFLEN ;;SET BUFFER LENGTH
STAX D
ELSE
MVI A,127
STAX D ;;SET BUFFER DEFAULT MAXIMUM
ENDIF
CALL BDOS ;;BDOS ENTRY
ENDM
;
; . . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
; PRINT MACRO PRINT A STRING ON CONSOLE
;
; PRINT (CARRIAGE RETURN, LINE FEED)
; PRINT 'LITERAL'
; PRINT <'LITERAL',CR,LF,'SECOND LITERAL'>
;
; PRINT ADDR,$ (ASCII OUTPUT UNTIL $)
; PRINT ADDR,L,H (HEX OUTPUT L CHARACTERS)
; PRINT ADDR,L,A (ASCII OUTPUT L CHARACTERS)
;
; LITERALS MUST BE IN SINGLE QUOTES 'LIT'
; IF LITERAL CONTAINS CONTROL CODES ENTIRE STRING IN <> BRACKETS
; MACRO ALSO ASSEMBLES
; CR = CARRIAGE RETURN
; LF = LINE FEED
; BEL = BELL CODE
;
; MACRO ASSUMES ADDR ALREADY LOADED TO HL IF ARGUMENT OMITTED
;
PRINT MACRO ?STRING,LEN,TC
LOCAL @OVER,@MESS,PLOOP,PASTCR,@CRLF
CR SET 0DH
LF SET 0AH
BEL SET 07H
IF NUL ?STRING&LEN&TC
JMP PASTCR
@CRLF: DB CR
DB LF
DB '$'
PASTCR: LXI D,@CRLF
MVI C,9
CALL BDOS
ELSE
IF NUL LEN&TC
JMP @OVER
@MESS: DB ?STRING
DB '$'
@OVER: LXI D,@MESS
MVI C,9
CALL BDOS ;;BDOS ENTRY
ELSE
IF NUL TC
IF NOT NUL ?STRING
LXI D,?STRING ;;POINTER TO STRING
ENDIF
MVI C,9
CALL BDOS ;;BDOS ENTRY
ELSE
IF NOT NUL ?STRING
LXI H,?STRING ;;POINTER TO STRING
ENDIF
MVI C,LEN ;;LENGTH OF STRING
PLOOP: PUSH B
PUSH H
IF TC=H
MOV A,M ;;GET A BYTE
HEXOUT ;;CONV TO HEX & OUTPUT
ELSE
MOV E,M ;;GET A BYTE
MVI C,2 ;;OUT FROM E
CALL BDOS
ENDIF
POP H
POP B
INX H
DCR C ;;DECR LENGTH
JNZ PLOOP ;;CONTINUE TILL LEN 0
ENDIF
ENDIF
ENDIF
ENDM
;
; . . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
; HEXOUT MACRO CONVERT BINARY NO AND OUTPUT TO CONSOLE
;
; HEXOUT ADDR
;
; NUMBER ASSUMED IN A IF NO ARGUMENT
;
HEXOUT MACRO ADDR
LOCAL OUTCHR,HEXEND
JMP HEXEND
HEXPRN: SAVE PSW
RRC
RRC
RRC
RRC ;;SHIFT RIGHT 4
CALL OUTCHR
RESTORE PSW
OUTCHR: ANI 0FH ;;MASK 4 BITS
ADI 90H ;;ADD OFFSET
DAA ;;DEC ADJUST
ACI 40H ;;ADD OFFSET
DAA ;;DEC ADJUST
MOV E,A ;;TO E FOR OUTPUT
MVI C,2 ;;CONOUT
JMP BDOS ;;CALL BDOS
HEXEND:
HEXOUT MACRO ?ADDR
IF NOT NUL ?ADDR
LDA ?ADDR
ENDIF
CALL HEXPRN
ENDM
HEXOUT ADDR
ENDM
;
;
; . . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
; HEXIN MACRO CONVERT A NUMBER IN MEMORY FROM HEX TO BINARY
;
; IF NO ARGUMENT MACRO ASSUMES ADDR OF HEX STRING IN HL
; ANSWER LEFT IN HL WITH LEAST SIGNIFICANT 8 BITS IN A
; CARRY SET ON ERROR. CONVERSION STOPS WHEN ZERO IS
; FOUND IN HEX STRING.
;
HEXIN MACRO ADDR
LOCAL IN1,IN2,OVERSUB
JMP OVERSUB
@HEXIN LXI H,0 ;;ZERO NUMBER
IN1: LDAX D ;;GET A CHAR
ORA A ;;CHECK FOR END OF BUFFER
RZ
SUI '0' ;;CHECK < 0 AND CONVERT TO HEX
RC
ADI '0'-'G' ;;CHECK > F
RC
ADI 6
JP IN2 ;;NO BETWEEN A AND F
ADI 7
RC
IN2: ADI 10
ORA A ;;CLEAR CARRY
MOV C,A ;;HEX DIGIT TO C
MVI B,0 ;;ZERO TO B
DAD H
DAD H
DAD H
DAD H ;;SHIFT LEFT 4
DAD B ;;ADD IN NEW DIGIT
INX D ;;INCR BUFFER POINTER
JMP IN1 ;;RETURN FOR MORE INPUT
OVERSUB:
HEXIN MACRO ?ADDR
IF NOT NUL ?ADDR
LXI D,?ADDR ;;LOAD BUFFER ADDR
ELSE
XCHG
ENDIF
CALL @HEXIN
MOV A,L ;;LEAST SIGNIFICANT 8 BITS TO A
ENDM
HEXIN ADDR
ENDM
;
; . . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
; DECOUT MACRO CONVERT A POSITIVE INTEGER TO DECIMAL AND OUTPUT
; TO THE CONSOLE.
;
; DECOUT ADDR
;
; IF ADDR OMITTED, NUMBER ASSUMED TO BE IN HL, ELSE LOADED TO HL
; LEADING ZEROS SUPRESSED. MAXIMUM NUMBER 65,767
;
DECOUT MACRO ADDR
LOCAL ENDDEC,DX
JMP ENDDEC
@DECOUT:SAVE ;;PUSH STACK
LXI B,-10 ;;RADIX FOR CONVERSION
LXI D,-1 ;;THIS BECOMES NO DIVIDED BY RADIX
DX DAD B ;;SUBTRACT 10
INX D
JC DX
LXI B,10
DAD B ;;ADD RADIX BACK IN ONCE
XCHG
MOV A,H
ORA L ;;TEST FOR ZERO
CNZ @DECOUT ;;RECURSIVE CALL
MOV A,E
ADI '0' ;;CONVERT FROM BCD TO HEX
MOV E,A ;;TO E FOR OUTPUT
CHAROUT ;;CONSOLE OUTPUT
RESTORE ;;POP STACK
RET
ENDDEC:
DECOUT MACRO ?ADDR
IF NOT NUL ?ADDR
LHLD ?ADDR
ENDIF
CALL @DECOUT ;;CALL THE SUBROUTINE
ENDM
DECOUT ADDR
ENDM
;
;
;
; . . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
; DECIN MACRO CONVERT A NUMBER IN MEMORY FROM ASCII TO BINARY
;
; DECIN ADDR
;
; ADDR POINTS TO MEMORY LOCATION OF START OF NO, IF
; ARG OMITTED POINTER ASSUMED LOADED TO HL
; MACRO RETURNS WITH CARRY SET IF ALPHABETIC CHAR FOUND
; CONVERSION STOPS WHEN CHAR LESS THAN ZERO IS FOUND.
; BINARY NUMBER IS LEFT IN HL, MAXIMUM 65,767
; LEAST SIGNIFICANT 8 BITS OF NUMBER IN A.
;
DECIN MACRO ADDR
LOCAL DLOOP,OVERSUB
JMP OVERSUB
@DECIN: LXI D,0 ;;ZERO DE
XCHG ;;ADDR POINTER TO DE, ZERO TO HL
DLOOP: LDAX D ;;GET A ASCII DIGIT
SUI '0' ;;CONVERT TO BCD AND TEST
ANA A ;;RESET CARRY
RM ;;TERMINATE CONVERSION IF < ZERO
CPI 10 ;;CHECK LEGITIMATE DIGIT (0-9)
CMC ;;COMPLEMENT CARRY
RC ;;RET WITH CARRY SET IF ERROR
INX D ;;INCR ADDR POINTER
DAD H ;;SHIFT LEFT 1
PUSH H ;;SAVE RESULT
DAD H
DAD H ;;SHIFT LEFT 2
POP B ;;NO * 2 TO B
DAD B ;;HL NOW CONTAINS 10*NO
MOV C,A ;;ADD PRODUCT TO DIGIT
MVI B,0
DAD B
JMP DLOOP ;;BACK FOR ANOTHER DIGIT
OVERSUB:
DECIN MACRO ?ADDR
IF NOT NUL ?ADDR
LXI H,?ADDR
ENDIF
CALL @DECIN ;;CALL THE SUBROUTINE
MOV A,L ;;LEAST SIGNIFICANT HALF OF NO TO A
ENDM
DECIN ADDR
ENDM
;
; . . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
; MOVE MACRO MOVE A BLOCK FROM SOURCE TO DEST
;
; MOVE SOURCE,DEST,COUNT
;
; SOURCE TO HL MACRO ASSUMES REGISTERS ALREADY
; DEST TO DE LOADED IF ARG OMITTED
; COUNT TO BC
;
MOVE MACRO SOURCE,DEST,COUNT
LOCAL OVERSUB
JMP OVERSUB
@MOVE: MOV A,B
ORA C
RZ ;;EXIT COUNT ZERO
MOV A,M ;;GET A BYTE
STAX D ;;STORE IT
INX H
INX D
DCX B
JMP @MOVE ;;BACK TO MOVE LOOP
OVERSUB:
MOVE MACRO SRC,?D,?C
IF NOT NUL SRC
LXI H,SRC
ENDIF
IF NOT NUL ?D
LXI D,?D
ENDIF
IF NOT NUL ?C
LXI B,?C
ENDIF
CALL @MOVE ;;CALL THE MOVE SUBROUTINE
ENDM
MOVE SOURCE,DEST,COUNT
ENDM
;
; . . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
; FILL MACRO - FILL A BLOCK OF MEMORY WITH A CONSTANT
;
; FILL START,STOP,CONSTANT
;
; CONSTANT OMITTED, FILL WITH 0
; END OMITTED, FILL ONE BYTE
;
FILL MACRO START,STOP,CONST
LOCAL @FILL,BLKLEN
BLKLEN SET STOP-START+1
LXI H,START ;;LOAD START ADDR
IF NOT NUL STOP
LXI B,BLKLEN ;;LOAD BLOCK LENGTH
IF NOT NUL CONST
MVI E,CONST ;;LOAD CONST IF NOT NULL
ELSE
MVI E,0
ENDIF
@FILL: MOV M,E ;;STORE A BYTE
INX H ;;INCR MEMORY POINTER
DCX B ;;DECR COUNT
MOV A,C ;;TEST LIMIT
ORA B
JNZ @FILL ;;CONTINUE
ELSE
IF NUL CONST
MVI M,0 ;;STORE A ZERO
ELSE
MVI M,CONST ;;STORE SINGLE BYTE
ENDIF
ENDIF
ENDM
;
; . . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
;
; MATCH MACRO COMPARE 2 STRINGS OF SAME LENGTH SET CARRY IF EQUAL
;
; MATCH STR1,'LITERAL STRING'
; MATCH STR1,STR2,LENGTH
; MATCH
;
; DE POINTS TO STR1 MACRO WILL LOAD REG IF ARG
; HL POINTS TO STR2 PRESENT
; C CONTAINS LENGTH
;
; SUBTRACT STR2 FROM STR1 AND SET FLAGS, ZERO INDICATES MATCH.
; NORMALLY THE SECOND ARG IS A LITERAL STRING AND THE LENGTH
; IS OMITTED. IF THE LEN ARG IS PRESENT THE SECOND STRING
; ARG IS ASSUMED TO BE A MEMORY ADDR. IF ALL ARGUMENTS OMITTED
; REGISTERS ASSUMED ALREADY LOADED.
;
MATCH MACRO STR1,STR2,LEN
LOCAL OVERSUB,M1
JMP OVERSUB
@MATCH: INR C ;;PRE INCREMENT COUNT (IT MIGHT BE ZERO)
M1: DCR C ;;DECR LENGTH COUNT
RZ ;;RETURN IF MATCH FOUND
LDAX D ;;GET A BYTE FROM ONE STRING
SUB M ;;COMPARE WITH OTHER
RNZ ;;RETURN
INX H
INX D ;;INCR STRING POINTERS
JMP M1 ;;TRY SOME MORE
OVERSUB:
MATCH MACRO ?STR1,?STR2,?LEN
LOCAL LITSTR,ENDLIT
IF NUL ?STR1&?STR2&?LEN
CALL @MATCH
ELSE
IF NOT NUL ?STR1
LXI D,?STR1 ;;LOAD STRING1 POINTER
ENDIF
IF NUL ?LEN ;;TEST FOR LITERAL
MVI C,ENDLIT-LITSTR ;;LENGTH OF LITERAL STRING
LXI H,LITSTR ;;POINTER TO LITERAL
CALL @MATCH
JMP ENDLIT
LITSTR: DB ?STR2 ;;LITERAL STRING
ENDLIT: ;;END OF STRING
ELSE
IF NOT NUL ?STR2
LXI H,?STR2 ;;LOAD POINTER TO STRING2
ENDIF
MVI C,?LEN ;;LOAD STRING LENGTH
CALL @MATCH ;;CALL MATCH SUBROUTINE
ENDIF
ENDIF
ENDM
MATCH STR1,STR2,LEN
ENDM
;
; . . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
; INSTR MACRO SEARCH STRING FOR SUBSTRING AND SET CARRY IF FOUND
;
; INSTR STRING,LENGTH,SUBSTR
;
; HL POINTS TO STRING
; DE POINTS TO SUBSTRING
; B CONTAINS STRING LENGTH
; C CONTAINS SUBSTRING LENGTH
;
; MACRO RETURNS POINTER TO END OF SUBSTRING IN HL
;
INSTR MACRO STRING,LENGTH,SUBSTR
LOCAL OVERSUB,S1,SSX
JMP OVERSUB
@INSTR: MOV A,B ;;STRING LENGTH
SUB C ;;SUBTRACT SUBSTR LENGTH
CMC ;;COMP CARRY
RNC ;;ERROR RETURN SUBSTR > STRING
MOV B,A ;;NEW STRING LIMIT TO B
S1: SAVE
MATCH
RESTORE
JZ SSX ;;MATCH IF ZERO ON RET
ANA A ;;RESET CARRY
DCR B ;;BYTES LEFT
RM ;;FINISHED IF MINUS, NO MATCH
INX H ;;INCR STRING POINTER
JMP S1 ;;TRY AGAIN
SSX: MVI B,0 ;;SET D TO 0
DAD B
STC ;;SET CARRY
RET
OVERSUB:
INSTR MACRO ?STR,?LEN,?SUBSTR
LOCAL LITSTR,ENDLIT
IF NOT NUL ?STR
LXI H,?STR
ENDIF
MVI B,?LEN
MVI C,ENDLIT-LITSTR
LXI D,LITSTR
CALL @INSTR
JMP ENDLIT
LITSTR: DB ?SUBSTR
ENDLIT:
ENDM
INSTR STRING,LENGTH,SUBSTR
ENDM
;
; . . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
; SCAN MACRO SCAN A STRING UNTIL A CHAR IS FOUND, SKIP BLANKS
; AND CONTROL CHARACTERS
;
; CARRY SET IF NUMERIC, CARRY OFF IF ALPHABETIC
;
;
SCAN MACRO ADDR
LOCAL OVERSUB
JMP OVERSUB
@SCAN: MOV A,M ;;GET A BYTE
CPI 21H ;;SPACE OR LESS?
RP
INX H ;;INCR POINTER
JMP @SCAN ;;KEEP SEARCHING
OVERSUB:
SCAN MACRO ?ADDR
IF NOT NUL ?ADDR
LXI H,?ADDR
ENDIF
CALL @SCAN ;;CALL SUBROUTINE
CPI 3AH ;;NUMBER OR ALPHA
ENDM
SCAN ADDR
ENDM
;
; . . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
; DISKIO MACRO EXECUTE BDOS DISK ACCESS PRIMITIVES
;
; DISKIO FUNCTION,PARAMETER
;
; NO FUNCTION ENTRY PARAM
;
; 12 LIFTHEAD
; 13 INITIAL
; 14 LOGIN DISK NO 0 - 1
; 15 OPEN FCB
; 16 CLOSE FCB
; 17 SEARCH FCB
; 18 SERNXT FCB
; 19 DELETE FCB
; 20 READ FCB
; 21 WRITE FCB
; 22 MAKE FCB
; 23 RENAME FCB
; 24 ?LOGIN
; 25 ?DRIVE
; 26 SETDMA BUFFER
; 27 ?ALLOC
; SEE CP/M INTERFACE GUIDE FOR DETAILED INFORMATION ON THE
; DISK ACCESS PRIMITIVES
;
; DISKIO READ,FCB (TYPICAL MACRO CALL)
;
DISKIO MACRO FUNCTION,PARAMETER
LIFTHEAD SET 12
INITIAL SET 13
LOGIN SET 14
OPEN SET 15
CLOSE SET 16
SEARCH SET 17
SERNXT SET 18
DELETE SET 19
READ SET 20
WRITE SET 21
MAKE SET 22
RENAME SET 23
?LOGIN SET 24
?DRIVE SET 25
SETDMA SET 26
?ALLOC SET 27
;
?C SET FUNCTION
IF NOT NUL PARAMETER
LXI D,PARAMETER
ENDIF
MVI C,?C
CALL BDOS ;;BDOS ENTRY
ENDM
;
; . . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
; CALLBIOS MACRO CALL BIOS ROUTINES DIRECTLY
;
; CALLBIOS FUNCTION,PARAM
;
CALLBIOS MACRO FUNCT,PARAM
LOCAL @CALL
;
DCOLD SET 00H
DWBOOT SET 03H
DSTAT SET 06H
DCONIN SET 09H
DCONOUT SET 0CH ;;CHAR IN C
DLIST SET 0FH ;;CHAR IN C
DPUNCH SET 12H
DREADER SET 15H
DHOME SET 18H
DSELDSK SET 1BH
DSETTRK SET 1EH
DSETSEC SET 21H ;;SECTOR NO IN C
DSETDMA SET 24H ;;DMA ADDR IN BC
DREAD SET 27H
DWRITE SET 2AH
;
?F SET FUNCT
IF NOT NUL PARAM
MVI C,PARAM
ENDIF
LHLD BOOT+1 ;;ADDR OF BIOS
MVI L,?F ;;JUMP OFFSET
SHLD @CALL+1 ;;MODIFY CALL ADDR
@CALL: CALL 0
ENDM
;
; . . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
; DLOAD MACRO DOUBLE PRECISION INDEXED LOAD HL
;
; LOAD (ADDR + INDX) TO HL
;
DLOAD MACRO ADDR,INDX
IF NUL INDX
LHLD ADDR
ELSE
LHLD INDX
LXI D,ADDR
DAD D
MOV E,M
INX H
MOV D,M
XCHG
ENDIF
ENDM
; . . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
; CPHL MACRO SUBTRACT DE FROM HL AND SET FLAGS
;
CPHL MACRO
LOCAL @END
MOV A,H
CMP D ;;COMPARE HIGH BYTES
JNZ @END
MOV A,L
CMP E ;;COMPARE LOW BYTES
@END: ENDM
;
; . . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
; DJZ MACRO DOUBLE PRECISION TEST HL AND JUMP ON ZERO
;
DJZ MACRO ADDR
MOV A,H
ORA L
JZ ADDR
ENDM
; . . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
; DSTORE MACRO DOUBLE PRECISION INDEXED STORE HL
;
; STORE (HL) IN (ADDR + INDX)
;
DSTORE MACRO ADDR,INDX
IF NUL INDX
SHLD ADDR
ELSE
SAVE H
LHLD INDX
XCHG
LXI H,ADDR
DAD D
RESTORE D
MOV M,E
INX H
MOV M,D
ENDIF
ENDM
;
; . . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
; INDEX MACRO INDEX AN ADDRESS POINTER BY A CONSTANT
;
; INDEX POINTER,INCR
;
INDEX MACRO POINTER,INCR
LHLD POINTER
LXI D,INCR
DAD D ;;DOUBLE ADD
SHLD POINTER
ENDM
;
; . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
; FILFCB MACRO FILL IN THE ID FIELDS OF FCB
;
; FILFCB FCB,IDSTRING
;
; IDSTRING CONTAINS FILE NAME AND TYPE (FILNAM.TYP)
; CARRY SET IF ERROR (NAME TOO LONG)
;
FILFCB MACRO FCB,IDSTRING
LOCAL OVERSUB,F1,F2,F3,F4,F5,F6
JMP OVERSUB
@FLFCB: MVI M,0 ;;CLEAR FIRST BYTE OF FCB
INX H
PUSH H ;;SAVE POINTER TO NAME
MVI C,11 ;;SIZE OF ID FIELD
MVI A,' ' ;;SPACE TO A
F1: MOV M,A ;;FILL NAME WITH SPACES
INX H
DCR C
JNZ F1
POP H ;;RESTORE NAME POINTER
MVI C,8 ;;MAXIMUM SIZE OF NAME
F2: LDAX D ;;GET BYTE FROM ID FIELD
CPI ' ' ;;LEADING SPACES?
JNZ F3
INX D ;;SKIP LEADING SPACES
JMP F2
F3: LDAX D ;;GET ID BYTE
CPI 0 ;;ZERO END OF FIELD
RZ
CPI ' ' ;;SPACE END OF FIELD
RZ
CPI '.' ;;PERIOD TYPE SEPARATOR
JZ F4 ;;DO TYPE
MOV M,A ;;STORE NAME BYTE
INX H
INX D ;;INCR POINTERS
DCR C ;;DECR MAXIMUM COUNT
JP F3 ;;LOOP BACK
STC ;;SET CARRY NAME TOO LARGE
RET
F4: INX D ;;SKIP THE PERIOD
MOV A,C
ORA A
JZ F6 ;;TEST C FOR ZERO
F5: INX H
DCR C
JNZ F5 ;;INDEX TO TYPE FIELD
F6: MVI C,3 ;;SIZE OF TYPE FIELD
F7: LDAX D ;;GET ID BYTE
CPI 0 ;;ZERO?
RZ ;;FINISHED
CPI ' ' ;;SPACE?
RZ
MOV M,A ;;STORE TYPE BYTE
INX H
INX D ;INCR POINTERS
DCR C ;;DECR MAX COUNT
JNZ F7 ;;LOOP BACK
RET
OVERSUB:
FILFCB MACRO ?FCB,?ID
IF NOT NUL ?ID
LXI D,?ID
ENDIF
IF NOT NUL ?FCB
LXI H,?FCB
ENDIF
CALL @FLFCB
XCHG
ENDM
FILFCB FCB,IDSTRING
ENDM
;
; . . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
; SETTRK MACRO SET AND TEST TRACK NUMBER
;
; CARRY SET IF > 76
;
SETTRK MACRO TRKNO
LOCAL ENDTRK
IF NOT NUL TRKNO
LDA TRKNO
ENDIF
CPI 77
CMC
JC ENDTRK
MOV C,A ;;TRACK NO TO C
CALLBIOS DSETTRK
ENDTRK: ENDM
;
; . . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
; SETSEC MACRO SET AND TEST SECTOR NUMBER
;
; RETURN WITH CARRY SET < 1 OR > 26
;
SETSEC MACRO SECNO
LOCAL ENDSEC
IF NOT NUL SECNO
LDA SECNO
ENDIF
ORA A ;CHECK ZERO
STC
JZ ENDSEC
CPI 27 ;CHECK > 26
CMC
JC ENDSEC
MOV C,A ;MOVE TO C
CALLBIOS DSETSEC
ENDSEC: ENDM
; . . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
; HALF MACRO DIVIDES A 16 BIT NUMBER BY 2
;
HALF MACRO I
LOCAL OVER
JMP OVER
@HALF: XRA A ;;CLEAR CARRY
MOV A,H
RAR ;;SHIFT UPPER HALF
MOV H,A
MOV A,L
RAR ;;SHIFT LOWER HALF
MOV L,A
RET
OVER:
HALF MACRO ?I
IF NOT NUL ?I
LHLD ?I
ENDIF
CALL @HALF
ENDM
HALF I
ENDM
; . . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
;
;AMATCH MACRO COMPARE 2 STRINGS OF SAME LENGTH SET CARRY IF EQUAL
; AMBIGUOUS MATCH THAT IS '?' MATCHES ANYTHING
;
; MATCH STR1,'LITERAL STRING'
; MATCH STR1,STR2,LENGTH
; MATCH
;
; DE POINTS TO STR1 MACRO WILL LOAD REG IF ARG
; HL POINTS TO STR2 PRESENT
; C CONTAINS LENGTH
;
; SUBTRACT STR2 FROM STR1 AND SET FLAGS, ZERO INDICATES MATCH.
; NORMALLY THE SECOND ARG IS A LITERAL STRING AND THE LENGTH
; IS OMITTED. IF THE LEN ARG IS PRESENT THE SECOND STRING
; ARG IS ASSUMED TO BE A MEMORY ADDR. IF ALL ARGUMENTS OMITTED
; REGISTERS ASSUMED ALREADY LOADED.
;
AMATCH MACRO STR1,STR2,LEN
LOCAL OVERSUB,M1,M2
JMP OVERSUB
@AMATCH:
INR C ;;PRE INCREMENT COUNT (IT MIGHT BE ZERO)
M1: DCR C ;;DECR LENGTH COUNT
RZ ;;RETURN IF MATCH FOUND
MOV A,M
CPI '?'
JZ M2
LDAX D ;;GET A BYTE FROM ONE STRING
CPI '?'
JZ M2
SUB M ;;COMPARE WITH OTHER
RNZ ;;RETURN
M2: INX H
INX D ;;INCR STRING POINTERS
JMP M1 ;;TRY SOME MORE
OVERSUB:
AMATCH MACRO ?STR1,?STR2,?LEN
LOCAL LITSTR,ENDLIT
IF NUL ?STR1&?STR2&?LEN
CALL @AMATCH
ELSE
IF NOT NUL ?STR1
LXI D,?STR1 ;;LOAD STRING1 POINTER
ENDIF
IF NUL ?LEN ;;TEST FOR LITERAL
MVI C,ENDLIT-LITSTR ;;LENGTH OF LITERAL STRING
LXI H,LITSTR ;;POINTER TO LITERAL
CALL @AMATCH
JMP ENDLIT
LITSTR: DB ?STR2 ;;LITERAL STRING
ENDLIT: ;;END OF STRING
ELSE
IF NOT NUL ?STR2
LXI H,?STR2 ;;LOAD POINTER TO STRING2
ENDIF
MVI C,?LEN ;;LOAD STRING LENGTH
CALL @AMATCH ;;CALL MATCH SUBROUTINE
ENDIF
ENDIF
ENDM
AMATCH STR1,STR2,LEN
ENDM
;