Commit 5207ffbf authored by John P. Willis's avatar John P. Willis
Browse files

First run at external assembler... not going well

parent 29cee8f5
OBJS = ilxi.o alu.o asm.o cpu.o error.o host.o storage.o lexer.o inst.o
VM_OBJS = ilxi.o alu.o asm.o cpu.o error.o host.o storage.o lexer.o inst.o util.o
XIASM_OBJS = xiasm.o asm.o cpu.o lexer.o storage.o inst.o error.o util.o
FBCFLAGS = -g
#-d LEXDEBUG
ilxi: $(OBJS)
fbc $(FBCFLAGS) -x ilxi $(OBJS)
vm: ilxi
assembler: xiasm
xiasm: $(XIASM_OBJS)
fbc $(FBCFLAGS) -x xiasm $(XIASM_OBJS)
xiasm.o: xiasm.bas
fbc $(FBCFLAGS) -m xiasm -o xiasm.o -c xiasm.bas
ilxi: $(VM_OBJS)
fbc $(FBCFLAGS) -x ilxi $(VM_OBJS)
alu.o: alu.bas
fbc $(FBCFLAGS) -o alu.o -c alu.bas
......@@ -32,5 +43,8 @@ inst.o: inst.bas
ilxi.o: ilxi.bas
fbc -m ilxi $(FBCFLAGS) -o ilxi.o -c ilxi.bas
util.o: util.bas
fbc $(FBCFLAGS) -o util.o -c util.bas
clean:
rm -f *.o ilxi
......@@ -8,9 +8,9 @@
#include "cpu.bi"
#include "lexer.bi"
#include "storage.bi"
#include "ilxi.bi"
#include "util.bi"
dim shared asm_offset as ushort
function asm_encode_amod(ops_following as ubyte, amod as ubyte, disp as ubyte) as ubyte
' 7 6543 210
......@@ -252,6 +252,26 @@ function asm_encode_register(register_name as string) as ubyte
return NREG_GO
case "gp"
return NREG_GP
case "la"
return NREG_LA
case "lb"
return NREG_LB
case "lc"
return NREG_LC
case "ld"
return NREG_LD
case "le"
return NREG_LE
case "ha"
return NREG_HA
case "hb"
return NREG_HB
case "hc"
return NREG_HC
case "hd"
return NREG_HD
case "he"
return NREG_HE
end select
end function ' asm_encode_register()
......@@ -307,6 +327,26 @@ function asm_decode_register(reg as ubyte) as string
return "go"
case NREG_GP
return "gp"
case NREG_LA
return "la"
case NREG_LB
return "lb"
case NREG_LC
return "lc"
case NREG_LD
return "ld"
case NREG_LE
return "le"
case NREG_HA
return "ha"
case NREG_HB
return "hb"
case NREG_HC
return "hc"
case NREG_HD
return "hd"
case NREG_HE
return "he"
end select
end function ' asm_decode_register()
......
'
' asm.bi
'
common shared asm_offset as ushort
#define O_MASK &H80
#define AMOD_MASK &H78
#define DISP_MASK &H7
type t_operand
amod as ubyte
low_byte as ubyte
high_byte as ubyte
byte_count as ubyte
displacement as ubyte
register as ubyte
memory as ubyte
immediate as ubyte
has_displacement as ubyte
indirect as ubyte
end type
declare function asm_encode_amod(ops_following as ubyte, amod as ubyte, disp as ubyte) as ubyte
declare function asm_amod_following(amod as ubyte) as ubyte
declare function asm_amod_amod(amod as ubyte) as ubyte
declare function asm_amod_disp(amod as ubyte) as ubyte
declare function asm_decode_disp(disp as ubyte) as ushort
declare function asm_encode_address(ops_following as ubyte, addr_string as string) as t_operand
declare function asm_encode_register(register_name as string) as ubyte
declare function asm_decode_register(reg as ubyte) as string
declare function asm_encode_opcode(instruction as string) as ubyte
declare function asm_decode_opcode(opcode as ubyte) as string
declare function asm_operand_count(opcode as ubyte) as ubyte
declare sub asm_assemble(instruction as string)
declare function asm_disassemble(page as ushort, offset as ushort) as string
declare function asm_bytes_to_ushort(lsb as ubyte, msb as ubyte) as ushort
declare sub asm_assemble_interactive(origin_address as ushort)
......@@ -5,7 +5,7 @@
#include "cpu.bi"
#include "storage.bi"
#include "asm.bi"
#include "ilxi.bi"
#include "util.bi"
#include "inst.bi"
sub init_cpu()
......@@ -261,20 +261,20 @@ sub cpu_dump_state()
print ""
print "Page Size:", PAGESIZE,"Page Count:",PAGECOUNT
print ""
print "PC "; x.pc, "EC "; x.ec, "ES "; x.es, "CP "; x.cp, "DP "; x.dp
print "EP "; x.ep, "SP "; x.sp, "SO "; x.so, "FL "; x.fl
print "PC "; ilxi_pad_left(hex(x.pc),"0",4), "EC "; ilxi_pad_left(hex(x.ec),"0",4), "ES "; ilxi_pad_left(hex(x.es),"0",4), "CP "; ilxi_pad_left(hex(x.cp),"0",4), "DP "; ilxi_pad_left(hex(x.dp),"0",4)
print "EP "; ilxi_pad_left(hex(x.ep),"0",4), "SP "; ilxi_pad_left(hex(x.sp),"0",4), "SO "; ilxi_pad_left(hex(x.so),"0",4), "FL "; ilxi_pad_left(hex(x.fl),"0",4)
print ""
print "GA "; x.ga, "GB "; x.gb, "GC "; x.gc, "GD "; x.gd, "GE "; x.ge
print "GF "; x.gf, "GG "; x.gg, "GH "; x.gh, "GI "; x.gi, "GJ "; x.gj
print "GK "; x.gk, "GL "; x.gl, "GM "; x.gm, "GN "; x.gn, "GO "; x.go
print "GP "; x.gp
print "GA "; ilxi_pad_left(hex(x.ga),"0",4), "GB "; ilxi_pad_left(hex(x.gb),"0",4), "GC "; ilxi_pad_left(hex(x.gc),"0",4), "GD "; ilxi_pad_left(hex(x.gd),"0",4), "GE "; ilxi_pad_left(hex(x.ge),"0",4)
print "GF "; ilxi_pad_left(hex(x.gf),"0",4), "GG "; ilxi_pad_left(hex(x.gg),"0",4), "GH "; ilxi_pad_left(hex(x.gh),"0",4), "GI "; ilxi_pad_left(hex(x.gi),"0",4), "GJ "; ilxi_pad_left(hex(x.gj),"0",4)
print "GK "; ilxi_pad_left(hex(x.gk),"0",4), "GL "; ilxi_pad_left(hex(x.gl),"0",4), "GM "; ilxi_pad_left(hex(x.gm),"0",4), "GN "; ilxi_pad_left(hex(x.gn),"0",4), "GO "; ilxi_pad_left(hex(x.go),"0",4)
print "GP "; ilxi_pad_left(hex(x.gp),"0",4)
print ""
print "Flags:"
print ""
print "HF="; cpu_get_flag(FL_HALT); " TF="; cpu_get_flag(FL_TRACE); " OF="; cpu_get_flag(FL_OVERFLOW);
print " CF="; cpu_get_flag(FL_CARRY); " IF="; cpu_get_flag(FL_INTERRUPT); " EF="; cpu_get_flag(FL_EQUALITY);
print " LF="; cpu_get_flag(FL_LESSTHAN); " GF="; cpu_get_flag(FL_GREATERTHAN); " ZF="; cpu_get_flag(FL_ZERO);
print " PL=0 PF="; cpu_get_flag(FL_PARITY); " SF="; cpu_get_flag(FL_SIGN); " DF="; cpu_get_flag(FL_DEBUG);
print " PL="; cpu_get_pl(); " PF="; cpu_get_flag(FL_PARITY); " SF="; cpu_get_flag(FL_SIGN); " DF="; cpu_get_flag(FL_DEBUG);
print ""
end sub ' cpu_dump_state()
......@@ -358,6 +358,30 @@ sub cpu_set_reg_alpha(register as string, value as ushort)
cpu_state.go = value
case REG_GP
cpu_state.gp = value
' LSB of regs GA through GE
case REG_LA
cpu_state.ga = asm_bytes_to_ushort(cubyte(value), cpu_get_reg(NREG_HA))
case REG_LB
cpu_state.gb = asm_bytes_to_ushort(cubyte(value), cpu_get_reg(NREG_HB))
case REG_LC
cpu_state.gc = asm_bytes_to_ushort(cubyte(value), cpu_get_reg(NREG_HC))
case REG_LD
cpu_state.gd = asm_bytes_to_ushort(cubyte(value), cpu_get_reg(NREG_HD))
case REG_LE
cpu_state.ge = asm_bytes_to_ushort(cubyte(value), cpu_get_reg(NREG_HE))
'MSB of regs GA through GEs
case REG_HA
cpu_state.ga = asm_bytes_to_ushort(cpu_get_reg(NREG_LA), cubyte(value))
case REG_HB
cpu_state.gb = asm_bytes_to_ushort(cpu_get_reg(NREG_LB), cubyte(value))
case REG_HC
cpu_state.gc = asm_bytes_to_ushort(cpu_get_reg(NREG_LC), cubyte(value))
case REG_HD
cpu_state.gd = asm_bytes_to_ushort(cpu_get_reg(NREG_LD), cubyte(value))
case REG_HE
cpu_state.ge = asm_bytes_to_ushort(cpu_get_reg(NREG_LE), cubyte(value))
end select
end sub ' cpu_set_reg_alpha()
......@@ -414,6 +438,190 @@ function cpu_get_reg_alpha(register as string) as ushort
return cpu_state.go
case REG_GP
return cpu_state.gp
case REG_LA
return (cpu_state.ga and LSB_MASK)
case REG_LB
return (cpu_state.gb and LSB_MASK)
case REG_LC
return (cpu_state.gc and LSB_MASK)
case REG_LD
return (cpu_state.gd and LSB_MASK)
case REG_LE
return (cpu_state.ge and LSB_MASK)
case REG_HA
return (cpu_state.ga and MSB_MASK) shr 8
case REG_HB
return (cpu_state.gb and MSB_MASK) shr 8
case REG_HC
return (cpu_state.gc and MSB_MASK) shr 8
case REG_HD
return (cpu_state.gd and MSB_MASK) shr 8
case REG_HE
return (cpu_state.ge and MSB_MASK) shr 8
end select
end function ' cpu_get_reg_alpha()
sub cpu_set_reg(register as ubyte, value as ushort)
select case register
case NREG_PC
cpu_state.pc = value
case NREG_EC
cpu_state.ec = value
case NREG_ES
cpu_state.es = value
case NREG_FL
cpu_state.fl = value
case NREG_CP
cpu_state.cp = value
case NREG_DP
cpu_state.dp = value
case NREG_EP
cpu_state.ep = value
case NREG_SP
cpu_state.sp = value
case NREG_SO
cpu_state.so = value
case NREG_GA
cpu_state.ga = value
case NREG_GB
cpu_state.gb = value
case NREG_GC
cpu_state.gc = value
case NREG_GD
cpu_state.gd = value
case NREG_GE
cpu_state.ge = value
case NREG_GF
cpu_state.gf = value
case NREG_GG
cpu_state.gg = value
case NREG_GH
cpu_state.gh = value
case NREG_GI
cpu_state.gi = value
case NREG_GJ
cpu_state.gj = value
case NREG_GK
cpu_state.gk = value
case NREG_GL
cpu_state.gl = value
case NREG_GM
cpu_state.gm = value
case NREG_GN
cpu_state.gn = value
case NREG_GO
cpu_state.go = value
case NREG_GP
cpu_state.gp = value
' LSB of regs GA through GE
case NREG_LA
cpu_state.ga = asm_bytes_to_ushort(cubyte(value), cpu_get_reg(NREG_HA))
case NREG_LB
cpu_state.gb = asm_bytes_to_ushort(cubyte(value), cpu_get_reg(NREG_HB))
case NREG_LC
cpu_state.gc = asm_bytes_to_ushort(cubyte(value), cpu_get_reg(NREG_HC))
case NREG_LD
cpu_state.gd = asm_bytes_to_ushort(cubyte(value), cpu_get_reg(NREG_HD))
case NREG_LE
cpu_state.ge = asm_bytes_to_ushort(cubyte(value), cpu_get_reg(NREG_HE))
'MSB of regs GA through GEs
case NREG_HA
cpu_state.ga = asm_bytes_to_ushort(cpu_get_reg(NREG_LA), cubyte(value))
case NREG_HB
cpu_state.gb = asm_bytes_to_ushort(cpu_get_reg(NREG_LB), cubyte(value))
case NREG_HC
cpu_state.gc = asm_bytes_to_ushort(cpu_get_reg(NREG_LC), cubyte(value))
case NREG_HD
cpu_state.gd = asm_bytes_to_ushort(cpu_get_reg(NREG_LD), cubyte(value))
case NREG_HE
cpu_state.ge = asm_bytes_to_ushort(cpu_get_reg(NREG_LE), cubyte(value))
end select
end sub ' cpu_set_reg()
function cpu_get_reg(register as ubyte) as ushort
select case register
case NREG_PC
return cpu_state.pc
case NREG_EC
return cpu_state.ec
case NREG_ES
return cpu_state.es
case NREG_FL
return cpu_state.fl
case NREG_CP
return cpu_state.cp
case NREG_DP
return cpu_state.dp
case NREG_EP
return cpu_state.ep
case NREG_SP
return cpu_state.sp
case NREG_SO
return cpu_state.so
case NREG_GA
return cpu_state.ga
case NREG_GB
return cpu_state.gb
case NREG_GC
return cpu_state.gc
case NREG_GD
return cpu_state.gd
case NREG_GE
return cpu_state.ge
case NREG_GF
return cpu_state.gf
case NREG_GG
return cpu_state.gg
case NREG_GH
return cpu_state.gh
case NREG_GI
return cpu_state.gi
case NREG_GJ
return cpu_state.gj
case NREG_GK
return cpu_state.gk
case NREG_GL
return cpu_state.gl
case NREG_GM
return cpu_state.gm
case NREG_GN
return cpu_state.gn
case NREG_GO
return cpu_state.go
case NREG_GP
return cpu_state.gp
case NREG_LA
return (cpu_state.ga and LSB_MASK)
case NREG_LB
return (cpu_state.gb and LSB_MASK)
case NREG_LC
return (cpu_state.gc and LSB_MASK)
case NREG_LD
return (cpu_state.gd and LSB_MASK)
case NREG_LE
return (cpu_state.ge and LSB_MASK)
case NREG_HA
return (cpu_state.ga and MSB_MASK) shr 8
case NREG_HB
return (cpu_state.gb and MSB_MASK) shr 8
case NREG_HC
return (cpu_state.gc and MSB_MASK) shr 8
case NREG_HD
return (cpu_state.gd and MSB_MASK) shr 8
case NREG_HE
return (cpu_state.ge and MSB_MASK) shr 8
end select
end function ' cpu_get_reg_alpha()
\ No newline at end of file
end function ' cpu_get_reg()
\ No newline at end of file
......@@ -2,6 +2,9 @@
' cpu.bi
'
#define MSB_MASK &HFF00
#define LSB_MASK &HFF
'
' Instruction Format
'
......@@ -155,6 +158,19 @@
#define REG_GO "go"
#define REG_GP "gp"
#define REG_LA "la"
#define REG_LB "lb"
#define REG_LC "lc"
#define REG_LD "ld"
#define REG_LE "le"
#define REG_HA "ha"
#define REG_HB "hb"
#define REG_HC "hc"
#define REG_HD "hd"
#define REG_HE "he"
'
' register encodings (numeric)
'
......@@ -188,6 +204,18 @@
#define NREG_GO 54
#define NREG_GP 55
#define NREG_LA 60
#define NREG_LB 61
#define NREG_LC 62
#define NREG_LD 63
#define NREG_LE 64
#define NREG_HA 65
#define NREG_HB 66
#define NREG_HC 67
#define NREG_HD 68
#define NREG_HE 69
'
' flags
'
......@@ -274,3 +302,5 @@ declare function cpu_get_flag(flag as ushort) as ubyte
declare function cpu_fetch() as ubyte
declare sub cpu_set_reg_alpha(register as string, value as ushort)
declare function cpu_get_reg_alpha(register as string) as ushort
declare sub cpu_set_reg(register as ubyte, value as ushort)
declare function cpu_get_reg(register as ubyte) as ushort
\ No newline at end of file
......@@ -7,6 +7,7 @@
#include "lexer.bi"
#include "storage.bi"
#include "asm.bi"
#include "util.bi"
startup
......@@ -38,6 +39,30 @@ sub cli()
cmd_name = get_lexer_entry(0).strval
select case cmd_name
case "loadpage", "lp"
dim img_file as string = get_lexer_entry(1).strval
dim page_index as integer
if get_lexer_entry(2).lexer_class = LC_BYTE then
page_index = get_lexer_entry(2).byteval
else
page_index = get_lexer_entry(2).intval
end if
st_load_page img_file, page_index
case "savepage", "sp"
dim img_file as string = get_lexer_entry(1).strval
dim page_index as integer
if get_lexer_entry(2).lexer_class = LC_BYTE then
page_index = get_lexer_entry(2).byteval
else
page_index = get_lexer_entry(2).intval
end if
st_save_page img_file, page_index
case "assemble"
dim le_origin as lexer_entry
dim origin_addr as ushort
......@@ -149,7 +174,7 @@ sub cli()
setm_value = le_setm_value.byteval
st_write_byte cpu_state.dp, setm_addr, setm_value
case "dumpcpu"
case "dumpcpu","d"
cpu_dump_state
case "trace"
if get_lexer_entry(1).byteval = 0 then
......@@ -179,18 +204,3 @@ sub ilxi_setr(register as string, value as integer)
cpu_set_reg_alpha lcase(register), value
end sub
function ilxi_pad_left(input_str as string, pad_char as string, total_size as integer) as string
dim output_str as string
dim diff as integer
dim i as integer
diff = total_size - len(input_str)
for i = 1 to diff
output_str = output_str & pad_char
next
output_str = output_str & input_str
return output_str
end function
\ No newline at end of file
......@@ -5,5 +5,4 @@
declare sub startup()
declare sub cli()
declare sub ilxi_getr(register as string)
declare sub ilxi_setr(register as string, value as integer)
declare function ilxi_pad_left(input_str as string, pad_char as string, total_size as integer) as string
\ No newline at end of file
declare sub ilxi_setr(register as string, value as integer)
\ No newline at end of file
;
; rom.xa
;
; ILXI ROM
;
ORIGIN MAIN
PROGRAM SEGMENT CODE "ROMCODE.BIN"
SYMBOL ZSTRING NAME "ILXIM ROM Monitor"
SYMBOL WORD VID_PAGE 3
SYMBOL WORD VID_OFFSET 0
LABEL MAIN
;
; main entry point
;
push %ep
push %ga
push %gb
push %gc
copy %ga,{NAME}
copy %ep,{VID_PAGE}
copy %gb,{VID_OFFSET}
scall {STRCPY}
pop %gc
pop %gb
pop %ga
pop %ep
hlt
LABEL STRCPY
;
; STRCPY
; DP:GA source
; EP:GB target
;
LABEL STRCPY_TOP
; copy the source byte to %gc
copy %gc,(%ga)
; exit if null byte encountered
cmp %gc,0
beq {STRCPY_END}
; save dp and set dp = ep
push %dp
copy %dp,%ep
; copy %gc to the target
copy (%gb),%gc
pop %dp
add %ga,1
add %gb,1
branch {STRCPY_TOP}
LABEL STRCPY_END
; return
lret
......@@ -27,3 +27,25 @@ sub st_write_byte(page as integer, offset as integer, value as byte)
mem(page).contents(offset) = value
end sub
sub st_load_page(file as string, page as integer)
dim file_handle as integer
file_handle = freefile()
open file for binary as #file_handle
get #file_handle, , mem(page)
close #file_handle
end sub
sub st_save_page(file as string, page as integer)
dim file_handle as integer
file_handle = freefile()
open file for binary as #file_handle
put #file_handle, , mem(page)
close #file_handle
end sub
\ No newline at end of file
......@@ -9,3 +9,5 @@ end type
declare function st_read_byte(page as integer, offset as integer) as byte
declare sub st_write_byte(page as integer, offset as integer, value as byte)
declare sub st_load_page(file as string, page as integer)
declare sub st_save_page(file as string, page as integer)
\ No newline at end of file
'
' util.bas
'
function ilxi_pad_left(input_str as string, pad_char as string, total_size as integer) as string
dim output_str as string
dim diff as integer
dim i as integer
diff = total_size - len(input_str)
for i = 1 to diff
output_str = output_str & pad_char
next
output_str = output_str & input_str
return output_str
end function
\ No newline at end of file
'
' util.bi
'
declare function ilxi_pad_left(input_str as string, pad_char as string, total_size as integer) as string
\ No newline at end of file
'
'
' xiasm.bas
'
' ILXI external assembler
'
'
#define SYMTAB_SIZE &HFF