home *** CD-ROM | disk | FTP | other *** search
-
-
- ; ------------------------------------------------------------
- ; .REL files are encoded as a bitstream according to certain
- ; rules which are spelled out in Microsoft's FORTRAN manual.
- ; As a consequence a normal disk dump program will not be very
- ; intelligible, even to people who have learned to recognize
- ; 8080 opcodes in hexadecimal form, or to spot ASCII constants
- ; in a program. The purpose of READREL.CMD is to generate a
- ; hexadecimal dump of a .REL file, interspersed with special
- ; directives as they are produced by M80.COM, F80.COM or other
- ; relocating assemblers using the same format.
- ;
- ; READREL - Copyright (C) 1983
- ; Universidad Autonoma de Puebla
- ; November 24, 1983
- ;
- ; [Harold V. McIntosh, 24 November 1983]
- ; ------------------------------------------------------------
-
-
- BDOS equ 224 ;CP/M interrupt to BDOS
-
- TFCB equ 005CH
- TSIZ equ 0080H ;CP/M's record size
- DSIZ equ 0100H ;size of .OUT buffer (must be 100H)
- RSIZ equ 0400H ;size of relfile buffer
- LSIZ: equ 16 ;line length (maximum spaces per line)
-
- LF equ 0AH
- CR equ 0DH
-
- ; -------------
- org 0100H
- ; -------------
-
- BEGN: sto #0000,BCTR ;byte counter
- sto #DSIZ,DCTR ;output downcounter
- sto #DBUF,DPTR ;output pointer
- sto #0000,RCTR ;relfile counter
- sto #RBUF,RPTR ;relfile pointer
- stob #LSIZ,LCTR ;count 16 bytes/line
- stob #00,COLM ;FF=column 1
- cmpb TFCB+1,#' '
- jnz NNUL
- ld dx,#LOGO ;'UAP...'
- call MSSG ;type text at (dx)
- ld dx,#TUTO ;instructions for usage
- call MSSG ;type text at (dx)
- jmp GBYE ;normal exit
-
- NNUL: ld cl,#021H ;count
- ld dx,#TFCB ;source
- ld bx,#RFCB ;.REL FCB = destination
- call MIUC ;block move
-
- stob #'R',RFCB+9
- stob #'E',RFCB+10
- stob #'L',RFCB+11
- stob #00H,RFCB+12
-
- ld cl,#15 ;(0F) open file
- ld dx,#RFCB ;.REL FCB
- int BDOS
- cmpb al,#0FFH
- ld dx,#COSO ;'can''t open .REL file'
- jnz ORLF
- jmp TEMA ;type text at (dx), quit
-
- ORLF: stob #00,DOUT ;z=no disk output
- cmpb TFCB+17,#' ' ;output filename
- jz NOUT
- stob #0FFH,DOUT ;z=no disk output
-
- ld cl,#16
- ld dx,#TFCB+16
- ld bx,#TFCB ;CP/M's file control block (.OUT)
- call MIUC
-
- cmpb TFCB+9,#' ' ;output extension
- jnz YEXT
- stob #'O',TFCB+9
- stob #'U',TFCB+10
- stob #'T',TFCB+11
-
- YEXT: ld cx,#0003
- ld bx,#TFCB+9
- ld dx,#RFCB+9
- YEXX: xchg bx,dx
- ld al,[bx]
- xchg bx,dx
- cmp al,[bx]
- inc bx
- inc dx
- loopz YEXX
- jnz NEQL
- ld dx,#MEQL ;'extensions equal'
- jmp TEMA ;type text at (dx), quit
-
- NEQL: ld cl,#19 ;(13) delete file
- ld dx,#TFCB ;CP/M's file control block (.OUT)
- int BDOS
-
- ld cl,#22 ;(16) create file
- ld dx,#TFCB ;CP/M's file control block (.OUT)
- int BDOS
-
- ld cl,#15 ;(0F) open file
- ld dx,#TFCB ;CP/M's file control block (.OUT)
- int BDOS
- cmp al,#0FFH
- ld dx,#DDFU ;'no more directory'
- jnz NOUT
- jmp TEMA ;type text at (dx), quit
-
- NOUT: sto #0FF00H,ROBY ;rotating byte, bit counter
- call REFI ;process the .REL file
- cmpb DOUT,#00 ;z=no disk output
- jz FINI
-
- ; Fill the remainder of the output file with ^Z's, write
- ; the tag end to disk, and close the file.
-
- ld cx,DCTR ;output downcounter
- ld bx,DPTR ;output pointer
- ld al,#1AH ;^Z
- jcxz CLOP
- CLOO: sto al,[bx]
- loop CLOO
-
- CLOP: cmpb DBUF,#1AH ;^Z
- jz CLOS
- ld cl,#26 ;(1A) set DMA address
- ld dx,#DBUF
- int BDOS
-
- call BUDK ;record to disk
-
- cmpb DBUF+TSIZ,#1AH ;^Z
- jz CLOS
- ld cl,#26 ;(1A) set DMA address
- ld dx,#DBUF+TSIZ
- int BDOS
-
- call BUDK ;record to disk
-
- CLOS: ld cl,#16 ;(10) close file
- ld dx,#TFCB ;CP/M's file control block (.OUT)
- int BDOS
- cmp al,#0FFH
- ld dx,#NCLO ;'can''t close file'
- jnz FINI
- jmp EDSK ;delete .OUT file, type messages
-
- FINI: call CRLF ;CR,LF
- GBYE: ld dl,#00
- ld cl,#00
- int BDOS
-
- ; Type CR, LF.
-
- CRLF: ld al,#CR
- call CONA ;console from A
- ld al,#LF
- call CONA ;console from A
- stob #LSIZ,LCTR ;count 16 bytes/line
- stob #0FFH,COLM ;FF=column 1
- ld cl,#11 ;(0B) console status
- int BDOS
- or al,al
- jz CRLR
- ld cl,#1 ;(01) read console
- int BDOS
- ld dx,#IRRP ;'analysis interrupted'
- call MSSG
- cmpb DOUT,#00 ;z=no disk output
- jz GBYE
- jmp EDSQ ;delete .OUT file, type messages
- CRLR: ret
-
- ; word: type dx as four nibbles.
- ; byte: type A as two nibbles.
-
- WORD: mov al,dh
- call BYTE ;type A as two nibbles
- mov al,dl
- BYTE: call TADR ;type address if column 1
- BEIT: push ax
- rcr al
- rcr al
- rcr al
- rcr al
- call NIBL ;type A as hex
- pop ax
- NIBL: and al,#0FH
- add al,#90H
- daa
- adc al,#40H
- daa
- CONA: push bx
- push dx
- push ax
- ld cl,#2 ;(02) write console
- mov dl,al
- int BDOS
- pop ax
- cmpb DOUT,#00 ;z=no disk output
- jz CONB
- call DDDA
- CONB: pop dx
- pop bx
- ret
-
- ; Type several spaces.
-
- DUBL: call SNGL ;type one space
- SNGL: decb LCTR ;count 16 bytes/line
- jnz NOCR
- call CRLF
- NOCR: ld al,#' '
- jmp CONA
-
- ; Type relative address if at start of a new line.
-
- TADR: push bx
- incb COLM ;FF=column 1
- jnz TRET
- push ax
- ld al,#'('
- call CONA
- ld bx,BCTR
- mov al,bh
- call BEIT
- mov al,bl
- call BEIT
- ld al,#')'
- call CONA
- call SNGL
- pop ax
- TRET: pop bx
- ret
-
- ; Type message at (dx).
-
- MSSG: xchg bx,dx
- MSSH: ld al,[bx]
- cmp al,#'$'
- jz MSSR
- call CONA
- inc bx
- jmp MSSH
- MSSR: ret
-
- ; Type message, erase .OUT file, quit.
-
- EDSK: call MSSG
- EDSQ: ld cl,#19 ;(13) delete file
- ld dx,#TFCB ;CP.M's file control block (.OUT)
- int BDOS ;don't leave a partial file
- ld dx,#ERAD ;'output file erased'
- TEMA: call MSSG
- jmp GBYE
-
- ; Block move.
-
- MIUC: xchg bx,dx
- ld al,[bx]
- xchg bx,dx
- sto al,[bx]
- inc bx
- inc dx
- dec cl
- jnz MIUC ;block move
- ret
-
- ; Place disk output in buffer, store the buffer in the
- ; disk as it is filled and reinitialize it.
-
- DDDA: cmp DCTR,#0000
- jnz DDDB
- call BUDI ;output downcounter
- DDDB: dec DCTR
- ld bx,DPTR ;output pointer
- sto al,[bx]
- inc DPTR ;output downcounter
- ret
-
- ; Send DBUF to disk.
-
- BUDI: push ax
- call BUDJ
- sto #DBUF,DPTR ;output pointer
- sto #DSIZ,DCTR
- pop ax
- ret
-
- BUDJ: ld cl,#26 ;(1A) set DMA address
- ld dx,#DBUF ;output buffer
- int BDOS
-
- call BUDK ;record to disk
-
- ld cl,#26 ;(1A) set DMA address
- ld dx,#DBUF+TSIZ ;CP/M's record size
- int BDOS
-
- BUDK: ld cl,#21 ;(15) write one record
- ld dx,#TFCB ;CP/M's file control block (.OUT)
- int BDOS
- cmp al,#00H
- ld dx,#DIWR ;'disk write error'
- jnz EDSK ;delete .OUT file, type messages
- ret
-
- ; Get next bit.
-
- GEBI: incb ROBY+1
- jnz GEBJ
- call NXHX
- stob al,ROBY
- stob #0F8H,ROBY+1 ;-8
- GEBJ: rclb ROBY
- ret
-
- ; Read sixteen bits from the .REL file, leave them in dx.
-
- GEWO: call GEBY
- push ax
- call GEBY
- pop dx
- mov dh,al
- ret
-
- ; Read a full byte from the .REL file, leave it in al.
-
- GEBY: ld cl,#08
- BITS: ld ch,#00
- MORE: call GEBI ;get next bit
- rcl ch
- dec cl
- jnz MORE
- mov al,ch
- ret
-
- ; Get next relfile element.
-
- NXHX: push cx
- push bx
- cmp RCTR,#0000 ;relfile counter
- jnz NXHV ;byte available
- sto #RBUF,RPTR
- NXHY: cmp RPTR,#(RBUF+RSIZ)
- jnc NXHU ;reset relfile, read 1st element
- ld cl,#26 ;(1A) set DMA address
- ld dx,RPTR ;relfile buffer
- int BDOS
- ld cl,#20 ;(14) read one record
- ld dx,#RFCB ;.REL FCB
- int BDOS
- cmp al,#000H
- jnz NXHZ
- add RPTR,#TSIZ
- add RCTR,#TSIZ
- jmp NXHY
-
- NXHZ: cmp al,#001H
- ld dx,#DIRD ;'disk read error'
- jz NXHU
- jmp TEMA ;type text at (dx), quit
-
- NXHU: sto #RBUF,RPTR
- NXHV: dec RCTR
- ld bx,RPTR
- inc RPTR
- ld al,[bx]
- pop bx
- pop cx
- ret
-
- ; -------------------
- ; Read the .REL file.
- ; -------------------
-
-
- ; The first bit read determines whether a single byte
- ; follows (bit = 0), to be used without alteration, or
- ; whether the following information may be relocatable
- ; (bit = 1).
-
- REFI: call GEBI ;get next bit
- jc RELA ;not absolute byte
- call GEBY ;full byte from .REL
- call BYTE ;type A as two nibbles
- call SNGL ;type one space
- inc BCTR ;byte counter
- jmp REFI ;.REL read loop
-
- ; When the leadin bit is 1, two more bits are read to
- ; distinguish four alternatives: 00 for further analysis,
- ; 01 for program segment, 10 for data segment, or 11 for
- ; common segment. In the latter three cases, a two-byte
- ; address will be read, which a loader would assign to its
- ; proper memory segment.
-
- RELA: ld cl,#2
- call BITS ;get C bits from .REL
- or al,al
- jz SPEC ;'special LINK element'
- call TADR ;type address if column 1
- call GTYQ ;fetch segment descriptor
- call MSSG ;type text at (dx)
- call GEWO ;sixteen bits from .REL
- call WORD ;type dx as four nibbles
- call CRLF ;CR, LF
- ld bx,BCTR ;byte counter
- inc bx
- inc bx
- sto bx,BCTR ;byte counter
- jmp REFI ;.REL read loop
-
- ; There are sixteen 'special LINK elements' ranging from
- ; entry point definitions to the EOF indicator. They fall
- ; into three or four general groups, depending on whether
- ; they are associated with an eight-byte ASCII label, a
- ; relocatable address, both, or neither. Since they represent
- ; parenthetic information, they are set off on a line by
- ; themselves.
-
- SPEC: cmpb LCTR,#LSIZ ;max spaces/line
- jz SPED
- call CRLF ;CR,LF
- SPED: stob #0,COLM ;FF=column 1
- ld cl,#4
- call BITS ;get C bits from .REL
- ld ah,#0
- add ax,ax ;case number indexes two tables
- mov bx,ax
- ld di,#META ;case table for messages
- ld dx,[bx+di]
- ld di,#JUTA ;case table for action addresses
- push [bx+di]
- jmp MSSG ;type text at (dx)
-
- ; Message table, to correspond to the 'special' relocation
- ; elements, of which there are sixteen. These are the
- ; descriptive messages inserted into the output stream.
-
- META: dw ME0 ;'entry symbol'
- dw ME1 ;'COMMON block'
- dw ME2 ;'program name'
- dw ME3 ;'request library search'
- dw ME4 ; reserved
- dw ME5 ;'COMMON size'
- dw ME6 ;'chain external'
- dw ME7 ;'define entry'
- dw ME8 ; reserved
- dw ME9 ;'external add offset'
- dw MEA ;'size of DATA area'
- dw MEB ;'loading location counter'
- dw MEC ;'chain address'
- dw MED ;'define program size'
- dw MEE ;'end of program'
- dw MEF ;'end of file'
-
- ; There may be a label or a further address associated
- ; with each 'special LINK item.' These subroutines take
- ; the appropriate action in each case.
-
- JUTA: dw TEXT ;ASCII label
- dw TEXT ;ASCII label
- dw TEXT ;ASCII label
- dw TEXT ;ASCII label
- dw TEXT ;ASCII label
- dw STYP ;storage type
- dw STYP ;storage type
- dw STYP ;storage type
- dw STYP ;storage type
- dw PHUE ;storage type w/ address
- dw PHUE ;storage type w/ address
- dw PHUE ;storage type w/ address
- dw PHUE ;storage type w/ address
- dw PHUE ;storage type w/ address
- dw PHOO ;program end - flush byte
- dw EOFI ;EOF
-
- ; The 'special LINK item' includes an 8-byte label
- ; or similar ASCII string. 8 bytes is maximum, there
- ; must be at least 1, 8 is taken for 0.
-
- TEXT: ld cl,#3
- call BITS ;get C bits from .REL
- or al,al ;take 0 to mean 8
- jnz X2X
- ld al,#8
- X2X: push ax
- call GEBY ;full byte from .REL
- call CONA
- pop ax
- dec al
- jnz X2X
- call CRLF ;CR,LF
- jmp REFI ;.REL read loop
-
- ; The 'special LINK item' requires identification via
- ; the following two bits, as to whether it is absolute
- ; (00), code (01), data (10), or common (11).
-
- STYP: call GTYP ;ascertain storage type
- call MSSG ;type text at (dx)
- call TWRD ;read & type word from .REL
- call DUBL ;type one space
- jmp TEXT ;ASCII label
-
- ; Read two bits to ascertain storage type, then load
- ; address of appropriate descriptor for console typing.
-
- GTYP: ld cl,#2
- call BITS ;get C bits from .REL
- GTYQ: ld dx,#MABS ;'ABS:'
- or al,al
- jz GTYR
- ld dx,#MPRG ;'PREL'
- dec al
- jz GTYR
- ld dx,#MDAT ;'DREL'
- dec al
- jz GTYR
- ld dx,#MCOM ;'CREL'
- GTYR: ret
-
- ; This class of 'special LINK items' require a two-bit
- ; storage classigication followed by a two-byte address.
-
- PHUE: call GTYP ;ascertain storage type
- call MSSG ;type text at (dx)
- call TWRD ;read & type word from .REL
- call CRLF ;CR,LF
- jmp REFI ;.REL read loop
-
- ; At the program end, the bit stream should be squared
- ; off at a byte boundary. A start address may be present.
-
- PHOO: call GTYP ;ascertain storage type
- call MSSG ;type text at (dx)
- call TWRD ;read & type word from .REL
- call CRLF ;CR,LF
- sto #0FF00H,ROBY ;rotating byte, bit counter
- jmp REFI ;.REL read loop
-
- ; End of File.
-
- EOFI: ret
-
- ; Read a word from .REL and type it.
-
- TWRD: call GEWO ;sixteen bits from .REL
- jmp WORD ;type dx as four nibbles
-
- ; -------------------------------------------------------
-
-
- LOGO: db CR,LF
- db ' READREL/ICUAP',CR,LF
- db 'Universidad Autonoma de Puebla',CR,LF
- db ' November 24, 1983',CR,LF,'$'
-
- TUTO: db CR,LF
- db 'READREL.CMD will decompose the bitstream which',CR,LF
- db 'constitutes a .REL file into hexadecimal bytes',CR,LF
- db 'and addresses interspersed with commentaries',CR,LF
- db 'derived from the ''special LINK elements'' and',CR,LF
- db 'other clarifying information. The command:',CR,LF,CR,LF
- db ' READREL [D:]FILE[.REL] [[D:]LIST[.OUT]]',CR,LF,CR,LF
- db 'will analyze the requested file. If no extension',CR,LF
- db 'is given, .REL will be used. The analysis will',CR,LF
- db 'always appear at the console. When a second file is',CR,LF
- db 'given (with default extension .OUT), it will gather',CR,LF
- db 'in the output listing. Pressing any key will stop',CR,LF
- db 'the program.',CR,LF
- db '$'
-
- ME0: db 'entry symbol $'
- ME1: db 'COMMON block $'
- ME2: db 'program name $'
- ME3: db 'req lib srch $'
- ME4: db 'reserved $'
- ME5: db 'COM size $'
- ME6: db 'chain ext $'
- ME7: db 'def entry $'
- ME8: db 'reserved $'
- ME9: db 'extnl + offset $'
- MEA: db 'size DATA area $'
- MEB: db 'ldng locn cntr $'
- MEC: db 'chain address $'
- MED: db 'def prgrm size $'
- MEE: db 'end of program $'
- MEF: db 'EOF$'
- MABS: db 'ABS: $'
- MPRG: db 'PREL $'
- MDAT: db 'DREL $'
- MCOM: db 'CREL $'
- DIRD: db 'Disk read error.$'
- DIWR: db 'Disk write error.$'
- COSO: db 'Can''t open .REL file.$'
- DDFU: db 'Disk or Directory full.$'
- NCLO: db 'Cannot close file.$'
- MEQL: db 'Duplicate extensions.$'
- IRRP: db '-- Analysis interrupted --',CR,LF,'$'
- ERAD: db '- Output file suppressed -$'
-
- RFCB: ds 21H ;.REL FCB
- RBUF: ds RSIZ ;relfile buffer (400H)
- RPTR: ds 2 ;relfile pointer
- RCTR: ds 2 ;relfile counter
- ROBY: ds 2 ;rotating byte, bit counter
- DOUT: ds 1 ;z=no disk output
- DCTR: ds 2 ;output downcounter
- DPTR: ds 2 ;output pointer
- LCTR: ds 1 ;count 16 bytes/line
- COLM: ds 1 ;FF=column 1
- BCTR: ds 2 ;byte counter
- DBUF: ds DSIZ ;.OUT buffer
-
- end
-
-