1
0
mirror of https://github.com/wfjm/w11.git synced 2026-05-05 07:34:43 +00:00

BUGFIX: cc state unchanged after abort - mtp/mfp case

- rtl/w11a/
  - pdp11_dpath.vhd: use c_dpath_dsrc_src,c_dpath_ddst_dst
  - pdp11_sequencer.vhd: BUGFIX: cc state unchanged after abort (mtp/mfp)
- tools/tcode
  - cpu_basics.mac: add F4.1-6
  - cpu_details.mac: add B3.2-3
This commit is contained in:
wfjm
2023-01-02 16:27:46 +01:00
parent b59d545956
commit 26daa71634
8 changed files with 475 additions and 28 deletions

View File

@@ -6,7 +6,7 @@
### Background ### Background
The PDP-11 architecture requires that The PDP-11 architecture requires that
- for direct writes to the `PSW` the cc state of the write must prevail - for direct writes to the `PSW`, the cc state of the write must prevail
- the cc state must remain unchanged after an instruction abort - the cc state must remain unchanged after an instruction abort
The first requirement implies that the usual updating of cc's after an The first requirement implies that the usual updating of cc's after an
@@ -48,6 +48,10 @@ In a first round, the `dstw` flow was fixed. The condition code requests
`s_dstw_inc`, `s_dstw_dec`, and `s_dstw_ind` and add to the two exit states `s_dstw_inc`, `s_dstw_dec`, and `s_dstw_ind` and add to the two exit states
`s_dstw_def_w` and `s_dstw_inc_w`. `s_dstw_def_w` and `s_dstw_inc_w`.
In a second round, the `MTP*` and `MFP*` instructions, which use the `dsta`
flow, were fixed. Again, the `ndpcntl.psr_ccwe := '1';` was moved to the
last `*_w` state of the respective flows.
### Hindsight ### Hindsight
Further analysis showed that this bug had in practice no consequences Further analysis showed that this bug had in practice no consequences
- `MOV` and `CLR` don't depend on the cc state, so a re-execution with a - `MOV` and `CLR` don't depend on the cc state, so a re-execution with a
@@ -56,6 +60,6 @@ Further analysis showed that this bug had in practice no consequences
extension. `MFP*` and `MTP*` also don't depend on the cc state and extension. `MFP*` and `MTP*` also don't depend on the cc state and
re-execution will give correct results. Moreover, they are usually used re-execution will give correct results. Moreover, they are usually used
in kernel mode and therefore never re-executed in 2.11bsd. in kernel mode and therefore never re-executed in 2.11bsd.
- `SXT` depends on the `N` bit, but that bit is not changed by this - `SXT` depends on the `N` bit, but this bit is not changed by this
instruction, so a re-execution with Z, V, or C changed will give a instruction, so a re-execution with Z, V, or C changed will give a
correct result. correct result.

View File

@@ -0,0 +1,32 @@
## Known differences between SimH, 11/70, and w11a
### SimH: condition codes are not always unchanged after an abort
The PDP-11 architecture requires that
- for direct writes to the `PSW`, the cc state of the write must prevail
- the cc state must remain unchanged after an instruction abort
To satisfy the first requirement, SimH updates the condition codes
for `MOV`, `CLR`, `SXT`, `MFP*`, and `MTP*` _before_ the last write is
executed. This ensures that in direct writes to the `PSW` the cc state
of the write prevails, simply because an explicit `PSW` write is done
_after_ the instruction level condition code update and overwrites it.
However, an address error abort on the last write would leave the CPU in a
state with modified condition codes, which violates of the second requirement.
A detailed analysis shows that this bug has in practice no consequences
- `SXT` depends on the `N` bit, but this bit is not changed by this
instruction, so a re-execution with Z, V, or C changed will give a
correct result.
- the other affected instructions don't depend on the cc state, so a
re-execution with a changed initial cc state will give the same result.
Confirmed deficiency, might be fixed in a future release.
The w11 implements instruction aborts correctly, the condition codes are not
unchanged when an instruction is aborted. The corresponding tests are skipped
when executed on SimH
(see [cpu_details.mac](../tools/tcode/cpu_details.mac) tests B3.1-3).
Tested with SimH V3.12-3.

View File

