Commit 56692fcd authored by John P. Willis's avatar John P. Willis
Browse files

Defined the instruction format

parent 7e535c46
......@@ -49,14 +49,14 @@ sub init_cpu()
end sub
sub cpu()
dim opcode as byte
dim srcmod as byte
dim srcbytes as byte
dim opcode as ubyte
dim srcmod as ubyte
dim srcbytes as ubyte
dim src as integer
dim dstmod as byte
dim dstbytes as byte
dim dstmod as ubyte
dim dstbytes as ubyte
dim dst as integer
dim inst_size as byte
dim inst_size as ubyte
cpu_state.hf = 0
......@@ -66,9 +66,77 @@ sub cpu()
select case opcode
case 0 'NOP
case OP_LOAD
case OP_STORE
case OP_ADD
case OP_SUB
case OP_MUL
case OP_DIV
case OP_SHL
case OP_SHR
case OP_OR
case OP_NOT
case OP_AND
case OP_XOR
case OP_EQV
case OP_EQ
case OP_NE
case OP_GT
case OP_LT
case OP_GE
case OP_LE
case OP_BRANCH
case OP_BEQ
case OP_BNE
case OP_BLE
case OP_BGE
case OP_BLT
case OP_BGT
case OP_SCALL
case OP_LCALL
case OP_ICALL
case OP_SRET
case OP_LRET
case OP_IRET
case OP_PUSH
case OP_POP
case OP_NOP
case 1 'HLT
case OP_HLT
cpu_state.hf = 1
case else
......@@ -100,11 +168,11 @@ sub cpu()
end sub
function cpu_fetch() as byte
function cpu_fetch() as ubyte
return st_read_byte(cpu_state.cp, cpu_state.pc)
end function
function cpu_decode(opcode as byte) as byte
function cpu_decode(opcode as ubyte) as ubyte
return 1
end function
......@@ -127,7 +195,7 @@ sub cpu_dump_state()
print ""
end sub
sub cpu_set_reg_alpha(register as string, value as byte)
sub cpu_set_reg_alpha(register as string, value as integer)
select case register
case REG_PC
......@@ -189,7 +257,7 @@ sub cpu_set_reg_alpha(register as string, value as byte)
end select
end sub
function cpu_get_reg_alpha(register as string) as byte
function cpu_get_reg_alpha(register as string) as integer
select case register
case REG_PC
......
......@@ -2,6 +2,128 @@
' cpu.bi
'
'
' Instruction Format
'
'PC + 0 7 8 9 C D F 10
' +--------+-+----+---+--------+
' |OPCODE |O|MOD |DSP|OPERAND |
' +--------+-+----+---+--------+
' |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
'
' BYTE 1 is the OPCODE byte
' BYTE 2 is the AMOD byte for the first operand, describing
' its addressing mode. If the addressing mode is one of the register modes,
' the operand will be one byte. If the addressing mode is a memory address,
' the operand will be two bytes.
'
' The end of an instruction is indicated by a zero in the most significant bit of
' the AMOD byte of a given operand.
'
' Example:
'
' STORE GA, [CP]+2
'
' opcodes
'
#define OP_DATA 000
#define OP_COPY 001
#define OP_ADD 003
#define OP_SUB 004
#define OP_MUL 005
#define OP_DIV 006
#define OP_SHL 007
#define OP_SHR 008
#define OP_OR 009
#define OP_NOT 010
#define OP_AND 011
#define OP_XOR 012
#define OP_EQV 013
#define OP_EQ 014
#define OP_NE 015
#define OP_GT 016
#define OP_LT 017
#define OP_GE 018
#define OP_LE 019
#define OP_BRANCH 020
#define OP_BEQ 021
#define OP_BNE 022
#define OP_BLE 023
#define OP_BGE 024
#define OP_BLT 025
#define OP_BGT 026
#define OP_SCALL 027
#define OP_LCALL 028
#define OP_ICALL 029
#define OP_SRET 030
#define OP_LRET 031
#define OP_IRET 032
#define OP_PUSH 033
#define OP_POP 034
#define OP_NOP 254
#define OP_HLT 255
'
' addressing modes; 4 least significant bits
'
#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
'
' addressing displacements; 4 most significant bits
'
#define AM_DISP1 0
#define AM_DISP2 1
#define AM_DISP3 2
#define AM_DISP4 3
#define AM_DISP5 4
#define AM_DISP6 5
#define AM_DISP7 6
#define AM_DISP8 7
#define AM_DISP9 8
#define AM_DISP10 9
#define AM_DISP11 10
#define AM_DISP12 11
#define AM_DISP13 12
#define AM_DISP14 13
#define AM_DISP15 14
#define AM_DISP16 15
'
' register names (string)
'
......@@ -75,37 +197,47 @@
#define NREG_GP 55
type t_cpu_state
pc as integer 'program counter
ec as integer 'error code
es as integer 'error severity
hf as integer 'halt flag
rf as integer 'result flag
ei as integer 'enable interrupts
te as integer 'trace enable
pl as integer 'privilege level
cp as integer 'code page
dp as integer 'data page
sp as integer 'stack page
so as integer 'stack offset
ga as integer 'general a
gb as integer 'general b
gc as integer 'general c
gd as integer 'general d
ge as integer 'general e
gf as integer 'general f
gg as integer 'general g
gh as integer 'general h
gi as integer 'general i
gj as integer 'general j
gk as integer 'general k
gl as integer 'general l
gm as integer 'general m
gn as integer 'general n
go as integer 'general o
gp as integer 'general p
pc as ushort 'program counter
ec as ushort 'error code
es as ushort 'error severity
hf as ushort 'halt flag
rf as ushort 'result flag
ei as ushort 'enable interrupts
te as ushort 'trace enable
pl as ushort 'privilege level
cp as ushort 'code page
dp as ushort 'data page
sp as ushort 'stack page
so as ushort 'stack offset
ga as ushort 'general a
gb as ushort 'general b
gc as ushort 'general c
gd as ushort 'general d
ge as ushort 'general e
gf as ushort 'general f
gg as ushort 'general g
gh as ushort 'general h
gi as ushort 'general i
gj as ushort 'general j
gk as ushort 'general k
gl as ushort 'general l
gm as ushort 'general m
gn as ushort 'general n
go as ushort 'general o
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
......@@ -113,7 +245,7 @@ common shared cpu_state as t_cpu_state
declare sub init_cpu()
declare sub cpu()
declare sub cpu_dump_state()
declare function cpu_fetch() as byte
declare function cpu_decode(opcode as byte) as byte
declare sub cpu_set_reg_alpha(register as string, value as byte)
declare function cpu_get_reg_alpha(register as string) as byte
\ No newline at end of file
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
#include "ilxi.bi"
#include "cpu.bi"
#include "lexer.bi"
#include "storage.bi"
startup
sub startup()
......@@ -31,20 +31,83 @@ sub cli()
cmd_name = get_lexer_entry(0).strval
select case cmd_name
case "gr"
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
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 "dumpcpu"
cpu_dump_state
case "trace"
if trace = 0 then
trace = 1
print "trace on"
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
trace = 0
print "trace off"
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); " ";
next k
print " | ";
for k = i to i + 7
if st_read_byte(cpu_state.dp, k) = 0 then print ".";
if st_read_byte(cpu_state.dp, k) > 0 then print chr(st_read_byte(cpu_state.dp, k));
next k
next i
print
print
case "setm"
dim le_setm_addr as lexer_entry
dim le_setm_value as lexer_entry
dim setm_addr as integer
dim setm_value as integer
le_setm_addr = get_lexer_entry(1)
le_setm_value = get_lexer_entry(2)
cpu_state.te = trace
if le_setm_addr.lexer_class = LC_BYTE then
setm_addr = le_setm_addr.byteval
else
setm_addr = le_setm_addr.intval
end if
setm_value = le_setm_value.byteval
st_write_byte cpu_state.dp, setm_addr, setm_value
case "dumpcpu"
cpu_dump_state
case "trace"
cpu_state.te = get_lexer_entry(1).byteval
case "ver"
print "ILXI 0.1"
case "run"
......@@ -57,4 +120,28 @@ sub cli()
end select
loop until cli_cmd = "exit"
end sub
\ No newline at end of file
end sub
sub ilxi_getr(register as string)
print ucase(register); ": "; trim(str(cpu_get_reg_alpha(lcase(register))))
end sub
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
'
' ilxi.bi
'
declare sub startup()
declare sub cli()
\ No newline at end of file
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
......@@ -14,8 +14,6 @@ function lex(input_str as string) as integer
dim tmp_int as integer
dim tmp_float as double
dim in_quoted_string as integer = 0
dim recog_state as byte = LC_UNKNOWN
lex_reset_storage
......
......@@ -21,7 +21,7 @@ type lexer_entry
intval as integer
floatval as double
byteval as byte
byteval as ubyte
strval as string
end type
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment