8bitworkshop/gen/astrocade-B6S7IURT.js.map

8 lines
46 KiB
Plaintext

{
"version": 3,
"sources": ["../src/machine/astrocade.ts", "../src/platform/astrocade.ts"],
"sourcesContent": ["\nimport { Z80, Z80State } from \"../common/cpu/ZilogZ80\";\nimport { BasicScanlineMachine, AcceptsPaddleInput, Bus } from \"../common/devices\";\nimport { KeyFlags, newAddressDecoder, padBytes, Keys, makeKeycodeMap, newKeyboardHandler } from \"../common/emu\";\nimport { TssChannelAdapter, MasterAudio, AY38910_Audio } from \"../common/audio\";\nimport { hex, rgb2bgr, lzgmini, stringToByteArray } from \"../common/util\";\n\n// http://metopal.com/projects/ballybook/doku.php\n\n// TODO: fix keys, more controllers, vibrato/noise, border color\n// http://atariage.com/forums/topic/251416-programming-the-bally-arcadeastrocade/\n// https://ballyalley.com/faqs/BPA%20Video%20Hardware%20FAQ/Bally_Professional_Arcade_Video_Hardware%20(2001)(Tony%20Miller).pdf\n// https://atariage.com/forums/topic/290858-notes-from-a-2019-interview-with-jamie-fenton/ (http://www.fentonia.com/bio/)\n// https://thehistoryofhowweplay.wordpress.com/2018/04/03/interview-tom-mchugh/\n// https://ballyalley.com/faqs/Programmers%20of%20the%20Astrocade%20Built-In%20Programs.txt\n\nconst ASTROCADE_KEYCODE_MAP = makeKeycodeMap([\n // player 1\n [Keys.UP, 0x10, 0x1],\n [Keys.DOWN, 0x10, 0x2],\n [Keys.LEFT, 0x10, 0x4],\n [Keys.RIGHT, 0x10, 0x8],\n [Keys.A, 0x10, 0x10],\n // player 2\n [Keys.P2_UP, 0x11, 0x1],\n [Keys.P2_DOWN, 0x11, 0x2],\n [Keys.P2_LEFT, 0x11, 0x4],\n [Keys.P2_RIGHT, 0x11, 0x8],\n [Keys.P2_A, 0x11, 0x10],\n // keypad $14\n [Keys.VK_P, 0x14, 0x1],\n [Keys.VK_SLASH, 0x14, 0x2],\n [Keys.VK_X, 0x14, 0x4],\n [Keys.VK_MINUS, 0x14, 0x8],\n [Keys.VK_COMMA, 0x14, 0x10],\n [Keys.VK_EQUALS, 0x14, 0x20],\n // keypad $15\n [Keys.VK_O, 0x15, 0x1],\n [Keys.VK_L, 0x15, 0x2],\n [Keys.VK_9, 0x15, 0x4],\n [Keys.VK_6, 0x15, 0x8],\n [Keys.VK_3, 0x15, 0x10],\n [Keys.VK_PERIOD, 0x15, 0x20],\n // keypad $16\n [Keys.VK_I, 0x16, 0x1],\n [Keys.VK_K, 0x16, 0x2],\n [Keys.VK_8, 0x16, 0x4],\n [Keys.VK_5, 0x16, 0x8],\n [Keys.VK_2, 0x16, 0x10],\n [Keys.VK_0, 0x16, 0x20],\n // keypad $17\n [Keys.VK_U, 0x17, 0x1],\n [Keys.VK_J, 0x17, 0x2],\n [Keys.VK_7, 0x17, 0x4],\n [Keys.VK_4, 0x17, 0x8],\n [Keys.VK_1, 0x17, 0x10],\n [Keys.VK_BACK_SLASH, 0x17, 0x20],\n]);\n\nconst audioOversample = 2;\n\nconst _BallyAstrocade = function(arcade:boolean) {\n\n var cpu : Z80;\n var ram : Uint8Array;\n var membus, iobus : Bus;\n var rom, bios;\n var pixels;\n var psg;\n //var watchdog_counter;\n const swidth = arcade ? 320 : 160;\n const sheight = arcade ? 204 : 102;\n const swbytes = swidth >> 2;\n const samask = arcade ? 0x3fff : 0xfff;\n const INITIAL_WATCHDOG = 256;\n const PIXEL_ON = 0xffeeeeee;\n const PIXEL_OFF = 0xff000000;\n\n // state variables\n var inputs = new Uint8Array(0x20);\n var magicop = 0;\n var xpand = 0;\n var xplower = false;\n var shift2 = 0;\n var horcb = 0;\n var inmod = 0;\n var inlin = 0;\n var infbk = 0;\n var verbl = sheight;\n var palette = new Uint32Array(8);\n var palinds = new Uint8Array(8);\n var refreshlines = 0;\n var dirtylines = new Uint8Array(arcade ? 262 : 131);\n var rotdata = new Uint8Array(4);\n var rotcount = 0;\n var intst = 0;\n var waitstates = 0;\n var patboard = new Uint8Array(0x08);\n var patdest = 0;\n\n function ramwrite(a: number, v: number) {\n // set RAM\n ram[a] = v;\n waitstates++;\n // mark scanline as dirty\n dirtylines[((a & samask) / swbytes) | 0] = 1;\n // this was old behavior where we updated instantly\n // but it had problems if we had mid-screen palette changes\n //ramupdate(a, v);\n }\n\n function ramupdate(a: number, v: number) {\n var ofs = a * 4 + 3; // 4 pixels per byte\n for (var i = 0; i < 4; i++) {\n var lr = ((a % swbytes) >= (horcb & 0x3f)) ? 0 : 4;\n pixels[ofs--] = palette[lr + (v & 3)];\n v >>= 2;\n }\n }\n\n function refreshline(y: number) {\n var ofs = y * swidth / 4;\n for (var i = 0; i < swidth / 4; i++)\n ramupdate(ofs + i, ram[ofs + i]);\n }\n\n function magicwrite(a: number, v: number) {\n // expand\n if (magicop & 0x8) {\n var v2 = 0;\n if (!xplower)\n v >>= 4;\n for (var i = 0; i < 4; i++) {\n var pix = (v & 1) ? ((xpand >> 2) & 3) : (xpand & 3);\n v2 |= pix << (i * 2);\n v >>= 1;\n }\n v = v2;\n xplower = !xplower;\n }\n // rotate\n if (magicop & 0x4) {\n if (rotcount & 4) {\n // drain buffer\n var sh = 2 * (~rotcount & 3);\n v = (((rotdata[3] >> sh) & 3) << 6) |\n (((rotdata[2] >> sh) & 3) << 4) |\n (((rotdata[1] >> sh) & 3) << 2) |\n (((rotdata[0] >> sh) & 3) << 0);\n } else {\n // fill buffer\n rotdata[rotcount & 3] = v;\n }\n rotcount++;\n } else {\n // shift\n var sh = (magicop & 3) << 1;\n var v2 = (v >> sh) | shift2;\n shift2 = (v << (8 - sh)) & 0xff;\n v = v2;\n }\n // flop\n if (magicop & 0x40) {\n v =\n ((v & 0x03) << 6) |\n ((v & 0x0c) << 2) |\n ((v & 0x30) >> 2) |\n ((v & 0xc0) >> 6);\n }\n // or/xor\n if (magicop & 0x30) {\n var oldv = ram[a];\n // collision detect\n var icpt = 0;\n if ((oldv & 0xc0) && (v & 0xc0)) icpt |= 0x1;\n if ((oldv & 0x30) && (v & 0x30)) icpt |= 0x2;\n if ((oldv & 0x0c) && (v & 0x0c)) icpt |= 0x4;\n if ((oldv & 0x03) && (v & 0x03)) icpt |= 0x8;\n // apply op\n if (magicop & 0x10)\n v |= oldv;\n if (magicop & 0x20)\n v ^= oldv; // TODO: what if both?\n // upper 4 bits persist, lower are just since last write\n intst = (intst & 0xf0) | icpt | (icpt << 4);\n }\n // commit write to ram/screen\n ramwrite(a, v);\n }\n\n function setpalette(a: number, v: number) {\n palinds[a & 7] = v & 0xff;\n palette[a & 7] = ASTROCADE_PALETTE[v & 0xff];\n refreshall();\n }\n\n function setbordercolor() {\n var col = horcb >> 6;\n // TODO\n }\n\n function refreshall() {\n refreshlines = sheight;\n }\n\n // bally astrocade pattern board\n // https://github.com/mamedev/mame/blob/7ff10685c56a6e123336c684e5e96fdb9e8b3674/src/mame/midway/astrocde_v.cpp#L726\n function xfer_patboard() {\n let m_pattern_source = patboard[0] | (patboard[1] << 8);\n let m_pattern_mode = patboard[2] & 0x3f;\n let m_pattern_skip = patboard[3];\n let m_pattern_dest = (patdest & 0xff) | (patboard[4] << 8);\n let m_pattern_width = patboard[5];\n let m_pattern_height = patboard[6] + 1;\n\n let curwidth: number;\n let u13ff: number = 0;\n let cycles: number = 0;\n\n u13ff = 0;\n\n if ((m_pattern_mode & 0x02) === 0) {\n u13ff = 1;\n }\n\n function incrementSource(): void {\n if (u13ff && (m_pattern_mode & 0x04) !== 0 && (curwidth !== 0 || (m_pattern_mode & 0x08) === 0)) {\n m_pattern_source++;\n }\n\n if ((m_pattern_mode & 0x02) !== 0) {\n u13ff ^= 1;\n }\n }\n\n function incrementDest(): void {\n if (curwidth !== 0) {\n if ((m_pattern_mode & 0x20) !== 0) {\n m_pattern_dest++;\n } else {\n m_pattern_dest--;\n }\n }\n }\n\n // Loop over height\n while (m_pattern_height >= 0) {\n let carry: number;\n\n curwidth = m_pattern_width;\n\n // Loop over width\n while (curwidth >= 0) {\n let busaddr: number;\n let busdata: number;\n\n // Read Phase\n busaddr = (m_pattern_mode & 0x01) === 0 ? m_pattern_source : m_pattern_dest;\n\n if (curwidth === 0 && (m_pattern_mode & 0x08) !== 0) {\n busdata = 0;\n } else {\n busdata = membus.read(m_pattern_source);\n }\n\n if ((m_pattern_mode & 0x01) === 0) {\n incrementSource();\n } else {\n incrementDest();\n }\n\n // Write Phase\n busaddr = (m_pattern_mode & 0x01) !== 0 ? m_pattern_source : m_pattern_dest;\n ramwrite(busaddr, busdata);\n\n if ((m_pattern_mode & 0x01) === 0) {\n incrementDest();\n } else {\n incrementSource();\n }\n\n cycles += 4;\n curwidth--;\n }\n\n // At the end of each row, adjust m_pattern_dest\n carry = ((m_pattern_dest & 0xff) + m_pattern_skip) & 0x100;\n m_pattern_dest = (m_pattern_dest & 0xff00) | ((m_pattern_dest + m_pattern_skip) & 0xff);\n\n if ((m_pattern_mode & 0x10) === 0) {\n m_pattern_dest += carry;\n } else {\n m_pattern_dest -= carry ^ 0x100;\n }\n\n m_pattern_height--;\n }\n\n // Adjust m_maincpu.icount\n // m_maincpu.adjust_icount(-cycles);\n // Replace the above line with the actual adjustment of icount.\n }\n \n this.drawScanline = (sl:number) => {\n // interrupt\n if (sl == inlin && (inmod & 0x8)) {\n cpu.retryInterrupts = !(inmod & 0x4);\n this.probe && this.probe.logInterrupt(infbk);\n cpu.interrupt(infbk);\n }\n // refresh this line in frame buffer?\n if (sl < sheight && refreshlines > 0) {\n dirtylines[sl] = 0;\n refreshline(sl);\n refreshlines--;\n }\n else if (dirtylines[sl]) {\n dirtylines[sl] = 0;\n refreshline(sl);\n }\n }\n \n this.init = (machine:BallyAstrocade, c:Z80, r:Uint8Array, inp:Uint8Array, psgg) => {\n cpu = c;\n ram = r;\n inputs = inp;\n psg = psgg;\n if (!arcade) {\n //bios = padBytes(ASTROCADE_MINIMAL_BIOS, 0x2000);\n bios = padBytes(new lzgmini().decode(stringToByteArray(atob(ASTROLIBRE_BIOS_LZG))), 0x2000);\n // game console\n membus = {\n read: newAddressDecoder([\n [0x0000, 0x1fff, 0x1fff, function(a) { return bios[a]; }],\n [0x2000, 0x3fff, 0x1fff, function(a) { return rom ? rom[a] : 0; }],\n [0x4000, 0x4fff, 0xfff, function(a) { waitstates++; return ram[a]; }],\n ]),\n write: newAddressDecoder([\n [0x4000, 0x4fff, 0xfff, ramwrite],\n [0x0000, 0x3fff, 0xfff, magicwrite],\n ]),\n }\n } else {\n // arcade game (TODO: wait states 1/4 of the time)\n membus = {\n read: newAddressDecoder([\n [0x4000, 0x7fff, 0x3fff, function(a) { return ram[a]; }],\t// screen RAM\n [0xd000, 0xdfff, 0x0fff, function(a) { return ram[a + 0x4000]; }], // static RAM\n [0x0000, 0x3fff, 0x3fff, function(a) { return rom ? rom[a] : 0; }], // ROM\n [0x8000, 0xbfff, 0x3fff, function(a) { return rom ? rom[a + 0x4000] : 0; }], // ROM\n ]),\n write: newAddressDecoder([\n [0x4000, 0x7fff, 0x3fff, ramwrite],\n [0x0000, 0x3fff, 0x3fff, magicwrite],\n [0xd000, 0xdfff, 0x0fff, function(a, v) { ramwrite(a + 0x4000, v); }], // static RAM\n ]),\n }\n }\n iobus = {\n read: function(addr) {\n addr &= 0x1f;\n var rtn;\n switch (addr) {\n case 8:\n rtn = intst;\n intst = 0;\n break;\n default:\n rtn = inputs[addr];\n break;\n // $10 = watchdog\n }\n return rtn;\n },\n write: function(addr, val) {\n if (addr == 0xa55b) {\n // TODO: protected_ram_enable_w\n return;\n }\n addr &= 0xff;\n // pattern board\n if (addr > 0x78 && addr < 0x80) {\n patboard[addr & 7] = val;\n if (addr == 0x72) { patdest = 0; }\n if (addr == 0x74) { patdest = (patdest + patboard[3]) & 0xff; }\n if (addr == 0x7e) { xfer_patboard(); }\n return;\n }\n addr &= 0x1f;\n val &= 0xff;\n switch (addr) {\n case 0:\n case 1:\n case 2:\n case 3:\n case 4:\n case 5:\n case 6:\n case 7:\n setpalette(addr, val);\n break;\n case 9: // HORCB (horizontal boundary byte)\n horcb = val;\n setbordercolor();\n refreshall();\n break;\n case 0xa: // VERBL (vertical blank)\n verbl = arcade ? val : val >> 1;\n refreshall();\n break;\n case 0xb: // OTIR (set palette)\n var c = cpu.saveState();\n //console.log(c.BC>>8, c.HL);\n setpalette((c.BC >> 8) - 1, membus.read(c.HL));\n break;\n case 0xc: // magic register\n magicop = val;\n shift2 = 0;\n rotcount = 0;\n xplower = false;\n break;\n case 0xd: // INFBK (interrupt feedback)\n infbk = val;\n break;\n case 0xe: // INMOD (interrupt enable)\n inmod = val;\n break;\n case 0xf: // INLIN (interrupt line)\n inlin = arcade ? val : val >> 1;\n break;\n case 0x10:\n case 0x11:\n case 0x12:\n case 0x13:\n case 0x14:\n case 0x15:\n case 0x16:\n case 0x17:\n psg.setACRegister(addr, val);\n break;\n case 0x18:\n var c = cpu.saveState();\n psg.setACRegister((c.BC >> 8) - 1, membus.read(c.HL));\n break;\n case 0x19: // XPAND\n xpand = val;\t\n break;\n case 0x1a:\n case 0x1b:\n case 0x1c:\n case 0x1d:\n case 0x1e:\n //psg2.setACRegister(addr - 0x1a, val);\n break;\n default:\n //console.log('IO write', hex(addr, 4), hex(val, 2));\n break;\n }\n }\n }\n machine.connectCPUMemoryBus(membus);\n machine.connectCPUIOBus(iobus);\n this.membus = membus;\n this.iobus = iobus;\n // default palette\n for (var i = 0; i < 8; i++) {\n setpalette(i,i);\n }\n };\n\n this.resetWaitStates = function(sl) {\n var n = sl < verbl ? waitstates : 0; // only wait if video active\n waitstates = 0;\n return n;\n }\n\n this.loadState = (state) => {\n cpu.loadState(state.c);\n ram.set(state.ram);\n palette.set(state.palette);\n palinds.set(state.palinds);\n magicop = state.magicop;\n xpand = state.xpand;\n xplower = state.xplower;\n shift2 = state.shift2;\n horcb = state.horcb;\n inmod = state.inmod;\n inlin = state.inlin;\n infbk = state.infbk;\n verbl = state.verbl;\n rotcount = state.rotcount;\n rotdata.set(state.rotdata);\n intst = state.intst;\n inputs.set(state.inputs);\n patboard.set(state.patboard);\n patdest = state.patdest;\n refreshall();\n }\n \n this.saveState = () => {\n return {\n c: cpu.saveState(),\n ram: ram.slice(0),\n inputs: inputs.slice(0),\n palette: palette.slice(0),\n palinds: palinds.slice(0),\n magicop: magicop,\n xpand: xpand,\n xplower: xplower,\n shift2: shift2,\n horcb: horcb,\n inmod: inmod,\n inlin: inlin,\n infbk: infbk,\n verbl: verbl,\n rotcount: rotcount,\n rotdata: rotdata.slice(0),\n intst: intst,\n patboard: patboard.slice(0),\n patdest: patdest,\n };\n }\n this.reset = () => {\n // TODO?\n magicop = xpand = inmod = inlin = infbk = shift2 = horcb = 0;\n verbl = sheight;\n xplower = false;\n //watchdog_counter = INITIAL_WATCHDOG;\n }\n \n this.toLongString = (st) => {\n var s = \"\";\n //s += \" Scan Y: \" + st.sl;\n s += \"\\n INLIN: \" + st.inlin;\n s += \"\\n VERBL: \" + st.verbl;\n s += \"\\nMAGICOP: $\" + hex(st.magicop);\n s += \"\\n XPAND: $\" + hex(st.xpand);\n s += \"\\nXPLOWER: \" + st.xplower;\n s += \"\\n SHIFT2: $\" + hex(st.shift2);\n s += \"\\n HORCB: $\" + hex(st.horcb);\n s += \"\\n INMOD: $\" + hex(st.inmod);\n s += \"\\n INFBK: $\" + hex(st.infbk);\n s += \"\\n INTST: $\" + hex(st.intst); // intercept status\n s += \"\\nPalette: \";\n for (var i = 0; i < 8; i++)\n s += hex(palinds[i]);\n s += \"\\n\";\n return s;\n }\n \n this.connectVideo = function(pix) {\n pixels = pix;\n }\n this.loadROM = function(data) {\n rom = data;\n }\n this.loadBIOS = function(data) {\n bios = data;\n }\n this.getVisiblePixelWords = function() {\n return verbl * swidth;\n }\n}\n\nexport class BallyAstrocade extends BasicScanlineMachine implements AcceptsPaddleInput {\n \n cpuFrequency = 1789000;\n numTotalScanlines = 262;\n numVisibleScanlines : number;\n cpuCyclesPerLine : number;\n defaultROMSize : number;\n canvasWidth : number;\n sampleRate = 60 * 262 * audioOversample;\n ram : Uint8Array;\n cpu : Z80;\n m; // _BallyAstrocade\n arcade : boolean;\n\n psg: AstrocadeAudio;\n audioadapter;\n backbuffer : Uint32Array;\n frontbuffer : Uint32Array;\n\n constructor(arcade:boolean) {\n super();\n this.arcade = arcade;\n this.cpu = new Z80();\n this.psg = new AstrocadeAudio(new MasterAudio());\n this.audioadapter = new TssChannelAdapter(this.psg.psg, audioOversample, this.sampleRate);\n this.handler = newKeyboardHandler(this.inputs, ASTROCADE_KEYCODE_MAP);\n this.defaultROMSize = arcade ? 0xb000 : 0x2000;\n this.ram = new Uint8Array(arcade ? 0x5000 : 0x1000);\n this.numVisibleScanlines = arcade ? 204 : 102;\n this.canvasWidth = arcade ? 320 : 160;\n this.cpuCyclesPerLine = (this.cpuFrequency / (60 * this.numVisibleScanlines * 1.286)) | 0;\n //this.cpuCyclesPerHBlank = Math.floor(this.cpuCyclesPerLine * 0.33);\n //this.cpuCyclesPerVisible = this.cpuCyclesPerLine - this.cpuCyclesPerHBlank;\n this.m = new _BallyAstrocade(arcade);\n this.m.init(this, this.cpu, this.ram, this.inputs, this.psg);\n if (arcade) {\n this.inputs[0x10] = 0xff; // switches (active low)\n this.inputs[0x11] = 0xff; // switches (active low)\n this.inputs[0x12] = 0x00;\n this.inputs[0x13] = 0x08; // dip switches\n }\n }\n \n read(a:number) : number {\n return this.m.membus.read(a);\n }\n write(a:number, v:number) : void {\n this.m.membus.write(a,v);\n }\n \n connectVideo(pixels:Uint32Array) : void {\n super.connectVideo(pixels);\n this.frontbuffer = pixels;\n this.backbuffer = new Uint32Array(pixels.length);\n this.m.connectVideo(this.backbuffer);\n }\n preFrame() {\n this.m.resetWaitStates(0);\n }\n postFrame() {\n // copy back buffer to front buffer, omitting bottom non-visible pixels\n var nbytes = this.m.getVisiblePixelWords();\n this.frontbuffer.set(this.backbuffer.slice(0, nbytes), 0);\n this.frontbuffer.fill(0, nbytes);\n }\n\n setPaddleInput(controller:number, value:number) : void {\n switch (controller) {\n case 0: this.inputs[0x1c] = value & 0xff; break;\n case 1: this.inputs[0x1d] = value & 0xff; break;\n }\n }\n\n startScanline() {\n this.audio && this.audioadapter.generate(this.audio);\n }\n \n drawScanline() {\n var sl = this.scanline;\n this.m.drawScanline(sl);\n /*\n if (watchdog_counter-- <= 0) {\n console.log(\"WATCHDOG FIRED\"); // TODO: alert on video\n this.reset();\n }\n */\n }\n\n advanceCPU() {\n var clk = super.advanceCPU();\n // TODO: disable 33% of the time (hblank)\n var xtra = this.m.resetWaitStates(this.scanline);\n if (xtra) {\n clk += xtra;\n this.probe.logClocks(xtra);\n }\n return clk;\n }\n\n loadROM(data) {\n super.loadROM(data);\n this.m.loadROM(this.rom);\n this.reset();\n }\n loadBIOS(data) {\n this.m.loadBIOS(padBytes(data, 0x2000));\n this.reset();\n }\n reset() {\n super.reset();\n this.m.reset();\n }\n loadState(state) {\n this.m.loadState(state);\n }\n saveState() {\n return this.m.saveState();\n }\n getDebugCategories() {\n return ['CPU','Stack','Astro'];\n }\n getDebugInfo(category, state) {\n switch (category) {\n case 'Astro': return this.m.toLongString(state);\n }\n }\n getRasterCanvasPosition() {\n return { x: this.getRasterX(), y: this.getRasterY() };\n }\n getVideoParams() {\n if (this.arcade) {\n return { width: 320, height: 204, rotate: 180 };\n } else {\n return { width: 160, height: 102 };\n }\n }\n}\n\n/////\n\n// TODO: https://github.com/mamedev/mame/blob/master/src/devices/sound/astrocde.cpp\nclass AstrocadeAudio extends AY38910_Audio {\n setACRegister(addr: number, val: number) {\n addr &= 0x7;\n val &= 0xff;\n switch (addr) {\n case 0:\n this.psg.setClock(1789000 * 16 / (val + 1));\n this.psg.writeRegisterAY(7, 0x7 ^ 0xff); // disable noise\n break;\n case 1:\n case 2:\n case 3:\n var i = (addr - 1) * 2;\n var j = val * 2 + 1;\n this.psg.writeRegisterAY(i, j & 0xff); // freq lo\n this.psg.writeRegisterAY(i + 1, (j >> 8) & 0xff); // freq hi\n break;\n case 5:\n this.psg.writeRegisterAY(10, val & 0xf); // tone c vol\n break;\n case 6:\n this.psg.writeRegisterAY(8, val & 0xf);\t// tone a vol\n this.psg.writeRegisterAY(9, (val >> 4) & 0xf); // tone b vol\n break;\n }\n }\n}\n\n/////\n\n//http://glankonian.com/~lance/astrocade_palette.html\nvar ASTROCADE_PALETTE = [0x000000, 0x242424, 0x484848, 0x6D6D6D, 0x919191, 0xB6B6B6, 0xDADADA, 0xFFFFFF, 0x2500BB, 0x4900E0, 0x6E11FF, 0x9235FF, 0xB75AFF, 0xDB7EFF, 0xFFA3FF, 0xFFC7FF, 0x4900B0, 0x6D00D5, 0x9201F9, 0xB625FF, 0xDA4AFF, 0xFF6EFF, 0xFF92FF, 0xFFB7FF, 0x6A009F, 0x8E00C3, 0xB300E7, 0xD718FF, 0xFB3CFF, 0xFF61FF, 0xFF85FF, 0xFFA9FF, 0x870087, 0xAB00AB, 0xD000D0, 0xF40EF4, 0xFF32FF, 0xFF56FF, 0xFF7BFF, 0xFF9FFF, 0x9F006A, 0xC3008E, 0xE700B3, 0xFF07D7, 0xFF2CFB, 0xFF50FF, 0xFF74FF, 0xFF99FF, 0xB00049, 0xD5006D, 0xF90092, 0xFF05B6, 0xFF29DA, 0xFF4DFF, 0xFF72FF, 0xFF96FF, 0xBB0025, 0xE00049, 0xFF006E, 0xFF0692, 0xFF2AB7, 0xFF4FDB, 0xFF73FF, 0xFF98FF, 0xBF0000, 0xE30024, 0xFF0048, 0xFF0B6D, 0xFF3091, 0xFF54B6, 0xFF79DA, 0xFF9DFF, 0xBB0000, 0xE00000, 0xFF0023, 0xFF1447, 0xFF396C, 0xFF5D90, 0xFF82B5, 0xFFA6D9, 0xB00000, 0xD50000, 0xF90000, 0xFF2124, 0xFF4548, 0xFF6A6C, 0xFF8E91, 0xFFB3B5, 0x9F0000, 0xC30000, 0xE70C00, 0xFF3003, 0xFF5527, 0xFF794B, 0xFF9E70, 0xFFC294, 0x870000, 0xAB0000, 0xD01E00, 0xF44200, 0xFF670A, 0xFF8B2E, 0xFFAF53, 0xFFD477, 0x6A0000, 0x8E0D00, 0xB33100, 0xD75600, 0xFB7A00, 0xFF9E17, 0xFFC33B, 0xFFE75F, 0x490000, 0x6D2100, 0x924500, 0xB66A00, 0xDA8E00, 0xFFB305, 0xFFD729, 0xFFFC4E, 0x251100, 0x493500, 0x6E5A00, 0x927E00, 0xB7A300, 0xDBC700, 0xFFEB1E, 0xFFFF43, 0x002500, 0x244900, 0x486D00, 0x6D9200, 0x91B600, 0xB6DB00, 0xDAFF1B, 0xFFFF3F, 0x003700, 0x005B00, 0x238000, 0x47A400, 0x6CC900, 0x90ED00, 0xB5FF1E, 0xD9FF43, 0x004700, 0x006C00, 0x009000, 0x24B400, 0x48D900, 0x6CFD05, 0x91FF29, 0xB5FF4E, 0x005500, 0x007900, 0x009D00, 0x03C200, 0x27E600, 0x4BFF17, 0x70FF3B, 0x94FF5F, 0x005F00, 0x008300, 0x00A800, 0x00CC00, 0x0AF00A, 0x2EFF2E, 0x53FF53, 0x77FF77, 0x006500, 0x008A00, 0x00AE00, 0x00D203, 0x00F727, 0x17FF4B, 0x3BFF70, 0x5FFF94, 0x006800, 0x008C00, 0x00B100, 0x00D524, 0x00F948, 0x05FF6C, 0x29FF91, 0x4EFFB5, 0x006600, 0x008B00, 0x00AF23, 0x00D447, 0x00F86C, 0x00FF90, 0x1EFFB5, 0x43FFD9, 0x006100, 0x008524, 0x00AA48, 0x00CE6D, 0x00F391, 0x00FFB6, 0x1BFFDA, 0x3FFFFE, 0x005825, 0x007C49, 0x00A16E, 0x00C592, 0x00EAB7, 0x00FFDB, 0x1EFFFF, 0x43FFFF, 0x004B49, 0x00706D, 0x009492, 0x00B9B6, 0x00DDDA, 0x05FFFF, 0x29FFFF, 0x4EFFFF, 0x003C6A, 0x00608E, 0x0085B3, 0x00A9D7, 0x00CEFB, 0x17F2FF, 0x3BFFFF, 0x5FFFFF, 0x002A87, 0x004FAB, 0x0073D0, 0x0097F4, 0x0ABCFF, 0x2EE0FF, 0x53FFFF, 0x77FFFF, 0x00179F, 0x003BC3, 0x0060E7, 0x0384FF, 0x27A8FF, 0x4BCDFF, 0x70F1FF, 0x94FFFF, 0x0002B0, 0x0027D5, 0x004BF9, 0x2470FF, 0x4894FF, 0x6CB9FF, 0x91DDFF, 0xB5FFFF, 0x0000BB, 0x0013E0, 0x2337FF, 0x475BFF, 0x6C80FF, 0x90A4FF, 0xB5C9FF, 0xD9EDFF];\n// swap palette RGB to BGR\nfor (var i = 0; i < 256; i++) {\n var x = ASTROCADE_PALETTE[i];\n ASTROCADE_PALETTE[i] = rgb2bgr(x) | 0xff000000;\n}\n\n/*\n0000 F3 [ 4] 196 \tDI\t; disable interrupts\n0001 21 00 20 [10] 197 \tLD\tHL,#0x2000\n0004 7E [ 7] 198 \tLD\tA,(HL) ; A <- mem[0x2000]\n0005 FE 55 [ 7] 199 \tCP\t#0x55 ; found sentinel byte? ($55)\n0007 CA 0D 00 [10] 200 \tJP\tZ,FoundSentinel ; yes, load program\n000A C3 00 20 [10] 201 \tJP\t_main ; jump to test program\n000D 202 \tFoundSentinel:\n000D 31 CE 4F [10] 203 \tLD\tSP,#0x4fce ; position stack below BIOS vars\n0010 CD 84 02 [17] 204 \tCALL\t_bios_init ; misc. bios init routines\n0013 21 05 20 [10] 205 \tLD\tHL,#0x2005 ; cartridge start vector\n0016 7E [ 7] 206 \tLD\tA,(HL)\n0017 23 [ 6] 207 \tINC\tHL\n0018 66 [ 7] 208 \tLD\tH,(HL)\n0019 6F [ 4] 209 \tLD\tL,A\n001A E9 [ 4] 210 \tJP\t(HL) ; jump to cart start vector\n*/\nvar ASTROCADE_MINIMAL_BIOS = [\n 0xf3, 0x21, 0x00, 0x20, 0x7e, 0xfe, 0x55, 0xca, 0x0d, 0x00, 0xc3, 0x00, 0x20,\n 0x31, 0xce, 0x4f,\n 0x21, 0x05, 0x20, 0x7e, 0x23, 0x66, 0x6f,\n 0xe9,\n];\n\nvar ASTROLIBRE_BIOS_LZG = `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`;\n\n", "\nimport { BallyAstrocade } from \"../machine/astrocade\";\nimport { BaseZ80MachinePlatform } from \"../common/baseplatform\";\nimport { Platform } from \"../common/baseplatform\";\nimport { PLATFORMS } from \"../common/emu\";\n\n// http://metopal.com/projects/ballybook/doku.php\n\nconst ASTROCADE_PRESETS = [\n { id: '01-helloworlds.asm', name: 'Hello World (ASM)' },\n { id: '02-telephone.asm', name: 'Telephone (ASM)' },\n { id: '03-horcbpal.asm', name: 'Paddle Demo (ASM)' },\n { id: 'hello.c', name: 'Hello Graphics' },\n { id: 'lines.c', name: 'Lines' },\n { id: 'sprites.c', name: 'Sprites' },\n { id: 'vsync.c', name: 'Sprites w/ VSYNC' },\n { id: 'fastsprites.c', name: 'Fast Sprites' },\n { id: 'music.c', name: 'Music' },\n { id: 'rotate.c', name: 'Rotate Op' },\n { id: 'rainbow.c', name: 'Rainbow' },\n { id: 'cosmic.c', name: 'Cosmic Impalas Game' },\n { id: 'racing.c', name: 'Pseudo 3-D Racing Game' },\n];\n\nconst ASTROCADE_BIOS_PRESETS = [\n { id: 'bios.c', name: 'BIOS' },\n];\n\nconst ASTROCADE_ARCADE_PRESETS = [\n { id: 'hello.c', name: 'Hello Graphics' },\n];\n\nclass BallyAstrocadePlatform extends BaseZ80MachinePlatform<BallyAstrocade> implements Platform {\n\n newMachine() { return new BallyAstrocade(false); }\n getPresets() { return ASTROCADE_PRESETS; }\n getDefaultExtension() { return \".c\"; };\n readAddress(a) { return this.machine.read(a); }\n getMemoryMap = function() { return { main:[\n {name:'BIOS',start:0x0,size:0x2000,type:'rom'},\n //{name:'Cart ROM',start:0x2000,size:0x2000,type:'rom'},\n //{name:'Magic RAM',start:0x0,size:0x4000,type:'ram'},\n {name:'Screen RAM',start:0x4000,size:0x1000,type:'ram'},\n {name:'BIOS Variables',start:0x4fce,size:0x5000-0x4fce,type:'ram'},\n ] } };\n showHelp() { return \"https://8bitworkshop.com/docs/platforms/astrocade/\"; }\n}\n\nclass BallyAstrocadeBIOSPlatform extends BallyAstrocadePlatform implements Platform {\n\n getPresets() { return ASTROCADE_BIOS_PRESETS; }\n loadROM(title,rom) { this.machine.loadBIOS(rom); }\n\n}\n\nclass BallyArcadePlatform extends BallyAstrocadePlatform implements Platform {\n\n newMachine() { return new BallyAstrocade(true); }\n getPresets() { return ASTROCADE_ARCADE_PRESETS; }\n\n getMemoryMap = function() { return { main:[\n {name:'ROM',start:0x0,size:0x4000,type:'rom'},\n {name:'Magic RAM',start:0x0,size:0x4000,type:'ram'},\n {name:'Screen RAM',start:0x4000,size:0x4000,type:'ram'},\n {name:'ROM',start:0x8000,size:0x4000,type:'rom'},\n ] } };\n}\n\nPLATFORMS['astrocade'] = BallyAstrocadePlatform;\nPLATFORMS['astrocade-bios'] = BallyAstrocadeBIOSPlatform;\nPLATFORMS['astrocade-arcade'] = BallyArcadePlatform;\n\n"],
"mappings": "0NAgBA,GAAM,IAAwB,GAAe,CAE3C,CAAC,EAAK,GAAI,GAAM,GAChB,CAAC,EAAK,KAAM,GAAM,GAClB,CAAC,EAAK,KAAM,GAAM,GAClB,CAAC,EAAK,MAAO,GAAM,GACnB,CAAC,EAAK,EAAG,GAAM,IAEf,CAAC,EAAK,MAAO,GAAM,GACnB,CAAC,EAAK,QAAS,GAAM,GACrB,CAAC,EAAK,QAAS,GAAM,GACrB,CAAC,EAAK,SAAU,GAAM,GACtB,CAAC,EAAK,KAAM,GAAM,IAElB,CAAC,EAAK,KAAM,GAAM,GAClB,CAAC,EAAK,SAAU,GAAM,GACtB,CAAC,EAAK,KAAM,GAAM,GAClB,CAAC,EAAK,SAAU,GAAM,GACtB,CAAC,EAAK,SAAU,GAAM,IACtB,CAAC,EAAK,UAAW,GAAM,IAEvB,CAAC,EAAK,KAAM,GAAM,GAClB,CAAC,EAAK,KAAM,GAAM,GAClB,CAAC,EAAK,KAAM,GAAM,GAClB,CAAC,EAAK,KAAM,GAAM,GAClB,CAAC,EAAK,KAAM,GAAM,IAClB,CAAC,EAAK,UAAW,GAAM,IAEvB,CAAC,EAAK,KAAM,GAAM,GAClB,CAAC,EAAK,KAAM,GAAM,GAClB,CAAC,EAAK,KAAM,GAAM,GAClB,CAAC,EAAK,KAAM,GAAM,GAClB,CAAC,EAAK,KAAM,GAAM,IAClB,CAAC,EAAK,KAAM,GAAM,IAElB,CAAC,EAAK,KAAM,GAAM,GAClB,CAAC,EAAK,KAAM,GAAM,GAClB,CAAC,EAAK,KAAM,GAAM,GAClB,CAAC,EAAK,KAAM,GAAM,GAClB,CAAC,EAAK,KAAM,GAAM,IAClB,CAAC,EAAK,cAAe,GAAM,MAGvB,GAAkB,EAElB,GAAkB,SAAS,EAAgB,CAE/C,GAAI,GACA,EACA,EAAQ,EACR,EAAK,EACL,GACA,EAEJ,GAAM,GAAS,EAAS,IAAM,IACxB,EAAU,EAAS,IAAM,IACzB,GAAU,GAAU,EACpB,GAAS,EAAS,MAAS,KAC3B,GAAmB,IACnB,GAAW,WACX,GAAY,WAGlB,GAAI,GAAS,GAAI,YAAW,IACxB,EAAU,EACV,EAAQ,EACR,EAAU,GACV,EAAS,EACT,EAAQ,EACR,EAAQ,EACR,EAAQ,EACR,EAAQ,EACR,EAAQ,EACR,EAAU,GAAI,aAAY,GAC1B,EAAU,GAAI,YAAW,GACzB,EAAe,EACf,EAAa,GAAI,YAAW,EAAS,IAAM,KAC3C,EAAU,GAAI,YAAW,GACzB,EAAW,EACX,EAAQ,EACR,EAAa,EACb,EAAW,GAAI,YAAW,GAC1B,EAAU,EAEd,WAAkB,EAAW,EAAW,CAEtC,EAAI,GAAK,EACT,IAEA,EAAa,GAAI,IAAU,GAAW,GAAK,EAM7C,YAAmB,EAAW,EAAW,CAEvC,OADI,GAAM,EAAI,EAAI,EACT,EAAI,EAAG,EAAI,EAAG,IAAK,CAC1B,GAAI,GAAO,EAAI,IAAa,GAAQ,IAAS,EAAI,EACjD,GAAO,KAAS,EAAQ,EAAM,GAAI,IAClC,IAAM,GAIV,YAAqB,EAAW,CAE9B,OADI,GAAM,EAAI,EAAS,EACd,EAAI,EAAG,EAAI,EAAS,EAAG,IAC9B,GAAU,EAAM,EAAG,EAAI,EAAM,IAGjC,YAAoB,EAAW,EAAW,CAExC,GAAI,EAAU,EAAK,CACjB,GAAI,GAAK,EACT,AAAK,GACH,KAAM,GACR,OAAS,GAAI,EAAG,EAAI,EAAG,IAAK,CAC1B,GAAI,GAAO,EAAI,EAAO,GAAS,EAAK,EAAM,EAAQ,EAClD,GAAM,GAAQ,EAAI,EAClB,IAAM,EAER,EAAI,EACJ,EAAU,CAAC,EAGb,GAAI,EAAU,EAAK,CACjB,GAAI,EAAW,EAAG,CAEhB,GAAI,GAAK,EAAK,EAAC,EAAW,GAC1B,EAAO,GAAQ,IAAM,EAAM,IAAM,EAC5B,GAAQ,IAAM,EAAM,IAAM,EAC1B,GAAQ,IAAM,EAAM,IAAM,EAC1B,GAAQ,IAAM,EAAM,IAAM,MAG/B,GAAQ,EAAW,GAAK,EAE1B,QACK,CAEL,GAAI,GAAM,GAAU,IAAM,EACtB,EAAM,GAAK,EAAM,EACrB,EAAU,GAAM,EAAI,EAAO,IAC3B,EAAI,EAWN,GARI,EAAU,IACZ,GACI,GAAI,IAAS,EACb,GAAI,KAAS,EACb,GAAI,KAAS,EACb,GAAI,MAAS,GAGf,EAAU,GAAM,CAClB,GAAI,GAAO,EAAI,GAEX,EAAO,EACX,AAAK,EAAO,KAAU,EAAI,KAAO,IAAQ,GACpC,EAAO,IAAU,EAAI,IAAO,IAAQ,GACpC,EAAO,IAAU,EAAI,IAAO,IAAQ,GACpC,EAAO,GAAU,EAAI,GAAO,IAAQ,GAErC,EAAU,IACZ,IAAK,GACH,EAAU,IACZ,IAAK,GAEP,EAAS,EAAQ,IAAQ,EAAQ,GAAQ,EAG3C,EAAS,EAAG,GAGd,WAAoB,EAAW,EAAW,CACxC,EAAQ,EAAI,GAAK,EAAI,IACrB,EAAQ,EAAI,GAAK,EAAkB,EAAI,KACvC,IAGF,aAA0B,CACxB,GAAI,GAAM,GAAS,EAIrB,YAAsB,CACpB,EAAe,EAKjB,aAAyB,CACvB,GAAI,GAAmB,EAAS,GAAM,EAAS,IAAM,EACjD,EAAiB,EAAS,GAAK,GAC/B,EAAiB,EAAS,GAC1B,EAAkB,EAAU,IAAS,EAAS,IAAM,EACpD,EAAkB,EAAS,GAC3B,EAAmB,EAAS,GAAK,EAEjC,EACA,EAAgB,EAChB,EAAiB,EAErB,EAAQ,EAEH,GAAiB,IAAU,GAC9B,GAAQ,GAGV,aAAiC,CAC/B,AAAI,GAAU,GAAiB,IAAU,GAAM,KAAa,GAAM,GAAiB,IAAU,IAC3F,IAGG,GAAiB,IAAU,GAC9B,IAAS,GAIb,aAA+B,CAC7B,AAAI,IAAa,GACf,CAAK,GAAiB,KAAU,EAC9B,IAEA,KAMN,KAAO,GAAoB,GAAG,CAC5B,GAAI,GAKJ,IAHA,EAAW,EAGJ,GAAY,GAAG,CACpB,GAAI,GACA,EAGJ,EAAW,GAAiB,IAAU,EAAI,EAAmB,EAE7D,AAAI,IAAa,GAAM,GAAiB,IAAU,EAChD,EAAU,EAEV,EAAU,EAAO,KAAK,GAGxB,AAAK,GAAiB,IAAU,EAC9B,KAEA,KAIF,EAAW,GAAiB,IAAU,EAAI,EAAmB,EAC7D,EAAS,EAAS,GAElB,AAAK,GAAiB,IAAU,EAC9B,KAEA,KAGF,GAAU,EACV,IAIF,EAAU,GAAiB,KAAQ,EAAkB,IACrD,EAAkB,EAAiB,MAAY,EAAiB,EAAkB,IAElF,AAAK,GAAiB,KAAU,EAC9B,GAAkB,EAElB,GAAkB,EAAQ,IAG5B,KAQJ,KAAK,aAAe,AAAC,GAAc,CAEjC,AAAI,GAAM,GAAU,EAAQ,GAC1B,GAAI,gBAAkB,CAAE,GAAQ,GAChC,KAAK,OAAS,KAAK,MAAM,aAAa,GACtC,EAAI,UAAU,IAGhB,AAAI,EAAK,GAAW,EAAe,EACjC,GAAW,GAAM,EACjB,GAAY,GACZ,KAEO,EAAW,IAClB,GAAW,GAAM,EACjB,GAAY,KAIhB,KAAK,KAAO,CAAC,EAAwB,EAAO,EAAc,EAAgB,IAAS,CACjF,EAAM,EACN,EAAM,EACN,EAAS,EACT,EAAM,EACN,AAAK,EAiBH,EAAS,CACP,KAAM,EAAkB,CACtB,CAAC,MAAQ,MAAQ,MAAQ,SAAS,EAAG,CAAE,MAAO,GAAI,KAClD,CAAC,MAAQ,MAAQ,KAAQ,SAAS,EAAG,CAAE,MAAO,GAAI,EAAI,SACtD,CAAC,EAAQ,MAAQ,MAAQ,SAAS,EAAG,CAAE,MAAO,GAAM,EAAI,GAAK,IAC7D,CAAC,MAAQ,MAAQ,MAAQ,SAAS,EAAG,CAAE,MAAO,GAAM,EAAI,EAAI,OAAU,MAExE,MAAO,EAAkB,CACvB,CAAC,MAAQ,MAAQ,MAAQ,GACzB,CAAC,EAAQ,MAAQ,MAAQ,IACzB,CAAC,MAAQ,MAAQ,KAAQ,SAAS,EAAG,EAAG,CAAE,EAAS,EAAI,MAAQ,QAzBnE,GAAO,EAAS,GAAI,MAAU,OAAO,GAAkB,KAAK,MAAwB,MAEpF,EAAS,CACP,KAAM,EAAkB,CACtB,CAAC,EAAQ,KAAQ,KAAQ,SAAS,EAAG,CAAE,MAAO,GAAK,KACnD,CAAC,KAAQ,MAAQ,KAAQ,SAAS,EAAG,CAAE,MAAO,GAAM,EAAI,GAAK,IAC7D,CAAC,MAAQ,MAAQ,KAAO,SAAS,EAAG,CAAE,WAAqB,EAAI,OAEjE,MAAO,EAAkB,CACvB,CAAC,MAAQ,MAAQ,KAAO,GACxB,CAAC,EAAQ,MAAQ,KAAO,QAmB9B,EAAQ,CACN,KAAM,SAAS,EAAM,CACnB,GAAQ,GACR,GAAI,GACJ,OAAQ,OACD,GACH,EAAM,EACN,EAAQ,EACR,cAEA,EAAM,EAAO,GACb,MAGJ,MAAO,IAET,MAAO,SAAS,EAAM,EAAK,CACzB,GAAI,GAAQ,MAMZ,IAFA,GAAQ,IAEJ,EAAO,KAAQ,EAAO,IAAM,CAC9B,EAAS,EAAO,GAAK,EACjB,GAAQ,KAAQ,GAAU,GAC1B,GAAQ,KAAQ,GAAW,EAAU,EAAS,GAAM,KACpD,GAAQ,KAAQ,KACpB,OAIF,OAFA,GAAQ,GACR,GAAO,IACC,OACD,OACA,OACA,OACA,OACA,OACA,OACA,OACA,GACH,EAAW,EAAM,GACjB,UACG,GACH,EAAQ,EACR,KACA,IACA,UACG,IACH,EAAQ,EAAS,EAAM,GAAO,EAC9B,IACA,UACG,IACH,GAAI,GAAI,EAAI,YAEZ,EAAY,GAAE,IAAM,GAAK,EAAG,EAAO,KAAK,EAAE,KAC1C,UACG,IACH,EAAU,EACV,EAAS,EACT,EAAW,EACX,EAAU,GACV,UACG,IACH,EAAQ,EACR,UACG,IACH,EAAQ,EACR,UACG,IACH,EAAQ,EAAS,EAAM,GAAO,EAC9B,UACG,QACA,QACA,QACA,QACA,QACA,QACA,QACA,IACH,EAAI,cAAc,EAAM,GACxB,UACG,IACH,GAAI,GAAI,EAAI,YACZ,EAAI,cAAe,GAAE,IAAM,GAAK,EAAG,EAAO,KAAK,EAAE,KACjD,UACG,IACH,EAAQ,EACR,UACG,QACA,QACA,QACA,QACA,IAEH,cAGA,UAIR,EAAQ,oBAAoB,GAC5B,EAAQ,gBAAgB,GACxB,KAAK,OAAS,EACd,KAAK,MAAQ,EAEb,OAAS,GAAI,EAAG,EAAI,EAAG,IACrB,EAAW,EAAE,IAIjB,KAAK,gBAAkB,SAAS,EAAI,CAClC,GAAI,GAAI,EAAK,EAAQ,EAAa,EAClC,SAAa,EACN,GAGT,KAAK,UAAY,AAAC,GAAU,CAC1B,EAAI,UAAU,EAAM,GACpB,EAAI,IAAI,EAAM,KACd,EAAQ,IAAI,EAAM,SAClB,EAAQ,IAAI,EAAM,SAClB,EAAU,EAAM,QAChB,EAAQ,EAAM,MACd,EAAU,EAAM,QAChB,EAAS,EAAM,OACf,EAAQ,EAAM,MACd,EAAQ,EAAM,MACd,EAAQ,EAAM,MACd,EAAQ,EAAM,MACd,EAAQ,EAAM,MACd,EAAW,EAAM,SACjB,EAAQ,IAAI,EAAM,SAClB,EAAQ,EAAM,MACd,EAAO,IAAI,EAAM,QACjB,EAAS,IAAI,EAAM,UACnB,EAAU,EAAM,QAChB,KAGF,KAAK,UAAY,IACR,EACL,EAAG,EAAI,YACP,IAAK,EAAI,MAAM,GACf,OAAQ,EAAO,MAAM,GACrB,QAAS,EAAQ,MAAM,GACvB,QAAS,EAAQ,MAAM,GACvB,QAAS,EACT,MAAO,EACP,QAAS,EACT,OAAQ,EACR,MAAO,EACP,MAAO,EACP,MAAO,EACP,MAAO,EACP,MAAO,EACP,SAAU,EACV,QAAS,EAAQ,MAAM,GACvB,MAAO,EACP,SAAU,EAAS,MAAM,GACzB,QAAS,IAGb,KAAK,MAAQ,IAAM,CAEjB,EAAU,EAAQ,EAAQ,EAAQ,EAAQ,EAAS,EAAQ,EAC3D,EAAQ,EACR,EAAU,IAIZ,KAAK,aAAe,AAAC,GAAQ,CAC3B,GAAI,GAAI,GAER,GAAK;AAAA,WAAgB,EAAG,MACxB,GAAK;AAAA,WAAgB,EAAG,MACxB,GAAK;AAAA,YAAiB,EAAI,EAAG,SAC7B,GAAK;AAAA,YAAiB,EAAI,EAAG,OAC7B,GAAK;AAAA,WAAgB,EAAG,QACxB,GAAK;AAAA,YAAiB,EAAI,EAAG,QAC7B,GAAK;AAAA,YAAiB,EAAI,EAAG,OAC7B,GAAK;AAAA,YAAiB,EAAI,EAAG,OAC7B,GAAK;AAAA,YAAiB,EAAI,EAAG,OAC7B,GAAK;AAAA,YAAiB,EAAI,EAAG,OAC7B,GAAK;AAAA,WACL,OAAS,GAAI,EAAG,EAAI,EAAG,IACrB,GAAK,EAAI,EAAQ,IACnB,UAAK;AAAA,EACE,GAGT,KAAK,aAAe,SAAS,EAAK,CAChC,GAAS,GAEX,KAAK,QAAU,SAAS,EAAM,CAC5B,EAAM,GAER,KAAK,SAAW,SAAS,EAAM,CAC7B,EAAO,GAET,KAAK,qBAAuB,UAAW,CACrC,MAAO,GAAQ,IAIZ,eAA6B,GAAmD,CAmBrF,YAAY,EAAgB,CAC1B,QAlBF,kBAAe,OACf,uBAAoB,IAKpB,gBAAa,GAAK,IAAM,GAatB,KAAK,OAAS,EACd,KAAK,IAAM,GAAI,IACf,KAAK,IAAM,GAAI,IAAe,GAAI,KAClC,KAAK,aAAe,GAAI,IAAkB,KAAK,IAAI,IAAK,GAAiB,KAAK,YAC9E,KAAK,QAAU,GAAmB,KAAK,OAAQ,IAC/C,KAAK,eAAiB,EAAS,MAAS,KACxC,KAAK,IAAM,GAAI,YAAW,EAAS,MAAS,MAC5C,KAAK,oBAAsB,EAAS,IAAM,IAC1C,KAAK,YAAc,EAAS,IAAM,IAClC,KAAK,iBAAoB,KAAK,aAAgB,IAAK,KAAK,oBAAsB,OAAU,EAGxF,KAAK,EAAI,GAAI,IAAgB,GAC7B,KAAK,EAAE,KAAK,KAAM,KAAK,IAAK,KAAK,IAAK,KAAK,OAAQ,KAAK,KACpD,GACF,MAAK,OAAO,IAAQ,IACpB,KAAK,OAAO,IAAQ,IACpB,KAAK,OAAO,IAAQ,EACpB,KAAK,OAAO,IAAQ,GAIxB,KAAK,EAAmB,CACtB,MAAO,MAAK,EAAE,OAAO,KAAK,GAE5B,MAAM,EAAU,EAAiB,CAC/B,KAAK,EAAE,OAAO,MAAM,EAAE,GAGxB,aAAa,EAA2B,CACtC,MAAM,aAAa,GACnB,KAAK,YAAc,EACnB,KAAK,WAAa,GAAI,aAAY,EAAO,QACzC,KAAK,EAAE,aAAa,KAAK,YAE3B,UAAW,CACT,KAAK,EAAE,gBAAgB,GAEzB,WAAY,CAEV,GAAI,GAAS,KAAK,EAAE,uBACpB,KAAK,YAAY,IAAI,KAAK,WAAW,MAAM,EAAG,GAAS,GACvD,KAAK,YAAY,KAAK,EAAG,GAG3B,eAAe,EAAmB,EAAqB,CACrD,OAAQ,OACD,GAAG,KAAK,OAAO,IAAQ,EAAQ,IAAM,UACrC,GAAG,KAAK,OAAO,IAAQ,EAAQ,IAAM,OAI9C,eAAgB,CACd,KAAK,OAAS,KAAK,aAAa,SAAS,KAAK,OAGhD,cAAe,CACb,GAAI,GAAK,KAAK,SACd,KAAK,EAAE,aAAa,GAStB,YAAa,CACX,GAAI,GAAM,MAAM,aAEZ,EAAO,KAAK,EAAE,gBAAgB,KAAK,UACvC,MAAI,IACF,IAAO,EACP,KAAK,MAAM,UAAU,IAEhB,EAGT,QAAQ,EAAM,CACZ,MAAM,QAAQ,GACd,KAAK,EAAE,QAAQ,KAAK,KACpB,KAAK,QAEP,SAAS,EAAM,CACb,KAAK,EAAE,SAAS,EAAS,EAAM,OAC/B,KAAK,QAEP,OAAQ,CACN,MAAM,QACN,KAAK,EAAE,QAET,UAAU,EAAO,CACf,KAAK,EAAE,UAAU,GAEnB,WAAY,CACV,MAAO,MAAK,EAAE,YAEhB,oBAAqB,CACnB,MAAO,CAAC,MAAM,QAAQ,SAExB,aAAa,EAAU,EAAO,CAC5B,OAAQ,OACD,QAAS,MAAO,MAAK,EAAE,aAAa,IAG7C,yBAA0B,CACxB,MAAO,CAAE,EAAG,KAAK,aAAc,EAAG,KAAK,cAEzC,gBAAiB,CACf,MAAI,MAAK,OACA,CAAE,MAAO,IAAK,OAAQ,IAAK,OAAQ,KAEnC,CAAE,MAAO,IAAK,OAAQ,OAQnC,gBAA6B,GAAc,CACzC,cAAc,EAAc,EAAa,CAGvC,OAFA,GAAQ,EACR,GAAO,IACC,OACD,GACH,KAAK,IAAI,SAAS,OAAU,GAAM,GAAM,IACxC,KAAK,IAAI,gBAAgB,EAAG,EAAM,KAClC,UACG,OACA,OACA,GACH,GAAI,GAAK,GAAO,GAAK,EACjB,EAAI,EAAM,EAAI,EAClB,KAAK,IAAI,gBAAgB,EAAG,EAAI,KAChC,KAAK,IAAI,gBAAgB,EAAI,EAAI,GAAK,EAAK,KAC3C,UACG,GACH,KAAK,IAAI,gBAAgB,GAAI,EAAM,IACnC,UACG,GACH,KAAK,IAAI,gBAAgB,EAAG,EAAM,IAClC,KAAK,IAAI,gBAAgB,EAAI,GAAO,EAAK,IACzC,SAQJ,EAAoB,CAAC,EAAU,QAAU,QAAU,QAAU,QAAU,SAAU,SAAU,SAAU,QAAU,QAAU,QAAU,QAAU,SAAU,SAAU,SAAU,SAAU,QAAU,QAAU,QAAU,SAAU,SAAU,SAAU,SAAU,SAAU,QAAU,QAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,QAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,QAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,QAAU,QAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,QAAU,QAAU,QAAU,SAAU,SAAU,SAAU,SAAU,SAAU,QAAU,QAAU,OAAU,QAAU,SAAU,SAAU,SAAU,SAAU,KAAU,QAAU,QAAU,QAAU,QAAU,SAAU,SAAU,SAAU,MAAU,MAAU,QAAU,QAAU,QAAU,QAAU,SAAU,SAAU,MAAU,MAAU,MAAU,QAAU,QAAU,QAAU,QAAU,SAAU,MAAU,MAAU,MAAU,OAAU,QAAU,QAAU,QAAU,QAAU,MAAU,MAAU,MAAU,MAAU,OAAU,QAAU,QAAU,QAAU,MAAU,MAAU,MAAU,MAAU,MAAU,QAAU,QAAU,QAAU,MAAU,MAAU,MAAU,MAAU,MAAU,OAAU,QAAU,QAAU,MAAU,MAAU,MAAU,MAAU,MAAU,MAAU,QAAU,QAAU,MAAU,MAAU,MAAU,MAAU,MAAU,MAAU,QAAU,QAAU,MAAU,MAAU,MAAU,MAAU,MAAU,MAAU,QAAU,QAAU,MAAU,MAAU,MAAU,MAAU,MAAU,OAAU,QAAU,QAAU,MAAU,MAAU,MAAU,MAAU,MAAU,QAAU,QAAU,QAAU,MAAU,MAAU,MAAU,MAAU,OAAU,QAAU,QAAU,QAAU,KAAU,MAAU,MAAU,OAAU,QAAU,QAAU,QAAU,QAAU,IAAU,MAAU,MAAU,QAAU,QAAU,QAAU,QAAU,SAAU,IAAU,KAAU,QAAU,QAAU,QAAU,QAAU,SAAU,UAE/gF,IAAS,EAAI,EAAG,EAAI,IAAK,IACnB,GAAI,EAAkB,GAC1B,EAAkB,GAAK,GAAQ,IAAK,WADhC,OADG,EA6BT,GAAI,IAAsB,+1NCvvB1B,GAAM,IAAoB,CACxB,CAAE,GAAI,qBAAsB,KAAM,qBAClC,CAAE,GAAI,mBAAoB,KAAM,mBAChC,CAAE,GAAI,kBAAmB,KAAM,qBAC/B,CAAE,GAAI,UAAW,KAAM,kBACvB,CAAE,GAAI,UAAW,KAAM,SACvB,CAAE,GAAI,YAAa,KAAM,WACzB,CAAE,GAAI,UAAW,KAAM,oBACvB,CAAE,GAAI,gBAAiB,KAAM,gBAC7B,CAAE,GAAI,UAAW,KAAM,SACvB,CAAE,GAAI,WAAY,KAAM,aACxB,CAAE,GAAI,YAAa,KAAM,WACzB,CAAE,GAAI,WAAY,KAAM,uBACxB,CAAE,GAAI,WAAY,KAAM,2BAGpB,GAAyB,CAC7B,CAAE,GAAI,SAAU,KAAM,SAGlB,GAA2B,CAC/B,CAAE,GAAI,UAAW,KAAM,mBAGzB,eAAqC,GAA2D,CAAhG,aAhCA,CAgCA,oBAME,kBAAe,UAAW,CAAE,MAAO,CAAE,KAAK,CACtC,CAAC,KAAK,OAAO,MAAM,EAAI,KAAK,KAAO,KAAK,OAGxC,CAAC,KAAK,aAAa,MAAM,MAAO,KAAK,KAAO,KAAK,OACjD,CAAC,KAAK,iBAAiB,MAAM,MAAO,KAAK,MAAO,MAAO,KAAK,UAThE,YAAsB,CAAE,MAAO,IAAI,GAAe,IAClD,YAAsB,CAAE,MAAO,IAC/B,qBAAsB,CAAE,MAAO,KAC/B,YAAY,EAAU,CAAE,MAAO,MAAK,QAAQ,KAAK,GAQjD,UAAW,CAAE,MAAO,uDAGtB,gBAAyC,EAA2C,CAElF,YAAsB,CAAE,MAAO,IAC/B,QAAQ,EAAM,EAAQ,CAAE,KAAK,QAAQ,SAAS,KAIhD,gBAAkC,EAA2C,CAA7E,aAvDA,CAuDA,oBAKE,kBAAe,UAAW,CAAE,MAAO,CAAE,KAAK,CACtC,CAAC,KAAK,MAAM,MAAM,EAAI,KAAK,MAAO,KAAK,OACvC,CAAC,KAAK,YAAY,MAAM,EAAI,KAAK,MAAO,KAAK,OAC7C,CAAC,KAAK,aAAa,MAAM,MAAO,KAAK,MAAO,KAAK,OACjD,CAAC,KAAK,MAAM,MAAM,MAAO,KAAK,MAAO,KAAK,UAP9C,YAAsB,CAAE,MAAO,IAAI,GAAe,IAClD,YAAsB,CAAE,MAAO,MAUjC,EAAU,UAAe,EACzB,EAAU,kBAAoB,GAC9B,EAAU,oBAAsB",
"names": []
}