Skip to content
Game 1 Unit 5 of 64 1 hr learning time

Custom Tiles

Design better tile graphics for the arena.

8% of Neon Nexus

What You’re Building

Custom-designed tiles that make the arena look polished.

Custom Tiles

The border has a brick pattern. The corners have diagonal edges. The floor has a subtle grid.

How NES Tiles Work

Each tile is 8×8 pixels with 4 possible colours. The pattern table stores tiles as two bit-planes:

  • Low plane: 8 bytes, one per row
  • High plane: 8 bytes, one per row
  • Combine bits from both planes: 0-3 selects palette colour
Low bit:  1  High bit: 0  →  Colour 1
Low bit:  0  High bit: 1  →  Colour 2
Low bit:  1  High bit: 1  →  Colour 3
Low bit:  0  High bit: 0  →  Colour 0 (transparent/background)

Designing the Border Tile

A brick pattern alternates between solid rows and rows with gaps:

; Tile 1: Border (brick pattern)
.byte %11111111   ; Row 0: solid
.byte %10000001   ; Row 1: edges only
.byte %10000001   ; Row 2: edges only
.byte %11111111   ; Row 3: solid
.byte %11111111   ; Row 4: solid
.byte %00010001   ; Row 5: offset gaps
.byte %00010001   ; Row 6: offset gaps
.byte %11111111   ; Row 7: solid

The high plane adds colour variation within the tile.

Corner Tiles

Diagonal corners make the arena look less blocky:

; Tile 3: Corner TL (diagonal from top-left)
.byte %11111111   ; Row 0
.byte %11000000   ; Row 1
.byte %10100000   ; Row 2
.byte %10010000   ; Row 3
.byte %10001000   ; Row 4
.byte %10000100   ; Row 5
.byte %10000010   ; Row 6
.byte %10000001   ; Row 7

Four corner tiles (TL, TR, BL, BR) are mirrored versions of each other.

The Floor Tile

A subtle grid pattern adds visual texture without being distracting:

; Tile 2: Floor (subtle grid)
.byte %00000000
.byte %00000000
.byte %00000000
.byte %00000000
.byte %00000000
.byte %00000000
.byte %00000000
.byte %10000001   ; Small dots at corners

Drawing Corners

The arena drawing code now places corner tiles at the four corners:

@top_row:
    lda row_counter
    cmp #0
    bne @top_row_inner

    ; Very top row with corners
    lda #TILE_CORNER_TL
    sta PPUDATA
    lda #TILE_BORDER
    ldx #30
@top_fill:
    sta PPUDATA
    dex
    bne @top_fill
    lda #TILE_CORNER_TR
    sta PPUDATA
    jmp @next_row

The Code

; =============================================================================
; NEON NEXUS - Unit 5: Custom Tiles
; =============================================================================
; Design better tile graphics for the arena.
; =============================================================================

; -----------------------------------------------------------------------------
; NES Hardware Addresses
; -----------------------------------------------------------------------------
PPUCTRL   = $2000
PPUMASK   = $2001
PPUSTATUS = $2002
OAMADDR   = $2003
PPUSCROLL = $2005
PPUADDR   = $2006
PPUDATA   = $2007
OAMDMA    = $4014

JOYPAD1   = $4016
JOYPAD2   = $4017

; Controller buttons
BTN_A      = %10000000
BTN_B      = %01000000
BTN_SELECT = %00100000
BTN_START  = %00010000
BTN_UP     = %00001000
BTN_DOWN   = %00000100
BTN_LEFT   = %00000010
BTN_RIGHT  = %00000001

; -----------------------------------------------------------------------------
; Game Constants
; -----------------------------------------------------------------------------
PLAYER_START_X = 124
PLAYER_START_Y = 116
PLAYER_SPEED   = 2

; Tile indices (background)
TILE_EMPTY     = 0
TILE_BORDER    = 1
TILE_FLOOR     = 2
TILE_CORNER_TL = 3   ; Top-left corner
TILE_CORNER_TR = 4   ; Top-right corner
TILE_CORNER_BL = 5   ; Bottom-left corner
TILE_CORNER_BR = 6   ; Bottom-right corner

; Sprite tiles (after background tiles in pattern table 0)
SPRITE_PLAYER  = 7

