title COM to HEX Converter name ('UNLOAD') ; ; DASMed version of UNLOAD.COM ; .z80 aseg org 0100h 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 hl,(BDOS+1) ; Get top of memory dec hl ld sp,hl ; For stack jp FIcopy ; Start program ; ; Copy ^HL to ^DE C-times ; move: ld a,(hl) ; Simple copy ld (de),a inc hl inc de dec c jp nz,move ret ; ; Copy filename ; FIcopy: ld hl,FCB ld de,FIN ld c,fdrv+fnam call move ; Unpack filename jp Freset ; FIN: ds fdrv+fnam db 'COM' ds 21 FIDMAptr: dw FINDMA RdPos: dw reclng*RECBUF RdPtr: dw 0 ; Freset: jp reset ; ; Get byte from COM file - Z set says end of file ; fget: ld hl,(RdPos) ; Get top pointer ex de,hl ld hl,(RdPtr) ; Get read index ld a,l sub e ; Test still character in buffer ld a,h sbc a,d jp 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 jp nc,RdEnd ; Yeap ld hl,(FIDMAptr) ; Get base input buffer add hl,de ex de,hl ld c,setdma call BDOS ; Set disk buffer ld de,FIN ld c,rdseq call BDOS ; Read record or a ; Test read successfull jp nz,RdEOF ; End of file ld de,reclng ld hl,(RdPtr) ; Get read index add hl,de ; Update it ld (RdPtr),hl jp RdNext RdEOF: ld hl,(RdPtr) ; Get read index ld (RdPos),hl ; Set for top pointer RdEnd: ld de,DMA ld c,setdma call BDOS ; Set disk buffer ld hl,0 ld (RdPtr),hl ; Init read index getc: ex de,hl ld hl,(FIDMAptr) ; Get base input buffer add hl,de ; Position buffer ex de,hl ld hl,(RdPos) ; Get top pointer ld a,l or h ld a,eof ret z ld a,(de) ld hl,(RdPtr) inc hl ; Update read index ld (RdPtr),hl ret ; ; Reset input file ; reset: 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 jp nz,FOcopy ; Yeap ld c,string ld de,OPENMSG call BDOS ; Tell file not found jp OS ; OPENMSG: db cr,lf,'NO IFILE FILE',eot ; FOcopy: ld hl,FCB ld de,FOT ld c,fdrv+fnam call move ; Unpack filename jp Frewrite ; FOT: ds fdrv+fnam db 'HEX' ds 21 FODMAptr: dw FOTDMA WrTop: dw reclng*RECBUF WrPtr: dw 0 ; Frewrite: jp rewrite ; ; Put character to HEX file ; fput: push af ld hl,(WrTop) ; Get last write index ex de,hl ld hl,(WrPtr) ; Get write index ld a,l sub e ; Test space in buffer ld a,h sbc a,d jp 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 jp nc,WrEnd ; Yeap ld hl,(FODMAptr) ; Get base output buffer add hl,de ex de,hl ld c,setdma call BDOS ; Set disk buffer ld de,FOT ld c,wrseq call BDOS ; Write record or a ; Test write successfull jp nz,WrErr ; Write error ld de,reclng ld hl,(WrPtr) ; Get write index add hl,de ; Update it ld (WrPtr),hl jp WrNext WrErr: ld c,string ld de,CREATEMSG call BDOS ; Tell no disk space pop af jp OS ; CREATEMSG: db cr,lf,'DISK FULL: OFILE',eot ; WrEnd: ld de,DMA ld c,setdma call BDOS ; Set disk buffer ld hl,0 ld (WrPtr),hl ; Init write index putc: ex de,hl ld hl,(FODMAptr) ; Get base output buffer add hl,de ; Position in buffer ex de,hl pop af ; Get back byte ld (de),a ; Store it ld hl,(WrPtr) inc hl ; Advance write index ld (WrPtr),hl ret ; ; Rewrite output file ; rewrite: xor a ld (FOT+FEX),a ; Clear FCB locations ld (FOT+FCR),a ld hl,reclng*RECBUF ld (WrTop),hl ; Init top write index ld hl,0 ld (WrPtr),hl ; Init 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 jp nz,COM2HEX ld c,string ld de,DIRMSG call BDOS ; Cannot create jp OS ; DIRMSG: db cr,lf,'NO DIR SPACE: OFILE',eot ; ; Conversion routine ; COM2HEX: 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 jp c,COM2HEXgo ; That's it cp 9+1 ; Test range jp c,BldStrt sub 'A'-'0'-10 ; Maybe hex jp c,COM2HEXgo cp 15+1 ; Test range again jp 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 jp NxtAdr ; ; >>>> MAIN JOB <<<< ; COM2HEXgo: ld (StrtAdr),hl ; Save start address call fget ; Get byte from COM file jp 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 jp z,HEXnl call fget ; Get next byte from COM file jp HEXline ; ; 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,'0' ; Add offset cp '9'+1 ; Test range jp c,fputdec add a,'A'-'0'-10 fputdec: push bc call fput ; Put character to HEX file pop bc ret ; ; Process end of HEX line ; HEXnl: ld a,(HexChksum) ; Get checksum call fputbyte ; Put hex ASCII to file ld a,cr call fput ; Put character to HEX file ld a,lf call fput ld hl,(StrtAdr) ; Get current address ld de,HEXLEN add hl,de ; Update it jp 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 dec b jp nz,ZeroHEX ld a,cr call fput ; Close line of HEX file ld a,lf call fput EofHEX: ld hl,(WrPtr) ; Get write index ld a,l and reclng-1 ; Mask it jp 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 jp nz,EofHEX ; Record not yet filled ld c,close ld de,FOT call BDOS ; Close file inc a jp nz,Halt ld c,string ld de,CLOSEMSG call BDOS ; Tell close error jp Halt ; CLOSEMSG: db cr,lf,'CANNOT CLOSE OFILE',eot ; Halt: jp OS ; StrtAdr: dw 0 HexChksum: db 0 ; FINDMA equ $ FOTDMA equ FINDMA+reclng*RECBUF end