Files
Anachronaut e1273337c4 Two mechanical fixes SplitLint found: MVQA, and RSTA for zero
Twenty four places moved Q into A or B by pushing it and popping it back.
That is four bus cycles and two bytes to do what MVQA does in one of each,
and several of them are inside loops - Life, the calculator, int8. Nineteen
more loaded zero with INIA 0d0 where RSTA says the same thing in one byte.

Both are equivalent at the CPU rather than by assertion: RSTA and INIA both
leave Status alone, and PSHQ followed by POPA nets to A = Q with the Stack
Pointer where it started. The one difference is that the pair leaves a copy
of Q in memory just below the Stack Pointer and MVQA does not, which
nothing here reads.

Five recorded outputs moved and every one of them says the change worked:

- 16x16Life fits five more generations into the same cycle budget, the
  first 457 lines identical, because the loop got cheaper.
- Life.sbx is 1409 bytes rather than 1411, in three tests that list it.
- Edit.sbx is 1995 rather than 1996.

That last one broke a check I added this morning, and the hole is worth
recording: the CosmOS README's claim about Edit's size did not have the
word "Edit" on the same line as the number, because the subject was in the
sentence before, so the check that measures quoted sizes skipped it
silently. The sentence now names what it is talking about, which makes it
both checkable and clearer, and the check fails on a wrong number there.

Comments on either half of a replaced pair are carried onto the
instruction that replaces them, so nothing anybody wrote was lost.
2026-08-26 17:53:10 -04:00

130 lines
2.9 KiB
NASM

; The six instructions added after the first sixty four, and what each is for.
;
; Two of them are a call that puts nothing back, and four move a Data Pointer by a value
; worked out while the program is running rather than one written into it.
;
; WHY A SECOND KIND OF CALL. CALL puts A, B and Data Pointers 0 through 2 back the way it
; found them, which costs ten bytes of Stack and means a subroutine can only hand anything
; back through Q, DP3 or memory. That is the right default and it is what almost everything
; here uses. RCAL costs two bytes and puts nothing back at all, which is what a short leaf
; routine wants - and it is unsafe in exactly the way its name says, because everything the
; callee touches, the caller has lost.
;
; The two frames are different sizes, so RCAL must be returned from with RRET and CALL with
; RET. Crossing them walks the Stack to somewhere that was never a return address.
;
; WHY OFFSET BY A REGISTER. DPUP and DPDN take a byte written into the program, so moving a
; pointer by something just worked out meant storing it and loading it back. DPUA and DPDA
; take A; DPUW and DPDW take A and B together, which is how every sixteen bit value on this
; machine is carried between registers.
;
; Written by Anachronaut
#Program
start:
; ---- Offsetting by a byte, up and then back down ----
SETD.0 Text
INIA 0d7
DPUA.0
LDA.0
OUTA 0x00 ; the eighth character
INIA 0d4
DPDA.0
LDA.0
OUTA 0x00 ; and four before it
; ---- Offsetting by a whole sixteen bit value ----
SETD.1 Text
RSTA
INIB 0d13
DPUW.1
LDA.1
OUTA 0x00
RSTA
INIB 0d13
DPDW.1
LDA.1
OUTA 0x00 ; back where it started
; ---- What each kind of call puts back ----
;
; The same callee is reached both ways and sets A to something else. After the raw call
; that is what A holds; after the safe one it is not.
INIA 0x41
RCAL wrecker
OUTA 0x00 ; Z - the callee's
INIA 0x41
CALL polite
OUTA 0x00 ; A - put back
; ---- And what each costs ----
;
; Printed as a digit added to '0', so two bytes reads as "2" and ten reads as the
; character ten along from it.
MVSD.0
PSHD.0
POPB
POPA
SETD.2 Before
STB.2
RCAL rawCost
CALL safeCost
INIA 0x0A
OUTA 0x00
HALT
wrecker:
INIA 0x5A
RRET
polite:
INIA 0x5A
RET
; WRITTEN OUT TWICE RATHER THAN CALLED, because a call would put its own frame down on
; top of the one being measured and each of these would report ten bytes more than it
; costs. The first version of this did exactly that and printed twelve and twenty.
rawCost:
MVSD.1
PSHD.1
POPB
POPA
SETD.2 Before
LDA.2
CCF
SUB
MVQA
INIB 0x30
CCF
ADD
MVQA
OUTA 0x00
RRET
safeCost:
MVSD.1
PSHD.1
POPB
POPA
SETD.2 Before
LDA.2
CCF
SUB
MVQA
INIB 0x30
CCF
ADD
MVQA
OUTA 0x00
RET
#Data
Text:
"0123456789abcdefg"
Before:
0x00