|
|
|
@ -1,66 +1,270 @@
|
|
|
|
|
org 0x100 |
|
|
|
|
|
|
|
|
|
jmp main |
|
|
|
|
|
|
|
|
|
%include "print.asm" |
|
|
|
|
%include "error.asm" |
|
|
|
|
;; string output |
|
|
|
|
|
|
|
|
|
; print AX in base BX |
|
|
|
|
; destroys DX |
|
|
|
|
putnum xor dx, dx |
|
|
|
|
div bx |
|
|
|
|
test cx, cx |
|
|
|
|
loopnz .pad |
|
|
|
|
test ax, ax |
|
|
|
|
je .nib |
|
|
|
|
.pad push dx |
|
|
|
|
call putnum |
|
|
|
|
pop dx |
|
|
|
|
; print lower DL as digit |
|
|
|
|
.nib add dl, 0x30 |
|
|
|
|
cmp dl, 0x3a |
|
|
|
|
jl putc |
|
|
|
|
add dl, 7 |
|
|
|
|
; print DL as char |
|
|
|
|
putc mov ah, 2 |
|
|
|
|
int 0x21 |
|
|
|
|
ret |
|
|
|
|
|
|
|
|
|
b_err db "OOM", 0 |
|
|
|
|
; print str at SI |
|
|
|
|
; NUL-terminated |
|
|
|
|
puts lodsb |
|
|
|
|
test al, al |
|
|
|
|
jz .l01 |
|
|
|
|
mov dl, al |
|
|
|
|
call putc |
|
|
|
|
jmp puts |
|
|
|
|
.l01 ret |
|
|
|
|
|
|
|
|
|
; print str at return addr |
|
|
|
|
; NUL-terminated |
|
|
|
|
putsh pop si |
|
|
|
|
call puts |
|
|
|
|
jmp si |
|
|
|
|
|
|
|
|
|
; print a newline |
|
|
|
|
newlin mov dl, 0x0A |
|
|
|
|
call putc |
|
|
|
|
mov dl, 0x0D |
|
|
|
|
jmp putc |
|
|
|
|
|
|
|
|
|
; print register set |
|
|
|
|
; order AX CX DX BX BP SI DI IP |
|
|
|
|
; trashes flags |
|
|
|
|
debug push di |
|
|
|
|
push si |
|
|
|
|
push bp |
|
|
|
|
push bx |
|
|
|
|
push dx |
|
|
|
|
push cx |
|
|
|
|
push ax |
|
|
|
|
mov si, sp |
|
|
|
|
call dump |
|
|
|
|
pop ax |
|
|
|
|
pop cx |
|
|
|
|
pop dx |
|
|
|
|
pop bx |
|
|
|
|
pop bp |
|
|
|
|
pop si |
|
|
|
|
pop di |
|
|
|
|
ret |
|
|
|
|
|
|
|
|
|
; dump the 8 words at SI |
|
|
|
|
dump lea di, [si+16] |
|
|
|
|
mov bx, 0x10 |
|
|
|
|
.loop lodsw |
|
|
|
|
mov cx, 4 |
|
|
|
|
call putnum |
|
|
|
|
mov dl, ' ' |
|
|
|
|
call putc |
|
|
|
|
cmp si, di |
|
|
|
|
jc .loop |
|
|
|
|
jmp newlin |
|
|
|
|
|
|
|
|
|
%include "error.asm" |
|
|
|
|
|
|
|
|
|
b_vrfy mov ax, output |
|
|
|
|
add ax, 0 |
|
|
|
|
sub ax, [s_start] |
|
|
|
|
jc .l01 |
|
|
|
|
mov bp, b_err |
|
|
|
|
jmp error |
|
|
|
|
call errmsg |
|
|
|
|
db "OOM", 0 |
|
|
|
|
.l01: ret |
|
|
|
|
|
|
|
|
|
%include "symbols.asm" |
|
|
|
|
%include "file.asm" |
|
|
|
|
%include "parse.asm" |
|
|
|
|
;; input file reading |
|
|
|
|
|
|
|
|
|
; label of current line |
|
|
|
|
l_cur db " " |
|
|
|
|
lfcnt dw 1 ; LF counter |
|
|
|
|
chrptr dw 0xFFFF ; infile blk ptr |
|
|
|
|
|
|
|
|
|
l_read mov di, l_cur |
|
|
|
|
call rdwrd |
|
|
|
|
fcb1 equ 0x5C |
|
|
|
|
eof equ 0x1A |
|
|
|
|
dta equ 0x80 |
|
|
|
|
|
|
|
|
|
chr db ' ' ; input file next char |
|
|
|
|
|
|
|
|
|
; read next chr from inbuf |
|
|
|
|
nextc mov bx, [chrptr] |
|
|
|
|
cmp bx, 0x80 |
|
|
|
|
jc .getit |
|
|
|
|
; load new sector into dta |
|
|
|
|
mov ah, 0x14 |
|
|
|
|
mov dx, fcb1 |
|
|
|
|
int 0x21 |
|
|
|
|
cmp al, 1 |
|
|
|
|
je .eof |
|
|
|
|
mov bx, 0 |
|
|
|
|
mov [chrptr], bx |
|
|
|
|
; we still have chars in dta |
|
|
|
|
.getit mov al, [dta+bx] |
|
|
|
|
cmp al, eof |
|
|
|
|
je .l03 |
|
|
|
|
cmp al, 0 |
|
|
|
|
jne .l03 |
|
|
|
|
.eof mov al, eof |
|
|
|
|
.l03 cmp al, eof |
|
|
|
|
je .ret |
|
|
|
|
cmp al, 0x0A |
|
|
|
|
jne .ok |
|
|
|
|
inc word [lfcnt] |
|
|
|
|
.ok inc word [chrptr] |
|
|
|
|
.ret xchg al, [chr] |
|
|
|
|
ret |
|
|
|
|
|
|
|
|
|
;; word and whitespace parsing |
|
|
|
|
|
|
|
|
|
inword db " ", 0 |
|
|
|
|
|
|
|
|
|
issep cmp al, ',' |
|
|
|
|
je .ret |
|
|
|
|
cmp al, ';' |
|
|
|
|
.ret ret |
|
|
|
|
|
|
|
|
|
isws cmp al, 0x20 |
|
|
|
|
je .ret |
|
|
|
|
cmp al, 0x09 |
|
|
|
|
.ret ret |
|
|
|
|
|
|
|
|
|
iseol cmp al, 0x0A |
|
|
|
|
je .ret |
|
|
|
|
cmp al, 0x0D |
|
|
|
|
.ret ret |
|
|
|
|
|
|
|
|
|
; read inword from infile |
|
|
|
|
readw mov di, inword |
|
|
|
|
lea cx, [di+6] |
|
|
|
|
.loop mov al, [chr] |
|
|
|
|
call issep |
|
|
|
|
je .fill |
|
|
|
|
call isws |
|
|
|
|
je .fill |
|
|
|
|
call iseol |
|
|
|
|
je .fill |
|
|
|
|
call nextc |
|
|
|
|
cmp di, cx |
|
|
|
|
jnc .loop |
|
|
|
|
stosb |
|
|
|
|
jmp .loop |
|
|
|
|
.fill cmp di, cx |
|
|
|
|
jnc .end |
|
|
|
|
mov al, 0x20 |
|
|
|
|
stosb |
|
|
|
|
jmp .fill |
|
|
|
|
.end jmp eatws |
|
|
|
|
|
|
|
|
|
; IN al ascii char |
|
|
|
|
; OUT al number |
|
|
|
|
; carry flag set if not digit |
|
|
|
|
prsdgt sub al, 0x30 |
|
|
|
|
jc .ret |
|
|
|
|
cmp al, 0x09 |
|
|
|
|
cmc |
|
|
|
|
.ret ret |
|
|
|
|
|
|
|
|
|
; parse integer from inword into DX |
|
|
|
|
prsint mov si, inword |
|
|
|
|
xor dx, dx |
|
|
|
|
mov bx, 0xA |
|
|
|
|
mov cx, 6 |
|
|
|
|
.loop lodsb |
|
|
|
|
cmp al, ' ' |
|
|
|
|
je .ret |
|
|
|
|
cmp al, 'x' |
|
|
|
|
jne .nox |
|
|
|
|
mov bx, 0x10 |
|
|
|
|
mov dx, 0 |
|
|
|
|
jmp .cont |
|
|
|
|
.nox call prsdgt |
|
|
|
|
jc .err |
|
|
|
|
xor ah, ah |
|
|
|
|
xchg ax, dx |
|
|
|
|
push dx |
|
|
|
|
mul bx |
|
|
|
|
test dx, dx |
|
|
|
|
jnz .err |
|
|
|
|
pop dx |
|
|
|
|
add dx, ax |
|
|
|
|
.cont loop .loop |
|
|
|
|
.ret ret |
|
|
|
|
.err call errmsg |
|
|
|
|
db "BADINT", 0 |
|
|
|
|
|
|
|
|
|
; eat space and tabs from inbuf |
|
|
|
|
eatws mov al, [chr] |
|
|
|
|
call isws |
|
|
|
|
jne .ret |
|
|
|
|
call nextc |
|
|
|
|
jmp eatws |
|
|
|
|
.ret ret |
|
|
|
|
|
|
|
|
|
%include "symbols.asm" |
|
|
|
|
|
|
|
|
|
i_cur dw 0 ; ptr to generator function |
|
|
|
|
i_offs dw 0 ; offset of current instr in binary |
|
|
|
|
|
|
|
|
|
; lookup in_str in opcode table |
|
|
|
|
i_lkup mov dx, [in_str] |
|
|
|
|
mov si, [in_str+2] |
|
|
|
|
mov di, [in_str+4] |
|
|
|
|
; lookup inword in opcode table |
|
|
|
|
i_lkup mov dx, [inword] |
|
|
|
|
mov si, [inword+2] |
|
|
|
|
mov di, [inword+4] |
|
|
|
|
mov bx, i_tab |
|
|
|
|
.loop call s_comp |
|
|
|
|
jz .found |
|
|
|
|
add bx, 8 |
|
|
|
|
cmp byte [bx], 0 |
|
|
|
|
jne .loop |
|
|
|
|
mov bp, i_err |
|
|
|
|
jmp error |
|
|
|
|
call errmsg |
|
|
|
|
db "BAD OPCODE", 0 |
|
|
|
|
.found mov ax, [bx+6] |
|
|
|
|
mov [i_cur], ax |
|
|
|
|
ret |
|
|
|
|
|
|
|
|
|
i_err db "BAD OPCODE", 0 |
|
|
|
|
|
|
|
|
|
i_tab db "equ " |
|
|
|
|
dw i_equ |
|
|
|
|
db "org " |
|
|
|
|
dw i_org |
|
|
|
|
db "jmp " |
|
|
|
|
dw i_jmp |
|
|
|
|
db "dw " |
|
|
|
|
dw i_dw |
|
|
|
|
db 0 |
|
|
|
|
|
|
|
|
|
i_equ ret |
|
|
|
|
|
|
|
|
|
i_org call rdint |
|
|
|
|
mov [o_org], dx |
|
|
|
|
i_org call readw |
|
|
|
|
call prsint |
|
|
|
|
mov [b_org], dx |
|
|
|
|
ret |
|
|
|
|
|
|
|
|
|
i_dw xor ax, ax |
|
|
|
|
mov [di], ax |
|
|
|
|
mov bx, di |
|
|
|
|
call wval |
|
|
|
|
add word [wptr], 2 |
|
|
|
|
mov al, [chr] |
|
|
|
|
cmp al, ',' |
|
|
|
|
jne .ret |
|
|
|
|
call nextc |
|
|
|
|
call eatws |
|
|
|
|
jmp i_dw |
|
|
|
|
.ret ret |
|
|
|
|
|
|
|
|
|
i_jmp mov bx, [i_offs] |
|
|
|
|
mov byte [output+bx], 0xE9 |
|
|
|
|
lea ax, [bx+3] |
|
|
|
@ -73,19 +277,18 @@ i_jmp mov bx, [i_offs]
|
|
|
|
|
; read word value (literal or symbol) |
|
|
|
|
; add it to [bx] now or when filling backrefs |
|
|
|
|
wval push bx |
|
|
|
|
mov di, in_str |
|
|
|
|
call rdwrd |
|
|
|
|
mov al, [in_str] |
|
|
|
|
call pdigit |
|
|
|
|
call readw |
|
|
|
|
mov al, [inword] |
|
|
|
|
call prsdgt |
|
|
|
|
jc .sym |
|
|
|
|
call psint |
|
|
|
|
call prsint |
|
|
|
|
pop bx |
|
|
|
|
add [bx], dx |
|
|
|
|
ret |
|
|
|
|
; try to find defined symbol |
|
|
|
|
.sym mov dx, [in_str] |
|
|
|
|
mov si, [in_str+2] |
|
|
|
|
mov di, [in_str+4] |
|
|
|
|
.sym mov dx, [inword] |
|
|
|
|
mov si, [inword+2] |
|
|
|
|
mov di, [inword+4] |
|
|
|
|
call s_get |
|
|
|
|
jc .bref |
|
|
|
|
pop bx |
|
|
|
@ -97,39 +300,88 @@ wval push bx
|
|
|
|
|
pop word [bx+6] |
|
|
|
|
ret |
|
|
|
|
|
|
|
|
|
lineno dw 0 |
|
|
|
|
|
|
|
|
|
main mov dx, fcb1 |
|
|
|
|
mov ah, 0xf |
|
|
|
|
int 0x21 |
|
|
|
|
; fail if al != 0 |
|
|
|
|
test al, al |
|
|
|
|
mov bp, e_open |
|
|
|
|
call errnz |
|
|
|
|
mloop call l_read |
|
|
|
|
mov di, in_str |
|
|
|
|
call rdwrd |
|
|
|
|
cmp byte [in_str], ' ' |
|
|
|
|
call ztoc |
|
|
|
|
cmc |
|
|
|
|
call errifc |
|
|
|
|
db "INFILE", 0 |
|
|
|
|
; read first char |
|
|
|
|
call nextc |
|
|
|
|
; handle eof specially |
|
|
|
|
mloop mov al, [chr] |
|
|
|
|
cmp al, 0x1A |
|
|
|
|
je final |
|
|
|
|
; snapshot current line number |
|
|
|
|
mov ax, [lfcnt] |
|
|
|
|
mov [lineno], ax |
|
|
|
|
; read label string |
|
|
|
|
call readw |
|
|
|
|
; push label string to stack |
|
|
|
|
push word [inword] |
|
|
|
|
push word [inword+2] |
|
|
|
|
push word [inword+4] |
|
|
|
|
; read op name |
|
|
|
|
call readw |
|
|
|
|
mov al, [inword] |
|
|
|
|
cmp al, ' ' |
|
|
|
|
je .eol |
|
|
|
|
cmp al, ';' |
|
|
|
|
je .cmt |
|
|
|
|
; loop up addr of instr generator |
|
|
|
|
call i_lkup |
|
|
|
|
mov bx, [i_cur] |
|
|
|
|
; restore label string from stack |
|
|
|
|
pop word [inword+4] |
|
|
|
|
pop word [inword+2] |
|
|
|
|
pop word [inword] |
|
|
|
|
; handle instruction generator |
|
|
|
|
mov di, [wptr] |
|
|
|
|
call bx |
|
|
|
|
; eat leftovers at end of line |
|
|
|
|
; look what leftovers we got |
|
|
|
|
call eatws |
|
|
|
|
.eol call fpeek |
|
|
|
|
mov bp, e_extr |
|
|
|
|
.eol mov al, [chr] |
|
|
|
|
cmp al, ';' |
|
|
|
|
je .cmt ; a comment |
|
|
|
|
cmp al, eof |
|
|
|
|
je final ; end of file |
|
|
|
|
call iseol |
|
|
|
|
call errnz |
|
|
|
|
call fgetc |
|
|
|
|
jne .err ; characters! bad! |
|
|
|
|
call nextc |
|
|
|
|
; eat CR and LF until next line |
|
|
|
|
.eatnl call fpeek |
|
|
|
|
.eatnl mov al, [chr] |
|
|
|
|
call iseol |
|
|
|
|
jne mloop |
|
|
|
|
call fgetc |
|
|
|
|
call nextc |
|
|
|
|
jmp .eatnl |
|
|
|
|
ret |
|
|
|
|
|
|
|
|
|
e_extr db "EXTRA DATA", 0 |
|
|
|
|
; eat comment txt until eol |
|
|
|
|
.cmt mov al, [chr] |
|
|
|
|
call iseol |
|
|
|
|
je .eatnl |
|
|
|
|
call nextc |
|
|
|
|
jmp .cmt |
|
|
|
|
; complain about extra shit on line |
|
|
|
|
.err call errmsg |
|
|
|
|
db "EXTRA DATA", 0 |
|
|
|
|
|
|
|
|
|
e_open db "INFILE", 0 |
|
|
|
|
final nop |
|
|
|
|
; close |
|
|
|
|
call putsh |
|
|
|
|
db "BYTES: ", 0 |
|
|
|
|
mov bx, 0x0A |
|
|
|
|
mov cx, 1 |
|
|
|
|
mov ax, [wptr] |
|
|
|
|
sub ax, output |
|
|
|
|
call putnum |
|
|
|
|
call newlin |
|
|
|
|
call errmsg |
|
|
|
|
db "EOF", 0 |
|
|
|
|
|
|
|
|
|
o_org dw 0 ; offset of whole file |
|
|
|
|
wptr dw output ; how far we've written |
|
|
|
|
b_org dw 0 ; offset of binary start |
|
|
|
|
output db 0 |
|
|
|
|