From 24ee0b935aa2e47c22d0fb31879e3e4e2b2e61cf Mon Sep 17 00:00:00 2001 From: Dominic Grimm Date: Sat, 9 Jul 2022 17:29:42 +0200 Subject: [PATCH] Added carry flag and status register --- src/hence/emulator.cr | 133 ++++++++++++----------- src/hence/firmware/firmwares/default.yml | 33 ++++++ 2 files changed, 105 insertions(+), 61 deletions(-) diff --git a/src/hence/emulator.cr b/src/hence/emulator.cr index 269d1fd..7308981 100644 --- a/src/hence/emulator.cr +++ b/src/hence/emulator.cr @@ -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 diff --git a/src/hence/firmware/firmwares/default.yml b/src/hence/firmware/firmwares/default.yml index 2f67f1e..7652970 100644 --- a/src/hence/firmware/firmwares/default.yml +++ b/src/hence/firmware/firmwares/default.yml @@ -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: