Files
SplitBit-Emulator/Programs/testPrograms/stackPointerTest.asm
T
AnachronautandClaude Opus 5 4fd8bf7b3f Step a Data Pointer with INCD and DECD, not DPUP and DPDN by one
DPUP takes an immediate, so an offset of one is legal and does exactly the
right thing. It is also three bytes where INCD is two, and reads as "offset
the pointer up by one" where INCD reads as "step the pointer".

56 of them across 15 files: the system, the assembler, the editor, and eight
test programs. CosmOS is 9,564 bytes to 9,537, the native assembler 11,648
to 11,635, and every program in the repository together 49 bytes lighter.

The worst offender was numbers.asm, written this week, where every sixteen
bit helper reaches the low byte and comes back the long way round. It is the
file every other part of the assembler includes, so it is the first thing
anybody reads when they go looking - and it was teaching them the long way.
Pattern matched off sbfs.asm rather than off the instruction table I had
just embedded in two programs.

THIS IS NOT TWO WAYS TO DO ONE THING. DPUP takes an arbitrary number, so one
is inevitably among them; INCD earns its place by making the common case a
byte cheaper. The overlap is structural and the choice is a usage question,
which is a linter's job rather than an ISA's - "DPUP.n 0d01: INCD.n does
this in a byte less" is a mechanical rule with no judgement in it.

Nothing needed re-recording, which was not a foregone conclusion: cosmosBreak
prints the system addresses the registers happened to hold, and they did not
move. Both assemblers still produce identical bytes and CosmOS still builds
itself to a fixed point.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW
2026-08-21 18:16:27 -04:00

37 lines
1.0 KiB
NASM

; Tests MVSD, which copies the Stack Pointer into a Data Pointer.
;
; The Stack Pointer still cannot be written, so this does not let a program move the
; Stack. It lets a program find it, which is what reading anything already on the Stack
; requires. Without it, the manual's claim that a Data Pointer can be aimed at the Stack
; is not something a program can actually act on: there is no way to learn where the
; Stack is without already knowing.
;
; An interrupt handler needs this to reach its own frame, which is how a fault handler
; steps over the byte that failed and carries on.
;
; Correct output is:
; OK
#Program
start:
; Push two bytes, then go looking for them.
INIA 0d79 ; 'O'
PSHA
INIA 0d75 ; 'K'
PSHA
; The Stack Pointer points at the next free slot, so the byte pushed last sits one
; above it, and the one before that sits two above.
MVSD.0
INCD.0
LDA.0 ; 'K', the last one pushed.
INCD.0
LDB.0 ; 'O', the one before it.
OUTB 0x00
OUTA 0x00
INIA 0x0A
OUTA 0x00
HALT