@@ -17,6 +17,8 @@ ones are listed here:
- [SimH: stack limit check and addressing modes](simh_diff_stklim_amode.md) - [SimH: stack limit check and addressing modes](simh_diff_stklim_amode.md)
- [SimH: stack limit check and vector push aborts](simh_diff_stklim_vpush.md) - [SimH: stack limit check and vector push aborts](simh_diff_stklim_vpush.md)
- [SimH: Red stack zone PSW protection](simh_diff_red_psw.md) - [SimH: Red stack zone PSW protection](simh_diff_red_psw.md)
- instruction abort handling
- [SimH: condition codes are not always unchanged after an abort](simh_diff_cc_and_aborts.md)
- service order and trap handling - service order and trap handling
- [SimH: trap and interrupt service order has J11 behavior](simh_diff_service-order.md) - [SimH: trap and interrupt service order has J11 behavior](simh_diff_service-order.md)
- [SimH: traced `WAIT` has J11 behavior](simh_diff_traced-wait.md) - [SimH: traced `WAIT` has J11 behavior](simh_diff_traced-wait.md)

View File

@@ -1,6 +1,6 @@
-- $Id: sys_w11a_c7.vhd 1340 2023-01-01 08:43:05Z mueller $ -- $Id: sys_w11a_c7.vhd 1342 2023-01-02 15:18:19Z mueller $
-- SPDX-License-Identifier: GPL-3.0-or-later -- SPDX-License-Identifier: GPL-3.0-or-later
-- Copyright 2017-2022 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> -- Copyright 2017-2023 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
-- --
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
-- Module Name: sys_w11a_c7 - syn -- Module Name: sys_w11a_c7 - syn
@@ -28,6 +28,7 @@
-- --
-- Synthesized: -- Synthesized:
-- Date Rev viv Target flop lutl lutm bram slic -- Date Rev viv Target flop lutl lutm bram slic
-- 2023-01-02 1342 2022.1 xc7a35t-1 3434 6005 279 50.0 1969
-- 2022-12-31 1340 2022.1 xc7a35t-1 3450 6018 279 50.0 1986 -- 2022-12-31 1340 2022.1 xc7a35t-1 3450 6018 279 50.0 1986
-- 2022-12-27 1339 2022.1 xc7a35t-1 3454 6026 279 50.0 2013 -- 2022-12-27 1339 2022.1 xc7a35t-1 3454 6026 279 50.0 2013
-- 2022-12-06 1324 2022.1 xc7a35t-1 3447 5998 278 50.0 1992 -- 2022-12-06 1324 2022.1 xc7a35t-1 3447 5998 278 50.0 1992

View File

@@ -1,6 +1,6 @@
-- $Id: pdp11_dpath.vhd 1339 2022-12-27 12:11:34Z mueller $ -- $Id: pdp11_dpath.vhd 1342 2023-01-02 15:18:19Z mueller $
-- SPDX-License-Identifier: GPL-3.0-or-later -- SPDX-License-Identifier: GPL-3.0-or-later
-- Copyright 2006-2022 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> -- Copyright 2006-2023 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
-- --
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
-- Module Name: pdp11_dpath - syn -- Module Name: pdp11_dpath - syn
@@ -19,6 +19,7 @@
-- --
-- Revision History: -- Revision History:
-- Date Rev Version Comment -- Date Rev Version Comment
-- 2023-01-01 1342 1.2.8 use c_dpath_dsrc_src,c_dpath_ddst_dst
-- 2022-12-27 1339 1.2.7 remove PCOUT port -- 2022-12-27 1339 1.2.7 remove PCOUT port
-- 2022-10-25 1309 1.2.6 rename _gpr -> _gr -- 2022-10-25 1309 1.2.6 rename _gpr -> _gr
-- 2015-07-19 702 1.2.5 set new DM_STAT_DP fields -- 2015-07-19 702 1.2.5 set new DM_STAT_DP fields
@@ -242,7 +243,7 @@ begin
if rising_edge(CLK) then if rising_edge(CLK) then
if CNTL.dsrc_we = '1' then if CNTL.dsrc_we = '1' then
if CNTL.dsrc_sel = '0' then if CNTL.dsrc_sel = c_dpath_dsrc_src then
R_DSRC <= GR_DSRC; R_DSRC <= GR_DSRC;
else else
R_DSRC <= DRES; R_DSRC <= DRES;
@@ -250,7 +251,7 @@ begin
end if; end if;
if CNTL.ddst_we = '1' then if CNTL.ddst_we = '1' then
if CNTL.ddst_sel = '0' then if CNTL.ddst_sel = c_dpath_ddst_dst then
R_DDST <= GR_DDST; R_DDST <= GR_DDST;
else else
R_DDST <= DRES; R_DDST <= DRES;

View File

