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
03420914
Commit
03420914
authored
May 24, 2015
by
John P. Willis
Browse files
Some encoding working
parent
56692fcd
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
628 additions
and
252 deletions
+628
-252
Makefile
Makefile
+1
-1
asm.bas
asm.bas
+316
-0
cpu.bas
cpu.bas
+50
-43
cpu.bi
cpu.bi
+30
-25
ilxi.bas
ilxi.bas
+106
-85
lexer.bas
lexer.bas
+122
-95
lexer.bi
lexer.bi
+3
-3
No files found.
Makefile
View file @
03420914
OBJS
=
ilxi.o alu.o asm.o cpu.o error.o host.o storage.o lexer.o
FBCFLAGS
=
-g
FBCFLAGS
=
-g
#-d LEXDEBUG
ilxi
:
$(OBJS)
...
...
asm.bas
View file @
03420914
'
' asm.bas
'
' assembles instructions into dp:asm_offset
'
#include "asm.bi"
#include "cpu.bi"
#include "lexer.bi"
dim shared asm_offset as ushort = 0
function asm_encode_amod(ops_following as ubyte, amod as ubyte, disp as ubyte) as ubyte
' 7 6543 210
' +-+----+---+
' |O|MOD |DSP|
' +-+----+---+
' 1 6318 421
' 2 426
' 8
dim t as ubyte = 0
if ops_following = 1 then
t or= (1 shl 7)
end if
t or= (amod shl 3)
t or= (disp)
return t
end function
function asm_amod_following(amod as ubyte) as ubyte
return (amod and O_MASK) shr 7
end function
function asm_amod_amod(amod as ubyte) as ubyte
return (amod and AMOD_MASK) shr 4
end function
function asm_amod_disp(amod as ubyte) as ubyte
return (amod and DISP_MASK)
end function
function asm_encode_address(ops_following as ubyte, addr_string as string) as t_operand
'
' xxxx immediate
' %ga reg direct
' #xxxx mem direct
' (%ga) reg indirect
' (#xxxx) mem indirect
'
' Any of the last 4 with +xxxx appended indicates displacement;
' &H02-&HFF by powers of 2
'
dim byte_count as ubyte = 0
dim addr_part as string
dim addr_val as ushort
dim amod as ubyte
dim tmp as t_operand
dim is_immediate as ubyte = 0
dim is_register as ubyte = 0
dim is_memory as ubyte = 0
dim is_indirect as ubyte = 0
dim has_displacement as ubyte = 0
dim displacement as ubyte = 0
select case left(addr_string, 1)
case "%"
is_register = 1
addr_part = mid(addr_string, 2)
case "#"
is_memory = 1
addr_part = mid(addr_string, 2)
case "("
is_indirect = 1
select case mid(addr_string, 2, 1)
case "%"
is_register = 1
addr_part = mid(addr_string, 3)
addr_part = left(addr_part, instr(addr_part, ")") - 1)
case "#"
is_memory = 1
addr_part = mid(addr_string, 3)
addr_part = left(addr_part, instr(addr_part, ")") - 1)
end select
case else
is_immediate = 1
end select
if instr(addr_string, "+") > 0 then
has_displacement = 1
displacement = valint(mid(addr_string, instr(addr_string, "+") + 1))
select case displacement
case 2
displacement = 0
case 4
displacement = 1
case 8
displacement = 2
case 16
displacement = 3
case 32
displacement = 4
case 64
displacement = 5
case 128
displacement = 6
case 256
displacement = 7
end select
end if
if is_immediate = 1 then ' immediate
amod = asm_encode_amod(ops_following, AM_IMM, displacement)
elseif is_register = 1 then
if is_indirect = 1 then
if has_displacement = 1 then ' register indirect + displacement
amod = asm_encode_amod(ops_following, AM_REGID, displacement)
else ' reigster indirect, no displacement
amod = asm_encode_amod(ops_following, AM_REGI, displacement)
end if
else
if has_displacement = 1 then ' register direct + displacement
amod = asm_encode_amod(ops_following, AM_REGDD, displacement)
else ' register direct, no displacement
amod = asm_encode_amod(ops_following, AM_REGD, displacement)
end if
end if
elseif is_memory = 1 then
if is_indirect = 1 then
if has_displacement = 1 then ' memory indirect + displacement
amod = asm_encode_amod(ops_following, AM_MEMID, displacement)
else ' memory indirect, no displacement
amod = asm_encode_amod(ops_following, AM_MEMI, displacement)
end if
else
if has_displacement = 1 then ' memory direct + displacement
amod = asm_encode_amod(ops_following, AM_MEMDD, displacement)
else ' memory direct, no displacement
amod = asm_encode_amod(ops_following, AM_MEMD, displacement)
end if
end if
end if
if is_memory = 1 then
addr_val = valint(addr_part)
tmp.low_byte = addr_val and &HFF
tmp.high_byte = (addr_val and &HFF00) shr 8
if addr_val > 255 then
tmp.byte_count = 2
else
tmp.byte_count = 1
end if
elseif is_register = 1 then
addr_val = asm_encode_register(addr_part)
tmp.low_byte = addr_val
tmp.byte_count = 1
endif
tmp.amod = amod
return tmp
end function
function asm_encode_register(register_name as string) as ubyte
select case lcase(register_name)
case "pc"
return NREG_PC
case "ec"
return NREG_EC
case "es"
return NREG_ES
case "hf"
return NREG_HF
case "rf"
return NREG_RF
case "ei"
return NREG_EI
case "te"
return NREG_TE
case "pl"
return NREG_PL
case "cp"
return NREG_CP
case "dp"
return NREG_DP
case "sp"
return NREG_SP
case "so"
return NREG_SO
case "ga"
return NREG_GA
case "gb"
return NREG_GB
case "gc"
return NREG_GC
case "gd"
return NREG_GD
case "ge"
return NREG_GE
case "gf"
return NREG_GF
case "gg"
return NREG_GG
case "gh"
return NREG_GH
case "gi"
return NREG_GI
case "gj"
return NREG_GJ
case "gk"
return NREG_GK
case "gl"
return NREG_GL
case "gm"
return NREG_GM
case "gn"
return NREG_GN
case "go"
return NREG_GO
case "gp"
return NREG_GP
end select
end function
function asm_encode_opcode(instruction as string) as ubyte
select case lcase(instruction)
case "copy"
return OP_COPY
case "add"
return OP_ADD
case "sub"
return OP_SUB
case "mul"
return OP_MUL
case "div"
return OP_DIV
case "shl"
return OP_SHL
case "shr"
return OP_SHR
case "or"
return OP_OR
case "not"
return OP_NOT
case "and"
return OP_AND
case "xor"
return OP_XOR
case "eqv"
return OP_EQV
case "eq"
return OP_EQ
case "ne"
return OP_NE
case "gt"
return OP_GT
case "lt"
return OP_LT
case "ge"
return OP_GE
case "le"
return OP_LE
case "branch"
return OP_BRANCH
case "beq"
return OP_BEQ
case "bne"
return OP_BNE
case "ble"
return OP_BLE
case "bge"
return OP_BGE
case "blt"
return OP_BLT
case "bgt"
return OP_BGT
case "scall"
return OP_SCALL
case "lcall"
return OP_LCALL
case "icall"
return OP_ICALL
case "sret"
return OP_SRET
case "lret"
return OP_LRET
case "iret"
return OP_IRET
case "push"
return OP_PUSH
case "pop"
return OP_POP
case "nop"
return OP_NOP
case "hlt"
return OP_HLT
end select
end function
sub asm_assemble(instruction as string)
end sub
sub asm_assemble_interactive(origin_address as ushort)
end sub
\ No newline at end of file
cpu.bas
View file @
03420914
...
...
@@ -9,43 +9,44 @@
'
#include "cpu.bi"
#include "storage.bi"
#include "asm.bi"
sub init_cpu()
with cpu_state
.pc = 0
.ec = 0
.es = 0
.hf = 0
.rf = 0
.ei = 1
.te = 0
.pl = 0
.cp = 0
.dp = 0
.sp = 0
.so = 0
.ga = 0
.gb = 0
.gc = 0
.gd = 0
.ge = 0
.gf = 0
.gg = 0
.gh = 0
.gi = 0
.gj = 0
.gk = 0
.gl = 0
.gm = 0
.gn = 0
.go = 0
.gp = 0
end with
with cpu_state
.pc = 0
.ec = 0
.es = 0
.hf = 0
.rf = 0
.ei = 1
.te = 0
.pl = 0
.cp = 0
.dp = 0
.sp = 0
.so = 0
.ga = 0
.gb = 0
.gc = 0
.gd = 0
.ge = 0
.gf = 0
.gg = 0
.gh = 0
.gi = 0
.gj = 0
.gk = 0
.gl = 0
.gm = 0
.gn = 0
.go = 0
.gp = 0
end with
end sub
sub cpu()
...
...
@@ -58,17 +59,23 @@ sub cpu()
dim dst as integer
dim inst_size as ubyte
dim tmp as t_operand
tmp = asm_encode_address(1, "%ga")
tmp = asm_encode_address(1, "#05")
tmp = asm_encode_address(1, "#1024")
tmp = asm_encode_address(1, "(%ga)+4")
tmp = asm_encode_address(1, "(#05)+4")
tmp = asm_encode_address(1, "(#1024)+4")
cpu_state.hf = 0
do
opcode = cpu_fetch()
opcode = cpu_fetch()
inst_size = cpu_decode(opcode)
select case opcode
case OP_LOAD
case OP_STORE
case OP_COPY
case OP_ADD
...
...
@@ -142,7 +149,7 @@ sub cpu()
end select
if cpu_state.pc >= PAGESIZE then
if cpu_state.pc >=
(
PAGESIZE
- 1)
then
cpu_state.hf = 1
cpu_state.ec = 0
cpu_state.es = 0
...
...
@@ -195,7 +202,7 @@ sub cpu_dump_state()
print ""
end sub
sub cpu_set_reg_alpha(register as string, value as
integer
)
sub cpu_set_reg_alpha(register as string, value as
ushort
)
select case register
case REG_PC
...
...
@@ -257,7 +264,7 @@ sub cpu_set_reg_alpha(register as string, value as integer)
end select
end sub
function cpu_get_reg_alpha(register as string) as
integer
function cpu_get_reg_alpha(register as string) as
ushort
select case register
case REG_PC
...
...
cpu.bi
View file @
03420914
...
...
@@ -12,24 +12,26 @@
' |BYTE 1 | BYTE 2 |BYTE 3 |
' +--------+----------+--------+
'
' OPCODE (instruction opcode) 0-255
' O (operands following) 0 = no operands following; 1 = 1 operand following
' MOD (addressing mode)
' 0000 = immediate
' 0001 = register direct
' 0010 = memory direct
' 0011 = register indirect
' 0100 = memory indirect
' 0101 = register indirect + displacement
' 0110 = memory indirect + displacement
' DISP 000 = 2 bytes displacement
' 001 = 4 bytes displacement
' 010 = 8 bytes displacement
' 011 = 16 bytes displacement
' 100 = 32 bytes displacement
' 101 = 64 bytes displacement
' 110 = 128 bytes displacement
' 111 = 256 bytes displacement
' OPCODE (instruction opcode) 0-255
' O (operands following) 0 = no operands following; 1 = 1 operand following
' MOD (addressing mode)
' 0 0000 = immediate
' 1 0001 = register direct
' 2 0010 = memory direct
' 3 0011 = register direct + displacement
' 4 0100 = memory direct + displacement
' 5 0101 = register indirect
' 6 0110 = memory indirect
' 7 0111 = register indirect + displacement
' 8 1000 = memory indirect + displacement
' DISP 0 000 = 2 bytes displacement
' 1 001 = 4 bytes displacement
' 2 010 = 8 bytes displacement
' 3 011 = 16 bytes displacement
' 4 100 = 32 bytes displacement
' 5 101 = 64 bytes displacement
' 6 110 = 128 bytes displacement
' 7 111 = 256 bytes displacement
'
' BYTE 1 is the OPCODE byte
' BYTE 2 is the AMOD byte for the first operand, describing
...
...
@@ -98,10 +100,12 @@
#define AM_IMM 0
#define AM_REGD 1
#define AM_MEMD 2
#define AM_REGI 3
#define AM_MEMI 4
#define AM_REGID 5
#define AM_MEMID 6
#define AM_REGDD 3
#define AM_MEMDD 4
#define AM_REGI 5
#define AM_MEMI 6
#define AM_REGID 7
#define AM_MEMID 8
'
' addressing displacements; 4 most significant bits
...
...
@@ -196,7 +200,8 @@
#define NREG_GO 54
#define NREG_GP 55
type t_cpu_state
type t_cpu_state
pc as ushort 'program counter
ec as ushort 'error code
...
...
@@ -226,7 +231,7 @@ type t_cpu_state
gl as ushort 'general l
gm as ushort 'general m
gn as ushort 'general n
go as ushort
'general o
go as ushort 'general o
gp as ushort 'general p
end type
...
...
@@ -248,4 +253,4 @@ declare sub cpu_dump_state()
declare function cpu_fetch() as ubyte
declare function cpu_decode(opcode as ubyte) 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
\ No newline at end of file
declare function cpu_get_reg_alpha(register as string) as ushort
ilxi.bas
View file @
03420914
'
' ilxi.bas
'
#include "ilxi.bi"
#include "cpu.bi"
#include "lexer.bi"
#include "storage.bi"
#include "asm.bi"
startup
sub startup()
print "ILXI Virtual Machine"
print "ILXI
M
Virtual Machine"
print " Copyright (C) 2015 Coherent Logic Development LLC"
print ""
...
...
@@ -16,109 +22,124 @@ sub startup()
end sub
sub cli()
dim cli_cmd as string
dim cmd_name as string
dim trace as integer
dim arg_count as integer = 0
trace = 0
do
line input "ilxi> ", cli_cmd
arg_count = lex(cli_cmd)
cmd_name = get_lexer_entry(0).strval
select case cmd_name
case "getr"
ilxi_getr get_lexer_entry(1).strval
case "setr"
line input "ilxim> ", cli_cmd
arg_count = lex(cli_cmd)
cmd_name = get_lexer_entry(0).strval
select case cmd_name
case "assemble"
dim le_origin as lexer_entry
dim origin_addr as ushort
if get_lexer_entry(1).lexer_class = LC_BYTE then
origin_addr = get_lexer_entry(1).byteval
else
origin_addr = get_lexer_entry(1).intval
end if
asm_assemble_interactive origin_addr
case "getr"
ilxi_getr get_lexer_entry(1).strval
case "setr"
dim regval as integer
if get_lexer_entry(2).lexer_class = LC_BYTE then
regval = get_lexer_entry(2).byteval
elseif get_lexer_entry(2).lexer_class = LC_INT then
regval = get_lexer_entry(2).intval
end if
if get_lexer_entry(2).lexer_class = LC_BYTE then
regval = get_lexer_entry(2).byteval
elseif get_lexer_entry(2).lexer_class = LC_INT then
regval = get_lexer_entry(2).intval
end if
ilxi_setr get_lexer_entry(1).strval, regval
case "getm"
dim le_from as lexer_entry
dim le_to as lexer_entry
dim m_from as integer
dim m_to as integer
case "getm"
dim le_from as lexer_entry
dim le_to as lexer_entry
dim m_from as integer
dim m_to as integer
le_from = get_lexer_entry(1)
le_to = get_lexer_entry(2)
if le_from.lexer_class = LC_BYTE then
m_from = le_from.byteval
else
m_from = le_from.intval
end if
if le_to.lexer_class = LC_BYTE then
m_to = le_to.byteval
else
m_to = le_to.intval
end if
le_from = get_lexer_entry(1)
le_to = get_lexer_entry(2)
if le_from.lexer_class = LC_BYTE then
m_from = le_from.byteval
else
m_from = le_from.intval
end if
if le_to.lexer_class = LC_BYTE then
m_to = le_to.byteval
else
m_to = le_to.intval
end if
dim i as integer
dim k as integer
for i = m_from to m_to step 8
print
print trim(ilxi_pad_left(hex(cpu_state.dp), "0", 4)); ":";
print trim(ilxi_pad_left(hex(i), "0", 4)),
for k = i to i + 7
print ilxi_pad_left(hex(st_read_byte(cpu_state.dp, k)), "0", 2); " ";