mirror of
https://github.com/mikpe/pdp10-tools.git
synced 2026-01-22 02:26:24 +00:00
sim: sim_shifts: handle ROT/ROTC, add unit tests
This commit is contained in:
parent
82ee356c37
commit
edf7257d21
@ -280,7 +280,9 @@ dispatch(Core, Mem, IR, EA) ->
|
||||
8#215 -> sim_moves:handle_MOVEI(Core, Mem, IR, EA); % MOVMI = MOVEI
|
||||
8#216 -> sim_moves:handle_MOVMM(Core, Mem, IR, EA);
|
||||
8#217 -> sim_moves:handle_MOVMS(Core, Mem, IR, EA);
|
||||
8#241 -> sim_shifts:handle_ROT(Core, Mem, IR, EA);
|
||||
8#242 -> sim_shifts:handle_LSH(Core, Mem, IR, EA);
|
||||
8#245 -> sim_shifts:handle_ROTC(Core, Mem, IR, EA);
|
||||
8#246 -> sim_shifts:handle_LSHC(Core, Mem, IR, EA);
|
||||
8#250 -> sim_moves:handle_EXCH(Core, Mem, IR, EA);
|
||||
8#251 -> sim_moves:handle_BLT(Core, Mem, IR, EA);
|
||||
|
||||
@ -26,6 +26,8 @@
|
||||
|
||||
-export([ handle_LSH/4
|
||||
, handle_LSHC/4
|
||||
, handle_ROT/4
|
||||
, handle_ROTC/4
|
||||
]).
|
||||
|
||||
-include("sim_core.hrl").
|
||||
@ -53,6 +55,27 @@ handle_LSHC(Core, Mem, IR, EA) ->
|
||||
{Word0, Word1} = lshc(CA0, CA1, EA#ea.offset),
|
||||
set_acs_next_pc(Core, Mem, AC, Word0, Word1).
|
||||
|
||||
%% ROT - Rotate
|
||||
|
||||
-spec handle_ROT(#core{}, sim_mem:mem(), IR :: word(), #ea{})
|
||||
-> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
|
||||
handle_ROT(Core, Mem, IR, EA) ->
|
||||
AC = IR band 8#17,
|
||||
CA = sim_core:get_ac(Core, AC),
|
||||
Word = rot(CA, EA#ea.offset),
|
||||
set_ac_next_pc(Core, Mem, AC, Word).
|
||||
|
||||
%% ROTC - Rotate Combined
|
||||
|
||||
-spec handle_ROTC(#core{}, sim_mem:mem(), IR :: word(), #ea{})
|
||||
-> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
|
||||
handle_ROTC(Core, Mem, IR, EA) ->
|
||||
AC = IR band 8#17,
|
||||
CA0 = sim_core:get_ac(Core, AC),
|
||||
CA1 = sim_core:get_ac(Core, (AC + 1) band 8#17),
|
||||
{Word0, Word1} = rotc(CA0, CA1, EA#ea.offset),
|
||||
set_acs_next_pc(Core, Mem, AC, Word0, Word1).
|
||||
|
||||
%% Miscellaneous ===============================================================
|
||||
|
||||
lsh(CA, Offset) ->
|
||||
@ -98,6 +121,44 @@ lshc(CA0, CA1, Offset) ->
|
||||
end
|
||||
end.
|
||||
|
||||
rot(CA, Offset) ->
|
||||
case Offset band (1 bsl 17) of
|
||||
0 -> % rotate left
|
||||
Count = (Offset band ((1 bsl 8) - 1)) rem 36,
|
||||
((CA band ((1 bsl (36 - Count)) - 1)) bsl Count) bor (CA bsr (36 - Count));
|
||||
_ -> % rotate right
|
||||
Count = ((-Offset) band ((1 bsl 8) - 1)) rem 36,
|
||||
(CA bsr Count) bor ((CA band ((1 bsl Count) - 1)) bsl (36 - Count))
|
||||
end.
|
||||
|
||||
rotc(CA0, CA1, Offset) ->
|
||||
case Offset band (1 bsl 17) of
|
||||
0 -> % rotate left
|
||||
Count = (Offset band ((1 bsl 8) - 1)) rem 72,
|
||||
if Count >= 36 ->
|
||||
Count1 = Count - 36,
|
||||
Word0 = ((CA1 band ((1 bsl (36 - Count1)) - 1)) bsl Count1) bor (CA0 bsr (36 - Count1)),
|
||||
Word1 = ((CA0 band ((1 bsl (36 - Count1)) - 1)) bsl Count1) bor (CA1 bsr (36 - Count1)),
|
||||
{Word0, Word1};
|
||||
true ->
|
||||
Word0 = ((CA0 band ((1 bsl (36 - Count)) - 1)) bsl Count) bor (CA1 bsr (36 - Count)),
|
||||
Word1 = ((CA1 band ((1 bsl (36 - Count)) - 1)) bsl Count) bor (CA0 bsr (36 - Count)),
|
||||
{Word0, Word1}
|
||||
end;
|
||||
_ -> % rotate right
|
||||
Count = ((-Offset) band ((1 bsl 8) - 1)) rem 72,
|
||||
if Count >= 36 ->
|
||||
Count1 = Count - 36,
|
||||
Word0 = (CA1 bsr Count1) bor ((CA0 band ((1 bsl Count1) - 1)) bsl (36 - Count1)),
|
||||
Word1 = (CA0 bsr Count1) bor ((CA1 band ((1 bsl Count1) - 1)) bsl (36 - Count1)),
|
||||
{Word0, Word1};
|
||||
true ->
|
||||
Word0 = (CA0 bsr Count) bor ((CA1 band ((1 bsl Count) - 1)) bsl (36 - Count)),
|
||||
Word1 = (CA1 bsr Count) bor ((CA0 band ((1 bsl Count) - 1)) bsl (36 - Count)),
|
||||
{Word0, Word1}
|
||||
end
|
||||
end.
|
||||
|
||||
set_acs_next_pc(Core, Mem, AC, Word0, Word1) ->
|
||||
set_ac_next_pc(sim_core:set_ac(Core, AC, Word0), Mem, (AC + 1) band 8#17, Word1).
|
||||
|
||||
|
||||
@ -46,7 +46,9 @@
|
||||
|
||||
-define(INSN_INVALID, ?INSN(0, 0, 0, 0, 0)).
|
||||
|
||||
-define(OP_ROT, 8#241).
|
||||
-define(OP_LSH, 8#242).
|
||||
-define(OP_ROTC, 8#245).
|
||||
-define(OP_LSHC, 8#246).
|
||||
|
||||
%% 2.5 Shift and Rotate ========================================================
|
||||
@ -112,6 +114,67 @@ lshc_test() ->
|
||||
, {?AC(2), ?COMMA2(8#000000, 8#111222)} % AC2 = 000000111222
|
||||
]).
|
||||
|
||||
%% ROT - Rotate
|
||||
|
||||
rot_test() ->
|
||||
ACS =
|
||||
[ {1, ?COMMA2(8#111222, 8#333444)} % AC1 = 111222333444
|
||||
],
|
||||
Prog1 =
|
||||
[ {1, 8#100, ?INSN(?OP_ROT, 1, 0, 0, 36+9)} % 1,,100/ ROT 1,55
|
||||
, {1, 8#101, ?INSN_INVALID} % 1,,101/ <invalid>
|
||||
],
|
||||
expect(Prog1, ACS, {1, 8#101}, ?DEFAULT_FLAGS,
|
||||
[ {?AC(1), ?COMMA2(8#222333, 8#444111)} % AC1 = 222333444111
|
||||
]),
|
||||
Prog2 =
|
||||
[ {1, 8#100, ?INSN(?OP_ROT, 1, 0, 0, -(36+9))} % 1,,100/ ROT 1,-55
|
||||
, {1, 8#101, ?INSN_INVALID} % 1,,101/ <invalid>
|
||||
],
|
||||
expect(Prog2, ACS, {1, 8#101}, ?DEFAULT_FLAGS,
|
||||
[ {?AC(1), ?COMMA2(8#444111, 8#222333)} % AC1 = 444111222333
|
||||
]).
|
||||
|
||||
%% ROTC - Rotate Combined
|
||||
|
||||
rotc_test() ->
|
||||
ACS =
|
||||
[ {1, ?COMMA2(8#000111, 8#222333)} % AC1 = 000111222333
|
||||
, {2, ?COMMA2(8#444555, 8#666777)} % AC2 = 444555666777
|
||||
],
|
||||
Prog1 =
|
||||
[ {1, 8#100, ?INSN(?OP_ROTC, 1, 0, 0, 18)} % 1,,100/ ROTC 1,22
|
||||
, {1, 8#101, ?INSN_INVALID} % 1,,101/ <invalid>
|
||||
],
|
||||
expect(Prog1, ACS, {1, 8#101}, ?DEFAULT_FLAGS,
|
||||
[ {?AC(1), ?COMMA2(8#222333, 8#444555)} % AC1 = 222333444555
|
||||
, {?AC(2), ?COMMA2(8#666777, 8#000111)} % AC2 = 666777000111
|
||||
]),
|
||||
Prog2 =
|
||||
[ {1, 8#100, ?INSN(?OP_ROTC, 1, 0, 0, 36+18)} % 1,,100/ ROTC 1,66
|
||||
, {1, 8#101, ?INSN_INVALID} % 1,,101/ <invalid>
|
||||
],
|
||||
expect(Prog2, ACS, {1, 8#101}, ?DEFAULT_FLAGS,
|
||||
[ {?AC(1), ?COMMA2(8#666777, 8#000111)} % AC1 = 666777000111
|
||||
, {?AC(2), ?COMMA2(8#222333, 8#444555)} % AC2 = 222333444555
|
||||
]),
|
||||
Prog3 =
|
||||
[ {1, 8#100, ?INSN(?OP_ROTC, 1, 0, 0, -18)} % 1,,100/ ROTC 1,-22
|
||||
, {1, 8#101, ?INSN_INVALID} % 1,,101/ <invalid>
|
||||
],
|
||||
expect(Prog3, ACS, {1, 8#101}, ?DEFAULT_FLAGS,
|
||||
[ {?AC(1), ?COMMA2(8#666777, 8#000111)} % AC1 = 666777000111
|
||||
, {?AC(2), ?COMMA2(8#222333, 8#444555)} % AC2 = 222333444555
|
||||
]),
|
||||
Prog4 =
|
||||
[ {1, 8#100, ?INSN(?OP_ROTC, 1, 0, 0, -(36+18))} % 1,,100/ ROTC 1,-66
|
||||
, {1, 8#101, ?INSN_INVALID} % 1,,101/ <invalid>
|
||||
],
|
||||
expect(Prog4, ACS, {1, 8#101}, ?DEFAULT_FLAGS,
|
||||
[ {?AC(1), ?COMMA2(8#222333, 8#444555)} % AC1 = 222333444555
|
||||
, {?AC(2), ?COMMA2(8#666777, 8#000111)} % AC2 = 666777000111
|
||||
]).
|
||||
|
||||
%% Common code to run short sequences ==========================================
|
||||
|
||||
expect(Prog, ACs, ExpectedPC, ExpectedFlags, ExpectedEs) ->
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user