; Arena boundaries
ARENA_LEFT   = 16
ARENA_RIGHT  = 232
ARENA_TOP    = 16
ARENA_BOTTOM = 208

BG_COLOUR = $0F

; -----------------------------------------------------------------------------
; Memory Layout
; -----------------------------------------------------------------------------
.segment "ZEROPAGE"
player_x:    .res 1
player_y:    .res 1
buttons:     .res 1
temp:        .res 1
row_counter: .res 1

.segment "OAM"
oam_buffer:  .res 256

.segment "BSS"

; -----------------------------------------------------------------------------
; iNES Header
; -----------------------------------------------------------------------------
.segment "HEADER"
    .byte "NES", $1A
    .byte 2
    .byte 1
    .byte $01
    .byte $00
    .byte 0,0,0,0,0,0,0,0

; -----------------------------------------------------------------------------
; Code
; -----------------------------------------------------------------------------
.segment "CODE"

reset:
    sei
    cld
    ldx #$40
    stx $4017
    ldx #$FF
    txs
    inx
    stx PPUCTRL
    stx PPUMASK
    stx $4010

@vblank1:
    bit PPUSTATUS
    bpl @vblank1

    lda #0
@clear_ram:
    sta $0000, x
    sta $0100, x
    sta $0200, x
    sta $0300, x
    sta $0400, x
    sta $0500, x
    sta $0600, x
    sta $0700, x
    inx
    bne @clear_ram

@vblank2:
    bit PPUSTATUS
    bpl @vblank2

    jsr load_palette
    jsr draw_arena

    ; Set up player
    lda #PLAYER_START_X
    sta player_x
    lda #PLAYER_START_Y
    sta player_y

    ; Initialise player sprite
    lda player_y
    sta oam_buffer+0
    lda #SPRITE_PLAYER
    sta oam_buffer+1
    lda #0
    sta oam_buffer+2
    lda player_x
    sta oam_buffer+3

    ; Hide other sprites
    lda #$FF
    ldx #4
@hide_sprites:
    sta oam_buffer, x
    inx
    bne @hide_sprites

    lda #0
    sta PPUSCROLL
    sta PPUSCROLL

    ; Enable rendering - both background and sprites from pattern table 0
    lda #%10000000
    sta PPUCTRL
    lda #%00011110
    sta PPUMASK

main_loop:
    jsr read_controller
    jsr move_player
    jmp main_loop

; -----------------------------------------------------------------------------
; Load Palette
; -----------------------------------------------------------------------------
load_palette:
    bit PPUSTATUS
    lda #$3F
    sta PPUADDR
    lda #$00
    sta PPUADDR

    ldx #0
@loop:
    lda palette_data, x
    sta PPUDATA
    inx
    cpx #32
    bne @loop
    rts

; -----------------------------------------------------------------------------
; Draw Arena (with corner tiles)
; -----------------------------------------------------------------------------
draw_arena:
    bit PPUSTATUS
    lda #$20
    sta PPUADDR
    lda #$00
    sta PPUADDR

    lda #0
    sta row_counter

@draw_row:
    lda row_counter

    ; Row 0: top border with corners
    cmp #0
    beq @top_row
    cmp #1
    beq @top_row

    ; Row 28-29: bottom border with corners
    cmp #28
    beq @bottom_row
    cmp #29
    beq @bottom_row

    ; Middle rows
    jmp @middle_row

@top_row:
    lda row_counter
    cmp #0
    bne @top_row_inner

    ; Very top row with corners
    lda #TILE_CORNER_TL
    sta PPUDATA
    lda #TILE_BORDER
    ldx #30
@top_fill:
    sta PPUDATA
    dex
    bne @top_fill
    lda #TILE_CORNER_TR
    sta PPUDATA
    jmp @next_row

@top_row_inner:
    ; Second row - all border
    lda #TILE_BORDER
    ldx #32
@top_inner_fill:
    sta PPUDATA
    dex
    bne @top_inner_fill
    jmp @next_row

@bottom_row:
    lda row_counter
    cmp #29
    bne @bottom_row_inner

    ; Very bottom row with corners
    lda #TILE_CORNER_BL
    sta PPUDATA
    lda #TILE_BORDER
    ldx #30