@@ -1,6 +1,6 @@
-- $Id: pdp11_sequencer.vhd 1340 2023-01-01 08:43:05Z mueller $ -- $Id: pdp11_sequencer.vhd 1342 2023-01-02 15:18:19Z mueller $
-- SPDX-License-Identifier: GPL-3.0-or-later -- SPDX-License-Identifier: GPL-3.0-or-later
-- Copyright 2006-2022 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> -- Copyright 2006-2023 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
-- --
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
-- Module Name: pdp11_sequencer - syn -- Module Name: pdp11_sequencer - syn
@@ -13,7 +13,7 @@
-- --
-- Revision History: -- Revision History:
-- Date Rev Version Comment -- Date Rev Version Comment
-- 2022-12-31 1340 1.6.27 BUGFIX: cc state unchanged after abort -- 2023-01-01 1342 1.6.27 BUGFIX: cc state unchanged after abort
-- 2022-12-26 1337 1.6.26 tbit logic overhaul 2, now fully 11/70 compatible -- 2022-12-26 1337 1.6.26 tbit logic overhaul 2, now fully 11/70 compatible
-- 2022-12-12 1330 1.6.25 implement MMR0,MMR2 instruction complete -- 2022-12-12 1330 1.6.25 implement MMR0,MMR2 instruction complete
-- 2022-12-10 1329 1.6.24 BUGFIX: get correct PS after vector push abort -- 2022-12-10 1329 1.6.24 BUGFIX: get correct PS after vector push abort
@@ -2070,6 +2070,8 @@ begin
when s_opa_mtp_pop_w => -- ----------------------------------- when s_opa_mtp_pop_w => -- -----------------------------------
nstate := s_opa_mtp_pop_w; nstate := s_opa_mtp_pop_w;
ndpcntl.ddst_sel := c_dpath_ddst_dst; -- DDST = R(DST)
ndpcntl.ddst_we := '1'; -- update DDST (needed for sp)
ndpcntl.dres_sel := c_dpath_res_vmdout; -- DRES = VMDOUT ndpcntl.dres_sel := c_dpath_res_vmdout; -- DRES = VMDOUT
ndpcntl.dtmp_sel := c_dpath_dtmp_dres; -- DTMP = DRES ndpcntl.dtmp_sel := c_dpath_dtmp_dres; -- DTMP = DRES
do_memcheck(nstate, nstatus, imemok); do_memcheck(nstate, nstatus, imemok);
@@ -2087,8 +2089,6 @@ begin
end case; end case;
end if; end if;
end if; end if;
ndpcntl.ddst_sel := c_dpath_ddst_dst; -- DDST = R(DST)
ndpcntl.ddst_we := '1'; -- update DDST (needed for sp)
when s_opa_mtp_reg => -- ----------------------------------- when s_opa_mtp_reg => -- -----------------------------------
ndpcntl.ounit_asel := c_ounit_asel_dtmp; -- OUNIT A = DTMP ndpcntl.ounit_asel := c_ounit_asel_dtmp; -- OUNIT A = DTMP
@@ -2104,7 +2104,6 @@ begin
ndpcntl.ounit_asel := c_ounit_asel_dtmp; -- OUNIT A = DTMP ndpcntl.ounit_asel := c_ounit_asel_dtmp; -- OUNIT A = DTMP
ndpcntl.ounit_bsel := c_ounit_bsel_const; -- OUNIT B = const(0) ndpcntl.ounit_bsel := c_ounit_bsel_const; -- OUNIT B = const(0)
ndpcntl.dres_sel := c_dpath_res_ounit; -- DRES = OUNIT ndpcntl.dres_sel := c_dpath_res_ounit; -- DRES = OUNIT
ndpcntl.psr_ccwe := '1'; -- set cc (from ounit too)
ndpcntl.vmaddr_sel := c_dpath_vmaddr_ddst;-- VA = DDST ndpcntl.vmaddr_sel := c_dpath_vmaddr_ddst;-- VA = DDST
nvmcntl.dspace := IREG(15); -- msb indicates I/D: 0->I, 1->D nvmcntl.dspace := IREG(15); -- msb indicates I/D: 0->I, 1->D
nvmcntl.mode := PSW.pmode; nvmcntl.mode := PSW.pmode;
@@ -2114,8 +2113,11 @@ begin
when s_opa_mtp_mem_w => -- ----------------------------------- when s_opa_mtp_mem_w => -- -----------------------------------
nstate := s_opa_mtp_mem_w; nstate := s_opa_mtp_mem_w;
ndpcntl.ounit_asel := c_ounit_asel_dtmp; -- OUNIT A = DTMP (for cc)
ndpcntl.ounit_bsel := c_ounit_bsel_const; -- OUNIT B = const(0) (for cc)
do_memcheck(nstate, nstatus, imemok); do_memcheck(nstate, nstatus, imemok);
if imemok then if imemok then
ndpcntl.psr_ccwe := '1'; -- set cc (ounit via res_sel)
idm_idone := '1'; -- instruction done idm_idone := '1'; -- instruction done
do_fork_next(nstate, nstatus, nmmumoni); -- fetch next do_fork_next(nstate, nstatus, nmmumoni); -- fetch next
end if; end if;
@@ -2166,7 +2168,6 @@ begin
ndpcntl.ounit_asel := c_ounit_asel_ddst; -- OUNIT A=DDST ndpcntl.ounit_asel := c_ounit_asel_ddst; -- OUNIT A=DDST
ndpcntl.ounit_bsel := c_ounit_bsel_const; -- OUNIT B=const(0) ndpcntl.ounit_bsel := c_ounit_bsel_const; -- OUNIT B=const(0)
ndpcntl.dres_sel := c_dpath_res_ounit; -- DRES = OUNIT ndpcntl.dres_sel := c_dpath_res_ounit; -- DRES = OUNIT
ndpcntl.psr_ccwe := '1'; -- set cc (from ounit too)
ndpcntl.vmaddr_sel := c_dpath_vmaddr_dsrc; -- VA = DSRC ndpcntl.vmaddr_sel := c_dpath_vmaddr_dsrc; -- VA = DSRC
nvmcntl.dspace := '1'; nvmcntl.dspace := '1';
nvmcntl.kstack := is_kmode; nvmcntl.kstack := is_kmode;
@@ -2176,8 +2177,11 @@ begin
when s_opa_mfp_push_w => -- ----------------------------------- when s_opa_mfp_push_w => -- -----------------------------------
nstate := s_opa_mfp_push_w; nstate := s_opa_mfp_push_w;
ndpcntl.ounit_asel := c_ounit_asel_ddst; -- OUNIT A=DDST (for cc)
ndpcntl.ounit_bsel := c_ounit_bsel_const; -- OUNIT B=const(0) (for cc)
do_memcheck(nstate, nstatus, imemok); do_memcheck(nstate, nstatus, imemok);
if imemok then if imemok then
ndpcntl.psr_ccwe := '1'; -- set cc (ounit via res_sel)
idm_idone := '1'; -- instruction done idm_idone := '1'; -- instruction done
do_fork_next(nstate, nstatus, nmmumoni); -- fetch next do_fork_next(nstate, nstatus, nmmumoni); -- fetch next
end if; end if;

