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

frame 120
frame 120
frame 140
frame 140
frame 160
frame 160
frame 180
frame 180

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 cartridgeThe Legend of Zelda
which name tables sit side by sideside by side, fixed by the boardone 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 left103 to 102119 to 118
frames from the number changing to the picture moving231
frames the slide takes6464
pixels moved, and pixels a frame256, 4 a frame256, 4 a frame
written before the picture movesnone23 rows of 32 tiles across, 2 rows of 24 tiles across
written while it slides32 columns of 30 tiles down32 columns of 22 tiles down, 2 rows of 24 tiles across
frame of the slide the first column is written in031
frames between columns21
the room's number, before and after a step up119 to 103119 to 103
a step up: rows written across, tiles in each30, 3222, 32
from row, to row29, 029, 8
frames from the number changing to the first row26
frames between rows22

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
    RTS

Before this one: The camera's dead zone, the way Mario's is

Next: One byte chooses the screen, the way Mario's does

All the lessons