mirror of
https://github.com/wfjm/w11.git
synced 2026-02-27 01:19:57 +00:00
cpu_basics.mac:test jsr sp,dst and rts sp
This commit is contained in:
29
doc/w11a_diff_70_jsr_sp.md
Normal file
29
doc/w11a_diff_70_jsr_sp.md
Normal file
@@ -0,0 +1,29 @@
|
||||
## Known differences between w11a and KB11-C (11/70)
|
||||
|
||||
### `jsr sp` pushes original `sp` value
|
||||
|
||||
In the logic of the `jsr` instruction is the given register the
|
||||
_linkage register_, meant to be used for parameter passing.
|
||||
`jsr` pushes the _linkage register_ to the stack, and the matching `rts`
|
||||
will restore it. That works fine for `r0` to `r5` and for `pc`.
|
||||
But in a `jsr sp` that interferes with the implicit use of `sp`
|
||||
as the stack pointer, `sp` is saved on the stack which is defined by `sp`.
|
||||
The question is whether the original `sp` value is saved, or the `sp`
|
||||
value after it has been decremented to hold the address for the write
|
||||
to stack. The specification simply says
|
||||
```
|
||||
down(sp) := sp
|
||||
```
|
||||
and the question is whether the side effect of the left side happens before
|
||||
the right side is evaluated.
|
||||
|
||||
The 11/70 implementation of `jsr` first decrements the `sp` in
|
||||
microstate `jsr.20` and then starts a write of `sp` in `jsr.30`.
|
||||
So the modified `sp` is stored.
|
||||
|
||||
The w11 implement ion first reads `sp` into a register, then decrements
|
||||
`sp` and writes. So the original `sp` is stored.
|
||||
|
||||
`jsr sp` is never used due to its bizarre semantics. The matching `rts sp`
|
||||
results in a useless `sp` too. Given that, this is considered an
|
||||
acceptable deviation from 11/70 behavior.
|
||||
@@ -8,6 +8,7 @@ The issues of the w11 CPU and systems are listed in a separate document
|
||||
- [Instruction fetch after `SPL`](w11a_diff_70_spl_bug.md)
|
||||
- ['red stack violation' loses PSW](w11a_diff_70_red_stack_abort.md)
|
||||
- ['instruction completed flag' in `MMR0` is not implemented](w11a_diff_70_instruction_complete.md)
|
||||
- [`jsr sp` pushes original `sp` value](w11a_diff_70_jsr_sp.md)
|
||||
- [18-bit UNIBUS address space not mapped](w11a_diff_70_unibus_mapping.md)
|
||||
|
||||
All points relate to very 11/70 specific behavior, no operating system
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
; $Id: cpu_basics.mac 1263 2022-07-28 09:00:42Z mueller $
|
||||
; $Id: cpu_basics.mac 1285 2022-08-25 06:15:42Z mueller $
|
||||
; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
; Copyright 2015-2022 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
;
|
||||
@@ -944,6 +944,50 @@ ta0403: clr 900$ ; reset call counter
|
||||
;
|
||||
9999$: iot ; end of test A4.3
|
||||
;
|
||||
; Test A4.4 -- jsr sp and rts sp ++++++++++++++++++++++++++++++++++++++
|
||||
; In case of jsr sp and rts sp, the sp register is used both as linkage
|
||||
; register and implicitly as stack pointer. That interferes and gives
|
||||
; quite bizarre semantics, certainly never used, but should work
|
||||
; - jsr sp,<dst> will
|
||||
; - push current SP onto stack
|
||||
; - set SP to the location of following instruction
|
||||
; - jump to <dst>
|
||||
; - rts sp will
|
||||
; - set PC to current SP
|
||||
; - pop SP of the current stack
|
||||
; that will set SP to the opcode of instruction being returned to !
|
||||
;
|
||||
ta0404: hcmpeq sp,#stack ; check stack is default
|
||||
clr 100$ ; clear 'args' after jsr
|
||||
clr 100$+2
|
||||
;
|
||||
jsr sp,300$ ; will push SP to current stack
|
||||
100$: .word 0 ; 'args', will be overwritten
|
||||
.word 0 ;
|
||||
;
|
||||
200$: clr r1 ; return instruction, also loaded SP
|
||||
hcmpeq sp,200$ ; check loaded SP
|
||||
mov #stack-2,sp ; restore stack to where jsr pushed it
|
||||
;
|
||||
; w11 saves original sp, 11/70,SimH,e11 save sp after it was decremented
|
||||
; This is considered a minor deviation (jsr sp never used!)
|
||||
;
|
||||
mov #stack,r1
|
||||
tstb systyp ; check environment
|
||||
bge 210$ ; >=0 is on w11
|
||||
sub #2,r1 ; if not, subtract 2 (now sp-2)
|
||||
210$: hcmpeq (sp)+,r1 ; check jsr stored stack pointer
|
||||
hcmpeq 100$,#123 ; check writes via SP in routine
|
||||
hcmpeq 100$+2,#345 ; check writes via SP in routine
|
||||
jmp 9999$
|
||||
;
|
||||
; this routine must never 'push' that will overwrite the calling jsr !!
|
||||
300$: mov #123,(sp)+
|
||||
mov #345,(sp)+
|
||||
rts sp
|
||||
;
|
||||
9999$: iot ; end of test A4.4
|
||||
;
|
||||
; Test A5 -- mark ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
; This sub-section verifies
|
||||
; x xxx xxx xxx xxx xxx NZVC Instruction / Remark
|
||||
@@ -3094,7 +3138,7 @@ tf0301: mov #v..iot+2,v..iot ; block iot handler
|
||||
; END OF ALL TESTS - loop closure ============================================
|
||||
;
|
||||
mov tstno,r0 ; hack, for easy monitoring ...
|
||||
hcmpeq tstno,#52. ; all tests done ?
|
||||
hcmpeq tstno,#53. ; all tests done ?
|
||||
;
|
||||
jmp loop
|
||||
;
|
||||
|
||||
Reference in New Issue
Block a user