@bottom_fill:
    sta PPUDATA
    dex
    bne @bottom_fill
    lda #TILE_CORNER_BR
    sta PPUDATA
    jmp @next_row

@bottom_row_inner:
    ; Row 28 - all border
    lda #TILE_BORDER
    ldx #32
@bottom_inner_fill:
    sta PPUDATA
    dex
    bne @bottom_inner_fill
    jmp @next_row

@middle_row:
    ; Left border
    lda #TILE_BORDER
    sta PPUDATA
    sta PPUDATA

    ; Floor
    lda #TILE_FLOOR
    ldx #28
@floor_fill:
    sta PPUDATA
    dex
    bne @floor_fill

    ; Right border
    lda #TILE_BORDER
    sta PPUDATA
    sta PPUDATA

@next_row:
    inc row_counter
    lda row_counter
    cmp #30
    beq @done_drawing
    jmp @draw_row

@done_drawing:
    rts

; -----------------------------------------------------------------------------
; Read Controller
; -----------------------------------------------------------------------------
read_controller:
    lda #1
    sta JOYPAD1
    lda #0
    sta JOYPAD1

    ldx #8
@read_loop:
    lda JOYPAD1
    lsr a
    rol buttons
    dex
    bne @read_loop
    rts

; -----------------------------------------------------------------------------
; Move Player
; -----------------------------------------------------------------------------
move_player:
    lda buttons
    and #BTN_UP
    beq @check_down
    lda player_y
    sec
    sbc #PLAYER_SPEED
    cmp #ARENA_TOP
    bcc @check_down
    sta player_y

@check_down:
    lda buttons
    and #BTN_DOWN
    beq @check_left
    lda player_y
    clc
    adc #PLAYER_SPEED
    cmp #ARENA_BOTTOM
    bcs @check_left
    sta player_y

@check_left:
    lda buttons
    and #BTN_LEFT
    beq @check_right
    lda player_x
    sec
    sbc #PLAYER_SPEED
    cmp #ARENA_LEFT
    bcc @check_right
    sta player_x

@check_right:
    lda buttons
    and #BTN_RIGHT
    beq @done
    lda player_x
    clc
    adc #PLAYER_SPEED
    cmp #ARENA_RIGHT
    bcs @done
    sta player_x

@done:
    rts

; === NMI ===
nmi:
    pha
    txa
    pha
    tya
    pha

    lda #0
    sta OAMADDR
    lda #>oam_buffer
    sta OAMDMA

    lda player_y
    sta oam_buffer+0
    lda player_x
    sta oam_buffer+3

    lda #0
    sta PPUSCROLL
    sta PPUSCROLL

    pla
    tay
    pla
    tax
    pla
    rti

irq:
    rti

; -----------------------------------------------------------------------------
; Data
; -----------------------------------------------------------------------------
palette_data:
    ; Background palettes - neon theme
    .byte BG_COLOUR, $11, $21, $31  ; Blue gradient
    .byte BG_COLOUR, $11, $21, $31
    .byte BG_COLOUR, $11, $21, $31
    .byte BG_COLOUR, $11, $21, $31
    ; Sprite palettes
    .byte BG_COLOUR, $30, $27, $17  ; White, orange, brown
    .byte BG_COLOUR, $30, $27, $17
    .byte BG_COLOUR, $30, $27, $17
    .byte BG_COLOUR, $30, $27, $17

; -----------------------------------------------------------------------------
; Vectors
; -----------------------------------------------------------------------------
.segment "VECTORS"
    .word nmi
    .word reset
    .word irq

; -----------------------------------------------------------------------------
; CHR-ROM - Background Tiles (Pattern Table 0)
; -----------------------------------------------------------------------------
.segment "CHARS"

; Tile 0: Empty
.byte $00,$00,$00,$00,$00,$00,$00,$00
.byte $00,$00,$00,$00,$00,$00,$00,$00

; Tile 1: Border (brick pattern)
.byte %11111111   ; Row 0
.byte %10000001   ; Row 1
.byte %10000001   ; Row 2
.byte %11111111   ; Row 3
.byte %11111111   ; Row 4
.byte %00010001   ; Row 5
.byte %00010001   ; Row 6
.byte %11111111   ; Row 7
; High plane - add colour variation
.byte %00000000
.byte %01111110
.byte %01111110
.byte %00000000
.byte %00000000
.byte %11101110
.byte %11101110
.byte %00000000

