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
56cb49ab
Commit
56cb49ab
authored
Jun 17, 2015
by
John P. Willis
Browse files
Clean up the CLI, add skeletal support for interrupts, begin work on supporting console input
parent
2f8a09a1
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
205 additions
and
70 deletions
+205
-70
.ilximrc
.ilximrc
+1
-1
Makefile
Makefile
+1
-3
asm.bas
asm.bas
+4
-0
bus.bas
bus.bas
+10
-1
bus.bi
bus.bi
+2
-0
console.bas
console.bas
+11
-5
cpu.bas
cpu.bas
+72
-19
cpu.bi
cpu.bi
+12
-11
error.bas
error.bas
+20
-1
error.bi
error.bi
+2
-1
ilxi.bas
ilxi.bas
+16
-8
inst.bas
inst.bas
+36
-10
message.bas
message.bas
+2
-0
pty.sh
pty.sh
+4
-0
rom.xa
rom.xa
+12
-10
No files found.
.ilximrc
View file @
56cb49ab
[console]
mode=serial
port=
COM
port=
/dev/ilxim
bps=9600
parity=N
data_bits=8
...
...
Makefile
View file @
56cb49ab
VM_OBJS
=
ilxi.o asm.o cpu.o error.o host.o storage.o lexer.o inst.o util.o bus.o console.o signal.o message.o profile.o config.o
XIASM_OBJS
=
xiasm.o asm.o cpu.o lexer.o storage.o inst.o error.o util.o console.o bus.o signal.o message.o profile.o config.o
FBCFLAGS
=
-g
-mt
# -d STACKDEBUG
# -d LEXDEBUG
FBCFLAGS
=
-g
-mt
#-d STACKDEBUG -d INSTDEBUG #-d LEXDEBUG
all
:
vm assembler rom test
...
...
asm.bas
View file @
56cb49ab
...
...
@@ -228,6 +228,8 @@ function asm_encode_register(register_name as string) as ubyte
return NREG_SI
case "di"
return NREG_DI
case "bp"
return NREG_BP
case "ga"
return NREG_GA
case "gb"
...
...
@@ -311,6 +313,8 @@ function asm_decode_register(reg as ubyte) as string
return "si"
case NREG_DI
return "di"
case NREG_BP
return "bp"
case NREG_GA
return "ga"
case NREG_GB
...
...
bus.bas
View file @
56cb49ab
...
...
@@ -43,15 +43,22 @@ end sub
sub bus_start()
if bus_started = 1 then exit sub
dim i as integer
for i = 1 to dev_count
message_print "bus_start(): starting device " & devices(i)
bus(devices(i)).dev_thread = threadcreate(bus(devices(i)).dev_cycle, @devices(i))
bus(devices(i)).dev_thread_started = 1
bus(devices(i)).dev_thread_started = 1
next i
message_print "bus_start(): waiting for bus quiescence"
sleep 500
bus_started = 1
end sub
sub bus_stop()
...
...
@@ -71,6 +78,8 @@ sub bus_stop()
end if
next i
bus_started = 0
end sub
sub bus_sig_stop(device_number as ushort)
...
...
bus.bi
View file @
56cb49ab
...
...
@@ -31,6 +31,8 @@ dim shared io_ports(0 to IOPORT_COUNT - 1) as short
dim shared devices() as ubyte
dim shared dev_count as ubyte = 0
dim shared bus_started as ubyte = 0
declare sub bus_clear()
declare sub bus_init()
declare sub bus_start()
...
...
console.bas
View file @
56cb49ab
...
...
@@ -156,12 +156,20 @@ sub console_cycle_serial(byval userdata as any ptr)
dim col as ubyte = 1 'x
dim row as ubyte = 1 'y
dim bytes_waiting as integer
dim input_buffer as string
do
bytes_waiting = lof(console_file_number)
if bytes_waiting > 0 then
message_print "console_cycle_serial(): reading " & bytes_waiting & " bytes from console"
input_buffer &= input(bytes_waiting, console_file_number)
end if
col = 1
row = 1
mutexlock console_mutex
for i = CONSOLE_OFFSET to CONSOLE_LIMIT - 1
c = st_read_byte(CONSOLE_PAGE, i)
...
...
@@ -178,9 +186,7 @@ sub console_cycle_serial(byval userdata as any ptr)
end if
next i
mutexunlock console_mutex
sleep 25
sleep 25, 1
if bus_get_stop_flag(0) = 1 then exit do
loop
...
...
cpu.bas
View file @
56cb49ab
...
...
@@ -10,9 +10,13 @@
#include "console.bi"
#include "bus.bi"
#include "signal.bi"
#include "error.bi"
#include "message.bi"
sub init_cpu()
interrupts_waiting = 0
redim interrupt_queue(0 to interrupts_waiting) as ubyte
with cpu_state
.pc = 0
...
...
@@ -91,6 +95,14 @@ sub cpu()
' main cpu loop
do
#ifdef INSTDEBUG
message_print cpu_get_cppc() & " executing " & asm_disassemble(cpu_state.cp, cpu_state.pc)
#endif
if cpu_get_flag(FL_DEBUG) = 1 then
message_print cpu_get_cppc() & " " & asm_disassemble(cpu_state.cp, cpu_state.pc)
end if
inst_pc = cpu_state.pc
opcode = cpu_fetch()
...
...
@@ -266,21 +278,27 @@ sub cpu()
cpu_state.es = 0
end if
if cpu_get_flag(FL_HALT) then exit do
if cpu_get_flag(FL_HALT) then
bus_stop
exit do
end if
cpu_process_interrupts
if cpu_get_flag(FL_DEBUG) then exit do
loop
bus_stop
if cpu_get_flag(FL_DEBUG) = 0 then
if cpu_state.es > 0 then
message_print "cpu(): trap at " & cpu_get_cppc()
message_print "cpu(): trap " & cpu_state.ec & " (severity " & cpu_state.es & ") at " & cpu_get_cppc() & " '" & error_string(cpu_state.ec) & "'"
message_print cpu_get_cppc() & " " & asm_disassemble(cpu_state.pc, cpu_state.pc)
else
message_print "cpu(): halt at " & cpu_get_cppc()
message_print "cpu():
halt at " & cpu_get_cppc()
end if
else
message_print cpu_get_cppc() & " " & asm_disassemble(cpu_state.cp, cpu_state.pc)
end if
end sub ' cpu()
...
...
@@ -295,18 +313,21 @@ function cpu_fetch() as ubyte
end function ' cpu_fetch()
sub cpu_push_byte(byteval as ubyte)
st_write_byte cpu_state.sp, cpu_state.so, byteval
#ifdef STACKDEBUG
message_print "cpu_push_byte(): " & hex(byteval)
#endif
cpu_state.so -= 1
cpu_state.so -= 1
st_write_byte cpu_state.sp, cpu_state.so, byteval
end sub ' cpu_push_byte()
function cpu_pop_byte() as ubyte
dim retval as ubyte
dim retval as ubyte
retval = st_read_byte(cpu_state.sp, cpu_state.so)
cpu_state.so += 1
...
...
@@ -318,27 +339,29 @@ function cpu_pop_byte() as ubyte
end function ' cpu_pop_byte()
sub cpu_push_word(wordval as ushort)
st_write_word cpu_state.sp, cpu_state.so - 1, wordval
#ifdef STACKDEBUG
locate 30,1
message_print "cpu_push_word(): " & hex(wordval)
#endif
cpu_state.so -= 1
cpu_state.so -= 2
st_write_word cpu_state.sp, cpu_state.so, wordval
end sub ' cpu_push_word()
function cpu_pop_word() as ushort
dim retval as ushort
retval = st_read_word(cpu_state.sp, cpu_state.so)
cpu_state.so += 2
#ifdef STACKDEBUG
locate 30,1
message_print "cpu_pop_word(): " & hex(retval)
#endif
#endif
return retval
cpu_state.so += 2
end function ' cpu_pop_word()
sub cpu_dump_state()
...
...
@@ -353,7 +376,7 @@ sub cpu_dump_state()
print ""
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), "SS "; ilxi_pad_left(hex(x.ss),"0",4)
print "DS "; ilxi_pad_left(hex(x.ds),"0",4), "SI "; ilxi_pad_left(hex(x.ds),"0",4), "DI "; ilxi_pad_left(hex(x.di),"0",4)
print "DS "; ilxi_pad_left(hex(x.ds),"0",4), "SI "; ilxi_pad_left(hex(x.ds),"0",4), "DI "; ilxi_pad_left(hex(x.di),"0",4)
, "BP "; ilxi_pad_left(hex(x.bp),"0",4)
print ""
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)
...
...
@@ -427,6 +450,8 @@ sub cpu_set_reg_alpha(register as string, value as ushort)
cpu_state.si = value
case REG_DI
cpu_state.di = value
case REG_BP
cpu_state.bp = value
case REG_GA
cpu_state.ga = value
case REG_GB
...
...
@@ -515,6 +540,8 @@ function cpu_get_reg_alpha(register as string) as ushort
return cpu_state.si
case REG_DI
return cpu_state.di
case REG_BP
return cpu_state.bp
case REG_GA
return cpu_state.ga
case REG_GB
...
...
@@ -603,6 +630,8 @@ sub cpu_set_reg(register as ubyte, value as ushort)
cpu_state.si = value
case NREG_DI
cpu_state.di = value
case NREG_BP
cpu_state.bp = value
case NREG_GA
cpu_state.ga = value
case NREG_GB
...
...
@@ -692,6 +721,8 @@ function cpu_get_reg(register as ubyte) as ushort
return cpu_state.si
case NREG_DI
return cpu_state.di
case NREG_BP
return cpu_state.bp
case NREG_GA
return cpu_state.ga
case NREG_GB
...
...
@@ -749,4 +780,26 @@ function cpu_get_reg(register as ubyte) as ushort
end select
end function ' cpu_get_reg()
\ No newline at end of file
end function ' cpu_get_reg()
sub cpu_queue_interrupt(interrupt_number as ubyte)
interrupts_waiting += 1
redim preserve interrupt_queue(0 to interrupts_waiting) as ubyte
interrupt_queue(interrupts_waiting) = interrupt_number
end sub ' cpu_queue_interrupt()
sub cpu_process_interrupts()
dim i as integer
for i = 1 to interrupts_waiting
message_print "cpu_process_interrupts(): dispatching interrupt " & trim(str(interrupt_queue(i)))
next i
interrupts_waiting = 0
redim interrupt_queue(0 to interrupts_waiting) as ubyte
end sub ' cpu_process_interrupts()
cpu.bi
View file @
56cb49ab
...
...
@@ -143,6 +143,8 @@
#define REG_SI "si"
#define REG_DI "di"
#define REG_BP "bp"
#define REG_GA "ga"
#define REG_GB "gb"
#define REG_GC "gc"
...
...
@@ -194,6 +196,8 @@
#define NREG_SI 27
#define NREG_DI 28
#define NREG_BP 30
#define NREG_GA 40
#define NREG_GB 41
#define NREG_GC 42
...
...
@@ -280,6 +284,8 @@ type t_cpu_state
si as ushort 'source index
di as ushort 'dest index
bp as ushort 'base pointer
ga as ushort 'general a
gb as ushort 'general b
gc as ushort 'general c
...
...
@@ -298,18 +304,11 @@ type t_cpu_state
gp as ushort 'general p
end type
type t_instruction
opcode as byte
src_amod as byte
src_bytecount as byte
src_address(256) as byte
dst_amod as byte
dst_bytecount as byte
dst_address(256) as byte
end type
common shared cpu_state as t_cpu_state
dim shared interrupt_queue() as ubyte
dim shared interrupts_waiting as integer
declare sub init_cpu()
declare function cpu_get_cppc() as string
declare sub cpu()
...
...
@@ -327,4 +326,6 @@ declare function cpu_get_reg(register as ubyte) as ushort
declare sub cpu_push_byte(byteval as ubyte)
declare function cpu_pop_byte() as ubyte
declare sub cpu_push_word(wordval as ushort)
declare function cpu_pop_word() as ushort
\ No newline at end of file
declare function cpu_pop_word() as ushort
declare sub cpu_queue_interrupt(interrupt_number as ubyte)
declare sub cpu_process_interrupts()
\ No newline at end of file
error.bas
View file @
56cb49ab
...
...
@@ -15,4 +15,23 @@ sub machine_error(error_code as integer, severity as integer)
cpu_set_flag FL_HALT
end if
end sub
\ No newline at end of file
end sub
function error_string(error_code as integer) as string
select case error_code
case ERR_INVALID_PAGE_ID
return "invalid memory access (page out of bounds)"
case ERR_INVALID_OFFSET
return "invalid memory access (offset out of bounds)"
case ERR_DIVZERO
return "division by zero"
case ERR_INVALID_IOPORT
return "invalid I/O port"
case ERR_INVALID_DATA_TYPE
return "invalid data type in instruction operand"
end select
return "invalid error code"
end function
\ No newline at end of file
error.bi
View file @
56cb49ab
...
...
@@ -23,4 +23,5 @@
'
#define ERR_INVALID_DATA_TYPE 151
declare sub machine_error(error_code as integer, severity as integer)
\ No newline at end of file
declare sub machine_error(error_code as integer, severity as integer)
declare function error_string(error_code as integer) as string
\ No newline at end of file
ilxi.bas
View file @
56cb49ab
...
...
@@ -84,7 +84,7 @@ sub cli()
end if
st_save_page img_file, page_index
case "assemble"
case "assemble"
, "a"
dim le_origin as lexer_entry
dim origin_addr as ushort
...
...
@@ -116,10 +116,14 @@ sub cli()
asm_disassemble_range page_addr, start_offset_addr, da_count
case "step"
cpu_clear_flag FL_DEBUG
cpu_set_flag FL_DEBUG
cpu
case "step"
if cpu_get_flag(FL_HALT) = 0 then
if cpu_get_flag(FL_DEBUG) = 0 then cpu_set_flag FL_DEBUG
cpu
else
message_print "cli(): CPU is halted. Type 'reset' at the prompt before attempting 'step'."
end if
case "getr"
ilxi_getr get_lexer_entry(1).strval
case "setr"
...
...
@@ -217,8 +221,12 @@ sub cli()
case "ver"
print "ILXI 0.1"
case "run"
cpu_clear_flag FL_DEBUG
cpu
if cpu_get_flag(FL_HALT) = 0 then
cpu_clear_flag FL_DEBUG
cpu
else
message_print "cli(): CPU is halted. Type 'reset' at the prompt before attempting 'run'."
end if
case "reset"
init_cpu
case "exit"
...
...
@@ -231,7 +239,7 @@ sub cli()
end sub
sub ilxi_getr(register as string)
message_print ucase(register) & ": " & trim(
str
(cpu_get_reg_alpha(lcase(register))))
message_print ucase(register) & ": " & trim(
hex
(cpu_get_reg_alpha(lcase(register))))
end sub
sub ilxi_setr(register as string, value as integer)
...
...
inst.bas
View file @
56cb49ab
...
...
@@ -9,13 +9,14 @@
#include "ilxi.bi"
#include "error.bi"
#include "bus.bi"
#include "message.bi"
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
case NREG_LA, NREG_LB, NREG_LC, NREG_LD, NREG_LE, NREG_HA, NREG_HB, NREG_HC, NREG_HD, NREG_HE
return cubyte(cpu_get_reg(op.low_byte))
case else
machine_error ERR_INVALID_DATA_TYPE, 10
...
...
@@ -34,6 +35,12 @@ function inst_getbyte(op as t_operand, page as integer) as ubyte
return st_read_byte(page, ptr_val + op.displacement)
end if
elseif op.immediate = 1 then
#ifdef INSTDEBUG
message_print "inst_getbyte(): immediate " & hex(op.low_byte)
#endif
return op.low_byte
end if
...
...
@@ -45,7 +52,7 @@ function inst_getword(op as t_operand, page as integer) as ushort
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
case NREG_LA, NREG_LB, NREG_LC, NREG_LD, NREG_LE, NREG_HA, NREG_HB, NREG_HC, NREG_HD, NREG_HE
machine_error ERR_INVALID_DATA_TYPE, 10
case else
return cpu_get_reg(op.low_byte)
...
...
@@ -70,11 +77,12 @@ end function ' inst_getword()
sub inst_setbyte(op as t_operand, page as integer, value 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
case NREG_LA, NREG_LB, NREG_LC, NREG_LD, NREG_LE, NREG_HA, NREG_HB, NREG_HC, NREG_HD, NREG_HE
cpu_set_reg op.low_byte, value
case else
machine_error ERR_INVALID_DATA_TYPE, 10
...
...
@@ -101,13 +109,11 @@ end sub ' inst_setbyte()
sub inst_setword(op as t_operand, page as integer, value as ushort)
print "inst_setword(): "; value
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
case NREG_LA, NREG_LB, NREG_LC, NREG_LD, NREG_LE, NREG_HA, NREG_HB, NREG_HC, NREG_HD, NREG_HE
machine_error ERR_INVALID_DATA_TYPE, 10
exit sub
case else
...
...
@@ -388,6 +394,9 @@ sub inst_shl(dest as t_operand, count as t_operand)
end if
inst_setbyte dest, cpu_state.dp, cubyte(result)
if a2 >= 8 then cpu_set_flag FL_OVERFLOW
case DT_WORD
a1 = inst_getword(dest, cpu_state.dp)
a2 = inst_getword(count, cpu_state.dp)
...
...
@@ -399,10 +408,13 @@ sub inst_shl(dest as t_operand, count as t_operand)
end if
inst_setword dest, cpu_state.dp, cushort(result)
if a2 >= 16 then cpu_set_flag FL_OVERFLOW
end select
if result = 0 then cpu_set_flag FL_ZERO
end sub ' inst_shl()
sub inst_shr(dest as t_operand, count as t_operand)
...
...
@@ -432,6 +444,9 @@ sub inst_shr(dest as t_operand, count as t_operand)
end if
inst_setbyte dest, cpu_state.dp, cubyte(result)
if a2 >= 8 then cpu_set_flag FL_OVERFLOW
case DT_WORD
a1 = inst_getword(dest, cpu_state.dp)
a2 = inst_getword(count, cpu_state.dp)
...
...
@@ -443,6 +458,8 @@ sub inst_shr(dest as t_operand, count as t_operand)
end if
inst_setword dest, cpu_state.dp, cushort(result)
if a2 >= 16 then cpu_set_flag FL_OVERFLOW
end select
if result = 0 then cpu_set_flag FL_ZERO
...
...
@@ -713,11 +730,20 @@ sub inst_icall(dest as t_operand)
exit sub
end if
cpu_queue_interrupt inst_getbyte(dest, cpu_state.dp)
end sub ' inst_icall()
sub inst_sret()
cpu_state.pc = cpu_pop_word()
dim new_pc as ushort = cpu_pop_word()
#ifdef INSTDEBUG
message_print "inst_sret(): returning to " & hex(new_pc)
#endif
cpu_state.pc = new_pc
end sub ' inst_sret()
sub inst_lret()
...
...
@@ -797,4 +823,4 @@ end sub ' inst_out()
sub inst_hlt()
cpu_set_flag FL_HALT
end sub ' inst_hlt()
\ No newline at end of file
end sub ' inst_hlt()
message.bas
View file @
56cb49ab
...
...
@@ -4,6 +4,8 @@
#include "message.bi"
#include "console.bi"
#include "cpu.bi"
#include "asm.bi"
sub message_init()
...
...
pty.sh
0 → 100755
View file @
56cb49ab
#!/bin/bash
sudo
socat
-d
-d
pty,raw,echo
=
0,link
=
/dev/ilximcon pty,raw,echo
=
0,link
=
/dev/modem &
sudo chmod
777 /dev/pts/
*
rom.xa
View file @
56cb49ab
...
...
@@ -40,10 +40,7 @@ LABEL __rom_init
SCALL WORD {__term_print_string}
;;
;; HALT
;;
HLT
BRANCH WORD {__rom_init}
;; __term_print_string
;;
...
...
@@ -52,9 +49,12 @@ LABEL __term_print_string
;;
;; PRESERVE REGISTERS
;;
;PUSH WORD %SS
;PUSH WORD %DS
;PUSH WORD %DI
PUSH WORD %BP
COPY WORD %BP,%SO
PUSH WORD %SS
PUSH WORD %DS
PUSH WORD %DI
COPY WORD %DS,{VID_PAGE}
COPY WORD %DI,#{TERM_PTR}
...
...
@@ -66,9 +66,11 @@ LABEL __term_print_string
;;
;; RESTORE REGISTERS AND RETURN
;;
;POP WORD %DI
;POP WORD %DS
;POP WORD %SS
POP WORD %DI
POP WORD %DS
POP WORD %SS
POP WORD %BP
SRET
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment