8bitworkshop/gen/atari8-N4PRCBAP.js.map

8 lines
93 KiB
Plaintext

{
"version": 3,
"sources": ["../src/machine/chips/antic.ts", "../src/machine/chips/gtia.ts", "../src/machine/chips/pokey.ts", "../src/machine/atari8.ts", "../src/platform/atari8.ts"],
"sourcesContent": ["import { dumpRAM } from \"../../common/emu\";\nimport { hex, lpad, safe_extend } from \"../../common/util\";\n\n// ANTIC\n// https://www.atarimax.com/jindroush.atari.org/atanttim.html\n// http://www.virtualdub.org/blog/pivot/entry.php?id=243\n// http://www.beipmu.com/Antic_Timings.txt\n// https://user.xmission.com/~trevin/atari/antic_regs.html\n// https://user.xmission.com/~trevin/atari/antic_insns.html\n// http://www.atarimuseum.com/videogames/consoles/5200/conv_to_5200.html\n// https://www.virtualdub.org/downloads/Altirra%20Hardware%20Reference%20Manual.pdf\n\nconst PF_LEFT = [0, 25, 17, 9];\nconst PF_RIGHT = [0, 25 + 64, 17 + 80, 9 + 96];\n\nconst DMACTL = 0;\nconst CHACTL = 1;\nconst DLISTL = 2;\nconst DLISTH = 3;\nconst HSCROL = 4;\nconst VSCROL = 5;\nconst PMBASE = 7;\nconst CHBASE = 9;\nconst WSYNC = 10;\nconst VCOUNT = 11;\nconst PENH = 12;\nconst PENV = 13;\nconst NMIEN = 14;\nconst NMIRES = 15;\nconst NMIST = 15;\n\nconst PFNONE = 0;\nconst PFNARROW = 1;\nconst PFNORMAL = 2;\nconst PFWIDE = 3;\n\nconst NMIST_CYCLE = 12;\nconst NMI_CYCLE = 24;\nconst WSYNC_CYCLE = 212;\n\nconst ANTIC_LEFT = 17 - 4; // gtia 34, 4 cycle delay\nconst ANTIC_RIGHT = 110 - 4; // gtia 221, 4 cycle delay\nconst LAST_DMA_H = 105; // last DMA cycle\n\nexport const MODE_LINES = [0, 0, 8, 10, 8, 16, 8, 16, 8, 4, 4, 2, 1, 2, 1, 1];\n// how many bits before DMA clock repeats?\nconst MODE_PERIOD = [0, 0, 2, 2, 2, 2, 4, 4, 8, 4, 4, 4, 4, 2, 2, 2];\nconst MODE_YPERIOD = [0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 2, 1, 0, 0, 0, 0];\n//const MODE_BPP = [0, 0, 1, 1, 2, 2, 1, 1, 2, 1, 2, 1, 1, 2, 2, 1];\n// how many color clocks / pixel * 2\nexport const MODE_SHIFT = [0, 0, 1, 1, 2, 2, 2, 2, 8, 4, 4, 2, 2, 2, 2, 1];\n\nexport class ANTIC {\n read: (address: number) => number;\t// bus read function\n nmi: () => void; // generate NMI\n\n regs = new Uint8Array(0x10);\t\t\t\t// registers\n\n left: number;\n right: number;\t\t\t\t\t// left/right clocks for mode\n\n dma_enabled: boolean = false;\n dliop: number = 0; // dli operation\n mode: number = 0;\t\t\t// current mode\n jmp = false; // TODO\n lms = false; // TODO\n dlarg_lo: number = 0;\n dlarg_hi: number = 0;\n period: number = 0;\t\t// current mode period bitmask\n scanaddr: number = 0; // Scan Address (via LMS)\n startaddr: number = 0;\t// Start of line Address\n pfbyte: number = 0;\t\t// playfield byte fetched\n ch: number = 0;\t\t\t\t// char read\n linesleft: number = 0; // # of lines left in mode\n yofs: number = 0;\t\t\t// yofs fine\n isfirstline: boolean = false;\n v: number = 0;\t\t\t\t\t// vertical scanline #\n h: number = 0;\t\t\t\t\t// horizontal color clock\n\n linebuf = new Uint8Array(48);\n dmaclock: number = 0;\n dmaidx: number = 0;\n output: number = 0;\n dramrefresh = false;\n in_vscroll = 0;\n\n constructor(readfn, nmifn) {\n this.read = readfn; // bus read function\n this.nmi = nmifn; // NMI function\n }\n reset() {\n this.regs.fill(0);\n this.regs[NMIEN] = 0x00;\n this.regs[NMIST] = 0x7f;\n this.regs[PENH] = 0x00;\n this.regs[PENV] = 0xff;\n this.setReg(DMACTL, 0x0);\n this.h = this.v = 0;\n this.startaddr = this.scanaddr = 0;\n this.dmaclock = 0;\n }\n saveState() {\n return safe_extend(0, {}, this);\n }\n loadState(s) {\n safe_extend(0, this, s);\n this.setReg(DMACTL, s.regs[DMACTL]);\n }\n static stateToLongString(state): string {\n let s = \"\";\n s += \"H: \" + lpad(state.h, 3) + \" V: \" + lpad(state.v, 3) + \"\\n\";\n s += \"DLIOp: \" + hex(state.dliop, 2) + \" Lines: \" + state.yofs + \"/\" + state.linesleft;\n s += \" DMA \" + (state.dma_enabled ? \"ON \" : \"off\")\n if (state.dma_enabled) s += \" idx \" + state.dmaidx + \" clk \" + hex(state.dmaclock) \n s += \"\\n\"\n s += \"Addr: \" + hex(state.scanaddr, 4) + \"\\n\";\n s += dumpRAM(state.regs, 0, 16).replace('$00', 'Regs');\n return s;\n }\n setReg(a: number, v: number) {\n switch (a) {\n case WSYNC:\n this.regs[WSYNC] = 0xff;\n return; // this is readonly (we reset it)\n case NMIRES:\n this.regs[NMIST] = 0x1f;\n return; // this is readonly, don't mess with it\n }\n this.regs[a] = v;\n }\n readReg(a: number) {\n switch (a) {\n case NMIST:\n return this.regs[a];\n case VCOUNT:\n return this.v >> 1;\n default:\n return 0xff;\n }\n }\n processDLIEntry() {\n if (this.mode == 0) { // N Blank Lines\n this.linesleft = ((this.dliop >> 4) & 7) + 1;\n this.dmaclock = 0;\n } else {\n this.linesleft = MODE_LINES[this.mode];\n this.period = MODE_PERIOD[this.mode];\n if (this.jmp) {\n this.regs[DLISTL] = this.dlarg_lo;\n this.regs[DLISTH] = this.dlarg_hi;\n this.mode = this.period = 0;\n // JVB (Jump and wait for Vertical Blank)\n if (this.dliop & 0x40) {\n this.linesleft = 1; //(248 - this.v) & 0xff; // TODO?\n this.dma_enabled = false;\n }\n this.dmaclock = 0;\n } else if (this.lms) {\n this.scanaddr = this.dlarg_lo + (this.dlarg_hi << 8);\n //console.log('scanaddr', hex(this.scanaddr));\n }\n this.startaddr = this.scanaddr;\n // horiz scroll\n let effwidth = this.regs[DMACTL] & 3;\n let hscroll = (this.dliop & 0x10) ? (this.regs[HSCROL] & 15) >> 1 : 0;\n if ((this.dliop & 0x10) && effwidth < 3) effwidth++;\n this.left = PF_LEFT[effwidth] + hscroll;\n this.right = PF_RIGHT[effwidth] + hscroll;\n // vertical scroll\n let vscrol = this.regs[VSCROL] & 0xf;\n if ((this.dliop & 0x20) ^ this.in_vscroll) {\n if (this.in_vscroll) {\n this.linesleft = vscrol+1; // exiting\n } else {\n this.linesleft -= vscrol; // entering\n this.yofs += vscrol;\n }\n this.linesleft &= 0xf;\n this.in_vscroll ^= 0x20;\n }\n }\n }\n\n nextLine() {\n if (this.linesleft > 0) {\n this.linesleft--;\n this.yofs++;\n this.isfirstline = false;\n if (this.mode >= 8 && this.linesleft) {\n this.scanaddr = this.startaddr; // reset line addr\n }\n }\n }\n\n triggerNMI(mask: number) {\n this.regs[NMIST] = mask | 0x1f;\n if (this.regs[NMIEN] & mask) {\n this.nmi();\n }\n }\n\n getDlistAddr() {\n return this.regs[DLISTL] + (this.regs[DLISTH] << 8);\n }\n\n nextInsn(): number {\n let pc = this.getDlistAddr();\n let b = this.read(pc);\n //console.log('nextInsn', hex(pc), hex(b), this.v);\n pc = ((pc + 1) & 0x3ff) | (pc & ~0x3ff);\n this.regs[DLISTL] = pc & 0xff;\n this.regs[DLISTH] = pc >> 8;\n return b;\n }\n\n nextScreen(): number {\n let b = this.read(this.scanaddr);\n this.incScanAddr();\n return b;\n }\n incScanAddr() {\n this.scanaddr = ((this.scanaddr + 1) & 0xfff) | (this.scanaddr & ~0xfff);\n }\n\n dlDMAEnabled() { return this.regs[DMACTL] & 0b100000; }\n\n isVisibleScanline() {\n return this.v >= 8 && this.v < 248;\n }\n isPlayfieldDMAEnabled() {\n return this.dma_enabled && !this.linesleft;\n }\n isPlayerDMAEnabled() {\n return this.regs[DMACTL] & 0b1000;\n }\n isMissileDMAEnabled() {\n return this.regs[DMACTL] & 0b1100;\n }\n isWSYNC() {\n return this.regs[WSYNC] != 0;\n }\n\n clockPulse(): boolean {\n let did_dma = this.isWSYNC();\n if (!this.isVisibleScanline()) {\n this.doVBlank();\n } else {\n switch (this.h) {\n case 0:\n if (this.isMissileDMAEnabled()) {\n this.doPlayerMissileDMA(3);\n did_dma = true;\n }\n break;\n case 1:\n if (this.isPlayfieldDMAEnabled()) {\n let op = this.nextInsn(); // get mode\n // TODO: too many booleans\n this.jmp = (op & ~0x40) == 0x01; // JMP insn?\n this.lms = (op & 0x40) != 0 && (op & 0xf) != 0; // LMS insn?\n this.mode = op & 0xf;\n this.dliop = op;\n this.yofs = 0;\n this.isfirstline = true;\n did_dma = true;\n }\n break;\n case 2: case 3: case 4: case 5:\n if (this.isPlayerDMAEnabled()) {\n this.doPlayerMissileDMA(this.h + 2);\n did_dma = true;\n }\n break;\n case 6:\n case 7:\n if (this.isPlayfieldDMAEnabled() && this.isfirstline && (this.jmp || this.lms)) {\n if (this.h == 6) this.dlarg_lo = this.nextInsn();\n if (this.h == 7) this.dlarg_hi = this.nextInsn();\n did_dma = true;\n }\n break;\n case 8:\n // TODO? is this at cycle 8?\n if (this.isfirstline) {\n this.processDLIEntry();\n }\n if (this.dliop & 0x80) { // TODO: what if DLI disabled?\n if (this.linesleft == 1) {\n this.triggerNMI(0x80); // DLI interrupt\n }\n }\n break;\n case 9:\n break;\n case 111:\n if (this.dma_enabled) this.nextLine();\n ++this.v;\n break;\n }\n this.output = 0; // background color (TODO: only for blank lines)\n if (this.mode >= 2 && this.period) {\n let candma = this.h <= LAST_DMA_H;\n this.dmaclock = (this.dmaclock << 1) & 0x1ff;\n if (this.dmaclock & (1 << this.period)) {\n this.dmaclock |= 1;\n }\n if (this.h == this.left) { this.dmaclock |= 1; this.dmaidx = 0; }\n if (this.h == this.right) { this.dmaclock &= ~1; this.dmaidx++; }\n if (this.dmaclock & 1) {\n if (this.mode < 8 && this.isfirstline) { // only read chars on 1st line\n if (candma) {\n this.linebuf[this.dmaidx] = this.nextScreen(); // read char name\n } else {\n this.incScanAddr();\n }\n did_dma = candma;\n }\n this.dmaidx++;\n } else if (this.dmaclock & 8) {\n this.ch = this.linebuf[this.dmaidx - 4 / this.period]; // latch char\n if (candma) {\n this.readBitmapData(); // read bitmap\n } else {\n if (this.mode >= 8) this.incScanAddr();\n }\n did_dma = candma;\n }\n this.output = this.h >= this.left + 3 && this.h <= this.right + 2 ? 4 : 0;\n }\n }\n if (this.h < ANTIC_LEFT || this.h > ANTIC_RIGHT) this.output = 2;\n this.incHorizCounter();\n if (!did_dma && this.dramrefresh) {\n this.read(0); // to log a VRAM_READ event\n this.dramrefresh = false;\n did_dma = true;\n }\n return did_dma;\n }\n incHorizCounter() {\n switch (this.h) {\n case 25: case 25 + 4 * 1: case 25 + 4 * 2: case 25 + 4 * 3: case 25 + 4 * 4:\n case 25 + 4 * 5: case 25 + 4 * 6: case 25 + 4 * 7: case 25 + 4 * 8:\n this.dramrefresh = true;\n break;\n case 102:\n this.regs[WSYNC] = 0; // TODO: dram refresh delay to 106?\n break;\n case 113:\n this.h = 0;\n return\n }\n ++this.h;\n }\n doVBlank() {\n this.linesleft = this.mode = this.period = 0;\n if (this.h == 111) { this.v++; }\n if (this.v == 248 && this.h == 0) { this.triggerNMI(0x40); } // VBI\n if (this.v == 262 && this.h == 112) { this.v = 0; }\n if (this.v == 7 && this.h == 113) { \n this.dma_enabled = this.dlDMAEnabled() != 0;\n }\n this.output = 2; // blank\n this.dmaclock = 0;\n }\n\n doPlayerMissileDMA(section: number) {\n let oneline = this.regs[DMACTL] & 0x10;\n let pmaddr = this.regs[PMBASE] << 8;\n if (oneline) {\n pmaddr &= 0xf800;\n pmaddr |= section << 8;\n pmaddr |= this.v & 0xff;\n } else {\n pmaddr &= 0xfc00;\n pmaddr |= section << 7;\n pmaddr |= this.v >> 1;\n }\n this.read(pmaddr);\n }\n\n readBitmapData() {\n const mode = this.mode;\n if (mode < 8) {\t// character mode\n let ch = this.ch;\n let y = this.yofs >> MODE_YPERIOD[this.mode];\n let addrofs = y & 7;\n let chbase = this.regs[CHBASE];\n // modes 6 & 7\n if ((mode & 0xe) == 6) { // or 7\n ch &= 0x3f;\n chbase &= 0xfe;\n } else {\n ch &= 0x7f;\n chbase &= 0xfc;\n }\n let addr = (ch << 3) + (chbase << 8);\n // modes 2 & 3\n if ((mode & 0xe) == 2) { // or 3\n let chactl = this.regs[CHACTL];\n let mode3lc = mode == 3 && (ch & 0x60) == 0x60;\n if (chactl & 4)\n this.pfbyte = this.read(addr + (addrofs ^ 7)); // mirror\n else\n this.pfbyte = this.read(addr + addrofs);\n if (mode3lc && y < 2) { this.pfbyte = 0; }\n if (!mode3lc && y > 7) { this.pfbyte = 0; }\n if (this.ch & 0x80) {\n if (chactl & 1)\n this.pfbyte = 0x0; // blank\n if (chactl & 2)\n this.pfbyte ^= 0xff; // invert\n }\n } else {\n this.pfbyte = this.read(addr + addrofs);\n }\n } else {\t// map mode\n this.pfbyte = this.nextScreen();\n }\n }\n\n shiftout() {\n if (this.output == 4) { // visible pixel?\n switch (this.mode) {\n case 2: case 3:\n case 15:\n {\n let v = (this.pfbyte >> 7) & 1;\n this.pfbyte <<= 1;\n return v ? 8 : 6;\n }\n case 6: case 7:\n {\n let v = (this.pfbyte >> 7) & 1;\n this.pfbyte <<= 1;\n return v ? (this.ch >> 6) + 4 : 0;\n }\n case 9: case 11: case 12:\n {\n let v = (this.pfbyte >> 7) & 1;\n this.pfbyte <<= 1;\n return v ? 4 : 0;\n }\n case 4: case 5:\n {\n let v = (this.pfbyte >> 6) & 3;\n this.pfbyte <<= 2;\n if (this.ch & 0x80)\n return [0, 4, 5, 7][v];\n else\n return [0, 4, 5, 6][v];\n }\n case 8: case 10:\n case 13: case 14:\n {\n let v = (this.pfbyte >> 6) & 3;\n this.pfbyte <<= 2;\n return [0, 4, 5, 6][v];\n }\n }\n }\n return this.output;\n }\n\n}\n", "\n// GTIA\n// https://user.xmission.com/~trevin/atari/gtia_regs.html\n// https://user.xmission.com/~trevin/atari/gtia_pinout.html\n\nimport { dumpRAM, gtia_ntsc_to_rgb } from \"../../common/emu\";\nimport { hex, lpad, safe_extend } from \"../../common/util\";\n\n\n// write regs\nconst HPOSP0 = 0x0;\nconst HPOSM0 = 0x4;\nconst SIZEP0 = 0x8;\nconst SIZEM = 0x0c;\nconst GRAFP0 = 0x0d;\nconst GRAFM = 0x11;\nconst COLPM0 = 0x12;\nconst COLPF0 = 0x16;\nconst COLPF1 = 0x17;\nconst COLPF2 = 0x18;\nconst COLPF3 = 0x19;\nconst COLBK = 0x1a;\nconst PRIOR = 0x1b;\nconst VDELAY = 0x1c; // TODO\nconst GRACTL = 0x1d;\nconst HITCLR = 0x1e;\nconst CONSPK = 0x1f;\n// read regs\nconst M0PF = 0x0;\nconst P0PF = 0x4;\nconst M0PL = 0x8;\nconst P0PL = 0xc;\nexport const TRIG0 = 0x10;\nexport const CONSOL = 0x1f;\n\nconst HOFFSET = -9; // bias to account for antic->gtia delay\n\nconst PRIOR_TABLE : number[] = [\n 0,1,2,3, 7,7,7,7, 8,8,8,8, 4,5,6,7, // 0001 - 0\n 0,1,2,3, 7,7,7,7, 8,8,8,8, 4,5,6,7, // 0001\n 0,1,6,7, 5,5,5,5, 8,8,8,8, 2,3,4,5, // 0010 - 2\n 0,1,6,7, 5,5,5,5, 8,8,8,8, 2,3,4,5, // 0010\n 4,5,6,7, 3,3,3,3, 8,8,8,8, 0,1,2,3, // 0100 - 4\n 4,5,6,7, 3,3,3,3, 8,8,8,8, 0,1,2,3, // 0100\n 4,5,6,7, 3,3,3,3, 8,8,8,8, 0,1,2,3, // 0100\n 4,5,6,7, 3,3,3,3, 8,8,8,8, 0,1,2,3, // 0100\n 2,3,4,5, 7,7,7,7, 8,8,8,8, 0,1,6,7, // 1000 - 8\n 2,3,4,5, 7,7,7,7, 8,8,8,8, 0,1,6,7, // 1000\n 2,3,4,5, 7,7,7,7, 8,8,8,8, 0,1,6,7, // 1000\n 2,3,4,5, 7,7,7,7, 8,8,8,8, 0,1,6,7, // 1000\n 2,3,4,5, 7,7,7,7, 8,8,8,8, 0,1,6,7, // 1000\n 2,3,4,5, 7,7,7,7, 8,8,8,8, 0,1,6,7, // 1000\n 2,3,4,5, 7,7,7,7, 8,8,8,8, 0,1,6,7, // 1000\n 2,3,4,5, 7,7,7,7, 8,8,8,8, 0,1,6,7, // 1000\n];\n\nconst MODE_9_LOOKUP = [\n COLPM0+0, COLPM0+1, COLPM0+2, COLPM0+3,\n COLPF0+0, COLPF0+1, COLPF0+2, COLPF0+3,\n COLBK, COLBK, COLBK, COLBK,\n COLPF0+0, COLPF0+1, COLPF0+2, COLPF0+3,\n]\n\nexport class GTIA {\n regs = new Uint8Array(0x20);\n readregs = new Uint8Array(0x20);\n shiftregs = new Uint32Array(8);\n\n count = 0;\n an = 0;\n rgb = 0;\n pmcol = 0;\n gtiacol = 0;\n gtiacol2 = 0;\n hbias = HOFFSET;\n pmDebugMask = -1;\n\n reset() {\n this.regs.fill(0);\n this.readregs.fill(0); // TODO?\n this.readregs[0x14] = 0xf; // NTSC\n this.readregs.fill(0xf, 0x15); // default value for write-only regs\n this.count = 0;\n }\n saveState() {\n return safe_extend(0, {}, this);\n }\n loadState(s) {\n safe_extend(0, this, s);\n }\n setReg(a: number, v: number) {\n switch (a) {\n case COLPM0: case COLPM0+1: case COLPM0+2: case COLPM0+3:\n case COLPF0: case COLPF0+1: case COLPF0+2: case COLPF0+3:\n case COLBK:\n v &= 0xfe; // bit 0 unused in color regs\n break;\n case HITCLR:\n this.readregs.fill(0, 0, 16);\n return;\n }\n this.regs[a] = v;\n }\n readReg(a: number) {\n switch (a) {\n case CONSOL:\n return this.readregs[a] & ~this.regs[CONSPK];\n }\n return this.readregs[a];\n }\n sync() {\n this.count = 0;\n }\n setBias(b: number) {\n this.hbias = HOFFSET + b;\n }\n updateGfx(h: number, v: number, data: number) {\n switch (h) {\n case 0:\n if (this.regs[GRACTL] & 1) {\n // TODO: VDELAY\n this.regs[GRAFM] = data;\n }\n break;\n case 2: case 3: case 4: case 5:\n if (this.regs[GRACTL] & 2) {\n if (!(v&1) || !(this.regs[VDELAY] & (1<<(h+2))))\n this.regs[GRAFP0 - 2 + h] = data;\n }\n break;\n }\n }\n getPlayfieldColor(): number {\n // which GTIA mode?\n switch (this.regs[PRIOR] >> 6) {\n // normal mode\n case 0:\n switch (this.an) {\n case 0:\n return COLBK;\n case 4: case 5: case 6: case 7:\n return COLPF0 + this.an - 4;\n case 8:\n // combine PF2 hue and PF1 luminance\n return (this.regs[COLPF2] & 0xf0) | (this.regs[COLPF1] & 0x0f) | 0x100;\n }\n break;\n // mode 9 -- 16 luminances\n case 1:\n return (this.regs[COLBK] & 0xf0) | (this.gtiacol & 0xf) | 0x100;\n // mode 10 -- 9 colors from registers\n case 2:\n return MODE_9_LOOKUP[this.gtiacol];\n // mode 11 -- 16 hues\n case 3:\n return (this.regs[COLBK] & 0xf) | (this.gtiacol << 4) | 0x100;\n }\n return 0x100; // black\n }\n anySpriteActive() {\n return this.shiftregs[0] || this.shiftregs[1] || this.shiftregs[2]\n || this.shiftregs[3] || this.shiftregs[4] || this.shiftregs[5]\n || this.shiftregs[6] || this.shiftregs[7];\n }\n processPlayerMissile() {\n // no p/m gfx, just evaluate horiz. triggers\n if (!this.anySpriteActive()) {\n this.evalTrigger(0);\n this.evalTrigger(1);\n this.evalTrigger(2);\n this.evalTrigger(3);\n this.evalTrigger(4);\n this.evalTrigger(5);\n this.evalTrigger(6);\n this.evalTrigger(7);\n this.pmcol = -1;\n return;\n }\n // no collisions in blank area, but shift and trigger anyway\n if (this.an == 2) {\n this.shiftObject(0);\n this.shiftObject(1);\n this.shiftObject(2);\n this.shiftObject(3);\n this.shiftObject(4);\n this.shiftObject(5);\n this.shiftObject(6);\n this.shiftObject(7);\n this.pmcol = -1;\n return;\n }\n // TODO: gtia, hi-res mode collisions\n // compute gfx and collisions for players/missiles\n let priobias = (this.regs[PRIOR] & 15) << 4; // TODO\n let topprio = PRIOR_TABLE[(this.an & 7) + 8 + priobias];\n let pfset = this.an - 4; // TODO?\n let topobj = -1;\n let ppmask = 0;\n // players\n for (let i = 0; i < 4; i++) {\n let bit = this.shiftObject(i);\n if (bit) {\n if (pfset >= 0) { // TODO: hires and GTIA modes\n this.readregs[P0PF + i] |= 1 << pfset;\n }\n ppmask |= 1 << i;\n let prio = PRIOR_TABLE[i + priobias];\n if (prio < topprio) {\n topobj = i;\n topprio = prio;\n }\n }\n }\n // missiles\n for (let i = 0; i < 4; i++) {\n let bit = this.shiftObject(i + 4);\n if (bit) {\n if (pfset >= 0) {\n this.readregs[M0PF + i] |= 1 << pfset;\n }\n this.readregs[M0PL + i] |= ppmask;\n let prio = (this.regs[PRIOR] & 0x10) \n ? PRIOR_TABLE[priobias + 15]\n : PRIOR_TABLE[i + priobias];\n if (prio < topprio) {\n topobj = i + 4;\n topprio = prio;\n }\n }\n }\n // set player-player collision flags\n // TODO: either as a player or a GTIA mode 2 color\n if (ppmask & 1) this.readregs[P0PL + 0] |= ppmask & ~1;\n if (ppmask & 2) this.readregs[P0PL + 1] |= ppmask & ~2;\n if (ppmask & 4) this.readregs[P0PL + 2] |= ppmask & ~4;\n if (ppmask & 8) this.readregs[P0PL + 3] |= ppmask & ~8;\n this.pmcol = topobj >= 0 ? this.getObjectColor(topobj) : -1;\n }\n shiftObject(i: number) {\n let bit = (this.shiftregs[i] & 0x80000000) != 0;\n this.shiftregs[i] <<= 1;\n this.evalTrigger(i);\n return bit;\n }\n getObjectColor(i: number) {\n if ((this.regs[PRIOR] & 0x10) && i >= 4) {\n return this.regs[COLPF3];\n } else {\n return this.regs[COLPM0 + (i & 3)];\n }\n }\n evalTrigger(i: number) {\n if (this.regs[HPOSP0 + i] + this.hbias == this.count) {\n this.triggerObject(i);\n }\n }\n triggerObject(i: number) {\n let size, data;\n if (!(this.pmDebugMask & (1<<i))) return;\n if (i < 4) {\n size = this.regs[SIZEP0 + i] & 3;\n data = this.regs[GRAFP0 + i];\n } else {\n let s = (i - 4) << 1;\n size = (this.regs[SIZEM] >> s) & 3;\n data = ((this.regs[GRAFM] >> s) & 3) << 6;\n }\n if (size & 1) data = expandBits(data); else data <<= 8;\n if (size == 3) data = expandBits(data); else data <<= 16;\n this.shiftregs[i] |= data;\n }\n\n clockPulse1(): void {\n this.processPlayerMissile();\n this.clockPulse2();\n this.count++;\n }\n\n clockPulse2(): void {\n var col: number;\n if (this.pmcol >= 0) {\n col = this.pmcol;\n } else {\n let pf = this.getPlayfieldColor();\n col = pf & 0x100 ? pf & 0xff : this.regs[pf];\n }\n this.rgb = COLORS_RGBA[col];\n // TODO: hires modes return 8, so other modes wont work\n this.gtiacol2 = (this.gtiacol2 << 1) | (this.an >> 3);\n }\n\n clockPulse4() {\n // latch GTIA buffer\n this.gtiacol = this.gtiacol2 & 15;\n }\n\n static stateToLongString(state): string {\n let s = ''\n s += `X: ${lpad(state.count, 3)} ANTIC: ${hex(state.an, 1)} PM: ${hex(state.pmcol, 3)}\\n`;\n s += \"Write Registers:\\n\";\n s += dumpRAM(state.regs, 0, 32);\n s += \"Read Registers:\\n\";\n s += dumpRAM(state.readregs, 0, 32);\n return s;\n }\n}\n\nfunction expandBits(x: number): number {\n x = (x | (x << 8)) & 0x00FF00FF;\n x = (x | (x << 4)) & 0x0F0F0F0F;\n x = (x | (x << 2)) & 0x33333333;\n x = (x | (x << 1)) & 0x55555555;\n return x | (x << 1);\n}\n\nvar COLORS_RGBA = new Uint32Array(256);\nfor (var i = 0; i < 256; i++) {\n COLORS_RGBA[i] = gtia_ntsc_to_rgb(i);\n}\n\n", "/*\n * pokey.c - POKEY sound chip emulation\n *\n * Copyright (C) 1995-1998 David Firth\n * Copyright (C) 1998-2008 Atari800 development team (see DOC/CREDITS)\n *\n * This file is part of the Atari800 emulator project which emulates\n * the Atari 400, 800, 800XL, 130XE, and 5200 8-bit computers.\n *\n * Atari800 is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * Atari800 is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with Atari800; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n*/\n\nimport { dumpRAM } from \"../../common/emu\"\nimport { hex, lpad, safe_extend } from \"../../common/util\"\n\nconst AUDF1 = 0x00\nconst AUDC1 = 0x01\nconst AUDF2 = 0x02\nconst AUDC2 = 0x03\nconst AUDF3 = 0x04\nconst AUDC3 = 0x05\nconst AUDF4 = 0x06\nconst AUDC4 = 0x07\nconst AUDCTL = 0x08\nconst STIMER = 0x09\nconst SKRES = 0x0a\nconst POTGO = 0x0b\nconst SEROUT = 0x0d\nconst IRQEN = 0x0e\nconst SKCTL = 0x0f\n\nconst POT0 = 0x00\nconst POT1 = 0x01\nconst POT2 = 0x02\nconst POT3 = 0x03\nconst POT4 = 0x04\nconst POT5 = 0x05\nconst POT6 = 0x06\nconst POT7 = 0x07\nconst ALLPOT = 0x08\nconst KBCODE = 0x09\nconst RANDOM = 0x0a\nconst SERIN = 0x0d\nconst IRQST = 0x0e\nconst SKSTAT = 0x0f\n\n/* definitions for AUDCx (D201, D203, D205, D207) */\nconst NOTPOLY5 = 0x80 /* selects POLY5 or direct CLOCK */\nconst POLY4 = 0x40 /* selects POLY4 or POLY17 */\nconst PURETONE = 0x20 /* selects POLY4/17 or PURE tone */\nconst VOL_ONLY = 0x10 /* selects VOLUME OUTPUT ONLY */\nconst VOLUME_MASK = 0x0f /* volume mask */\n\n/* definitions for AUDCTL (D208) */\nconst POLY9 = 0x80 /* selects POLY9 or POLY17 */\nconst CH1_179 = 0x40 /* selects 1.78979 MHz for Ch 1 */\nconst CH3_179 = 0x20 /* selects 1.78979 MHz for Ch 3 */\nconst CH1_CH2 = 0x10 /* clocks channel 1 w/channel 2 */\nconst CH3_CH4 = 0x08 /* clocks channel 3 w/channel 4 */\nconst CH1_FILTER = 0x04 /* selects channel 1 high pass filter */\nconst CH2_FILTER = 0x02 /* selects channel 2 high pass filter */\nconst CLOCK_15 = 0x01 /* selects 15.6999kHz or 63.9210kHz */\n\n/* for accuracy, the 64kHz and 15kHz clocks are exact divisions of\n the 1.79MHz clock */\nconst DIV_64 = 28 /* divisor for 1.79MHz clock to 64 kHz */\nconst DIV_15 = 114 /* divisor for 1.79MHz clock to 15 kHz */\n\n/* the size (in entries) of the 4 polynomial tables */\nconst POLY4_SIZE = 0x000f\nconst POLY5_SIZE = 0x001f\nconst POLY9_SIZE = 0x01ff\nconst POLY17_SIZE = 0x0001ffff\n\nconst CHAN1 = 0\nconst CHAN2 = 1\nconst CHAN3 = 2\nconst CHAN4 = 3\n\nconst ANTIC_LINE_C = 114\n\n/* Some defines about the serial I/O timing. Currently fixed! */\nconst SIO_XMTDONE_INTERVAL = 15\nconst SIO_SERIN_INTERVAL = 8\nconst SIO_SEROUT_INTERVAL = 8\nconst SIO_ACK_INTERVAL = 36\n\nvar poly9: Uint8Array;\nvar poly17: Uint8Array;\n\nfunction initPolyTables() {\n poly9 = new Uint8Array(511);\n poly17 = new Uint8Array(16385);\n /* initialise poly9_lookup */\n let reg = 0x1ff;\n for (let i = 0; i < 511; i++) {\n reg = ((((reg >> 5) ^ reg) & 1) << 8) + (reg >> 1);\n poly9[i] = reg;\n }\n /* initialise poly17_lookup */\n reg = 0x1ffff;\n for (let i = 0; i < 16385; i++) {\n reg = ((((reg >> 5) ^ reg) & 0xff) << 9) + (reg >> 8);\n poly17[i] = (reg >> 1);\n }\n}\n\nexport class POKEY {\n regs = new Uint8Array(16);\n readregs = new Uint8Array(16);\n divnirq = new Uint32Array(4);\n divnmax = new Uint32Array(4);\n pot_inputs = new Uint8Array(8);\n basemult = 0;\n pot_scanline = 0;\n random_scanline_counter = 0;\n kbcode = 0;\n DELAYED_SERIN_IRQ = 0;\n DELAYED_SEROUT_IRQ = 0;\n DELAYED_XMTDONE_IRQ = 0;\n\n constructor(\n public irq: () => void,\n public antic_xpos: () => number,\n ) {\n this.init();\n }\n\n saveState() {\n return safe_extend(0, {}, this);\n }\n loadState(s) {\n safe_extend(0, this, s);\n }\n\n init() {\n /* Initialise Serial Port Interrupts */\n //DELAYED_SERIN_IRQ = 0;\n //DELAYED_SEROUT_IRQ = 0;\n //DELAYED_XMTDONE_IRQ = 0;\n this.readregs.fill(0xff);\n this.readregs[SKSTAT] = 0xef;\n //SERIN = 0x00;\t/* or 0xff ? */\n //IRQEN = 0x00;\n //SKCTL = 0x00;\n this.basemult = DIV_64;\n this.pot_inputs.fill(128);\n initPolyTables();\n }\n\n\n read(addr: number): number {\n let byte = this.readregs[addr];\n addr &= 0xf;\n switch (addr) {\n case 0: case 1: case 2: case 3:\n case 4: case 5: case 6: case 7:\n byte = this.pot_inputs[addr];\n return (byte < this.pot_scanline) ? byte : this.pot_scanline;\n case ALLPOT:\n for (let i = 0; i < 8; i++) {\n if (this.pot_inputs[i] <= this.pot_scanline)\n byte &= ~(1 << i);\t\t// reset bit if pot value known\n }\n break;\n case KBCODE:\n return this.kbcode;\n case SKSTAT:\n byte = SKSTAT + (this.CASSETTE_IOLineStatus() << 4);\n break;\n case RANDOM:\n if ((this.regs[SKCTL] & 0x03) != 0) {\n let i = this.random_scanline_counter + this.antic_xpos();\n if (this.regs[AUDCTL] & POLY9)\n byte = poly9[i % POLY9_SIZE];\n else {\n i %= POLY17_SIZE;\n let ptr = i >> 3;\n i &= 7;\n byte = (poly17[ptr] >> i) + (poly17[ptr + 1] << (8 - i));\n }\n }\n break;\n }\n return byte & 0xff;\n }\n\n write(addr: number, byte: number): void {\n addr &= 0x0f;\n this.regs[addr] = byte;\n switch (addr) {\n case AUDCTL:\n /* determine the base multiplier for the 'div by n' calculations */\n if (byte & CLOCK_15)\n this.basemult = DIV_15;\n else\n this.basemult = DIV_64;\n this.update_counter((1 << CHAN1) | (1 << CHAN2) | (1 << CHAN3) | (1 << CHAN4));\n break;\n case AUDF1:\n this.update_counter((this.regs[AUDCTL] & CH1_CH2) ? ((1 << CHAN2) | (1 << CHAN1)) : (1 << CHAN1));\n break;\n case AUDF2:\n this.update_counter(1 << CHAN2);\n break;\n case AUDF3:\n this.update_counter((this.regs[AUDCTL] & CH3_CH4) ? ((1 << CHAN4) | (1 << CHAN3)) : (1 << CHAN3));\n break;\n case AUDF4:\n this.update_counter(1 << CHAN4);\n break;\n case IRQEN:\n this.readregs[IRQST] |= ~byte & 0xf7;\t/* Reset disabled IRQs except XMTDONE */\n let mask = ~this.readregs[IRQST] & this.regs[IRQEN];\n if (mask) {\n this.generateIRQ(this.readregs[IRQST]);\n }\n break;\n case SKRES:\n this.readregs[SKSTAT] |= 0xe0;\n break;\n case POTGO:\n if (!(this.regs[SKCTL] & 4))\n this.pot_scanline = 0;\t/* slow pot mode */\n break;\n case SEROUT:\n if ((this.regs[SKCTL] & 0x70) == 0x20 && this.siocheck()) {\n this.SIO_PutByte(byte);\n }\n // check if cassette 2-tone mode has been enabled \n if ((this.regs[SKCTL] & 0x08) == 0x00) {\n // intelligent device\n this.DELAYED_SEROUT_IRQ = SIO_SEROUT_INTERVAL;\n this.readregs[IRQST] |= 0x08;\n this.DELAYED_XMTDONE_IRQ = SIO_XMTDONE_INTERVAL;\n }\n else {\n // cassette \n // some savers patch the cassette baud rate, so we evaluate it here \n // scanlines per second*10 bit*audiofrequency/(1.79 MHz/2) \n this.DELAYED_SEROUT_IRQ = 312 * 50 * 10 * (this.regs[AUDF3] + this.regs[AUDF4] * 0x100) / 895000;\n // safety check \n if (this.DELAYED_SEROUT_IRQ >= 3) {\n this.readregs[IRQST] |= 0x08;\n this.DELAYED_XMTDONE_IRQ = 2 * this.DELAYED_SEROUT_IRQ - 2;\n }\n else {\n this.DELAYED_SEROUT_IRQ = 0;\n this.DELAYED_XMTDONE_IRQ = 0;\n }\n };\n break;\n case STIMER:\n this.divnirq[CHAN1] = this.divnmax[CHAN1];\n this.divnirq[CHAN2] = this.divnmax[CHAN2];\n this.divnirq[CHAN3] = this.divnmax[CHAN3];\n this.divnirq[CHAN4] = this.divnmax[CHAN4];\n //POKEYSND_Update(STIMER, byte, 0, SOUND_GAIN);\n break;\n case SKCTL:\n //VOICEBOX_SKCTLPutByte(byte);\n //POKEYSND_Update(SKCTL, byte, 0, SOUND_GAIN);\n if (byte & 4)\n this.pot_scanline = 228;\t/* fast pot mode - return results immediately */\n if ((byte & 0x03) == 0) {\n /* POKEY reset. */\n /* Stop serial IO. */\n this.DELAYED_SERIN_IRQ = 0;\n this.DELAYED_SEROUT_IRQ = 0;\n this.DELAYED_XMTDONE_IRQ = 0;\n // TODO: CASSETTE_ResetPOKEY();\n /* TODO other registers should also be reset. */\n }\n break;\n }\n this.snd_update(addr);\n //POKEYSND_Update(AUDC1, byte, 0, SOUND_GAIN);\n }\n\n /*****************************************************************************/\n /* Module: Update_Counter() */\n /* Purpose: To process the latest control values stored in the AUDF, AUDC, */\n /* and AUDCTL registers. It pre-calculates as much information as */\n /* possible for better performance. This routine has been added */\n /* here again as I need the precise frequency for the pokey timers */\n /* again. The pokey emulation is therefore somewhat sub-optimal */\n /* since the actual pokey emulation should grab the frequency values */\n /* directly from here instead of calculating them again. */\n /* */\n /* Author: Ron Fries,Thomas Richter */\n /* Date: March 27, 1998 */\n /* */\n /* Inputs: chan_mask: Channel mask, one bit per channel. */\n /* The channels that need to be updated */\n /* */\n /* Outputs: Adjusts local globals - no return value */\n /* */\n /*****************************************************************************/\n\n update_counter(chan_mask: number): void {\n\n /************************************************************/\n /* As defined in the manual, the exact Div_n_cnt values are */\n /* different depending on the frequency and resolution: */\n /* 64 kHz or 15 kHz - AUDF + 1 */\n /* 1 MHz, 8-bit - AUDF + 4 */\n /* 1 MHz, 16-bit - AUDF[CHAN1]+256*AUDF[CHAN2] + 7 */\n /************************************************************/\n\n /* only reset the channels that have changed */\n\n if (chan_mask & (1 << CHAN1)) {\n /* process channel 1 frequency */\n if (this.regs[AUDCTL] & CH1_179)\n this.divnmax[CHAN1] = this.regs[AUDF1 + CHAN1] + 4;\n else\n this.divnmax[CHAN1] = (this.regs[AUDF1 + CHAN1] + 1) * this.basemult;\n if (this.divnmax[CHAN1] < ANTIC_LINE_C)\n this.divnmax[CHAN1] = ANTIC_LINE_C;\n }\n\n if (chan_mask & (1 << CHAN2)) {\n /* process channel 2 frequency */\n if (this.regs[AUDCTL] & CH1_CH2) {\n if (this.regs[AUDCTL] & CH1_179)\n this.divnmax[CHAN2] = this.regs[AUDF1 + CHAN2] * 256 + this.regs[AUDF1 + CHAN1] + 7;\n else\n this.divnmax[CHAN2] = (this.regs[AUDF1 + CHAN2] * 256 + this.regs[AUDF1 + CHAN1] + 1) * this.basemult;\n }\n else\n this.divnmax[CHAN2] = (this.regs[AUDF1 + CHAN2] + 1) * this.basemult;\n if (this.divnmax[CHAN2] < ANTIC_LINE_C)\n this.divnmax[CHAN2] = ANTIC_LINE_C;\n }\n\n if (chan_mask & (1 << CHAN4)) {\n /* process channel 4 frequency */\n if (this.regs[AUDCTL] & CH3_CH4) {\n if (this.regs[AUDCTL] & CH3_179)\n this.divnmax[CHAN4] = this.regs[AUDF1 + CHAN4] * 256 + this.regs[AUDF1 + CHAN3] + 7;\n else\n this.divnmax[CHAN4] = (this.regs[AUDF1 + CHAN4] * 256 + this.regs[AUDF1 + CHAN3] + 1) * this.basemult;\n }\n else\n this.divnmax[CHAN4] = (this.regs[AUDF1 + CHAN4] + 1) * this.basemult;\n if (this.divnmax[CHAN4] < ANTIC_LINE_C)\n this.divnmax[CHAN4] = ANTIC_LINE_C;\n }\n\n //console.log(chan_mask, this.divnmax);\n }\n\n snd_update(addr: number) {\n\n }\n\n advanceScanline() {\n /***************************************************************************\n ** Generate POKEY Timer IRQs if required **\n ** called on a per-scanline basis, not very precise, but good enough **\n ** for most applications **\n ***************************************************************************/\n\n\n /* on nonpatched i/o-operation, enable the cassette timing */\n /*\n if (!ESC_enable_sio_patch) {\n if (CASSETTE_AddScanLine())\n DELAYED_SERIN_IRQ = 1;\n }\n */\n\n if ((this.regs[SKCTL] & 0x03) == 0)\n /* Don't process timers when POKEY is in reset mode. */\n return;\n\n if (this.pot_scanline < 228)\n this.pot_scanline++;\n\n this.random_scanline_counter += ANTIC_LINE_C;\n this.random_scanline_counter %= (this.regs[AUDCTL] & POLY9) ? POLY9_SIZE : POLY17_SIZE;\n\n if (this.DELAYED_SERIN_IRQ > 0) {\n if (--this.DELAYED_SERIN_IRQ == 0) {\n // Load a byte to SERIN - even when the IRQ is disabled. \n this.readregs[SERIN] = this.SIO_GetByte();\n this.generateIRQ(0x20);\n }\n }\n\n if (this.DELAYED_SEROUT_IRQ > 0) {\n if (--this.DELAYED_SEROUT_IRQ == 0) {\n this.generateIRQ(0x10);\n }\n }\n\n if (this.DELAYED_XMTDONE_IRQ > 0)\n if (--this.DELAYED_XMTDONE_IRQ == 0) {\n this.generateIRQ(0x08);\n }\n\n this.advanceIRQTimer(CHAN1, 0x1);\n this.advanceIRQTimer(CHAN2, 0x2);\n this.advanceIRQTimer(CHAN4, 0x4);\n }\n\n advanceIRQTimer(chan: number, mask: number) {\n if ((this.divnirq[chan] -= ANTIC_LINE_C) < 0) {\n this.divnirq[chan] += this.divnmax[chan];\n this.generateIRQ(mask);\n //console.log('irq', chan, this.divnirq[chan], this.divnmax[chan])\n }\n }\n\n generateIRQ(mask: number) {\n if (this.regs[IRQEN] & mask) {\n this.irq();\n this.readregs[IRQST] &= ~mask;\n }\n }\n\n static stateToLongString(state): string {\n let s = ''\n s += \"Write Registers:\\n\";\n s += dumpRAM(state.regs, 0, 16);\n s += \"Read Registers:\\n\";\n s += dumpRAM(state.readregs, 0, 16);\n return s;\n }\n\n CASSETTE_IOLineStatus() {\n return 0;\n }\n\n siocheck() {\n return (((this.regs[AUDF1 + CHAN3] == 0x28 || this.regs[AUDF1 + CHAN3] == 0x10\n || this.regs[AUDF1 + CHAN3] == 0x08 || this.regs[AUDF1 + CHAN3] == 0x0a)\n && this.regs[AUDF1 + CHAN4] == 0x00) // intelligent peripherals speeds\n || (this.regs[SKCTL] & 0x78) == 0x28) // cassette save mode\n && (this.regs[AUDCTL] & 0x28) == 0x28;\n }\n SIO_PutByte(byte: number) {\n // TODO\n console.log(\"SIO put byte\", byte);\n }\n SIO_GetByte() {\n return 0; // TODO\n }\n\n}\n\n\n//const SOUND_GAIN 4\n/*\nvoid Frame(void)\n{\n random_scanline_counter %= (this.regs[AUDCTL] & POLY9) ? POLY9_SIZE : POLY17_SIZE;\n}\n*/\n\n\n\n", "import { newPOKEYAudio, TssChannelAdapter } from \"../common/audio\";\nimport { MOS6502 } from \"../common/cpu/MOS6502\";\nimport { AcceptsPaddleInput, BasicScanlineMachine } from \"../common/devices\";\nimport { KeyFlags, Keys, makeKeycodeMap, newAddressDecoder, newKeyboardHandler } from \"../common/emu\";\nimport { hex } from \"../common/util\";\nimport { ANTIC, MODE_LINES, MODE_SHIFT } from \"./chips/antic\";\nimport { CONSOL, GTIA, TRIG0 } from \"./chips/gtia\";\nimport { POKEY } from \"./chips/pokey\";\n\nconst ATARI8_KEYMATRIX_INTL_NOSHIFT = [\n Keys.VK_L, Keys.VK_J, Keys.VK_SEMICOLON, Keys.VK_F4, Keys.VK_F5, Keys.VK_K, Keys.VK_BACK_SLASH, Keys.VK_TILDE,\n Keys.VK_O, null, Keys.VK_P, Keys.VK_U, Keys.VK_ENTER, Keys.VK_I, Keys.VK_MINUS2, Keys.VK_EQUALS2,\n Keys.VK_V, Keys.VK_F7, Keys.VK_C, Keys.VK_F6, Keys.VK_F4, Keys.VK_B, Keys.VK_X, Keys.VK_Z,\n Keys.VK_4, null, Keys.VK_3, Keys.VK_6, Keys.VK_ESCAPE, Keys.VK_5, Keys.VK_2, Keys.VK_1,\n Keys.VK_COMMA, Keys.VK_SPACE, Keys.VK_PERIOD, Keys.VK_N, null, Keys.VK_M, Keys.VK_SLASH, null/*invert*/,\n Keys.VK_R, null, Keys.VK_E, Keys.VK_Y, Keys.VK_TAB, Keys.VK_T, Keys.VK_W, Keys.VK_Q,\n Keys.VK_9, null, Keys.VK_0, Keys.VK_7, Keys.VK_BACK_SPACE, Keys.VK_8, null, null,\n Keys.VK_F, Keys.VK_H, Keys.VK_D, null, Keys.VK_CAPS_LOCK, Keys.VK_G, Keys.VK_S, Keys.VK_A,\n];\n\n//TODO\nvar ATARI8_KEYCODE_MAP = makeKeycodeMap([\n [Keys.UP, 0, 0x1],\n [Keys.DOWN, 0, 0x2],\n [Keys.LEFT, 0, 0x4],\n [Keys.RIGHT, 0, 0x8],\n [{ c: 16, n: \"Shift\", plyr: 0, button: 0 }, 2, 0x1],\n /*\n [Keys.P2_UP, 0, 0x10],\n [Keys.P2_DOWN, 0, 0x20],\n [Keys.P2_LEFT, 0, 0x40],\n [Keys.P2_RIGHT, 0, 0x80],\n [Keys.P2_A, 3, 0x1],\n */\n [Keys.VK_F1, 3, 0x1], // START\n [Keys.VK_F2, 3, 0x2], // SELECT\n [Keys.VK_F3, 3, 0x4], // OPTION\n]);\n\n\nexport class Atari800 extends BasicScanlineMachine implements AcceptsPaddleInput {\n\n // http://www.ataripreservation.org/websites/freddy.offenga/megazine/ISSUE5-PALNTSC.html\n cpuFrequency = 1789773;\n numTotalScanlines = 262;\n cpuCyclesPerLine = 114;\n canvasWidth = 336;\n numVisibleScanlines = 224;\n aspectRatio = this.canvasWidth / this.numVisibleScanlines * 0.857;\n firstVisibleScanline = 16;\n firstVisibleClock = (44 - 6) * 2; // ... to 215 * 2\n defaultROMSize = 0x8000;\n overscan = true;\n audioOversample = 2;\n sampleRate = this.numTotalScanlines * 60 * this.audioOversample;\n run_address = -1;\n\n cpu: MOS6502;\n ram: Uint8Array;\n bios: Uint8Array;\n bus;\n audio_pokey;\n audioadapter;\n antic: ANTIC;\n gtia: GTIA;\n irq_pokey: POKEY;\n inputs = new Uint8Array(4);\n linergb = new Uint32Array(this.canvasWidth);\n lastdmabyte = 0;\n keycode = 0;\n cart_80 = false;\n cart_a0 = false;\n xexdata = null;\n keyboard_active = true;\n d500 = new Uint8Array(0x100);\n // TODO: save/load vars\n\n constructor() {\n super();\n this.cpu = new MOS6502();\n this.ram = new Uint8Array(0x10000);\n this.bios = new Uint8Array(0x2800);\n this.bus = this.newBus();\n this.connectCPUMemoryBus(this.bus);\n // create support chips\n this.antic = new ANTIC(this.readDMA.bind(this), this.antic_nmi.bind(this));\n this.gtia = new GTIA();\n this.irq_pokey = new POKEY(this.pokey_irq.bind(this), () => this.antic.h);\n this.audio_pokey = newPOKEYAudio(1);\n this.audioadapter = new TssChannelAdapter(this.audio_pokey.pokey1, this.audioOversample, this.sampleRate);\n this.handler = newKeyboardHandler(\n this.inputs, ATARI8_KEYCODE_MAP, this.getKeyboardFunction(), true);\n }\n newBus() {\n return {\n read: newAddressDecoder([\n [0x0000, 0x7fff, 0xffff, (a) => { return this.ram[a]; }],\n [0x8000, 0x9fff, 0xffff, (a) => { return this.cart_80 ? this.rom[a - 0x8000] : this.ram[a]; }],\n [0xa000, 0xbfff, 0xffff, (a) => { return this.cart_a0 ? this.rom[a - 0x8000] : this.ram[a]; }],\n [0xd000, 0xd0ff, 0x1f, (a) => { return this.gtia.readReg(a); }],\n [0xd200, 0xd2ff, 0xf, (a) => { return this.readPokey(a); }],\n [0xd300, 0xd3ff, 0xf, (a) => { return this.readPIA(a); }],\n [0xd400, 0xd4ff, 0xf, (a) => { return this.antic.readReg(a); }],\n [0xd500, 0xd5ff, 0xff, (a) => { return this.d500[a]; }],\n [0xd800, 0xffff, 0xffff, (a) => { return this.bios[a - 0xd800]; }],\n ]),\n write: newAddressDecoder([\n [0x0000, 0xbffa, 0xffff, (a, v) => { this.ram[a] = v; }],\n [0xbffb, 0xbfff, 0xffff, (a, v) => { this.ram[a] = v; this.initCartA(); }],\n [0xd000, 0xd0ff, 0x1f, (a, v) => { this.gtia.setReg(a, v); }],\n [0xd200, 0xd2ff, 0xf, (a, v) => { this.writePokey(a, v); }],\n [0xd400, 0xd4ff, 0xf, (a, v) => { this.antic.setReg(a, v); }],\n [0xd500, 0xd5ff, 0xff, (a, v) => { this.writeMapper(a, v); }],\n ]),\n };\n }\n\n loadBIOS(bios: Uint8Array) {\n this.bios.set(bios);\n }\n\n reset() {\n super.reset();\n this.antic.reset();\n this.gtia.reset();\n this.keycode = 0;\n //if (this.xexdata) this.cart_a0 = true; // TODO\n }\n\n read(a) {\n // TODO: lastdmabyte?\n return this.bus.read(a);\n }\n // used by ANTIC\n readDMA(a) {\n let v = this.bus.read(a);\n this.probe.logDMARead(a, v);\n this.lastdmabyte = v;\n return v;\n }\n readConst(a) {\n return a < 0xd000 || a >= 0xd500 ? this.bus.read(a) : 0xff;\n }\n write(a, v) {\n this.bus.write(a, v);\n }\n readPokey(a: number) {\n switch (a & 0xf) {\n case 9: // KBCODE\n return this.keycode & 0xff;\n case 15: // SKSTAT\n return ((~this.keycode >> 6) & 0x4) | ((~this.keycode >> 3) & 0x8) | 0x12;\n default:\n return this.irq_pokey.read(a);\n }\n }\n readPIA(a: number) {\n if (a == 0 || a == 1) { return ~this.inputs[a]; }\n }\n writePokey(a, v) {\n this.audio_pokey.pokey1.setRegister(a, v);\n this.irq_pokey.write(a, v);\n }\n\n startScanline() {\n // TODO: if (this.antic.h != 0) throw new Error(this.antic.h+\"\");\n //if (this.cpu.isHalted()) throw new EmuHalt(\"CPU HALTED\");\n // set GTIA switch inputs\n this.gtia.sync();\n // TODO: trigger latching mode\n for (let i = 0; i < 4; i++)\n this.gtia.readregs[TRIG0 + i] = (~this.inputs[2] >> i) & 1;\n // console switches\n this.gtia.readregs[CONSOL] = ~this.inputs[3] & 0x7;\n // advance POKEY audio\n this.audio && this.audioadapter.generate(this.audio);\n // advance POKEY IRQ timers\n this.irq_pokey.advanceScanline();\n }\n\n drawScanline() {\n // TODO\n let y = this.antic.v - this.firstVisibleScanline;\n if (y >= 0 && y < this.numVisibleScanlines) {\n this.pixels.set(this.linergb, y * this.canvasWidth);\n }\n }\n\n advanceCPU(): number {\n // update ANTIC\n if (this.antic.clockPulse()) {\n // ANTIC DMA cycle, update GTIA\n if (this.antic.h < 8)\n this.gtia.updateGfx(this.antic.h - 1, this.antic.v, this.lastdmabyte); // HALT pin\n if (this.antic.isWSYNC())\n this.probe.logWait(0);\n this.probe.logClocks(1);\n } else {\n super.advanceCPU();\n }\n // update GTIA\n // get X coordinate within scanline\n let xofs = this.antic.h * 4 - this.firstVisibleClock;\n // GTIA tick functions\n let gtiatick1 = () => {\n this.gtia.clockPulse1();\n this.linergb[xofs++] = this.gtia.rgb;\n }\n let gtiatick2 = () => {\n this.gtia.clockPulse2();\n this.linergb[xofs++] = this.gtia.rgb;\n }\n // tick 4 GTIA clocks for each CPU/ANTIC cycle\n this.gtia.clockPulse4();\n // correct for HSCROL -- bias antic +2, bias gtia -1\n if ((this.antic.dliop & 0x10) && (this.antic.regs[4] & 1)) {\n xofs += 2;\n this.gtia.setBias(-1);\n } else {\n this.gtia.setBias(0);\n }\n let bp = MODE_SHIFT[this.antic.mode];\n let odd = this.antic.h & 1;\n if (bp < 8 || odd) { this.gtia.an = this.antic.shiftout(); }\n gtiatick1();\n if (bp == 1) { this.gtia.an = this.antic.shiftout(); }\n gtiatick2();\n if (bp <= 2) { this.gtia.an = this.antic.shiftout(); }\n gtiatick1();\n if (bp == 1) { this.gtia.an = this.antic.shiftout(); }\n gtiatick2();\n return 1;\n }\n\n loadState(state: any) {\n this.loadControlsState(state);\n this.cpu.loadState(state.c);\n this.ram.set(state.ram);\n this.antic.loadState(state.antic);\n this.gtia.loadState(state.gtia);\n this.irq_pokey.loadState(state.pokey);\n this.lastdmabyte = state.lastdmabyte;\n this.cart_80 = state.cart_80;\n this.cart_a0 = state.cart_a0;\n }\n saveState() {\n return {\n c: this.cpu.saveState(),\n ram: this.ram.slice(0),\n antic: this.antic.saveState(),\n gtia: this.gtia.saveState(),\n pokey: this.irq_pokey.saveState(),\n inputs: this.inputs.slice(0),\n lastdmabyte: this.lastdmabyte,\n keycode: this.keycode,\n cart_80: this.cart_80,\n cart_a0: this.cart_a0,\n };\n }\n loadControlsState(state) {\n this.inputs.set(state.inputs);\n this.keycode = state.keycode;\n }\n saveControlsState() {\n return {\n inputs: this.inputs.slice(0),\n keycode: this.keycode,\n };\n }\n getRasterY() {\n return this.antic.v;\n }\n getRasterX() {\n return this.antic.h;\n }\n getRasterCanvasPosition() {\n return {\n x: this.antic.h * 4 - this.firstVisibleClock,\n y: this.antic.v - this.firstVisibleScanline,\n }\n }\n getDebugCategories() {\n return ['CPU', 'Stack', 'ANTIC', 'GTIA', 'POKEY'];\n }\n getDebugInfo(category, state) {\n switch (category) {\n case 'ANTIC': return ANTIC.stateToLongString(state.antic);\n case 'GTIA': return GTIA.stateToLongString(state.gtia);\n case 'POKEY': return POKEY.stateToLongString(state.pokey);\n }\n }\n getKeyboardFunction() {\n return (o, key, code, flags) => {\n if (!this.keyboard_active) return false;\n if (flags & (KeyFlags.KeyDown | KeyFlags.KeyUp)) {\n //console.log(o, key, code, flags, hex(this.keycode));\n var keymap = ATARI8_KEYMATRIX_INTL_NOSHIFT;\n if (key == Keys.VK_F9.c) {\n this.irq_pokey.generateIRQ(0x80); // break IRQ\n return true;\n }\n for (var i = 0; i < keymap.length; i++) {\n if (keymap[i] && keymap[i].c == key) {\n this.keycode = i;\n if (flags & KeyFlags.Shift) { this.keycode |= 0x40; }\n if (flags & KeyFlags.Ctrl) { this.keycode |= 0x80; }\n if (flags & KeyFlags.KeyDown) {\n this.keycode |= 0x100;\n this.irq_pokey.generateIRQ(0x40); // key pressed IRQ\n return true;\n }\n }\n }\n };\n }\n }\n pokey_irq() {\n this.cpu.IRQ();\n this.probe.logInterrupt(2);\n }\n antic_nmi() {\n this.cpu.NMI();\n this.probe.logInterrupt(1);\n }\n\n loadROM(rom: Uint8Array, title: string) {\n if ((rom[0] == 0xff && rom[1] == 0xff) && !title?.endsWith('.rom')) {\n // XEX file, chill out and wait for BIOS hook\n this.xexdata = rom;\n } else {\n this.loadCartridge(rom);\n }\n }\n\n loadCartridge(rom: Uint8Array) {\n // TODO: https://github.com/dmlloyd/atari800/blob/master/DOC/cart.txt\n // strip off header\n if (rom[0] == 0x43 && rom[1] == 0x41 && rom[2] == 0x52 && rom[3] == 0x54) {\n rom = rom.slice(16);\n }\n if (rom.length != 0x1000 && rom.length != 0x2000 && rom.length != 0x4000 && rom.length != 0x8000)\n throw new Error(\"Sorry, this platform can only load 4/8/16/32 KB cartridges at the moment.\");\n // TODO: support other than 8 KB carts\n // support 4/8/16/32 KB carts\n let rom2 = new Uint8Array(0x8000);\n for (let i = 0; i <= rom2.length - rom.length; i += rom.length) {\n rom2.set(rom, i);\n }\n this.run_address = rom2[0x7ffe] + rom2[0x7fff]*256;\n this.cart_a0 = true; // TODO\n this.cart_80 = rom.length == 0x4000;\n super.loadROM(rom2);\n }\n\n writeMapper(addr: number, value: number) {\n // TODO\n if (addr == 0xff) {\n if (value == 0x80) this.cart_80 = false;\n if (value == 0xa0) this.cart_a0 = false;\n }\n }\n\n loadXEX(rom: Uint8Array) {\n let ofs = 2;\n let stub = this.d500;\n let stubofs = 0; // stub routine \n var runaddr = -1;\n // load segments into RAM\n while (ofs < rom.length) {\n let start = rom[ofs + 0] + rom[ofs + 1] * 256;\n let end = rom[ofs + 2] + rom[ofs + 3] * 256;\n console.log('XEX', hex(ofs), hex(start), hex(end));\n ofs += 4;\n for (let i = start; i <= end; i++) {\n this.ram[i] = rom[ofs++];\n }\n if (start == 0x2e0 && end == 0x2e1) {\n runaddr = this.ram[0x2e0] + this.ram[0x2e1] * 256;\n console.log('XEX run', hex(runaddr));\n }\n if (start == 0x2e2 && end == 0x2e3) {\n var initaddr = this.ram[0x2e2] + this.ram[0x2e3] * 256;\n console.log('XEX init', hex(initaddr));\n stub[stubofs++] = 0x20;\n stub[stubofs++] = initaddr & 0xff;\n stub[stubofs++] = initaddr >> 8;\n }\n if (ofs > rom.length) throw new Error(\"Bad .XEX file format\");\n }\n if (runaddr >= 0) {\n // build stub routine at 0xd500\n stub[stubofs++] = 0xa9; // lda #$a0\n stub[stubofs++] = 0xa0;\n stub[stubofs++] = 0x8d; // sta $d5ff (disable cart)\n stub[stubofs++] = 0xff;\n stub[stubofs++] = 0xd5;\n stub[stubofs++] = 0x4c; // jmp runaddr\n stub[stubofs++] = runaddr & 0xff;\n stub[stubofs++] = runaddr >> 8;\n // set DOSVEC to 0xd500\n this.ram[0xa] = 0x00;\n this.ram[0xb] = 0xd5;\n this.run_address = 0xd500;\n }\n }\n\n initCartA() {\n if (this.cpu.getPC() == 0xf17f && this.xexdata) {\n this.loadXEX(this.xexdata);\n }\n }\n\n setPaddleInput(controller: number, value: number): void {\n this.irq_pokey.pot_inputs[controller] = 255 - value;\n }\n\n getDebugDisplayList() {\n let pc = this.antic.getDlistAddr();\n const nextInsn = () => {\n let b = this.read(pc);\n pc = ((pc + 1) & 0x3ff) | (pc & ~0x3ff);\n return b;\n }\n let dlist = [];\n let y = 0;\n for (let i=0; i<256 && y<240; i++) {\n let pc0 = pc;\n let op = nextInsn(); // get mode\n let mode = op & 0xf;\n let debugmsg = \"\" // \"op=\" + hex(op);\n let jmp = false;\n let lines;\n if (mode == 0) {\n lines = (((op >> 4) & 7) + 1);\n debugmsg += \" blank=\" + lines;\n } else {\n lines = MODE_LINES[mode];\n debugmsg += \" mode=\" + hex(mode);\n debugmsg += \" lines=\" + lines;\n jmp = (op & ~0x40) == 0x01; // JMP insn?\n let lms = (op & 0x40) != 0 && (op & 0xf) != 0; // LMS insn?\n if (op & 0x10) { debugmsg += \" HSCROL\"; }\n if (op & 0x20) { debugmsg += \" VSCROL\"; }\n if (op & 0x80) { debugmsg += \" DLI\"; }\n if (jmp && (op & 0x40)) { debugmsg += \" JVB\"; }\n else if (jmp) debugmsg += \" JMP\";\n else if (lms) debugmsg += \" LMS\";\n if (jmp || lms) {\n let dlarg_lo = nextInsn();\n let dlarg_hi = nextInsn();\n debugmsg += \" $\" + hex(dlarg_hi) + \"\" + hex(dlarg_lo);\n }\n }\n dlist.push(\"$\"+hex(pc0) + \" y=\" + y + \" \" + debugmsg);\n if (jmp) break;\n y += lines;\n }\n return dlist;\n }\n\n}\n\nexport class Atari5200 extends Atari800 {\n newBus() {\n return {\n read: newAddressDecoder([\n [0x0000, 0x3fff, 0xffff, (a) => { return this.ram[a]; }],\n [0x4000, 0xbfff, 0xffff, (a) => { return this.rom ? this.rom[a - 0x4000] : 0; }],\n [0xc000, 0xcfff, 0x1f, (a) => { return this.gtia.readReg(a); }],\n [0xd400, 0xd4ff, 0xf, (a) => { return this.antic.readReg(a); }],\n [0xe800, 0xefff, 0xf, (a) => { return this.readPokey(a); }],\n [0xf800, 0xffff, 0x7ff, (a) => { return this.bios[a]; }],\n ]),\n write: newAddressDecoder([\n [0x0000, 0x3fff, 0xffff, (a, v) => { this.ram[a] = v; }],\n [0xc000, 0xcfff, 0x1f, (a, v) => { this.gtia.setReg(a, v); }],\n [0xd400, 0xd4ff, 0xf, (a, v) => { this.antic.setReg(a, v); }],\n [0xe800, 0xefff, 0xf, (a, v) => { this.writePokey(a, v); }],\n ]),\n };\n }\n}\n\n", "\nimport { Platform, getOpcodeMetadata_6502, getToolForFilename_6502, Base6502MachinePlatform, Preset } from \"../common/baseplatform\";\nimport { PLATFORMS } from \"../common/emu\";\nimport { BaseMAME6502Platform } from \"../common/mameplatform\";\nimport { Atari5200, Atari800 } from \"../machine/atari8\";\n\ndeclare var jt; // for 6502\n\nvar Atari8_PRESETS : Preset[] = [\n {id:'hello.dasm', name:'Hello World (ASM)'},\n {id:'hellopm.dasm', name:'Hello Sprites (ASM)'},\n {id:'helloconio.c', name:'Text Mode (C)'},\n {id:'siegegame.c', name:'Siege Game (C)'},\n {id:'hellodlist.c', name:'Display List (C)'},\n];\n\nvar Atari800_PRESETS = Atari8_PRESETS.concat([\n {id:'testmusic.c', name:'POKEY Music (C)'},\n {id:'sieve.bas', name:'Benchmark (FastBasic)', category:'FastBasic'},\n {id:'pmtest.bas', name:'Sprites Test (FastBasic)'},\n {id:'dli.bas', name:'DLI Test (FastBasic)'},\n {id:'joyas.bas', name:'Match-3 Game (FastBasic)'},\n]);\n\nconst Atari800_MemoryMap = { main:[\n {name:'RAM',start:0x0,size:0xc000,type:'ram'},\n {name:'Left Cartridge ROM',start:0xa000,size:0x2000,type:'rom'},\n {name:'GTIA',start:0xd000,size:0x20,type:'io'},\n {name:'POKEY',start:0xd200,size:0x10,type:'io'},\n {name:'PIA',start:0xd300,size:0x04,type:'io'},\n {name:'ANTIC',start:0xd400,size:0x10,type:'io'},\n {name:'Cartridge Control Line',start:0xd600,size:0x100,type:'io'},\n {name:'ROM',start:0xd800,size:0x800,type:'rom'},\n {name:'Character Set',start:0xe000,size:0x400,type:'rom'},\n {name:'ROM',start:0xe400,size:0x1c00,type:'rom'},\n] }\n\nfunction getToolForFilename_Atari8(fn:string) {\n if (fn.endsWith(\".bas\") || fn.endsWith(\".fb\") || fn.endsWith(\".fbi\")) return \"fastbasic\";\n else return getToolForFilename_6502(fn);\n}\n\nclass Atari800Platform extends Base6502MachinePlatform<Atari800> {\n newMachine() { return new Atari800(); }\n getPresets() { return Atari800_PRESETS; }\n getDefaultExtension() { return \".c\"; };\n getToolForFilename = getToolForFilename_Atari8;\n readAddress(a) { return this.machine.readConst(a); }\n getMemoryMap() { return Atari800_MemoryMap; }\n showHelp = atari8_showHelp;\n getROMExtension = atari8_getROMExtension;\n \n async start() {\n let bios = await this.loadKernel();\n await super.start();\n this.machine.loadBIOS(bios);\n }\n biosPath = 'res/altirra/kernel.rom';\n async loadKernel() {\n var biosResponse = await fetch(this.biosPath);\n if (biosResponse.status == 200 || (biosResponse as any as Blob).size) {\n var biosBinary = await biosResponse.arrayBuffer();\n return new Uint8Array(biosBinary);\n } else throw new Error('could not load BIOS file');\n }\n getDebugTree() {\n let tree = super.getDebugTree();\n tree['display_list'] = this.machine.getDebugDisplayList();\n return tree;\n }\n}\n\nclass Atari5200Platform extends Atari800Platform {\n getPresets() { return Atari8_PRESETS; }\n newMachine() { return new Atari5200(); }\n biosPath = 'res/altirra/superkernel.rom';\n}\n\n\n/// MAME support\n\nabstract class Atari8MAMEPlatform extends BaseMAME6502Platform {\n getPresets() { return Atari8_PRESETS; }\n getToolForFilename = getToolForFilename_Atari8;\n getOpcodeMetadata = getOpcodeMetadata_6502;\n getDefaultExtension() { return \".asm\"; };\n showHelp = atari8_showHelp;\n}\n\nclass Atari800MAMEPlatform extends Atari8MAMEPlatform implements Platform {\n getPresets() { return Atari800_PRESETS; }\n loadROM(title, data) {\n if (!this.started) {\n this.startModule(this.mainElement, {\n jsfile:'mame8bitws.js',\n biosfile:'a800xl.zip',\n cfgfile:'a800xl.cfg',\n driver:'a800xl',\n width:336*2,\n height:225*2,\n romfn:'/emulator/cart.rom',\n romdata:new Uint8Array(data),\n romsize:0x2000,\n preInit:function(_self) {\n },\n });\n } else {\n this.loadROMFile(data);\n this.loadRegion(\":cartleft:cart:rom\", data);\n }\n }\n start() {\n }\n getMemoryMap = function() { return Atari800_MemoryMap };\n}\n\nclass Atari5200MAMEPlatform extends Atari8MAMEPlatform implements Platform {\n loadROM(title, data) {\n if (!this.started) {\n this.startModule(this.mainElement, {\n jsfile:'mame8bitws.js',\n biosfile:'a5200/5200.rom',\n cfgfile:'a5200.cfg',\n driver:'a5200',\n width:336*2,\n height:225*2,\n romfn:'/emulator/cart.rom',\n romdata:new Uint8Array(data),\n romsize:0x8000,\n preInit:function(_self) {\n },\n });\n } else {\n this.loadROMFile(data);\n this.loadRegion(\":cartleft:cart:rom\", data);\n }\n }\n start() {\n }\n getMemoryMap = function() { return { main:[\n {name:'RAM',start:0x0,size:0x4000,type:'ram'},\n {name:'Cartridge ROM',start:0x4000,size:0x8000,type:'rom'},\n {name:'GTIA',start:0xc000,size:0x20,type:'io'},\n {name:'ANTIC',start:0xd400,size:0x10,type:'io'},\n {name:'POKEY',start:0xe800,size:0x10,type:'io'},\n {name:'ATARI Character Set',start:0xf800,size:0x400,type:'rom'},\n {name:'ROM',start:0xfc00,size:0x400,type:'rom'},\n ] } };\n}\n\nfunction atari8_getROMExtension(rom: Uint8Array) {\n if (rom == null) return \".bin\";\n if (rom[0] == 0xff && rom[1] == 0xff) return \".xex\";\n else return \".rom\";\n}\n\nfunction atari8_showHelp() {\n return \"https://8bitworkshop.com/docs/platforms/atari8/\";\n}\n\n///\n\nPLATFORMS['atari8-800.xlmame'] = Atari800MAMEPlatform\nPLATFORMS['atari8-800xl.mame'] = Atari800MAMEPlatform // for dithertron\nPLATFORMS['atari8-5200.mame'] = Atari5200MAMEPlatform\nPLATFORMS['atari8-800'] = Atari800Platform\nPLATFORMS['atari8-5200'] = Atari5200Platform\n"],
"mappings": "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",
"names": []
}