Assembly Language Fundamentals

Intermediate
Version:
2.0

Name Table Tile Map

Drawing Borders and Patterns Across the Full Screen

In the previous lesson, you learned how to write simple pattern data into the Pattern Generator Table (PGT) and display a single tile on screen.
In this lesson, we’ll take the next big step: building a complete screen map that draws a border around the edges and fills the interior with patterned “spots.”

You’ll see how multiple tile designs combine to form a cohesive graphic, how they’re written into each of the three VRAM pattern banks, and how we use a loop to write an entire Name Table map automatically.

Understanding the Goal

We’re going to construct a screen that looks like this conceptually:

################################
#..............................#
#..............................#
#..............................#
#..............................#
#..............................#
#..............................#
#..............................#
#..............................#
################################

Each tile (8×8 pixels) is drawn using binary patterns stored in the PGT, and the entire arrangement is defined in a Tile Map — a list of numbers that the program copies into the Name Table.

The Pattern Generator Table Revisited

Just like before, we’re working in Graphics Mode II, where the PGT is split into three banks:

Screen RegionPGT Start AddressVRAM OffsetScreen RowsTop third0×000064 (high byte 64)Rows 0–7Middle third0×080072 (high byte 72)Rows 8–15Bottom third0×100080 (high byte 80)Rows 16–23

This means that each pattern must be defined in every bank if it’s to appear correctly across the whole screen.
We’ll define:

Each one is defined multiple times — once per screen third — so that the graphics are consistent from top to bottom.

Step-by-Step Through the Program

Step 1: Enable Graphics Mode II

LD   A,2 : OUT  (9),A
LD   A,128 : OUT  (9),A
LD   A,224 : OUT  (9),A
LD   A,129 : OUT  (9),A

As before, these register settings enable Graphics Mode II, giving us access to all three pattern table banks.

Step 2: Set Foreground and Background Colours

LD   A,240        ; 11110000 = white ink on black background
OUT  (9),A
LD   A,135        ; Register 7
OUT  (9),A

White text on black background keeps our shapes clear and high-contrast.

Step 3: Write Blank Tiles

We still begin with a blank tile (all zeros) written to all three VRAM sections. This ensures that the background is clean and that any unreferenced tile numbers display as black.

; --- Top, Middle, and Bottom Blank Tiles ---
; (Addresses 64, 72, and 80 high bytes)
; Each written with 8 zero bytes

This step is identical in purpose to the previous lesson — but now it’s a foundation for our custom graphics.

Step 4: Write Pattern Tiles

Now we create four distinct patterns: corner, horizontal, vertical, and spot.
Each one has a visual purpose in our final map.

4.1 Corner Tile

The corner tile frames the outermost points of the border.
Its binary pattern forms a thick, boxy outline:

11111111
10000001
10111101
10100101
10100101
10111101
10000001
11111111

This creates a solid edge with an inner hollow shape.

We write this into:

(The middle section doesn’t need corners because they only appear at the very top and bottom of the screen.)

4.2 Horizontal Border Tile

This tile makes up the top and bottom border edges, stretching across the screen.

Its alternating solid and blank rows create a textured bar:

00000000
11111111
00000000
11111111
11111111
00000000
11111111
00000000

We write this into:

These tiles fill the long horizontal runs of the screen’s border.

4.3 Vertical Border Tile

The vertical tile forms the left and right walls of the border.
Its repeating diagonal stripe pattern gives a clear textured side edge:

01011010
01011010
01011010
01011010
01011010
01011010
01011010
01011010

We write this tile into:

Because the vertical borders run the entire height of the screen, this tile must exist in all three pattern banks.

4.4 Spot Tile (Filling the Interior)

This tile forms the repeating “dot” pattern that fills the inside area of the screen.
Its binary layout creates a 4×4 pixel square in the centre of an 8×8 grid:

00000000
00000000
00111100
00111100
00111100
00111100
00000000
00000000

The result is a neat, soft-looking spot that repeats seamlessly across the interior.

We write this into:

so that it can appear anywhere on screen without visual corruption.

Step 5: Clear the Name Table

LD A, 0
OUT (9),A
LD A, 120
OUT (9),A

LD BC, 768
ClearLoop:
  LD A, 0
  OUT (8),A
  DEC BC
  LD A,B
  OR C
  JR NZ, ClearLoop

