title DUMPASC - ASCII File Dump Program name ('DUMPASC') BDOS equ 0005h FCB equ 005ch DMA equ 0080h .conout equ 2 .string equ 9 .consta equ 11 .open equ 15 .rdseq equ 20 .fsize equ 35 OSerr equ -1 .drv equ 1 .nam equ 8 _CR equ 32 _RRN equ 33 reclng equ 128 bell equ 07h lf equ 0ah cr equ 0dh eot equ '$' LOMASK equ 00001111b DATBASE equ 0000h COMBASE equ 0100h CONCOL equ 64 STKSIZE equ 32 db 'DUMPASC by Emmanuel ROCHE' ; DUMPASC: ld hl,0 add hl,sp ; Copy stack ld (StkSav),hl ; Save it ld sp,LocStk ; Get local stack call Open ; Open file cp OSerr ; Test found jp nz,GotFile ; Yeap ld de,NO$FILE call String ; Tell file not found jp DumpExit ; Exit ; ; Verify any record to be dumped ; CheckRec: ld c,.fsize ld de,FCB call BDOS ; Get size of file ld a,(FCB+_RRN) cp 0 ; Verify any record there ret nz ld de,NO$REC call String ; Tell zero length file jp DumpExit ; Exit ; GotFile: call CheckRec ; Test any record to be dumped ld hl,FCB+.drv+.nam ld a,(hl) ; Get extension cp 'C' ; Test .COM file jp nz,AnyFile inc hl ld a,(hl) cp 'O' jp nz,AnyFile inc hl ld a,(hl) cp 'M' jp nz,AnyFile ld hl,COMBASE ; Set start on .COM file jp SetMaxRec AnyFile: ld hl,DATBASE ; Set start on other files SetMaxRec: ld a,reclng ld (RecPtr),a ; Force read DumpLop: push hl call Getbyte ; Read byte from file pop hl jp c,DumpExit ; Exit if end of file ld b,a ; Save character ld a,l and CONCOL-1 ; Test line boundary jp nz,DumpIt ; Nope call NewLine ; Put new line to console call Consta ; Get state of console rrca ; Test key pressed jp c,DumpExit ; Exit if so ld a,h call CnvHtA ; Print current hex address ld a,l call CnvHtA ld a,':' call Conout ; Give delimiter ld a,' ' call Conout DumpIt: inc hl ; Point to next address ld a,b call PrChar ; Print as character if possible jp DumpLop ; ; End of program, exit ; DumpExit: call NewLine ; Put new line to console ld hl,(StkSav) ; Get back caller's stack ld sp,hl ret ; Exit ; ; Print byte in Accu ; PrChar: cp '~'+1 ; Test printable jp nc,MapDot cp ' ' jp nc,_Conout MapDot: ld a,'.' ; Map not printable _Conout: jp Conout ; Put to console ; ; Get state of console ; Consta: push hl push de push bc ld c,.consta call BDOS ; Get state pop bc pop de pop hl ret ; ; Put character to console ; Conout: push hl push de push bc ld c,.conout ld e,a ; Get character call BDOS ; Put to console pop bc pop de pop hl ret ; ; Put new line to console ; NewLine: ld a,cr call Conout ; Simple closure ld a,lf call Conout ret ; ; Print four bits as hex ; prHexChar: and LOMASK ; Mask bits cp 9+1 ; Test range jp nc,prHexDig add a,'0' ; Add offset jp prDecDig prHexDig: add a,'A'-10 ; Fix for hex prDecDig: call Conout ret ; ; Print byte as hex ASCII ; CnvHtA: push af rrca ; Get hi bits rrca rrca rrca call prHexChar ; Put to console pop af call prHexChar ; Then lo bits ret ; ; Put string to console ; String: ld c,.string call BDOS ; Put string to console ret ; ; Read byte from file - C set says end of file ; Getbyte: ld a,(RecPtr) ; Get record index cp reclng ; Test record scanned jp nz,Getmem ; Nope call RdRec ; Read record or a ; Test end of file jp z,Getmem ; Nope scf ret Getmem: ld e,a ; Build index ld d,0 inc a ld (RecPtr),a ; Update record index ld hl,DMA add hl,de ; Build buffer address ld a,(hl) ; Fetch byre or a ret ; ; Open file ; Open: xor a ld (FCB+_CR),a ; Clear current record ld de,FCB ld c,.open call BDOS ; Open file ret ; ; Read record from file ; RdRec: push hl push de push bc ld de,FCB ld c,.rdseq call BDOS pop bc pop de pop hl ret ; NO$FILE: db cr,lf,bell,'File not found.',eot NO$REC: db cr,lf,bell,'No records exist (zero-length file).',eot RecPtr: db 0 StkSav equ $+1 LocStk equ StkSav+2+2*STKSIZE end DUMPASC