Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
John P. Willis
ilxi
Commits
e7fe1692
Commit
e7fe1692
authored
Jun 04, 2015
by
John P. Willis
Browse files
External assembler and CMPSZ instruction working
parent
8b2956f4
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
358 additions
and
106 deletions
+358
-106
Makefile
Makefile
+5
-2
asm.bas
asm.bas
+9
-1
console.bas
console.bas
+26
-0
console.bi
console.bi
+8
-0
cpu.bas
cpu.bas
+27
-5
cpu.bi
cpu.bi
+2
-0
ilxi.bas
ilxi.bas
+7
-1
inst.bas
inst.bas
+24
-1
inst.bi
inst.bi
+2
-0
rom.xa
rom.xa
+63
-60
termfill.xa
termfill.xa
+30
-0
xiasm.bas
xiasm.bas
+136
-32
xiasm.bi
xiasm.bi
+19
-4
No files found.
Makefile
View file @
e7fe1692
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
VM_OBJS
=
ilxi.o alu.o asm.o cpu.o error.o host.o storage.o lexer.o inst.o util.o
console.o
XIASM_OBJS
=
xiasm.o asm.o cpu.o lexer.o storage.o inst.o error.o util.o
console.o
FBCFLAGS
=
-g
#-d LEXDEBUG
...
...
@@ -24,6 +24,9 @@ alu.o: alu.bas
asm.o
:
asm.bas
fbc
$(FBCFLAGS)
-o
asm.o
-c
asm.bas
console.o
:
console.bas
fbc
$(FBCFLAGS)
-o
console.o
-c
console.bas
cpu.o
:
cpu.bas
fbc
$(FBCFLAGS)
-o
cpu.o
-c
cpu.bas
...
...
asm.bas
View file @
e7fe1692
...
...
@@ -370,6 +370,8 @@ function asm_encode_opcode(instruction as string) as ubyte
select case lcase(instruction)
case "copy", "copy"
return OP_COPY
case "cpsz"
return OP_CPSZ
case "add", "add"
return OP_ADD
case "sub", "sub"
...
...
@@ -394,6 +396,8 @@ function asm_encode_opcode(instruction as string) as ubyte
return OP_EQV
case "cmp"
return OP_CMP
case "cmpsz"
return OP_CMPSZ
case "branch"
return OP_BRANCH
case "beq"
...
...
@@ -433,6 +437,8 @@ function asm_decode_opcode(opcode as ubyte) as string
select case opcode
case OP_COPY
return "copy"
case OP_CPSZ
return "cpsz"
case OP_ADD
return "add"
case OP_SUB
...
...
@@ -457,6 +463,8 @@ function asm_decode_opcode(opcode as ubyte) as string
return "eqv"
case OP_CMP
return "cmp"
case OP_CMPSZ
return "cmpsz"
case OP_BRANCH
return "branch"
case OP_BEQ
...
...
@@ -559,7 +567,7 @@ function asm_operand_count(opcode as ubyte) as ubyte
return 2
case OP_BEQ, OP_BNE, OP_BZ, OP_BLT, OP_BGT
return 1
case OP_SRET, OP_LRET, OP_IRET, OP_NOP, OP_HLT
case OP_SRET, OP_LRET, OP_IRET, OP_NOP, OP_HLT
, OP_CPSZ, OP_CMPSZ
return 0
end select
end function ' asm_operand_count()
...
...
console.bas
0 → 100644
View file @
e7fe1692
'
' console.bas
'
#include "console.bi"
#include "storage.bi"
sub console_refresh()
dim i as integer
dim c as ubyte
dim col as ubyte = 1 'x
dim row as ubyte = 1 'y
for i = CONSOLE_OFFSET to CONSOLE_LIMIT - 1
c = st_read_byte(CONSOLE_PAGE, i)
locate row, col, 0: print chr(c);
if col >= CONSOLE_WIDTH then
row = row + 1
col = 1
else
col = col + 1
end if
next i
end sub
\ No newline at end of file
console.bi
0 → 100644
View file @
e7fe1692
#define CONSOLE_PAGE &H0001
#define CONSOLE_OFFSET &H0000
#define CONSOLE_LIMIT &H07D0
#define CONSOLE_WIDTH 80
#define CONSOLE_HEIGHT 25
declare sub console_refresh()
\ No newline at end of file
cpu.bas
View file @
e7fe1692
...
...
@@ -7,11 +7,12 @@
#include "asm.bi"
#include "util.bi"
#include "inst.bi"
#include "console.bi"
sub init_cpu()
with cpu_state
.pc =
0
.pc =
1
.ec = 0
.es = 0
...
...
@@ -21,7 +22,7 @@ sub init_cpu()
.dp = 0
.ep = 0
.sp = 0
.so = PAGESIZE -
1
.so = PAGESIZE -
2
.ss = 0
.ds = 0
...
...
@@ -46,10 +47,15 @@ sub init_cpu()
.go = 0
.gp = 0
end with
cpu_set_flag FL_INTERRUPT
st_load_page "rom.bin", 0
end sub
sub cpu()
dim clock_count as long = 0
dim opcode as ubyte
dim inst_pc as ushort
...
...
@@ -62,9 +68,17 @@ sub cpu()
dim data_type as ubyte
cpu_clear_flag FL_HALT
cls
' main cpu loop
do
clock_count += 1
if clock_count = 100 then
console_refresh
clock_count = 0
end if
inst_pc = cpu_state.pc
if cpu_get_flag(FL_DEBUG) then
...
...
@@ -166,6 +180,8 @@ sub cpu()
select case opcode
case OP_COPY
inst_copy operands(1), operands(2)
case OP_CPSZ
inst_cpsz
case OP_ADD
inst_add operands(1), operands(2)
case OP_SUB
...
...
@@ -190,6 +206,8 @@ sub cpu()
inst_eqv operands(1), operands(2)
case OP_CMP
inst_cmp operands(1), operands(2)
case OP_CMPSZ
inst_cmpsz
case OP_BRANCH
inst_branch operands(1)
case OP_BEQ
...
...
@@ -241,11 +259,16 @@ sub cpu()
end if
if cpu_get_flag(FL_HALT) then
console_refresh
if cpu_state.es > 0 then
print ""
print "cpu(): trap "; trim(str(cpu_state.ec)); " at pc = "; trim(str(cpu_state.pc))
else
print ""
print "cpu(): halt at "; ilxi_pad_left(hex(cpu_state.cp), "0", 4); ":"; ilxi_pad_left(hex(inst_pc), "0", 4)
end if
end if
exit do
end if
...
...
@@ -254,7 +277,6 @@ sub cpu()
loop
end sub ' cpu()
function cpu_fetch() as ubyte
...
...
cpu.bi
View file @
e7fe1692
...
...
@@ -57,6 +57,7 @@
#define OP_DATA 000
#define OP_COPY 001
#define OP_CPSZ 002
#define OP_ADD 003
#define OP_SUB 004
#define OP_MUL 005
...
...
@@ -69,6 +70,7 @@
#define OP_XOR 012
#define OP_EQV 013
#define OP_CMP 014
#define OP_CMPSZ 015
#define OP_BRANCH 020
#define OP_BEQ 021
...
...
ilxi.bas
View file @
e7fe1692
...
...
@@ -8,11 +8,15 @@
#include "storage.bi"
#include "asm.bi"
#include "util.bi"
#include "console.bi"
startup
sub startup()
color 7,0
color 12,0: color 7,0 ' hack to get around weird terminal bug around 7 being the default
cls
print "ILXIM Virtual Machine"
print " Copyright (C) 2015 Coherent Logic Development LLC"
print ""
...
...
@@ -39,6 +43,8 @@ sub cli()
cmd_name = get_lexer_entry(0).strval
select case cmd_name
case "redraw"
cls: console_refresh
case "loadpage", "lp"
dim img_file as string = get_lexer_entry(1).strval
dim page_index as integer
...
...
inst.bas
View file @
e7fe1692
...
...
@@ -13,7 +13,6 @@ function inst_getbyte(op as t_operand, page as integer) as ubyte
if op.register = 1 then
if op.indirect = 0 then 'register direct
select case op.low_byte
case NREG_LA, NREG_LB, NREG_LC, NREG_LC, NREG_LD, NREG_LE, NREG_HA, NREG_HB, NREG_HC, NREG_HD, NREG_HE
return cubyte(cpu_get_reg(op.low_byte))
...
...
@@ -155,6 +154,26 @@ sub inst_copy(dest as t_operand, source as t_operand)
end sub ' inst_copy()
sub inst_cpsz()
' copy ZSTRING from SS:SI to DS:DI
dim sb as ubyte
do
sb = st_read_byte(cpu_state.ss, cpu_state.si)
if sb <> 0 then
st_write_byte cpu_state.ds, cpu_state.di, sb
cpu_state.si += 1
cpu_state.di += 1
else
exit sub
end if
loop
end sub ' inst_cpsz()
sub inst_add(dest as t_operand, source as t_operand)
' cannot store a result in an immediate value
...
...
@@ -308,6 +327,10 @@ sub inst_cmp(dest as t_operand, source as t_operand)
end sub ' inst_cmp()
sub inst_cmpsz()
end sub ' inst_cmpsz()
sub inst_branch(dest as t_operand)
select case dest.data_type
case DT_BYTE
...
...
inst.bi
View file @
e7fe1692
...
...
@@ -5,6 +5,7 @@
#include once "asm.bi"
declare sub inst_copy(dest as t_operand, source as t_operand)
declare sub inst_cpsz()
declare sub inst_add(dest as t_operand, source as t_operand)
declare sub inst_sub(dest as t_operand, source as t_operand)
declare sub inst_mul(dest as t_operand, source as t_operand)
...
...
@@ -17,6 +18,7 @@ declare sub inst_and(dest as t_operand, source as t_operand)
declare sub inst_xor(dest as t_operand, source as t_operand)
declare sub inst_eqv(dest as t_operand, source as t_operand)
declare sub inst_cmp(dest as t_operand, source as t_operand)
declare sub inst_cmpsz()
declare sub inst_branch(dest as t_operand)
declare sub inst_beq(dest as t_operand)
declare sub inst_bne(dest as t_operand)
...
...
rom.xa
View file @
e7fe1692
...
...
@@ -3,71 +3,74 @@
;
; 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
; Copyright (C) 2015 Coherent Logic Development LLC
;
pop %dp
PROGRAM TITLE 'ROM'
ORIGIN 1 ; ROM CODE BEGINS AT 0000:0001
add %ga,1
add %gb,1
branch {STRCPY_TOP}
LABEL STRCPY_END
; return
lret
EQU VID_PAGE 1 ; VIDEO BUFFER IS AT 0001:0000 - 0001:07D0
EQU VID_BASE 0 ; VIDEO BUFFER BASE OFFSET
EQU ROM_DATA_PAGE 0
EQU ROM_STACK 10 ; ROM RESERVES PAGE 10 FOR STACK OPERATIONS
LABEL __rom_start
;;
;; JUMP TO ROM INITIALIZATION ROUTINE
;;
BRANCH WORD {__rom_init}
;; DEFINES
VAR ZSTRING ROM_VS "ILXI ROM MONITOR V0.01 COPYRIGHT (C) 2015 COHERENT LOGIC DEVELOPMENT LLC"
VAR WORD TERM_PTR 1
LABEL __rom_init
;;
;; SET UP DATA AND STACK
;;
COPY WORD %DP,{ROM_DATA_PAGE}
COPY WORD %SP,{ROM_STACK}
;;
;; PRINT ROM VERSION
;;
COPY WORD %SS,%DP
COPY WORD %SI,{ROM_VS}
SCALL WORD {__term_print_string}
;;
;; HALT
;;
HLT
;; __term_print_string
;;
;; PRINTS STRING AT SS:SI
LABEL __term_print_string
;;
;; PRESERVE REGISTERS
;;
PUSH WORD %SS
PUSH WORD %DS
PUSH WORD %DI
COPY WORD %DS,{VID_PAGE}
COPY WORD %DI,#{TERM_PTR}
CPSZ
ADD WORD (#{TERM_PTR}),%DI
;;
;; RESTORE REGISTERS AND RETURN
;;
POP WORD %DI
POP WORD %DS
POP WORD %SS
SRET
termfill.xa
0 → 100644
View file @
e7fe1692
;
; termfill.xa
;
; Test program to fill screen with letters
;
PROGRAM TITLE 'TERMFILL'
ORIGIN 256
EQU OUT_CHAR 65 ; the letter 'A'
EQU VID_PAGE 1 ; video segment
EQU VID_BASE 0 ; video offset
EQU CHAR_COUNT 2000 ; characters to be output
LABEL MAIN
COPY WORD %DS,{VID_PAGE} ; set dest. segment to video segment
COPY BYTE %LA,{OUT_CHAR} ; put OUT_CHAR in low byte of %GA
COPY WORD %GC,{VID_BASE} ; initialize counter
LABEL NEXT
COPY BYTE (%GC),%LA ; copy character to next slot in memory
CMP WORD %GC,{CHAR_COUNT} ; see if we have already reached the maximum char count
BEQ WORD {MAIN_tail} ; if we do, jump out of the loop
ADD WORD %GC,1 ; else, increment counter
BRANCH WORD {NEXT} ; and do it again
LABEL MAIN_tail
HLT
\ No newline at end of file
xiasm.bas
View file @
e7fe1692
...
...
@@ -11,6 +11,8 @@
#include "lexer.bi"
#include "util.bi"
#include "xiasm.bi"
#include "console.bi"
#include "cpu.bi"
sub main(args as string)
...
...
@@ -27,12 +29,45 @@ sub main(args as string)
end sub
sub do_asm(filename as string)
sub do_asm(filename as string, argi as integer)
dim output_file_name as string
dim line_count as integer = read_source_file(filename)
st_save_page output_file_name, 0
initial_pass argi
if udidx > 0 then ' we have a need for a fix-up pass
print ">>> PASS 2 [INFO]: Attempting to resolve "; trim(str(udidx)); " symbol(s) left over from pass 1"
dim i as integer
dim e as undef_entry
dim f as symtab_entry
dim fixup_offset as ushort
for i = 1 to udidx
e = udtab(i)
fixup_offset = e.byte_offset
f = lookup_symbol(e.e_key)
if f.resolved = 0 then
print ">>> PASS 2 [FATAL]: Unresolved symbol "; e.e_key
end
else
print ">>> PASS 2 [INFO]: Resolved symbol "; e.e_key; " (symbol found at offset "; hex(f.offset); "h, inserted at fix-up offset "; hex(fixup_offset); "h)"
st_write_word argi, fixup_offset, f.offset
end if
next i
end if
output_file_name = left(filename, instrrev(filename, ".") - 1) & ".bin"
st_save_page output_file_name, argi
end sub
...
...
@@ -77,28 +112,47 @@ function read_source_file(filename as string) as integer
end function
function
pass(pa
ss
_number as
integer) as byte
sub initial_
pass(pa
ge
_number as
ushort)
dim arg_count as integer = 0
dim cur_arg as string
dim t_sym as symtab_entry
dim i as integer
cpu_state.ep = page_number
for i = 1 to ubound(input_lines)
t_sym.resolved = 0
arg_count = lex(input_lines(i))
cur_arg = get_lexer_entry(0).strval
select case cur_arg
case "PROGRAM"
case "ORIGIN"
case "PROGRAM"
output_file_name = get_lexer_entry(3).strval
case "SYMBOL"
if get_lexer_entry(1).lexer_class = LC_BYTE then
asm_offset = get_lexer_entry(1).byteval
else
asm_offset = get_lexer_entry(1).intval
end if
print ">>> PASS 1 [INFO]: Program ORIGIN set to offset "; hex(asm_offset)
case "EQU"
t_sym.e_key = get_lexer_entry(1).strval
t_sym.e_class = SYMCLASS_EQU
t_sym.strval = get_lexer_entry(2).strval
t_sym.resolved = 1
install_symbol t_sym
case "VAR"
t_sym.e_key = get_lexer_entry(2).strval
t_sym.e_type = get_lexer_entry(1).strval
t_sym.e_class = SYMCLASS_VAR
t_sym.offset = asm_offset
t_sym.resolved = 1
select case t_sym.e_type
case "ZSTRING"
dim j as integer
...
...
@@ -108,7 +162,6 @@ function pass(pass_number as integer) as byte
for j = 1 to len(get_lexer_entry(3).strval)
b = asc(mid(get_lexer_entry(3).strval, j, 1))
st_write_byte 0, asm_offset, b
...
...
@@ -119,31 +172,40 @@ function pass(pass_number as integer) as byte
t_sym.strval = get_lexer_entry(3).strval
case "WORD"
' st_write_byte 0, asm_offset,
t_sym.byteval = get_lexer_entry(3).byteval
st_write_word page_number, asm_offset, t_sym.wordval
asm_offset += 2
case "BYTE"
t_sym.byteval = get_lexer_entry(3).byteval
t_sym.offset = asm_offset
st_write_byte
0
, asm_offset, t_sym.byteval
st_write_byte
page_number
, asm_offset, t_sym.byteval
asm_offset += 1
end select
install_symbol t_sym
case "LABEL"
t_sym.e_key = get_lexer_entry(1).strval
t_sym.e_
type = "
LABEL
"
t_sym.e_
class = SYMCLASS_
LABEL
t_sym.offset = asm_offset
t_sym.resolved = 1
install_symbol t_sym
case else
dim ts as string
fixup_flag = 0
ts = expand_macros(input_lines(i))
print ilxi_pad_left(hex(asm_offset), "0", 4); ": "; ts
print
">>> PASS 1 [OUTPUT]: ";
ilxi_pad_left(hex(asm_offset), "0", 4); ":
"; ts
asm_assemble ts
asm_offset += 1
if fixup_flag = 1 then udtab(udidx).byte_offset = asm_offset - 2
end select
next i
end
function
end
sub ' initial_pass()
sub install_symbol(sym_entry as symtab_entry)
stidx += 1
...
...
@@ -160,11 +222,27 @@ function lookup_symbol(key as string) as symtab_entry
next i
dim tmp as symtab_entry
tmp.offset = -1
tmp.resolved = 0
tmp.e_class = SYMCLASS_LABEL 'what a hack...
return tmp
end function
sub install_undef(uent as undef_entry)
udidx += 1
redim preserve udtab(udidx) as undef_entry
udtab(udidx) = uent
end sub
function lookup_undef(key as string) as undef_entry
dim i as integer
for i = 1 to udidx
next
end function
function expand_macros(input_string as string) as string
dim macro_name as string
...
...
@@ -176,39 +254,65 @@ function expand_macros(input_string as string) as string
dim symbol as symtab_entry
dim in_macro as ubyte = 0
dim in_label as ubyte = 0
dim in_macro as ubyte = 0
for i = 1 to len(input_string)
c = mid(input_string, i, 1)
select case c
case "["
in_label = 1
case "]"
in_label = 0
symbol = lookup_symbol(label_name)