; -- 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,<,,,> 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,<,,,> 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 5 ;;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 5 ;;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 5 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 5 ;;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 5 ELSE IF NUL LEN&TC JMP @OVER @MESS: DB ?STRING DB '$' @OVER: LXI D,@MESS MVI C,9 CALL 5 ;;BDOS ENTRY ELSE IF NUL TC IF NOT NUL ?STRING LXI D,?STRING ;;POINTER TO STRING ENDIF MVI C,9 CALL 5 ;;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 5 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 5 ;;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 IF BLKLEN > 255 LXI B,BLKLEN ;;LOAD BLOCK LENGTH ELSE MVI C,BLKLEN ENDIF 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 IF BLKLEN > 255 DCX B ;;DECR COUNT MOV A,C ;;TEST LIMIT ORA B JNZ @FILL ;;CONTINUE ELSE DCR C JNZ @FILL ENDIF 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 5 ;;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 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 35 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 > 18 ; SETSEC MACRO SECNO LOCAL ENDSEC IF NOT NUL SECNO LDA SECNO ENDIF ORA A ;CHECK ZERO STC JZ ENDSEC CPI 19 ;SECTOR >18 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