; 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 sits at the top of video memory, at 0xFC00, 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 0xFC84. INIA 0xFC 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