#asm ; ZSC-COMP.LIB - SUPPORT ROUTINES FOR SMALL-C COMPILER ; Supplemented with routines from Mike Bernson's version ; ; ; ; DEFINITIONS ; CR EQU 0DH LF EQU 0AH BS EQU 08 DEL EQU 7FH CZ EQU 1AH ESC EQU 1BH IOBYTE EQU 3 CURDSK EQU 4 BDOS EQU 5 FCB EQU 5CH OUTBUF EQU 80H ; ; cpm ; cpm: POP HL POP BC POP DE PUSH DE PUSH BC PUSH HL CALL 5 JP ccsxt ; ; putc. ; putc: POP BC POP DE POP HL PUSH HL PUSH DE PUSH BC LD A,(CONFLG) CP 1 LD A,L JP NZ,WNB JP ATOVDU ; ; getc - GET BYTE FROM READ (CH 2) OR INCLUDE (3) ; getc: POP BC POP HL PUSH HL PUSH BC LD A,L CP 2 JP NZ,GETC3 CALL GNB1K GETC1: CP CZ JP NZ,GETC2 LD A,0FFH GETC2: JP ccsxt GETC3: CALL GNB1KB JP GETC1 ; ; gets ; gets: POP HL POP DE PUSH DE PUSH HL CALL INLIN EX DE,HL RET ; ; OPEN FILE ; ONLY 3 SORTS NEEDED ; 1. WRITE FILE USING THE STANDARD CPM FCB AND BUFFER (CHANNEL 1) ; CAN BE CON:OR LST: ; 2. MAIN READ USING FCBI1K AND 1K I/P BUFFER (CHANNEL 2) ; 3. #INCLUDE READ USING FCBIB1K AND 1K BUFFER (CHANNEL 3) ; fopen: POP BC POP DE POP HL PUSH HL PUSH DE PUSH BC LD A,(DE) AND 5FH CP 'W' JP NZ,FOPEN1 LD DE,1 PUSH DE JP FOPEN4 FOPEN1: CP 'R' JP NZ,FOPEN2 LD DE,2 LD A,E PUSH DE LD DE,FCBI1K JP FOPEN7 FOPEN2: CP 'I' JP Z,FOPEN3 LD HL,0 RET FOPEN3: LD DE,3 LD A,E PUSH DE LD DE,FCBIB1K JP FOPEN7 FOPEN4: PUSH HL LD DE,CONSTR CALL COMPSTR JP Z,FOPEN5 POP HL PUSH HL LD DE,LSTSTR CALL COMPSTR JP NZ,FOPEN6 LD A,1 FOPEN5: LD (LSTFLAG),A POP DE POP HL LD A,L LD (CONFLG),A RET FOPEN6: POP HL LD DE,FCB LD A,1 FOPEN7: CALL SETFCB CP 1 JP NZ,FOPEN8 FOPEN7A: PUSH DE LD DE,OUTBUF CALL SETDMA POP DE CALL DELFIL CALL CREATFL JP Z,DIRFUL XOR A LD (OBP),A POP HL RET FOPEN8: POP HL ;CHAN NO PUSH HL PUSH DE LD A,L CP 2 JP NZ,FOPEN9 LD DE,IBUF1K CALL SETDMA POP DE CALL OPENFL JP Z,NOFILE LD HL,IBUF1K+1024 LD (IBP1K),HL POP HL RET FOPEN9: LD DE,IBUF1KB CALL SETDMA POP DE CALL OPENFL JP Z,NOFILE LD HL,IBUF1KB+1024 LD (IBP1KB),HL POP HL RET ; COMPSTR: LD B,4 COMPST1: LD A,(HL) CALL CAPSET ;CONVERT TO U/C EX DE,HL CP (HL) EX DE,HL RET NZ ;MATCH FAILED INC HL INC DE DEC B JP NZ,COMPST1 XOR A ;SET Z AND SET A TO 0 RET ; ; fclose ; fclose: POP BC POP HL PUSH HL PUSH BC LD A,L CP 1 RET NZ LD A,(CONFLG) CP 1 JP Z,FCLOS1 LD A,CZ CALL WNB LD DE,OUTBUF CALL SETDMA LD DE,FCB CALL DWRITE CALL CLOSEFL FCLOS1: XOR A LD (LSTFLAG),A LD (CONFLG),A RET ; ; SET FCB. ENTER WITH DE->FCB, HL->FILENAME, A NEEDS PRESERVING ; SETFCB: PUSH AF PUSH HL PUSH DE CALL CLEAR POP DE POP HL PUSH DE LD (FNSTORE),HL CALL SCRUB SETFCB1: INC HL LD A,(HL) CP ':' DEC HL JP NZ,SETFCB2 LD A,(HL) CALL CAPSET SUB '@' LD (DE),A INC HL INC HL JP SETFCB3 SETFCB2: XOR A LD (DE),A SETFCB3: INC DE LD B,8 SETFCB4: CALL SCRUB LD A,(HL) CALL CAPSET CP '.' JP Z,SETFCB5 CP 0 JP Z,SETFCB7 LD (DE),A INC HL INC DE DEC B JP NZ,SETFCB4 SETFCB5: CALL SCRUB LD A,(HL) CP 0 JP Z,SETFCB7 CP 20H JP Z,SETFCB7 CP '.' INC HL JP NZ,SETFCB5 LD B,3 POP DE PUSH DE PUSH HL LD HL,9 ADD HL,DE EX DE,HL POP HL SETFCB6: CALL SCRUB LD A,(HL) CALL CAPSET CP 0 JP Z,SETFCB7 LD (DE),A INC HL INC DE DEC B JP NZ,SETFCB6 SETFCB7: POP DE POP AF RET ; ; Scrub out '<','"', and '>' from file name ; SCRUB: LD A,(HL) CP ' ' JR NZ,SCRUB1 INC HL JR SCRUB SCRUB1: CP '"' JR NZ,SCRUB2 INC HL JR SCRUB SCRUB2: CP '<' JR NZ,SCRUB3 INC HL JR SCRUB SCRUB3: CP '>' JR NZ,SCRUB4 INC HL JR SCRUB SCRUB4: CP 27H ;"'" RET NZ INC HL JR SCRUB ; CLEAR: PUSH DE POP HL LD (HL),0 INC HL LD A,20H LD B,11 CLEAR1: LD (HL),A INC HL DEC B JP NZ,CLEAR1 XOR A LD (HL),A LD HL,20H ADD HL,DE LD (HL),A RET ; CAPSET: CP 61H ;'a' RET C CP 7BH ;'z'+1 RET NC SUB 20H RET ; DIRFUL: CALL PFILE LD DE,DFLMSG DIRFUL1: CALL PMESS JP 0 ;Exit to CP/M ; NOFILE: CALL PFILE LD DE,NOFLMSG JP DIRFUL1 ; ; CONSTR: DEFB 'CON:' LSTSTR: DEFB 'LST:' NOFLMSG: DEFB ' - No such file' DEFW 0A0DH DEFB '$' DFLMSG: DEFB ' - Directory full' DEFW 0A0DH DEFB '$' ; ;PRINT OUT FILE NAME POINTED TO BY (FNSTORE) ; PFILE: PUSH HL CALL crlf LD HL,(FNSTORE) PFILE1: LD A,(HL) CP 0 JR Z,PFILE2 CALL ATOVDU INC HL JR PFILE1 PFILE2: POP HL RET ; ; O/P FLAG BYTES ; LSTFLAG: DEFB 0 ;LST: ON IF 1 CONFLG DEFB 0 ;FLAG TO SHOW CON: IS THE O/P FILE FNSTORE: DEFS 2 ;Store pointer to file name ; ATOVDU: PUSH AF PUSH HL PUSH DE PUSH BC LD C,2 LD E,A PUSH DE CALL BDOS POP DE LD C,5 LD A,(LSTFLAG) CP 1 CALL Z,BDOS POP BC POP DE POP HL POP AF RET ; ; crlf ; crlf: PUSH AF LD A,CR CALL ATOVDU LD A,LF CALL ATOVDU POP AF RET ; VDUTOA: CALL CHARIN JP ATOVDU ; CHARIN: PUSH HL PUSH DE PUSH BC LD HL,(1) LD DE,6 ADD HL,DE LD DE,CHRIN1 PUSH DE JP (HL) CHRIN1: POP BC POP DE POP HL PUSH AF CP 3 JP Z,0 POP AF CP 10H RET NZ PUSH HL LD HL,LSTFLAG LD A,1 XOR (HL) LD (HL),A POP HL JP CHARIN ; INLIN: PUSH HL PUSH DE PUSH BC LD B,0 EX DE,HL INLIN1: CALL CHARIN CP CR JP Z,INLIN3 CP BS JP Z,INLIN2 CP DEL JP Z,INLIN2 PUSH AF LD A,4EH CP B JP Z,INLIN4 POP AF CALL ATOVDU LD (HL),A INC HL INC B JP INLIN1 INLIN2: XOR A CP B JP Z,INLIN1 LD A,BS CALL ATOVDU DEC HL DEC B JP INLIN1 INLIN3: CALL crlf XOR A LD (HL),A POP BC POP DE POP HL RET INLIN4: LD A,BS CALL ATOVDU POP AF DEC HL CALL ATOVDU LD (HL),A INC HL JP INLIN1 ; ; ASSORTED DISK ROUTINES - MANY BASED ON THOSE IN CPMUG VOL 16. ; ; ENTRY IS A GENERAL REGISTER SAVER FOR USE WITH BDOS CALLS ; ENTRY: PUSH HL PUSH DE PUSH BC CALL 5 POP BC POP DE POP HL RET ; ; DELFIL - DELETE FILE. FCB POINTED BY DE ; DELFIL: PUSH BC LD C,19 ;DELETE CALL ENTRY POP BC ;NO EXIT CONDS RET ; ; PMESS - PRINTS OUT MESSAGE ->DE UNTIL $ ; PMESS: PUSH AF PUSH BC LD C,9 CALL ENTRY POP BC POP AF RET ; ; OPENFL OPEN AN EXISTING FILE WHOSE FCB IS POINTED TO BY DE ; OPENFL: PUSH HL PUSH BC LD HL,12 ADD HL,DE LD (HL),0 LD HL,32 ADD HL,DE LD (HL),0 LD C,15 CALL ENTRY CP 0FFH POP BC POP HL RET ; ; CLOSEFL - CLOSE FILE WHOSE FCB IS POINTED TO BY DE ; CLOSEFL: PUSH BC LD C,16 CALL ENTRY POP BC CP 0FFH RET ; ; CREATFL - CREATE FILE WHOSE FCB IS POINTED TO BY DE ; CREATFL: PUSH BC LD C,22 CALL ENTRY CP 0FFH POP BC RET ; ; SETDMA - SET DMA BUFFER TO ADDRESS IN DE ; SETDMA: PUSH BC LD C,26 CALL ENTRY POP BC RET ; ; DREAD - READ A FILE SECTOR. DE POINTS TO FCB ; DREAD: PUSH BC LD C,20 CALL ENTRY CP 0 POP BC RET ; ; DWRITE - WRITE A FILE SECTOR. DE POINTS TO FCB ; DWRITE: PUSH BC LD C,21 CALL ENTRY CP 0 POP BC RET ; ; MAIN READ VERSION ; GNB1K - GET NEXT BYTE FROM 1K BUFFER. REFILL BUFF WHEN NEEDED ; ; DEFINE BUFFERS ETC. IBUF1K: DEFS 1024 ;I/P BUFF IBP1K: DEFS 2 ;BUFFER POINTER GBP1K: DEFS 2 ;TEMP BUFFER POINTER FCBI1K: DEFB 0 ;FCB FOR BUFFERED FILE DEFS 35 ;REST OF FCB ; GNB1K: PUSH HL PUSH DE LD HL,(IBP1K) LD DE,IBUF1K+1024 CALL DPCMP POP DE POP HL JP NZ,GB1K2 PUSH HL PUSH DE PUSH BC LD HL,IBUF1K LD (GBP1K),HL LD B,8 GB1K1: PUSH BC LD HL,(GBP1K) EX DE,HL CALL SETDMA LD DE,FCBI1K CALL DREAD LD HL,(GBP1K) LD DE,128 ADD HL,DE LD (GBP1K),HL POP BC DEC B JP NZ,GB1K1 POP BC POP DE LD HL,IBUF1K LD (IBP1K),HL POP HL GB1K2: PUSH HL LD HL,(IBP1K) LD A,(HL) INC HL LD (IBP1K),HL POP HL CP 0AH JP Z,GNB1K RET ; ; #INCLUDE VERSION ; GNB1KB - GET NEXT BYTE FROM 1K BUFFER. REFILL BUFF WHEN NEEDED ; IBUF1KB: DEFS 1024 ;I/P BUFF IBP1KB: DEFS 2 ;BUFFER POINTER GBP1KB: DEFS 2 ;TEMP BUFFER POINTER FCBIB1K: DEFB 0 ;FCB FOR BUFFERED FILE DEFS 35 ;REST OF FCB ; GNB1KB: PUSH HL PUSH DE LD HL,(IBP1KB) LD DE,IBUF1KB+1024 CALL DPCMP POP DE POP HL JP NZ,GB1KB2 PUSH HL PUSH DE PUSH BC LD HL,IBUF1KB LD (GBP1KB),HL LD B,8 GB1KB1: PUSH BC LD HL,(GBP1KB) EX DE,HL CALL SETDMA LD DE,FCBIB1K CALL DREAD LD HL,(GBP1KB) LD DE,128 ADD HL,DE LD (GBP1KB),HL POP BC DEC B JP NZ,GB1KB1 POP BC POP DE LD HL,IBUF1KB LD (IBP1KB),HL POP HL GB1KB2: PUSH HL LD HL,(IBP1KB) LD A,(HL) INC HL LD (IBP1KB),HL POP HL CP 0AH JP Z,GNB1KB RET ; ; WRITE NEXT BYTE TO FILE VIA STANDARD BUFFER AT 80H WITH THE ; STANDARD FCB. ; WNB: PUSH HL PUSH DE PUSH AF LD A,(OBP) CP 80H JP NZ,WNB0 LD DE,OUTBUF CALL SETDMA LD DE,FCB CALL DWRITE JP Z,WNB00 CALL PFILE LD DE,WERRMSG CALL PMESS JP 100H WERRMSG: DEFB ' Write Error' DEFW 0A0DH DEFB '$' WNB00: XOR A WNB0: LD E,A LD D,0 INC A LD (OBP),A LD HL,OUTBUF ADD HL,DE POP AF LD (HL),A POP DE POP HL RET ; OBP: DEFS 1 ; DPCMP: PUSH BC LD B,A LD A,H CP D JP NZ,DPCMP1 LD A,L CP E DPCMP1: LD A,B POP BC RET ; Modified CRUN.LIB routines by Ron Cain ; ccgchar: LD A,(HL) ccsxt: LD L,A RLCA SBC A,A LD H,A RET ccgint: LD A,(HL) INC HL LD H,(HL) LD L,A RET ccpchar: LD A,L LD (DE),A RET ccpint: LD A,L LD (DE),A INC DE LD A,H LD (DE),A RET ccor: LD A,L OR E LD L,A LD A,H OR D LD H,A RET ccxor: LD A,L XOR E LD L,A LD A,H XOR D LD H,A RET ccand: LD A,L AND E LD L,A LD A,H AND D LD H,A RET cceq: CALL cccmp RET Z DEC HL RET ccne: CALL cccmp RET NZ DEC HL RET ccgt: EX DE,HL JP cclt ccle: CALL cccmp RET Z RET C DEC HL RET ccge: CALL cccmp RET NC DEC HL RET cclt: CALL cccmp RET C DEC HL RET cccmp: LD A,E SUB L LD E,A LD A,D SBC A,H LD HL,1 JP M,cccmp1 OR E RET cccmp1: OR E SCF RET ccuge: CALL ccucmp RET NC DEC HL RET ccult: CALL ccucmp RET C DEC HL RET ccugt: EX DE,HL JP ccult ccule: CALL ccucmp RET Z RET C DEC HL RET ccucmp: LD A,D CP H JP NZ,ccucmp1 LD A,E CP L ccucmp1: LD HL,1 RET ccasr: EX DE,HL ccasr1: LD A,H RLA LD A,H RRA LD H,A LD A,L RRA LD L,A DEC E JP NZ,ccasr1 RET ccasl: EX DE,HL ccasl1: ADD HL,HL DEC E JP NZ,ccasl1 RET ccsub: LD A,E SUB L LD L,A LD A,D SBC A,H LD H,A RET ccneg: CALL cccom INC HL RET cccom: LD A,H CPL LD H,A LD A,L CPL LD L,A RET ccmult: LD B,H LD C,L LD HL,0 ccmult1: LD A,C RRCA JP NC,ccmult2 ADD HL,DE ccmult2: XOR A LD A,B RRA LD B,A LD A,C RRA LD C,A OR B RET Z XOR A LD A,E RLA LD E,A LD A,D RLA LD D,A OR E RET Z JP ccmult1 ccdiv: LD B,H LD C,L LD A,D XOR B PUSH AF LD A,D OR A CALL M,ccdeneg LD A,B OR A CALL M,ccbcneg LD A,16 PUSH AF EX DE,HL LD DE,0 ccdiv1: ADD HL,HL CALL ccrdel JP Z,ccdiv2 CALL cccbcde JP M,ccdiv2 LD A,L OR 1 LD L,A LD A,E SUB C LD E,A LD A,D SBC A,B LD D,A ccdiv2: POP AF DEC A JP Z,ccdiv3 PUSH AF JP ccdiv1 ccdiv3: POP AF RET P CALL ccdeneg EX DE,HL CALL ccdeneg EX DE,HL RET ccdeneg: LD A,D CPL LD D,A LD A,E CPL LD E,A INC DE RET ccbcneg: LD A,B CPL LD B,A LD A,C CPL LD C,A INC BC RET ccrdel: LD A,E RLA LD E,A LD A,D RLA LD D,A OR E RET cccbcde: LD A,E SUB C LD A,D SBC A,B RET ; ; ; TAKE COMMAND BUFFER AND BUILD POINTER LIST ; Routine derived from Mike Bernson's Small-C in CUG ; ccinit: LD HL,(6) DEC HL LD SP,HL LD HL,80H LD E,(HL) LD D,0 ADD HL,DE INC HL LD (HL),0 LD DE,cchptr LD HL,80H LD BC,1 ccinit2: INC HL LD A,(HL) OR A JP Z,ccinit4 CP ' ' JP Z,ccinit2 LD A,L LD (DE),A LD A,H INC DE LD (DE),A INC DE INC C ccinit3: INC HL LD A,(HL) OR A JP Z,ccinit4 CP ' ' JP NZ,ccinit3 LD (HL),0 JP ccinit2 ccinit4: LD HL,cchptr-2 PUSH BC ;argc PUSH HL ;argv CALL main JP 0 DEFW ccNULL cchptr: DEFW ccNULL,ccNULL,ccNULL,ccNULL,ccNULL DEFW ccNULL,ccNULL,ccNULL,ccNULL,ccNULL DEFW ccNULL,ccNULL,ccNULL,ccNULL,ccNULL DEFW ccNULL,ccNULL,ccNULL,ccNULL,ccNULL DEFW ccNULL,ccNULL,ccNULL,ccNULL,ccNULL ccNULL: DEFB 'NONAME',0 ; ; From Mike Bernson ; USED BY SWITCH TO SEARCH TABLE ; CALLING FORMAT FROM COMPILER ; DE-POINTER TO TABLE ; HL-WHERE TO GO IF VALUE NOT IN TABLE ; BC- NUMBER OF ENTRY IN TABLE ; ccswtch: EX (SP),HL EX DE,HL ccswch1: LD A,E CP (HL) INC HL JP NZ,ccswch2 LD A,D CP (HL) JP NZ,ccswch2 INC HL LD E,(HL) INC HL LD D,(HL) EX DE,HL POP BC JP (HL) ccswch2: INC HL INC HL INC HL DEC B JP NZ,ccswch1 EX (SP),HL POP BC JP (HL) #endasm  (HL) INC HL JP NZ,ccswch2 LD A,D CP (HL) JP NZ,ccswch2 INC HL