Just as before, this step clears all 768 Name Table bytes to the blank tile (pattern 0).
It prepares the grid so we can safely write our map data next.

Step 6: Build and Write the Full Name Table Map

Now we bring everything together by writing a complete Tile Map to the Name Table.

At the end of the code, you’ll find a data block labeled TileMap: — this is a 32×24 grid of bytes that defines exactly which pattern goes in each tile position.

Each number represents one of our patterns:

Tile IDPatternDescription0BlankBackground1CornerBorder corners2HorizontalTop/bottom border3VerticalLeft/right border4SpotInterior fill

The map starts and ends with corners (1), fills the top and bottom with horizontals (2), and surrounds the sides with verticals (3).
The inner area is filled with spot tiles (4).

Here’s how it works in code:

LD A, 0
OUT (9), A
LD A, 120
OUT (9), A        ; Point to start of Name Table

LD HL, TileMap    ; HL = address of TileMap data
LD BC, 768        ; 32×24 tiles = 768 bytes

Loop:
  LD A, (HL)    ; Load next tile number
  OUT (8), A    ; Write to Name Table
  INC HL        ; Move to next tile in TileMap
  DEC BC        ; Decrement counter
  LD A, B
  OR C
  JR NZ, Loop   ; Continue until all bytes are written

When the loop finishes, the entire screen’s Name Table has been filled with the contents of TileMap, and the display will show the full bordered pattern.

This loop-based approach is flexible and powerful — you can replace the tile map data block with any arrangement of numbers, and the same loop will draw that new screen layout automatically.

Step 7: Halt the Program

JP $

This halts execution, keeping the display visible indefinitely.

The Tile Map Data

At the bottom of the code, the TileMap defines our full screen layout using pattern IDs. Each DB line defines one horizontal row (32 tiles across).

Here’s the structure:

TileMap:
DB 1,2,2,2,...,2,2,2,1   ; Top border
DB 3,4,4,4,...,4,4,4,3   ; Inner rows with spots and vertical edges
...
DB 1,2,2,2,...,2,2,2,1   ; Bottom border

The repeating use of tile IDs makes it easy to “draw” with numbers.

This method is scalable — later lessons will build on this technique to load maps dynamically from memory or files, enabling scrolling backgrounds and more complex scenes.

