CosmOS pre-alpha and launchable application versions of old programs.
This commit is contained in:
@@ -0,0 +1,210 @@
|
||||
; Tests MVDS, which copies a Data Pointer into the Stack Pointer.
|
||||
;
|
||||
; This is the dangerous one. Moving the Stack Pointer abandons everything below the new
|
||||
; position: return addresses, saved registers, interrupt frames, all of it. Nothing is
|
||||
; unwound, because moving the Stack does not move what is on it.
|
||||
;
|
||||
; It is here for one job, and that job is what this program acts out. A system that runs
|
||||
; other programs and takes the machine back afterwards cannot do so without it. A program
|
||||
; that gives up part way through leaves whatever it pushed behind, and nothing is ever
|
||||
; going to return and tidy it away. Without MVDS the Stack only ever moves downward, a
|
||||
; little further with every program run, and a shell cannot outlive many of them.
|
||||
;
|
||||
; The other half of the story is that moving the Stack does not destroy what was on it.
|
||||
; A routine that puts the Stack Pointer back where it found it returns perfectly normally,
|
||||
; because the frame was only stepped away from. Both halves are acted out here, and the
|
||||
; nesting case with them: two routines that each borrow a Stack, one inside the other,
|
||||
; each keeping its own saved Stack Pointer on the Stack it borrowed. A fixed location in
|
||||
; Data Memory would fail exactly there, and would fail silently.
|
||||
;
|
||||
; Both sequences are the ones the Programming Manual prints under "The Stack Pointer,
|
||||
; Set By Hand", so if either example ever stops working this test says so.
|
||||
;
|
||||
; Correct output is:
|
||||
; stack reclaim test
|
||||
; at start: FFFF
|
||||
; spent: FFF7
|
||||
; reclaimed: FFFF
|
||||
; still good: 33
|
||||
; borrowed: 7 and 9
|
||||
; back home: FFFF
|
||||
|
||||
#Include console.asm
|
||||
|
||||
#Program
|
||||
|
||||
start:
|
||||
SETD.0 Banner
|
||||
CALL printString
|
||||
CALL newLine
|
||||
|
||||
; Where the Stack is before anything has touched it. Read first, so that no call has
|
||||
; had a chance to move it.
|
||||
MVSD.0
|
||||
SETD.1 SavedStack
|
||||
STD.0.1
|
||||
|
||||
SETD.0 StartLabel
|
||||
CALL printString
|
||||
SETD.0 SavedStack
|
||||
CALL printWordHex
|
||||
CALL newLine
|
||||
|
||||
; Spend some Stack and never give it back. This is not a subroutine, because a
|
||||
; subroutine that pushed without popping would take its own return address with it.
|
||||
; It stands in for a program that stops half way through.
|
||||
INIA 0x11
|
||||
PSHA PSHA PSHA PSHA
|
||||
PSHA PSHA PSHA PSHA
|
||||
|
||||
MVSD.0
|
||||
SETD.1 Spent
|
||||
STD.0.1
|
||||
|
||||
SETD.0 SpentLabel
|
||||
CALL printString
|
||||
SETD.0 Spent
|
||||
CALL printWordHex
|
||||
CALL newLine
|
||||
|
||||
; Take it back. Nothing pops those eight bytes: they are simply no longer on the Stack,
|
||||
; which is the whole of what reclaiming means.
|
||||
SETD.1 SavedStack
|
||||
LDD.0.1
|
||||
MVDS.0
|
||||
|
||||
MVSD.0
|
||||
SETD.1 Reclaimed
|
||||
STD.0.1
|
||||
|
||||
SETD.0 ReclaimedLabel
|
||||
CALL printString
|
||||
SETD.0 Reclaimed
|
||||
CALL printWordHex
|
||||
CALL newLine
|
||||
|
||||
; A Stack Pointer in the right place is not proof that the Stack works. Push something
|
||||
; through it and get it back, so that the reclaimed Stack is shown to be usable and not
|
||||
; merely well positioned.
|
||||
SETD.0 GoodLabel
|
||||
CALL printString
|
||||
INIA 0d33
|
||||
PSHA
|
||||
RSTA
|
||||
POPA
|
||||
CALL printByteDecimal
|
||||
CALL newLine
|
||||
|
||||
; ---- Moving the Stack and coming back from it ----
|
||||
; borrower runs on a Stack of its own and returns with a plain RET, which only works
|
||||
; because putting the Stack Pointer back leaves the frame exactly as CALL left it.
|
||||
CALL borrower
|
||||
|
||||
SETD.0 BorrowedLabel
|
||||
CALL printString
|
||||
SETD.0 OuterResult
|
||||
LDA.0
|
||||
CALL printByteDecimal
|
||||
SETD.0 AndText
|
||||
CALL printString
|
||||
SETD.0 InnerResult
|
||||
LDA.0
|
||||
CALL printByteDecimal
|
||||
CALL newLine
|
||||
|
||||
; The Stack has to be back where it started, or the nesting quietly lost track of it.
|
||||
MVSD.0
|
||||
SETD.1 Reclaimed
|
||||
STD.0.1
|
||||
SETD.0 HomeLabel
|
||||
CALL printString
|
||||
SETD.0 Reclaimed
|
||||
CALL printWordHex
|
||||
CALL newLine
|
||||
HALT
|
||||
|
||||
; Borrows a Stack, works on it, calls something that does the same thing again, then puts
|
||||
; the Stack back and returns. The old Stack Pointer goes onto the borrowed Stack rather
|
||||
; than into a fixed place in memory, which is what makes the nesting safe: the inner
|
||||
; routine keeps its own copy on its own Stack and cannot tread on this one.
|
||||
borrower:
|
||||
MVSD.3
|
||||
SETD.0 OuterTop
|
||||
MVDS.0
|
||||
PSHD.3
|
||||
|
||||
INIA 0d7
|
||||
PSHA
|
||||
RSTA
|
||||
POPA
|
||||
SETD.1 OuterResult
|
||||
STA.1
|
||||
|
||||
CALL innerBorrower
|
||||
|
||||
POPD.3
|
||||
MVDS.3
|
||||
RET
|
||||
|
||||
; The same again, one level down and on a Stack of its own.
|
||||
innerBorrower:
|
||||
MVSD.3
|
||||
SETD.0 InnerTop
|
||||
MVDS.0
|
||||
PSHD.3
|
||||
|
||||
INIA 0d9
|
||||
PSHA
|
||||
RSTA
|
||||
POPA
|
||||
SETD.1 InnerResult
|
||||
STA.1
|
||||
|
||||
POPD.3
|
||||
MVDS.3
|
||||
RET
|
||||
|
||||
#Data
|
||||
|
||||
Banner:
|
||||
"stack reclaim test"
|
||||
StartLabel:
|
||||
"at start: "
|
||||
SpentLabel:
|
||||
"spent: "
|
||||
ReclaimedLabel:
|
||||
"reclaimed: "
|
||||
GoodLabel:
|
||||
"still good: "
|
||||
BorrowedLabel:
|
||||
"borrowed: "
|
||||
AndText:
|
||||
" and "
|
||||
HomeLabel:
|
||||
"back home: "
|
||||
|
||||
SavedStack:
|
||||
0x00 0x00
|
||||
Spent:
|
||||
0x00 0x00
|
||||
Reclaimed:
|
||||
0x00 0x00
|
||||
OuterResult:
|
||||
0x00
|
||||
InnerResult:
|
||||
0x00
|
||||
|
||||
; Two places a Stack can live, sixty four bytes each. The label is on the last byte of
|
||||
; each, because a Stack grows downward from wherever it is set.
|
||||
OuterStack:
|
||||
#Reserve 0d63
|
||||
OuterTop:
|
||||
0x00
|
||||
InnerStack:
|
||||
#Reserve 0d63
|
||||
InnerTop:
|
||||
0x00
|
||||
|
||||
#Vectors
|
||||
|
||||
Boot start
|
||||
Reference in New Issue
Block a user