Rooms that slide in the way Zelda's do
The square in a grid of rooms, seen from above. The picture stands still while it walks; out of the left or right side, the next room slides in and carries it along. The program is 497 instructions in 1,032 bytes, built and checked the same way.
Play it here Change it on the desk The cartridge, to play anywhere that plays NES cartridges: rooms.nes
On the screen
A room at a time
Watching The Legend of Zelda’s memory showed one byte that changes each time Link leaves a screen: it went down by 1 for a step left and by 16 for a step up, so the land is a grid 16 rooms wide, numbered along its rows. At the edge, the picture slides a whole screen at a steady rate and Link is carried with it. This cartridge keeps a room number the same way and slides the same way. How each draws the room that is coming in is where they differ, and the table says how, from the log of every write each made to the picture chip.
| this cartridge | The Legend of Zelda | |
|---|---|---|
| which name tables sit side by side | side by side, fixed by the board | one above the other while playing; side by side from 4 frames before the slide to 2 after it |
| the room's number, before and after a step left | 103 to 102 | 119 to 118 |
| frames from the number changing to the picture moving | 2 | 31 |
| frames the slide takes | 64 | 64 |
| pixels moved, and pixels a frame | 256, 4 a frame | 256, 4 a frame |
| written before the picture moves | none | 23 rows of 32 tiles across, 2 rows of 24 tiles across |
| written while it slides | 32 columns of 30 tiles down | 32 columns of 22 tiles down, 2 rows of 24 tiles across |
| frame of the slide the first column is written in | 0 | 31 |
| frames between columns | 2 | 1 |
| the room's number, before and after a step up | 119 to 103 | 119 to 103 |
| a step up: rows written across, tiles in each | 30, 32 | 22, 32 |
| from row, to row | 29, 0 | 29, 8 |
| frames from the number changing to the first row | 2 | 6 |
| frames between rows | 2 | 2 |
Where the two part ways
The Legend of Zelda writes 23 rows of 32 tiles across, 2 rows of 24 tiles across before the picture moves, which takes it 31 frames, and writes nothing for the first half of the slide; its columns come from frame 31 of the slide on, one a frame. This cartridge writes nothing beforehand and draws the incoming room through the whole slide, a column every second frame, each just ahead of the edge coming into sight.
What The Legend of Zelda’s rows are for came out of a log of its writes to the cartridge’s own registers. Its board lets the program choose which of the two name tables sit side by side. While Link walks, they sit one above the other, so the rows go into the table below the screen, out of sight. Just before the slide the game turns them side by side, which puts that new room beside the one on the screen, and the slide scrolls across into it. Meanwhile the columns copy the new room into the first table, and just after the slide the tables go back one above the other with the new room on the screen. This cartridge’s board cannot do that: its tables are soldered side by side, so it draws the new room as it goes.
Up and down, written over the room on the screen
Across, there is a second name table to draw the new room into. Up and down there is not, so both write the new room over the old one in the table on the screen, a row at a time, each just before the picture brings it into sight. The row being written is, for those frames, also the one leaving at the other edge, so an eight-line band there shows the new room a moment early; on most televisions those lines are outside the picture. The Legend of Zelda writes fewer rows because its top rows are its status bar, which stays put.
As written
The part of the program this lesson is about. The whole program is a plain text file: rooms.s
;; Sliding: on every second step a column of the new room, the next to
;; come into sight (from its right side going left, from its left going
;; right); then the scroll moves 4 pixels toward the new room, the square
;; goes with the picture, and after 64 steps the new room is the one on
;; the screen.
slide:
LDA $34
AND #$01
BNE stepped
LDA $34
LSR A
LDX $32
BNE fromleft
EOR #$1F
fromleft:
JSR prepcol
LDA $35
EOR #$01
ASL A
ASL A
ORA $39
STA $39
LDA #$01
STA $38
stepped:
LDA $32
BNE east
SEC
LDA $36
SBC #$04
STA $36
LDA $37
SBC #$00
AND #$01
STA $37
LDA $11
CMP #$EC
BCS carried
CLC
ADC #$04
STA $11
JMP carried
east:
CLC
LDA $36
ADC #$04
STA $36
LDA $37
ADC #$00
AND #$01
STA $37
LDA $11
CMP #$04
BCC carried
SEC
SBC #$04
STA $11
carried:
INC $34
LDA $34
CMP #$40
BNE sliding
LDA $35
EOR #$01
STA $35
STA $37
LDA #$00
STA $36
STA $31
sliding:
RTS
;; What tile is at a place in a room: the column in $05, the row in X,
;; the room in $3B; the tile comes back in A and X is kept. Trees along
;; the top and bottom two rows and down both sides, with a gap in the
;; middle of each to walk out by; inside, a tree wherever the room's
;; number and the place agree on it, so each room is different.
tileat:
CPX #$02
BCC edge
CPX #$1C
BCS edge
LDA $05
BEQ side
CMP #$1F
BEQ side
CMP #$04
BCC sand
CMP #$1C
BCS sand
CPX #$04
BCC sand
CPX #$1A
BCS sand
;; inside: col*7 + row*3 + room, a tree when its low five bits are 0
LDA $05
ASL A
ASL A
ASL A
SEC
SBC $05
STA $07
TXA
ASL A
STA $08
TXA
CLC
ADC $08
CLC
ADC $07
CLC
ADC $3B
AND #$1F
BEQ tree
JMP sand
edge:
LDA $05
CMP #$0E
BCC tree
CMP #$12
BCS tree
JMP sand
side:
CPX #$0C
BCC tree
CPX #$12
BCS tree
sand:
LDA #$00
RTS
tree:
LDA #$03
RTSBefore this one: The camera's dead zone, the way Mario's is