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 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
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] free dw 0 ; free ram size
call dumpdx 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 getc mov bx, [rdptr]
mov cx, [line_length] cmp bx, 0x80
mov ah, 2 jc l01
l03: lodsb mov ah, 0x14
mov dl, al mov dx, fcb1
int 0x21 int 0x21
loop l03 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 e_eof db "EOF "
xor bx, bx e_dup db "DUPSYM "
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
; read a character from the input file into DL ; scan word
getc: mov dl, 26 scawrd mov si, wrd
push dx l04 call getc
mov ah, 0x3f ; EOF is fatal
mov bx, [fd] mov bx, e_eof
mov cx, 1 jz error
mov dx, sp ; tab=end
int 0x21 cmp al, 9
pop dx je pad
ret ; 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 ; print wrd
mov di, line_buffer dmpwrd mov si, wrd
mov cx, line_buflen mov cx, 0x10
l02: push cx mov ah, 2
call getc l05 mov dl, [si]
pop cx cmp dl, 0x20
mov al, dl je l07
cmp al, 0x0A inc si
je l01 int 0x21
cmp al, 0x0D loop l05
je l01 l07 call newlin
cmp al, 0x1A ret
je l01
inc word [line_length]
loop l02
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 ; compares 6 bytes [bx] with [wrd]
line_length: dw 0 ; valid bytes in buffer ; bit 7 of each byte is ignored
line_prefix: times 16 db " " symcmp mov si, wrd
line_buffer: times line_buflen db 0 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 "