; TXTSAVER.ASM ; written by Claude Ostyn ; July 13, 1983 ; ; This program salvages text file in memory after a text editor crash. ; Contents of text buffer is saved under the name 'SALVAGED.TXT'. ;========================================================================= ; 04 Sep 85 - Mike Dingacci ; See TXTBUFFR Equate for editor's text buffer location. ; Buffer locations noted for Turbo Pascal versions 1.0, 2.0, and 3.0. ; Also noted are buffer locations for Wordstar 3.3 and VDO25 editors. ; ; 20 Apr 84 - Bill McGee ; modified TXTSAVER.ASM to handle TURBO PASCAL crashes. ; ; 12/17/83 - Loren Cook ; Cleaned up file, fixed outbuff: error, and reworked messages ; for 80 column screens. ; ; 06/21/83 - Claude Ostyn ; Make compatible with WordStar 3.x (see TXTBUFFR equate below). ; ; Equates ; CR: EQU 0DH LF: EQU 0AH CTRLZ: EQU 1AH ; ; BDOS functions ; WCONF: EQU 2 ;write character to console RCONF: EQU 6 ;direct input from console PBUFF: EQU 9 ;print a line to console RBUFF: EQU 10 ;read console buffer ; ; CP/M disk access functions ; INITF: EQU 13 ;initial BDOS OPENF: EQU 15 ;open file CLOSF: EQU 16 ;close file FINDF: EQU 17 ;find file DELEF: EQU 19 ;delete file WRITF: EQU 21 ;write one record MAKEF: EQU 22 ;create file SDMAF: EQU 26 ;set DMA function ; ; CP/M addresses ; BOOT: EQU 0 ;warm boot DRIVE: EQU BOOT+4 ;current drive BDOS: EQU BOOT+5 ;BDOS entry for calls TPATOP: EQU BOOT+7 ;MSB of top memory TFCB: EQU 5CH ;transient file control block FCBEX: EQU TFCB+12 ;file extent FCBS2: EQU TFCB+14 ;system use in FCB FCBCR: EQU TFCB+32 ;current record in FCB TBUFF: EQU 80H ;transient buffer TPA: EQU BOOT+100H ;TPA ; ; TXTBUFFR: EQU 7714H ;Turbo text buffer location v1.0 - change to ; 802Ah for v2.0 & 8118h for v3.0 - others are ; 1D52h for VDO v. 2.5 and ; 846Dh for Wordstar v. 3.3 ; ; CP/M flags ; BDAOK: EQU 0 ;BDOS return for all ok BDERR: EQU 255 ;BDOS return error flag ; ; ******************************************************************** ; Program starts here - ; ORG TPA ; START: LXI SP,STAK ;set user's stack LDA DRIVE ;save intial drive selected STA DRSAV LXI D,SINON ;with sign-on message CALL COMSG CALL PREPFCB ;get the FCB ready ; START3: LXI D,DRPROMPT ;get drive for write CALL COMSG CALL DRSEL ;get valid drive select CPI CR ;if (return), exit JZ DONE CPI 0 JZ START3 ;if no good, try again STA TFCB ;set designator into FCB LXI D,PROMPT ;point to disk in prompt CALL COMSG ;and print first part LDA DRNAME CALL COUT ;complete with drive name LXI D,PROMPTK ;and end of prompt CALL COMSG CALL CHRIN ;get any key CALL PUT ;write the file to disk LDA ERRORFLAG CPI 0 JNZ START3 ;error encountered, try again LXI D,JAIFINI CALL COMSG ; DONE: LDA DRSAV ;restore initial drive STA DRIVE JMP BOOT ; ; Read file name into outfcb ; PREPFCB: LXI H,FILENAME ;point to filename LXI D,TFCB+1 ;point to fcb name area MVI C,11 ;set counter ; MOVENAME: MOV A,M STAX D INX H INX D DCR C MOV A,C CPI 0 JNZ MOVENAME RET ; ; Write from "buffer" to disk ; PUT: XRA A ;zero flags STA EOFFLAG STA ERRORFLAG LDA TFCB ;log-in selected disk ORA A ;is it leagal? JNZ PUT1 LXI D,WOMSG ;no, show unable to open JMP PUTERROR ;and try again ; PUT1: MVI C,INITF ;enable write on any disk CALL BDOS XRA A ;initialize FCB STA FCBCR ;current record LXI H,0 SHLD FCBEX ;extent and s1 SHLD FCBS2 ;s2 and record count LXI D,TFCB ;see if file exists MVI C,FINDF ;find function CALL BDOS CPI BDERR ;is it there? JZ PUT2 ; ASKYN: LXI D,ALREADY ;yes, overwrite CALL COMSG CALL CHRIN ;get answer CPI 'N' ;is it no? JNZ YES ;maybe yes? CALL COUT ;print 'N' on console LXI D,BLANK ;skip a line JMP PUTERROR ;if no, try again ; YES: CPI 'Y' JNZ ASKYN ;no valid answer CALL COUT ;print 'Y' on console LXI D,BLANK ;skip a line CALL COMSG LXI D,TFCB ;if yes, erase it MVI C,DELEF CALL BDOS ; PUT2: LXI D,TFCB ;point to FCB MVI C,MAKEF ;attempt to CALL BDOS ;create the file CPI BDERR ;if no error, JNZ PUT3 ;go on LXI D,WOMSG ;otherwise print JMP PUTERROR ;error message and quit ; PUT3: LXI D,OUTBUFF ;set DMA MVI C,SDMAF ;to outbuff location CALL BDOS LXI H,TXTBUFFR SHLD POSINBUF ; ; Fill one output buffer ; FILL: LHLD POSINBUF ;get current read position LXI D,OUTBUFF MVI C,128 ;set character counter ; ONEMORE: MOV A,M ;read one character STAX D ;and put in output buffer CPI 1AH ;end of file character? CZ WRAP ;yes, finish this up INX H INX D DCR C MOV A,C CPI 0 ;check counter JNZ ONEMORE ; ; Check our position (there may not have been an EOF character) ; LDA TPATOP ;check MSB of end of tpa CMP H ;compare with value in H CZ WRAP ;if the same, time to quit ; ; Copy one record to disk ; SHLD POSINBUF ;store current read position LXI D,TFCB MVI C,WRITF ;write a record function CALL BDOS CPI BDAOK ;write ok? JZ NICEWRIT LXI D,WEMSG JMP PUTERROR ; NICEWRIT: LDA EOFFLAG CPI 1 ;end of file flag on? JNZ FILL ;no, read another records worth CALL CPDMA ;yes, reset DMA to normal LXI D,TFCB ;and close the file MVI C,CLOSF CALL BDOS RET ;from put (1 of 2 exits) ; PUTERROR: CALL COMSG LXI H,ERRORFLAG MVI M,1 RET ;from put (2 of 2 exits) ; WRAP: MVI A,1 STA EOFFLAG ;set EOF flag RET ; ; Restore CP/M DMA address to the trnsient buffer ; CPDMA: LXI D,TBUFF MVI C,SDMAF CALL BDOS RET ; ; Get valid drive select designator ; DRSEL: CALL CHRIN CPI CR RZ STA DRNAME SUI 40H CPI 01 JZ DROK CPI 02 JNZ DRERR ; DROK: PUSH PSW LDA DRNAME CALL COUT POP PSW RET ; DRERR: XRA A RET ; ; Console character into register A ; CHRIN: PUSH B PUSH D PUSH H ; CI: MVI E,0FFH ;setup for input MVI C,RCONF ;get one character CALL BDOS ;from console CPI 0 JZ CI ;no key pressed, try again ANI 01011111B ;make upper case POP H POP D POP B RET ; COUT: PUSH B ;save registers PUSH D PUSH H MOV E,A PUSH PSW MVI C,WCONF CALL BDOS ;...send to console POP PSW POP H POP D POP B RET ; ; Message pointed to by HL out to console ; COMSG: MVI C,PBUFF CALL BDOS RET ; ; RAM variables and buffers ; DRSAV: DS 1 POSINBUF: DS 2 EOFFLAG: DB 0 ERRORFLAG: DB 0 ; ;Set up stack space ; DS 64 STAK: DB 0 DRNAME: DS 1 FILENAME: DB 'SALVAGEDTXT' SINON: DB 26,'SAVER by Claude Ostyn - July 13,1983' DB CR,LF,LF,'This program salvages text in' DB ' memory after a Turbo v. 1.0 crash.',CR,LF,'It' ; ; *** change v. to 2.0 or 3.0, if appropriate ; DB ' will create a file named SALVAGED.TXT on the' DB ' drive specified.',CR,LF,LF,LF,'$' DRPROMPT: DB CR,LF,'Select the drive for output (A or B),' DB ' or (RETURN) to exit: $' PROMPT: DB CR,LF,'Put a disk with plenty of room in drive $' PROMPTK: DB ' and press ANY key.',CR,LF,LF,'$' ALREADY: DB 'There is already a file named SALVAGED.TXT' DB ' on this disk.',CR,LF,'OK to overwrite?$' WEMSG: DB 'PERMANENT WRITE ERROR!!!',CR,LF,'$' WOMSG: DB 'Can not open for write!',CR,LF,'$' JAIFINI: DB 26,'......All done.',CR,LF,LF DB 'You may need to use Turbo to clean up' DB ' the file SALVAGED.TXT.',CR,LF,LF,'$' BLANK: DB CR,LF,LF,'$' OUTBUFF DB 0 ; END