@PSMA2HC Z80SMADC Z806SMAFDC Z80' ASMFN1 Z802'SMFN2 Z807.SMFN3 Z80=*SMHL4HC Z80ESMHL5DC Z80ISMHLFDC Z80\SMOVE Z80lYSMTH01 Z80eSMTH02 Z80LPSMTH03 Z80SMTH04 Z80YSMTH05 Z80SMTH06 Z80SMTH07 Z80λSMTH08 Z806SMTH09 Z80SMTH10 Z80&SMTH11 Z80 _SMTH12 Z80 SPA2HC Z80SPADC Z80 SPAFDC Z80 |SPAUSE Z80SPFN1 Z80SPFN2 Z80 %SPFN3 Z80qHSPHL4HC Z80BSPHL5DC Z80 SPHLFDC Z80 DSPOUT Z80SPRINT Z80$]SPSTR Z80(SRAND Z806 e~SRIN Z80BjhSRREAD Z80H uSRWRITE Z80Q [;SSA2HC Z80ZpSSADC Z80` ]SSAFDC Z80k 0SSCANNERZ80t SSCFA Z80_SSCOUT Z80hSSCRLF Z80sSSCTLFL Z80$SSDMA Z80ucSSFA Z80SSFN1 Z808SSFN2 Z80| SSFN3 Z80SSHL4HC Z80SSHL5DC Z80 nSSHLFDC Z80 YSSKPUN Z80SSKSP Z80USSORT Z80qFSSOUT Z80`vSSPRINT Z80eSSPSTR Z80iSSUA Z80wvXSUD1 Z80|:SUD2 Z80HSUD3 Z80`SVERSIONZ80, ; ; SYSLIB Module Name: SMA2HC ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.1 public ma2hc ; ; MA2HC -- ; STORE REG A AS 2 HEXADECIMAL CHARACTERS IN MEMORY PTED TO BY DE; ; ON INPUT, A=VALUE AND HL=PTR TO 2-BYTE BUFFER ; ON RETURN, DE PTS TO NEXT BYTE AFTER BUFFER ; EXT EN MA2HC: EX DE,HL ; PTR IN HL INSTEAD PUSH AF ; SAVE A PUSH AF CALL EN ; EXCHANGE NYBBLES CALL PAHC ; PRINT LOW-ORDER NYBBLE AS HEX POP AF ; GET A CALL PAHC ; PRINT LOW-ORDER NYBBLE AS HEX POP AF ; RESTORE A EX DE,HL ; POINTER BACK IN DE RET PAHC: AND 0FH ; MASK FOR LOW NYBBLE CP 10 ; LETTER OR DIGIT? JP C,PADIG ; DIGIT IF CARRY ADD 'A'-10 ; CONVERT TO 'A'-'F' JP PUT ; PUT IN MEMORY PADIG: ADD '0' ; CONVERT TO '0'-'9' PUT: LD (HL),A ; CHAR IN MEMORY INC HL ; PT TO NEXT LOCATION RET END ; ; SYSLIB Module Name: SMADC ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.1 public ma3dc,madc ; ; MA3DC -- ; STORE REG A AS 3 DECIMAL CHARACTERS IN MEMORY ; ON INPUT, A=VALUE AND DE=PTR TO 3-BYTE BUFFER ; ON RETURN, DE PTS TO BYTE AFTER BUFFER ; MA3DC: EX DE,HL ; PTR IN HL PUSH AF ; SAVE A PUSH AF XOR A ; TURN OFF LEADING FLAG LD (LSFLG),A JP PADC1 ; ; MADC -- ; STORE REG A AS DECIMAL CHARACTERS W/LEADING IN 3-CHAR FIELD ; IN MEMORY; ON INPUT, A=VALUE AND HL=PTR TO 3-BYTE BUFFER ; ON RETURN, HL PTS TO BYTE AFTER BUFFER ; MADC: EX DE,HL ; PTR IN HL PUSH AF ; SAVE A PUSH AF LD A,1 ; TURN ON LEADING FLAG LD (LSFLG),A ; ; PRINT ROUTINE ; PADC1: POP AF ; GET A PUSH BC ; SAVE BC LD B,100 ; PRINT HUNDREDS CALL PAC ; PRINT A CHAR LD B,10 ; PRINT TENS CALL PAC ADD '0' ; CONVERT TO ASCII CALL PUT ; PRINT POP BC ; RESTORE BC POP AF ; RESTORE A EX DE,HL ; PTR BACK IN DE RET ; BUFFER LSFLG: DS 1 ; LEADING FLAG ; PRINT RESULT OF DIVISION OF A BY B W/LEADING (INTEGER DIVISION) PAC: LD C,0 ; SET COUNT PACL: SUB B ; COMPUTE COUNT JP C,PACD INC C ; INCR COUNT JP PACL PACD: ADD A,B ; ADD B BACK IN PUSH AF ; SAVE A LD A,C ; GET COUNT OR A ; ZERO? JP NZ,PACD1 LD A,(LSFLG) ; CHECK FOR LEADING OR A ; 0 MEANS NO JP Z,PACD1 LD A,' ' ; PRINT CALL PUT POP AF ; RESTORE A RET PACD1: XOR A ; A=0 LD (LSFLG),A ; TURN OFF LEADING FLAG LD A,C ; GET COUNT ADD '0' ; CONVERT TO DECIMAL CALL PUT ; PRINT IT POP AF ; RESTORE A RET PUT: LD (HL),A ; PUT BYTE INC HL ; PT TO NEXT RET END ; ; SYSLIB Module Name: SMAFDC ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.1 public mafdc ; ; MAFDC -- ; STORE REG A AS DECIMAL CHARACTERS IN 1-TO-3 CHAR FIELD ; IN MEMORY; ON INPUT, A=VALUE AND DE=PTR TO 3-BYTE BUFFER ; ON RETURN, DE PTS TO BYTE AFTER LAST CHAR STORED ; MAFDC: PUSH AF ; SAVE REGS PUSH BC PUSH HL EX DE,HL ; PTR IN HL LD D,1 ; TURN ON LEADING FLAG ; ; PRINT ROUTINE ; PADC1: LD B,100 ; PRINT HUNDREDS CALL PAC ; PRINT A CHAR LD B,10 ; PRINT TENS CALL PAC ADD '0' ; CONVERT TO ASCII CALL PUT ; PRINT EX DE,HL ; PTR BACK IN DE POP HL ; RESTORE REGS POP BC POP AF RET ; ; PRINT RESULT OF DIVISION OF A BY B (INTEGER DIVISION) ; PAC: LD C,0 ; SET COUNT PACL: SUB B ; COMPUTE COUNT JP C,PACD INC C ; INCR COUNT JP PACL PACD: ADD A,B ; ADD B BACK IN LD E,A ; SAVE A LD A,C ; GET COUNT OR A ; ZERO? JP NZ,PACD1 OR D ; CHECK FOR LEADING (A=0, A OR D = 0 MEANS D=0) LD A,E ; RESTORE A FOR POSSIBLE RETURN RET NZ ; RETURN IF LEADING PACD1: LD D,0 ; D=0 FOR NO LEADING LD A,C ; GET COUNT ADD '0' ; CONVERT TO DECIMAL CALL PUT ; PRINT IT LD A,E ; RESTORE A RET ; ; PUT BYTE IN A IN MEMORY AT ADDRESS PTED TO BY HL; ADVANCE HL ; PUT: LD (HL),A ; PUT BYTE INC HL ; PT TO NEXT RET END ; ; SYSLIB Module Name: SMFN1 ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.1 public mfn1 ; ; Print FCB file name and type pted to by DE to memory pted to by HL ; Format of Output: xxxxxxxx.xxx ; mfn1: push hl ; save regs push de push bc push af ld b,8 ; 8 chars first call prfnx ld (hl),'.' inc hl ld b,3 ; 3 more chars call prfnx pop af ; restore regs pop bc pop de pop hl ret prfnx: ld a,(de) ; get char and 7fh ; mask out msb ld (hl),a ; put char inc hl ; pt to next inc de dec b ; count down jp nz,prfnx ret end ; ; SYSLIB Module Name: SMFN2 ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.1 public mfn2 ; ; Print FCB file name and type pted to by DE to memory pted to by HL ; Format of Output: xxxxxxxx.yyy (0-8 x's, 0-3 y's) ; mfn2: push hl ; save regs push de push bc push af ld b,8 ; 8 chars first call prfnx ld (hl),'.' inc hl ld b,3 ; 3 more chars call prfnx pop af ; restore regs pop bc pop de pop hl ret prfnx: ld a,(de) ; get char and 7fh ; mask out msb cp ' ' ; skip spaces jp z,prfnx1 ld (hl),a ; put char inc hl ; pt to next prfnx1: inc de dec b ; count down jp nz,prfnx ret end ; ; SYSLIB Module Name: SMFN3 ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.1 public mfn3 ; ; Print FCB file name and type pted to by DE to memory pted to by HL ; Format of Output: xxxxxxxx.yyy (0-8 x's, 0-3 y's, req'd spaces) ; mfn3: push hl ; save regs push de push bc push af ld c,11 ; 11 chars total ld b,8 ; 8 chars first call prfnx ld (hl),'.' inc hl ld b,3 ; 3 more chars call prfnx ld a,c ; get count of spaces or a ; 0=none call nz,spacer pop af ; restore regs pop bc pop de pop hl ret prfnx: ld a,(de) ; get char and 7fh ; mask out msb cp ' ' ; skip space call nz,prout ; print it inc de ; pt to next dec b ; count down jp nz,prfnx ret prout: ld (hl),a ; store char inc hl ; pt to next dec c ; count chars ret spacer: ld (hl),' ' ; space over inc hl dec c ; count down jp nz,spacer ret end ; ; SYSLIB Module Name: SMHL4HC ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.1 public mhl4hc ; ; MHL4HC -- Store HL as 4 Hex Characters in memory; on input, DE pts ; to 4-byte buffer and HL=value; on return, DE pts to byte after buffer ; No Registers are to be affected. ; EXT MA2HC ; STORE A AS 2 HEX CHARACTERS MHL4HC: PUSH AF ; SAVE A LD A,H ; PRINT H CALL MA2HC LD A,L ; PRINT L CALL MA2HC POP AF ; RESTORE A RET END ; ; SYSLIB Module Name: SMHL5DC ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.1 public mhl5dc,mhldc PUTRG MACRO PUSH BC ; SAVE BC, DE, HL PUSH DE PUSH HL ENDM GETRG MACRO POP HL ; RESTORE HL, DE, BC POP DE POP BC ENDM ; ; MHL5DC -- ; STORE HL AS 5 DECIMAL CHARACTERS IN MEMORY ; ON INPUT, HL=VALUE AND DE=PTR TO 5-BYTE BUFFER ; ON OUTPUT, DE PTS TO NEXT BYTE AFTER BUFFER ; MHL5DC: PUSH AF ; SAVE ALL REGS EX DE,HL ; HL PTS TO BUFFER LD (MEMPTR),HL EX DE,HL PUTRG XOR A ; A=0 LD (LSFLG0),A ; TURN OFF LEADING JP PHDC ; ; MHLDC -- ; STORE HL AS DECIMAL CHARACTERS W/LEADING SPACES IN 5-CHAR FIELD ; IN MEMORY; ON INPUT, HL=VALUE AND DE=PTR TO 5-BYTE BUFFER ; ON RETURN, DE PTS TO BYTE AFTER BUFFER ; MHLDC: PUSH AF ; SAVE ALL REGS EX DE,HL ; HL PTS TO BUFFER LD (MEMPTR),HL EX DE,HL PUTRG LD A,1 ; A=1 LD (LSFLG0),A ; TURN ON LEADING ; ; PRINT HL USING LEADING FLAG LSFLG0 ; PHDC: LD DE,10000 ; PRINT 10000'S CALL PHDC1 LD DE,1000 ; PRINT 1000'S CALL PHDC1 LD DE,100 ; PRINT 100'S CALL PHDC1 LD DE,10 ; PRINT 10'S CALL PHDC1 LD A,L ; PRINT 1'S ADD '0' ; CONVERT TO ASCII CALL PUT GETRG ; RESTORE ALL REGS EX DE,HL ; DE=VALUE LD HL,(MEMPTR) ; GET PTR TO NEXT BYTE EX DE,HL ; ... IN DE POP AF RET ; BUFFERS LSFLG0: DS 1 ; LEADING FLAG MEMPTR: DS 2 ; PTR TO NEXT MEMORY ADDRESS ; DIVIDE HL BY DE AND PRINT QUOTIENT WITH LEADING S PHDC1: LD C,0 ; SET COUNT PHDC2: LD A,L ; SUB E FROM L SUB E LD L,A ; RESULT IN L LD A,H ; SUB D FROM H W/BORROW SBC A,D LD H,A ; RESULT IN H JP C,PHDC3 ; DONE IF CARRY SET (FURTHER BORROW) INC C ; INCR COUNT JP PHDC2 PHDC3: LD A,L ; ADD E TO L ADD A,E LD L,A ; RESULT IN L LD A,H ; ADD D TO H W/CARRY ADC A,D LD H,A ; RESULT IN H LD A,C ; GET RESULT OR A ; CHECK FOR ZERO JP NZ,PHDC4 LD A,(LSFLG0) ; CHECK FOR LEADING OR A ; PRINT VALUE IF NOT (A=0) JP Z,PHDC4 LD A,' ' ; PRINT JP PUT PHDC4: XOR A ; TURN OFF LEADING LD (LSFLG0),A LD A,C ; GET VALUE ADD '0' ; CONVERT TO ASCII PUT: PUSH HL ; SAVE HL LD HL,(MEMPTR) ; GET PTR LD (HL),A ; PUT BYTE INC HL ; PT TO NEXT LD (MEMPTR),HL ; PUT PTR POP HL ; RESTORE HL RET END ; ; SYSLIB Module Name: SMHLFDC ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.1 public mhlfdc ; ; MACROS ; PUTRG MACRO PUSH BC ; SAVE BC, DE, HL PUSH DE PUSH HL ENDM GETRG MACRO POP HL ; RESTORE HL, DE, BC POP DE POP BC ENDM ; ; MHLFDC -- ; STORE HL AS UP TO 5 DECIMAL CHARACTERS IN MEMORY ; ON INPUT, HL=VALUE AND DE=PTR TO 5-BYTE BUFFER ; ON OUTPUT, DE PTS TO NEXT BYTE AFTER LAST BYTE STORED ; MHLFDC: PUSH AF ; SAVE ALL REGS PUTRG EX DE,HL ; HL PTS TO BUFFER LD (MEMPTR),HL EX DE,HL LD B,1 ; B=1 FOR LEADING FLAG ; ; PRINT HL USING LEADING FLAG IN B ; PHDC: LD DE,10000 ; PRINT 10000'S CALL PHDC1 LD DE,1000 ; PRINT 1000'S CALL PHDC1 LD DE,100 ; PRINT 100'S CALL PHDC1 LD DE,10 ; PRINT 10'S CALL PHDC1 LD A,L ; PRINT 1'S ADD '0' ; CONVERT TO ASCII CALL PUT GETRG ; RESTORE ALL REGS EX DE,HL ; DE=VALUE LD HL,(MEMPTR) ; GET PTR TO NEXT BYTE EX DE,HL ; ... IN DE POP AF RET ; ; DIVIDE HL BY DE AND PRINT QUOTIENT WITH LEADING S ; PHDC1: LD C,0 ; SET COUNT PHDC2: LD A,L ; SUB E FROM L SUB E LD L,A ; RESULT IN L LD A,H ; SUB D FROM H W/BORROW SBC A,D LD H,A ; RESULT IN H JP C,PHDC3 ; DONE IF CARRY SET (FURTHER BORROW) INC C ; INCR COUNT JP PHDC2 PHDC3: LD A,L ; ADD E TO L ADD A,E LD L,A ; RESULT IN L LD A,H ; ADD D TO H W/CARRY ADC A,D LD H,A ; RESULT IN H LD A,C ; GET RESULT OR A ; CHECK FOR ZERO JP NZ,PHDC4 OR B ; CHECK FOR LEADING (A=0, A OR B = 0 IF B=0) RET NZ ; DONE IF NO LEADING PHDC4: LD B,0 ; TURN OFF LEADING LD A,C ; GET VALUE ADD '0' ; CONVERT TO ASCII AND FALL THRU TO PUT ; ; PUT BYTE IN A INTO NEXT MEMORY POSITION AND ADVANCE MEMORY PTR ; PUT: PUSH HL ; SAVE HL LD HL,(MEMPTR) ; GET PTR LD (HL),A ; PUT BYTE INC HL ; PT TO NEXT LD (MEMPTR),HL ; PUT PTR POP HL ; RESTORE HL RET ; ; BUFFERS ; MEMPTR: DS 2 ; PTR TO NEXT MEMORY ADDRESS END ; ; SYSLIB Module Name: SMOVE ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.1 public hmovb,hmovbc,moveb,movebc ; ; SMOVEB.MAC -- SYSLIB MODULE ; ; ENTRY POINTS -- ; EXT MOVEB -- MOVE BYTES PTED TO BY HL TO ; LOCATION PTED TO BY DE FOR B BYTES ; EXT MOVEBC -- MOVE BYTES PTED TO BY HL TO ; LOCATION PTED TO BY DE FOR BC BYTES ; ; NO REGISTERS ARE TO BE AFFECTED ; ; EXT HMOVB -- LIKE MOVEB, BUT HL AND DE PT TO BYTE AFTER ; LAST BYTE MOVED WHEN DONE ; EXT HMOVBC -- LIKE MOVEBC, BUT HL AND DE PT TO BYTE AFTER ; LAST BYTE MOVED WHEN DONE ; ; ; SUPPORTING MACROS -- ; PUTRG MACRO ; SAVE ALL REGS PUSH AF PUSH BC PUSH DE PUSH HL ENDM GETRG MACRO ; RESTORE ALL REGS POP HL POP DE POP BC POP AF ENDM ; ; HMOVB AND HMOVBC ROUTINES -- ; HMOVB: CALL MOVEB ; DO THE MOVE PUSH BC ; SAVE BC LD C,B ; BC=B LD B,0 ADD HL,BC ; HL PTS TO BYTE AFTER LAST BYTE MOVED EX DE,HL ADD HL,BC ; DE PTS TO BYTE AFTER LAST BYTE MOVED EX DE,HL POP BC ; GET BC RET HMOVBC: CALL MOVEBC ; DO THE MOVE PUSH BC ; SAVE BC ADD HL,BC ; HL PTS TO BYTE AFTER LAST BYTE MOVED EX DE,HL ADD HL,BC ; DE PTS TO BYTE AFTER LAST BYTE MOVED EX DE,HL POP BC ; GET BC RET ; ; MOVEB AND MOVEBC ROUTINES -- ; MOVEB: PUSH BC ; SAVE BC LD C,B ; C=B LD B,0 ; B=0 CALL MOVEBC ; USE MOVEBC POP BC ; RESTORE BC RET MOVEBC: PUTRG ; SAVE ALL REGS ; ; DETERMINE IF HL < DE; IF SO, MOVE BACK TO FRONT; OTHERWISE, FRONT TO BACK ; LD A,H ; HLDE LD A,L ; HL DE ; LD A,H CP D ; H > D? JP C,DOVFL ; ZERO RESULT IF H < D JP NZ,DNOVFL LD A,L CP E ; L > E? JP C,DOVFL ; ZERO RESULT IF HL < DE DNOVFL: LD B,16 ; 16 LOOPS DVHD: CALL SHFTLH ; SHIFT DIVIDEND LEFT PUSH HL ; SAVE DIVIDEND LD HL,(ACC) ; GET ACC CALL SHFLCH ; ROTATE ACC AND MOVE IN CARRY LD (ACC),HL ; NEW ACC LD A,L ; LOW COMPARISON SUB E ; COMPARE AND SUBTRACT LD L,A LD A,H ; HIGH COMPARISON SBC A,D ; COMPARE AND SUBTRACT LD H,A JP C,DVHD0 LD (ACC),HL ; SAVE NEW ACC POP HL ; GET DIVIDEND LD A,L ; PLACE IN A 1 TO QUOTIENT OR 1 LD L,A JP DVHD1 DVHD0: POP HL ; GET DIVIDEND AND LEAVE LSB AT ZERO DVHD1: DEC B ; COUNT DOWN JP NZ,DVHD DVRET: POP BC POP AF RET DOVFL: LD HL,0 ; RESULT IS ZERO JP DVRET ; ; SHIFT ROUTINES ; SHFTLH: ; SHIFT HL LEFT PUSH AF AND A ; CLEAR CARRY SHFL: LD A,L ; SHIFT LOW RLA ; ROTATE 9-BIT ACC LEFT LD L,A LD A,H ; SHIFT HIGH RLA LD H,A JP NC,OKRET POP AF SCF ; SET CARRY FOR OVERFLOW RET OKRET: POP AF OR A ; CLEAR CARRY FOR NO OVERFLOW RET SHFLCH: ; SHIFT HL LEFT, BUT SHIFT IN CARRY FLAG PUSH AF JP SHFL ; ; BUFFERS ; ACC: DS 2 ; TEMP ACCUMULATOR OVFL: DS 1 ; OVERFLOW FLAG END ; ; SYSLIB Module Name: SPA2HC ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.2 public pa2hc ; ; PA2HC -- ; PRINT REG A AS 2 HEXADECIMAL CHARACTERS ON CON: ; EXT COUT PA2HC: PUSH AF ; SAVE A PUSH AF RRCA ; EXCHANGE NYBBLES RRCA RRCA RRCA CALL PAHC ; PRINT LOW-ORDER NYBBLE AS HEX POP AF ; GET A CALL PAHC ; PRINT LOW-ORDER NYBBLE AS HEX POP AF ; RESTORE A RET PAHC: AND 0FH ; MASK FOR LOW NYBBLE CP 10 ; LETTER OR DIGIT? JP C,PADIG ; DIGIT IF CARRY ADD 'A'-10 ; CONVERT TO 'A'-'F' JP COUT ; PRINT PADIG: ADD '0' ; CONVERT TO '0'-'9' JP COUT ; PRINT END ; ; SYSLIB Module Name: SPADC ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.2 public pa3dc,padc EXT COUT ; ; PA3DC -- ; PRINT REG A AS 3 DECIMAL CHARACTERS ; PA3DC: PUSH BC ; SAVE REGS PUSH DE PUSH AF ; SAVE A LD D,0 ; TURN OFF LEADING FLAG JP PADC1 ; ; PADC -- ; PRINT REG A AS DECIMAL CHARACTERS W/LEADING IN 3-CHAR FIELD ; PADC: PUSH BC ; SAVE REGS PUSH DE PUSH AF ; SAVE A LD D,1 ; TURN ON LEADING FLAG ; ; PRINT ROUTINE ; PADC1: LD B,100 ; PRINT HUNDREDS CALL PAC ; PRINT A CHAR LD B,10 ; PRINT TENS CALL PAC ADD '0' ; CONVERT TO ASCII CALL COUT ; PRINT POP AF ; RESTORE A POP DE ; RESTORE REGS POP BC RET ; ; PRINT RESULT OF DIVISION OF A BY B W/LEADING (INTEGER DIVISION) ; PAC: LD C,0 ; SET COUNT PACL: SUB B ; COMPUTE COUNT JP C,PACD INC C ; INCR COUNT JP PACL PACD: ADD A,B ; ADD B BACK IN LD E,A ; SAVE A LD A,C ; GET COUNT OR A ; ZERO? JP NZ,PACD1 OR D ; 0 MEANS NO LEADING (A=0, SO A OR D = 0 IF D=0) JP Z,PACD1 LD A,' ' ; PRINT CALL COUT LD A,E ; RESTORE A RET PACD1: LD D,0 ; D=0 FOR NO LEADING LD A,C ; GET COUNT ADD '0' ; CONVERT TO DECIMAL CALL COUT ; PRINT IT LD A,E ; RESTORE A RET END ; ; SYSLIB Module Name: SPAFDC ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.1 public pafdc EXT COUT ; ; PAFDC -- ; PRINT REG A AS DECIMAL CHARACTERS IN N-CHAR FIELD ; FLOATING PRINT, WHERE 1-3 CHARS ARE USED ; PAFDC: PUSH BC ; SAVE REGS PUSH DE PUSH AF ; SAVE A LD D,1 ; TURN ON LEADING FLAG ; ; PRINT ROUTINE ; LD B,100 ; PRINT HUNDREDS CALL PAC ; PRINT A CHAR LD B,10 ; PRINT TENS CALL PAC ADD '0' ; CONVERT TO ASCII CALL COUT ; PRINT POP AF ; RESTORE A POP DE ; RESTORE REGS POP BC RET ; ; PRINT RESULT OF DIVISION OF A BY B W/LEADING (INTEGER DIVISION) ; PAC: LD C,0 ; SET COUNT PACL: SUB B ; COMPUTE COUNT JP C,PACD INC C ; INCR COUNT JP PACL PACD: ADD A,B ; ADD B BACK IN LD E,A ; SAVE A LD A,C ; GET COUNT OR A ; ZERO? JP NZ,PACD1 OR D ; 0 MEANS NO LEADING (A=0, A OR D = 0 MEANS D=0) JP Z,PACD1 LD A,E ; RESTORE A RET PACD1: LD D,0 ; D=0 FOR NO LEADING LD A,C ; GET COUNT ADD '0' ; CONVERT TO DECIMAL CALL COUT ; PRINT IT LD A,E ; RESTORE A RET END ; ; SYSLIB Module Name: SPAUSE ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.1 public pause ; ; PAUSE -- Pause N 10ths of a Second ; PAUSE will simply enter a delay loop for N 10ths of a Second. ; ; Input Parameters: HL = Number of 10ths of a Second to Pause ; B = Processor CLock Speed (in MHz) ; Output Parameters: None ; Registers Affected: None ; SYSLIB Routines Called: None ; Special Error Conditions: None ; ; ; EQUATES ; BOOT EQU 0 ; WARM BOOT ADDRESS CS$OFF EQU 6 ; CONSOLE STATUS OFFSET CIN$OFF EQU 9 ; CONSOLE INPUT OFFSET ; ; PAUSE ROUTINE ; HL = N 10THS OF A SEC, B = PROCESSOR SPEED ; ; COMPUTATION OF TIME DELAY CONSTANT: ; INITIAL OVERHEAD 49 CYCLES ; TERMINATING OVERHEAD 50 CYCLES ; PROCESSOR SPEED (P) (10+15)*P CYCLES ; MAJOR OVERHEAD TIME*132 CYCLES ; N-COUNT OVERHEAD (5+24)*N CYCLES ; ** REQUIRED TOTAL ** 100,000 CYCLES (1/10 SEC AT P=1) ; ; SINCE THIS IS A GUESTIMATE ANYWAY AND PROCESSOR SPEED WILL NOT BE EXACTLY ; P MHZ, I WILL THROW OUT THE PROCESSOR SPEED DELAY (AT MOST 100 CYCLES) ; ; CALCULATIONS: 100,000 = 49 + 50 + TIME*132 + 29*N ; TIME = (100,000 - 49 - 50 - 29*N)/132 ; TIME = (99,901 - 29*N)/132 ; CHART: ; N TIME ; 1 757 1/10 SEC ; 2 756 ; 3 756 ; 4 756 ; 5 756 1/2 SEC ; 10 755 1 SEC ; 15 754 ; 20 752 2 SECS ; 25 751 ; 50 746 5 SECS ; 100 735 10 SECS ; 500 647 50 SECS ; ; SINCE MOST CALLS TO THIS ROUTINE WILL REQUIRE BETWEEN 1/10 AND 5 SECS, ; I SHALL SELECT AN "AVERAGE" TIME CONSTANT OF (757+746)/2 = 752 ; SINCE AN "AVERAGE" CLOCK IS 2+ OR 4+ MHZ, I SHALL FUDGE THIS (THRU PRACTICE) ; TO 740 ; TIME EQU 700 ; TIME CONSTANT PAUSE: PUSH HL ; SAVE REGS [4*11 = 44] PUSH DE PUSH BC PUSH AF LD C,B ; SAVE PROCESSOR SPEED IN C [5] ; ; THE ABOVE INSTRUCTIONS REPRESENT THE INITIAL OVERHEAD = 49 CYCLES ; PAUSL: LD B,C ; GET PROCESSOR SPEED [5] PAUSL1: LD DE,TIME ; GET DELAY CONSTANT [10] ; ; THE ABOVE INSTRUCTIONS REPRESENT PART OF THE PROCESSOR SPEED OVERHEAD = 15 ; PAUSL2: EX (SP),HL ; LONG INSTRUCTION FOR DELAY [6*18 = 108] EX (SP),HL EX (SP),HL EX (SP),HL EX (SP),HL EX (SP),HL DEC DE ; COUNT DOWN INNER-MOST LOOP [5] LD A,D ; DONE? [5] OR E ; [4] JP NZ,PAUSL2 ; [10] ; ; THE ABOVE INSTRUCTIONS REPRESENT THE MAJOR OVERHEAD = TIME*(108+5+5+4+10) ; = TIME*132 ; DEC B ; COUNT DOWN 10TH-SEC LOOP [5] JP NZ,PAUSL1 ; [10] ; ; THE ABOVE INSTRUCTIONS REPRESENT THE REST OF THE PROCESSOR SPEED OVERHEAD ; = 15 ; DEC HL ; COUNT DOWN N 10THS LOOP [5] LD A,H ; DONE? [5] OR L ; [4] JP NZ,PAUSL ; [10] ; ; THE ABOVE INSTRUCTIONS REPRESENT THE N-COUNT OVERHEAD = 24 CYCLES ; POP AF ; RESTORE REGS [4*10 = 40] POP BC POP DE POP HL RET ; [10] ; ; THE ABOVE INSTRUCTIONS REPRESENT THE TERMINATING OVERHEAD = 50 CYCLES ; END ; ; SYSLIB Module Name: SPFN1 ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.1 public pfn1 ext cout ; ; Print FCB file name and type pted to by DE on CON: ; Format of Output: xxxxxxxx.xxx ; pfn1: push de ; save regs push bc push af ld b,8 ; 8 chars first call prfnx ld a,'.' ; dot call cout ld b,3 ; 3 more chars call prfnx pop af ; restore regs pop bc pop de ret prfnx: ld a,(de) ; get char and 7fh ; mask out msb call cout ; print it inc de ; pt to next dec b ; count down jp nz,prfnx ret end ; ; SYSLIB Module Name: SPFN2 ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.1 public pfn2 ext cout ; ; Print FCB file name and type pted to by DE on CON: ; Format of Output: xxxxxxxx.yyy (0-8 x's, 0-3 y's) ; pfn2: push de ; save regs push bc push af ld b,8 ; 8 chars first call prfnx ld a,'.' ; dot call cout ld b,3 ; 3 more chars call prfnx pop af ; restore regs pop bc pop de ret prfnx: ld a,(de) ; get char and 7fh ; mask out msb cp ' ' ; done? call nz,cout ; print it inc de ; pt to next dec b ; count down jp nz,prfnx ret end ; ; SYSLIB Module Name: SPFN3 ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.1 public pfn3 ext cout ; ; Print FCB file name and type pted to by DE on CON: ; Format of Output: xxxxxxxx.yyy (0-8 x's, 0-3 y's, req'd spaces) ; pfn3: push de ; save regs push bc push af ld c,11 ; 11 chars total ld b,8 ; 8 chars first call prfnx ld a,'.' ; dot call cout ld b,3 ; 3 more chars call prfnx ld a,c ; get count of spaces or a ; 0=none call nz,spacer pop af ; restore regs pop bc pop de ret prfnx: ld a,(de) ; get char and 7fh ; mask out msb cp ' ' ; skip space call nz,prout ; print it inc de ; pt to next dec b ; count down jp nz,prfnx ret prout: dec c ; count chars jp cout ; print char spacer: ld a,' ' ; space over call cout dec c ; count down jp nz,spacer ret end ; ; SYSLIB Module Name: SPHL4HC ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.2 public phl4hc ; ; PHL4HC -- Print HL as 4 Hex Characters ; No Registers are to be affected. ; EXT PA2HC ; PRINT A AS 2 HEX CHARACTERS PHL4HC: PUSH AF ; SAVE A LD A,H ; PRINT H CALL PA2HC LD A,L ; PRINT L CALL PA2HC POP AF ; RESTORE A RET END ; ; SYSLIB Module Name: SPHL5DC ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.2 public phl5dc,phldc EXT COUT PUTRG MACRO PUSH BC ; SAVE BC, DE, HL PUSH DE PUSH HL ENDM GETRG MACRO POP HL ; RESTORE HL, DE, BC POP DE POP BC ENDM ; ; PHL5DC -- ; PRINT HL AS 5 DECIMAL CHARACTERS ; PHL5DC: PUSH AF ; SAVE ALL REGS PUTRG LD B,0 ; B=0 FOR NO LEADING JP PHDC ; ; PHLDC -- ; PRINT HL AS DECIMAL CHARACTERS W/LEADING SPACES IN 5-CHAR FIELD ; PHLDC: PUSH AF ; SAVE ALL REGS PUTRG LD B,1 ; A=1 FOR LEADING ; ; PRINT HL USING LEADING FLAG IN B ; PHDC: LD DE,10000 ; PRINT 10000'S CALL PHDC1 LD DE,1000 ; PRINT 1000'S CALL PHDC1 LD DE,100 ; PRINT 100'S CALL PHDC1 LD DE,10 ; PRINT 10'S CALL PHDC1 LD A,L ; PRINT 1'S ADD '0' ; CONVERT TO ASCII CALL COUT GETRG ; RESTORE ALL REGS POP AF RET ; ; DIVIDE HL BY DE AND PRINT QUOTIENT WITH LEADING S ; PHDC1: LD C,0 ; SET COUNT PHDC2: LD A,L ; SUB E FROM L SUB E LD L,A ; RESULT IN L LD A,H ; SUB D FROM H W/BORROW SBC A,D LD H,A ; RESULT IN H JP C,PHDC3 ; DONE IF CARRY SET (FURTHER BORROW) INC C ; INCR COUNT JP PHDC2 PHDC3: LD A,L ; ADD E TO L ADD A,E LD L,A ; RESULT IN L LD A,H ; ADD D TO H W/CARRY ADC A,D LD H,A ; RESULT IN H LD A,C ; GET RESULT OR A ; CHECK FOR ZERO JP NZ,PHDC4 OR B ; 0 = NO LEADING (A=0, A OR B = 0 IF B=0) JP Z,PHDC4 LD A,' ' ; PRINT JP COUT PHDC4: LD B,0 ; TURN OFF LEADING LD A,C ; GET VALUE ADD '0' ; CONVERT TO ASCII JP COUT END ; ; SYSLIB Module Name: SPHLFDC ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.1 public phlfdc EXT COUT PUTRG MACRO PUSH BC ; SAVE BC, DE, HL PUSH DE PUSH HL ENDM GETRG MACRO POP HL ; RESTORE HL, DE, BC POP DE POP BC ENDM ; ; PHLFDC -- ; PRINT HL AS DECIMAL CHARACTERS IN N-CHAR FIELD ; FLOATING PRINT, WHERE FIELD SIZE IS FROM 1 TO 5 CHARS ; PHLFDC: PUSH AF ; SAVE ALL REGS PUTRG LD B,1 ; B=1 FOR LEADING ; ; PRINT HL USING LEADING FLAG IN B ; LD DE,10000 ; PRINT 10000'S CALL PHDC1 LD DE,1000 ; PRINT 1000'S CALL PHDC1 LD DE,100 ; PRINT 100'S CALL PHDC1 LD DE,10 ; PRINT 10'S CALL PHDC1 LD A,L ; PRINT 1'S ADD '0' ; CONVERT TO ASCII CALL COUT GETRG ; RESTORE ALL REGS POP AF RET ; ; DIVIDE HL BY DE AND PRINT QUOTIENT WITH LEADING S ; PHDC1: LD C,0 ; SET COUNT PHDC2: LD A,L ; SUB E FROM L SUB E LD L,A ; RESULT IN L LD A,H ; SUB D FROM H W/BORROW SBC A,D LD H,A ; RESULT IN H JP C,PHDC3 ; DONE IF CARRY SET (FURTHER BORROW) INC C ; INCR COUNT JP PHDC2 PHDC3: LD A,L ; ADD E TO L ADD A,E LD L,A ; RESULT IN L LD A,H ; ADD D TO H W/CARRY ADC A,D LD H,A ; RESULT IN H LD A,C ; GET RESULT OR A ; CHECK FOR ZERO JP NZ,PHDC4 OR B ; 0=NO LEADING (A=0, A OR B = 0 MEANS B = 0) RET NZ PHDC4: LD B,0 ; TURN OFF LEADING LD A,C ; GET VALUE ADD '0' ; CONVERT TO ASCII JP COUT END ; ; SYSLIB Module Name: SPOUT ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.1 public pout ; ; POUT -- ; PUNCH OUTPUT ROUTINE ; OUTPUT CHAR IN REG A ON PUN: ; AFFECT NO REGISTERS OR FLAGS ; PUTRG MACRO PUSH BC ; SAVE BC, DE, HL PUSH DE PUSH HL ENDM GETRG MACRO POP HL ; RESTORE HL, DE, BC POP DE POP BC ENDM POUT: PUSH AF ; SAVE REG A AND FLAGS PUTRG ; SAVE REGISTERS LD C,A ; CHAR IN C LD HL,(JTABL) ; GET ADDRESS OF JUMP TABLE LD L,P$OFF ; PUNCH OUTPUT ADR LD DE,PRET ; SET UP RET ADR PUSH DE ; ... ON STACK JP (HL) PRET: GETRG ; RESTORE REGISTERS POP AF ; RESTORE REG A AND FLAGS RET BOOT EQU 0 ; CP/M BOOT ADDRESS JTABL EQU BOOT+1 ; CP/M JUMP TABLE ADDRESS P$OFF EQU 12H ; PUNCH OUTPUT OFFSET END ; ; SYSLIB Module Name: SPRINT ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.1 public print ; ; PRINT -- ; PRINT STRING PTED TO BY RET ADR UNTIL BINARY 0 ENCOUNTERED ; AFFECT NO REGISTERS OR FLAGS ; EXT PSTR PRINT: EX (SP),HL ; HL=ADR, OLD HL ON STACK CALL PSTR ; PRINT STRING PTED TO BY HL EX (SP),HL ; RESTORE HL AND NEW RET ADR RET END ; ; SYSLIB Module Name: SPSTR ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.1 public pstr ; ; PSTR -- ; PRINT STRING PTED TO BY HL ; AFFECT ONLY HL -- WHEN DONE, HL PTS TO BYTE AFTER STRING ; EXT CCOUT EXT COUT PSTR: PUSH DE ; SAVE REGS PUSH BC PUSH AF ; SAVE REG A AND FLAGS LD C,0 ; SET POSITION COUNT PSL: LD A,(HL) ; GET BYTE INC HL ; PT TO NEXT OR A ; 0=DONE JP Z,PSD CP TAB ; EXPAND JP Z,PST ; ; PRINT CHAR ; INC C ; INCR POSITION CALL CCOUT ; PRINT IT ON CON: CP CR ; CHECK FOR JP Z,PCR CP LF ; CHECK FOR JP Z,PLF CP BEL ; CHECK FOR JP Z,PLF CP BS ; CHECK FOR JP Z,PBS JP PSL ; ; -- RESET POSITION COUNT ; PCR: LD C,0 ; RESET JP PSL ; ; , , -- CURSOR DIDN'T ADVANCE ; PLF: DEC C ; BACK UP COUNT BY 1 JP PSL ; ; -- CURSOR WENT BACKWARD, MAYBE ; PBS: LD A,C ; CHECK FOR ZERO OR A JP Z,PSL DEC C ; BACK UP COUNT BY 2 DEC C JP PSL ; ; EXPAND ; PST: LD A,C ; GET COUNT AND 7 ; MASK FOR SUB FROM 8 LD B,A ; STORE TEMPORARILY LD A,8 ; SUBTRACT FROM 8 FOR COUNT SUB B LD B,A ; COUNT IN B ADD A,C ; ADD TO POSITION COUNT LD C,A LD A,' ' ; PRINT PSTL: CALL COUT DEC B ; COUNT DOWN JP NZ,PSTL JP PSL ; ; PSTR DONE ; PSD: POP AF ; RESTORE REG A AND FLAGS POP BC ; RESTORE REGS POP DE RET ; ; ASCII SPECIAL CHARACTER EQUATES ; NULL EQU 0 ; NULL BEL EQU 7 ; BELL BS EQU 8 ; BACKSPACE TAB EQU 9 ; TAB LF EQU 10 ; LINE FEED CR EQU 13 ; CARRIAGE RETURN CTRLR EQU 'R'-40H ; CTRL-R CTRLU EQU 'U'-40H ; CTRL-U CTRLX EQU 'X'-40H ; CTRL-X DEL EQU 7FH ; DELETE CHAR END ; ; SYSLIB Module Name: SRAND ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.1 public rnd,rndinit,rndseed ; ; EXTERNALS ; EXT PRINT EXT CONDIN ; ; RNDINIT -- INITIALIZE RANDOM NUMBER GENERATOR ; THIS ROUTINE PROMPTS THE USER FOR A KEYPRESS, AND THEN SETS THE ; SEE VALUE FOR THE RANDOM NUMBER GENERATOR (8-BIT) ; NO INPUT OR OUTPUT PARAMETERS ; GENERALLY, IT IS LEFT TO THE USER TO PRINT A MESSAGE BEFORE THIS ROUTINE ; IS CALLED ; RNDINIT: PUSH AF ; SAVE REGS PUSH BC LD B,0 ; START AT 0 RNDIL: INC B ; INCREMENT SEED CALL CONDIN ; INPUT? JP Z,RNDIL LD A,B ; GET SEED RNDID: LD (SEED),A ; SAVE IT FOR LATER CALL RND ; GENERATE A RANDOM NUMBER LD (ADDEND),A ; SAVE A INITIAL ADDEND POP BC ; RESTORE REGS POP AF RET ; ; RNDSEED -- ALLOW USER TO SPECIFY A SEED VALUE FOR THE RANDOM NUMBER GEN ; SEED IS PASSED IN A; NO REGS AFFECTED ; RNDSEED: PUSH AF ; SAVE REGS PUSH BC JP RNDID ; SAVE SEED AND GENERATE ADDEND ; ; RANDOM NUMBER SEED VALUE ; SEED: DS 1 ; 1 BYTE ADDEND: DS 1 ; ADDEND ; ; RANDOM NUMBER GENERATOR ; RANDOM NUMBER RETURNED IN A ; RND: PUSH HL ; DON'T AFFECT HL LD HL,SEED ; PT TO SEED LD A,(HL) ; GET IT RLCA ; PLAY WITH IT XOR (HL) RRCA INC HL ; PT TO ADDEND INC (HL) ; INCREMENT IT ADD A,(HL) ; ADD IN ADDEND JP PE,SKIP INC (HL) ; INCREMENT ADDEND AGAIN SKIP: DEC HL ; PT TO SEED AGAIN LD (HL),A ; SAVE NEW SEED POP HL ; RESTORE HL RET END ; ; SYSLIB Module Name: SRIN ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.1 public rin ; ; RIN -- ; READER INPUT ROUTINE ; INPUT CHARACTER FROM RDR: INTO REG A ; AFFECT ONLY REG A AND FLAGS ; PUTRG MACRO PUSH BC ; SAVE BC, DE, HL PUSH DE PUSH HL ENDM GETRG MACRO POP HL ; RESTORE HL, DE, BC POP DE POP BC ENDM RIN: PUTRG ; SAVE REGISTERS LD HL,(JTABL) ; GET ADDRESS OF JUMP TABLE LD L,R$OFF ; READER INPUT ADR LD DE,RRET1 ; SET UP RET ADR PUSH DE ; ... ON STACK JP (HL) RRET1: GETRG ; RESTORE REGISTERS RET BOOT EQU 0 ; CP/M BOOT ADDRESS JTABL EQU BOOT+1 ; CP/M JUMP TABLE ADDRESS R$OFF EQU 15H ; READER INPUT OFFSET END ; ; SYSLIB Module Name: SRREAD ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.1 public r$read ; ; Equates ; bdos equ 5 ranrec equ 33 ; offset to random record number readran equ 33 ; function code for random read ; ; Macros ; putrg macro push hl push de push bc endm getrg macro pop bc pop de pop hl endm ; ; R$READ reads the random record whose number is given in HL of ; the file whose FCB is pointed to by DE. It is assumed that the file ; has been previously opened by a routine like F$OPEN. ; ; On exit, A=0 and Z if OK ; r$read: putrg ; save registers push de ; save FCB ptr ex de,hl ; HL pts to FCB, DE = record number ld bc,ranrec ; BC = offset to random record number add hl,bc ; HL pts to random record number ld (hl),e ; store low-order value inc hl ld (hl),d ; store high-order value inc hl ld (hl),0 ; store 0 pop de ; get FCB ptr ld c,readran ; function code call bdos ; perform function getrg ; restore registers or a ; set flags ret end ; ; SYSLIB Module Name: SRWRITE ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.1 public r$write ; ; Equates ; bdos equ 5 ranrec equ 33 ; offset to random record number writran equ 34 ; function code for random read ; ; Macros ; putrg macro push hl push de push bc endm getrg macro pop bc pop de pop hl endm ; ; R$WRITE writes the random record whose number is given in HL of ; the file whose FCB is pointed to by DE. It is assumed that the file ; has been previously opened by a routine like F$OPEN. ; ; On exit, A=0 and Z if OK ; r$write: putrg ; save registers push de ; save FCB ptr ex de,hl ; HL pts to FCB, DE = record number ld bc,ranrec ; BC = offset to random record number add hl,bc ; HL pts to random record number ld (hl),e ; store low-order value inc hl ld (hl),d ; store high-order value inc hl ld (hl),0 ; store 0 pop de ; get FCB ptr ld c,writran ; function code call bdos ; perform function getrg ; restore registers or a ; set flags ret end ; ; SYSLIB Module Name: SSA2HC ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.1 public sa2hc ; ; SA2HC -- ; PRINT REG A AS 2 HEXADECIMAL CHARACTERS ON CON: OR LST: ; EXT SOUT SA2HC: PUSH AF ; SAVE A PUSH AF RRCA ; EXCHANGE NYBBLES RRCA RRCA RRCA CALL PAHC ; PRINT LOW-ORDER NYBBLE AS HEX POP AF ; GET A CALL PAHC ; PRINT LOW-ORDER NYBBLE AS HEX POP AF ; RESTORE A RET PAHC: AND 0FH ; MASK FOR LOW NYBBLE CP 10 ; LETTER OR DIGIT? JP C,PADIG ; DIGIT IF CARRY ADD 'A'-10 ; CONVERT TO 'A'-'F' JP SOUT ; PRINT PADIG: ADD '0' ; CONVERT TO '0'-'9' JP SOUT ; PRINT END ; ; SYSLIB Module Name: SSADC ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.1 public sa3dc,sadc EXT SOUT ; ; SA3DC -- ; PRINT REG A AS 3 DECIMAL CHARACTERS ON CON: OR LST: ; SA3DC: PUSH BC ; SAVE REGS PUSH DE PUSH AF ; SAVE A LD D,0 ; TURN OFF LEADING FLAG JP PADC1 ; ; SADC -- ; PRINT REG A AS DECIMAL CHARACTERS W/LEADING IN 3-CHAR FIELD ; ON CON: OR LST: ; SADC: PUSH BC ; SAVE REGS PUSH DE PUSH AF ; SAVE A LD D,1 ; TURN ON LEADING FLAG ; ; PRINT ROUTINE ; PADC1: LD B,100 ; PRINT HUNDREDS CALL PAC ; PRINT A CHAR LD B,10 ; PRINT TENS CALL PAC ADD '0' ; CONVERT TO ASCII CALL SOUT ; PRINT POP AF ; RESTORE A POP DE ; RESTORE REGS POP BC RET ; ; PRINT RESULT OF DIVISION OF A BY B W/LEADING (INTEGER DIVISION) ; PAC: LD C,0 ; SET COUNT PACL: SUB B ; COMPUTE COUNT JP C,PACD INC C ; INCR COUNT JP PACL PACD: ADD A,B ; ADD B BACK IN LD E,A ; SAVE A LD A,C ; GET COUNT OR A ; ZERO? JP NZ,PACD1 OR D ; 0 MEANS NO LEADING (A=0, SO A OR D = 0 IF D=0) JP Z,PACD1 LD A,' ' ; PRINT CALL SOUT LD A,E ; RESTORE A RET PACD1: LD D,0 ; D=0 FOR NO LEADING LD A,C ; GET COUNT ADD '0' ; CONVERT TO DECIMAL CALL SOUT ; PRINT IT LD A,E ; RESTORE A RET END ; ; SYSLIB Module Name: SSAFDC ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.1 public safdc EXT SOUT ; ; SAFDC -- ; PRINT REG A AS DECIMAL CHARACTERS IN N-CHAR FIELD ON CON: OR LST: ; FLOATING PRINT, WHERE 1-3 CHARS ARE USED ; SAFDC: PUSH BC ; SAVE REGS PUSH DE PUSH AF ; SAVE A LD D,1 ; TURN ON LEADING FLAG ; ; PRINT ROUTINE ; LD B,100 ; PRINT HUNDREDS CALL PAC ; PRINT A CHAR LD B,10 ; PRINT TENS CALL PAC ADD '0' ; CONVERT TO ASCII CALL SOUT ; PRINT POP AF ; RESTORE A POP DE ; RESTORE REGS POP BC RET ; ; PRINT RESULT OF DIVISION OF A BY B W/LEADING (INTEGER DIVISION) ; PAC: LD C,0 ; SET COUNT PACL: SUB B ; COMPUTE COUNT JP C,PACD INC C ; INCR COUNT JP PACL PACD: ADD A,B ; ADD B BACK IN LD E,A ; SAVE A LD A,C ; GET COUNT OR A ; ZERO? JP NZ,PACD1 OR D ; 0 MEANS NO LEADING (A=0, A OR D = 0 MEANS D=0) JP Z,PACD1 LD A,E ; RESTORE A RET PACD1: LD D,0 ; D=0 FOR NO LEADING LD A,C ; GET COUNT ADD '0' ; CONVERT TO DECIMAL CALL SOUT ; PRINT IT LD A,E ; RESTORE A RET END ; ; SYSLIB Module Name: SCANNER ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.1 public scanner ; ; SSCANNER -- ; SCANNER scans the vector of bytes pointed to by HL for ; the vector of bytes pointed to by DE. The HL-byte vector is B bytes ; long, and the DE-byte vector is C bytes long. ; On return, if found, HL points to the beginning location within ; the original HL vector of the located vector and Zero Flag is set. ; If not found, Zero Flag is not set and HL is unaffected. DE and BC ; are not affected by this routine. ; SCANNER: PUSH BC ; SAVE REGISTERS PUSH HL ; MAIN LOOP SCAN: ; CHECK FOR DONE LD A,B ; DONE IF B TO CON: OR LST: ; AFFECT NO REGISTERS OR FLAGS ; SCRLF: PUSH AF ; SAVE PSW LD A,(SCTLFL) ; GET CONTROL FLAG PUSH AF ; SAVE CONTROL FLAG AND 80H ; LST:? CALL NZ,LCRLF POP AF ; GET CONTROL FLAG AND 1 ; CON:? CALL NZ,CRLF POP AF ; RESTORE PSW RET END ; ; SYSLIB Module Name: SSCTLFL ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.1 public sctlfl ; ; SCTLFL is a data byte accessed by the SOUT and SCOUT routines. ; If its MSB (Bit 7) is Set, output is sent to LST:; if its LSB (Bit 0) ; is Set, output is sent to CON:. ; SCTLFL: DB 1 ; CON: BY DEFAULT END ; ; SYSLIB Module: SETDMA ; AUTHOR: RICHARD CONN ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.1 ; Previous Versions: None ; public setdma ; ; SETDMA sets the DMA address in HL. No registers are affected. ; bdos equ 5 setdma: push hl ; save all regs push de push bc push af ld c,26 ; SET DMA function ex de,hl ; DE=address call bdos pop af ; restore registers pop bc pop de pop hl ret end ; ; SYSLIB Module Name: SSFA ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.1 public sfa ; ; Externals ; ext initfcb ; ; Equates ; bdos equ 5 ; base address of BDOS bsfa equ 30 ; set file attributes function code ; ; Macros ; putrg macro push hl ; save regs push de push bc endm getrg macro pop bc ; restore regs pop de pop hl endm ; ; SFA sets the unambiguous file whose FCB is pted to by DE ; to the attributes coded in A, where A0 is the R/O bit and ; A7 is the SYS bit; all other file attributes reflected in ; this FCB are retained ; On exit, A=0FFH and NZ if file not found or ambigous file reference ; A=0 and Z if OK ; All FCB fields are cleared except for file name and type ; sfa: putrg ; save registers ld c,a ; save file attributes in C ; ; Check for ambiguous file name ; push de ; save ptr to FCB inc de ; pt to first char ld b,11 ; check 11 bytes amb: ld a,(de) ; get char and 7fh ; mask MSB cp '?' jp z,amb1 inc de dec b jp nz,amb inc b ; make NZ amb1: pop de jp z,error push de ; save ptr to FCB ld hl,9 ; offset to R/O attribute add hl,de ; pt to R/O byte ; ; Set R/O Bit ; ld a,c ; get file attributes rrca ; set new MSB call attset inc hl ; pt to SYS attribute ; ; Set SYS Bit ; ld a,c ; get attribute call attset ; ; Change attributes on disk ; pop de ; pt to FCB call initfcb ld c,bsfa ; use BDOS function call bdos cp 0ffh ; error? jp z,error xor a ; OK getrg ; restore registers ret ; ; Error Return ; error: ld a,0ffh ; set code or a ; set flags getrg ; restore registers ret ; ; Set attribute in A (MSB) ; attset: push af ; save A ld a,(hl) ; get byte and 7fh ; mask out MSB ld b,a ; save in B pop af ; get A and 80h ; check SYS bit or b ; OR in SYS byte ld (hl),a ; put SYS byte ret end ; ; SYSLIB Module Name: SSFN1 ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.1 public sfn1 ext sout ; ; Print FCB file name and type pted to by DE on switched output ; (CON: or LST:) ; Format of Output: xxxxxxxx.xxx ; sfn1: push de ; save regs push bc push af ld b,8 ; 8 chars first call prfnx ld a,'.' ; dot call sout ld b,3 ; 3 more chars call prfnx pop af ; restore regs pop bc pop de ret prfnx: ld a,(de) ; get char and 7fh ; mask out msb call sout ; print it inc de ; pt to next dec b ; count down jp nz,prfnx ret end ; ; SYSLIB Module Name: SSFN2 ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.1 public sfn2 ext sout ; ; Print FCB file name and type pted to by DE on switched output ; (CON: or LST:) ; Format of Output: xxxxxxxx.yyy (0-8 x's, 0-3 y's) ; sfn2: push de ; save regs push bc push af ld b,8 ; 8 chars first call prfnx ld a,'.' ; dot call sout ld b,3 ; 3 more chars call prfnx pop af ; restore regs pop bc pop de ret prfnx: ld a,(de) ; get char and 7fh ; mask out msb cp ' ' ; skip space call nz,sout ; print it inc de ; pt to next dec b ; count down jp nz,prfnx ret end ; ; SYSLIB Module Name: SSFN3 ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.1 public sfn3 ext sout ; ; Print FCB file name and type pted to by DE on switched output ; (CON: or LST:) ; Format of Output: xxxxxxxx.yyy (0-8 x's, 0-3 y's, req'd spaces) ; sfn3: push de ; save regs push bc push af ld c,11 ; 11 chars total ld b,8 ; 8 chars first call prfnx ld a,'.' ; dot call sout ld b,3 ; 3 more chars call prfnx ld a,c ; get count of spaces or a ; 0=none call nz,spacer pop af ; restore regs pop bc pop de ret prfnx: ld a,(de) ; get char and 7fh ; mask out msb cp ' ' ; skip space call nz,prout ; print it inc de ; pt to next dec b ; count down jp nz,prfnx ret prout: dec c ; count chars jp sout ; print char spacer: ld a,' ' ; space over call sout dec c ; count down jp nz,spacer ret end ; ; SYSLIB Module Name: SSHL4HC ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.1 public shl4hc ; ; SHL4HC -- Print HL as 4 Hex Characters on CON: or LST: ; No Registers are to be affected. ; EXT SA2HC ; PRINT A AS 2 HEX CHARACTERS ON CON: OR LST: SHL4HC: PUSH AF ; SAVE A LD A,H ; PRINT H CALL SA2HC LD A,L ; PRINT L CALL SA2HC POP AF ; RESTORE A RET END ; ; SYSLIB Module Name: SSHL5DC ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.1 public shl5dc,shldc EXT SOUT PUTRG MACRO PUSH BC ; SAVE BC, DE, HL PUSH DE PUSH HL ENDM GETRG MACRO POP HL ; RESTORE HL, DE, BC POP DE POP BC ENDM ; ; SHL5DC -- ; PRINT HL AS 5 DECIMAL CHARACTERS ON CON: OR LST: ; SHL5DC: PUSH AF ; SAVE ALL REGS PUTRG LD B,0 ; B=0 FOR NO LEADING JP PHDC ; ; SHLDC -- ; PRINT HL AS DECIMAL CHARACTERS W/LEADING SPACES IN 5-CHAR FIELD ; ON CON: OR LST: ; SHLDC: PUSH AF ; SAVE ALL REGS PUTRG LD B,1 ; A=1 FOR LEADING ; ; PRINT HL USING LEADING FLAG IN B ; PHDC: LD DE,10000 ; PRINT 10000'S CALL PHDC1 LD DE,1000 ; PRINT 1000'S CALL PHDC1 LD DE,100 ; PRINT 100'S CALL PHDC1 LD DE,10 ; PRINT 10'S CALL PHDC1 LD A,L ; PRINT 1'S ADD '0' ; CONVERT TO ASCII CALL SOUT GETRG ; RESTORE ALL REGS POP AF RET ; ; DIVIDE HL BY DE AND PRINT QUOTIENT WITH LEADING S ; PHDC1: LD C,0 ; SET COUNT PHDC2: LD A,L ; SUB E FROM L SUB E LD L,A ; RESULT IN L LD A,H ; SUB D FROM H W/BORROW SBC A,D LD H,A ; RESULT IN H JP C,PHDC3 ; DONE IF CARRY SET (FURTHER BORROW) INC C ; INCR COUNT JP PHDC2 PHDC3: LD A,L ; ADD E TO L ADD A,E LD L,A ; RESULT IN L LD A,H ; ADD D TO H W/CARRY ADC A,D LD H,A ; RESULT IN H LD A,C ; GET RESULT OR A ; CHECK FOR ZERO JP NZ,PHDC4 OR B ; 0 = NO LEADING (A=0, A OR B = 0 IF B=0) JP Z,PHDC4 LD A,' ' ; PRINT JP SOUT PHDC4: LD B,0 ; TURN OFF LEADING LD A,C ; GET VALUE ADD '0' ; CONVERT TO ASCII JP SOUT END ; ; SYSLIB Module Name: SSHLFDC ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.1 public shlfdc EXT SOUT PUTRG MACRO PUSH BC ; SAVE BC, DE, HL PUSH DE PUSH HL ENDM GETRG MACRO POP HL ; RESTORE HL, DE, BC POP DE POP BC ENDM ; ; SHLFDC -- ; PRINT HL AS DECIMAL CHARACTERS IN N-CHAR FIELD ON CON: OR LST: ; FLOATING PRINT, WHERE FIELD SIZE IS FROM 1 TO 5 CHARS ; SHLFDC: PUSH AF ; SAVE ALL REGS PUTRG LD B,1 ; B=1 FOR LEADING ; ; PRINT HL USING LEADING FLAG IN B ; LD DE,10000 ; PRINT 10000'S CALL PHDC1 LD DE,1000 ; PRINT 1000'S CALL PHDC1 LD DE,100 ; PRINT 100'S CALL PHDC1 LD DE,10 ; PRINT 10'S CALL PHDC1 LD A,L ; PRINT 1'S ADD '0' ; CONVERT TO ASCII CALL SOUT GETRG ; RESTORE ALL REGS POP AF RET ; ; DIVIDE HL BY DE AND PRINT QUOTIENT WITH LEADING S ; PHDC1: LD C,0 ; SET COUNT PHDC2: LD A,L ; SUB E FROM L SUB E LD L,A ; RESULT IN L LD A,H ; SUB D FROM H W/BORROW SBC A,D LD H,A ; RESULT IN H JP C,PHDC3 ; DONE IF CARRY SET (FURTHER BORROW) INC C ; INCR COUNT JP PHDC2 PHDC3: LD A,L ; ADD E TO L ADD A,E LD L,A ; RESULT IN L LD A,H ; ADD D TO H W/CARRY ADC A,D LD H,A ; RESULT IN H LD A,C ; GET RESULT OR A ; CHECK FOR ZERO JP NZ,PHDC4 OR B ; 0=NO LEADING (A=0, A OR B = 0 MEANS B = 0) RET NZ PHDC4: LD B,0 ; TURN OFF LEADING LD A,C ; GET VALUE ADD '0' ; CONVERT TO ASCII JP SOUT END ; ; SYSLIB Module Name: SSKPUN ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.1 public skpun,sknpun ; ; SKPUN skips punctuation in the string pointed to by HL until ; a non-punctuation char is encountered. HL pts to the non-punctuation char ; when done. ; SKNPUN skips non-punctuation chars in the string pointed to by HL until ; either a punctuation char or a null are encountered. HL pts to the ; punctuation char or null when done. ; EXT ISPUN SKPUN: PUSH AF ; SAVE PSW SKP1: LD A,(HL) ; GET NEXT CHAR INC HL ; PT TO NEXT OR A ; DONE? JP Z,SKP2 CALL ISPUN ; IS A PUNCTUATION CHAR? JP Z,SKP1 ; CONTINUE SKIP IF SO SKP2: DEC HL ; PT TO OFFENDING CHAR POP AF ; GET PSW RET SKNPUN: PUSH AF ; SAVE PSW SKNP1: LD A,(HL) ; GET NEXT CHAR INC HL ; PT TO NEXT OR A ; DONE? JP Z,SKP2 CALL ISPUN ; IS A PUNCTUATION CHAR? JP NZ,SKNP1 JP SKP2 END ; ; SYSLIB Module Name: SSKSP ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.1 public sksp,sknsp ; ; SKSP skips spaces in the string pointed to by HL until either ; a non-space or null are encountered. HL pts to the non-space or null ; when done. ; SKNSP skips non-spaces in the string pointed to by HL until ; either a space or a null are encountered. HL pts to the space or null ; when done. ; EXT ISSP SKSP: PUSH AF ; SAVE PSW SKSP1: LD A,(HL) ; GET NEXT CHAR INC HL ; PT TO NEXT OR A ; DONE? JP Z,SKSP2 CALL ISSP ; IS A SPACE? JP Z,SKSP1 ; CONTINUE SKIP IF SO SKSP2: DEC HL ; PT TO OFFENDING CHAR POP AF ; GET PSW RET SKNSP: PUSH AF ; SAVE PSW SKNSP1: LD A,(HL) ; GET NEXT CHAR INC HL ; PT TO NEXT OR A ; DONE? JP Z,SKSP2 CALL ISSP ; IS A SPACE? JP NZ,SKNSP1 JP SKSP2 END ; ; SYSLIB Module Name: SSORT ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.2 public ssbinit,sort ; ; EXTERNALS ; EXT MOVEB EXT PRINT ; ; BASIC EQUATES ; CPM EQU 0 ; CP/M WARM BOOT BIOS EQU CPM+1 ; BIOS BASE ADDRESS BDOS EQU CPM+5 ; BDOS ENTRY POINT ESIZE EQU 16 ; NUMBER OF BYTES/ENTRY IN MEMORY BUFFER BUFF EQU CPM+80H ; DEFAULT DMA BUFFER ; ; SSBINI -- Initialize SSB ; This routine sets the value of FIRSTP and ORDER for the SORT ; routine. On Entry, HL pts to first available byte after user's ; program (beginning of buffer area) and DE pts to an SSB. On exit, ; HL pts to first available byte for the user's in-memory data file ; (same address as FIRSTP). If the TPA is overflowed by the ORDER ; table that would be generated by SORT, then the Z flag is returned set ; (Z); if no error, NZ is returned. ; If the user has already loaded his data and just wants to ; allocate an ORDER table, then he should have HL before calling SSBINI, ; restore HL upon return from SSBINI, and then store HL into his FIRSTP ; entry before calling SORT. ; SSBINIT: PUSH DE ; SAVE REGS PUSH BC PUSH HL ; SAVE NEXT AVAILABLE BYTE ADDRESS EX DE,HL ; MAKE HL PT TO USER'S SSB LD (USRSSB),HL ; SAVE PTR TO USER'S SSB LD DE,SSB ; COPY INTO MY SSB LD B,12 ; 12 BYTES CALL MOVEB POP HL ; GET NEXT AVAILABLE BYTE ADDRESS LD (ORDER),HL ; SET PTR TO IT LD HL,(RECNT) ; GET NUMBER OF RECORDS LD A,L ; DOUBLE IT WITH ERROR CHECKING ADD A,L LD L,A LD A,H ADC A,H LD H,A JP C,SSBOVFL ; OVERFLOW IF CARRY EX DE,HL ; SIZE OF ORDER TABLE IN DE LD HL,(ORDER) ; BASE ADDRESS OF ORDER TABLE IN HL LD A,L ; ADD HL TO DE WITH ERROR CHECKING ADD A,E LD L,A LD A,H ADC A,D LD H,A ; HL IS NOW ADDRESS OF BYTE AFTER ORDER TABLE JP C,SSBOVFL ; OVERFLOW IF CARRY LD (FIRSTP),HL ; SET PTR TO NEXT AVAILABLE BYTE LD HL,(USRSSB) ; PT TO USER'S SSB EX DE,HL ; ... IN DE LD HL,SSB ; PT TO USER'S NEW SSB LD B,12 ; COPY IT BACK CALL MOVEB POP BC ; RESTORE REGS POP DE LD HL,(FIRSTP) ; PT TO NEXT AVAILABLE MEMORY ADDRESS LD A,0FFH ; SET NO ERROR CODE OR A RET SSBOVFL: POP BC ; RESTORE REGS POP DE LD HL,(ORDER) ; RESTORE PTR TO USER'S BUFFER XOR A ; ERROR CODE RET USRSSB: DS 2 ; BUFFER FOR ADDRESS OF USER'S SSB ; ; SORT -- Sort memory-resident file of fixed-length records in an order ; specified by the user; On entry, DE pts to a SORT Specification ; Block (SSB) which contains the following information: ; ; Bytes 0&1: Starting Address of File (1st byte of 1st record) ; Bytes 2&3: Number of Records in the File ; Bytes 4&5: Size of Each Record (in Bytes) ; Bytes 6&7: Address of a Compare Routine Provided by the User ; This routine compares two records, one pted ; to by HL and the other pted to by DE; if the ; record pted to by DE is less in sorting order ; than that pted to by HL, this routine returns ; with Carry Set (C); if the records are equal ; in sorting order, this routine returns with ; Zero Set (Z); no registers asside from the PSW ; are to be affected by this routine ; Bytes 8&9: Address of ORDER Buffer (RECNT*2 in size) ; Byte 10: Flag; 0 means to use pointers, 0FFH means to not ; use pointers ; Byte 11: Unused ; ; SORT does not have any net affect on any registers ; ; ; SORT SPECIFICATION BLOCK (SSB) FOR USE BY SORT ROUTINE ; SSB: FIRSTP: DS 2 ; POINTER TO FIRST RECORD IN FILE RECNT: DS 2 ; NUMBER OF RECORDS IN FILE RECSIZ: DS 2 ; SIZE OF EACH RECORD CMPADR: DS 2 ; ADDRESS OF COMPARE ROUTINE ORDER: DS 2 ; ADDRESS OF ORDER TABLE SFLAG: DS 1 ; USE POINTERS? 0=NO DS 1 ; UNUSED, BUT RESERVED, AT THIS TIME ; ; SORT AND POINTER BUFFERS ; N: DS 2 ; NUMBER OF RECS GAP: DS 2 ; VARIABLE GAP J: DS 2 ; REC PTR 1 JG: DS 2 ; REC PTR 2 IDX: DS 2 ; INDEX PTR PTPTR: DS 2 ; 2-LEVEL INDIRECT PTR PTFIL: DS 2 ; REC PTR ; ; START OF SORT ROUTINE ; SORT: PUSH HL ; SAVE REGS PUSH DE PUSH BC PUSH AF EX DE,HL ; PTR IN HL LD DE,SSB ; COPY HIS SORT BLOCK INTO MINE FOR EASIER ACCESS LD B,12 ; 12 BYTES LONG CALL MOVEB LD HL,(RECNT) ; GET RECORD COUNT LD (N),HL ; SET "N" LD B,H ; ... IN BC LD C,L ; ; CHECK FOR TRIVIAL CASE - 0 OR 1; DON'T DO IT IF SO ; LD A,B ; SEE IF BC=1 OR A ; B=0? JP NZ,SHELL ; DO SORT IF B<>0 LD A,C ; C=0 OR 1? CP 2 JP C,SEXIT ; ; SHELL SORT -- ; THIS SORT ROUTINE IS ADAPTED FROM "SOFTWARE TOOLS" ; BY KERNIGAN AND PLAUGHER, PAGE 106. COPYRIGHT, 1976, ADDISON-WESLEY. ; ON ENTRY, BC=NUMBER OF ENTRIES ; SHELL: LD A,(SFLAG) ; USE POINTERS? OR A ; 0=NO JP Z,SORT2 LD HL,(FIRSTP) ; PT TO FIRST RECORD EX DE,HL ; POINTER TO 1ST RECORD IN DE LD HL,(ORDER) ; PT TO ORDER TABLE ; ; SET UP ORDER TABLE; HL PTS TO NEXT ENTRY IN ORDER TABLE, DE PTS TO NEXT ; REC IN FILE, BC = NUMBER OF RECS REMAINING ; SORT1: LD A,B ; DONE? OR C ; 0 IF SO JP Z,SORT2 DEC BC ; COUNT DOWN LD (HL),E ; STORE LOW-ORDER ADDRESS INC HL ; PT TO NEXT ORDER BYTE LD (HL),D ; STORE HIGH-ORDER ADDRESS INC HL ; PT TO NEXT ORDER ENTRY PUSH HL ; SAVE PTR LD HL,(RECSIZ) ; HL=NUMBER OF BYTES/ENTRY ADD HL,DE ; PT TO NEXT DIR1 ENTRY EX DE,HL ; DE PTS TO NEXT ENTRY POP HL ; GET PTR TO ORDER TABLE JP SORT1 ; ; THIS IS THE MAIN SORT LOOP FOR THE SHELL SORT IN "SOFTWARE TOOLS" BY K&P ; SORT2: LD HL,(N) ; NUMBER OF ITEMS TO SORT LD (GAP),HL ; SET INITIAL GAP TO N FOR FIRST DIVISION BY 2 ; FOR (GAP = N/2; GAP > 0; GAP = GAP/2) SRTL0: OR A ; CLEAR CARRY LD HL,(GAP) ; GET PREVIOUS GAP LD A,H ; ROTATE RIGHT TO DIVIDE BY 2 RRA LD H,A LD A,L RRA LD L,A ; TEST FOR ZERO OR H JP Z,SDONE ; DONE WITH SORT IF GAP = 0 LD (GAP),HL ; SET VALUE OF GAP LD (IDX),HL ; SET I=GAP FOR FOLLOWING LOOP ; FOR (I = GAP + 1; I <= N; I = I + 1) SRTL1: LD HL,(IDX) ; ADD 1 TO I INC HL LD (IDX),HL ; TEST FOR I <= N EX DE,HL ; I IS IN DE LD HL,(N) ; GET N LD A,L ; COMPARE BY SUBTRACTION SUB E LD A,H SBC A,D ; CARRY SET MEANS I > N JP C,SRTL0 ; DON'T DO FOR LOOP IF I > N LD HL,(IDX) ; SET J = I INITIALLY FOR FIRST SUBTRACTION OF GAP LD (J),HL ; FOR (J = I - GAP; J > 0; J = J - GAP) SRTL2: LD HL,(GAP) ; GET GAP EX DE,HL ; ... IN DE LD HL,(J) ; GET J LD A,L ; COMPUTE J - GAP SUB E LD L,A LD A,H SBC A,D LD H,A LD (J),HL ; J = J - GAP JP C,SRTL1 ; IF CARRY FROM SUBTRACTIONS, J < 0 AND ABORT LD A,H ; J=0? OR L JP Z,SRTL1 ; IF ZERO, J=0 AND ABORT ; SET JG = J + GAP EX DE,HL ; J IN DE LD HL,(GAP) ; GET GAP ADD HL,DE ; J + GAP LD (JG),HL ; JG = J + GAP ; IF (V(J) <= V(JG)) CALL ICOMPARE ; J IN DE, JG IN HL ; ... THEN BREAK JP C,SRTL1 ; ... ELSE EXCHANGE LD HL,(J) ; SWAP J, JG EX DE,HL LD HL,(JG) CALL ISWAP ; J IN DE, JG IN HL ; END OF INNER-MOST FOR LOOP JP SRTL2 ; ; SORT IS DONE -- RESTRUCTURE FILE IN SORTED ORDER IN PLACE ; SDONE: LD A,(SFLAG) ; USE POINTERS? OR A ; 0=NO JP Z,SEXIT ; DONE IF NO POINTERS LD HL,(RECNT) ; NUMBER OF RECORDS LD (J),HL ; SAVE COUNT IN J LD HL,(ORDER) ; PTR TO ORDERED POINTER TABLE LD (PTPTR),HL ; SET PTR PTR LD HL,(FIRSTP) ; PTR TO UNORDERED FILE LD (PTFIL),HL ; SET PTR TO FILE BUFFER ; FIND PTR TO NEXT FILE ENTRY SRTDN: LD HL,(J) ; GET ENTRY COUNT LD B,H ; ... IN BC LD C,L LD HL,(PTPTR) ; PT TO REMAINING POINTERS EX DE,HL ; ... IN DE LD HL,(PTFIL) ; HL PTS TO NEXT FILE ENTRY ; FIND PTR TABLE ENTRY SRTDN1: LD A,(DE) ; GET CURRENT POINTER TABLE ENTRY VALUE INC DE ; PT TO HIGH-ORDER POINTER BYTE CP L ; COMPARE AGAINST FILE ADDRESS LOW JP NZ,SRTDN2 ; NOT FOUND YET LD A,(DE) ; LOW-ORDER BYTES MATCH -- GET HIGH-ORDER POINTER BYTE CP H ; COMPARE AGAINST FILE ADDRESS HIGH JP Z,SRTDN3 ; MATCH FOUND SRTDN2: INC DE ; PT TO NEXT PTR TABLE ENTRY DEC BC ; COUNT DOWN LD A,C ; END OF TABLE? OR B JP NZ,SRTDN1 ; CONTINUE IF NOT ; FATAL ERROR -- INTERNAL ERROR; POINTER TABLE NOT CONSISTENT FERR$PTR: CALL PRINT DB 0DH,0AH,'SORT Pointer Error',0 JP CPM ; FOUND THE POINTER TABLE ENTRY WHICH POINTS TO THE NEXT UNORDERED FILE ENTRY ; MAKE BOTH POINTERS (PTR TO NEXT, PTR TO CURRENT UNORDERED FILE ENTRY) ; POINT TO SAME LOCATION (PTR TO NEXT FILE ENTRY TO BE ORDERED) SRTDN3: LD HL,(PTPTR) ; GET PTR TO NEXT ORDERED ENTRY DEC DE ; DE PTS TO LOW-ORDER POINTER ADDRESS LD A,(HL) ; MAKE PTR TO NEXT UNORDERED REC PT TO BUFFER FOR LD (DE),A ; FILE REC TO BE MOVED TO NEXT UNORDERED FILE POS INC HL ; PT TO NEXT PTR ADDRESS INC DE LD A,(HL) ; MAKE HIGH POINT SIMILARLY LD (DE),A ; INTERCHANGE NEXT ENTRY IN LINE WITH THE ENTRY CURRENTLY IN ITS POSITION LD HL,(RECSIZ) ; HL=NUMBER OF BYTES/ENTRY LD B,H ; BC=NUMBER OF BYTES/ENTRY LD C,L LD HL,(PTFIL) ; PT TO ENTRY EX DE,HL ; COPY TO-BE-ORDERED FILE ENTRY TO NEXT ORDERED FILE POSITION LD HL,(PTPTR) ; POINT TO ITS POINTER LD A,(HL) ; GET LOW-ADDRESS POINTER INC HL LD H,(HL) ; GET HIGH-ADDRESS POINTER LD L,A ; HL IS ADDRESS OF UNORDERED ENTRY EX DE,HL ; HL PTS TO ORDERED ENTRY TO BE MOVED, DE PTS TO REPL SRTDN4: PUSH BC ; SAVE COUNT LD A,(DE) ; GET BYTES LD C,(HL) EX DE,HL ; EXCHANGE PTRS LD (DE),A ; PUT BYTE LD (HL),C EX DE,HL ; RESTORE PTRS TO ORIGINAL POP BC ; GET COUNT INC HL ; PT TO NEXT INC DE DEC BC ; COUNT DOWN LD A,B ; DONE? OR C JP NZ,SRTDN4 ; POINT TO NEXT TARGET RECORD POSITION LD HL,(RECSIZ) ; GET SIZE OF RECORD EX DE,HL ; ... IN DE LD HL,(PTFIL) ; PT TO ENTRY JUST PLACED ADD HL,DE ; PT TO NEXT ENTRY LD (PTFIL),HL ; SET POINTER FOR NEXT LOOP ; POINT TO NEXT ENTRY IN POINTER TABLE LD HL,(PTPTR) ; POINTER TO CURRENT REC INC HL ; PT TO NEXT REC INC HL LD (PTPTR),HL ; COUNT DOWN LD HL,(J) ; GET COUNT DEC HL ; COUNT DOWN LD (J),HL ; PUT COUNT LD A,H ; DONE? OR L JP NZ,SRTDN ; EXIT SEXIT: POP AF ; RESTORE REGS POP BC POP DE POP HL RET ; DONE ; ; ISWAP -- Perform exchange of elements whose indices are in HL and DE ; ISWAP: LD A,(SFLAG) ; USE POINTERS? OR A ; 0=NO JP NZ,SWAP ; DO POINTER SWAP CALL ADRCOMP ; COMPUTE ADDRESS OF RECORDS FROM THEIR INDICES PUSH HL ; SAVE HL PTR LD HL,(RECSIZ) ; SIZE OF RECORD LD B,H ; ... IN BC LD C,L POP HL ; GET HL PTR SWAPC: PUSH BC ; SAVE COUNT LD A,(DE) ; GET BYTES LD C,(HL) LD (HL),A ; PUT BYTES LD A,C LD (DE),A ; PUT BYTES INC HL ; PT TO NEXT INC DE POP BC ; GET COUNT DEC BC ; COUNT DOWN LD A,B ; DONE? OR C JP NZ,SWAPC RET ; ; GIVEN INDICES IN HL AND DE, RETURN ADDRESSES OF RECORDS PTED TO BY ; THESE INDICES IN HL AND DE, RESP ; ADRCOMP: PUSH HL ; SAVE HL RECORD CALL ADROFF ; COMPUTE OFFSET TO RECORD PTED TO BY DE LD (REC1),HL ; SAVE ADDRESS OF RECORD POP DE ; GET OLD HL INDEX CALL ADROFF ; COMPUTE OFFSET TO THE DESIRED RECORD EX DE,HL ; ADDRESS IN DE LD HL,(REC1) ; GET ADDRESS EX DE,HL ; ORIGINAL ORDER RET REC1: DS 2 ; TEMP STORAGE FOR SWAPC ADROFF: LD HL,(RECSIZ) ; SIZE OF RECORD LD B,H ; ... IN BC LD C,L LD HL,0 ; OFFSET IN HL ADRO1: DEC DE ; DECREMENT BY 1 SO BASE-RELATIVE LD A,D ; DONE WITH LOOP? OR E JP Z,ADRO2 ADD HL,BC ; ADD IN RECORD SIZE JP ADRO1 ADRO2: EX DE,HL ; OFFSET IN DE LD HL,(FIRSTP) ; PT TO FIRST ENTRY ADD HL,DE ; ADD IN OFFSET RET ; ; SWAP (Exchange) the pointers in the ORDER table whose indexes are in ; HL and DE ; SWAP: PUSH HL ; SAVE HL LD HL,(ORDER) ; ADDRESS OF ORDER TABLE LD B,H ; ... IN BC LD C,L POP HL DEC HL ; ADJUST INDEX TO 0...N-1 FROM 1...N ADD HL,HL ; HL PTS TO OFFSET ADDRESS INDICATED BY INDEX ; OF ORIGINAL HL (0, 2, 4, ...) ADD HL,BC ; HL NOW PTS TO POINTER INVOLVED EX DE,HL ; DE NOW PTS TO POINTER INDEXED BY HL DEC HL ; ADJUST INDEX TO 0...N-1 FROM 1...N ADD HL,HL ; HL PTS TO OFFSET ADDRESS INDICATED BY INDEX ; OF ORIGINAL DE (0, 2, 4, ...) ADD HL,BC ; HL NOW PTS TO POINTER INVOLVED LD C,(HL) ; EXCHANGE POINTERS -- GET OLD (DE) LD A,(DE) ; -- GET OLD (HL) EX DE,HL ; SWITCH LD (HL),C ; PUT NEW (HL) LD (DE),A ; PUT NEW (DE) INC HL ; PT TO NEXT BYTE OF POINTER INC DE LD C,(HL) ; GET OLD (HL) LD A,(DE) ; GET OLD (DE) EX DE,HL ; SWITCH LD (HL),C ; PUT NEW (DE) LD (DE),A ; PUT NEW (HL) RET ; ; ICOMPARE - Compares entries whose indices are in HL and DE; on exit, ; Carry Set means ((DE)) < ((HL)), Zero Set means ((HL)) = ((DE)) ; ICOMPARE: LD A,(SFLAG) ; USE POINTERS? OR A ; 0=NO JP NZ,COMPARE CALL ADRCOMP ; COMPUTE ADDRESSES JP CALLCMP ; CALL COMPARE ROUTINE OF USER ; ; COMPARE compares the entry pointed to by the pointer pointed to by HL ; with that pointed to by DE (1st level indirect addressing); on entry, ; HL and DE contain the numbers of the elements to compare (1, 2, ...); ; on exit, Carry Set means ((DE)) < ((HL)), Zero Set means ((HL)) = ((DE)), ; and Non-Zero and No-Carry means ((DE)) > ((HL)) ; COMPARE: PUSH HL ; SAVE HL LD HL,(ORDER) ; ADDRESS OF ORDER LD B,H ; ... IN BC LD C,L POP HL DEC HL ; ADJUST INDEX TO 0...N-1 FROM 1...N ADD HL,HL ; DOUBLE THE ELEMENT NUMBER TO POINT TO THE PTR ADD HL,BC ; ADD TO THIS THE BASE ADDRESS OF THE PTR TABLE EX DE,HL ; RESULT IN DE DEC HL ; ADJUST INDEX TO 0...N-1 FROM 1...N ADD HL,HL ; DO THE SAME WITH THE ORIGINAL DE ADD HL,BC EX DE,HL ; ; HL NOW POINTS TO THE POINTER WHOSE INDEX WAS IN HL TO BEGIN WITH ; DE NOW POINTS TO THE POINTER WHOSE INDEX WAS IN DE TO BEGIN WITH ; FOR EXAMPLE, IF DE=5 AND HL=4, DE NOW POINTS TO THE 5TH PTR AND HL ; TO THE 4TH POINTER ; LD C,(HL) ; BC IS MADE TO POINT TO THE OBJECT INDEXED TO INC HL ; ... BY THE ORIGINAL HL LD B,(HL) EX DE,HL LD E,(HL) ; DE IS MADE TO POINT TO THE OBJECT INDEXED TO INC HL ; ... BY THE ORIGINAL DE LD D,(HL) LD H,B ; SET HL = OBJECT PTED TO INDIRECTLY BY BC LD L,C ; ; COMPARE DIR ENTRY PTED TO BY HL WITH THAT PTED TO BY DE; ; NO NET EFFECT ON HL, DE; RET W/CARRY SET MEANS DE JP Z,PST ; ; PRINT CHAR ; INC C ; INCR POSITION CALL CSOUT ; PRINT IT ON CON: CP CR ; CHECK FOR JP Z,PCR CP LF ; CHECK FOR JP Z,PLF CP BEL ; CHECK FOR JP Z,PLF CP BS ; CHECK FOR JP Z,PBS JP PSL ; ; -- RESET POSITION COUNT ; PCR: LD C,0 ; RESET JP PSL ; ; , , -- CURSOR DIDN'T ADVANCE ; PLF: DEC C ; BACK UP COUNT BY 1 JP PSL ; ; -- CURSOR WENT BACKWARD, MAYBE ; PBS: LD A,C ; CHECK FOR ZERO OR A JP Z,PSL DEC C ; BACK UP COUNT BY 2 DEC C JP PSL ; ; EXPAND ; PST: LD A,C ; GET COUNT AND 7 ; MASK FOR SUB FROM 8 LD B,A ; STORE TEMPORARILY LD A,8 ; SUBTRACT FROM 8 FOR COUNT SUB B LD B,A ; COUNT IN B ADD A,C ; ADD TO POSITION COUNT LD C,A LD A,' ' ; PRINT PSTL: CALL SOUT DEC B ; COUNT DOWN JP NZ,PSTL JP PSL ; ; PSTR DONE ; PSD: POP AF ; RESTORE REG A AND FLAGS POP BC ; RESTORE REGS POP DE RET ; ; ASCII SPECIAL CHARACTER EQUATES ; NULL EQU 0 ; NULL BEL EQU 7 ; BELL BS EQU 8 ; BACKSPACE TAB EQU 9 ; TAB LF EQU 10 ; LINE FEED CR EQU 13 ; CARRIAGE RETURN CTRLR EQU 'R'-40H ; CTRL-R CTRLU EQU 'U'-40H ; CTRL-U CTRLX EQU 'X'-40H ; CTRL-X DEL EQU 7FH ; DELETE CHAR END ; ; SYSLIB Module Name: SSUA ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.1 public sua ; ; Equates ; bdos equ 5 bsua equ 32 ; set user number ; ; Macros ; putrg macro push af push bc push de push hl endm getrg macro pop hl pop de pop bc pop af endm ; ; SUA sets the user number specified in the low-order 5 bytes ; of A. No error code is returned. ; sua: putrg ; save registers and 1fh ; mask out upper 3 bits ld e,a ; user area in E ld c,bsua ; set user function call bdos getrg ; restore registers ret end ; ; SYSLIB Module Name: SUD1 ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.2 public getud,putud ; ; CONSTANT ; BDOS EQU 5 ; BDOS ENTRY POINT ; ; MACROS ; PUTRG MACRO PUSH AF PUSH BC PUSH DE PUSH HL ENDM GETRG MACRO POP HL POP DE POP BC POP AF ENDM ; ; PUTUD -- SAVE CURRENT USER/DISK FOR LATER RESTORE ; NO REGS AFFECTED ; PUTUD: PUTRG LD C,25 ; GET CURRENT DISK CALL BDOS LD (CDISK),A ; SET CURRENT DISK LD E,0FFH ; GET CURRENT USER LD C,32 CALL BDOS LD (CUSER),A ; SET CURRENT USER JP DONE ; ; GETUD -- RESTORE USER/DISK FROM PREVIOUS PUTUD ; GETUD: PUTRG LD A,(CDISK) ; SELECT DISK LD E,A LD C,14 ; SELECT CALL BDOS LD A,(CUSER) ; SELECT USER LD E,A LD C,32 ; SELECT CALL BDOS DONE: GETRG RET ; ; BUFFERS ; CDISK: DS 1 ; CURRENT DISK CUSER: DS 1 ; CURRENT USER END ; ; SYSLIB Module Name: SUD2 ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.2 public logud ; ; CONSTANTS ; BDOS EQU 5 ; BDOS ENTRY ; ; MACROS ; PUTRG MACRO PUSH AF PUSH BC PUSH DE PUSH HL ENDM GETRG MACRO POP HL POP DE POP BC POP AF ENDM ; ; LOGUD -- LOG IN USER/DISK, WHERE C=USER AND B=DISK ; LOGUD: PUTRG LD E,C ; SELECT USER LD C,32 PUSH BC CALL BDOS POP BC LD E,B ; SELECT DISK LD C,14 CALL BDOS GETRG RET END ; ; SYSLIB Module Name: SUD3 ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.2 public retud ; ; CONSTANT ; BDOS EQU 5 ; ; MACROS ; PUTRG MACRO PUSH AF PUSH DE PUSH HL ENDM GETRG MACRO POP HL POP DE POP AF ENDM ; ; RETUD -- RETURN CURRENT USER AND DISK IN C AND B, RESP ; AFFECT ONLY BC ; RETUD: PUTRG LD C,25 ; GET CURRENT DISK CALL BDOS PUSH AF ; SAVE IT LD E,0FFH ; GET CURRENT USER LD C,32 CALL BDOS LD C,A ; USER IN C POP AF ; GET DISK LD B,A ; DISK IN B GETRG RET END ; ; SYSLIB Module Name: SVERSION ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.6 public version ; Date: 10 Dec 85 ; Version: 3.6 ; Revised: Richard Conn ; Changes: Z80 mnemonics, many minor ; ; Date: 1 Dec 85 ; Version: 3.5 ; Revised: Richard Conn ; Changes: Many minor ; ; Date: 19 Aug 85 ; Version: 3.4 ; Revised: Richard Conn ; Changes: Added SETDMA, LUINIT, LUDIR, LUOPEN, LUREAD, LUCLOSE ; ; Date: 4 Aug 85 ; Version: 3.3 ; Revised: Richard Conn ; Changes: - SFXIO, SFYIO ; - Adding: ; SACAS1, SACAS2, SACAS3, SAGO1, SAGO2, SAIF1, SAIF2, ; SBGO1, SBGO2, ; SHCAS1, SHCAS2, SHCAS3, SHGO1, SHGO2, SHIF1, SHIF2, ; SDGO1, SDGO2, ; SARGV ; ; Date: 4 Jul 85 ; Version: 3.2 ; Revised: Richard Conn ; Changes: - S0FILEIO, S1FILEIO, S2FILEIO, S3FILEIO ; - SFILEIO, SFXIO, SFYIO, SDIR04 ; - SYSLIB3.HLP, SYSLIB4.HLP ; - Adding: ; SFAPPEND, SGRR, SGRR1 ; ; Date: 4 May 85 ; Version: 3.1 ; Revised: Al Dunsmuir ; Changes: - S0FILEIO (FI0$OPEN, F0$GET, FI0$CLOSE, ; FO0$OPEN, F0$PUT, FO0$CLOSE) ; - S1FILEIO (FI1$OPEN, F1$GET, FI1$CLOSE, ; FO1$OPEN, F1$PUT, FO1$CLOSE) ; - S2FILEIO (FI2$OPEN, F2$GET, FI2$CLOSE, ; FO2$OPEN, F2$PUT, FO2$CLOSE) ; - S3FILEIO (FI3$OPEN, F3$GET, FI3$CLOSE, ; FO3$OPEN, F3$PUT, FO3$CLOSE) ; - SFILEIO (FI$OPEN, F$GET, FI$CLOSE, ; FO$OPEN, F$PUT, FO$CLOSE) ; - SFXIO (FXI$OPEN, FX$GET, FXI$CLOSE, ; FXO$OPEN, FX$PUT, FXO$CLOSE) ; ; Previous Version: 1.0 (16 Jan 84) ; ; VERSION -- Return the SYSLIB Version Number in HL; H=Major Version, ; L=Minor Version ; VERS EQU 36 ; Version Number VERSION: LD H,VERS/10 ; GET MAJOR PART LD L,[VERS MOD 10] ; GET MINOR PART RET ; ; Identifying Text ; DB 'SYSLIB ' DB [VERS/10]+'0','.',[VERS MOD 10]+'0' DB ' by Richard Conn' DB 0 END