; PWDIR2.ASM -- DISK DIRECTORIES FROM INSIDE THE PW EDITOR -- ; ; PWDIR2.ASM -- PWDIR.ASM by Ron Friedrich, 5/1/87; modifications ; in this version by Andrew Marchant Shapiro, 4/30/89. ; ; NOTE: This version will ONLY work with Perfect Writer 1.20; it ; probably can be modified for 1.03 without trouble, but be careful! ; ; Ron's original PWDIR.ASM addressed two shortfalls in the PW editor: ; it allowed you to get a directory of any disk from within the editor, ; and it automatically logged in new disks, so you didn't need to ; worry about hitting a disk R/O error. ; ; The one problem was that Ron made space for it by overwriting the ; Perfect Speller functions that integrated PW with its spell checker. ; That was no real problem unless you LIKED PS, and I do, since I have ; a RAMdisk that's just big enough for PW and PS to reside on. No ; other spelling checker quite fit, or was as nicely integrated. ; ; So I decided to fix things up. In this version of PWDIR.ASM, PWDIR is ; added on the END of PW.COM instead of in the middle. You assemble ; this file to HEX, and patch it onto PW.COM with DDT. You then have ; to SAVE 142 PW.COM. This makes a PW file that's 36K long ; instead of 35K on the disk, but that's no problem. ; ; OK, so the patch is in place. HOW DO YOU ACTIVATE THE SUCKER? ; For this part, you need DDT or PATCH or somesuch. Use the ; PW.SYM file (it came with PW) to find a function you don't ; really need -- like the HELP function, MHELP, which resides at ; 45F1H. Go to address 45F1H, and patch in the following code: ; ; CALL 89A0 ; RET ; ; If you're doing this with PATCH, enter the following bytes: ; ; CD A0 89 C9 ; ; and save the result. Now, whenever you push the HELP key sequence ; (usually ^X-H or ESC-H), it calls MHELP, which in turn calls -- ; yup -- that set of routines hanging off the end of PW. No ; sacrifice of internal code is needed, beyond your giving up ; your least favorite function. You might want to patch in the ; calling code at MWHATVER (4AC9). That's the really useful function ; that returns the version and date for PW. Wherever you do the ; patch, the code remains the same. ; ; Note -- the directory output overwrites what you have on the screen, ; but doesn't actually enter the buffer. It's video only. To get back ; to your editing session. use the refresh screen command, ^L or ESC-^L. ; ; ; -----------------------IMPORTANT------------------------- ; ; Note that I have removed the disk system reset code from ; PWDIR.ASM. The reason has to do with the fact that Ron ; located it at MGOSPELL, the routine that calls PS.COM in the ; first place, and that most people still using CP/M now have ; BDOS replacements that handle logging in new floppies ; ; --------------------------------------------------------- ; ; The modified code follows. Like Friedrich's original, it's PD, ; and you can give it to anyone you want... ; ; ; PWDIR2.ASM -- ANDREW MARCHANT SHAPIRO rev. 4/30/89 ; PWDIR.ASM -- RON FRIEDRICH rev. 5/1/87 ; YES EQU 0FFH NO EQU 0 ; ; ORG 36E1H TAIL EQU 89A0H OVLSTART EQU 5F00H ;NEXT ROUND SECTOR ADR AFTER MGOSPELL ; RECSTART EQU (OVLSTART-100H)/80H ; ; ;bdos functions CONIN EQU 1 ;READ CONSOLE (C; BYTE RETURNED TO A) CONOUT EQU 2 ;TYPE CHARACTER (C; BYTE IN E) PRINTS EQU 9 ;PRINT STRING FUNCTION (C; ADR IN DE) RSTDSK EQU 13 ;RESET DISK SYSTEM (C) SELDSK EQU 14 ;SELECT DISK (C; DISK # IN E) OPENF EQU 15 ;OPEN FILE CLOSEF EQU 16 ;CLOSE FILE SRCH EQU 17 ;SEARCH DIRECTORY (C; FCB IN DE) SRCHMOR EQU 18 ;SEARCH FOR NEXT IN DIRECTORY (C) DELF EQU 19 ;DELETE FILE READF EQU 20 ;READ FILE WRITEF EQU 21 ;WRITE FILE MAKEF EQU 22 ;CREATE FILE CURDSK EQU 25 ;CURRENT DISK (C; DISK # RETURNED IN A) SETDMA EQU 26 ;(C; DMA adr in DE) ALLOC EQU 27 ;Get ALLOCATION address (C; returned in HL) PARAMS EQU 31 ;Get DISK PARAMETER address (C; returned in HL) READRND EQU 33 ;READ RANDOM FILE ; ;BDOS ADR BDOS EQU 5 ;DOS ENTRY POINT FCB1 EQU 5CH ;DEFAULT FILE CONTROL BLOCK DMA1 EQU 80H ;DEFAULT DIRECT (DISK) MEMORY ACCESS AREA FCBLEN EQU 36 CPMREC EQU 33 ; ; NON GRAPHIC CHARACTERS LF EQU 10 ;LINE FEED UP EQU 11 ;CURSOR UP CR EQU 13 ;CARRIAGE RETURN CLINE EQU 24 ;CLEAR TO END OF LINE CLEAR EQU 26 ;CLEAR SCREEN ESC EQU 27 HOME EQU 30 SPACE EQU 32 ; ;DISPLAY DISK DIRECTORY ROUTINE: ; ORG TAIL PUSH B CALL TYPE DB ESC,'=7 ',CLINE,'DIRECTORY: Which disk drive? ',0 mvi c,conin call bdos CPI 'A' JC ABORT call upcase STA DIRSTAT ; MVI C,CURDSK CALL BDOS STA OLDSEL MVI C,RSTDSK ;NB: also resets DMA to 80H CALL BDOS LDA DIRSTAT SUI 'A' MOV E,A MVI C,SELDSK CALL BDOS MVI A,1 STA FIVE MVI B,5 LXI H,COLCT MVI M,4 INX H XRA A CALL FILLMEM LXI H,OVLSTART SHLD DIRTBL ; ;START DIRECTORY SEARCH LXI H,0 SHLD FILECT CALL CLEARFCB LXI H,FCB1+1 MVI B,11 MVI A,'?' CALL FILLMEM LXI D,FCB1 MVI C,SRCH NEXTNAME: CALL BDOS cpi 255 JZ CALCFREE PUSH PSW ;PUSH A LXI H,FILECT INR M LDA FIVE DCR A JNZ STA5 MVI A,5 STA5 STA FIVE MOV E,A MVI D,0 LXI H,COLCT DAD D INR M POP PSW ;A * 32 + 1 RLC ;Rotate A five times. RLC ; ADD A five times also works. RLC RLC RLC INR A MVI B,0 ;CLEAR B MOV C,A ;DMA BYTE COUNT IN BC LXI H,DMA1 ;DMA ADDRESS IN HL DAD B ;ADD BC+LH = FIRST BYTE OF FILENAME XCHG LHLD DIRTBL MVI M,0 INX H XCHG LXI B,11 DB 0EDH,0B0H ;Z80 (HL) -> (DE), BC COUNT XCHG SHLD DIRTBL MVI C,SRCHMOR JMP NEXTNAME ; CALCFREE: ;CALCULATE FREE SPACE MVI C,PARAMS CALL BDOS INX H INX H MOV A,M STA ABYTE INX H INX H INX H MOV E,M INX H MOV D,M PUSH D MVI C,ALLOC CALL BDOS XCHG POP H INX H LXI B,0 LOOP1: PUSH D LDAX D MVI E,8 LOOP2: RAL JC JMP1 INX B JMP1: MOV D,A DCX H MOV A,L ORA H JZ JMP2 MOV A,D DCR E JNZ LOOP2 POP D INX D JMP LOOP1 JMP2: POP D MOV L,C MOV H,B LDA ABYTE SUI 3 JZ SORTNAMES LOOP3: DAD H DCR A JNZ LOOP3 ; SORTNAMES: SHLD FREESIZE LHLD DIRTBL INX H SHLD SORTBL SHLD SORPTR LDA FILECT STA FILECTR ana a jz PSIZE ; NEXTSORT: LXI H,OVLSTART-12 LXI D,12 LDA FILECT INR A MOV B,A XRA A SEEK1ST DCR B DAD D CMP M JNZ SEEK1ST SHLD LOWSTRING SEEK2ND DCR B JZ LDTBL DAD D PUSH H ;SAVE TEST ADR PUSH D ;SAVE 12 XCHG LHLD LOWSTRING CMPLOOP: LDAX D CMP M JNZ OKCMP INX H INX D JMP CMPLOOP OKCMP: POP D POP H JNC SEEK2ND ;HL$ < DE$ SHLD LOWSTRING ;DE$ < HL$ JMP SEEK2ND LDTBL: LHLD LOWSTRING MVI M,0FFH INX H XCHG LHLD SORPTR MOV M,E ! INX H MOV M,D ! INX H SHLD SORPTR LXI H,FILECTR DCR M JNZ NEXTSORT ; call type! db HOME,cline,0 LDA FILECT STA FILECTR PDIR0: MVI A,21 STA LINECT PDIR1: MVI A,5 STA FIVE LHLD SORTBL PDIR2: SHLD SORPTR MOV A,M INX H MOV H,M MOV L,A MVI B,8 CALL PLINE MVI A,'.' CALL PCHAR MVI B,3 CALL PLINE LXI H,FILECTR DCR M JZ PSIZE LXI H,FIVE mov e,m mvi d,0 DCR M JZ NEXTLINE lxi h,colct DAD d MOV E,M mvi d,0 LHLD SORPTR DAD D! DAD D push h CALL TYPE! DB ' | ',0 pop h JMP PDIR2 NEXTLINE: call type! db cr,lf,CLINE,0 LHLD SORTBL INX H! INX H SHLD SORTBL LXI H,LINECT DCR M JNZ PDIR1 CALL TYPE! DB 'Hit any key to continue.',0 mvi c,conin call bdos CALL TYPE! DB CR,CLINE,0 JMP PDIR0 ; PSIZE: CALL type db cr,lf,cline,lf,esc,'=7 ',cline,up,cline dirstat db 'A: ',0 LHLD FILECT call prnum CALL TYPE! DB ' files; ',0 LHLD FREESIZE CALL PRNUM CALL TYPE DB 'K free disk space',0 ; CALL LDPWDIROVL MVI C,OPENF CALL BDOS LXI H,RECSTART SHLD FCB1+CPMREC MVI B,32 MVI C,SETDMA LXI D,OVLSTART RESTORE: PUSH B! PUSH D CALL BDOS LXI D,FCB1 MVI C,READRND CALL BDOS POP D! POP B ANA A JNZ NOPE LHLD FCB1+CPMREC INX H SHLD FCB1+CPMREC LXI H,128 DAD D XCHG DCR B JNZ RESTORE ; EXITDIR LDA OLDSEL MOV E,A MVI C,SELDSK CALL BDOS POP B RET ; ABORT: CALL TYPE ! DB CR,CLINE,0 POP B RET ; NOPE CALL TYPE DB 7,esc,'=7 BAD TROUBLE! Unable to read A:PW.COM',7,0 POP B RET ; ;---------------------------------------------------- ;subroutines ; LDPWDIROVL CALL CLEARFCB LXI H,PWDIROVL LXI D,FCB1 LXI B,12 DB 0EDH,0B0H ;Z80 COPY MEMORY CMD LXI D,FCB1 RET ; clearfcb: xra a mvi b,fcblen lxi h,fcb1 ;fall into.. ; FILLMEM: MOV M,A INX H DCR B JNZ FILLMEM RET ; UPCASE: ;MAKES BYTE IN A UPPERCASE ana a ;clear carry flag CPI 60H ;IS IT lower case? RC ;no SUI 20H RET ; PCHAR: ;PRINT CHARACTER IN A, save BC and HL push h ! push b MVI C,CONOUT MOV E,A CALL BDOS pop b ! POP H RET ; TYPE: ;type text that immediately follows the call to this function. XTHL ;= POP H (stack had next program address=text adr) TYPELOOP: MOV A,M ANA A JZ EXITYPE CALL PCHAR ;Be sure HL is preserved INX H JMP TYPELOOP EXITYPE: INX H XTHL ;= push h RET ; PLINE: ;PRINT (HL) B COUNT MOV A,M CALL PCHAR INX H DCR B JNZ PLINE RET ; ; ;****** ARITHMETIC ROUTINES ******* ; CMPDH: ;IF DE=HL set ZERO FLAG, if HL