Words that crawl up the screen, the way Zelda's story does
An about screen for our square: a few lines of our own, crawling up the screen and starting again when they run out. Play it and read along. The program is 221 instructions in 663 bytes, built and checked the same way.
Play it here The cartridge, to play anywhere that plays NES cartridges: about.nes
On the screen
One row for every row it moves
Leave the title of The Legend of Zelda alone and it tells you its story, the words creeping up the screen. The console holds two screens of background, stacked one above the other on this board, and the game simply scrolls down through them and round again, one pixel every second frame. It never redraws the screen: each time the words have moved up by one row’s height, 8 pixels, it writes a single new row of 32 tiles into the row about to come into view, plus a few colour bytes now and then for the words it shows in colour. That is all the drawing a whole story needs. This cartridge does the same with our own words, in one colour.
| this cartridge | The Legend of Zelda | |
|---|---|---|
| pixels the words move, and frames between moves | 1, every 2 | 1, every 2 |
| rows written, and frames apart | 74, every 16 | 80, every 16 |
| pixels of crawl for each row written | 8 | 8 |
| colour bytes written | 0 | 152 |
| other tiles written | 0 | 0 |
| the picture is split | no | no |
| pixels crawled in the frames measured | 590 in 1,182 | 638 in 1,278 |
As written
The part of the program this lesson is about. The whole program is a plain text file: about.s
;; Every second frame the scroll moves down one pixel, round from 479 to
;; 0; each time it is a whole row down, the next row is made ready.
crawl:
LDA $42
EOR #$01
STA $42
BNE crawled
INC $40
BNE carried
INC $41
carried:
LDA $41
BEQ within
LDA $40
CMP #$E0
BCC within
LDA #$00
STA $40
STA $41
within:
;; The register's view: within the top screen below 240, else the lower.
LDA $41
BNE lower
LDA $40
CMP #$F0
BCS lower
STA $47
LDA #$00
STA $48
JMP view
lower:
SEC
LDA $40
SBC #$F0
STA $47
LDA #$02
STA $48
view:
LDA $40
AND #$07
BNE crawled
JSR prepare
crawled:
RTS
;; The row 240 below the scroll, which comes into view as it next moves:
;; its place (counting down both screens, round at 480), and in it a line
;; of the words, centred, or the gap between two lines.
prepare:
CLC
LDA $40
ADC #$F0
STA $45
LDA $41
ADC #$00
STA $46
BEQ first
LDA $45
CMP #$E0
BCC first
SBC #$E0
STA $45
LDA #$00
STA $46
first:
;; $45/$46 is now 0 to 479. Below 240 it is the top screen ($2000),
;; else the lower ($2800), 240 less.
LDA #$20
STA $49
LDA $46
BNE second
LDA $45
CMP #$F0
BCC place
second:
SEC
LDA $45
SBC #$F0
STA $45
LDA #$28
STA $49
place:
;; The row's address: the screen's, and 32 for each 8 pixels.
LDA $45
AND #$F8
ASL A
ASL A
STA $46
LDA $45
LSR A
LSR A
LSR A
LSR A
LSR A
LSR A
ORA $49
STA $45
LDA #$00
LDX #$1F
blank:
STA $0300,X
DEX
BPL blank
LDA $43
EOR #$01
STA $43
BEQ ready
;; A line: its length, then its letters, placed in the middle. A length
;; of $FF is the end of the words, and they start again.
LDY #$00
LDA ($20),Y
CMP #$FF
BNE line
LDA wordslo
STA $20
LDA wordshi
STA $21
LDA ($20),Y
line:
TAX
LDA #$20
SEC
STX $4A
SBC $4A
LSR A
TAX
LDY #$00
copy:
CPY $4A
BEQ copied
INY
LDA ($20),Y
STA $0300,X
INX
JMP copy
copied:
INY
TYA
CLC
ADC $20
STA $20
LDA $21
ADC #$00
STA $21