Add skeleton of assembler

This commit is contained in:
Nero 2021-04-20 21:23:40 +00:00
parent 24f04792f6
commit 1dea0c40bc

View File

@ -1,34 +1,25 @@
org 0x100 org 0x100
mov ax, 0x3D00 jmp init
mov dx, infile
int 0x21
jc err
mov [fd], ax fcb1 equ 0x5C
eof equ 0x1A
stack equ 0x10 ; stack size
call getline dumpax push ax
push cx
mov dx, [line_length] push dx
call dumpdx mov dx, ax
call dmpdx0
mov si, line_buffer mov al, 0x0A
mov cx, [line_length] call dmpdx3
mov ah, 2 mov al, 0x0D
l03: lodsb call dmpdx3
mov dl, al pop dx
int 0x21 pop cx
loop l03 pop ax
ret
end: ret dmpdx0 mov ah, 0xe
line_num: dw 1
err: mov dx, ax
dumpdx: ; setup bx and ah for int 10h call
xor bx, bx
mov ah, 0x0e
mov cl, 4 mov cl, 4
; this double-call is essentially a 4 times repeating loop ; this double-call is essentially a 4 times repeating loop
call dmpdx1 call dmpdx1
@ -49,40 +40,228 @@ dmpdx2: ; grab highest nibble from dx
dmpdx3: int 0x10 dmpdx3: int 0x10
ret ret
; read a character from the input file into DL free dw 0 ; free ram size
getc: mov dl, 26 lncnt dw 0 ; line count
push dx rdptr dw 0xFFFF ; infile blk ptr
mov ah, 0x3f symbol dw 0 ; symbol of current line
mov bx, [fd] offset dw 0 ; byte offset in outfile
mov cx, 1 len db 0 ; len for wrd (must be before it)
mov dx, sp wrd dw 0,0,0,0,0,0,0,0 ; 16 byte word buf
getc mov bx, [rdptr]
cmp bx, 0x80
jc l01
mov ah, 0x14
mov dx, fcb1
int 0x21 int 0x21
pop dx cmp al, 1
je l02
mov bx, 0
l01 mov al, [0x80+bx]
cmp al, eof
je l02
cmp al, 0
je l02
cmp al, 0x0A
jne l01b
inc word [lncnt]
l01b inc bx
mov [rdptr], bx
jmp l03
l02 mov al, 0x1A
l03 cmp al, eof
ret ret
getline: mov word [line_length], 0 ;getc2 call peek
mov di, line_buffer ; cmp al, eof
mov cx, line_buflen ; jne getc_
l02: push cx ; inc word [rdptr]
call getc ;getc_ ret
pop cx
mov al, dl
cmp al, 0x0A
je l01
cmp al, 0x0D
je l01
cmp al, 0x1A
je l01
inc word [line_length]
loop l02
l01: ret newlin mov dl, 0x0A
mov ah, 2
int 0x21
mov dl, 0x0D
int 0x21
ret
infile: db "com/a86.asm", 0 error mov dl, [bx]
mov ah, 2
int 0x21
inc bx
cmp dl, 0x20
jne error
mov ax, [lncnt]
call dumpax
call newlin
int 0x20
line_buflen: equ 0x100 e_eof db "EOF "
line_length: dw 0 ; valid bytes in buffer e_dup db "DUPSYM "
line_prefix: times 16 db " "
line_buffer: times line_buflen db 0
fd: dw 0 ; scan word
scawrd mov si, wrd
l04 call getc
; EOF is fatal
mov bx, e_eof
jz error
; tab=end
cmp al, 9
je pad
; space=end
cmp al, 0x20
je pad
; if lbl full, continue eating
cmp si, wrd+0x10
jnc l04
; insert
mov [si], al
inc si
jmp l04
; pad with spaces
pad mov cx, si
sub cx, wrd
mov [len], cl
cmp si, wrd+0x10
jnc l06
mov ah, 0x20
xchg ah, [si]
inc si
cmp ah, 0x20
jne pad
l06 ret
; print wrd
dmpwrd mov si, wrd
mov cx, 0x10
mov ah, 2
l05 mov dl, [si]
cmp dl, 0x20
je l07
inc si
int 0x21
loop l05
l07 call newlin
ret
; create symbol table entry
; name is read from [wrd]
; offset is written to [symbol]
symins cmp byte [wrd], 0x20
je nosym
mov bx, init ; walk ptr
mov bp, [free]
add bp, bx ; end addr
jmp l09
l08 add bx, 8
l09 mov al, [bx]
cmp al, 0
je l10
call symcmp
jnz l08
mov bx, e_dup
jmp error
; copy str to table
l10 mov si, wrd
mov di, bx
movsw
movsw
movsw
xor ax, ax
stosw
mov byte [bx+8], 0
mov [symbol], bx
ret
nosym xor ax, ax
mov [symbol], ax
ret
; compares 6 bytes [bx] with [wrd]
; bit 7 of each byte is ignored
symcmp mov si, wrd
xor ax, ax
mov dx, [wrd]
xor dx, [bx]
or ax, dx
mov dx, [wrd+2]
xor dx, [bx+2]
or ax, dx
mov dx, [wrd+4]
xor dx, [bx+4]
or ax, dx
test ax, 0x8F8F
ret
; look up keyword in wrd
; result is stored in bx
lookup mov ch, 0
mov bx, s_org
l11 mov si, bx
mov di, len ; wrd immediately follows
mov cl, [bx]
test cx, cx
jz l13
inc cl
mov dx, cx
rep cmpsb
je l12
add bx, dx
jmp l11
; found!
l12 clc
ret
; give up
l13 xor bx, bx
stc
ret
s_org db 3, "org"
s_equ db 3, "equ"
db 0
; clear symbol table
main mov byte [init], 0
; scan and create label
mloop call scawrd
call symins
; scan instruction word
call scawrd
call lookup
; special stuff
cmp bx, s_org
je iorg
mov ax, bx
call dumpax
int 0x20
; org pseudo instruction
iorg mov ax, 0x5A5A
call dumpax
int 0x20
align 16
; stuff behind here gets overwritten
; by symbol table and program data
init mov ax, [6]
mov dx, sp
sub dx, stack
cmp ax, dx
jc il01
mov ax, dx
il01 sub ax, init
shr ax, 1
and ax, 0xFFF0
mov [free], ax
; open input file
mov ah, 0x0F
mov dx, fcb1
int 0x21
mov bx, e_op
test al, al
jnz error
jmp main
e_op db "NOFILE "