summaryrefslogtreecommitdiff
path: root/v1.25/source/ASM.ASM
diff options
context:
space:
mode:
Diffstat (limited to 'v1.25/source/ASM.ASM')
-rw-r--r--v1.25/source/ASM.ASM4006
1 files changed, 4006 insertions, 0 deletions
diff --git a/v1.25/source/ASM.ASM b/v1.25/source/ASM.ASM
new file mode 100644
index 0000000..d870d97
--- /dev/null
+++ b/v1.25/source/ASM.ASM
@@ -0,0 +1,4006 @@
1; Seattle Computer Products 8086 Assembler version 2.44
2; by Tim Paterson
3; Runs on the 8086 under MS-DOS
4
5;* * * * * * REVISION HISTORY * * * * * *
6;
7; 12/29/80 2.01 General release with 86-DOS version 0.34
8; 02/22/81 2.10 Increased buffer size from 128 bytes to 1024 bytes
9; 03/18/81 2.11 General cleanup and more documentation
10; 03/24/81 2.20 Modify ESC handling for full 8087 operation
11; 04/01/81 2.21 Fix date in HEX and PRN files; modify buffer handling
12; 04/03/81 2.22 Fix 2.21 buffer handling
13; 04/13/81 2.23 Re-open source file for listing to allow assembling CON:
14; 04/28/81 2.24 Allow nested IFs
15; 07/30/81 2.25 Add Intel string mnemonics; clean up a little
16; 08/02/81 2.30 Re-write pass 2:
17; Always report errors to console
18; Exact byte lengths for HEX and PRN files
19; 11/08/81 2.40 Add 8087 mnemonics; print full error messages;
20; allow expressions with *, /, and ()
21; 07/04/82 2.41 Fix Intel's 8087 "reverse-bit" bug; don't copy date
22; 08/18/82 2.42 Increase stack from 80 to 256 (Damn! Overflowed again!)
23; 01/05/83 2.43 Correct over-zealous optimization in 2.42
24; 05/09/83 2.44 Add memory usage report
25;
26;* * * * * * * * * * * * * * * * * * * * *
27
28SYMWID: EQU 5 ;5 symbols per line in dump
29FCB: EQU 5CH
30BUFSIZ: EQU 1024 ;Source code buffer
31LSTBUFSIZ:EQU BUFSIZ ;List file buffer
32HEXBUFSIZ:EQU 70 ;Hex file buffer (26*2 + 5*2 + 3 + EXTRA)
33EOL: EQU 13 ;ASCII carriage return
34OBJECT: EQU 100H ;DEFAULT "PUT" ADDRESS
35
36;System call function codes
37PRINTMES: EQU 9
38OPEN: EQU 15
39CLOSE: EQU 16
40READ: EQU 20
41SETDMA: EQU 26
42MAKE: EQU 22
43BLKWRT: EQU 40
44
45;The following equates define some token values returned by GETSYM
46UNDEFID:EQU 0 ;Undefined identifier (including no nearby RET)
47CONST: EQU 1 ;Constant (including $)
48REG: EQU 2 ;8-bit register
49XREG: EQU 3 ;16-bit register (except segment registers)
50SREG: EQU 4 ;Segment register
51FREG: EQU 6 ;8087 floating point register
52
53;Bits to build 8087 opcode table entries
54ONEREG: EQU 40H ;Single ST register OK as operand
55NEEDOP: EQU 80H ;Must have an operand
56INTEGER:EQU 20H ;For integer operations
57REAL: EQU 28H ;For real operations
58EXTENDED EQU 10H ;For Long integers or Temporary real
59MEMORY: EQU 18H ;For general memory operations
60STACKOP:EQU 10H ;Two register arithmetic with pop
61ARITH: EQU 8 ;Non-pop arithmetic operations
62
63 ORG 100H
64 PUT 100H
65
66 JMPS BEGIN
67
68HEADER: DB 13,10,'Seattle Computer Products 8086 Assembler Version 2.44'
69 DB 13,10,'Copyright 1979-1983 by Seattle Computer Products, Inc.'
70 DB 13,10,13,10,'$'
71
72BEGIN:
73 MOV SP,STACK
74 MOV DX,HEADER
75 MOV AH,PRINTMES
76 INT 33
77 MOV AL,[FCB+17]
78 MOV [SYMFLG],AL ;Save symbol table request flag
79 MOV SI,FCB+9 ;Point to file extension
80 LODB ;Get source drive letter
81 CALL CHKDSK ;Valid drive?
82 OR AL,AL
83 JZ DEFAULT ;If no extension, use existing drive spec
84 MOV [FCB],AL
85DEFAULT:
86 LODB ;Get HEX file drive letter
87 CMP AL,'Z' ;Suppress HEX file?
88 JZ L0000
89 CALL CHKDSK
90L0000:
91 MOV [HEXFCB],AL
92 LODB ;Get PRN file drive letter
93 MOV AH,0 ;Signal no PRN file
94 CMP AL,'Z' ;Suppress PRN file?
95 JZ NOPRN
96 CMP AL,'Y' ;Print errors only on console?
97 JZ NOPRN
98 MOV AH,2
99 CMP AL,'X' ;PRN file to console?
100 JZ NOPRN
101 MOV AH,4
102 CMP AL,'P' ;PRN file to printer?
103 JZ NOPRN
104 CALL CHKDSK
105 MOV AH,80H
106NOPRN:
107 MOV [LSTFCB],AL
108 MOV [LSTDEV],AH ;Flag device for list ouput
109 MOV SI,EXTEND
110 MOV DI,FCB+9
111 MOVW
112 MOVB ;Set extension to ASM
113 MOVW ;Zero extent field
114 MOV DX,FCB
115 MOV AH,OPEN
116 INT 33
117 MOV BX,NOFILE
118 OR AL,AL
119 JZ $+5
120 JMP PRERR
121 MOV DX,HEXFCB
122 CALL MAKFIL
123 MOV DX,LSTFCB
124 CALL MAKFIL
125 XOR AX,AX
126 MOV [FCB+12],AX ;Zero CURRENT BLOCK field
127 MOV [FCB+32],AL ;Zero Next Record field
128 MOV [FCB+14],BUFSIZ ;Set record size
129 MOV [BUFPT],SRCBUF ;Initialize buffer pointer
130 MOV [CODE],START+1 ;POINTER TO NEXT BYTE OF INTERMEDIATE CODE
131 MOV [IY],START ;POINTER TO CURRENT RELOCATION BYTE
132 XOR AX,AX
133 MOV [PC],AX ;DEFAULT PROGRAM COUNTER
134 MOV [BASE],AX ;POINTER TO ROOT OF ID TREE=NIL
135 MOV [RETPT],AX ;Pointer to last RET record
136 MOV [IFFLG],AL ;NOT WITHIN IF/ENDIF
137 MOV [CHKLAB],AL ;LOOKUP ALL LABELS
138 DEC AX
139 MOV [LSTRET],AX ;Location of last RET
140 MOV AX,[6] ;HL=END OF MEMORY
141 MOV [HEAP],AX ;BACK END OF SYMBOL TABLE SPACE
142 MOV [BCOUNT],4 ;CODE BYTES PER RELOCATION BYTE
143
144;Assemble each line of code
145
146LOOP:
147 CALL NEXTCHR ;Get first character on line
148 CMP AL,1AH
149 JZ ENDJ
150 MOV AL,-1 ;Flag that no tokens have been read yet
151 MOV [SYM],AL
152 CALL ASMLIN ;Assemble the line
153 MOV AL,[SYM]
154 CMP AL,-1 ;Any tokens found on line?
155 JNZ L0002
156 CALL GETSYM ;If no tokens read yet, read first one
157L0002:
158 CMP AL,';'
159 JZ ENDLN
160 CMP AL,EOL
161 JZ ENDLN
162 MOV AL,14H ;Garbage at end of line error
163 JP ENDLIN
164ENDJ: JMP END
165
166ENDLN:
167 XOR AL,AL ;Flag no errors on line
168ENDLIN:
169;AL = error code for line. Stack depth unknown
170 MOV SP,STACK
171 CALL NEXLIN
172 JP LOOP
173
174NEXLIN:
175 MOV CH,0C0H ;Put end of line marker and error code (AL)
176 CALL PUTCD
177 CALL GEN1
178 MOV AL,[CHR]
179GETEOL:
180 CMP AL,10
181 JZ RET
182 CMP AL,1AH
183 JZ ENDJ
184 CALL NEXTCHR ;Scan over comments for linefeed
185 JP GETEOL
186
187ABORT:
188 MOV BX,NOMEM
189PRERR:
190 MOV DX,BX
191 MOV AH,PRINTMES
192 INT 33
193 INT 32
194
195MAKFIL:
196 MOV SI,DX
197 LODB ;Get drive select byte
198 CMP AL,20H ;If not valid, don't make file
199 JNC RET
200 MOV CX,4
201 MOV DI,SI
202 MOV SI,FCB+1
203 REP
204 MOVW ;Copy source file name
205 MOV AH,MAKE
206 INT 33
207 MOV [DI-9+14],1 ;Set record length to 1 byte
208 MOV BX,NOSPAC
209 OR AL,AL ;Success?
210 JNZ PRERR
211 RET
212
213CHKDSK:
214 SUB AL,' ' ;If not present, set zero flag
215 JZ RET
216 SUB AL,20H
217 JZ DSKERR ;Must be in range A-O
218 CMP AL,'P'-'@'
219 JC RET
220DSKERR:
221 MOV BX,BADDSK
222 JP PRERR
223
224ERROR:
225 MOV AL,CL
226 JMP ENDLIN
227
228NEXTCHR:
229 MOV SI,[BUFPT]
230 CMP SI,SRCBUF
231 JNZ GETCH
232;Buffer empty so refill it
233 PUSH DX
234 PUSH AX ;AH must be saved
235 MOV DX,SI
236 MOV AH,SETDMA
237 INT 33
238 MOV DX,FCB
239 MOV AH,READ
240 INT 33
241 XCHG AX,DX ;Put error code in DL
242 POP AX ;Restore AH
243 MOV AL,DL ;Error code back in AL
244 POP DX
245 CMP AL,1
246 MOV AL,1AH ;Possibly signal End of File
247 JZ NOMOD ;If nothing read
248GETCH:
249 LODB
250 CMP SI,SRCBUF+BUFSIZ
251 JNZ NOMOD
252 MOV SI,SRCBUF
253NOMOD:
254 MOV [BUFPT],SI
255 MOV [CHR],AL
256 RET
257
258
259MROPS:
260
261; Get two operands and check for certain types, according to flag byte
262; in CL. OP code in CH. Returns only if immediate operation.
263
264 PUSH CX ;Save type flags
265 CALL GETOP
266 PUSH DX ;Save first operand
267 CALL GETOP2
268 POP BX ;First op in BX, second op in DX
269 MOV AL,SREG ;Check for a segment register
270 CMP AL,BH
271 JZ SEGCHK
272 CMP AL,DH
273 JZ SEGCHK
274 MOV AL,CONST ;Check if the first operand is immediate
275 MOV CL,26
276 CMP AL,BH
277 JZ ERROR ;Error if so
278 POP CX ;Restore type flags
279 CMP AL,DH ;If second operand is immediate, then done
280 JZ RET
281 MOV AL,UNDEFID ;Check for memory reference
282 CMP AL,BH
283 JZ STORE ;Is destination memory?
284 CMP AL,DH
285 JZ LOAD ;Is source memory?
286 TEST CL,1 ;Check if register-to-register operation OK
287 MOV CL,27
288 JZ ERROR
289 MOV AL,DH
290 CMP AL,BH ;Registers must be of same length
291RR:
292 MOV CL,22
293 JNZ ERROR
294RR1:
295 AND AL,1 ;Get register length (1=16 bits)
296 OR AL,CH ;Or in to OP code
297 CALL PUT ;And write it
298 POP CX ;Dump return address
299 MOV AL,BL
300 ADD AL,AL ;Rotate register number into middle position
301 ADD AL,AL
302 ADD AL,AL
303 OR AL,0C0H ;Set register-to-register mode
304 OR AL,DL ;Combine with other register number
305 JMP PUT
306
307SEGCHK:
308;Come here if at least one operand is a segment register
309 POP CX ;Restore flags
310 TEST CL,8 ;Check if segment register OK
311 MOV CL,22
312 JZ ERR1
313 MOV CX,8E03H ;Segment register move OP code
314 MOV AL,UNDEFID
315 CMP AL,DH ;Check if source is memory
316 JZ LOAD
317 CMP AL,BH ;Check if destination is memory
318 JZ STORE
319 MOV AL,XREG
320 SUB AL,DH ;Check if source is 16-bit register
321 JZ RR ;If so, AL must be zero
322 MOV CH,8CH ;Change direction
323 XCHG DX,BX ;Flip which operand is first and second
324 MOV AL,XREG
325 SUB AL,DH ;Let RR perform finish the test
326 JP RR
327
328STORE:
329 TEST CL,004H ;Check if storing is OK
330 JNZ STERR
331 XCHG DX,BX ;If so, flip operands
332 AND CH,0FDH ; and zero direction bit
333LOAD:
334 MOV DH,25
335 CMP AL,BH ;Check if memory-to-memory
336 JZ MRERR
337 MOV AL,BH
338 CMP AL,REG ;Check if 8-bit operation
339 JNZ XRG
340 MOV DH,22
341 TEST CL,1 ;See if 8-bit operation is OK
342 JZ MRERR
343XRG:
344 MOV AL,DL
345 SUB AL,6 ;Check for R/M mode 6 and register 0
346 OR AL,BL ; meaning direct load/store of accumulator
347 JNZ NOTAC
348 TEST CL,8 ;See if direct load/store of accumulator
349 JZ NOTAC ; means anything in this case
350; Process direct load/store of accumulator
351 MOV AL,CH
352 AND AL,2 ;Preserve direction bit only
353 XOR AL,2 ; but flip it
354 OR AL,0A0H ;Combine with OP code
355 MOV CH,AL
356 MOV AL,BH ;Check byte/word operation
357 AND AL,1
358 OR AL,CH
359 POP CX ;Dump return address
360 JMP PUTADD ;Write the address
361
362NOTAC:
363 MOV AL,BH
364 AND AL,1 ;Get byte/word bit
365 AND AL,CL ;But don't use it in word-only operations
366 OR AL,CH ;Combine with OP code
367 CALL PUT
368 MOV AL,BL
369 ADD AL,AL ;Rotate to middle position
370 ADD AL,AL
371 ADD AL,AL
372 OR AL,DL ;Combine register field
373 POP CX ;Dump return address
374 JMP PUTADD ;Write the address
375
376STERR:
377 MOV DH,29
378MRERR:
379 MOV CL,DH
380
381ERR1: JMP ERROR
382
383GETOP2:
384;Get the second operand: look for a comma and drop into GETOP
385 MOV AL,[SYM]
386 CMP AL,','
387 MOV CL,21
388 JNZ ERR1
389
390
391GETOP:
392
393; Get one operand. Operand may be a memory reference in brackets, a register,
394; or a constant. If a flag (such as "B" for byte operation) is encountered,
395; it is noted and processing continues to find the operand.
396;
397; On exit, AL (=DH) has the type of operand. Other information depends
398; on the actual operand:
399;
400; AL=DH=0 Memory Reference. DL has the address mode properly prepared in
401; the 8086 R/M format (middle bits zero). The constant part of the address
402; is in ADDR. If an undefined label needs to be added to this, a pointer to
403; its information fields is in ALABEL, otherwise ALABEL is zero.
404;
405; AL=DH=1 Value. The constant part is in DATA. If an undefined label needs
406; to be added to this, a pointer to its information fields is in DLABEL,
407; otherwise DLABEL is zero. "$" and "RET" are in this class.
408;
409; AL=DH=2 8-bit Register. DL has the register number.
410;
411; AL=DH=3 16-bit Register. DL has the register number.
412;
413; AL=DH=4 Segment Register. DL has the register number.
414
415 CALL GETSYM
416GETOP1:
417;Enter here if we don't need a GETSYM first
418 CMP AL,'[' ;Memory reference?
419 JZ MEM
420 CMP AL,5 ;Flag ("B", "W", etc.)?
421 JZ FLG
422 CMP AL,REG ;8-Bit register?
423 JZ NREG
424 CMP AL,XREG ;16-Bit register?
425 JZ NREG
426 CMP AL,SREG ;Segment register?
427 JZ NREG
428VAL: ;Must be immediate
429 XOR AL,AL ;No addressing modes allowed
430VAL1:
431 CALL GETVAL
432 MOV AX,[CON] ;Defined part
433 MOV [DATA],AX
434 MOV AX,[UNDEF] ;Undefined part
435 MOV [DLABEL],AX
436 MOV DL,CH
437 MOV DH,CONST
438 MOV AL,DH
439 RET
440NREG:
441 PUSH DX
442 CALL GETSYM
443 POP DX
444 MOV AL,DH
445 RET
446MEM:
447 CALL GETSYM
448 MOV AL,1
449 CALL GETVAL
450 MOV AL,[SYM]
451 CMP AL,']'
452 MOV CL,24
453 JNZ ERR1
454 CALL GETSYM
455 MOV BX,[CON]
456 MOV [ADDR],BX
457 MOV BX,[UNDEF]
458 MOV [ALABEL],BX
459 MOV DL,CH
460 MOV DH,UNDEFID
461 MOV AL,DH
462 RET
463FLG:
464 CMP DL,[MAXFLG] ;Invalid flag for this operation?
465 MOV CL,27H
466 JG ERR1
467 CALL GETSYM
468 CMP AL,','
469 JZ GETOP
470 JP GETOP1
471
472
473GETVAL:
474
475; Expression analyzer. On entry, if AL=0 then do not allow base or index
476; registers. If AL=1, we are analyzing a memory reference, so allow base
477; and index registers, and compute addressing mode when done. The constant
478; part of the expression will be found in CON. If an undefined label is to
479; be added to this, a pointer to its information fields will be found in
480; UNDEF.
481
482 MOV AH,AL ;Flag is kept in AH
483 MOV [UNDEF],0
484 MOV AL,[SYM]
485 CALL EXPRESSION
486 MOV [CON],DX
487 MOV AL,AH
488 MOV CH,0 ;Initial mode
489 TEST AL,10H ;Test INDEX bit
490 RCL AL ;BASE bit (zero flag not affected)
491 JZ NOIND ;Jump if not indexed, with BASE bit in carry
492 CMC
493 RCL CH ;Rotate in BASE bit
494 RCL AL ;BP bit
495 RCL CH
496 RCL AL ;DI bit
497 RCL CH ;The low 3 bits now have indexing mode
498MODE:
499 OR CH,080H ;If undefined label, force 16-bit displacement
500 TEST [UNDEF],-1
501 JNZ RET
502 MOV BX,[CON]
503 MOV AL,BL
504 CBW ;Extend sign
505 CMP AX,BX ;Is it a signed 8-bit number?
506 JNZ RET ;If not, use 16-bit displacement
507 AND CH,07FH ;Reset 16-bit displacement
508 OR CH,040H ;Set 8-bit displacement
509 OR BX,BX
510 JNZ RET ;Use it if not zero displacement
511 AND CH,7 ;Specify no displacement
512 CMP CH,6 ;Check for BP+0 addressing mode
513 JNZ RET
514 OR CH,040H ;If BP+0, use 8-bit displacement
515 RET
516
517NOIND:
518 MOV CH,6 ;Try direct address mode
519 JNC RET ;If no base register, that's right
520 RCL AL ;Check BP bit
521 JC MODE
522 INC CH ;If not, must be BX
523 JP MODE
524
525EXPRESSION:
526;Analyze arbitrary expression. Flag byte in AH.
527;On exit, AL has type byte: 0=register or undefined label
528 MOV CH,-1 ;Initial type
529 MOV DI,DX
530 XOR DX,DX ;Initial value
531 CMP AL,'+'
532 JZ PLSMNS
533 CMP AL,'-'
534 JZ PLSMNS
535 MOV CL,'+'
536 PUSH DX
537 PUSH CX
538 MOV DX,DI
539 JP OPERATE
540PLSMNS:
541 MOV CL,AL
542 PUSH DX
543 PUSH CX
544 OR AH,4 ;Flag that a sign was found
545 CALL GETSYM
546OPERATE:
547 CALL TERM
548 POP CX ;Recover operator
549 POP BX ;Recover current value
550 XCHG DX,BX
551 AND CH,AL
552 OR AL,AL ;Is it register or undefined label?
553 JZ NOCON ;If so, then no constant part
554 CMP CL,"-" ;Subtract it?
555 JNZ ADD
556 NEG BX
557ADD:
558 ADD DX,BX
559NEXTERM:
560 MOV AL,[SYM]
561 CMP AL,'+'
562 JZ PLSMNS
563 CMP AL,'-'
564 JZ PLSMNS
565 MOV AL,CH
566 RET
567NOCON:
568 CMP CL,"-"
569 JNZ NEXTERM
570BADOP:
571 MOV CL,5
572 JMP ERROR
573
574TERM:
575 CALL FACTOR
576MULOP:
577 PUSH DX ;Save value
578 PUSH AX ;Save type
579 CALL GETSYM
580 POP CX
581 CMP AL,"*"
582 JZ GETFACT
583 CMP AL,"/"
584 JNZ ENDTERM
585GETFACT:
586 OR CL,CL ;Can we operate on this type?
587 JZ BADOP
588 PUSH AX ;Save operator
589 CALL GETSYM ;Get past operator
590 CALL FACTOR
591 OR AL,AL
592 JZ BADOP
593 POP CX ;Recover operator
594 POP BP ;And current value
595 XCHG AX,BP ;Save AH in BP
596 CMP CL,"/" ;Do we divide?
597 JNZ DOMUL
598 OR DX,DX ;Dividing by zero?
599 MOV CL,29H
600 JZ ERR2
601 MOV BX,DX
602 XOR DX,DX ;Make 32-bit dividend
603 DIV AX,BX
604 JMPS NEXFACT
605DOMUL:
606 MUL AX,DX
607NEXFACT:
608 MOV DX,AX ;Result in DX
609 XCHG AX,BP ;Restore flags to AH
610 MOV AL,-1 ;Indicate a number
611 JMPS MULOP
612ENDTERM:
613 POP DX
614 MOV AL,CL
615 RET
616
617FACTOR:
618 MOV AL,[SYM]
619 CMP AL,CONST
620 JZ RET
621 CMP AL,UNDEFID
622 JZ UVAL
623 CMP AL,"("
624 JZ PAREN
625 CMP AL,'"'
626 JZ STRING
627 CMP AL,"'"
628 JZ STRING
629 CMP AL,XREG ;Only 16-bit register may index
630 MOV CL,20
631 JNZ ERR2
632 TEST AH,1 ;Check to see if indexing is OK
633 MOV CL,1
634 JZ ERR2
635 MOV AL,DL
636 MOV CL,3
637 SUB AL,3 ;Check for BX
638 JZ BXJ
639 SUB AL,2 ;Check for BP
640 JZ BPJ
641 DEC AL ;Check for SI
642 MOV CL,4
643 JZ SIJ
644 DEC AL ;Check for DI
645 JZ DIJ
646 MOV CL,2 ;Invalid base/index register
647ERR2: JMP ERROR
648
649DIJ:
650 OR AH,20H ;Flag seeing index register DI
651SIJ:
652 TEST AH,10H ;Check if already seen index register
653 JNZ ERR2
654 OR AH,10H ;Flag seeing index register
655 RET
656
657BPJ:
658 OR AH,40H ;Flag seeing base register BP
659BXJ:
660 TEST AH,80H ;Check if already seen base register
661 JNZ ERR2
662 OR AH,80H ;Flag seeing base register
663 RET
664
665PAREN:
666 CALL GETSYM ;Eat the "("
667 CALL EXPRESSION
668 CMP B,[SYM],")" ;Better have closing paren
669 MOV CL,20
670 JNZ ERR30
671 RET
672
673UVAL:
674 MOV CL,6
675 TEST AH,8 ;Check if undefined label has been seen
676 JNZ ERR30
677 OR AH,8 ;Flag seeing undefined label
678 MOV [UNDEF],BX
679 RET
680
681ERR30: JMP ERROR
682
683STRING:
684 MOV CH,AL
685 MOV AL,[CHR]
686 CMP AL,CH
687 MOV CL,35
688 MOV DL,AL
689 MOV DH,0
690 JNZ L0003
691 CALL ZERLEN
692L0003:
693 CALL GETCHR
694 MOV CL,37
695 TEST AH,2
696 JZ ERR30
697 TEST AH,4
698 MOV CL,38
699 JNZ ERR30
700STRGDAT:
701 MOV AL,DL
702 CMP AL,EOL
703 MOV CL,39
704 JZ ERR30
705 CALL PUT
706 MOV AL,[DATSIZ]
707 OR AL,AL
708 JNZ BYTSIZ
709 MOV AL,DH
710 CALL PUT
711BYTSIZ:
712 MOV AL,[CHR]
713 MOV DL,AL
714 CALL GETCHR
715 JP STRGDAT
716
717ZERLEN:
718 CALL NEXTCHR
719 CMP AL,CH
720 JNZ ERR30
721 RET
722
723GETCHR:
724 CALL NEXTCHR
725 CMP AL,CH
726 JNZ RET
727 CALL NEXTCHR
728 CMP AL,CH
729 JZ RET
730 POP BX ;Kill return address to STRGDAT loop
731 MOV AL,-1 ;Flag type as constant
732 RET
733
734
735GETSYM:
736
737; The lexical scanner. Used only in the operand field. Returns with the token
738; in SYM and AL, sometimes with additional info in BX or DX.
739;
740; AL=SYM=0 Undefined label. BX has pointer to information fields.
741;
742; AL=SYM=1 Constant (or defined label). DX has value.
743;
744; AL=SYM=2,3,4 8-bit register, 16-bit register, or segment register,
745; respectively. DL has register number.
746;
747; AL=SYM=5 A mode flag (such as "B" for byte operation). Type of flag in DL
748; and also stored in FLAG: -1=no flags, 0=B, 1=W, 2=S, 3=L, 4=T.
749;
750; AL=SYM=6 8087 floating point register, ST(n) or ST. DL has register number.
751;
752; All other values are the ASCII code of the character. Note that this may
753; never be a letter or number.
754
755 PUSH AX ;Save AH
756 CALL GETSY
757 POP AX
758 MOV AL,[SYM]
759 RET
760
761SCANB:
762 MOV AL,[CHR]
763SCANT:
764 CMP AL,' '
765 JZ NEXB
766 CMP AL,9
767 JNZ RET
768NEXB:
769 CALL NEXTCHR
770 JP SCANT
771
772DOLLAR:
773 MOV DX,[OLDPC]
774 MOV AL,CONST
775 MOV [SYM],AL
776NEXTCHJ:
777 JMP NEXTCHR
778
779GETSY:
780 CALL SCANB
781 CMP AL,'$'
782 JZ DOLLAR
783 MOV [SYM],AL
784 OR AL,20H
785 CMP AL,'z'+1
786 JNC NEXTCHJ
787 CMP AL,'a'
788 JC $+5
789 JMP LETTER
790 CMP AL,'9'+1
791 JNC NEXTCHJ
792 CMP AL,'0'
793 JC NEXTCHJ
794 MOV BX,SYM
795 MOV B,[BX],CONST
796 CALL READID
797 DEC BX
798 MOV AL,[BX]
799 MOV CL,7
800 MOV BX,0
801 CMP AL,'h'
802 JNZ $+5
803 JMP HEX
804 INC CL
805 MOV [IX],ID
806DEC:
807 MOV SI,[IX]
808 MOV AL,[SI]
809 INC [IX]
810 CMP AL,'9'+1
811 JC $+5
812 JMP ERROR
813 SUB AL,'0'
814 MOV DX,BX
815 SHL BX
816 SHL BX
817 ADD BX,DX
818 SHL BX
819 MOV DL,AL
820 MOV DH,0
821 ADD BX,DX
822 DEC CH
823 JNZ DEC
824 XCHG DX,BX
825 RET
826
827HEX:
828 MOV DX,ID
829 DEC CH
830HEX1:
831 MOV SI,DX
832 LODB
833 INC DX
834 SUB AL,'0'
835 CMP AL,10
836 JC GOTIT
837 CMP AL,'g'-'0'
838 JNC ERR4
839 SUB AL,'a'-10-'0'
840GOTIT:
841 SHL BX
842 SHL BX
843 SHL BX
844 SHL BX
845 ADD BL,AL
846 DEC CH
847 JNZ HEX1
848 XCHG DX,BX
849 RET
850
851ERR4: JMP ERROR
852
853GETLET:
854 CALL SCANB
855 CMP AL,EOL
856 STC
857 JZ RET
858 CMP AL,';'
859 STC
860 JZ RET
861 MOV CL,10
862 OR AL,20H
863 CMP AL,'a'
864 JC ERR4
865 CMP AL,'z'+1
866 JNC ERR4
867READID:
868 MOV BX,ID
869 MOV CH,0
870MOREID:
871 MOV [BX],AL
872 INC CH
873 INC BX
874 CALL NEXTCHR
875 CMP AL,'0'
876 JC NOMORE
877 OR AL,20H
878 CMP AL,'z'+1
879 JNC NOMORE
880 CMP AL,'9'+1
881 JC MOREID
882 CMP AL,'a'
883 JNC MOREID
884NOMORE:
885 MOV CL,AL
886 MOV AL,CH
887 MOV [LENID],AL
888 OR AL,AL
889 MOV AL,CL
890 RET
891
892LETTER:
893 CALL READID
894 MOV AL,CH
895 DEC AL
896 JNZ NOFLG
897 MOV AL,[ID]
898 MOV CX,5
899 MOV DI,FLGTAB
900 UP
901 REPNE
902 SCAB ;See if one of B,W,S,L,T
903 JZ SAVFLG ;Go save flag
904 XOR AL,AL
905 MOV CH,[LENID]
906NOFLG:
907 DEC AL
908 PUSH BX
909 JNZ L0004
910 CALL REGCHK
911L0004:
912 POP BX
913 MOV AL,DH
914 JZ SYMSAV
915 CALL LOOKRET
916SYMSAV:
917 MOV [SYM],AL
918 RET
919
920SAVFLG:
921 MOV DL,CL ;Need flag type in DL
922 XCHG [FLAG],CL
923 CMP CL,-1
924 MOV CL,32
925 MOV AL,5
926 JZ SYMSAV
927ERRJ3: JMP ERROR
928
929FLGTAB: DB "tlswb"
930
931FPREG:
932;Have detected "ST" for 8087 floating point stack register
933 MOV DL,0 ;Default is ST(0)
934 CALL SCANB ;Get next character
935 CMP AL,"(" ;Specifying register number?
936 JNZ HAVREG
937;Get register number
938 CALL NEXTCHR ;Skip over the "("
939 CALL GETOP ;A little recursion never hurt anybody
940 CMP AL,CONST ;Better have found a constant
941 MOV CL,20 ;Operand error if not
942 JNZ ERRJ3
943 CMP [DLABEL],0 ;Constant must be defined
944 MOV CL,30
945 JNZ ERRJ3
946 MOV DX,[DATA] ;Get constant
947 CMP DX,7 ;Constant must be in range 0-7
948 MOV CL,31
949 JA ERRJ3
950 MOV AL,[SYM]
951 CMP AL,")"
952 MOV CL,24
953 JNZ ERRJ3
954HAVREG:
955 MOV DH,FREG
956 XOR AL,AL ;Zero set means register found
957 RET
958
959REGCHK:
960 MOV BX,ID
961 CMP [BX],"s"+7400H ;"st"
962 JZ FPREG
963 MOV CL,[BX]
964 INC BX
965 MOV AL,[BX]
966 MOV BX,REGTAB
967 MOV DH,XREG
968 MOV DL,0
969 CMP AL,'x'
970 JZ SCANREG
971 MOV DH,REG
972 CMP AL,'l'
973 JZ SCANREG
974 MOV DL,4
975 CMP AL,'h'
976 JZ SCANREG
977 MOV DH,SREG
978 MOV DL,0
979 MOV BX,SEGTAB
980 CMP AL,'s'
981 JZ SCANREG
982 MOV DH,XREG
983 CMP AL,'p'
984 JZ PREG
985 CMP AL,'i'
986 JNZ RET
987 MOV DL,6
988 MOV AL,CL
989 CMP AL,'s'
990 JZ RET
991 INC DL
992 CMP AL,'d'
993 RET
994PREG:
995 MOV DL,4
996 MOV AL,CL
997 CMP AL,'s'
998 JZ RET
999 INC DL
1000 CMP AL,'b'
1001 RET
1002SCANREG:
1003 MOV AL,CL
1004 MOV CX,4
1005 UP
1006 MOV DI,BX
1007 REPNZ
1008 SCAB
1009 MOV BX,DI
1010 JNZ RET
1011 MOV AL,CL
1012 ADD AL,DL
1013 MOV DL,AL
1014 XOR AL,AL
1015 RET
1016
1017REGTAB: DB 'bdca'
1018
1019SEGTAB: DB 'dsce'
1020
1021LOOK:
1022 MOV CH,[BX]
1023 INC BX
1024 MOV DX,ID
1025 CALL CPSLP
1026 JZ RET
1027 XOR AL,80H
1028 ROL AL ;Make end-of-symbol bit least significant
1029 MOV CL,AL
1030 DEC BX
1031 MOV AL,[BX]
1032 XOR AL,80H
1033 ROL AL
1034 CMP AL,CL
1035 JNC SMALL
1036 INC CH
1037 INC CH
1038SMALL:
1039 MOV DL,CH
1040 MOV DH,0
1041 ADD BX,DX
1042 MOV DX,[BX]
1043 INC BX
1044 MOV AL,DL
1045 OR AL,DH
1046 STC
1047 JZ RET
1048 XCHG DX,BX
1049 JP LOOK
1050
1051LOOKRET:
1052 MOV AL,CH
1053 CMP AL,3 ;RET has 3 letters
1054 JNZ LOOKUP
1055 DEC BX
1056 OR B,[BX],080H
1057 MOV DX,RETSTR+2
1058CHKRET:
1059 MOV SI,DX
1060 LODB
1061 CMP AL,[BX]
1062 JNZ LOOKIT
1063 DEC BX
1064 DEC DX
1065 DEC CH
1066 JNZ CHKRET
1067 MOV DX,[LSTRET]
1068 MOV AL,DL
1069 AND AL,DH
1070 INC AL
1071 JZ ALLRET
1072 MOV BX,[PC]
1073 SUB BX,DX
1074 MOV AL,BL
1075 CBW
1076 CMP AX,BX ;Signed 8-bit number?
1077 MOV AL,1
1078 JZ RET
1079ALLRET:
1080 MOV BX,[RETPT]
1081 MOV AL,BH
1082 OR AL,BL
1083 MOV AL,0
1084 JNZ RET
1085 MOV BX,[HEAP]
1086 DEC BX
1087 DEC BX
1088 DEC BX
1089 MOV [HEAP],BX
1090 XOR AL,AL
1091 MOV [BX],AL
1092 MOV [RETPT],BX
1093 RET
1094
1095LOOKUP:
1096 DEC BX
1097 OR B,[BX],080H
1098LOOKIT:
1099 MOV BX,[BASE]
1100 MOV AL,BH
1101 OR AL,BL
1102 JZ EMPTY
1103 CALL LOOK
1104 JC ENTER
1105 MOV DX,4
1106 ADD BX,DX
1107 MOV AL,[BX]
1108 OR AL,AL
1109 JZ RET
1110 INC BX
1111 MOV DX,[BX]
1112 INC BX
1113 RET
1114
1115ENTER:
1116 PUSH BX ;Save pointer to link field
1117 CALL CREATE ;Add the node
1118 POP SI
1119 MOV [SI-1],DX ;Link new node
1120 RET ;Zero was set by CREATE
1121
1122EMPTY:
1123 CALL CREATE
1124 MOV [BASE],DX
1125 RET
1126
1127
1128CREATE:
1129
1130; Add a new node to the identifier tree. The identifier is at ID with
1131; bit 7 of the last character set to one. The length of the identifier is
1132; in LENID, which is ID-1.
1133;
1134; Node format:
1135; 1. Length of identifier (1 byte)
1136; 2. Identifier (1-80 bytes)
1137; 3. Left link (2-byte pointer to alphabetically smaller identifiers)
1138; 4. Right link (0 if none larger)
1139; 5. Data field:
1140; a. Defined flag (0=undefined, 1=defined)
1141; b. Value (2 bytes)
1142;
1143; This routine returns with AL=zero and zero flag set (which indicates
1144; on return from LOOKUP that it has not yet been defined), DX points
1145; to start of new node, and BX points to data field of new node.
1146
1147 MOV AL,[LENID]
1148 ADD AL,8 ;Storage needed for the node
1149 MOV BX,[HEAP]
1150 MOV DL,AL
1151 MOV DH,0
1152 SUB BX,DX ;Heap grows downward
1153 MOV [HEAP],BX
1154 XCHG DX,BX
1155 MOV BX,[CODE] ;Check to make sure there's enough
1156 CMP BX,DX
1157 JB $+5
1158 JMP ABORT
1159 PUSH DX
1160 MOV BX,LENID
1161 MOV CL,[BX]
1162 INC CL
1163 MOV CH,0
1164 UP
1165 MOV SI,BX
1166 MOV DI,DX
1167 REP
1168 MOVB ;Move identifier and length into node
1169 MOV DX,DI
1170 MOV BX,SI
1171 MOV CH,4
1172 XCHG DX,BX
1173NILIFY:
1174 MOV [BX],CL ;Zero left and right links
1175 INC BX
1176 DEC CH
1177 JNZ NILIFY
1178 XOR AL,AL ;Set zero flag
1179 MOV [BX],AL ;Zero defined flag
1180 POP DX ;Restore pointer to node
1181 RET
1182
1183CPSLP:
1184 MOV SI,DX
1185 LODB
1186 CMP AL,[BX]
1187 LAHF
1188 INC DX
1189 INC BX
1190 SAHF
1191 JNZ RET
1192 DEC CH
1193 JNZ CPSLP
1194 RET
1195
1196GETLAB:
1197 MOV BX,0
1198 MOV [LABPT],BX
1199 MOV B,[FLAG],-1
1200 MOV DH,0
1201 MOV AL,[CHR]
1202 CMP AL,' '+1
1203 JC NOT1
1204 OR DH,001H
1205NOT1:
1206 CALL GETLET
1207 JC RET
1208 CMP AL,':'
1209 JNZ LABCHK
1210 CALL NEXTCHR
1211 JP LABEL
1212LABCHK:
1213 OR AL,AL
1214 TEST DH,001H
1215 JZ RET
1216LABEL:
1217 MOV AL,[CHKLAB]
1218 OR AL,AL
1219 JZ $+5
1220 JMP GETLET
1221 CALL LOOKUP
1222 MOV CL,11
1223 JNZ ERR5
1224 MOV DX,[PC]
1225 MOV B,[BX],1
1226 INC BX
1227 MOV [BX],DX
1228 MOV [LABPT],BX
1229 JMP GETLET
1230
1231ERR5: JMP ERROR
1232
1233ASMLIN:
1234 MOV B,[MAXFLG],1 ;Allow only B and W flags normally
1235 MOV BX,[PC]
1236 MOV [OLDPC],BX
1237 CALL GETLAB
1238 JNC $+5
1239 JMP ENDLN
1240 MOV BX,LENID
1241 MOV AL,[BX]
1242 MOV CL,12
1243 SUB AL,2
1244 MOV CH,AL
1245 JC ERR5
1246 INC BX
1247 CMP B,[BX],"f" ;See if an 8087 mnemonic
1248 JZ NDPOP
1249 CMP AL,5
1250 JNC ERR5
1251 MOV AL,[BX]
1252 SUB AL,'a'
1253 MOV CL,AL
1254 ADD AL,AL
1255 ADD AL,AL
1256 ADD AL,CL
1257 ADD AL,CH
1258 ADD AL,AL
1259 MOV BX,OPTAB
1260 MOV DL,AL
1261 MOV DH,0
1262 ADD BX,DX
1263 MOV BX,[BX]
1264 INC CH
1265 MOV CL,CH
1266 MOV AH,[BX]
1267 INC BX
1268 OR AH,AH
1269 JZ OPERR
1270FINDOP:
1271 MOV CH,CL
1272 MOV DX,ID+1
1273 XCHG AX,BP ;Save count of opcodes in BP
1274 CALL CPSLP
1275 JZ HAVOP
1276 XCHG AX,BP
1277 MOV DH,0
1278 MOV DL,CH
1279 INC DX
1280 INC DX
1281 ADD BX,DX
1282 DEC AH
1283 JNZ FINDOP
1284OPERR:
1285 MOV CL,12
1286 JMP ERROR
1287
1288HAVOP:
1289 MOV AL,[BX+2] ;Get opcode
1290 JMP [BX]
1291
1292NDPOP: ;First letter is "F" so must be 8087 opcode ("Numeric Data Processor")
1293 MOV B,[MAXFLG],4 ;Allow all type flags
1294 INC BX
1295 CMP B,[BX],"n" ;"No-wait" form?
1296 MOV AH,0
1297 JNZ SAVNFLG
1298 MOV AH,1
1299 DEC AL
1300 INC BX ;Skip over the "N"
1301SAVNFLG:
1302 MOV [NOWAIT],AH ;0 for wait, 1 for no wait
1303 CMP AL,1
1304 JB OPERR ;Not enough char left for valid opcode?
1305 CMP AL,5
1306 JA OPERR ;Too many?
1307 CBW
1308 XCHG AX,DX ;Save length in DX
1309 MOV SI,DX
1310 OR B,[SI+BX],80H ;Set high bit of last character
1311 MOV AL,[BX] ;Get first char of opcode
1312 INC BX
1313 SUB AL,"a"
1314 JB TRY2XM1 ;Go see if opcode starts with "2"
1315 CMP AL,"z"-"a"
1316 JA OPERR
1317 CBW
1318 SHL AX ;Double to index into address table
1319 XCHG AX,SI ;Put in index register
1320 MOV DI,[SI+NDPTAB] ;Get start of opcode table for this letter
1321LOOKNDP:
1322 MOV AH,[DI] ;Number of opcodes starting with this letter
1323 OR AH,AH
1324 JZ OPERR ;Any start with this letter?
1325FNDNDP:
1326 INC DI
1327 MOV SI,BX ;Pointer to start of opcode
1328 MOV CX,DX ;Get length of opcode
1329 REPE
1330 CMPB ;Compare opcode to table entry
1331 JZ HAVNDP
1332 DEC DI ;Back up in case that was last letter
1333 MOV AL,80H ;Look for char with high bit set
1334ENDOP:
1335 SCASB
1336 JA ENDOP
1337 INC DI ;Skip over info about opcode
1338 DEC AH
1339 JNZ FNDNDP
1340OPERRJ: JP OPERR
1341
1342TRY2XM1:
1343 CMP AL,"2"-"a"
1344 JNZ OPERR
1345 MOV DI,XM1
1346 JP LOOKNDP
1347
1348SPECIALOP:
1349 AND AL,7 ;Mask to special op number
1350 JZ FWAIT ;If zero, go handle FWAIT
1351;Handle FNOP
1352 CMP B,[NOWAIT],0 ;Was "N" present (If not opcode was "FOP")
1353 JZ OPERR
1354 MOV AL,9BH ;Need Wait opcode after all
1355 CALL PUT
1356 MOV AL,0D9H
1357 CALL PUT
1358 MOV AL,0D0H
1359 JMP PUT
1360
1361FWAIT:
1362 CMP B,[NOWAIT],0 ;"FNWAIT" not legal
1363 JNZ OPERRJ
1364 RET ;Nothing to do - "WAIT" already sent
1365
1366HAVNDP:
1367 MOV SI,DI
1368 CMP B,[NOWAIT],0
1369 JNZ NWAIT
1370 MOV AL,9BH ;Wait opcode
1371 CALL PUT
1372NWAIT:
1373 LODW ;Get opcode info
1374 TEST AL,0F8H ;Any operand bits set?
1375 JZ NOOPS ;If no operands, output code
1376 TEST AL,78H ;Special case?
1377 JZ SPECIALOP
1378 PUSH AX
1379 CALL GETSYM ;See if any operands
1380 POP CX
1381 CMP AL,";"
1382 JZ NOOPCHK
1383 CMP AL,EOL
1384 JZ NOOPCHK
1385 CMP AL,FREG ;Is it 8087 register?
1386 JNZ MEMOP
1387 XCHG AX,CX
1388 TEST AL,ONEREG ;One register OK as operand?
1389 JNZ PUTREG ;Yes - save it
1390 TEST AL,20H ;Memory-only operation?
1391 MOV CL,20
1392 JNZ ERRJ4
1393 TEST AL,18H ;Two-register operation?
1394 JPE ERRJ4 ;Must be exactly one bit set
1395 PUSH DX ;Save register number
1396 PUSH AX ;Save opcode
1397 CALL GETSYM
1398 CMP AL,","
1399 MOV CL,15H
1400 JNZ ERRJ4
1401 CALL GETSYM
1402 MOV CL,20
1403 CMP AL,FREG
1404 JNZ ERRJ4
1405 POP AX
1406 POP BX
1407 XOR AL,2 ;Flip "POP" bit
1408 AND AL,0FBH ;Reset direction bit to ST(0)
1409 OR BL,BL ;Is first register ST(0)?
1410 JZ ST0DEST
1411 XCHG DX,BX
1412 OR BL,BL ;One of these must be ST(0)
1413 JNZ ERRJ4
1414 XOR AL,4 ;Flip direction
1415 JMPS PUTREG
1416ST0DEST:
1417 TEST AL,2 ;Is POP bit set?
1418 JNZ ERRJ4 ;Don't allow destination ST(0) then pop
1419PUTREG:
1420 AND AH,0F8H ;Zero out register field
1421 OR AH,DL
1422 OR AH,0C0H
1423 PUSH AX
1424 CALL GETSYM ;Get to next symbol
1425 POP AX
1426 JMPS NOOPS
1427
1428NOOPCHK:
1429 XCHG AX,CX
1430 TEST AL,80H ;Is no operands OK?
1431 MOV CL,20
1432 JNZ ERRJ4
1433NOOPS:
1434;First test for FDIV or FSUB and reverse "R" bit if "D" bit is set
1435 PUSH AX
1436 AND AX,0E005H
1437 CMP AX,0E004H
1438 POP AX
1439 JNZ NOREV
1440 XOR AH,8 ;Reverse "R" bit
1441NOREV:
1442 AND AL,7
1443 OR AL,0D8H ;ESC hook
1444 CALL PUT
1445 MOV AL,AH
1446 JMP PUT
1447
1448BADFLAG:
1449 MOV CL,20H
1450ERRJ4: JMP ERROR
1451
1452MEMOP:
1453 PUSH CX ;Save opcode
1454 CALL GETOP1 ;Get memory operand
1455 CMP AL,UNDEFID ;Is it?
1456 MOV CL,20
1457 JNZ ERRJ4
1458 POP AX
1459 TEST AL,20H ;Does it have memory format field?
1460 JNZ GETFORMAT
1461 TEST AL,8 ;Check if any memory operand legal
1462 JZ ERRJ4
1463 TEST AL,10H ;Check for 2-op arithmetic
1464 JNZ PUTMEM ;If not, just use as plain memory op
1465GETFORMAT:
1466 AND AL,0F9H ;Zero memory format bits
1467 MOV CL,[FLAG]
1468 DEC CL ;Must now be in range 0-3
1469 JL BADFLAG
1470 MOV CH,AL ;Save opcode byte
1471 SHR AL ;Put format bits in bits 2 & 3
1472 AND AL,0CH
1473 OR AL,CL ;Combine format bits with flag
1474 MOV BX,FORMATTAB
1475 XLAT
1476 OR AL,AL ;Valid combination?
1477 JS BADFLAG
1478 OR AH,AL ;Possibly set new bits in second byte
1479 OR AL,CH ;Set memory format bits
1480PUTMEM:
1481 AND AL,7
1482 OR AL,0D8H
1483 CALL PUT
1484 MOV AL,AH
1485 AND AL,38H
1486 OR AL,DL ;Combine addressing mode
1487 JMP PUTADD
1488
1489FORMATTAB:
1490;There are 16 entries in this table. The 4-bit index is built like this:
1491; Bit 3 0 for normal memory ops, 1 if extended is OK
1492; Bit 2 0 for integer, 1 for real
1493; Bit 0 & 1 Flag: 00=W, 01=S, 10=L, 11=T
1494;
1495;The entries in the table are used as two 3-bit fields. Bits 0-2 are ORed
1496;into the first byte of the opcode for the Memory Format field. Bits 3-6
1497;are ORed into the second byte to modify the opcode for extended operands.
1498;If bit 7 is set, then that combination is illegal.
1499
1500 DB 6,2,80H,80H ;Normal integers
1501 DB 80H,0,4,80H ;Normal reals
1502 DB 6,2,2EH,80H ;Extended integers
1503 DB 80H,0,4,2BH ;Extended reals
1504
1505GRP1:
1506 MOV CX,8A09H
1507 CALL MROPS
1508 MOV CX,0C6H
1509 MOV AL,BH
1510 CMP AL,UNDEFID
1511 JNZ L0006
1512 CALL STIMM
1513L0006:
1514 AND AL,1
1515 JZ BYTIMM
1516 MOV AL,0B8H
1517 OR AL,BL
1518 CALL PUT
1519 JMP PUTWOR
1520
1521BYTIMM:
1522 MOV AL,0B0H
1523 OR AL,BL
1524 CALL PUT
1525PUTBJ: JMP PUTBYT
1526
1527IMMED:
1528 MOV AL,BH
1529 CMP AL,UNDEFID
1530 JZ STIMM
1531 MOV AL,BL
1532 OR AL,AL
1533 JZ RET
1534 MOV AL,BH
1535 CALL IMM
1536 OR AL,0C0H
1537 CALL PUT
1538FINIMM:
1539 MOV AL,CL
1540 POP CX
1541 TEST AL,1
1542 JZ PUTBJ
1543 CMP AL,83H
1544 JZ PUTBJ
1545 JMP PUTWOR
1546
1547STIMM:
1548 MOV AL,[FLAG]
1549 CALL IMM
1550 CALL PUTADD
1551 JP FINIMM
1552
1553IMM:
1554 AND AL,1
1555 OR AL,CL
1556 MOV CL,AL
1557 CALL PUT
1558 MOV AL,CH
1559 AND AL,38H
1560 OR AL,BL
1561 RET
1562
1563PUT:
1564;Save byte in AL as pure code, with intermediate code bits 00. AL and
1565;DI destroyed, no other registers affected.
1566 PUSH BX
1567 PUSH CX
1568 MOV CH,0 ;Flag as pure code
1569 CALL GEN
1570 POP CX
1571 POP BX
1572 RET
1573
1574GEN:
1575;Save byte of code in AL, given intermediate code bits in bits 7&8 of CH.
1576 CALL PUTINC ;Save it and bump code pointer
1577GEN1:
1578 MOV AL,[RELOC]
1579 RCL CH
1580 RCL AL
1581 RCL CH
1582 RCL AL
1583 MOV [RELOC],AL
1584 MOV BX,BCOUNT
1585 DEC B,[BX]
1586 JNZ RET
1587 MOV B,[BX],4
1588 MOV BX,RELOC
1589 MOV AL,[BX]
1590 MOV B,[BX],0
1591 MOV DI,[IY]
1592 MOV [DI],AL
1593 MOV BX,[CODE]
1594 MOV [IY],BX
1595 INC BX
1596 MOV [CODE],BX
1597 RET
1598
1599PUTINC:
1600 INC [PC]
1601PUTCD:
1602 MOV DI,[CODE]
1603 STOB
1604 MOV [CODE],DI
1605 RET
1606
1607PUTWOR:
1608;Save the word value described by [DLABEL] and [DATA] as code. If defined,
1609;two bytes of pure code will be produced. Otherwise, appropriate intermediate
1610;code will be generated.
1611 PUSH CX
1612 MOV CH,80H
1613 PUSH DX
1614 PUSH BX
1615 JP PUTBW
1616
1617PUTBYT:
1618;Same as PUTWOR, above, but for byte value.
1619 PUSH CX
1620 MOV CH,40H
1621 PUSH DX
1622 PUSH BX
1623 MOV BX,[DLABEL]
1624 MOV AL,BH
1625 OR AL,BL
1626 JNZ PUTBW
1627 MOV BX,[DATA]
1628 OR AL,BH
1629 JZ PUTBW
1630 INC BH
1631 JZ PUTBW
1632 MOV CL,31
1633 JMP ERROR
1634PUTBW:
1635 MOV DX,[DLABEL]
1636 MOV BX,[DATA]
1637PUTCHK:
1638 OR DX,DX
1639 JZ NOUNDEF
1640 MOV AL,DL
1641 CALL PUTCD
1642 MOV AL,DH
1643 CALL PUTCD
1644 MOV AL,BL
1645 CALL PUTINC
1646 MOV AL,BH
1647 TEST CH,080H
1648 JZ SMPUT
1649 CALL GEN
1650 JP PRET
1651SMPUT:
1652 CALL PUTCD
1653 CALL GEN1
1654PRET:
1655 POP BX
1656 POP DX
1657 POP CX
1658 RET
1659
1660NOUNDEF:
1661 MOV AL,BL
1662 MOV CL,BH
1663 PUSH CX
1664 MOV CH,0
1665 CALL GEN
1666 POP CX
1667 MOV AL,CL
1668 TEST CH,080H
1669 MOV CH,0
1670 JZ PRET
1671 CALL GEN
1672 JP PRET
1673
1674PUTADD:
1675;Save complete addressing mode. Addressing mode is in AL; if this is a register
1676;operation (>=C0), then the one byte will be saved as pure code. Otherwise,
1677;the details of the addressing mode will be investigated and the optional one-
1678;or two-byte displacement will be added, as described by [ADDR] and [ALABEL].
1679 PUSH CX
1680 PUSH DX
1681 PUSH BX
1682 MOV CH,0
1683 MOV CL,AL
1684 CALL GEN ;Save the addressing mode as pure code
1685 MOV AL,CL
1686 MOV CH,80H
1687 AND AL,0C7H
1688 CMP AL,6
1689 JZ TWOBT ;Direct address?
1690 AND AL,0C0H
1691 JZ PRET ;Indirect through reg, no displacement?
1692 CMP AL,0C0H
1693 JZ PRET ;Register to register operation?
1694 MOV CH,AL ;Save whether one- or two-byte displacement
1695TWOBT:
1696 MOV BX,[ADDR]
1697 MOV DX,[ALABEL]
1698 JP PUTCHK
1699
1700GRP2:
1701 CALL GETOP
1702 MOV CX,0FF30H
1703 CMP AL,UNDEFID
1704 JZ PMEM
1705 MOV CH,50H
1706 CMP AL,XREG
1707 JZ PXREG
1708 MOV CH,6
1709 CMP AL,SREG
1710 JNZ $+5
1711 JMP PACKREG
1712 MOV CL,20
1713 JMP ERROR
1714
1715PMEM:
1716 MOV AL,CH
1717 CALL PUT
1718 MOV AL,CL
1719 OR AL,DL
1720 JMP PUTADD
1721
1722PXREG:
1723 MOV AL,CH
1724 OR AL,DL
1725 JMP PUT
1726
1727GRP3:
1728 CALL GETOP
1729 PUSH DX
1730 CALL GETOP2
1731 POP BX
1732 MOV CX,8614H
1733 MOV AL,SREG
1734 CMP AL,BH
1735 JZ ERR6
1736 CMP AL,DH
1737 JZ ERR6
1738 MOV AL,CONST
1739 CMP AL,BH
1740 JZ ERR6
1741 CMP AL,DH
1742 JZ ERR6
1743 MOV AL,UNDEFID
1744 CMP AL,BH
1745 JZ EXMEM
1746 CMP AL,DH
1747 JZ EXMEM1
1748 MOV AL,BH
1749 CMP AL,DH
1750 MOV CL,22
1751 JNZ ERR6
1752 CMP AL,XREG
1753 JZ L0008
1754 CALL RR1
1755L0008: ;RR1 never returns
1756 MOV AL,BL
1757 OR AL,AL
1758 JZ EXACC
1759 XCHG DX,BX
1760 MOV AL,BL
1761 OR AL,AL
1762 MOV AL,BH
1763 JZ EXACC
1764 CALL RR1
1765EXACC:
1766 MOV AL,90H
1767 OR AL,DL
1768 JMP PUT
1769
1770EXMEM:
1771 XCHG DX,BX
1772EXMEM1:
1773 CMP AL,BH
1774 JZ ERR6
1775 MOV CL,1 ;Flag word as OK
1776 CALL NOTAC ;NOTAC never returns
1777ERR6: JMP ERROR
1778
1779GRP4:
1780 PUSH AX
1781 CALL GETOP
1782 POP CX
1783 XCHG CL,CH
1784 CMP AL,CONST
1785 JZ FIXED
1786 SUB AL,XREG
1787 DEC DL
1788 DEC DL
1789 OR AL,DL
1790 MOV CL,20
1791 JNZ ERR6
1792 MOV AL,CH
1793 OR AL,8
1794 JMP PUT
1795FIXED:
1796 MOV AL,CH
1797 CALL PUT
1798 JMP PUTBYT
1799
1800GRP5:
1801 PUSH AX
1802 CALL GETOP
1803 MOV CL,20
1804 CMP AL,CONST
1805 JNZ ERR6
1806 MOV BX,[DLABEL]
1807 MOV AL,BH
1808 OR AL,BL
1809 MOV CL,30
1810 JNZ ERR6
1811 MOV BX,[DATA]
1812 POP AX
1813 OR AL,AL
1814 JZ ORG
1815 DEC AL
1816 JZ DSJ
1817 DEC AL
1818 JZ EQU
1819 DEC AL
1820 JZ $+5
1821 JMP IF
1822PUTOP:
1823 MOV AL,-3
1824 JP NEWLOC
1825ALIGN:
1826 MOV AL,[PC]
1827 AND AL,1
1828 JZ RET
1829 MOV BX,1
1830DSJ:
1831 XCHG DX,BX
1832 MOV BX,[PC]
1833 ADD BX,DX
1834 MOV [PC],BX
1835 XCHG DX,BX
1836 MOV AL,-4
1837 JP NEWLOC
1838EQU:
1839 XCHG DX,BX
1840 MOV BX,[LABPT]
1841 MOV AL,BH
1842 OR AL,BL
1843 MOV CL,34
1844 JZ ERR7
1845 MOV [BX],DL
1846 INC BX
1847 MOV [BX],DH
1848 RET
1849ORG:
1850 MOV [PC],BX
1851 MOV AL,-2
1852NEWLOC:
1853 CALL PUTCD
1854 MOV AL,BL
1855 CALL PUTCD
1856 MOV AL,BH
1857 CALL PUTCD
1858 MOV CH,0C0H
1859 JMP GEN1
1860GRP6:
1861 MOV CH,AL
1862 MOV CL,4
1863 CALL MROPS
1864 MOV CL,23
1865ERR7: JMP ERROR
1866GRP7:
1867 MOV CH,AL
1868 MOV CL,1
1869 CALL MROPS
1870 MOV CL,80H
1871 MOV DX,[DLABEL]
1872 MOV AL,DH
1873 OR AL,DL
1874 JNZ ACCJ
1875 XCHG DX,BX
1876 MOV BX,[DATA]
1877 MOV AL,BL
1878 CBW
1879 CMP AX,BX
1880 XCHG DX,BX
1881 JNZ ACCJ
1882 OR CL,002H
1883ACCJ: JMP ACCIMM
1884GRP8:
1885 MOV CL,AL
1886 MOV CH,0FEH
1887 JP ONEOP
1888GRP9:
1889 MOV CL,AL
1890 MOV CH,0F6H
1891ONEOP:
1892 PUSH CX
1893 CALL GETOP
1894ONE:
1895 MOV CL,26
1896 CMP AL,CONST
1897 JZ ERR7
1898 CMP AL,SREG
1899 MOV CL,22
1900 JZ ERR7
1901 POP CX
1902 CMP AL,UNDEFID
1903 JZ MOP
1904 AND AL,1
1905 JZ ROP
1906 TEST CL,001H
1907 JZ ROP
1908 MOV AL,CL
1909 AND AL,0F8H
1910 OR AL,DL
1911 JMP PUT
1912MOP:
1913 MOV AL,[FLAG]
1914 AND AL,1
1915 OR AL,CH
1916 CALL PUT
1917 MOV AL,CL
1918 AND AL,38H
1919 OR AL,DL
1920 JMP PUTADD
1921ROP:
1922 OR AL,CH
1923 CALL PUT
1924 MOV AL,CL
1925 AND AL,38H
1926 OR AL,0C0H
1927 OR AL,DL
1928 JMP PUT
1929GRP10:
1930 MOV CL,AL
1931 MOV CH,0F6H
1932 PUSH CX
1933 CALL GETOP
1934 MOV CL,20
1935 MOV AL,DL
1936 OR AL,AL
1937 JNZ ERRJ1
1938 MOV AL,DH
1939 CMP AL,XREG
1940 JZ G10
1941 CMP AL,REG
1942ERRJ1: JNZ ERR8
1943G10:
1944 PUSH AX
1945 CALL GETOP
1946 POP AX
1947 AND AL,1
1948 MOV [FLAG],AL
1949 MOV AL,DH
1950ONEJ: JP ONE
1951GRP11:
1952 CALL PUT
1953 MOV AL,0AH
1954 JMP PUT
1955GRP12:
1956 MOV CL,AL
1957 MOV CH,0D0H
1958 PUSH CX
1959 CALL GETOP
1960 MOV AL,[SYM]
1961 CMP AL,','
1962 MOV AL,DH
1963 JNZ ONEJ
1964 PUSH DX
1965 CALL GETOP
1966 SUB AL,REG
1967 MOV CL,20
1968 DEC DL
1969 OR AL,DL
1970 JNZ ERR8
1971 POP DX
1972 MOV AL,DH
1973 POP CX
1974 OR CH,002H
1975 PUSH CX
1976 JMP ONE
1977GRP13:
1978 MOV CH,AL
1979 MOV CL,1
1980 CALL MROPS
1981 MOV CL,80H
1982ACCIMM:
1983 CALL IMMED
1984 OR CH,004H
1985 AND CH,0FDH
1986AIMM:
1987 MOV AL,BH
1988 AND AL,1
1989 LAHF
1990 PUSH AX
1991 OR AL,CH
1992 CALL PUT
1993 POP AX
1994 SAHF
1995 JNZ $+5
1996 JMP PUTBYT
1997 JMP PUTWOR
1998
1999ERR8: JMP ERROR
2000
2001GRP14:
2002;JMP and CALL mnemonics
2003 LAHF
2004 XCHG AH,AL
2005 PUSH AX
2006 XCHG AH,AL
2007 MOV B,[MAXFLG],3 ;Allow "L" flag
2008 CALL GETOP
2009 CMP AL,CONST
2010 JZ DIRECT
2011 MOV CL,20
2012 CMP AL,REG
2013 JZ ERR8
2014 CMP AL,SREG
2015 JZ ERR8
2016 CMP AL,XREG
2017 JNZ NOTRG
2018 OR DL,0C0H
2019NOTRG:
2020;Indirect jump. DL has addressing mode.
2021 MOV AL,0FFH
2022 CALL PUT
2023 POP AX
2024 XCHG AH,AL
2025 SAHF
2026 AND AL,38H
2027 OR AL,DL
2028 MOV CH,[FLAG]
2029 CMP CH,3 ;Flag "L" present?
2030 JZ PUTADDJ ;If so, do inter-segment
2031 MOV CL,27H
2032 CMP CH,-1 ;Better not be a flag
2033 JNZ ERR8
2034 AND AL,0F7H ;Convert to intra-segment
2035PUTADDJ:
2036 JMP PUTADD
2037DIRECT:
2038 MOV AL,[SYM]
2039 CMP AL,','
2040 JZ LONGJ
2041 POP AX
2042 XCHG AH,AL
2043 SAHF
2044 DEC AL
2045 CMP AL,0E9H
2046 JZ GOTOP
2047 MOV AL,0E8H
2048GOTOP:
2049 CALL PUT
2050 MOV DX,[PC]
2051 INC DX
2052 INC DX
2053 SUB [DATA],DX
2054 JMP PUTWOR
2055LONGJ:
2056 POP AX
2057 XCHG AH,AL
2058 SAHF
2059 CALL PUT
2060 CALL PUTWOR
2061 CALL GETOP
2062 MOV CL,20
2063 CMP AL,CONST
2064 JNZ ERR8
2065 JMP PUTWOR
2066
2067GRP16:
2068;RET mnemonic
2069 LAHF
2070 XCHG AH,AL
2071 PUSH AX
2072 XCHG AH,AL
2073 CALL GETSYM
2074 CMP AL,5
2075 JZ LONGR
2076 CMP AL,EOL
2077 JZ NODEC
2078 CMP AL,';'
2079 JZ NODEC
2080GETSP:
2081 CALL GETOP1
2082 POP CX
2083 CMP AL,CONST
2084 MOV CL,20
2085 JNZ ERR9
2086 MOV AL,CH
2087 AND AL,0FEH
2088 CALL PUT
2089 JMP PUTWOR
2090LONGR:
2091 CMP DL,3 ;Is flag "L"?
2092 MOV CL,27H
2093 JNZ ERR10 ;If not, bad flag
2094 POP AX
2095 XCHG AH,AL
2096 SAHF
2097 OR AL,8
2098 LAHF
2099 XCHG AH,AL
2100 PUSH AX
2101 XCHG AH,AL
2102NOTLON:
2103 CALL GETSYM
2104 CMP AL,EOL
2105 JZ DORET
2106 CMP AL,';'
2107 JZ DORET
2108 CMP AL,','
2109 JNZ L0011
2110 CALL GETSYM
2111L0011:
2112 JP GETSP
2113NODEC:
2114;Return is intra-segment (short) without add to SP.
2115;Record position for RET symbol.
2116 MOV BX,[PC]
2117 MOV [LSTRET],BX
2118 XCHG DX,BX
2119 MOV BX,[RETPT]
2120 MOV AL,BH
2121 OR AL,BL
2122 JZ DORET
2123 MOV B,[BX],1
2124 INC BX
2125 MOV [BX],DX
2126 MOV BX,0
2127 MOV [RETPT],BX
2128DORET:
2129 POP AX
2130 XCHG AH,AL
2131 SAHF
2132 JMP PUT
2133
2134GRP17:
2135 CALL PUT
2136 CALL GETOP
2137 CMP AL,CONST
2138 MOV CL,20
2139ERR9: JNZ ERR10
2140 MOV BX,[DATA]
2141 MOV DX,[PC]
2142 INC DX
2143 SUB BX,DX
2144 MOV [DATA],BX
2145 CALL PUTBYT
2146 MOV BX,[DLABEL]
2147 MOV AL,BH
2148 OR AL,BL
2149 JNZ RET
2150 MOV BX,[DATA]
2151 MOV AL,BL
2152 CBW
2153 CMP AX,BX ;Signed 8-bit number?
2154 JZ RET
2155 MOV CL,31
2156ERR10: JMP ERROR
2157 RET
2158GRP18:
2159 CALL GETOP
2160 CMP AL,CONST
2161 MOV CL,20
2162 JNZ ERR10
2163 MOV BX,[DLABEL]
2164 MOV AL,BH
2165 OR AL,BL
2166 JNZ GENINT
2167 MOV BX,[DATA]
2168 MOV DX,3
2169 SBB BX,DX
2170 JNZ GENINT
2171 MOV AL,0CCH
2172 JMP PUT
2173GENINT:
2174 MOV AL,0CDH
2175 CALL PUT
2176 JMP PUTBYT
2177
2178GRP19: ;ESC opcode
2179 CALL GETOP
2180 MOV CL,20
2181 CMP AL,CONST
2182 JNZ ERRJ ;First operand must be immediate
2183 MOV CL,1EH
2184 TEST [DLABEL],-1 ;See if all labels have been defined
2185 JNZ ERRJ
2186 MOV AX,[DATA]
2187 CMP AX,64 ;Must only be 6 bits
2188 MOV CL,1FH
2189 JNB ERRJ
2190 MOV BL,AL ;Save for second byte
2191 SHR AL
2192 SHR AL
2193 SHR AL
2194 OR AL,0D8H ;ESC opcode
2195 CALL PUT
2196 PUSH BX
2197 CALL GETOP2
2198 POP BX
2199 AND BL,7 ;Low 3 bits of first operand
2200 SHL BL
2201 SHL BL
2202 SHL BL
2203 CMP AL,UNDEFID ;Check for memory operand
2204 JZ ESCMEM
2205 CMP AL,CONST ;Check for another immediate
2206 JZ ESCIMM
2207 MOV CL,20
2208ERRJ: JMP ERROR
2209
2210ESCMEM:
2211 OR BL,DL ;Combine mode with first operand
2212 MOV AL,BL
2213 JMP PUTADD
2214
2215ESCIMM:
2216 MOV CL,1EH
2217 TEST [DLABEL],-1 ;See if second operand is fully defined
2218 JNZ ERRJ
2219 MOV AX,[DATA]
2220 MOV CL,1FH
2221 CMP AX,8 ;Must only be 3 bit value
2222 JNB ERRJ
2223 OR AL,BL ;Combine first and second operands
2224 OR AL,0C0H ;Force "register" mode
2225 JMP PUT
2226
2227GRP20:
2228 MOV CH,AL
2229 MOV CL,1
2230 CALL MROPS
2231 MOV CL,0F6H
2232 CALL IMMED
2233 MOV CH,0A8H
2234 JMP AIMM
2235GRP21:
2236 CALL GETOP
2237 CMP AL,SREG
2238 MOV CL,28
2239 JNZ ERRJ
2240 MOV CH,26H
2241PACKREG:
2242 MOV AL,DL
2243 ADD AL,AL
2244 ADD AL,AL
2245 ADD AL,AL
2246 OR AL,CH
2247 JMP PUT
2248GRP22:
2249 CALL GETOP
2250 MOV CX,8F00H
2251 CMP AL,UNDEFID
2252 JNZ $+5
2253 JMP PMEM
2254 MOV CH,58H
2255 CMP AL,XREG
2256 JNZ $+5
2257 JMP PXREG
2258 MOV CH,7
2259 CMP AL,SREG
2260 JZ PACKREG
2261 MOV CL,20
2262ERR11: JMP ERROR
2263GRP23:
2264 MOV [DATSIZ],AL
2265GETDAT:
2266 CALL GETSYM
2267 MOV AL,2
2268 CALL VAL1
2269 MOV AL,[SYM]
2270 CMP AL,','
2271 MOV AL,[DATSIZ]
2272 JNZ ENDDAT
2273 CALL SAVDAT
2274 JP GETDAT
2275ENDDAT:
2276 CMP AL,2
2277 JNZ SAVDAT
2278 MOV BX,[DATA]
2279 LAHF
2280 OR BL,080H
2281 SAHF
2282 MOV [DATA],BX
2283SAVDAT:
2284 OR AL,AL
2285 JZ $+5
2286 JMP PUTBYT
2287 JMP PUTWOR
2288IF:
2289 OR BX,BX
2290 JZ SKIPCD
2291 INC B,[IFFLG]
2292 RET
2293
2294SKIPCD:
2295 INC B,[CHKLAB]
2296SKIPLP:
2297 XOR AL,AL
2298 CALL NEXLIN
2299 CALL NEXTCHR
2300 CMP AL,1AH
2301 JZ END
2302 CALL GETLAB
2303 JC SKIPLP
2304 MOV DI,LENID
2305 MOV SI,IFEND
2306 MOV CH,0
2307 MOV CL,[DI]
2308 INC CL
2309 REPE
2310 CMPB
2311 JZ ENDCOND
2312 MOV DI,LENID
2313 MOV SI,IFNEST
2314 MOV CL,[DI]
2315 INC CL
2316 REPE
2317 CMPB
2318 JNZ SKIPLP
2319 INC B,[CHKLAB]
2320 JP SKIPLP
2321
2322ENDCOND:
2323 DEC B,[CHKLAB]
2324 JNZ SKIPLP
2325 RET
2326
2327ENDIF:
2328 MOV AL,[IFFLG]
2329 MOV CL,36
2330 DEC AL
2331 JS ERRJMP
2332 MOV [IFFLG],AL
2333 RET
2334
2335ERRJMP: JMP ERROR
2336
2337;*********************************************************************
2338;
2339; PASS 2
2340;
2341;*********************************************************************
2342
2343END:
2344 MOV DL,4
2345WREND:
2346 MOV CH,0FFH
2347 MOV AL,CH
2348 CALL GEN
2349 DEC DL
2350 JNZ WREND
2351 MOV [BUFPT],SRCBUF
2352 MOV B,[HEXCNT],-5 ;FLAG HEX BUFFER AS EMPTY
2353 MOV [LSTPNT],LSTBUF
2354 MOV [HEXPNT],HEXBUF
2355 XOR AX,AX
2356 MOV [ERRCNT],AX
2357 MOV [PC],AX
2358 MOV [LINE],AX ;Current line number
2359 MOV [HEXADD],OBJECT
2360 MOV DX,FCB
2361 MOV AH,OPEN
2362 INT 33 ;Re-open source file
2363 XOR AX,AX
2364 MOV [FCB+12],AX ;Set CURRENT BLOCK to zero
2365 MOV [FCB+20H],AL ;Set NEXT RECORD field to zero
2366 MOV [FCB+14],BUFSIZ
2367 MOV [COUNT],AL
2368 MOV CH,1
2369 MOV SI,START
2370FIXLINE:
2371 MOV DI,START ;Store code over used up intermediate code
2372 XOR AL,AL
2373 MOV [SPC],AL ;No "special" yet (ORG, PUT, DS)
2374 MOV [ERR],AL ;No second pass errors yet
2375NEXBT:
2376 SHL CL ;Shift out last bit of previous code
2377 DEC CH ;Still have codes left?
2378 JNZ TESTTYP
2379 LODB ;Get next flag byte
2380 MOV CL,AL
2381 MOV CH,4
2382TESTTYP:
2383 SHL CL ;Set flags based on two bits
2384 JO FIXUP
2385 LODB
2386 JC EMARK
2387OBJBT:
2388 STOB
2389 JP NEXBT
2390
2391FIXUP:
2392;Either a word or byte fixup is needed from a forward reference
2393 LODW ;Get pointer to symbol
2394 XCHG AX,BX
2395 LODW ;Get constant part
2396 ADD AX,[BX+1] ;Add symbol value to constant part
2397 CMP B,[BX],0 ;See if symbol got defined
2398 JNZ HAVDEF
2399 MOV B,[ERR],100 ;Undefined - flag error
2400 XOR AX,AX
2401HAVDEF:
2402 OR CL,CL ;See if word or byte fixup
2403 JS DEFBYT
2404 STOW
2405 JP NEXBT
2406
2407DEFBYT:
2408 MOV DX,AX
2409 CBW ;Extend sign
2410 CMP AX,DX ;See if in range +127 to -128
2411 JZ OBJBT ;If so, it's always OK
2412 NOT AH ;Check for range +255 to -256
2413 CMP AH,DH
2414 JNZ RNGERR ;Must always be in this range
2415;Check for short jump. If so, we're out of range; otherwise we're OK
2416 CMP DI,START+1 ;Only one other byte on line?
2417 JNZ OBJBT ;Can't be short jump if not
2418 MOV AL,[START] ;Get the first byte of this line
2419 CMP AL,0EBH ;Direct short jump?
2420 JZ RNGERR
2421 AND AL,0FCH
2422 CMP AL,0E0H ;LOOP or JCXZ instruction?
2423 JZ RNGERR
2424 AND AL,0F0H
2425 CMP AL,70H ;Conditional jump?
2426 MOV AL,DL ;Get code byte in AL
2427 JNZ OBJBT ;If not, we're OK
2428RNGERR:
2429 MOV B,[ERR],101 ;Value out of range
2430 JP OBJBT
2431
2432FINIJ: JMP FINI
2433
2434EMARK:
2435 CMP AL,-1 ;End of file?
2436 JZ FINIJ
2437 CMP AL,-10 ;Special item?
2438 JA SPEND
2439 PUSH CX
2440 PUSH SI
2441 PUSH AX ;Save error code
2442 MOV AH,[LSTDEV]
2443 AND AH,0FEH ;Reset error indicator
2444 OR AL,[ERR] ;See if any errors on this line
2445 JZ NOERR
2446 OR AH,1 ;Send line to console if error occured
2447NOERR:
2448 MOV [LSTDEV],AH
2449 MOV CX,DI
2450 CALL STRTLIN ;Print address of line
2451 MOV SI,START
2452 SUB CX,SI ;Get count of bytes of code
2453 JZ SHOLIN
2454CODLP:
2455 LODB
2456 CALL SAVCD ;Ouput code to HEX and PRN files
2457 LOOP CODLP
2458SHOLIN:
2459 MOV AL,0
2460 XCHG AL,[COUNT]
2461 MOV CX,7 ;Allow 7 bytes of code per line
2462 SUB CL,AL
2463 MOV AL,' '
2464 JZ NOFIL
2465BLNK: ;Put in 3 blanks for each byte not present
2466 CALL LIST
2467 CALL LIST
2468 CALL LIST
2469 LOOP BLNK
2470NOFIL:
2471 CALL OUTLIN
2472 POP AX ;Restore error code
2473 CALL REPERR
2474 MOV AL,[ERR]
2475 CALL REPERR
2476 POP SI
2477 POP CX
2478 MOV AL,[SPC] ;Any special funtion?
2479 OR AL,AL
2480 JNZ SPCFUN
2481 JMP FIXLINE
2482
2483SPEND:
2484 MOV [SPC],AL ;Record special function
2485 LODW ;Get it's data
2486 MOV [DATA],AX
2487 JMP NEXBT
2488
2489SPCFUN:
2490 MOV DX,[DATA]
2491 CMP AL,-2
2492 JZ DORG
2493 CMP AL,-3
2494 JZ DPUT
2495DDS:
2496;Handle DS pseudo-op
2497 ADD [PC],DX
2498 ADD [HEXADD],DX
2499 JMP FIXLINE
2500
2501DORG:
2502;Handle ORG pseudo-op
2503 MOV [PC],DX
2504 JMP FIXLINE
2505
2506DPUT:
2507;Handle PUT pseudo-op
2508 MOV [HEXADD],DX
2509 JMP FIXLINE
2510
2511OUTLIN:
2512;Copy the source line to the ouput device. Line will be preceded by
2513;assembler-generated line number. This routine may be called several times
2514;on one line (once for each line of object code bytes), so it sets a flag
2515;so the line will only be output on the first call.
2516 MOV AL,-1
2517 XCHG AL,[LINFLG]
2518 OR AL,AL
2519 JNZ CRLF ;Output line only if first time
2520 MOV AX,[LINE]
2521 INC AX
2522 MOV [LINE],AX
2523 MOV BH,0 ;No leading zero suppression
2524 CALL OUT10
2525 MOV AL," "
2526 CALL LIST
2527 MOV AL,[LSTFCB]
2528 CMP AL,'Z'
2529 JZ CRLF ;Don't call NEXTCHR if listing suppressed
2530 PUSH SI ;Save the only register destroyed by NEXTCHR
2531OUTLN:
2532 CALL NEXTCHR
2533 CALL LIST
2534 CMP AL,10 ;Output until linefeed found
2535 JNZ OUTLN
2536 POP SI
2537 RET
2538
2539PRTCNT:
2540 MOV AX,[ERRCNT]
2541 MOV BX,ERCNTM
2542PRNT10:
2543 PUSH AX
2544 CALL PRINT
2545 POP AX
2546 MOV BH,"0"-" " ;Enable leading zero suppression
2547 CALL OUT10
2548CRLF:
2549 MOV AL,13
2550 CALL LIST
2551 MOV AL,10
2552 JP LIST
2553
2554OUT10:
2555 XOR DX,DX
2556 MOV DI,10000
2557 DIV AX,DI
2558 OR AL,AL ;>10,000?
2559 JNZ LEAD
2560 SUB AL,"0"-" " ;Convert leading zero to blank
2561LEAD:
2562 ADD AL,"0"
2563 CALL LIST
2564 XCHG AX,DX
2565 MOV BL,100
2566 DIV AL,BL
2567 MOV BL,AH
2568 CALL HIDIG ;Convert to decimal and print 1000s digit
2569 CALL DIGIT ;Print 100s digit
2570 MOV AL,BL
2571 CALL HIDIG ;Convert to decimal and print 10s digit
2572 MOV BH,0 ;Ensure leading zero suppression is off
2573 JP DIGIT
2574
2575HIDIG:
2576 AAM ;Convert binary to unpacked BCD
2577 OR AX,3030H ;Add "0" bias
2578DIGIT:
2579 XCHG AL,AH
2580 CMP AL,"0"
2581 JZ SUPZ
2582 MOV BH,0 ;Turn off zero suppression if not zero
2583SUPZ:
2584 SUB AL,BH ;Convert leading zeros to blanks
2585 JP LIST
2586
2587STRTLIN:
2588 MOV B,[LINFLG],0
2589 MOV BX,[PC]
2590 MOV AL,BH
2591 CALL PHEX
2592 MOV AL,BL
2593PHEXB:
2594 CALL PHEX
2595 MOV AL,' '
2596LIST:
2597 PUSH AX
2598 PUSH DX
2599 AND AL,7FH
2600 MOV DL,AL
2601 TEST B,[LSTDEV],3 ;See if output goes to console
2602 JZ PRNCHK
2603 MOV AH,2
2604 INT 33 ;Output to console
2605PRNCHK:
2606 TEST B,[LSTDEV],4 ;See if output goes to printer
2607 JZ FILCHK
2608 MOV AH,5
2609 INT 33 ;Output to printer
2610FILCHK:
2611 MOV AL,DL
2612 POP DX
2613 TEST B,[LSTDEV],80H ;See if output goes to a file
2614 JZ LISTRET
2615 CALL WRTBUF
2616LISTRET:
2617 POP AX
2618 RET
2619
2620WRTBUF:
2621 PUSH DI
2622 MOV DI,[LSTPNT]
2623 STOB
2624 CMP DI,LSTBUF+LSTBUFSIZ
2625 JNZ SAVPT
2626 PUSH AX
2627 PUSH CX
2628 PUSH DX
2629 CALL FLUSHBUF
2630 POP DX
2631 POP CX
2632 POP AX
2633SAVPT:
2634 MOV [LSTPNT],DI
2635 POP DI
2636 RET
2637
2638PHEX:
2639 PUSH AX
2640 CALL UHALF
2641 CALL LIST
2642 POP AX
2643 CALL LHALF
2644 JP LIST
2645
2646FINI:
2647 OR B,[LSTDEV],1
2648 CALL PRTCNT
2649 MOV BX,SYMSIZE
2650 MOV AX,[6]
2651 SUB AX,[HEAP] ;Size of symbol table
2652 CALL PRNT10
2653 MOV BX,FRESIZE
2654 MOV AX,[HEAP]
2655 SUB AX,[CODE] ;Free space remaining
2656 CALL PRNT10
2657 AND B,[LSTDEV],0FEH
2658 MOV AL,[HEXFCB]
2659 CMP AL,'Z'
2660 JZ SYMDMP
2661 MOV AL,[HEXCNT]
2662 CMP AL,-5
2663 JZ L0012
2664 CALL ENHEXL
2665L0012:
2666 MOV AL,':'
2667 CALL PUTCHR
2668 MOV CH,10
2669HEXEND:
2670 PUSH CX
2671 MOV AL,'0'
2672 CALL PUTCHR
2673 POP CX
2674 DEC CH
2675 JNZ HEXEND
2676 MOV AL,13
2677 CALL PUTCHR
2678 MOV AL,10
2679 CALL PUTCHR
2680 MOV AL,1AH
2681 CALL PUTCHR
2682 CALL WRTHEX ;Flush HEX file buffer
2683 MOV DX,HEXFCB
2684 MOV AH,CLOSE
2685 INT 33
2686SYMDMP:
2687 MOV AL,[SYMFLG]
2688 CMP AL,'S'
2689 JNZ ENDSYM
2690 MOV AL,[LSTDEV]
2691 OR AL,AL ;Any output device for symbol table dump?
2692 JNZ DOSYMTAB
2693 OR AL,1 ;If not, send it to console
2694 MOV [LSTDEV],AL
2695DOSYMTAB:
2696 MOV BX,SYMMES
2697 CALL PRINT
2698 MOV DX,[BASE]
2699 MOV AL,DH
2700 OR AL,DL
2701 JZ ENDSYM
2702 MOV B,[SYMLIN],SYMWID ;No symbols on this line yet
2703 MOV BX,[HEAP]
2704 MOV SP,BX ;Need maximum stack for recursive tree walk
2705 CALL NODE
2706ENDSYM:
2707 TEST B,[LSTDEV],80H ;Print listing to file?
2708 JZ EXIT
2709 MOV AL,1AH
2710 CALL WRTBUF ;Write end-of-file mark
2711 MOV DI,[LSTPNT]
2712 CALL FLUSHBUF
2713 MOV AH,CLOSE
2714 INT 33
2715EXIT: JMP 0
2716
2717NODE:
2718 XCHG DX,BX
2719 PUSH BX
2720 MOV DL,[BX]
2721 MOV DH,0
2722 INC BX
2723 ADD BX,DX
2724 MOV DX,[BX]
2725 OR DX,DX
2726 JZ L0014
2727 CALL NODE
2728L0014:
2729 POP BX
2730 MOV AL,[BX]
2731 INC BX
2732 MOV CH,AL
2733 ADD AL,24
2734 SHR AL
2735 SHR AL
2736 SHR AL
2737 MOV CL,AL
2738 INC CL ;Invert last bit
2739 AND CL,1 ;Number of extra tabs needed (0 or 1)
2740 SHR AL ;Number of positions wide this symbol needs
2741 SUB [SYMLIN],AL
2742 JNC WRTSYM ;Will it fit?
2743 SUB AL,SYMWID
2744 NEG AL
2745 MOV [SYMLIN],AL
2746 CALL CRLF ;Start new line if not
2747WRTSYM:
2748 MOV AL,[BX]
2749 INC BX
2750 CALL LIST
2751 DEC CH
2752 JNZ WRTSYM
2753 INC CL
2754TABVAL:
2755 MOV AL,9
2756 CALL LIST
2757 LOOP TABVAL
2758 INC BX
2759 INC BX
2760 PUSH BX
2761 MOV AL,[BX+4]
2762 CALL PHEX
2763 MOV AL,[BX+3]
2764 CALL PHEX
2765 CMP B,[SYMLIN],0 ;Will any more fit on line?
2766 JZ NEXSYMLIN
2767 MOV AL,9
2768 CALL LIST
2769 JP RIGHTSON
2770NEXSYMLIN:
2771 CALL CRLF
2772 MOV B,[SYMLIN],SYMWID
2773RIGHTSON:
2774 POP BX
2775 MOV DX,[BX]
2776 OR DX,DX
2777 JNZ NODE
2778 RET
2779
2780SAVCD:
2781 MOV [PREV],AL
2782 PUSH BX
2783 PUSH CX
2784 PUSH AX
2785 PUSH DX
2786 CALL CODBYT
2787 POP DX
2788 MOV BX,COUNT
2789 INC B,[BX]
2790 MOV AL,[BX]
2791 CMP AL,8
2792 JNZ NOEXT
2793 MOV B,[BX],1
2794 CALL OUTLIN
2795 MOV AL,' '
2796 MOV CH,5
2797TAB:
2798 CALL LIST
2799 DEC CH
2800 JNZ TAB
2801NOEXT:
2802 POP AX
2803 CALL PHEXB
2804 POP CX
2805 INC [PC]
2806 INC [HEXADD]
2807 POP BX
2808 RET
2809
2810REPERR:
2811 OR AL,AL ;Did an error occur?
2812 JZ RET
2813 INC [ERRCNT]
2814 PUSH AX
2815 MOV BX,ERRMES ;Print "ERROR"
2816 CALL PRINT
2817 POP AX
2818;We have error number in AL. See if there's an error message for it
2819 MOV DI,ERRTAB
2820 MOV BL,80H
2821ERRLOOK:
2822 SCASB ;Do we have the error message
2823 JBE HAVMES ;Quit looking if we have it or passed it
2824 XCHG AX,BX ;Put 80H in AL to look for end of this message
2825NEXTMES:
2826 SCASB ;Look for high bit set in message
2827 JA NEXTMES ; which means we've reached the end
2828 XCHG AX,BX ;Restore error number to AL
2829 JMPS ERRLOOK ;Keep looking
2830
2831HAVMES:
2832 MOV BX,DI ;Put address of message in BX
2833 JZ PRNERR ;Do we have a message for this error?
2834 CALL PHEX ;If not, just print error number
2835 JMP CRLF
2836
2837PRNERR:
2838 CALL PRINT
2839 JMP CRLF
2840
2841PRINT:
2842 MOV AL,[BX]
2843 CALL LIST
2844 OR AL,AL
2845 JS RET
2846 INC BX
2847 JP PRINT
2848
2849OUTA:
2850 MOV DL,AL
2851OUT:
2852 AND DL,7FH
2853 MOV CL,2
2854SYSTEM:
2855 CALL 5
2856 RET
2857
2858CODBYT:
2859 CMP B,[HEXFCB],"Z"
2860 JZ RET
2861 PUSH AX
2862 MOV DX,[LASTAD]
2863 MOV BX,[HEXADD]
2864 MOV [LASTAD],BX
2865 INC DX
2866 MOV AL,[HEXCNT]
2867 CMP AL,-5
2868 JZ NEWLIN
2869 CMP BX,DX
2870 JZ AFHEX
2871 CALL ENHEXL
2872NEWLIN:
2873 MOV AL,':'
2874 CALL PUTCHR
2875 MOV AL,-4
2876 MOV [HEXCNT],AL
2877 XOR AL,AL
2878 MOV [CHKSUM],AL
2879 MOV BX,[HEXPNT]
2880 MOV [HEXLEN],BX
2881 CALL HEXBYT
2882 MOV AL,[HEXADD+1]
2883 CALL HEXBYT
2884 MOV AL,[HEXADD]
2885 CALL HEXBYT
2886 XOR AL,AL
2887 CALL HEXBYT
2888AFHEX:
2889 POP AX
2890HEXBYT:
2891 MOV CH,AL
2892 MOV BX,CHKSUM
2893 ADD AL,[BX]
2894 MOV [BX],AL
2895 MOV AL,CH
2896 CALL UHALF
2897 CALL PUTCHR
2898 MOV AL,CH
2899 CALL LHALF
2900 CALL PUTCHR
2901 MOV BX,HEXCNT
2902 INC B,[BX]
2903 MOV AL,[BX]
2904 CMP AL,26
2905 JNZ RET
2906ENHEXL:
2907 MOV DI,[HEXLEN]
2908 MOV CH,AL
2909 CALL UHALF
2910 STOB
2911 MOV AL,CH
2912 CALL LHALF
2913 STOB
2914 MOV AL,-6
2915 MOV [HEXCNT],AL
2916 MOV AL,[CHKSUM]
2917 ADD AL,CH
2918 NEG AL
2919 CALL HEXBYT
2920 MOV AL,13
2921 CALL PUTCHR
2922 MOV AL,10
2923 CALL PUTCHR
2924WRTHEX:
2925;Write out the line
2926 MOV DX,HEXBUF
2927 MOV [HEXPNT],DX
2928 MOV AH,SETDMA
2929 INT 33
2930 SUB DI,DX ;Length of buffer
2931 MOV CX,DI
2932 MOV DX,HEXFCB
2933 MOV AH,BLKWRT
2934 INT 33
2935 OR AL,AL
2936 JNZ DSKFUL
2937 RET
2938
2939PUTCHR:
2940 MOV DI,[HEXPNT]
2941 STOB
2942 MOV [HEXPNT],DI
2943 RET
2944
2945FLUSHBUF:
2946 MOV CX,DI
2947 MOV DX,LSTBUF
2948 MOV DI,DX
2949 SUB CX,DX
2950 JZ RET ;Buffer empty?
2951 MOV AH,SETDMA
2952 INT 33
2953 MOV DX,LSTFCB
2954 MOV AH,BLKWRT
2955 INT 33
2956 OR AL,AL
2957 JZ RET
2958DSKFUL:
2959 MOV BX,WRTERR
2960 JMP PRERR
2961
2962UHALF:
2963 RCR AL
2964 RCR AL
2965 RCR AL
2966 RCR AL
2967LHALF:
2968 AND AL,0FH
2969 OR AL,30H
2970 CMP AL,'9'+1
2971 JC RET
2972 ADD AL,7
2973 RET
2974
2975NONE: DB 0
2976
2977; 8086 MNEMONIC TABLE
2978
2979; This table is actually a sequence of subtables, each starting with a label.
2980; The label signifies which mnemonics the subtable applies to--A3, for example,
2981; means all 3-letter mnemonics beginning with A.
2982
2983A3:
2984 DB 7
2985 DB 'dd'
2986 DW GRP7
2987 DB 2
2988 DB 'nd'
2989 DW GRP13
2990 DB 22H
2991 DB 'dc'
2992 DW GRP7
2993 DB 12H
2994 DB 'aa'
2995 DW PUT
2996 DB 37H
2997 DB 'as'
2998 DW PUT
2999 DB 3FH
3000 DB 'am'
3001 DW GRP11
3002 DB 0D4H
3003 DB 'ad'
3004 DW GRP11
3005 DB 0D5H
3006A5:
3007 DB 1
3008 DB 'lign'
3009 DW ALIGN
3010 DB 0
3011C3:
3012 DB 7
3013 DB 'mp'
3014 DW GRP7
3015 DB 3AH
3016 DB 'lc'
3017 DW PUT
3018 DB 0F8H
3019 DB 'ld'
3020 DW PUT
3021 DB 0FCH
3022 DB 'li'
3023 DW PUT
3024 DB 0FAH
3025 DB 'mc'
3026 DW PUT
3027 DB 0F5H
3028 DB 'bw'
3029 DW PUT
3030 DB 98H
3031 DB 'wd'
3032 DW PUT
3033 DB 99H
3034C4:
3035 DB 3
3036 DB 'all'
3037 DW GRP14
3038 DB 9AH
3039 DB 'mpb'
3040 DW PUT
3041 DB 0A6H
3042 DB 'mpw'
3043 DW PUT
3044 DB 0A7H
3045C5:
3046 DB 2
3047 DB 'mpsb'
3048 DW PUT
3049 DB 0A6H
3050 DB 'mpsw'
3051 DW PUT
3052 DB 0A7H
3053D2:
3054 DB 5
3055 DB 'b'
3056 DW GRP23
3057 DB 1
3058 DB 'w'
3059 DW GRP23
3060 DB 0
3061 DB 'm'
3062 DW GRP23
3063 DB 2
3064 DB 's'
3065 DW GRP5
3066 DB 1
3067 DB 'i'
3068 DW PUT
3069 DB 0FAH
3070D3:
3071 DB 4
3072 DB 'ec'
3073 DW GRP8
3074 DB 49H
3075 DB 'iv'
3076 DW GRP10
3077 DB 30H
3078 DB 'aa'
3079 DW PUT
3080 DB 27H
3081 DB 'as'
3082 DW PUT
3083 DB 2FH
3084D4:
3085 DB 1
3086 DB 'own'
3087 DW PUT
3088 DB 0FDH
3089E2:
3090 DB 1
3091 DB 'i'
3092 DW PUT
3093 DB 0FBH
3094E3:
3095 DB 3
3096 DB 'qu'
3097 DW GRP5
3098 DB 2
3099 DB 'sc'
3100 DW GRP19
3101 DB 0D8H
3102 DB 'nd'
3103 DW END
3104 DB 0
3105E5:
3106 DB 1
3107 DB 'ndif'
3108 DW ENDIF
3109 DB 0
3110H3:
3111 DB 1
3112 DB 'lt'
3113 DW PUT
3114 DB 0F4H
3115H4:
3116 DB 1
3117 DB 'alt'
3118 DW PUT
3119 DB 0F4H
3120I2:
3121 DB 2
3122 DB 'n'
3123 DW GRP4
3124 DB 0E4H
3125 DB 'f'
3126 DW GRP5
3127 DB 4
3128I3:
3129 DB 4
3130 DB 'nc'
3131 DW GRP8
3132 DB 41H
3133 DB 'nb'
3134 DW GRP4
3135 DB 0E4H
3136 DB 'nw'
3137 DW GRP4
3138 DB 0E5H
3139 DB 'nt'
3140 DW GRP18
3141 DB 0CCH
3142I4:
3143 DB 4
3144 DB 'mul'
3145 DW GRP10
3146 DB 28H
3147 DB 'div'
3148 DW GRP10
3149 DB 38H
3150 DB 'ret'
3151 DW PUT
3152 DB 0CFH
3153 DB 'nto'
3154 DW PUT
3155 DB 0CEH
3156J2:
3157 DB 10
3158 DB 'p'
3159 DW GRP17
3160 DB 0EBH
3161 DB 'z'
3162 DW GRP17
3163 DB 74H
3164 DB 'e'
3165 DW GRP17
3166 DB 74H
3167 DB 'l'
3168 DW GRP17
3169 DB 7CH
3170 DB 'b'
3171 DW GRP17
3172 DB 72H
3173 DB 'a'
3174 DW GRP17
3175 DB 77H
3176 DB 'g'
3177 DW GRP17
3178 DB 7FH
3179 DB 'o'
3180 DW GRP17
3181 DB 70H
3182 DB 's'
3183 DW GRP17
3184 DB 78H
3185 DB 'c'
3186 DW GRP17
3187 DB 72H
3188J3:
3189 DB 17
3190 DB 'mp'
3191 DW GRP14
3192 DB 0EAH
3193 DB 'nz'
3194 DW GRP17
3195 DB 75H
3196 DB 'ne'
3197 DW GRP17
3198 DB 75H
3199 DB 'nl'
3200 DW GRP17
3201 DB 7DH
3202 DB 'ge'
3203 DW GRP17
3204 DB 7DH
3205 DB 'nb'
3206 DW GRP17
3207 DB 73H
3208 DB 'ae'
3209 DW GRP17
3210 DB 73H
3211 DB 'nc'
3212 DW GRP17
3213 DB 73H
3214 DB 'ng'
3215 DW GRP17
3216 DB 7EH
3217 DB 'le'
3218 DW GRP17
3219 DB 7EH
3220 DB 'na'
3221 DW GRP17
3222 DB 76H
3223 DB 'be'
3224 DW GRP17
3225 DB 76H
3226 DB 'pe'
3227 DW GRP17
3228 DB 7AH
3229 DB 'np'
3230 DW GRP17
3231 DB 7BH
3232 DB 'po'
3233 DW GRP17
3234 DB 7BH
3235 DB 'no'
3236 DW GRP17
3237 DB 71H
3238 DB 'ns'
3239 DW GRP17
3240 DB 79H
3241J4:
3242 DB 6
3243 DB 'mps'
3244 DW GRP17
3245 DB 0EBH
3246 DB 'cxz'
3247 DW GRP17
3248 DB 0E3H
3249 DB 'nge'
3250 DW GRP17
3251 DB 7CH
3252 DB 'nae'
3253 DW GRP17
3254 DB 72H
3255 DB 'nbe'
3256 DW GRP17
3257 DB 77H
3258 DB 'nle'
3259 DW GRP17
3260 DB 7FH
3261L3:
3262 DB 3
3263 DB 'ea'
3264 DW GRP6
3265 DB 8DH
3266 DB 'ds'
3267 DW GRP6
3268 DB 0C5H
3269 DB 'es'
3270 DW GRP6
3271 DB 0C4H
3272L4:
3273 DB 5
3274 DB 'oop'
3275 DW GRP17
3276 DB 0E2H
3277 DB 'odb'
3278 DW PUT
3279 DB 0ACH
3280 DB 'odw'
3281 DW PUT
3282 DB 0ADH
3283 DB 'ahf'
3284 DW PUT
3285 DB 9FH
3286 DB 'ock'
3287 DW PUT
3288 DB 0F0H
3289L5:
3290 DB 4
3291 DB 'oope'
3292 DW GRP17
3293 DB 0E1H
3294 DB 'oopz'
3295 DW GRP17
3296 DB 0E1H
3297 DB 'odsb'
3298 DW PUT
3299 DB 0ACH
3300 DB 'odsw'
3301 DW PUT
3302 DB 0ADH
3303L6:
3304 DB 2
3305 DB 'oopne'
3306 DW GRP17
3307 DB 0E0H
3308 DB 'oopnz'
3309 DW GRP17
3310 DB 0E0H
3311M3:
3312 DB 2
3313 DB 'ov'
3314 DW GRP1
3315 DB 88H
3316 DB 'ul'
3317 DW GRP10
3318 DB 20H
3319M4:
3320 DB 2
3321 DB 'ovb'
3322 DW PUT
3323 DB 0A4H
3324 DB 'ovw'
3325 DW PUT
3326 DB 0A5H
3327M5:
3328 DB 2
3329 DB 'ovsb'
3330 DW PUT
3331 DB 0A4H
3332 DB 'ovsw'
3333 DW PUT
3334 DB 0A5H
3335N3:
3336 DB 3
3337 DB 'ot'
3338 DW GRP9
3339 DB 10H
3340 DB 'eg'
3341 DW GRP9
3342 DB 18H
3343 DB 'op'
3344 DW PUT
3345 DB 90H
3346O2:
3347 DB 1
3348 DB 'r'
3349 DW GRP13
3350 DB 0AH
3351O3:
3352 DB 2
3353 DB 'ut'
3354 DW GRP4
3355 DB 0E6H
3356 DB 'rg'
3357 DW GRP5
3358 DB 0
3359O4:
3360 DB 2
3361 DB 'utb'
3362 DW GRP4
3363 DB 0E6H
3364 DB 'utw'
3365 DW GRP4
3366 DB 0E7H
3367P3:
3368 DB 2
3369 DB 'op'
3370 DW GRP22
3371 DB 8FH
3372 DB 'ut'
3373 DW GRP5
3374 DB 3
3375P4:
3376 DB 2
3377 DB 'ush'
3378 DW GRP2
3379 DB 0FFH
3380 DB 'opf'
3381 DW PUT
3382 DB 9DH
3383P5:
3384 DB 1
3385 DB 'ushf'
3386 DW PUT
3387 DB 9CH
3388R3:
3389 DB 6
3390 DB 'et'
3391 DW GRP16
3392 DB 0C3H
3393 DB 'ep'
3394 DW PUT
3395 DB 0F3H
3396 DB 'ol'
3397 DW GRP12
3398 DB 0
3399 DB 'or'
3400 DW GRP12
3401 DB 8
3402 DB 'cl'
3403 DW GRP12
3404 DB 10H
3405 DB 'cr'
3406 DW GRP12
3407 DB 18H
3408R4:
3409 DB 2
3410 DB 'epz'
3411 DW PUT
3412 DB 0F3H
3413 DB 'epe'
3414 DW PUT
3415 DB 0F3H
3416R5:
3417 DB 2
3418 DB 'epnz'
3419 DW PUT
3420 DB 0F2H
3421 DB 'epne'
3422 DW PUT
3423 DB 0F2H
3424S3:
3425 DB 11
3426 DB 'ub'
3427 DW GRP7
3428 DB 2AH
3429 DB 'bb'
3430 DW GRP7
3431 DB 1AH
3432 DB 'bc'
3433 DW GRP7
3434 DB 1AH
3435 DB 'tc'
3436 DW PUT
3437 DB 0F9H
3438 DB 'td'
3439 DW PUT
3440 DB 0FDH
3441 DB 'ti'
3442 DW PUT
3443 DB 0FBH
3444 DB 'hl'
3445 DW GRP12
3446 DB 20H
3447 DB 'hr'
3448 DW GRP12
3449 DB 28H
3450 DB 'al'
3451 DW GRP12
3452 DB 20H
3453 DB 'ar'
3454 DW GRP12
3455 DB 38H
3456 DB 'eg'
3457 DW GRP21
3458 DB 26H
3459S4:
3460 DB 5
3461 DB 'cab'
3462 DW PUT
3463 DB 0AEH
3464 DB 'caw'
3465 DW PUT
3466 DB 0AFH
3467 DB 'tob'
3468 DW PUT
3469 DB 0AAH
3470 DB 'tow'
3471 DW PUT
3472 DB 0ABH
3473 DB 'ahf'
3474 DW PUT
3475 DB 9EH
3476S5:
3477 DB 4
3478 DB 'casb'
3479 DW PUT
3480 DB 0AEH
3481 DB 'casw'
3482 DW PUT
3483 DB 0AFH
3484 DB 'tosb'
3485 DW PUT
3486 DB 0AAH
3487 DB 'tosw'
3488 DW PUT
3489 DB 0ABH
3490T4:
3491 DB 1
3492 DB 'est'
3493 DW GRP20
3494 DB 84H
3495U2:
3496 DB 1
3497 DB 'p'
3498 DW PUT
3499 DB 0FCH
3500W4:
3501 DB 1
3502 DB 'ait'
3503 DW PUT
3504 DB 9BH
3505X3:
3506 DB 1
3507 DB 'or'
3508 DW GRP13
3509 DB 32H
3510X4:
3511 DB 2
3512 DB 'chg'
3513 DW GRP3
3514 DB 86H
3515 DB 'lat'
3516 DW PUT
3517 DB 0D7H
3518
3519
3520; 8087 MNEMONIC TABLE
3521; Similar to 8086 table above, except NOT distinguished by opcode length
3522
3523XM1: ;F2XM1
3524 DB 1 ;One opcode
3525 DM "xm1"
3526 DB 1,0F0H
3527
3528NDPA:
3529 DB 3
3530 DM "dd"
3531 DB 6+ARITH,0C1H
3532 DM "ddp"
3533 DB NEEDOP+STACKOP,0
3534 DM "bs"
3535 DB 1,0E1H
3536
3537NDPB:
3538 DB 2
3539 DM "ld"
3540 DB 7+NEEDOP+MEMORY,20H
3541 DM "stp"
3542 DB 7+NEEDOP+MEMORY,30H
3543
3544NDPC:
3545 DB 5
3546 DM "om"
3547 DB 0+ONEREG+REAL,0D1H
3548 DM "omp"
3549 DB 0+ONEREG+REAL,0D9H
3550 DM "hs"
3551 DB 1,0E0H
3552 DM "ompp"
3553 DB 6,0D9H
3554 DM "lex"
3555 DB 3,0E2H
3556
3557NDPD:
3558 DB 6
3559 DM "iv"
3560 DB 6+ARITH,0F1H
3561 DM "ivp"
3562 DB NEEDOP+STACKOP,30H
3563 DM "ivr"
3564 DB 6+ARITH,0F9H
3565 DM "ivrp"
3566 DB NEEDOP+STACKOP,38H
3567 DM "ecstp"
3568 DB 1,0F6H
3569 DM "isi"
3570 DB 3,0E1H
3571
3572NDPE:
3573 DB 1
3574 DM "ni"
3575 DB 3,0E0H
3576
3577NDPF:
3578 DB 1
3579 DM "ree"
3580 DB 5+NEEDOP+ONEREG,0
3581
3582NDPI:
3583 DB 13
3584 DM "add"
3585 DB 2+NEEDOP+INTEGER,0
3586 DM "ld"
3587 DB 3+NEEDOP+INTEGER+EXTENDED,0
3588 DM "sub"
3589 DB 2+NEEDOP+INTEGER,20H
3590 DM "stp"
3591 DB 3+NEEDOP+INTEGER+EXTENDED,18H
3592 DM "st"
3593 DB 3+NEEDOP+INTEGER,10H
3594 DM "mul"
3595 DB 2+NEEDOP+INTEGER,8
3596 DM "div"
3597 DB 2+NEEDOP+INTEGER,30H
3598 DM "subr"
3599 DB 2+NEEDOP+INTEGER,28H
3600 DM "divr"
3601 DB 2+NEEDOP+INTEGER,38H
3602 DM "com"
3603 DB 2+NEEDOP+INTEGER,10H
3604 DM "comp"
3605 DB 2+NEEDOP+INTEGER,18H
3606 DM "ncstp"
3607 DB 1,0F7H
3608 DM "nit"
3609 DB 3,0E3H
3610
3611NDPL:
3612 DB 10
3613 DM "d"
3614 DB 1+NEEDOP+ONEREG+REAL+EXTENDED,0
3615 DM "dz"
3616 DB 1,0EEH
3617 DM "d1"
3618 DB 1,0E8H
3619 DM "dpi"
3620 DB 1,0EBH
3621 DM "dl2t"
3622 DB 1,0E9H
3623 DM "dl2e"
3624 DB 1,0EAH
3625 DM "dlg2"
3626 DB 1,0ECH
3627 DM "dln2"
3628 DB 1,0EDH
3629 DM "dcw"
3630 DB 1+NEEDOP+MEMORY,28H
3631 DM "denv"
3632 DB 1+NEEDOP+MEMORY,20H
3633
3634NDPM:
3635 DB 2
3636 DM "ul"
3637 DB 6+ARITH,0C9H
3638 DM "ulp"
3639 DB NEEDOP+STACKOP,8
3640
3641NDPO:
3642 DB 1
3643 DM "p"
3644 DB NEEDOP+1,0 ;Flag special handling
3645
3646NDPN:
3647 DB 1
3648 DM "op"
3649 DB 1,0D0H
3650
3651NDPP:
3652 DB 3
3653 DM "rem"
3654 DB 1,0F8H
3655 DM "tan"
3656 DB 1,0F2H
3657 DM "atan"
3658 DB 1,0F3H
3659
3660NDPR:
3661 DB 2
3662 DM "ndint"
3663 DB 1,0FCH
3664 DM "stor"
3665 DB 5+NEEDOP+MEMORY,20H
3666
3667NDPS:
3668 DB 12
3669 DM "t"
3670 DB 5+NEEDOP+ONEREG+REAL,0D0H
3671 DM "tp"
3672 DB 7+NEEDOP+ONEREG+REAL+EXTENDED,0D8H
3673 DM "ub"
3674 DB 6+ARITH,0E1H
3675 DM "ubp"
3676 DB NEEDOP+STACKOP,0E0H
3677 DM "ubr"
3678 DB 6+ARITH,0E9H
3679 DM "ubrp"
3680 DB NEEDOP+STACKOP,0E8H
3681 DM "qrt"
3682 DB 1,0FAH
3683 DM "cale"
3684 DB 1,0FDH
3685 DM "ave"
3686 DB 5+NEEDOP+MEMORY,30H
3687 DM "tcw"
3688 DB 1+NEEDOP+MEMORY,38H
3689 DM "tenv"
3690 DB 1+NEEDOP+MEMORY,30H
3691 DM "tsw"
3692 DB 5+NEEDOP+MEMORY,38H
3693
3694NDPT:
3695 DB 1
3696 DM "st"
3697 DB 1,0E4H
3698
3699NDPW:
3700 DB 1
3701 DM "ait"
3702 DB NEEDOP,0 ;Flag special handling
3703
3704NDPX:
3705 DB 3
3706 DM "ch"
3707 DB 1+ONEREG,0C9H
3708 DM "am"
3709 DB 1,0E5H
3710 DM "tract"
3711 DB 1,0F4H
3712
3713NDPY:
3714 DB 2
3715 DM "l2x"
3716 DB 1,0F1H
3717 DM "l2xp1"
3718 DB 1,0F9H
3719
3720
3721OPTAB:
3722; Table of pointers to mnemonics. For each letter of the alphabet (the
3723; starting letter of the mnemonic), there are 5 entries. Each entry
3724; corresponds to a mnemonic whose length is 2, 3, 4, 5, and 6 characters
3725; long, respectively. If there are no mnemonics for a given combination
3726; of first letter and length (such as A-2), then the corresponding entry
3727; points to NONE. Otherwise, it points to a place in the mnemonic table
3728; for that type.
3729
3730; This table only needs to be modified if a mnemonic is added to a group
3731; previously marked NONE. Change the NONE to a label made up of the first
3732; letter of the mnemonic and its length, then add a new subsection to
3733; the mnemonic table in alphabetical order.
3734
3735 DW NONE
3736 DW A3
3737 DW NONE
3738 DW A5
3739 DW NONE
3740 DW NONE ;B
3741 DW NONE
3742 DW NONE
3743 DW NONE
3744 DW NONE
3745 DW NONE ;C
3746 DW C3
3747 DW C4
3748 DW C5
3749 DW NONE
3750 DW D2 ;D
3751 DW D3
3752 DW D4
3753 DW NONE
3754 DW NONE
3755 DW E2 ;E
3756 DW E3
3757 DW NONE
3758 DW E5
3759 DW NONE
3760 DW NONE ;F
3761 DW NONE
3762 DW NONE
3763 DW NONE
3764 DW NONE
3765 DW NONE ;G
3766 DW NONE
3767 DW NONE
3768 DW NONE
3769 DW NONE
3770 DW NONE ;H
3771 DW H3
3772 DW H4
3773 DW NONE
3774 DW NONE
3775 DW I2 ;I
3776 DW I3
3777 DW I4
3778 DW NONE
3779 DW NONE
3780 DW J2 ;J
3781 DW J3
3782 DW J4
3783 DW NONE
3784 DW NONE
3785 DW NONE ;K
3786 DW NONE
3787 DW NONE
3788 DW NONE
3789 DW NONE
3790 DW NONE ;L
3791 DW L3
3792 DW L4
3793 DW L5
3794 DW L6
3795 DW NONE ;M
3796 DW M3
3797 DW M4
3798 DW M5
3799 DW NONE
3800 DW NONE ;N
3801 DW N3
3802 DW NONE
3803 DW NONE
3804 DW NONE
3805 DW O2 ;O
3806 DW O3
3807 DW O4
3808 DW NONE
3809 DW NONE
3810 DW NONE ;P
3811 DW P3
3812 DW P4
3813 DW P5
3814 DW NONE
3815 DW NONE ;Q
3816 DW NONE
3817 DW NONE
3818 DW NONE
3819 DW NONE
3820 DW NONE ;R
3821 DW R3
3822 DW R4
3823 DW R5
3824 DW NONE
3825 DW NONE ;S
3826 DW S3
3827 DW S4
3828 DW S5
3829 DW NONE
3830 DW NONE ;T
3831 DW NONE
3832 DW T4
3833 DW NONE
3834 DW NONE
3835 DW U2 ;U
3836 DW NONE
3837 DW NONE
3838 DW NONE
3839 DW NONE
3840 DW NONE ;V
3841 DW NONE
3842 DW NONE
3843 DW NONE
3844 DW NONE
3845 DW NONE ;W
3846 DW NONE
3847 DW W4
3848 DW NONE
3849 DW NONE
3850 DW NONE ;X
3851 DW X3
3852 DW X4
3853 DW NONE
3854 DW NONE
3855 DW NONE ;Y
3856 DW NONE
3857 DW NONE
3858 DW NONE
3859 DW NONE
3860 DW NONE ;Z
3861 DW NONE
3862 DW NONE
3863 DW NONE
3864 DW NONE
3865
3866NDPTAB:
3867;Lookup table for 8087 mnemonics. There is one entry for each letter of the
3868;alphabet
3869 DW NDPA
3870 DW NDPB
3871 DW NDPC
3872 DW NDPD
3873 DW NDPE
3874 DW NDPF
3875 DW NONE ;G
3876 DW NONE ;H
3877 DW NDPI
3878 DW NONE ;J
3879 DW NONE ;K
3880 DW NDPL
3881 DW NDPM
3882 DW NDPN
3883 DW NDPO
3884 DW NDPP
3885 DW NONE ;Q
3886 DW NDPR
3887 DW NDPS
3888 DW NDPT
3889 DW NONE ;U
3890 DW NONE ;V
3891 DW NDPW
3892 DW NDPX
3893 DW NDPY
3894 DW NONE ;Z
3895
3896;Error message table
3897
3898ERRTAB:
3899 DM 1,"Register not allowed in immediate value"
3900 DM 2,"Index or base register must be BP, BX, SI, or DI"
3901 DM 3,"Only one base register (BX, BP) allowed"
3902 DM 4,"Only one index register (SI or DI) allowed"
3903 DM 5,"Only addition allowed on register or undefined label"
3904 DM 6,"Only one undefined label per expression allowed"
3905 DM 7,"Illegal digit in hexadecimal number"
3906 DM 8,"Illegal digit in decimal number"
3907 DM 10,"Illegal character in label or opcode"
3908 DM 11,"Label defined twice"
3909 DM 12,"Opcode not recognized"
3910 DM 20,"Invalid operand"
3911 DM 21,'"," and second operand expected'
3912 DM 22,"Register mismatch"
3913 DM 23,"Immediate operand not allowed"
3914 DM 24,'"]" expected'
3915 DM 25,"Two memory operands not allowed"
3916 DM 26,"Destination must not be immediate value"
3917 DM 27,"Both operands must not be registers"
3918 DM 28,"Operand must be segment register"
3919 DM 29,"First operand must be register"
3920 DM 30,"Undefined label not allowed"
3921 DM 31,"Value out of range"
3922 DM 32,"Missing or illegal operand size flag"
3923 DM 33,"Must have label on same line"
3924 DM 35,"Zero-length string illegal"
3925 DM 36,"ENDIF without IF"
3926 DM 37,"One-character strings only"
3927 DM 38,"Illegal expression"
3928 DM 39,"End of string not found"
3929 DM 100,"Undefined label"
3930 DM 101,"Value out of range (forward)"
3931 DB 255
3932
3933ERRMES: DM '***** ERROR: '
3934NOSPAC: DB 13,10,'File creation error',13,10,"$"
3935NOMEM: DB 13,10,'Insufficient memory',13,10,'$'
3936NOFILE: DB 13,10,'File not found',13,10,'$'
3937WRTERR: DB 13,10,'Disk full',13,10,'$'
3938BADDSK: DB 13,10,'Bad disk specifier',13,10,'$'
3939ERCNTM: DM 13,10,13,10,'Error Count ='
3940SYMSIZE DM 13,10,'Symbol Table size = '
3941FRESIZE DM 'Free space = '
3942SYMMES: DM 13,10,'Symbol Table',13,10,13,10
3943EXTEND: DB 'ASM',0,0
3944IFEND: DB 5,'endif'
3945IFNEST: DB 2,'if'
3946RETSTR: DM 'ret'
3947HEXFCB: DB 0,' HEX',0,0,0,0
3948 DS 16
3949 DB 0,0,0,0,0
3950LSTFCB: DB 0,' PRN',0,0,0,0
3951 DS 16
3952 DB 0,0,0,0,0
3953PC: DS 2
3954OLDPC: DS 2
3955LABPT: DS 2
3956FLAG: DS 1
3957MAXFLG: DS 1
3958ADDR: DS 2
3959ALABEL: DS 2
3960DATA: DS 2
3961DLABEL: DS 2
3962CON: DS 2
3963UNDEF: DS 2
3964LENID: DS 1
3965ID: DS 80
3966CHR: DS 1
3967SYM: DS 1
3968BASE: DS 2
3969HEAP: DS 2
3970SYMFLG: DS 1
3971SYMLIN: DS 1
3972CODE: DS 2
3973DATSIZ: DS 1
3974RELOC: DS 1
3975BCOUNT: DS 1
3976COUNT: DS 1
3977ERR: DS 1
3978LINE: DS 2
3979HEXLEN: DS 2
3980HEXADD: DS 2
3981LASTAD: DS 2
3982HEXCNT: DS 1
3983CHKSUM: DS 1
3984LINFLG: DS 1
3985PREV: DS 1
3986IFFLG: DS 1
3987CHKLAB: DS 1
3988ERRCNT: DS 2
3989LSTRET: DS 2
3990RETPT: DS 2
3991LSTDEV: DS 2
3992SPC: DS 1
3993NOWAIT: DS 1
3994IX: DS 2
3995IY: DS 2
3996HEXPNT: DS 2
3997LSTPNT: DS 2
3998HEXBUF: DS HEXBUFSIZ
3999LSTBUF: DS LSTBUFSIZ
4000BUFPT: DS 2
4001SRCBUF: DS BUFSIZ
4002 DS 100H
4003 ALIGN
4004STACK: EQU $
4005START: EQU $
4006 \ No newline at end of file