X-Assembler 1.5.

This commit is contained in:
Piotr Fusik 1998-09-06 18:05:14 +02:00
parent ed65c4f163
commit 8acc5c528f
1 changed files with 378 additions and 189 deletions

567
xasm.asm
View File

@ -31,42 +31,68 @@ val dw ?
nam db ?
ENDS
STRUC movt
cod db ?
vec dw ?
ENDS
m_pass = 80h
m_eofl = 40h
eol equ 13,10
eot equ 13,10,'$'
MACRO lda _rg
xchg ax, _rg ;shorter than 'mov ax, _rg'
ENDM
MACRO sta _rg
xchg _rg, ax ;shorter than 'mov _rg, ax'
ENDM
MACRO dos _func
IFNB <_func>
IF _func and 0ff00h
IFNB <_func>
IF _func and 0ff00h
mov ax, _func
ELSE
ELSE
mov ah, _func
ENDIF
ENDIF
ENDIF
ENDIF
int 21h
ENDM
MACRO file _func, _errtx
mov bp, offset _errtx
IF _func and 0ff00h
IF _func and 0ff00h
mov ax, _func
ELSE
ELSE
mov ah, _func
ENDIF
ENDIF
call xdisk
ENDM
MACRO print _text
IFNB <_text>
IFNB <_text>
mov dx, offset _text
ENDIF
ENDIF
dos 9
ENDM
MACRO error _err
push offset _err
jmp errln
ENDM
MACRO jpass1 _dest
test [flags], m_pass
jz _dest
ENDM
MACRO jpass2 _dest
test [flags], m_pass
jnz _dest
ENDM
MACRO cmd _oper
_tp SUBSTR <_oper>, 4, 2
_tp CATSTR <0>, &_tp, <h>
@ -116,7 +142,7 @@ adex2: mov [byte di-1], '.'
stosd
lvex2: call fopen
main: test [eoflag], 0ffh
main: test [flags], m_eofl
jnz filend
mov bx, [iclen]
mov bx, [(icl bx).prev]
@ -136,7 +162,7 @@ gline1: cmp di, offset line+255
jne gline1
jmp syntax
eof: inc [eoflag]
eof: or [flags], m_eofl
mov [word di], 0a0dh
syntax: mov si, offset line
@ -161,8 +187,7 @@ syntax: mov si, offset line
mov [pslaben], bx
inc [labvec] ;1
jmp s_cmd
ltwice: mov ax, offset e_twice
jmp panica
ltwice: error e_twice
asilab: push si
mov si, offset tlabel
mov di, [laben]
@ -220,17 +245,15 @@ sfcmd3: shr bx, 1
ja sfcmd1
mov bl, 0
je sfcmd1
mov ax, offset e_inst
jmp panica
error e_inst
filend: mov [eoflag], 0
filend: and [flags], not m_eofl
call fclose
cmp bx, offset t_icl
ja main
cmp [pass], 1
jnb fin
jpass2 fin
inc [pass]
or [flags], m_pass
call putorg
call ldname
mov si, di
@ -268,50 +291,73 @@ fin: mov bx, [ohand]
mov eax, [bytes]
call pridec
print byttxt
dos 4c00h
mov ax, [exitcod]
dos
tmlab: mov ax, offset e_tlab
jmp panica
tmlab: error e_tlab
linlon: mov ax, offset e_long
; Obsluga bledow
panica: mov [errad], ax
panic: cmp [errad], offset lislin
jb panifn
mov si, offset line-1
prilin: inc si
mov dl, [si]
dos 2
cmp [byte si], 0ah
jne prilin
panifn: mov bx, [iclen]
linlon: push offset e_long
jmp erron
; ERROR
errln: call ppline
erron: call prname
print errtxt
pop si
call prline
dos 4c02h
; WARNING
warln: call ppline
waron: call prname
print wartxt
pop ax
pop si
push ax
mov [byte exitcod], 1
jmp prline
prname: mov bx, [iclen]
cmp bx, offset t_icl
jna eronly
jna prnamx
mov di, [(icl bx).prev]
push di
lea dx, [(icl di).nam]
mov [byte bx-1], ' '
mov [word bx], '$('
mov [byte bx-1], '$'
print
mov dl, ' '
dos 2
mov dl, '('
dos 2
pop bx
mov eax, [(icl bx).line]
call pridec
mov dl, ')'
dos 2
eronly: print errtxt
mov dx, [errad]
print
dos 4c02h
mov dl, ' '
dos 2
prnamx: ret
; I/O
xdisk: mov [errad], bp
dos
jc panic
ppline: mov si, offset line
prline: mov dl, [si]
dos 2
inc si
cmp [byte si-1], 0ah
jne prline
ret
fopen: mov ax, offset e_icl
cmp di, offset t_icl+l_icl-2
jnb panica
; I/O
xdisk: push bp
dos
jc erron
pop bp
ret
icler: push offset e_icl
jmp erron
fopen: cmp di, offset t_icl+l_icl-2
jnb icler
mov bx, [iclen]
mov [(icl bx).line], 0
lea dx, [(icl bx).nam]
@ -344,8 +390,7 @@ putwor: push ax
pop ax
mov al, ah
putbyt: mov cx, 1
cmp [pass], cl
jb putx
jpass1 putx
mov [oper], al
mov dx, offset oper
mov bx, [ohand]
@ -384,16 +429,30 @@ pride1: cdq
print
ret
; Zapisuje hex AX od [DI]
phword: push ax
mov al, ah
call phbyte
pop ax
phbyte: push ax
shr al, 4
call phdig
pop ax
and al, 0fh
phdig: cmp al, 10
sbb al, 69h
das
stosb
ret
; Pobiera znak (eol=error)
get: lodsb
cmp al, 0dh
je uneol
ret
uneol: mov ax, offset e_uneol
jmp panica
uneol: error e_uneol
ilchar: mov ax, offset e_char
jmp panica
ilchar: error e_char
; Omija spacje i tabulatory
spaces: call get
@ -401,8 +460,7 @@ spaces: call get
je space1
cmp al, 9
je space1
mov ax, offset e_spac
jmp panica
error e_spac
space1: call get
cmp al, ' '
je space1
@ -419,8 +477,7 @@ linend: lodsb
je rstret
cmp al, 9
je rstret
mov ax, offset e_xtra
jmp panica
error e_xtra
; Czyta nazwe pliku
rfname: call spaces
@ -444,8 +501,7 @@ rstr1: call get
sub cx, dx
jnz rstret
strer: mov ax, offset e_str
jmp panica
strer: error e_str
; Przepisuje etykiete do tlabel, szuka w t_lab
; na wyjsciu: dx-dlugosc etykiety
@ -498,7 +554,7 @@ getval: call spaces
; Czyta wyrazenie i zwraca jego wartosc w [val]
; (C=1 wartosc nieokreslona w pass 1)
value: mov [val], 0
mov [undef], 0
mov [ukp1], 0
lodsb
cmp al, '-'
je valuem
@ -506,15 +562,15 @@ value: mov [val], 0
mov al, '+'
valuem: mov [oper], al
xor dx, dx
mov ch, -1
call get
cmp al, '*'
je valorg
xor dx, dx
cmp al, "'"
je valchr
cmp al, '^'
je valreg
mov ch, -1
mov bx, 16
cmp al, '$'
je rdnum3
@ -527,8 +583,8 @@ valuem: mov [oper], al
cmp al, '9'
ja vlabel
rdnum1: cmp al, 'A'
jb rdnum2
rdnum1: cmp al, '9'
jbe rdnum2
and al, 0dfh
cmp al, 'A'
jb value0
@ -549,13 +605,12 @@ rdnum3: lodsb
vlabel: dec si
call rlabel
jnc vlabkn
cmp [pass], 1
jb vlabun
jpass1 vlabun
jmp unknow
vlabkn: mov dx, [(lab bx).val]
cmp bx, [pslaben]
jbe value1
vlabun: mov [undef], 0ffh
vlabun: mov [ukp1], 0ffh
jmp value1
valchr: call get
@ -564,7 +619,7 @@ valchr: call get
lodsb
cmp al, "'"
jne strer
valch1: movzx dx, al
valch1: mov dl, al
lodsb
cmp al, "'"
jne strer
@ -582,11 +637,11 @@ valreg: call get
add al, 0d0h
mov ah, al
call get
cmp al, 'A'
jb valre1
cmp al, '9'
jbe valre1
and al, 0dfh
cmp al, 'A'
jb valre1
jb ilchar
add al, '0'+10-'A'
valre1: sub al, '0'
cmp al, 0fh
@ -614,23 +669,22 @@ value2: add [val], dx
cmp al, '-'
je valuem
dec si
add [undef], 1
mov al, 1
cmp al, [ukp1]
ret
toobig: mov ax, offset e_nbig
jmp panica
toobig: error e_nbig
; Pobiera operand rozkazu i rozpoznaje tryb adresowania
getadr: call spaces
lodsb
xor dl, dl
xor dx, dx
cmp al, '@'
je getadx
push 0ffh
inc dx
cmp al, '#'
je getad1
mov dl, 10
mov dl, 4
cmp al, '<'
je getad1
inc dx
@ -642,45 +696,56 @@ getadr: call spaces
dec si
lodsw
and al, 0dfh
xor dx, dx
cmp ax, ':Z'
je getad0
dec dx
mov dl, 2
cmp ax, ':A'
je getad0
je getad1
inc dx
cmp ax, ':Z'
je getad1
dec si
dec si
jmp getad9
getad0: pop ax
push dx
getad9: mov dl, 2
xor dx, dx
getad1: mov [amod], dl
getad1: push dx
call value
mov al, [byte high val]
jnc getad2
sbb al, al
jnz getad2
mov al, [byte high val]
getad2: pop dx
and al, dl
or al, dh
mov dl, [amod]
cmp dl, 1
je getart
cmp dl, 10
jnb getalh
cmp dl, 8
je getaid
jae getaid
cmp dl, 4
jae getalh
cmp dl, 1
je getadx
ja getad3
cmp al, 1
adc dl, 0
lodsw
adc dl, 2
getad3: lodsw
and ah, 0dfh
mov bl, 2
cmp ax, 'X,'
je getaxi
je getabi
mov bl, 4
cmp ax, 'Y,'
je getayi
je getabi
dec si
dec si
jmp getadx
getabi: add dl, bl
getaxt: lodsb
cmp al, '+'
je getabx
inc bx
cmp al, '-'
je getabx
dec si
jmp getadx
getabx: mov dh, bl
getadx: lda dx
mov [word amod], ax
ret
getalh: mov bx, offset val
je getal1
inc bx
@ -688,31 +753,34 @@ getal1: movzx ax, [bx]
mov [val], ax
mov dl, 1
jmp getadx
getaid: lodsb
cmp al, ','
je getaix
cmp al, ')'
jne mbrack
lodsw
mov dx, 709h
cmp ax, '0,'
je getadx
xor dh, dh
mov bl, 4
and ah, 0dfh
cmp ax, 'Y,'
je getaiy
mov dl, 10
je getaxt
inc dx
dec si
dec si
jmp getadx
getaix: lodsw
mov dh, 6
cmp ax, ')0'
je getadx
xor dh, dh
and al, 0dfh
cmp ax, ')X'
je getart
je getadx
jmp ilchar
getayi: inc dx
inc dx
getaxi: inc dx
getaiy: inc dx
getadx: mov [amod], dl
getart: mov al, [amod]
putret: ret
p_imp = savbyt
@ -724,23 +792,28 @@ p_ads: call getadr
je p_as1
mov al, 0e0h
p_as1: mov [cod], al
mov al, [amod]
jmp p_ac1
p_acc: call getadr
p_ac1: cmp al, 7
p_ac1: mov ax, [word amod]
cmp al, 7
jne acc1
dec ax
mov [amod], al
acc1: mov bx, offset acctab
dec [amod]
acc1: cmp ah, 6
jb acc3
mov ax, 0a2h
je acc2
mov al, 0a0h
acc2: call savwor
acc3: mov al, [amod]
mov bx, offset acctab
xlat
test al, al
jz ilamod
or al, [cod]
cmp al, 89h
jne putcmd
ilamod: mov ax, offset e_amod
jmp panica
jne putsfx
ilamod: error e_amod
p_srt: call getadr
cmp al, 6
@ -754,7 +827,13 @@ p_srt: call getadr
je ilamod
cmp al, 0e0h
je ilamod
jmp putcmd
putsfx: call putcmd
mov al, [amod+1]
mov bx, offset sfxtab
xlat
test al, al
jnz savbyt
putret: ret
p_inw: call getadr
cmp al, 6
@ -772,9 +851,10 @@ p_inw: call getadr
dec ah
p_iw1: call savwor
pop ax
jmp putcmd
jmp putsfx
p_ldi: call getadr
p_ld1: mov al, [amod]
cmp al, 1
jb ilamod
cmp al, 4
@ -787,6 +867,8 @@ p_ldi: call getadr
ldi1: mov bx, offset lditab
xlat
putcod: or al, [cod]
jmp putsfx
putcmd: call savbyt
mov al, [amod]
mov bx, offset lentab
@ -795,17 +877,17 @@ putcmd: call savbyt
jb putret
mov ax, [val]
jne savwor
cmp [pass], 1
jb putcm1
jpass1 putcm1
test ah, ah
jnz toobig
putcm1: jmp savbyt
p_sti: call getadr
p_st1: mov al, [amod]
cmp al, 2
jb ilamod
je cod8
cmp al, 3
jb cod8
je cod0
and al, 0feh
xor al, [cod]
@ -831,8 +913,7 @@ p_cpi: call getadr
jmp putcod
p_bra: call getadr
cmp [pass], 1
jb bra1
jpass1 bra1
mov ax, [val]
sub ax, [origin]
add ax, 7eh
@ -845,8 +926,14 @@ bra1: call savbyt
mov al, [byte val]
jmp savbyt
toofar: mov ax, offset e_bra
jmp panica
toofar: cmp ax, 8080h
jae toofa1
sub ax, 0ffh
neg ax
toofa1: neg ax
mov di, offset brange
call phword
error e_bra
p_jsr: call getadr
mov al, 20h
@ -868,17 +955,111 @@ p_juc: call getadr
jmp p_jp1
p_jmp: call getadr
p_jp1: mov al, 6ch
cmp [amod], 10
je putcmd
mov al, 4ch
p_jp1: cmp [amod], 10
je chkbug
jpass1 p_jpu
cmp [cod], 4ch
je p_jpu
mov ax, [val]
sub ax, [origin]
add ax, 80h
test ah, ah
jnz p_jpu
push si
push offset w_bras
call warln
pop si
p_jpu: mov al, 4ch
p_abs: and [amod], 0feh
cmp [amod], 2
jne ilamod
jmp putcmd
je p_jpp
jmp ilamod
chkbug: jpass1 p_jid
cmp [byte val], 0ffh
jne p_jid
push si
push offset w_bugjp
call warln
pop si
p_jid: mov al, 6ch
p_jpp: jmp putcmd
p_opt: mov ax, offset e_opt
jmp panica
getops: call getadr
mov di, offset op1
call stop
push [word ukp1]
call getadr
pop [word ukp1]
mov [tempsi], si
mov di, offset op2
call stop
movzx bx, [cod]
add bx, offset movtab
ldop1: mov si, offset op1
ldop: lodsw
mov [val], ax
lodsw
mov [word amod], ax
ret
stop: mov ax, [val]
stosw
mov ax, [word amod]
stosw
ret
mcall1: mov al, [(movt bx).cod]
mov [cod], al
push bx
call [(movt bx).vec]
pop bx
ret
mcall2: mov al, [(movt bx+3).cod]
mov [cod], al
push bx
call [(movt bx+3).vec]
pop bx
ret
p_mvs: call getops
call mcall1
mov si, offset op2
call ldop
p_mvx: call mcall2
mov si, [tempsi]
ret
p_mws: call getops
mov ax, [word amod]
cmp ax, 8
jae ilamod
cmp al, 1
jne p_mw1
mov [byte high val], 0
p_mw1: call mcall1
mov si, offset op2
call ldop
cmp [word amod], 8
jae ilamod
call mcall2
call ldop1
cmp [amod], 1
je p_mwi
inc [val]
jmp p_mw2
p_mwi: movzx ax, [byte high val]
cmp [ukp1], ah ;0
jnz p_mwh
cmp al, [byte val]
je p_mw3
p_mwh: mov [val], ax
p_mw2: call mcall1
p_mw3: mov si, offset op2
call ldop
inc [val]
jmp p_mvx
p_opt: error e_opt
p_equ: mov di, [labvec]
cmp di, 1
@ -888,8 +1069,7 @@ p_equ: mov di, [labvec]
call getval
mov di, [labvec]
jnc equ1
cmp [pass], 1
jb lbund
jpass1 lbund
equ1: mov ax, [val]
stosw
equret: ret
@ -898,13 +1078,11 @@ lbund: lea ax, [di-2]
mov [laben], ax
ret
nolabl: mov ax, offset e_label
jmp panica
nolabl: error e_label
p_org: call getval
jc unknow
p_org1: cmp [pass], 1
jnb org1
p_org1: jpass2 org1
call putorg
stc
org1: mov ax, [val]
@ -928,8 +1106,7 @@ putorg: mov bx, [orgvec]
mov [bx], ax
ret
tmorgs: mov ax, offset e_orgs
jmp panica
tmorgs: error e_orgs
p_rui: mov ah, 2
mov [val], ax
@ -945,8 +1122,7 @@ valuco: call value
jne badsin
mov ax, [val]
ret
badsin: mov ax, offset e_sin
jmp panica
badsin: error e_sin
p_dta: call spaces
dta1: call get
@ -1014,19 +1190,18 @@ presin: finit
faddp st(1), st
fidiv [sinsiz]
gensin: fild [sinmin]
inc [sinmin]
fmul st, st(1)
fsin
fimul [sinamp]
fistp [val]
inc [sinmin]
mov ax, [sinadd]
add [val], ax
jmp dtasto
dtansi: sub si, 4
call value
dtasto: cmp [pass], 1
jb dtan3
dtasto: jpass1 dtan3
mov al, [cod]
cmp al, 'B'
je dtanb
@ -1063,11 +1238,9 @@ dtanx: mov ax, [sinmin]
cmp al, ')'
je dtanxt
mbrack: mov ax, offset e_brack
jmp panica
mbrack: error e_brack
unknow: mov ax, offset e_uknow
jmp panica
unknow: error e_uknow
dtat1: mov di, offset tlabel
call rstr
@ -1118,8 +1291,7 @@ p_in1: mov cx, 256
mov bx, [iclen]
mov bx, [(icl bx).prev]
add [(icl bx).line], eax
cmp [pass], 1
jb p_in1
jpass1 p_in1
add [bytes], eax
sta cx
mov bx, [ohand]
@ -1141,6 +1313,12 @@ acctab db 0,9,0dh,5,1dh,15h,19h,19h,1,11h,0
srttab db 0ah,0,0eh,6,1eh,16h
lditab db 0,0,0ch,4,1ch,14h,1ch,14h
inwtab db 0eeh,0e6h,0feh,0f6h
; pseudo-adr modes: 2-X+ 3-X- 4-Y+ 5-Y- 6-,0) 7-),0
sfxtab db 0,0,0e8h,0cah,0c8h,088h,0,0
movtab movt <0a0h,p_ac1>,<080h,p_ac1>
movt <0a2h,p_ld1>,<086h,p_st1>
movt <0a0h,p_ld1>,<084h,p_st1>
comtab: cmd ADC60p_acc
cmd ADD18p_ads
@ -1191,6 +1369,12 @@ comtab: cmd ADC60p_acc
cmd LDXa2p_ldi
cmd LDYa0p_ldi
cmd LSR40p_srt
cmd MVA00p_mvs
cmd MVX06p_mvs
cmd MVY0cp_mvs
cmd MWA00p_mws
cmd MWX06p_mws
cmd MWY0cp_mws
cmd NOPeap_imp
cmd OPT00p_opt
cmd ORA00p_acc
@ -1220,39 +1404,43 @@ comtab: cmd ADC60p_acc
cmd TYA98p_imp
comend:
hello db 'X-Assembler 1.4 by Fox/Taquart',eot
hello db 'X-Assembler 1.5 by Fox/Taquart',eot
usgtxt db 'Give a source filename. Default extension is .ASX.',eol
db 'Object file will be written with .COM extension.',eot
lintxt db ' lines assembled',eot
byttxt db ' bytes written',eot
dectxt db 10 dup(' '),'$'
errtxt db ' ERROR: $'
e_open db 'Can''t open file',eot
e_read db 'Disk read error',eot
e_creat db 'Can''t write destination',eot
e_writ db 'Disk write error',eot
e_icl db 'Too many files nested',eot
e_long db 'Line too long',eot
lislin:
e_uneol db 'Unexpected eol',eot
e_char db 'Illegal character',eot
e_twice db 'Label declared twice',eot
e_inst db 'Illegal instruction',eot
e_nbig db 'Number too big',eot
e_uknow db 'Unknown value',eot
e_xtra db 'Extra characters on line',eot
e_label db 'Label name required',eot
e_str db 'String error',eot
e_orgs db 'Too many ORGs',eot
e_brack db 'Need parenthesis',eot
e_tlab db 'Too many labels',eot
e_amod db 'Illegal adressing mode',eot
e_bra db 'Branch too far',eot
e_sin db 'Bad or missing sinus parameter',eot
e_spac db 'Space expected',eot
e_opt db 'OPT directive not supported',eot
wartxt db 'WARNING: $'
w_bugjp db 'Buggy indirect jump',eol
w_bras db 'Branch would be sufficient',eol
errtxt db 'ERROR: $'
e_open db 'Can''t open file',eol
e_read db 'Disk read error',eol
e_creat db 'Can''t write destination',eol
e_writ db 'Disk write error',eol
e_icl db 'Too many files nested',eol
e_long db 'Line too long',eol
e_uneol db 'Unexpected eol',eol
e_char db 'Illegal character',eol
e_twice db 'Label declared twice',eol
e_inst db 'Illegal instruction',eol
e_nbig db 'Number too big',eol
e_uknow db 'Unknown value',eol
e_xtra db 'Extra characters on line',eol
e_label db 'Label name required',eol
e_str db 'String error',eol
e_orgs db 'Too many ORGs',eol
e_brack db 'Need parenthesis',eol
e_tlab db 'Too many labels',eol
e_amod db 'Illegal adressing mode',eol
e_bra db 'Branch out of range by $'
brange db ' bytes',eol
e_sin db 'Bad or missing sinus parameter',eol
e_spac db 'Space expected',eol
e_opt db 'OPT directive not supported',eol
pass db 0
exitcod dw 4c00h
flags db 0
lines dd 0
bytes dd 0
iclen dw t_icl
@ -1260,22 +1448,23 @@ laben dw t_lab
p1laben dw 0
pslaben dw -1
orgvec dw t_org
eoflag db 0
sinmin dw 1
sinmax dw 0
sinadd dw ?
sinamp dw ?
sinsiz dw ?
ohand dw ?
errad dw ?
val dw ?
amod db ?,?
ukp1 db ?,?
oper db ?
cod db ?
amod db ?
origin dw ?
undef db ?
labvec dw ?
fnad dw ?
tempsi dw ?
op1 dw ?,?
op2 dw ?,?
line db 258 dup(?)
tlabel db 256 dup(?)