; Tile 2: Floor (subtle grid)
.byte %00000000
.byte %00000000
.byte %00000000
.byte %00000000
.byte %00000000
.byte %00000000
.byte %00000000
.byte %10000001
; High plane
.byte %00000000
.byte %00000000
.byte %00000000
.byte %00000000
.byte %00000000
.byte %00000000
.byte %00000000
.byte %00000000

; Tile 3: Corner TL
.byte %11111111
.byte %11000000
.byte %10100000
.byte %10010000
.byte %10001000
.byte %10000100
.byte %10000010
.byte %10000001
.byte %00000000
.byte %00111111
.byte %01011111
.byte %01101111
.byte %01110111
.byte %01111011
.byte %01111101
.byte %01111110

; Tile 4: Corner TR
.byte %11111111
.byte %00000011
.byte %00000101
.byte %00001001
.byte %00010001
.byte %00100001
.byte %01000001
.byte %10000001
.byte %00000000
.byte %11111100
.byte %11111010
.byte %11110110
.byte %11101110
.byte %11011110
.byte %10111110
.byte %01111110

; Tile 5: Corner BL
.byte %10000001
.byte %10000010
.byte %10000100
.byte %10001000
.byte %10010000
.byte %10100000
.byte %11000000
.byte %11111111
.byte %01111110
.byte %01111101
.byte %01111011
.byte %01110111
.byte %01101111
.byte %01011111
.byte %00111111
.byte %00000000

; Tile 6: Corner BR
.byte %10000001
.byte %01000001
.byte %00100001
.byte %00010001
.byte %00001001
.byte %00000101
.byte %00000011
.byte %11111111
.byte %01111110
.byte %10111110
.byte %11011110
.byte %11101110
.byte %11110110
.byte %11111010
.byte %11111100
.byte %00000000

; Sprite 0: Player (better ship design) - at tile index 0 in sprite table
; This goes immediately after background tiles
.byte %00011000   ; Row 0
.byte %00011000   ; Row 1
.byte %00111100   ; Row 2
.byte %01111110   ; Row 3
.byte %11111111   ; Row 4
.byte %10111101   ; Row 5
.byte %00100100   ; Row 6
.byte %00100100   ; Row 7
; High plane
.byte %00000000
.byte %00011000
.byte %00011000
.byte %00111100
.byte %01000010
.byte %01000010
.byte %00011000
.byte %00000000

; Fill rest of CHR-ROM (8KB total = 8192 bytes, used 128 so far)
.res 8192 - 128, $00

Build It

ca65 nexus.asm -o nexus.o
ld65 -C nes.cfg nexus.o -o nexus.nes

The arena now has character. Custom tiles transform a functional border into something that looks designed.

Next

The tiles look good but use only one palette. Unit 6 adds colour regions with the attribute table.

What Changed

