home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
simtel
/
sigm
/
vols000
/
vol091
/
dasm.mac
< prev
next >
Wrap
Text File
|
1984-04-29
|
72KB
|
3,511 lines
;
; Program: DASM
; Version: 1.5
; Author: Richard Conn
; Date: 16 Aug 82
; Previous Versions: 1.3 (23 May 82), 1.4 (12 June 82)
; Previous Versions: 1.0 (1 May 82), 1.1 (8 May 82), 1.2 (15 May 82)
; Derivation: ZZSOURCE and RESOURCE
;
; DASM is a TDL/ZILOG Disassembler derived from Dave Barker's
; ZZSOURCE and Ward Christensen's RESOURCE by Richard Conn. Refer to
; the documentation on RESOURCE and the built-in HELP data for information
; on the commands used for DASM. A Help file is also being planned for DASM.
;
VERS equ 15 ; Version Number
.Z80 ; USE ZILOG MNEMONICS
ASEG ; USE ABSOLUTE SEGMENTS
; Values for TRUE and FALSE
FALSE equ 0
TRUE equ NOT FALSE
; Set one and ONLY one of the following to TRUE
ZILOG equ TRUE
TDL equ FALSE
; Initial Values for DASM
RDCOMQ EQU FALSE ;TRUE OF QUERY USER TO READ COM FILE
; WHEN 'ALL' IS FILE TYPE
CTLTBL EQU ENDALL ;BEGINNING OF CONTROL TABLE
SYMTAB EQU CTLTBL+600H ;BEGINNING OF SYMBOL TABLE
INITOFF EQU SYMTAB+2000H ;INITIAL OFFSET VALUE
COMTBL EQU INITOFF+4000H ;BEGINNING OF COMMENTS
SYMMAX EQU 12 ;MAX NUMBER OF CHARS/SYMBOL (<= 12)
INITLCNT EQU 20 ;NUMBER OF LINES TO DISPLAY VIA L, A, B
INITDLEN EQU 80H ;NUMBER OF BYTES TO DISPLAY VIA D
INITPC EQU 100H ;INITIAL VALUE OF PC
INITELST EQU 0FFFFH ;INITIAL END OF LIST VALUE
IBUFLEN EQU 80 ;LENGTH OF INPUT LINE BUFFER
; CP/M Constants
WBOOT EQU 00H
BDOS EQU 05H
FCB EQU 5CH
FCBNR EQU 7CH
FCBTYPE EQU 65H
RECLEN EQU 80H
;
; Beginning of Program
;
ORG 0100H
JP START
JP GETCMD ;This is an easy entry point for a restart.
;
; The following INCLUDE is used to include the appropriate file defining
; the Mnemonics for the desired language. Choices at this time are:
; DASMZLG.MAC -- ZILOG-Standard Mnemonics
; DASMTDL.MAC -- TDL Mnemonics
;
IF ZILOG
INCLUDE DASMZLG.MAC ;Include ZILOG Mnemonic File
ENDIF
IF TDL
INCLUDE DASMTDL.MAC ;Include TDL Mnemonic File
ENDIF
;
; PRINT HEADERS
;
START:
LD SP,OLDST ;SET STACK
CALL PSTRNG
DEFB 0DH,0AH,'DASM, Version '
DEFB VERS/10+'0','.',(VERS MOD 10)+'0',0DH,0AH,0
;
; PERFORM REENTRANT INITIALIZATION
;
CALL INIT0 ;INITIALIZE BUFFERS SO DASM IS REENTRANT
CALL INIT ;CLEANUP INITIALIZATION
;
; READ IN ALL FILES IF A FILE WAS SPECIFIED
;
LD A,(FCB+1) ;GET FIRST LETTER OF FILE NAME
CP ' '+1 ;VALID CHAR?
JR C,SIGNON ;SKIP READ IF NOT VALID CHAR
CALL PSTRNG
DEFB 0DH,0AH,'Reading in All Files for ',0
LD HL,FCB+1 ;PT TO FILE NAME
LD B,8 ;8 CHARS
ARDNAME:
LD A,(HL) ;GET CHAR
CALL COUT ;PRINT IT
INC HL ;PT TO NEXT
DJNZ ARDNAME
CALL ALLRD ;READ IN ALL FILES
CALL PSTRNG
DEFB 0DH,0AH,'-- Read Complete --',0DH,0AH,0
;
; PRINT REST OF SIGNON MESSAGE
;
SIGNON:
LD DE,HEADER ;PRINT HEADER FROM INCLUDE FILE
LD C,9
CALL BDOS
CALL PSTRNG ;PRINT INITIAL INFO
DEFB 0DH,0AH,'Type H for Help, ? for Stats',0DH,0AH,0
JR GETCMD ;PERFORM COMMAND PROCESSING
;
; CLEAN UP DASM AND COMPLETELY REINITIALIZE
;
CLEAN:
CALL INIT ;DO INITIALIZATION
;
; MAIN COMMAND PROCESSING LOOP
;
GETCMD:
XOR A ;A=0
LD (WRTENAB),A ;DISABLE OUTPUT TO FILE
LD (HUSH),A ;SET NOT QUIET
LD (XCPTR),A
LD (XCPTR+1),A
LD SP,OLDST ;RESET STACK
;
; INPUT COMMAND LINE AND CAPITALIZE
;
CALL PROMPT ;INPUT COMMAND LINE VIA BDOS
;
; PROCESS COMMAND LINE
;
PRCEDE:
LD A,(INBUF+2) ;PT TO FIRST CHAR OF COMMAND LINE
LD B,A ;GET IT
LD DE,CMDTABL ;PT TO COMMAND TABLE
PRCLOOP:
LD A,(DE) ;GET COMMAND FROM COMMAND TABLE
OR A ;END OF TABLE IF 0
JR Z,WHAT ;TELL USER THAT COMMAND WAS INVALID
INC DE ;PREP FOR NO MATCH
INC DE ;...PT TO NEXT COMMAND
INC DE
CP B ;MATCH?
JR NZ,PRCLOOP ;CONTINUE LOOPING IF NOT
DEC DE ;PT TO ADDRESS
LD A,(DE) ;GET ADR HIGH
LD B,A ;... IN B
DEC DE ;PT TO LOW
LD A,(DE) ;GET ADR LOW
LD C,A ;... IN C
PUSH BC ;ADDRESS ON STACK
RET ;"JUMP TO" COMMAND
;
; GENERAL ERROR
;
WHAT:
XOR A
LD (WRTENAB),A
LD (HUSH),A
CALL PSTRNG
DEFB 0DH,0AH,'** Command Error **',0DH,0AH,0
JR GETCMD
;
; COMMAND TABLE -- CONTAINS COMMAND LETTER FOLLOWED BY ADDRESS OF ROUTINE
; AND ENDS IN 0 AS THE NEXT COMMAND LETTER
;
CMDTABL:
DEFB 0DH ;EMPTY LINE
DEFW GETCMD
DEFB ';' ;COMMENTS
DEFW CMNT
DEFB 'A' ;BUILD ASCII
DEFW ASCASM
DEFB 'B' ;BUILD LABELS
DEFW BLDASM
DEFB 'C' ;CONTROL TABLE
DEFW CTL
DEFB 'D' ;MEMORY DUMP
DEFW DUMP
DEFB 'E' ;ENTER SYMBOL
DEFW ENTER
DEFB 'F' ;FIND LABEL
DEFW FIND
DEFB 'H' ;HELP
DEFW HELP
DEFB 'I' ;INCREMENT SYMBOL VALUES
DEFW INCMNT
DEFB 'K' ;KILL SYMBOL
DEFW KILL
DEFB 'L' ;LIST CODE
DEFW LIST
DEFB 'O' ;SET OFFSET
DEFW SETOS
DEFB 'P' ;GENERATE PROLOG
DEFW PROLOG
DEFB 'Q' ;QUIET MODE
DEFW QUIET
DEFB 'R' ;READ FILES
DEFW READ
DEFB 'S' ;SAVE FILES
DEFW SAVE
DEFB 'U' ;SET COMMENTS
DEFW UAREA
DEFB 'X' ;PURGE SYMBOLS AND CONTROL
DEFW PURGE
DEFB 'Z' ;CLOSE ASM FILE
DEFW CLOSE
DEFB '?' ;STATISTICS DISPLAY
DEFW STAT
DEFB 0 ;END OF COMMAND TABLE
;
;COMMAND: H
; PRINT HELP INFORMATION
;
HELP:
CALL PSTRNG ;JUST ONE BIG PRINT
;LINE 1
DEFB 0DH,0AH,' HELP on DASM -- Command Summary'
;LINE 2
DEFB 0DH,0AH,';addr,comment Enter Comment at addr '
DEFB ';addr List comment at addr'
;LINE 3
DEFB 0DH,0AH,'; List Comments Table '
DEFB ';addr, Delete Comment'
;LINE 4
DEFB 0DH,0AH,'A (see L) Attempt to find DB''s '
DEFB 'B (see L) Build Symbol Table'
;LINE 5
DEFB 0DH,0AH,'C Dump Control Table '
DEFB 'Cnnnn Dump Ctrl Table at nnnn'
;LINE 6
DEFB 0DH,0AH,'Cnnnn,x Set Ctrl (x=BEHISW) '
DEFB 'Dnnnn Dump from nnnn on'
;LINE 7
DEFB 0DH,0AH,'Daaaa,bbbb Dump over range '
DEFB 'D,bbbb Dump thru bbbb'
;LINE 8
DEFB 0DH,0AH,'D Dump 80H more '
DEFB 'D=nn Set Dump Size Default'
;LINE 9
DEFB 0DH,0AH,'DS Dump the Symbol Table '
DEFB 'DS.symbol Dump starting at symbol'
;LINE 10
DEFB 0DH,0AH,'Ennnn,.symbol Enter symbol into table '
DEFB 'Fnnnn,ssss Find nnnn after ssss'
;LINE 11
DEFB 0DH,0AH,'F or Fnnnn Cont Find or Find nnnn '
DEFB 'Issss,oooo Inc addrs>=ssss by oooo'
;LINE 12
DEFB 0DH,0AH,'K.symbol Kill symbol from table '
DEFB 'L List next '
DEFB (INITLCNT/10)+'0',(INITLCNT MOD 10)+'0'
DEFB ' lines'
;LINE 13
DEFB 0DH,0AH,'Lssss,eeee List over range '
DEFB 'L,eeee List to eeee'
;LINE 14
DEFB 0DH,0AH,'Lssss List '
DEFB (INITLCNT/10)+'0',(INITLCNT MOD 10)+'0'
DEFB ' lines from ssss '
DEFB 'L=nn[,others] Set list default'
;LINE 15
DEFB 0DH,0AH,'O Print current offset '
DEFB 'Onnnn Set new offset'
;LINE 16
DEFB 0DH,0AH,'Pssss,eeee Generate program prolog '
DEFB 'Q Quiet prefix'
;LINE 17
DEFB 0DH,0AH,'Rfilename.COM Read file @ offset+100H '
DEFB 'Rfilename.CTL Read Control Table'
;LINE 18
DEFB 0DH,0AH,'Rfilename.SYM Read Symbol Table '
DEFB 'Rfilename.DOC Read Comments Table'
;LINE 19
DEFB 0DH,0AH,'Rfilename.ALL Read CTL, SYM, DOC, COM '
DEFB 'Sfilename.ASM Save ASM File'
;LINE 20
DEFB 0DH,0AH,'Sfilename.CTL Save CTL File '
DEFB 'Sfilename.SYM Save SYM File'
;LINE 21
DEFB 0DH,0AH,'Sfilename.DOC Save DOC File '
DEFB 'Sfilename.ALL CTL, SYM, DOC, ASM'
;LINE 22
DEFB 0DH,0AH,'Unnnn Set Comment Table addr '
DEFB 'X Restart DASM'
;LINE 23
DEFB 0DH,0AH,'Z Write EOF to ASM File '
DEFB '? Print Statistics'
;LINE 24
DEFB 0DH,0AH,0
JP GETCMD
;
;COMMAND: X
; PURGE ALL SYMBOLS AND CONTROL
;
PURGE:
CALL PSTRNG ;PROMPT USER
DEFB 'Restart DASM (Y/N)? ',0
CALL CHIN ;GET SINGLE CHAR AND CAP
CP 'Y'
JP NZ,GETCMD
CALL PSTRNG ;PRINT FUNCTION
DEFB 'Restarting DASM',0DH,0AH,0
JP CLEAN ;RESTART DASM AT INIT
;
; INPUT A SINGLE CHAR IN A VIA THE BDOS AND CAPITALIZE IT; FOLLOW WITH <CRLF>
;
CHIN:
LD C,1 ;GET CHAR FROM CON:
CALL BDOS
AND 5FH ;CAPITALIZE
PUSH AF
CALL CRLF
POP AF
RET
;
;COMMAND: P
; ENTER PROLOG INTO ASSEMBLY LANGUAGE PROGRAM
;
PROLOG:
LD HL,INBUF+3 ;PT TO STARTING ADDRESS
LD A,(HL) ;NO ADDRESS SPECIFIED?
CP 0DH ;ERROR IF SO
JP Z,WHAT
CALL CNVRT ;CONVERT ADDRESS VALUE TO BINARY IN DE
CP ' ' ;CHAR AFTER ADDRESS = <SP>?
JR Z,PRLG0 ;CONT IF SO
CP ',' ;CHAR AFTER ADDRESS = ','?
JP NZ,WHAT ;ERROR IF NOT ',' OR <SP>
PRLG0:
INC HL ;PT TO 2ND ADDRESS
PUSH DE ;SAVE FIRST ADDRESS ON STACK
PUSH HL ;SAVE PTR TO 2ND ADDRESS
LD A,1 ;TURN ON DISK OUTPUT
LD (WRTENAB),A
CALL PSTG ;PRINT NEW ORG
DEFB 9,'ORG',9,0
POP HL
POP DE
LD A,D ;ORG AT FIRST ADDRESS
CALL PASHEX ;PRINT AS 'nnH'
LD A,E
CALL PHEX
LD A,'H'
CALL COUT
CALL CRLF
PUSH DE ;SAVE FIRST ADDRESS
CALL CNVRT ;GET 2ND ADDRESS IN DE
CP 0DH ;ERROR IF <CR>
JP NZ,WHAT
POP BC ;BC=START ADDRESS, DE=END ADDRESS
LD HL,SYMTAB ;PT TO SYMBOL TABLE
PRLG1:
INC HL ;SKIP OVER SYMBOL ADDRESS
INC HL
LD A,(HL) ;GET 1ST CHAR OF SYMBOL
OR A ;END OF SYMBOL TABLE? (CHAR COUNT = 0)
JP Z,GETCMD ;DONE IF SO
DEC HL ;PT TO SYMBOL ADDRESS
DEC HL
LD A,(HL) ;COMPARE SYMBOL ADDRESS TO CURRENT ADDRESS
SUB C ;... IN BC
INC HL
LD A,(HL)
SBC A,B
JR C,GENEQU ;GENERATE EQU IF SYMBOL < START ADDRESS
DEC HL ;PT TO SYMBOL LOW-ORDER ADDRESS AGAIN
LD A,(HL) ;COMPARE SYMBOL ADDRESS TO END ADDRESS
SUB E
INC HL
LD A,(HL)
SBC A,D
JP C,WITHIN ;PROCESS NORMALLY IF START <= SYMBOL <= END
;
; SYMBOL IS NOT IN RANGE OF:
; START ADDRESS <= SYMBOL <= END ADDRESS
; GENERATE EQUATE FOR IT
;
GENEQU:
PUSH HL ;SAVE PTR TO SYMBOL
PUSH BC ;SAVE START ADDRESS
INC HL ;PT TO SYMBOL CHAR COUNT
LD B,(HL) ;B=CHAR COUNT
PUSH HL ;SAVE PTR TO CHAR COUNT
INC HL ;PT TO FIRST LETTER OF SYMBOL
LD A,(HL) ;GET IT
DEC HL ;PT BACK TO CHAR COUNT
CP 'A' ;IF FIRST LETTER IS LESS THAN A, DON'T GENERATE 'EQU'
JR C,PRLG3
;
; SCAN SYMBOL FOR '+' OR '-' AND DON'T GENERATE 'EQU' IF IT CONTAINS ONE
;
PRLG2:
INC HL ;PT TO NEXT CHAR
LD A,(HL) ;GET IT
CP '+' ;CHECK
JR Z,PRLG3
CP '-' ;CHECK
JR Z,PRLG3
DJNZ PRLG2 ;LOOP
POP HL ;GET PTR TO SYMBOL CHAR COUNT
LD B,(HL) ;B=CHAR COUNT
LD A,1 ;ENABLE DISK OUTPUT
LD (WRTENAB),A
;
; PRINT SYMBOL EQUATE; HL PTS TO BYTE BEFORE SYMBOL AND B=NUMBER OF CHARS
;
LOOPB:
INC HL ;PT TO NEXT CHAR
LD A,(HL) ;GET IT
CALL COUT ;PRINT IT
DJNZ LOOPB ;LOOP FOR NUMBER OF CHARS IN B
CALL PSTG
DB 9,'EQU',9,0
POP BC ;GET START ADR
POP HL ;PT TO CHAR COUNT OF CURRENT SYMBOL
LD A,(HL) ;CHECK FOR HIGH-ORDER VALUE
OR A ;DON'T PRINT SIGNIFICANT ZERO
CALL NZ,PASHEX
DEC HL ;PT TO LOW-ORDER VALUE
LD A,(HL) ;GET IT
CALL PHEX ;PRINT IT
LD A,'H' ;FOLLOWING 'H' FOR 'nnH' AND NEW LINE
CALL COUT
CALL CRLF
XOR A ;DISABLE WRITE TO DISK
LD (WRTENAB),A
INC HL ;PT TO HIGH-ORDER VALUE OF SYMBOL
;
; SYMBOL IS WITHIN THE DESIRED RANGE (START <= SYMBOL <= END)
;
WITHIN:
INC HL ;PT TO CHAR COUNT OF SYMBOL
LD A,(HL) ;GET IT
CALL SKIP ;SKIP TO NEXT SYMBOL
INC HL ;PT TO ITS ADDRESS
CALL BRKCHK ;CHECK FOR BREAK
JP PRLG1 ;CONTINUE GENERATING PROLOG
;
; SKIP CURRENT SYMBOL FOR ONE REASON OR ANOTHER
;
PRLG3:
POP HL ;RESTORE REGS AND CONTINUE
POP BC
POP HL
JR WITHIN
;
;COMMAND: Q PREFIX
; EXECUTE THE COMMAND IN THE QUIET MODE
;
QUIET:
LD A,1 ;TURN ON QUIET MODE
LD (HUSH),A
LD DE,INBUF+2 ;COPY COMMAND LINE LEFT 1 CHARACTER
LD HL,INBUF+3
SHFTBF:
LD A,(HL) ;COPY IN ORDER TO CONTINUE PROCESSING
LD (DE),A ;... NORMALLY
INC HL
INC DE
CP 0DH
JR NZ,SHFTBF
JP PRCEDE ;RETURN TO MAIN COMMAND PROCESSOR
;
;COMMAND: D
; DUMP THE MEMORY, SYMBOL TABLE, OR SET THE DEFAULT DUMP LENGTH
;
DUMP:
LD HL,(DMPSTRT) ;GET PTR TO STARTING ADR FOR DUMP
PUSH HL
EX DE,HL ;... IN DE
LD HL,(DMPLEN) ;GET DEFAULT LENGTH OF DUMP
ADD HL,DE ;CALCULATE END ADDRESS OF DUMP
LD (DMPEND),HL ;SAVE IT
POP DE
LD HL,INBUF+3 ;LOOK AT COMMAND LINE
LD A,(HL) ;GET CHAR AFTER THE 'D'
CP 0DH ;IF <CR>, THEN DUMP FROM DMPSTRT TO DMPEND
JP Z,DMPHDR
CP 'S' ;IF S, THEN DUMP THE SYMBOL TABLE
JP Z,DMPSYM
CP '=' ;IF =, THEN SET THE DEFAULT DUMP LENGTH
JP Z,DUMP5
CP ',' ;IF ',', THEN DUMP FROM CURRENT TO END SPEC
JP Z,DUMP1
;
; NUMBER SHOULD FOLLOW THE D -- PROCESS IT
;
DUMP0:
CALL CNVRT ;GET VALUE
PUSH HL ;SAVE IT
LD HL,(DMPLEN) ;GET DEFAULT LENGTH
ADD HL,DE ;COMPUTE END OF DUMP
LD (DMPEND),HL ;SAVE IT
POP HL ;GET START ADDRESS OF DUMP
;
; CHECK FOR DELIMITER AFTER FIRST NUMBER
;
DUMP1:
CP 0DH ;IF <CR>, DUMP FOR THE DEFAULT LENGTH
JR Z,DUMP3
CP ' ' ;IF <SP>, GET 2ND NUMBER
JR Z,DUMP2
CP ',' ;IF ',', GET 2ND NUMBER
JP NZ,WHAT ;ERROR IF NOT
;
; EXTRACT 2ND NUMBER FROM DUMP COMMAND
;
DUMP2:
INC HL ;PT TO NUMBER
PUSH DE
CALL CNVRT ;RETURN IT IN DE
EX DE,HL
LD (DMPEND),HL ;SET END ADDRESS OF DUMP
POP DE ;GET START ADDRESS OF DUMP IN DE
;
; ADD OFFSET TO BEGINNING AND ENDING DUMP ADDRESSES
; ON INPUT, DE=START OF DUMP ADDRESS
;
DUMP3:
LD HL,(OFFSET) ;GET OFFSET
PUSH HL ;SAVE IT
ADD HL,DE ;ADD TO BEGINNING DUMP ADDRESS
LD (DMPSTRT),HL ;SET PTR
LD HL,(DMPEND) ;GET END ADDRESS OF DUMP
POP DE ;GET OFFSET IN DE
ADD HL,DE ;ADD OFFSET TO END ADDRESS OF DUMP
LD (DMPEND),HL ;NEW END ADDRESS OF DUMP
CP 0DH ;MAKE SURE <CR> AFTER DUMP COMMAND
JP NZ,WHAT ;ERROR IF NOT
;
; PRINT HEADER FOR DUMP AND THEN PERFORM DUMP
;
DMPHDR:
CALL PSTRNG ;PRINT A HEADER FOR THE DUMP
DEFB 'Addr +0 +2 +4 +6 +8 +A +C +E ASCII'
DEFB 0DH,0AH,0
;
; MAIN DUMP LOOP
;
CNTDMP:
LD HL,(DMPSTRT) ;GET START ADDRESS OF DUMP
DUMP4:
CALL BRKCHK ;CHECK FOR BREAK
PUSH HL ;SAVE PTR TO NEXT BYTE
CALL TWOS ;MAKE HL CONTAIN RELATIVE VALUE
CALL PVALUE ;... BY SUBTRACTING OFFSET; THEN PRINT IT
POP HL ;GET PTR
PUSH HL ;SAVE PTR
CALL SPACE ;PRINT A SPACE
;
; DUMP AS HEX
;
DMPLN:
LD A,(HL) ;GET BYTE
CALL PHEX ;PRINT AS HEX
INC HL ;PT TO NEXT
LD A,L ;PRINT ONE SPACE FOR EVERY 2 VALUES
AND 1
CALL Z,SPACE
LD A,L ;PRINT TWO SPACES EVERY 4
AND 3
CALL Z,SPACE
LD A,L ;PRINT THREE SPACES EVERY 8
AND 7
CALL Z,SPACE
LD A,L ;CHECK FOR END OF DUMP LINE (EVERY 16)
AND 0FH
JR NZ,DMPLN
LD A,'!' ;PRINT BEGINNING '!'
CALL COUT
POP HL ;GET PTR TO FIRST BYTE
;
; DUMP AS ASCII
;
DMPASC:
LD A,(HL) ;GET CHAR
CP ' ' ;PRINT . IF LESS THAN <SP>
JR C,PERIOD
CP 7FH ;PRINT . IF GREATER THAN <DEL>
JR C,CHRCTR
;
; PRINT '.'
;
PERIOD:
LD A,'.'
;
; PRINT CHAR IN A AND ADVANCE FOR UP TO 16 CHARS
;
CHRCTR:
CALL COUT ;PRINT CHAR
INC HL ;PT TO NEXT
LD A,L ;END OF LINE?
AND 0FH ;EVERY 16
JR Z,LCMPLT ;DONE IF SO
AND 7 ;EXTRA SPACE FOR EVERY 8
CALL Z,SPACE
JR DMPASC ;CONTINUE ASCII DUMP
;
; TIDY UP THE LINE
;
LCMPLT:
LD A,'!' ;PRINT ENDING '!'
CALL COUT
CALL CRLF ;NEW LINE
LD (DMPSTRT),HL ;COMPARE CURRENT START ADDRESS TO END ADDRESS
LD A,(DMPEND)
SUB L
LD A,(DMPEND+1)
SBC A,H
JR NC,DUMP4 ;CONTINUE IF CURRENT START <= END
JP GETCMD ;RETURN TO COMMAND PROCESSING OTHERWISE
;
; SET THE DEFAULT NUMBER OF BYTES TO DUMP
;
DUMP5:
INC HL ;PT TO VALUE
CALL CNVRT ;RETURN VALUE IN DE
INC HL
DEC DE
EX DE,HL
LD (DMPLEN),HL ;SAVE VALUE
EX DE,HL
CP ','
JP Z,DUMP0
CP ' '
JP Z,DUMP0
CP 0DH
JP Z,GETCMD
JP WHAT
;
; DS -- DUMP THE SYMBOL TABLE
;
DMPSYM:
CALL IECNT ;INIT ECNT
LD HL,INBUF+4 ;PT TO CHAR AFTER 'DS'
LD A,(HL) ;GET IT
CP '.' ;SYMBOL SPECIFIED?
JR NZ,FRMBGN ;NO, SO DUMP FROM BEGINNING OF TABLE
CALL LNGTH ;COMPUTE LENGTH OF GIVEN SYMBOL
CALL PLCSYM ;RETURN PTR TO THIS SYMBOL IN HL
JR NC,FRMSYM ;PROCESS NORMALLY IF FOUND
LD HL,(SYMRKR)
JR FRMSYM
FRMBGN:
LD HL,SYMTAB ;PT TO TABLE
FRMSYM:
LD E,(HL) ;GET ADDRESS OF SYMBOL IN DE
INC HL
LD D,(HL)
INC HL
LD A,(HL) ;GET LENGTH OF SYMBOL IN A
OR A ;DONE IF LENGTH = 0
JP Z,SPITCR
EX DE,HL ;PRINT VALUE OF SYMBOL
CALL PVALUE
EX DE,HL
LD A,'=' ;PRINT =
CALL COUT
LD B,(HL) ;GET LENGTH OF SYMBOL IN B
LD A,SYMMAX+1 ;COMPUTE DIFF FROM MAX
SUB B
LD C,A ;DIFFERENCE IN C (NUMBER OF SPACES AFTER SYM)
INC HL
;
; PRINT THE SYMBOL PTED TO BY HL; B=NUMBER OF BYTES LONG THE SYMBOL IS
;
SPIT:
LD A,(HL) ;GET SYMBOL CHAR
CALL COUT ;PRINT IT
INC HL ;PT TO NEXT
DJNZ SPIT ;UNTIL DONE
;
; PRINT TRAILING SPACES AFTER SYMBOL
;
LD B,C ;SP COUNT IN B
SPIT1:
CALL SPACE
DJNZ SPIT1
CALL SPCRLF ;NEW LINE
CALL BRKCHK ;CHECK FOR BREAK
JR FRMSYM ;CONTINUE
;
; PRINT <CRLF> AND EXIT
;
SPITCR:
CALL CRLF ;NEW LINE
JP GETCMD
;
; COUNT DOWN ECNT AND OUTPUT <CRLF> ON ZERO
;
SPCRLF:
LD A,(ECNT) ;GET COUNT
DEC A
LD (ECNT),A
RET NZ
CALL CRLF ;NEW LINE
;
; INIT ECNT
;
IECNT:
LD A,4 ;SET 4 ENTRIES
LD (ECNT),A
RET
;
; PRINT THE VALUE OF THE OFFSET.
;
PRNTOS:
CALL PSTRNG
DB 'Offset = ',0
LD HL,(OFFSET) ;GET IT AND PRINT IT
CALL PVALUE
CALL CRLF ;NEW LINE
JP GETCMD
;
;COMMAND: O
; SET OR PRINT OFFSET ADDRESS
;
SETOS:
LD HL,INBUF+3 ;FORMAT: O c/r
LD A,(HL) ;.. or Oxxxx c/r
CP 0DH ;IF JUST O, DO IT VIA PRNTOS
JR Z,PRNTOS
CALL CNVRT ;GET VALUE IN DE
CP 0DH ;ERROR?
JP NZ,WHAT
EX DE,HL ;SAVE AS OFFSET
LD (OFFSET),HL
CALL CRLF ;NEW LINE AND PRINT NEW VALUE
JR PRNTOS
;
; SET UP THE FILE CONTROL BLOCK.
;
SETFCB:
LD A,(FOPEN) ;FILE OPEN?
OR A ;0 IF NOT
JP NZ,CANT
LD (FCB),A ;SET DEFAULT DRIVE
LD (FCB+12),A ;SET EXTENT NUMBER TO ZERO
LD HL,INBUF+3 ;PT TO FIRST LETTER OF POSSIBLE FILE NAME
LD A,(INBUF+4) ;GET SECOND LETTER
CP ' ' ;ERROR IF JUST <SP>
JP Z,WHAT
CP ':' ;GET AND SET DRIVE IF ':'
JR NZ,SMDRV
LD A,(HL) ;GET SPECIFIED DRIVE
SUB '@' ;CONVERT IT TO BINARY
LD (FCB),A ;SET DRIVE NUMBER IN FCB
INC HL
INC HL
;
; WRITE FILE NAME AND TYPE INTO FCB
;
SMDRV:
LD DE,FCB+1 ;PT TO FILE NAME FIELD OF FCB
LD B,8
CALL SLIDE ;PUT FILE NAME
LD B,3
CALL SLIDE ;PUT FILE TYPE
RET
;
; WRITE CHARS PTED TO BY HL INTO BUFFER PTED TO BY DE; WRITE AT MOST B
; CHARS, AND <SP> FILL THE BUFFER PTED TO BY DE
;
SLIDE:
LD A,(HL) ;GET NEXT CHAR
CP 0DH ;DONE?
JR Z,BLANK ;BLANK FILL IF SO
INC HL ;PT TO NEXT
CP '.' ;FILE TYPE FOLLOWS?
JR Z,BLANK ;BLANK FILL IF SO
LD (DE),A ;PUT CHAR
INC DE ;PT TO NEXT
DJNZ SLIDE ;COUNT DOWN
;
; CHECK FOR ERROR IF AFTER 8 CHARACTERS IN THE FILENAME
;
AFTR8:
LD A,(HL) ;GET NEXT CHAR
CP 0DH ;OK IF <CR>
RET Z
CP '.' ;OK IF '.'
INC HL ;PT TO NEXT AFTER '.'
RET Z
JR AFTR8
;
; BLANK FILL FOR THE REMAINDER OF THE NAME
;
BLANK:
LD A,' ' ;GET <SP>
LD (DE),A ;PUT IT
INC DE ;PT TO NEXT
DJNZ BLANK ;COUNT DOWN
RET
;
;COMMAND: A
; BUILD ASCII STRINGS USING DB'S
;
ASCASM:
LD A,1 ;SET FLAG
LD (ASCBLD),A
XOR A ;TURN OFF BUILD BY B COMMAND
LD (BUILD),A
JR LIST1 ;PERFORM LIST
;
;COMMAND: B
; BUILD LABELS
;
BLDASM:
LD A,1 ;TURN ON BUILD BY B COMMAND
LD (BUILD),A
XOR A ;TURN OFF BUILD BY A COMMAND
LD (ASCBLD),A
JR LIST1
;
;COMMAND: L
; DISASSEMBLE WITH THE 'L' OPTION
;
LIST:
XOR A ;TURN OFF A AND B FLAGS
LD (BUILD),A
LD (ASCBLD),A
LIST1:
XOR A ;DISABLE OUTPUT TO DISK
LD (WRTENAB),A
LD A,(NLINES) ;SET LINE COUNT
LD (LCTR),A
LD (CNTENAB),A ;ENABLE LINE COUNT
LD HL,INBUF+3 ;PT TO CHAR AFTER L, A, OR B COMMAND
LD A,(HL) ;GET IT
CP 0DH ;DO DEFAULT NUMBER IF EOL
JR Z,TENL
CP ',' ;USE CURRENT POSITION FOR FIRST ARG IF ','
JR Z,LIST3
CP ' ' ;SAME AS ','
JR Z,LIST3
CP '=' ;SET DEFAULT NUMBER OF LINES IF '='
JR NZ,LIST2
;
; SET DEFAULT NUMBER OF LINES FOR LIST
;
NWLNCT:
INC HL ;PT TO ARG
CALL CNVRT ;GET IT IN DE
LD A,E ;ERROR IF ZERO
OR A
JP Z,WHAT
LD (NLINES),A ;SET COUNTS
LD (LCTR),A
LD A,(HL) ;GET NEXT CHAR
INC HL
CP ',' ;CONTINUE IF COMMA OR SPACE
JR Z,LIST2
CP ' '
JR Z,LIST2
CP 0DH ;DONE IF <CR>
JP Z,GETCMD
JP WHAT ;ERROR OTHERWISE
;
; GET FIRST ARG FOR L, A, OR B FROM COMMAND LINE
;
LIST2:
CALL CNVRT ;GET VALUE IN DE
EX DE,HL
LD (PC),HL ;SET PC TO IT
EX DE,HL
CP 0DH ;DONE?
JR Z,TENL ;DO DEFAULT NUMBER IF SO
CP ' ' ;GET 2ND ARG IF <SP>
JR Z,LIST3
CP ',' ;SAME IF ','
JP NZ,WHAT ;ERROR OTHERWISE
;
; GET 2ND ARG FOR L, A, OR B COMMAND
;
LIST3:
INC HL ;PT TO FIRST CHAR OF 2ND ARG
CALL CNVRT ;GET ITS VALUE IN DE
EX DE,HL
LD (ENDLST),HL ;SET END OF LISTING TO IT
XOR A ;TURN OFF LINE COUNTING
LD (CNTENAB),A
;
; MAIN PROCESSING LOOP FOR L, A, AND B COMMANDS
;
TENL:
CALL BRKCHK ;CHECK FOR BREAK
LD A,(CNTENAB) ;CHECK FOR LINE COUNTING IN PROGRESS
OR A ;0 = NO
JR Z,CONTL ;CONTINUE IF NOT
LD A,(LCTR) ;GET COUNT
DEC A ;COUNT DOWN
JP M,GETCMD ;RETURN TO COMMAND PROCESSING IF DONE
JR FLAGA
;
; COMPARE ENDLST WITH PC
;
CONTL:
LD HL,(ENDLST) ;DONE WITH DISPLAY?
LD A,(PC)
SUB L
LD A,(PC+1)
SBC A,H
JP NC,GETCMD
;
; CHECK FOR A OR B COMMANDS
;
FLAGA:
LD A,(ASCBLD) ;A COMMAND IF ASCBLD NOT ZERO
OR A
JR Z,MOREL
;
; THIS IS THE MAJOR FUNCTION TO BUILD ASCII DB'S
;
BUILDA:
LD HL,(PC) ;HL PTS TO NEXT BYTE (RELATIVE)
EX DE,HL ;PTR IN DE
LD HL,(OFFSET) ;HL CONTAINS OFFSET
ADD HL,DE ;HL PTS TO NEXT BYTE ABSOLUTE
LD B,8 ;LOOK FOR 8 ASCII CHARS IN A ROW
LOOP8:
LD A,(HL) ;CHECK FOR ASCII CHAR
CALL ISITASC ;IS IT ASCII?
JR C,MOREL ;NO, SKIP TO NEXT BYTE
INC HL ;YES, PT TO NEXT
DJNZ LOOP8
;
; FIND END OF THIS ASCII STRING
;
FOLLOW:
LD A,(HL) ;LOOK UNTIL NON-ASCII
INC HL ;PT TO NEXT
CALL ISITASC
JR NC,FOLLOW
DEC HL ;PT TO NON-ASCII CHAR
CALL TWOS ;SUBTRACT OFFSET FROM LOCATION
EX DE,HL ;RESULT IN DE
PUSH DE ;SAVE PTR TO BYTE AFTER DB STRING FOR 'I' CONTROL
LD HL,(PC) ;GET VALUE OF BEGINNING OF ASCII STRING
EX DE,HL ;... IN DE
LD A,'B' ;SET B CONTROL POINT
CALL FTCTL0 ;A='B', DE=ADDRESS
POP HL
LD (PC),HL ;SET NEW ADDRESS TO CONTINUE FROM
EX DE,HL
LD A,'I' ;A='I', DE=ADDRESS FOR INSTR CONTROL
CALL FTCTL0
;
; NOW LOOK FOR ANY COMMENTS AT THIS ADDRESS
;
MOREL:
LD HL,(COMST) ;COMMENT TABLE IN USE?
LD A,H ;ADDRESS IS ZERO IF NOT
OR L
JR Z,NCMT
LD HL,(PC) ;HL PTS TO PC
EX DE,HL ;DE PTS TO PC
CALL CMCHK ;CHECK COMMENT TABLE FOR MATCH
JR C,NCMT ;NO MATCH
INC HL ;PT TO CHAR COUNT OF COMMENT
INC HL
LD B,(HL) ;B=NUMBER OF CHARS IN COMMENT
INC HL ;PT TO FIRST CHARACTER
LD A,(HL) ;A=FIRST CHAR OF COMMENT
CP ';' ;A ';' COMMENT IS LISTED AFTER THE OPCODE
DEC HL ;PT BACK TO CHAR COUNT
JR NZ,MOREL1 ;CONTINUE IF NO ';'
LD (XCPTR),HL ;SAVE THE COMMENT ADDRESS
JR NCMT
;
; THIS ROUTINE WILL
; PRINT COMMENTS
; LIKE THIS
;
NWLN:
SCF
NWLN0:
LD A,1 ;ENABLE WRITING
LD (WRTENAB),A
CALL C,SEMI ;OUTPUT SEMI BEFORE NEW COMMENT
XOR A
OR B ;CHECK CHAR COUNT FOR DONE
RET Z ;DONE IF ZERO CHARS LEFT
CNTCMT:
INC HL ;PT TO NEXT CHAR
LD A,(HL) ;GET IT
CP '\' ;NEW LINE?
JR NZ,NTBKSL
CALL CRLF ;NEW LINE
DEC B ;DEC CHAR COUNT
JR NWLN ;CONT
NTBKSL:
CALL COUT ;PRINT CHAR
DEC B ;DECREMENT COUNT
JR NZ,CNTCMT
RET
MOREL1:
CP '*' ; A '*' COMMENT REPLACES THE ENTIRE LINE
JR NZ,MOREL2
LD (RPLPTR),HL
JR NCMT
;
; PRINT COMMENT PTED TO BY HL AND THEN NEW LINE
;
MOREL2:
CALL NWLN ;PRINT COMMENT
CALL CRLF
;
; NOW PROCESS THE BYTE AS AN INSTRUCTION IF IT IS
;
NCMT:
LD HL,(PC) ;PT TO PC
EX DE,HL ;... IN DE
CALL SCHCTL ;CHECK CONTROL TABLE
DEC HL ;PT TO CONTROL MODE OF PREVIOUS ENTRY
JR C,RDCTL ;IF NO MATCH, CONTROL MODE OF PREVIOUS ENTRY IS IT
INC HL ;SINCE MATCH, PT TO CONTROL MODE OF MATCHED ENTRY
INC HL
INC HL
;
; CHECK CONTROL MODE
;
RDCTL:
LD A,(HL) ;GET CONTROL MODE
CP 'I' ;IS IT INSTRUCTION?
JR Z,ICTL ;PROCESS IF SO
CP 'E' ;END OF PROGRAM?
JP Z,CLOSE ;DONE IF SO
PUSH AF ;ELSE SAVE CONTROL MODE
INC HL ;PT TO ADDRESS OF NEXT CONTROL MODE
LD E,(HL) ;ADDRESS IN DE
INC HL
LD D,(HL)
PUSH DE ;SAVE ADDRESS OF NEXT CONTROL ENTRY
LD HL,(PC) ;PT TO PC
EX DE,HL ;... IN DE
CALL HSYM ;PRINT SYMBOL IF THERE
POP HL ;HL IS ADDRESS OF NEXT CONTROL ENTRY
LD (NXTCTL),HL ;SAVE IT
EX DE,HL ;... IN DE ALSO
XOR A ;DISABLE WRITE
LD (WRTENAB),A
POP AF ;GET CONTROL MODE
CP 'S' ;DS?
JP Z,DSMODE
CP 'B' ;DB?
JP Z,BMODE
CP 'H' ;DB HEX?
JP Z,HMODE
CP 'W' ;DW?
JP Z,WMODE
CALL COUT ;ELSE PRINT AS ERROR
CALL PSTRNG
DEFB ': Invalid CTL Entry',0DH,0AH,0
JP GETCMD
;
; EXECUTE HERE IF THE 'I' CTL IS IN EFFECT -- INTERPRET AS INSTRUCTION
; DE PTS TO BYTE WHICH IS BEING PROCESSED
;
ICTL:
CALL DASM ;INVOKE DISASSEMBLER
XOR A ;DISABLE WRITE
LD (WRTENAB),A
JP TENL
;
; DS CTL -- DE CONTAIN NEXT CTL ADDRESS
;
DSMODE:
PUSH DE ;SAVE NEXT CONTROL
LD A,(PC) ;COMPUTE -PC IN HL
CPL
LD L,A
LD A,(PC+1)
CPL
LD H,A
INC HL
ADD HL,DE ;HL = LENGTH OF SPACE DEFINED
LD A,1 ;ENABLE WRITING
LD (WRTENAB),A
CALL PSTG ;PRINT 'DS'
DEFB 'DS',9,0
LD A,H ;PRINT SIZE OF AREA
CALL PASHEX
LD A,L
CALL PHEX
LD A,'H'
CALL COUT
CALL CRLF
POP HL ;GET PTR TO NEXT CONTROL ENTRY
LD (PC),HL ;SET PC TO IT
JP TENL ;CONTINUE
;
; DW CTL -- PROCESS DW AND LOOK FOR LABELS
;
WMODE:
LD A,1 ;ENABLE WRITING
LD (WRTENAB),A
CALL PSTG ;PRINT 'DW'
DEFB 'DW',9,0
LD HL,(PC) ;GET PC
EX DE,HL ;... IN DE
LD HL,(OFFSET) ;GET OFFSET
ADD HL,DE ;HL PTS TO ACTUAL BYTE PAIR
LD E,(HL) ;SET DE TO DW VALUE
INC HL
LD D,(HL)
CALL PRNTDE ;PRINT DW VALUE
CALL CRLF
LD HL,(PC) ;ADVANCE PC TO BYTE AFTER DW VALUE
INC HL
INC HL
LD (PC),HL
JP TENL ;CONTINUE PROCESSING
;
; NEW LINE AND CONTINUE
;
STPLN:
CALL CRLF
JP TENL
;
; DB HEX MODE -- BUILD HEX DB'S
;
HMODE:
XOR A ;SET FLAG
LD (ADB),A
JR BMODE1
;
; DB MODE -- BUILD ASCII STRINGS LONGER THAN 8 CHARACTERS
;
BMODE:
LD A,0FFH ;SET FLAG FOR ASCII
LD (ADB),A
BMODE1:
XOR A ;INIT LENGTH TO ZERO
LD (BLNGTH),A
INC A ;ENABLE WRITING
LD (WRTENAB),A
CALL PSTG ;PRINT 'DB'
DEFB 'DB',9,0
;
; PROCESS BYTES OF DB
;
MOREB:
LD HL,(PC) ;GET RELATIVE ADDRESS
EX DE,HL ;... IN DE
LD HL,(OFFSET) ;GET OFFSET
ADD HL,DE ;PT TO ACTUAL BYTE
LD A,(ADB) ;CHECK FOR ASCII BUILD
OR A ;0=NO
LD A,(HL) ;GET BYTE OF DB
JR Z,LTSPC ;XXH BUILD
CP 0AH ;<LF>?
JR C,LTLF ;PROCESS IF LESS THAN
CP ' ' ;<SP>
JR C,LTSPC ;PROCESS IF LESS THAN <SP>
CP 7FH ;<DEL>?
JP C,LTRUB ;PROCESS IF GREATER THAN
;
; PRINT BYTE AS HEX NUMBER
;
LTSPC:
CALL PASHEX ;PRINT BYTE IN A AS HEX
LD A,'H'
CALL COUT
LD A,(BLNGTH) ;INCREASE LENGTH BY 2
ADD A,2
LD (BLNGTH),A
JR MVUP
;
; CHAR IS LESS THAN <LF> -- MAKE IT SINGLE DIGIT (LIKE 9 FOR TAB)
;
LTLF:
OR '0' ;MASK FOR ASCII
CALL COUT ;PRINT DIGIT
;
; ADVANCE TO NEXT BYTE
;
MVUP:
INC HL ;PT TO NEXT BYTE
EX DE,HL ;... IN DE
LD HL,(PC) ;PT TO PC
INC HL ;ADVANCE PC
LD (PC),HL
EX DE,HL ;DE PTS TO PC, HL PTS TO NEXT BYTE
;
; CHECK TO SEE IF THE NEXT CONTROL POINT BEEN REACHED
;
CNXCTL:
LD A,(NXTCTL) ;COMPARE AGAINST PC
CP E
JR NZ,TRYSYM
LD A,(NXTCTL+1)
CP D
JP Z,QTB
;
; SEE IF WE ARE POINTING TO A SYMBOL'S ADDRESS
;
TRYSYM:
LD HL,(PC) ;PC IN DE
EX DE,HL
CALL SYMSCH ;LOOK FOR SYMBOL
JP NC,STPLN ;NEW LINE IF THERE IS A SYMBOL
LD A,(BLNGTH) ;INCREASE LINE BY 2
ADD A,2
LD (BLNGTH),A
CP 27
JP NC,STPLN ;NEW LINE IF STRING EXCEEDS 27 CHARS
LD A,',' ;SEPARATE BY COMMA OTHERWISE
CALL COUT
JP MOREB
;
; VALID CHAR ... BEGIN PROCESSING AS QUOTED STRING
;
LTRUB:
LD A,'''' ;OUTPUT QUOTE
CALL COUT
LD A,(BLNGTH) ;INC LENGTH
INC A
LD (BLNGTH),A
LD A,(HL) ;GET CHAR
;
; OUTPUT AS ASCII CHARS
;
MORASC:
CALL COUT ;PRINT CHAR
LD A,(HL) ;CHECK FOR QUOTE
CP '''' ;COMPARE
CALL Z,COUT ;DOUBLE QUOTE
INC HL ;PT TO NEXT CHAR
EX DE,HL ;... IN DE
LD HL,(PC) ;INCR PC
INC HL
LD (PC),HL
EX DE,HL ;DE=NEXT PC
LD A,(NXTCTL) ;CHECK FOR CONTROL
CP E
JR NZ,YET
LD A,(NXTCTL+1)
CP D
JR Z,FNLQT
;
; CHECK FOR SYMBOL HERE
;
YET:
PUSH HL
LD HL,(PC)
EX DE,HL
CALL SYMSCH
POP HL
JR NC,FNLQT ;OUTPUT ENDING QUOTE AND NEW LINE FOR SYMBOL
LD A,(BLNGTH) ; BREAK
INC A ;INCR LINE LENGTH
;
; KEEP THE LINES LESS THAN 27 LONG
;
LD (BLNGTH),A
CP 35
JR NC,LASTQT
CP 27
JR C,STILL
;
; OVER 17H CHARACTERS HAVE BEEN QUOTED
;
DEC HL
LD A,(HL)
INC HL
CP ' '
JR Z,FNLQT
STILL:
LD A,(HL)
CP ' '
JR C,LASTQT
CP 7FH
JP C,MORASC
;
; PRINT A TRAILING QUOTE
;
LASTQT:
LD A,'''' ;PRINT QUOTE
CALL COUT
JP CNXCTL
;
; PRINT ENDING QUOTE AND NEW LINE
;
FNLQT:
LD A,''''
CALL COUT
QTB:
CALL CRLF
JP TENL
;
;COMMAND: I<address>,<offset>
; INCREMENT SYMBOL TABLE ADDRESSES AFTER AND ON <ADDRESS> BY <OFFSET>
; FOR DISASSEMBLY OF NEW VERSIONS OF PROGRAMS
;
INCMNT:
LD HL,INBUF+3 ;LOOK AT COMMAND LINE
LD A,(HL) ;GET CHAR AFTER 'I'
CP 0DH ;ERROR IF EOL
JP Z,WHAT
CALL CNVRT ;GET FIRST VALUE IN DE
PUSH DE ;SAVE STARTING ADDRESS ON STACK
CP ' ' ;CHECK FOR VALID DELIMITER
JR Z,INCM1
CP ',' ;' ' OR ',' DELIMITER
JP NZ,WHAT
INCM1:
INC HL ;PT TO FIRST CHAR AFTER DELIMITER
CALL CNVRT ;GET OFFSET IN DE
CP 0DH ;MUST BE EOL NOW
JP NZ,WHAT
LD B,D ;BC=OFFSET
LD C,E
POP DE ;DE=START ADDRESS
LD HL,SYMTAB ;PT TO TABLE
; MAJOR LOOP FOR SCANNING SYMBOL TABLE -- HL PTS TO LOW SYM ADDRESS BYTE
INCM2:
INC HL ;PT TO HI SYM ADDRESS
LD A,(HL) ;GET HI
DEC HL ;PT TO LOW SYM ADDRESS
CP D ;COMPARE
JR C,INCM4 ;SKIP SYMBOL ENTRY
JR NZ,INCM3 ;SYMBOL IS GREATER SO ADD OFFSET TO IT
LD A,(HL) ;GET LOW
CP E ;COMPARE
JR C,INCM4 ;SKIP SYMBOL ENTRY
; ADD OFFSET TO SYMBOL ADDRESS PTED TO BY HL
INCM3:
LD A,(HL) ;GET LOW ADDRESS BYTE
ADD A,C ;ADD LOW OFFSET BYTE
LD (HL),A ;PUT LOW ADDRESS BYTE
INC HL ;PT TO HI ADDRESS BYTE
LD A,(HL) ;GET HIGH ADDRESS BYTE
ADC A,B ;ADD HI OFFSET BYTE
LD (HL),A ;PUT HI ADDRESS BYTE
DEC HL ;PT TO LOW ADDRESS BYTE
; SKIP TO NEXT SYMBOL -- HL PTS TO LOW ADDRESS BYTE
INCM4:
INC HL ;PT TO HI ADDRESS
INC HL ;PT TO CHAR COUNT
LD A,(HL) ;GET CHAR COUNT
OR A ;DONE IF ZERO
JP Z,GETCMD
INC HL ;PT TO FIRST CHAR OF SYMBOL
ADD A,L ;ADD SYMBOL LENGTH TO HL
LD L,A
LD A,0 ;ADD IN HI NOW
ADC A,H
LD H,A ;HL PTS TO FIRST BYTE OF NEXT SYMBOL
JR INCM2 ;CONTINUE PROCESSING
;
;COMMAND: ?
; STATISTIC OUTPUT
;
STAT:
CALL PSTRNG ;THIS IS RATHER STRAIGHT-FORWARD, SO FEW COMMENTS
DEFB 'Scratch Area Start = ',0
LD HL,ENDALL
CALL PVALUE ;PRINT VALUE
CALL PSTRNG
DEFB 0DH,0AH
DEFB 'Scratch Area End = ',0
LD HL,(6)
LD L,0
CALL PVALUE ;print the beginning of BDOS (not CCP)
CALL PSTRNG
DEFB 0DH,0AH,0AH
DEFB 'COM Start = 0100',0dh,0ah
DEFB 'COM End = ',0
LD HL,(RELEND) ;GET END ADDRESS
CALL PVALUE
CALL PSTRNG
DEFB 0DH,0AH,0AH
DEFB 'SYMTBL = ',0
LD HL,SYMTAB
CALL PVALUE
LD HL,(SYMEND)
CALL PVALUE
CALL CRLF
CALL PSTRNG
DEFB 'PC = ',0
LD HL,(PC)
CALL PVALUE
CALL CRLF
CALL PSTRNG
DEFB 'OFFSET = ',0
LD HL,(OFFSET)
CALL PVALUE
CALL CRLF
LD HL,(COMST)
LD A,H
OR L
JR Z,CTLSTT
CALL PSTRNG
DEFB 'COMNTS = ',0
LD HL,(COMST)
CALL PVALUE
LD HL,(COMEND)
CALL PVALUE
CALL CRLF
CTLSTT:
CALL CTLST
CALL CMNTST
JP GETCMD
;
; PRINT PARAMETERS OF CONTROL TABLE
;
CTLST:
CALL PSTRNG ;PRINT THE START AND END OF CONTROL TABLE
DEFB 'CTLTBL = ',0
LD HL,CTLTBL
CALL PVALUE
;
; FIND THE END OF THE CTLTBL (FF,FF)
;
FNDEND:
LD A,(HL) ;GET FIRST BYTE
INC HL ;PT TO NEXT
AND (HL) ;AND IT IN ... IF BOTH ARE 0FFH, RESULT IS 0FFH
INC HL ;PT TO CTL LETTER
INC HL ;PT TO NEXT BYTE OF ADDRESS
INC A ;IF RESULT WAS 0FFH, A NOW EQUALS 0
JR NZ,FNDEND ;CONTINUE UNTIL A=0
DEC HL ;BACK UP TO PREVIOUS ENTRY (END OF TABLE)
DEC HL
DEC HL
CALL PVALUE ;PRINT THE VALUE 0FFFFH
JP CRLF
;
; PRINT THE STATUS MESSAGE OF THE SYMBOL COMMENTS FACILITY
;
CMNTST:
CALL PSTRNG ;PRINT THE STATUS OF SYMBOL COMMENTS
DEFB 'Symbol Comments are O',0
LD A,(XCSW)
OR A
LD A,'N'
JR NZ,CMTST1
LD A,'F'
CALL COUT
CMTST1:
CALL COUT
JP CRLF
;
;COMMAND: F
; FIND THE OCCURRENCE OF ADDRESSES
;
FIND:
LD HL,INBUF+3
LD A,(HL)
CP 0DH ;CHECK FOR NO FURTHER ARGS
JR Z,PREVF
CALL CNVRT ;GET ARG IN DE
EX DE,HL ; ... IN HL
LD (FNDADD),HL ;ADDRESS TO LOOK FOR
LD HL,(OFFSET) ;GET OFFSET
LD (FNDPC),HL ;SET START OF SEARCH ADDRESS
EX DE,HL ;RESTORE HL TO PT TO CHAR IN COMMAND LINE
CP 0DH ;DONE?
JR Z,PREVF
CP ' ' ;<SP> OR ',' MEAN TO CONTINUE
JR Z,FIND0
CP ','
JP NZ,WHAT
FIND0:
INC HL
CALL CNVRT ;GET 2ND ARG FOR FIND
CP 0DH
JP NZ,WHAT
LD HL,(OFFSET) ;SET THIS AS STARTING ADDRESS
ADD HL,DE ;WITH PROPER OFFSET
LD (FNDPC),HL ;START LOOKING FROM HERE
;
; CONTINUE THE PREVIOUS 'F' COMMAND
;
PREVF:
LD HL,(FNDADD) ;GET ADDRESS WE ARE LOOKING FOR
EX DE,HL ;... IN DE
NYET:
CALL BRKCHK ;CHECK FOR BREAK
LD HL,(FNDPC) ;PT TO PC
LD A,(HL) ;GET BYTE AT PC
INC HL ;PT TO NEXT
LD (FNDPC),HL
CP E ;COMPARE BYTE WITH ADDRESS WE ARE LOOKING FOR
JR NZ,NYET
LD A,(HL) ;PARTIAL MATCH -- TRY HIGH BYTE
CP D
JR NZ,NYET
;
; WE FOUND ADDRESS IN MEMORY -- PRINT DATA
;
PUSH HL
PUSH DE
CALL TWOS
DEC HL
CALL PVALUE ;PRINT LOCATION OF FOUND ADDRESS (RELATIVE)
POP DE
POP HL
CALL SPACE ;PRINT <SP>
JR NYET
;
; HL=HL-OFFSET
; TAKE 2'S COMPLEMENT OF OFFSET AND ADD TO H & L.
;
TWOS:
LD A,(OFFSET) ;GET 2'S COMP OF OFFSET IN DE
CPL
LD E,A
LD A,(OFFSET+1)
CPL
LD D,A
INC DE
ADD HL,DE ;HL=HL+DE
RET
;
;COMMAND: Z
; CLOSE THE FILE
;
CLOSE:
CALL HSYM
LD A,1 ;ENABLE WRITING TO DISK FILE
LD (WRTENAB),A
CALL PSTG ;WRITE END STATEMENT
DEFB 'END',0DH,0AH,0
XOR A ;DISABLE WRITING TO FILE
LD (WRTENAB),A
LD A,(FOPEN) ;CHECK IF FILE WAS OPEN
OR A
JP Z,GETCMD
LD A,1AH ;FILL WITH ^Z
CALL WRTFILE
CALL NXTRCRD
XOR A ;CLOSE FILE
LD (FOPEN),A
CALL PSTRNG ;PRINT MESSAGE
DEFB '++ ASM File Closed ++',0DH,0AH,0
JP GETCMD
;
;COMMAND: R
; READ A FILE OR FILES
;
READ:
CALL SETFCB ;LOAD THE FCB WITH THE PROPER FILE NAME AND TYPE
LD A,(FOPEN) ;CHECK TO SEE IF A FILE IS ALREADY OPENED
OR A
JP NZ,CANT ;ABORT IF SO
LD HL,FCBTYPE ;CHECK FILE TYPE
LD DE,TPALL ;IS IT 'ALL'?
LD C,3
CALL CHKSTG
JP NZ,NOTALL ;PROCEED IF NOT
;
; READ IN DOC, SYM, CTL FILES
;
CALL ALLRD ;READ IN ALL FILES
JP STAT ;PRINT STATISTICS
;
; READ IN ALL FILES -- COMMON ROUTINE
;
ALLRD:
LD HL,TPDOC ;SET FILE TYPE TO DOC
CALL FIXTYP
CALL PSTRNG ;TELL USER WHAT IS HAPPENING
DEFB 0dh,0ah
DEFB 'Reading DOC file...',0dh,0ah,0
CALL DOCRD ;READ FILE IN
LD HL,TPSYM ;SET FILE TYPE TO SYM
CALL FIXTYP
CALL PSTRNG ;TELL USER WHAT IS HAPPENING
DEFB 'Reading SYM file...',0dh,0ah,0
CALL SYMRD ;READ FILE IN
LD HL,TPCTL ;SET FILE TYPE TO CTL
CALL FIXTYP
CALL PSTRNG ;TELL USER WHAT IS HAPPENING
DEFB 'Reading CTL file...',0dh,0ah,0
CALL CTLRD ;READ FILE IN
IF RDCOMQ ;ENABLE QUESTION OF COM FILE READ?
CALL PSTRNG
DEFB 'Read in COM File (Y/N)? ',0
CALL CHIN ;GET RESPONSE
CP 'Y'
JP NZ,STAT ;PRINT STATISTICS
ENDIF
LD HL,TPCOM ;SET FILE TYPE TO COM
CALL FIXTYP
CALL PSTRNG ;TELL USER WHAT IS HAPPENING
DEFB 'Reading COM file...',0dh,0ah,0
CALL COMRD ;READ FILE IN
RET
;
; SET THE FILE TYPE TO THAT PTED TO BY HL
;
FIXTYP:
LD DE,FCBTYPE
LD B,3
XOR A
LD (FCB+0CH),A ;zero the extent byte
JP SLIDE
;
; FILE TYPE WAS NOT 'ALL', SO CHECK TO SEE WHAT TYPE IT WAS AND PROCESS
;
NOTALL:
LD HL,FCBTYPE ;CHECK FOR SYM
LD DE,TPSYM
LD C,3
CALL CHKSTG
JR NZ,NOTSYM
CALL SYMRD ;READ SYM FILE
JP STAT ;PRINT STATS
NOTSYM:
LD HL,FCBTYPE ;CHECK FOR COM
LD DE,TPCOM
LD C,3
CALL CHKSTG
JP NZ,NOTCOM
CALL COMRD ;READ IN A COM FILE
JP GETCMD ;CONTINUE COMMAND LINE PROCESSING
;
; READ IN COM FILE
;
COMRD:
CALL RDOPEN ;OPEN COM FILE FOR READ
LD HL,(OFFSET) ;HL=OFFSET
LD A,H
CP (SYMTAB+600H) SHR 8 ;CHECK FOR NO OVERWRITE OF SYMTABLE
JP C,OSERR
LD DE,0100H ;SET DMA ADDRESS TO OFFSET PLUS 100H
ADD HL,DE
SETDMA:
PUSH HL ;SET THE DMA ADDRESS.
EX DE,HL
LD C,1AH
CALL BDOS
LD DE,FCB ;READ A RECORD.
LD C,14H
CALL BDOS
OR A ;DONE?
JR NZ,RDCMPLT
POP HL
LD DE,RECLEN ;PT TO NEXT BLOCK FOR READ
ADD HL,DE
JP SETDMA ;CONTINUE
;
; DONE WITH LOAD OF COM FILE
;
RDCMPLT:
POP HL ;GET DMA ADDRESS OF LAST READ
CALL PSTRNG
DEFB 'Last Block Read into Memory at ',0
CALL PVALUE
CALL PSTRNG
DEFB 0DH,0AH
DEFB 'Last Block Ends at Relative ',0
CALL TWOS
LD (RELEND),HL ;SAVE RELATIVE END ADDRESS
CALL PVALUE
CALL CRLF
LD DE,RECLEN ;RESET THE DMA ADDRESS TO 80H
LD C,1AH
CALL BDOS
RET
;
; THE READ IS NOT A .SYM OR A .COM FILE
;
NOTCOM:
LD HL,FCBTYPE ;CHECK FOR CTL FILE
LD DE,TPCTL
LD C,3
CALL CHKSTG
JR NZ,NOTCTL
JP ISCTL ;READ IN CTL FILE
NOTCTL:
LD HL,FCBTYPE ;CHECK FOR DOC FILE
LD DE,TPDOC
LD C,3
CALL CHKSTG
JP NZ,WHAT ;ERROR IF NOT COM, SYM, CTL, OR DOC
CALL DOCRD ;READ IN DOC FILE
JP STAT
;
; ERROR -- ATTEMPT TO OVERLAY THE SYMBOL TABLE OR DISASSEMBLER
;
OSERR:
CALL PSTRNG
DEFB '++ NO, that would overlay '
DEFB 'the Disassembler',0DH,0AH
DEFB 'because the Offset is too small: '
DEFB 0
CALL PRNTOS
CALL PSTRNG
DEFB ' ++',0DH,0AH,0
RET
;
; READ THE SYMBOL TABLE FROM DISK
;
SYMRD:
LD HL,SYMTAB ;PT TO SYMBOL TABLE
CALL READFILE ;READ FILE INTO IT
LD (SYMEND),HL ;SET END ADDRESS OF SYMBOL TABL
INC HL ;PT TO NEXT SYMBOL CHAR COUNT
INC HL
LD (HL),0 ;SET CHAR COUNT TO ZERO
RET
;
; READ THE DOC (COMMENTS) FILE FROM DISK
;
DOCRD:
CALL AREACK ;MAKE SURE COMMENTS AREA DEFINED
LD HL,(COMST) ;PT TO START OF COMMENTS AREA
CALL READFILE ;READ FILE IN
LD (COMEND),HL ;SET END OF COMMENTS AREA
LD (HL),0FFH ;STORE 0FFFFH AS ADDRESS OF NEXT COMMENT
INC HL
LD (HL),0FFH
RET
;
; READ FILE SET IN FCB INTO MEMORY PTED TO BY HL
;
READFILE:
CALL RDOPEN ;OPEN FILE
RDFL1:
CALL READMA ;READ NEXT BYTE (RETURNED IN A)
CP 1AH ;RETURN IF EOF EACHED
RET Z
CP 9 ;IGNORE <TAB>, <CR>, <LF>
JR Z,RDFL1
CP 0DH
JR Z,RDFL1
CP 0AH
JR Z,RDFL1
CALL NUM1 ;CONVERT FROM HEX CHARS TO VALUE IN DE
LD (HL),E ;SAVE THE ADDRESS
INC HL
LD (HL),D
INC HL
PUSH HL
INC HL
LD B,0 ;COUNT CHARS IN SYMBOL
SYMLUP:
CALL READMA ;GET NEXT BYTE
CP 9 ;DONE IF <TAB> OR <CR>
JR Z,SYMTERM
CP 0DH
JR Z,SYMTERM
LD (HL),A ;STORE BYTE
INC HL ;PT TO NEXT
INC B ;INCR CHAR COUNT
JR SYMLUP
SYMTERM:
EX (SP),HL
LD (HL),B
POP HL
JP RDFL1
;
; READ NUMBER FROM DISK FILE (1ST HEX DIGIT IN A ON ENTRY)
; VALUE RETURNED IN DE
;
NUM1:
LD DE,0 ;INIT NUMBER TO ZERO
LUP1:
CP ' ' ;DONE IF <SP>
RET Z
CP 1AH ;ERROR IF EOF
JP Z,ERROR1
CP '9'+1 ;WITHIN DIGIT RANGE?
JR C,NUMER1 ;IS A DIGIT
SUB 7 ;CONVERT 'A' TO 'F' TO '9'+1 TO 'E'+1
NUMER1:
SUB '0' ;CONVERT TO BINARY IN A
EX DE,HL ;OLD VALUE IN HL
ADD HL,HL ;*2
ADD HL,HL ;*4
ADD HL,HL ;*8
ADD HL,HL ;*16
ADD A,L ;+A
LD L,A ;ONLY CHANGES LOW-ORDER BYTE
EX DE,HL ;VALUE BACK IN DE
CALL READMA
CP 1AH
JP Z,ERROR1
JR LUP1
;
;COMMAND: S
; SAVE THE FILES
;
SAVE:
CALL SETFCB ;LOAD THE FCB FROM THE COMMAND LINE
LD A,(FOPEN) ;CHECK FOR FILE ALREADY OPEN
OR A ;ABORT IF SO
JP NZ,CANT
LD HL,FCBTYPE ;CHECK FOR TYPE OF 'ALL'
LD DE,TPALL
LD C,3
CALL CHKSTG
JP NZ,NTALL ;CHECK FOR SPECIFIC TYPE IF NOT ALL
LD HL,TPDOC ;SAVE DOC FILE
CALL FIXTYP
CALL PSTRNG
DEFB 0dh,0ah
DEFB 'Saving .DOC file...',0dh,0ah,0
CALL DOCSV
LD HL,TPSYM ;SAVE SYM FILE
CALL FIXTYP
CALL PSTRNG
DEFB 'Saving .SYM file...',0dh,0ah,00
CALL SYMSV
LD HL,TPCTL ;SAVE CTL FILE
CALL FIXTYP
CALL PSTRNG
DEFB 'Saving .CTL file...',0dh,0ah,0
CALL SVCTL0
CALL PSTRNG ;OPTIONALLY SAVE ASM FILE
DEFB 'Create a New .ASM File (Y/N)? ',0
CALL CHIN ;GET CHAR
CP 'Y'
JP NZ,GETCMD
LD HL,TPASM ;SAVE ASM FILE
CALL FIXTYP
;
; SAVE THE ASM FILE
;
SVASM:
LD A,1 ;MARK FILE AS OPEN
LD (FOPEN),A
XOR A ;DISABLE WRITING AT THIS TIME
LD (WRTENAB),A
CALL OPEN ;OPEN FILE FOR OUTPUT
CALL PSTRNG ;PRINT MESSAGE
DEFB '++ Writing ASM Enabled'
DEFB 0DH,0AH,'Use Z Command or '
DEFB 'E Control to Close File ++'
DEFB 0DH,0AH,0
JP GETCMD ;NOW PROCESS USER'S NEXT COMMANDS
;
; TYPE WAS NOT ALL, SO CHECK FOR SPECIFIC FILE TYPES
;
NTALL:
LD HL,FCBTYPE ;CHECK FOR SYM
LD DE,TPSYM
LD C,3
CALL CHKSTG
JP NZ,NTSYM
CALL SYMSV
JP GETCMD
;
; ROUTINE TO SAVE THE SYMBOL TABLE
;
SYMSV:
LD HL,SYMTAB ;PT TO SYMBOL TABLE
SVFL:
CALL OPEN ;OPEN THE FILE
LUP2:
LD E,(HL) ;GET ADDRESS OF SYMBOL IN DE
INC HL
LD D,(HL)
INC HL
LD A,(HL) ;GET LENGTH OF SYMBOL IN A
INC HL
LD B,A ;... AND B
OR A ;DONE IF LENGTH IS ZERO
JP Z,WRTEOF ;WRITE EOF TO FILE IF DONE
CALL EXPND ;WRITE ADDRESS IN DE AS ASCII CHARS ON DISK
LD A,' ' ;OUTPUT <SP>
CALL WRTFILE
WRTSYM:
LD A,(HL) ;GET NEXT CHAR OF SYMBOL
CALL WRTFILE ;WRITE TO DISK
INC HL ;PT TO NEXT
DJNZ WRTSYM ;COUNT DOWN SIZE OF SYMBOL
LD A,0DH ;WRITE NEW LINE CHARS
CALL WRTFILE
LD A,0AH
CALL WRTFILE
JR LUP2
;
; WRITE AN EOF
;
WRTEOF:
LD A,1AH ;WRITE EOF
CALL WRTFILE
CALL NXTRCRD
RET
;
; EXPAND AN ADDRESS IN DE TO ASCII CHARS AND SAVE ON DISK
;
EXPND:
LD A,D ;OUTPUT HIGH NYBBLE OF HIGH-ORDER BYTE
CALL HINIB ;ROUTINE TO DO THIS
CALL WRTFILE ;WRITE ASCII CHAR IN A TO DISK
LD A,D ;OUTPUT LOW NYBBLE
CALL LONIB
CALL WRTFILE
LD A,E ;HIGH OF LOW-ORDER BYTE
CALL HINIB
CALL WRTFILE
LD A,E ;LOW OF LOW-ORDER BYTE
CALL LONIB
JP WRTFILE
;
; NOT OF TYPE SYM -- CHECK FOR CTL
;
NTSYM:
LD HL,FCBTYPE ;CHECK FOR CTL TYPE
LD DE,TPCTL
LD C,3
CALL CHKSTG
JP Z,SVCTL ;YES, SO SAVE CTL FILE
LD HL,FCBTYPE ;CHECK FOR DOC TYPE
LD DE,TPDOC
LD C,3
CALL CHKSTG
JR Z,SVDOC ;YES, SO SAVE DOC FILE
LD HL,FCBTYPE ;CHECK FOR ASM TYPE
LD DE,TPASM
LD C,3
CALL CHKSTG
JP NZ,WHAT ;ERROR IF NOT ASM AT THIS POINT
JP SVASM ;SAVE ASSEMBLY LANGUAGE (TYPE ALREADY ASM)
;
; SAVE THE COMMENT TABLE
;
SVDOC:
CALL DOCSV
JP GETCMD
;
; SAVE COMMENTS
;
DOCSV:
CALL AREACK ;FIND END OF COMMENTS
LD HL,(COMEND) ;GET PTR IN HL
INC HL
INC HL
LD (HL),0 ;SET NULL FINAL COMMENT
LD HL,(COMST) ;PT TO START OF TABLE
JP SVFL ;PERFORM STRAIGHT SAVE
;
; ATTEMPT TO OPEN ANOTHER FILE WHILE ASM FILE ALREADY OPENED
;
CANT:
CALL PSTRNG
DEFB '++ No File Accessed Permitted '
DEFB 'until ASM Closed ++',0DH,0AH
DEFB 0
JP GETCMD
;
; EOF ENCOUNTERED TOO SOON
;
ERROR1:
CALL PSTRNG
DEFB '++ Unexpected EOF ++',0DH,0AH
DEFB 0
JP GETCMD
;
;COMMAND: C
; CONTROL TABLE ENTRIES ARE MADE HERE
;
CTL:
CALL IECNT ;INIT ECNT
LD HL,INBUF+3
LD A,(HL)
CP 0DH ;DUMP CONTROL TABLE IF JUST A 'C' COMMAND
JP Z,CDUMP1
CALL CNVRT ;GET ADDRESS
CP 0DH ;ERROR?
JP Z,CDUMP ;DUMP IF SO
CP ' ' ;DELIMITER?
JR Z,CTL0 ;PROCESS 2ND OPERAND IF SO
CP ',' ;SAME
JP NZ,WHAT ;ERROR OTHERWISE
CTL0:
INC HL ;PT TO 2ND OPERAND
LD A,(HL) ;GET IT (CONTROL TYPE)
CALL FTCTL ;PROCESS ENTRY WITH CONTROL TABLE
JP GETCMD
;
; PLACE A NEW ENTRY INTO THE CONTROL TABLE
; A=TYPE OF ENTRY (B, E, I, K, S, W) AND DE=ADDRESS
;
FTCTL0:
PUSH HL ;SAVE REGS
PUSH DE ;NEW ADDRESS
PUSH AF ;NEW TYPE
CALL SCHCTL ;FIND ENTRY IN CONTROL TABLE
DEC HL ;PT TO TYPE OF PREVIOUS CONTROL ENTRY
JR C,FTCTL1 ;IF CARRY, WE DIDN'T MATCH
INC HL ;PT TO TYPE OF CURRENT ENTRY WHICH MATCHES
INC HL
INC HL
FTCTL1:
POP AF ;GET NEW TYPE AND
POP DE ;... ADDRESS
CP (HL) ;DO OUR TYPES MATCH?
POP HL ;RESTORE HL
RET Z ;NO CHANGE IF THEY DO
;
; PLACE A NEW ENTRY INTO THE CONTROL TABLE
;
FTCTL:
LD (OPCTP),A ;SAVE TYPE OF ENTRY
CALL SCHCTL ;SCAN FOR A MATCH
JP C,PLACE ;NO MATCH, SO ENTRY MUST BE ADDED
;
; MATCH OF ADDRESS, SO SIMPLY CHANGE CONTROL MODE AT THAT POINT
;
LD A,(OPCTP) ;GET TYPE OF ENTRY
CP 'I' ;INSTRUCTION?
JR Z,RNCTL
CP 'W' ;DW?
JR Z,RNCTL
CP 'H' ;DB HEX?
JR Z,RNCTL
CP 'B' ;DB?
JR Z,RNCTL
CP 'S' ;DS?
JR Z,RNCTL
CP 'E' ;END OF PROGRAM?
JR Z,RNCTL
CP 'K' ;KILL SYMBOL?
JR Z,DELCTL
JP WHAT ;ERROR IF NONE OF THESE
;
; READ A NEW CONTROL MODE
; ENTRY FORM IS:
; DW ADDRESS
; DB CONTROL MODE
;
RNCTL:
INC HL ;ADDRESS IS SAME
INC HL ;PT TO CONTROL MODE
LD (HL),A ;ONLY SET NEW CONTROL MODE
RET
;
; DELETE THE ENTRY FROM THE CONTROL TABLE
;
DELCTL:
EX DE,HL ;DE PTS TO ENTRY TO DELETE
LD HL,3
ADD HL,DE ;HL PTS TO NEXT ENTRY
EX DE,HL ;DE PTS TO NEXT ENTRY, HL PTS TO ENTRY TO DELETE
;
; COPY CONTROL TABLE DOWN
;
CMPCT:
LD A,(HL) ;CHECK FOR END OF CONTROL TABLE
INC HL
AND (HL) ;ADDRESS IS 0FFFFH IF END
DEC HL
INC A ;A=0 MEANS ADDRESS IS 0FFFFH
JR Z,PNTHLL
LD BC,3 ;NOT AT END -- COPY 3 BYTES DOWN AND CONTINUE
EX DE,HL ;HL PTS TO SOURCE, DE TO DEST
LDIR ;COPY THE 3 BYTES
EX DE,HL ;DE PTS TO NEXT ENTRY, HL PTS TO ENTRY TO DELETE
JR CMPCT ;CONTINUE COPY OPERATION
;
; COPY COMPLETE
;
PNTHLL:
CALL CTLST ;PRINT CONTROL TABLE INFORMATION
JP GETCMD
;
; PLACE AN ENTRY INTO THE CONTROL TABLE
; ON ENTRY, HL PTS TO ENTRY TO INSERT BEFORE
;
PLACE:
LD A,(OPCTP) ;GET TYPE OF COMMAND
CP 'K' ;ERROR IF KILL
JP Z,WHAT
CP 'E' ;SET END OF PROGRAM AREA
JR Z,LGLCTL
CP 'H' ;DB HEX
JR Z,LGLCTL
CP 'B' ;DB
JR Z,LGLCTL
CP 'W' ;DW
JR Z,LGLCTL
CP 'I' ;INSTRUCTION
JR Z,LGLCTL
CP 'S' ;DS
JP NZ,WHAT ;ERROR IF NONE OF THESE
;
; PLACE ENTRY INTO CONTROL TABLE; A=TYPE, DE=ADDRESS, HL=ADDR OF ENTRY
; TO INSERT BEFORE
;
LGLCTL:
PUSH DE ;SAVE ADDRESS
PUSH HL ;SAVE ADDRESS OF ENTRY TO INSERT BEFORE
LD HL,CTLTBL ;PT TO FRONT OF TABLE
;
; LOOP TO THE END OF THE TABLE
;
LP2END:
LD A,(HL) ;CHECK FOR 0FFFFH AT END OF TABLE
INC HL
AND (HL) ;A=0FFH IF SO
INC HL ;PT TO CURR CONTROL TYPE
INC HL ;PT TO NEXT CONTROL ADDRESS
INC A ;A=0 AND ZERO FLAG SET IF AT END
JR NZ,LP2END ;CONTINUE UNTIL AT END OF TABLE
LD D,H ;DE=HL=PTR TO NEW LAST TABLE ENTRY LOC
LD E,L
INC HL ;PT TO ENTRY AFTER LAST ENTRY IN TABLE
INC HL
INC HL ;HL PTS TO NEW LAST TABLE ENTRY LOCATION
EX DE,HL ;DE PTS TO NEW, HL PTS TO OLD
POP BC ;BC=ADDRESS OF ENTRY TO INSERT BEFORE
;
; EXPAND THE TABLE BY 3 PLACES UNTIL THE PROPER PLACE IS REACHED
;
EXPTBL:
DEC HL ;BACK UP
DEC DE
LD A,(HL) ;COPY PREVIOUS BYTE INTO NEW TABLE LOCATION
LD (DE),A
LD A,L ;ARE WE AT ENTRY TO INSERT BEFORE?
CP C
JR NZ,EXPTBL ;CONTINUE IF NOT
LD A,H ;CHECK HIGH BYTES
CP B
JR NZ,EXPTBL
POP DE ;DE=NEW ENTRY ADDRESS, HL=ADDRESS TO INSERT AT
LD (HL),E ;PLACE NEW ENTRY ADDRESS INTO TABLE
INC HL
LD (HL),D
INC HL
LD A,(OPCTP) ;PLACE NEW ENTRY TYPE INTO TABLE
LD (HL),A
RET
;
; SEARCH CTL TBL FOR AN ENTRY FOR (DE)
; ON EXIT, HL PTS TO LOW-ORDER BYTE OF CONTROL TABLE ENTRY IF MATCHED
; OR LESS THAN
; MATCH: C=0
; NO MATCH: C=1
;
SCHCTL:
LD HL,CTLTBL ;PT TO TABLE
;
; IF NO MATCH THEN CARRY IS SET
;
SMORE:
LD A,(HL) ;GET LOW ADDRESS
INC HL ;PT TO HIGH
AND (HL) ;AND IN HIGH ADDRESS; IF ADDR=0FFFFH, THEN A=0FFH
DEC HL ;PT TO LOW ADDRESS
INC A ;IF A=0FFH BEFORE, NOW A=0
SCF ;SET CARRY FLAG FOR ERROR RETURN
RET Z ;RETURN IF A=0 (WE ARE AT END OF TABLE)
INC HL ;PT TO HIGH ADDRESS
LD A,D ;GET ADDRESS TO COMPARE AGAINST
CP (HL) ;DO COMPARE
DEC HL ;PT TO LOW ADDRESS
RET C ;RETURN IF ADDRESS IS LESS THAN TABLE ENTRY
JR NZ,NXTRY ;CONTINUE IF NOT THE SAME
LD A,E ;GET LOW ADDRESS
CP (HL) ;COMPARE TO LOW ADDRESS
RET Z ;CARRY IS OFF AND ZERO IS SET IF COMPLETE MATCH
RET C ;CARRY IS ON AND ZERO IS NOT SET IF TARGET IS LESS
;
; ADVANCE TO THE NEXT TABLE ENTRY
;
NXTRY:
INC HL ;PT TO HIGH ADDRESS
INC HL ;PT TO TYPE OF NEXT CONTROL ENTRY
INC HL ;PT TO LOW ADDRESS OF NEXT ENTRY IN TABLE
JR SMORE ;CONTINUE
;
; DUMP CONTROL TABLE FROM ADDRESS IN DE
;
CDUMP:
CALL SCHCTL ;FIND ENTRY IN CONTROL TABLE >= ADDRESS IN DE
JR CDUMP2
;
; DUMP ENTIRE CONTROL TABLE
;
CDUMP1:
LD HL,CTLTBL ;PT TO FIRST ENTRY IN CONTROL TABLE
CDUMP2:
CALL BRKCHK ;CHECK FOR ABORT
LD E,(HL) ;GET ADDRESS OF CONTROL ENTRY IN DE
INC HL
LD D,(HL)
INC HL
LD A,D ;CHECK FOR END OF TABLE
AND E ;END IF DE=0FFFFH
INC A ;SET A TO 0 IF SO
JR NZ,MOREDMP
CALL CRLF ;DONE, SO OUTPUT NEW LINE AND PRINT CONTROL INFO
CALL CTLST
JP GETCMD
;
; DUMP CONTROL TABLE ENTRY TO USER
;
MOREDMP:
PUSH DE
PUSH HL
CALL SYMSCH ;SEARCH FOR A SYMBOL WHOSE VALUE = ADDRESS IN DE
JR C,AHEAD ;SKIP IF NOT FOUND
;
; PRINT A SYMBOL SINCE IT WAS FOUND; SYMBOL PTED TO BY HL
;
CALL IECNT ;INIT ECNT
CALL CRLF ;NEW LINE
PRNTSYM:
LD A,(HL) ;OUTPUT CHARS OF SYMBOL
CALL COUT ;... COUNT IN B FROM SYMSCH
INC HL
DJNZ PRNTSYM
LD A,':' ;OUTPUT COLON AFTER SYMBOL
CALL COUT
;
; OUTPUT CONTROL TABLE ENTRY
;
AHEAD:
POP HL ;GET PTR TO CONTROL MODE
POP DE ;GET ADDRESS OF ENTRY
CALL SPACE ;2 <SP>S
CALL SPACE
EX DE,HL ;ADDRESS IN HL
CALL PVALUE ;PRINT VALUE OF ADDRESS
LD A,'=' ;PRINT DELIMITERS
CALL COUT
LD A,' '
CALL COUT
EX DE,HL ;RESTORE HL AS PTR TO CONTROL MODE
LD A,(HL) ;GET CONTROL MODE LETTER
CALL COUT ;PRINT IT
CALL SPACE ;<SP> OUT
CALL SPACE
CALL SPCRLF ;OUTPUT NEW LINE OCCASIONALLY
INC HL ;PT TO NEXT CONTROL TABLE ENTRY
JR CDUMP2
;
; SAVE THE CONTROL TABLE ON DISK
;
SVCTL:
CALL SVCTL0 ;USE ROUTINE
JP GETCMD
;
; ROUTINE TO SAVE THE CONTROL TABLE ON DISK
;
SVCTL0:
CALL OPEN ;OPEN FILE
LD HL,CTLTBL ;PT TO TABLE
SVCTL1:
LD E,(HL) ;GET ADDRESS IN DE
INC HL
LD D,(HL)
INC HL
LD A,D ;CHECK FOR END (0FFFFH)
AND E
INC A ;A=0 IF SO
JR Z,CTLSVED
CALL EXPND ;OUTPUT ADDRESS IN DE AS 4 HEX CHARS
LD A,',' ;OUTPUT COMMA
CALL WRTFILE
LD A,(HL) ;OUTPUT CONTROL MODE CHAR
CALL WRTFILE
LD A,0DH ;OUTPUT NEW LINE
CALL WRTFILE
LD A,0AH
CALL WRTFILE
INC HL ;PT TO NEXT CONTROL TABLE ENTRY
JR SVCTL1
;
; THE CONTROL TABLE HAS BEEN SAVED
;
CTLSVED:
LD A,1AH ;WRITE EOF
CALL WRTFILE
CALL NXTRCRD
RET
;
; READ IN A CONTROL TABLE
;
ISCTL:
CALL CTLRD ;READ CONTROL FILE
JP STAT ;PRINT STATISTICS
;
; ROUTINE TO READ IN A CONTROL TABLE
;
CTLRD:
CALL RDOPEN ;OPEN FILE FOR READING
LD HL,CTLTBL ;PT TO CONTROL TABLE
LUP:
CALL READMA ;READ NEXT CHAR
LD DE,0 ;SET VALUE = 0
NUMLUP:
CP 1AH ;ERROR IF EOF ENCOUNTERED
JR Z,TERMF
CP ',' ;DONE WITH NUMBER IF COMMA FOUND
JR Z,STRDE
CP '9'+1 ;CHECK FOR DIGIT
JR C,NUM ;PROCESS IF SO
SUB 7 ;ADJUST FOR 'A'-'F'
NUM:
SUB '0' ;CONVERT HEX ASCII TO BINARY
EX DE,HL ;VALUE IN HL
ADD HL,HL ;*2
ADD HL,HL ;*4
ADD HL,HL ;*8
ADD HL,HL ;*16
ADD A,L ;ADD IN NEW VALUE
LD L,A
EX DE,HL ;VALUE BACK IN DE
CALL READMA ;READ NEXT CHAR
JR NUMLUP ;CONTINUE
;
; STORE THE ADDRESS ACCUMULATED IN DE INTO THE CONTROL TABLE
;
STRDE:
LD (HL),E ;STORE ADDRESS
INC HL
LD (HL),D
INC HL
CALL READMA ;READ CONTROL MODE CHAR
LD (HL),A ;STORE IT
INC HL ;PT TO NEXT CONTROL TABLE ENTRY
JR LUP
;
; STORE ENDING 0FFFFH IN CONTROL TABLE
;
TERMF:
LD (HL),0FFH
INC HL
LD (HL),0FFH
RET
;
;COMMAND: ;
; COMMENT ROUTINE. IT ADDS OR LISTS COMMENTS
;
CMNT:
CALL AREACK ;VERIFY THAT COMMENT TABLE EXISTS
LD HL,INBUF+3 ;PT TO CHAR AFTER COMMAND
LD A,(HL) ;GET IT
CP 0DH ;DONE?
JP Z,LSTCMT ;YES, SO LIST COMMENTS
CP 'O' ;LOOK FOR 'ON/OFF' SWITCH
JR NZ,CMNT1
INC HL
LD A,(HL) ;SECOND CHARACTER OF THE COMMENT
SBC A,'F' ;CREATE A 0 FOR 'OFF'
JR Z,CMNT2
CP 'N'-'F' ;LOOK FOR AN 'N' (FOR 'ON')
JP NZ,WHAT
CMNT2:
LD (XCSW),A ;TURN OFF COMMENTS
JP GETCMD
;
; PROCESS NEW COMMENT ENTRY
;
CMNT1:
CALL CNVRT ;GET ADDRESS IN DE
INC HL ;PT TO NEXT CHAR
CP 0DH ;IF DONE, WE DELETE COMMENT
JP Z,ONECMT
CP ' ' ;<SP> OR ',' SAYS TEXT FOLLOWS
JR Z,CMNT0
CP ','
JP NZ,WHAT ;ERROR IF NOT <CR>, <SP>, OR ','
CMNT0:
PUSH HL ;SAVE PTR TO NEXT CHAR
CALL CMCHK ;CHECK FOR COMMENT ALREADY AT ADDRESS IN DE
JR C,ADDCMT ;IF NOT, JUST ADD COMMENT
CALL DELCMT ;IF SO, FIRST DELETE EXISTING COMMENT
;
; ADD COMMENT TO COMMENT TABLE
;
ADDCMT:
POP HL ;GET PTR
PUSH HL
LD A,(HL) ;CHECK FOR ANY TEXT
CP 0DH ;IF NONE, OLD COMMENT IS JUST DELETED
JP Z,GETCMD
LD HL,(COMEND) ;PT TO END OF COMMENT TABLE
LD (HL),E ;SAVE NEW ADDRESS OF COMMENT
INC HL
LD (HL),D
INC HL
POP DE ;PT TO FIRST CHAR OF COMMENT
LD B,0 ;INIT CHAR COUNT TO ZERO
PUSH HL ;SAVE ADDRESS TO CHAR COUNT OF COMMENT
;
; SAVE TEXT OF COMMENT
;
STRTXT:
INC HL ;PT TO POSITION TO STORE AT
LD A,(DE) ;GET COMMENT TEXT
LD (HL),A ;STORE IT
INC DE ;PT TO NEXT
INC B ;INCR CHAR COUNT
LD A,(DE) ;CHECK FOR DONE
CP 0DH ;DONE IF <CR>
JR NZ,STRTXT ;CONTINUE IF NOT <CR>
INC HL ;PT TO ADDRESS AFTER <CR>
LD (COMEND),HL ;SET PTR TO END OF COMMENT TABLE
LD (HL),0FFH ;STORE 0FFFFH AS NEXT ENTRY
INC HL
LD (HL),0FFH
POP HL ;GET PTR TO COMMENT CHAR COUNT
LD (HL),B ;SAVE CHAR COUNT
JP GETCMD
;
; CHECK FOR A COMMENT AT THE ADDRESS IN DE
; MATCH: CARRY IS OFF (NC CONDITION)
;
CMCHK:
LD HL,(COMST) ;PT TO START OF COMMENT TABLE
CMCHK1:
LD A,(HL) ;CHECK ADDRESS FOR 0FFFFH
INC HL
AND (HL)
DEC HL
INC A ;A=0 IF SO
SCF ;PREP FOR ERROR RETURN
RET Z ;NOT FOUND IF A=0
INC HL ;PT TO ADDRESS HIGH
LD A,D ;GET TARGET ADDRESS IN DE
CP (HL) ;COMPARE AGAINST THAT STORED
DEC HL ;PT TO ADDRESS LOW
JR NZ,NXTC ;IF NOT A MATCH, CONTINUE
LD A,E ;COMPARE LOW BYTES
CP (HL)
RET Z ;THERE IS A COMMENT AT THIS ADDRESS, SO CARRY=1
NXTC:
INC HL ;PT TO CHAR COUNT
INC HL
LD A,(HL) ;GET CHAR COUNT
CALL SKIP ;SKIP TO NEXT COMMENT
INC HL ;PT TO LOW BYTE OF NEXT COMMENT
JP CMCHK1
;
; DUMP COMMENT TABLE FROM A GIVEN ADDRESS FORWARD
;
ONECMT:
CALL CMCHK ;FIND COMMENT REFD IN DE
JR LSTAGN
;
; DUMP ENTIRE COMMENT TABLE
;
LSTCMT:
LD HL,(COMST) ;PT TO FIRST COMMENT
LSTAGN:
CALL BRKCHK ;CHECK FOR ABORT
LD E,(HL) ;GET ADDRESS OF COMMENT IN DE
INC HL
LD D,(HL)
INC HL
LD A,D ;CHECK FOR 0FFFFH AS END OF TABLE
AND E
INC A ;A=0 IF SO
JP Z,GETCMD ;DONE IF SO
EX DE,HL ;VALUE IN HL
CALL PVALUE ;PRINT IT
EX DE,HL ;VALUE IN DE, PTR TO COMMENT CHAR COUNT IN HL
LD A,';' ;PRINT SEMICOLON BEFORE COMMENT
CALL COUT
LD B,(HL) ;GET CHAR COUNT IN B
TEXT:
INC HL ;PT TO COMMENT CHAR
LD A,(HL) ;GET AND PRINT IT
CALL COUT
DJNZ TEXT ;CONTINUE UNTIL DONE
CALL CRLF ;NEW LINE
INC HL ;PT TO ADDRESS OF NEXT COMMENT
JR LSTAGN ;CONTINUE
;
; DELETE AN EXISTING COMMENT WHOSE ADDRESS IS IN DE; HL PTS TO CMT TABLE
;
DELCMT:
LD A,(HL) ;CHECK FOR END OF COMMENT TABLE
INC HL
AND (HL)
INC A ;A=0 IF AT END
RET Z
DEC HL ;PT TO ADDRESS IN CURRENT COMMENT
PUSH DE ;SAVE ADDRESS TO DELETE
LD D,H ;SAVE ADDRESS OF CURRENT COMMENT IN DE
LD E,L
INC HL ;PT TO CHAR COUNT OF CURRENT COMMENT
INC HL
LD A,(HL) ;GET IT IN A
CALL SKIP ;SKIP TO NEXT COMMENT
INC HL ;PT TO ITS ADDRESS
LD B,0 ;INIT TO NOT DONE FOR LOOP
;
; COPY (HL) TO (DE) UNTIL FFFFH IS ENCOUNTERED
;
SHFTCT:
LD A,(HL) ;GET CHAR
LD (DE),A ;PUT CHAR
INC HL ;PT TO NEXT
INC DE
LD C,A ;DONE IF BC=0FFFFH
AND B
INC A ;A=0 IF DONE
LD B,C
JR NZ,SHFTCT ;CONTINUE UNTIL TWO SUCCESSIVE FF'S FOUND
EX DE,HL ;SET END OF COMMENT TABLE
DEC HL
DEC HL
LD (COMEND),HL
POP DE
RET
;
; CHECK TO SEE THAT AREA FOR COMMENTS WAS DEFINED (START <> 0) AND
; ABORT WITH ERROR MESSAGE IF NOT
;
AREACK:
LD HL,(COMST) ;HL=START ADDRESS
LD A,H
OR L
RET NZ ;ERROR IF ZERO
CALL PSTRNG
DEFB '++ COMMAND IGNORED ++',0DH
DEFB 0AH,'++ Issue ''UNNNN'' to tell '
DEFB 'DASM to use address '
DEFB 'NNNN',0DH,0AH,'as the start '
DEFB 'of the comments table ++',0DH
DEFB 0AH,0
JP GETCMD
;
;COMMAND: U
; DEFINE THE COMMENTS AREA
;
UAREA:
LD HL,INBUF+3 ;CHECK ARGS
LD A,(HL)
CP 0DH ;ERROR IF JUST <CR>
JP Z,WHAT
CP '.' ;ERROR IF SYMBOL
JP Z,WHAT
CALL CNVRT ;CONVERT TO NUMBER IN DE
EX DE,HL ;... IN HL
LD A,H ;CHECK FOR WITHIN RANGE
CP (SYMTAB+600H) SHR 8 ;THIS ALLOWS 600H BYTES FOR SYM TBL
JR C,UAREA0 ;ERROR IF LESS
LD (COMST),HL ;SET START AND END OF TABLE
LD (COMEND),HL
LD (HL),0FFH ;SET ENDING 0FFFFH IN TABLE
INC HL
LD (HL),0FFH
JP GETCMD
UAREA0:
CALL PSTRNG ;PRINT ERROR MESSAGE
DEFB 'NO!! Address is less than '
DEFB 0
LD HL,SYMTAB+600H
LD L,0
CALL PVALUE
CALL CRLF
JP GETCMD
;
; HANDLE SYMBOLS FOR THE DISASSEMBLER; ADDRESS IN PC
; IF A SYMBOL EXISTS AT THIS ADDRESS, PRINT IT
;
HSYM:
PUSH DE
PUSH HL
LD A,1 ;ENABLE DISK OUTPUT
LD (WRTENAB),A
LD HL,(PC) ;GET ADDRESS OF PC
EX DE,HL ;... IN DE
CALL SYMSCH ;LOOK FOR SYMBOL
JP C,RESUME ;GOTO RESUME IF NO SYMBOL
LD C,B ;GET CHAR COUNT OF SYMBOL INTO C
PUSH HL ;SAVE PTR TO IT
;
; CHECK TO SEE THAT SYMBOL CONTAINS NO + OR -; DON'T PRINT IF IT DOES
;
HSYM0:
LD A,(HL) ;GET CHAR
CP '+' ;CHECK IT
JR Z,HSYM1
CP '-'
JR Z,HSYM1
INC HL ;PT TO NEXT
DEC C ;CONTINUE TO END OF SYMBOL
JR NZ,HSYM0
POP HL ;PT TO SYMBOL
CALL PRNT ;PRINT THE SYMBOL
LD A,':' ;.. AND A FOLLOWING COLON
CALL COUT
CALL TAB ;PRINT THE TAB
CALL PDERTN ;PRINT THE ADDRESS AS A COMMENT (ADR IN DE)
CALL CRLF ;NEW LINE
JR RESUME ;CONTINUE
HSYM1:
POP HL
RESUME:
XOR A ;PRINT ADDRESS OF PC ON CRT
LD (WRTENAB),A ;.. BUT NOT INTO THE FILE
CALL SPACE ;<SP> OVER
CALL SPACE
LD HL,(PC) ;PRINT PC VALUE
CALL PVALUE
LD A,1 ;REENABLE WRITE OF MNEMONIC
LD (WRTENAB),A
CALL TAB ;TAB FOR FOLLOWING MNEMONIC
POP HL
POP DE
RET
;
; BUILD A SYMBOL IN INBUF FOR THE VALUE IN DE
;
BLDSYM:
LD HL,INBUF ;PT TO INBUF
LD (HL),'L' ;STORE LEADING L
INC HL ;PT TO NEXT CHAR
LD A,D ;GET VALUE IN DE
CALL ACCTOASC ;STORE AS ASCII CHARS IN BUFFER
LD A,E
CALL ACCTOASC
LD HL,INBUF ;PT TO SYMBOL
LD B,5 ;SYMBOL IS 5 CHARS LONG
;
; INSERT A SYMBOL ALPHABETICALLY INTO TABLE
;
INSERT:
CALL PLCSYM ;FIND SYMBOL
JR C,NEWSYM ;PROCESS AS NEW IF NOT FOUND
LD (HL),E ;IF FOUND, SET NEW ADDRESS FOR IT
INC HL
LD (HL),D
RET
;
; INSERT NEW SYMBOL INTO TABLE; LOCATION TO INSERT AT PTED TO BY HL
;
NEWSYM:
PUSH HL
PUSH DE
PUSH BC
LD HL,(SYMEND) ;MOVE THE TABLE BY LENGTH+3
LD D,H ;DE PTS TO END OF SYMBOL TABLE
LD E,L
LD A,B ;LENGTH OF SYMBOL IN A
ADD A,3 ;LENGTH OF SYMBOL + 3
ADD A,L ;PT TO NEW END OF TABLE
LD L,A
LD A,H
ADC A,0
LD H,A
LD (SYMEND),HL ;NEW END OF SYMBOL TABLE
INC HL ;PT TO LENGTH OF SYMBOL AFTER LAST ONE
INC HL
LD (HL),0 ;SET THIS TO ZERO TO MARK END OF TABLE
DEC HL
DEC HL
LD B,H ;ADDRESS OF LAST BYTE IN BC
LD C,L
LD HL,(SYMRKR) ;ADDRESS OF REV DEST TO MOVE TO IN HL
;
; EXPAND THE TABLE UNTIL SPACE IS MADE AT THE NEW SPOT
;
LUP3:
LD A,E ;AT DESTINATION?
CP L
JR NZ,AHD
LD A,D
CP H
JR Z,STICKAD ;DONE IF SO
AHD:
DEC DE ;COPY BACKWARDS (DE) TO (BC)
DEC BC
LD A,(DE)
LD (BC),A
JR LUP3
;
; ENTER THE ADDRESS AND LENGTH
;
STICKAD:
POP BC
POP DE
LD (HL),E ;STORE ADDRESS OF SYMBOL
INC HL
LD (HL),D
INC HL
LD (HL),B ;STORE LENGTH OF SYMBOL
POP DE
;
; STORE THE SYMBOL STRING
;
STICKSM:
INC HL
LD A,(DE)
LD (HL),A
INC DE
DJNZ STICKSM
RET
;
; FIND SPOT FOR NEW SYMBOL PTED TO BY HL, VALUE IN DE, B=LENGTH OF SYMBOL
; RETURN: C=0 FOR MTCH, HL=SYMBOL
;
PLCSYM:
PUSH DE ;SAVE VALUE
PUSH HL ;SAVE ADDRESS OF SYMBOL
LD HL,SYMTAB ;PT TO SYMBOL TABLE
ANTHR:
POP DE ;GET SYMBOL ADDRESS IN DE
PUSH DE
INC HL ;PT TO SYMBOL CHAR COUNT
INC HL
PUSH HL
LD A,(HL) ;GET CHAR COUNT
INC HL ;PT TO FIRST CHAR
OR A ;CHECK FOR END OF SYMBOL TABLE
JR Z,NONE ;GOTO NONE IF AT END OF TABLE
CP B ;COMPARE SYMBOL LENGTHS
JR C,LESS ;NO MATCH IF NOT SAME LENGTH
JR NZ,NTLESS
LD C,A ;SYMBOL LENGTH IN C
CALL CHKSTG ;COMPARE (DE) TO (HL)
JR Z,FOUND
JR C,NONE
;
; TARGET SYMBOL GOES BEHIND CURRENT SYMBOL
;
LATER:
POP HL ;GET ADDRESS OF SYMBOL TABLE SYMBOL
LD A,(HL)
INC HL
CALL SKIP ;SKIP TO NEXT
JR ANTHR
;
; MATCH OF SYMBOLS
;
FOUND:
POP HL
DEC HL
DEC HL
POP DE
POP DE
OR A ;RET WITH CARRY CLEAR FOR MATCH
RET
;
; CHECK SHORTER STRING FOR PARTIAL MATCH
;
LESS:
LD C,A
CALL CHKSTG
JR NC,LATER
JR NONE
NTLESS:
LD C,B
CALL CHKSTG
JR Z,NONE
JR NC,LATER
;
; THERE IS NO SYMBOL FOR THIS VALUE, SO THIS VALUE SHOULD GO AT HL
;
NONE:
POP HL
DEC HL
DEC HL
LD (SYMRKR),HL ;SET MARKER
POP HL
POP DE
SCF ;SET CARRY FOR NO MATCH
RET
;
; SEARCH THE SYMBOL TABLE FOR AN ENTRY WHOSE VALUE IS DE
; MATCH: C=0
;
SYMSCH:
LD HL,SYMTAB ;PT TO SYMBOL TABLE
;
; (HL) IS START OF SYMBOL; (B) IS LENGTH
;
MORE:
LD A,(HL) ;GET AND COMPARE SYMBOL TABLE VALUES
INC HL
CP E
JR NZ,SKPOVR
LD A,(HL)
CP D
JR Z,FNDSYM
;
; GOTO NEXT SYMBOL
;
SKPOVR:
INC HL ;CHECK CHAR COUNT FOR DONE
LD A,(HL) ;0 IF DONE
OR A
SCF ;SET CARRY FOR NO MATCH IF SO
RET Z
INC HL ;PT TO NEXT SYMBOL
ADD A,L
LD L,A
JR NC,MORE
INC H
JR MORE
;
; RETURN WITH NO CARRY AND LENGTH IN B IF MATCHED
;
FNDSYM:
INC HL
LD A,(HL)
INC HL
LD B,A
OR A ;MATCH
RET NZ
SCF ;NO MATCH
RET
;
;COMMAND: E
; PLACE A SYMBOL IN THE SYMBOL TABLE
;
ENTER:
LD HL,INBUF+3 ;CHECK FOR CHARS AFTER THE E
CALL CNVRT ;GET VALUE
LD A,(HL) ;CHECK FOR ERROR
CP ' ' ;MUST BE FOLLOWED BY <SP> OR ','
JR Z,ENTER0
CP ','
JP NZ,WHAT
;
; GET SYMBOL
;
ENTER0:
INC HL ;PT TO SYMBOL
LD A,(HL) ;GET '.'
CP '.' ;MUST BE '.'
JP NZ,WHAT
PUSH DE ;SAVE THE SYMBOL'S VALUE
PUSH HL ;SAVE THE BUFFER PTR
CALL SYMSCH ;RETURN WITH C=0 FOR MATCH
;.. B=LENGTH HL=START OF STRING
JR C,ENTER1 ;NOTHING TO DELETE
PUSH HL
CALL CRLF ;PRINT MESSAGE THAT SYMBOL WAS KILLED
CALL PRNT
CALL PSTRNG
DEFB ' was Killed',0DH,0AH,0
POP HL
DEC HL
DEC HL
DEC HL
CALL KILL0 ;KILL SYMBOL
ENTER1:
POP HL
PUSH HL
CALL LNGTH ;COMPUTE LENGTH OF SYMBOL IN B
POP DE
LD A,B ;CHECK FOR SYMBOL TOO LONG
CP SYMMAX+1
JR C,ENTER2
PUSH HL
LD BC,SYMMAX ;SET TO MAX LENGTH
LD H,D ;HL=DE
LD L,E
INC HL ;ADD 1 FOR 1ST CHAR
ADD HL,BC
LD (HL),0 ;TERMINATE SYMBOL
LD B,C ;B=SYMMAX
POP HL
ENTER2:
POP DE
CALL INSERT ;INSERT SYMBOL INTO SYMBOL TABLE
JP GETCMD
;
;COMMAND: K
; DELETE A SYMBOL FROM THE TABLE
;
KILL:
LD HL,INBUF+3 ;CHECK FOR SYMBOL SPECIFIED
LD A,(HL) ;MUST BE '.'
CP '.'
JP NZ,WHAT
CALL LNGTH ;GET LENGTH IN B
CALL PLCSYM ;FIND SYMBOL PTED TO BY HL
JP C,WHAT ;ERROR IF NOT FOUND
CALL KILL0 ;KILL IT
JP GETCMD
;
; KILL THE SYMBOL WHOSE VALUE IS PTED TO BY HL
;
KILL0:
LD B,H ;SAVE PTR IN BC
LD C,L
INC HL
INC HL
LD A,(HL) ;GET THE LENGTH OF THE SYMBOL
INC HL
CALL SKIP ;SKIP TO NEXT
EX DE,HL ;DE PTS TO NEXT SYMBOL
LD HL,(SYMEND) ;SHIFT THE SYMBOL TABLE DOWN TO DELETE SYM
LUP4:
LD A,E ;SHIFT COMPLETE?
CP L
JR NZ,AHD1
LD A,D
CP H
JR Z,DEAD
AHD1:
LD A,(DE) ;COPY DOWN
LD (BC),A
INC BC
INC DE
JR LUP4
;
; THE SYMBOL IS DEAD -- SET NEW END OF SYMBOL TABLE
;
DEAD:
LD H,B
LD L,C
LD (SYMEND),HL ;SET END
INC HL
INC HL
LD (HL),0 ;SET END OF TABLE MARKER
RET
;
; SCAN SYMBOL STARTING AT (HL) AND RETURN WITH LENGTH IN B, PTR TO FIRST
; CHAR OF SYMBOL IN HL, AND PTR TO CHAR AFTER LAST CHAR IN SYMBOL IN DE
;
LNGTH:
INC HL ;PT TO FIRST CHAR
LD B,0 ;INIT LENGTH
PUSH HL
CHAROK:
LD A,(HL) ;GET CHAR
INC HL ;PT TO NEXT
INC B ;INCR LENGTH
CP '+' ;CHECK FOR END OF SYMBOL MARK
JR Z,CHAROK
CP '-'
JR Z,CHAROK
CP '0'
JR C,ILLSYM
CP '9'+1
JR C,CHAROK
CP 'A'
JR C,ILLSYM
CP 'Z'+1
JR C,CHAROK
;
; AN ILLEGAL CHARACTER FOUND IN A SYMBOL SCAN, SO SCAN IS DONE
;
ILLSYM:
DEC B ;COMPENSATE FOR COUNT
JP Z,WHAT ;ERROR IF NO SYMBOL CHARS
DEC HL ;BACK UP
EX DE,HL ;PTR TO NEXT CHAR IN DE
POP HL ;PT TO FIRST CHAR IN HL
RET
;
; CONVERT THE ACCUMULATOR TO HEX ASCII IN MEMORY PTED TO BY HL (2 BYTES)
;
ACCTOASC:
PUSH AF
CALL HINIB ;CONVERT HIGH NYBBLE
LD (HL),A ;STORE IT
INC HL ;PT TO NEXT
POP AF
CALL LONIB ;CONVERT LOW NYBBLE
LD (HL),A ;STORE IT
INC HL ;PT TO NEXT
RET
;
; CONVERT THE HIGH NIBBLE OF A TO ASCII CHAR
;
HINIB:
RRA ;ROTATE HIGH NYBBLE TO LOW NYBBLE
RRA
RRA
RRA
;
; CONVERT THE LOW NYBBLE OF A TO ASCII CHAR
;
LONIB:
AND 0FH ;MASK OUT NEW HIGH NYBBLE
CP 10 ;CHECK FOR DIGIT
JR C,AHD2 ;SKIP IF SO
ADD A,7 ;ADD OFFSET OF 7 FOR '9' TO 'A'
AHD2:
ADD A,'0' ;CONVERT TO ASCII IN A
RET
;
; PRINT THE HEX CHARACTERS FOR THE VALUE IN A
;
PHEX:
PUSH AF
CALL HINIB ;PRINT HIGH NYBBLE
CALL COUT
POP AF
CALL LONIB ;PRINT LOW NYBBLE
JP COUT
;
; PRINT THE 4 HEX CHARACTERS FOR CONTENTS OF HL
;
PVALUE:
LD A,H ;PRINT HIGH BYTE
CALL PHEX
LD A,L ;PRINT LOW BYTE
CALL PHEX
;
; PRINT A <SP>
;
SPACE:
LD A,' ' ;PRINT <SP>
JP COUT
;
; READ HEX ASCII FROM COMMAND LINE AND CONVERT AND PLACE IN (DE)
;
CNVRT:
LD A,(HL) ;GET FIRST CHAR
CP '.' ;IT IS A SYMBOL IF '.'
JR Z,ITSASYM
LD DE,0 ;INIT VALUE TO ZERO
AGAIN:
LD A,(HL) ;GET CHAR
CP '0' ;IN RANGE?
RET C ;DONE IF NOT
CP '9'+1 ;RANGE?
JR C,NUMER ;OK IF SO
CP 'A' ;RANGE?
RET C ;DONE IF NOT
CP 'F'+1 ;RANGE?
RET NC ;DONE IF NOT
SUB 7 ;CONVERT FOR 'A'-'F'
NUMER:
SUB '0' ;CONVERT FROM ASCII TO BINARY
EX DE,HL ;HL=VALUE
ADD HL,HL ;*2
ADD HL,HL ;*4
ADD HL,HL ;*8
ADD HL,HL ;*16
ADD A,L ;ADD IN NEW NYBBLE
LD L,A
EX DE,HL ;DE=VALUE
INC HL ;PT TO NEXT CHAR
JR AGAIN ;CONTINUE
;
; EVALUATE THE SYMBOL IN MEMORY AND RETURN WITH VALUE IN DE
;
ITSASYM:
CALL LNGTH ;DETERMINE LENGTH OF SYMBOL
PUSH DE
CALL PLCSYM ;FIND IT IN TABLE
JP C,WHAT ;ERROR IF NOT FOUND
LD E,(HL) ;PUT ITS VALUE IN DE
INC HL
LD D,(HL)
POP HL
LD A,(HL)
RET
;
; OPEN A FILE FOR READING
;
RDOPEN:
PUSH HL
LD HL,0100H ;SET DMA TO 100H
LD (DMAPTR),HL
XOR A ;SET NEXT RECORD FIELD TO 0
LD (FCBNR),A
LD DE,FCB ;PT TO FCB
LD C,0FH ;OPEN THE FILE
CALL BDOS
POP HL
INC A ;FILE FOUND?
RET NZ ;RET IF SO
CALL PSTRNG ;ERROR IF NOT
DEFB ' File Not Found',0DH,0AH,0
EX (SP),HL ;SAVE HL ON STACK
POP HL ;RESTORE HL
RET
; JP GETCMD ;OLD ERROR RETURN
;
; READ NEXT BYTE FROM DMA BUFFER AND RETURN IT IN A
;
READMA:
PUSH HL ;SAVE HL
LD HL,(DMAPTR) ;PT TO NEXT BYTE
LD A,H ;BEYOND END OF BUFFER?
CP 1 ;1 IF SO
JR NZ,NOTREAD ;IF NOT, THEN GET THE BYTE
PUSH BC ;SAVE BC, DE
PUSH DE
LD DE,FCB ;PT TO FCB
LD C,14H ;READ RECORD INTO DMA ADDRESS
CALL BDOS
OR A ;SET FLAG FOR ERROR
POP DE ;RESTORE REGS
POP BC
LD HL,RECLEN ;PT TO FIRST BYTE OF BUFFER
JR NZ,ERROR ;ERROR IF EOF ENCOUNTERED
NOTREAD:
LD A,(HL) ;GET NEXT CHAR IN A
INC HL ;PT TO CHAR AFTER
LD (DMAPTR),HL ;SET PTR FOR LATER USE
POP HL ;RESTORE HL
RET
ERROR:
CP 3
JR C,RDDMA0
CALL PSTRNG
DEFB '++ Unexpected EOF ++',0DH,0AH
DEFB 0
JP GETCMD
;
; AT EOF ... SET ^Z AS RESPONSE CHAR FROM READ
;
RDDMA0:
LD A,1AH
LD (HL),A
JR NOTREAD
;
; OPEN FILE PTED TO BY FCB FOR OUTPUT
;
OPEN:
PUSH HL
LD DE,FCB ;ERASE IT FIRST
LD C,13H
CALL BDOS
LD DE,FCB ;NOW CREATE IT
LD C,16H
CALL BDOS
INC A ;ERROR IN CREATING IT?
JP Z,WHAT ;SAY SO (NO ROOM IN DIR)
XOR A ;SET RECORD FIELD TO ZERO
LD (FCBNR),A
LD HL,RECLEN ;SET DMA ADDRESS
LD (DMAPTR),HL
POP HL
RET
;
; WRITE THE NEXT RECORD TO OPEN FILE
;
NXTRCRD:
LD DE,FCB ;WRITE IT
LD C,15H
CALL BDOS
OR A ;ERROR?
JR NZ,WRTERR
LD DE,FCB ;CLOSE THE FILE
LD C,10H
CALL BDOS
INC A ;ERROR IN CLOSING?
RET NZ
CALL PSTRNG ;SAY SO IF SO
DEFB '++ Close Error ++',0DH,0AH,0
JP GETCMD
;
; AN ERROR OCCURRED DURING A WRITE RECORD ATTEMPT
;
WRTERR:
CALL PSTRNG
DEFB '++ Write Error ++',0DH,0AH,0
;
; WRITE INTO THE DMA BUFFER AND WRITE TO DISK WHEN IT FILLS
; CHAR TO WRITE PASSED IN A
;
WRTFILE:
PUSH HL
LD HL,(DMAPTR) ;GET PTR
LD (HL),A ;STORE NEXT CHAR
INC L ;PT TO NEXT
LD (DMAPTR),HL ;SET NEXT DMA
POP HL
RET NZ ;IF L REACHED ZERO, BUFFER WAS FULL; RET IF NZ
PUSH BC ;WRITE RECORD TO DISK AND REINIT DMA PTR
PUSH DE
PUSH HL
LD DE,FCB ;DO THE WRITE
LD C,15H
CALL BDOS
OR A ;ERROR?
JR NZ,WRTERR
LD HL,RECLEN ;RESET DMA PTR
LD (DMAPTR),HL
POP HL
POP DE
POP BC
RET
;
; PRINT COMMENT IF PTED TO BY XCPTR
;
DCRLF:
LD HL,(XCPTR)
LD A,H
OR L ;LOOK FOR A COMMENT ADDRESS
JR Z,DCRLF3
CALL TAB ;TABULATE COMMENT
LD B,(HL) ;GET CHAR COUNT
XOR A ;CHECK FOR NO COMMENT
OR B
JR Z,DCRLF2
DCRLF1:
INC HL ;OUTPUT COMMENT
LD A,(HL)
CALL COUT
DJNZ DCRLF1
DCRLF2:
LD HL,0 ;SET NO COMMENT NOW
LD (XCPTR),HL
DCRLF3:
LD (RPLPTR),HL ;SET RPLPTR=0
;
; OUTPUT <CR> <LF>
;
CRLF:
LD A,0DH
CALL COUT
LD A,0AH
JP COUT
;
; PRINT THE PROMPT
;
PRTSTAR:
LD A,'*'
;
; PRINT THE CHARACTER IN A ON CON: AND/OR DISK
; THE FOLLOWING FLAGS TAKE EFFECT:
; HUSH (QUIET MODE) -- IF =0, CON: OUTPUT, ELSE NO CON: OUTPUT
; FOPEN (FILE OPEN) AND WRTENAB (WRITE ENABLE) -- IF BOTH <>0, DISK
; OUTPUT
; CNTENAB (COUNT ENABLE) -- IF <>0, ENABLE <LF> COUNT (LCTR)
;
COUT:
PUSH AF ;SAVE REGS
PUSH BC
PUSH DE
PUSH HL
LD E,A ;CHAR IN E
PUSH DE ;PREP TO PRINT CHAR
LD C,2 ;USE BDOS OUTPUT
LD A,(HUSH) ;QUIET MODE?
OR A ;0=YES
CALL Z,BDOS ;PRINT THE CHAR IF NOT QUIET MODE
POP DE
LD A,(FOPEN) ;GET FILE OPEN FLAG
LD HL,WRTENAB ;PT TO FILE WRITE ENABLED FLAG
AND (HL) ;IF BOTH ENABLED, WRITE CHAR TO DISK ALSO
LD A,E ;CHAR IN A, NOT ZERO FLAG = DISK OUTPUT
CALL NZ,WRTFILE ;WRITE TO DISK IF OK
LD A,E ;CHECK FOR <LF>
CP 0AH
JR NZ,COUT1
LD A,(CNTENAB) ;DECREMENT THE LINE COUNT IF A <LF> WAS SENT
OR A ;CHECK IF COUNTING ENABLED
JR Z,COUT1
LD HL,LCTR ;PT TO LINE COUNT
DEC (HL) ;DECREMENT IT
COUT1:
POP HL ;RESTORE REGS AND EXIT
POP DE
POP BC
POP AF
RET
;
; PROMPT AND READ A COMMAND LINE FROM THE KEYBOARD
;
PROMPT:
CALL PRTSTAR ;PRINT PROMPT
LD DE,INBUF ;PT TO INPUT LINE BUFFER
LD A,80 ;SET BUFFER SIZE
LD (DE),A
LD C,10 ;READ INTO BUFFER FCT
CALL BDOS
LD HL,INBUF+1 ;PT TO CHAR COUNT READ
LD E,(HL) ;GET IT IN DE
LD D,0
ADD HL,DE ;PT TO AFTER LAST CHAR IN BUFFER
INC HL
LD (HL),0DH ;STORE ENDING <CR>
LD HL,INBUF+1 ;PT TO CHAR COUNT OF BUFFER
;
; CONVERT TO UPPER CASE
;
UPPR:
INC HL ;PT TO NEXT CHAR
LD A,(HL) ;GET IT
CP 0DH ;DONE?
JP Z,CRLF
CP 61H ;SMALL A?
JR C,UPPR ;OK IF LESS
CP 7BH ;SMALL Z + 1?
JR NC,UPPR ;OK IF MORE
AND 5FH ;CAPITALIZE
LD (HL),A ;PUT CHAR
JR UPPR ;CONTINUE
;
; PRINT THE STRING: ADDR AT TOP OF STACK, TERMINATED BY 0
;
PSTRNG:
XOR A ;DISABLE QUIET MODE AND DISK OUTPUT
LD (WRTENAB),A
LD (HUSH),A
PSTG:
EX (SP),HL ;PT TO STRING IN HL AND SAVE OLD HL
LUP5:
LD A,(HL) ;OUTPUT CHARS
CALL COUT
INC HL ;PT TO NEXT
LD A,(HL) ;GET NEXT CHAR
OR A ;DONE?
JR NZ,LUP5
INC HL ;PT TO AFTER STRING
EX (SP),HL ;RESTORE HL AND SET NEW RET ADR
RET
;
; INITIALIZE SPECIAL CONSTANTS SO CODE IS REENTRANT
;
INIT0:
LD A,IBUFLEN ;SIZE OF INPUT LINE BUFFER
LD (INBUF),A
LD A,INITDLEN-1 ;INITIAL SIZE OF MEMORY DUMP
LD (DMPLEN),A
LD A,INITLCNT ;INITIAL SIZE OF LIST DISPLAY
LD (NLINES),A
LD (LCTR),A
LD HL,BLNGTH ;INITIAL CTL PTR
LD (NXTCTL),HL
LD HL,INITPC ;INITIAL VALUE OF PC
LD (DMPSTRT),HL
LD (DMPEND),HL
LD (PC),HL
LD HL,INITOFF ;INITIAL OFFSET
LD (OFFSET),HL
LD HL,INITELST ;INITIAL END OF LISTING VALUE
LD (ENDLST),HL
LD HL,COMTBL ;INITIAL POSITION OF COMMENTS
LD (COMST),HL
LD (COMEND),HL
RET
;
; INITIALIZE SYMBOL TABLE, CONTROL TABLE, AND COMMENTS TABLE
; SET EOL
;
INIT:
XOR A ;A=0
LD (SYMTAB+2),A ;CLEAR SYMBOL TABLE BY SET CHAR COUNT OF
LD HL,SYMTAB ;... FIRST ENTRY TO ZERO
LD (SYMEND),HL ;SET END ADDRESS OF SYMBOL TABLE
LD A,0DH ;SET END OF INPUT LINE
LD (INBUF+3),A
LD HL,0FFFFH ;SET NO ENTRIES IN CONTROL TABLE
LD (CTLTBL),HL
LD A,'I' ;SET FOR INSTRUCTION MODE INITIALLY
LD (CTLTBL-1),A ;"PREVIOUS" CONTROL TABLE ENTRY IS SET TO 'I'
LD HL,COMTBL ;SET ADDRESS OF COMMENT TABLE
LD (COMST),HL ;START ADDRESS
LD (COMEND),HL ;END ADDRESS
LD (HL),0FFH ;CLEAR FIRST ENTRY TO NO COMMENT
INC HL
LD (HL),0FFH
RET
;
; RETURN WITH ZERO IF STRINGS (DE) AND (HL) MATCH; LENGTH IS (C)
;
CHKSTG:
LD A,(DE) ;GET CHAR
CP (HL) ;COMPARE
RET NZ ;NO MATCH
INC DE ;PT TO NEXT
INC HL
DEC C ;COUNT DOWN
JR NZ,CHKSTG
RET
;
; WATCH THE CONSOLE FOR A BREAK KEY AND ABORT IF SO
;
BRKCHK:
PUSH BC
PUSH DE
PUSH HL
LD C,0BH ;CHECK FOR KEY PRESS
CALL BDOS
OR A ;NONE IF ZERO
JR Z,AHD3
LD C,1 ;GET NEW CHAR
CALL BDOS
CP 3 ;CHECK FOR ^C
JR Z,ABORT ;ABORT IF SO
CALL CRLF ;ELSE NEW LINE
JP GETCMD
ABORT:
CALL PSTRNG ;PROMPT USER
DEFB 0DH,0AH,'Abort (Y/N)? ',0
CALL CHIN
CP 'Y'
JP Z,WBOOT
JP GETCMD
AHD3:
POP HL
POP DE
POP BC
RET
;
; CHECK FOR AN ASCII CHARACTER IN A
; RETURN WITH ZERO TRUE AND NO CARRY FOR <CR>, <LF>
; RETURN WITH NO CARRY IF PRINTABLE ASCII
;
ISITASC:
CP 0DH
RET Z ;NO CARRY
CP 0AH
RET Z ;NO CARRY
CP ' '
RET C ;CARRY IF < <SP>
CP 7FH
CCF ;CARRY IF > 7FH
RET
;
; FILE TYPES
;
TPALL:
DEFB 'ALL' ;FILE TYPE FOR ALL (CTL, SYM, DOC, COM, AND ASM) FILES
TPASM:
DEFB 'ASM' ;ASM FILE TYPE
TPCOM:
DEFB 'COM' ;COM FILE TYPE
TPCTL:
DEFB 'CTL' ;CTL FILE TYPE
TPSYM:
DEFB 'SYM' ;SYM FILE TYPE
TPDOC:
DEFB 'DOC' ;DOC FILE TYPE
DEFB '.'
;
; BUFFERS
;
RELEND:
DEFS 2 ;RELATIVE END ADDRESS OF COM FILE
DMPSTRT:
DEFS 2 ;STARTING ADDRESS OF DUMP (CURRENT ADDR ALSO)
DMPEND:
DEFS 2 ;ENDING ADDRESS OF DUMP
DMPLEN:
DEFS 2 ;NUMBER OF BYTES TO DUMP AT ONE TIME - 1
OFFSET:
DEFS 2 ;OFFSET VALUE
SYMEND:
DEFS 2 ;END OF SYMBOL TABLE
PC:
DEFS 2 ;CURRENT VALUE OF PC
ENDLST:
DEFS 2 ;END OF LISTING PTR
BIASED:
DEFS 2 ;BIASED OFFSET
COMST:
DEFS 2 ;START ADDRESS OF COMMENTS
COMEND:
DEFS 2 ;END ADDRESS OF COMMENTS
ADB:
DEFS 1 ;FLAG FOR DB BUILD (0=HEX, <>0=ASCII AND HEX)
FNDPC:
DEFS 2 ;TEMP PC FOR FIND FUNCTION
FNDADD:
DEFS 2 ;TEMP ADDRESS FOR FIND FUNCTION
ECNT:
DEFS 1 ;TEMP LINE COUNTER
NLINES:
DEFS 1 ;NUMBER OF LINES FOR LIST
LCTR:
DEFS 1 ;COUNTER FOR LINES
CNTENAB:
DEFS 1 ;ENABLE LINE COUNT IF <> 0, ELSE DISABLE LINE CNT
WRTENAB:
DEFS 1 ;OUTPUT TO FILE IS ENABLED IF <> 0, NOT IF 0
RPLPTR:
DEFS 2 ;MISC PTR
XCPTR:
DEFS 2 ;MISC PTR
XCSW:
DEFS 1 ;MISC PTR
FOPEN:
DEFS 1 ;FILE IS OPEN IF <> 0, NOT OPEN IF 0
HUSH:
DEFS 1 ;DON'T PRINT COMMAND RESULT (QUIET MODE) IF 0
NXTCTL:
DEFS 2 ;PTR TO NEXT CTL ENTRY
BLNGTH:
DEFS 1 ;BUFFER LENGTH
SYMRKR:
DEFS 2 ;SYMBOL MARKER
DMAPTR:
DEFS 2 ;PT TO DMA ADDRESS
ASCBLD:
DEFS 1 ;FLAG FOR A COMMAND (0=NOT A)
BUILD:
DEFS 1 ;FLAG FOR B COMMAND (0=NOT B)
OPCTP:
DEFS 3
;
; INPUT LINE BUFFER
;
INBUF:
DEFS 1 ;SIZE OF BUFFER
DEFS IBUFLEN+1 ;SIZE OF INPUT LINE AND BUFFER CONTENTS
;
; STACK AREA
;
DEFS 40 ;STACK SPACE
OLDST:
DEFS 2 ;OLD STACK PTR
;
DEFS 1 ;1 BYTE FOR INITIAL 'I' IN CONTROL TABLE
;
; NEXT PAGE AFTER PROGRAM MARKS BEGINNING OF BUFFER AREAS
;
ORG $/100H*100H+100H
ENDALL EQU $
END