1
0
mirror of https://github.com/wfjm/w11.git synced 2026-01-13 15:37:43 +00:00
wfjm.w11/tools/tcode/cpu_details.mac
wfjm c3f36925c2 use call+return+push+pop
- tools/tcode/*.mac: use call+return+push+pop
- tools/asm-11
  - lib/push_pop.mac: added, contains push/pop macros
  - lib/tcode_std_start.mac: include push_pop.mac; ensure PRI=0 at start
  - tests/test_0170_misc.mac: added, verifies call,return response
2022-07-30 11:14:57 +02:00

281 lines
9.6 KiB
Plaintext

; $Id: cpu_details.mac 1264 2022-07-30 07:42:17Z mueller $
; SPDX-License-Identifier: GPL-3.0-or-later
; Copyright 2022- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
;
; Revision History:
; Date Rev Version Comment
; 2022-07-28 1264 1.0 Initial version
; 2022-07-18 1259 0.1 First draft
;
; Test CPU details
; Section A: CPU registers
; Section B: stress tests
; Section C: 11/70 specifics
;
.include |lib/tcode_std_base.mac|
;
; Section A: CPU registers ===================================================
;
; Test A1: PIRQ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; This sub-section verifies operation of PIRQ register
;
; Test A1.1 -- PIRQ + spl ++++++++++++++++++++++++++++++++++++++++++++
; This test will exercise all 7 pirq interrupt levels:
; set 1+3 -> handle 3, set 7
; -> handle 7, set 6+4
; -> handle 6
; -> handle 4, set 5+2
; -> handle 5
; -> handle 2
; -> handle 1
;
; some useful definitions
pi.r00=bit08 ; pir 0 bit
pi.r01=bit09 ; pir 1 bit
pi.r02=bit10 ; pir 2 bit
pi.r03=bit11 ; pir 3 bit
pi.r04=bit12 ; pir 4 bit
pi.r05=bit13 ; pir 5 bit
pi.r06=bit14 ; pir 6 bit
pi.r07=bit15 ; pir 7 bit
pi.n00=0. ; lsb for no pir pending
pi.n01=1*042 ; lsb for pir 1 next
pi.n02=2*042 ; lsb for pir 2 next
pi.n03=3*042 ; lsb for pir 3 next
pi.n04=4*042 ; lsb for pir 4 next
pi.n05=5*042 ; lsb for pir 5 next
pi.n06=6*042 ; lsb for pir 6 next
pi.n07=7*042 ; lsb for pir 7 next
;
ta0101: mov #1000$,v..pir ; setup handler
mov #cp.pr7,v..pir+2 ; which runs at pr7
mov #cp.pir,r3 ; ptr to PIRQ
mov #cp.psw,r4 ; ptr to PSW
mov #1200$,r5 ; ptr to check data
clr 1300$ ; clear nesting counter
;
spl 7 ; lockout interrupts
bisb #bit01,1(r3) ; set PIRQ 1
hcmpeq (r3),#<pi.r01!pi.n01> ; check set 1
bisb #bit03,1(r3) ; set PIRQ 3
hcmpeq (r3),#<pi.r01!pi.r03!pi.n03> ; check set 1+3
spl 2
nop ; allow interrupts to happen
spl 0
nop ; allow interrupts to happen
htsteq (r3) ; PIRQ should clear now
mov #v..pir+2,v..pir; restore pirq vector catcher
clr v..pir+2
jmp 9999$
;
; PIRQ interrupt handler
; - it starts at pr7 from the vector
; - quickly lowers the priority to what is currently processed
; - new pirq bits are set at lowered priority
; - that leads to nested interrupts (tracked by a level counter)
;
1000$: inc 1300$ ; up level counter
mov (r3),r0 ; get PIRQ value
hcmpeq 1300$,(r5)+ ; check nesting level
hcmpeq r0,(r5)+ ; check pirq value
movb r0,(r4) ; PSW=PIRQ (sets priority)
bic #177761,r0 ; mask out index bits
mov r0,r1 ; r0 is word index (pri*2)
asr r1 ; r1 is byte index (pri*1)
mov #pi.r00,r2
ash r1,r2 ; r2 = pi.r00 <<(pri)
bic r2,(r3) ; clear current level in pirq
bis 1100$(r0),(r3) ; trigger new pirqs
nop ; allow nestec interrupts to happem
nop ; "
dec 1300$ ; down level counter
rti
;
; table with new pirqs triggered at a level
1100$: .word 0 ; new pirq @ level 0
.word 0 ; new pirq @ level 1
.word 0 ; new pirq @ level 2
.word pi.r07 ; new pirq @ level 3 -> 7
.word pi.r05!pi.r02 ; new pirq @ level 4 -> 5+2
.word 0 ; new pirq @ level 5
.word 0 ; new pirq @ level 6
.word pi.r06!pi.r04 ; new pirq @ level 7 -> 6+4
;
; table with expected values of pirq register in interrupt sequence
1200$: .word 1,pi.r01!pi.r03!pi.n03 ; set 1+3 -> handle 3, set 7
.word 2,pi.r01!pi.r07!pi.n07 ; set 1+7 -> handle 7, set 6+4
.word 2,pi.r01!pi.r04!pi.r06!pi.n06 ; set 1+4+6 -> handle 6
.word 2,pi.r01!pi.r04!pi.n04 ; set 1+4 -> handle 4, set 5+2
.word 3,pi.r01!pi.r02!pi.r05!pi.n05 ; set 1+2+5 -> handle 5
.word 1,pi.r01!pi.r02!pi.n02 ; set 1+2 -> handle 2
.word 1,pi.r01!pi.n01 ; set 1 -> handle 1
; nesting level counter
1300$: .word 0
;
9999$: iot ; end of test A1.1
;
; Section B: Stress tests ====================================================
;
; Test B1: address mode torture tests +++++++++++++++++++++++++++++++++++++++
; This sub-section tests peculiar address node usage
;
; Test B1.1 -- src-dst update hazards with (r0)+,(r0) ++++++++++++++++
;
tb0101: mov #2,r5
100$: mov #1000$,r0
mov #1110$,r1
push 1000$+2 ; save data that will change
push 1000$+6
push 1100$+0
push 1100$+4
;
mov (r0)+,(r0)+ ; mov 111 over 222
add (r0)+,(r0)+ ; add 333 to 444
mov -(r1),-(r1) ; mov 444 over 333
add -(r1),-(r1) ; add 222 to 111
;
hcmpeq 1000$+2,#000111
hcmpeq 1000$+6,#000777
hcmpeq 1100$+4,#000444
hcmpeq 1100$+0,#000333
;
pop 1100$+4 ; restore data
pop 1100$+0
pop 1000$+6
pop 1000$+2
sob r5,100$
jmp 9999$
;
1000$: .word 000111 ; data for (r0)+ part
.word 000222
.word 000333
.word 000444
;
1100$: .word 000111 ; data for -(r0) part
.word 000222
.word 000333
.word 000444
1110$:
;
9999$: iot ; end of test B1.1
;
; Test B1.2 -- (pc)+ as destination ++++++++++++++++++++++++++++++++++
;
tb0102: mov #2,r5
100$: push 1000$+4 ; save data that will change
push 1100$+4
push 1200$+2
;
clr r0
1000$: mov #1,#0 ; (pc)+,(pc)+: write #1 over #0
1100$: add #1,#2 ; (pc)+,(pc)+: add #1 to #2
mov 1000$+4,1200$+2 ; -14(pc),2(pc): dst of mov -> src of add
1200$: add #0,r0 ; add #1(!) to r0
;
hcmpeq 1000$+4,#1
hcmpeq 1100$+4,#3
hcmpeq r0,#1
;
pop 1200$+2 ; restore data
pop 1100$+4
pop 1000$+4
sob r5,100$
;
9999$: iot ; end of test B1.2
;
; Test B1.3 -- pc as destination in clr, mov, and add ++++++++++++++++
;
tb0103: mov #000137,@#0 ; setup jmp 1000$ at mem(0)
mov #1000$,@#2
clr pc
halt
halt
halt
1000$: mov #1100$,pc
halt
halt
halt
1100$: clr r0
add #4,pc ; skip two instructions
inc r0
inc r0
inc r0 ; lands here
inc r0
hcmpeq r0,#2
;
clr @#0 ; remove jmp 1000$ at mem(0)
clr @#2
;
9999$: iot ; end of test B1.3
;
; Test B2: pipeline torture tests +++++++++++++++++++++++++++++++++++++++++++
; This sub-section tests self-modifying code
;
; Test B2.1 -- self-modifying code, use (pc), -(pc) ++++++++++++++++++
;
tb0201: mov #2,r5
100$: mov 1000$,-(sp)
mov 1100$,-(sp)
;
clr r0
clr r1
clr r2
mov #005201,r3 ; r3= inc r1
mov #005202,r4 ; r4= inc r2
;
inc r0
mov r3,(pc) ; will overwrite next instruction
1000$: halt ; will be overwritten with 'inc r1'
inc r0
1100$: mov r4,-(pc) ; will overwrite itself and re-execute(!)
inc r0
;
hcmpeq r0,#3 ; 3 inc r0 in code
hcmpeq r1,#1 ; check that 'inc r1' was executed
hcmpeq r2,#1 ; check that 'inc r2' was executed
;
mov (sp)+,1100$
mov (sp)+,1000$
sob r5,100$
;
9999$: iot ; end of test B2.1
;
; Test B2.2 -- self-modifying code, use (pc) case 2 ++++++++++++++++++
; Was insprired by KDJ11A.MAC (J11 is indeed pipelined)
;
tb0202: mov #2,r5
100$: mov 1000$,-(sp)
mov 1100$,-(sp)
mov 1200$,-(sp)
;
mov #1999$,r1
clr r2
;
mov #005202,(pc) ; will replace jmp (r1) with 'inc r2'
1000$: jmp (r1)
mov #005202,(pc) ; will replace jmp (r1) with 'inc r2'
1100$: jmp (r1)
mov #005202,(pc) ; will replace jmp (r1) with 'inc r2'
1200$: jmp (r1)
;
hcmpeq r2,#3 ; check that 'inc r2' was executed
;
mov (sp)+,1200$
mov (sp)+,1100$
mov (sp)+,1000$
sob r5,100$
jmp 9999$
;
1999$: halt ; halt as target for 'jmp (r1)'
;
9999$: iot ; end of test B2.2
;
; END OF ALL TESTS - loop closure ============================================
;
mov tstno,r0 ; hack, for easy monitoring ...
hcmpeq tstno,#6. ; all tests done ?
;
jmp loop
;
.end start