From 4ae04ca3ece8bfb7947aeb24c582ff6f6fefb768 Mon Sep 17 00:00:00 2001 From: Mikael Pettersson Date: Wed, 22 Jul 2020 20:52:33 +0200 Subject: [PATCH] sim: sim_boolean: new, handle SETZ, add unit test --- erlang/apps/sim/src/sim_boolean.erl | 40 ++++++++ erlang/apps/sim/src/sim_core.erl | 1 + erlang/apps/sim/test/sim_boolean_tests.erl | 108 +++++++++++++++++++++ 3 files changed, 149 insertions(+) create mode 100644 erlang/apps/sim/src/sim_boolean.erl create mode 100644 erlang/apps/sim/test/sim_boolean_tests.erl diff --git a/erlang/apps/sim/src/sim_boolean.erl b/erlang/apps/sim/src/sim_boolean.erl new file mode 100644 index 0000000..30aab63 --- /dev/null +++ b/erlang/apps/sim/src/sim_boolean.erl @@ -0,0 +1,40 @@ +%%% -*- erlang-indent-level: 2 -*- +%%% +%%% simulator for pdp10-elf +%%% Copyright (C) 2020 Mikael Pettersson +%%% +%%% This file is part of pdp10-tools. +%%% +%%% pdp10-tools is free software: you can redistribute it and/or modify +%%% it under the terms of the GNU General Public License as published by +%%% the Free Software Foundation, either version 3 of the License, or +%%% (at your option) any later version. +%%% +%%% pdp10-tools is distributed in the hope that it will be useful, +%%% but WITHOUT ANY WARRANTY; without even the implied warranty of +%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +%%% GNU General Public License for more details. +%%% +%%% You should have received a copy of the GNU General Public License +%%% along with pdp10-tools. If not, see . +%%% +%%%============================================================================= +%%% +%%% 2.4 Boolean Functions + +-module(sim_boolean). + +-export([ handle_SETZ/4 + ]). + +-include("sim_core.hrl"). + +%% 2.4 Boolean Functions ======================================================= + +%% SETZ - Set to Zeros + +-spec handle_SETZ(#core{}, sim_mem:mem(), IR :: word(), #ea{}) + -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}. +handle_SETZ(Core, Mem, IR, _EA) -> + AC = IR band 8#17, + sim_core:next_pc(sim_core:set_ac(Core, AC, 0), Mem). diff --git a/erlang/apps/sim/src/sim_core.erl b/erlang/apps/sim/src/sim_core.erl index 48dc397..17a31aa 100644 --- a/erlang/apps/sim/src/sim_core.erl +++ b/erlang/apps/sim/src/sim_core.erl @@ -253,6 +253,7 @@ dispatch(Core, Mem, IR, EA) -> 8#217 -> sim_moves:handle_MOVMS(Core, Mem, IR, EA); 8#250 -> sim_moves:handle_EXCH(Core, Mem, IR, EA); 8#251 -> sim_moves:handle_BLT(Core, Mem, IR, EA); + 8#400 -> sim_boolean:handle_SETZ(Core, Mem, IR, EA); _ -> PC = (Core#core.pc_section bsl 18) bor Core#core.pc_offset, {Core, Mem, {error, {?MODULE, {dispatch, PC, IR, EA}}}} diff --git a/erlang/apps/sim/test/sim_boolean_tests.erl b/erlang/apps/sim/test/sim_boolean_tests.erl new file mode 100644 index 0000000..71917d1 --- /dev/null +++ b/erlang/apps/sim/test/sim_boolean_tests.erl @@ -0,0 +1,108 @@ +%%% -*- erlang-indent-level: 2 -*- +%%% +%%% simulator for pdp10-elf +%%% Copyright (C) 2020 Mikael Pettersson +%%% +%%% This file is part of pdp10-tools. +%%% +%%% pdp10-tools is free software: you can redistribute it and/or modify +%%% it under the terms of the GNU General Public License as published by +%%% the Free Software Foundation, either version 3 of the License, or +%%% (at your option) any later version. +%%% +%%% pdp10-tools is distributed in the hope that it will be useful, +%%% but WITHOUT ANY WARRANTY; without even the implied warranty of +%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +%%% GNU General Public License for more details. +%%% +%%% You should have received a copy of the GNU General Public License +%%% along with pdp10-tools. If not, see . +%%% +%%%============================================================================= +%%% +%%% Test cases for 2.4 Boolean Functions + +-module(sim_boolean_tests). + +-include("../src/sim_core.hrl"). +-include_lib("eunit/include/eunit.hrl"). + +-define(DEFAULT_FLAGS, (1 bsl ?PDP10_PF_USER)). + +-define(LOW18(X), ((X) band ((1 bsl 18) - 1))). + +-define(INSN(OP, AC, I, X, Y), + (((OP) bsl (35 - 8)) bor + ((AC) bsl (35 - 12)) bor + ((I) bsl (35 - 13)) bor + ((X) bsl (35 - 17)) bor + ?LOW18(Y))). + +-define(COMMA2(LEFT, RIGHT), ((?LOW18(LEFT) bsl 18) bor ?LOW18(RIGHT))). % LEFT,,RIGHT in MACRO-10 + +-define(INSN_INVALID, ?INSN(0, 0, 0, 0, 0)). + +-define(OP_MOVEI, 8#201). +-define(OP_SETZ, 8#400). + +%% 2.4 Boolean Functions ======================================================= + +%% SETZ - Set to Zeros + +setz_test() -> + Prog = + [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 1)} % 1,,100/ MOVEI 1,1 + , {1, 8#101, ?INSN(?OP_SETZ, 1, 0, 0, 0)} % 1,,101/ SETZ 1, + , {1, 8#102, ?INSN_INVALID} % 1,,102/ + ], + expect(Prog, [], {1, 8#102}, ?DEFAULT_FLAGS, + [ {#ea{section = 1, offset = 1, islocal = false}, 0} % AC1 = 0 + ]). + +%% Common code to run short sequences ========================================== + +expect(Prog, ACs, ExpectedPC, ExpectedFlags, ExpectedEs) -> + {Core, Mem} = init(Prog, ACs), + {Core1, Mem1, {error, {sim_core, {dispatch, PC, _IR, _EA}}}} = sim_core:run(Core, Mem), + ActualPC = {PC bsr 18, PC band ((1 bsl 18) - 1)}, + ?assertEqual(ExpectedPC, ActualPC), + ?assertEqual(ExpectedFlags, Core1#core.flags), + lists:foreach(fun({EA, ExpectedE}) -> + {ok, ActualE} = sim_core:c(Core1, Mem1, EA), + ?assertEqual(ExpectedE, ActualE) + end, ExpectedEs), + sim_mem:delete(Mem). + +init(Prog, ACs) -> + {PCSection, PCOffset} = prog_pc(Prog), + Mem = init_mem(Prog), + Core = init_core(PCSection, PCOffset, ACs), + {Core, Mem}. + +prog_pc([{Section, Offset, _Word} | _Rest]) -> {Section, Offset}. + +init_mem(Prog) -> init_mem(Prog, sim_mem:new()). + +init_mem([], Mem) -> Mem; +init_mem([{Section, Offset, Word} | Rest], Mem) -> + init_word(Section, Offset, Word, Mem), + init_mem(Rest, Mem). + +init_word(Section, Offset, Word, Mem) -> + Address = (Section bsl 18) bor Offset, + PFN = Address bsr 9, + case sim_mem:mquery(Mem, PFN) of + false -> sim_mem:mmap(Mem, PFN, 4+2, core); + {_Prot, _What} -> ok + end, + ok = sim_mem:write_word(Mem, Address, Word). + +init_core(PCSection, PCOffset, ACs) -> + #core{ pc_section = PCSection + , pc_offset = PCOffset + , acs = init_acs(ACs, list_to_tuple(lists:duplicate(16, 0))) + , flags = ?DEFAULT_FLAGS + }. + +init_acs([], ACS) -> ACS; +init_acs([{AC, Val} | Rest], ACS) -> init_acs(Rest, setelement(AC + 1, Val, ACS)).