mirror of https://github.com/microsoft/MS-DOS.git
4006 lines
58 KiB
NASM
4006 lines
58 KiB
NASM
|
; Seattle Computer Products 8086 Assembler version 2.44
|
|||
|
; by Tim Paterson
|
|||
|
; Runs on the 8086 under MS-DOS
|
|||
|
|
|||
|
;* * * * * * REVISION HISTORY * * * * * *
|
|||
|
;
|
|||
|
; 12/29/80 2.01 General release with 86-DOS version 0.34
|
|||
|
; 02/22/81 2.10 Increased buffer size from 128 bytes to 1024 bytes
|
|||
|
; 03/18/81 2.11 General cleanup and more documentation
|
|||
|
; 03/24/81 2.20 Modify ESC handling for full 8087 operation
|
|||
|
; 04/01/81 2.21 Fix date in HEX and PRN files; modify buffer handling
|
|||
|
; 04/03/81 2.22 Fix 2.21 buffer handling
|
|||
|
; 04/13/81 2.23 Re-open source file for listing to allow assembling CON:
|
|||
|
; 04/28/81 2.24 Allow nested IFs
|
|||
|
; 07/30/81 2.25 Add Intel string mnemonics; clean up a little
|
|||
|
; 08/02/81 2.30 Re-write pass 2:
|
|||
|
; Always report errors to console
|
|||
|
; Exact byte lengths for HEX and PRN files
|
|||
|
; 11/08/81 2.40 Add 8087 mnemonics; print full error messages;
|
|||
|
; allow expressions with *, /, and ()
|
|||
|
; 07/04/82 2.41 Fix Intel's 8087 "reverse-bit" bug; don't copy date
|
|||
|
; 08/18/82 2.42 Increase stack from 80 to 256 (Damn! Overflowed again!)
|
|||
|
; 01/05/83 2.43 Correct over-zealous optimization in 2.42
|
|||
|
; 05/09/83 2.44 Add memory usage report
|
|||
|
;
|
|||
|
;* * * * * * * * * * * * * * * * * * * * *
|
|||
|
|
|||
|
SYMWID: EQU 5 ;5 symbols per line in dump
|
|||
|
FCB: EQU 5CH
|
|||
|
BUFSIZ: EQU 1024 ;Source code buffer
|
|||
|
LSTBUFSIZ:EQU BUFSIZ ;List file buffer
|
|||
|
HEXBUFSIZ:EQU 70 ;Hex file buffer (26*2 + 5*2 + 3 + EXTRA)
|
|||
|
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
|
|||
|
READ: EQU 20
|
|||
|
SETDMA: EQU 26
|
|||
|
MAKE: EQU 22
|
|||
|
BLKWRT: EQU 40
|
|||
|
|
|||
|
;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
|
|||
|
FREG: EQU 6 ;8087 floating point register
|
|||
|
|
|||
|
;Bits to build 8087 opcode table entries
|
|||
|
ONEREG: EQU 40H ;Single ST register OK as operand
|
|||
|
NEEDOP: EQU 80H ;Must have an operand
|
|||
|
INTEGER:EQU 20H ;For integer operations
|
|||
|
REAL: EQU 28H ;For real operations
|
|||
|
EXTENDED EQU 10H ;For Long integers or Temporary real
|
|||
|
MEMORY: EQU 18H ;For general memory operations
|
|||
|
STACKOP:EQU 10H ;Two register arithmetic with pop
|
|||
|
ARITH: EQU 8 ;Non-pop arithmetic operations
|
|||
|
|
|||
|
ORG 100H
|
|||
|
PUT 100H
|
|||
|
|
|||
|
JMPS BEGIN
|
|||
|
|
|||
|
HEADER: DB 13,10,'Seattle Computer Products 8086 Assembler Version 2.44'
|
|||
|
DB 13,10,'Copyright 1979-1983 by Seattle Computer Products, Inc.'
|
|||
|
DB 13,10,13,10,'$'
|
|||
|
|
|||
|
BEGIN:
|
|||
|
MOV SP,STACK
|
|||
|
MOV DX,HEADER
|
|||
|
MOV AH,PRINTMES
|
|||
|
INT 33
|
|||
|
MOV AL,[FCB+17]
|
|||
|
MOV [SYMFLG],AL ;Save symbol table request flag
|
|||
|
MOV SI,FCB+9 ;Point to file extension
|
|||
|
LODB ;Get source drive letter
|
|||
|
CALL CHKDSK ;Valid drive?
|
|||
|
OR AL,AL
|
|||
|
JZ DEFAULT ;If no extension, use existing drive spec
|
|||
|
MOV [FCB],AL
|
|||
|
DEFAULT:
|
|||
|
LODB ;Get HEX file drive letter
|
|||
|
CMP AL,'Z' ;Suppress HEX file?
|
|||
|
JZ L0000
|
|||
|
CALL CHKDSK
|
|||
|
L0000:
|
|||
|
MOV [HEXFCB],AL
|
|||
|
LODB ;Get PRN file drive letter
|
|||
|
MOV AH,0 ;Signal no PRN file
|
|||
|
CMP AL,'Z' ;Suppress PRN file?
|
|||
|
JZ NOPRN
|
|||
|
CMP AL,'Y' ;Print errors only on console?
|
|||
|
JZ NOPRN
|
|||
|
MOV AH,2
|
|||
|
CMP AL,'X' ;PRN file to console?
|
|||
|
JZ NOPRN
|
|||
|
MOV AH,4
|
|||
|
CMP AL,'P' ;PRN file to printer?
|
|||
|
JZ NOPRN
|
|||
|
CALL CHKDSK
|
|||
|
MOV AH,80H
|
|||
|
NOPRN:
|
|||
|
MOV [LSTFCB],AL
|
|||
|
MOV [LSTDEV],AH ;Flag device for list ouput
|
|||
|
MOV SI,EXTEND
|
|||
|
MOV DI,FCB+9
|
|||
|
MOVW
|
|||
|
MOVB ;Set extension to ASM
|
|||
|
MOVW ;Zero extent field
|
|||
|
MOV DX,FCB
|
|||
|
MOV AH,OPEN
|
|||
|
INT 33
|
|||
|
MOV BX,NOFILE
|
|||
|
OR AL,AL
|
|||
|
JZ $+5
|
|||
|
JMP PRERR
|
|||
|
MOV DX,HEXFCB
|
|||
|
CALL MAKFIL
|
|||
|
MOV DX,LSTFCB
|
|||
|
CALL MAKFIL
|
|||
|
XOR AX,AX
|
|||
|
MOV [FCB+12],AX ;Zero CURRENT BLOCK field
|
|||
|
MOV [FCB+32],AL ;Zero Next Record field
|
|||
|
MOV [FCB+14],BUFSIZ ;Set record size
|
|||
|
MOV [BUFPT],SRCBUF ;Initialize buffer pointer
|
|||
|
MOV [CODE],START+1 ;POINTER TO NEXT BYTE OF INTERMEDIATE CODE
|
|||
|
MOV [IY],START ;POINTER TO CURRENT RELOCATION BYTE
|
|||
|
XOR AX,AX
|
|||
|
MOV [PC],AX ;DEFAULT PROGRAM COUNTER
|
|||
|
MOV [BASE],AX ;POINTER TO ROOT OF ID TREE=NIL
|
|||
|
MOV [RETPT],AX ;Pointer to last RET record
|
|||
|
MOV [IFFLG],AL ;NOT WITHIN IF/ENDIF
|
|||
|
MOV [CHKLAB],AL ;LOOKUP ALL LABELS
|
|||
|
DEC AX
|
|||
|
MOV [LSTRET],AX ;Location of last RET
|
|||
|
MOV AX,[6] ;HL=END OF MEMORY
|
|||
|
MOV [HEAP],AX ;BACK END OF SYMBOL TABLE SPACE
|
|||
|
MOV [BCOUNT],4 ;CODE BYTES PER RELOCATION BYTE
|
|||
|
|
|||
|
;Assemble each line of code
|
|||
|
|
|||
|
LOOP:
|
|||
|
CALL NEXTCHR ;Get first character on line
|
|||
|
CMP AL,1AH
|
|||
|
JZ ENDJ
|
|||
|
MOV AL,-1 ;Flag that no tokens have been read yet
|
|||
|
MOV [SYM],AL
|
|||
|
CALL ASMLIN ;Assemble the line
|
|||
|
MOV AL,[SYM]
|
|||
|
CMP AL,-1 ;Any tokens found on line?
|
|||
|
JNZ L0002
|
|||
|
CALL GETSYM ;If no tokens read yet, read first one
|
|||
|
L0002:
|
|||
|
CMP AL,';'
|
|||
|
JZ ENDLN
|
|||
|
CMP AL,EOL
|
|||
|
JZ ENDLN
|
|||
|
MOV AL,14H ;Garbage at end of line error
|
|||
|
JP ENDLIN
|
|||
|
ENDJ: JMP END
|
|||
|
|
|||
|
ENDLN:
|
|||
|
XOR AL,AL ;Flag no errors on line
|
|||
|
ENDLIN:
|
|||
|
;AL = error code for line. Stack depth unknown
|
|||
|
MOV SP,STACK
|
|||
|
CALL NEXLIN
|
|||
|
JP LOOP
|
|||
|
|
|||
|
NEXLIN:
|
|||
|
MOV CH,0C0H ;Put end of line marker and error code (AL)
|
|||
|
CALL PUTCD
|
|||
|
CALL GEN1
|
|||
|
MOV AL,[CHR]
|
|||
|
GETEOL:
|
|||
|
CMP AL,10
|
|||
|
JZ RET
|
|||
|
CMP AL,1AH
|
|||
|
JZ ENDJ
|
|||
|
CALL NEXTCHR ;Scan over comments for linefeed
|
|||
|
JP GETEOL
|
|||
|
|
|||
|
ABORT:
|
|||
|
MOV BX,NOMEM
|
|||
|
PRERR:
|
|||
|
MOV DX,BX
|
|||
|
MOV AH,PRINTMES
|
|||
|
INT 33
|
|||
|
INT 32
|
|||
|
|
|||
|
MAKFIL:
|
|||
|
MOV SI,DX
|
|||
|
LODB ;Get drive select byte
|
|||
|
CMP AL,20H ;If not valid, don't make file
|
|||
|
JNC RET
|
|||
|
MOV CX,4
|
|||
|
MOV DI,SI
|
|||
|
MOV SI,FCB+1
|
|||
|
REP
|
|||
|
MOVW ;Copy source file name
|
|||
|
MOV AH,MAKE
|
|||
|
INT 33
|
|||
|
MOV [DI-9+14],1 ;Set record length to 1 byte
|
|||
|
MOV BX,NOSPAC
|
|||
|
OR AL,AL ;Success?
|
|||
|
JNZ PRERR
|
|||
|
RET
|
|||
|
|
|||
|
CHKDSK:
|
|||
|
SUB AL,' ' ;If not present, set zero flag
|
|||
|
JZ RET
|
|||
|
SUB AL,20H
|
|||
|
JZ DSKERR ;Must be in range A-O
|
|||
|
CMP AL,'P'-'@'
|
|||
|
JC RET
|
|||
|
DSKERR:
|
|||
|
MOV BX,BADDSK
|
|||
|
JP PRERR
|
|||
|
|
|||
|
ERROR:
|
|||
|
MOV AL,CL
|
|||
|
JMP ENDLIN
|
|||
|
|
|||
|
NEXTCHR:
|
|||
|
MOV SI,[BUFPT]
|
|||
|
CMP SI,SRCBUF
|
|||
|
JNZ GETCH
|
|||
|
;Buffer empty so refill it
|
|||
|
PUSH DX
|
|||
|
PUSH AX ;AH must be saved
|
|||
|
MOV DX,SI
|
|||
|
MOV AH,SETDMA
|
|||
|
INT 33
|
|||
|
MOV DX,FCB
|
|||
|
MOV AH,READ
|
|||
|
INT 33
|
|||
|
XCHG AX,DX ;Put error code in DL
|
|||
|
POP AX ;Restore AH
|
|||
|
MOV AL,DL ;Error code back in AL
|
|||
|
POP DX
|
|||
|
CMP AL,1
|
|||
|
MOV AL,1AH ;Possibly signal End of File
|
|||
|
JZ NOMOD ;If nothing read
|
|||
|
GETCH:
|
|||
|
LODB
|
|||
|
CMP SI,SRCBUF+BUFSIZ
|
|||
|
JNZ NOMOD
|
|||
|
MOV SI,SRCBUF
|
|||
|
NOMOD:
|
|||
|
MOV [BUFPT],SI
|
|||
|
MOV [CHR],AL
|
|||
|
RET
|
|||
|
|
|||
|
|
|||
|
MROPS:
|
|||
|
|
|||
|
; Get two operands and check for certain types, according to flag byte
|
|||
|
; in CL. OP code in CH. Returns only if immediate operation.
|
|||
|
|
|||
|
PUSH CX ;Save type flags
|
|||
|
CALL GETOP
|
|||
|
PUSH DX ;Save first operand
|
|||
|
CALL GETOP2
|
|||
|
POP BX ;First op in BX, second op in DX
|
|||
|
MOV AL,SREG ;Check for a segment register
|
|||
|
CMP AL,BH
|
|||
|
JZ SEGCHK
|
|||
|
CMP AL,DH
|
|||
|
JZ SEGCHK
|
|||
|
MOV AL,CONST ;Check if the first operand is immediate
|
|||
|
MOV CL,26
|
|||
|
CMP AL,BH
|
|||
|
JZ ERROR ;Error if so
|
|||
|
POP CX ;Restore type flags
|
|||
|
CMP AL,DH ;If second operand is immediate, then done
|
|||
|
JZ RET
|
|||
|
MOV AL,UNDEFID ;Check for memory reference
|
|||
|
CMP AL,BH
|
|||
|
JZ STORE ;Is destination memory?
|
|||
|
CMP AL,DH
|
|||
|
JZ LOAD ;Is source memory?
|
|||
|
TEST CL,1 ;Check if register-to-register operation OK
|
|||
|
MOV CL,27
|
|||
|
JZ ERROR
|
|||
|
MOV AL,DH
|
|||
|
CMP AL,BH ;Registers must be of same length
|
|||
|
RR:
|
|||
|
MOV CL,22
|
|||
|
JNZ ERROR
|
|||
|
RR1:
|
|||
|
AND AL,1 ;Get register length (1=16 bits)
|
|||
|
OR AL,CH ;Or in to OP code
|
|||
|
CALL PUT ;And write it
|
|||
|
POP CX ;Dump return address
|
|||
|
MOV AL,BL
|
|||
|
ADD AL,AL ;Rotate register number into middle position
|
|||
|
ADD AL,AL
|
|||
|
ADD AL,AL
|
|||
|
OR AL,0C0H ;Set register-to-register mode
|
|||
|
OR AL,DL ;Combine with other register number
|
|||
|
JMP PUT
|
|||
|
|
|||
|
SEGCHK:
|
|||
|
;Come here if at least one operand is a segment register
|
|||
|
POP CX ;Restore flags
|
|||
|
TEST CL,8 ;Check if segment register OK
|
|||
|
MOV CL,22
|
|||
|
JZ ERR1
|
|||
|
MOV CX,8E03H ;Segment register move OP code
|
|||
|
MOV AL,UNDEFID
|
|||
|
CMP AL,DH ;Check if source is memory
|
|||
|
JZ LOAD
|
|||
|
CMP AL,BH ;Check if destination is memory
|
|||
|
JZ STORE
|
|||
|
MOV AL,XREG
|
|||
|
SUB AL,DH ;Check if source is 16-bit register
|
|||
|
JZ RR ;If so, AL must be zero
|
|||
|
MOV CH,8CH ;Change direction
|
|||
|
XCHG DX,BX ;Flip which operand is first and second
|
|||
|
MOV AL,XREG
|
|||
|
SUB AL,DH ;Let RR perform finish the test
|
|||
|
JP RR
|
|||
|
|
|||
|
STORE:
|
|||
|
TEST CL,004H ;Check if storing is OK
|
|||
|
JNZ STERR
|
|||
|
XCHG DX,BX ;If so, flip operands
|
|||
|
AND CH,0FDH ; and zero direction bit
|
|||
|
LOAD:
|
|||
|
MOV DH,25
|
|||
|
CMP AL,BH ;Check if memory-to-memory
|
|||
|
JZ MRERR
|
|||
|
MOV AL,BH
|
|||
|
CMP AL,REG ;Check if 8-bit operation
|
|||
|
JNZ XRG
|
|||
|
MOV DH,22
|
|||
|
TEST CL,1 ;See if 8-bit operation is OK
|
|||
|
JZ MRERR
|
|||
|
XRG:
|
|||
|
MOV AL,DL
|
|||
|
SUB AL,6 ;Check for R/M mode 6 and register 0
|
|||
|
OR AL,BL ; meaning direct load/store of accumulator
|
|||
|
JNZ NOTAC
|
|||
|
TEST CL,8 ;See if direct load/store of accumulator
|
|||
|
JZ NOTAC ; means anything in this case
|
|||
|
; Process direct load/store of accumulator
|
|||
|
MOV AL,CH
|
|||
|
AND AL,2 ;Preserve direction bit only
|
|||
|
XOR AL,2 ; but flip it
|
|||
|
OR AL,0A0H ;Combine with OP code
|
|||
|
MOV CH,AL
|
|||
|
MOV AL,BH ;Check byte/word operation
|
|||
|
AND AL,1
|
|||
|
OR AL,CH
|
|||
|
POP CX ;Dump return address
|
|||
|
JMP PUTADD ;Write the address
|
|||
|
|
|||
|
NOTAC:
|
|||
|
MOV AL,BH
|
|||
|
AND AL,1 ;Get byte/word bit
|
|||
|
AND AL,CL ;But don't use it in word-only operations
|
|||
|
OR AL,CH ;Combine with OP code
|
|||
|
CALL PUT
|
|||
|
MOV AL,BL
|
|||
|
ADD AL,AL ;Rotate to middle position
|
|||
|
ADD AL,AL
|
|||
|
ADD AL,AL
|
|||
|
OR AL,DL ;Combine register field
|
|||
|
POP CX ;Dump return address
|
|||
|
JMP PUTADD ;Write the address
|
|||
|
|
|||
|
STERR:
|
|||
|
MOV DH,29
|
|||
|
MRERR:
|
|||
|
MOV CL,DH
|
|||
|
|
|||
|
ERR1: JMP ERROR
|
|||
|
|
|||
|
GETOP2:
|
|||
|
;Get the second operand: look for a comma and drop into GETOP
|
|||
|
MOV AL,[SYM]
|
|||
|
CMP AL,','
|
|||
|
MOV CL,21
|
|||
|
JNZ ERR1
|
|||
|
|
|||
|
|
|||
|
GETOP:
|
|||
|
|
|||
|
; Get one operand. Operand may be a memory reference in brackets, a register,
|
|||
|
; or a constant. If a flag (such as "B" for byte operation) is encountered,
|
|||
|
; it is noted and processing continues to find the operand.
|
|||
|
;
|
|||
|
; On exit, AL (=DH) has the type of operand. Other information depends
|
|||
|
; on the actual operand:
|
|||
|
;
|
|||
|
; AL=DH=0 Memory Reference. DL has the address mode properly prepared in
|
|||
|
; the 8086 R/M format (middle bits zero). The constant part of the address
|
|||
|
; is in ADDR. If an undefined label needs to be added to this, a pointer to
|
|||
|
; its information fields is in ALABEL, otherwise ALABEL is zero.
|
|||
|
;
|
|||
|
; AL=DH=1 Value. The constant part is in DATA. If an undefined label needs
|
|||
|
; to be added to this, a pointer to its information fields is in DLABEL,
|
|||
|
; otherwise DLABEL is zero. "$" and "RET" are in this class.
|
|||
|
;
|
|||
|
; AL=DH=2 8-bit Register. DL has the register number.
|
|||
|
;
|
|||
|
; AL=DH=3 16-bit Register. DL has the register number.
|
|||
|
;
|
|||
|
; AL=DH=4 Segment Register. DL has the register number.
|
|||
|
|
|||
|
CALL GETSYM
|
|||
|
GETOP1:
|
|||
|
;Enter here if we don't need a GETSYM first
|
|||
|
CMP AL,'[' ;Memory reference?
|
|||
|
JZ MEM
|
|||
|
CMP AL,5 ;Flag ("B", "W", etc.)?
|
|||
|
JZ FLG
|
|||
|
CMP AL,REG ;8-Bit register?
|
|||
|
JZ NREG
|
|||
|
CMP AL,XREG ;16-Bit register?
|
|||
|
JZ NREG
|
|||
|
CMP AL,SREG ;Segment register?
|
|||
|
JZ NREG
|
|||
|
VAL: ;Must be immediate
|
|||
|
XOR AL,AL ;No addressing modes allowed
|
|||
|
VAL1:
|
|||
|
CALL GETVAL
|
|||
|
MOV AX,[CON] ;Defined part
|
|||
|
MOV [DATA],AX
|
|||
|
MOV AX,[UNDEF] ;Undefined part
|
|||
|
MOV [DLABEL],AX
|
|||
|
MOV DL,CH
|
|||
|
MOV DH,CONST
|
|||
|
MOV AL,DH
|
|||
|
RET
|
|||
|
NREG:
|
|||
|
PUSH DX
|
|||
|
CALL GETSYM
|
|||
|
POP DX
|
|||
|
MOV AL,DH
|
|||
|
RET
|
|||
|
MEM:
|
|||
|
CALL GETSYM
|
|||
|
MOV AL,1
|
|||
|
CALL GETVAL
|
|||
|
MOV AL,[SYM]
|
|||
|
CMP AL,']'
|
|||
|
MOV CL,24
|
|||
|
JNZ ERR1
|
|||
|
CALL GETSYM
|
|||
|
MOV BX,[CON]
|
|||
|
MOV [ADDR],BX
|
|||
|
MOV BX,[UNDEF]
|
|||
|
MOV [ALABEL],BX
|
|||
|
MOV DL,CH
|
|||
|
MOV DH,UNDEFID
|
|||
|
MOV AL,DH
|
|||
|
RET
|
|||
|
FLG:
|
|||
|
CMP DL,[MAXFLG] ;Invalid flag for this operation?
|
|||
|
MOV CL,27H
|
|||
|
JG ERR1
|
|||
|
CALL GETSYM
|
|||
|
CMP AL,','
|
|||
|
JZ GETOP
|
|||
|
JP GETOP1
|
|||
|
|
|||
|
|
|||
|
GETVAL:
|
|||
|
|
|||
|
; Expression analyzer. On entry, if AL=0 then do not allow base or index
|
|||
|
; registers. If AL=1, we are analyzing a memory reference, so allow base
|
|||
|
; and index registers, and compute addressing mode when done. The constant
|
|||
|
; part of the expression will be found in CON. If an undefined label is to
|
|||
|
; be added to this, a pointer to its information fields will be found in
|
|||
|
; UNDEF.
|
|||
|
|
|||
|
MOV AH,AL ;Flag is kept in AH
|
|||
|
MOV [UNDEF],0
|
|||
|
MOV AL,[SYM]
|
|||
|
CALL EXPRESSION
|
|||
|
MOV [CON],DX
|
|||
|
MOV AL,AH
|
|||
|
MOV CH,0 ;Initial mode
|
|||
|
TEST AL,10H ;Test INDEX bit
|
|||
|
RCL AL ;BASE bit (zero flag not affected)
|
|||
|
JZ NOIND ;Jump if not indexed, with BASE bit in carry
|
|||
|
CMC
|
|||
|
RCL CH ;Rotate in BASE bit
|
|||
|
RCL AL ;BP bit
|
|||
|
RCL CH
|
|||
|
RCL AL ;DI bit
|
|||
|
RCL CH ;The low 3 bits now have indexing mode
|
|||
|
MODE:
|
|||
|
OR CH,080H ;If undefined label, force 16-bit displacement
|
|||
|
TEST [UNDEF],-1
|
|||
|
JNZ RET
|
|||
|
MOV BX,[CON]
|
|||
|
MOV AL,BL
|
|||
|
CBW ;Extend sign
|
|||
|
CMP AX,BX ;Is it a signed 8-bit number?
|
|||
|
JNZ RET ;If not, use 16-bit displacement
|
|||
|
AND CH,07FH ;Reset 16-bit displacement
|
|||
|
OR CH,040H ;Set 8-bit displacement
|
|||
|
OR BX,BX
|
|||
|
JNZ RET ;Use it if not zero displacement
|
|||
|
AND CH,7 ;Specify no displacement
|
|||
|
CMP CH,6 ;Check for BP+0 addressing mode
|
|||
|
JNZ RET
|
|||
|
OR CH,040H ;If BP+0, use 8-bit displacement
|
|||
|
RET
|
|||
|
|
|||
|
NOIND:
|
|||
|
MOV CH,6 ;Try direct address mode
|
|||
|
JNC RET ;If no base register, that's right
|
|||
|
RCL AL ;Check BP bit
|
|||
|
JC MODE
|
|||
|
INC CH ;If not, must be BX
|
|||
|
JP MODE
|
|||
|
|
|||
|
EXPRESSION:
|
|||
|
;Analyze arbitrary expression. Flag byte in AH.
|
|||
|
;On exit, AL has type byte: 0=register or undefined label
|
|||
|
MOV CH,-1 ;Initial type
|
|||
|
MOV DI,DX
|
|||
|
XOR DX,DX ;Initial value
|
|||
|
CMP AL,'+'
|
|||
|
JZ PLSMNS
|
|||
|
CMP AL,'-'
|
|||
|
JZ PLSMNS
|
|||
|
MOV CL,'+'
|
|||
|
PUSH DX
|
|||
|
PUSH CX
|
|||
|
MOV DX,DI
|
|||
|
JP OPERATE
|
|||
|
PLSMNS:
|
|||
|
MOV CL,AL
|
|||
|
PUSH DX
|
|||
|
PUSH CX
|
|||
|
OR AH,4 ;Flag that a sign was found
|
|||
|
CALL GETSYM
|
|||
|
OPERATE:
|
|||
|
CALL TERM
|
|||
|
POP CX ;Recover operator
|
|||
|
POP BX ;Recover current value
|
|||
|
XCHG DX,BX
|
|||
|
AND CH,AL
|
|||
|
OR AL,AL ;Is it register or undefined label?
|
|||
|
JZ NOCON ;If so, then no constant part
|
|||
|
CMP CL,"-" ;Subtract it?
|
|||
|
JNZ ADD
|
|||
|
NEG BX
|
|||
|
ADD:
|
|||
|
ADD DX,BX
|
|||
|
NEXTERM:
|
|||
|
MOV AL,[SYM]
|
|||
|
CMP AL,'+'
|
|||
|
JZ PLSMNS
|
|||
|
CMP AL,'-'
|
|||
|
JZ PLSMNS
|
|||
|
MOV AL,CH
|
|||
|
RET
|
|||
|
NOCON:
|
|||
|
CMP CL,"-"
|
|||
|
JNZ NEXTERM
|
|||
|
BADOP:
|
|||
|
MOV CL,5
|
|||
|
JMP ERROR
|
|||
|
|
|||
|
TERM:
|
|||
|
CALL FACTOR
|
|||
|
MULOP:
|
|||
|
PUSH DX ;Save value
|
|||
|
PUSH AX ;Save type
|
|||
|
CALL GETSYM
|
|||
|
POP CX
|
|||
|
CMP AL,"*"
|
|||
|
JZ GETFACT
|
|||
|
CMP AL,"/"
|
|||
|
JNZ ENDTERM
|
|||
|
GETFACT:
|
|||
|
OR CL,CL ;Can we operate on this type?
|
|||
|
JZ BADOP
|
|||
|
PUSH AX ;Save operator
|
|||
|
CALL GETSYM ;Get past operator
|
|||
|
CALL FACTOR
|
|||
|
OR AL,AL
|
|||
|
JZ BADOP
|
|||
|
POP CX ;Recover operator
|
|||
|
POP BP ;And current value
|
|||
|
XCHG AX,BP ;Save AH in BP
|
|||
|
CMP CL,"/" ;Do we divide?
|
|||
|
JNZ DOMUL
|
|||
|
OR DX,DX ;Dividing by zero?
|
|||
|
MOV CL,29H
|
|||
|
JZ ERR2
|
|||
|
MOV BX,DX
|
|||
|
XOR DX,DX ;Make 32-bit dividend
|
|||
|
DIV AX,BX
|
|||
|
JMPS NEXFACT
|
|||
|
DOMUL:
|
|||
|
MUL AX,DX
|
|||
|
NEXFACT:
|
|||
|
MOV DX,AX ;Result in DX
|
|||
|
XCHG AX,BP ;Restore flags to AH
|
|||
|
MOV AL,-1 ;Indicate a number
|
|||
|
JMPS MULOP
|
|||
|
ENDTERM:
|
|||
|
POP DX
|
|||
|
MOV AL,CL
|
|||
|
RET
|
|||
|
|
|||
|
FACTOR:
|
|||
|
MOV AL,[SYM]
|
|||
|
CMP AL,CONST
|
|||
|
JZ RET
|
|||
|
CMP AL,UNDEFID
|
|||
|
JZ UVAL
|
|||
|
CMP AL,"("
|
|||
|
JZ PAREN
|
|||
|
CMP AL,'"'
|
|||
|
JZ STRING
|
|||
|
CMP AL,"'"
|
|||
|
JZ STRING
|
|||
|
CMP AL,XREG ;Only 16-bit register may index
|
|||
|
MOV CL,20
|
|||
|
JNZ ERR2
|
|||
|
TEST AH,1 ;Check to see if indexing is OK
|
|||
|
MOV CL,1
|
|||
|
JZ ERR2
|
|||
|
MOV AL,DL
|
|||
|
MOV CL,3
|
|||
|
SUB AL,3 ;Check for BX
|
|||
|
JZ BXJ
|
|||
|
SUB AL,2 ;Check for BP
|
|||
|
JZ BPJ
|
|||
|
DEC AL ;Check for SI
|
|||
|
MOV CL,4
|
|||
|
JZ SIJ
|
|||
|
DEC AL ;Check for DI
|
|||
|
JZ DIJ
|
|||
|
MOV CL,2 ;Invalid base/index register
|
|||
|
ERR2: JMP ERROR
|
|||
|
|
|||
|
DIJ:
|
|||
|
OR AH,20H ;Flag seeing index register DI
|
|||
|
SIJ:
|
|||
|
TEST AH,10H ;Check if already seen index register
|
|||
|
JNZ ERR2
|
|||
|
OR AH,10H ;Flag seeing index register
|
|||
|
RET
|
|||
|
|
|||
|
BPJ:
|
|||
|
OR AH,40H ;Flag seeing base register BP
|
|||
|
BXJ:
|
|||
|
TEST AH,80H ;Check if already seen base register
|
|||
|
JNZ ERR2
|
|||
|
OR AH,80H ;Flag seeing base register
|
|||
|
RET
|
|||
|
|
|||
|
PAREN:
|
|||
|
CALL GETSYM ;Eat the "("
|
|||
|
CALL EXPRESSION
|
|||
|
CMP B,[SYM],")" ;Better have closing paren
|
|||
|
MOV CL,20
|
|||
|
JNZ ERR30
|
|||
|
RET
|
|||
|
|
|||
|
UVAL:
|
|||
|
MOV CL,6
|
|||
|
TEST AH,8 ;Check if undefined label has been seen
|
|||
|
JNZ ERR30
|
|||
|
OR AH,8 ;Flag seeing undefined label
|
|||
|
MOV [UNDEF],BX
|
|||
|
RET
|
|||
|
|
|||
|
ERR30: JMP ERROR
|
|||
|
|
|||
|
STRING:
|
|||
|
MOV CH,AL
|
|||
|
MOV AL,[CHR]
|
|||
|
CMP AL,CH
|
|||
|
MOV CL,35
|
|||
|
MOV DL,AL
|
|||
|
MOV DH,0
|
|||
|
JNZ L0003
|
|||
|
CALL ZERLEN
|
|||
|
L0003:
|
|||
|
CALL GETCHR
|
|||
|
MOV CL,37
|
|||
|
TEST AH,2
|
|||
|
JZ ERR30
|
|||
|
TEST AH,4
|
|||
|
MOV CL,38
|
|||
|
JNZ ERR30
|
|||
|
STRGDAT:
|
|||
|
MOV AL,DL
|
|||
|
CMP AL,EOL
|
|||
|
MOV CL,39
|
|||
|
JZ ERR30
|
|||
|
CALL PUT
|
|||
|
MOV AL,[DATSIZ]
|
|||
|
OR AL,AL
|
|||
|
JNZ BYTSIZ
|
|||
|
MOV AL,DH
|
|||
|
CALL PUT
|
|||
|
BYTSIZ:
|
|||
|
MOV AL,[CHR]
|
|||
|
MOV DL,AL
|
|||
|
CALL GETCHR
|
|||
|
JP STRGDAT
|
|||
|
|
|||
|
ZERLEN:
|
|||
|
CALL NEXTCHR
|
|||
|
CMP AL,CH
|
|||
|
JNZ ERR30
|
|||
|
RET
|
|||
|
|
|||
|
GETCHR:
|
|||
|
CALL NEXTCHR
|
|||
|
CMP AL,CH
|
|||
|
JNZ RET
|
|||
|
CALL NEXTCHR
|
|||
|
CMP AL,CH
|
|||
|
JZ RET
|
|||
|
POP BX ;Kill return address to STRGDAT loop
|
|||
|
MOV AL,-1 ;Flag type as constant
|
|||
|
RET
|
|||
|
|
|||
|
|
|||
|
GETSYM:
|
|||
|
|
|||
|
; The lexical scanner. Used only in the operand field. Returns with the token
|
|||
|
; in SYM and AL, sometimes with additional info in BX or DX.
|
|||
|
;
|
|||
|
; AL=SYM=0 Undefined label. BX has pointer to information fields.
|
|||
|
;
|
|||
|
; AL=SYM=1 Constant (or defined label). DX has value.
|
|||
|
;
|
|||
|
; AL=SYM=2,3,4 8-bit register, 16-bit register, or segment register,
|
|||
|
; respectively. DL has register number.
|
|||
|
;
|
|||
|
; AL=SYM=5 A mode flag (such as "B" for byte operation). Type of flag in DL
|
|||
|
; and also stored in FLAG: -1=no flags, 0=B, 1=W, 2=S, 3=L, 4=T.
|
|||
|
;
|
|||
|
; AL=SYM=6 8087 floating point register, ST(n) or ST. DL has register number.
|
|||
|
;
|
|||
|
; All other values are the ASCII code of the character. Note that this may
|
|||
|
; never be a letter or number.
|
|||
|
|
|||
|
PUSH AX ;Save AH
|
|||
|
CALL GETSY
|
|||
|
POP AX
|
|||
|
MOV AL,[SYM]
|
|||
|
RET
|
|||
|
|
|||
|
SCANB:
|
|||
|
MOV AL,[CHR]
|
|||
|
SCANT:
|
|||
|
CMP AL,' '
|
|||
|
JZ NEXB
|
|||
|
CMP AL,9
|
|||
|
JNZ RET
|
|||
|
NEXB:
|
|||
|
CALL NEXTCHR
|
|||
|
JP SCANT
|
|||
|
|
|||
|
DOLLAR:
|
|||
|
MOV DX,[OLDPC]
|
|||
|
MOV AL,CONST
|
|||
|
MOV [SYM],AL
|
|||
|
NEXTCHJ:
|
|||
|
JMP NEXTCHR
|
|||
|
|
|||
|
GETSY:
|
|||
|
CALL SCANB
|
|||
|
CMP AL,'$'
|
|||
|
JZ DOLLAR
|
|||
|
MOV [SYM],AL
|
|||
|
OR AL,20H
|
|||
|
CMP AL,'z'+1
|
|||
|
JNC NEXTCHJ
|
|||
|
CMP AL,'a'
|
|||
|
JC $+5
|
|||
|
JMP LETTER
|
|||
|
CMP AL,'9'+1
|
|||
|
JNC NEXTCHJ
|
|||
|
CMP AL,'0'
|
|||
|
JC NEXTCHJ
|
|||
|
MOV BX,SYM
|
|||
|
MOV B,[BX],CONST
|
|||
|
CALL READID
|
|||
|
DEC BX
|
|||
|
MOV AL,[BX]
|
|||
|
MOV CL,7
|
|||
|
MOV BX,0
|
|||
|
CMP AL,'h'
|
|||
|
JNZ $+5
|
|||
|
JMP HEX
|
|||
|
INC CL
|
|||
|
MOV [IX],ID
|
|||
|
DEC:
|
|||
|
MOV SI,[IX]
|
|||
|
MOV AL,[SI]
|
|||
|
INC [IX]
|
|||
|
CMP AL,'9'+1
|
|||
|
JC $+5
|
|||
|
JMP ERROR
|
|||
|
SUB AL,'0'
|
|||
|
MOV DX,BX
|
|||
|
SHL BX
|
|||
|
SHL BX
|
|||
|
ADD BX,DX
|
|||
|
SHL BX
|
|||
|
MOV DL,AL
|
|||
|
MOV DH,0
|
|||
|
ADD BX,DX
|
|||
|
DEC CH
|
|||
|
JNZ DEC
|
|||
|
XCHG DX,BX
|
|||
|
RET
|
|||
|
|
|||
|
HEX:
|
|||
|
MOV DX,ID
|
|||
|
DEC CH
|
|||
|
HEX1:
|
|||
|
MOV SI,DX
|
|||
|
LODB
|
|||
|
INC DX
|
|||
|
SUB AL,'0'
|
|||
|
CMP AL,10
|
|||
|
JC GOTIT
|
|||
|
CMP AL,'g'-'0'
|
|||
|
JNC ERR4
|
|||
|
SUB AL,'a'-10-'0'
|
|||
|
GOTIT:
|
|||
|
SHL BX
|
|||
|
SHL BX
|
|||
|
SHL BX
|
|||
|
SHL BX
|
|||
|
ADD BL,AL
|
|||
|
DEC CH
|
|||
|
JNZ HEX1
|
|||
|
XCHG DX,BX
|
|||
|
RET
|
|||
|
|
|||
|
ERR4: JMP ERROR
|
|||
|
|
|||
|
GETLET:
|
|||
|
CALL SCANB
|
|||
|
CMP AL,EOL
|
|||
|
STC
|
|||
|
JZ RET
|
|||
|
CMP AL,';'
|
|||
|
STC
|
|||
|
JZ RET
|
|||
|
MOV CL,10
|
|||
|
OR AL,20H
|
|||
|
CMP AL,'a'
|
|||
|
JC ERR4
|
|||
|
CMP AL,'z'+1
|
|||
|
JNC ERR4
|
|||
|
READID:
|
|||
|
MOV BX,ID
|
|||
|
MOV CH,0
|
|||
|
MOREID:
|
|||
|
MOV [BX],AL
|
|||
|
INC CH
|
|||
|
INC BX
|
|||
|
CALL NEXTCHR
|
|||
|
CMP AL,'0'
|
|||
|
JC NOMORE
|
|||
|
OR AL,20H
|
|||
|
CMP AL,'z'+1
|
|||
|
JNC NOMORE
|
|||
|
CMP AL,'9'+1
|
|||
|
JC MOREID
|
|||
|
CMP AL,'a'
|
|||
|
JNC MOREID
|
|||
|
NOMORE:
|
|||
|
MOV CL,AL
|
|||
|
MOV AL,CH
|
|||
|
MOV [LENID],AL
|
|||
|
OR AL,AL
|
|||
|
MOV AL,CL
|
|||
|
RET
|
|||
|
|
|||
|
LETTER:
|
|||
|
CALL READID
|
|||
|
MOV AL,CH
|
|||
|
DEC AL
|
|||
|
JNZ NOFLG
|
|||
|
MOV AL,[ID]
|
|||
|
MOV CX,5
|
|||
|
MOV DI,FLGTAB
|
|||
|
UP
|
|||
|
REPNE
|
|||
|
SCAB ;See if one of B,W,S,L,T
|
|||
|
JZ SAVFLG ;Go save flag
|
|||
|
XOR AL,AL
|
|||
|
MOV CH,[LENID]
|
|||
|
NOFLG:
|
|||
|
DEC AL
|
|||
|
PUSH BX
|
|||
|
JNZ L0004
|
|||
|
CALL REGCHK
|
|||
|
L0004:
|
|||
|
POP BX
|
|||
|
MOV AL,DH
|
|||
|
JZ SYMSAV
|
|||
|
CALL LOOKRET
|
|||
|
SYMSAV:
|
|||
|
MOV [SYM],AL
|
|||
|
RET
|
|||
|
|
|||
|
SAVFLG:
|
|||
|
MOV DL,CL ;Need flag type in DL
|
|||
|
XCHG [FLAG],CL
|
|||
|
CMP CL,-1
|
|||
|
MOV CL,32
|
|||
|
MOV AL,5
|
|||
|
JZ SYMSAV
|
|||
|
ERRJ3: JMP ERROR
|
|||
|
|
|||
|
FLGTAB: DB "tlswb"
|
|||
|
|
|||
|
FPREG:
|
|||
|
;Have detected "ST" for 8087 floating point stack register
|
|||
|
MOV DL,0 ;Default is ST(0)
|
|||
|
CALL SCANB ;Get next character
|
|||
|
CMP AL,"(" ;Specifying register number?
|
|||
|
JNZ HAVREG
|
|||
|
;Get register number
|
|||
|
CALL NEXTCHR ;Skip over the "("
|
|||
|
CALL GETOP ;A little recursion never hurt anybody
|
|||
|
CMP AL,CONST ;Better have found a constant
|
|||
|
MOV CL,20 ;Operand error if not
|
|||
|
JNZ ERRJ3
|
|||
|
CMP [DLABEL],0 ;Constant must be defined
|
|||
|
MOV CL,30
|
|||
|
JNZ ERRJ3
|
|||
|
MOV DX,[DATA] ;Get constant
|
|||
|
CMP DX,7 ;Constant must be in range 0-7
|
|||
|
MOV CL,31
|
|||
|
JA ERRJ3
|
|||
|
MOV AL,[SYM]
|
|||
|
CMP AL,")"
|
|||
|
MOV CL,24
|
|||
|
JNZ ERRJ3
|
|||
|
HAVREG:
|
|||
|
MOV DH,FREG
|
|||
|
XOR AL,AL ;Zero set means register found
|
|||
|
RET
|
|||
|
|
|||
|
REGCHK:
|
|||
|
MOV BX,ID
|
|||
|
CMP [BX],"s"+7400H ;"st"
|
|||
|
JZ FPREG
|
|||
|
MOV CL,[BX]
|
|||
|
INC BX
|
|||
|
MOV AL,[BX]
|
|||
|
MOV BX,REGTAB
|
|||
|
MOV DH,XREG
|
|||
|
MOV DL,0
|
|||
|
CMP AL,'x'
|
|||
|
JZ SCANREG
|
|||
|
MOV DH,REG
|
|||
|
CMP AL,'l'
|
|||
|
JZ SCANREG
|
|||
|
MOV DL,4
|
|||
|
CMP AL,'h'
|
|||
|
JZ SCANREG
|
|||
|
MOV DH,SREG
|
|||
|
MOV DL,0
|
|||
|
MOV BX,SEGTAB
|
|||
|
CMP AL,'s'
|
|||
|
JZ SCANREG
|
|||
|
MOV DH,XREG
|
|||
|
CMP AL,'p'
|
|||
|
JZ PREG
|
|||
|
CMP AL,'i'
|
|||
|
JNZ RET
|
|||
|
MOV DL,6
|
|||
|
MOV AL,CL
|
|||
|
CMP AL,'s'
|
|||
|
JZ RET
|
|||
|
INC DL
|
|||
|
CMP AL,'d'
|
|||
|
RET
|
|||
|
PREG:
|
|||
|
MOV DL,4
|
|||
|
MOV AL,CL
|
|||
|
CMP AL,'s'
|
|||
|
JZ RET
|
|||
|
INC DL
|
|||
|
CMP AL,'b'
|
|||
|
RET
|
|||
|
SCANREG:
|
|||
|
MOV AL,CL
|
|||
|
MOV CX,4
|
|||
|
UP
|
|||
|
MOV DI,BX
|
|||
|
REPNZ
|
|||
|
SCAB
|
|||
|
MOV BX,DI
|
|||
|
JNZ RET
|
|||
|
MOV AL,CL
|
|||
|
ADD AL,DL
|
|||
|
MOV DL,AL
|
|||
|
XOR AL,AL
|
|||
|
RET
|
|||
|
|
|||
|
REGTAB: DB 'bdca'
|
|||
|
|
|||
|
SEGTAB: DB 'dsce'
|
|||
|
|
|||
|
LOOK:
|
|||
|
MOV CH,[BX]
|
|||
|
INC BX
|
|||
|
MOV DX,ID
|
|||
|
CALL CPSLP
|
|||
|
JZ RET
|
|||
|
XOR AL,80H
|
|||
|
ROL AL ;Make end-of-symbol bit least significant
|
|||
|
MOV CL,AL
|
|||
|
DEC BX
|
|||
|
MOV AL,[BX]
|
|||
|
XOR AL,80H
|
|||
|
ROL AL
|
|||
|
CMP AL,CL
|
|||
|
JNC SMALL
|
|||
|
INC CH
|
|||
|
INC CH
|
|||
|
SMALL:
|
|||
|
MOV DL,CH
|
|||
|
MOV DH,0
|
|||
|
ADD BX,DX
|
|||
|
MOV DX,[BX]
|
|||
|
INC BX
|
|||
|
MOV AL,DL
|
|||
|
OR AL,DH
|
|||
|
STC
|
|||
|
JZ RET
|
|||
|
XCHG DX,BX
|
|||
|
JP LOOK
|
|||
|
|
|||
|
LOOKRET:
|
|||
|
MOV AL,CH
|
|||
|
CMP AL,3 ;RET has 3 letters
|
|||
|
JNZ LOOKUP
|
|||
|
DEC BX
|
|||
|
OR B,[BX],080H
|
|||
|
MOV DX,RETSTR+2
|
|||
|
CHKRET:
|
|||
|
MOV SI,DX
|
|||
|
LODB
|
|||
|
CMP AL,[BX]
|
|||
|
JNZ LOOKIT
|
|||
|
DEC BX
|
|||
|
DEC DX
|
|||
|
DEC CH
|
|||
|
JNZ CHKRET
|
|||
|
MOV DX,[LSTRET]
|
|||
|
MOV AL,DL
|
|||
|
AND AL,DH
|
|||
|
INC AL
|
|||
|
JZ ALLRET
|
|||
|
MOV BX,[PC]
|
|||
|
SUB BX,DX
|
|||
|
MOV AL,BL
|
|||
|
CBW
|
|||
|
CMP AX,BX ;Signed 8-bit number?
|
|||
|
MOV AL,1
|
|||
|
JZ RET
|
|||
|
ALLRET:
|
|||
|
MOV BX,[RETPT]
|
|||
|
MOV AL,BH
|
|||
|
OR AL,BL
|
|||
|
MOV AL,0
|
|||
|
JNZ RET
|
|||
|
MOV BX,[HEAP]
|
|||
|
DEC BX
|
|||
|
DEC BX
|
|||
|
DEC BX
|
|||
|
MOV [HEAP],BX
|
|||
|
XOR AL,AL
|
|||
|
MOV [BX],AL
|
|||
|
MOV [RETPT],BX
|
|||
|
RET
|
|||
|
|
|||
|
LOOKUP:
|
|||
|
DEC BX
|
|||
|
OR B,[BX],080H
|
|||
|
LOOKIT:
|
|||
|
MOV BX,[BASE]
|
|||
|
MOV AL,BH
|
|||
|
OR AL,BL
|
|||
|
JZ EMPTY
|
|||
|
CALL LOOK
|
|||
|
JC ENTER
|
|||
|
MOV DX,4
|
|||
|
ADD BX,DX
|
|||
|
MOV AL,[BX]
|
|||
|
OR AL,AL
|
|||
|
JZ RET
|
|||
|
INC BX
|
|||
|
MOV DX,[BX]
|
|||
|
INC BX
|
|||
|
RET
|
|||
|
|
|||
|
ENTER:
|
|||
|
PUSH BX ;Save pointer to link field
|
|||
|
CALL CREATE ;Add the node
|
|||
|
POP SI
|
|||
|
MOV [SI-1],DX ;Link new node
|
|||
|
RET ;Zero was set by CREATE
|
|||
|
|
|||
|
EMPTY:
|
|||
|
CALL CREATE
|
|||
|
MOV [BASE],DX
|
|||
|
RET
|
|||
|
|
|||
|
|
|||
|
CREATE:
|
|||
|
|
|||
|
; Add a new node to the identifier tree. The identifier is at ID with
|
|||
|
; bit 7 of the last character set to one. The length of the identifier is
|
|||
|
; in LENID, which is ID-1.
|
|||
|
;
|
|||
|
; Node format:
|
|||
|
; 1. Length of identifier (1 byte)
|
|||
|
; 2. Identifier (1-80 bytes)
|
|||
|
; 3. Left link (2-byte pointer to alphabetically smaller identifiers)
|
|||
|
; 4. Right link (0 if none larger)
|
|||
|
; 5. Data field:
|
|||
|
; a. Defined flag (0=undefined, 1=defined)
|
|||
|
; b. Value (2 bytes)
|
|||
|
;
|
|||
|
; This routine returns with AL=zero and zero flag set (which indicates
|
|||
|
; on return from LOOKUP that it has not yet been defined), DX points
|
|||
|
; to start of new node, and BX points to data field of new node.
|
|||
|
|
|||
|
MOV AL,[LENID]
|
|||
|
ADD AL,8 ;Storage needed for the node
|
|||
|
MOV BX,[HEAP]
|
|||
|
MOV DL,AL
|
|||
|
MOV DH,0
|
|||
|
SUB BX,DX ;Heap grows downward
|
|||
|
MOV [HEAP],BX
|
|||
|
XCHG DX,BX
|
|||
|
MOV BX,[CODE] ;Check to make sure there's enough
|
|||
|
CMP BX,DX
|
|||
|
JB $+5
|
|||
|
JMP ABORT
|
|||
|
PUSH DX
|
|||
|
MOV BX,LENID
|
|||
|
MOV CL,[BX]
|
|||
|
INC CL
|
|||
|
MOV CH,0
|
|||
|
UP
|
|||
|
MOV SI,BX
|
|||
|
MOV DI,DX
|
|||
|
REP
|
|||
|
MOVB ;Move identifier and length into node
|
|||
|
MOV DX,DI
|
|||
|
MOV BX,SI
|
|||
|
MOV CH,4
|
|||
|
XCHG DX,BX
|
|||
|
NILIFY:
|
|||
|
MOV [BX],CL ;Zero left and right links
|
|||
|
INC BX
|
|||
|
DEC CH
|
|||
|
JNZ NILIFY
|
|||
|
XOR AL,AL ;Set zero flag
|
|||
|
MOV [BX],AL ;Zero defined flag
|
|||
|
POP DX ;Restore pointer to node
|
|||
|
RET
|
|||
|
|
|||
|
CPSLP:
|
|||
|
MOV SI,DX
|
|||
|
LODB
|
|||
|
CMP AL,[BX]
|
|||
|
LAHF
|
|||
|
INC DX
|
|||
|
INC BX
|
|||
|
SAHF
|
|||
|
JNZ RET
|
|||
|
DEC CH
|
|||
|
JNZ CPSLP
|
|||
|
RET
|
|||
|
|
|||
|
GETLAB:
|
|||
|
MOV BX,0
|
|||
|
MOV [LABPT],BX
|
|||
|
MOV B,[FLAG],-1
|
|||
|
MOV DH,0
|
|||
|
MOV AL,[CHR]
|
|||
|
CMP AL,' '+1
|
|||
|
JC NOT1
|
|||
|
OR DH,001H
|
|||
|
NOT1:
|
|||
|
CALL GETLET
|
|||
|
JC RET
|
|||
|
CMP AL,':'
|
|||
|
JNZ LABCHK
|
|||
|
CALL NEXTCHR
|
|||
|
JP LABEL
|
|||
|
LABCHK:
|
|||
|
OR AL,AL
|
|||
|
TEST DH,001H
|
|||
|
JZ RET
|
|||
|
LABEL:
|
|||
|
MOV AL,[CHKLAB]
|
|||
|
OR AL,AL
|
|||
|
JZ $+5
|
|||
|
JMP GETLET
|
|||
|
CALL LOOKUP
|
|||
|
MOV CL,11
|
|||
|
JNZ ERR5
|
|||
|
MOV DX,[PC]
|
|||
|
MOV B,[BX],1
|
|||
|
INC BX
|
|||
|
MOV [BX],DX
|
|||
|
MOV [LABPT],BX
|
|||
|
JMP GETLET
|
|||
|
|
|||
|
ERR5: JMP ERROR
|
|||
|
|
|||
|
ASMLIN:
|
|||
|
MOV B,[MAXFLG],1 ;Allow only B and W flags normally
|
|||
|
MOV BX,[PC]
|
|||
|
MOV [OLDPC],BX
|
|||
|
CALL GETLAB
|
|||
|
JNC $+5
|
|||
|
JMP ENDLN
|
|||
|
MOV BX,LENID
|
|||
|
MOV AL,[BX]
|
|||
|
MOV CL,12
|
|||
|
SUB AL,2
|
|||
|
MOV CH,AL
|
|||
|
JC ERR5
|
|||
|
INC BX
|
|||
|
CMP B,[BX],"f" ;See if an 8087 mnemonic
|
|||
|
JZ NDPOP
|
|||
|
CMP AL,5
|
|||
|
JNC ERR5
|
|||
|
MOV AL,[BX]
|
|||
|
SUB AL,'a'
|
|||
|
MOV CL,AL
|
|||
|
ADD AL,AL
|
|||
|
ADD AL,AL
|
|||
|
ADD AL,CL
|
|||
|
ADD AL,CH
|
|||
|
ADD AL,AL
|
|||
|
MOV BX,OPTAB
|
|||
|
MOV DL,AL
|
|||
|
MOV DH,0
|
|||
|
ADD BX,DX
|
|||
|
MOV BX,[BX]
|
|||
|
INC CH
|
|||
|
MOV CL,CH
|
|||
|
MOV AH,[BX]
|
|||
|
INC BX
|
|||
|
OR AH,AH
|
|||
|
JZ OPERR
|
|||
|
FINDOP:
|
|||
|
MOV CH,CL
|
|||
|
MOV DX,ID+1
|
|||
|
XCHG AX,BP ;Save count of opcodes in BP
|
|||
|
CALL CPSLP
|
|||
|
JZ HAVOP
|
|||
|
XCHG AX,BP
|
|||
|
MOV DH,0
|
|||
|
MOV DL,CH
|
|||
|
INC DX
|
|||
|
INC DX
|
|||
|
ADD BX,DX
|
|||
|
DEC AH
|
|||
|
JNZ FINDOP
|
|||
|
OPERR:
|
|||
|
MOV CL,12
|
|||
|
JMP ERROR
|
|||
|
|
|||
|
HAVOP:
|
|||
|
MOV AL,[BX+2] ;Get opcode
|
|||
|
JMP [BX]
|
|||
|
|
|||
|
NDPOP: ;First letter is "F" so must be 8087 opcode ("Numeric Data Processor")
|
|||
|
MOV B,[MAXFLG],4 ;Allow all type flags
|
|||
|
INC BX
|
|||
|
CMP B,[BX],"n" ;"No-wait" form?
|
|||
|
MOV AH,0
|
|||
|
JNZ SAVNFLG
|
|||
|
MOV AH,1
|
|||
|
DEC AL
|
|||
|
INC BX ;Skip over the "N"
|
|||
|
SAVNFLG:
|
|||
|
MOV [NOWAIT],AH ;0 for wait, 1 for no wait
|
|||
|
CMP AL,1
|
|||
|
JB OPERR ;Not enough char left for valid opcode?
|
|||
|
CMP AL,5
|
|||
|
JA OPERR ;Too many?
|
|||
|
CBW
|
|||
|
XCHG AX,DX ;Save length in DX
|
|||
|
MOV SI,DX
|
|||
|
OR B,[SI+BX],80H ;Set high bit of last character
|
|||
|
MOV AL,[BX] ;Get first char of opcode
|
|||
|
INC BX
|
|||
|
SUB AL,"a"
|
|||
|
JB TRY2XM1 ;Go see if opcode starts with "2"
|
|||
|
CMP AL,"z"-"a"
|
|||
|
JA OPERR
|
|||
|
CBW
|
|||
|
SHL AX ;Double to index into address table
|
|||
|
XCHG AX,SI ;Put in index register
|
|||
|
MOV DI,[SI+NDPTAB] ;Get start of opcode table for this letter
|
|||
|
LOOKNDP:
|
|||
|
MOV AH,[DI] ;Number of opcodes starting with this letter
|
|||
|
OR AH,AH
|
|||
|
JZ OPERR ;Any start with this letter?
|
|||
|
FNDNDP:
|
|||
|
INC DI
|
|||
|
MOV SI,BX ;Pointer to start of opcode
|
|||
|
MOV CX,DX ;Get length of opcode
|
|||
|
REPE
|
|||
|
CMPB ;Compare opcode to table entry
|
|||
|
JZ HAVNDP
|
|||
|
DEC DI ;Back up in case that was last letter
|
|||
|
MOV AL,80H ;Look for char with high bit set
|
|||
|
ENDOP:
|
|||
|
SCASB
|
|||
|
JA ENDOP
|
|||
|
INC DI ;Skip over info about opcode
|
|||
|
DEC AH
|
|||
|
JNZ FNDNDP
|
|||
|
OPERRJ: JP OPERR
|
|||
|
|
|||
|
TRY2XM1:
|
|||
|
CMP AL,"2"-"a"
|
|||
|
JNZ OPERR
|
|||
|
MOV DI,XM1
|
|||
|
JP LOOKNDP
|
|||
|
|
|||
|
SPECIALOP:
|
|||
|
AND AL,7 ;Mask to special op number
|
|||
|
JZ FWAIT ;If zero, go handle FWAIT
|
|||
|
;Handle FNOP
|
|||
|
CMP B,[NOWAIT],0 ;Was "N" present (If not opcode was "FOP")
|
|||
|
JZ OPERR
|
|||
|
MOV AL,9BH ;Need Wait opcode after all
|
|||
|
CALL PUT
|
|||
|
MOV AL,0D9H
|
|||
|
CALL PUT
|
|||
|
MOV AL,0D0H
|
|||
|
JMP PUT
|
|||
|
|
|||
|
FWAIT:
|
|||
|
CMP B,[NOWAIT],0 ;"FNWAIT" not legal
|
|||
|
JNZ OPERRJ
|
|||
|
RET ;Nothing to do - "WAIT" already sent
|
|||
|
|
|||
|
HAVNDP:
|
|||
|
MOV SI,DI
|
|||
|
CMP B,[NOWAIT],0
|
|||
|
JNZ NWAIT
|
|||
|
MOV AL,9BH ;Wait opcode
|
|||
|
CALL PUT
|
|||
|
NWAIT:
|
|||
|
LODW ;Get opcode info
|
|||
|
TEST AL,0F8H ;Any operand bits set?
|
|||
|
JZ NOOPS ;If no operands, output code
|
|||
|
TEST AL,78H ;Special case?
|
|||
|
JZ SPECIALOP
|
|||
|
PUSH AX
|
|||
|
CALL GETSYM ;See if any operands
|
|||
|
POP CX
|
|||
|
CMP AL,";"
|
|||
|
JZ NOOPCHK
|
|||
|
CMP AL,EOL
|
|||
|
JZ NOOPCHK
|
|||
|
CMP AL,FREG ;Is it 8087 register?
|
|||
|
JNZ MEMOP
|
|||
|
XCHG AX,CX
|
|||
|
TEST AL,ONEREG ;One register OK as operand?
|
|||
|
JNZ PUTREG ;Yes - save it
|
|||
|
TEST AL,20H ;Memory-only operation?
|
|||
|
MOV CL,20
|
|||
|
JNZ ERRJ4
|
|||
|
TEST AL,18H ;Two-register operation?
|
|||
|
JPE ERRJ4 ;Must be exactly one bit set
|
|||
|
PUSH DX ;Save register number
|
|||
|
PUSH AX ;Save opcode
|
|||
|
CALL GETSYM
|
|||
|
CMP AL,","
|
|||
|
MOV CL,15H
|
|||
|
JNZ ERRJ4
|
|||
|
CALL GETSYM
|
|||
|
MOV CL,20
|
|||
|
CMP AL,FREG
|
|||
|
JNZ ERRJ4
|
|||
|
POP AX
|
|||
|
POP BX
|
|||
|
XOR AL,2 ;Flip "POP" bit
|
|||
|
AND AL,0FBH ;Reset direction bit to ST(0)
|
|||
|
OR BL,BL ;Is first register ST(0)?
|
|||
|
JZ ST0DEST
|
|||
|
XCHG DX,BX
|
|||
|
OR BL,BL ;One of these must be ST(0)
|
|||
|
JNZ ERRJ4
|
|||
|
XOR AL,4 ;Flip direction
|
|||
|
JMPS PUTREG
|
|||
|
ST0DEST:
|
|||
|
TEST AL,2 ;Is POP bit set?
|
|||
|
JNZ ERRJ4 ;Don't allow destination ST(0) then pop
|
|||
|
PUTREG:
|
|||
|
AND AH,0F8H ;Zero out register field
|
|||
|
OR AH,DL
|
|||
|
OR AH,0C0H
|
|||
|
PUSH AX
|
|||
|
CALL GETSYM ;Get to next symbol
|
|||
|
POP AX
|
|||
|
JMPS NOOPS
|
|||
|
|
|||
|
NOOPCHK:
|
|||
|
XCHG AX,CX
|
|||
|
TEST AL,80H ;Is no operands OK?
|
|||
|
MOV CL,20
|
|||
|
JNZ ERRJ4
|
|||
|
NOOPS:
|
|||
|
;First test for FDIV or FSUB and reverse "R" bit if "D" bit is set
|
|||
|
PUSH AX
|
|||
|
AND AX,0E005H
|
|||
|
CMP AX,0E004H
|
|||
|
POP AX
|
|||
|
JNZ NOREV
|
|||
|
XOR AH,8 ;Reverse "R" bit
|
|||
|
NOREV:
|
|||
|
AND AL,7
|
|||
|
OR AL,0D8H ;ESC hook
|
|||
|
CALL PUT
|
|||
|
MOV AL,AH
|
|||
|
JMP PUT
|
|||
|
|
|||
|
BADFLAG:
|
|||
|
MOV CL,20H
|
|||
|
ERRJ4: JMP ERROR
|
|||
|
|
|||
|
MEMOP:
|
|||
|
PUSH CX ;Save opcode
|
|||
|
CALL GETOP1 ;Get memory operand
|
|||
|
CMP AL,UNDEFID ;Is it?
|
|||
|
MOV CL,20
|
|||
|
JNZ ERRJ4
|
|||
|
POP AX
|
|||
|
TEST AL,20H ;Does it have memory format field?
|
|||
|
JNZ GETFORMAT
|
|||
|
TEST AL,8 ;Check if any memory operand legal
|
|||
|
JZ ERRJ4
|
|||
|
TEST AL,10H ;Check for 2-op arithmetic
|
|||
|
JNZ PUTMEM ;If not, just use as plain memory op
|
|||
|
GETFORMAT:
|
|||
|
AND AL,0F9H ;Zero memory format bits
|
|||
|
MOV CL,[FLAG]
|
|||
|
DEC CL ;Must now be in range 0-3
|
|||
|
JL BADFLAG
|
|||
|
MOV CH,AL ;Save opcode byte
|
|||
|
SHR AL ;Put format bits in bits 2 & 3
|
|||
|
AND AL,0CH
|
|||
|
OR AL,CL ;Combine format bits with flag
|
|||
|
MOV BX,FORMATTAB
|
|||
|
XLAT
|
|||
|
OR AL,AL ;Valid combination?
|
|||
|
JS BADFLAG
|
|||
|
OR AH,AL ;Possibly set new bits in second byte
|
|||
|
OR AL,CH ;Set memory format bits
|
|||
|
PUTMEM:
|
|||
|
AND AL,7
|
|||
|
OR AL,0D8H
|
|||
|
CALL PUT
|
|||
|
MOV AL,AH
|
|||
|
AND AL,38H
|
|||
|
OR AL,DL ;Combine addressing mode
|
|||
|
JMP PUTADD
|
|||
|
|
|||
|
FORMATTAB:
|
|||
|
;There are 16 entries in this table. The 4-bit index is built like this:
|
|||
|
; Bit 3 0 for normal memory ops, 1 if extended is OK
|
|||
|
; Bit 2 0 for integer, 1 for real
|
|||
|
; Bit 0 & 1 Flag: 00=W, 01=S, 10=L, 11=T
|
|||
|
;
|
|||
|
;The entries in the table are used as two 3-bit fields. Bits 0-2 are ORed
|
|||
|
;into the first byte of the opcode for the Memory Format field. Bits 3-6
|
|||
|
;are ORed into the second byte to modify the opcode for extended operands.
|
|||
|
;If bit 7 is set, then that combination is illegal.
|
|||
|
|
|||
|
DB 6,2,80H,80H ;Normal integers
|
|||
|
DB 80H,0,4,80H ;Normal reals
|
|||
|
DB 6,2,2EH,80H ;Extended integers
|
|||
|
DB 80H,0,4,2BH ;Extended reals
|
|||
|
|
|||
|
GRP1:
|
|||
|
MOV CX,8A09H
|
|||
|
CALL MROPS
|
|||
|
MOV CX,0C6H
|
|||
|
MOV AL,BH
|
|||
|
CMP AL,UNDEFID
|
|||
|
JNZ L0006
|
|||
|
CALL STIMM
|
|||
|
L0006:
|
|||
|
AND AL,1
|
|||
|
JZ BYTIMM
|
|||
|
MOV AL,0B8H
|
|||
|
OR AL,BL
|
|||
|
CALL PUT
|
|||
|
JMP PUTWOR
|
|||
|
|
|||
|
BYTIMM:
|
|||
|
MOV AL,0B0H
|
|||
|
OR AL,BL
|
|||
|
CALL PUT
|
|||
|
PUTBJ: JMP PUTBYT
|
|||
|
|
|||
|
IMMED:
|
|||
|
MOV AL,BH
|
|||
|
CMP AL,UNDEFID
|
|||
|
JZ STIMM
|
|||
|
MOV AL,BL
|
|||
|
OR AL,AL
|
|||
|
JZ RET
|
|||
|
MOV AL,BH
|
|||
|
CALL IMM
|
|||
|
OR AL,0C0H
|
|||
|
CALL PUT
|
|||
|
FINIMM:
|
|||
|
MOV AL,CL
|
|||
|
POP CX
|
|||
|
TEST AL,1
|
|||
|
JZ PUTBJ
|
|||
|
CMP AL,83H
|
|||
|
JZ PUTBJ
|
|||
|
JMP PUTWOR
|
|||
|
|
|||
|
STIMM:
|
|||
|
MOV AL,[FLAG]
|
|||
|
CALL IMM
|
|||
|
CALL PUTADD
|
|||
|
JP FINIMM
|
|||
|
|
|||
|
IMM:
|
|||
|
AND AL,1
|
|||
|
OR AL,CL
|
|||
|
MOV CL,AL
|
|||
|
CALL PUT
|
|||
|
MOV AL,CH
|
|||
|
AND AL,38H
|
|||
|
OR AL,BL
|
|||
|
RET
|
|||
|
|
|||
|
PUT:
|
|||
|
;Save byte in AL as pure code, with intermediate code bits 00. AL and
|
|||
|
;DI destroyed, no other registers affected.
|
|||
|
PUSH BX
|
|||
|
PUSH CX
|
|||
|
MOV CH,0 ;Flag as pure code
|
|||
|
CALL GEN
|
|||
|
POP CX
|
|||
|
POP BX
|
|||
|
RET
|
|||
|
|
|||
|
GEN:
|
|||
|
;Save byte of code in AL, given intermediate code bits in bits 7&8 of CH.
|
|||
|
CALL PUTINC ;Save it and bump code pointer
|
|||
|
GEN1:
|
|||
|
MOV AL,[RELOC]
|
|||
|
RCL CH
|
|||
|
RCL AL
|
|||
|
RCL CH
|
|||
|
RCL AL
|
|||
|
MOV [RELOC],AL
|
|||
|
MOV BX,BCOUNT
|
|||
|
DEC B,[BX]
|
|||
|
JNZ RET
|
|||
|
MOV B,[BX],4
|
|||
|
MOV BX,RELOC
|
|||
|
MOV AL,[BX]
|
|||
|
MOV B,[BX],0
|
|||
|
MOV DI,[IY]
|
|||
|
MOV [DI],AL
|
|||
|
MOV BX,[CODE]
|
|||
|
MOV [IY],BX
|
|||
|
INC BX
|
|||
|
MOV [CODE],BX
|
|||
|
RET
|
|||
|
|
|||
|
PUTINC:
|
|||
|
INC [PC]
|
|||
|
PUTCD:
|
|||
|
MOV DI,[CODE]
|
|||
|
STOB
|
|||
|
MOV [CODE],DI
|
|||
|
RET
|
|||
|
|
|||
|
PUTWOR:
|
|||
|
;Save the word value described by [DLABEL] and [DATA] as code. If defined,
|
|||
|
;two bytes of pure code will be produced. Otherwise, appropriate intermediate
|
|||
|
;code will be generated.
|
|||
|
PUSH CX
|
|||
|
MOV CH,80H
|
|||
|
PUSH DX
|
|||
|
PUSH BX
|
|||
|
JP PUTBW
|
|||
|
|
|||
|
PUTBYT:
|
|||
|
;Same as PUTWOR, above, but for byte value.
|
|||
|
PUSH CX
|
|||
|
MOV CH,40H
|
|||
|
PUSH DX
|
|||
|
PUSH BX
|
|||
|
MOV BX,[DLABEL]
|
|||
|
MOV AL,BH
|
|||
|
OR AL,BL
|
|||
|
JNZ PUTBW
|
|||
|
MOV BX,[DATA]
|
|||
|
OR AL,BH
|
|||
|
JZ PUTBW
|
|||
|
INC BH
|
|||
|
JZ PUTBW
|
|||
|
MOV CL,31
|
|||
|
JMP ERROR
|
|||
|
PUTBW:
|
|||
|
MOV DX,[DLABEL]
|
|||
|
MOV BX,[DATA]
|
|||
|
PUTCHK:
|
|||
|
OR DX,DX
|
|||
|
JZ NOUNDEF
|
|||
|
MOV AL,DL
|
|||
|
CALL PUTCD
|
|||
|
MOV AL,DH
|
|||
|
CALL PUTCD
|
|||
|
MOV AL,BL
|
|||
|
CALL PUTINC
|
|||
|
MOV AL,BH
|
|||
|
TEST CH,080H
|
|||
|
JZ SMPUT
|
|||
|
CALL GEN
|
|||
|
JP PRET
|
|||
|
SMPUT:
|
|||
|
CALL PUTCD
|
|||
|
CALL GEN1
|
|||
|
PRET:
|
|||
|
POP BX
|
|||
|
POP DX
|
|||
|
POP CX
|
|||
|
RET
|
|||
|
|
|||
|
NOUNDEF:
|
|||
|
MOV AL,BL
|
|||
|
MOV CL,BH
|
|||
|
PUSH CX
|
|||
|
MOV CH,0
|
|||
|
CALL GEN
|
|||
|
POP CX
|
|||
|
MOV AL,CL
|
|||
|
TEST CH,080H
|
|||
|
MOV CH,0
|
|||
|
JZ PRET
|
|||
|
CALL GEN
|
|||
|
JP PRET
|
|||
|
|
|||
|
PUTADD:
|
|||
|
;Save complete addressing mode. Addressing mode is in AL; if this is a register
|
|||
|
;operation (>=C0), then the one byte will be saved as pure code. Otherwise,
|
|||
|
;the details of the addressing mode will be investigated and the optional one-
|
|||
|
;or two-byte displacement will be added, as described by [ADDR] and [ALABEL].
|
|||
|
PUSH CX
|
|||
|
PUSH DX
|
|||
|
PUSH BX
|
|||
|
MOV CH,0
|
|||
|
MOV CL,AL
|
|||
|
CALL GEN ;Save the addressing mode as pure code
|
|||
|
MOV AL,CL
|
|||
|
MOV CH,80H
|
|||
|
AND AL,0C7H
|
|||
|
CMP AL,6
|
|||
|
JZ TWOBT ;Direct address?
|
|||
|
AND AL,0C0H
|
|||
|
JZ PRET ;Indirect through reg, no displacement?
|
|||
|
CMP AL,0C0H
|
|||
|
JZ PRET ;Register to register operation?
|
|||
|
MOV CH,AL ;Save whether one- or two-byte displacement
|
|||
|
TWOBT:
|
|||
|
MOV BX,[ADDR]
|
|||
|
MOV DX,[ALABEL]
|
|||
|
JP PUTCHK
|
|||
|
|
|||
|
GRP2:
|
|||
|
CALL GETOP
|
|||
|
MOV CX,0FF30H
|
|||
|
CMP AL,UNDEFID
|
|||
|
JZ PMEM
|
|||
|
MOV CH,50H
|
|||
|
CMP AL,XREG
|
|||
|
JZ PXREG
|
|||
|
MOV CH,6
|
|||
|
CMP AL,SREG
|
|||
|
JNZ $+5
|
|||
|
JMP PACKREG
|
|||
|
MOV CL,20
|
|||
|
JMP ERROR
|
|||
|
|
|||
|
PMEM:
|
|||
|
MOV AL,CH
|
|||
|
CALL PUT
|
|||
|
MOV AL,CL
|
|||
|
OR AL,DL
|
|||
|
JMP PUTADD
|
|||
|
|
|||
|
PXREG:
|
|||
|
MOV AL,CH
|
|||
|
OR AL,DL
|
|||
|
JMP PUT
|
|||
|
|
|||
|
GRP3:
|
|||
|
CALL GETOP
|
|||
|
PUSH DX
|
|||
|
CALL GETOP2
|
|||
|
POP BX
|
|||
|
MOV CX,8614H
|
|||
|
MOV AL,SREG
|
|||
|
CMP AL,BH
|
|||
|
JZ ERR6
|
|||
|
CMP AL,DH
|
|||
|
JZ ERR6
|
|||
|
MOV AL,CONST
|
|||
|
CMP AL,BH
|
|||
|
JZ ERR6
|
|||
|
CMP AL,DH
|
|||
|
JZ ERR6
|
|||
|
MOV AL,UNDEFID
|
|||
|
CMP AL,BH
|
|||
|
JZ EXMEM
|
|||
|
CMP AL,DH
|
|||
|
JZ EXMEM1
|
|||
|
MOV AL,BH
|
|||
|
CMP AL,DH
|
|||
|
MOV CL,22
|
|||
|
JNZ ERR6
|
|||
|
CMP AL,XREG
|
|||
|
JZ L0008
|
|||
|
CALL RR1
|
|||
|
L0008: ;RR1 never returns
|
|||
|
MOV AL,BL
|
|||
|
OR AL,AL
|
|||
|
JZ EXACC
|
|||
|
XCHG DX,BX
|
|||
|
MOV AL,BL
|
|||
|
OR AL,AL
|
|||
|
MOV AL,BH
|
|||
|
JZ EXACC
|
|||
|
CALL RR1
|
|||
|
EXACC:
|
|||
|
MOV AL,90H
|
|||
|
OR AL,DL
|
|||
|
JMP PUT
|
|||
|
|
|||
|
EXMEM:
|
|||
|
XCHG DX,BX
|
|||
|
EXMEM1:
|
|||
|
CMP AL,BH
|
|||
|
JZ ERR6
|
|||
|
MOV CL,1 ;Flag word as OK
|
|||
|
CALL NOTAC ;NOTAC never returns
|
|||
|
ERR6: JMP ERROR
|
|||
|
|
|||
|
GRP4:
|
|||
|
PUSH AX
|
|||
|
CALL GETOP
|
|||
|
POP CX
|
|||
|
XCHG CL,CH
|
|||
|
CMP AL,CONST
|
|||
|
JZ FIXED
|
|||
|
SUB AL,XREG
|
|||
|
DEC DL
|
|||
|
DEC DL
|
|||
|
OR AL,DL
|
|||
|
MOV CL,20
|
|||
|
JNZ ERR6
|
|||
|
MOV AL,CH
|
|||
|
OR AL,8
|
|||
|
JMP PUT
|
|||
|
FIXED:
|
|||
|
MOV AL,CH
|
|||
|
CALL PUT
|
|||
|
JMP PUTBYT
|
|||
|
|
|||
|
GRP5:
|
|||
|
PUSH AX
|
|||
|
CALL GETOP
|
|||
|
MOV CL,20
|
|||
|
CMP AL,CONST
|
|||
|
JNZ ERR6
|
|||
|
MOV BX,[DLABEL]
|
|||
|
MOV AL,BH
|
|||
|
OR AL,BL
|
|||
|
MOV CL,30
|
|||
|
JNZ ERR6
|
|||
|
MOV BX,[DATA]
|
|||
|
POP AX
|
|||
|
OR AL,AL
|
|||
|
JZ ORG
|
|||
|
DEC AL
|
|||
|
JZ DSJ
|
|||
|
DEC AL
|
|||
|
JZ EQU
|
|||
|
DEC AL
|
|||
|
JZ $+5
|
|||
|
JMP IF
|
|||
|
PUTOP:
|
|||
|
MOV AL,-3
|
|||
|
JP NEWLOC
|
|||
|
ALIGN:
|
|||
|
MOV AL,[PC]
|
|||
|
AND AL,1
|
|||
|
JZ RET
|
|||
|
MOV BX,1
|
|||
|
DSJ:
|
|||
|
XCHG DX,BX
|
|||
|
MOV BX,[PC]
|
|||
|
ADD BX,DX
|
|||
|
MOV [PC],BX
|
|||
|
XCHG DX,BX
|
|||
|
MOV AL,-4
|
|||
|
JP NEWLOC
|
|||
|
EQU:
|
|||
|
XCHG DX,BX
|
|||
|
MOV BX,[LABPT]
|
|||
|
MOV AL,BH
|
|||
|
OR AL,BL
|
|||
|
MOV CL,34
|
|||
|
JZ ERR7
|
|||
|
MOV [BX],DL
|
|||
|
INC BX
|
|||
|
MOV [BX],DH
|
|||
|
RET
|
|||
|
ORG:
|
|||
|
MOV [PC],BX
|
|||
|
MOV AL,-2
|
|||
|
NEWLOC:
|
|||
|
CALL PUTCD
|
|||
|
MOV AL,BL
|
|||
|
CALL PUTCD
|
|||
|
MOV AL,BH
|
|||
|
CALL PUTCD
|
|||
|
MOV CH,0C0H
|
|||
|
JMP GEN1
|
|||
|
GRP6:
|
|||
|
MOV CH,AL
|
|||
|
MOV CL,4
|
|||
|
CALL MROPS
|
|||
|
MOV CL,23
|
|||
|
ERR7: JMP ERROR
|
|||
|
GRP7:
|
|||
|
MOV CH,AL
|
|||
|
MOV CL,1
|
|||
|
CALL MROPS
|
|||
|
MOV CL,80H
|
|||
|
MOV DX,[DLABEL]
|
|||
|
MOV AL,DH
|
|||
|
OR AL,DL
|
|||
|
JNZ ACCJ
|
|||
|
XCHG DX,BX
|
|||
|
MOV BX,[DATA]
|
|||
|
MOV AL,BL
|
|||
|
CBW
|
|||
|
CMP AX,BX
|
|||
|
XCHG DX,BX
|
|||
|
JNZ ACCJ
|
|||
|
OR CL,002H
|
|||
|
ACCJ: JMP ACCIMM
|
|||
|
GRP8:
|
|||
|
MOV CL,AL
|
|||
|
MOV CH,0FEH
|
|||
|
JP ONEOP
|
|||
|
GRP9:
|
|||
|
MOV CL,AL
|
|||
|
MOV CH,0F6H
|
|||
|
ONEOP:
|
|||
|
PUSH CX
|
|||
|
CALL GETOP
|
|||
|
ONE:
|
|||
|
MOV CL,26
|
|||
|
CMP AL,CONST
|
|||
|
JZ ERR7
|
|||
|
CMP AL,SREG
|
|||
|
MOV CL,22
|
|||
|
JZ ERR7
|
|||
|
POP CX
|
|||
|
CMP AL,UNDEFID
|
|||
|
JZ MOP
|
|||
|
AND AL,1
|
|||
|
JZ ROP
|
|||
|
TEST CL,001H
|
|||
|
JZ ROP
|
|||
|
MOV AL,CL
|
|||
|
AND AL,0F8H
|
|||
|
OR AL,DL
|
|||
|
JMP PUT
|
|||
|
MOP:
|
|||
|
MOV AL,[FLAG]
|
|||
|
AND AL,1
|
|||
|
OR AL,CH
|
|||
|
CALL PUT
|
|||
|
MOV AL,CL
|
|||
|
AND AL,38H
|
|||
|
OR AL,DL
|
|||
|
JMP PUTADD
|
|||
|
ROP:
|
|||
|
OR AL,CH
|
|||
|
CALL PUT
|
|||
|
MOV AL,CL
|
|||
|
AND AL,38H
|
|||
|
OR AL,0C0H
|
|||
|
OR AL,DL
|
|||
|
JMP PUT
|
|||
|
GRP10:
|
|||
|
MOV CL,AL
|
|||
|
MOV CH,0F6H
|
|||
|
PUSH CX
|
|||
|
CALL GETOP
|
|||
|
MOV CL,20
|
|||
|
MOV AL,DL
|
|||
|
OR AL,AL
|
|||
|
JNZ ERRJ1
|
|||
|
MOV AL,DH
|
|||
|
CMP AL,XREG
|
|||
|
JZ G10
|
|||
|
CMP AL,REG
|
|||
|
ERRJ1: JNZ ERR8
|
|||
|
G10:
|
|||
|
PUSH AX
|
|||
|
CALL GETOP
|
|||
|
POP AX
|
|||
|
AND AL,1
|
|||
|
MOV [FLAG],AL
|
|||
|
MOV AL,DH
|
|||
|
ONEJ: JP ONE
|
|||
|
GRP11:
|
|||
|
CALL PUT
|
|||
|
MOV AL,0AH
|
|||
|
JMP PUT
|
|||
|
GRP12:
|
|||
|
MOV CL,AL
|
|||
|
MOV CH,0D0H
|
|||
|
PUSH CX
|
|||
|
CALL GETOP
|
|||
|
MOV AL,[SYM]
|
|||
|
CMP AL,','
|
|||
|
MOV AL,DH
|
|||
|
JNZ ONEJ
|
|||
|
PUSH DX
|
|||
|
CALL GETOP
|
|||
|
SUB AL,REG
|
|||
|
MOV CL,20
|
|||
|
DEC DL
|
|||
|
OR AL,DL
|
|||
|
JNZ ERR8
|
|||
|
POP DX
|
|||
|
MOV AL,DH
|
|||
|
POP CX
|
|||
|
OR CH,002H
|
|||
|
PUSH CX
|
|||
|
JMP ONE
|
|||
|
GRP13:
|
|||
|
MOV CH,AL
|
|||
|
MOV CL,1
|
|||
|
CALL MROPS
|
|||
|
MOV CL,80H
|
|||
|
ACCIMM:
|
|||
|
CALL IMMED
|
|||
|
OR CH,004H
|
|||
|
AND CH,0FDH
|
|||
|
AIMM:
|
|||
|
MOV AL,BH
|
|||
|
AND AL,1
|
|||
|
LAHF
|
|||
|
PUSH AX
|
|||
|
OR AL,CH
|
|||
|
CALL PUT
|
|||
|
POP AX
|
|||
|
SAHF
|
|||
|
JNZ $+5
|
|||
|
JMP PUTBYT
|
|||
|
JMP PUTWOR
|
|||
|
|
|||
|
ERR8: JMP ERROR
|
|||
|
|
|||
|
GRP14:
|
|||
|
;JMP and CALL mnemonics
|
|||
|
LAHF
|
|||
|
XCHG AH,AL
|
|||
|
PUSH AX
|
|||
|
XCHG AH,AL
|
|||
|
MOV B,[MAXFLG],3 ;Allow "L" flag
|
|||
|
CALL GETOP
|
|||
|
CMP AL,CONST
|
|||
|
JZ DIRECT
|
|||
|
MOV CL,20
|
|||
|
CMP AL,REG
|
|||
|
JZ ERR8
|
|||
|
CMP AL,SREG
|
|||
|
JZ ERR8
|
|||
|
CMP AL,XREG
|
|||
|
JNZ NOTRG
|
|||
|
OR DL,0C0H
|
|||
|
NOTRG:
|
|||
|
;Indirect jump. DL has addressing mode.
|
|||
|
MOV AL,0FFH
|
|||
|
CALL PUT
|
|||
|
POP AX
|
|||
|
XCHG AH,AL
|
|||
|
SAHF
|
|||
|
AND AL,38H
|
|||
|
OR AL,DL
|
|||
|
MOV CH,[FLAG]
|
|||
|
CMP CH,3 ;Flag "L" present?
|
|||
|
JZ PUTADDJ ;If so, do inter-segment
|
|||
|
MOV CL,27H
|
|||
|
CMP CH,-1 ;Better not be a flag
|
|||
|
JNZ ERR8
|
|||
|
AND AL,0F7H ;Convert to intra-segment
|
|||
|
PUTADDJ:
|
|||
|
JMP PUTADD
|
|||
|
DIRECT:
|
|||
|
MOV AL,[SYM]
|
|||
|
CMP AL,','
|
|||
|
JZ LONGJ
|
|||
|
POP AX
|
|||
|
XCHG AH,AL
|
|||
|
SAHF
|
|||
|
DEC AL
|
|||
|
CMP AL,0E9H
|
|||
|
JZ GOTOP
|
|||
|
MOV AL,0E8H
|
|||
|
GOTOP:
|
|||
|
CALL PUT
|
|||
|
MOV DX,[PC]
|
|||
|
INC DX
|
|||
|
INC DX
|
|||
|
SUB [DATA],DX
|
|||
|
JMP PUTWOR
|
|||
|
LONGJ:
|
|||
|
POP AX
|
|||
|
XCHG AH,AL
|
|||
|
SAHF
|
|||
|
CALL PUT
|
|||
|
CALL PUTWOR
|
|||
|
CALL GETOP
|
|||
|
MOV CL,20
|
|||
|
CMP AL,CONST
|
|||
|
JNZ ERR8
|
|||
|
JMP PUTWOR
|
|||
|
|
|||
|
GRP16:
|
|||
|
;RET mnemonic
|
|||
|
LAHF
|
|||
|
XCHG AH,AL
|
|||
|
PUSH AX
|
|||
|
XCHG AH,AL
|
|||
|
CALL GETSYM
|
|||
|
CMP AL,5
|
|||
|
JZ LONGR
|
|||
|
CMP AL,EOL
|
|||
|
JZ NODEC
|
|||
|
CMP AL,';'
|
|||
|
JZ NODEC
|
|||
|
GETSP:
|
|||
|
CALL GETOP1
|
|||
|
POP CX
|
|||
|
CMP AL,CONST
|
|||
|
MOV CL,20
|
|||
|
JNZ ERR9
|
|||
|
MOV AL,CH
|
|||
|
AND AL,0FEH
|
|||
|
CALL PUT
|
|||
|
JMP PUTWOR
|
|||
|
LONGR:
|
|||
|
CMP DL,3 ;Is flag "L"?
|
|||
|
MOV CL,27H
|
|||
|
JNZ ERR10 ;If not, bad flag
|
|||
|
POP AX
|
|||
|
XCHG AH,AL
|
|||
|
SAHF
|
|||
|
OR AL,8
|
|||
|
LAHF
|
|||
|
XCHG AH,AL
|
|||
|
PUSH AX
|
|||
|
XCHG AH,AL
|
|||
|
NOTLON:
|
|||
|
CALL GETSYM
|
|||
|
CMP AL,EOL
|
|||
|
JZ DORET
|
|||
|
CMP AL,';'
|
|||
|
JZ DORET
|
|||
|
CMP AL,','
|
|||
|
JNZ L0011
|
|||
|
CALL GETSYM
|
|||
|
L0011:
|
|||
|
JP GETSP
|
|||
|
NODEC:
|
|||
|
;Return is intra-segment (short) without add to SP.
|
|||
|
;Record position for RET symbol.
|
|||
|
MOV BX,[PC]
|
|||
|
MOV [LSTRET],BX
|
|||
|
XCHG DX,BX
|
|||
|
MOV BX,[RETPT]
|
|||
|
MOV AL,BH
|
|||
|
OR AL,BL
|
|||
|
JZ DORET
|
|||
|
MOV B,[BX],1
|
|||
|
INC BX
|
|||
|
MOV [BX],DX
|
|||
|
MOV BX,0
|
|||
|
MOV [RETPT],BX
|
|||
|
DORET:
|
|||
|
POP AX
|
|||
|
XCHG AH,AL
|
|||
|
SAHF
|
|||
|
JMP PUT
|
|||
|
|
|||
|
GRP17:
|
|||
|
CALL PUT
|
|||
|
CALL GETOP
|
|||
|
CMP AL,CONST
|
|||
|
MOV CL,20
|
|||
|
ERR9: JNZ ERR10
|
|||
|
MOV BX,[DATA]
|
|||
|
MOV DX,[PC]
|
|||
|
INC DX
|
|||
|
SUB BX,DX
|
|||
|
MOV [DATA],BX
|
|||
|
CALL PUTBYT
|
|||
|
MOV BX,[DLABEL]
|
|||
|
MOV AL,BH
|
|||
|
OR AL,BL
|
|||
|
JNZ RET
|
|||
|
MOV BX,[DATA]
|
|||
|
MOV AL,BL
|
|||
|
CBW
|
|||
|
CMP AX,BX ;Signed 8-bit number?
|
|||
|
JZ RET
|
|||
|
MOV CL,31
|
|||
|
ERR10: JMP ERROR
|
|||
|
RET
|
|||
|
GRP18:
|
|||
|
CALL GETOP
|
|||
|
CMP AL,CONST
|
|||
|
MOV CL,20
|
|||
|
JNZ ERR10
|
|||
|
MOV BX,[DLABEL]
|
|||
|
MOV AL,BH
|
|||
|
OR AL,BL
|
|||
|
JNZ GENINT
|
|||
|
MOV BX,[DATA]
|
|||
|
MOV DX,3
|
|||
|
SBB BX,DX
|
|||
|
JNZ GENINT
|
|||
|
MOV AL,0CCH
|
|||
|
JMP PUT
|
|||
|
GENINT:
|
|||
|
MOV AL,0CDH
|
|||
|
CALL PUT
|
|||
|
JMP PUTBYT
|
|||
|
|
|||
|
GRP19: ;ESC opcode
|
|||
|
CALL GETOP
|
|||
|
MOV CL,20
|
|||
|
CMP AL,CONST
|
|||
|
JNZ ERRJ ;First operand must be immediate
|
|||
|
MOV CL,1EH
|
|||
|
TEST [DLABEL],-1 ;See if all labels have been defined
|
|||
|
JNZ ERRJ
|
|||
|
MOV AX,[DATA]
|
|||
|
CMP AX,64 ;Must only be 6 bits
|
|||
|
MOV CL,1FH
|
|||
|
JNB ERRJ
|
|||
|
MOV BL,AL ;Save for second byte
|
|||
|
SHR AL
|
|||
|
SHR AL
|
|||
|
SHR AL
|
|||
|
OR AL,0D8H ;ESC opcode
|
|||
|
CALL PUT
|
|||
|
PUSH BX
|
|||
|
CALL GETOP2
|
|||
|
POP BX
|
|||
|
AND BL,7 ;Low 3 bits of first operand
|
|||
|
SHL BL
|
|||
|
SHL BL
|
|||
|
SHL BL
|
|||
|
CMP AL,UNDEFID ;Check for memory operand
|
|||
|
JZ ESCMEM
|
|||
|
CMP AL,CONST ;Check for another immediate
|
|||
|
JZ ESCIMM
|
|||
|
MOV CL,20
|
|||
|
ERRJ: JMP ERROR
|
|||
|
|
|||
|
ESCMEM:
|
|||
|
OR BL,DL ;Combine mode with first operand
|
|||
|
MOV AL,BL
|
|||
|
JMP PUTADD
|
|||
|
|
|||
|
ESCIMM:
|
|||
|
MOV CL,1EH
|
|||
|
TEST [DLABEL],-1 ;See if second operand is fully defined
|
|||
|
JNZ ERRJ
|
|||
|
MOV AX,[DATA]
|
|||
|
MOV CL,1FH
|
|||
|
CMP AX,8 ;Must only be 3 bit value
|
|||
|
JNB ERRJ
|
|||
|
OR AL,BL ;Combine first and second operands
|
|||
|
OR AL,0C0H ;Force "register" mode
|
|||
|
JMP PUT
|
|||
|
|
|||
|
GRP20:
|
|||
|
MOV CH,AL
|
|||
|
MOV CL,1
|
|||
|
CALL MROPS
|
|||
|
MOV CL,0F6H
|
|||
|
CALL IMMED
|
|||
|
MOV CH,0A8H
|
|||
|
JMP AIMM
|
|||
|
GRP21:
|
|||
|
CALL GETOP
|
|||
|
CMP AL,SREG
|
|||
|
MOV CL,28
|
|||
|
JNZ ERRJ
|
|||
|
MOV CH,26H
|
|||
|
PACKREG:
|
|||
|
MOV AL,DL
|
|||
|
ADD AL,AL
|
|||
|
ADD AL,AL
|
|||
|
ADD AL,AL
|
|||
|
OR AL,CH
|
|||
|
JMP PUT
|
|||
|
GRP22:
|
|||
|
CALL GETOP
|
|||
|
MOV CX,8F00H
|
|||
|
CMP AL,UNDEFID
|
|||
|
JNZ $+5
|
|||
|
JMP PMEM
|
|||
|
MOV CH,58H
|
|||
|
CMP AL,XREG
|
|||
|
JNZ $+5
|
|||
|
JMP PXREG
|
|||
|
MOV CH,7
|
|||
|
CMP AL,SREG
|
|||
|
JZ PACKREG
|
|||
|
MOV CL,20
|
|||
|
ERR11: JMP ERROR
|
|||
|
GRP23:
|
|||
|
MOV [DATSIZ],AL
|
|||
|
GETDAT:
|
|||
|
CALL GETSYM
|
|||
|
MOV AL,2
|
|||
|
CALL VAL1
|
|||
|
MOV AL,[SYM]
|
|||
|
CMP AL,','
|
|||
|
MOV AL,[DATSIZ]
|
|||
|
JNZ ENDDAT
|
|||
|
CALL SAVDAT
|
|||
|
JP GETDAT
|
|||
|
ENDDAT:
|
|||
|
CMP AL,2
|
|||
|
JNZ SAVDAT
|
|||
|
MOV BX,[DATA]
|
|||
|
LAHF
|
|||
|
OR BL,080H
|
|||
|
SAHF
|
|||
|
MOV [DATA],BX
|
|||
|
SAVDAT:
|
|||
|
OR AL,AL
|
|||
|
JZ $+5
|
|||
|
JMP PUTBYT
|
|||
|
JMP PUTWOR
|
|||
|
IF:
|
|||
|
OR BX,BX
|
|||
|
JZ SKIPCD
|
|||
|
INC B,[IFFLG]
|
|||
|
RET
|
|||
|
|
|||
|
SKIPCD:
|
|||
|
INC B,[CHKLAB]
|
|||
|
SKIPLP:
|
|||
|
XOR AL,AL
|
|||
|
CALL NEXLIN
|
|||
|
CALL NEXTCHR
|
|||
|
CMP AL,1AH
|
|||
|
JZ END
|
|||
|
CALL GETLAB
|
|||
|
JC SKIPLP
|
|||
|
MOV DI,LENID
|
|||
|
MOV SI,IFEND
|
|||
|
MOV CH,0
|
|||
|
MOV CL,[DI]
|
|||
|
INC CL
|
|||
|
REPE
|
|||
|
CMPB
|
|||
|
JZ ENDCOND
|
|||
|
MOV DI,LENID
|
|||
|
MOV SI,IFNEST
|
|||
|
MOV CL,[DI]
|
|||
|
INC CL
|
|||
|
REPE
|
|||
|
CMPB
|
|||
|
JNZ SKIPLP
|
|||
|
INC B,[CHKLAB]
|
|||
|
JP SKIPLP
|
|||
|
|
|||
|
ENDCOND:
|
|||
|
DEC B,[CHKLAB]
|
|||
|
JNZ SKIPLP
|
|||
|
RET
|
|||
|
|
|||
|
ENDIF:
|
|||
|
MOV AL,[IFFLG]
|
|||
|
MOV CL,36
|
|||
|
DEC AL
|
|||
|
JS ERRJMP
|
|||
|
MOV [IFFLG],AL
|
|||
|
RET
|
|||
|
|
|||
|
ERRJMP: JMP ERROR
|
|||
|
|
|||
|
;*********************************************************************
|
|||
|
;
|
|||
|
; PASS 2
|
|||
|
;
|
|||
|
;*********************************************************************
|
|||
|
|
|||
|
END:
|
|||
|
MOV DL,4
|
|||
|
WREND:
|
|||
|
MOV CH,0FFH
|
|||
|
MOV AL,CH
|
|||
|
CALL GEN
|
|||
|
DEC DL
|
|||
|
JNZ WREND
|
|||
|
MOV [BUFPT],SRCBUF
|
|||
|
MOV B,[HEXCNT],-5 ;FLAG HEX BUFFER AS EMPTY
|
|||
|
MOV [LSTPNT],LSTBUF
|
|||
|
MOV [HEXPNT],HEXBUF
|
|||
|
XOR AX,AX
|
|||
|
MOV [ERRCNT],AX
|
|||
|
MOV [PC],AX
|
|||
|
MOV [LINE],AX ;Current line number
|
|||
|
MOV [HEXADD],OBJECT
|
|||
|
MOV DX,FCB
|
|||
|
MOV AH,OPEN
|
|||
|
INT 33 ;Re-open source file
|
|||
|
XOR AX,AX
|
|||
|
MOV [FCB+12],AX ;Set CURRENT BLOCK to zero
|
|||
|
MOV [FCB+20H],AL ;Set NEXT RECORD field to zero
|
|||
|
MOV [FCB+14],BUFSIZ
|
|||
|
MOV [COUNT],AL
|
|||
|
MOV CH,1
|
|||
|
MOV SI,START
|
|||
|
FIXLINE:
|
|||
|
MOV DI,START ;Store code over used up intermediate code
|
|||
|
XOR AL,AL
|
|||
|
MOV [SPC],AL ;No "special" yet (ORG, PUT, DS)
|
|||
|
MOV [ERR],AL ;No second pass errors yet
|
|||
|
NEXBT:
|
|||
|
SHL CL ;Shift out last bit of previous code
|
|||
|
DEC CH ;Still have codes left?
|
|||
|
JNZ TESTTYP
|
|||
|
LODB ;Get next flag byte
|
|||
|
MOV CL,AL
|
|||
|
MOV CH,4
|
|||
|
TESTTYP:
|
|||
|
SHL CL ;Set flags based on two bits
|
|||
|
JO FIXUP
|
|||
|
LODB
|
|||
|
JC EMARK
|
|||
|
OBJBT:
|
|||
|
STOB
|
|||
|
JP NEXBT
|
|||
|
|
|||
|
FIXUP:
|
|||
|
;Either a word or byte fixup is needed from a forward reference
|
|||
|
LODW ;Get pointer to symbol
|
|||
|
XCHG AX,BX
|
|||
|
LODW ;Get constant part
|
|||
|
ADD AX,[BX+1] ;Add symbol value to constant part
|
|||
|
CMP B,[BX],0 ;See if symbol got defined
|
|||
|
JNZ HAVDEF
|
|||
|
MOV B,[ERR],100 ;Undefined - flag error
|
|||
|
XOR AX,AX
|
|||
|
HAVDEF:
|
|||
|
OR CL,CL ;See if word or byte fixup
|
|||
|
JS DEFBYT
|
|||
|
STOW
|
|||
|
JP NEXBT
|
|||
|
|
|||
|
DEFBYT:
|
|||
|
MOV DX,AX
|
|||
|
CBW ;Extend sign
|
|||
|
CMP AX,DX ;See if in range +127 to -128
|
|||
|
JZ OBJBT ;If so, it's always OK
|
|||
|
NOT AH ;Check for range +255 to -256
|
|||
|
CMP AH,DH
|
|||
|
JNZ RNGERR ;Must always be in this range
|
|||
|
;Check for short jump. If so, we're out of range; otherwise we're OK
|
|||
|
CMP DI,START+1 ;Only one other byte on line?
|
|||
|
JNZ OBJBT ;Can't be short jump if not
|
|||
|
MOV AL,[START] ;Get the first byte of this line
|
|||
|
CMP AL,0EBH ;Direct short jump?
|
|||
|
JZ RNGERR
|
|||
|
AND AL,0FCH
|
|||
|
CMP AL,0E0H ;LOOP or JCXZ instruction?
|
|||
|
JZ RNGERR
|
|||
|
AND AL,0F0H
|
|||
|
CMP AL,70H ;Conditional jump?
|
|||
|
MOV AL,DL ;Get code byte in AL
|
|||
|
JNZ OBJBT ;If not, we're OK
|
|||
|
RNGERR:
|
|||
|
MOV B,[ERR],101 ;Value out of range
|
|||
|
JP OBJBT
|
|||
|
|
|||
|
FINIJ: JMP FINI
|
|||
|
|
|||
|
EMARK:
|
|||
|
CMP AL,-1 ;End of file?
|
|||
|
JZ FINIJ
|
|||
|
CMP AL,-10 ;Special item?
|
|||
|
JA SPEND
|
|||
|
PUSH CX
|
|||
|
PUSH SI
|
|||
|
PUSH AX ;Save error code
|
|||
|
MOV AH,[LSTDEV]
|
|||
|
AND AH,0FEH ;Reset error indicator
|
|||
|
OR AL,[ERR] ;See if any errors on this line
|
|||
|
JZ NOERR
|
|||
|
OR AH,1 ;Send line to console if error occured
|
|||
|
NOERR:
|
|||
|
MOV [LSTDEV],AH
|
|||
|
MOV CX,DI
|
|||
|
CALL STRTLIN ;Print address of line
|
|||
|
MOV SI,START
|
|||
|
SUB CX,SI ;Get count of bytes of code
|
|||
|
JZ SHOLIN
|
|||
|
CODLP:
|
|||
|
LODB
|
|||
|
CALL SAVCD ;Ouput code to HEX and PRN files
|
|||
|
LOOP CODLP
|
|||
|
SHOLIN:
|
|||
|
MOV AL,0
|
|||
|
XCHG AL,[COUNT]
|
|||
|
MOV CX,7 ;Allow 7 bytes of code per line
|
|||
|
SUB CL,AL
|
|||
|
MOV AL,' '
|
|||
|
JZ NOFIL
|
|||
|
BLNK: ;Put in 3 blanks for each byte not present
|
|||
|
CALL LIST
|
|||
|
CALL LIST
|
|||
|
CALL LIST
|
|||
|
LOOP BLNK
|
|||
|
NOFIL:
|
|||
|
CALL OUTLIN
|
|||
|
POP AX ;Restore error code
|
|||
|
CALL REPERR
|
|||
|
MOV AL,[ERR]
|
|||
|
CALL REPERR
|
|||
|
POP SI
|
|||
|
POP CX
|
|||
|
MOV AL,[SPC] ;Any special funtion?
|
|||
|
OR AL,AL
|
|||
|
JNZ SPCFUN
|
|||
|
JMP FIXLINE
|
|||
|
|
|||
|
SPEND:
|
|||
|
MOV [SPC],AL ;Record special function
|
|||
|
LODW ;Get it's data
|
|||
|
MOV [DATA],AX
|
|||
|
JMP NEXBT
|
|||
|
|
|||
|
SPCFUN:
|
|||
|
MOV DX,[DATA]
|
|||
|
CMP AL,-2
|
|||
|
JZ DORG
|
|||
|
CMP AL,-3
|
|||
|
JZ DPUT
|
|||
|
DDS:
|
|||
|
;Handle DS pseudo-op
|
|||
|
ADD [PC],DX
|
|||
|
ADD [HEXADD],DX
|
|||
|
JMP FIXLINE
|
|||
|
|
|||
|
DORG:
|
|||
|
;Handle ORG pseudo-op
|
|||
|
MOV [PC],DX
|
|||
|
JMP FIXLINE
|
|||
|
|
|||
|
DPUT:
|
|||
|
;Handle PUT pseudo-op
|
|||
|
MOV [HEXADD],DX
|
|||
|
JMP FIXLINE
|
|||
|
|
|||
|
OUTLIN:
|
|||
|
;Copy the source line to the ouput device. Line will be preceded by
|
|||
|
;assembler-generated line number. This routine may be called several times
|
|||
|
;on one line (once for each line of object code bytes), so it sets a flag
|
|||
|
;so the line will only be output on the first call.
|
|||
|
MOV AL,-1
|
|||
|
XCHG AL,[LINFLG]
|
|||
|
OR AL,AL
|
|||
|
JNZ CRLF ;Output line only if first time
|
|||
|
MOV AX,[LINE]
|
|||
|
INC AX
|
|||
|
MOV [LINE],AX
|
|||
|
MOV BH,0 ;No leading zero suppression
|
|||
|
CALL OUT10
|
|||
|
MOV AL," "
|
|||
|
CALL LIST
|
|||
|
MOV AL,[LSTFCB]
|
|||
|
CMP AL,'Z'
|
|||
|
JZ CRLF ;Don't call NEXTCHR if listing suppressed
|
|||
|
PUSH SI ;Save the only register destroyed by NEXTCHR
|
|||
|
OUTLN:
|
|||
|
CALL NEXTCHR
|
|||
|
CALL LIST
|
|||
|
CMP AL,10 ;Output until linefeed found
|
|||
|
JNZ OUTLN
|
|||
|
POP SI
|
|||
|
RET
|
|||
|
|
|||
|
PRTCNT:
|
|||
|
MOV AX,[ERRCNT]
|
|||
|
MOV BX,ERCNTM
|
|||
|
PRNT10:
|
|||
|
PUSH AX
|
|||
|
CALL PRINT
|
|||
|
POP AX
|
|||
|
MOV BH,"0"-" " ;Enable leading zero suppression
|
|||
|
CALL OUT10
|
|||
|
CRLF:
|
|||
|
MOV AL,13
|
|||
|
CALL LIST
|
|||
|
MOV AL,10
|
|||
|
JP LIST
|
|||
|
|
|||
|
OUT10:
|
|||
|
XOR DX,DX
|
|||
|
MOV DI,10000
|
|||
|
DIV AX,DI
|
|||
|
OR AL,AL ;>10,000?
|
|||
|
JNZ LEAD
|
|||
|
SUB AL,"0"-" " ;Convert leading zero to blank
|
|||
|
LEAD:
|
|||
|
ADD AL,"0"
|
|||
|
CALL LIST
|
|||
|
XCHG AX,DX
|
|||
|
MOV BL,100
|
|||
|
DIV AL,BL
|
|||
|
MOV BL,AH
|
|||
|
CALL HIDIG ;Convert to decimal and print 1000s digit
|
|||
|
CALL DIGIT ;Print 100s digit
|
|||
|
MOV AL,BL
|
|||
|
CALL HIDIG ;Convert to decimal and print 10s digit
|
|||
|
MOV BH,0 ;Ensure leading zero suppression is off
|
|||
|
JP DIGIT
|
|||
|
|
|||
|
HIDIG:
|
|||
|
AAM ;Convert binary to unpacked BCD
|
|||
|
OR AX,3030H ;Add "0" bias
|
|||
|
DIGIT:
|
|||
|
XCHG AL,AH
|
|||
|
CMP AL,"0"
|
|||
|
JZ SUPZ
|
|||
|
MOV BH,0 ;Turn off zero suppression if not zero
|
|||
|
SUPZ:
|
|||
|
SUB AL,BH ;Convert leading zeros to blanks
|
|||
|
JP LIST
|
|||
|
|
|||
|
STRTLIN:
|
|||
|
MOV B,[LINFLG],0
|
|||
|
MOV BX,[PC]
|
|||
|
MOV AL,BH
|
|||
|
CALL PHEX
|
|||
|
MOV AL,BL
|
|||
|
PHEXB:
|
|||
|
CALL PHEX
|
|||
|
MOV AL,' '
|
|||
|
LIST:
|
|||
|
PUSH AX
|
|||
|
PUSH DX
|
|||
|
AND AL,7FH
|
|||
|
MOV DL,AL
|
|||
|
TEST B,[LSTDEV],3 ;See if output goes to console
|
|||
|
JZ PRNCHK
|
|||
|
MOV AH,2
|
|||
|
INT 33 ;Output to console
|
|||
|
PRNCHK:
|
|||
|
TEST B,[LSTDEV],4 ;See if output goes to printer
|
|||
|
JZ FILCHK
|
|||
|
MOV AH,5
|
|||
|
INT 33 ;Output to printer
|
|||
|
FILCHK:
|
|||
|
MOV AL,DL
|
|||
|
POP DX
|
|||
|
TEST B,[LSTDEV],80H ;See if output goes to a file
|
|||
|
JZ LISTRET
|
|||
|
CALL WRTBUF
|
|||
|
LISTRET:
|
|||
|
POP AX
|
|||
|
RET
|
|||
|
|
|||
|
WRTBUF:
|
|||
|
PUSH DI
|
|||
|
MOV DI,[LSTPNT]
|
|||
|
STOB
|
|||
|
CMP DI,LSTBUF+LSTBUFSIZ
|
|||
|
JNZ SAVPT
|
|||
|
PUSH AX
|
|||
|
PUSH CX
|
|||
|
PUSH DX
|
|||
|
CALL FLUSHBUF
|
|||
|
POP DX
|
|||
|
POP CX
|
|||
|
POP AX
|
|||
|
SAVPT:
|
|||
|
MOV [LSTPNT],DI
|
|||
|
POP DI
|
|||
|
RET
|
|||
|
|
|||
|
PHEX:
|
|||
|
PUSH AX
|
|||
|
CALL UHALF
|
|||
|
CALL LIST
|
|||
|
POP AX
|
|||
|
CALL LHALF
|
|||
|
JP LIST
|
|||
|
|
|||
|
FINI:
|
|||
|
OR B,[LSTDEV],1
|
|||
|
CALL PRTCNT
|
|||
|
MOV BX,SYMSIZE
|
|||
|
MOV AX,[6]
|
|||
|
SUB AX,[HEAP] ;Size of symbol table
|
|||
|
CALL PRNT10
|
|||
|
MOV BX,FRESIZE
|
|||
|
MOV AX,[HEAP]
|
|||
|
SUB AX,[CODE] ;Free space remaining
|
|||
|
CALL PRNT10
|
|||
|
AND B,[LSTDEV],0FEH
|
|||
|
MOV AL,[HEXFCB]
|
|||
|
CMP AL,'Z'
|
|||
|
JZ SYMDMP
|
|||
|
MOV AL,[HEXCNT]
|
|||
|
CMP AL,-5
|
|||
|
JZ L0012
|
|||
|
CALL ENHEXL
|
|||
|
L0012:
|
|||
|
MOV AL,':'
|
|||
|
CALL PUTCHR
|
|||
|
MOV CH,10
|
|||
|
HEXEND:
|
|||
|
PUSH CX
|
|||
|
MOV AL,'0'
|
|||
|
CALL PUTCHR
|
|||
|
POP CX
|
|||
|
DEC CH
|
|||
|
JNZ HEXEND
|
|||
|
MOV AL,13
|
|||
|
CALL PUTCHR
|
|||
|
MOV AL,10
|
|||
|
CALL PUTCHR
|
|||
|
MOV AL,1AH
|
|||
|
CALL PUTCHR
|
|||
|
CALL WRTHEX ;Flush HEX file buffer
|
|||
|
MOV DX,HEXFCB
|
|||
|
MOV AH,CLOSE
|
|||
|
INT 33
|
|||
|
SYMDMP:
|
|||
|
MOV AL,[SYMFLG]
|
|||
|
CMP AL,'S'
|
|||
|
JNZ ENDSYM
|
|||
|
MOV AL,[LSTDEV]
|
|||
|
OR AL,AL ;Any output device for symbol table dump?
|
|||
|
JNZ DOSYMTAB
|
|||
|
OR AL,1 ;If not, send it to console
|
|||
|
MOV [LSTDEV],AL
|
|||
|
DOSYMTAB:
|
|||
|
MOV BX,SYMMES
|
|||
|
CALL PRINT
|
|||
|
MOV DX,[BASE]
|
|||
|
MOV AL,DH
|
|||
|
OR AL,DL
|
|||
|
JZ ENDSYM
|
|||
|
MOV B,[SYMLIN],SYMWID ;No symbols on this line yet
|
|||
|
MOV BX,[HEAP]
|
|||
|
MOV SP,BX ;Need maximum stack for recursive tree walk
|
|||
|
CALL NODE
|
|||
|
ENDSYM:
|
|||
|
TEST B,[LSTDEV],80H ;Print listing to file?
|
|||
|
JZ EXIT
|
|||
|
MOV AL,1AH
|
|||
|
CALL WRTBUF ;Write end-of-file mark
|
|||
|
MOV DI,[LSTPNT]
|
|||
|
CALL FLUSHBUF
|
|||
|
MOV AH,CLOSE
|
|||
|
INT 33
|
|||
|
EXIT: JMP 0
|
|||
|
|
|||
|
NODE:
|
|||
|
XCHG DX,BX
|
|||
|
PUSH BX
|
|||
|
MOV DL,[BX]
|
|||
|
MOV DH,0
|
|||
|
INC BX
|
|||
|
ADD BX,DX
|
|||
|
MOV DX,[BX]
|
|||
|
OR DX,DX
|
|||
|
JZ L0014
|
|||
|
CALL NODE
|
|||
|
L0014:
|
|||
|
POP BX
|
|||
|
MOV AL,[BX]
|
|||
|
INC BX
|
|||
|
MOV CH,AL
|
|||
|
ADD AL,24
|
|||
|
SHR AL
|
|||
|
SHR AL
|
|||
|
SHR AL
|
|||
|
MOV CL,AL
|
|||
|
INC CL ;Invert last bit
|
|||
|
AND CL,1 ;Number of extra tabs needed (0 or 1)
|
|||
|
SHR AL ;Number of positions wide this symbol needs
|
|||
|
SUB [SYMLIN],AL
|
|||
|
JNC WRTSYM ;Will it fit?
|
|||
|
SUB AL,SYMWID
|
|||
|
NEG AL
|
|||
|
MOV [SYMLIN],AL
|
|||
|
CALL CRLF ;Start new line if not
|
|||
|
WRTSYM:
|
|||
|
MOV AL,[BX]
|
|||
|
INC BX
|
|||
|
CALL LIST
|
|||
|
DEC CH
|
|||
|
JNZ WRTSYM
|
|||
|
INC CL
|
|||
|
TABVAL:
|
|||
|
MOV AL,9
|
|||
|
CALL LIST
|
|||
|
LOOP TABVAL
|
|||
|
INC BX
|
|||
|
INC BX
|
|||
|
PUSH BX
|
|||
|
MOV AL,[BX+4]
|
|||
|
CALL PHEX
|
|||
|
MOV AL,[BX+3]
|
|||
|
CALL PHEX
|
|||
|
CMP B,[SYMLIN],0 ;Will any more fit on line?
|
|||
|
JZ NEXSYMLIN
|
|||
|
MOV AL,9
|
|||
|
CALL LIST
|
|||
|
JP RIGHTSON
|
|||
|
NEXSYMLIN:
|
|||
|
CALL CRLF
|
|||
|
MOV B,[SYMLIN],SYMWID
|
|||
|
RIGHTSON:
|
|||
|
POP BX
|
|||
|
MOV DX,[BX]
|
|||
|
OR DX,DX
|
|||
|
JNZ NODE
|
|||
|
RET
|
|||
|
|
|||
|
SAVCD:
|
|||
|
MOV [PREV],AL
|
|||
|
PUSH BX
|
|||
|
PUSH CX
|
|||
|
PUSH AX
|
|||
|
PUSH DX
|
|||
|
CALL CODBYT
|
|||
|
POP DX
|
|||
|
MOV BX,COUNT
|
|||
|
INC B,[BX]
|
|||
|
MOV AL,[BX]
|
|||
|
CMP AL,8
|
|||
|
JNZ NOEXT
|
|||
|
MOV B,[BX],1
|
|||
|
CALL OUTLIN
|
|||
|
MOV AL,' '
|
|||
|
MOV CH,5
|
|||
|
TAB:
|
|||
|
CALL LIST
|
|||
|
DEC CH
|
|||
|
JNZ TAB
|
|||
|
NOEXT:
|
|||
|
POP AX
|
|||
|
CALL PHEXB
|
|||
|
POP CX
|
|||
|
INC [PC]
|
|||
|
INC [HEXADD]
|
|||
|
POP BX
|
|||
|
RET
|
|||
|
|
|||
|
REPERR:
|
|||
|
OR AL,AL ;Did an error occur?
|
|||
|
JZ RET
|
|||
|
INC [ERRCNT]
|
|||
|
PUSH AX
|
|||
|
MOV BX,ERRMES ;Print "ERROR"
|
|||
|
CALL PRINT
|
|||
|
POP AX
|
|||
|
;We have error number in AL. See if there's an error message for it
|
|||
|
MOV DI,ERRTAB
|
|||
|
MOV BL,80H
|
|||
|
ERRLOOK:
|
|||
|
SCASB ;Do we have the error message
|
|||
|
JBE HAVMES ;Quit looking if we have it or passed it
|
|||
|
XCHG AX,BX ;Put 80H in AL to look for end of this message
|
|||
|
NEXTMES:
|
|||
|
SCASB ;Look for high bit set in message
|
|||
|
JA NEXTMES ; which means we've reached the end
|
|||
|
XCHG AX,BX ;Restore error number to AL
|
|||
|
JMPS ERRLOOK ;Keep looking
|
|||
|
|
|||
|
HAVMES:
|
|||
|
MOV BX,DI ;Put address of message in BX
|
|||
|
JZ PRNERR ;Do we have a message for this error?
|
|||
|
CALL PHEX ;If not, just print error number
|
|||
|
JMP CRLF
|
|||
|
|
|||
|
PRNERR:
|
|||
|
CALL PRINT
|
|||
|
JMP CRLF
|
|||
|
|
|||
|
PRINT:
|
|||
|
MOV AL,[BX]
|
|||
|
CALL LIST
|
|||
|
OR AL,AL
|
|||
|
JS RET
|
|||
|
INC BX
|
|||
|
JP PRINT
|
|||
|
|
|||
|
OUTA:
|
|||
|
MOV DL,AL
|
|||
|
OUT:
|
|||
|
AND DL,7FH
|
|||
|
MOV CL,2
|
|||
|
SYSTEM:
|
|||
|
CALL 5
|
|||
|
RET
|
|||
|
|
|||
|
CODBYT:
|
|||
|
CMP B,[HEXFCB],"Z"
|
|||
|
JZ RET
|
|||
|
PUSH AX
|
|||
|
MOV DX,[LASTAD]
|
|||
|
MOV BX,[HEXADD]
|
|||
|
MOV [LASTAD],BX
|
|||
|
INC DX
|
|||
|
MOV AL,[HEXCNT]
|
|||
|
CMP AL,-5
|
|||
|
JZ NEWLIN
|
|||
|
CMP BX,DX
|
|||
|
JZ AFHEX
|
|||
|
CALL ENHEXL
|
|||
|
NEWLIN:
|
|||
|
MOV AL,':'
|
|||
|
CALL PUTCHR
|
|||
|
MOV AL,-4
|
|||
|
MOV [HEXCNT],AL
|
|||
|
XOR AL,AL
|
|||
|
MOV [CHKSUM],AL
|
|||
|
MOV BX,[HEXPNT]
|
|||
|
MOV [HEXLEN],BX
|
|||
|
CALL HEXBYT
|
|||
|
MOV AL,[HEXADD+1]
|
|||
|
CALL HEXBYT
|
|||
|
MOV AL,[HEXADD]
|
|||
|
CALL HEXBYT
|
|||
|
XOR AL,AL
|
|||
|
CALL HEXBYT
|
|||
|
AFHEX:
|
|||
|
POP AX
|
|||
|
HEXBYT:
|
|||
|
MOV CH,AL
|
|||
|
MOV BX,CHKSUM
|
|||
|
ADD AL,[BX]
|
|||
|
MOV [BX],AL
|
|||
|
MOV AL,CH
|
|||
|
CALL UHALF
|
|||
|
CALL PUTCHR
|
|||
|
MOV AL,CH
|
|||
|
CALL LHALF
|
|||
|
CALL PUTCHR
|
|||
|
MOV BX,HEXCNT
|
|||
|
INC B,[BX]
|
|||
|
MOV AL,[BX]
|
|||
|
CMP AL,26
|
|||
|
JNZ RET
|
|||
|
ENHEXL:
|
|||
|
MOV DI,[HEXLEN]
|
|||
|
MOV CH,AL
|
|||
|
CALL UHALF
|
|||
|
STOB
|
|||
|
MOV AL,CH
|
|||
|
CALL LHALF
|
|||
|
STOB
|
|||
|
MOV AL,-6
|
|||
|
MOV [HEXCNT],AL
|
|||
|
MOV AL,[CHKSUM]
|
|||
|
ADD AL,CH
|
|||
|
NEG AL
|
|||
|
CALL HEXBYT
|
|||
|
MOV AL,13
|
|||
|
CALL PUTCHR
|
|||
|
MOV AL,10
|
|||
|
CALL PUTCHR
|
|||
|
WRTHEX:
|
|||
|
;Write out the line
|
|||
|
MOV DX,HEXBUF
|
|||
|
MOV [HEXPNT],DX
|
|||
|
MOV AH,SETDMA
|
|||
|
INT 33
|
|||
|
SUB DI,DX ;Length of buffer
|
|||
|
MOV CX,DI
|
|||
|
MOV DX,HEXFCB
|
|||
|
MOV AH,BLKWRT
|
|||
|
INT 33
|
|||
|
OR AL,AL
|
|||
|
JNZ DSKFUL
|
|||
|
RET
|
|||
|
|
|||
|
PUTCHR:
|
|||
|
MOV DI,[HEXPNT]
|
|||
|
STOB
|
|||
|
MOV [HEXPNT],DI
|
|||
|
RET
|
|||
|
|
|||
|
FLUSHBUF:
|
|||
|
MOV CX,DI
|
|||
|
MOV DX,LSTBUF
|
|||
|
MOV DI,DX
|
|||
|
SUB CX,DX
|
|||
|
JZ RET ;Buffer empty?
|
|||
|
MOV AH,SETDMA
|
|||
|
INT 33
|
|||
|
MOV DX,LSTFCB
|
|||
|
MOV AH,BLKWRT
|
|||
|
INT 33
|
|||
|
OR AL,AL
|
|||
|
JZ RET
|
|||
|
DSKFUL:
|
|||
|
MOV BX,WRTERR
|
|||
|
JMP PRERR
|
|||
|
|
|||
|
UHALF:
|
|||
|
RCR AL
|
|||
|
RCR AL
|
|||
|
RCR AL
|
|||
|
RCR AL
|
|||
|
LHALF:
|
|||
|
AND AL,0FH
|
|||
|
OR AL,30H
|
|||
|
CMP AL,'9'+1
|
|||
|
JC RET
|
|||
|
ADD AL,7
|
|||
|
RET
|
|||
|
|
|||
|
NONE: DB 0
|
|||
|
|
|||
|
; 8086 MNEMONIC TABLE
|
|||
|
|
|||
|
; This table is actually a sequence of subtables, each starting with a label.
|
|||
|
; The label signifies which mnemonics the subtable applies to--A3, for example,
|
|||
|
; means all 3-letter mnemonics beginning with A.
|
|||
|
|
|||
|
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
|
|||
|
C5:
|
|||
|
DB 2
|
|||
|
DB 'mpsb'
|
|||
|
DW PUT
|
|||
|
DB 0A6H
|
|||
|
DB 'mpsw'
|
|||
|
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 6
|
|||
|
DB 'mps'
|
|||
|
DW GRP17
|
|||
|
DB 0EBH
|
|||
|
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 4
|
|||
|
DB 'oope'
|
|||
|
DW GRP17
|
|||
|
DB 0E1H
|
|||
|
DB 'oopz'
|
|||
|
DW GRP17
|
|||
|
DB 0E1H
|
|||
|
DB 'odsb'
|
|||
|
DW PUT
|
|||
|
DB 0ACH
|
|||
|
DB 'odsw'
|
|||
|
DW PUT
|
|||
|
DB 0ADH
|
|||
|
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
|
|||
|
M5:
|
|||
|
DB 2
|
|||
|
DB 'ovsb'
|
|||
|
DW PUT
|
|||
|
DB 0A4H
|
|||
|
DB 'ovsw'
|
|||
|
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
|
|||
|
S5:
|
|||
|
DB 4
|
|||
|
DB 'casb'
|
|||
|
DW PUT
|
|||
|
DB 0AEH
|
|||
|
DB 'casw'
|
|||
|
DW PUT
|
|||
|
DB 0AFH
|
|||
|
DB 'tosb'
|
|||
|
DW PUT
|
|||
|
DB 0AAH
|
|||
|
DB 'tosw'
|
|||
|
DW PUT
|
|||
|
DB 0ABH
|
|||
|
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
|
|||
|
|
|||
|
|
|||
|
; 8087 MNEMONIC TABLE
|
|||
|
; Similar to 8086 table above, except NOT distinguished by opcode length
|
|||
|
|
|||
|
XM1: ;F2XM1
|
|||
|
DB 1 ;One opcode
|
|||
|
DM "xm1"
|
|||
|
DB 1,0F0H
|
|||
|
|
|||
|
NDPA:
|
|||
|
DB 3
|
|||
|
DM "dd"
|
|||
|
DB 6+ARITH,0C1H
|
|||
|
DM "ddp"
|
|||
|
DB NEEDOP+STACKOP,0
|
|||
|
DM "bs"
|
|||
|
DB 1,0E1H
|
|||
|
|
|||
|
NDPB:
|
|||
|
DB 2
|
|||
|
DM "ld"
|
|||
|
DB 7+NEEDOP+MEMORY,20H
|
|||
|
DM "stp"
|
|||
|
DB 7+NEEDOP+MEMORY,30H
|
|||
|
|
|||
|
NDPC:
|
|||
|
DB 5
|
|||
|
DM "om"
|
|||
|
DB 0+ONEREG+REAL,0D1H
|
|||
|
DM "omp"
|
|||
|
DB 0+ONEREG+REAL,0D9H
|
|||
|
DM "hs"
|
|||
|
DB 1,0E0H
|
|||
|
DM "ompp"
|
|||
|
DB 6,0D9H
|
|||
|
DM "lex"
|
|||
|
DB 3,0E2H
|
|||
|
|
|||
|
NDPD:
|
|||
|
DB 6
|
|||
|
DM "iv"
|
|||
|
DB 6+ARITH,0F1H
|
|||
|
DM "ivp"
|
|||
|
DB NEEDOP+STACKOP,30H
|
|||
|
DM "ivr"
|
|||
|
DB 6+ARITH,0F9H
|
|||
|
DM "ivrp"
|
|||
|
DB NEEDOP+STACKOP,38H
|
|||
|
DM "ecstp"
|
|||
|
DB 1,0F6H
|
|||
|
DM "isi"
|
|||
|
DB 3,0E1H
|
|||
|
|
|||
|
NDPE:
|
|||
|
DB 1
|
|||
|
DM "ni"
|
|||
|
DB 3,0E0H
|
|||
|
|
|||
|
NDPF:
|
|||
|
DB 1
|
|||
|
DM "ree"
|
|||
|
DB 5+NEEDOP+ONEREG,0
|
|||
|
|
|||
|
NDPI:
|
|||
|
DB 13
|
|||
|
DM "add"
|
|||
|
DB 2+NEEDOP+INTEGER,0
|
|||
|
DM "ld"
|
|||
|
DB 3+NEEDOP+INTEGER+EXTENDED,0
|
|||
|
DM "sub"
|
|||
|
DB 2+NEEDOP+INTEGER,20H
|
|||
|
DM "stp"
|
|||
|
DB 3+NEEDOP+INTEGER+EXTENDED,18H
|
|||
|
DM "st"
|
|||
|
DB 3+NEEDOP+INTEGER,10H
|
|||
|
DM "mul"
|
|||
|
DB 2+NEEDOP+INTEGER,8
|
|||
|
DM "div"
|
|||
|
DB 2+NEEDOP+INTEGER,30H
|
|||
|
DM "subr"
|
|||
|
DB 2+NEEDOP+INTEGER,28H
|
|||
|
DM "divr"
|
|||
|
DB 2+NEEDOP+INTEGER,38H
|
|||
|
DM "com"
|
|||
|
DB 2+NEEDOP+INTEGER,10H
|
|||
|
DM "comp"
|
|||
|
DB 2+NEEDOP+INTEGER,18H
|
|||
|
DM "ncstp"
|
|||
|
DB 1,0F7H
|
|||
|
DM "nit"
|
|||
|
DB 3,0E3H
|
|||
|
|
|||
|
NDPL:
|
|||
|
DB 10
|
|||
|
DM "d"
|
|||
|
DB 1+NEEDOP+ONEREG+REAL+EXTENDED,0
|
|||
|
DM "dz"
|
|||
|
DB 1,0EEH
|
|||
|
DM "d1"
|
|||
|
DB 1,0E8H
|
|||
|
DM "dpi"
|
|||
|
DB 1,0EBH
|
|||
|
DM "dl2t"
|
|||
|
DB 1,0E9H
|
|||
|
DM "dl2e"
|
|||
|
DB 1,0EAH
|
|||
|
DM "dlg2"
|
|||
|
DB 1,0ECH
|
|||
|
DM "dln2"
|
|||
|
DB 1,0EDH
|
|||
|
DM "dcw"
|
|||
|
DB 1+NEEDOP+MEMORY,28H
|
|||
|
DM "denv"
|
|||
|
DB 1+NEEDOP+MEMORY,20H
|
|||
|
|
|||
|
NDPM:
|
|||
|
DB 2
|
|||
|
DM "ul"
|
|||
|
DB 6+ARITH,0C9H
|
|||
|
DM "ulp"
|
|||
|
DB NEEDOP+STACKOP,8
|
|||
|
|
|||
|
NDPO:
|
|||
|
DB 1
|
|||
|
DM "p"
|
|||
|
DB NEEDOP+1,0 ;Flag special handling
|
|||
|
|
|||
|
NDPN:
|
|||
|
DB 1
|
|||
|
DM "op"
|
|||
|
DB 1,0D0H
|
|||
|
|
|||
|
NDPP:
|
|||
|
DB 3
|
|||
|
DM "rem"
|
|||
|
DB 1,0F8H
|
|||
|
DM "tan"
|
|||
|
DB 1,0F2H
|
|||
|
DM "atan"
|
|||
|
DB 1,0F3H
|
|||
|
|
|||
|
NDPR:
|
|||
|
DB 2
|
|||
|
DM "ndint"
|
|||
|
DB 1,0FCH
|
|||
|
DM "stor"
|
|||
|
DB 5+NEEDOP+MEMORY,20H
|
|||
|
|
|||
|
NDPS:
|
|||
|
DB 12
|
|||
|
DM "t"
|
|||
|
DB 5+NEEDOP+ONEREG+REAL,0D0H
|
|||
|
DM "tp"
|
|||
|
DB 7+NEEDOP+ONEREG+REAL+EXTENDED,0D8H
|
|||
|
DM "ub"
|
|||
|
DB 6+ARITH,0E1H
|
|||
|
DM "ubp"
|
|||
|
DB NEEDOP+STACKOP,0E0H
|
|||
|
DM "ubr"
|
|||
|
DB 6+ARITH,0E9H
|
|||
|
DM "ubrp"
|
|||
|
DB NEEDOP+STACKOP,0E8H
|
|||
|
DM "qrt"
|
|||
|
DB 1,0FAH
|
|||
|
DM "cale"
|
|||
|
DB 1,0FDH
|
|||
|
DM "ave"
|
|||
|
DB 5+NEEDOP+MEMORY,30H
|
|||
|
DM "tcw"
|
|||
|
DB 1+NEEDOP+MEMORY,38H
|
|||
|
DM "tenv"
|
|||
|
DB 1+NEEDOP+MEMORY,30H
|
|||
|
DM "tsw"
|
|||
|
DB 5+NEEDOP+MEMORY,38H
|
|||
|
|
|||
|
NDPT:
|
|||
|
DB 1
|
|||
|
DM "st"
|
|||
|
DB 1,0E4H
|
|||
|
|
|||
|
NDPW:
|
|||
|
DB 1
|
|||
|
DM "ait"
|
|||
|
DB NEEDOP,0 ;Flag special handling
|
|||
|
|
|||
|
NDPX:
|
|||
|
DB 3
|
|||
|
DM "ch"
|
|||
|
DB 1+ONEREG,0C9H
|
|||
|
DM "am"
|
|||
|
DB 1,0E5H
|
|||
|
DM "tract"
|
|||
|
DB 1,0F4H
|
|||
|
|
|||
|
NDPY:
|
|||
|
DB 2
|
|||
|
DM "l2x"
|
|||
|
DB 1,0F1H
|
|||
|
DM "l2xp1"
|
|||
|
DB 1,0F9H
|
|||
|
|
|||
|
|
|||
|
OPTAB:
|
|||
|
; Table of pointers to mnemonics. For each letter of the alphabet (the
|
|||
|
; starting letter of the mnemonic), there are 5 entries. Each entry
|
|||
|
; corresponds to a mnemonic whose length is 2, 3, 4, 5, and 6 characters
|
|||
|
; long, respectively. If there are no mnemonics for a given combination
|
|||
|
; of first letter and length (such as A-2), then the corresponding entry
|
|||
|
; points to NONE. Otherwise, it points to a place in the mnemonic table
|
|||
|
; for that type.
|
|||
|
|
|||
|
; This table only needs to be modified if a mnemonic is added to a group
|
|||
|
; previously marked NONE. Change the NONE to a label made up of the first
|
|||
|
; letter of the mnemonic and its length, then add a new subsection to
|
|||
|
; the mnemonic table in alphabetical order.
|
|||
|
|
|||
|
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 C5
|
|||
|
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 M5
|
|||
|
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 S5
|
|||
|
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
|
|||
|
|
|||
|
NDPTAB:
|
|||
|
;Lookup table for 8087 mnemonics. There is one entry for each letter of the
|
|||
|
;alphabet
|
|||
|
DW NDPA
|
|||
|
DW NDPB
|
|||
|
DW NDPC
|
|||
|
DW NDPD
|
|||
|
DW NDPE
|
|||
|
DW NDPF
|
|||
|
DW NONE ;G
|
|||
|
DW NONE ;H
|
|||
|
DW NDPI
|
|||
|
DW NONE ;J
|
|||
|
DW NONE ;K
|
|||
|
DW NDPL
|
|||
|
DW NDPM
|
|||
|
DW NDPN
|
|||
|
DW NDPO
|
|||
|
DW NDPP
|
|||
|
DW NONE ;Q
|
|||
|
DW NDPR
|
|||
|
DW NDPS
|
|||
|
DW NDPT
|
|||
|
DW NONE ;U
|
|||
|
DW NONE ;V
|
|||
|
DW NDPW
|
|||
|
DW NDPX
|
|||
|
DW NDPY
|
|||
|
DW NONE ;Z
|
|||
|
|
|||
|
;Error message table
|
|||
|
|
|||
|
ERRTAB:
|
|||
|
DM 1,"Register not allowed in immediate value"
|
|||
|
DM 2,"Index or base register must be BP, BX, SI, or DI"
|
|||
|
DM 3,"Only one base register (BX, BP) allowed"
|
|||
|
DM 4,"Only one index register (SI or DI) allowed"
|
|||
|
DM 5,"Only addition allowed on register or undefined label"
|
|||
|
DM 6,"Only one undefined label per expression allowed"
|
|||
|
DM 7,"Illegal digit in hexadecimal number"
|
|||
|
DM 8,"Illegal digit in decimal number"
|
|||
|
DM 10,"Illegal character in label or opcode"
|
|||
|
DM 11,"Label defined twice"
|
|||
|
DM 12,"Opcode not recognized"
|
|||
|
DM 20,"Invalid operand"
|
|||
|
DM 21,'"," and second operand expected'
|
|||
|
DM 22,"Register mismatch"
|
|||
|
DM 23,"Immediate operand not allowed"
|
|||
|
DM 24,'"]" expected'
|
|||
|
DM 25,"Two memory operands not allowed"
|
|||
|
DM 26,"Destination must not be immediate value"
|
|||
|
DM 27,"Both operands must not be registers"
|
|||
|
DM 28,"Operand must be segment register"
|
|||
|
DM 29,"First operand must be register"
|
|||
|
DM 30,"Undefined label not allowed"
|
|||
|
DM 31,"Value out of range"
|
|||
|
DM 32,"Missing or illegal operand size flag"
|
|||
|
DM 33,"Must have label on same line"
|
|||
|
DM 35,"Zero-length string illegal"
|
|||
|
DM 36,"ENDIF without IF"
|
|||
|
DM 37,"One-character strings only"
|
|||
|
DM 38,"Illegal expression"
|
|||
|
DM 39,"End of string not found"
|
|||
|
DM 100,"Undefined label"
|
|||
|
DM 101,"Value out of range (forward)"
|
|||
|
DB 255
|
|||
|
|
|||
|
ERRMES: DM '***** ERROR: '
|
|||
|
NOSPAC: DB 13,10,'File creation error',13,10,"$"
|
|||
|
NOMEM: DB 13,10,'Insufficient memory',13,10,'$'
|
|||
|
NOFILE: DB 13,10,'File not found',13,10,'$'
|
|||
|
WRTERR: DB 13,10,'Disk full',13,10,'$'
|
|||
|
BADDSK: DB 13,10,'Bad disk specifier',13,10,'$'
|
|||
|
ERCNTM: DM 13,10,13,10,'Error Count ='
|
|||
|
SYMSIZE DM 13,10,'Symbol Table size = '
|
|||
|
FRESIZE DM 'Free space = '
|
|||
|
SYMMES: DM 13,10,'Symbol Table',13,10,13,10
|
|||
|
EXTEND: DB 'ASM',0,0
|
|||
|
IFEND: DB 5,'endif'
|
|||
|
IFNEST: DB 2,'if'
|
|||
|
RETSTR: DM 'ret'
|
|||
|
HEXFCB: DB 0,' HEX',0,0,0,0
|
|||
|
DS 16
|
|||
|
DB 0,0,0,0,0
|
|||
|
LSTFCB: DB 0,' PRN',0,0,0,0
|
|||
|
DS 16
|
|||
|
DB 0,0,0,0,0
|
|||
|
PC: DS 2
|
|||
|
OLDPC: DS 2
|
|||
|
LABPT: DS 2
|
|||
|
FLAG: DS 1
|
|||
|
MAXFLG: 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
|
|||
|
SYMLIN: DS 1
|
|||
|
CODE: DS 2
|
|||
|
DATSIZ: DS 1
|
|||
|
RELOC: DS 1
|
|||
|
BCOUNT: DS 1
|
|||
|
COUNT: DS 1
|
|||
|
ERR: DS 1
|
|||
|
LINE: DS 2
|
|||
|
HEXLEN: DS 2
|
|||
|
HEXADD: DS 2
|
|||
|
LASTAD: DS 2
|
|||
|
HEXCNT: DS 1
|
|||
|
CHKSUM: DS 1
|
|||
|
LINFLG: DS 1
|
|||
|
PREV: DS 1
|
|||
|
IFFLG: DS 1
|
|||
|
CHKLAB: DS 1
|
|||
|
ERRCNT: DS 2
|
|||
|
LSTRET: DS 2
|
|||
|
RETPT: DS 2
|
|||
|
LSTDEV: DS 2
|
|||
|
SPC: DS 1
|
|||
|
NOWAIT: DS 1
|
|||
|
IX: DS 2
|
|||
|
IY: DS 2
|
|||
|
HEXPNT: DS 2
|
|||
|
LSTPNT: DS 2
|
|||
|
HEXBUF: DS HEXBUFSIZ
|
|||
|
LSTBUF: DS LSTBUFSIZ
|
|||
|
BUFPT: DS 2
|
|||
|
SRCBUF: DS BUFSIZ
|
|||
|
DS 100H
|
|||
|
ALIGN
|
|||
|
STACK: EQU $
|
|||
|
START: EQU $
|
|||
|
|