Added carry flag and status register
This commit is contained in:
parent
164dc59dde
commit
24ee0b935a
2 changed files with 105 additions and 61 deletions
|
@ -32,7 +32,6 @@ module Hence
|
|||
data.reg_a = 0_u16
|
||||
data.reg_b = 0_u16
|
||||
data.reg_c = 0_u16
|
||||
data.reg_d = 0_u16
|
||||
end
|
||||
|
||||
data
|
||||
|
@ -54,7 +53,7 @@ module Hence
|
|||
property reg_a
|
||||
property reg_b
|
||||
property reg_c
|
||||
property reg_d
|
||||
property reg_s
|
||||
property reg_inp
|
||||
property reg_out
|
||||
|
||||
|
@ -75,7 +74,7 @@ module Hence
|
|||
@reg_a = 0_u16,
|
||||
@reg_b = 0_u16,
|
||||
@reg_c = 0_u16,
|
||||
@reg_d = 0_u16,
|
||||
@reg_s = 0_u8,
|
||||
@reg_inp = 0_u16,
|
||||
@reg_out = 0_u16,
|
||||
@stack = Slice(UInt16).new({{ 8 * 1024 }}),
|
||||
|
@ -112,7 +111,7 @@ module Hence
|
|||
when 0xc_u8
|
||||
@reg_c
|
||||
when 0xd_u8
|
||||
@reg_d
|
||||
@reg_s.to_u16
|
||||
when 0xe_u8
|
||||
@reg_inp
|
||||
when 0xf_u8
|
||||
|
@ -151,7 +150,7 @@ module Hence
|
|||
when 0xc_u8
|
||||
@reg_c = value
|
||||
when 0xd_u8
|
||||
@reg_d = value
|
||||
@reg_s = value
|
||||
when 0xe_u8
|
||||
@reg_inp = value
|
||||
when 0xf_u8
|
||||
|
@ -162,63 +161,75 @@ module Hence
|
|||
end
|
||||
|
||||
def alu(op : UInt8) : UInt16
|
||||
@reg_tmp =
|
||||
case op
|
||||
when 0x00 # not
|
||||
~@reg_a
|
||||
when 0x01 # and
|
||||
@reg_a & @reg_b
|
||||
when 0x02 # nand
|
||||
~(@reg_a & @reg_b)
|
||||
when 0x03 # or
|
||||
@reg_a | @reg_b
|
||||
when 0x04 # nor
|
||||
~(@reg_a | @reg_b)
|
||||
when 0x05 # xor
|
||||
@reg_a ^ @reg_b
|
||||
when 0x06 # xnor
|
||||
~(@reg_a ^ @reg_b)
|
||||
when 0x07 # shl
|
||||
@reg_a << @reg_b
|
||||
when 0x08 # shr
|
||||
@reg_a >> @reg_b
|
||||
when 0x09 # add
|
||||
@reg_a &+ @reg_b
|
||||
when 0x0a # sub
|
||||
@reg_a &- @reg_b
|
||||
when 0x0b # mul
|
||||
@reg_a &* @reg_b
|
||||
when 0x0c # div
|
||||
@reg_a // @reg_b
|
||||
when 0x0d # mod
|
||||
@reg_a % @reg_b
|
||||
when 0x0e # cmp
|
||||
if @reg_a < @reg_b
|
||||
1_u16
|
||||
elsif @reg_a > @reg_b
|
||||
2_u16
|
||||
else
|
||||
0_u16
|
||||
end
|
||||
when 0x0f # eq
|
||||
@reg_a == @reg_b ? 1_u16 : 0_u16
|
||||
when 0x10 # neq
|
||||
@reg_a != @reg_b ? 1_u16 : 0_u16
|
||||
when 0x11 # lt
|
||||
@reg_a < @reg_b ? 1_u16 : 0_u16
|
||||
when 0x12 # gt
|
||||
@reg_a > @reg_b ? 1_u16 : 0_u16
|
||||
when 0x13 # leq
|
||||
@reg_a <= @reg_b ? 1_u16 : 0_u16
|
||||
when 0x14 # geq
|
||||
@reg_a >= @reg_b ? 1_u16 : 0_u16
|
||||
when 0x15 # bol
|
||||
@reg_a == 1 ? 1_u16 : 0_u16
|
||||
when 0x16 # neg
|
||||
@reg_a == 1 ? 0_u16 : 1_u16
|
||||
else
|
||||
raise "Invalid ALU operation: 0x#{op.to_s(16).rjust(2, '0')}"
|
||||
case op
|
||||
when 0x00 # not
|
||||
@reg_tmp = ~@reg_a
|
||||
when 0x01 # and
|
||||
@reg_tmp = @reg_a & @reg_b
|
||||
when 0x02 # nand
|
||||
@reg_tmp = ~(@reg_a & @reg_b)
|
||||
when 0x03 # or
|
||||
@reg_tmp = @reg_a | @reg_b
|
||||
when 0x04 # nor
|
||||
@reg_tmp = ~(@reg_a | @reg_b)
|
||||
when 0x05 # xor
|
||||
@reg_tmp = @reg_a ^ @reg_b
|
||||
when 0x06 # xnor
|
||||
@reg_tmp = ~(@reg_a ^ @reg_b)
|
||||
when 0x07 # shl
|
||||
@reg_tmp = @reg_a << @reg_b
|
||||
when 0x08 # shr
|
||||
@reg_tmp = @reg_a >> @reg_b
|
||||
when 0x09 # add
|
||||
@reg_tmp = @reg_a &+ @reg_b
|
||||
@reg_s &= 0b11111110_u8
|
||||
if @reg_tmp < @reg_a
|
||||
@reg_s |= 0b00000001_u8
|
||||
end
|
||||
when 0x0a # sub
|
||||
@reg_tmp = @reg_a &- @reg_b
|
||||
@reg_s &= 0b11111110_u8
|
||||
if @reg_tmp > @reg_a
|
||||
@reg_s |= 0b00000001_u8
|
||||
end
|
||||
when 0x0b # mul
|
||||
@reg_tmp = @reg_a &* @reg_b
|
||||
@reg_s &= 0b11111110_u8
|
||||
when 0x0c # div
|
||||
@reg_tmp = @reg_a // @reg_b
|
||||
@reg_s &= 0b11111110_u8
|
||||
when 0x0d # mod
|
||||
@reg_tmp = @reg_a % @reg_b
|
||||
@reg_s &= 0b11111110_u8
|
||||
when 0x0e # cmp
|
||||
@reg_tmp = if @reg_a < @reg_b
|
||||
1_u16
|
||||
elsif @reg_a > @reg_b
|
||||
2_u16
|
||||
else
|
||||
0_u16
|
||||
end
|
||||
when 0x0f # eq
|
||||
@reg_tmp = @reg_a == @reg_b ? 1_u16 : 0_u16
|
||||
when 0x10 # neq
|
||||
@reg_tmp = @reg_a != @reg_b ? 1_u16 : 0_u16
|
||||
when 0x11 # lt
|
||||
@reg_tmp = @reg_a < @reg_b ? 1_u16 : 0_u16
|
||||
when 0x12 # gt
|
||||
@reg_tmp = @reg_a > @reg_b ? 1_u16 : 0_u16
|
||||
when 0x13 # leq
|
||||
@reg_tmp = @reg_a <= @reg_b ? 1_u16 : 0_u16
|
||||
when 0x14 # geq
|
||||
@reg_tmp = @reg_a >= @reg_b ? 1_u16 : 0_u16
|
||||
when 0x15 # bol
|
||||
@reg_tmp = @reg_a == 1 ? 1_u16 : 0_u16
|
||||
when 0x16 # neg
|
||||
@reg_tmp = @reg_a == 1 ? 0_u16 : 1_u16
|
||||
else
|
||||
raise "Invalid ALU operation: 0x#{op.to_s(16).rjust(2, '0')}"
|
||||
end
|
||||
|
||||
@reg_tmp
|
||||
end
|
||||
|
||||
def get_memory(address : UInt16) : UInt16
|
||||
|
|
|
@ -71,6 +71,39 @@ sections:
|
|||
tmpl 0xa
|
||||
tmpsr 0xc
|
||||
tmplc 0x0
|
||||
- name: sts
|
||||
description: Pushes value of status register to stack
|
||||
opcode: null
|
||||
arg: null
|
||||
stack:
|
||||
input: []
|
||||
output: ["status"]
|
||||
microcode: |
|
||||
tmpsr 0xd
|
||||
push
|
||||
- name: cls
|
||||
description: Clears status register
|
||||
opcode: null
|
||||
arg: null
|
||||
stack:
|
||||
input: []
|
||||
output: []
|
||||
microcode: |
|
||||
tmpl 0xd
|
||||
- name: car
|
||||
description: Pushes first bit of status register to stack
|
||||
opcode: null
|
||||
arg: null
|
||||
stack:
|
||||
input: []
|
||||
output: ["carry"]
|
||||
microcode: |
|
||||
tmpsr 0xd
|
||||
tmpl 0xa
|
||||
tmps 0b00000001
|
||||
tmpl 0xb
|
||||
alu 0x01
|
||||
push
|
||||
- name: stack-manipulation
|
||||
description: Stack manipulation
|
||||
opcodes:
|
||||
|
|
Loading…
Reference in a new issue