Add skeleton of assembler

This commit is contained in:
Nero 2021-04-20 21:23:40 +00:00
parent 24f04792f6
commit 1dea0c40bc
1 changed files with 252 additions and 73 deletions

View File

@ -1,88 +1,267 @@
org 0x100
org 0x100
mov ax, 0x3D00
mov dx, infile
int 0x21
jc err
jmp init
mov [fd], ax
fcb1 equ 0x5C
eof equ 0x1A
stack equ 0x10 ; stack size
call getline
dumpax push ax
push cx
push dx
mov dx, ax
call dmpdx0
mov al, 0x0A
call dmpdx3
mov al, 0x0D
call dmpdx3
pop dx
pop cx
pop ax
ret
dmpdx0 mov ah, 0xe
mov cl, 4
; this double-call is essentially a 4 times repeating loop
call dmpdx1
dmpdx1: call dmpdx2
dmpdx2: ; grab highest nibble from dx
mov al, dh
; remove highest nibble from dx
shl dx, cl
; shift away second-highest nibble that we accidentally copied
shr al, cl
; map 0-9 to ascii codes for '0' to '9'
add al, 0x30
; if result is larger than '9', ...
cmp al, 0x3a
jl dmpdx3
; ... add 7 so we continue at 'A'
add al, 7
dmpdx3: int 0x10
ret
mov dx, [line_length]
call dumpdx
free dw 0 ; free ram size
lncnt dw 0 ; line count
rdptr dw 0xFFFF ; infile blk ptr
symbol dw 0 ; symbol of current line
offset dw 0 ; byte offset in outfile
len db 0 ; len for wrd (must be before it)
wrd dw 0,0,0,0,0,0,0,0 ; 16 byte word buf
mov si, line_buffer
mov cx, [line_length]
mov ah, 2
l03: lodsb
mov dl, al
int 0x21
loop l03
getc mov bx, [rdptr]
cmp bx, 0x80
jc l01
mov ah, 0x14
mov dx, fcb1
int 0x21
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
end: ret
;getc2 call peek
; cmp al, eof
; jne getc_
; inc word [rdptr]
;getc_ ret
line_num: dw 1
newlin mov dl, 0x0A
mov ah, 2
int 0x21
mov dl, 0x0D
int 0x21
ret
err: mov dx, ax
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
dumpdx: ; setup bx and ah for int 10h call
xor bx, bx
mov ah, 0x0e
mov cl, 4
; this double-call is essentially a 4 times repeating loop
call dmpdx1
dmpdx1: call dmpdx2
dmpdx2: ; grab highest nibble from dx
mov al, dh
; remove highest nibble from dx
shl dx, cl
; shift away second-highest nibble that we accidentally copied
shr al, cl
; map 0-9 to ascii codes for '0' to '9'
add al, 0x30
; if result is larger than '9', ...
cmp al, 0x3a
jl dmpdx3
; ... add 7 so we continue at 'A'
add al, 7
dmpdx3: int 0x10
ret
e_eof db "EOF "
e_dup db "DUPSYM "
; read a character from the input file into DL
getc: mov dl, 26
push dx
mov ah, 0x3f
mov bx, [fd]
mov cx, 1
mov dx, sp
int 0x21
pop dx
ret
; 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
getline: mov word [line_length], 0
mov di, line_buffer
mov cx, line_buflen
l02: push cx
call getc
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
; 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
l01: 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
infile: db "com/a86.asm", 0
nosym xor ax, ax
mov [symbol], ax
ret
line_buflen: equ 0x100
line_length: dw 0 ; valid bytes in buffer
line_prefix: times 16 db " "
line_buffer: times line_buflen db 0
; 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
fd: dw 0
; 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 "