home *** CD-ROM | disk | FTP | other *** search
- ; TITLE XREF.ASM VER 2.50 13-Jan-85 B.Eiben (EIBEN@MARKET)
- ;
- ; for Assembly with LASM.COM
- ;
- ; Cross Reference Program
- ; for ASM and MAC files
- ;
- ; jeff kravitz
- ;
- ; modified by john mahr
- ; ray malitzke z80, m80
- ;
- ; This program generates a cross reference list for all Symbols in a .MAC
- ;.ASM assembler program. Its input is either an assembler source file
- ;(FN.typ) or an assembler listing file (FN.PRN). It will number the lines
- ;and generate a cross reference listing at the end of the program. The
- ;output defaults to the CPM list device, but it can be directed to the
- ;console or to a disk file instead. If the output is directed to a disk
- ;file, that file will be named FN.XRF. The filename will be the filename of
- ;the input file.
- ;
- ; It is invoked by entering:
- ; XREF FN.typ (OUTPUT TO LIST DEVICE)
- ; XREF FN.PRN CON (OUTPUT TO CONSOLE)
- ; XREF FN.ASM D (OUTPUT TO DISK-DEFAULT
- ; DRIVE)
- ; XREF FN.PRN B:D (OUTPUT TO DISK-DRIVE
- ; NUMBER SPECIFIED)
- ;
- ; To invoke help function enter:
- ; XREF ?
- ;
- ;13/Jan/85. Modified help-message and introduced XRF-only option (most
- ;editors allow to get to line-numbers easily). added marker "<>" for line
- ;holding symbol-definition. Shortened line-Nr. display to be consistent
- ;with CREF output. Moved code to conserve space - Warning XREF is NOT
- ;restartable. Moved comments from M80 source - not anymore needed - LASM is
- ;there and does the job. XREF assumes, that a symbol-definition ONLY is
- ;valid, if the specific token is the FIRST token on the line. This seems to
- ;work pretty well - with one exception : Since XREF works from unmarked
- ;source, it does NOT keep track (can't) of IF -- ENDIF phrases. So some
- ;symbols will appear to be multiply defined. (B.Eiben)
- ;
- ;01/30/83 Added operation (and pseudo) codes for Z80 and M80 assembler.
- ; (RMG)
- ;
- ;03/15/82 This program would lock up if there was a comment line that started
- ;with an asterisk('*') instead of a semicolon. The program then processed
- ;the whole line as a valid line of assemble code. This usually resulted in
- ;the cross reference program locking up if there were a lot lines that
- ;started with an asterisk. The program now treats an asterisk the same as a
- ;semicolon. This was done by changing the table CTAB1 so that the program
- ;branches to LSEMI when it finds an asterisk. Also fixed bug that occurred
- ;when the last record of a file was completely filled with data and thus had
- ;no control Z's(EOF characters) in it. This was done by always placing two
- ;control Z's after the last record was read. Finally fixed a bug that showed
- ;up only when a program had no symbols or labels in it. Added a check for an
- ;empty symbol table before attempting to print the symbol table. (JRM)
- ;
- ;03/06/82 Changed the code so that the size of output disk buffer can be
- ;specified at assembly time. The size is set by OUTSECT which equals the
- ;number of disk sectors to be written when the buffer is full. Implemented
- ;the same feature for disk input. INSECT sets the number of disk records to
- ;be read into the input buffer. On file type PRN the was a bug. Whenever
- ;the first symbol on a line was preceded by a character, the line was not
- ;listed in the cross reference listing. This was caused by skipping over the
- ;first 16 characters in the line on a CR(carriage return) instead of on a
- ;LF(line feed). This bug has been fixed. Added help function. This is
- ;invoked by entering XFER ?. (JRM)
- ;
- ;03/03/82 Added a 2k buffer for disk output writes. This was done to speed
- ;up the execution of program when disk output was specified. Fixed bug when
- ;page size was specified. CPM assembler was not doing the conditional IF
- ;assembly correctly. Changed the code to test if page size is in effect by
- ;testing LPAGE to see if it is zero. Changed test to question to erase
- ;existing disk cross reference file to handle lower case as well as upper
- ;case. (JRM)
- ;
- ;02/20/82 Changed code so that the size of the symbol that is referenced in
- ;the cross reference listing can be set at assembly time. The original
- ;program only allowed for 5 char per symbol. This did not allow for separate
- ;unique symbols where the uniqueness occurred after the first 5 characters.
- ;I tested this function for a length of 5, 8, and 10 characters labels. It
- ;should work for any length of symbol. I also allowed the '$' character to
- ;be a valid character in a symbol. The equ SYMSIZ was added and all other
- ;values and variables that are dependent on the size of the symbol are
- ;expressed using SYMSIZ.
- ;
- ;Added a disk file output option. The output disk file will the filename of
- ;the input file and always a file type of 'XRF'. This option is enabled by
- ;specifying a 'D' as the second parameter when executing the program. The
- ;user can optionally specify a different drive than the default drive for the
- ;cross reference disk output. (JRM)
- ;
- ;11/01/81 Changed the code so that the hex addresses and the hex translation
- ;of the instructions are not included in the cross reference listing for PRN
- ;files from CPM assembler. The listing can now be directed at execution time
- ;to the console or the list (LST:) device. (JRM)
- ;
- ;Modifications 4/5/79, 4/26/79, 5/3/79, 8/28/79 by SAN: Suppress initial page
- ;eject, add page eject at completion Automatically convert lower case in
- ;source file to UPPER Abort execution if ^C typed, but ignore other typed
- ;chars Add ELSE, PAGE to reserved word table
- ;
- ;LPAGE is Number of lines per output page
- ;
- ;NREFS is Number of symbol refs per table entry. This value should be set to
- ;the average number of references that a symbol will have in program. It is
- ;used to build the symbol reference table entries. Each entry will be equal
- ;to (NREFS * 2)+2. If it is made unnecessarily large, then the symbol
- ;reference table will be very large with a lot of unused slots. Example: a
- ;program with 300 symbols will require a reference table that is at least
- ;12600 bytes if NREFS=20, whereas the same program will require a reference
- ;table that is at least 3600 bytes if NREFS=5. Each symbol that exceeds
- ;NREFS references will require ((Total references/NREFS)rounded up) reference
- ;table entries. Recommended values: 3-5.
- ;
- ;LREFS is Number of symbol references to be printed per output line. It
- ;should be a multiple of NREFS. If it is not, then the first number that is
- ;less than LREFS and is a multiple of NREFS will be printed on the line.
- ;Example: if NREFS is 5 and LREFS is 13, then only 10 entries will be printed
- ;per line. The total number of references that will fit on one line without
- ;overflow is equal to the size of the line minus (SYMSIZ+2) divided by 5.
- ;Example: if the line size is 132 characters and SYMSIZ equals 8, then Total
- ;num of ref/line can be INT((132-(8+2))/5) or INT(122/5) or 20.
- ;
- ;SYMSIZ sets the Symbol size. This is the symbol size that the program will
- ;use in the cross reference listing. It should be large enough to make each
- ;symbol unique in cross reference listing. If a symbol is larger than the
- ;value for SYMSIZ, then the symbol will be truncated in the output(eg:
- ;LARGE$SYMBOL would be LARGE$SYM if SYMSIZ was set to 9. Recommended value
- ;is 8.
- ;
- ;OUTSECT sets the number of disk records that will be written to disk when
- ;the output disk buffer is full. This value is used by the program to
- ;calculate the size of the output disk buffer. Output buffer size = OUTSECT
- ;* 128. Recommended value is from 8 to 32. 16 works well.
- ;
- ;INSECT is the number of disk records that will be read when the disk input
- ;buffer is empty. It is used to calculate the size of the input buffer.
- ;Input buffer size = INSECT * 128. Recommend value is from 8 to 32. 16
- ;works well.
- ;
- ;NOTE: If OUTSECT and INSECT are made too large, there will not be be enough
- ;memory left to build the cross reference table for a large program. Largest
- ;tested values so far(3/6/82) is 64 for OUTSECT and 64 for INSECT on a 64K
- ;system. The file successfully cross referenced was MODEM74.PRN. (JRM)
- ;
- ; Equates which COULD be changed
- ;
- LPAGE EQU 00 ; num lines per page if peject is true
- NREFS EQU 03 ; number of references per ref tbl entry
- LREFS EQU 21 ; references per output line
- SYMSIZ EQU 08 ; number of symbol char
- OUTSECT EQU 04 ; number of disk sectors written from buffer
- INSECT EQU 08 ; number of disk sectors read into buffer
- LEADIN EQU '[' ; Left marker for definition ref in CREF
- TRAIL EQU ']' ; Right marker for above reference
- ;
- ; Equates NOT to be changed
- ;
- RSIZ EQU 05 ; size of rtab table entry
- SSIZ EQU SYMSIZ+3 ; symbol table entry size
- REFSZ EQU 2+(NREFS*2) ; number of bytes in ref block
- ;
- CR EQU 0DH ; carriage return 2.5
- LF EQU 0AH ; line feed 2.5
- BS EQU 08H ; backspace
- EOF EQU 1AH ; eof code
- ;
- ; operating system equates
- ;
- BOOT EQU 0000H ; reboot entry point
- CPM EQU 0005H ; cpm entry point
- ;
- MEMSZ EQU 0006H ; end of memory pointer
- TFCB EQU 005CH ; trans. fcb
- ;
- CONIN EQU 01 ; console input function code
- PSTRING EQU 09 ; print string function code
- CSTAT EQU 11 ; console status
- OPEN EQU 15 ; open function code
- CLOSE EQU 16 ; close file function code
- DELETE EQU 19 ; delete file function code
- READ EQU 20 ; read disk function code
- WRITE EQU 21 ; write disk function code
- MAKE EQU 22 ; make file function code
- SETDMA EQU 26 ; set dma function code
- ;
- ; main loop
- ;
- ; ASEG
- ORG 100H ; origin address
- XREF: LXI SP,STACK ; set stack pointer
- CALL SETUP ; initialize
- MAIN: CALL GETBT ; get a byte from source file
- CALL SAVBT ; save byte in print buffer
- MAIN2: CALL CKNUM ; test for numeric
- JNC LNUM ; yes, found a number, process
- CALL CKALP ; test for alphabetic
- JNC LALPH ; yes, process
- LXI H,CTAB1 ; point to character table
- CALL LOOK ; look up char in char table
- JC MAIN ; not found, ignore 2.5
- PCHL ; execute routine
- ;
- ; done
- ;
- ; final symbol table print
- ;
- DONE: CALL EJECT ; issue page eject
- MVI A,0FFH ;
- STA LISTFLG ; cref-list on always
- LHLD SYMBT ; get symbol table bottom
- MVI A,0FFH ; check to see if there were...
- CMP M ; any symbols in the program
- JZ DLP4 ; no, don't print symbol table
- SHLD SYM ; set symbol pointer
- LHLD SYMTP ; get symbol table top
- MVI M,0FFH ; end off symbol table
- DLP1: LHLD SYM ; get symbol table pointer
- CALL PSYM ; print symbol
- LHLD SYM
- LXI D,SYMSIZ+1 ; offset to ref link
- DAD D
- MOV E,M
- INX H
- MOV D,M ; get ref block addr
- XCHG ; into hl
- SHLD REF
- CALL PREFS ; print references
- LHLD SYM ; get symbol table pointer
- LXI D,SSIZ ; size of sym table entry
- DAD D
- SHLD SYM
- MOV A,M ; get byte
- CPI 0FFH ; end of table?
- JNZ DLP1 ; loop
-
- DLP2: CALL EJECT ; page eject
- LDA DISKOUT ; get disk output switch
- ORA A ; disk output being used?
- JZ DLP3 ; no, issue end msg & return to cpm
- LXI H,DISKBUF ; get output disk buffer
- LXI D,OFCB ; and out fcb
- CALL DCLOSE ; and close output disk file
-
- DLP3: LXI D,TFCB ; close the...
- MVI C,CLOSE ; input...
- CALL CPM ; file.
- LXI D,DONEMSG ; tell operator we're done
- CALL PSOUT ;
- JMP BOOT ; and return to cp/m
-
- DLP4: LXI H,NOSYMS ; get no symbol message
- MVI B,28 ; number of char in msg
- DLP5: MOV E,M ; print the...
- CALL PBYT ; message
- INX H
- DCR B
- JNZ DLP5
- JMP DLP2 ; go close files
- ;
- ; symbol print routine
- ;
- PSYM: MVI B,SYMSIZ ; symbol size
- PSYM2: MOV E,M ; get byte
- CALL PBYT ; print byte
- INX H
- DCR B
- JNZ PSYM2
- MVI E,' '
- CALL PBYT ; print 2 spaces
- CALL PBYT
- RET
- ;
- ; reference print routine
- ;
- PREFS: MVI A,LREFS/NREFS ; number of blocks to print on one line
- STA NLINS ; to nlins
- PREF0: LHLD REF ; get ref block addr
- INX H
- INX H ; bump to first ref number
- SHLD TEMP ; save ref num addr
- MVI A,(REFSZ-2)/2 ; number of ref slots
- STA SYMCT ; save in symct
- PREF: LHLD TEMP ; get ref slot addr
- MOV E,M
- INX H
- MOV D,M ; get ref
- LXI H,0000 ; zero?
- CALL CPHL
- JZ CRLF ; yes, done
- MOV A,D ; 2.5
- ANI 080H ; High bit set ? 2.5
- JZ PREF1 ; nope 2.5
- MOV A,D ; 2.5
- ANI 07FH ; 2.5
- MOV D,A ; clear it 2.5
- PUSH D ; 2.5
- MVI E,' ' ; 2.5
- CALL PBYT ; 2.5
- MVI A,LEADIN ; 2.5
- STA DECMRK ; modify lead-in marker 2.5
- MVI A,TRAIL ; 2.5
- STA DECEND ; and trailing marker 2.5
- POP D ; 2.5
- PREF1: XCHG ; get num in hl
- CALL DECOT ; convert
- CALL DECPNT ; print it 2.5
- MVI A,' ' ; 2.5
- STA DECMRK ; restore lead-in space 2.5
- MVI A,'$' ; 2.5
- STA DECEND ; and trailing marker 2.5
- LHLD TEMP ; get ref slot addr
- INX H
- INX H ; bump to next slot
- SHLD TEMP
- LDA SYMCT ; get count
- DCR A ; decrement
- STA SYMCT
- JNZ PREF
- LHLD REF ; get ref block address
- MOV E,M
- INX H
- MOV D,M ; get link to next block
- LXI H,0000
- CALL CPHL ; any more blocks?
- JZ CRLF ; no, exit
- XCHG ; yes, set next block pointer in ref
- SHLD REF
- LDA NLINS
- DCR A ; decrement lines count
- STA NLINS
- JNZ PREF0 ; and print more on same line
- CALL CRLF ; print cr,lf
- MVI B,SYMSIZ+2 ; indent continuation line...
- PREF3: MVI E,' ' ; with spaces
- CALL PBYT ; print spaces
- DCR B
- JNZ PREF3 ; print 6 spaces
- JMP PREFS
- ;
- ; character parsing routines
- ;
- LALPH: LXI H,SBUF ; point to symbol buffer
- MVI C,SYMSIZ
- MVI A,' ' ; fill symbol...
- LALX: MOV M,A ; with...
- INX H ; blanks
- DCR C
- JNZ LALX ; clear symbol buffer
- LXI H,SBUF
- SHLD SYMPT
- MVI A,00
- STA SYMCT ; reset symbol pointer+count
- LDA CHAR ; get character again
- CALL GTSYM ; collect identifier
- LALC: CALL GETBT ; get a byte from source file
- CALL SAVBT ; save byte in print buffer
- CALL CKNUM ; test for number
- JNC LAL3 ; yes, continue
- CALL CKALP ; test for alphabetic
- JNC LAL3 ; yes, continue
- CALL CRES ; test for reserved word
- JC LAL1 ; no, continue
- LAL0: CALL LINUP ; Up LINSYM 2.5
- LDA CHAR ; get character that ended ID
- JMP MAIN2 ; continue scan
- LAL1: CALL FIND ; see if defined
- JC LAL2 ; no, continue
- CALL ADDRF ; yes, add reference
- JMP LAL0 ; done
- LAL2: CALL ENSYM ; enter symbol definition
- CALL ADDRF ; add reference
- JMP LAL0 ; continue
- LAL3: CALL GTSYM ; collect identifier
- JMP LALC ; continue
- ;
- LNUM: CALL GETBT ; get byte
- CALL SAVBT ; save byte in printer buffer
- CALL CKNUM ; test for numeric
- JNC LNUM ; yes, continue
- CALL CKALP ; test for alphabetic
- JNC LNUM ; yes, continue
- JMP MAIN2 ; continue with main scan
- ;
- LQUOT: CALL GETBT ; get a byte
- CALL SAVBT ; save byte in printer buffer
- CPI '''' ; see if string quote
- JNZ LQUOT ; no, keep looping
- CALL GETBT ; get next byte
- CALL SAVBT ; save byte
- CPI '''' ; test for doubles
- JZ LQUOT ; yes, start scan again
- JMP MAIN2 ; no, continue in main scan
- ;
- LSEMI: CALL GETBT ; get a byte
- CALL SAVBT ; save byte
- CPI CR ; wait for cr
- JNZ LSEMI ; continue
- JMP MAIN2 ; enter main loop
- ;
- LCR: CALL PLINE ; print line
- LHLD LCNT ; get line number
- INX H ; bump line number
- SHLD LCNT ; store
- JMP MAIN
- ;
- LLF: PUSH PSW ; save char
- LDA FTPRN ; is it file...
- ORA A ; type prn?
- JZ LLF2 ; yes, skip 1rst 16 char
- POP PSW ; restore char
- LLF1A: PUSH PSW ; 2.5
- MVI A,0 ; reset LINSYM 2.5
- STA LINSYM ; 2.5
- POP PSW ; 2.5
- JMP MAIN
- ;
- LLF2: POP PSW ; restore character
- MVI B,16 ; # of char to skip over
- ;
- LLF3: CALL GETBT ; get next byte
- CALL SAVBT ; put in print buf
- CPI CR ; carriage return?
- JZ LCR ; yes, get next line
- DCR B ; skipped all char?
- JNZ LLF3 ; no, continue skipping
- JMP LLF1A ; continue 2.5
- ;
- LIGN: JMP MAIN ; re-enter main loop
- LSPC EQU LIGN
- LTAB EQU LIGN
- LDOL EQU LIGN
- LDEL EQU LIGN
- ;
- ;
- ; subroutines
- ;
- ; check for reserved word
- ;
- CRES: LXI H,RTAB ; point to reserved word table
- SHLD TEMP ; save in temp word
- CRES1: LHLD TEMP ; get table pointer
- LXI D,SBUF ; point to symbol
- MVI B,5 ; symbol size
- CRES2: LDAX D ; get symbol byte
- CMP M ; compare against table entry
- RC ; less, not in table
- JNZ CRES3 ; greater, get next table entry
- INX D ; bump pointers
- INX H
- DCR B ; decrement byte count
- JNZ CRES2 ; keep testing
- JMP CRES4 ; found
- CRES3: LHLD TEMP ; get table pointer
- LXI D,RSIZ ; size of entry
- DAD D ; bump pointer
- SHLD TEMP ; store new pointer
- MOV A,M ; get table byte
- CPI 0FFH ; end of table?
- JNZ CRES1 ; no, loop
- STC ; set carry (not in table)
- RET
- CRES4: ORA A ; reset carry
- RET
- ;
- ; find symbol in table
- ;
- FIND: LHLD SYMBT ; get begin of sym table
- SHLD SYM ; set temp pointer
- FIND1: LHLD SYM ; get temp pointer
- LXI D,SBUF ; point to current symbol
- MVI B,SYMSIZ ; symbol size
- FIND2: LDAX D ; get byte from sbuf
- CMP M ; compare to sym table byte
- RC ; greater, not in table
- JNZ FIND3 ; less, get next table entry
- INX D ; bump pointer
- INX H ; bump pointer
- DCR B ; decrement byte count
- JNZ FIND2 ; loop
- RET ; true zero, found
- FIND3: LHLD SYM ; get current pointer
- LXI D,SSIZ ; symbol table entry size
- DAD D ; bump pointer
- XCHG ; into de
- LHLD SYMTP ; get top of symbol table
- CALL CPHL ; test for end of table
- JZ FIND4 ; yes, done
- JC FERR ; table overflow, error
- XCHG ; current pointer into hl
- SHLD SYM ; set current pointer
- JMP FIND1 ; loop
- FIND4: STC ; set carry for not found
- LHLD SYMTP ; get current top
- SHLD SYM ; set current pointer
- RET
- ;
- FERR: LXI D,EMSG1 ; symbol table err msg
- FERR1: CALL PSOUT ;
- JMP BOOT ; exit
- ;
- FERR2: LXI D,EMSG6 ; no room for symbol table
- JMP FERR1
- ;
- ; add reference to ref table
- ;
- ADDRF: LHLD SYM ; get symbol pointer
- LXI D,SYMSIZ+1 ; offset past symbol&flags
- DAD D
- MOV E,M
- INX H
- MOV D,M ; get reference pointer
- LXI H,0000
- CALL CPHL ; test for zero ref ptr
- JZ BLDRF ; yes, build reference entry
- LINK1: XCHG ; ref ptr in hl
- MOV E,M ; get ref link
- INX H
- MOV D,M ; into de
- DCX H ; reposition hl
- PUSH H ; save ref ptr
- LXI H,0000
- CALL CPHL ; if link is zero
- POP H
- JNZ LINK1 ; non zero, get next link
- SHLD REF ; save ref pointer
- INX H
- INX H ; skip to first ref number
- MVI B,(REFSZ-2)/2 ; number of ref numbers/entry
- LINK3: MOV E,M ; get ref number
- INX H
- MOV D,M
- DCX H ; reposition
- PUSH H ; save ref num addr
- LXI H,0000
- CALL CPHL ; see if ref num is zero
- POP H
- JZ ENREF ; yes, enter reference
- INX H
- INX H ; skip to next ref num
- DCR B ; decrement count
- JNZ LINK3 ; try again at next slot
- CALL ADBLK ; add new ref block
- LHLD REF ; get ref pointer
- INX H
- INX H ; skip to first ref slot
- ENREF: PUSH H ; save ref slot addr
- LHLD LCNT ; get line number
- XCHG ; into de
- POP H ; get ref slot addr
- LDA LINSYM ; first SYMBOL on line ? 2.5
- ORA A ; 2.5
- JNZ ENREF1 ; nope 2.5
- CALL LINUP ; up LINSYM 2.5
- MOV A,D ; 2.5
- ADI 080H ; 2.5
- MOV D,A ; set high bit 2.5
- ENREF1: MOV M,E
- INX H
- MOV M,D ; store line ref
- RET ; done
- ;
- ; build ref table block
- ;
- BLDRF: LHLD SYM ; get symbol pointer
- LXI D,SYMSIZ+1 ; offset to ref pointer
- DAD D
- SHLD REF ; set temp ref pointer to here
- CALL ADBLK ; add block
- LHLD REF ; get real ref pointer
- INX H
- INX H ; position to first ref slot
- JMP ENREF ; add reference
- ADBLK: LHLD REFBT ; get ref bottom
- LXI D,REFSZ ; subtract ref size
- MOV A,L
- SUB E
- MOV L,A
- MOV A,H
- SBB D
- MOV H,A
- SHLD TEMP ; save new ref bottom
- XCHG ; into de also
- LHLD SYMTP ; get symbol top
- CALL CPHL ; check for bump
- JZ FERR2 ; yes, no room
- JNC FERR2 ; no room
- LHLD TEMP ; get ref bottom
- XCHG ; into de
- LHLD REF ; get ref pointer
- MOV M,E ; set link
- INX H
- MOV M,D ; to new ref block
- LHLD TEMP ; get new ref block addr
- SHLD REF ; store in ref
- MVI B,REFSZ ; size of ref block
- MVI A,00
- ADB2: MOV M,A ; zero the ref block
- INX H
- DCR B
- JNZ ADB2
- LHLD TEMP ; get new ref bottom
- SHLD REFBT ; set refbt
- RET
- ;
- ; enter symbol in sym table
- ;
- ENSYM: LHLD SYM ; get symbol pointer
- XCHG ; into de
- LHLD SYMTP ; get symbol table top
- CALL CPHL ; check for end of table
- JZ NWSYM ; yes, add symbol at end
- LXI D,SSIZ ; symbol table entry size
- DAD D ; calculate new end of table
- XCHG ; into de
- LHLD REFBT ; reference table bottom
- CALL CPHL ; test for table overflow
- LXI D,EMSG7 ; addr of err msg in of overflow
- JZ FERR1 ; full, error
- JC FERR1 ; yes, error
- LHLD SYMTP ; get table top
- LXI D,SSIZ-1 ; bump to end of entry
- DAD D
- SHLD TO ; store in to address
- LXI D,SSIZ
- MOV A,L
- SUB E
- MOV L,A
- MOV A,H
- SBB D
- MOV H,A ; subtract size of one entry
- SHLD FROM ; store as from address
- LHLD SYM ; get current pointer
- SHLD LIMIT ; store as limit address
- CALL MVUP ; move table up in memory
- NWSYM: LHLD SYM ; get current pointer
- LXI D,SBUF ; point to symbol
- MVI B,SYMSIZ ; size of symbol
- CALL MOVE ; copy symbol to table
- MVI A,0
- MOV M,A
- INX H
- MOV M,A
- INX H
- MOV M,A ; set pointers to 0000
- LHLD SYMTP ; get symbol table top
- LXI D,SSIZ ; get symbol entry size
- DAD D ; bump
- SHLD SYMTP ; store ew top
- RET
- ;
- ; move symbol table up
- ;
- MVUP: LHLD TO ; get to pointer
- MOV B,H
- MOV C,L ; into bc
- LHLD FROM ; get from pointer
- XCHG ; into de
- LHLD LIMIT ; get limit address
- MVUP2: LDAX D ; get from byte
- STAX B ; store at to address
- CALL CPHL ; compare from to limit
- RZ ; exit if done
- DCX B ; decrement to
- DCX D ; decrment from
- JMP MVUP2 ; loop
- ;
- ; general purpose move routine
- ;
- MOVE: LDAX D ; get byte
- MOV M,A ; store byte
- INX D
- INX H ; bump pointers
- DCR B ; decrement count
- JNZ MOVE ; loop
- RET
- ;
- ; binary to decimal conversion
- ;
- DECOT: LXI D,DEC
- XCHG
- LXI B,10000
- CALL DIG
- LXI B,1000
- CALL DIG
- LXI B,100
- CALL DIG
- LXI B,10
- CALL DIG
- LXI B,1
- CALL DIG
- RET
- ;
- DIG: MVI M,'0'
- DI0: MOV A,E
- SUB C
- MOV E,A
- MOV A,D
- SBB B
- MOV D,A
- JM DI2
- INR M
- JMP DI0
- DI2: MOV A,E
- ADD C
- MOV E,A
- MOV A,D
- ADC B
- MOV D,A
- INX H
- RET
- ;
- ; Print number string in DEC
- ;
- DECPNT: LXI H,DEC ; point to dec string
- LDA DECMRK ; 2.5
- MOV M,A ; set lead-in marker 2.5
- DCPNT1: MOV E,M ; get string byte
- MOV A,E ;
- CPI '$' ; done?
- RZ ; yes
- CALL PBYT ; print byte
- INX H ; bump pointer
- JMP DCPNT1 ;
- ;
- ; Up LINSYM after symbol found
- LINUP: PUSH PSW ; 2.5
- LDA LINSYM ; 2.5
- INR A ; 2.5
- STA LINSYM ; found first separator 2.5
- POP PSW ; 2.5
- RET ; 2.5
- ;
- ; test for alphabetic char.
- ;
- CKALP: CPI '$' ; treat '$' like a char
- RZ
- CPI 'A' ; ascii 'a'
- RC ; no, exit
- CPI 'Z'+1
- CMC
- RET
- ;
- ; test for numeric char
- ;
- CKNUM: CPI '0'
- RC
- CPI '9'+1
- CMC
- RET
- ;
- ; look up char in parse table
- ;
- LOOK: LXI D,0003 ; table entry size
- MOV B,A ; argument byte in b
- LOOK2: MOV A,M ; get table byte
- CPI 0FFH ; end of table?
- JZ LOOKN ; yes, not found
- CMP B ; compare
- JZ LOOKY ; found
- DAD D ; bump pointer
- JMP LOOK2 ; loop
- LOOKN: STC ; carry = not found
- RET
- ;
- LOOKY: INX H ; skip to table byte
- MOV E,M
- INX H
- MOV D,M ; table entry in de
- XCHG ; into hl
- RET
- ;
- ; save byte in line buffer
- ;
- SAVBT: LHLD LPNT ; get line pointer
- MOV M,A ; save byte
- INX H ; bump pointer
- SHLD LPNT ; save pointer
- CALL LWRUPR ; convert lower to upper case
- STA CHAR ; save char in char
- RET
- ;
- ; print source line with number
- ;
- PLINE:
- LHLD LCNT ; get line number
- CALL DECOT ; convert to decimal
- CALL DECPNT ; print it 2.5
- MVI E,':'
- CALL PBYT ; print ':'
- MVI E,' '
- CALL PBYT ; print ' '
- CALL PBYT ; print space
- LXI H,PBUF ; point to print buffer
- MVI A,00
- STA COL ; set column count
- PL41: MOV E,M ; get byte
- MOV A,E
- CPI CR ; done?
- JZ PL5
- CPI LF ; lf?
- JZ PL4A ; yes, ignore
- CPI 09H ; tab?
- JNZ PL42 ; no, continue
- PUSH H ; save hl
- PL43: MVI E,' '
- CALL PBYT ; print space
- LXI H,COL
- INR M
- MOV A,M
- ANI 07H ; modulo 8
- JNZ PL43
- POP H
- JMP PL4A
- PL42: LDA COL
- INR A
- STA COL
- CALL PBYT ; print byte
- PL4A: INX H
- JMP PL41
- PL5: CALL CRLF ; print cr,lf
- LXI H,PBUF
- SHLD LPNT ; reset line pointer
- RET
- ;
- ; collect symbol in sym buf
- ;
- GTSYM: MOV B,A ; save char
- LDA SYMCT ; get symbol count
- CPI SYMSIZ ; max?
- RNC ; yes, done
- INR A
- STA SYMCT
- LHLD SYMPT
- MOV M,B
- INX H ; bump symbol pointer
- SHLD SYMPT
- RET
- ;
- ; print a single byte
- ;
- PBYT: PUSH B
- PUSH D
- PUSH H
- PUSH PSW
- LDA LISTFLG ; listing on ? 2.5
- ORA A ; 2.5
- JZ PBYT3 ; no listing 2.5
- LDA DISKOUT ; disk output...
- ORA A ; in effect?
- JNZ DBYT ; yes, go write to disk
- MVI C,05
- LDA CONSOLE ; get console out switch
- ORA A ; console output?
- JZ PBYT2 ; no, print output
- MVI C,2 ; console output
- ;
- PBYT2: CALL CPM
- ;
- PBYT3: MVI C,CSTAT ; check console status
- CALL CPM
- ORA A ; if zero, ok
- JZ PBYTX ; exit
- MVI C,CONIN
- CALL CPM ; read console char
- CPI 3
- JZ BOOT ; abort if ^c, otherwise ignore
- PBYTX: POP PSW
- POP H
- POP D
- POP B
- RET
- ;
- ; put output character into disk buffer.
- ;
- DBYT: MOV A,E ; save char to be put in buffer
- LHLD DSKCNT ; get num of char left in buf
- XCHG ; put num in d,e
- LHLD DCHAR ; point to next char in buf
- MOV M,A ; put char in disk buf
- DCR E ; at end of buf?
- JNZ DBYT1 ; no, don't write buffer
- DCR D ; at end of buf?
- JZ PUTREC ; yes, go write buffer
- ;
- DBYT1: INX H ; point to next char in buf
- SHLD DCHAR ; save next pos
- XCHG ; put num of char left in h,l
- SHLD DSKCNT ; save num of remaining char
- JMP PBYT3 ; go check console status
- ;
- ; write out disk buffer to disk
- ;
- PUTREC: LXI H,DISKBUF ; address of disk buffer
- SHLD BUFADR ; save it for later dma's
- MVI B,OUTSECT ; number of disk sectors to write
- ;
- PUTRC2: PUSH B ; save sector count
- LHLD BUFADR ; get disk buffer address
- XCHG ; put it in d,e for dma
- LXI H,80H ; put 128 h,l
- DAD D ; add 128 to disk buf adr for next dma
- SHLD BUFADR ; save it for next dma
- MVI C,SETDMA ; point dma to...
- CALL CPM ; correct buffer
- LXI D,OFCB ; get output disk fcb
- MVI C,WRITE ; write sector...
- CALL CPM ; to disk
- ORA A ; was write successfull?
- POP B ; restore num of sectors left
- LXI D,EMSG4 ; get err msg in case write failed
- JNZ FERR1 ; disk write failed, display err msg, quit
- DCR B ; written 16 sectors yet?
- JNZ PUTRC2 ; no, continue writing disk sectors
- LXI H,OUTSECT*128 ; put disk buffer size into h,l
- SHLD DSKCNT ; set num of char left in buf to buffer size
- LXI H,DISKBUF ; point to front...
- SHLD DCHAR ; of disk buffer
- JMP PBYT3 ; go check console status for ^c
- ;
- ; issue page eject
- ;
- EJECT: MVI E,0CH ; printer eject command
- CALL PBYT
- MVI E,00H
- MVI B,10
- EJECT2: CALL PBYT ; print 10 nulls
- DCR B
- JNZ EJECT2
- MVI A,00
- STA LINES ; set line count
- RET
- ;
- ; issue cr, lf & test page
- ;
- CRLF: MVI E,CR
- CALL PBYT
- MVI E,LF
- CALL PBYT
- LDA LINES
- INR A
- STA LINES ; increment line count
- MVI A,LPAGE ; get number of lines
- ORA A ; is it zero?
- LDA LINES
- RZ ; yes, return
- CPI LPAGE ; test line count
- CZ EJECT ; if eq to lpage then new page
- RET
- ;
- ; routine to open a disk file
- ;
- FOPEN: MVI C,OPEN ; open code
- CALL CPM ; issue open
- CPI 0FFH ; error?
- RNZ ; no error
- LXI D,EMSG0
- JMP FERR1
- ;
- ; routine to close output disk cross reference file
- ;
- DCLOSE: PUSH D ; save fcb address
- PUSH H ; save buffer address
- LHLD DSKCNT ; put number of char left...
- XCHG ; in buffer into d,e
- LHLD DCHAR ; point to next char in output buf
- MVI A,1AH ; put a control z in accum
- DCLSE2: MOV M,A ; fill...
- INX H ; rest of...
- DCR E ; buffer...
- JNZ DCLSE2 ; with...
- DCR D ; control z's.
- JNZ DCLSE2
- POP H ; point to...
- ;
- DCLSE4: XCHG ; output buffer
- LXI H,128 ; put 128 into h,l
- DAD D ; add 128 to disk buf addr for next dma
- SHLD BUFADR ; save it for next dma after this one
- MVI C,SETDMA ; disk buffer for...
- CALL CPM ; last disk write
- POP D ; do last...
- PUSH D ; (d,e contains ofcb)...
- MVI C,WRITE ; disk...
- CALL CPM ; write
- ;
- ;check to see if last record has been written. do this by comparing
- ;address of next available char to address of buffer for next disk write.
- ;if address of next available char is equal or greater, close file.
- LHLD DCHAR ; put high order address
- XCHG ; of last char+1...
- MOV A,D ; into accum
- LHLD BUFADR ; get addr of next disk buffer
- CMP H ; compare to last char+1 in buffer
- JC DCLSE5 ; if next addr is greater, close file
- JNZ DCLSE4 ; if not equal, continue
- MOV A,E ; put low order address of last char+1
- CMP L ; into accum and test
- JNC DCLSE4 ; if not less, do another write
- ;
- DCLSE5: POP D ; close the...(d,e contains ofcb)
- MVI C,CLOSE ; output disk
- CALL CPM ; cross ref file
- CPI 0FFH ; close successfull?
- RNZ ; yes, return
- LXI D,EMSG5 ; no, display error msg...
- JMP FERR1 ; and quit
- ;
- ; routine to read a byte
- ;
- GETBT: LXI H,TBUF+(INSECT*128) ; end of input buf addr
- XCHG ; buffer end addr. in de
- LHLD INPTR ; current pointer in hl
- CALL CPHL ; test for end of buffer
- CZ GETREC ; yes, read disk records
- MOV A,M ; get byte
- INX H ; bump pointer
- SHLD INPTR ; save pointer
- ORA A ; clear carry
- RET ; return carry reset
- ;
- ; getrec
- ;
- GETREC: LDA CONSOLE ; Console on ? 2.5
- ORA A ; 2.5
- JNZ GTREC1 ; Then he sees progress 2.5
- LHLD LCNT ; Line-count 2.5
- CALL DECOT ; into ASCII 2.5
- LXI D,DECERA ; Erase area 2.5
- CALL PSOUT ; 2.5
- LXI D,DEC ; ASCII linecount 2.5
- CALL PSOUT ; to show progress 2.5
- GTREC1: MVI B,INSECT ; number of sectors to read
- LXI H,TBUF ; get address of disk input buffer
- SHLD IDADDR ; initialize current buffer address
-
- GETRC2: LHLD IDADDR ; get addr of input buffer
- XCHG ; put it in d,e
- LXI H,128 ; add 128 to input buf
- DAD D ; addr for read after next
- SHLD IDADDR ; save it read after next
- PUSH B ; save sector count
- PUSH D ; save current buf ptr in case eof occurrs
- MVI C,SETDMA ; point to input buffer...
- CALL CPM
- MVI C,READ ; read code
- LXI D,TFCB ; fcb address
- CALL CPM ; issue read
- POP D ; restore current buf pointer
- POP B ; restore sector count
- CPI 00 ; error?
- JNZ GETRC4 ; yes
- DCR B ; read all of the sectors?
- JNZ GETRC2 ; no, continue reading
-
- GETRC3: LXI H,TBUF ; reset buffer pointer
- SHLD INPTR
- RET ; return to caller
-
- GETRC4: XCHG ; point to first char past buf
- MVI M,26H ; put two...
- INX H ; control z's
- MVI M,26H ; after last rec in file
- JMP GETRC3 ; go reset buffer pointer
- ;
- ; converts lower to upper case
- ;
- LWRUPR: CPI 'A'+20H ; is it upper case?
- CMC ; complement carry
- RNC ; yes, return with carry reset
- CPI 'Z'+21H ; over lower case 'z'?
- RNC ; no, return no carry
- SUI 20H ; convert to upper case
- RET
- ;
- ; PSOUT prints string in D
- ;
- PSOUT: MVI C,PSTRING ;
- CALL CPM ;Print String
- RET
- ;
- ; routine to compare hl vs de
- ;
- CPHL: MOV A,H
- CMP D
- RNZ
- MOV A,L
- CMP E
- RET
- ;
- ; d a t a
- ;
- ;
- ; character parsing table
- ;
- CTAB1: DB CR
- DW LCR
- DB LF
- DW LLF
- DB ''''
- DW LQUOT
- DB ';'
- DW LSEMI
- DB ' '
- DW LSPC
- DB 09H
- DW LTAB
- DB '$'
- DW LDOL
- DB '('
- DW LDEL
- DB ')'
- DW LDEL
- DB '+'
- DW LDEL
- DB '-'
- DW LDEL
- DB '*'
- DW LSEMI
- DB '/'
- DW LDEL
- DB ','
- DW LDEL
- DB ':'
- DW LDEL
- DB EOF
- DW DONE
- DB 0FFH
- DW 0000H
- ;
- ; reserved word table
- ;
- RTAB: DB '8080 '
- DB 'A ','ACI ','ADC ','ADD ','ADI '
- DB 'AF ','ANA ','AND ','ANI ','ASEG '
- DB 'B ','BC ','BIT '
- DB 'C ','CALL ','CC ','CCF ','CM '
- DB 'CMA ','CMC ','CMP ','CNC ','CNZ '
- DB 'COMME','COMMO','COND ','CP ','CPD '
- DB 'CPDR ','CPE ','CPI ','CPL ','CPO '
- DB 'CSEG ','CZ '
- DB 'D ','DAA ','DAD ','DB ','DC '
- DB 'DCR ','DCX ','DE ','DEC ','DEFB '
- DB 'DEFL ','DEFM ','DEFW ','DI ','DJNZ '
- DB 'DS ','DSEG ','DW '
- DB 'E ','EI ','ELSE ','END ','ENDC '
- DB 'ENDIF','ENDM ','ENTRY','EQ ','EQU '
- DB 'EX ','EXX ','EXITM','EXT ','EXTRN'
- DB 'GE ','GLOBA','GT '
- DB 'H ','HL ','HIGH ','HALT '
- DB 'IF ','IFB ','IFDEF','IFE ','IFF '
- DB 'IFNB ','IFNDE','IFT ','IF1 ','IF2 '
- DB 'IM ','IN ','INC ','INCLU','IND '
- DB 'INDR ','INIR ','INR ','INX ','IRP '
- DB 'IRPC ','IX ','IY '
- DB 'JC ','JM ','JMP ','JNC ','JNZ '
- DB 'JP ','JPE ','JPO ','JR ','JZ '
- DB 'L ','LALL ','LD ','LDA ','LDAX '
- DB 'LDD ','LDDR ','LDI ','LDIR ','LE '
- DB 'LHLD ','LIST ','LOCAL','LOW ','LT '
- DB 'LXI '
- DB 'M ','MACRO','MOD ','MOV ','MVI '
- DB 'NAME ','NC ','NE ','NEG ','NOP '
- DB 'NOT ','NUL ','NZ '
- DB 'OR ','ORA ','ORG ','ORI ','OTDR '
- DB 'OTIR ','OUT ','OUTI ','OUTD '
- DB 'PAGE ','PCHL ','P ','PE ','PO '
- DB 'POP '
- DB 'PRINT','PSW ','PUBLI','PUSH '
- DB 'RADIX','RAL ','RAR ','RC ','REPT '
- DB 'RES ','RET ','RETI ','RL ','RLA '
- DB 'RLC ','RLCA ','RLD ','RM ','RNC '
- DB 'RNZ ','RP ','RPE ','RPO ','RR '
- DB 'RRA ','RRC ','RRCA ','RRD ','RST '
- DB 'RZ '
- DB 'SALL ','SBB ','SBC ','SBI ','SCF '
- DB 'SET ','SHL ','SHLD ','SHR ','SLA '
- DB 'SP ','SPHL ','SRA ','SRL ','STA '
- DB 'STAX ','STC ','SUB ','SUBTT','SUI '
- DB 'TITLE'
- DB 'XALL ','XCHG ','XLIST','XOR ','XRA '
- DB 'XRI ','XTHL '
- DB 'Z ','Z80 '
- DB 0FFH ; end of reserved word table
- ;
- EMSG1: DB 'Symbol Table Error',CR,LF,'$'
- EMSG2: DB 'Failed to delete existing cross reference file',CR,LF,'$'
- EMSG3: DB 'Failed to create cross reference file',CR,LF,'$'
- EMSG4: DB 'Disk write failed - Out of space?',CR,LF,'$'
- EMSG5: DB 'Close failed on disk cross reference file',CR,LF,'$'
- EMSG6: DB '++ERROR++ Not enough memory for Symbol Table',CR,LF,'$'
- EMSG7: DB '++ERROR++ Symbol table Overflow?',CR,LF,'$'
- DONEMSG: DB CR,LF,'Cross Reference List is done',CR,LF,'$'
- NOSYMS: DB 'No Symbols in this Program'
- CONCRLF:DB CR,LF,'$'
- OFCB: DB 0 ; disk output fcb, default drive
- DS 8 ; file name
- DB 'XRF' ; file type
- DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
- DCHAR: DW DISKBUF ; pointer for disk buffer
- BUFADR: DS 2 ; pointer to disk output buffer for dma
- IDADDR: DS 2 ; pointer to disk input buffer for dma
- DSKCNT: DW OUTSECT*128 ; number of char left in disk buffer
- INPTR: DW TBUF+(INSECT*128) ; pointer to char in input buffer
- DISKBUF:DS OUTSECT*128 ; output disk buffer
- TBUF: DS INSECT*128 ; disk input buffer
- EOFCHR: DB 26H,26H ; control z's in case last block is
- ; filled with data
- ;
- SYMBT: DS 2 ; symbol table bottom address
- SYMTP: DS 2 ; symbol table top address
- REFBT: DS 2 ; reference table bottom address
- REFTP: DS 2 ; reference table top address
- SYM: DS 2 ; current symbol table address
- REF: DS 2 ; current reference table address
- FROM: DS 2 ; move pointer
- TO: DS 2 ; to pointer
- LIMIT: DS 2 ; limit pointer
- COL: DS 1
- CHAR: DS 1
- LCNT: DS 2 ; line counter
- LINSYM: DS 1 ; 0 if first symbol on line
- LPNT: DS 2
- DEC: DS 5
- DECEND: DB '$$'
- DECMRK: DB ' '
- DECERA: DB BS,BS,BS,BS,BS,'$' ;Erase string for Line-Nr display
- PBUF: DS 132
- SYMCT: DS 1
- SYMPT: DS 2
- SBUF: DS SYMSIZ ; symbol buffer
- NLINS: DB 0 ; buffers to print on line
- LINES: DB 0 ; print line count
- ;
- CONSOLE:DB 0 ; console output switch
- DISKOUT:DB 0 ; disk output switch
- LISTFLG:DB 0 ; 0=no source listing 2.5
- FTPRN: DB 1 ; prn file type
- TEMP: DS 2 ; temp save word
- DS 64 ; stack contains 32 words
- STACK EQU $
- ;
- ; symbol table area
- ;
- ; the symbol table must be the
- ; last byte before ONCE ONLY CODE - XREF is NOT RESTARTABLE 2.5
- ;
- ORG $ ;
- SYMT: DB 0FFH
- ;
- LOGO: DB CR,LF,'CP/M Assembler Cross Reference List Ver 2.50',CR,LF,'$'
- MSG1: DB 'Disk Cross Reference File Exists - ERAse it(Y/N) ? ','$'
- MSG2: DB 'Want Line-numbered Listing (Y/N) ? ','$' ;2.5
- EMSG0: DB '++ERROR++ Input File does not exist',CR,LF ;2.5
- HELP: DB CR,LF,'This program can be used to'
- DB ' create a cross reference listing',CR,LF
- DB 'of CPM assembler programs.'
- DB ' The input can be either the assembler',CR,LF
- DB 'language source code(FN.ASM) or the assembly listing(FN.PRN).',CR,LF
- DB 'The output can be printed on the CPM list device, displayed on',CR,LF
- DB 'the console, or written to disk(file type will be XRF). It is',CR,LF
- DB 'invoked by keying:',CR,LF,LF
- DB 09H,'XREF FN.ASM (Output on List device)',CR,LF
- DB 09H,'XREF FN.PRN CON (Output on the Console)',CR,LF
- DB 09H,'XREF FN.ASM D (Output on disk-default drive)',CR,LF
- DB 09H,'XREF FN.PRN B:D (Output on disk-drive specified)',CR,LF,'$'
- ;
- ; setup or initialization
- ;
-
- SETUP: LXI D,LOGO ; get program logo msg
- CALL PSOUT ; 2.5
- LDA TFCB+1 ; get first char of file name
- CPI '?' ; help function?
- JNZ SETUP1 ; no, go check input file type
- LXI D,HELP ; display help message
- JMP FERR1
-
- SETUP1: MVI A,0 ; 2.5
- STA LISTFLG ; no listing 2.5
- LDA TFCB+9 ; get first char of file type
- CPI 'P' ; is it type prn?
- JNZ SETUP2 ; no, don't set switch
- LDA TFCB+10 ; get 2nd char of file type
- CPI 'R'
- JNZ SETUP2
- LDA TFCB+11 ; get 3rd char of file type
- CPI 'N'
- JNZ SETUP2
- XRA A
- STA FTPRN ; turn on prn file type
- ;
- SETUP2: LDA TFCB+17 ; get 1rst char of 2nd fcb
- CPI 'C' ; output to console?
- JNZ SETUP3 ; no, don't turn on switch
- LDA TFCB+18 ; get 2nd char of 2nd fcb
- CPI 'O' ; output to console?
- JNZ SETUP3 ; no, don't turn on switch
- MVI A,0FFH ; turn on...
- STA CONSOLE ; console output
- JMP SETUP6 ; go open input file
- SETUP3: LDA TFCB+17 ; get 1rst char of 2nd fcb
- CPI 'D' ; output to be written to disk?
- JNZ SETUP6 ; no, go open input file.
- MVI A,0FFH ; 2.5
- STA DISKOUT ; turn on disk output switch
- LDA TFCB+16 ; get output file drive number
- STA OFCB ; move to output fcb
- LXI D,TFCB ; point to fcb
- CALL FOPEN ; open disk input file
- LXI D,TFCB+1 ; point to input file name
- MVI B,8 ; length of file name
- LXI H,OFCB+1 ; point to output fcb file name
- CALL MOVE ; move input file name to output fcb
- LXI D,OFCB ; does output file...
- MVI C,OPEN ; already...
- CALL CPM ; exist?
- CPI 0FFH ; open succeed?
- JZ SETUP4 ; no, file does not exist
- ;
- LXI D,OFCB ; close...
- MVI C,CLOSE ; the open...
- CALL CPM ; file.
- LXI D,MSG1 ; ask operator...
- CALL PSOUT ; if old file should be deleted 2.5
- MVI C,CONIN ; deleted
- CALL CPM
- ANI 05FH ; make upper case
- CPI 'Y' ; operator say yes?
- JNZ BOOT ; no, terminate
- ;
- LXI D,CONCRLF ; write CRLF to console
- CALL PSOUT ; 2.5
- LXI D,OFCB ; point to fcb to delete file
- MVI C,DELETE ; delete the...
- CALL CPM ; file
- CPI 0FFH ; delete succeed?
- LXI D,EMSG2 ; get err msg in case of failure
- JZ FERR1 ; failure, print msg & quit
- ;
- SETUP4: LXI D,OFCB ; point to output fcb
- MVI C,MAKE ; create new...
- CALL CPM ; cross reference file.
- CPI 0FFH ; create succeed?
- LXI D,EMSG3 ; get err msg in case of failure
- JZ FERR1 ; create failed, print msg & quit
- LXI H,DISKBUF ; get addr of disk buffer
- SHLD DCHAR ; init disk char pointer
- ;
- SETUP6: LXI D,TFCB ; point to fcb
- CALL FOPEN ; open fcb
- LXI D,MSG2 ; "Want Listing.." 2.5
- CALL PSOUT ; 2.5
- MVI C,CONIN ; 2.5
- CALL CPM ; get answer 2.5
- ANI 05FH ; make upper case 2.5
- CPI 'N' ; 2.5
- JZ STUP61 ; no listing 2.5
- MVI A,0FFH ; 2.5
- STA LISTFLG ; wants listing 2.5
- STUP61: LXI D,CONCRLF ; write CRLF to console 2.5
- CALL PSOUT ; 2.5
- LXI H,PBUF
- SHLD LPNT ; set print pointer
- LXI H,00001 ; set line counter...
- SHLD LCNT ; to one.
- LXI H,SYMT ; get address of symbol table
- SHLD SYM
- SHLD SYMBT
- SHLD SYMTP ; set symbol table pointers
- LHLD MEMSZ ; get available memory address
- DCX H
- SHLD REF
- SHLD REFBT
- SHLD REFTP ; set reference table pointers
- RET
- ;
- END XREF
- .
- LXI H,SYMT ; get address of symbol table
- SHLD SYM
- SHLD SYMBT