Files
SplitBit-Emulator/Programs/Examples/colours.asm
T
AnachronautandClaude Opus 5 ff4b025058 Make the cursor blink while the machine is waiting, and show how the palette works
THE CURSOR DID NOT BLINK, and the reason is worth stating: it blinks on the machine's clock,
and the machine's clock had stopped. A console waiting on a key stops the CPU, so no cycles
passed, so the phase never moved - and the one moment somebody is looking at a cursor is the
moment they are being asked to type.

Waiting is now charged as IDLE CYCLES, which is what they were built for: a machine stopped
on a device is not using memory, the same distinction WAIT makes, arrived at from the other
direction. And the devices are told as it happens rather than when the instruction finally
finishes, because a display controller does not stop blinking because the processor is
waiting on a keyboard, any more than a disk stops turning.

A keyboard file can now say NOTHING happened. A zero is a byte no keyboard sends, so it is
free to mean "a moment went by with nobody typing" - which is the commonest thing behind a
window and the only thing a file otherwise could not express. That unlocked the whole waiting
path: three checks that the cursor is lit, then dark half a second later, then lit again,
which is what blinking is.

And Programs/Examples/colours.asm, because the palette had nowhere a newcomer could read it.
It prints the sixteen pairs, prints each one again turned inside out, and then CHANGES ONE by
writing three bytes into the palette - so the difference between using the colours a machine
wakes up with and choosing your own is visible in one program. Its header explains what a
cell is, what the attribute nibble does, why palette entries are four bytes rather than
three, and why video memory has to be reached through the controller.

The manual now says where the palette lives and points at it.

SplitLint found a redundant RSTA in the example, which was worth acting on rather than
suppressing: the zero was already in A from the mode write two lines up, and saying so in a
comment teaches that SETD does not touch A, which is a thing worth knowing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW
2026-08-29 08:26:15 -04:00

143 lines
4.2 KiB
NASM

; colours.asm
; Every colour the machine wakes up with, and how to change one.
; Written by Anachronaut
;
; ---- What a colour is on this machine ----
;
; The screen draws CELLS, and a cell is two bytes: which tile, and an attribute. A tile is
; eight by eight pixels and every pixel is a byte - a number, not a colour. What colour that
; number means is looked up in the PALETTE, which is 256 entries of four bytes: red, green,
; blue, and one spare. Four rather than three so that entry n begins at n times four, which
; is a shift; three would need a multiply and this machine has none.
;
; A cell's attribute nibble is ADDED to every number in its tile, sixteen at a time. So the
; same tile drawn with attribute 0 reads palette entries 0 and 1, with attribute 1 it reads
; 16 and 17, and so on. Sixteen banks of sixteen.
;
; The console's glyphs are drawn in numbers 0 and 1 - paper and ink - so for text those
; sixteen banks are sixteen INK AND PAPER PAIRS. Writing the attribute register at port 0x06
; says which one to use.
;
; The palette a machine wakes up with is laid out so one bit inverts a pair:
;
; banks 0 to 7 a colour on black
; banks 8 to 15 the same colour AS the background, with black text on it
;
; So attribute XOR 8 highlights, which is all a cursor is.
;
; ---- Reaching the palette ----
;
; Video memory belongs to the screen, not to the program, so the CPU cannot write it with a
; store. It is reached the way every device's memory is reached: registered as a bank, and
; written through the memory controller. That is what the last part of this program does.
#Program
start:
; The console wants sixteen columns for the name and a bit more, so the wide screen is
; not needed. This is the mode the machine wakes up in and is here to be seen.
RSTA
OUTA 0x31
; ---- Sixteen pairs, one line each ----
;
; Counting in memory rather than in a register, because the loop below uses A and B for
; the arithmetic and there is nowhere else to keep it.
SETD.0 Bank
STA.0 ; Still the zero from the mode write above: SETD does not touch A
nextBank:
LDA.0
OUTA 0x06 ; Draw in this pair from now on
SETD.1 SampleText
RCAL say
; The same bank with bit 3 set, which is the same colour inside out.
LDA.0
INIB 0x08
XOR
MVQA
OUTA 0x06
SETD.1 HighlightText
RCAL say
RSTA
OUTA 0x06 ; Back to plain for the newline
INIA 0x0A
OUTA 0x00
LDA.0
INCA
STA.0
INIB 0d8 ; Eight banks; the other eight are their reverses
CCF
SUB
BNQ nextBank
; ---- And one written by hand ----
;
; Bank 2 is green when the machine starts. This makes its ink orange instead, by writing
; three bytes into the palette - which means reaching video memory, which means the
; controller.
; Give the screen's memory a bank number. The screen answers on port 0x30, and bank 3 is
; the first number software is allowed to hand out: 0, 1 and 2 belong to the machine.
INIA 0d3
OUTA 0xE3 ; DestBank: the number being given
INIA 0x30
OUTA 0xE2 ; SourceLow: the port that owns the memory
INIA 0x03
OUTA 0xE8 ; Command: RegisterBank
; The palette starts at 0xC000, and entry n is at n times four. Bank 2's ink is entry
; 2 * 16 + 1, which is 33, and 33 * 4 is 132 - so 0xC084.
INIA 0xC0
OUTA 0xE4 ; DestHigh
INIA 0x84
OUTA 0xE5 ; DestLow
; Writing the controller's Data port puts a byte at the destination and steps it on, so
; three writes are red, green and blue in order.
INIA 0xF0
OUTA 0xE9 ; red
INIA 0x80
OUTA 0xE9 ; green
INIA 0x20
OUTA 0xE9 ; blue
INIA 0x02
OUTA 0x06 ; That pair again, now that it has been changed
SETD.1 ChangedText
RCAL say
RSTA
OUTA 0x06
HALT
; DP1 names a string. Printing is one byte at a time out of port 0x00, which is the oldest
; thing on this machine and has never changed.
say:
LDA.1
BRA sayDone
OUTA 0x00
INCD.1
BRI say
sayDone:
RRET
#Data
Bank:
0x00
SampleText:
" ordinary "
HighlightText:
" highlighted "
ChangedText:
"
bank 2's ink is orange now, because this program said so
"
#Vectors
Boot start