; 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