Files
86-DOS-0.11/CPM Tools/ASM86.Z80
T

3149 lines
38 KiB
Z80 Assembly

; Seattle Computer Products 8086 Assembler version 1.00
; by Tim Paterson
; Runs on the Z80 under CP/M
SYMWID: EQU 10
FCB: EQU 5CH
BUFSIZ: EQU 128
EOL: EQU 13 ;ASCII carriage return
OBJECT: EQU 100H ;DEFAULT "PUT" ADDRESS
;System call function codes
PRINTMES: EQU 9
OPEN: EQU 15
CLOSE: EQU 16
DELETE: EQU 19
READ: EQU 20
SETDMA: EQU 26
MAKE: EQU 22
SEQWRT: EQU 21
;The following equates define some token values returned by GETSYM
UNDEFID:EQU 0 ;Undefined identifier (including no nearby RET)
CONST: EQU 1 ;Constant (including $)
REG: EQU 2 ;8-bit register
XREG: EQU 3 ;16-bit register (except segment registers)
SREG: EQU 4 ;Segment register
ORG 100H
JP BEGIN
CPYRHT: DB 'Copyright 1979 by Seattle Computer Products, Inc.'
DB 13,10,13,10,'$'
BEGIN:
LD SP,STACK
LD DE,HEADER
LD C,PRINTMES
CALL SYSTEM
LD DE,CPYRHT
CALL SYSTEM
LD A,(FCB+17)
LD (SYMFLG),A ;Save symbol table request flag
LD HL,FCB+9 ;Point to file extension
LD A,(HL) ;Get source drive letter
CALL CHKDSK ;Valid drive?
OR A
JR Z,DEFAULT ;If no extension, use existing drive spec
LD (FCB),A
DEFAULT:
INC HL
LD A,(HL) ;Get HEX file drive letter
CP 'Z' ;Suppress HEX file?
CALL NZ,CHKDSK
LD (HEXFCB),A
INC HL
LD A,(HL) ;Get PRN file drive letter
CP 'Z' ;Suppress PRN file?
JR Z,NOPRN
CP 'X' ;PRN file to console?
JR Z,NOPRN
CALL CHKDSK
NOPRN:
LD (LSTFCB),A
CALL ADDEXT
LD DE,FCB
LD C,OPEN
CALL SYSTEM
LD HL,NOFILE
INC A
JP Z,PRERR
XOR A
LD (FCB+32),A ;Zero Next Record field
LD DE,HEXFCB
CALL MAKFIL
LD DE,LSTFCB
CALL MAKFIL
LD HL,0FFH
EXX
LD HL,START+1 ;POINTER TO NEXT BYTE OF INTERMEDIATE CODE
LD (CODE),HL
LD IY,START ;POINTER TO CURRENT RELOCATION BYTE
LD HL,0
LD (PC),HL ;DEFAULT PROGRAM COUNTER
LD (BASE),HL ;POINTER TO ROOT OF ID TREE=NIL
LD (RETPT),HL ;Pointer to last RET record
DEC HL
LD (LSTRET),HL ;Location of last RET
LD HL,(6) ;HL=END OF MEMORY
LD (HEAP),HL ;BACK END OF SYMBOL TABLE SPACE
LD A,4
LD (BCOUNT),A ;CODE BYTES PER RELOCATION BYTE
XOR A
LD (IFFLG),A ;NOT WITHIN IF/ENDIF
LD (CHKLAB),A ;LOOKUP ALL LABELS
;Assemble each line of code
LOOP:
CALL NEXTCHR ;Get first character on line
CP 1AH
JP Z,END
LD A,-1 ;Flag that no tokens have been read yet
LD (SYM),A
CALL ASMLIN ;Assemble the line
LD A,(SYM)
CP -1 ;Any tokens found on line?
CALL Z,GETSYM ;If no tokens read yet, read first one
CP ';'
JR Z,ENDLN
CP EOL
JR Z,ENDLN
LD A,14H ;Garbage at end of line error
JR ENDLIN
JP END
ENDLN:
XOR A ;Flag no errors on line
ENDLIN:
LD SP,STACK
CALL NEXLIN
JR LOOP
NEXLIN:
LD B,0C0H ;Put end of line marker and error code (AL)
CALL PUTCD
CALL GEN1
LD A,(CHR)
GETEOL:
CP 10
RET Z
CP 1AH
JP Z,END
CALL NEXTCHR ;Scan over comments for linefeed
JR GETEOL
ABORT:
LD HL,NOMEM
PRERR:
EX DE,HL
LD C,PRINTMES
CALL SYSTEM
JP 0
MAKFIL:
LD A,(DE) ;Get drive select byte
CP 20H ;If not valid, don't make file
RET NC
PUSH DE
INC DE
LD HL,FCB+1
LD BC,8
LDIR ;Copy source file name
POP DE
LD C,DELETE
CALL SYSTEM
LD C,MAKE
CALL SYSTEM
LD HL,NOSPAC
INC A ;Success?
JR Z,PRERR
LD C,OPEN
JP SYSTEM
ADDEXT:
LD DE,FCB+9
LD HL,EXTEND ;Set extension to ASM
LD BC,7
LDIR
RET
CHKDSK:
SUB ' ' ;If not present, set zero flag
RET Z
SUB 20H
JR Z,DSKERR ;Must be in range A-W
CP 'X'-'@'
RET C
DSKERR:
LD HL,BADDSK
JR PRERR
ERROR:
LD A,C
JR ENDLIN
NEXTCHR:
EXX
INC L
JR NZ,GETCH
;Buffer empty so refill it
LD DE,80H
LD C,SETDMA
CALL SYSTEM
EX DE,HL
LD DE,FCB
LD C,READ
CALL SYSTEM
OR A
LD A,1AH ;Possibly signal End of File
JR NZ,NOMOD ;If nothing read
GETCH:
LD A,(HL)
NOMOD:
EXX
LD (CHR),A
RET
MROPS:
PUSH BC ;Save type flags
CALL GETOP
PUSH DE ;Save first operand
CALL GETOP2
POP HL ;First op in BX, second op in DX
LD A,SREG ;Check for a segment register
CP H
JR Z,SEGCHK
CP D
JR Z,SEGCHK
LD A,CONST ;Check if the first operand is immediate
LD C,26
CP H
JR Z,ERROR ;Error if so
POP BC ;Restore type flags
CP D ;If second operand is immediate, then done
RET Z
LD A,UNDEFID ;Check for memory reference
CP H
JR Z,STORE ;Is destination memory?
CP D
JR Z,LOAD ;Is source memory?
BIT 0,C ;Check if register-to-register operation OK
LD C,27
JR Z,ERROR
LD A,D
CP H ;Registers must be of same length
RR:
LD C,22
JR NZ,ERROR
RR1:
AND 1 ;Get register length (1=16 bits)
OR B ;Or in to OP code
CALL PUT ;And write it
POP BC ;Dump return address
LD A,L
ADD A,A ;Rotate register number into middle position
ADD A,A
ADD A,A
OR 0C0H ;Set register-to-register mode
OR E ;Combine with other register number
JP PUT
SEGCHK:
;Come here if at least one operand is a segment register
POP BC ;Restore flags
BIT 3,C ;Check if segment register OK
LD C,22
JR Z,ERROR
LD BC,8E03H ;Segment register move OP code
LD A,UNDEFID
CP D ;Check if source is memory
JR Z,LOAD
CP H ;Check if destination is memory
JR Z,STORE
LD A,XREG
SUB D ;Check if source is 16-bit register
JR Z,RR ;If so, AL must be zero
RES 1,B ;Change direction
EX DE,HL ;Flip which operand is first and second
LD A,XREG
SUB D ;Let RR perform finish the test
JR RR
STORE:
BIT 2,C ;Check if storing is OK
JR NZ,STERR
EX DE,HL ;If so, flip operands
RES 1,B ; and zero direction bit
LOAD:
LD D,25
CP H ;Check if memory-to-memory
JR Z,MRERR
LD A,H
CP REG ;Check if 8-bit operation
JR NZ,XRG
LD D,22
BIT 0,C ;See if 8-bit operation is OK
JR Z,MRERR
XRG:
LD A,E
SUB 6 ;Check for R/M mode 6 and register 0
OR L ; meaning direct load/store of accumulator
JR NZ,NOTAC
BIT 3,C ;See if direct load/store of accumulator
JR Z,NOTAC ; means anything in this case
; Process direct load/store of accumulator
LD A,B
AND 2 ;Preserve direction bit only
XOR 2 ; but flip it
OR 0A0H ;Combine with OP code
LD B,A
LD A,H ;Check byte/word operation
AND 1
OR B
POP BC ;Dump return address
JP PUTADD ;Write the address
NOTAC:
LD A,H
AND 1 ;Get byte/word bit
AND C ;But don't use it in word-only operations
OR B ;Combine with OP code
CALL PUT
LD A,L
ADD A,A ;Rotate to middle position
ADD A,A
ADD A,A
OR E ;Combine register field
POP BC ;Dump return address
JP PUTADD ;Write the address
STERR:
LD D,29
MRERR:
LD C,D
JP ERROR
GETOP2:
;Get the second operand: look for a comma and drop into GETOP
LD A,(SYM)
CP ','
LD C,21
JP NZ,ERROR
GETOP:
CALL GETSYM
GETOP1:
;Enter here if we don't need a GETSYM first
CP '[' ;Memory reference?
JR Z,MEM
CP 5 ;Flag ("B", "W", etc.)?
JR Z,FLG
CP REG ;8-Bit register?
JR Z,NREG
CP XREG ;16-Bit register?
JR Z,NREG
CP SREG ;Segment register?
JR Z,NREG
VAL: ;Must be immediate
XOR A ;No addressing modes allowed
VAL1:
CALL GETVAL
LD HL,(CON) ;Defined part
LD (DATA),HL
LD HL,(UNDEF) ;Undefined part
LD (DLABEL),HL
LD E,B
LD D,CONST
LD A,D
RET
NREG:
PUSH DE
CALL GETSYM
POP DE
LD A,D
RET
MEM:
CALL GETSYM
LD A,1
CALL GETVAL
LD A,(SYM)
CP ']'
LD C,24
JP NZ,ERROR
CALL GETSYM
LD HL,(CON)
LD (ADDR),HL
LD HL,(UNDEF)
LD (ALABEL),HL
LD E,B
LD D,UNDEFID
LD A,D
RET
FLG:
CALL GETSYM
CP ','
JR Z,GETOP
JR GETOP1
GETVAL:
EX AF,AF'
PUSH HL
LD HL,0
LD (CON),HL
LD (UNDEF),HL
POP HL
LD A,(SYM)
CP '+'
JR Z,PLSMNS
CP '-'
JR Z,PLSMNS
LD B,'+'
PUSH BC
JR OPERATE
PLSMNS:
PUSH AF
EX AF,AF'
SET 2,A ;Flag that a sign was found
EX AF,AF'
CALL GETSYM
OPERATE:
CP CONST
JP Z,CVAL
CP UNDEFID
JP Z,UVAL
CP '"'
JP Z,STRING
CP '''
JP Z,STRING
CP XREG ;Only 16-bit register may index
LD C,20
JP NZ,ERROR
EX AF,AF'
BIT 0,A ;Check to see if indexing is OK
LD C,1
JP Z,ERROR
EX AF,AF'
LD A,E
LD C,3
CP 3 ;Check for BX
JR Z,BXJ
SUB 5 ;Check for BP
JR Z,BPJ
DEC A ;Check for SI
LD C,4
JR Z,SIJ
DEC A ;Check for DI
JR Z,DIJ
LD C,2 ;Invalid base/index register
JP ERROR
DIJ:
EX AF,AF'
BIT 4,A ;Check if already seen index register
JP NZ,ERROR
OR 30H ;Flag seeing index register DI
JR LPCHK
SIJ:
EX AF,AF'
BIT 4,A ;Check if already seen index register
JP NZ,ERROR
SET 4,A ;Flag seeing index register SI
JR LPCHK
BXJ:
EX AF,AF'
BIT 7,A ;Check if already seen base register
JP NZ,ERROR
SET 7,A ;Flag seeing base register BX
JR LPCHK
BPJ:
EX AF,AF'
BIT 7,A ;Check if already seen base register
JP NZ,ERROR
OR 0C0H ;Flag seeing base register BP
LPCHK:
EX AF,AF'
POP AF ;Get operator
CP '-' ;Can't subtract a register
LD C,5
JP Z,ERROR
NEXTER:
EX AF,AF'
SET 2,A ;Flag that a term was processed
EX AF,AF'
CALL GETSYM
CP '+'
JR Z,PLSMNS
CP '-'
JP Z,PLSMNS
EX AF,AF'
LD B,0
BIT 4,A ;Test INDEX bit
RLA ;BASE bit (zero flag not affected)
JR Z,NOIND ;Jump if not indexed, with BASE bit in carry
CCF
RL B
RLA ;BP bit
RL B
RLA ;DI bit
RL B ;The low 3 bits now have indexing mode
MODE:
LD HL,(UNDEF)
LD A,H
OR L
SET 7,B ;If undefined label, force 16-bit displacement
RET NZ
LD HL,(CON)
CALL SIGNEXT ;Check if 8-bit with sign extended
RET NZ ;If not, use 16-bit displacement
RES 7,B ;Reset 16-bit displacement
SET 6,B ;Set 8-bit displacement
LD A,H
OR L
RET NZ ;Use it if not zero displacement
LD A,B
AND 7 ;Specify no displacement
LD B,A
CP 6 ;Check for BP+0 addressing mode
RET NZ
SET 6,B ;If BP+0, use 8-bit displacement
RET
SIGNEXT:
LD A,H
OR A
JR Z,HIZERO
INC A
RET NZ
HIZERO:
LD A,L
XOR H
AND 80H
RET
NOIND:
LD B,6 ;Try direct address mode
RET NC ;If no base register, that's right
RLA ;Check BP bit
JR C,MODE
INC B ;If not, must be BX
JR MODE
CVAL:
LD HL,(CON)
POP AF
CP '-'
JR NZ,ADDCON
SBC HL,DE
SETCON:
LD (CON),HL
JR NEXTER
ADDCON:
ADD HL,DE
JR SETCON
UVAL:
EX AF,AF'
LD C,6
BIT 3,A ;Check if undefined label has been seen
JP NZ,ERROR
SET 3,A ;Flag seeing undefined label
EX AF,AF'
LD (UNDEF),HL
POP AF
CP '+' ;Undefined label may only be added
LD C,5
JP NZ,ERROR
JR NEXTER
GETSYM:
CALL GETSY
LD A,(SYM)
RET
SCANB:
LD A,(CHR)
SCANT:
CP ' '
JR Z,NEXB
CP 9
RET NZ
NEXB:
CALL NEXTCHR
JR SCANT
DOLLAR:
LD DE,(OLDPC)
LD A,CONST
LD (SYM),A
JP NEXTCHR
GETSY:
CALL SCANB
CP '$'
JR Z,DOLLAR
LD (SYM),A
OR 20H
CP 'z'+1
JP NC,NEXTCHR
CP 'a'
JP NC,LETTER
CP '9'+1
JP NC,NEXTCHR
CP '0'
JP C,NEXTCHR
LD HL,SYM
LD (HL),CONST
CALL READID
DEC HL
LD A,(HL)
LD C,7
LD HL,0
CP 'h'
JR Z,HEX
INC C
LD IX,ID
DEC:
LD A,(IX)
INC IX
CP '9'+1
JP NC,ERROR
SUB '0'
LD D,H
LD E,L
ADD HL,HL
ADD HL,HL
ADD HL,DE
ADD HL,HL
LD E,A
LD D,0
ADD HL,DE
DJNZ DEC
EX DE,HL
RET
STRING:
LD B,A
LD A,(CHR)
CP B
LD C,35
LD E,A
LD D,0
CALL Z,ZERLEN
CALL GETCHR
EX AF,AF'
LD C,37
BIT 1,A
JP Z,ERROR
BIT 2,A
LD C,38
JP NZ,ERROR
EX AF,AF'
STRGDAT:
LD A,E
CP EOL
LD C,39
JP Z,ERROR
CALL PUT
LD A,(DATSIZ)
OR A
JR NZ,BYTSIZ
LD A,D
CALL PUT
BYTSIZ:
LD A,(CHR)
LD E,A
CALL GETCHR
JR STRGDAT
ZERLEN:
CALL NEXTCHR
CP B
JP NZ,ERROR
RET
GETCHR:
CALL NEXTCHR
CP B
RET NZ
CALL NEXTCHR
CP B
RET Z
POP HL
JP CVAL
HEX:
LD DE,ID
DEC B
HEX1:
LD A,(DE)
INC DE
SUB '0'
CP 10
JR C,GOTIT
CP 'g'-'0'
JP NC,ERROR
SUB 'a'-10-'0'
GOTIT:
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD A,L
LD L,A
DJNZ HEX1
EX DE,HL
RET
GETLET:
CALL SCANB
CP EOL
SCF
RET Z
CP ';'
SCF
RET Z
LD C,10
OR 20H
CP 'a'
JP C,ERROR
CP 'z'+1
JP NC,ERROR
READID:
LD HL,ID
LD B,0
MOREID:
LD (HL),A
INC B
INC HL
CALL NEXTCHR
CP '0'
JR C,NOMORE
OR 20H
CP 'z'+1
JR NC,NOMORE
CP '9'+1
JR C,MOREID
CP 'a'
JR NC,MOREID
NOMORE:
LD C,A
LD A,B
LD (LENID),A
OR A
LD A,C
RET
LETTER:
CALL READID
LD A,B
DEC A
JR NZ,NOFLG
LD A,(ID)
CP 'l'
LD C,0
LD DE,LONG
JR Z,BWFLAG
CP 'b'
LD DE,FLAG
JR Z,BWFLAG
CP 'w'
LD C,1
JR Z,BWFLAG
XOR A
NOFLG:
DEC A
PUSH HL
CALL Z,REGCHK
POP HL
LD A,D
CALL NZ,LOOKRET
SYMSAV:
LD (SYM),A
RET
BWFLAG:
EX DE,HL
LD A,(HL)
INC A
LD (HL),C
LD C,32
JP NZ,ERROR
LD A,5
JR SYMSAV
REGCHK:
LD HL,ID
LD C,(HL)
INC HL
LD A,(HL)
LD HL,REGTAB
LD D,XREG
LD E,0
CP 'x'
JR Z,SCANREG
LD D,REG
CP 'l'
JR Z,SCANREG
LD E,4
CP 'h'
JR Z,SCANREG
LD D,SREG
LD E,0
LD HL,SEGTAB
CP 's'
JR Z,SCANREG
LD D,XREG
CP 'p'
JR Z,PREG
CP 'i'
RET NZ
LD E,6
LD A,C
CP 's'
RET Z
INC E
CP 'd'
RET
PREG:
LD E,4
LD A,C
CP 's'
RET Z
INC E
CP 'b'
RET
SCANREG:
LD A,C
LD BC,4
CPIR
RET NZ
LD A,C
ADD A,E
LD E,A
XOR A
RET
REGTAB: DB 'bdca'
SEGTAB: DB 'dsce'
LOOK:
LD B,(HL)
INC HL
LD DE,ID
CALL CPSLP
RET Z
XOR 80H
LD C,A
DEC HL
LD A,(HL)
XOR 80H
CP C
JR NC,SMALL
INC B
INC B
SMALL:
LD E,B
LD D,0
ADD HL,DE
LD E,(HL)
INC HL
LD D,(HL)
LD A,D
OR E
SCF
RET Z
EX DE,HL
JR LOOK
LOOKRET:
LD A,B
CP 3 ;RET has 3 letters
JR NZ,LOOKUP
DEC HL
SET 7,(HL)
LD DE,RETSTR+2
CHKRET:
LD A,(DE)
CP (HL)
JR NZ,LOOKIT
DEC HL
DEC DE
DJNZ CHKRET
LD DE,(LSTRET)
LD A,E
AND D
INC A
JR Z,ALLRET
LD HL,(PC)
SBC HL,DE
CALL SIGNEXT
LD A,1
RET Z
ALLRET:
LD HL,(RETPT)
LD A,H
OR L
LD A,0
RET NZ
LD HL,(HEAP)
DEC HL
DEC HL
DEC HL
LD (HEAP),HL
XOR A
LD (HL),A
LD (RETPT),HL
RET
LOOKUP:
DEC HL
SET 7,(HL)
LOOKIT:
LD HL,(BASE)
LD A,H
OR L
JR Z,EMPTY
CALL LOOK
JR C,ENTER
LD DE,4
ADD HL,DE
LD A,(HL)
OR A
RET Z
INC HL
LD E,(HL)
INC HL
LD D,(HL)
RET
ENTER:
PUSH HL ;Save pointer to link field
CALL CREATE ;Add the node
EX (SP),HL
LD (HL),D ;Link new node
DEC HL
LD (HL),E
POP HL
RET ;Zero was set by CREATE
EMPTY:
CALL CREATE
LD (BASE),DE
RET
CREATE:
LD A,(LENID)
ADD A,8 ;Storage needed for the node
LD HL,(HEAP)
LD E,A
LD D,0
SBC HL,DE ;Heap grows downward
LD (HEAP),HL
EX DE,HL
LD HL,(CODE) ;Check to make sure there's enough
SBC HL,DE
JP NC,ABORT
PUSH DE
LD HL,LENID
LD C,(HL)
INC C
LD B,0
LDIR ;Move identifier and length into node
LD B,4
EX DE,HL
NILIFY:
LD (HL),C ;Zero left and right links
INC HL
DJNZ NILIFY
XOR A ;Set zero flag
LD (HL),A ;Zero defined flag
POP DE ;Restore pointer to node
RET
CPSLP:
LD A,(DE)
CP (HL)
INC DE
INC HL
RET NZ
DJNZ CPSLP
RET
GETLAB:
LD HL,0
LD (LABPT),HL
LD A,-1
LD (FLAG),A
LD (LONG),A
LD D,0
LD A,(CHR)
CP ' '+1
JR C,NOT1
SET 0,D
NOT1:
CALL GETLET
RET C
CP ':'
JR NZ,LABCHK
CALL NEXTCHR
JR LABEL
LABCHK:
OR A
BIT 0,D
RET Z
LABEL:
LD A,(CHKLAB)
OR A
JP NZ,GETLET
CALL LOOKUP
LD C,11
JP NZ,ERROR
LD DE,(PC)
LD (HL),1
INC HL
LD (HL),E
LD (LABPT),HL
INC HL
LD (HL),D
JP GETLET
ASMLIN:
LD HL,(PC)
LD (OLDPC),HL
CALL GETLAB
JP C,ENDLN
LD HL,LENID
LD A,(HL)
LD C,12
SUB 2
LD B,A
JP C,ERROR
CP 5
JP NC,ERROR
INC HL
LD A,(HL)
SUB 'a'
LD C,A
ADD A,A
ADD A,A
ADD A,C
ADD A,B
ADD A,A
LD HL,OPTAB
LD E,A
LD D,0
ADD HL,DE
LD E,(HL)
INC HL
LD D,(HL)
EX DE,HL
INC B
LD C,B
LD A,(HL)
INC HL
OR A
JR Z,OPERR
FINDOP:
LD B,C
EX AF,AF'
LD DE,ID+1
CALL CPSLP
JR Z,HAVOP
LD D,0
LD E,B
INC E
INC E
ADD HL,DE
EX AF,AF'
DEC A
JR NZ,FINDOP
OPERR:
LD C,12
JP ERROR
HAVOP:
LD E,(HL)
INC HL
LD D,(HL)
INC HL
LD A,(HL) ;Get opcode
EX DE,HL
JP (HL)
GRP1:
LD BC,8A09H
CALL MROPS
LD BC,0C6H
LD A,H
CP UNDEFID
CALL Z,STIMM
AND 1
JR Z,BYTIMM
LD A,0B8H
OR L
CALL PUT
JP PUTWOR
BYTIMM:
LD A,0B0H
OR L
CALL PUT
JP PUTBYT
IMMED:
LD A,H
CP UNDEFID
JR Z,STIMM
LD A,L
OR A
RET Z
LD A,H
CALL IMM
OR 0C0H
CALL PUT
FINIMM:
LD A,C
POP BC
BIT 0,A
JR Z,PUTBYT
CP 83H
JR Z,PUTBYT
JR PUTWOR
STIMM:
LD A,(FLAG)
CALL IMM
CALL PUTADD
JR FINIMM
IMM:
AND 1
OR C
LD C,A
CALL PUT
LD A,B
AND 38H
OR L
RET
PUT:
PUSH HL
PUSH BC
LD B,0 ;Flag as pure code
CALL GEN
POP BC
POP HL
RET
GEN:
CALL PUTINC ;Save it and bump code pointer
GEN1:
LD A,(RELOC)
RL B
RLA
RL B
RLA
LD (RELOC),A
LD HL,BCOUNT
DEC (HL)
RET NZ
LD (HL),4
LD HL,RELOC
LD A,(HL)
LD (HL),0
LD (IY),A
LD HL,(CODE)
PUSH HL
POP IY
INC HL
LD (CODE),HL
RET
PUTINC:
PUSH HL
LD HL,(PC)
INC HL
LD (PC),HL
JR PUTCD1
PUTCD:
PUSH HL
PUTCD1: LD HL,(CODE)
LD (HL),A
INC HL
LD (CODE),HL
POP HL
RET
PUTWOR:
PUSH BC
LD B,80H
PUSH DE
PUSH HL
JR PUTBW
PUTBYT:
PUSH BC
LD B,40H
PUSH DE
PUSH HL
LD HL,(DLABEL)
LD A,H
OR L
JR NZ,PUTBW
LD HL,(DATA)
OR H
JR Z,PUTBW
INC H
JR Z,PUTBW
LD C,31
JP ERROR
PUTBW:
LD DE,(DLABEL)
LD HL,(DATA)
PUTCHK:
LD A,D
OR E
JR Z,NOUNDEF
LD A,E
CALL PUTCD
LD A,D
CALL PUTCD
LD A,L
CALL PUTINC
LD A,H
BIT 7,B
JR Z,SMPUT
CALL GEN
JR PRET
SMPUT:
CALL PUTCD
CALL GEN1
PRET:
POP HL
POP DE
POP BC
RET
NOUNDEF:
LD A,L
LD C,H
PUSH BC
LD B,0
CALL GEN
POP BC
LD A,C
BIT 7,B
LD B,0
CALL NZ,GEN
JR PRET
PUTADD:
PUSH BC
PUSH DE
PUSH HL
LD B,0
LD C,A
CALL GEN ;Save the addressing mode as pure code
LD A,C
LD B,80H
AND 0C7H
CP 6
JR Z,TWOBT ;Direct address?
AND 0C0H
JR Z,PRET ;Indirect through reg, no displacement?
CP 0C0H
JR Z,PRET ;Register to register operation?
LD B,A ;Save whether one- or two-byte displacement
TWOBT:
LD HL,(ADDR)
LD DE,(ALABEL)
JR PUTCHK
GRP2:
CALL GETOP
LD BC,0FF30H
CP UNDEFID
JR Z,PMEM
LD B,50H
CP XREG
JR Z,PXREG
LD B,6
CP SREG
JP Z,PACKREG
LD C,20
JP ERROR
PMEM:
LD A,B
CALL PUT
LD A,C
OR E
JR PUTADD
PXREG:
LD A,B
OR E
JP PUT
GRP3:
CALL GETOP
PUSH DE
CALL GETOP2
POP HL
LD BC,8614H
LD A,SREG
CP H
JP Z,ERROR
CP D
JP Z,ERROR
LD A,CONST
CP H
JP Z,ERROR
CP D
JP Z,ERROR
LD A,UNDEFID
CP H
JR Z,EXMEM
CP D
JR Z,EXMEM1
LD A,H
CP D
LD C,22
JP NZ,ERROR
CP XREG
CALL NZ,RR1 ;RR1 never returns
LD A,L
OR A
JR Z,EXACC
EX DE,HL
LD A,L
OR A
LD A,H
CALL NZ,RR1
EXACC:
LD A,90H
OR E
JP PUT
EXMEM:
EX DE,HL
EXMEM1:
CP H
JP Z,ERROR
LD C,1 ;Flag word as OK
CALL NOTAC ;NOTAC never returns
GRP4:
PUSH AF
CALL GETOP
POP BC
CP CONST
JR Z,FIXED
SUB XREG
DEC E
DEC E
OR E
LD C,20
JP NZ,ERROR
LD A,B
OR 8
JP PUT
FIXED:
LD A,B
CALL PUT
JP PUTBYT
GRP5:
PUSH AF
CALL GETOP
CP CONST
JP NZ,ERROR
LD HL,(DLABEL)
LD A,H
OR L
LD C,30
JP NZ,ERROR
LD HL,(DATA)
POP AF
OR A
JR Z,ORG
DEC A
JR Z,DSJ
DEC A
JR Z,EQU
DEC A
JP NZ,IF
PUTOP:
LD A,-3
JR NEWLOC
ALIGN:
LD A,(PC)
AND 1
RET Z
LD HL,1
DSJ:
EX DE,HL
LD HL,(PC)
ADD HL,DE
LD (PC),HL
EX DE,HL
LD A,-4
JR NEWLOC
EQU:
EX DE,HL
LD HL,(LABPT)
LD A,H
OR L
LD C,34
JP Z,ERROR
LD (HL),E
INC HL
LD (HL),D
RET
ORG:
LD (PC),HL
LD A,-2
NEWLOC:
CALL PUTCD
LD A,L
CALL PUTCD
LD A,H
CALL PUTCD
LD B,0C0H
JP GEN1
GRP6:
LD B,A
LD C,4
CALL MROPS
LD C,23
JP ERROR
GRP7:
LD B,A
LD C,1
CALL MROPS
LD C,80H
LD DE,(DLABEL)
LD A,D
OR E
JP NZ,ACCIMM
EX DE,HL
LD HL,(DATA)
CALL SIGNEXT
EX DE,HL
JP NZ,ACCIMM
SET 1,C
JP ACCIMM
GRP8:
LD C,A
LD B,0FEH
JR ONEOP
GRP9:
LD C,A
LD B,0F6H
ONEOP:
PUSH BC
CALL GETOP
ONE:
LD C,26
CP CONST
JP Z,ERROR
CP SREG
LD C,22
JP Z,ERROR
POP BC
CP UNDEFID
JR Z,MOP
AND 1
JR Z,ROP
BIT 0,C
JR Z,ROP
LD A,C
AND 0F8H
OR E
JP PUT
MOP:
LD A,(FLAG)
AND 1
OR B
CALL PUT
LD A,C
AND 38H
OR E
JP PUTADD
ROP:
OR B
CALL PUT
LD A,C
AND 38H
OR 0C0H
OR E
JP PUT
GRP10:
LD C,A
LD B,0F6H
PUSH BC
CALL GETOP
LD C,20
LD A,E
OR A
JP NZ,ERROR
LD A,D
CP XREG
JR Z,G10
CP REG
JP NZ,ERROR
G10:
PUSH AF
CALL GETOP
POP AF
AND 1
LD (FLAG),A
LD A,D
JR ONE
GRP11:
CALL PUT
LD A,0AH
JP PUT
GRP12:
LD C,A
LD B,0D0H
PUSH BC
CALL GETOP
LD A,(SYM)
CP ','
LD A,D
JR NZ,ONE
PUSH DE
CALL GETOP
SUB REG
LD C,20
DEC E
OR E
JP NZ,ERROR
POP DE
LD A,D
POP BC
SET 1,B
PUSH BC
JP ONE
GRP13:
LD B,A
LD C,1
CALL MROPS
LD C,80H
ACCIMM:
CALL IMMED
SET 2,B
RES 1,B
AIMM:
LD A,H
AND 1
PUSH AF
OR B
CALL PUT
POP AF
JP Z,PUTBYT
JP PUTWOR
GRP14:
PUSH AF
CALL GETOP
CP CONST
JR Z,DIRECT
LD C,20
CP REG
JP Z,ERROR
CP SREG
JP Z,ERROR
CP XREG
JR NZ,NOTRG
SET 6,E
SET 7,E
NOTRG:
LD A,0FFH
CALL PUT
POP AF
AND 38H
OR E
LD B,A
LD A,(LONG)
OR A
LD A,B
JP Z,PUTADD
RES 3,A
JP PUTADD
DIRECT:
LD A,(SYM)
CP ','
JR Z,LONGJ
POP AF
DEC A
CP 0E9H
JR Z,GOTOP
LD A,0E8H
GOTOP:
CALL PUT
LD HL,(DATA)
LD DE,(PC)
INC DE
INC DE
OR A
SBC HL,DE
LD (DATA),HL
JP PUTWOR
LONGJ:
POP AF
CALL PUT
CALL PUTWOR
CALL GETOP
LD C,20
CP CONST
JP NZ,ERROR
JP PUTWOR
GRP16:
PUSH AF
CALL GETSYM
CP 5
JR Z,LONGR
CP EOL
JR Z,NODEC
CP ';'
JR Z,NODEC
GETSP:
CALL GETOP1
POP BC
CP CONST
LD C,20
JP NZ,ERROR
LD A,B
AND 0FEH
CALL PUT
JP PUTWOR
LONGR:
LD A,(LONG)
OR A
JR NZ,NOTLON
POP AF
OR 8
PUSH AF
NOTLON:
CALL GETSYM
CP EOL
JR Z,DORET
CP ';'
JR Z,DORET
CP ','
CALL Z,GETSYM
JR GETSP
NODEC:
LD HL,(PC)
LD (LSTRET),HL
EX DE,HL
LD HL,(RETPT)
LD A,H
OR L
JR Z,DORET
LD (HL),1
INC HL
LD (HL),E
INC HL
LD (HL),D
LD HL,0
LD (RETPT),HL
DORET:
POP AF
JP PUT
GRP17:
CALL PUT
CALL GETOP
CP CONST
LD C,20
JP NZ,ERROR
LD HL,(DATA)
LD DE,(PC)
INC DE
SBC HL,DE
LD (DATA),HL
CALL PUTBYT
LD HL,(DLABEL)
LD A,H
OR L
RET NZ
LD HL,(DATA)
CALL SIGNEXT
RET Z
LD C,31
JP ERROR
RET
GRP18:
CALL GETOP
CP CONST
LD C,20
JP NZ,ERROR
LD HL,(DLABEL)
LD A,H
OR L
JR NZ,GENINT
LD HL,(DATA)
LD DE,3
SBC HL,DE
JR NZ,GENINT
LD A,0CCH
JP PUT
GENINT:
LD A,0CDH
CALL PUT
JP PUTBYT
GRP19: ;ESC opcode
LD BC,0D800H
JP ONEOP
GRP20:
LD B,A
LD C,1
CALL MROPS
LD C,0F6H
CALL IMMED
LD B,0A8H
JP AIMM
GRP21:
CALL GETOP
CP SREG
LD C,28
JP NZ,ERROR
LD B,26H
PACKREG:
LD A,E
ADD A,A
ADD A,A
ADD A,A
OR B
JP PUT
GRP22:
CALL GETOP
LD BC,8F00H
CP UNDEFID
JP Z,PMEM
LD B,58H
CP XREG
JP Z,PXREG
LD B,7
CP SREG
JR Z,PACKREG
LD C,20
JP ERROR
GRP23:
LD (DATSIZ),A
GETDAT:
CALL GETSYM
LD A,2
CALL VAL1
LD A,(SYM)
CP ','
LD A,(DATSIZ)
JR NZ,ENDDAT
CALL SAVDAT
JR GETDAT
ENDDAT:
CP 2
JR NZ,SAVDAT
LD HL,(DATA)
SET 7,L
LD (DATA),HL
SAVDAT:
OR A
JP NZ,PUTBYT
JP PUTWOR
IF:
LD A,H
OR L
LD A,1
JR Z,SKIPCD
LD (IFFLG),A
RET
SKIPCD:
LD (CHKLAB),A
SKIPLP:
XOR A
CALL NEXLIN
CALL NEXTCHR
CP 1AH
JR Z,END
CALL GETLAB
JR C,SKIPLP
LD HL,LENID
LD DE,IFEND
LD B,(HL)
INC B
CALL CPSLP
JR NZ,SKIPLP
XOR A
LD (CHKLAB),A
RET
ENDIF:
LD HL,IFFLG
LD A,(HL)
LD (HL),0
LD C,36
OR A
JP Z,ERROR
RET
;*********************************************************************
; PASS 2
;*********************************************************************
END:
LD C,4
WREND:
LD B,0FFH
LD A,B
CALL GEN
DEC C
JR NZ,WREND
LD A,(LSTFCB)
CP 'Z'
JR Z,NOREOPN
CALL ADDEXT
LD DE,FCB
LD C,OPEN
CALL SYSTEM
LD HL,0FFH
EXX
NOREOPN:
LD A,-5
LD (HEXCNT),A ;FLAG HEX BUFFER AS EMPTY
LD (SKPFLG),A
LD HL,HEXBUF
LD (HEXPNT),HL
LD HL,LSTBUF
LD (LSTPNT),HL
LD HL,0
LD (ERRCNT),HL
LD (PC),HL
LD HL,OBJECT
LD (HEXADD),HL
XOR A
LD (FCB+20H),A ;Set NEXT RECORD field to zero
LD (COUNT),A
CALL STRTLIN
LD HL,START
NEXBT:
LD B,4
LD C,(HL) ;Get flag byte
INC HL ;Point to code
CDLP:
RL C ;Get high bit
JR C,TESTTYP ;Word fixup or special
RL C
JR C,DEFBYT ;Byte fixup
LD A,(HL)
OBJBT:
CALL SAVCD
NEXCD:
INC HL
DJNZ CDLP ;Still have codes left?
JR NEXBT
TESTTYP:
RL C
JP NC,DEFWRD
LD A,(HL)
CP -10
JP NC,SPCFUN
PUSH BC
PUSH HL
LD HL,COUNT
LD A,6
SUB (HL)
LD (HL),0
LD B,A
LD A,' '
JR Z,NOFIL
BLNK: ;Put in 3 blanks for each byte not present
CALL LIST
CALL LIST
CALL LIST
DJNZ BLNK
NOFIL:
CALL OUTLIN
POP HL
LD A,(HL)
PUSH HL
CALL REPERR
LD A,(ERR)
CALL REPERR
CALL STRTLIN
POP HL
POP BC
JR NEXCD
OUTLIN:
CALL LIST
LD A,(LSTFCB)
CP 'Z'
RET Z
LD HL,LINFLG
LD A,(HL)
LD (HL),-1
OR A
JR NZ,CRLF ;Output line only if first time
OUTLN:
CALL NEXTCHR
CALL LIST
CP 10 ;Output until linefeed found
JR NZ,OUTLN
RET
PRTCNT:
LD HL,ERCNTM
CALL PRINT
LD HL,(ERRCNT)
CALL CONV10
CALL PRNT10
CRLF:
LD A,13
CALL LIST
LD A,10
JR LIST
DEFBYT:
CALL FIXUP
EX DE,HL
CALL SIGNEXT ;See if in range +127 to -128
EX DE,HL
JR Z,OBJBTE ;If so, it's always OK
LD A,D
OR A ;Check for range +255 to -256
JR Z,CHKJMP
INC A
JR Z,CHKJMP
RNGERR:
LD A,101 ;Value out of range
LD (ERR),A
OBJBTE:
LD A,E
JP OBJBT
CHKJMP:
;Check for short jump. If so, we're out of range; otherwise we're OK
LD A,(COUNT)
DEC A ;Only one other byte on line?
JR NZ,OBJBTE ;Can't be short jump if not
LD A,(PREV) ;Get the first byte of this line
CP 0EBH ;Direct short jump?
JR Z,RNGERR
AND 0FCH
CP 0E0H ;LOOP or JCXZ instruction?
JR Z,RNGERR
AND 0F0H
CP 70H ;Conditional jump?
JR Z,RNGERR
JR OBJBTE
DEFWRD:
CALL FIXUP
LD A,E
CALL SAVCD
LD A,D
JP OBJBT
FIXUP:
PUSH BC
LD E,(HL) ;Get pointer to symbol
INC HL
LD D,(HL)
INC HL
EX DE,HL
LD A,(HL) ;Whether symbol was defined
INC HL
LD C,(HL) ;Get symbol value
INC HL
LD B,(HL)
EX DE,HL
LD E,(HL) ;Get constant part
INC HL
LD D,(HL)
EX DE,HL
ADD HL,BC ;Add symbol value to constant part
POP BC
EX DE,HL
OR A ;See if symbol got defined
RET NZ
LD A,100 ;Undefined - flag error
LD (ERR),A
LD DE,0
RET
STRTLIN:
XOR A
LD (ERR),A
LD (LINFLG),A
LD HL,(PC)
LD A,H
CALL PHEX
LD A,L
PHEXB:
CALL PHEX
LD A,' '
LIST:
PUSH AF
LD A,(LSTFCB)
CP 'Z'
JR Z,OUTRET
CP 'X'
JR Z,LSTCON
POP AF
PUSH AF
AND 7FH
PUSH HL
LD HL,(LSTPNT)
LD (HL),A
CALL INCBUF
LD (LSTPNT),HL
JR NZ,HAVSPC
LD HL,LSTBUF
LD (LSTPNT),HL
PUSH DE
EX DE,HL
PUSH BC
LD C,SETDMA
CALL 5
LD DE,LSTFCB
LD C,SEQWRT
CALL 5
POP BC
POP DE
HAVSPC:
POP HL
OUTRET:
POP AF
RET
LSTCON:
POP AF
PUSH AF
CALL OUTA
POP AF
RET
PHEX:
LD B,A
CALL UHALF
CALL LIST
LD A,B
CALL LHALF
JR LIST
SPCFUN:
INC A ;End of file?
JR Z,FINI
INC HL
LD E,(HL) ;Get address
INC HL
LD D,(HL)
PUSH HL
INC A ;ORG?
JR Z,DORG
INC A ;PUT?
JR Z,DPUT
DDS:
;Handle DS pseudo-op
LD HL,(PC)
ADD HL,DE
LD (PC),HL
LD HL,(HEXADD)
ADD HL,DE
LD (HEXADD),HL
JR SPEND
DPUT:
;Handle PUT pseudo-op
LD (HEXADD),DE
JR SPEND
DORG:
;Handle ORG pseudo-op
LD (PC),DE
SPEND:
POP HL
JP NEXCD
FINI:
CALL PRTCNT
LD A,(HEXFCB)
CP 'Z'
JR Z,SYMDMP
LD A,(HEXCNT)
CP -5
CALL NZ,ENHEXL
LD A,':'
CALL PUTCHR
LD B,10
HEXEND:
PUSH BC
LD A,'0'
CALL PUTCHR
POP BC
DJNZ HEXEND
CALL HEXCRLF
CALL NZ,HEXEOF
CALL HEXEOF
LD C,CLOSE
LD DE,HEXFCB
CALL SYSTEM
SYMDMP:
LD A,(SYMFLG)
CP 'S'
JR NZ,ENDSYM
LD HL,SYMMES
CALL PRINT
LD DE,(BASE)
LD A,D
OR E
JR Z,EXIT
LD HL,(HEAP)
LD SP,HL
CALL NODE
ENDSYM:
LD A,(LSTFCB)
CP 'X'
JR Z,EXIT
CP 'Z'
JR Z,ERRCON ;Print error count to console
CALL LSTEOF
LD DE,LSTFCB
LD C,CLOSE
CALL 5
ERRCON:
LD A,'X'
LD (LSTFCB),A
CALL PRTCNT
EXIT: JP 0
RET
LSTEOF:
LD HL,(LSTPNT)
LD DE,LSTBUF
OR A
SBC HL,DE
RET Z
LD A,1AH
CALL LIST
JR LSTEOF
NODE:
EX DE,HL
PUSH HL
LD E,(HL)
LD D,0
INC HL
ADD HL,DE
LD E,(HL)
INC HL
LD D,(HL)
LD A,E
OR D
CALL NZ,NODE
POP HL
LD B,(HL)
INC HL
LD A,SYMWID
SUB B
JR NC,LENOK
LD A,1
LENOK:
LD D,A
WRTSYM:
LD A,(HL)
INC HL
CALL LIST
DJNZ WRTSYM
LD B,D
INC B
LD A,' '
OUTB:
CALL LIST
DJNZ OUTB
INC HL
INC HL
PUSH HL
INC HL
INC HL
INC HL
INC HL
LD A,(HL)
CALL PHEX
DEC HL
LD A,(HL)
CALL PHEX
CALL CRLF
POP HL
LD E,(HL)
INC HL
LD D,(HL)
LD A,D
OR E
JR NZ,NODE
RET
CONV10:
LD B,16
LD DE,0
CONVLP:
ADD HL,HL
LD A,E
ADC A,A
DAA
LD E,A
LD A,D
ADC A,A
DAA
LD D,A
RL C
DJNZ CONVLP
RET
PRNT10:
EX DE,HL
LD B,'0'-' ' ;Enable leading zero suppression
LD A,C
CALL LODIG
LD A,H
CALL HIDIG
LD A,H
CALL LODIG
LD A,L
CALL HIDIG
LD A,L
LD B,0 ;Don't suppress last digit
LODIG:
CALL LHALF
DIGIT:
CP '0'
JR Z,SUPZ
LD B,0 ;Turn off zero suppression if not zero
SUPZ:
SUB B ;Convert leading zeros to blanks
JP LIST
HIDIG:
CALL UHALF
JR DIGIT
HEXEOF:
LD A,1AH
CALL PUTCHR
JR NZ,HEXEOF
RET
SAVCD:
LD (PREV),A
PUSH HL
PUSH BC
PUSH AF
PUSH DE
CALL CODBYT
POP DE
LD HL,COUNT
INC (HL)
LD A,(HL)
CP 7
JR NZ,NOEXT
LD (HL),1
LD A,' '
CALL OUTLIN
LD A,' '
LD B,5
TAB:
CALL LIST
DJNZ TAB
NOEXT:
POP AF
CALL PHEXB
POP BC
LD HL,(PC)
INC HL
LD (PC),HL
LD HL,(HEXADD)
INC HL
LD (HEXADD),HL
POP HL
RET
REPERR:
OR A
RET Z
PUSH AF
LD HL,ERRMES
CALL PRINT
POP AF
CALL PHEX
LD HL,ENDMES
CALL PRINT
LD HL,(ERRCNT)
INC HL
LD (ERRCNT),HL
RET
PRINT:
LD A,(HL)
CALL LIST
OR A
RET M
INC HL
JR PRINT
OUTA:
LD E,A
LD C,2
SYSTEM:
PUSH BC
PUSH DE
PUSH HL
CALL 5
POP HL
POP DE
POP BC
RET
CODBYT:
PUSH AF
LD A,(HEXFCB)
CP 'Z'
JP Z,OUTRET
LD DE,(LASTAD)
LD HL,(HEXADD)
LD (LASTAD),HL
INC DE
LD A,(HEXCNT)
CP -5
JR Z,NEWLIN
OR A
SBC HL,DE
JR Z,AFHEX
CALL ENHEXL
NEWLIN:
LD A,':'
CALL PUTCHR
LD A,-4
LD (HEXCNT),A
XOR A
LD (CHKSUM),A
LD HL,(HEXPNT)
LD (HEXLEN),HL
CALL HEXBYT
LD A,(HEXADD+1)
CALL HEXBYT
LD A,(HEXADD)
CALL HEXBYT
XOR A
CALL HEXBYT
AFHEX:
POP AF
HEXBYT:
LD B,A
LD HL,CHKSUM
ADD A,(HL)
LD (HL),A
LD A,B
CALL UHALF
CALL PUTCHR
LD A,B
CALL LHALF
CALL PUTCHR
LD HL,HEXCNT
INC (HL)
LD A,(HL)
CP 26
RET NZ
ENHEXL:
LD HL,(HEXLEN)
LD B,A
CALL UHALF
LD (HL),A
CALL INCBUF
LD A,B
CALL LHALF
LD (HL),A
LD A,-6
LD (HEXCNT),A
LD A,(CHKSUM)
ADD A,B
NEG
CALL HEXBYT
HEXCRLF:
LD A,13
CALL PUTCHR
LD A,10
PUTCHR:
LD HL,(HEXPNT)
LD (HL),A
CALL INCBUF
LD (HEXPNT),HL
RET NZ
PUSH HL
LD HL,SKPFLG
LD A,(HL)
LD (HL),0 ;Buffer filled, don't skip next time
POP HL
OR A ;Both buffers filled?
RET NZ
LD C,SETDMA
EX DE,HL
CALL SYSTEM
LD DE,HEXFCB
LD C,SEQWRT
CALL SYSTEM
EX DE,HL
OR A
RET Z
LD HL,WRTERR
JP PRERR
UHALF:
RRA
RRA
RRA
RRA
LHALF:
AND 0FH
OR 30H
CP '9'+1
RET C
ADD A,7
RET
INCBUF:
INC HL
PUSH DE
PUSH HL
LD DE,HEXBUF+BUFSIZ
OR A
SBC HL,DE
POP HL
POP DE
RET Z
PUSH DE
PUSH HL
LD DE,LSTBUF+BUFSIZ
OR A
SBC HL,DE
POP HL
POP DE
RET Z
PUSH DE
PUSH HL
LD DE,HEXBUF+BUFSIZ+BUFSIZ
OR A
SBC HL,DE
POP HL
POP DE
RET NZ
LD HL,HEXBUF ;Wrap back to first buffer
RET
NONE: DB 0
; 8086 MNEMONIC TABLE
A3:
DB 7
DB 'dd'
DW GRP7
DB 2
DB 'nd'
DW GRP13
DB 22H
DB 'dc'
DW GRP7
DB 12H
DB 'aa'
DW PUT
DB 37H
DB 'as'
DW PUT
DB 3FH
DB 'am'
DW GRP11
DB 0D4H
DB 'ad'
DW GRP11
DB 0D5H
A5:
DB 1
DB 'lign'
DW ALIGN
DB 0
C3:
DB 7
DB 'mp'
DW GRP7
DB 3AH
DB 'lc'
DW PUT
DB 0F8H
DB 'ld'
DW PUT
DB 0FCH
DB 'li'
DW PUT
DB 0FAH
DB 'mc'
DW PUT
DB 0F5H
DB 'bw'
DW PUT
DB 98H
DB 'wd'
DW PUT
DB 99H
C4:
DB 3
DB 'all'
DW GRP14
DB 9AH
DB 'mpb'
DW PUT
DB 0A6H
DB 'mpw'
DW PUT
DB 0A7H
D2:
DB 5
DB 'b'
DW GRP23
DB 1
DB 'w'
DW GRP23
DB 0
DB 'm'
DW GRP23
DB 2
DB 's'
DW GRP5
DB 1
DB 'i'
DW PUT
DB 0FAH
D3:
DB 4
DB 'ec'
DW GRP8
DB 49H
DB 'iv'
DW GRP10
DB 30H
DB 'aa'
DW PUT
DB 27H
DB 'as'
DW PUT
DB 2FH
D4:
DB 1
DB 'own'
DW PUT
DB 0FDH
E2:
DB 1
DB 'i'
DW PUT
DB 0FBH
E3:
DB 3
DB 'qu'
DW GRP5
DB 2
DB 'sc'
DW GRP19
DB 0D8H
DB 'nd'
DW END
DB 0
E5:
DB 1
DB 'ndif'
DW ENDIF
DB 0
H3:
DB 1
DB 'lt'
DW PUT
DB 0F4H
H4:
DB 1
DB 'alt'
DW PUT
DB 0F4H
I2:
DB 2
DB 'n'
DW GRP4
DB 0E4H
DB 'f'
DW GRP5
DB 4
I3:
DB 4
DB 'nc'
DW GRP8
DB 41H
DB 'nb'
DW GRP4
DB 0E4H
DB 'nw'
DW GRP4
DB 0E5H
DB 'nt'
DW GRP18
DB 0CCH
I4:
DB 4
DB 'mul'
DW GRP10
DB 28H
DB 'div'
DW GRP10
DB 38H
DB 'ret'
DW PUT
DB 0CFH
DB 'nto'
DW PUT
DB 0CEH
J2:
DB 10
DB 'p'
DW GRP17
DB 0EBH
DB 'z'
DW GRP17
DB 74H
DB 'e'
DW GRP17
DB 74H
DB 'l'
DW GRP17
DB 7CH
DB 'b'
DW GRP17
DB 72H
DB 'a'
DW GRP17
DB 77H
DB 'g'
DW GRP17
DB 7FH
DB 'o'
DW GRP17
DB 70H
DB 's'
DW GRP17
DB 78H
DB 'c'
DW GRP17
DB 72H
J3:
DB 17
DB 'mp'
DW GRP14
DB 0EAH
DB 'nz'
DW GRP17
DB 75H
DB 'ne'
DW GRP17
DB 75H
DB 'nl'
DW GRP17
DB 7DH
DB 'ge'
DW GRP17
DB 7DH
DB 'nb'
DW GRP17
DB 73H
DB 'ae'
DW GRP17
DB 73H
DB 'nc'
DW GRP17
DB 73H
DB 'ng'
DW GRP17
DB 7EH
DB 'le'
DW GRP17
DB 7EH
DB 'na'
DW GRP17
DB 76H
DB 'be'
DW GRP17
DB 76H
DB 'pe'
DW GRP17
DB 7AH
DB 'np'
DW GRP17
DB 7BH
DB 'po'
DW GRP17
DB 7BH
DB 'no'
DW GRP17
DB 71H
DB 'ns'
DW GRP17
DB 79H
J4:
DB 5
DB 'cxz'
DW GRP17
DB 0E3H
DB 'nge'
DW GRP17
DB 7CH
DB 'nae'
DW GRP17
DB 72H
DB 'nbe'
DW GRP17
DB 77H
DB 'nle'
DW GRP17
DB 7FH
L3:
DB 3
DB 'ea'
DW GRP6
DB 8DH
DB 'ds'
DW GRP6
DB 0C5H
DB 'es'
DW GRP6
DB 0C4H
L4:
DB 5
DB 'oop'
DW GRP17
DB 0E2H
DB 'odb'
DW PUT
DB 0ACH
DB 'odw'
DW PUT
DB 0ADH
DB 'ahf'
DW PUT
DB 9FH
DB 'ock'
DW PUT
DB 0F0H
L5:
DB 2
DB 'oope'
DW GRP17
DB 0E1H
DB 'oopz'
DW GRP17
DB 0E1H
L6:
DB 2
DB 'oopne'
DW GRP17
DB 0E0H
DB 'oopnz'
DW GRP17
DB 0E0H
M3:
DB 2
DB 'ov'
DW GRP1
DB 88H
DB 'ul'
DW GRP10
DB 20H
M4:
DB 2
DB 'ovb'
DW PUT
DB 0A4H
DB 'ovw'
DW PUT
DB 0A5H
N3:
DB 3
DB 'ot'
DW GRP9
DB 10H
DB 'eg'
DW GRP9
DB 18H
DB 'op'
DW PUT
DB 90H
O2:
DB 1
DB 'r'
DW GRP13
DB 0AH
O3:
DB 2
DB 'ut'
DW GRP4
DB 0E6H
DB 'rg'
DW GRP5
DB 0
O4:
DB 2
DB 'utb'
DW GRP4
DB 0E6H
DB 'utw'
DW GRP4
DB 0E7H
P3:
DB 2
DB 'op'
DW GRP22
DB 8FH
DB 'ut'
DW GRP5
DB 3
P4:
DB 2
DB 'ush'
DW GRP2
DB 0FFH
DB 'opf'
DW PUT
DB 9DH
P5:
DB 1
DB 'ushf'
DW PUT
DB 9CH
R3:
DB 6
DB 'et'
DW GRP16
DB 0C3H
DB 'ep'
DW PUT
DB 0F3H
DB 'ol'
DW GRP12
DB 0
DB 'or'
DW GRP12
DB 8
DB 'cl'
DW GRP12
DB 10H
DB 'cr'
DW GRP12
DB 18H
R4:
DB 2
DB 'epz'
DW PUT
DB 0F3H
DB 'epe'
DW PUT
DB 0F3H
R5:
DB 2
DB 'epnz'
DW PUT
DB 0F2H
DB 'epne'
DW PUT
DB 0F2H
S3:
DB 11
DB 'ub'
DW GRP7
DB 2AH
DB 'bb'
DW GRP7
DB 1AH
DB 'bc'
DW GRP7
DB 1AH
DB 'tc'
DW PUT
DB 0F9H
DB 'td'
DW PUT
DB 0FDH
DB 'ti'
DW PUT
DB 0FBH
DB 'hl'
DW GRP12
DB 20H
DB 'hr'
DW GRP12
DB 28H
DB 'al'
DW GRP12
DB 20H
DB 'ar'
DW GRP12
DB 38H
DB 'eg'
DW GRP21
DB 26H
S4:
DB 5
DB 'cab'
DW PUT
DB 0AEH
DB 'caw'
DW PUT
DB 0AFH
DB 'tob'
DW PUT
DB 0AAH
DB 'tow'
DW PUT
DB 0ABH
DB 'ahf'
DW PUT
DB 9EH
T4:
DB 1
DB 'est'
DW GRP20
DB 84H
U2:
DB 1
DB 'p'
DW PUT
DB 0FCH
W4:
DB 1
DB 'ait'
DW PUT
DB 9BH
X3:
DB 1
DB 'or'
DW GRP13
DB 32H
X4:
DB 2
DB 'chg'
DW GRP3
DB 86H
DB 'lat'
DW PUT
DB 0D7H
OPTAB:
DW NONE
DW A3
DW NONE
DW A5
DW NONE
DW NONE ;B
DW NONE
DW NONE
DW NONE
DW NONE
DW NONE ;C
DW C3
DW C4
DW NONE
DW NONE
DW D2 ;D
DW D3
DW D4
DW NONE
DW NONE
DW E2 ;E
DW E3
DW NONE
DW E5
DW NONE
DW NONE ;F
DW NONE
DW NONE
DW NONE
DW NONE
DW NONE ;G
DW NONE
DW NONE
DW NONE
DW NONE
DW NONE ;H
DW H3
DW H4
DW NONE
DW NONE
DW I2 ;I
DW I3
DW I4
DW NONE
DW NONE
DW J2 ;J
DW J3
DW J4
DW NONE
DW NONE
DW NONE ;K
DW NONE
DW NONE
DW NONE
DW NONE
DW NONE ;L
DW L3
DW L4
DW L5
DW L6
DW NONE ;M
DW M3
DW M4
DW NONE
DW NONE
DW NONE ;N
DW N3
DW NONE
DW NONE
DW NONE
DW O2 ;O
DW O3
DW O4
DW NONE
DW NONE
DW NONE ;P
DW P3
DW P4
DW P5
DW NONE
DW NONE ;Q
DW NONE
DW NONE
DW NONE
DW NONE
DW NONE ;R
DW R3
DW R4
DW R5
DW NONE
DW NONE ;S
DW S3
DW S4
DW NONE
DW NONE
DW NONE ;T
DW NONE
DW T4
DW NONE
DW NONE
DW U2 ;U
DW NONE
DW NONE
DW NONE
DW NONE
DW NONE ;V
DW NONE
DW NONE
DW NONE
DW NONE
DW NONE ;W
DW NONE
DW W4
DW NONE
DW NONE
DW NONE ;X
DW X3
DW X4
DW NONE
DW NONE
DW NONE ;Y
DW NONE
DW NONE
DW NONE
DW NONE
DW NONE ;Z
DW NONE
DW NONE
DW NONE
DW NONE
HEADER: DB 13,10,'Seattle Computer Products 8086 Assembler Version 1.00'
DB 13,10,'$'
ERRMES: DM '***** ERROR no. '
NOSPAC: DB 13,10,'No directory space',13,10,24H
ENDMES: DM 'H',13,10
NOMEM: DB 13,10,'Insufficient memory',13,10,'$'
NOFILE: DB 13,10,'File not found',13,10,'$'
WRTERR: DB 13,10,'Disk write error',13,10,'$'
BADDSK: DB 13,10,'Bad disk specifier',13,10,'$'
ERCNTM: DM 13,10,13,10,'Error Count ='
SYMMES: DM 13,10,'Symbol Table',13,10,13,10
EXTEND: DB 'A86',0,0,0,0
IFEND: DB 5,'endif'
RETSTR: DM 'ret'
HEXFCB: DB 0,' HEX',0,0,0,0
DS 16
DB 0
LSTFCB: DB 0,' PRN',0,0,0,0
DS 16
DB 0
PC: DS 2
OLDPC: DS 2
LABPT: DS 2
FLAG: DS 1
LONG: DS 1
ADDR: DS 2
ALABEL: DS 2
DATA: DS 2
DLABEL: DS 2
CON: DS 2
UNDEF: DS 2
LENID: DS 1
ID: DS 80
CHR: DS 1
SYM: DS 1
BASE: DS 2
HEAP: DS 2
SYMFLG: DS 1
CODE: DS 2
DATSIZ: DS 1
RELOC: DS 1
BCOUNT: DS 1
COUNT: DS 1
ERR: DS 1
HEXPNT: DS 2
HEXLEN: DS 2
HEXADD: DS 2
LASTAD: DS 2
HEXCNT: DS 1
CHKSUM: DS 1
SKPFLG: DS 1
LINFLG: DS 1
PREV: DS 1
IFFLG: DS 1
CHKLAB: DS 1
LSTPNT: DS 2
ERRCNT: DS 2
LSTRET: DS 2
RETPT: DS 2
HEXBUF: DS BUFSIZ+BUFSIZ
LSTBUF: DS BUFSIZ
DS 50
STACK: EQU $
START: EQU $