Full Program

      ORG 256

     ; -----------------------
     ; Enable Graphics Mode II
     ; ----------------------

      ; Set Register 0 values

      LD   A,2
      OUT  (9),A
      LD   A,128
      OUT  (9),A

      ; Set Register 1 values

      LD   A,224
      OUT  (9),A
      LD   A,129
      OUT  (9),A

     ; ---------------------------
     ; Set Foreground / Background
     ; ---------------------------

     LD   A, 240        ; 11110000 (white foreground, black background)
     OUT  (9), A        ; Send to Port 9
     LD   A, 135        ; 128 (bit 7 set) + 7 (register 7)
     OUT  (9), A        ; Send to Port 9

     ; -----------------
     ; Write Blank Tiles
     ; -----------------

     ; Top Third Blank Tile

     LD   A, 0            ; Load zero into A register
     OUT  (9), A          ; Send to Port 9
     LD   A, 64           ; Load 64 into A register
     OUT  (9), A          ; Send to Port 9

     LD A, 0            ; Load 170 into A
     OUT (8), A           ; Send to Port 8
     OUT (8), A           ; Send to Port 8
     OUT (8), A           ; Send to Port 8
     OUT (8), A           ; Send to Port 8
     OUT (8), A           ; Send to Port 8
     OUT (8), A           ; Send to Port 8
     OUT (8), A           ; Send to Port 8
     OUT (8), A           ; Send to Port 8

     ; Middle Third Blank Tile

     LD   A, 0            ; Load zero into A register
     OUT  (9), A          ; Send to Port 9
     LD   A, 72           ; Load 72 into A register
     OUT  (9), A          ; Send to Port 9

     LD A, 0            ; Load 170 into A
     OUT (8), A           ; Send to Port 8
     OUT (8), A           ; Send to Port 8
     OUT (8), A           ; Send to Port 8
     OUT (8), A           ; Send to Port 8
     OUT (8), A           ; Send to Port 8
     OUT (8), A           ; Send to Port 8
     OUT (8), A           ; Send to Port 8
     OUT (8), A           ; Send to Port 8

     ; Bottom Third Blank Tile

     LD   A, 0            ; Load zero into A register
     OUT  (9), A          ; Send to Port 9
     LD   A, 80           ; Load 80 into A register
     OUT  (9), A          ; Send to Port 9

     LD A, 0              ; Load 170 into A
     OUT (8), A           ; Send to Port 8
     OUT (8), A           ; Send to Port 8
     OUT (8), A           ; Send to Port 8
     OUT (8), A           ; Send to Port 8
     OUT (8), A           ; Send to Port 8
     OUT (8), A           ; Send to Port 8
     OUT (8), A           ; Send to Port 8
     OUT (8), A           ; Send to Port 8

     ; -------------------
     ; Write Pattern Tiles
     ; -------------------

     ; Top Third Pattern Tiles


     ; Corner Tile

     LD   A, 8            ; Load zero into A register
     OUT  (9), A          ; Send to Port 9
     LD   A, 64           ; Load 64 into A register
     OUT  (9), A          ; Send to Port 9

     LD A,%11111111 : OUT (8),A
     LD A,%10000001 : OUT (8),A
     LD A,%10111101 : OUT (8),A
     LD A,%10100101 : OUT (8),A
     LD A,%10100101 : OUT (8),A
     LD A,%10111101 : OUT (8),A
     LD A,%10000001 : OUT (8),A
     LD A,%11111111 : OUT (8),A

     ; Horizontal Tile

     LD   A, 16            ; Load zero into A register
     OUT  (9), A          ; Send to Port 9
     LD   A, 64           ; Load 64 into A register
     OUT  (9), A          ; Send to Port 9

     LD A,%00000000 : OUT (8),A
     LD A,%11111111 : OUT (8),A
     LD A,%00000000 : OUT (8),A
     LD A,%11111111 : OUT (8),A
     LD A,%11111111 : OUT (8),A
     LD A,%00000000 : OUT (8),A
     LD A,%11111111 : OUT (8),A
     LD A,%00000000 : OUT (8),A

     ; Vertical Tile

     LD   A, 24            ; Load zero into A register
     OUT  (9), A          ; Send to Port 9
     LD   A, 64           ; Load 64 into A register
     OUT  (9), A          ; Send to Port 9

     LD A,%01011010 : OUT (8),A
     LD A,%01011010 : OUT (8),A
     LD A,%01011010 : OUT (8),A
     LD A,%01011010 : OUT (8),A
     LD A,%01011010 : OUT (8),A
     LD A,%01011010 : OUT (8),A
     LD A,%01011010 : OUT (8),A
     LD A,%01011010 : OUT (8),A

     ; Spot Tile

     LD   A, 32            ; Load zero into A register
     OUT  (9), A          ; Send to Port 9
     LD   A, 64           ; Load 64 into A register
     OUT  (9), A          ; Send to Port 9

     LD A,%00000000 : OUT (8),A
     LD A,%00000000 : OUT (8),A
     LD A,%00111100 : OUT (8),A
     LD A,%00111100 : OUT (8),A
     LD A,%00111100 : OUT (8),A
     LD A,%00111100 : OUT (8),A
     LD A,%00000000 : OUT (8),A
     LD A,%00000000 : OUT (8),A


     ; Middle Third Pattern Tiles


     ; Vertical Tile

     LD   A, 24            ; Load zero into A register
     OUT  (9), A          ; Send to Port 9
     LD   A, 72           ; Load 64 into A register
     OUT  (9), A          ; Send to Port 9

     LD A,%01011010 : OUT (8),A
     LD A,%01011010 : OUT (8),A
     LD A,%01011010 : OUT (8),A
     LD A,%01011010 : OUT (8),A
     LD A,%01011010 : OUT (8),A
     LD A,%01011010 : OUT (8),A
     LD A,%01011010 : OUT (8),A
     LD A,%01011010 : OUT (8),A

     ; Spot Tile

     LD   A, 32            ; Load zero into A register
     OUT  (9), A          ; Send to Port 9
     LD   A, 72           ; Load 64 into A register
     OUT  (9), A          ; Send to Port 9

     LD A,%00000000 : OUT (8),A
     LD A,%00000000 : OUT (8),A
     LD A,%00111100 : OUT (8),A
     LD A,%00111100 : OUT (8),A
     LD A,%00111100 : OUT (8),A
     LD A,%00111100 : OUT (8),A
     LD A,%00000000 : OUT (8),A
     LD A,%00000000 : OUT (8),A


     ; Bottom Third Pattern Tiles

     ; Corner Tile

     LD   A, 8            ; Load zero into A register
     OUT  (9), A          ; Send to Port 9
     LD   A, 80           ; Load 64 into A register
     OUT  (9), A          ; Send to Port 9

     LD A,%11111111 : OUT (8),A
     LD A,%10000001 : OUT (8),A
     LD A,%10111101 : OUT (8),A
     LD A,%10100101 : OUT (8),A
     LD A,%10100101 : OUT (8),A
     LD A,%10111101 : OUT (8),A
     LD A,%10000001 : OUT (8),A
     LD A,%11111111 : OUT (8),A

     ; Horizontal Tile

     LD   A, 16            ; Load zero into A register
     OUT  (9), A          ; Send to Port 9
     LD   A, 80           ; Load 64 into A register
     OUT  (9), A          ; Send to Port 9

     LD A,%00000000 : OUT (8),A
     LD A,%11111111 : OUT (8),A
     LD A,%00000000 : OUT (8),A
     LD A,%11111111 : OUT (8),A
     LD A,%11111111 : OUT (8),A
     LD A,%00000000 : OUT (8),A
     LD A,%11111111 : OUT (8),A
     LD A,%00000000 : OUT (8),A

     ; Vertical Tile

     LD   A, 24            ; Load zero into A register
     OUT  (9), A          ; Send to Port 9
     LD   A, 80           ; Load 64 into A register
     OUT  (9), A          ; Send to Port 9

     LD A,%01011010 : OUT (8),A
     LD A,%01011010 : OUT (8),A
     LD A,%01011010 : OUT (8),A
     LD A,%01011010 : OUT (8),A
     LD A,%01011010 : OUT (8),A
     LD A,%01011010 : OUT (8),A
     LD A,%01011010 : OUT (8),A
     LD A,%01011010 : OUT (8),A

     ; Spot Tile

     LD   A, 32            ; Load zero into A register
     OUT  (9), A          ; Send to Port 9
     LD   A, 80           ; Load 64 into A register
     OUT  (9), A          ; Send to Port 9

     LD A,%00000000 : OUT (8),A
     LD A,%00000000 : OUT (8),A
     LD A,%00111100 : OUT (8),A
     LD A,%00111100 : OUT (8),A
     LD A,%00111100 : OUT (8),A
     LD A,%00111100 : OUT (8),A
     LD A,%00000000 : OUT (8),A
     LD A,%00000000 : OUT (8),A

     ; --------------------------------
     ; Clear Name Table with Blank Tile
     ; --------------------------------

     LD A, 0            ; Low Byte
     OUT (9), A         ; Send to Port 9
     LD A, 120          ; High Byte
     OUT (9), A         ; Send to Port 9

     LD BC, 768         ; Set Counter for table address space

