From 9aa2490dbac97fc2d26ebb439df9b7bcceb5c04c Mon Sep 17 00:00:00 2001 From: Steven Hugg Date: Thu, 22 Oct 2026 11:11:09 +0200 Subject: [PATCH] vic20: fix the text window geometry The VIC-I draws a fixed 22x23 character window, centered in the picture. The emulator used the VIC-II's display window registers, so the window was placed at a garbage offset: the first character column was clipped in half and the whole picture was shifted 24 pixels to the right to hide it. - the new emulator core (chips) centers the window and takes its vertical position from the ROM, so NTSC and PAL ROMs both work - the 24 pixel video shift is gone - the platform loads res/vic20/vic20.bios (a real ROM set) when it is available, and falls back to the stub BIOS otherwise - a regression test checks the geometry of the rendered frame --- CHANGELOG.md | 4 ++ res/vic20/vic20.wasm | Bin 88311 -> 90996 bytes src/machine/vic20.ts | 20 ++++++++- test/cli/testvic20.js | 95 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 118 insertions(+), 1 deletion(-) create mode 100644 test/cli/testvic20.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 6043635e..a0b0e82e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +### Emulators + +- **VIC-20**: the text window is drawn correctly now. The VIC-I emulated the VIC-II's display window registers, so the 22 column window was placed at a garbage offset: the first character column was clipped in half and the screen was shifted 24 pixels to the right. The VIC-I window is fixed at 22x23 characters and centered in the picture; its vertical position still comes from the ROM (the "upper border" register), so NTSC and PAL ROMs both work. + ### Editor and UI - The IDE now works in Firefox: a synchronous XHR with a `responseType` hangs in Firefox when the response is 1MB or more, so the build worker hung forever on platforms with a big toolchain package (Game Boy, Atari 8-bit, Apple II, ...). The worker now fetches those packages as ArrayBuffers. A worker that dies no longer leaves the IDE spinning: the error is shown and the build stops. diff --git a/res/vic20/vic20.wasm b/res/vic20/vic20.wasm index 34d9f1aa69c029fc752168e92fd111488875187b..c1603e4c5f2015e30a98a8e115df436e0b6b3928 100755 GIT binary patch literal 90996 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 literal 88311 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 L?uW;X-sk@V#D7s9 diff --git a/src/machine/vic20.ts b/src/machine/vic20.ts index 964d14b1..cf78ffec 100644 --- a/src/machine/vic20.ts +++ b/src/machine/vic20.ts @@ -15,7 +15,9 @@ export class VIC20_WASMMachine extends BaseWASMMachine implements Machine, Probe numTotalScanlines = 312; cpuCyclesPerLine = 71; - videoOffsetBytes = -24 * 4; + // the VIC-I draws its 22x23 character window centered in the frame, + // so no video offset is needed + videoOffsetBytes = 0; prgstart : number; joymask0 = 0; @@ -27,6 +29,22 @@ export class VIC20_WASMMachine extends BaseWASMMachine implements Machine, Probe super.loadBIOS(srcArray); } async fetchBIOS() { + // use the real VIC-20 ROM set (BASIC, character ROM and KERNAL) if it is + // available, otherwise fall back to a tiny stub BIOS that only knows how + // to start an autostart cartridge + try { + const resp = await fetch('res/vic20/vic20.bios'); + if (resp.status == 200) { + const bios = new Uint8Array(await resp.arrayBuffer()); + if (bios.length == 0x5000) { + this.allocateBIOS(bios); + this.loadBIOS(bios); + return; + } + } + } catch (e) { + // no ROM set available, use the stub BIOS below + } let bios = new Uint8Array(20480); bios.set(DEFAULT_BIOS, bios.length - DEFAULT_BIOS.length); this.allocateBIOS(bios); diff --git a/test/cli/testvic20.js b/test/cli/testvic20.js new file mode 100644 index 00000000..c7f0444d --- /dev/null +++ b/test/cli/testvic20.js @@ -0,0 +1,95 @@ +var assert = require('assert'); +var { loadPlatform } = require('../../gen/tools/emutarget.js'); + +/* + A tiny cartridge that programs the VIC-I and draws two characters, so + that the text window can be checked. + + The cartridge file has a 2 byte load address, then the cold and warm + start vectors, then the "A0CBM" signature; the code is loaded at $A009: + + $A009 A9 1B LDA #$1B ; bg color white, border color cyan + $A00B 8D 0F 90 STA $900F + $A00D A9 19 LDA #$19 ; upper border = raster line 25 + $A00F 8D 01 90 STA $9001 + $A011 A9 F0 LDA #$F0 ; screen pointer A13..A10 + $A013 8D 05 90 STA $9005 + $A015 A9 96 LDA #$96 ; screen pointer A9 + $A017 8D 02 90 STA $9002 + $A019 A9 00 LDA #$00 ; clear the screen page + $A01B A2 00 LDX #$00 + $A01D 9D 00 1E STA $1E00,X + $A020 9D 00 1F STA $1F00,X + $A023 E8 INX + $A024 D0 F7 BNE $A01D + $A026 A9 06 LDA #$06 ; clear the color RAM, blue + $A028 A2 00 LDX #$00 + $A02A 9D 00 96 STA $9600,X + $A02D E8 INX + $A02E E0 28 CPX #$28 + $A030 D0 F8 BNE $A02A + $A032 A9 48 LDA #'H' + $A034 8D 00 1E STA $1E00 + $A037 A9 49 LDA #'I' + $A039 8D 01 1E STA $1E01 + $A03C 4C 40 A0 JMP $A040 + $A03F 00 + $A040 4C 40 A0 JMP $A040 +*/ +var CART = [ + 0x00, 0xA0, 0x09, 0xA0, 0x09, 0xA0, 0x41, 0x30, 0xC3, 0xC2, 0xCD, 0xA9, + 0x1B, 0x8D, 0x0F, 0x90, 0xA9, 0x19, 0x8D, 0x01, 0x90, 0xA9, 0xF0, 0x8D, + 0x05, 0x90, 0xA9, 0x96, 0x8D, 0x02, 0x90, 0xA9, 0x00, 0xA2, 0x00, 0x9D, + 0x00, 0x1E, 0x9D, 0x00, 0x1F, 0xE8, 0xD0, 0xF7, 0xA9, 0x06, 0xA2, 0x00, + 0x9D, 0x00, 0x96, 0xE8, 0xE0, 0x28, 0xD0, 0xF8, 0xA9, 0x48, 0x8D, 0x00, + 0x1E, 0xA9, 0x49, 0x8D, 0x01, 0x1E, 0x4C, 0x40, 0xA0, +]; + +var CYAN = 0xFFFFF04D; + +describe('VIC-20 video', function () { + it('should draw the 22 column text window centered in the frame', async function () { + this.timeout(60000); + var target = await loadPlatform('vic20'); + await target.start(); + var video = target.getVideo(); + assert.equal(video.width, 232); + assert.equal(video.height, 272); + // load the cartridge that programs the VIC + await target.loadROM(new Uint8Array(CART), 'cart.bin'); + // run until the cartridge has set up the screen (with a real KERNAL + // this takes a moment, with the stub BIOS it is immediate) + var color = function () { return -1; }; + for (var i = 0; i < 300; i++) { + target.advanceFrame(); + video = target.getVideo(); + var px = video.pixels; + color = function (x, y) { return px[y * video.width + x]; }; + if (color(0, 100) == CYAN) break; + } + assert.equal(color(0, 100), CYAN, 'the cartridge screen did not appear'); + // the cartridge sets the colors before the window position, so let + // a few more frames pass before the picture is checked + for (var i = 0; i < 5; i++) { + target.advanceFrame(); + } + video = target.getVideo(); + var px = video.pixels; + color = function (x, y) { return px[y * video.width + x]; }; + // the text window is 22 columns (176 pixels) wide and centered, so + // there are 28 pixels of border color on either side. The pixels + // inside the window are the background color or a character, but + // never the border color. + assert.equal(color(0, 100), CYAN, 'left border'); + assert.equal(color(27, 100), CYAN, 'left border'); + assert.notEqual(color(28, 100), CYAN, 'first text column'); + assert.notEqual(color(203, 100), CYAN, 'last text column'); + assert.equal(color(204, 100), CYAN, 'right border'); + assert.equal(color(231, 100), CYAN, 'right border'); + // the window is 23 rows (184 lines) tall, starting at raster line 25 + assert.equal(color(100, 25), CYAN, 'above the text window'); + assert.notEqual(color(100, 26), CYAN, 'first text row'); + assert.notEqual(color(100, 209), CYAN, 'last text row'); + assert.equal(color(100, 210), CYAN, 'below the text window'); + }); +});