; DUT - Disk Utility for TurboDOS ; 11/29/85 by ESKAY ; All Lefts Reversed ; cr equ 0dh lf equ 0ah ; cfunc equ 5 tfunc equ 50h ; .z80 .request syslib ; cseg ; start: jr begin ; cls: db 1bh,'E',0,0,0,0 ; clear screen curpos: db 1bh,'F',0,0,0,0 ; cursor pos xory: db 0 ; 0=xy, nz=yx coffs: db 32 ; cursor offset ; begin: ld sp,stack ; set up local stack ld c,25 call bdos## ld (curdsk),a call clrscr ; clear the screen ld bc,9*256+0 ; line 9 col 0 call gotoxy call print## ; display banner cr,lf 9,9,'+--------------------------------------------+',cr,lf 9,9,'| DUT vers 1.50 11/29/85 (c) ESKAY |',cr,lf 9,9,'| Disk editor for TurboDOS - Type H for HELP |',cr,lf 9,9,'+--------------------------------------------+',cr,lf,lf,0 ld c,12 ; get priv level call tfunc bit 7,b jr nz,.isp ; continue if privileged call print## cr,lf,7 'ERROR: non-privileged logon',cr,lf,0 di halt ; crash slave on the poor sucker ; .isp: call opnnew ; open new $.DSK loop: call disdrv ; display drive ld bc,22*256+27 ; line 22 column 27 call gotoxy call print## 'Enter command (H=HELP) [_]',8,8,0 call capin## ; get command character call cout## ; echo it call clrerr ; clear error line call getca ; get command address jr nz,.bcmd ; skip if bad command jp (hl) ; .bcmd: ld bc,23*256+29 call gotoxy call print## 'Invalid command - H=HELP',7,0 jr loop ; ; read next record ; nxtrec: call incgrp ; increment group jp .ggrp. ; ; read previous record ; prvrec: call decgrp jp .ggrp. ; incgrp: ld hl,(curgrp) ld a,(grpsz) ld b,a ld a,(cursec) inc a cp b jr nz,.igrn. ld de,(maxgrp) call comphd## inc hl jr nz,..ngrz ld hl,0 ..ngrz: xor a ld (curgrp),hl .igrn.: ld (cursec),a ret ; decgrp: ld hl,(curgrp) ld a,(cursec) dec a jp p,.dgrn. ld a,h or l dec hl jr nz,.dgr1. ld hl,(maxgrp) .dgr1.: ld (curgrp),hl ld a,(grpsz) dec a .dgrn.: ld (cursec),a ret ; ; help ; help: call clrscr call print## 'DUT vers 1.40 (c) 1985 ESKAY',cr,lf,lf 'Command list (see manual for details):',cr,lf,lf,lf 9,'D - (re)display current buffer',cr,lf 9,'F - Find the start of a file',cr,lf 9,'G - Goto group address',cr,lf 9,'> - next group (also .)',cr,lf 9,'< - previous group (also ,)',cr,lf 9,'Q - exit to TurboDOS',cr,lf 9,'+ - increment current sector and display (also =)',cr,lf 9,'- - decrement current sector and display',cr,lf 9,'! - step to first data group',cr,lf 9,'? or H = this list',cr,lf,0 ld bc,22*256+27 call gotoxy call print## 'Press any key to continue',0 call cin## call clrscr jp loop ; ; go to group ; .gthi: ld bc,23*256+20 call gotoxy call print## 'ERROR: too high!',7,0 ; goto: ld bc,22*256+10 ; row 16 col 10 call gotoxy call print## 'Enter GROUP NUMBER (0000..',0 ld hl,(maxgrp) dec hl call phl4hc## call print## ') in hex : [____]',8,8,8,8,8,0 call bbline## or a jr z,.gotx. ; aborted call eval16## ld hl,(maxgrp) call comphd## ; too high? jr c,.gthi ; too high! grpntr: ld (curgrp),de ex de,hl xor a ld (cursec),a ggdis1: call clcgrp ld (dskfcb+35),a ld (dskfcb+33),hl .ggdis: ld de,dskfcb ld c,33 call bdos## result::nop ; check rr result jp disbuf ; .gotx.: ld bc,22*256+0 call gotoxy call clreol call clrerr jp loop ; ; find a file ; filfnd: ld bc,22*256+20 call gotoxy call print## 'Enter filename to be found : ',0 ld a,1 call bbline## or a jr z,.filx. ; abort ld de,5ch ; point to fcb area call fname## ; parse file name ld a,c ; get specified user cp 0ffh ; none? jr z,..nus. ; skip if no user ld e,c ld c,32 call bdos## ..nus.: ld de,fndbuf ; set up temporary dma ld c,26 call bdos## ld de,5ch ld c,17 ; search first call bdos## push af ld de,80h ld c,26 call bdos## pop af inc a jr nz,..ff.. ; found file call print## 'FILE NOT FOUND - press any key ',7,0 call cin## jr .filx. ; ..ff..: ld de,fndbuf ld hl,-16 ld bc,32 ..fl..: add hl,bc dec a jr nz,..fl.. add hl,de ld e,(hl) inc hl ld d,(hl) jp grpntr ; .filx.: ld bc,22*256+0 call gotoxy call clreol jp loop ; ; go to next group ; nxtgrp: ld hl,(curgrp) inc hl ld (curgrp),hl push hl dec hl ld de,(maxgrp) or a sbc hl,de ld a,h or l pop hl jr nz,.ggrp. ld hl,0 ld (curgrp),hl .ggrp.:: call clcgrp ; calc sector from group ld (dskfcb+35),a ld b,a ld a,(cursec) ld e,a ld d,0 add hl,de ld (dskfcb+33),hl ld a,b jr nc,..novf inc a ..novf: ld (dskfcb+35),a jp .ggdis ; set file pointer and display ; prvgrp: ld hl,(curgrp) ld a,h or l jr nz,.pg. ld hl,(maxgrp) jr .pg1. ; .pg.: dec hl .pg1.: ld (curgrp),hl jr .ggrp. ; ; step to first data group ; frstdt: ld hl,(dirsiz) ld (curgrp),hl xor a ld (cursec),a ld (dskfcb+35),a call clcgrp ld (dskfcb+33),hl jp .ggdis ; ; edit command ; edit: ld a,(dison) dec a jr z,.eact. ld a,7 call cout## jp loop ; .eact.: ld bc,3*256+6 ; beginning of field ld (editpt),bc edlp: ld bc,(editpt) call gotoxy call capin## cp 3 ; exit jp z,loop cp 'E'-40h ; ^E = up jr z,.edup. cp 'X'-40h ; ^X = down jr z,.eddn. cp 'S'-40h ; ^S = left jr z,.edlf. cp 'D'-40h ; ^D = right jr z,.edrt. cp 27h ; check ' jp z,.edasc ; edit ascii call nybble ; see if nybble jp nc,.edda. ; it is, edit data ld a,7 call cout## jr edlp ; .edup.: ld a,(editpt+1) ; get row dec a cp 2 jr nz,.esnt. ld a,10 ; set bottom .esnt.: ld (editpt+1),a jr edlp ; .eddn.: ld a,(editpt+1) inc a cp 11 jr nz,.esnt. ld a,3 jr .esnt. ; .edlf.: ld a,(editpt) sub 3 cp 3 jr nz,.eslt. ld a,51 .eslt.: ld (editpt),a jp edlp ; .edrt.: ld a,(editpt) add a,3 cp 54 jr nz,.eslt. ld a,6 jr .eslt. ; .edasc: call cin## ; get ascii character call pa2hc## jr ..asci ; .edda.: call hexo ; display high nybble cp 'A' jr c,...x sub 7 ...x: and 0fh rla rla rla rla ld b,a ; save it .ede..: call capin## call nybble jr c,.ede.. call hexo cp 'A' jr c,...y sub 7 ...y: and 0fh or b ; a has byte now ..asci: push af call calcbp ; calculate buffer pointer pop af ld (hl),a ld a,l and 0fh add a,55 ld bc,(editpt) ld c,a call gotoxy ld a,(hl) and 7fh cp 7fh jr z,.ed... cp ' ' jr nc,.edn.. cp 7fh .ed...: ld a,'.' .edn..: call cout## jp .edrt. ; go to next hex on same line ; ; write buffer ; write: ld de,dskfcb ld c,34 call bdos## jp loop ; ; advance and display directory buffer ; advdir: ; ; display buffer command ; disbuf: call clrscr ld a,1 ld (dison),a call print## 'RELATIVE SECTOR : ',0 ld hl,(dskfcb+33) inc hl ld a,(dskfcb+35) ld e,a call p24b ld bc,0*256+25 call gotoxy call print## ' OF ',0 ld hl,(maxrec) inc hl ld a,(maxrec+2) ld e,a call p24b ld bc,0*256+38 call gotoxy call print## 'GROUP:SECTOR : ',0 ld hl,(curgrp) call phl4hc## ld a,':' call cout## ld a,(cursec) call pa2hc## call disdrv ; display drive call dispbf ; display buffer contents jp loop ; and go back for next command ; quit: call clrscr ld bc,23*256+0 call gotoxy rst 0 ; ; subroutines ; ; calculate buffer from screen address ; calcbp:: ld hl,(editpt) ld a,l ; get column ld b,0 sub 6 .div3.: inc b sub 3 jr nc,.div3. ld l,b ld a,h ld h,0 sub 3 rla rla rla rla add a,7fh add a,l ld l,a ret ; ; test a if valid nybble ; nybble: cp '0' ret c cp 'F'+1 ccf ret c cp '9'+1 ccf ret nc sub 7 cp '9'+1 ret ; ; hex out ; hexo: cp '9'+1 jp c,cout## add a,7 jp cout## ; ; calc sector from group ; clcgrp:: ld a,(grpmul) ld b,a xor a .ggrm.: rl l rl h rla djnz .ggrm. ret ; ; open $.DSK, $.DIR ; opnnew: ld de,dskfcb call initfcb## ld c,35 ; get file size call bdos## ld hl,(dskfcb+33) ld a,(dskfcb+35) dec hl ld (maxrec),hl ld (maxrec+2),a call f$open## ld de,80h ld c,26 call bdos## ld de,dskfcb ld hl,0 ld (dskfcb+32),hl ld (dskfcb+34),hl call f$read## ld c,19 ld a,(curdsk) ld e,a call tfunc dec hl ld (maxgrp),hl and 0fh ld (grpmul),a sub 2 ld b,a ld a,4 .sla.: or a rla djnz .sla. ld (grpsz),a ld a,c ld (dirsiz),a ret ; ; display drive ; disdrv: ld bc,0*256+70 call gotoxy call print## 'DRIVE ',0 ld a,(curdsk) add a,'A' call cout## ld a,':' jp cout## ; ; display buffer on screen (80H) ; dispbf: ld de,0 ld bc,3*256+0 ; row 3 col 0 disobf: call gotoxy add hl,de ld hl,80h ; point to buffer .disl.: push hl ; save hl ld b,16 ; display 16 hex bytes push hl res 7,l ld h,0 call phl4hc## ; display relative address pop hl call space2 ; 2 spaces .h16l.: ld a,(hl) ; get byte call pa2hc## ; print hex call space inc hl djnz .h16l. ; complete 16 bytes pop hl ; get addr back ld b,16 ; 16 bytes again call space .a16l.: ld a,(hl) ; get byte and 7fh ; strip hi bit cp 7fh jr z,.a16.. cp ' ' ; dot if control jr nc,.a16n. .a16..: ld a,'.' .a16n.: call cout## inc hl djnz .a16l. ; loop until done call crlf## ; new line ld a,l ; get low byte of buffer addr or a ; zero? ret z ; yes, done jr .disl. ; else do next line ; ; get command address or NZ ; getca: ld hl,cmdtbl ld b,a .gca.: ld a,(hl) or a jr z,.gcx. cp b jr z,.gcg. inc hl inc hl inc hl jr .gca. ; .gcg.: inc hl ld a,(hl) inc hl ld h,(hl) ld l,a xor a ret ; .gcx.: dec a ret ; clrerr: push af push bc ld bc,23*256+0 ; row 23 col 0 call gotoxy pop bc pop af ; clreol: push af push bc ld b,79 ld a,' ' .clel.: call cout## djnz .clel. pop bc pop af ret ; space2: call space space: ld a,' ' jp cout## ; ; position cursor. b=x, c=y ; gotoxy: push hl ld hl,curpos call pstrg ld a,(xory) ; check xy or yx or a ; if zero, then xy jr z,..xy ld a,b ld b,c ld c,a ; exchange b and c ..xy: ld a,(coffs) ; get cursor offset push af ; save for next add a,b call cout## pop af add a,c call cout## pop hl ret ; clrscr: push hl ld hl,cls call pstrg pop hl ret ; pstrg: ld a,(hl) or a ret z call cout## inc hl jr pstrg ; p24b: ld ix,n24b push ix ld b,12 xor a .p24l: ld (ix+0),a inc ix djnz .p24l pop ix ld a,3 call hxdc24## ld hl,n24b jp pstr## ; dseg ; ; command table ; cmdtbl: db 'Q' ; exit dw quit db 'D' ; display buffer dw disbuf db '+' ; next record dw nxtrec db '=' dw nxtrec db '-' ; previous record dw prvrec db 'H' dw help db '?' dw help db 'G' ; go to group dw goto db 'F' ; find file dw filfnd db '<' ; previous group dw prvgrp db '>' ; next group dw nxtgrp db ',' dw prvgrp db '.' dw nxtgrp db '!' ; first data grp dw frstdt db 'E' ; edit dw edit db 'W' ; write dw write db 0 ; curdsk: db 0 dirsiz: dw 0 maxrec: ds 3 curgrp: dw 0 cursec: db 0 maxgrp: dw 0 grpsz: db 0 grpmul: db 0 ; n24b: db 0,0,0,0,0,0,0,0,0,0,0,0 ; dison: db 0 editpt: dw 0 ; dskfcb: db 0,'$ DSK',0,0,0,0 ds 24 ; fndbuf: ds 128 ds 100 stack equ $ end ld a,(hl) or a ret z call cout## inc hl jr pstrg ; p24b: ld ix,n24b push ix ld b,12 xor a .p24l: ld (ix+0),