; ; Program to dump Microsoft format ; rel files field by field ; with field comments ; ; See Microsoft 'linking loader' manual ; for more information on .rel files ; ; ; Requires Digital Research 'MAC' ; assembler, or alternatively, you ; can expand the macros and use ; the cp/m assembler 'asm'. ; ; ; 8/22/80 by Ron Fowler ; Westland, Mich. ; cr equ 13 lf equ 10 bdos equ 5 fcb equ 5ch buf equ 80h ; cifnc equ 1 prtchr equ 2 printf equ 9 cstsf equ 11 openf equ 15 readf equ 20 ; maxperline equ 16 ;abs items per line ; ; define some macros ; pchar macro x if not nul x mvi a,x endif call outchr endm ; print macro string local overstring call overstring db string overstring: pop d mvi c,printf call bdos endm ; bits macro num mvi b,num call getbits endm page ; ; get local stack and ; set up fcb ; ORG 100H ; base: lxi h,0 dad sp shld stack lxi sp,stack lda fcb+9 ;look at filetype cpi ' ' ;see if type specified jnz sk1 ;jmp if so lxi h,'RE' ;part of 'REl' shld fcb+9 ;store into fcb mvi a,'L' ;rest of 'reL' sta fcb+11 sk1: mvi c,openf ;open the .rel file lxi d,fcb call bdos cpi 0ffh ;should not be jnz main ;jump if not call msgxit ;else say can't find db 'File not found.$' page ; ; main work loop ; main: call item ;identify one item jc done ;cy is eof indicator call stop ;console says stop? jnc main ;continue if not done: call msgxit ;else print 'done' db cr,lf,'done.$' ; stop: mvi c,cstsf call bdos ora a rz mvi c,cifnc call bdos cpi 'C'-40h ;control-c? stc ;says stop rz cmc ;false char ret page ; ; decode an item ; item: bits 1 ;get first bit of item ora a ;test for zero jnz not$abs ;not zero, jmp for rel lxi h,relflg mov a,m mvi m,0 ora a jz cont1 call crlf mvi a,maxperline+1 sta abscnt cont1: lxi h,abscnt ;line up abs values mov a,m inr a mov m,a cpi maxperline jc lnok ;max values per line xra a mov m,a call crlf print 'ABS: $' lnok: bits 8 ;get 8 absolute bits call hexout ;display 'em pchar ' ' ora a ;no eof yet ret ; not$abs: call crlf call crlf mvi a,0ffh ;idntfy rel iterm sta relflg mvi a,maxperline+1 ;make new abs line sta abscnt print 'REL: type $' bits 2 ;get rel type spec push psw call hexout pop psw ora a jz spl ;0 is special type dcr a jz prgrel ;1 is program relative dcr a jz datrel ;2 is data relative ; ; must be 3, common relative ; print ', com rel, val=$' jmp prnt16 prgrel: print ', prg rel, val=$' jmp prnt16 datrel: print ', dat rel, val=$' prnt16: bits 8 ;get rel byte push psw ;save lst sig byte bits 8 ;next call hexout ;print most sig pop psw call hexout ;print least sig pchar ' ' ;print a space ora a ;not eof yet ret page ; ; handle special relative field ; spl: print ', (special), ctrl fld=$' bits 4 ;spl fld has.. sta ctrlfld ;..4 bits push psw call hexout ;print it print ', $' pop psw mov l,a mvi h,0 ;ctl fld in hl dad h ;offset for table lxi d,msgtable dad d mov e,m ;get lo byte inx h mov d,m ;de has field msg mvi c,printf call bdos ;identify type lda ctrlfld ;get control byte cpi 15 ;15 is eof stc ;so say so rz push psw ;new lin for a & b flds call crlf print ' $';tab over pop psw cpi 4+1 ;type 0-4 has no a fld jc bonly call afield ;show the a field lda ctrlfld cpi 14 ;end program... jnz not14 ;..forces byte boundary call refill ;go next byte ora a ;return cy clr ret not14: cpi 9 ;type 9-15 has no b rnc bonly: call bfield ora a ;say no eof ret page ; ; handle special rel fields ; afield: print 'a fld type: $' bits 2 ;get the a field push psw call hexout ;print it print ', $' ;make a comma,spc pop psw ;get back a field ora a ;examine it for type jz absad ;0=absolute adrs dcr a jz prg2 ;1=program rel dcr a jz data2 ;2=data rel ; ; must be common relative ; print '(common rel) value= $' jmp prnt16 data2: print '(data rel) value= $' jmp prnt16 prg2: print '(prog rel) value= $' jmp prnt16 absad: print '(absolute) value= $' jmp prnt16 ; bfield: bits 3 ;get b-field size mov e,a ;make a counter pchar '"' ;enclose in quotes bsym: mov a,e ;when e is zero ora a ;then we are done jz brout dcr e ;count down bits 8 ;get sym char pchar ;print it jmp bsym ;loop till done brout: pchar '"' ;close quotes ret page ; ;************************* ;* subroutines * ;************************* ; ; ; get number of bits from ; input stream as in b reg ; getbits: push h push d xra a ;zero our byte bitlop: call nxtbit ;next bit into cy flg ral ;shift into our byte dcr b ;count down jnz bitlop pop d pop h ret ; ; get next bit from input stream ; nxtbit: push b mov b,a ;can't alter a lda bitcnt ;any left this byte? ora a cz refill ;get another if not dcr a sta bitcnt ;update for nxt time lda char ;current byte ral ;bit into cy sta char mov a,b ;restore accumulator pop b ret ; ; get the next byte from input buffer ; refill: push b lda bufptr cpi 80h ;see if buf empty cz diskrd ;fill if so mov l,a mvi h,0 ;form 16 bits inr a ;update buf pntr sta bufptr lxi d,buf dad d ;point into buffer mov a,m ;reach in and get byte sta char ;save it mvi a,8 ;new bit count sta bitcnt pop b ret ; ; read next sector from file ; diskrd: mvi c,readf lxi d,fcb call bdos cpi 0ffh ;should not be.. mvi a,0 ;..early eof rnz call msgxit ;oops! db '??? Unexpected end of file.$' ; ; print message pointed ; to by tos then exit ; msgxit: pop d mvi c,printf call bdos lhld stack sphl ret ;to ccp crlf: mvi a,cr call outx mvi a,lf call outx lda lincnt inr a sta lincnt cpi 61 ;lines/page rnz mvi b,6 ;lines to nxt page formfd: mvi a,lf call outx ;<<< dcr b jnz formfd mvi a,1 ;say first line sta lincnt ret hexout: push psw rar rar rar rar call nybble pop psw nybble: ani 0fh cpi 10 jc xnum adi 7 xnum: adi '0' pchar ret page ; ; print char in a (called from ; macros only). ; outchr: cpi ' ' ;check for printable.. jnc chka ;..characters, make... fix: mvi a,'.' ;...non-printing chars.... chka: cpi 7fh ;....dots jnc fix outx: push h push d push b mvi c,prtchr mov e,a call bdos pop b pop d pop h ret ; ; table of control-field ; type messages ; msgtable: dw m0,m1,m2,m3 dw m4,m5,m6,m7 dw m8,m9,m10,m11 dw m12,m13,m14,m15 ; ; the messages: ; m0: db '* entry symbol *$' m1: db '* sel com blk *$' m2: db '* program name *$' m3: db '* request library search *$' m4: db '* extension link item *$' m5: db '* common size *$' m6: db '* chain external *$' m7: db '* define entry point *$' m8: db '* external - offset *$' m9: db '* external + offset *$' m10: db '* define data size *$' m11: db '* set loc counter *$' m12: db '* chain address *$' m13: db '* program size *$' m14: db '* end program *$' m15: db '* end of file *$' page ; ; variables ; bufptr: db 80h ;force initial read bitcnt: db 0 ;and empty char char: db 0 ctrlfld: db 0 abscnt: db maxperline+1 ;force initial crlf lincnt: db 1 ;start paper at line 1 relflg: db 0 db 0 ds 50 ;stack space stack: ;stk prt save end