ClearLoop:
     LD A, 0            ; Load zero into A register
     OUT (8), A         ; Send to Port 8
     DEC BC             ; Decrement BC Counter
     LD A, B            ; Load B into A register
     OR C               ; Bitwise OR to compare
     JR NZ, ClearLoop    ; Jump to start unless BC is zero

     ; -------------------------------------
     ; Write Tiles to Name Table / Tile Map
     ; -------------------------------------

     ; Point to start of name table

      LD A, 0            ; Low Byte
      OUT (9), A         ; Send to Port 9
      LD A, 120          ; High Byte
      OUT (9), A         ; Send to Port 9

      LD HL, TileMap

      LD BC, 768
Loop:
      LD A, (HL)
      OUT (8), A
      INC HL
      DEC BC
      LD A, B            ; Load B into A register
      OR C               ; Bitwise OR to compare
      JR NZ, Loop    ; Jump to start unless BC is zero


      JP $            ; JP Idefinitely


TileMap:
    DB 1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1
    DB 3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3
    DB 3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3
    DB 3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3
    DB 3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3
    DB 3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3
    DB 3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3
    DB 3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3
    DB 3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3
    DB 3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3
    DB 3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3
    DB 3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3
    DB 3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3
    DB 3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3
    DB 3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3
    DB 3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3
    DB 3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3
    DB 3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3
    DB 3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3
    DB 3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3
    DB 3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3
    DB 3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3
    DB 3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3
    DB 1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1

Summary

You’ve now taken your first step into tile mapping, the core of classic 8-bit graphics.

Key Takeaways

Previous Module
Next Module