org 0x100 jmp init fcb1 equ 0x5C eof equ 0x1A stack equ 0x10 ; stack size 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 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 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 ;getc2 call peek ; cmp al, eof ; jne getc_ ; inc word [rdptr] ;getc_ ret newlin mov dl, 0x0A mov ah, 2 int 0x21 mov dl, 0x0D int 0x21 ret 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 e_eof db "EOF " e_dup db "DUPSYM " ; 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 "