; ; DU314-01.Z80 ; ;Beginning of Program ; ; ; Environment Definition ; if z3env ne 0 ; ; External ZCPR3 Environment Descriptor ; jp start db 'Z3ENV' ;This is a ZCPR3 Utility db 1 ;External Environment Descriptor z3eadr: dw z3env ; ; Space Added for Initial Macro Definitions ; ;label to help locate when patching db 'INITIAL MACROS:' imac0: db 'G0,D',cr ;macro 0 - display first directory sector db '-D',cr ;macro 1 - back up one sector and display db '+D',cr ;macro 2 - forward one sector and display db '-8D',cr ;macro 3 - back 8 sectors and display db '+8D',cr ;macro 4 - forward 8 sectors and display db 'T0,S1,D',cr ;macro 5 - display first disk sector db '+D,*',cr ;macro 6 - forward, display, repeat db 'D, pop hl ;GET PTR TO NEXT CHAR IN COMMAND LINE exmac2: ld a,(hl) ;GET CHAR ld (de),a ;PUT CHAR inc hl ;PT TO NEXT inc de call mtest ;TEST FOR END OF BUFFER cp cr ;DONE? jp z,exmac3 cp eolch ;LOGICAL EOL? jp nz,exmac2 jp exmac1 ;PROCESS NEXT COMMAND exmac3: ld hl,(ctemp) ;COPY COMMAND LINE BACK ex de,hl ld hl,(inbuf) ;INTO INBUF ex de,hl call copycr ;COPY TO ld hl,(inbuf) ;PT TO INBUF ret ;EXPANSION COMPLETE ; ;Copy Macro Into Command Line Buffer ; copym: ld a,(hl) ;GET CHAR ld (de),a ;PUT CHAR inc hl ;PT TO NEXT inc de call mtest ;CHECK FOR LIMIT cp cr ;END OF MACRO? jp nz,copym ret ; ;Test for Buffer Full ; mtest: push hl ;SAVE HL push af ;SAVE A ld hl,(ctempx) ;CHECK FOR END OF BUFFER ld a,h ;GET PAGE cp d ;CHECK PAGE jp z,macerr pop af ;GET A pop hl ;GET HL ret ; ;Macro Command Expansion Error ; macerr: call ilprt db cr,lf,'Error -- Macro Expanded Command Line too Long',0 jp prmptr ;NEW COMMAND ; ;Save INBUF into PINBUF for later processing by '@' command ; sinbuf: ld hl,(pinbuf) ;PT TO PINBUF (PREVIOUS INBUF) ex de,hl ld hl,(inbuf) ;PT TO INBUF ; ;Copy (HL) to (DE) until Encountered ; copycr: ld a,(hl) ;GET CHAR ld (de),a ;PUT CHAR inc hl ;PT TO NEXT inc de cp cr ;DONE? jp nz,copycr ret ; ;Command Not Found Error ; what: pop hl ; RESTORE HL call ilprt db dim,'Invalid Command at or after ',bright,0 ld a,b ;GET COMMAND LETTER call type ;PRINT IT jp prmptr ; ;Memory full error ; memful: call ilprt db '+++ Out of memory +++' db cr,lf,0 jp prmptr ; ;COMMAND: E ;Edit Current Block ; erow equ 6 ;FIRST ROW OF EDITOR DISPLAY ecol equ 4 ;FIRST COL OF EDITOR DISPLAY ecolc equ ecol+16*3+2 ;FIRST COL OF EDITOR CHAR DISPLAY ecurs equ '>' ;EDITOR CURSOR ; edit: call sinbuf ;SAVE COMMAND LINE AS PREVIOUS ld a,0ffh ld (edrun),a ;EDITOR IS RUNNING ; ; SET UP ARROW KEYS ; ld hl,(envptr) ;PT TO ENVIRONMENT DESCRIPTOR ld de,80h+10h ;PT TO ARROW KEY INFO add hl,de ld de,edcurt ;PT TO CURSOR TABLE ld b,4 ;4 ARROW KEYS edita: ld a,(hl) ;GET CHAR ld (de),a ;STORE CHAR inc hl ;PT TO NEXT inc de ;PT TO NEXT ENTRY inc de inc de djnz edita ;COUNT DOWN ; ; REENTER EDIT WITH PTRS RESET ; REFRESH EDIT SCREEN ; edit0: call cls ;NEW SCREEN call at ; db 2,32 ;ROW 2, COL 32 db 2,ecol ; call ilprt ;BANNER db 'DU3 Block Editor',0 ld h,erow+9 ;POSITION FOR COMMAND DISPLAY ; ld l,1 ld l,9 ; call gotoxy ;POSITION CURSOR call ilprt ;PRINT COMMAND SUMMARY ; added tabs to shift help over db ' -- Movement --' db ' -------------- Operation ---------------',cr,lf db tab,' ^E ' db dim,'Enter: ',bright,'A',dim,' ASCII Chars',bright db ' .',dim,' Next Sector',bright,cr,lf ; db tab,' ^ ' db dim,' ',bright,'H',dim,' Hex Numbers',bright db ' ,',dim,' Last Sector',bright,cr,lf ; db tab,' ^S <-+-> ^D ' db ' ' db ' ^C',dim,' Exit DU3 ',bright db cr,lf db tab,' v ' db 'C',dim,' DU3 Command Line ',bright db ' ^R',dim,' Rescreen ',bright,cr,lf db tab,' ^X ' db 'X',dim,' Exit Editor to DU3',bright db ' ^W',dim,' Write Block',bright db 0 call at ; db 2,65 ; db 2,54 call ilprt db dim,'Position:',bright,0 ; JMP EDITCMD ; ; REFRESH SCREEN DISPLAY DATA ONLY ; editr: xor a ;A=0 ld (eindex),a ;SET INDEX TO 0 (FIRST ELEMENT) ld (ederr),a ;SET NO PREVIOUS ERROR call at ;POSITION CURSOR db erow-2,ecol call inqsub ;PRINT POSITION DATA call edplot ;PLOT BUFFER DATA ; ; INPUT EDITOR COMMAND ; editcmd: call edercl ;CLEAR EDITOR INVALID COMMAND MESSAGE editcmd1: call at ;POSITION FOR COMMAND LINE db 22,10 call ilprt db dim,'Edit Command? ',bright,bs,0 call conin ;GET CHAR call upcase ;CAPITALIZE ld b,a ;COMMAND IN B ld de,edcurt ;PROCESS CURSOR COMMANDS FIRST call cmd ;PROCESS COMMAND ld de,ecmdtbl ;EDITOR COMMAND TABLE call cmd ;PROCESS COMMAND ld a,0ffh ;SET ERROR FLAG ld (ederr),a call at ;CLEAR ERROR MESSAGE db 23,15 call ilprt db 'Invalid Command',0 jp editcmd1 ; ;Clear Editor Invalid Command Message ; edercl: ld a,(ederr) ;PREVIOUS ERROR? or a ;0=NO ret z xor a ;CLEAR FLAG ld (ederr),a call at ;CLEAR ERROR MESSAGE db 23,15 call ilprt db ' ',0 ret ; ;PLOT BUFFER DATA ; edplot: ld h,erow ;SET ROW ld l,ecol-1 ;SET COLUMN (ONE BEFORE FOR LEADING SPACE) call gotoxy ;POSITION CURSOR ex de,hl ;POSITION IN DE ld hl,tbuff ;PT TO DATA ld b,8 ;8 LINES edit00: ld c,16 ;16 ELEMENTS edit01: call space ;PRINT LEADING SPACE (1ST SPACE WIPES CURSOR) ld a,(hl) ;GET BYTE call hex ;PRINT AS HEX inc hl ;PT TO NEXT dec c ;COUNT DOWN jp nz,edit01 ex de,hl ;POSITION AGAIN inc h ;NEXT ROW call gotoxy ex de,hl dec b ;COUNT DOWN jp nz,edit00 ld h,erow ;RESET ROW ld l,ecolc ;RESET COL call gotoxy ;POSITION CURSOR ex de,hl ;POSITION IN DE ld hl,tbuff ;PT TO DATA ld b,8 ;8 LINES edit02: call aster ;PRINT BAR ld c,16 ;16 ELEMENTS edit03: ld a,(hl) ;GET BYTE and 7fh ;MASK MSB cp 7fh ;7FH IS DOT jp z,edit7f cp ' ' ;SPACE OR MORE? jp nc,edit04 edit7f: ld a,'.' ;PRINT DOT edit04: call type ;PRINT BYTE inc hl ;PT TO NEXT dec c ;COUNT DOWN jp nz,edit03 call aster ;PRINT ENDING BAR ex de,hl ;POSITION AGAIN inc h ;NEXT ROW call gotoxy ex de,hl dec b ;COUNT DOWN jp nz,edit02 call edcur ;POSITION CURSOR ret ; ;EDITOR COMMAND TABLE ; ecmdtbl: db cr ;NOP dw editcmd db 'C'-'@' ;^C = EXIT DU3 dw edcc db 'R'-'@' ;^R = REFRESH dw edit0 db 'E'-'@' ;^E=UP dw edup db 'X'-'@' ;^X=DOWN dw eddown db 'D'-'@' ;^D=RIGHT dw edright db 'S'-'@' ;^S=LEFT dw edleft db 'W'-'@' ;WRITE BLOCK dw editwr db ' ' ;NOP dw editcmd db '+' ;ADVANCE dw editplus db '.' ; dw editplus db ',' ; dw editminus db '-' ;BACKUP dw editminus db 'A' ;CHANGE ALPHA dw editalp db 'C' ;COMMAND LINE dw editcl db 'H' ;CHANGE HEX dw edithex db 'X' ;EXIT dw editx db 0 ;END OF TABLE ; ; ARROW KEY DEFINITONS FROM TCAP ; edcurt: db 0 ;0 INDICATES NO ARROW KEYS dw edup db 0 dw eddown db 0 dw edright db 0 dw edleft db 0 ;END OF TABLE ; ;EDITOR BUFFERS ; eindex: ds 1 ;INDEX ENTRY ederr: ds 1 ;ERROR FLAG edrun: ds 1 ;FLAG SAYING THAT EDITOR IS RUNNING ; ;Write Block to Disk ; editwr: call edercl ;CLEAR ERROR LINE call write ;WRITE BLOCK call at db 23,15 ;MESSAGE call ilprt db 'Block Written',0 ld a,0ffh ;SET ERROR ld (ederr),a jp editcmd1 ; ;Enter ASCII Chars ; editalp: call edercl ;CLEAR ERROR LINE call at db 22,35 call ilprt db dim,'Enter Text ( for Hex)',bright db cr,lf,' --> ',0 call rdbuf1 ;INPUT TEXT WITHOUT PROMPT call edprcl ;CLEAR PROMPT LINE ld a,(eindex) ;PT TO POSITION ld de,tbuff ;COMPUTE OFFSET add a,e ld e,a ld a,d adc a,0 ld d,a ;DE PTS TO BYTE, HL PTS TO TEXT edita1: ld a,(hl) ;GET CHAR cp cr ;EOL? jp z,edita2 ;REFRESH SCREEN call getval ;GET ASCII OR VALUE ld (de),a ;UPDATE BYTE inc hl ;PT TO NEXT INPUT CHAR inc e ;PT TO NEXT BUFFER BYTE jp nz,edita1 edita2: call edplot ;REPLOT jp editcmd1 ;DONE-REFRESH SCREEN ; ;Enter Numbers ; edithex: call edercl ;CLEAR ERROR LINE call at db 22,35 call ilprt db dim,'Enter Hex Numbers (#nn for Dec)' db bright db cr,lf,' --> ',0 call rdbuf1 ;INPUT TEXT WITHOUT PROMPT call edprcl ;CLEAR PROMPT LINE ld a,(eindex) ;PT TO POSITION ld de,tbuff ;COMPUTE OFFSET add a,e ld e,a ld a,d adc a,0 ld d,a ;DE PTS TO BYTE, HL PTS TO TEXT edith1: ld a,(hl) ;GET HEX DIGIT cp cr ;EOL? jp z,edita2 ;REFRESH SCREEN cp ' ' ;SKIP SPACES jp nz,edith2 inc hl ;SKIP SPACE jp edith1 edith2: push de ;SAVE PTR call hexin ;GET VALUE AND POSITION HL ld a,e ;... IN A pop de ;GET PTR ld (de),a ;PUT BYTE inc e ;ADVANCE TO NEXT BYTE jp nz,edith1 jp edita2 ;DONE-REFRESH ; ;CLEAR PROMPT LINE ; edprcl: call at ;PROMPT LINE db 22,35 ld b,40 ;40 POSITIONS call edpcl call at ;USER INPUT db 23,1 ld b,79 ;79 POSITIONS edpcl: call space ;CLEAR PROMPT LINE WITH SPACES dec b jp nz,edpcl ret ; ;Enter Command Line from Editor ; editcl: call edercl ;CLEAR ERROR LINE call crlf ;NEW LINE jp prmpte ;GET COMMAND LINE FROM USER ; ;Advance to Next Block ; editplus: call nxtsec ;ADVANCE SECTORS editp1: push hl ld hl,(cursec) ex de,hl call setsec ;SET SECTOR ld hl,(curtrk) ex de,hl call settrk ;SET TRACK pop hl call read ;READ IN BLOCK call clcsub ;CALCULATE GROUP DATA jp editr ;REFRESH DATA ONLY ; ;Backup to Last Block ; editminus: call lstsec ;BACKUP BLOCK jp editp1 ; ;Exit EDIT Mode ; editx: xor a ld (edrun),a ;EDITOR IS NOT RUNNING NOW call edercl ;CLEAR ERROR LINE jp prmptr ; ;Exit DU3 ; edcc: call edercl ;CLEAR ERROR LINE jp exit ; ;EDIT MOVE: UP ; edup: call edccur ;CLEAR CURSOR ld a,(eindex) ;BACKUP INDEX BY 16 sub 16 ; ;Common EDIT MOVE Routine - on input, A=new index ; edmove: and 7fh ;MOD 128 ld (eindex),a call edcur ;SET CURSOR jp editcmd ; ;EDIT MOVE: DOWN ; eddown: call edccur ;CLEAR CURSOR ld a,(eindex) ;INCREMENT INDEX BY 16 add a,16 jp edmove ;COMMON ROUTINE ; ;EDIT MOVE: RIGHT ; edright: call edccur ;CLEAR CURSOR ld a,(eindex) ;INCREMENT INDEX BY 1 inc a jp edmove ;COMMON ROUTINE ; ;EDIT MOVE: LEFT ; edleft: call edccur ;CLEAR CURSOR ld a,(eindex) ;DECREMENT INDEX BY 1 dec a jp edmove ;COMMON ROUTINE ; ;EDIT SUBROUTINE: EDCUR ; Position Editor Cursor at EINDEX ;EDIT SUBROUTINE: EDCCUR ; Clear Editor Cursor at EINDEX ; edcur: push hl ;SAVE HL ld c,ecurs ;CURSOR CHAR call edsetcur call at ;UPDATE DATA ; db 2,75 db 2,64 ; ld a,(eindex) ;PT TO BYTE AT CURSOR ld hl,tbuff add a,l ld l,a ld a,h adc a,0 ld h,a ;HL PTS TO BYTE AT CURSOR ld a,(hl) ;GET BYTE call hex ;PRINT AS HEX call space ld a,(hl) ;GET BYTE pop hl ;RESTORE HL and 7fh ;MASK cp 7fh ;7FH IS DOT jp z,edc7f cp ' ' ;OUTPUT CHAR OR DOT jp nc,type edc7f: ld a,'.' ;DOT jp type edccur: ld c,' ' ;CLEAR CURSOR edsetcur: call edrow ;COMPUTE ROW and 0fh ;COMPUTE COL MOD 16 ld b,a ;RESULT IN B add a,a ;*2 add a,b ;*3 add a,ecol ;ADD IN COL dec a ;SUBTRACT 1 ld l,a ;COL POSITION SET call gotoxy ;POSITION CURSOR ld a,c ;OUTPUT CHAR jp type ; ;Compute Row from EINDEX ; edrow: ld a,(eindex) ;GET INDEX ld b,a ;SAVE IN B rrca ;DIVIDE BY 16 rrca rrca rrca and 0fh ;MASK FOR LSB ONLY add a,erow ;COMPUTE ROW ld h,a ;ROW SET ld a,b ;GET INDEX ret ; ;COMMAND: @ ;Repeat Previous Command Line ; pcmd: ld a,(hl) ;GET NEXT CHAR cp cr ;SHOULD BE jp z,pcmd1 call ilprt db cr,lf,'Warning: Remainder of Command Line after "@" Deleted',0 pcmd1: call ilprt db cr,lf,dim,'Command --',bright,cr,lf,0 ld hl,(inbuf) ;COPY INTO INBUF ex de,hl ld hl,(pinbuf) ;GET PREVIOUS COMMAND pcmd2: ld a,(hl) ;GET CHAR ld (de),a ;PUT CHAR inc hl ;PT TO NEXT inc de cp cr ;END OF LINE? push af ;SAVE FLAG call type ;PRINT CHAR pop af ;GET FLAG jp nz,pcmd2 ld a,lf ; call type ld hl,(inbuf) ;RESTART COMMAND PROCESSING jp prmpti ;INCLUDE LOOP CAPABILITY ; ;COMMAND: : ;Define or Print Macro ;:n Defines Macro n, 0<=n<=9; ::n Prints Macro n, 0<=n<=9 ; mac: ld a,(hl) ;GET NEXT CHAR call upcase ;CAPITALIZE cp 'P' ;PRINT MACRO? jp nz,macrod ;IF NOT, DEFINE MACRO inc hl ;PT TO MACRO NUMBER ld a,(hl) ;GET IT call upcase ;CAPITALIZE cp '@' ;PRINT PREVIOUS COMMAND? jp z,pcpr push af ;SAVE A call cls call z,crlf call ilprt db dim,'Macro Definitions --',bright,0 pop af ;GET A cp 'A' ;PRINT ALL MACROS? jp z,amacpr call mnum ;CHECK FOR VALID NUMBER AND RETURN # IN D inc hl ;PT TO CHAR AFTER MACRO NUMBER call macpr ;PRINT MACRO WHOSE NUMBER IS IN D jp prompt ; ;Print Previous Command ; pcpr: inc hl ;PT TO CHAR AFTER '@' ld de,prompt ;SET UP RET ADR push de ;RETURN ADR ON STACK push hl ;SAVE PTR call ilprt db dim,'Previous Command Line Definition --',bright db cr,lf,'@: ',0 ld hl,(pinbuf) ;PT TO PREVIOUS COMMAND jp mprint ;USE MACRO PRINT FACILITY ; ;Print All Macros ; amacpr: inc hl ;PT TO CHAR AFTER 'A' ld d,0 ;SET FOR FIRST MACRO amprl: call macpr ;PRINT MACRO WHOSE NUMBER IS IN D inc d ;INCREMENT MACRO NUMBER ld a,d ;GET VALUE cp 10 ;DONE? jp nz,amprl jp prompt ;CONTINUE PROCESSING ; ;Print Macro Whose Number (0-9) is in D ; macpr: push hl ;SAVE PTR call ilprt ;PRINT HEADER db cr,lf,dim,0 ld a,d ;GET NUMBER add a,'0' ;CONVERT TO ASCII call type ;PRINT call ilprt db ': ',bright,0 ld hl,(mtabl) ;PT TO TABLE OF MACROS ld e,0 ;PAGE OFFSET OF ZERO; MACRO NUMBER ALREADY IN D add hl,de ;PT TO MACRO mprint: ld a,(hl) ;GET CHAR inc hl ;PT TO NEXT cp cr ;END OF MACRO? push af ;SAVE FLAG call type ;PRINT CHAR pop af ;GET FLAG jp nz,mprint ld a,lf ; call type pop hl ;GET PTR TO NEXT CHAR ret ; ;Check char in A for valid Macro Number (0-9), print error message if ; not, return number in D if so ; mnum: sub '0' ;CONVERT TO 0-9 jp c,mnerr ;ERROR IF LESS cp 10 ;RANGE? jp nc,mnerr ld d,a ;RESULT IN D ret mnerr: call ilprt db cr,lf,'Invalid Macro Number Specified in Command',0 jp prmptr ;NEW COMMAND ; ;Define Macro ; macrod: call mnum ;CHECK NUMBER AND RETURN IN D inc hl ;PT TO CHAR AFTER MACRO NUMBER push hl ;SAVE PTR ld hl,(mtabl) ;PT TO MACRO TABLE ld e,0 ;SET EVEN PAGE add hl,de ;PT TO MACRO ENTRY IN HL ex de,hl ;... IN DE pop hl ;PT TO MACRO TEXT call copycr ;COPY TO jp prmptr ;NEW COMMAND ; ;COMMAND: ! ;Delay for user input ; uwait: call wait ; USE WAIT ROUTINE jp prompt ; ;COMMAND: # ;Print disk statistics ; stats: push hl ;SAVE POINTER TO NEXT COMMAND call cls call z,crlf call ilprt db dim db ' -- Queue Information -- ',bright,cr,lf db cr,lf db 0 call qstats ;PRINT STATUS INFO call ilprt db cr,lf db dim db ' -- Disk Information -- ',bright,cr,lf db cr,lf db dim,'Disk Drive:',tab,tab,bright,' ',0 ld a,(drive) add a,'A' ;CONVERT TO ASCII call type ;PRINT DRIVE LETTER call ilprt db cr,lf,dim,'Tracks: ',tab,tab,bright,' ',0 ld hl,(maxtrk) ;PRINT NUMBER OF TRACKS inc hl call dec call ilprt db cr,lf,dim,'Sectors/Track:',tab,tab,bright,' ',0 ld hl,(spt) ;PRINT NUMBER OF SECTORS/TRACK call dec call ilprt db cr,lf,dim,'Blocks/Group:',tab,tab,bright,' ',0 ld a,(blm) ;PRINT SIZE OF A GROUP inc a ld l,a ld h,0 call dec call ilprt db cr,lf,dim,'Total Groups:',tab,tab,bright,' ',0 ld hl,(dsm) ;PRINT TOTAL NUMBER OF GROUPS ON A DISK call dec call ilprt db cr,lf,dim,'Directory Entries:',tab,bright,' ',0 ld hl,(drm) ;PRINT NUMBER OF DIRECTORY ENTRIES inc hl call dec call ilprt db cr,lf,dim,'System Tracks:',tab,tab,bright,' ',0 ld hl,(systrk) ;PRINT NUMBER OF SYSTEM TRACKS call dec ; call swait call crlf ; call crlf ; pop hl ;RESTORE POINTER TO NEXT COMMAND jp prompt ; ;COMMAND: N ;The following command resets the disk ;system thru CP/M, and may be usable for ;changing the disk density or format. ;This can only be done if your BIOS resets ;the auto-density select parameters at ;every track-zero access. ; newdsk: push hl ;SAVE POINTER TO NEXT LETTER ld c,resetdk ;BDOS RESET DISK FUNCTION call bdos ld a,(drive) ;RESELECT CURRENT DRIVE ld c,a pop hl call select jp prompt ; ;COMMAND: Q ;Queue Control ; queuer: ld a,(hl) ;GET 2ND ARGUMENT call upcase ;CAPITALIZE cp eolch ;END OF LINE? jp z,qstat ;STATUS REPORT cp cr ;END OF LINE? jp z,qstat inc hl ;PT TO AFTER KEY CHAR push hl ;SAVE PTR cp 'Z' ;ZERO QUEUE? jp z,qzero cp 'S' ;SAVE QUEUE? jp z,qfsave pop hl ;GET PTR call ilprt db 'Invalid Queue Command',cr,lf,0 jp prmptr ;ABORT LINE ON ERROR ; ; Zero the Queue ; qzero: ld hl,(direct) ;ZERO QUEUE ld (qnxt),hl ;SET NEXT ld (qlst),hl ;SET LAST ld hl,0 ;ZERO COUNT ld (qcnt),hl pop hl ;GET PTR AND FALL THRU TO QSTAT ; ; Print Status of Queue ; qstat: push hl ;SAVE PTR TO NEXT CHAR ; call cls ; call z,crlf call ilprt db dim,' -- Queue Information -- ',bright,cr,lf,cr,lf,0 call qstats ;PRINT STATUS pop hl ;RESTORE PTR jp prompt qstats: ld hl,(qcnt) ;GET SIZE OF QUEUE call prqcnt ;PRINT DATA call prqspac ;PRINT SPACE AVAILABLE INFO call ilprt db dim,tab,tab,tab,' ',bright,cr,lf db dim,'Group Save Buffer Address:',bright,' ',0 push hl ld hl,(gbuff) ;BC=ADDRESS ld b,h ld c,l pop hl call hexb1 ;PRINT AS HEX call ilprt db ' Hex',cr,lf db 0 call ilprt db dim,'Address of Head of Queue: ',bright,' ',0 ld hl,(qnxt) ;PRINT ADDRESS OF HEAD OF QUEUE ld b,h ;... ADDRESS IN BC ld c,l call hexb1 ;PRINT IN HEX call ilprt db ' Hex',cr,lf db dim,'Address of Tail of Queue: ',bright,' ',0 ld hl,(qlst) ;PRINT ADDRESS OF TAIL OF QUEUE ld b,h ld c,l call hexb1 call ilprt db ' Hex',cr,lf,0 ret ; ; Print Amount of Space Left in Queue ; prqspac: call ilprt db dim,'Blocks left in Queue:',tab,' ',bright,' ',0 ; ld bc,-1 ;SET COUNT ld hl,(qlst) ;GET PTR TO QUEUE TAIL qstat1: inc bc ;INCREMENT COUNT ld de,80h ;PT TO NEXT QUEUE ELEMENT add hl,de ex de,hl ;WRAP AROUND call qwrap ld hl,(qnxt) ;GET PTR TO FIRST ELEMENT ex de,hl ld a,h ;COMPARE cp d jp nz,qstat1 ld a,l cp e jp nz,qstat1 ld h,b ;HL=BLOCK COUNT ld l,c call dec ;PRINT AS DECIMAL call crlf ret ; ; Save Queue as a File ; qfsave: ld a,(hl) ;GET FIRST CHAR OF FILE NAME cp eolch ;EOL? jp z,what cp cr ;EOL? jp z,what ld de,fcb ;START TO FILL FCB xor a ;A=0 ld (de),a ;SELECT DEFAULT DRIVE inc de ;PT TO FILE NAME ld b,8 ;SAVE FILE NAME call mvname ld b,3 ;SAVE FILE TYPE call mvname push hl ;SAVE PTR TO NEXT CHAR ld hl,(qcnt) ;ANY ELEMENTS IN QUEUE? ld a,h or l jp z,qempty push hl ;SAVE QUEUE COUNT call norite ;CAN'T WRITE NOW ld de,fcb ;PT TO FCB call fcbinit ;INIT FCB ld c,delf ;DELETE FILE push de ;SAVE DE call bdos pop de call fcbinit ;INIT FCB AGAIN ld c,makef ;CREATE FILE call bdos pop bc ;GET QUEUE COUNT IN BC ld hl,(qnxt) ;PT TO NEXT BLOCK IN QUEUE qfs1: push bc ;SAVE COUNT ld de,tbuff ;COPY INTO TBUFF ld b,128 ;128 BYTES call move ex de,hl ;PT TO NEXT QUEUE BLOCK IN DE call qwrap ;WRAP AROUND push de ;SAVE PTRS ld de,fcb ;PT TO FCB ld c,writef ;WRITE BLOCK TO FILE call bdos pop hl ;GET PTR TO NEXT BLOCK pop bc ;GET COUNT dec bc ;COUNT DOWN ld a,b ;DONE? or c jp nz,qfs1 ld de,fcb ;CLOSE FILE ld c,closef call bdos call ilprt db 'Queue Saved in File',cr,lf,0 pop hl ;PT TO NEXT CHAR jp prompt fcbinit: push de ;SAVE PTR ld hl,12 ;SKIP TO EX FIELD add hl,de ld b,24 ;ZERO 36 BYTES xor a ;A=0 fcbin1: ld (hl),a ;STORE ZEROES inc hl djnz fcbin1 pop de ;RESTORE PTR ret ; ;COMMAND: * ;Repeat buffer contents ; repeat: call decin ;NN SPECIFIED? ld a,d or e jp z,nnn ;NO -- SET FOR INFINITE LOOP OR SIMPLE REPEAT ld hl,(togo) ;LOAD LOOP FLAG inc hl ;TEST FOR FIRST TIME ld a,h or l ;WAS IT 0FFFFH?; IF SO, WE HAVE NEW VALUE jp nz,nnn ;NO: COUNTING ex de,hl ;GET COUNT ld (togo),hl ;SET COUNT ; nnn: ld hl,(togo) ;GET CURRENT COUNT ex de,hl ;DE=CURRENT COUNT, HL=COUNT LIMIT ld hl,(inbuf) ;PT TO FIRST CHAR FOR REPEAT inc de ;TEST FOR 0FFFFH ld a,d ;IF 0FFFFH, INX D MADE DE=0 or e jp z,prompt ;CONTINOUS LOOP IF 0FFFFH dec de ;COUNT DOWN dec de ;MAKE UP FOR PREV INX D ex de,hl ld (togo),hl ;SET NEW COUNT (1 LESS THAN BEFORE) ld a,h ;ALL DONE? or l ex de,hl ;GET BACK INBUF PTR IN HL jp nz,prompt ;KEEP GOING IF NOT YET ZERO jp prmptr ;ALL DONE ; ;COMMAND: U ;Set CP/M 2.x user number ; user: call decin ;GET REQUESTED USER NO. ld a,(muser) ;GET MAX USER inc a ; to MAX USER+1 ld b,a ;... IN B ld a,e ; input # in E cp b ;VALID? jp nc,usrerr ld a,d ;HIGH-ORDER BYTE MUST BE ZERO FOR VALID NUMBER or a jp nz,usrerr ld a,e ;SAVE USER NUMBER ld (unum),a ld c,suser ;SET USER NUMBER push hl ;SAVE CHAR POINTER call bdos ;SET USER NO. pop hl jp prompt usrerr: call ilprt db 'User Number Out of Range',cr,lf,0 jp prmptr ; ;COMMAND: P ;Toggle print flag ; prntff: ld a,(pflag) ;TOGGLE PRINT FLAG xor 1 ld (pflag),a jp prompt ; ;COMMAND: Z ;Sleep routine, in seconds ; sleep: call decin ;GET COUNT IF ANY ld a,e ;ANY? or a jp nz,sleplp ld e,1 ; 1 SEC DEFAULT ; sleplp: ld a,(clock) ; GET CLOCK SPEED ld d,a ; sleep1: ld bc,41700 ; APPROX 1 SEC @ 1MHz ; sleep2: dec bc ;COUNT DOWN FOR 1 MHz [5 CYCLES] ld a,b ;[5 CYCLES] <-- TOTAL TIME: 24 CYCLES or c ;[4 CYCLES] <-- (24 MU-SECS AT 1MHz) jp nz,sleep2 ;[10 CYCLES] push de call ctlcs ;ABORT? pop de jp z,prmptr dec d ;COUNT DOWN FOR CLOCK SPEED jp nz,sleep1 dec e ;COUNT DOWN NUMBER OF REQUESTED SECONDS jp nz,sleplp jp prompt ; ;Check for control-C or S ; ctlcs: call const ;CHAR AVAILABLE? or a jp nz,getc or 1 ;NO CHAR, RETURN NZ ret ; getc: call conin ;INPUT CHAR and 1fh ;ALLOW ASCII cp 'S'-40h ;WAIT FOR NEXT CHAR IF ^S OR S OR s call z,conin cp 'C'-40h ;CHECK FOR ^C OR C OR c ret ;0 SET IF CTL-C ; ;Initialize Memory Buffers ; initp: xor a ;A=0 ld (hexad),a ;CLEAR ADDRESS ld (hexad+1),a ld (pflag),a ;SET NO PRINT ld (savefl),a ;SET NO SAVE DONE ld (wrflg),a ;MAY NOT WRITE ld (dirpos),a ;SET NO DIRECTORY POSITION ld (findfl),a ;SET NO POSITION inc a ;A=1 ld (ftsw),a ;SET SEARCH WITHOUT INCREMENT ld (notpos),a ;NOT POSITIONED ld hl,0 ;HL=0 ld (qcnt),hl ;SET NO ELEMENTS IN QUEUE ld (mfptr),hl ;SET NO MULTI FILE PTR ld (curtrk),hl ;SET TRACK 0 inc hl ;HL=1 ld (cursec),hl ;SET LOGICAL SECTOR 1 ld (physec),hl ;SET PHYSICAL SECTOR 1 ld hl,(pinbuf) ;SET PREVIOUS COMMAND TO NIL ld (hl),cr ;CLEAR PREVIOUS COMMAND ld hl,(direct) ;SET FIRST AND LAST QUEUE ELEMENT PTRS ld (qnxt),hl ld (qlst),hl ld hl,(mtabl) ;CLEAR MACRO TABLE ld b,10 ;10 ENTRIES ld de,imac0 ;point to beginning of default macro table initp1: push hl ;save pointer to start of each macro initp2: ld a,(de) ;get next initial macro character ld (hl),a ;store it in macro table inc de inc hl cp cr ;end of macro? jp nz,initp2 pop hl ;retrieve pointer to start of this macro dec b ;see if we've done all macros ret z ;if so, return inc h ;point to next macro jp initp1 ; ;Set up flags, etc, at initialization ;Find our way at initialization ; getstp: push hl ld hl,(inbuf) ;PT TO INPUT BUFFER ld (hl),cr ;INITIALIZE INPUT BUFFER pop hl ld c,suser ;GET USER NUMBER ld e,0ffh ;GET USER call bdos ld (unum),a ;SET USER NUMBER ld c,getdsk call bdos ;GET CURRENT DISK ld c,a ;WE HAVE TO SELECT jp select ;TO GET THE DPH ; ;COMMAND: L ;Log in the selected disk ; login: call dolog jp prompt ; dolog: ld a,(hl) ;DISK REQUESTED? ld de,0 cp cr ;NO REQUEST OF PHYSICAL EOL jp z,lgnodk cp eolch ;NO REQUEST IF LOGICAL EOL jp z,lgnodk call upcase ;CAPITALIZE inc hl ;POINT TO NEXT CHAR sub 'A' ;CONVERT TO 0-15 ld c,a ;DISK NUMBER IN C ld a,(mdisk) ;GET MAX DISK ld b,a ;... IN B ld a,c cp b jp c,select call ilprt db 'Disk Letter Out of Range',cr,lf,0 jp prmptr ; ;Select Disk Whose Number is in C (A=0, B=1, etc) ; select: push hl ;SAVE PTR TO NEXT COMMAND LETTER ld a,c ld (drive),a ;REMEMBER LATER WHERE WE ARE ; vseldk: call $-$ ;ADDR FILLED IN BY 'INIT' ld a,h or l jp z,what ;SELECT ERROR ld e,(hl) ;GET THE SECTOR TABLE PNTR inc hl ld d,(hl) inc hl ex de,hl ld (sectbl),hl ;SET THE SECTOR TABLE PTR ld hl,8 ;OFFSET TO DPBPTR add hl,de ld a,(hl) ;PICK UP DPB POINTER inc hl ; TO USE ld h,(hl) ; AS PARAMETER ld l,a ; TO LOGIT call logit ld hl,(systrk) ;RESET TRACK AND SECTOR ex de,hl ; TO DIRECTORY call settrk ; ON EVERY ld de,1 ; LOGIN call setsec ; CHANGE ld hl,(physec) ;THIS LOGIC WILL TELL ld a,h ; IF FIRST SEC or l ; IS PHYSICAL 0 ld (first0),a call clcsub ;CALCULATE WHAT GROUP/GRPDISP WE ARE IN pop hl ;GET PTR TO NEXT LETTER ; lgnodk: call norite ;SET NO DISK I/O DONE (NO POSITION) ret ; ;COMMAND: < ;Save the current sector ; Special Form of