Unit 4 → Unit 5
+235-82
11 ; =============================================================================
2-; NEON NEXUS - Unit 4: The Background
2+; NEON NEXUS - Unit 5: Custom Tiles
33 ; =============================================================================
4-; Add a bordered arena using the nametable.
4+; Design better tile graphics for the arena.
55 ; =============================================================================
66
77 ; -----------------------------------------------------------------------------
...
3636 PLAYER_START_Y = 116
3737 PLAYER_SPEED = 2
3838
39-; Tile indices
40-TILE_EMPTY = 0
41-TILE_BORDER = 1
42-TILE_FLOOR = 2
43-TILE_PLAYER = 3
39+; Tile indices (background)
40+TILE_EMPTY = 0
41+TILE_BORDER = 1
42+TILE_FLOOR = 2
43+TILE_CORNER_TL = 3 ; Top-left corner
44+TILE_CORNER_TR = 4 ; Top-right corner
45+TILE_CORNER_BL = 5 ; Bottom-left corner
46+TILE_CORNER_BR = 6 ; Bottom-right corner
4447
45-; Arena boundaries (in pixels, accounting for border)
46-ARENA_LEFT = 16 ; 2 border tiles × 8
47-ARENA_RIGHT = 232 ; 256 - 16 - 8 (sprite width)
48+; Sprite tiles (after background tiles in pattern table 0)
49+SPRITE_PLAYER = 7
50+
51+; Arena boundaries
52+ARENA_LEFT = 16
53+ARENA_RIGHT = 232
4854 ARENA_TOP = 16
49-ARENA_BOTTOM = 208 ; 240 - 16 - 16 (overscan + border)
55+ARENA_BOTTOM = 208
5056
51-; Palette
52-BG_COLOUR = $0F ; Black background
57+BG_COLOUR = $0F
5358
5459 ; -----------------------------------------------------------------------------
5560 ; Memory Layout
...
5964 player_y: .res 1
6065 buttons: .res 1
6166 temp: .res 1
67+row_counter: .res 1
6268
6369 .segment "OAM"
6470 oam_buffer: .res 256
...
114120 bit PPUSTATUS
115121 bpl @vblank2
116122
117- ; Load palette
118123 jsr load_palette
119-
120- ; Draw the arena
121124 jsr draw_arena
122125
123126 ; Set up player
...
129132 ; Initialise player sprite
130133 lda player_y
131134 sta oam_buffer+0
132- lda #TILE_PLAYER
135+ lda #SPRITE_PLAYER
133136 sta oam_buffer+1
134137 lda #0
135138 sta oam_buffer+2
...
144147 inx
145148 bne @hide_sprites
146149
147- ; Reset scroll
148150 lda #0
149151 sta PPUSCROLL
150152 sta PPUSCROLL
151153
152- ; Enable rendering
153- lda #%10000000 ; NMI on, background and sprites from pattern table 0
154+ ; Enable rendering - both background and sprites from pattern table 0
155+ lda #%10000000
154156 sta PPUCTRL
155- lda #%00011110 ; Show sprites and background
157+ lda #%00011110
156158 sta PPUMASK
157159
158-; === Main Loop ===
159160 main_loop:
160161 jsr read_controller
161162 jsr move_player
...
181182 rts
182183
183184 ; -----------------------------------------------------------------------------
184-; Draw Arena
185+; Draw Arena (with corner tiles)
185186 ; -----------------------------------------------------------------------------
186187 draw_arena:
187- ; Set PPU address to start of nametable ($2000)
188188 bit PPUSTATUS
189189 lda #$20
190190 sta PPUADDR
191191 lda #$00
192192 sta PPUADDR
193193
194- ; Draw 30 rows
195- ldy #0 ; Row counter
194+ lda #0
195+ sta row_counter
196196
197197 @draw_row:
198- ; Check if first row, last row, or middle
199- cpy #0
200- beq @border_row
201- cpy #1
202- beq @border_row
203- cpy #28
204- beq @border_row
205- cpy #29
206- beq @border_row
198+ lda row_counter
207199
208- ; Middle row: border + floor + border
200+ ; Row 0: top border with corners
201+ cmp #0
202+ beq @top_row
203+ cmp #1
204+ beq @top_row
205+
206+ ; Row 28-29: bottom border with corners
207+ cmp #28
208+ beq @bottom_row
209+ cmp #29
210+ beq @bottom_row
211+
212+ ; Middle rows
209213 jmp @middle_row
210214
211-@border_row:
212- ; All border tiles
215+@top_row:
216+ lda row_counter
217+ cmp #0
218+ bne @top_row_inner
219+
220+ ; Very top row with corners
221+ lda #TILE_CORNER_TL
222+ sta PPUDATA
223+ lda #TILE_BORDER
224+ ldx #30
225+@top_fill:
226+ sta PPUDATA
227+ dex
228+ bne @top_fill
229+ lda #TILE_CORNER_TR
230+ sta PPUDATA
231+ jmp @next_row
232+
233+@top_row_inner:
234+ ; Second row - all border
235+ lda #TILE_BORDER
213236 ldx #32
214-@border_loop:
237+@top_inner_fill:
238+ sta PPUDATA
239+ dex
240+ bne @top_inner_fill
241+ jmp @next_row
242+
243+@bottom_row:
244+ lda row_counter
245+ cmp #29
246+ bne @bottom_row_inner
247+
248+ ; Very bottom row with corners
249+ lda #TILE_CORNER_BL
250+ sta PPUDATA
215251 lda #TILE_BORDER
252+ ldx #30
253+@bottom_fill:
216254 sta PPUDATA
217255 dex
218- bne @border_loop
256+ bne @bottom_fill
257+ lda #TILE_CORNER_BR
258+ sta PPUDATA
259+ jmp @next_row
260+
261+@bottom_row_inner:
262+ ; Row 28 - all border
263+ lda #TILE_BORDER
264+ ldx #32
265+@bottom_inner_fill:
266+ sta PPUDATA
267+ dex
268+ bne @bottom_inner_fill
219269 jmp @next_row
220270
221271 @middle_row:
222- ; Left border (2 tiles)
272+ ; Left border
223273 lda #TILE_BORDER
224274 sta PPUDATA
225275 sta PPUDATA
226276
227- ; Floor (28 tiles)
228- ldx #28
229-@floor_loop:
277+ ; Floor
230278 lda #TILE_FLOOR
279+ ldx #28
280+@floor_fill:
231281 sta PPUDATA
232282 dex
233- bne @floor_loop
283+ bne @floor_fill
234284
235- ; Right border (2 tiles)
285+ ; Right border
236286 lda #TILE_BORDER
237287 sta PPUDATA
238288 sta PPUDATA
239289
240290 @next_row:
241- iny
242- cpy #30
243- bne @draw_row
291+ inc row_counter
292+ lda row_counter
293+ cmp #30
294+ beq @done_drawing
295+ jmp @draw_row
244296
297+@done_drawing:
245298 rts
246299
247300 ; -----------------------------------------------------------------------------
...
266319 ; Move Player
267320 ; -----------------------------------------------------------------------------
268321 move_player:
269- ; UP
270322 lda buttons
271323 and #BTN_UP
272324 beq @check_down
...
321373 tya
322374 pha
323375
324- ; DMA sprites
325376 lda #0
326377 sta OAMADDR
327378 lda #>oam_buffer
328379 sta OAMDMA
329380
330- ; Update sprite position
331381 lda player_y
332382 sta oam_buffer+0
333383 lda player_x
334384 sta oam_buffer+3
335385
336- ; Reset scroll (important after any PPU access)
337386 lda #0
338387 sta PPUSCROLL
339388 sta PPUSCROLL
...
352401 ; Data
353402 ; -----------------------------------------------------------------------------
354403 palette_data:
355- ; Background palettes
356- .byte BG_COLOUR, $12, $21, $30 ; Palette 0: black, blue, cyan (border), white
357- .byte BG_COLOUR, $12, $21, $30 ; Palette 1
358- .byte BG_COLOUR, $12, $21, $30 ; Palette 2
359- .byte BG_COLOUR, $12, $21, $30 ; Palette 3
404+ ; Background palettes - neon theme
405+ .byte BG_COLOUR, $11, $21, $31 ; Blue gradient
406+ .byte BG_COLOUR, $11, $21, $31
407+ .byte BG_COLOUR, $11, $21, $31
408+ .byte BG_COLOUR, $11, $21, $31
360409 ; Sprite palettes
361- .byte BG_COLOUR, $30, $20, $16 ; Palette 0: black, white, red, orange
362- .byte BG_COLOUR, $30, $20, $16 ; Palette 1
363- .byte BG_COLOUR, $30, $20, $16 ; Palette 2
364- .byte BG_COLOUR, $30, $20, $16 ; Palette 3
410+ .byte BG_COLOUR, $30, $27, $17 ; White, orange, brown
411+ .byte BG_COLOUR, $30, $27, $17
412+ .byte BG_COLOUR, $30, $27, $17
413+ .byte BG_COLOUR, $30, $27, $17
365414
366415 ; -----------------------------------------------------------------------------
367416 ; Vectors
...
372421 .word irq
373422
374423 ; -----------------------------------------------------------------------------
375-; CHR-ROM
424+; CHR-ROM - Background Tiles (Pattern Table 0)
376425 ; -----------------------------------------------------------------------------
377426 .segment "CHARS"
378-
379-; Tile 0: Empty (transparent)
380-.byte $00,$00,$00,$00,$00,$00,$00,$00
381-.byte $00,$00,$00,$00,$00,$00,$00,$00
382-
383-; Tile 1: Border (solid cyan block)
384-.byte $00,$00,$00,$00,$00,$00,$00,$00 ; Low plane = 0
385-.byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF ; High plane = 1 (colour 2 = cyan)
386427
387-; Tile 2: Floor (empty/dark)
428+; Tile 0: Empty
388429 .byte $00,$00,$00,$00,$00,$00,$00,$00
389430 .byte $00,$00,$00,$00,$00,$00,$00,$00
390431
391-; Tile 3: Player sprite (arrow)
392-.byte %00011000
393-.byte %00111100
432+; Tile 1: Border (brick pattern)
433+.byte %11111111 ; Row 0
434+.byte %10000001 ; Row 1
435+.byte %10000001 ; Row 2
436+.byte %11111111 ; Row 3
437+.byte %11111111 ; Row 4
438+.byte %00010001 ; Row 5
439+.byte %00010001 ; Row 6
440+.byte %11111111 ; Row 7
441+; High plane - add colour variation
442+.byte %00000000
394443 .byte %01111110
395-.byte %11111111
396-.byte %00111100
397-.byte %00111100
398-.byte %00111100
399-.byte %00111100
444+.byte %01111110
445+.byte %00000000
446+.byte %00000000
447+.byte %11101110
448+.byte %11101110
449+.byte %00000000
450+
451+; Tile 2: Floor (subtle grid)
452+.byte %00000000
453+.byte %00000000
454+.byte %00000000
455+.byte %00000000
456+.byte %00000000
457+.byte %00000000
458+.byte %00000000
459+.byte %10000001
460+; High plane
400461 .byte %00000000
401462 .byte %00000000
402463 .byte %00000000
...
406467 .byte %00000000
407468 .byte %00000000
408469
409-; Fill rest of CHR-ROM
410-.res 8192 - 64, $00
470+; Tile 3: Corner TL
471+.byte %11111111
472+.byte %11000000
473+.byte %10100000
474+.byte %10010000
475+.byte %10001000
476+.byte %10000100
477+.byte %10000010
478+.byte %10000001
479+.byte %00000000
480+.byte %00111111
481+.byte %01011111
482+.byte %01101111
483+.byte %01110111
484+.byte %01111011
485+.byte %01111101
486+.byte %01111110
487+
488+; Tile 4: Corner TR
489+.byte %11111111
490+.byte %00000011
491+.byte %00000101
492+.byte %00001001
493+.byte %00010001
494+.byte %00100001
495+.byte %01000001
496+.byte %10000001
497+.byte %00000000
498+.byte %11111100
499+.byte %11111010
500+.byte %11110110
501+.byte %11101110
502+.byte %11011110
503+.byte %10111110
504+.byte %01111110
505+
506+; Tile 5: Corner BL
507+.byte %10000001
508+.byte %10000010
509+.byte %10000100
510+.byte %10001000
511+.byte %10010000
512+.byte %10100000
513+.byte %11000000
514+.byte %11111111
515+.byte %01111110
516+.byte %01111101
517+.byte %01111011
518+.byte %01110111
519+.byte %01101111
520+.byte %01011111
521+.byte %00111111
522+.byte %00000000
523+
524+; Tile 6: Corner BR
525+.byte %10000001
526+.byte %01000001
527+.byte %00100001
528+.byte %00010001
529+.byte %00001001
530+.byte %00000101
531+.byte %00000011
532+.byte %11111111
533+.byte %01111110
534+.byte %10111110
535+.byte %11011110
536+.byte %11101110
537+.byte %11110110
538+.byte %11111010
539+.byte %11111100
540+.byte %00000000
541+
542+; Sprite 0: Player (better ship design) - at tile index 0 in sprite table
543+; This goes immediately after background tiles
544+.byte %00011000 ; Row 0
545+.byte %00011000 ; Row 1
546+.byte %00111100 ; Row 2
547+.byte %01111110 ; Row 3
548+.byte %11111111 ; Row 4
549+.byte %10111101 ; Row 5
550+.byte %00100100 ; Row 6
551+.byte %00100100 ; Row 7
552+; High plane
553+.byte %00000000
554+.byte %00011000
555+.byte %00011000
556+.byte %00111100
557+.byte %01000010
558+.byte %01000010
559+.byte %00011000
560+.byte %00000000
561+
562+; Fill rest of CHR-ROM (8KB total = 8192 bytes, used 128 so far)
563+.res 8192 - 128, $00
411564