From 700877e310ffb6edec72bc7222ae58f64ade3889 Mon Sep 17 00:00:00 2001 From: Steven Hugg Date: Fri, 31 May 2019 15:05:33 -0400 Subject: [PATCH] astrocade: split bios into .s file, fixed interrupt page, added music --- presets/astrocade-bios/astrocade.inc | 9 ++ presets/astrocade-bios/bios.c | 170 +++++++++++---------------- presets/astrocade-bios/biosasm.s | 39 +++--- presets/astrocade-bios/test1.s | 15 ++- presets/astrocade-bios/test2.s | 49 ++++++++ presets/astrocade-bios/test3.s | 103 ++++++++++++++++ presets/astrocade/aclib.c | 11 ++ presets/astrocade/aclib.h | 1 + presets/astrocade/music.c | 98 +++++++++++++++ src/platform/astrocade.ts | 4 +- src/project.ts | 2 +- src/ui.ts | 2 +- src/worker/workermain.ts | 10 +- 13 files changed, 388 insertions(+), 125 deletions(-) create mode 100644 presets/astrocade-bios/test2.s create mode 100644 presets/astrocade-bios/test3.s create mode 100644 presets/astrocade/music.c diff --git a/presets/astrocade-bios/astrocade.inc b/presets/astrocade-bios/astrocade.inc index 163613c5..f1afa914 100644 --- a/presets/astrocade-bios/astrocade.inc +++ b/presets/astrocade-bios/astrocade.inc @@ -381,3 +381,12 @@ URINAL = 0x4FFF ; WASTER flushes here! .macro DO CID .db CID + 1 .endm +; +; EXIT interpreter with context restore: + .macro EXIT + .db XINTC +;INTPCC = 0 + .endm +; +ENDx = 0xC0 ; END of DOIT Table +; diff --git a/presets/astrocade-bios/bios.c b/presets/astrocade-bios/bios.c index ae7d00e2..e68816c0 100644 --- a/presets/astrocade-bios/bios.c +++ b/presets/astrocade-bios/bios.c @@ -1,6 +1,22 @@ +/** +AstroLibre +An open source Bally Astrocade BIOS implementation in C +by Steven Hugg (@sehugg) for 8bitworkshop.com -#define TEST +To the extent possible under law, the author(s) have +dedicated all copyright and related and neighboring +rights to this software to the public domain worldwide. +This software is distributed without any warranty. + +See: http://creativecommons.org/publicdomain/zero/1.0/ +**/ + +//#resource "astrocade.inc" +//#link "biosasm.s" + +// comment out to build BIOS without demo +//#link "test1.s" #include @@ -62,7 +78,7 @@ __sfr __at(0x13) hw_p4ctrl; // player controls /// GRAPHICS FUNCTIONS -#define VHEIGHT 89 // number of scanlines +#define VHEIGHT 102 // number of scanlines #define VBWIDTH 40 // number of bytes per scanline #define PIXWIDTH 160 // 4 pixels per byte @@ -105,82 +121,13 @@ byte SENFLG; // sentry control byte* UMARGT; // user mask table (-64 bytes) word* USERTB; // user routine table (-128 bytes) -#ifdef TEST -#define MAIN _main -#else -#define MAIN 0x2000 -#endif - -// start routine @ 0x0 -void bios_start() __naked { -__asm - DI ; disable interrupts - LD HL,#MAIN - LD A,(HL) ; A <- mem[0x2000] - CP #0x55 ; found sentinel byte? ($55) - JP Z,FoundSentinel ; yes, load program - JP MAIN -FoundSentinel: - LD SP,#0x4fce ; position stack below BIOS vars - CALL _bios_init ; misc. bios init routines - LD HL,#(MAIN+5) ; cartridge start vector - LD A,(HL) - INC HL - LD H,(HL) - LD L,A - JP (HL) ; jump to cart start vector - .ds 0x38 - 0x1b ; eat up space until 0x38 -__endasm; -} - -void interrupt_0x38() __naked { -__asm - push hl - push af - push bc - push de - push ix - push iy - ld hl,#0 - add hl,sp - push hl ; HL points to context block - call _SYSCALL ; syscall handler - pop hl - pop iy - pop ix - pop de - pop bc - pop af - pop hl - ret -__endasm; -} - -void _predope() __naked { -__asm - .ds 0x200-0x52 ; skip to 0x200 -__endasm; -} - -// DOPE vector @ 0x200 -void DOPE() __naked { -__asm - JP _STIMER - JP _CTIMER - .db 0x20, 8, 8, 1, 7 ; Font descriptor (big font) - .dw _BIGFONT - .db 0xa0, 4, 6, 1, 5 ; Font descriptor (small font) - .dw _SMLFONT -__endasm; -} - typedef struct { - byte base_ch; - byte frame_x; - byte frame_y; - byte pattern_x; - byte pattern_y; - const byte* chartab; + byte base_ch; // first char + byte frame_x; // frame width + byte frame_y; // frame height + byte pattern_x; // pattern width + byte pattern_y; // pattern height + const byte* chartab; // pointer to char data } FontDescriptor; #define LOCHAR 0x20 @@ -192,6 +139,10 @@ extern const char SMLFONT[HICHAR-LOCHAR+1][5]; const FontDescriptor __at(0x206) FNTSYS; // = { 0x20, 8, 8, 1, 7, (byte*)BIGFONT }; const FontDescriptor __at(0x20d) FNTSML; // = { 0xa0, 4, 6, 1, 5, (byte*)SMLFONT }; + + +// INTERRUPT HANDLERS +// must be in 0x200 page void hw_interrupt() __interrupt { CT[0]++; CT[1]++; @@ -205,7 +156,22 @@ void hw_interrupt() __interrupt { } } -const void* const actint_vec = &hw_interrupt; +// TODO +byte add_counters(byte mask, byte delta) { + byte i = 0; + byte any0 = 0; + while (mask) { + if (mask & 1) { + if (CT[i]) { + if (!(CT[i] += delta)) + any0 = 1; + } + } + mask >>= 1; + i++; + } + return any0; +} void STIMER() { } @@ -213,6 +179,20 @@ void STIMER() { void CTIMER() { } +void TIMEZ() { + // updates game timer, blackout timer, and music processor +} + +void TIMEY() { + CT[0]--; + CT[1]--; + CT[2]--; + CT[3]--; +} + +void TIMEX() { +} + ///// INTERPRETER typedef struct { @@ -325,17 +305,23 @@ void SUCK(ContextBlock* ctx) { suckParams(ctx, _B); } + +const void* const actint_vec = &hw_interrupt; + void ACTINT(ContextBlock *ctx) { ctx; - hw_inlin = 200; - hw_infbk = (byte) &actint_vec; - hw_inmod = 8; __asm - LD A,#0x2 ; I = 0x200 + LD BC,#(_actint_vec) ; upper 8 bits of address + LD A,B LD I,A IM 2 ; mode 2 EI ; enable interrupts __endasm; + hw_inlin = 200; + hw_infbk = (byte) &actint_vec; + hw_inmod = 0x8; + TIMEZ(); + TIMEY(); } // Outputs D to port 0A, B to port 09, A to port 0E. @@ -766,23 +752,3 @@ void bios_init() { *((byte*)0x4fce) = 0; hw_magic = 0; } - -#ifdef TEST - -void _main() { -__asm -#include "astrocade.inc" -#include "test3.s" -__endasm; -} - -#else - -void _biosend() __naked { -__asm - ; eat up rest of space - .ds 0x2000 - (. - __biosend) -__endasm; -} - -#endif diff --git a/presets/astrocade-bios/biosasm.s b/presets/astrocade-bios/biosasm.s index 26179923..c5f8736e 100644 --- a/presets/astrocade-bios/biosasm.s +++ b/presets/astrocade-bios/biosasm.s @@ -1,34 +1,38 @@ ;#link "bioslib.c" +TEST = 1 + .module biosasm .globl _STIMER,_CTIMER,_BIGFONT,_SMLFONT - .area BIOSSTART (ABS) - .org 0x0 BIOSStart: di ; disable interrupts ld HL,#0x2000 ld A,(HL) ; A <- mem[0x2000] cp #0x55 ; found sentinel byte? ($55) jp Z,FoundSentinel ; yes, load program -.if 1 - jp 0x2000 ; jump to $2000 -.else +.if TEST jp _main ; jump to test program +.else + jp 0x2000 ; jump to $2000 .endif FoundSentinel: ld SP,#0x4fce ; position stack below BIOS vars call _bios_init ; misc. bios init routines +.if TEST + ld HL,#(_main+5) +.else ld HL,#0x2005 ; cartridge start vector +.endif ld A,(HL) inc HL ld H,(HL) ld L,A jp (HL) ; jump to cart start vector - + .ds 0x38 - (. - BIOSStart) ; eat up space until 0x38 + .globl SYSCALL38 SYSCALL38: - .org 0x38 push hl push af push bc @@ -47,16 +51,7 @@ SYSCALL38: pop af pop hl ret - -DOPEVector: - .org 0x200 - JP _STIMER - JP _CTIMER - .db 0x20, 8, 8, 1, 7 ; Font descriptor (big font) - .dw _BIGFONT - .db 0xa0, 4, 6, 1, 5 ; Font descriptor (small font) - .dw _SMLFONT - +; TODO? ReloadRegs: ld c,(hl) inc hl @@ -95,4 +90,14 @@ ReloadRegs: pop hl pop bc ret + .ds 0x200 - (. - BIOSStart) ; eat up space until 0x200 + +DOPEVector: + JP _STIMER + JP _CTIMER + .db 0x20, 8, 8, 1, 7 ; Font descriptor (big font) + .dw _BIGFONT + .db 0xa0, 4, 6, 1, 5 ; Font descriptor (small font) + .dw _SMLFONT + diff --git a/presets/astrocade-bios/test1.s b/presets/astrocade-bios/test1.s index 695b4320..5186f2fc 100644 --- a/presets/astrocade-bios/test1.s +++ b/presets/astrocade-bios/test1.s @@ -1,5 +1,16 @@ +; need these in 1st file sdcc linker sees +.area _HOME +.area _INITIALIZER +.area _DATA +.area _INITIALIZED +.area _BSEG +.area _BSS +.area _HEAP +.area _CODE + + .include "astrocade.inc" .globl _main _main: LD SP,#0x4fce ; position stack below BIOS vars @@ -62,7 +73,7 @@ _main: .dw 3 .dw _BCDNUM ; exit interpreter - DONT XINTC + EXIT .loop: SYSSUK DISNUM .db 80 @@ -123,3 +134,5 @@ BALL: .db 0,0 .db 0b11111101 .db 0b01111010 +RINGING: + .db 0x80,0x23,0xB0,0x80,0x00,0x3C,0x17,0x3C,0x11,0xE1,0x50,0x3C,0x17,0x3C,0x11,0xE1,0xA0,0xC3,0x5B,0x23,0x00 diff --git a/presets/astrocade-bios/test2.s b/presets/astrocade-bios/test2.s new file mode 100644 index 00000000..efd01259 --- /dev/null +++ b/presets/astrocade-bios/test2.s @@ -0,0 +1,49 @@ +; Demo 1: HELLO, WORLDS! / 2018 hxlnt +; Inspired by Adam Trionfo Hello World +; http://www.ballyalley.com/ml/ml_homebrew/helloworld/hello.asm +; From: https://github.com/hxlnt/astrocade + +; need these in 1st file sdcc linker sees +.area _HOME +.area _INITIALIZER +.area _DATA +.area _INITIALIZED +.area _BSEG +.area _BSS +.area _HEAP +.area _CODE + + .include "astrocade.inc" + .globl _main +_main: + .db 0x55 ; ... with the code for a normal menued cartridge + .dw MENUST ; Initialize menu + .dw PrgName ; ... with string at PrgName + .dw PrgStart ; ... such that selecting the program enters PrgStart +PrgName: .ascii "HELLO, WORLDS!"; String + .db 0 ; ... which must be followed by 0 +PrgStart: DI ; Disable interrupts + LD SP,#0x4fce ; position stack below BIOS vars + ld hl,#0x20d ; small font -> IX + push hl + pop ix + SYSTEM INTPC ; Begin interpreter mode + DO SETOUT ; Set output ports + .db 100*2 ; ... with VBLANK line set to line 100 + .db 112/4 ; ... with color boundary 112 pixels from the left of the screen + .db 0b00001000 ; ... with screen interrupts reenabled + DO COLSET ; Set color palettes + .dw Palettes ; ... with the values at Palettes + DO FILL ; Set background fill + .dw NORMEM ; ... starting at the beginning of screen RAM + .dw 99*BYTEPL ; ... and going for 100 lines + .db 0b00010010 ; ... with a fill pattern of three different colored pixels + DO STRDIS ; Set string display + .db 0 ; ... starting 0 pixels from the left of the screen + .db 32 ; ... and 32 pixels from the top of the screen + .db 0b00001100 ; ... with no enlargement, foreground color = 11, background color = 00 + .dw PrgName ; ... to show string at PrgName + DONT XINTC +Loop: JP Loop ; Play infinite loop +Palettes: .db 0xBF,0x00,0x00,0x00 ; Left color palette (11b, 10b, 01b, 00b) + .db 0xE7,0x9A,0x39,0x19 ; Right color palette (11b, 10b, 01b, 00b) diff --git a/presets/astrocade-bios/test3.s b/presets/astrocade-bios/test3.s new file mode 100644 index 00000000..30d26180 --- /dev/null +++ b/presets/astrocade-bios/test3.s @@ -0,0 +1,103 @@ +; "HORCB Pal" demo 2018 hxlnt +; Inspired by Michael Garber Color Picker +; http://ballyalley.com/ml/ml_homebrew/colorpicker.asm +; From: https://github.com/hxlnt/astrocade + +; need these in 1st file sdcc linker sees +.area _HOME +.area _INITIALIZER +.area _DATA +.area _INITIALIZED +.area _BSEG +.area _BSS +.area _HEAP +.area _CODE + + .include "astrocade.inc" + .globl _main +_main: +FrameCount = 0x4F00 ; Reserve a space for a frame counter + .db 0x55 ; ... with the code for a normal menued cartridge + .dw MENUST ; Initialize menu + .dw PrgName ; ... with string at PrgName + .dw PrgStart ; ... such that selecting the program enters PrgStart +PrgName: .ascii "HORCB PAL" ; String + .db 0 ; ... which must be followed by 0 +PrgStart: DI ; Disable interrupts + LD SP,#0x4fce ; position stack below BIOS vars + ld hl,#0x20d ; small font -> IX + push hl + pop ix + SYSTEM INTPC ; Begin interpreter mode + DO SETOUT ; Set output ports + .db 96*2 ; ... with VBLANK line set to line 96 + .db 0/4 ; ... with color boundary 0 pixels from the left of the screen + .db 0b00001000 ; ... with screen interrupts enabled + DO COLSET ; Set color palettes + .dw Palettes ; ... with the values at Palettes + DO FILL ; Set background fill + .dw NORMEM ; ... starting at the beginning of screen RAM + .dw 24*BYTEPL ; ... and going for 24 lines + .db 0b00011011 ; ... with a fill pattern of four different colored pixels + DO FILL ; Set background fill + .dw NORMEM+(24*BYTEPL) + .dw 24*BYTEPL ; ... and going for 24 lines + .db 0b00000000 ; ... with a solid fill of color 00 + DO FILL ; Set background fill + .dw NORMEM+(48*BYTEPL) + .dw 24*BYTEPL ; ... and going for 24 lines + .db 0b11111111 ; ... with a solid fill of color 11 + DO STRDIS ; Set string display + .db 28 ; ... starting 28 pixels from the left of the screen + .db 40 ; ... and 40 pixels from the top of the screen + .db 0b00001100 ; ... with no enlargement, foreground color = 11, background color = 00 + .dw PrgName ; ... with string at PrgName + DONT XINTC ; Exit interpreter mode +Loop: IN A,(POT0) ; Let A = controller 1 knob value + OUT (HORCB),A ; Let horizontal color boundary = A + CALL UpdateDisp ; Call UpdateDisp subroutine + JP Loop ; Go back to beginning of infinite loop +Palettes: .db 0xF4,0x1C,0x1F,0x5F ; Left color palette (11b, 10b, 01b, 00b) + .db 0xED,0xCD,0xD5,0x8E ; Right color palette (11b, 10b, 01b, 00b) +UpdateDisp: + DI ; Disable interrupts + PUSH AF ; Push AF to SP + LD C,A ; Get first hex digit from knob value + SRL C ; ... + SRL C ; ... + SRL C ; ... + SRL C ; ... + LD B,#0 ; Display first hex digit from knob value + LD HL,#Hex ; ... Load HL with address Hex + ADD HL,BC ; ... Offset Hex by BC to get first hex digit + LD A,(HL) ; ... Load A with first hex digit + LD C,#0b00000100 ; ... Load C with string options + LD D,#40 ; ... Load D with string Y-coordinate + LD E,#120 ; ... Load E with X-coordinate + SYSTEM (CHRDIS) ; ... Display first digit + POP AF ; Pop AF off SP + AND A,#0x0F ; Get second hex digit from knob value + LD C,A ; ... + LD B,#0 ; Display second hex digit from knob value + LD HL,#Hex ; ... Load HL with address Hex + ADD HL,BC ; ... Offset Hex by BC to get second hex digit + LD A,(HL) ; ... Load A with second hex digit + LD C,#0b00000100 ; ... Load C with string options + LD D,#40 ; ... Load D with Y-coordinate + LD E,#128 ; ... Load E with X-coordinate + SYSTEM (CHRDIS) ; ... Display second digit + LD A,(FrameCount) ; Increment frame counter + INC A ; ... + LD (FrameCount),A ; ... + AND #0b00000111 ; Every fourth frame, run AnimBars + CP #0b00000100 ; ... + JR Z, AnimBars ; ... + JP AnimDone ; Otherwise, skip AnimBars +AnimBars: SYSSUK RANGED ; Load a random 8-bit number in A + .db 0 ; ... + LD BC,#24*BYTEPL ; Load BC with one scanline length + LD DE,#NORMEM+(72*BYTEPL) + SYSTEM FILL ; Fill remainder of screen with repeating random tile +AnimDone: EI ; Enable interrupts + RET ; Return from subroutine +Hex: .ascii "0123456789ABCDEF" diff --git a/presets/astrocade/aclib.c b/presets/astrocade/aclib.c index 8c4b3827..6dee4931 100644 --- a/presets/astrocade/aclib.c +++ b/presets/astrocade/aclib.c @@ -20,6 +20,17 @@ __asm __endasm; } +// set entire sound registers at once (8 bytes to port 0x18) +// bytes in array should be in reverse +void set_sound_registers(byte regs[8]) __z88dk_fastcall { + regs; +__asm + ld bc,#0x818 ; B -> 8, C -> 0x18 + otir ; write C bytes from HL to port[B] + ret ; return +__endasm; +} + // draw vertical line void vline(byte x, byte y1, byte y2, byte col, byte op) { byte* dest = &vmagic[y1][x>>2];// destination address diff --git a/presets/astrocade/aclib.h b/presets/astrocade/aclib.h index c2ebcca0..13ba1a38 100644 --- a/presets/astrocade/aclib.h +++ b/presets/astrocade/aclib.h @@ -81,6 +81,7 @@ byte __at (0x4000) vidmem[VTOTAL][VBWIDTH]; void clrscr(); void set_palette(byte palette[8]) __z88dk_fastcall; // palette in reverse order +void set_sound_registers(byte regs[8]) __z88dk_fastcall; // in reverse too void vline(byte x, byte y1, byte y2, byte col, byte op); void pixel(byte x, byte y, byte col, byte op); void render_sprite(const byte* src, byte x, byte y, byte op); diff --git a/presets/astrocade/music.c b/presets/astrocade/music.c new file mode 100644 index 00000000..2c48cc8b --- /dev/null +++ b/presets/astrocade/music.c @@ -0,0 +1,98 @@ + +#include +#include + +//#resource "astrocade.inc" +#include "aclib.h" +//#link "aclib.c" +//#link "hdr_autostart.s" +#include "acbios.h" +//#link "acbios.s" + +byte soundregs[8]; + +//////// +// +// MUSIC ROUTINES +// + +// Namespace(bias=0, freq=6480.0, length=64, maxbits=12, upper=49) +// 430.0 38.11501356252539 49 +const int note_table[64] = { + 255,241,228,215,203,191,181,170,161,152,143,135,128,121,114,107,101,96,90,85,80,76,72,68,64,60,57,54,51,48,45,43,40,38,36,34,32,30,28,27,25,24,23,21,20,19,18,17,16,15,14,13,13,12,11,11,10,9,9,8,8,8,7,7,}; + +struct { + byte volume; +} voice[3]; + +byte music_index = 0; +byte cur_duration = 0; + +const byte music1[] = { +0x1e,0x12,0x8c,0x23,0x17,0x86,0x2f,0x86,0x36,0x2a,0x27,0x86,0x2f,0x86,0x33,0x1e,0x23,0x86,0x36,0x2a,0x86,0x24,0x18,0x86,0x2e,0x86,0x2a,0x36,0x25,0x86,0x2e,0x86,0x31,0x28,0x22,0x86,0x36,0x2a,0x86,0x1e,0x22,0x28,0x8c,0x1e,0x12,0x8c,0x23,0x17,0x86,0x2f,0x86,0x36,0x2a,0x27,0x86,0x2f,0x86,0x33,0x1e,0x23,0x86,0x36,0x2a,0x86,0x24,0x18,0x86,0x2e,0x86,0x36,0x2a,0x25,0x86,0x2e,0x86,0x31,0x28,0x22,0x86,0x36,0x2a,0x86,0x28,0x22,0x1e,0x8c,0x12,0x1e,0x86,0x36,0x2a,0x86,0x1f,0x13,0x86,0x2f,0x86,0x32,0x86,0x37,0x2b,0x86,0x1e,0x12,0x86,0x36,0x2a,0x86,0x1e,0x12,0x86,0x2a,0x36,0x86,0x1f,0x13,0x86,0x2f,0x86,0x32,0x86,0x37,0x2b,0x86,0x1e,0x12,0x86,0x36,0x2a,0x92,0x0b,0x86,0x17,0x86,0x1a,0x86,0x23,0x86,0x17,0x86,0x23,0x86,0x26,0x86,0x2f,0x86,0x23,0x86,0x2f,0x86,0x32,0x86,0x3b,0x86,0x2f,0x86,0x3b,0x86,0x3e,0x86,0x86,0x3b,0x29,0x2c,0x8c,0x3b,0x32,0x2f,0x8c,0x3b,0x32,0x2f,0x8c,0x3b,0x29,0x2c,0x86,0x3b,0x86,0x33,0x2f,0x2a,0x86,0x86,0x33,0x2f,0x2a,0x86,0x3f,0x86,0x2a,0x2f,0x33,0x86,0x3b,0x86,0x33,0x2f,0x2a,0x86,0x37,0x3b,0x86,0x32,0x2f,0x2b,0x86,0x3d,0x86,0x3e,0x37,0x2b,0x86,0x3b,0x86,0x3d,0x33,0x2f,0x86,0x3f,0x36,0x86,0x33,0x2f,0x2a,0x86,0x3b,0x86,0x3f,0x36,0x33,0x86,0x3b,0x86,0x3d,0x36,0x2a,0x8c,0x3b,0x36,0x33,0x92,0x3b,0x2f,0x86,0x26,0x23,0x20,0x8c,0x3b,0x2f,0x1d,0x8c,0x3b,0x2f,0x26,0x8c,0x3b,0x2f,0x26,0x86,0x3b,0x2f,0x86,0x1e,0x23,0x27,0x86,0x36,0x86,0x38,0x2f,0x27,0x86,0x33,0x86,0x36,0x27,0x23,0x86,0x38,0x2f,0x86,0x1e,0x23,0x27,0x86,0x2f,0x2b,0x86,0x26,0x23,0x1f,0x86,0x31,0x86,0x32,0x2b,0x26,0x86,0x2f,0x86,0x31,0x27,0x23,0x86,0x33,0x2a,0x86,0x1e,0x23,0x27,0x86,0x2f,0x86,0x2a,0x33,0x27,0x86,0x2f,0x86,0x31,0x2a,0x28,0x8c,0x2f,0x2a,0x27,0x8c,0x12,0x1e,0x8c,0x23,0x17,0x86,0x2f,0x86,0x36,0x2a,0x27,0x86,0x2f,0x86,0x33,0x27,0x23,0x86,0x36,0x2a,0x86,0x24,0x18,0x86,0x2e,0x86,0x36,0x2a,0x19,0x86,0x2e,0x86,0x31,0x28,0x22,0x86,0x36,0x2a,0x86,0x28,0x22,0x1e,0x8c,0x1e,0x12,0x8c,0x23,0x17,0x86,0x2f,0x86,0x36,0x2a,0x1e,0x86,0x2f,0x86,0x33,0x27,0x23,0x86,0x36,0x2a,0x86,0x24,0x18,0x86,0x2e,0x86,0x36,0x2a,0x25,0x86,0x2e,0x86,0x31,0x1e,0x22,0x86,0x36,0x2a,0x86,0x28,0x22,0x1e,0x8c,0x1e,0x12,0x86,0x36,0x2a,0x86,0x1f,0x13,0x86,0x2f,0x86,0x32,0x86,0x2b,0x37,0x86,0x12,0x1e,0x86,0x36,0x2a,0x86,0x1e,0x12,0x86,0x36,0x2a,0x86,0x1f,0x13,0x86,0x2f,0x86,0x32,0x86,0x37,0x2b,0x86,0x1e,0x12,0x86,0x36,0x2a,0x92,0x0b,0x86,0x17,0x86,0x1a,0x86,0x23,0x86,0x17,0x86,0x23,0x86,0x26,0x86,0x2f,0x86,0x23,0x86,0x2f,0x86,0x32,0x86,0x3b,0x86,0x2f,0x86,0x3b,0x86,0x3e,0x86,0x86,0x3b,0x32,0x2f,0x8c,0x3b,0x29,0x2c,0x8c,0x3b,0x32,0x2f,0x8c,0x3b,0x32,0x2f,0x86,0x3b,0x86,0x2a,0x2f,0x33,0x86,0x86,0x33,0x2f,0x2a,0x86,0x3f,0x86,0x33,0x2f,0x2a,0x86,0x3b,0x86,0x2a,0x2f,0x33,0x86,0x3b,0x37,0x86,0x32,0x2f,0x2b,0x86,0x3d,0x86,0x3e,0x37,0x32,0x86,0x3b,0x86,0x3d,0x33,0x2f,0x86,0x3f,0x36,0x86,0x2a,0x2f,0x33,0x86,0x3b,0x86,0x3f,0x36,0x33,0x86,0x3b,0x86,0x3d,0x36,0x34,0x8c,0x36,0x3b,0x33,0x92,0x3b,0x2f,0x86,0x1d,0x20,0x23,0x8c,0x3b,0x2f,0x26,0x8c,0x3b,0x2f,0x1d,0x8c,0x2f,0x3b,0x26,0x86,0x3b,0x2f,0x86,0x27,0x23,0x1e,0x86,0x36,0x86,0x38,0x2f,0x1e,0x86,0x33,0x86,0x36,0x27,0x23,0x86,0x2f,0x38,0x86,0x27,0x23,0x1e,0x86,0x2f,0x2b,0x86,0x26,0x23,0x1f,0x86,0x31,0x86,0x32,0x2b,0x1f,0x86,0x2f,0x86,0x31,0x27,0x23,0x86,0x2a,0x33,0x86,0x27,0x23,0x1e,0x86,0x2f,0x86,0x33,0x2a,0x1e,0x86,0x2f,0x86,0x31,0x2a,0x28,0x8c,0x2f,0x2a,0x27,0x8c,0x24,0x18,0x8c,0x25,0x19,0x86,0x3a,0x86,0x36,0x1e,0x22,0x86,0x3a,0x86,0x3d,0x1e,0x12,0x86,0x35,0x86,0x28,0x22,0x1e,0x86,0x3a,0x86,0x34,0x25,0x19,0x86,0x3a,0x86,0x3d,0x1e,0x22,0x86,0x33,0x3f,0x86,0x1e,0x12,0x86,0x36,0x86,0x3d,0x31,0x22,0x86,0x36,0x86,0x23,0x17,0x86,0x33,0x86,0x3b,0x2f,0x27,0x86,0x33,0x86,0x36,0x12,0x1e,0x86,0x38,0x2c,0x86,0x27,0x23,0x1e,0x86,0x33,0x86,0x3b,0x2f,0x23,0x86,0x33,0x86,0x36,0x27,0x23,0x86,0x38,0x2c,0x86,0x17,0x23,0x86,0x33,0x86,0x38,0x2c,0x24,0x8c,0x25,0x19,0x86,0x36,0x86,0x3a,0x2e,0x28,0x86,0x31,0x86,0x34,0x1e,0x12,0x86,0x38,0x2c,0x86,0x1e,0x22,0x28,0x86,0x36,0x86,0x3a,0x2e,0x25,0x86,0x31,0x86,0x34,0x28,0x22,0x86,0x38,0x2c,0x86,0x25,0x19,0x86,0x34,0x86,0x2c,0x38,0x26,0x8c,0x1b,0x27,0x86,0x33,0x86,0x3b,0x2f,0x27,0x86,0x33,0x86,0x36,0x1e,0x12,0x86,0x38,0x2c,0x86,0x27,0x23,0x1e,0x86,0x33,0x86,0x2f,0x3b,0x17,0x86,0x33,0x86,0x36,0x27,0x23,0x86,0x38,0x2c,0x86,0x23,0x17,0x86,0x33,0x86,0x38,0x2c,0x24,0x8c,0x25,0x19,0x86,0x3a,0x86,0x36,0x1e,0x22,0x86,0x3a,0x86,0x3d,0x1e,0x12,0x86,0x35,0x86,0x28,0x22,0x1e,0x86,0x3a,0x86,0x34,0x25,0x19,0x86,0x3a,0x86,0x3d,0x1e,0x22,0x86,0x3f,0x33,0x86,0x1e,0x12,0x86,0x36,0x86,0x3d,0x31,0x22,0x86,0x36,0x86,0x23,0x17,0x86,0x33,0x86,0x2f,0x3b,0x27,0x86,0x33,0x86,0x36,0x12,0x1e,0x86,0x38,0x2c,0x86,0x27,0x23,0x1e,0x86,0x33,0x86,0x3b,0x2f,0x23,0x8c,0x3b,0x2f,0x23,0x8c,0x2e,0x3a,0x22,0x8c,0x39,0x2d,0x15,0x8c,0x20,0x14,0x86,0x2c,0x86,0x30,0x20,0x14,0x86,0x33,0x86,0x38,0x24,0x18,0x86,0x33,0x86,0x30,0x24,0x18,0x86,0x2c,0x86,0x19,0x25,0x86,0x2c,0x86,0x31,0x28,0x25,0x86,0x34,0x86,0x38,0x2c,0x28,0x8c,0x34,0x31,0x2c,0x8c,0x29,0x2c,0x2f,0x8c,0x25,0x20,0x19,0x86,0x33,0x2f,0x2c,0x86,0x1e,0x12,0x86,0x31,0x28,0x86,0x22,0x16,0x86,0x2a,0x86,0x27,0x2f,0x23,0x8c,0x36,0x2a,0x1e,0x8c,0x36,0x2a,0x27,0x8c,0x36,0x2a,0x24,0x8c,0x25,0x19,0x86,0x3a,0x86,0x36,0x1e,0x22,0x86,0x3a,0x86,0x3d,0x1e,0x12,0x86,0x35,0x86,0x28,0x22,0x1e,0x86,0x3a,0x86,0x34,0x25,0x19,0x86,0x3a,0x86,0x3d,0x1e,0x22,0x86,0x3f,0x33,0x86,0x1e,0x12,0x86,0x36,0x86,0x3d,0x31,0x22,0x86,0x36,0x86,0x23,0x17,0x86,0x33,0x86,0x3b,0x2f,0x27,0x86,0x33,0x86,0x36,0x12,0x1e,0x86,0x2c,0x38,0x86,0x27,0x23,0x1e,0x86,0x33,0x86,0x3b,0x2f,0x23,0x86,0x33,0x86,0x36,0x27,0x23,0x86,0x38,0x2c,0x86,0x17,0x23,0x86,0x33,0x86,0x38,0x2c,0x24,0x8c,0x25,0x19,0x86,0x36,0x86,0x3a,0x2e,0x28,0x86,0x31,0x86,0x34,0x1e,0x12,0x86,0x38,0x2c,0x86,0x1e,0x22,0x28,0x86,0x36,0x86,0x2e,0x3a,0x25,0x86,0x31,0x86,0x34,0x28,0x22,0x86,0x38,0x2c,0x86,0x25,0x19,0x86,0x34,0x86,0x38,0x2c,0x26,0x8c,0x1b,0x27,0x86,0x33,0x86,0x3b,0x2f,0x27,0x86,0x33,0x86,0x36,0x1e,0x12,0x86,0x38,0x2c,0x86,0x27,0x23,0x1e,0x86,0x33,0x86,0x3b,0x2f,0x17,0x86,0x33,0x86,0x36,0x27,0x23,0x86,0x38,0x2c,0x86,0x23,0x17,0x86,0x33,0x86,0x38,0x2c,0x24,0x8c,0x25,0x19,0x86,0x3a,0x86,0x36,0x1e,0x22,0x86,0x3a,0x86,0x3d,0x1e,0x12,0x86,0x35,0x86,0x28,0x22,0x1e,0x86,0x3a,0x86,0x34,0x25,0x19,0x86,0x3a,0x86,0x3d,0x1e,0x22,0x86,0x33,0x3f,0x86,0x1e,0x12,0x86,0x36,0x86,0x3d,0x31,0x22,0x86,0x36,0x86,0x23,0x17,0x86,0x33,0x86,0x3b,0x2f,0x27,0x86,0x33,0x86,0x36,0x12,0x1e,0x86,0x38,0x2c,0x86,0x27,0x23,0x1e,0x86,0x33,0x86,0x3b,0x2f,0x23,0x8c,0x3b,0x2f,0x23,0x8c,0x3a,0x2e,0x22,0x8c,0x2d,0x39,0x15,0x8c,0x20,0x14,0x86,0x2c,0x86,0x30,0x20,0x14,0x86,0x33,0x86,0x38,0x24,0x18,0x86,0x33,0x86,0x30,0x24,0x18,0x86,0x2c,0x86,0x19,0x25,0x86,0x2c,0x86,0x31,0x28,0x25,0x86,0x34,0x86,0x38,0x2c,0x28,0x8c,0x34,0x31,0x2c,0x8c,0x33,0x2f,0x2c,0x8c,0x25,0x20,0x19,0x86,0x29,0x2c,0x2f,0x86,0x1e,0x12,0x86,0x31,0x28,0x86,0x22,0x16,0x86,0x2a,0x86,0x23,0x17,0x86,0x2f,0x86,0x33,0x23,0x27,0x86,0x36,0x86,0x2f,0x3b,0x2a,0x8c,0x1e,0x12,0x8c,0x23,0x17,0x86,0x2f,0x86,0x36,0x2a,0x1e,0x86,0x2f,0x86,0x33,0x27,0x23,0x86,0x36,0x2a,0x86,0x24,0x18,0x86,0x2e,0x86,0x2a,0x36,0x25,0x86,0x2e,0x86,0x31,0x1e,0x22,0x86,0x36,0x2a,0x86,0x28,0x22,0x1e,0x8c,0x1e,0x12,0x8c,0x23,0x17,0x86,0x2f,0x86,0x36,0x2a,0x1e,0x86,0x2f,0x86,0x33,0x27,0x23,0x86,0x36,0x2a,0x86,0x24,0x18,0x86,0x2e,0x86,0x36,0x2a,0x25,0x86,0x2e,0x86,0x31,0x1e,0x22,0x86,0x36,0x2a,0x86,0x28,0x22,0x1e,0x8c,0x1e,0x12,0x86,0x36,0x2a,0x86,0x1f,0x13,0x86,0x2f,0x86,0x32,0x86,0x37,0x2b,0x86,0x1e,0x12,0x86,0x36,0x2a,0x86,0x12,0x1e,0x86,0x36,0x2a,0x86,0x1f,0x13,0x86,0x2f,0x86,0x32,0x86,0x37,0x2b,0x86,0x1e,0x12,0x86,0x36,0x2a,0x92,0x0b,0x86,0x17,0x86,0x1a,0x86,0x23,0x86,0x17,0x86,0x23,0x86,0x26,0x86,0x2f,0x86,0x23,0x86,0x2f,0x86,0x32,0x86,0x3b,0x86,0x2f,0x86,0x3b,0x86,0x3e,0x86,0x86,0x3b,0x32,0x2f,0x8c,0x3b,0x29,0x2c,0x8c,0x3b,0x32,0x2f,0x8c,0x3b,0x32,0x2f,0x86,0x3b,0x86,0x2a,0x2f,0x33,0x86,0x86,0x33,0x2f,0x2a,0x86,0x3f,0x86,0x33,0x2f,0x2a,0x86,0x3b,0x86,0x33,0x2f,0x2a,0x86,0x3b,0x37,0x86,0x2b,0x2f,0x32,0x86,0x3d,0x86,0x3e,0x37,0x32,0x86,0x3b,0x86,0x3d,0x33,0x2f,0x86,0x3f,0x36,0x86,0x2a,0x2f,0x33,0x86,0x3b,0x86,0x36,0x3f,0x33,0x86,0x3b,0x86,0x3d,0x36,0x34,0x8c,0x3b,0x36,0x33,0x92,0x3b,0x2f,0x86,0x1d,0x20,0x23,0x8c,0x2f,0x3b,0x26,0x8c,0x3b,0x2f,0x26,0x8c,0x3b,0x2f,0x1d,0x86,0x3b,0x2f,0x86,0x27,0x23,0x1e,0x86,0x36,0x86,0x2f,0x38,0x27,0x86,0x33,0x86,0x36,0x1e,0x23,0x86,0x38,0x2f,0x86,0x27,0x23,0x1e,0x86,0x2f,0x2b,0x86,0x26,0x23,0x1f,0x86,0x31,0x86,0x2b,0x32,0x1f,0x86,0x2f,0x86,0x31,0x27,0x23,0x86,0x33,0x2a,0x86,0x27,0x23,0x1e,0x86,0x2f,0x86,0x33,0x2a,0x27,0x86,0x2f,0x86,0x2a,0x31,0x1e,0x8c,0x2f,0x2a,0x27,0x8c,0x3b,0x2f,0x8c,0x3b,0x36,0x33,0x8c,0x2d,0x27,0x23,0x86,0x31,0x33,0x36,0x86,0x15,0x21,0x86,0x36,0x33,0x86,0x31,0x2d,0x27,0x8c,0x2f,0x33,0x36,0x8c,0x2d,0x27,0x23,0x86,0x3b,0x36,0x33,0x86,0x12,0x1e,0x86,0x36,0x33,0x86,0x31,0x1b,0x0f,0x86,0x36,0x33,0x86,0x2f,0x1c,0x10,0x86,0x34,0x86,0x31,0x2c,0x28,0x86,0x34,0x86,0x38,0x23,0x17,0x86,0x2f,0x86,0x34,0x23,0x28,0x86,0x38,0x86,0x31,0x20,0x14,0x86,0x34,0x86,0x38,0x2c,0x28,0x86,0x2f,0x86,0x1c,0x10,0x86,0x38,0x86,0x31,0x11,0x1d,0x86,0x38,0x86,0x3b,0x36,0x33,0x8c,0x2d,0x27,0x23,0x86,0x3b,0x36,0x33,0x86,0x21,0x15,0x86,0x36,0x33,0x86,0x31,0x23,0x27,0x8c,0x3b,0x36,0x33,0x8c,0x2d,0x27,0x23,0x86,0x31,0x33,0x36,0x86,0x1e,0x12,0x86,0x36,0x33,0x86,0x31,0x1b,0x0f,0x86,0x33,0x36,0x86,0x2f,0x10,0x1c,0x86,0x34,0x86,0x31,0x2c,0x28,0x86,0x34,0x86,0x38,0x23,0x17,0x86,0x2f,0x86,0x34,0x2c,0x28,0x86,0x38,0x86,0x31,0x14,0x20,0x86,0x34,0x86,0x38,0x2c,0x28,0x86,0x2f,0x86,0x1c,0x10,0x86,0x38,0x86,0x30,0x1b,0x0f,0x86,0x38,0x36,0x86,0x31,0x35,0x38,0x8c,0x25,0x29,0x2f,0x86,0x3d,0x38,0x35,0x86,0x1d,0x11,0x86,0x35,0x38,0x86,0x33,0x2f,0x29,0x8c,0x3d,0x38,0x35,0x8c,0x25,0x29,0x2f,0x86,0x3d,0x38,0x35,0x86,0x25,0x19,0x86,0x38,0x35,0x86,0x33,0x2f,0x29,0x86,0x38,0x35,0x86,0x1e,0x12,0x86,0x36,0x86,0x3d,0x31,0x25,0x86,0x36,0x86,0x39,0x21,0x15,0x86,0x3f,0x33,0x86,0x2d,0x2a,0x25,0x86,0x36,0x86,0x3d,0x31,0x1e,0x86,0x36,0x86,0x39,0x25,0x2a,0x86,0x3f,0x33,0x86,0x21,0x15,0x86,0x36,0x86,0x3d,0x31,0x2d,0x8c,0x37,0x34,0x22,0x86,0x25,0x86,0x37,0x34,0x86,0x28,0x86,0x33,0x37,0x3f,0x86,0x28,0x86,0x3d,0x37,0x31,0x86,0x22,0x86,0x38,0x2f,0x23,0x86,0x34,0x86,0x36,0x2c,0x28,0x86,0x31,0x39,0x86,0x19,0x86,0x31,0x86,0x38,0x2f,0x29,0x8c,0x38,0x2e,0x1e,0x86,0x34,0x86,0x36,0x28,0x25,0x86,0x2d,0x38,0x86,0x27,0x23,0x86,0x33,0x86,0x36,0x2d,0x27,0x86,0x34,0x2c,0x86,0x1c,0x28,0x86,0x2f,0x3b,0x86,0x2c,0x28,0x23,0x86,0x38,0x86,0x3b,0x2f,0x2c,0x86,0x38,0x86,0x3b,0x2f,0x1d,0x86,0x38,0x86,0x2f,0x33,0x36,0x8c,0x23,0x27,0x2d,0x86,0x3b,0x36,0x33,0x86,0x21,0x15,0x86,0x36,0x33,0x86,0x31,0x2d,0x27,0x8c,0x3b,0x36,0x33,0x8c,0x23,0x27,0x2d,0x86,0x3b,0x36,0x33,0x86,0x1e,0x12,0x86,0x36,0x33,0x86,0x31,0x1b,0x0f,0x86,0x36,0x33,0x86,0x2f,0x1c,0x10,0x86,0x34,0x86,0x31,0x2c,0x28,0x86,0x34,0x86,0x38,0x17,0x23,0x86,0x2f,0x86,0x34,0x2c,0x28,0x86,0x38,0x86,0x31,0x20,0x14,0x86,0x34,0x86,0x38,0x2c,0x28,0x86,0x2f,0x86,0x10,0x1c,0x86,0x38,0x86,0x31,0x1d,0x11,0x86,0x38,0x86,0x3b,0x36,0x33,0x8c,0x2d,0x27,0x23,0x86,0x3b,0x36,0x33,0x86,0x21,0x15,0x86,0x36,0x33,0x86,0x31,0x23,0x27,0x8c,0x3b,0x36,0x33,0x8c,0x2d,0x27,0x23,0x86,0x31,0x33,0x36,0x86,0x1e,0x12,0x86,0x36,0x33,0x86,0x31,0x0f,0x1b,0x86,0x33,0x36,0x86,0x2f,0x1c,0x10,0x86,0x34,0x86,0x31,0x2c,0x28,0x86,0x34,0x86,0x38,0x23,0x17,0x86,0x2f,0x86,0x34,0x23,0x28,0x86,0x38,0x86,0x31,0x20,0x14,0x86,0x34,0x86,0x38,0x2c,0x28,0x86,0x2f,0x86,0x1c,0x10,0x86,0x38,0x86,0x30,0x1b,0x0f,0x86,0x38,0x36,0x86,0x31,0x35,0x38,0x8c,0x2f,0x29,0x25,0x86,0x3d,0x38,0x35,0x86,0x1d,0x11,0x86,0x35,0x38,0x86,0x33,0x2f,0x29,0x8c,0x3d,0x38,0x35,0x8c,0x25,0x29,0x2f,0x86,0x3d,0x38,0x35,0x86,0x25,0x19,0x86,0x38,0x35,0x86,0x33,0x2f,0x29,0x86,0x38,0x35,0x86,0x1e,0x12,0x86,0x36,0x86,0x3d,0x31,0x25,0x86,0x36,0x86,0x39,0x21,0x15,0x86,0x3f,0x33,0x86,0x2d,0x2a,0x25,0x86,0x36,0x86,0x3d,0x31,0x1e,0x86,0x36,0x86,0x39,0x25,0x2a,0x86,0x33,0x3f,0x86,0x21,0x15,0x86,0x36,0x86,0x3d,0x31,0x2d,0x8c,0x37,0x34,0x22,0x86,0x25,0x86,0x34,0x37,0x86,0x28,0x86,0x3f,0x37,0x33,0x86,0x28,0x86,0x3d,0x37,0x31,0x86,0x22,0x86,0x38,0x2f,0x23,0x86,0x34,0x86,0x36,0x2c,0x28,0x86,0x39,0x31,0x86,0x19,0x86,0x31,0x86,0x38,0x2f,0x29,0x8c,0x38,0x2e,0x1e,0x86,0x34,0x86,0x36,0x28,0x25,0x86,0x38,0x2d,0x86,0x27,0x23,0x86,0x33,0x86,0x36,0x2d,0x27,0x86,0x34,0x2c,0x86,0x1c,0x28,0x86,0x34,0x86,0x38,0x23,0x17,0x86,0x3b,0x86,0x34,0x1c,0x10,0x8c,0x27,0x1b,0x8c,0x3b,0x2f,0x28,0x8c,0x38,0x2f,0x23,0x8c,0x2f,0x3b,0x2c,0x8c,0x38,0x2f,0x27,0x8c,0x3b,0x38,0x28,0x8c,0x3d,0x38,0x23,0x86,0x3f,0x38,0x86,0x25,0x19,0x86,0x3d,0x86,0x3b,0x26,0x1a,0x86,0x38,0x86,0x36,0x27,0x1b,0x86,0x38,0x86,0x2a,0x27,0x23,0x86,0x33,0x2f,0x86,0x23,0x27,0x2a,0x8c,0x1e,0x12,0x8c,0x23,0x17,0x86,0x36,0x86,0x38,0x2f,0x27,0x86,0x33,0x86,0x36,0x12,0x1e,0x86,0x38,0x2f,0x86,0x24,0x18,0x86,0x33,0x86,0x36,0x2e,0x25,0x8c,0x38,0x28,0x22,0x86,0x31,0x2e,0x86,0x1e,0x12,0x8c,0x18,0x24,0x8c,0x25,0x19,0x86,0x34,0x86,0x38,0x2e,0x28,0x86,0x31,0x86,0x34,0x1e,0x12,0x86,0x2e,0x38,0x86,0x22,0x16,0x86,0x33,0x2f,0x86,0x17,0x23,0x86,0x36,0x86,0x38,0x2f,0x27,0x86,0x33,0x86,0x36,0x1e,0x12,0x86,0x2f,0x38,0x86,0x27,0x23,0x1e,0x86,0x33,0x2f,0x86,0x17,0x23,0x86,0x36,0x86,0x38,0x2f,0x27,0x86,0x33,0x86,0x36,0x25,0x19,0x86,0x2f,0x38,0x86,0x27,0x1b,0x86,0x36,0x86,0x3b,0x2f,0x28,0x8c,0x38,0x2f,0x23,0x8c,0x3b,0x2f,0x2c,0x8c,0x38,0x2f,0x27,0x8c,0x38,0x3b,0x28,0x8c,0x3d,0x38,0x23,0x86,0x3f,0x38,0x86,0x25,0x19,0x86,0x3d,0x86,0x3b,0x26,0x1a,0x86,0x38,0x86,0x3b,0x27,0x1b,0x8c,0x38,0x2a,0x27,0x8c,0x36,0x23,0x27,0x86,0x3b,0x86,0x1e,0x12,0x86,0x33,0x2f,0x86,0x23,0x17,0x86,0x36,0x86,0x38,0x2f,0x27,0x86,0x33,0x86,0x36,0x12,0x1e,0x86,0x38,0x2f,0x86,0x27,0x23,0x1e,0x86,0x2f,0x2c,0x86,0x1c,0x10,0x86,0x31,0x86,0x2c,0x2f,0x1c,0x8c,0x2f,0x2b,0x19,0x8c,0x31,0x2b,0x11,0x86,0x2f,0x2a,0x86,0x1e,0x12,0x86,0x31,0x86,0x2a,0x33,0x27,0x86,0x2f,0x86,0x31,0x1e,0x12,0x86,0x33,0x2a,0x86,0x1f,0x13,0x86,0x2f,0x29,0x86,0x14,0x20,0x86,0x31,0x86,0x29,0x33,0x20,0x86,0x2f,0x86,0x22,0x16,0x86,0x31,0x28,0x86,0x22,0x16,0x86,0x2a,0x86,0x2f,0x27,0x23,0x8c,0x36,0x2a,0x1e,0x8c,0x2a,0x36,0x25,0x8c,0x36,0x2a,0x27,0x8c,0x3b,0x2f,0x28,0x8c,0x38,0x2f,0x2c,0x8c,0x3b,0x2f,0x23,0x8c,0x2f,0x38,0x27,0x8c,0x3b,0x38,0x28,0x8c,0x3d,0x38,0x2c,0x86,0x3f,0x38,0x86,0x19,0x25,0x86,0x3d,0x86,0x3b,0x26,0x1a,0x86,0x38,0x86,0x36,0x27,0x1b,0x86,0x38,0x86,0x2a,0x27,0x23,0x86,0x33,0x2f,0x86,0x23,0x27,0x2a,0x8c,0x1e,0x12,0x8c,0x23,0x17,0x86,0x36,0x86,0x38,0x2f,0x27,0x86,0x33,0x86,0x36,0x1e,0x12,0x86,0x38,0x2f,0x86,0x18,0x24,0x86,0x33,0x86,0x36,0x2e,0x25,0x8c,0x38,0x28,0x22,0x86,0x31,0x2e,0x86,0x1e,0x12,0x8c,0x24,0x18,0x8c,0x19,0x25,0x86,0x34,0x86,0x38,0x2e,0x28,0x86,0x31,0x86,0x34,0x1e,0x12,0x86,0x38,0x2e,0x86,0x22,0x16,0x86,0x33,0x2f,0x86,0x23,0x17,0x86,0x36,0x86,0x38,0x2f,0x1e,0x86,0x33,0x86,0x36,0x1e,0x12,0x86,0x38,0x2f,0x86,0x27,0x23,0x1e,0x86,0x33,0x2f,0x86,0x23,0x17,0x86,0x36,0x86,0x38,0x2f,0x1e,0x86,0x33,0x86,0x36,0x25,0x19,0x86,0x38,0x2f,0x86,0x27,0x1b,0x86,0x36,0x86,0x3b,0x2f,0x28,0x8c,0x2f,0x38,0x2c,0x8c,0x3b,0x2f,0x23,0x8c,0x38,0x2f,0x27,0x8c,0x3b,0x38,0x28,0x8c,0x3d,0x38,0x2c,0x86,0x38,0x3f,0x86,0x25,0x19,0x86,0x3d,0x86,0x3b,0x1a,0x26,0x86,0x38,0x86,0x3b,0x27,0x1b,0x8c,0x38,0x2a,0x27,0x8c,0x36,0x2a,0x27,0x86,0x3b,0x86,0x12,0x1e,0x86,0x2f,0x33,0x86,0x23,0x17,0x86,0x36,0x86,0x38,0x2f,0x27,0x86,0x33,0x86,0x36,0x1e,0x12,0x86,0x2f,0x38,0x86,0x27,0x23,0x1e,0x86,0x2f,0x2c,0x86,0x10,0x1c,0x86,0x31,0x86,0x2f,0x2c,0x1c,0x8c,0x2f,0x2b,0x19,0x8c,0x2b,0x31,0x1d,0x86,0x2f,0x2a,0x86,0x1e,0x12,0x86,0x31,0x86,0x33,0x2a,0x1e,0x86,0x2f,0x86,0x31,0x1e,0x12,0x86,0x2a,0x33,0x86,0x1f,0x13,0x86,0x2f,0x29,0x86,0x20,0x14,0x86,0x31,0x86,0x33,0x29,0x20,0x86,0x2f,0x86,0x16,0x22,0x86,0x28,0x31,0x86,0x22,0x16,0x86,0x2a,0x86,0x2f,0x27,0x23,0x8c,0x36,0x34,0x2e,0x8c,0x3b,0x36,0x33,0xff +}; + +static const byte* music_ptr = music1; + +inline byte next_music_byte() { + return *music_ptr++; +} + +void play_music() { + byte ch; + byte freech = 0; + soundregs[1] = voice[0].volume | (voice[1].volume<<4); + soundregs[2] = voice[2].volume; + for (ch=0; ch<3; ch++) { + if (voice[ch].volume) { + voice[ch].volume--; + } else { + freech = ch; + } + } + if (music_ptr) { + ch = freech; + while (cur_duration == 0) { + byte note = next_music_byte(); + if ((note & 0x80) == 0) { + if (note >= 12) note - 12; + soundregs[6-ch] = note_table[note & 63]; + voice[ch].volume = 15; + ch = ch ? ch-1 : 2; + } else { + if (note == 0xff) + music_ptr = 0; + cur_duration = note & 63; + } + } + cur_duration--; + set_sound_registers(soundregs); + } +} + +void start_music(const byte* music) { + memset(voice, 0, sizeof(voice)); + music_ptr = music; + cur_duration == 0; +} + +const byte SOUND_INIT[8] = { + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x40, +}; + +void init_sound() { + memcpy(soundregs, SOUND_INIT, 8); + set_sound_registers(soundregs); +} + +void main() { + clrscr(); + init_sound(); + activate_interrupts(); + while (1) { + if (!music_ptr) start_music(music1); + play_music(); + sleep(2); + } +} diff --git a/src/platform/astrocade.ts b/src/platform/astrocade.ts index d6e4a083..390b28a4 100644 --- a/src/platform/astrocade.ts +++ b/src/platform/astrocade.ts @@ -15,6 +15,7 @@ const ASTROCADE_PRESETS = [ {id:'lines.c', name:'Lines'}, {id:'sprites.c', name:'Sprites'}, {id:'vsync.c', name:'Sprites w/ VSYNC'}, + {id:'music.c', name:'Music'}, {id:'cosmic.c', name:'Cosmic Impalas Game'}, ]; @@ -339,6 +340,7 @@ const _BallyAstrocadePlatform = function(mainElement, arcade) { } // interrupt if (sl == inlin && (inmod & 0x8)) { + // TODO: interrupt mode bit 0x4 cpu.requestInterrupt(infbk); } // refresh this line in frame buffer? @@ -458,7 +460,7 @@ const _BallyAstrocadePlatform = function(mainElement, arcade) { s += "\n HORCB: $" + hex(st.horcb); s += "\n INMOD: $" + hex(st.inmod); s += "\n INLIN: " + st.inlin; - s += "\n INFBK: " + st.infbk; + s += "\n INFBK: $" + hex(st.infbk); s += "\n VERBL: " + st.verbl; /* s += "\nPalette: "; diff --git a/src/project.ts b/src/project.ts index 5508a11b..786494ff 100644 --- a/src/project.ts +++ b/src/project.ts @@ -120,7 +120,7 @@ export class CodeProject { } return files; } - + loadFileDependencies(text:string) : Promise { let includes = this.parseIncludeDependencies(text); let linkfiles = this.parseLinkDependencies(text); diff --git a/src/ui.ts b/src/ui.ts index ab6b70cd..90359d34 100644 --- a/src/ui.ts +++ b/src/ui.ts @@ -1182,7 +1182,7 @@ function getDebugExprExamples() : string { if (cpu.SP) s += "c.SP < 0x" + hex(cpu.SP) + "\n"; if (platform.readAddress) s += "this.readAddress(0x1234) == 0x0\n"; if (platform.readVRAMAddress) s += "this.readVRAMAddress(0x1234) != 0x80\n"; - if (platform['getRasterPosition']) s += "this.getRasterPosition().y > 222\n"; + if (platform['getRasterScanline']) s += "this.getRasterScanline() > 222\n"; return s; } diff --git a/src/worker/workermain.ts b/src/worker/workermain.ts index fcf79b49..8d19881e 100644 --- a/src/worker/workermain.ts +++ b/src/worker/workermain.ts @@ -2020,8 +2020,14 @@ function executeBuildSteps() { for (var i=0; i