home *** CD-ROM | disk | FTP | other *** search
- *######################################################################
- * PROGRAM UNDEL...Undelete File Utility
- *
- * Dr. David C. Wilcox
- * DCW Industries, Inc.
- * 5354 Palm Drive, La Canada, CA 91011
- * 818/790-3844
- *
- * February 1, 1986
- *######################################################################
- boot equ 0 *warm boot
- msgf equ 9 *write console message
- rdcf equ 10 *read console line
- verf equ 12 *read CP/M version
- self equ 14 *select disk
- clof equ 16 *close file
- sfef equ 17 *find first occurance
- sfnf equ 18 *find next occurance
- makf equ 22 *create file
- dmaf equ 26 *set DMA
- dpbf equ 31 *get dpb fwa
- rsdf equ 37 *reset (log-out) disk drive
- lf equ 10 *line feed
- cr equ 13 *carriage return
- bdos equ $0002 *BDOS entry point
- *######################################################################
- * Special registers:
- *
- * a6 = address of DMA buffer
- * d6 = directory-entry buffer index (dbndx)
- * d7 = temporary count index (dbtmp)
- *######################################################################
- *
- * Locate DMA (for portability)
- *
- link a6,#0 *mark stack frame
- move.l 8(a6),a0 *get base page address
- lea $80(a0),a6 *get address of DMA and save it in a6
- *
- * Clear data registers
- *
- clr.l d3
- clr.l d4
- clr.l d5
- *
- * Set up local stack
- *
- movea.l #stack,a7
- *
- * Get the filename
- *
- movea.l a6,a2 *load DMA address
- suba.w #$23,a2 *adjust to FCB+1
- movea.l #fcb+1,a1
- move.w #11,d2
- jsr mmc
- *
- * Select disk
- *
- movea.l a6,a0 *load DMA address
- suba.w #$24,a0 *adjust to FCB
- move.b (a0),d0
- or.b d0,d0
- beq ref1 *if no selection
- *
- subq #1,d0
- move.w d0,d1
- move.w #self,d0
- trap #bdos
- *
- ref1: move.l #0,d6 *reset directory-entry buffer
- *
- move.l #cdpb,d1 *get extent mask
- move.w #dpbf,d0
- trap #bdos
- movea.l #cdpb+4,a2
- move.b (a2),d0
- not.b d0
- move.b d0,mfna
- *
- move.l a6,d1 *set dma
- move.w #dmaf,d0
- trap #bdos
- *
- move.w #sfef,d0 *find first occurance
- move.l #fcb,d1
- trap #bdos
- cmpi.b #$ff,d0
- beq ref5 *if file not found
- *
- ref2: jsr ffa *set a2=fnt address
- movea.l a2,a5
- movea.l #fcb+1,a1
- adda #1,a2
- move.l #8,d2
- jsr kst *compare strings
- bne ref3 *if not our filename
- *
- * we have a directory entry with matching filename.
- *
- movea.l a5,a1
- move.b d6,d0 *get buffer index
- addq.b #1,d6 *advance buffer index
- mulu #32,d0 *set a2=next buffer location
- movea.l #mbuff,a2
- adda.l d0,a2
- *
- exg a1,a2 *save the directory entry
- move.w #32,d2
- jsr mmc
- *
- * search for next occurence.
- *
- ref3: movea.l a5,a1
- move.w #sfnf,d0
- trap #bdos
- cmpi.b #$ff,d0
- bne ref2 *loop to end of directory
- *
- * we have searched the entire directory.
- *
- move.b d6,d0 *check file found
- or.b d0,d0
- beq ref5 *if file not found
- *
- * if file not erased, then don't restore it.
- *
- jsr cfe *check file erased
- bne ref7 *if file not erased
- *
- * if multiple erased files, issue a warning
- *
- jsr cme *check multiple entries
- bne ref8 *if more than one file
- *
- * restore the file
- *
- jsr rae *restore all extents
- ref4: move.w #boot,d0 *warmboot
- trap #bdos
- *
- * file not found.
- *
- ref5: move.l #refa,d1 *"file not found"
- ref6: move.w #msgf,d0
- trap #bdos
- jmp ref4
- *
- * file not erased
- *
- ref7: move.l #refb,d1 *"file not erased"
- jmp ref6
- *
- * multiple identical extent numbers found
- *
- ref8: move.l #refc,d1 *"multiple files found"
- move.b #msgf,d0
- trap #bdos
- move.w #rdcf,d0 *read response
- move.l #cbuff,d1
- trap #bdos
- movea.l #cbuff+2,a0
- move.b (a0),d0
- andi.b #$5f,d0
- cmpi.b #'Y',d0
- bne ref4 *if not "yes"
- *
- * close each extent under a unique name.
- *
- jsr mfn *modify all file names
- jsr rae *restore all
- jsr dfn *display new filenames
- jmp ref4
- *
- * MFN - Modify all filenames.
- * insert unique 2nd character into each filename
- * set 3rd filename char to "A" for phy ext 0, "B" for 1,
- * mark all extents 00.
- *
- mfn: move.b d6,d7
- movea.l #mbuff+2,a2 *2nd char
- movea.l #mbuff+$0c,a1 *ext
- move.b #'A',d0
- *
- mfn1: move.b d0,(a2) *insert new 2nd char
- addq.b #1,d0
- move.b d0,chtmp
- move.b (a1),d0 *set 3rd char = "ext"
- andi.b #$ff,d0
- mfna equ *-1
- addi.b #'A',d0
- adda #1,a2
- move.b d0,(a2)
- suba #1,a2
- eor.b d0,d0 *set extent = 00
- move.b d0,(a1)
- *
- adda #32,a1
- adda #32,a2
- *
- subq.b #1,d7
- movea.l #chtmp,a0
- move.b (a0),d0
- or.b d7,d7
- bne mfn1 *loop over all extents
- rts
- *
- * RAE - Restore all extents
- *
- rae: move.b #0,fcb
- move.b d6,d0
- move.b d0,d5
- movea.l #mbuff+1,a2
- *
- rae1: move.w #15,d2
- movea.l #fcb+1,a1
- jsr mmc *move filename
- movea.l a2,a4
- move.l #fcb,d1
- move.w #makf,d0 *create directory entry
- trap #bdos
- movea.l #fcb+$0e,a0 *clear "not-written" bit
- move.b (a0),d0
- andi.b #$7f,d0
- move.b d0,fcb+$0e
- movea.l a4,a2 *point to rbt image
- suba #1,a2 *get record count
- move.b (a2)+,d0
- movea.l #fcb+15,a1
- move.b d0,(a1)+
- move.w #16,d2
- jsr mmc
- move.l #fcb,d1 *close current extent
- move.w #clof,d0
- trap #bdos
- move.w d5,d1
- adda #1,a2
- subq #1,d5
- bne rae1 *loop over all extents
- rts
- *
- * DFN - Display new filenames.
- *
- dfn: move.l #dfna,d1 *"file names created"
- move.w #msgf,d0
- trap #bdos
- move.w d6,d0
- movea.l #mbuff+1,a2
- *
- dfn1: movea.l a2,a3
- move.b d0,d7
- movea.l #dfnb,a1 *move file name
- move.w #8,d2
- jsr mmc
- addq #1,(a1) *move file type
- move.w #3,d2
- jsr mmc
- move.l #dfnb,d1
- move.w #msgf,d0
- trap #bdos
- movea.l a3,a2
- adda #32,a2
- move.b d7,d0
- subq #1,d0
- bne dfn1 *loop for all extents
- rts
- *
- * CME - Check multiple erased entries
- * exit z = true, if one file found
- * d3 = file count
- *
- cme: move.b d6,d3
- movea.l #mbuff+$0c,a2 *point to ext bytes
- *
- cme1: move.b (a2),d0 *current extent number -> d0
- jsr cie *count identical extents
- beq cme11
- rts *if multiple files found
- *
- cme11: adda #32,a2
- subq #1,d3
- bne cme1 *loop over all extents
- rts
- *
- * CIE - Count identical extents
- * entry d0 = current extent
- * exit z = true, if one such extent found
- * d4 = extent count
- *
- cie: movea.l a2,a3
- move.l #0,d4
- move.b d6,d2
- movea.l #mbuff+$0c,a2
- *
- cie1: move.b (a2),d1
- cmp.b d0,d1
- bne cie2 *if not same extent
- addq #1,d4 *advance extent count
- *
- cie2: adda #32,a2
- subq #1,d2
- bne cie1 *loop over all extents
- *
- move.b d4,d0 *check extents found
- movea.l a3,a2
- cmpi.b #1,d0
- rts
- *
- * CFE - Check file erased
- * exit z = true, if file erased
- *
- cfe: move.b d6,d2
- movea.l #mbuff,a2
- *
- cfe1: cmpi.b #$e5,(a2)
- beq skip
- rts *if unerased extent found
- *
- skip: adda #32,a2
- subq #1,d2
- bne cfe1 *loop over all extents
- rts
- *
- * FFA - Form file address
- * entry d0 = FNT ordinal
- * exit a2 = FNT address
- *
- ffa: or.b d0,d0
- mulu #32,d0 * Multiply by 32
- movea.l a6,a2
- adda d0,a2
- rts
- *
- * KST - Compare strings
- * entry a2 = string 1 fwa
- * a1 = string 2 fwa
- * d2 = string compare length
- * exit z = true, if string 1 equal string 2
- *
- kst: cmpm.b (a1)+,(a2)+ *First check filename
- beq kstnxt
- rts *if mismatch
- *
- kstnxt: subq #1,d2
- bne kst *loop over compare length
- move.w #3,d2 *Now check the extension
- kst2: move.b (a2)+,d0
- andi.b #$7f,d0
- cmp.b (a1)+,d0
- beq kstnx2
- rts *if mismatch
- *
- kstnx2: subq #1,d2
- bne kst2 *loop over compare length
- rts
- *
- * MMC - Move memory
- * entry a2 = source fwa
- * a1 = destination fwa
- * d2 = byte count
- *
- mmc: move.b (a2)+,(a1)+
- subq #1,d2
- bne mmc *loop for d2 bytes
- rts
- *######################################################################
- * console messages
- *######################################################################
- even
- refa: dc.b 'File not found.$'
- refb: dc.b 'File not erased.$'
- refc: dc.b 'Multiple files found.'
- dc.b cr,lf,'Restore all? (Y/N):$'
- dfna: dc.b cr,lf,'File names created:',cr,lf,'$'
- dfnb: dc.b ' . ',cr,lf,'$'
- *######################################################################
- * data space
- *######################################################################
- even
- cdpb: dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
- chtmp: dc.b 0 *temp for 2nd char
- even
- fcb: dc.b '?'
- dc.b 0,0,0,0,0,0,0,0
- dc.b 0,0,0
- ext: dc.b 0,0,0,0
- dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
- nr: dc.b 0,0,0,0
- cbuff: dc.b 64 *console input buffer
- ds.b 64+2
- ds.l 32
- stack equ *
- even
- mbuff equ *+128
- *######################################################################
- end