View File

@@ -1,10 +1,10 @@
; $Id: cpu_basics.mac 1329 2022-12-11 17:28:28Z mueller $ ; $Id: cpu_basics.mac 1342 2023-01-02 15:18:19Z mueller $
; SPDX-License-Identifier: GPL-3.0-or-later ; SPDX-License-Identifier: GPL-3.0-or-later
; Copyright 2015-2022 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> ; Copyright 2015-2023 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
; ;
; Revision History: ; Revision History:
; Date Rev Version Comment ; Date Rev Version Comment
; 2022-12-06 1324 1.0 Initial version ; 2023-01-02 1342 1.0 Initial version
; 2015-08-30 710 0.1 First draft ; 2015-08-30 710 0.1 First draft
; ;
; Test CPU basics: most instructions except traps, EIS and FPP ; Test CPU basics: most instructions except traps, EIS and FPP
@@ -13,7 +13,7 @@
; Section C: binary instructions (word) ; Section C: binary instructions (word)
; Section D: unary instructions (byte) ; Section D: unary instructions (byte)
; Section E: binary instructions (byte) ; Section E: binary instructions (byte)
; Section F: miscellaneous (spl, reset, bpt,...) ; Section F: miscellaneous (spl, reset, bpt, m*p*, ...)
; ;
.include |lib/tcode_std_base.mac| .include |lib/tcode_std_base.mac|
.include |lib/defs_kwl.mac| .include |lib/defs_kwl.mac|
@@ -2964,7 +2964,7 @@ te0501: clr cp.psw
; ;
9999$: iot ; end of test E5.1 9999$: iot ; end of test E5.1
; ;
; Section F: miscellaneous (spl, reset) ====================================== ; Section F: miscellaneous (spl, reset, bpt, m*p*, ...) ======================
; F1 spl ; F1 spl
; F1.1 spl in kernel mode ; F1.1 spl in kernel mode
; F1.2 spl in supervisor and user mode ; F1.2 spl in supervisor and user mode
@@ -2973,6 +2973,13 @@ te0501: clr cp.psw
; F2.2 reset in supervisor and user mode ; F2.2 reset in supervisor and user mode
; F2.3 reset settling time ; F2.3 reset settling time
; F3 trap instructions: bpt,iot,emt,trap ; F3 trap instructions: bpt,iot,emt,trap
; F4 MTP* and MFP* basics
; F4.1 MTP* with all address mode
; F4.2 MTP* and cc for reg dst
; F4.3 MTP* and cc for mem dst
; F4.4 MFP* with all address modes
; F4.5 MFP* and cc for reg dst
; F4.6 MFP* and cc for mem dst
; ;
; Test F1: spl ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; Test F1: spl ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; This sub-section verifies ; This sub-section verifies
@@ -3216,10 +3223,360 @@ tf0301: mov #v..iot+2,v..iot ; block iot handler
; ;
9999$: iot ; end of test F3.1 9999$: iot ; end of test F3.1
; ;
; Test F4: MTP* and MFP* basics ++++++++++++++++++++++++++++++++++++++++++++++
; This sub-section verifies
; x xxx xxx xxx xxx xxx NZVC Instruction / Remark
; 0 000 110 101 ddd ddd NZ0- MFPI
; 0 000 110 110 ddd ddd NZ0- MTPI
; 1 000 110 101 ddd ddd NZ0- MFPD
; 1 000 110 110 ddd ddd NZ0- MTPD
;
; Only basic read-write functionality tested with cm=pm=kernel with MMU off.
; Only M*PI is tested, with MMU off there is not difference between I and D.
; All destination address modes are verified.
; This also verifies the dsta flow.
;
; Test F4.1 MTP* with all address modes ++++++++++++++++++++++++++++++
; Tests mode 0-7, and the special cases sp, (sp), -(sp), @(sp)+, n(sp),
;
tf0401: clr cp.psw
mov #123,r0 ; src for MOV
mov #100$,r1 ; dst for (r1),(r1)+,-(r1),0(r1)
mov #200$,r2 ; dst for @(r2)+,@-(r2),@0(r2)
mov r1,r3 ; ptr to dst
;
clr r5
push r0
mtpi r5 ; mode 0 - general purpose register
hcmpeq r0,r5 ; check dst
;
inc r0
push r0
mtpi (r1) ; mode 1
hcmpeq r0,(r3) ; check dst
;
inc r0
push r0
mtpi (r1)+ ; mode 2
hcmpeq #100$+2,r1 ; check r1
hcmpeq r0,(r3) ; check dst
;
inc r0
push r0
mtpi -(r1) ; mode 4
hcmpeq #100$,r1 ; check r1
hcmpeq r0,(r3) ; check dst
;
inc r0
push r0
mtpi 0(r1) ; mode 6
hcmpeq r0,(r3) ; check dst
;
inc r0
push r0
mtpi @(r2)+ ; mode 3
hcmpeq #200$+2,r2 ; check r2
hcmpeq r0,(r3) ; check dst
;
inc r0
push r0
mtpi @-(r2) ; mode 5
hcmpeq #200$,r2 ; check r2
hcmpeq r0,(r3) ; check dst
;
inc r0
push r0
mtpi @0(r2) ; mode 7
hcmpeq r0,(r3) ; check dst
;
hcmpeq #stack,sp ; check SP normal
;
; check SP special cases
;
inc r0
push r0
mtpi sp ; mode 0: SP as target
hcmpeq r0,sp ; check SP
;
mov #stack-2,sp ; ptr to writable stack word
inc r0
push r0
mtpi (sp) ; mode 1: (SP) as target
hcmpeq #stack-2,sp ; check SP
hcmpeq r0,stack-2 ; was stack modified ?
mov #stack,sp ; SP to normal
;
inc r0
push r0
mtpi -(sp) ; mode 4: -(SP) as target
hcmpeq #stack-2,sp ; check SP
hcmpeq r0,stack-2 ; was stack modified ?
tst (sp)+ ; pop value
;
inc r0
push #100$ ; push address - read 2nd
push r0 ; push value - read 1st
mtpi @(sp)+ ; mode 3: @(SP)+ as target
hcmpeq r0,(r3) ; check dst
;
inc r0
push r0
mtpi -2(sp) ; mode 6 - n(SP) as target
hcmpeq #stack,sp ; check SP
hcmpeq r0,stack-2 ; was stack modified ?
;
br 9999$
;
100$: .word 0 ; dst target
200$: .word 100$ ; ptr to dst
;
9999$: iot ; end of test F4.1
;
; Test F4.2 MTP* and cc for reg dst ++++++++++++++++++++++++++++++++++
;
tf0402: mov #cp.psw,r4
clr (r4)
;
clr -(sp) ; zero value
ccc
mtpi r5
hcmpeq #cp0z00,(r4) ; check N=0,Z=1
;
push #1. ; positive value
ccc
<sen!sez> ; NZ=1
mtpi r5
hcmpeq #cp0000,(r4) ; check N=0,Z=0
;
push #-1. ; negative value
ccc
mtpi r5
hcmpeq #cpn000,(r4) ; check N=1,Z=0
;
push #1. ; positive value
sec ; C=1
mtpi r5
hcmpeq #cp000c,(r4) ; check C=1 kept
;
push #1. ; positive word
scc ; NZVC=1
mtpi r5
hcmpeq #cp000c,(r4) ; check C kept, NZV cleared
;
9999$: iot ; end of test F4.2
;
; Test F4.3 MTP* and cc for mem dst ++++++++++++++++++++++++++++++++++
;
tf0403: mov #100$,r1 ; dst for (r1)
mov #cp.psw,r4
clr (r4)
;
clr -(sp) ; zero value
ccc
mtpi (r1)
hcmpeq #cp0z00,(r4) ; check N=0,Z=1
;
push #1. ; positive value
ccc
<sen!sez> ; NZ=1
mtpi (r1)
hcmpeq #cp0000,(r4) ; check N=0,Z=0
;
push #-1. ; positive value
ccc
mtpi (r1)
hcmpeq #cpn000,(r4) ; check N=1,Z=0
;
push #1. ; positive value
sec ; C=1
mtpi (r1)
hcmpeq #cp000c,(r4) ; check C=1 kept
;
push #1. ; positive value
scc ; NZVC=1
mtpi (r1)
hcmpeq #cp000c,(r4) ; check C kept, NZV cleared
br 9999$
;
100$: .word 0 ; dst target
;
9999$: iot ; end of test F4.3
;
; Test F4.4 MFP* with all address modes ++++++++++++++++++++++++++++++
; Tests mode 0-7, and the special cases sp, (sp), (sp)+, @(sp)+, n(sp)
;
tf0404: clr cp.psw
mov #321,r0 ; current test value
mov #100$,r1 ; dst for (r1),(r1)+,-(r1),0(r1)
mov #200$,r2 ; dst for @(r2)+,@-(r2),@0(r2)
mov r1,r3 ; ptr to dst
;
mov r0,r5
mfpi r5 ; mode 0 - general purpose register
hcmpeq r0,(sp)+ ; check
;
inc r0
mov r0,(r3)
mfpi (r1) ; mode 1
hcmpeq r0,(sp)+ ; check
;
inc r0
mov r0,(r3)
mfpi (r1)+ ; mode 2
hcmpeq #100$+2,r1 ; check r1
hcmpeq r0,(sp)+ ; check
;
inc r0
mov r0,(r3)
mfpi -(r1) ; mode 4
hcmpeq #100$,r1 ; check r1
hcmpeq r0,(sp)+ ; check
;
inc r0
mov r0,(r3)
mfpi 0(r1) ; mode 6
hcmpeq r0,(sp)+ ; check
;
inc r0
mov r0,(r3)
mfpi @(r2)+ ; mode 3
hcmpeq #200$+2,r2 ; check r2
hcmpeq r0,(sp)+ ; check
;
inc r0
mov r0,(r3)
mfpi @-(r2) ; mode 5
hcmpeq #200$,r2 ; check r2
hcmpeq r0,(sp)+ ; check
;
inc r0
mov r0,(r3)
mfpi @0(r2) ; mode 7
hcmpeq r0,(sp)+ ; check
;
hcmpeq #stack,sp ; check SP normal
;
; check SP special cases
;
mfpi sp ; mode 0: SP as source
hcmpeq #stack,(sp)+ ; check
;
inc r0
push r0
mfpi (sp) ; mode 1: (SP) as source
hcmpeq r0,(sp)+ ; check mfpi pushed value
hcmpeq r0,(sp)+ ; check data pushed value
hcmpeq #stack,sp ; check stack state
;
inc r0
push r0
mfpi (sp)+ ; mode 2: (SP)+ as source
hcmpeq r0,(sp)+ ; check mfpi pushed value
hcmpeq #stack,sp ; check stack state
;
inc r0
mov r0,(r3) ; write data
push r3 ; push address
mfpi @(sp)+ ; mode 3: @(SP)+ as source
hcmpeq r0,(sp)+ ; check mfpi pushed value
hcmpeq #stack,sp ; check stack state
;
inc r0
push r0
mfpi 0(sp) ; mode 6: n(SP) as source
hcmpeq r0,(sp)+ ; check mfpi pushed value
hcmpeq r0,(sp)+ ; check data pushed value
hcmpeq #stack,sp ; check stack state
;
br 9999$
;
100$: .word 0 ; dst target
200$: .word 100$ ; ptr to dst
;
9999$: iot ; end of test F4.4
;
; Test F4.5 MFP* and cc for reg dst ++++++++++++++++++++++++++++++++++
;
tf0405: mov #cp.psw,r4
clr (r4)
;
clr r5 ; zero value
ccc
mfpi r5
hcmpeq #cp0z00,(r4) ; check N=0,Z=1
tst (sp)+ ; pop value
;
inc r5 ; positive value
ccc
<sen!sez> ; NZ=1
mfpi r5
hcmpeq #cp0000,(r4) ; check N=0,Z=0
tst (sp)+ ; pop value
;
neg r5 ; negative value
ccc
mfpi r5
hcmpeq #cpn000,(r4) ; check N=1,Z=0
tst (sp)+ ; pop value
;
neg r5 ; positive value
sec ; C=1
mfpi r5
hcmpeq #cp000c,(r4) ; check C=1 kept
tst (sp)+ ; pop value
;
scc ; NZVC=1
mfpi r5
hcmpeq #cp000c,(r4) ; check C kept, NZV cleared
tst (sp)+ ; pop value
;
9999$: iot ; end of test F4.5
;
; Test F4.6 MFP* and cc for mem dst ++++++++++++++++++++++++++++++++++
;
tf0406: mov #100$,r1 ; dst for (r1)
mov #cp.psw,r4
clr (r4)
;
clr (r1) ; zero value
ccc
mfpi (r1)
hcmpeq #cp0z00,(r4) ; check N=0,Z=1
tst (sp)+ ; pop value
;
inc (r1) ; positive value
ccc
<sen!sez> ; NZ=1
mfpi (r1)
hcmpeq #cp0000,(r4) ; check N=0,Z=0
tst (sp)+ ; pop value
;
neg (r1) ; negative value
ccc
mfpi (r1)
hcmpeq #cpn000,(r4) ; check N=1,Z=0
tst (sp)+ ; pop value
;
neg (r1) ; positive value
sec ; C=1
mfpi (r1)
hcmpeq #cp000c,(r4) ; check C=1 kept
tst (sp)+ ; pop value
;
scc ; NZVC=1
mfpi (r1)
hcmpeq #cp000c,(r4) ; check C kept, NZV cleared
tst (sp)+ ; pop value
br 9999$
;
100$: .word 0 ; dst target
;
9999$: iot ; end of test F4.6
;
; END OF ALL TESTS - loop closure ============================================ ; END OF ALL TESTS - loop closure ============================================
; ;
mov tstno,r0 ; hack, for easy monitoring ... mov tstno,r0 ; hack, for easy monitoring ...
hcmpeq tstno,#54. ; all tests done ? hcmpeq tstno,#60. ; all tests done ?
; ;
jmp loop jmp loop
; ;

