MSX Assembly · the code
Every program in the book
The sources and the programs, in folders named exactly as the book names them. Free to use in your own work, commercial or not, under the MIT licence.
Assemble and run a chapter
You need sjasmplus (assembler), openMSX (emulator and debugger) and C-BIOS (a free BIOS for the emulator). Open a terminal in the folder and type:
cd ch05
openmsx -machine MSXBOOK_EU16 -carta border.romCheck everything
From the top folder of the full download, this assembles every source again and compares the result with the reference bytes:
python3 verify.py- First install sjasmplus 1.24.0, openMSX and C-BIOS (chapter 4 does it on Linux, Windows and macOS; on Debian and Ubuntu, sh setup_linux.sh in ch04 does all of it), then run python3 install_machines.py with the folder or the zip of the C-BIOS ROMs: it copies the book's twelve machines where openMSX finds them.
- A chapter folder holds everything the chapter prints: the sources, the cartridges that were photographed, the generator that wrote the sources, the meas script and its results, the figures. build.sh assembles the chapter again.
- verify.py assembles every program again and compares it, byte for byte, with the cartridges the book was photographed from. It needs Python 3 and sjasmplus on the PATH.
- No system ROM is included. The programs run on C-BIOS, a free BIOS that comes with openMSX.
Chapter by chapter
| Ch. | Title | Folder | Download |
|---|---|---|---|
| Part I · Before the first byte | |||
| 1 | A machine made from a standard: what MSX is, and why it is programmed this way | ch01/ | |
| 2 | Numbers a computer understands: bits, bytes, hexadecimal, and two's complement | ch02/ | |
| 3 | Inside the case: the Z80, the VDP, the PSG, the PPI, and the slots | ch03/ | |
| 4 | Setting up the development environment: sjasmplus, openMSX, and C-BIOS | ch04/ | |
| 5 | Your first program: a coloured border, from source to cartridge, photographed | ch05/ | |
| 6 | Seeing inside the machine: the openMSX debugger | ch06/ | |
| Part II · The Z80 language | |||
| 7 | Registers, flags, and the shape of a Z80 instruction | ch07/ | |
| 8 | Moving data: LD and every addressing mode | ch08/ | |
| 9 | Arithmetic: eight-bit and sixteen-bit sums, carries, and BCD | ch09/ | |
| 10 | Logic, bits, shifts, and rotates | ch10/ | |
| 11 | Making decisions: the flags, JP, JR, DJNZ, and conditional returns | ch11/ | |
| 12 | Subroutines and the stack: CALL, RET, PUSH, POP, and the shadow registers | ch12/ | |
| 13 | Blocks, tables, and the index registers: LDIR, IX, IY, and lookup tables | ch13/ | |
| 14 | Counting T-states: the Z80 at 3.58 MHz, and the wait the MSX adds to every M1 | ch14/ | |
| 15 | sjasmplus for the MSX: labels, macros, the cartridge header, and a ROM image | ch15/ | |
| 16 | The BIOS as a library: the jump table, the system variables, and the hooks | ch16/ | |
| Part III · The VDP: video memory behind a port, tiles, and thirty-two sprites | |||
| 17 | Taking the machine: the BIOS interrupt, the H.TIMI hook, and an interrupt of your own | ch17/ | |
| 18 | How a frame is built: 228 T-states a line, 313 lines in Europe and 262 in Japan | ch18/ | |
| 19 | Talking to the VDP: two ports, eight registers, and sixteen kilobytes you cannot address | ch19/ | |
| 20 | How fast the VDP listens: access slots, the 29 T-state loop, and what a write too soon destroys | ch20/ | |
| 21 | The screen modes: text, Graphic I, Graphic II, and multicolour | ch21/ | |
| 22 | Graphic II, the screen of the games: three thirds, 768 patterns, and colour in strips of eight | ch22/ | |
| 23 | Colour clash on the MSX: two colours in eight pixels, and how to draw around it | ch23/ | |
| 24 | Tiles and the name table: screens built from 8 × 8 pieces, and a copy in RAM | ch24/ | |
| 25 | Plotting and drawing in Graphic II: pixels and lines through a port | ch25/ | |
| 26 | Hardware sprites I: the attribute table, patterns, size, magnification, and the early clock | ch26/ | |
| 27 | Hardware sprites II: four on a line, the fifth-sprite flag, and flicker by rotation | ch27/ | |
| 28 | Software sprites in the tiles: redrawing patterns to move what the hardware cannot | ch28/ | |
| 29 | Scrolling without hardware help: by tile, by pre-shifted tiles, and what each costs | ch29/ | |
| 30 | Fonts and text: the BIOS character set, a set of your own, and a status line | ch30/ | |
| 31 | Fast transfers to VRAM: unrolled OUTI, the vertical-blank budget, and the blanked screen | ch31/ | |
| 32 | Racing the beam on an MSX1: register changes in mid-frame, timed from the interrupt | ch32/ | |
| Part IV · Making it a game machine | |||
| 33 | The frame loop: the interrupt as a heartbeat, fifty or sixty times a second | ch33/ | |
| 34 | Reading the keyboard: the PPI, eleven rows, ghosting, and layouts that change by country | ch34/ | |
| 35 | Joysticks through the PSG: two ports, two buttons, and one standard | ch35/ | |
| 36 | The PSG: three tones, noise, envelopes, and the mixer bits that must not move | ch36/ | |
| 37 | An engine for sound effects and music that runs from the interrupt, at 50 and 60 Hz | ch37/ | |
| 38 | Slots and memory: where the RAM is, how a 32 KB cartridge finds itself, and where things live | ch38/ | |
| 39 | Collisions: tile tests, bounding boxes, and the coincidence flag | ch39/ | |
| 40 | Score, text, and a status line that never flickers | ch40/ | |
| 41 | Random numbers, the R register, and game states | ch41/ | |
| 42 | The frame budget: fitting a game into 59,736 T-states | ch42/ | |
| Part V · Two complete games | |||
| 43 | The first game I: a single-screen arcade game, from specification to cartridge | ch43/ | |
| 44 | The first game II: sound, score, difficulty, and the finished ROM | ch44/ | |
| 45 | The second game I: a flip-screen world, rooms in ROM, and a map | ch45/ | |
| 46 | The second game II: enemies, items, music, and the finished ROM | ch46/ | |
| 47 | Where to go next: three projects, sketched | ch47/ | |
| Part VI · Beyond the 32 KB cartridge | |||
| 48 | MegaROMs: mappers, banks, and a 128 KB cartridge | ch48/ | |
| 49 | Samples through the PSG: drums and voices from the volume registers | ch49/ | |
| 50 | Tape and disk: BLOAD, CAS and DSK files, and when a cartridge is not the answer | ch50/ | |
| 51 | One cartridge, many machines: makers, MSX2 and later, 50 and 60 Hz, and the slot zoo | ch51/ | |
| 52 | Optimisation: T-states, unrolled loops, code copied to RAM, and self-modifying code | ch52/ | |
| Part VII · The rest of the craft | |||
| 53 | Compression: RLE, and a packer for screens and levels, unpacked straight into VRAM | ch53/ | |
| 54 | Title screens, demo mode, and attract mode | ch54/ | |
| 55 | Testing on real hardware: real MSX machines, flash cartridges, and the video output | ch55/ | |
| 56 | Releasing your work: ROM files, cartridges, labels, and the MSX scene today | ch56/ | |