1942
1942 (Capcom, 1984) is the WWII vertical-scrolling shooter in which the fighter "Super Ace" flies a Lockheed P-38 Lightning over the Pacific, shooting down waves of Japanese planes and clearing each stage's boss bomber, with a "loop" barrel-roll to dodge fire. This build is a from-scratch emulation of the pre-CPS Capcom arcade board in the browser: an all-Z80 design with a Zilog Z80 main CPU that runs the game and a second Zilog Z80 sound CPU, driving a scrolling 16×16 background, an 8×8 character foreground, the multi-height 16×16 sprite hardware and a six-PROM colour system. It boots straight into attract mode and is wired to the emulators.org in-frame debugger, so you can single-step the main Z80, read and write its registers and the 64K memory, and set execution breakpoints and write watchpoints.
Board ported from MAME's capcom/1942.cpp ↗
Runs on: Web browser
1942 Online Emulator
Play 1942 using JavaScript directly in your browser.
Controls
Configurations
| Configuration | Emulator | Machine | OS | Legal | |
|---|---|---|---|---|---|
| 1942 | 1942 | 1942 | grey | Open ⛶ |
Machine emulated
The 1942 arcade board (Capcom, 1984) is a pre-CPS, all-Z80 design: a Zilog Z80 main CPU at 3 MHz running the game and a second Zilog Z80 sound CPU at 3 MHz driving two AY-3-8910 PSGs. The video hardware is a scrolling 32×16 background of 16×16 three-bit tiles, a 32×32 foreground of 8×8 two-bit characters (score and text, transparent pen 0), and up to 32 four-bit 16×16 sprites that can be one, two, four or sixteen tiles tall. Colour is fixed in six PROMs — three 256×4 RGB PROMs give 256 master colours and a char / tile / sprite lookup PROM maps each layer's pens into them. The board is rotated (ROT270) and scanned as a 224×256 portrait, like the upright cabinet.
Chips
Notes
Embedding
1942 is Capcom's 1984 arcade machine: a Zilog Z80 main CPU at 3 MHz that runs the game, and a second Zilog Z80 sound CPU at 3 MHz driving two AY-3-8910 PSGs. This build is a from-scratch JavaScript emulation whose board is a port of MAME's capcom/1942.cpp and 1942_v.cpp. Both Z80 cores are Molly Howell's MIT Z80.js. The whole board runs from a host-owned loop, so the debugger can pause and single-step it.
Boot. Constructing the machine fetches the ROMs, decodes the character / tile / sprite graphics and the six colour PROMs, resets the main Z80 and starts the loop; the board comes up in attract mode:
var m = new C1942({ canvas, romBase, manifest });
m.boot(); // fetch ROMs, decode GFX + PROMs, reset the Z80, run
// each animation frame runs one 60Hz field of the main Z80, then draws the screen
The machine object. Everything the host and debugger need is a field or method on the machine:
| Member | Kind | What it does |
|---|---|---|
m.cpu | field | The main Z80 core. Registers are read with getReg(name) / written with setReg(name,v) for A F B C D E H L, the AF/BC/DE/HL pairs, IX IY SP PC, and I R. |
m.sound | field | The sound Z80. It runs so its two soundlatch handshakes stay live; audio itself is stubbed (the AY-3-8910s are not synthesised). |
m.dbgRead(a) / m.dbgWrite(a,v) | method | Side-effect-free read of the main 64K bus and the CPU write path -- what the debugger's memory views read and poke. |
m.setInput(id, down) | method | Drive a control (up, down, left, right, fire, loop, coin, start1, start2) into the input ports. |
EMU_BOOT.transport | field | The pause / resume / step / breakpoint / watchpoint surface the shared debugger drives. |
Video. The screen is a scrolling 32×16 background of 16×16 three-bit tiles (column-scan, with a scrambled tile-index map and a four-way palette bank), an 8×8 two-bit character foreground for the score and text (transparent pen 0), and up to 32 four-bit 16×16 sprites that can be one, two, four or sixteen tiles tall. Colour is fixed in six PROMs: three 256×4 RGB PROMs give 256 master colours, and a char / tile / sprite lookup PROM maps each layer's pens into them. The renderer draws a 256×224 raster and rotates it (ROT270) to a 224×256 portrait, like the upright cabinet.
Debugger integration
Because the whole board is ordinary JavaScript and the host owns the run loop, the debugger's controls need no changes to the CPU core: the loop can pause, single-step and check breakpoints between any two instructions. window.EMU_BOOT.transport maps the shared debugger onto the main Z80:
- pause / resume / isPaused -- stop or restart the
requestAnimationFrameloop. - stepInsn(n) -- run exactly n Z80 instructions through the core's
run_instruction()entry. - step(n) -- advance n whole 60 Hz fields of the main Z80 (plus the sound Z80), honouring the two mode-0 interrupts a field.
- breakpoints -- a
Setof PC values checked before each instruction; a match pauses before the instruction runs. - watchpoints -- the Z80's memory-write path flags a hit when a watched address is written, and the loop pauses on it.
The stock Z80.js keeps its registers in a closure and only exposes a whole-core getState()/setState(). To make the debugger's live register window cheap, the vendored core is given two extra hooks -- get_pc() and set_pc() -- so the run loop can read PC before every instruction (for breakpoints) without allocating a state object, and the machine wraps getState/setState in focused getReg/setReg/getFlag/setFlag helpers that the plug-in binds to. Memory reads use the machine's side-effect-free dbgRead, which returns work RAM, the video RAMs, the fixed and banked program ROM and the input ports without side effects, so inspecting memory never disturbs the sound latch or the bank register. The Z80 disassembler is the shared decoder at /debugger/src/cpus/z80.js -- reused unchanged, since the Z80 is already a first-class debugger CPU.
Architecture
The 1942 board (Capcom, 1984) is a pre-CPS design built from two Z80s and Capcom's early tile/sprite hardware, run on a rotated (ROT270) monitor:
- Main CPU -- Zilog Z80 at 3 MHz (12 MHz / 4). Fixed program ROM at
0x0000–0x7fff, a 16 KB banked ROM window at0x8000–0xbfff(four banks selected at0xc806), the input ports at0xc000–0xc004, the sound latches / scroll / control / palette-bank registers in the0xc800page, sprite RAM at0xcc00, character RAM at0xd000, background RAM at0xd800, and work RAM at0xe000. This is the CPU the debugger targets. - Interrupts -- the main Z80 takes two mode-0 interrupts each field:
RST 08hnear scanline 109 andRST 10hat vblank (scanline 240); the vector is the RST opcode placed on the data bus. - Sound CPU -- a second Z80 at 3 MHz with 2 KB RAM, fed one-byte commands through two latches the main CPU writes at
0xc800/0xc801, taking a periodic interrupt four times a field. It drives two AY-3-8910 PSGs. (Audio is stubbed here; the Z80 still runs so the latch handshake stays live.) - Tilemaps -- an 8×8 two-bit character foreground (score / text, transparent pen 0) and a scrolling 16×16 three-bit background. The background is a 32×16 column-scan map whose tile indices are scrambled as
(i&0x0f)|((i&0x1f0)<<1), with a four-way palette bank set at0xc805and per-tile X/Y flip. - Sprites -- up to 32 four-bit 16×16 sprites read from
0xcc00–0xcc7f; two attribute bits give a sprite a height of one, two, four or sixteen tiles. - Palette -- there is no palette RAM. Three 256×4 PROMs (one per gun, decoded through a resistor DAC) give 256 master colours; a char, a tile and a sprite lookup PROM map each layer's pen (offset into the char / tile / sprite palette bank) to one of those colours.
A control register at 0xc804 holds the screen-flip bit, the sound-CPU reset line and the coin counter; the graphics ROMs are decoded to one-byte-per-pixel tiles once at boot.