View File

@@ -1,10 +1,10 @@
; $Id: cpu_details.mac 1340 2023-01-01 08:43:05Z mueller $ ; $Id: cpu_details.mac 1342 2023-01-02 15:18:19Z mueller $
; SPDX-License-Identifier: GPL-3.0-or-later ; SPDX-License-Identifier: GPL-3.0-or-later
; Copyright 2022- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> ; Copyright 2022-2023 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
; ;
; Revision History: ; Revision History:
; Date Rev Version Comment ; Date Rev Version Comment
; 2022-12-25 1337 1.0 Initial version ; 2023-01-02 1342 1.0 Initial version
; 2022-07-18 1259 0.1 First draft ; 2022-07-18 1259 0.1 First draft
; ;
; Test CPU details ; Test CPU details
@@ -1542,12 +1542,14 @@ ta0404: mov #vhtbpt,v..bpt ; BPT handler
; B2 pipeline torture tests ; B2 pipeline torture tests
; B2.1 self-modifying code, use (pc), -(pc) ; B2.1 self-modifying code, use (pc), -(pc)
; B2.2 self-modifying code, use (pc) case 2 ; B2.2 self-modifying code, use (pc) case 2
; B3 specifier flow tests ; B3 specifier flow and abort tests
; B3.1 dstw flow and cc ; B3.1 dstw flow and cc
; part 1: check cc for MOV for all modes ; part 1: check cc for MOV for all modes
; part 2: check cc for CLR for all modes ; part 2: check cc for CLR for all modes
; part 3: check cc for SXT for all modes ; part 3: check cc for SXT for all modes
; part 4: check cc for MOV after abort for all modes ; part 4: check cc for MOV after abort for all modes
; B3.2 mtp and cc after abort
; B3.3 mfp and cc after abort
; ;
; Test B1: address mode torture tests +++++++++++++++++++++++++++++++++++++++ ; Test B1: address mode torture tests +++++++++++++++++++++++++++++++++++++++
; This sub-section tests peculiar address node usage ; This sub-section tests peculiar address node usage
@@ -1703,7 +1705,7 @@ tb0202: mov #2,r5
; ;
9999$: iot ; end of test B2.2 9999$: iot ; end of test B2.2
; ;
; Test B3: specifier flow tests +++++++++++++++++++++++++++++++++++++++++++++ ; Test B3: specifier flow and abort tests +++++++++++++++++++++++++++++++++++
; This sub-section tests flow and cc properties ; This sub-section tests flow and cc properties
; ;
; Test B3.1 -- dstw flow and cc ++++++++++++++++++++++++++++++++++++++ ; Test B3.1 -- dstw flow and cc ++++++++++++++++++++++++++++++++++++++
@@ -1824,7 +1826,7 @@ tb0301: mov #123,r0 ; src for MOV
br 4200$ br 4200$
; ;
4100$: inc r5 ; bump counter 4100$: inc r5 ; bump counter
hcmpeq #cpnzvc,2(sp) ; PS cc untouched !! hcmpeq #cpnzvc,2(sp) ; check PS cc untouched
rti ; continue (possible here!) rti ; continue (possible here!)
; ;
4200$: hcmpeq #7.,r5 ; check that all 7 mov get address error 4200$: hcmpeq #7.,r5 ; check that all 7 mov get address error
@@ -1832,6 +1834,50 @@ tb0301: mov #123,r0 ; src for MOV
; ;
9999$: iot ; end of test B3.1 9999$: iot ; end of test B3.1
; ;
; Test B3.2 -- mtp and cc after abort ++++++++++++++++++++++++++++++++
; Verifies that cc is unchanged if last write fails.
; MTP* uses the dsta flow, it is sufficient to test only mode 1 and
; an odd address abort.
;
tb0302: cmpb systyp,#sy.sih ; skip on SimH
beq 9999$
;
mov #1,r1 ; use odd address
mov #1000$,v..iit ; set up iit handler
clr -(sp) ; push value
scc
mtpi (r1) ; will fail
halt
;
1000$: hcmpeq #cpnzvc,2(sp) ; check PS cc untouched
mov #stack,sp ; restore
mov #v..iit+2,v..iit ; restore
;
9999$: iot ; end of test B3.2
;
; Test B3.3 -- mfp and cc after abort ++++++++++++++++++++++++++++++++
; Verifies that cc is unchanged if last write fails.
; The last write in MFP* is a stack push, the test uses an odd address abort.
;
tb0303: cmpb systyp,#sy.sih ; skip on SimH
beq 9999$
;
inc sp ; set up odd stack
mov #100$,r1 ; set up read address (a valid one)
mov #1000$,v..iit ; set up iit handler
scc
mfpi (r1) ; will fail
halt
;
100$: .word 123
;
1000$: hcmpeq #cpnzvc,2(sp) ; check PS cc untouched
htsteq sp ; check that fatal stack error seen
mov #stack,sp ; restore
mov #v..iit+2,v..iit ; restore
;
9999$: iot ; end of test B3.3
;
; Section C: 11/70 specifics ================================================= ; Section C: 11/70 specifics =================================================
; C1 Implementation differences ; C1 Implementation differences
; C1.1 Register used as source and changed in dst flow ; C1.1 Register used as source and changed in dst flow
@@ -1890,7 +1936,7 @@ tc0103: mov #vhugen,v..iit ; set iit handler
; END OF ALL TESTS - loop closure ============================================ ; END OF ALL TESTS - loop closure ============================================
; ;
mov tstno,r0 ; hack, for easy monitoring ... mov tstno,r0 ; hack, for easy monitoring ...
hcmpeq tstno,#30. ; all tests done ? hcmpeq tstno,#32. ; all tests done ?
; ;
jmp loop jmp loop
; ;