title Convert M80 to (R)MAC PRN format name ('PRINT80') maclib base80 ; Program converts print files generated by the M80 ; macro assembler into format as generated by MAC or ; RMAC assembler. The symbol table and statistic pages ; may be extracted optionally into a second file with ; extension .SMP ; The default extension of the file is .PRN ; Copyright (c) Werner Cirsovius ; Hohe Weide 44 ; D-20253 Hamburg ; Federal Republic of Germany ; Tel.: (+49)040/4223247 ; Version 3.2, January 2002 ; To get program running use : ; PRINT80 filename{.ext} {/{S}{L}} ; Filename may contain wildcards ; Default .ext is .PRN. The name of the converted file ; will not be changed. ; If option /S is selected, a symbol file "filename.SMP" ; will be generated ; If option /L is selected, the form feed will be expanded ; to FF, CR, LF. ; Externals from library BASELIB extrn create,close,delete,rename,puteof,files extrn string,open,fillin,emplin,dskput extrn filnam,wrfcb,wrbuf,wrbfp,rdbfp,comp2,crlf ; ===== Constants ===== linlen equ 132 ; Max line length MaxFile equ 256 ; Max files to be searched ; ***** Program starts here ***** ld sp,loc ; Get our stack ld a,(fcbnam) ; Check any input cp ' ' ld de,help jr z,comstr ld de,fcbext ld a,(de) ; Test extension cp ' ' jr nz,nonew ld hl,def$ ld bc,.fext ldir ; Set .PRN nonew: call get.opt ; Check option ld de,illopt jr c,comstr ; .. illegal ld de,fcb ld hl,($memry) ld bc,MaxFile call files ; .. search files ld de,nofil jr c,comstr ; Nothing on disk pr80.loop: push bc ld de,fcbnam ld bc,.fname+.fext inc hl ; Skip possible user ldir ; Set file push hl ld bc,ini.lp ld de,cur..pag ld hl,ini.pag ldir ; Init page count call do.print ; .. process it pop hl pop bc dec bc ld a,b ; Test ready or c jr nz,pr80.loop ld de,alldone comstr: call crlf ; Close line call string ; Tell anything call crlf jp OS ; Bye, bye ; ; The main conversion loop ; do.print: ld a,reclng ld (rdbfp),a ; Force read ld de,proc call string ld de,fcbnam call filnam ; Tell file processing call crlf ld de,fcb ld a,(de) ld (dumfcb),a ; Set same drive call open ; Open file ld de,nosing ; .. not here jr c,comstr ld de,dumfcb call delete call create ; Create PRINT80.$80 ld de,cancre jr c,comstr ; .. not possible ld hl,dumfcb ld (wrfcb),hl ; Init file pointers ld hl,ourdma ld (wrbuf),hl xor a ld (wrbfp),a ; Set empty buffer inloop: ld de,inbuf-1 ld b,null call fillin ; Get line from file ld de,illcod jr c,comdst ; .. test valid file call fixlin ; Format line jr c,done ; End found ld de,outbuf call _emplin ; Fix FF ld b,null call emplin ; Output line ld de,wrter jr c,comdst jr inloop done: call crlf call puteof ; Fill with EOF ld de,wrter jr c,comdst ld de,dumfcb call close ; Close file ld de,cancls jr c,comdst ld a,(SMP.req) ; Test request cp true call z,get.SMP ; Get SMP file if so ld de,fcb call delete ; Delete old file ld de,dumfcb+dirlen ld hl,fcb ld bc,dirlen ldir ; Unpack name ld de,dumfcb call rename ; Rename file ld de,okdone jr nc,tell ld de,baddne comdst: push de ld de,dumfcb call delete ; Delete PRINT80.$80 pop de tell: call string ; Tell state message call crlf ret ; ; Format a line ; fixlin: call ..fix ; Unpack line ld a,b ; Test count ld (cnt),a sub 2 or a ret z ; End if only cr/lf ld a,(inbuf) ; Test new page cp ff jr nz,norpag ld de,inbuf srclop: ld hl,pag push de call comp2 ; Find PAGE jr z,pagfnd pop de inc de djnz srclop or a ret pagfnd: inc de ld a,(de) pop de cp 'S' ; Test statistic page scf ret z call pr.pag ; Print current page ld a,(inbuf+1) cp tab ; Test tab jr z,tabset or a ret tabset: ld hl,inbuf+2 ld de,outbuf+1 ld a,(cnt) ld c,a ld b,0 dec c ldir ; Delete tab or a ret norpag: ld a,(inbuf+1) cp ' ' ; Test blanks ret nz ; No code if not ld a,(inbuf+7) cp ' ' ret nz ld a,(inbuf+8) cp ' ' ret nz ld hl,inbuf+2 ld de,outbuf+1 ld bc,5 ldir ; Unpack address bytes ld a,(inbuf+25) ld (de),a ; Save include indicator inc de ld hl,inbuf+10 ld a,(inbuf+12) ; Test possible address table cp '0' jr nc,adrtbl ; .. nope ld a,4 getbyt: ld bc,2 ldir ; Get next bytes ld b,a ld a,(hl) cp ' ' ; Test blank here ld a,b jr z,skpblk push hl dec de dec de ld bc,2 ldir ; Swap address bytes pop hl dec hl dec hl ld bc,2 ldir inc hl dec a ; Test end here jr z,endcod skpblk: inc hl ; Skip blanks dec a jr nz,getbyt endcod: ld a,(hl) ld (de),a ; Maybe code inc de exdcod: ld hl,inbuf+32 getcod: ld a,(hl) ; Unpack code ld (de),a or a ; Test end ret z inc hl inc de jr getcod adrtbl: ld a,2 ; Set loop adrl1: push af ld a,2 adrl2: ld c,(hl) ; Get next two characters inc hl ld b,(hl) inc hl push bc dec a jr nz,adrl2 ex de,hl ld a,2 adrl3: pop bc ; Swap characters ld (hl),c inc hl ld (hl),b inc hl dec a jr nz,adrl3 ex de,hl ld c,(hl) ; Save indicator inc hl ; Skip indicator and blank inc hl pop af dec a jr nz,adrl1 ld a,c ; Get indicator ld (de),a inc de jr exdcod ; Save rest of line ; ; Fix line ; ..fix: ld hl,inbuf ; Point to source ld de,outbuf ; And destination ld b,-1 ; Init count unplin: ld a,(hl) ld (de),a ; Unpack till zero inc hl inc de inc b or a jr nz,unplin ret ; ; Expand FF if requested ; _emplin: ld a,(FF.req) ; Test request cp true ret nz ; .. nope, print all ld a,(de) ; Test ff cp ff ret nz ; .. nope, print all inc de ; Skip it call dskput ; Print FF ld a,cr call dskput ; Print CR ld a,lf call dskput ; Print LF ret ; ; Get SMP file ; get.SMP: ld de,st.SMP call string ; Tell SMP building ld hl,fcb ld de,fcb.SMP ld (wrfcb),de ld bc,.fdrv+.fname ldir ld hl,def.S ld bc,.fext ldir xor a ld (wrbfp),a ld de,fcb.SMP call delete ; Delete old file call create ; Make SMP file jr c,SMP.ERR SMP.loop: ld de,outbuf ld b,null call emplin jr c,SMP.ERR ld de,inbuf-1 ld b,null call fillin ; Get line jr c,EOF.SMP call ..fix ; Unpack line jr SMP.loop EOF.SMP: call puteof jr c,SMP.ERR ld de,fcb.SMP call close ; Close file ret nc SMP.ERR: ld de,fcb.SMP call delete ; Delete SMP file ld de,err.SMP call string ret ; ; Print current page on console ; pr.pag: push bc push de push hl ld de,cur.pag call string ; Print page ld de,cur..pag call string ld hl,cur..pag+6 bmp.pag: inc (hl) ; Bump page ld a,(hl) cp '9'+1 ; .. test overflow jr nz,ex.pag ld (hl),'0' ; Clear digit dec hl ld a,(hl) cp ' ' ; Test new digit jr nz,bmp.pag ld (hl),'1' ; .. init if new ex.pag: pop hl pop de pop bc ret ; ; Check valid option ; EXIT Carry set on error ; get.opt: ld hl,fcbnm2 ld a,(hl) ; Test parameter here cp ' ' ret z ; .. nope cp '/' ; Verify option scf ret nz ; .. invalid inc hl ld a,(hl) inc hl call is.S? ; Test SMP file jr z,is.S ; .. yeap call is.L? ; Verify FF setting scf ret nz ; .. nope ld a,(hl) cp ' ' ; Test more ret z ; .. nope call is.S? ; Verify SMP file ret z ; .. ok scf ret ; .. invalid is.S: ld a,(hl) cp ' ' ; Test more ret z ; .. nope call is.L? ; Verify FF setting ret z ; .. ok scf ret ; .. invalid ; is.L?: cp 'L' ; Test FF setting ret nz ld a,true ld (FF.req),a ; Set request ret ; is.S?: cp 'S' ; Test SMP file ret nz ld a,true ld (SMP.req),a ; Set request ret dseg help: db 'To get program running use :' db cr,lf,lf db tab,tab,'PRINT80 filename{.ext} {/{S}{L}}' db cr,lf,lf db 'Filename may contain wildcards' db cr,lf db 'Program converts print files generated by the M80 macro assembler into format' db cr,lf db 'as generated by MAC or RMAC assembler.' db cr,lf db 'The symbol table and statistic pages will be extracted into a second file with' db cr,lf db 'extension .SMP, if option ' db '/S is selected' db cr,lf db 'If option /L is selected, the form feed will be expanded to FF, CR, LF' db eot proc: db 'Processing file ',eot illopt: db 'Illegal option',eot nofil: db 'No file present',eot nosing: db 'File not present',eot cancre: db 'Cannot create file',eot wrter: db 'File write error',eot cancls: db 'Cannot close file',eot baddne: db 'Cannot rename file',eot okdone: db 'File converted',eot alldone: db 'All files converted',eot err.SMP: db 'Cannot write symbol file',eot illcod: db 'Seems to be no M80 generated file',eot st.SMP: db 'Extracting symbols ..',eot cur.pag: db 'Current page',eot cur..pag: db ' 1' db cr,eot ini.pag: db ' 1' ini.lp equ $-ini.pag ; def$: db 'PRN' def.S: db 'SMP' pag: db pagl,'PAGE' pagl equ $-pag-1 ; dumfcb: db '@'-'@','PRINT80 $80' .dumfcb equ $-dumfcb ds fcblen-.dumfcb fcb.SMP: ds fcblen $memry:: ds 2 SMP.req: db false FF.req: db false ; ; Length of buffer follows ; db linlen inbuf: ds linlen outbuf: ds linlen cnt: db 0 ourdma: ds reclng ; ds 2*32 loc equ $ end