title COM to HEX Converter name ('UNLOAD') ; ; DASMed version of UNLOAD.COM ; ; Code flow optimized ; Z80 instructions used ; CSEG and DSEG divided ; .z80 cseg OS equ 0000h BDOS equ 0005h FCB equ 005ch DMA equ 0080h TPA equ 0100h .string equ 9 .open equ 15 .close equ 16 .delete equ 19 .rdseq equ 20 .wrseq equ 21 .make equ 22 .setdma equ 26 reclng equ 128 fdrv equ 1 fnam equ 8 FEX equ 12 FDIR equ 16 FCR equ 32 lf equ 0ah cr equ 0dh eof equ 1ah eot equ '$' HEXLEN equ 16 RECBUF equ 8 ld sp,(BDOS+1) ; Get top of memory for stack ld hl,FCB ld de,FIN ld bc,fdrv+fnam ldir ; Unpack filename ; ; Reset input file ; xor a ld (FIN+FEX),a ; Clear FCB locations ld (FIN+FCR),a ld hl,reclng*RECBUF ld (RdPos),hl ; Init record pointer ld (RdPtr),hl ; Set read index ld c,.open ld de,FIN call BDOS ; Open file inc a ; Test success ld de,OPENMSG ; Tell file not found jp z,ErrMsg ld hl,FCB ld de,FOT ld bc,fdrv+fnam ldir ; Unpack filename ; ; Rewrite output file ; rewrite: xor a ld l,a ld h,a ld (FOT+FEX),a ; Clear FCB locations ld (FOT+FCR),a ld (WrPtr),hl ; Init write index ld hl,reclng*RECBUF ld (WrTop),hl ; Init top write index ld c,.delete ld de,FOT call BDOS ; Delete file ld c,.make ld de,FOT call BDOS ; Create new file inc a ; Test success ld de,DIRMSG ; Cannot create jp z,ErrMsg ; ; Conversion routine ; ld hl,TPA ; Init start address ld b,0 ld de,FCB+FDIR+fdrv NxtAdr: ld a,(de) ; Test 2nd argument inc de sub '0' ; Strip off offset jr c,COM2HEXgo ; That's it cp 9+1 ; Test range jr c,BldStrt sub 'A'-'0'-10 ; Maybe hex jr c,COM2HEXgo cp 15+1 ; Test range again jr nc,COM2HEXgo BldStrt: add hl,hl ; Value *16 add hl,hl add hl,hl add hl,hl ld c,a add hl,bc ; Insert new digit jr NxtAdr ; ; >>>> MAIN JOB <<<< ; COM2HEXgo: ld (StrtAdr),hl ; Save start address call fget ; Get byte from COM file jr z,LastHEX ; End of file push af ld a,':' call fput ; Put start to HEX file xor a ld (HexChksum),a ; Init checksum ld a,HEXLEN call fputbyte ; Put hex ASCII to file ld a,(StrtAdr+1) ; Get lo of start address call fputbyte ld a,(StrtAdr) ; Get hi of start address call fputbyte xor a call fputbyte pop af ld b,HEXLEN HEXline: push bc call fputbyte ; Put hex ASCII to file pop bc dec b jr z,HEXnl call fget ; Get next byte from COM file jr HEXline ; ; Process end of HEX line ; HEXnl: ld a,(HexChksum) ; Get checksum call fputbyte ; Put hex ASCII to file call fnl ; Close line of HEX file ld hl,(StrtAdr) ; Get current address ld de,HEXLEN add hl,de ; Update it jr COM2HEXgo ; ; Set end of HEX file ; LastHEX: ld a,':' call fput ; Put sync to HEX file ld b,5 ZeroHEX: xor a push bc call fputbyte ; Put zero ASCII to file pop bc djnz ZeroHEX call fnl ; Close line of HEX file EofHEX: ld hl,(WrPtr) ; Get write index ld a,l and reclng-1 ; Mask it jr nz,WrRec ; Not a boundary ld (WrTop),hl ; Set last write index WrRec: ld a,eof push af ; Save end flag call fput ; Put end of file to HEX file pop af ; Get back end flag jr nz,EofHEX ; Record not yet filled ld c,.close ld de,FOT call BDOS ; Close file inc a jp nz,OS ld de,CLOSEMSG ; Tell close error jp ErrMsg ; ; ### Subroutines ; ; Get byte from COM file - Z set says end of file ; fget: ld de,(RdPos) ; Get top pointer ld hl,(RdPtr) ; Get read index ld a,l sub e ; Test still character in buffer ld a,h sbc a,d jr c,getc ; Yeap ld hl,0 ld (RdPtr),hl ; Init read index RdNext: ex de,hl ld hl,(RdPos) ; Get top pointer ld a,e sub l ; Test buffer filled ld a,d sbc a,h jr nc,RdEnd ; Yeap ld hl,(FIDMAptr) ; Get base input buffer add hl,de call SetDMA ; Set disk buffer ld de,FIN ld c,.rdseq call BDOS ; Read record or a ; Test read successfull jr nz,RdEOF ; End of file ld de,reclng ld hl,(RdPtr) ; Get read index add hl,de ; Update it ld (RdPtr),hl jr RdNext RdEOF: ld hl,(RdPtr) ; Get read index ld (RdPos),hl ; Set for top pointer RdEnd: call ResDMA ; Set disk buffer ld (RdPtr),hl ; Init read index getc: ld de,(FIDMAptr) ; Get base input buffer add hl,de ; Position buffer ld de,(RdPos) ; Get top pointer ld a,e or d ; Test any left ld a,eof ret z ; Nope, end of file ld a,(hl) ld hl,(RdPtr) inc hl ; Update read index ld (RdPtr),hl ret ; ; Put character to HEX file ; fnl: ld a,cr call fput ; Close line of HEX file ld a,lf fput: push af ld de,(WrTop) ; Get last write index ld hl,(WrPtr) ; Get write index ld a,l sub e ; Test space in buffer ld a,h sbc a,d jr c,putc ; Yeap ld hl,0 ld (WrPtr),hl ; Init write index WrNext: ex de,hl ld hl,(WrTop) ; Get last write index ld a,e sub l ; Test buffer emptied ld a,d sbc a,h jr nc,WrEnd ; Yeap ld hl,(FODMAptr) ; Get base output buffer add hl,de call SetDMA ; Set disk buffer ld de,FOT ld c,.wrseq call BDOS ; Write record or a ; Test write successfull ld de,CREATEMSG jp nz,ErrMsg ; Write error ld de,reclng ld hl,(WrPtr) ; Get write index add hl,de ; Update it ld (WrPtr),hl jr WrNext WrEnd: call ResDMA ; Set disk buffer ld (WrPtr),hl ; Init write index putc: ld de,(FODMAptr) ; Get base output buffer add hl,de ; Position in buffer pop af ; Get back byte ld (hl),a ; Store it ld hl,(WrPtr) inc hl ; Advance write index ld (WrPtr),hl ret ; ; Put byte in accu as ASCII to HEX file ; fputbyte: ld c,a ld a,(HexChksum) ; Get checksum sub c ; Update it ld (HexChksum),a ld a,c rrca rrca rrca rrca call fputnyb ld a,c fputnyb: and 00001111b ; Mask bits add a,90h ; Tricky conversion daa adc a,40h daa push bc call fput ; Put character to HEX file pop bc ret ; ; Reset disk buffer ; ResDMA: ld hl,DMA SetDMA: ex de,hl ld c,.setdma call BDOS ; Set disk buffer ld hl,0 ret ; ; Tell error and exit ; ErrMsg: ld c,.string call BDOS jp OS dseg ; ; Input file control ; FIN: ds fdrv+fnam db 'COM' ds 21 FIDMAptr: dw FINDMA RdPos: dw reclng*RECBUF RdPtr: dw 0 ; ; Ouput file control ; FOT: ds fdrv+fnam db 'HEX' ds 21 FODMAptr: dw FOTDMA WrTop: dw reclng*RECBUF WrPtr: dw 0 ; ; --------------------------------------- ; StrtAdr: dw 0 HexChksum: db 0 ; OPENMSG: db cr,lf,'NO IFILE FILE',eot CREATEMSG: db cr,lf,'DISK FULL: OFILE',eot DIRMSG: db cr,lf,'NO DIR SPACE: OFILE',eot CLOSEMSG: db cr,lf,'CANNOT CLOSE OFILE',eot ; ; I/O buffer ; FINDMA equ $ FOTDMA equ FINDMA+reclng*RECBUF end