title DUMP+ - Enhanced Dump Facility name ('DUMP3') ;-------------------------------------------------------------- ; Formatted Hex/ASCII Dump ; File : DUMP3.MAC ;-------------------------------------------------------------- _VERS macro db '2.1' endm ;-------------------------------------------------------------- ; ; It's from SIGM Vol.234 -- Date and author ???? ; ;-------------------------------------------------------------- ; ; I fixed a simple bug and expanded somethings. ; The new extensions are: ; - Indicating MSB set in file name with letter hilited ; (NOTE - This feature is machine dependend -> PCW) ; - Installing line counter holding on full screen ; (NOTE - This requires CP/M PLUS) ; - Listing is interruptable by Ctrl-C only ; - Allow processing of multiple files - wildcard allowed ; ; June 1987 -- Werner Cirsovius -- Germany ; February 1990 -- Werner Cirsovius -- Germany ; February 1993 -- Werner Cirsovius -- Germany ; ;-------------------------------------------------------------- ; ; Some equates ; Cols equ 16 ColMask equ Cols SHR 2 - 1 LoMask equ 00001111b MSB equ 7 ; ;-------------------------------------------------------------- ; ; Control character equates ; null equ 00h CtrlC equ 'C'-'@' cr equ 0dh lf equ 0ah esc equ 1bh eot equ '$' ; ;-------------------------------------------------------------- ; ; CPM system call codes ; OS equ 0000h ; CPM warm start BDOS equ 0005h ; CPM call address ; conout equ 2 ; CPM console output conio equ 6 ; Direct console I/O strout equ 9 ; Standard string output const equ 11 ; Console status open equ 15 ; Open file close equ 16 ; Close file readnx equ 20 ; Read next record setbuf equ 26 ; Set DMA address gsscb equ 49 ; Attache system control block ; OSerr equ -1 ; CPM disk error ; _CI equ -1 ; Get character ; ;-------------------------------------------------------------- ; ; FCB image for sequential file ; ;-------------------------------------------------------------- ; FCB equ 005ch ; Default FCB address _NAM equ 1 ; File name body _EXT equ 9 ; File name extension _CR equ 32 ; Next sequential record ; .nam equ 8 ; Length of name .ext equ 3 ; Length of extension ; DMA equ 0080h ; Standard disk buffer ; RecLng equ 128 ; Standard length of buffer ; _ConPag equ 1ch ; Console page length _get equ 0 ; ;-------------------------------------------------------------- ; ; Messages ; ;-------------------------------------------------------------- ; $HEADER: db 'DUMP Version ' _VERS db null $OPEN: db '**** File not found ***',cr $BAD: db '**** No file name entered ****',cr $EMPTY: db '**** No records in file ****',cr $NOWILD: db '**** No wildcards allowed here ****',cr $WAIT: db 'Press any key to continue',cr,eot $HIGH: db esc,'p' HI.chr: db ' ',esc,'q',eot $CLREOL: db esc,'K',eot ; ;----------------------------------------------------- ; ; Initialization of one DUMP cycle ; ;----------------------------------------------------- ; IniDUMP: ld hl,0 ld (RecNum),hl ; Zero record number ld a,(MaxLin) ; Init line count ld (CurLin),a ret ; ;----------------------------------------------------- ; ; Initialization - Set up stack and FCB ; ;----------------------------------------------------- ; DUMP:: ld sp,(BDOS+1) ; Put stack at top of RAM ; ;------------------------------- ; Get current screen lines ;------------------------------- ; ld de,SCB ; Point to parameter block ld c,gsscb call BDOS ; Fetch line count dec a ; Fix it ld (MaxLin),a ; Save count ld de,DMA ; Point to record buffer ld c,setbuf ; Set DMA system call call BDOS ; Set buffer address ; ;------------------------------------------------------ ; Check we were given a file name - Error if none ;------------------------------------------------------ ; ld a,(FCB+_NAM) ; Pick up drive header cp ' ' jp z,NoName ; Quit if error cp '?' jp z,NoWild ; Check illegal wildcard ld a,(FCB+_EXT) ; Pick up extension cp '?' jp z,NoWild ; Check illegal wildcard call IniDUMP ; Init a bit ld de,FCB ; Point to FCB ld c,open call BDOS ; Attempt to open file cp OSerr jp z,NoFile ; Quit if bad open xor a ; Clear register ld (FCB+_CR),a ; Zero record number call RdSect ; Read 1st record jr nz,NoRecs ; Empty file ld hl,$HEADER call Prnt ; Print header call CrLfc.2 ; Do a newline twice WrtFl: call WrtBuf ; Display the record call RdSect ; Get next record jp nz,OS ; Exit if EOF ld hl,(RecNum) inc hl ld (RecNum),hl ; Increment record count jr WrtFl NoRecs: ld hl,$EMPTY ; Print no records jr EOJ NoFile: ld hl,$OPEN ; Print cant open jr EOJ NoWild: ld hl,$NOWILD ; Print cant process wildcards jr EOJ NoName: ld hl,$BAD ; Print no file name EOJ: call Prnt jp OS ; Go away ; ;-------------------------------------------------------------- ; WRTBUF - Display data in buffer ;-------------------------------------------------------------- ; WrtBuf: call WrsHdr ; Display sector header ld hl,DMA ld (BuffAd),hl ; Save a(Pos in buffer) ld (SaveAd),hl ; Hold addr for ASCII xor a ld (LCnt),a ; Set line 0 ld (BufPos),a ; Offset 0 in buff WrtB01: ld hl,(BuffAd) ld (SaveAd),hl ; Start of current line xor a ld (CCnt),a ; Column 0 call PrtAdr ; Display address ld a,' ' call CPutCh ld a,' ' call CPutCh ; Space over for data ld a,(BaseAd+2) add a,Cols ld (BaseAd+2),a ; Inc addr for next line ; ;------------------------------- Display bytes in hex ; WrtB03: ld hl,(BuffAd) ; Get address in buffer ld a,(hl) ; Get character there inc hl ; Increment buff pointer ld (BuffAd),hl ; Save new value call XPutSp ; Print byte with space ld a,(CCnt) ; Get column in buff inc a ld (CCnt),a ; Increment it and ColMask ld a,' ' call z,CPutCh ; Print extra space on end ld a,(CCnt) ; Get col counter cp Cols jr nz,WrtB03 ; Do 16 cols ; ;------------------------------ Now display ASCII ; xor a ld (CCnt),a ; Zero col counter ld hl,(SaveAd) ld (BuffAd),hl ; Restore buffer address ld a,' ' call CPutCh ld a,' ' call CPutCh ; Space over for ASCII ld a,'|' call CPutCh ; Print margin WrtB02: ld hl,(BuffAd) ld a,(hl) ; Get current character inc hl ; Increment pointer ld (BuffAd),hl ; Save new value call FPutCh ; Print char ld a,(BufPos) inc a ld (BufPos),a ; Increment buffer posn ld a,(CCnt) ; Get col counter inc a ld (CCnt),a ; Inc col count cp Cols jr nz,WrtB02 ld a,'|' call CPutCh ; Print margin call CrLfc ; Close line ld a,(LCnt) inc a ld (LCnt),a ; Inc line count cp RecLng / Cols jp nz,WrtB01 ; Do somw lines call CrLfc ret ; ;-------------------------------------------------------------- ; WRSHDR - Display a record header ;-------------------------------------------------------------- ; WrsHdr: call CrLfc ; Take new line call PrtFN ; Print file name, call WrSNum ; and record number CrLfc.2: call CrLfc call CrLfc ret ; ;-------------------------------------------------------------- ; WRSNUM - Display current sector number ;-------------------------------------------------------------- ; WrSNum: ld hl,$REC call Prnt ld a,(RecNum+1) call XPut ; Print high byte ld a,(RecNum) call XPutSp ld a,(RecNum+1) srl a ; Divide by 2 ld (BaseAd),a ; Save shifted value ld a,(RecNum) rra ld (BaseAd+1),a ld a,0 rra ld (BaseAd+2),a ld hl,$ADDR call Prnt call PrtAdr ret ; $REC: db ' RECORD ',null $ADDR: db ' ADDRESS ',null ; ;-------------------------------------------------------------- ; PRNT - Print a line terminated by HL^C < 20h ;-------------------------------------------------------------- ; Prnt: ld a,(hl) cp ' ' jr c,Prnt02 ; Exit if < ' ' call CPutCh ; Output character inc hl ; Increment pointer jr Prnt Prnt02: or a call nz,CPutCh ; Print non zero terminator ret ; ;-------------------------------------------------------------- ; PRTADR - Print file address ;-------------------------------------------------------------- ; PrtAdr: ld a,(BaseAd) ; Get high address call XPut ld a,(BaseAd+1) call XPut ld a,(BaseAd+2) call XPut ret ; ;-------------------------------------------------------------- ; PRTFN - Print file name from FCB ;-------------------------------------------------------------- ; PrtFN: ld hl,FCB ld a,(hl) or a ; Test drive number jr z,PrtF01 ; If not default add a,'A'-1 ; Make it ASCII call CPutCh ; Print it ld a,':' call CPutCh ; Print separator PrtF01: ld b,.nam ; Print length of file call PrtF02 ld a,'.' call CPutCh ; Print separator ld b,.ext ; And length PrtF02: inc hl ld a,(hl) cp ' ' call nz,MPutCh ; Print it djnz PrtF02 ; Until all 3 done ret ; ;-------------------------------------------------------------- ; FPUTCH - Print ASCII character or '.' ;-------------------------------------------------------------- ; FPutCh: cp '~' jr nc,FPut01 cp ' ' jr nc,FPut02 FPut01: ld a,'.' FPut02: call CPutCh ret ; ;-------------------------------------------------------------- ; XPUTSP - Print byte in hex + space ;-------------------------------------------------------------- ; XPutSp: ld (Ch),a ; Save byte ld a,' ' jr XPfix ; ;-------------------------------------------------------------- ; XPUT - Print byte in hex ;-------------------------------------------------------------- ; XPut: ld (Ch),a xor a ; Clear A XPfix: ld (PstFix),a ; Set flag ; ;-------------------------------------------------------------- ; HEXPUT - Output hex byte + postfix ;-------------------------------------------------------------- ; HexPut: ld a,(Ch) rra rra rra rra call PrNibble ; Print nibble ld a,(Ch) ; Restore byte call PrNibble ; Print other nibble ld a,(PstFix) or a call nz,CPutCh ; Print trailing space if not 0 ret ; ;-------------------------------------------------------------- ; XPRT1 - Print low nibble of A as ASCII ;-------------------------------------------------------------- ; PrNibble: and LoMask ; Loose high nibble add a,90h ; Convert the tricky way daa adc a,40h daa call CPutCh ret ; ;-------------------------------------------------------------- ; CRLFC - Print carriage return / line feed - Update line count ;-------------------------------------------------------------- ; CrLfc: call CrLf ; Close line ld a,(CurLin) ; Get count dec a ld (CurLin),a ret nz ; Test any left ld a,(MaxLin) ; Reset count ld (CurLin),a push bc push de push hl ld de,$WAIT call String ; Tell waiting Wtkey: call Consta ; Get key pressed jr nc,Wtkey ; wait for it ld de,$CLREOL call String ; Clear line call IsBreak ; Test break pop hl pop de pop bc ret ; ;-------------------------------------------------------------- ; STRING - Print message ;-------------------------------------------------------------- ; String: ld c,strout call BDOS ; Tell message ret ; ;-------------------------------------------------------------- ; CONSTA - Get console state ;-------------------------------------------------------------- ; Consta: ld c,const call BDOS ; Test key pressed rra ret ; ;-------------------------------------------------------------- ; CRLF - Print carriage return / line feed ;-------------------------------------------------------------- ; CrLf: ld a,cr call CPutCh ld a,lf call CPutCh ret ; ;-------------------------------------------------------------- ; MPUTCH - Print character in A without MSB ;-------------------------------------------------------------- ; MPutCh: bit MSB,a ; Test MSB set jr z,CPutCh ; No,print normal res MSB,a ; Mask bit cp ' ' ; Check attribute on blank ret z ld (HI.chr),a ; Save character push bc push de push hl ld de,$HIGH call String ; Print hilite pop hl pop de pop bc ret ; ;-------------------------------------------------------------- ; CPUTCH - Print character in A ;-------------------------------------------------------------- ; CPutCh: push bc push de push hl push af call Consta ; Test console call c,IsBreak ; Test break on key pop af ; Restore character ld e,a ; Input to parm reg ld c,conout call BDOS ; Output the character pop hl pop de pop bc ret ; ;-------------------------------------------------------------- ; ISBREAK - Test break key pressed ;-------------------------------------------------------------- ; IsBreak: ld c,conio ld e,_CI call BDOS ; Get present key cp CtrlC ; Test CTRL-C jp z,OS ; End if so ret ; ;-------------------------------------------------------------- ; RDSEC - Read next logical record ;-------------------------------------------------------------- ; RdSect: ld de,FCB ; Point to FCB ld c,readnx call BDOS ; Read the record or a ret ; ;-------------------------------------------------------------- ; ; Work areas ; ;-------------------------------------------------------------- ; SCB: db _ConPag,_get Ch: db 0 PstFix: db 0 ; CurLin equ $ MaxLin equ CurLin+1 LCnt equ MaxLin+1 CCnt equ LCnt+1 RecNum equ CCnt+1 BufPos equ RecNum+2 SaveAd equ BufPos+1 BuffAd equ SaveAd+2 BaseAd equ BuffAd+2 ;;dirbuf equ BaseAd+3 ; end DUMP