home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
cpm
/
utils
/
asmutl
/
xlt86.lbr
/
XLT86.AQ6
/
XLT86.A86
Wrap
Text File
|
1985-09-16
|
48KB
|
3,147 lines
;*******************************************************
;
; XLT86
;
; Translates Intel 8080 assembly language source code
; to Intel 8086 assembly language source code.
;
; 11/11/84 Frank J. Zerilli
;
; 8086 version, 11/20/84
;
VERS EQU 105
;
;*******************************************************
;
; XLT86 processes lines with the exclamation point
; statement separator correctly. It strips trailing
; blanks or tabs from lines. It replaces initial
; asterisks in lines with semicolons. It provides
; several options to format the output file for best
; appearance.
;
; This program gives the choice of converting the
; case of instructions to upper or lower case or of
; trying to preserve the case of instructions.
;
; An activity dot is printed on the console for
; every 100 lines of input processed.
;
;
;
; Command line:
;
; XLT86 [d:]srcfile[.typ] [d:destfile.typ]
;
; All parameters in brackets are optional, and, if
; omitted, the default values are:
;
; Source file-type -- ASM
; Destination file-type -- A86
; Destination file-name -- same as the source file-name
; Drive -- current drive
;
; FLAG LOCATIONS:
;
; 103H -- Change to non-zero value to suppress
; translation of several non-standard opcodes:
; REQ, RNE, RLT, RGE, CEQ, CNE, CLT, CGE
; JEQ, JNE, JLT, JGE,
; ENT, NAM, RAM, ROG, IFC, ICL, LST, MAC
;
; 104H -- If non-zero (default) XLT86 converts lines
; with multiple statements separated by DR's EP
; separator into separate lines.
; Change to zero for output on a single line
; with the translated statements separated by
; EP.
;
; 107H-- If zero (default) XLT86 translates
;
; PUSH PSW POP PSW
;
; to
;
; LAHF POP AX
; PUSH AX SAHF
;
; Otherwise, the translation is
;
; LAHF POP AX
; XCHG AH,AL XCHG AH,AL
; PUSH AX SAHF
; XCHG AH,AL
;
; 108H-- If zero (default) XLT86 translates
;
; INX rp DCX rp
;
; to
;
; INC rp' DEC rp'
;
; Otherwise, the translation is
;
; PUSHF PUSHF
; INC rp' DEC rp'
; POPF POPF
;
; 109H-- If zero (default) XLT86 translates
;
; DAD rp
;
; to
;
; ADD BX,rp'
;
; Otherwise, the translation is
;
; PUSHF
; ADD BX,rp'
; POPF
;
N00 EQU 0
N01 EQU 1
;
N07 EQU 7
N09 EQU 9 ; Tab every 8th col.
NF8 EQU 0F8H ; Mod 8
;
LBUFLN EQU 80 ; Line buffer length
OPBFLN EQU 5 ; Opcode buffer length
MEMSIZ EQU 4 ; Memory available in Kb
IBNUM EQU 4*MEMSIZ
OBNUM EQU 4*MEMSIZ
RECLEN EQU 128 ;
STCKLN EQU 128 ; Stack size
IBFLEN EQU IBNUM*RECLEN
OBFLEN EQU OBNUM*RECLEN
;
CTRLC EQU 3
EOT EQU 4
BEL EQU 7
HT EQU 9
LF EQU 0AH
CR EQU 0DH
ESC EQU 1BH
QUOTE EQU 27H
;
;
ORG 005CH
;
;
DFCB1 RB 16
DFCB2 RB 16
;
FNLEN EQU 8
EOS EQU EOT ; Replacement for exclamation pt
EOF EQU 1AH
NFF EQU 0FFH ; Disk error return
;
;
; BDOS functions
;
NABT EQU 0
NCIN EQU 1
NCOUT EQU 2
NCDAV EQU 0BH
NOPEN EQU 0FH
NCLOSE EQU 10H
NDEL EQU 13H
NRDNR EQU 14H
NWRNR EQU 15H
NCREAT EQU 16H
NCDISK EQU 19H
NDMA EQU 1AH
;
;
ORG 100H
;
;
JMP START
;
;
; Option flags
;
PSEFLG DB 0 ; (103H) 0 to translate non-
; Standard opcodes
MLTLFL DB 0FFH ; (104H) 0 to put input line with
; Exc. pt. to output on one line
TCASFL DB 0 ; (105H) 0 to preserve case
;
LCASFL DB 0 ; (106H) 0 for upper case if
; TCASFL not zero
PSWFL DB 0 ; (107H) non-zero to preserve 8080
; Order of PSW registers on stack
INXFL DB 0 ; (108H) non-zero to preserve flags
; With INX and DCX translations
DADFL DB 0 ; (109H) non-zero to preserve flags
; With DAD translation
;
;
; BDOS Functions
;
BDOS: INT 224
RET
;.....
;
;
; Return to CP/M
;
ABORT: MOV CL,0
MOV DL,0
INT 224
;
;
; Help message
;
HMSG1 DB CR,LF
DB LF
DB 'XLT86 translates Intel 8080 assembly language source',CR,LF
DB 'code into Intel 8086 assembly language source code.',CR,LF
DB LF
DB 'It is invoked by a command of the form:',CR,LF
DB LF
DB ' XLT86 [d:]srcfile[.typ] [d:destfile.typ]',CR,LF
DB LF
DB 'The brackets denote optional parameters and the ',CR,LF
DB 'default values are:',CR,LF
DB LF
DB ' Source file-type -- ASM',CR,LF
DB ' Destination file-type -- A86',CR,LF
DB ' Destination file-name -- same as source file-name',CR,LF
DB ' Drive -- current drive',CR,LF
DB CR,LF
DB 'Press any key to continue - ',0
;
HMSG2 DB CR,LF
DB LF
DB 'Examples:',CR,LF
DB LF
DB 'XLT86 PRGM1 --translates PRGM1.ASM to PRGM1.A86',CR,LF
DB 'XLT86 PRGM1 PRGM2 --translates PRGM1.ASM to PRGM2.A86',CR,LF
DB 'XLT86 PRGM1.TXT PRGM2.MAC --translates PRGM1.TXT to PRGM2.MAC',CR,LF
DB LF
DB 'XLT86 also has the following features:',CR,LF
DB LF
DB 'Case will be preserved as well as possible -- if an opcode has',CR,LF
DB 'a lower case character, the translated opcode will be in lower',CR,LF
DB 'case.',CR,LF
DB LF
DB 'All asterisks at the beginning of lines will be replaced with',CR,LF
DB 'semicolons.',CR,LF
DB LF
DB 'A dot is printed on the console for every 100 lines of input ',CR,LF
DB 'processed.',CR,LF
DB LF
DB 0
;
;=======================================================================
;
;
; Program begins here
;
START: MOV AX,SS
MOV SSBDOS,AX
MOV SPBDOS,SP
MOV AX,CS
MOV SS,AX
MOV SP,OFFSET STACK
MOV AL,DFCB1+1 ; Check for a file name
CMP AL,' ' ; Print help if no name
JNZ BEGIN ; No help requested
MOV DX,OFFSET SIGNON
CALL PRTLIN
MOV DX,OFFSET HMSG1 ; Print help message
CALL PRTLIN
MOV CL,NCIN ; Wait for any character
CALL BDOS
MOV DX,OFFSET HMSG2 ; Print rest of help
CALL PRTLIN
MOV AX,SSBDOS
MOV SS,AX ; Retrieve system stack
MOV SP,SPBDOS ; Pointer and pop
RETF ; To PC
;
BEGIN: CALL HELLO ; Signon, open in & out files
;
NXTLIN: CALL GETLIN ; Get line from input file to buf
CALL PROCLIN ; Process line
JMP NXTLIN
;.....
;
;
;***********************************************************************
;
;
; Print signon, open input and output files.
;
HELLO: MOV DX,OFFSET SIGNON
CALL PRTLIN
;
HELLO0: MOV AL,'D' ; Translate DB & EQU (for
MOV OPTBDB,AL ; Uniform formatting)
MOV MLTSPC,HT ; For opcodes xltd to mlt stmts
MOV AL,HT ; HT after opcode
MOV BX,OFFSET PUTHT+1
MOV [BX],AL
MOV AL,41 ; Tab comments to col 33
MOV BX,OFFSET PUTND5+1
MOV [BX],AL
MOV AL,3CH ; CMP instruction
MOV BX,OFFSET EXCLAM
MOV [BX],AL
XOR AL,AL
MOV TCASFL,AL ; Don't convert case
MOV LCASFL,AL ; Lower case flag
MOV SEPMSG,OFFSET NEWLSP
MOV AL,PSEFLG ; Translate non-standard
OR AL,AL ; Opcodes ?
JZ $+5
CALL NXPSD
MOV DX,OFFSET DBMSG
CALL PRTLIN ;
CALL CHKYES ; Xlat DB & EQU ?
CMP AL,ESC
JNZ $+5
JMP HELLO0
CMP AL,CTRLC
JNZ $+5
JMP ABORT
CMP AL,'Y'
JZ $+5
CALL NXDBEQ
MOV AL,MLTLFL ; Force space after opcode
OR AL,AL ; If MLTLFL not set
JNZ $+5
JMP HELLO2
MOV DX,OFFSET SPCMSG
CALL PRTLIN ; Use space after
CALL CHKYES ; Opcode ?
CMP AL,ESC
JNZ $+5
JMP HELLO0
CMP AL,CTRLC
JNZ $+5
JMP ABORT
CMP AL,'Y'
;
HELLO2: JNZ $+5
CALL SETSPC
MOV DX,OFFSET COLMSG
CALL PRTLIN ;
CALL CHKYES ; Start comment
CMP AL,ESC
JNZ $+5
JMP HELLO0
CMP AL,CTRLC
JNZ $+5
JMP ABORT
CMP AL,'Y'
JNZ $+5
CALL SETCOL ; In column 25 ?
MOV DX,OFFSET EXCMSG
CALL PRTLIN ; Ignore exclamation point
CALL CHKYES ; Separator ?
CMP AL,ESC
JNZ $+5
JMP HELLO0
CMP AL,CTRLC
JNZ $+5
JMP ABORT
CMP AL,'Y'
JNZ $+5
CALL SETNEX
MOV DX,OFFSET MLTMSG
CALL PRTLIN ; Multiple statements
CALL CHKYES ; On one line ?
CMP AL,ESC
JNZ $+5
JMP HELLO0
CMP AL,CTRLC
JNZ $+5
JMP ABORT
CMP AL,'Y'
JNZ $+5
CALL SETMLT
MOV DX,OFFSET TRNMSG ; Convert case ?
CALL PRTLIN
CALL CHKYES
CMP AL,ESC
JNZ $+5
JMP HELLO0
CMP AL,CTRLC
JNZ $+5
JMP ABORT
CMP AL,'L'
JNZ $+5
CALL SETLC
CMP AL,'U'
JNZ $+5
CALL SETUC
MOV AL,N01
MOV COLNUM,AL
MOV CL,NCDISK
CALL BDOS
INC AL
MOV XCDISK,AL
CALL MAKFNS
CALL OPENIN
CALL CREATO
RET
;.....
;
;
SIGNON DB '8080-to-8086 Translator version '
DB VERS/100+'0','.',(VERS MOD 100)/10+'0'
DB (VERS MOD 10)+'0'
DB CR,LF,0
;
;
; Don't translate non-standard opcodes
;
NXPSD: XOR AL,AL
MOV OPTTDL,AL
MOV OPTENT,AL
MOV OPTIFC,AL
RET
;.....
;
;
DBMSG DB 'Translate DB & EQU ? '
DB '[Y/ret=N/esc/^C] ',0
;
NXDBEQ: XOR AL,AL
MOV OPTBDB,AL
RET
;.....
;
;
SPCMSG DB 'Use space (default TAB) after opcode ? '
DB '[Y/ret=N/esc/^C] ',0
;
SETSPC: MOV BX,OFFSET PUTHT+1
MOV AL,' '
MOV [BX],AL
MOV MLTSPC,AL
RET
;.....
;
;
COLMSG DB 'Start comment in column 25 (default 33) ? '
DB '[Y/ret=N/esc/^C] ',0
;
SETCOL: MOV BX,OFFSET PUTND5+1
MOV AL,33
MOV [BX],AL
RET
;.....
;
;
EXCMSG DB 'Ignore ! statement separator ? '
DB '[Y/ret=N/esc/^C] ',0
;
SETNEX: MOV AL,0C3H ; RET instruction
MOV BX,OFFSET EXCLAM
MOV [BX],AL
RET
;.....
;
;
MLTMSG DB 'Put opcodes converted to multiple'
DB ' statements on one line ? '
DB '[Y/ret=N/esc/^C] ',0
;
SETMLT: MOV SEPMSG,OFFSET EXCLSP
MOV MLTSPC,' '
RET
;.....
;
;
TRNMSG DB 'Translate instructions to Upper/Lower'
DB ' or preserve case ? [U/L/ret/esc/^C] ',0
;
SETLC: MOV TCASFL,AL
MOV LCASFL,AL
RET
;.....
;
;
SETUC: MOV TCASFL,AL
RET
;.....
;
;
;***********************************************************************
;
; Gets line from input file to line buffer until CR. Filters out con-
; trol characters except for horizontal tab. Truncates lines after
; LBUFLN characters. Terminates line with CR, LF, 0.
;
GETLIN: CALL PDOT ; Print activity dot
CALL CHKIN
CMP AL,CTRLC
JNZ $+5
JMP JABORT
XOR AL,AL
MOV QUOTFL,AL ; Not in quote
MOV CMNTFL,AL ; Not in comment
MOV BX,OFFSET LBUFF ; Line buffer
MOV CH,LBUFLN ; Max # of char
;
GETLN1: XCHG BX,DX
MOV BX,XIBUFF
XCHG BX,DX
MOV AL,DH
CMP AL,(OFFSET IBUFF+IBFLEN)/256
JZ $+5
JMP GETLN4
MOV AL,DL
CMP AL,(OFFSET IBUFF+IBFLEN) MOD 256
JZ $+5
JMP GETLN4
PUSH CX
PUSH BX
MOV DX,OFFSET IBUFF
;
GETLN2: MOV CL,NDMA
PUSH DX
CALL BDOS
POP DX
XCHG BX,DX
MOV DX,OFFSET INFCB
MOV CL,NRDNR
PUSH BX
CALL BDOS
POP BX
DEC AL
JZ $+5
JMP GETLN3
MOV AL,EOF
MOV [BX],AL
;
GETLN3: MOV DX,OFFSET RECLEN
ADD BX,DX
XCHG BX,DX
MOV AL,DH
CMP AL,(OFFSET IBUFF+IBFLEN)/256
JZ $+5
JMP GETLN2
MOV AL,DL
CMP AL,(OFFSET IBUFF+IBFLEN) MOD 256
JZ $+5
JMP GETLN2
POP BX
POP CX
MOV DX,OFFSET IBUFF
;
GETLN4: XCHG BX,DX
MOV AL,[BX]
XCHG BX,DX
INC DX
XCHG BX,DX
MOV XIBUFF,BX
XCHG BX,DX
MOV [BX],AL
CMP AL,QUOTE ; Set or reset
JZ $+5
JMP GTLN41 ; QUOTFL
MOV AL,QUOTFL
NOT AL
MOV QUOTFL,AL
;
GTLN41: MOV AL,[BX] ; Translate exclam. pt.
CALL EXCLAM ; Which is not in quote
MOV [BX],AL ; To EOS
MOV AL,TCASFL ; Translate to upper
OR AL,AL ; Or lower case ?
JNZ $+5
JMP GTLN46 ; NO
MOV AL,QUOTFL ; If in quote, do
OR AL,AL ; Nothing
JZ $+5
JMP GTLN43
MOV AL,[BX] ; Otherwise, ';' sets
CMP AL,';' ; CMNTFL and EOS resets
JNZ $+5
JMP GTLN42 ; It
CMP AL,EOS
JZ $+5
JMP GTLN43
XOR AL,AL
;
GTLN42: MOV CMNTFL,AL
GTLN43: MOV AL,QUOTFL ; If in quote,
OR AL,AL ; Do nothing
JZ $+5
JMP GTLN46
MOV AL,CMNTFL ; If in comment,
OR AL,AL ; Do nothing
JZ $+5
JMP GTLN46
MOV AL,LCASFL ; Otherwise,
OR AL,AL ; If LCASFL set
MOV AL,[BX]
JNZ $+5
JMP GTLN44
CALL LCASE ; Trns to lwr case
JMP GTLN45
;
GTLN44: CALL UCASE ; Else trns to upr case
;
GTLN45: MOV [BX],AL
GTLN46: MOV AL,[BX]
CMP AL,CR
JNZ $+5
JMP GETLN6
CMP AL,HT ; Filters out all ctrl
JNZ $+5
JMP GETLN5 ; Chars except tab
CMP AL,EOF
JNZ $+5
JMP GETLN7
CMP AL,EOS
JNZ $+5
JMP GETLN5
CMP AL,' '
JNC $+5
JMP GETLN1
;...
;
;
GETLN5: INC BX
DEC CH
JZ $+5
JMP GETLN1
DEC BX
INC CH
JMP GETLN1
;...
;
;
GETLN6: INC BX
MOV BYTE PTR [BX],LF
INC BX
MOV BYTE PTR [BX],N00
XCHG BX,DX
MOV XIBUFF,BX
XCHG BX,DX
RET
;.....
;
;
; Change exclamation point to EOS in A
;
EXCLAM: CMP AL,'!'
JZ $+3
RET
;...
;
;
MOV AL,QUOTFL
OR AL,AL
MOV AL,'!'
JZ $+3
RET
;...
;
;
MOV AL,EOS
RET
;.....
;
;
QUOTFL DB 0
CMNTFL DB 0
;
;
; Exit
;
GETLN7: CALL CLOSEO
MOV DX,OFFSET UPSMSG
CALL PRTLIN
MOV DX,OFFSET ENDIFL
CALL PRTLIN
MOV DX,OFFSET ICLFLG
CALL PRTLIN
MOV DX,OFFSET LSTFLG
CALL PRTLIN
MOV DX,OFFSET MACFLG
CALL PRTLIN
MOV DX,OFFSET EOJMSG
;
;
; Print message at DE and abort
;
EREXIT: PUSH DX
MOV DX,OFFSET CRLFMG
CALL PRTLIN
POP DX
CALL PRTLIN
JMP ABORT
;.....
;
;
JABORT: MOV DX,OFFSET JABTMG
CALL PRTLIN
JMP GETLN7
;.....
;
;
JABTMG DB CR,LF,'*** Job Cancelled ***',CR,LF,0
;
UPSMSG DB 0,LF,'The following operands'
DB ' have been used in your '
DB 'source and have not'
DB CR,LF
DB 'been fully translated. You must '
DB 'complete the translation using an editor.'
DB CR,LF,HT
DB 'original:',HT,HT
DB 'must be translated to:'
DB CR,LF,0
;
ENDIFL DB 0,'IF or IFC',HT,HT,'%IF(exp)THEN(txt1)',CR,LF
DB HT,'ELSE',HT,HT,HT,'ELSE(txt2)',CR,LF
DB HT,'ENDIF or #ENDIF',HT,HT,'FI'
DB CR,LF,0
;
ICLFLG DB 0,'ICL'
DB CR,LF,0
;
LSTFLG DB 0,'LST or LIST'
DB CR,LF,0
;
MACFLG DB 0,'MACRO or MAC',HT,HT,'%DEFINE(mname[(plist)])'
DB CR,LF
DB HT,'#macro-call',HT,HT,'%macro-call'
DB CR,LF,0
;
EOJMSG DB '*** End of Job ***',CR,LF,0
;.....
;
;
;***********************************************************************
;
; Process line
;
PROCLIN:MOV BX,OFFSET LBUFF
;
PROCLN0:CALL FNDOPC
JNZ PRCLN00
CALL PTCOLN ; Put out colon if
JMP PUTND6 ; Colon flag set
;.....
;
;
PRCLN00:MOV AL,COLNFL ; Is there a colon
OR AL,AL
JZ PRCLN01
MOV BX,OFFSET OPTPSD ; Don't put colon
MOV CX,OPBFLN ; If opcode is
CALL SCANOP ; DB, DW, DS, or EQU
JZ PRCLN01
MOV AL,':'
CALL PUTCHR
;
PRCLN01:MOV BX,XWHITE
CALL PUTSPT
;
PROCLN1:MOV BX,OFFSET OPTIMM ; Imm or one byte
MOV CX,2*OPBFLN
CALL SCANOP
JNZ $+5
JMP DOIMM
MOV BX,OFFSET OPTONE ; One byte opcodes
MOV CX,2*OPBFLN
CALL SCANOP
JNZ $+5
JMP DO_ONE
MOV BX,OFFSET OPTREG ; Register
MOV CX,2*OPBFLN
CALL SCANOP
JNZ $+5
JMP DOREG
MOV BX,OFFSET OPTBDB ; Db and equ
MOV CX,2*OPBFLN
CALL SCANOP
JNZ $+5
JMP DOSIMP
MOV BX,OFFSET OPTSMP ; Simple
MOV CX,2*OPBFLN
CALL SCANOP
JNZ $+5
JMP DOSIMP
MOV BX,OFFSET OPTROT ; Rotates
MOV CX,2*OPBFLN
CALL SCANOP
JNZ $+5
JMP DOROT
MOV BX,OFFSET OPTDCR ; Dcr, inr
MOV CX,2*OPBFLN
CALL SCANOP
JNZ $+5
JMP DODCR
MOV BX,OFFSET OPTWRD ; 16 bit dcx, inx
MOV CX,2*OPBFLN
CALL SCANOP
JNZ $+5
JMP DODCX
MOV BX,OFFSET OPTTDL ; Tdl
MOV CX,OPBFLN
CALL SCANOP
JNZ $+5
CALL DOTDL
MOV BX,OFFSET OPTRCC ; Ret cond
MOV CX,2*OPBFLN
CALL SCANOP
JNZ $+5
JMP DORET
MOV BX,OFFSET OPTCCC ; Call cond
MOV CX,2*OPBFLN
CALL SCANOP
JNZ $+5
JMP DOCALL
MOV BX,OFFSET OPTJCC ; Jump cond
MOV CX,2*OPBFLN
CALL SCANOP
JNZ $+5
JMP DOJMP
MOV BX,OFFSET OPTMSC ; Index & misc
MOV CX,2*OPBFLN+2
CALL SCANOP
JNZ $+5
JMP EXEC
;
PUTCOD: MOV BX,XOPCOD ; This fix prevents macro
JMP PUTEND ; Names from being split
;.....
;
;
PUTOPR: MOV BX,XOPRND
;
PUTEND: XOR AL,AL
MOV LCFLAG,AL
MOV LCDFLG,AL
MOV CL,N00 ; Putout w/o
;
PUTND1: MOV AL,[BX] ; Change
CMP AL,' '
JNZ $+5
JMP PUTND3
CMP AL,HT
JNZ $+5
JMP PUTND3
CMP AL,CR
JNZ $+5
JMP PUTLNC
CMP AL,';'
JNZ $+5
JMP PUTND4
CMP AL,EOS ; Process exclamation pt.
JNZ $+5
JMP PTND21 ; Statement separator
CMP AL,QUOTE
JZ $+5
JMP PUTND2
DEC CL
JNZ $+5
JMP PUTND2
MOV CL,N01
;
PUTND2: CALL PUTCHR
INC BX
JMP PUTND1
;...
;
;
PTND21: CALL SKSPHT
INC BX ; Increment past exclamation point
;
PTND22: MOV AL,[BX]
CMP AL,';'
JNZ $+5
JMP PUTND5
MOV AL,MLTLFL ; Put out as separate
OR AL,AL ; Lines
JNZ $+5
JMP PTND24 ; NO
MOV AL,[BX]
CMP AL,' ' ; Change space to HT
JZ $+5
JMP PTND23
MOV BYTE PTR [BX],HT
;
PTND23: CALL PCRLF
JMP PROCLN0
;...
;
;
PTND24: MOV AL,TEMP ; Was last character put
CMP AL,' ' ; Out a space ?
JNZ $+5
JMP PTND25
CMP AL,HT ; Or a TAB ?
JNZ $+5
JMP PTND25
MOV AL,' ' ; NO, put out a space
CALL PUTCHR
;
PTND25: MOV AL,'!'
CALL PUTCHR
JMP PROCLN0
;...
;
;
PUTND3: PUSH BX ; Space or Tab come here
CALL SKSPHT
CMP AL,CR ; This fix filters out
JNZ $+5
JMP PUTLNB ; Trailing spaces or tabs
POP BX
CMP AL,EOS ; Fix to process excl. pt.
JNZ $+5
JMP PTND21
CMP AL,';'
MOV AL,[BX] ; Prevent blank being replaced
JNZ $+5
JMP PUTND4
CALL PUTSPT
JMP PUTND1
;
PUTND4: DEC CL ; ';' come here
INC CL
JZ $+5
JMP PUTND2
CALL SKSPHT
;
;
; Tab comments to proper column
;
PUTND5: MOV CH,41
;
PTND51: MOV AL,COLNUM
CMP AL,CH ; Colnum>=41?
JC $+5
JMP PTND54
DEC AL ; No, insert
AND AL,NF8 ; Tabs to
ADD AL,N09 ; Start output
CMP AL,CH ; At col. 33
JNZ $+5
JMP PTND54
JNC $+5
JMP PTND52
MOV AL,' '
JMP PTND53
;
PTND52: MOV AL,HT
;
PTND53: CALL PUTCHR
JMP PTND51
;
PTND54: MOV AL,TEMP ; Insure
CMP AL,' ' ; Space
JNZ $+5
JMP PUTND6 ; Before
CMP AL,HT ; Semi-colon
JNZ $+5
JMP PUTND6
MOV AL,' '
CALL PUTCHR
;
PUTND6: MOV AL,[BX]
INC BX
CMP AL,EOS
JNZ $+5
JMP PTND22
OR AL,AL
JNZ $+3
RET
;...
;
;
CALL PUTCHR
JMP PUTND6
;.....
;
;
;
; Put line at HL to output file until 0 and reset colnum to 1.
;
PUTLNB: XCHG SP,BP
XCHG [BP],BX
XCHG SP,BP ; Filter trailing
POP BX ; Blanks or tabs
;
PUTLNC: JMP PUTLIN
;.....
;
;
;***********************************************************************
;
; Process labels, find potential opcode.
;
FNDOPC: MOV COLNFL,0 ; Reset colon flag
MOV AL,[BX]
CMP AL,' '
JNZ $+5
JMP FNDOP3
CMP AL,HT
JNZ $+5
JMP FNDOP3
CMP AL,CR ; Pass blank
JNZ $+3
RET ; Lines
;...
;
;
CMP AL,EOS ; Excl. pt. separator
JNZ $+3
RET
;...
;
;
CMP AL,';'
JNZ $+3
RET
;...
;
;
CMP AL,'*' ; Asterisk in first column
JZ $+5
JMP FNDOP1 ; Is a comment line
MOV BYTE PTR [BX],';'
RET
;...
;
;
FNDOP1: MOV CL,N00
MOV COLNFL,':' ; Set colon flag to
; ; insure colon after label
FNDOP2: MOV AL,BYTE PTR [BX]
CMP AL,':'
JNZ $+5
JMP FNDOP4
CMP AL,HT
JNZ $+5
JMP FNDOP6
CMP AL,' '
JNZ $+5
JMP FNDOP6
CMP AL,CR
JNZ $+3
RET
;...
;
;
CMP AL,EOS
JNZ $+3
RET
;...
;
;
CMP AL,';'
JNZ $+5
JMP FNDOP7
CALL PUTCHR
INC BX
INC CL
JMP FNDOP2
;...
;
;
; Comes here only if space or tab at beginning of line.
FNDOP3: PUSH BX
CALL SKSPHT ; Find first non-sp or tab
CMP AL,CR
JNZ $+5
JMP FNDOP9
CMP AL,EOS
JNZ $+5
JMP FNDOP9
POP BX
CALL PUTSPT ; Print until non-sp or ht
PUSH BX
CALL FINDLM ; Find ,:+-/*); CR HT or SP at HL
CMP AL,':'
POP BX
JNZ $+5
JMP FNDOP1
JMP FNDOP7
;...
;
;
; Colon terminating label comes here
;
FNDOP4: INC BX
MOV AL,[BX]
CMP AL,':'
JZ $+5
JMP FNDOP5
CALL PUTCHR
INC BX
;
FNDOP5: MOV COLNFL,':' ; Set colon flag
;
;
; HT or SP comes here
;
; See if there is an opcode field
;
FNDOP6:
FNDOP7: PUSH BX
CALL SKSPHT
MOV AL,[BX]
CMP AL,CR
JNZ $+5
JMP FNDOP9 ; Filter trailing SP or TAB
CMP AL,EOS
JNZ $+5
JMP FNDOP9 ; Excl. pt. separator
CMP AL,';'
JZ $+5
JMP FNDOP8
CALL PTCOLN ; Put out colon if flag set
XCHG SP,BP
XCHG [BP],BX
XCHG SP,BP
POP BX
POP CX ; Clear return
JMP PUTND5 ; Tab to proper column
;.....
;
;
; Have located opcode field
;
FNDOP8: POP BX
MOV XWHITE,BX
CALL SKSPHT
;
;
; Move potential opcode to OPCBUF
;
MOVOPC: MOV XOPCOD,BX
MOV CH,OPBFLN
MOV DX,OFFSET OPCBUF
CALL MOVBDH ; Move up to B char from HL to
CALL SKSPHT ; DE until ,:+-/*); CR HT SP
MOV XOPRND,BX
SUB AL,AL
INC AL
RET
;.....
;
;
; come here on CR to filter trailing SP or TAB
;
FNDOP9: CALL PTCOLN ; Put out colon if flag set
XCHG SP,BP
XCHG [BP],BX
XCHG SP,BP
POP BX
XOR AL,AL
RET
;.....
;
;
; Put out colon if COLNFL set.
;
PTCOLN: MOV AL,COLNFL
OR AL,AL
JZ PTCLN1
CALL PUTCHR
MOV COLNFL,0
;
PTCLN1: RET
;.....
;
;
COLNFL DB 0
XWHITE RW 1
;
;
;***********************************************************************
;
; Opcode tables
;
OPTIMM DB 'ACI ADC '
DB 'ADI ADD '
DB 'ANI AND '
DB 'CPI CMP '
DB 'ORI OR '
DB 'SBI SBB '
DB 'SUI SUB '
DB 'XRI XOR '
DB 0
;
OPTONE DB 'RET RET '
DB 'CMC CMC '
DB 'HLT HLT '
DB 'STC STC '
DB 'DAA DAA '
DB 'DI CLI '
DB 'EI STI '
DB 'NOP NOP '
DB 0
;
OPTREG DB 'ADC ADC '
DB 'ADD ADD '
DB 'ANA AND '
DB 'CMP CMP '
DB 'ORA OR '
DB 'SBB SBB '
DB 'SUB SUB '
DB 'XRA XOR '
DB 0
;
OPTPSD DB 'DB '
DB 'DW '
DB 'EQU '
DB 'DS '
DB 0
;
OPTBDB DB 'DB DB '
DB 'EQU EQU '
DB 0
;
OPTSMP DB 'JMP JMP '
DB 'CALL CALL '
DB 'DS RS '
DB 'DW DW '
DB 'SET EQU '
;
OPTENT DB 'ENT ENTRY'
DB 'NAM NAME '
DB 'RAM DATA '
DB 'ROG REL '
DB 0
;
OPTDCR DB 'DCR DEC '
DB 'INR INC '
DB 0
;
OPTROT DB 'RAL RCL '
DB 'RAR RCR '
DB 'RLC ROL '
DB 'RRC ROR '
DB 0
;
OPTWRD DB 'DCX DEC '
DB 'INX INC '
DB 0
;
OPTTDL DB 'REQ '
DB 'RNE '
DB 'RLT '
DB 'RGE '
DB 'CEQ '
DB 'CNE '
DB 'CLT '
DB 'CGE '
DB 'JEQ '
DB 'JNE '
DB 'JLT '
DB 'JGE '
DB 0
;
OPTRCC DB 'RC JNC '
DB 'RNC JC '
DB 'RZ JNZ '
DB 'RNZ JZ '
DB 'RP JS '
DB 'RM JNS '
DB 'RPE JPO '
DB 'RPO JPE '
DB 0
;
OPTCCC DB 'CC JNC '
DB 'CNC JC '
DB 'CZ JNZ '
DB 'CNZ JZ '
DB 'CP JS '
DB 'CM JNS '
DB 'CPE JPO '
DB 'CPO JPE '
DB 0
;
OPTJCC DB 'JC JNC '
DB 'JNC JC '
DB 'JZ JNZ '
DB 'JNZ JZ '
DB 'JP JS '
DB 'JM JNS '
DB 'JPE JPO '
DB 'JPO JPE '
DB 0
;
OPTMSC DB 'LXI MOV '
DW DOLXI
DB 'POP POP '
DW DOPOP
DB 'PUSH PUSH '
DW DOPSH
DB 'DAD ADD '
DW DODAD
DB 'LDA MOV '
DW DOLDA
DB 'LDAX MOV '
DW DOLDAX
DB 'LHLD MOV '
DW DOLHLD
DB 'MOV MOV '
DW DOMOV
DB 'MVI MOV '
DW DOMVI
DB 'IN IN '
DW DOIN
DB 'OUT OUT '
DW DOOUT
DB 'PCHL JMP '
DW DOPCHL
DB 'RST CALL '
DW DORST
DB 'SHLD MOV '
DW DOSHLD
DB 'SPHL MOV '
DW DOSPHL
DB 'STA MOV '
DW DOSTA
DB 'STAX MOV '
DW DOSTAX
DB 'XCHG XCHG '
DW DOXCHG
DB 'XTHL XCHG '
DW DOXTHL
DB 'CMA NOT '
DW DOCMA
DB 'IF IF '
DW DOIFC
DB 'LIST LIST '
DW DOLST
DB 'MACROMACRO'
DW DOMAC
;
OPTIFC DB 'IFC IF '
DW DOIFC
DB 'ICL *INCL'
DW DOICL
DB 'LST LIST '
DW DOLST
DB 'MAC MACRO'
DW DOMAC
DB 0
;.....
;
;
;***********************************************************************
;
; Scan table at HL for match to OPBFLN character string at OPCBUF. Ret
; Ret Z and BX -> entry if match.
;
SCANOP: MOV AL,[BX]
AND AL,AL
JNZ $+5
JMP SCNOP1
PUSH CX
MOV CH,OPBFLN
MOV DX,OFFSET OPCBUF
CALL CBDEHL ; Comp B bytes (DE)-(HL)
POP CX
JNZ $+3
RET
;...
;
;
ADD BX,CX
JMP SCANOP
;...
;
;
SCNOP1: INC AL
RET
;.....
;
;
; Gets routine address from HL+2*OPBFLN and jumps to routine.
;
EXEC: PUSH BX
MOV CX,2*OPBFLN
ADD BX,CX
MOV CL,[BX]
INC BX
MOV CH,[BX]
POP BX
PUSH CX ; Address on stack
RET ; Go to it
;.....
;
;
; Put up to OPBFLN char at HL+OPBFLN to output file. Stop at space
; and put tab to output file.
;
PUTOPHT:CALL PUTOPC
;
PUTHT: MOV AL,HT
JMP PUTCHR
;.....
;
;
; Put space or tab (contents of MLTSPC) to output file to separate
; opcode from operand in statements that get translated to multiple
; statements.
;
PUTHTS: MOV AL,MLTSPC
JMP PUTCHR
;.....
;
MLTSPC DB HT
;
;
PUTOPC: MOV CX,OFFSET OPBFLN
ADD BX,CX ; HL -> new opcode
MOV CH,CL
;
PUTOP1: MOV AL,[BX]
CMP AL,' '
JNZ $+3
RET
;...
;
;
CMP AL,HT
JNZ $+3
RET
;...
;
;
MOV AL,LCFLAG
OR AL,AL
MOV AL,[BX]
JNZ $+5
JMP PUTOP2
OR AL,20H
;
PUTOP2: CALL PUTCHR
INC BX
DEC CH
JZ $+5
JMP PUTOP1
RET
;.....
;
;
; Put string at HL to output file until 0. If (LCFLAG) set, convert to
; lower case.
;
PUTOPS: MOV AL,[BX]
OR AL,AL
JNZ $+3
RET
;...
;
;
MOV AL,LCFLAG
OR AL,AL
MOV AL,[BX]
JNZ $+5
JMP PUTOS0
CALL LCASE
;
PUTOS0: CALL PUTCHR
INC BX
JMP PUTOPS
;.....
;
;
; Put string at HL to output file until 0. If (LCDFLG) set, convert to
; lower case.
;
PUTRND: MOV AL,[BX]
OR AL,AL
JNZ $+3
RET
;...
;
;
MOV AL,LCDFLG
OR AL,AL
MOV AL,[BX]
JNZ $+5
JMP PUTRN0
CALL LCASE
;
PUTRN0: CALL PUTCHR
INC BX
JMP PUTRND
;.....
;
LCDFLG DB 0
;
;
; Find first ,:+-/*); CR HT or SP at HL, return A = (HL).
;
FINDLM: PUSH CX
CALL CHKDLM
POP CX
JNZ $+3
RET
;...
;
;
INC BX
JMP FINDLM
;.....
;
;
; Fill B locations at DE with spaces. Move up to B char from HL to DE
; until ,:+-/*); CR HT or SP encountered. Return Z and HL->special
; character if found. (Search B+1 loc for special char.)
;
MOVBDH: MOV CL,CH
MOV CH,N00
PUSH CX
PUSH DX
PUSH BX ; Fill BC locations
CALL FILLBD ; At DE with spaces
POP BX ;
POP DX
POP CX
;
MOVBD1: PUSH CX ; Ret Z, A=(HL)
CALL CHKDLM ; If (HL) is
POP CX ; ,:+-/*); CR HT or SP
JNZ $+3
RET
;...
;
;
MOV AL,[BX]
XCHG BX,DX
MOV [BX],AL
XCHG BX,DX
INC DX
INC BX
DEC CX
MOV AL,CH
OR AL,CL
JNZ $+5
JMP CHKDLM
JMP MOVBD1
;.....
;
;
; Skip spaces and tabs. Return HL -> non-space or non-tab
;
SKSPHT: MOV AL,[BX]
CMP AL,' '
JNZ $+5
JMP SKSPT1
CMP AL,HT
JZ $+3
RET
;...
;
;
SKSPT1: INC BX
JMP SKSPHT
;.....
;
;
; Ret Z, A=(HL) if HL is ,:+-/*); CR HT SP or EOS
;
CHKDLM: MOV AL,[BX]
CMP AL,HT
JZ CHKDRZ
CMP AL,' '
JZ CHKDRZ
CMP AL,','
JZ CHKDRZ
CMP AL,';'
JZ CHKDRZ
CMP AL,CR
JZ CHKDRZ
CMP AL,':'
JZ CHKDRZ
CMP AL,'+'
JZ CHKDRZ
CMP AL,'-'
JZ CHKDRZ
CMP AL,'/'
JZ CHKDRZ
CMP AL,'*'
JZ CHKDRZ
CMP AL,')'
JZ CHKDRZ
CMP AL,EOS
;
CHKDRZ: RET
;.....
;
;
; Compares B chars at DE with characters at HL. Ret Z if match.
; Preserve HL, DE, BC
;
CBDEHL: PUSH BX
PUSH DX
PUSH CX
;
CBDH1: XCHG BX,DX
MOV AL,[BX]
XCHG BX,DX
CMP AL,'a'
JNC $+5
JMP CBDH2
MOV LCFLAG,AL
AND AL,05FH
;
CBDH2: CMP AL,[BX]
JZ $+5
JMP CBDH3
INC BX
INC DX
DEC CH
JZ $+5
JMP CBDH1
;
CBDH3: POP CX
POP DX
POP BX
RET
;.....
;
;
LCFLAG DB 0
;
;
; Fill BC locations starting at DE with spaces. Returns A = space,
; DE -> next free location, HL = DE - 1, BC = 0.
;
FILLBD: MOV AL,' '
XCHG BX,DX
MOV [BX],AL
XCHG BX,DX
MOV BH,DH
MOV BL,DL
INC DX
DEC CX
CALL MOVIR
RET
;.....
;
;
; (DE)=(HL), INC HL, INC DE, DEC BC - repeat until BC = 0.
;
MOVIR: MOV AL,[BX]
XCHG BX,DX
MOV [BX],AL
XCHG BX,DX
INC BX
INC DX
DEC CX
MOV AL,CH
OR AL,CL
JZ $+5
JMP MOVIR
RET
;.....
;
;
;***********************************************************************
;
; Translation Routines
;
;*******************************************************
;
;
; Immediate i.e., XRI n -> XOR AL,n
;
DOIMM: CALL PUTOPHT
MOV BX,OFFSET OPALC
CALL PUTOPS
JMP PUTOPR
;.....
;
;
OPALC DB 'AL,',0
;
;
; One byte (implied) i.e., DI -> CLI
;
DO_ONE: CALL PUTOPC
JMP PUTOPR
;.....
;
;
; Simple translation i.e., DS n -> RS n
;
DOSIMP: CALL PUTOPHT
JMP PUTOPR
;.....
;
;
; Register instructions i.e., XRA r -> XOR AL,r'
;
DOREG: CALL PUTOPHT ; Put out opcode+tab
MOV BX,OFFSET OPALC
CALL PUTOPS
MOV BX,XOPRND
CALL TRNRG
JNZ DOREG1
XCHG DX,BX
CALL PUTRND
XCHG DX,BX
;
DOREG1: JMP PUTEND
;.....
;
;
; MOV r,s -> MOV r',s'
;
DOMOV: CALL PUTOPHT
MOV BX,XOPRND
CALL TRNRG
JZ $+5
JMP PUTOPR
XCHG DX,BX
CALL PUTRND
XCHG DX,BX
MOV AL,[BX] ; Get comma
INC BX ; Increment past comma
CALL PUTCHR
CALL TRNRG
JNZ DOMOV1
XCHG DX,BX
CALL PUTRND
XCHG DX,BX
;
DOMOV1: JMP PUTEND
;.....
;
;
; Decremebt and increment byte register
;
; DCR r -> DEC r'
;
; MVI r,n -> MOV r',n
;
DODCR:
DOMVI: CALL PUTOPHT
MOV BX,XOPRND
CALL TRNRG
JNZ DOMVI2
XCHG BX,DX
MOV AL,[BX]
XCHG BX,DX
CMP AL,'['
JNZ DOMVI1
PUSH BX
MOV BX,OFFSET OPBYTP
CALL PUTLIN
POP BX
;
DOMVI1: XCHG BX,DX
CALL PUTRND
XCHG BX,DX
;
DOMVI2: JMP PUTEND
;.....
;
;
OPBYTP DB 'BYTE PTR ',0
;
;
; Translate 8080 byte registers to 8086 byte registers. Enter with
; BX -> to 8080 register. If match, return Z set, BX -> next, DX ->
; translation, otherwise, return NZ, BX, DX unchanged.
;
TRNRG: MOV AL,[BX]
CMP AL,'a'
JNC $+5
JMP TRNRG2
MOV LCDFLG,AL
;
TRNRG2: AND AL,5FH
PUSH BX
MOV BX,OFFSET RTBL
MOV CH,LENGTH RTBL
;
TRNRG3: CMP AL,[BX]
JNZ $+5
JMP TRNRG4
INC BX
DEC CH
JZ $+5
JMP TRNRG3
POP BX ; HL -> R
MOV AL,0FFH ; Return NZ
OR AL,AL ; If no match
RET
;.....
;
;
TRNRG4: MOV DX,OFFSET RTBL
SUB BX,DX
ADD BX,BX
MOV DX,OFFSET RPTBL
ADD BX,DX
MOV DL,[BX]
INC BX
MOV DH,[BX]
POP BX
INC BX
XOR AL,AL
RET
;.....
;
;
RTBL DB 'ABCDEHLM'
;
RTBLE:
RPTBL DW ALREG
DW CHREG
DW CLREG
DW DHREG
DW DLREG
DW BHREG
DW BLREG
DW PBX
;
ALREG DB 'AL',0
CHREG DB 'CH',0
CLREG DB 'CL',0
DHREG DB 'DH',0
DLREG DB 'DL',0
BHREG DB 'BH',0
BLREG DB 'BL',0
PBX DB '[BX]',0
;
;
; Rotates
;
DOROT: CALL PUTOPHT
MOV BX,OFFSET OPALC
CALL PUTOPS
MOV AL,'1'
CALL PUTCHR
JMP PUTOPR
;.....
;
;
; DAD rp -> ADD BX,rp'
;
DODAD: MOV AL,DADFL
OR AL,AL
JZ DODAD2
PUSH BX
MOV BX,OFFSET OPPSHF ; 'PUSHF'
CALL PUTOPS
CALL SEP ; Put out separator
POP BX
CALL PUTOPC
CALL PUTHTS
;
DODAD1: MOV BX,OFFSET OPBXC ; 'BX,'
CALL PUTOPS
MOV BX,XOPRND
CALL TRNRP ; DX -> translated rp
JZ DODAD3
JMP PUTOPR
;
DODAD2: CALL PUTOPHT
JMP DODAD1
;
DODAD3: XCHG BX,DX
MOV AL,[BX]
XCHG BX,DX
CMP AL,'A'
JNZ $+5
JMP PUTOPR
XCHG BX,DX ; BX -> translated rp
CALL PUTRND
XCHG BX,DX ; BX -> next
MOV AL,DADFL
OR AL,AL
JZ DODAD4
PUSH BX
CALL SEP ; Put out separator
MOV BX,OFFSET OPPOPF ; 'POPF'
CALL PUTOPS
POP BX
;
DODAD4: JMP PUTEND
;.....
;
;
OPBXC DB 'BX,',0
;
;
; DCX or INX rp -> DEC or INC rp'
;
DODCX: MOV AL,INXFL
OR AL,AL
JZ DODCX2
PUSH BX
MOV BX,OFFSET OPPSHF ; 'PUSHF'
CALL PUTOPS
CALL SEP ; Put out separator
POP BX
CALL PUTOPC
CALL PUTHTS
;
DODCX1: MOV BX,XOPRND
CALL TRNRP ; DX -> translated rp
JZ DODCX3
JMP PUTOPR
;...
;
;
DODCX2: CALL PUTOPHT
JMP DODCX1
;...
;
;
DODCX3: XCHG BX,DX
MOV AL,[BX]
XCHG BX,DX
CMP AL,'A'
JNZ $+5
JMP PUTOPR
XCHG BX,DX ; BX -> translated rp
CALL PUTRND
XCHG BX,DX ; BX -> next
MOV AL,INXFL
OR AL,AL
JZ DODCX4
PUSH BX
CALL SEP ; Put out separator
MOV BX,OFFSET OPPOPF ; 'POPF'
CALL PUTOPS
POP BX
;
DODCX4: JMP PUTEND
;.....
;
;
OPPSHF DB 'PUSHF',0
OPPOPF DB 'POPF',0
;
;
; PUSH rp -> PUSH rp'
;
DOPSH: XCHG BX,DX
MOV BX,XOPRND
MOV AL,[BX]
AND AL,5FH
CMP AL,'P'
XCHG BX,DX
JNZ DOPSH1
XCHG BX,DX
CALL TRNRP ; DE -> trans, HL -> next
JZ $+5
JMP PUTCOD
PUSH BX
MOV BX,OFFSET OPLAHF
CALL PUTRND
MOV AL,PSWFL ; Preserve order of
OR AL,AL ; Registers on stack ?
JZ $+5
CALL XAHAL ; Yes, XCHG AH,AL
CALL SEP ; SP,EP,SP or CR, LF, HT
MOV BX,OFFSET OPPUSH
CALL PUTOPS
CALL PUTHTS
POP BX
XCHG BX,DX ; BX -> translated rp
CALL PUTRND
XCHG BX,DX ; BX -> next
MOV AL,PSWFL
OR AL,AL
JZ $+5
CALL XAHAL
JMP PUTEND
;
DOPSH1: CALL PUTOPHT
;
DOPSH2: MOV BX,XOPRND
CALL TRNRP ; DX -> translated rp
JZ $+5
JMP PUTOPR
;.....
;
;
DOPSH3: XCHG BX,DX ; BX -> translated rp
CALL PUTRND
XCHG BX,DX ; BX -> next
JMP PUTEND
;.....
;
;
OPLAHF DB 'LAHF',0
OPPUSH DB 'PUSH',0
;
XAHAL: PUSH BX
CALL SEP
MOV BX,OFFSET OPXCHG
CALL PUTRND
CALL PUTHTS
MOV BX,OFFSET OPAHAL
CALL PUTRND
POP BX
RET
;.....
;
;
OPXCHG DB 'XCHG',0
OPAHAL DB 'AH,AL',0
;
;
; POP rp -> POP rp'
;
DOPOP: XCHG BX,DX ; Save BX in DX
MOV BX,XOPRND
MOV AL,[BX]
AND AL,5FH
CMP AL,'P' ; Is it PSW ?
XCHG BX,DX ; Restore BX
JNZ DOPSH1
CALL PUTOPC
MOV AL,PSWFL
OR AL,AL
JZ DOPOP1
CALL PUTHTS ; Put space or tab
JMP DOPOP2
;...
;
;
DOPOP1: CALL PUTHT
;
DOPOP2: MOV BX,XOPRND
CALL TRNRP ; DE -> trans, HL -> next
JZ $+5
JMP PUTOPR
XCHG BX,DX ; BX -> tranlated rp
CALL PUTRND
MOV AL,PSWFL
OR AL,AL
JZ $+5
CALL XAHAL
CALL SEP ; SP,EP,SP or CR, LF, HT
MOV BX,OFFSET OPSAHF
CALL PUTRND
XCHG BX,DX
JMP PUTEND
;.....
;
;
OPSAHF DB 'SAHF',0
;
;
; LXI rp,n -> MOV rp',OFFSET n
;
DOLXI: CALL PUTOPHT
MOV BX,XOPRND
CALL TRNRP
JZ $+5
JMP PUTOPR
XCHG BX,DX
MOV AL,[BX]
XCHG BX,DX
CMP AL,'A'
JNZ $+5
JMP PUTOPR
XCHG BX,DX
CALL PUTRND
MOV BX,OFFSET OFFATR
CALL PUTLIN
XCHG BX,DX ; HL -> next
INC BX ; Skip comma
JMP PUTEND
;.....
;
;
OFFATR DB ',OFFSET ',0
;
;
; Translate 16 bit registers. Enter with HL -> rp. Returns HL -> next
; character, DE -> translation, Z set if match, otherwise, HL unchanged,
; NZ.
;
TRNRP: XOR AL,AL
MOV LCDFLG,AL
MOV AL,[BX]
CMP AL,'a'
JNC $+5
JMP TRNRP1
MOV LCDFLG,AL
;
TRNRP1: AND AL,5FH
CMP AL,'B'
JNZ $+5
JMP TRNRPB
CMP AL,'D'
JNZ $+5
JMP TRNRPD
CMP AL,'H'
JNZ $+5
JMP TRNRPH
CMP AL,'P'
JNZ $+5
JMP TRNRPP
CMP AL,'S'
JNZ $+5
JMP TRNRPS
;
TRNRP2: MOV AL,0
MOV LCDFLG,AL
RET
;.....
;
;
TRNRPB: MOV DX,OFFSET OPRCX ; 'CX'
INC BX
XOR AL,AL
RET
;.....
;
;
TRNRPD: MOV DX,OFFSET OPRDX ; 'DX'
INC BX
XOR AL,AL
RET
;.....
;
;
TRNRPH: MOV DX,OFFSET OPRBX ; 'BX'
INC BX
XOR AL,AL
RET
;.....
;
;
TRNRPP: INC BX
MOV AL,[BX]
AND AL,5FH
CMP AL,'S'
JZ $+5
JMP TRNRP4
INC BX
MOV AL,[BX]
AND AL,5FH
CMP AL,'W'
JZ $+5
JMP TRNRP3
MOV DX,OFFSET OPRAX ; 'AX'
INC BX
XOR AL,AL
RET
;.....
;
;
TRNRP3: DEC BX
;
TRNRP4: DEC BX
JMP TRNRP2
;...
;
;
TRNRPS: INC BX
MOV AL,[BX]
AND AL,5FH
CMP AL,'P'
JZ $+5
JMP TRNRP4
MOV DX,OFFSET OPRSP
INC BX
XOR AL,AL
RET
;.....
;
;
OPRAX DB 'AX',0
OPRCX DB 'CX',0
OPRDX DB 'DX',0
OPRBX DB 'BX',0
OPRSP DB 'SP',0
;
;
; Strange opcodes
;
DOTDL: MOV AL,OPCBUF+1
MOV BX,OFFSET CCZ ; 'Z '
CMP AL,'E'
JNZ $+5
JMP DOTDL1
MOV BX,OFFSET CCNZ ; 'NZ'
CMP AL,'N'
JNZ $+5
JMP DOTDL1
MOV BX,OFFSET CCC ; 'C '
CMP AL,'L'
JNZ $+5
JMP DOTDL1
MOV BX,OFFSET CCNC ; 'NC'
CMP AL,'G'
JNZ $+5
JMP DOTDL1
MOV BX,OFFSET CCZL
CMP AL,'e'
JNZ $+5
JMP DOTDL1
MOV BX,OFFSET CCNZL
CMP AL,'n'
JNZ $+5
JMP DOTDL1
MOV BX,OFFSET CCCL
CMP AL,'l'
JNZ $+5
JMP DOTDL1
MOV BX,OFFSET CCNCL
;
DOTDL1: MOV AL,[BX]
MOV OPCBUF+1,AL
INC BX
MOV AL,[BX]
MOV OPCBUF+2,AL
RET
;.....
;
;
CCZ DB 'Z '
CCNZ DB 'NZ'
CCC DB 'C '
CCNC DB 'NC'
CCZL DB 'z '
CCNZL DB 'nz'
CCCL DB 'c '
CCNCL DB 'nc'
;
;
; Return conditional
;
DORET: CALL PUTOPC
CALL PUTHT ; Could change to PUTHTS
MOV BX,OFFSET REL3
CALL PUTLIN
CALL SEP
MOV BX,OFFSET OPRET
CALL PUTOPS
JMP PUTOPR
;.....
;
;
REL3 DB '$+3',0
OPRET DB 'RET',0
;
;
; Call conditional
;
DOCALL: CALL PUTOPC
CALL PUTHT ; Could change to PUTHTS
MOV BX,OFFSET REL5
CALL PUTLIN
CALL SEP ; SP,EP,SP or CR, LF, HT
MOV BX,OFFSET OPCALL
CALL PUTOPS
CALL PUTHTS
JMP PUTOPR
;
REL5 DB '$+5',0
OPCALL DB 'CALL',0
;
;
; Jump conditional
;
DOJMP: CALL PUTOPC
CALL PUTHT ; Could change to PUTHTS
MOV BX,OFFSET REL5
CALL PUTLIN
CALL SEP ; SP,EP,SP or CR, LF, HT
MOV BX,OFFSET OPJMP
CALL PUTOPS
CALL PUTHTS ; Put space or tab
JMP PUTOPR
;.....
;
;
OPJMP DB 'JMP',0
;
;
; IN n -> IN AL,n
;
DOIN: JMP DOIMM
;
;
; LDA addr -> MOV AL,addr
;
DOLDA: JMP DOIMM
;
; XCHG BX,rp'
; LDAX rp -> MOV AL,[BX]
; XCHG BX,rp'
;
DOLDAX: MOV BX,XOPRND
CALL TRNRP ; DE -> trans, HL -> next
JZ $+5
JMP PUTCOD
PUSH BX
MOV BX,OFFSET OPXCHG
CALL PUTOPS
CALL PUTHTS
MOV BX,OFFSET OPBXC
CALL PUTOPS
XCHG BX,DX
PUSH BX
CALL PUTRND
CALL SEP ; SP,EP,SP or CR, LF, HT
MOV BX,OFFSET OPMOV
CALL PUTOPS
CALL PUTHTS
MOV BX,OFFSET OPLDAX
CALL PUTOPS
CALL SEP ; SP,EP,SP or CR, LF, HT
MOV BX,OFFSET OPXCHG
CALL PUTOPS
CALL PUTHTS
MOV BX,OFFSET OPBXC
CALL PUTOPS
POP BX ; HL -> rp'
CALL PUTRND
POP BX
JMP PUTEND
;.....
;
;
OPMOV DB 'MOV',0
OPLDAX DB 'AL,[BX]',0
;
;
; LHLD addr -> MOV BX,addr
;
DOLHLD: CALL PUTOPHT
MOV BX,OFFSET OPBXC ; 'BX,'
CALL PUTOPS
JMP PUTOPR
;.....
;
;
; OUT n -> OUT n,AL
;
DOOUT: CALL PUTOPHT
CALL PUTEXP
PUSH BX
MOV BX,OFFSET OPCAL ; ',AL'
JMP DOSTA1
;.....
;
;
; PCHL -> JMP BX
;
DOPCHL: CALL PUTOPHT
MOV BX,OFFSET OPRBX ; 'BX'
CALL PUTOPS
JMP PUTOPR
;.....
;
;
; RST -> CALL 8*
;
DORST: CALL PUTOPHT
MOV BX,OFFSET OPR8M ; '8*'
CALL PUTOPS
JMP PUTOPR
;.....
;
;
OPR8M DB '8*',0
;
;
; SHLD addr -> MOV addr,BX
;
DOSHLD: CALL PUTOPHT
CALL PUTEXP
PUSH BX
MOV BX,OFFSET OPCBX ; ',BX'
JMP DOSTA1
;.....
;
;
OPCBX DB ',BX',0
;
;
; SPHL -> MOV SP,BX
;
DOSPHL: CALL PUTOPHT
MOV BX,OFFSET OPSPBX ; 'SP,BX'
CALL PUTOPS
JMP PUTOPR
;.....
;
;
OPSPBX DB 'SP,BX',0
;
;
; STA addr -> MOV addr,AL
;
DOSTA: CALL PUTOPHT
CALL PUTEXP
PUSH BX
MOV BX,OFFSET OPCAL ; ',AL'
;
DOSTA1: CALL PUTOPS
POP BX
JMP PUTEND
;.....
;
;
OPCAL DB ',AL',0
;
; XCHG BX,rp'
; STAX rp -> MOV [BX],AL
; XCHG BX,rp'
;
DOSTAX: MOV BX,XOPRND
CALL TRNRP ; DE -> trans, HL -> next
JZ $+5
JMP PUTCOD
PUSH BX
MOV BX,OFFSET OPXCHG
CALL PUTOPS
CALL PUTHTS
MOV BX,OFFSET OPBXC
CALL PUTOPS
XCHG BX,DX
PUSH BX
CALL PUTRND
CALL SEP ; SP,EP,SP or CR, LF, HT
MOV BX,OFFSET OPMOV
CALL PUTOPS
CALL PUTHTS
MOV BX,OFFSET OPSTAX
CALL PUTOPS
CALL SEP ; SP,EP,SP or CR, LF, HT
MOV BX,OFFSET OPXCHG
CALL PUTOPS
CALL PUTHTS
MOV BX,OFFSET OPBXC
CALL PUTOPS
POP BX ; HL -> rp'
CALL PUTRND
POP BX
JMP PUTEND
;.....
;
;
OPSTAX DB '[BX],AL',0
;
;
; XCHG -> XCHG BX,DX
;
DOXCHG: CALL PUTOPHT
MOV BX,OFFSET OPBXDX ; 'BX,DX'
CALL PUTOPS
JMP PUTOPR
;.....
;
;
OPBXDX DB 'BX,DX',0
;
; XCHG SP,BP
; XTHL -> XCHG [BP],BX
; XCHG SP,BP
;
DOXTHL: MOV BX,OFFSET OPXCHG
CALL PUTOPS
CALL PUTHTS
MOV BX,OFFSET OPSPBP ; 'SP,BP'
CALL PUTOPS
CALL SEP ; SP,EP,SP or CR, LF, HT
MOV BX,OFFSET OPXCHG
CALL PUTOPS
CALL PUTHTS
MOV BX,OFFSET OPXTHL
CALL PUTOPS
CALL SEP ; SP,EP,SP or CR, LF, HT
MOV BX,OFFSET OPXCHG
CALL PUTOPS
CALL PUTHTS
MOV BX,OFFSET OPSPBP
CALL PUTOPS
JMP PUTOPR
;.....
;
;
OPSPBP DB 'SP,BP',0
OPXTHL DB '[BP],BX',0
;
;
; CMA -> NOT AL
;
DOCMA: CALL PUTOPHT
MOV BX,OFFSET ALREG
CALL PUTOPS
JMP PUTOPR
;.....
;
;
; Put 'expression' to output file. 'expression' is everything between
; (xOPRND) up to the tab or spaces before a ';' or CR.
;
PUTEXP: MOV BX,XOPRND
;
PUTEX1: MOV AL,[BX]
CMP AL,';'
JNZ $+5
JMP PUTEX4
CMP AL,CR
JNZ $+5
JMP PUTEX4
CMP AL,'!'
JNZ $+5
JMP PUTEX3
;
PUTEX2: INC BX
JMP PUTEX1
;.....
;
;
PUTEX3: DEC BX
MOV AL,[BX]
INC BX
CMP AL,' '
JNZ $+5
JMP PUTEX4
CMP AL,HT
JNZ $+5
JMP PUTEX4
JMP PUTEX2
;.....
;
;
PUTEX4: DEC BX
MOV AL,[BX]
CMP AL,' '
JNZ $+5
JMP PUTEX4
CMP AL,HT
JNZ $+5
JMP PUTEX4
INC BX
XCHG BX,DX
MOV BX,XOPRND
;
PUTEX5: MOV AL,DH
CMP AL,BH
JZ $+5
JMP PUTEX6
MOV AL,DL
CMP AL,BL
JNZ $+3
RET
;...
;
;
PUTEX6: MOV AL,[BX]
CALL PUTCHR
INC BX
JMP PUTEX5
;.....
;
;
; IFC -> IF
;
DOIFC: MOV AL,HT
MOV ENDIFL,AL
JMP DOUPS
;.....
;
;
; ICL -> *INCL
;
DOICL: MOV AL,HT
MOV ICLFLG,AL
JMP DOUPS
;.....
;
;
; LST -> LIST
;
DOLST: MOV AL,HT
MOV LSTFLG,AL
JMP DOUPS
;.....
;
;
; MAC -> MACRO
;
DOMAC: MOV AL,HT
MOV MACFLG,AL
;
DOUPS: CALL PUTOPHT
MOV AL,CR
MOV UPSMSG,AL
JMP PUTOPR
;.....
;
;
;***********************************************************************
;
; File operations
;
;***********************************************************************
;
; Set up input and output FCB's from DFCB
;
MAKFNS: MOV BX,OFFSET DFCB1
MOV DX,OFFSET INFCB
MOV CX,FNLEN+1
CALL MOVIR
MOV AL,[BX] ; Typ specified ?
CMP AL,' '
JNZ $+5
JMP MKFNS1
CMP AL,'?'
JNZ $+5
JMP MKFNS1
MOV CX,3
CALL MOVIR
;
MKFNS1: MOV BX,OFFSET DFCB1
MOV DX,OFFSET OUTFCB
MOV CX,FNLEN+1
CALL MOVIR
MOV AL,DFCB2
OR AL,AL ; Allows output to
JNZ $+5
JMP MKFNS2 ; Different drive
MOV OUTFCB,AL ; Than input
;
MKFNS2: MOV AL,DFCB2+1
CMP AL,' '
JNZ $+5
JMP MKFNS3 ; Allows output
MOV CX,8 ; File to have
MOV DX,OFFSET OUTFCB+1 ; Different name
MOV BX,OFFSET DFCB2+1 ; From input file
CALL MOVIR
;
MKFNS3: MOV AL,DFCB2+9
CMP AL,' '
JNZ $+5
JMP MKFNS4
MOV CX,3
MOV DX,OFFSET OUTFCB+9
MOV BX,OFFSET DFCB2+9
CALL MOVIR
;
MKFNS4: MOV DX,OFFSET PRFNM1
CALL PRTLIN
MOV BX,OFFSET INFCB
CALL PRFNAM
MOV DX,OFFSET PRFNM2
CALL PRTLIN
MOV BX,OFFSET OUTFCB
CALL PRFNAM
MOV DX,OFFSET CRLFMG
CALL PRTLIN
RET
;.....
;
;
; Print Filenames
;
PRFNAM: MOV AL,[BX] ; Disk number
OR AL,AL
JZ $+5
JMP PRFN1
MOV AL,XCDISK
;
PRFN1: ADD AL,'@'
CALL CONOUT
MOV AL,':'
CALL CONOUT
INC BX
MOV CH,8
CALL PRFN
MOV AL,'.'
CALL CONOUT
MOV CH,3
;
PRFN: MOV AL,[BX]
INC BX
CMP AL,' '
JZ $+5
CALL CONOUT
DEC CH
JZ $+5
JMP PRFN
RET
;.....
;
;
PRFNM1 DB 'Source File: ',0
PRFNM2 DB ', Destination File: ',0
;
;
; Open source file with ext ASM
;
OPENIN: MOV DX,OFFSET INFCB
MOV CL,NOPEN
CALL BDOS
CMP AL,NFF
JNZ $+5
JMP NSFERR
MOV AL,RECLEN
MOV BX,OFFSET IBUFF+IBFLEN
MOV XIBUFF,BX
RET
;.....
;
;
NSFERR: MOV DX,OFFSET NSFMSG ; 'No Source File'
JMP EREXIT
;.....
;
;
NSFMSG DB 'No Source File Found'
DB CR,LF,BEL,0
;
INFCB DB 0,0,0,0,0,0,0,0
DB 0,'ASM',0,0,0,0
DB 0,0,0,0,0,0,0,0
DB 0,0,0,0,0,0,0,0
DB 0
;.....
;
;
; Create output file with ext Z80
;
CREATO: MOV DX,OFFSET OUTFCB
MOV CL,NOPEN
CALL BDOS
CMP AL,NFF
JZ $+5
JMP OFEERR
;
CREAT4: MOV DX,OFFSET OUTFCB
MOV CL,NCREAT
CALL BDOS
CMP AL,NFF
JNZ $+5
JMP NDSERR
MOV DX,OFFSET OUTFCB
MOV CL,NOPEN
CALL BDOS
MOV AL,RECLEN
MOV OBUFCT,AL
MOV BX,OFFSET OBUFF
MOV XOBUFF,BX
RET
;.....
;
;
NDSERR: MOV DX,OFFSET NDSMSG ; 'No directory space'
JMP EREXIT
;.....
;
;
NDSMSG DB 'No Directory Space'
DB CR,LF,BEL,0
;
OUTFCB DB 0,0,0,0,0,0,0,0
DB 0,'A86',0,0,0,0
DB 0,0,0,0,0,0,0,0
DB 0,0,0,0,0,0,0,0
DB 0
;.....
;
;
OFEERR: MOV DX,OFFSET OFEMSG ; 'Output file exists'
CALL PRTLIN
CALL CHKYES
JZ $+5
JMP ABORT
MOV DX,OFFSET OUTFCB
MOV CL,NDEL
CALL BDOS
JMP CREAT4
;.....
;
;
OFEMSG DB 'Output File Already Exists'
DB ' -- Delete it and Continue ? (Y/N) '
DB BEL,0
;.....
;
;
;***********************************************************************
;
; Put line at HL to output file until 0.
;
PUTLIN: MOV AL,[BX]
AND AL,AL
JNZ $+3
RET
;...
;
;
CALL PUTCHR
INC BX
JMP PUTLIN
;.....
;
;
; Put spaces or tabs at HL to output file until non-(space or tab)
;
PUTSPT: MOV AL,[BX]
CMP AL,' '
JNZ $+5
JMP PUTSP1
CMP AL,HT
JZ $+3
RET
;...
;
;
PUTSP1: CALL PUTCHR
INC BX
JMP PUTSPT
;.....
;
;
; Put statement separator to output file.
;
SEP: MOV BX,SEPMSG
JMP PUTLIN
;.....
;
;
SEPMSG DW NEWLSP
EXCLSP DB ' ! ',0
NEWLSP DB CR,LF,HT,0
;
;
; Put CR, LF to output file.
;
PCRLF: MOV AL,CR
CALL PUTCHR
MOV AL,LF
;
;
; Put character in A to output file, update column number.
;
PUTCHR: PUSH BX
PUSH DX
PUSH CX
LAHF
PUSH AX
MOV TEMP,AL
MOV BX,XOBUFF
CMP AL,EOT
JNZ PCHR0
MOV AL,'!'
;
PCHR0: MOV [BX],AL
CMP AL,CR
JZ PUTCH0
CMP AL,LF
JZ PUTCH0
CMP AL,HT
JNZ PUTCH1
MOV AL,COLNUM
DEC AL
AND AL,NF8
ADD AL,N09
JMP PUTCH2
;...
;
;
PUTCH0: MOV AL,1
JMP PUTCH2
;...
;
;
PUTCH1: MOV AL,COLNUM
INC AL
;
PUTCH2: MOV COLNUM,AL
INC BX ; Inc obuff ptr
MOV AL,OBUFCT
DEC AL ; Dec obuff count
JNZ PTCH21
MOV AL,RECLEN
;
PTCH21: MOV OBUFCT,AL
MOV AL,BH
CMP AL,(OFFSET OBUFF+OBFLEN)/256
JNZ PUTCH4
MOV AL,BL
CMP AL,(OFFSET OBUFF+OBFLEN) MOD 256
JNZ PUTCH4
MOV DX,OFFSET OBUFF
;
PUTCH3: MOV CL,NDMA
PUSH DX
CALL BDOS
POP DX
XCHG BX,DX
MOV DX,OFFSET OUTFCB
CALL WRTREC ; Write record
MOV DX,OFFSET RECLEN
ADD BX,DX
XCHG BX,DX
MOV AL,DH
CMP AL,(OFFSET OBUFF+OBFLEN)/256
JNZ PUTCH3
MOV AL,DL
CMP AL,(OFFSET OBUFF+OBFLEN) MOD 256
JNZ PUTCH3
MOV BX,OFFSET OBUFF
;
PUTCH4: MOV XOBUFF,BX
POP AX
SAHF
POP CX
POP DX
POP BX
RET
;.....
;
;
TEMP DB 0
;
;
; Write record.
;
WRTREC: MOV CL,NWRNR
PUSH BX
CALL BDOS
POP BX
AND AL,AL
JNZ $+3
RET
;...
;
;
MOV DX,OFFSET OFWMSG ; 'output file write error'
JMP EREXIT
;.....
;
;
OFWMSG DB 'Output File Write Error'
DB CR,LF,BEL,0
;
;
; Fill rest of obuff with EOF, write record, and close file.
;
CLOSEO: MOV AL,EOF
CALL PUTCHR
MOV AL,OBUFCT
CMP AL,RECLEN
JNZ CLOSEO
;
CLOSE1: MOV DX,OFFSET OBUFF
MOV BX,XOBUFF
MOV AL,BH
CMP AL,DH
JNZ CLOSE3
MOV AL,BL
CMP AL,DL
JNZ CLOSE3
;
CLOSE2: MOV DX,OFFSET OUTFCB
MOV CL,NCLOSE
JMP BDOS
;.....
;
;
CLOSE3: MOV CL,NDMA
PUSH DX
CALL BDOS
POP DX
XCHG BX,DX
MOV DX,OFFSET OUTFCB
CALL WRTREC
MOV DX,RECLEN
ADD BX,DX
XCHG BX,DX
MOV AL,BYTE PTR XOBUFF+1
CMP AL,DH
JZ $+5
JMP CLOSE3
MOV AL,BYTE PTR XOBUFF
CMP AL,DL
JZ $+5
JMP CLOSE3
JMP CLOSE2
;.....
;
;
; Print line at DE until 0 on console.
;
PRTLIN: XCHG BX,DX
MOV AL,[BX]
XCHG BX,DX
AND AL,AL
JNZ $+3
RET
;...
;
;
CALL CONOUT
INC DX
JMP PRTLIN
;.....
;
;
; Console Output character in A.
;
CONOUT: LAHF
PUSH AX
PUSH CX
PUSH DX
PUSH BX
MOV DL,AL
MOV DH,N00
MOV CL,NCOUT
CALL BDOS
POP BX
POP DX
POP CX
POP AX
SAHF
RET
;.....
;
;
; Get character from CONSOLE and return Z set if char.AND.5FH = 'Y'
;
CHKYES: MOV CL,NCIN
CALL BDOS
LAHF
PUSH AX
CALL CRLF
POP AX
SAHF
AND AL,5FH
CMP AL,'Y'
RET
;.....
;
;
; Return Z if no char available, otherwise, get character in A.
;
CHKIN: MOV CL,NCDAV
CALL BDOS
OR AL,AL
JNZ $+3
RET
;...
;
;
MOV CL,NCIN
CALL BDOS
RET
;.....
;
;
;
CRLF: MOV DX,OFFSET CRLFMG
JMP PRTLIN
;.....
;
;
CRLFMG DB CR,LF,0
;
;
; Convert upper to lower case in A.
;
LCASE: CMP AL,'A'
JNC $+3
RET
;...
;
;
CMP AL,'Z'+1
JC $+3
RET
;...
;
;
OR AL,20H
RET
;.....
;
;
; Convert lower case to upper case in A.
;
UCASE: CMP AL,'a'
JNC $+3
RET
;...
;
;
CMP AL,'z'+1
JC $+3
RET
;...
;
;
AND AL,5FH
RET
;.....
;
;
; Print activity dot every 100 lines.
;
PDOT: DEC LNCNT
JNZ PDOT2
MOV AL,'.'
CALL CONOUT
MOV LNCNT,100 ; Dot every 100 lines
DEC DOTCNT
JNZ PDOT1
MOV AL,' '
CALL CONOUT
MOV DOTCNT,10 ; Space every 10 dots
;
PDOT1: DEC NLCNT
JNZ PDOT2
CALL CRLF
MOV NLCNT,50 ; 50 dots per line
;
PDOT2: RET
;.....
;
;
LNCNT DB 100 ; Dot every 100 lines
DOTCNT DB 10 ; Space every 10 dots
NLCNT DB 50 ; 50 dots per line
;
;
; Uninitialized storage.
;
XCDISK RS 1
SSBDOS RW 1
SPBDOS RW 1
RS STCKLN
STACK EQU $
COLNUM RS 1
XOPCOD RW 1
OPCBUF RS OPBFLN
XOPRND RW 1
XOBUFF RW 1
OBUFCT RS 1
OBUFF RS OBFLEN
LBUFF RS LBUFLN+3
XIBUFF RW 1
IBUFF RS IBFLEN
;.....
;
;
END