; -- NEW MACRO LIBRARY -- ; ; BY S. J. SINGER ; REVISION - FEB 1981 ; ; ; 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 ; ; ; . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; ; SAV MACRO SAVE REGISTERS B,D AND H ; SAV MACRO PUSH B PUSH D PUSH H ENDM ; ; ; . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; ; ; RES MACRO RESTORE REGISTERS H,D, AND B (INVERSE OF SAV) ; RES MACRO POP H POP D POP B 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: PUSH PSW RRC RRC RRC RRC ;;SHIFT RIGHT 4 CALL OUTCHR POP 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 NON HEX DIGIT OTHER THAN SPACE OR ZERO. ; CONVERSION STOPS ON SPACE OR ZERO. ; HEXIN MACRO ADDR LOCAL IN1,IN2,OVERSUB JMP OVERSUB @HEXIN LXI H,0 ;;ZERO NUMBER IN1: LDAX D ;;GET A CHAR ORA A RZ ;;RETURN IF ZERO IN FIELD CPI 20H ;;SPACE WORKS TOO RZ SUI '0' ;;CHECK < 0 AND CONVERT TO HEX RC ;;RETURN, CHAR < 0 FOUND 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: PUSH B ;PUSH STACK PUSH D PUSH H 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 POP H ;;POP STACK POP D POP B RET ENDDEC: DECOUT MACRO ?ADDR IF NOT NUL ?ADDR LHLD ?ADDR ENDIF CALL @DECOUT ;;CALL THE SUBROUTINE ENDM DECOUT ADDR ENDM ; ; . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; ; DECOUTLOC CONVERT A POSITIVE INTEGER TO DECIMAL AND OUTPUT ; TO THE CONSOLE. ; ; DECOUTLOC ADDR (THIS MAC CALLS LOCAL "CONOUT" FOR OUTPUT) ; ; IF ADDR OMITTED, NUMBER ASSUMED TO BE IN HL, ELSE LOADED TO HL ; LEADING ZEROS SUPRESSED. MAXIMUM NUMBER 65,767 ; DECOUTLOC MACRO ADDR LOCAL ENDDEC1,DX1 JMP ENDDEC1 @DECOUT1: PUSH B ;PUSH STACK PUSH D PUSH H LXI B,-10 ;;RADIX FOR CONVERSION LXI D,-1 ;;THIS BECOMES NO DIVIDED BY RADIX DX1: DAD B ;;SUBTRACT 10 INX D JC DX1 LXI B,10 DAD B ;;ADD RADIX BACK IN ONCE XCHG MOV A,H ORA L ;;TEST FOR ZERO CNZ @DECOUT1 ;;RECURSIVE CALL MOV A,E ADI '0' ;;CONVERT FROM BCD TO HEX MOV C,A ;;TO E FOR OUTPUT CALL CONOUT POP H ;;POP STACK POP D POP B RET ENDDEC1: DECOUT1 MACRO ?ADDR IF NOT NUL ?ADDR LHLD ?ADDR ENDIF CALL @DECOUT1 ;;CALL THE SUBROUTINE ENDM DECOUT1 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: PUSH B PUSH D PUSH H MATCH POP H POP D POP B 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 NUL ?STR&?LEN&?SUBSTR CALL @INSTR ELSE 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: ENDIF ENDM INSTR STRING,LENGTH,SUBSTR ENDM ; ; . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; ; SCAN MACRO SCAN A STRING UNTIL A CHAR IS FOUND, SKIP BLANKS ; AND CONTROL CHARACTERS ; ; ZERO SET IF NO DATA FOUND IN SPECIFIED FIELD ; ; SCAN MACRO ADDR,LENGTH LOCAL OVERSUB JMP OVERSUB @SCAN: MOV A,M ;;GET A BYTE CPI 21H ;;SPACE OR LESS? RP INX H ;;INCR POINTER DCR C ;;DECR SCAN COUNT RZ ;;RETURN IF COUNT ZERO JMP @SCAN ;;KEEP SEARCHING OVERSUB: SCAN MACRO ?ADDR,?LEN IF NOT NUL ?ADDR LXI H,?ADDR ENDIF IF NOT NUL ?LEN MVI C,?LEN ELSE MVI C,127 ;;DEFAULT SCAN LENGTH 127 BYTES ENDIF CALL @SCAN ;;CALL SUBROUTINE ENDM SCAN ADDR ENDM ; ; ; . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; ; UPPER MACRO SCAN A STRING CONVERTING ALL LOWER CASE CHAR TO UPPER ; CASE (Only a - z are converted) ; ; ; UPPER MACRO ADDR,LENGTH LOCAL OVERSUB JMP OVERSUB @UPPER: MOV A,M ;;GET A BYTE CPI 03H ;;Control C JZ UU2 ;;Exit with Carry Set CPI 61H ;;LOWER CASE A JM UU1 ;;LESS THAN A CPI 7BH ;;LOWER CASE Z + 1 JP UU1 ;;MORE THAN Z XRI 20H ;;MASK OFF LOWER CASE BIT MOV M,A ;;STORE THE BYTE BACK UU1: INX H ;;INCR POINTER XRA A ;;CLEAR CARRY BIT DCR C ;;DECR SCAN COUNT RZ ;;RETURN IF COUNT ZERO JMP @UPPER ;;KEEP SEARCHING UU2: STC ;;Set Carry RET OVERSUB: UPPER MACRO ?ADDR,?LEN IF NOT NUL ?ADDR LXI H,?ADDR ENDIF IF NOT NUL ?LEN MVI C,?LEN ELSE MVI C,127 ;;DEFAULT SCAN LENGTH 127 BYTES ENDIF CALL @UPPER ;;CALL SUBROUTINE ENDM UPPER 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 PUSH H LHLD INDX XCHG LXI H,ADDR DAD D POP D MOV M,E INX H MOV M,D ENDIF ENDM ; ; . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; ; INDEX MACRO INDEX AN ADDRESS POINTER BY A CONSTANT ; MOD MODULUS ; ; INDEX POINTER,INCR,MODULUS ; INDEX MACRO POINTER,INCR,MOD LOCAL IND1 LHLD POINTER LXI D,INCR DAD D ;;DOUBLE ADD IF NUL MOD SHLD POINTER ELSE PUSH H LXI D,-MOD DAD D ;;SUBTRACT MODULUS JNC IND1 POP H ;;GET BACK NO IND1: SHLD POINTER ENDIF 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 ; ; ; SETTRK MACRO TRKNO LOCAL ENDTRK LDA TRKNO MOV C,A LDA TRKNO+1 MOV B,A CALLBIOS DSETTRK ENDTRK: ENDM ; ; . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; ; SETSEC MACRO SET AND TEST SECTOR NUMBER ; ; RETURN WITH CARRY SET < 1 OR > 128 ; SETSEC MACRO SECNO LOCAL ENDSEC IF NOT NUL SECNO LDA SECNO ENDIF ORA A ;CHECK ZERO STC JZ ENDSEC CPI 128 ;CHECK > 127 CMC JC ENDSEC MVI B,0 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