diff --git a/doc/notes.txt b/doc/notes.txt index d196f1b1..be4e20d3 100644 --- a/doc/notes.txt +++ b/doc/notes.txt @@ -46,7 +46,6 @@ TODO: - debug bankswitching for funky formats - spaces in filename don't parse code listing (DASM, maybe more) - 'undefined' for bitmap replacer -- astrocade: run to cursor in hello world messes up emulation - requestInterrupt needs to be disabled after breakpoint? - C/asm formatter - fix WebAudio (https://news.ycombinator.com/item?id=18066474) @@ -66,6 +65,7 @@ TODO: - sdcc: - can't link asm files before c files (e.g. acheader.s must be last) - figure out area names ordering + - debug inline asm - live coding URL - resize memory browser when vertical div resize - preroll the emulator so optimizer does its thing before loading rom @@ -146,7 +146,7 @@ TODO: - don't have to include bootstrap-tourist each time? - don't have to include firebase always? - squelch error msgs? - - test offline? + - test offline? (if window.firebase) - Github - gh-pages branch with embedded - handle overwrite logic diff --git a/index.html b/index.html index 00248914..85c844f2 100644 --- a/index.html +++ b/index.html @@ -275,6 +275,18 @@ if (window.location.host.endsWith('8bitworkshop.com')) { A W S D Move ←↑↓→ Fire +
diff --git a/presets/astrocade-bios/bios.c b/presets/astrocade-bios/bios.c index 3ab56744..56dd2c7b 100644 --- a/presets/astrocade-bios/bios.c +++ b/presets/astrocade-bios/bios.c @@ -71,12 +71,16 @@ word* USERTB; // user routine table (-128 bytes) // from bmusic.c extern void music_update(void); -// INTERRUPT HANDLERS -// must be in 0x200 page -void hw_interrupt() __naked { - __asm__("ei"); - __asm__("exx"); +// INTERRUPT HANDLER +//#define USE_ALT_REGS +void hw_interrupt() +#ifdef USE_ALT_REGS +__naked { __asm__("ex af,af'"); + __asm__("exx"); +#else +__interrupt { +#endif CT[0]++; CT[1]++; CT[2]++; @@ -97,9 +101,12 @@ void hw_interrupt() __naked { music_update(); } } +#ifdef USE_ALT_REGS __asm__("exx"); __asm__("ex af,af'"); + __asm__("ei"); __asm__("reti"); +#endif } void add_counters(byte mask, byte delta) { @@ -134,11 +141,18 @@ void TIMEY() { void TIMEX() { } + +void DECCTS(ContextBlock *ctx) { + add_counters(_C, -1); +} + +// INTERPRETER void INTPC(ContextBlock *ctx) { while (ctx->params[0] != 2) { // 2 = exit SYSCALL(ctx); } + ctx->params++; // skip EXIT opcode } // never called, hopefully @@ -164,6 +178,10 @@ void MRET(ContextBlock *ctx) { ctx; // TODO } +void NOOP(ContextBlock *ctx) { + ctx; +} + // jump within MCALL void MJUMP(ContextBlock *ctx) { ctx->params = (byte*) _HL; // TODO? @@ -225,13 +243,7 @@ void SETOUT(ContextBlock *ctx) { // set entire palette at once (8 bytes to port 0xb) // bytes in array should be in reverse -void set_palette(byte palette[8]) __z88dk_fastcall { - palette; -__asm - ld bc,#0x80b ; B -> 8, C -> 0xb - otir ; write C bytes from HL to port[B] -__endasm; -} +void set_palette(byte palette[8]) __z88dk_fastcall; // sets color palettes from (HL) void COLSET(ContextBlock *ctx) { @@ -260,25 +272,10 @@ void PAWS(ContextBlock *ctx) { // MATH void MOVE(ContextBlock *ctx) { - byte* dest = (byte*) _DE; - const byte* src = (const byte*) _HL; - word nb = _BC; - memcpy(dest, src, nb); + memcpy((byte*)_DE, (const byte*)_HL, _BC); } -word bcdadd8(byte a, byte b, byte c) { - a;b;c; -__asm - ld a,6(ix) ; carry - rrc a ; set carry bit - ld h,#0 ; carry goes here - ld a,4(ix) ; a -> A - adc a,5(ix) ; a + b -> A - daa ; BCD conversion - ld l,a ; result -> L - rl h ; carry -> H -__endasm; -} +word bcdadd8(byte a, byte b, byte c); void BCDADD(ContextBlock *ctx) { byte* dest = (byte*) _DE; @@ -308,12 +305,7 @@ void RANGED(ContextBlock *ctx) { // input -const byte KCTASC_TABLE[25] = { - 0x00, - 0x43, 0x5e, 0x5c, 0x25, 0x52, 0x53, 0x3b, 0x2f, - 0x37, 0x38, 0x39, 0x2a, 0x34, 0x35, 0x36, 0x2d, - 0x31, 0x32, 0x33, 0x2b, 0x26, 0x30, 0x2e, 0x3d -}; +extern const byte KCTASC_TABLE[25]; void KCTASC(ContextBlock *ctx) { _A = KCTASC_TABLE[_B]; @@ -360,7 +352,7 @@ const SysCallEntry SYSCALL_TABLE[64] = { { &MJUMP, REG_HL }, { &SUCK, REG_B }, { &ACTINT, 0 }, - { 0, 0 }, + { &DECCTS, REG_C }, { &BMUSIC, REG_HL|REG_IX|REG_A }, /* 20 */ { &EMUSIC, }, @@ -369,64 +361,64 @@ const SysCallEntry SYSCALL_TABLE[64] = { { &FILL, REG_A|REG_BC|REG_DE }, { &RECTAN, REG_A|REG_B|REG_C|REG_D|REG_E }, /* 30 */ - { /*&VWRITR*/0, 0 }, + { &NOOP, REG_HL|REG_IX }, // VWRITR { &WRITR, REG_E|REG_D|REG_A|REG_HL }, { &WRITP, REG_E|REG_D|REG_A|REG_HL }, { &WRIT, REG_E|REG_D|REG_C|REG_B|REG_A|REG_HL }, - { /*&WRITA*/0, 0 }, + { &NOOP, REG_E|REG_D|REG_C|REG_B|REG_A|REG_HL }, // WRITA /* 40 */ - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, + { &NOOP, REG_E|REG_D|REG_IX }, // VBLANK + { &NOOP, REG_E|REG_D|REG_B|REG_HL }, // BLANK + { &NOOP, REG_B|REG_C|REG_DE|REG_HL }, // SAVE + { &NOOP, REG_DE|REG_HL }, // RESTORE + { &NOOP, REG_B|REG_C|REG_DE|REG_HL }, // SCROLL /* 50 */ { &CHRDIS, REG_E|REG_D|REG_C|REG_A }, { &STRDIS, REG_E|REG_D|REG_C|REG_HL }, { &DISNUM, REG_E|REG_D|REG_C|REG_B|REG_HL }, - { 0, 0 }, - { 0, 0 }, + { &NOOP, REG_DE|REG_A }, // RELABS + { &NOOP, REG_E|REG_D|REG_A }, // RELAB1 /* 60 */ - { 0, 0 }, - { 0, 0 }, + { &NOOP, REG_IX|REG_HL|REG_C }, // VECTC + { &NOOP, REG_IX|REG_HL }, // VECT { &KCTASC, 0 }, { &SENTRY, REG_DE }, { &DOIT, REG_HL }, /* 70 */ { &DOITB, REG_HL }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, + { &NOOP, 0 }, // PIZBRK + { &NOOP, REG_DE|REG_HL }, // MENU + { &NOOP, REG_BC|REG_HL }, // GETPAR + { &NOOP, REG_B|REG_C|REG_D|REG_E|REG_HL }, // GETNUM /* 80 */ { &PAWS, REG_B }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, + { &NOOP, REG_E|REG_D|REG_C }, // DISTIM + { &NOOP, REG_HL }, // INCSCR + { &NOOP, REG_C|REG_HL }, // INDEXN + { &NOOP, REG_HL }, // STOREN /* 90 */ - { 0, 0 }, - { 0, 0 }, + { &NOOP, REG_A|REG_HL }, // INDEXW + { &NOOP, REG_A|REG_HL }, // INDEXB { &MOVE, REG_DE|REG_BC|REG_HL }, - { 0, 0 }, + { &NOOP, 0 }, // SHIFTU { &BCDADD, REG_DE|REG_B|REG_HL }, /* 100 */ - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, + { &NOOP, 0 }, // BCDSUB + { &NOOP, 0 }, // BCDMUL + { &NOOP, 0 }, // BCDDIV + { &NOOP, 0 }, // BCDCHS + { &NOOP, 0 }, // BCDNEG /* 110 */ - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, + { &NOOP, 0 }, // DADD + { &NOOP, 0 }, // DSMG + { &NOOP, 0 }, // DABS + { &NOOP, 0 }, // NEGT { &RANGED, REG_A }, /* 120 */ - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, + { &NOOP, 0 }, // QUIT + { &NOOP, REG_A|REG_HL }, // SETB + { &NOOP, REG_DE|REG_HL }, // SETW + { &NOOP, REG_C|REG_DE|REG_HL }, // MSKTD }; void SYSCALL(ContextBlock *ctx) { @@ -447,22 +439,17 @@ void SYSCALL(ContextBlock *ctx) { suckParams(ctx, argmask); } // call the routine - if (routine) { - routine(ctx); - } + routine(ctx); } void bios_init() { + ContextBlock ctx; memset((void*)0x4fce, 0, 0x5000-0x4fce); ACTINT(0); hw_verbl = 96*2; hw_horcb = 41; hw_inmod = 0x8; - // clear shifter - hw_magic = 0; - *((byte*)0x4fce) = 0; - hw_magic = 0; // call SENTRY once to set current values // (context block doesn't matter) - SENTRY((ContextBlock*)0x4fce); + SENTRY(&ctx); } diff --git a/presets/astrocade-bios/biosasm.s b/presets/astrocade-bios/biosasm.s index b35358bc..e7ff624e 100644 --- a/presets/astrocade-bios/biosasm.s +++ b/presets/astrocade-bios/biosasm.s @@ -1,10 +1,8 @@ -;#link "bioslib.c" - TEST = 1 - .module biosasm - .globl _STIMER,_CTIMER,_BIGFONT,_SMLFONT +.module biosasm +.globl _STIMER,_CTIMER,_BIGFONT,_SMLFONT BIOSStart: di ; disable interrupts @@ -33,8 +31,9 @@ FoundSentinel: ld H,(HL) ld L,A jp (HL) ; jump to cart start vector - .ds 0x38 - (. - BIOSStart) ; eat up space until 0x38 - .globl SYSCALL38 + +.ds 0x38 - (. - BIOSStart) ; eat up space until 0x38 +.globl SYSCALL38 SYSCALL38: push hl push af @@ -56,53 +55,44 @@ SYSCALL38: ret ; out to port - .globl _portOut +.globl _portOut _portOut: ld c,h out (c),l ret -; TODO? -ReloadRegs: - ld c,(hl) - inc hl - ld b,(hl) - inc hl - push bc - pop iy - ld c,(hl) - inc hl - ld b,(hl) - inc hl - push bc +.globl _bcdadd8 +_bcdadd8: + push ix + ld ix,#0 + add ix,sp + ld a,6(ix) ; carry + rrc a ; set carry bit + ld h,#0 ; carry goes here + ld a,4(ix) ; a -> A + adc a,5(ix) ; a + b -> A + daa ; BCD conversion + ld l,a ; result -> L + rl h ; carry -> H pop ix - ld c,(hl) - inc hl - ld b,(hl) - inc hl - push bc - pop de - ld c,(hl) - inc hl - ld b,(hl) - inc hl - push bc - ld c,(hl) - inc hl - ld b,(hl) - inc hl - push bc - pop af - ld c,(hl) - inc hl - ld b,(hl) - inc hl - push bc - pop hl - pop bc - ret - .ds 0x200 - (. - BIOSStart) ; eat up space until 0x200 + ret +;void set_palette(byte palette[8]) __z88dk_fastcall; +.globl _set_palette +_set_palette: + ld bc,#0x80b ; B -> 8, C -> 0xb + otir ; write C bytes from HL to port[B] + ret + +.globl _KCTASC_TABLE +_KCTASC_TABLE: +.db 0x00 +.db 0x43, 0x5e, 0x5c, 0x25, 0x52, 0x53, 0x3b, 0x2f +.db 0x37, 0x38, 0x39, 0x2a, 0x34, 0x35, 0x36, 0x2d +.db 0x31, 0x32, 0x33, 0x2b, 0x26, 0x30, 0x2e, 0x3d + + + .ds 0x200 - (. - BIOSStart) ; eat up space until 0x200 DOPEVector: JP _STIMER JP _CTIMER @@ -110,5 +100,8 @@ DOPEVector: .dw _BIGFONT .db 0xa0, 4, 6, 1, 5 ; Font descriptor (small font) .dw _SMLFONT - + .db 0x3f ; all keys mask + .db 0x3f + .db 0x3f + .db 0x3f diff --git a/presets/astrocade-bios/gfx.c b/presets/astrocade-bios/gfx.c index 70962ed8..d74eb330 100644 --- a/presets/astrocade-bios/gfx.c +++ b/presets/astrocade-bios/gfx.c @@ -147,7 +147,7 @@ void CHRDIS(ContextBlock *ctx) { } // BCD routine -const char BCDTAB[17] = "0123456789*+,-./"; +const char BCDTAB[18] = "0123456789*+,-./ "; // DISNUM - (E.D) x/y (C) options (B) ext (HL) BCD-addr void DISNUM(ContextBlock *ctx) { @@ -170,6 +170,11 @@ void DISNUM(ContextBlock *ctx) { val &= 15; pbcd--; } + if (val == 0 && noleadingzero) { + val = 16; + } else { + noleadingzero = 0; + } x += draw_char(font, BCDTAB[val]+add, x, y, opt); } } diff --git a/presets/astrocade-bios/input.c b/presets/astrocade-bios/input.c index b7ca9edb..3e62aa10 100644 --- a/presets/astrocade-bios/input.c +++ b/presets/astrocade-bios/input.c @@ -55,6 +55,7 @@ void SENTRY(ContextBlock *ctx) { } } // key up? + // TODO: race condition with KEYSEX and interrupt if (key && key != KEYSEX) { B = KEYSEX = key; A = SKYD; diff --git a/presets/astrocade-bios/test1.s b/presets/astrocade-bios/test1.s index a19d32f4..ed5ce57d 100644 --- a/presets/astrocade-bios/test1.s +++ b/presets/astrocade-bios/test1.s @@ -19,7 +19,7 @@ _main: pop ix SYSTEM INTPC DO SETOUT - .db 89*2, 23, 0x00 + .db 102*2, 23, 0x00 DONT EMUSIC DONT ACTINT DO COLSET @@ -89,11 +89,12 @@ _main: .dw 3 .dw _BCDNUM DO BMUSIC - .dw 0x4000 + .dw 0x4e80 .db 0b11111100 .dw ANTHEM ; exit interpreter EXIT + nop .loop: SYSSUK DISNUM .db 80 @@ -149,7 +150,7 @@ keymask: BCDNUM = 0x4ea0 ; RAM _BCDNUM: - .db 0x97,0x34,0x12 + .db 0x97,0x99,0x09 BCDINC: .db 0x01,0x00,0x00 ; Critter Pattern diff --git a/presets/astrocade/acbios.h b/presets/astrocade/acbios.h index 59b833a9..0dbb79eb 100644 --- a/presets/astrocade/acbios.h +++ b/presets/astrocade/acbios.h @@ -15,8 +15,41 @@ typedef struct { const byte* chartab; } FontDescriptor; -const FontDescriptor __at(0x206) FNTSYS; -const FontDescriptor __at(0x20d) FNTSML; +const FontDescriptor __at(0x206) FNTSYS; // system font +const FontDescriptor __at(0x20d) FNTSML; // small font +const byte __at(0x214) ALKEYS[4]; // "all keys" keyboard mask + +// SENTRY + +typedef enum { + SNUL, + SCT0,SCT1,SCT2,SCT3,SCT4,SCT5,SCT6,SCT7, + SF0,SF1,SF2,SF3,SF4,SF5,SF6,SF7, + SSEC, + SKYU,SKYD, + ST0,SJ0,ST1,SJ1,ST2,SJ2,ST3,SJ3, + SP0,SP1,SP2,SP3 +} SENTRYCode; + +typedef struct { + byte code; + word address; +} DOITEntry; + +#define DOIT_END 0xff + +// PATTERNS + +typedef struct { + sbyte xofs, yofs; + byte xsize, ysize; + byte pattern[0]; +} RelativeBlock; + +typedef struct { + byte xsize, ysize; + byte pattern[0]; +} PatternBlock; // FUNCTIONS @@ -47,8 +80,11 @@ void display_bcd_number(byte x, byte y, byte options, const byte* number, byte e void bcdn_add(byte* dest, byte size, const byte* n); void bcdn_sub(byte* dest, byte size, const byte* n); byte ranged_random(byte n) __z88dk_fastcall; +byte keycode_to_ascii(byte n) __z88dk_fastcall; -word sense_transition(const byte* keypad_mask) __z88dk_fastcall; +word sense_transition(const byte keypad_mask[4]) __z88dk_fastcall; +void respond_to_input(const DOITEntry* doit_table, byte a); +void respond_to_input_b(const DOITEntry* doit_table, byte b); void begin_music(const byte* stack, byte voices, const byte* musicdata); void end_music(void); @@ -69,6 +105,13 @@ void end_music(void); __asm__(".dw "#count);\ __asm__(".db "#val);\ +#define SYS_MOVE(dest,src,count)\ + __asm__("rst 0x38");\ + __asm__(".db 0x5f");\ + __asm__(".dw "#dest);\ + __asm__(".dw "#count);\ + __asm__(".dw "#src);\ + #define RESET_TIMEOUT() \ __asm__("ld a,#0xff");\ __asm__("ld (0x4FEC),a"); diff --git a/presets/astrocade/acbios.s b/presets/astrocade/acbios.s index 57b0ef24..72ebd7fb 100644 --- a/presets/astrocade/acbios.s +++ b/presets/astrocade/acbios.s @@ -3,7 +3,7 @@ ;;; C functions - .area _LIB + .area _CODE_ACBIOS ; activate interrupts .globl _activate_interrupts @@ -99,6 +99,13 @@ _ranged_random: SYSTEM RANGED ret +; KCTASC n + .globl _keycode_to_ascii +_keycode_to_ascii: + ld a,l + SYSTEM KCTASC + ret + ; BLANK w h data video-addr .globl _blank_area _blank_area: @@ -116,6 +123,20 @@ _sense_transition: ld h,b ret +; DOIT table-addr + .globl _respond_to_input +_respond_to_input: + call load5_edca_hl + SYSTEM DOIT + ret + +; DOITB table-addr + .globl _respond_to_input_b +_respond_to_input_b: + call load5_edca_hl + SYSTEM DOIT + ret + ; BMUSIC stack-addr voices score-addr .globl _begin_music _begin_music: diff --git a/presets/astrocade/acextra.h b/presets/astrocade/acextra.h index 61524515..c9e61ba9 100644 --- a/presets/astrocade/acextra.h +++ b/presets/astrocade/acextra.h @@ -4,6 +4,9 @@ #include "aclib.h" +// special case for draw_sprite() +#define M_ERASE 0x04 + // font constants #define LOCHAR 32 #define HICHAR 127 diff --git a/presets/astrocade/acfast.s b/presets/astrocade/acfast.s new file mode 100644 index 00000000..900e49f8 --- /dev/null +++ b/presets/astrocade/acfast.s @@ -0,0 +1,34 @@ + + +.area _CODE_ACFAST + +;void fast_sprite_8(const byte* src, byte* dst) { +.globl _fast_sprite_8 +_fast_sprite_8: + push ix + ld ix,#0 + add ix,sp + ld l,4(ix) ; src (HL) + ld h,5(ix) + ld e,6(ix) ; dst (DE) + ld d,7(ix) + inc hl ; skip width + ld c,(hl) ; load height -> C + sla c ; C *= 2 + ld b,#0 ; B always 0 (BC < 256) + inc hl ; move to pattern bytes +001$: + ldi + ldi ; copy 2 bytes src to dst + ld a,b ; 0 -> A, doesnt affect flags + ld (de),a ; copy 3rd 0 (for shifts) + jp po,002$ ; exit if BC == 0 + ld a,e ; E -> A + add a,#38 ; next scanline (dest += 38) + ld e,a ; A -> E + jr nc,001$ ; loop unless lo byte overflow + inc d ; inc hi byte of dest. addr + jr 001$ ; loop to next line +002$: + pop ix + ret diff --git a/presets/astrocade/aclib.h b/presets/astrocade/aclib.h index e1c5ff21..7e87e11b 100644 --- a/presets/astrocade/aclib.h +++ b/presets/astrocade/aclib.h @@ -52,14 +52,16 @@ __sfr __at(0x18) hw_sndbx; #define M_SHIFT1 0x01 #define M_SHIFT2 0x02 #define M_SHIFT3 0x03 +#define M_ROTATE 0x04 #define M_XPAND 0x08 #define M_MOVE 0x00 #define M_OR 0x10 #define M_XOR 0x20 #define M_FLOP 0x40 + #define M_SHIFT(x) ((x)&3) + #define XPAND_COLORS(off,on) (((off)&3) | (((on)&3)<<2)) -#define M_ERASE 0x04 // special case for draw_sprite() #define VTOTAL 102 // number of total scanlines #define VHEIGHT 89 // number of scanlines in use diff --git a/presets/astrocade/fastsprites.c b/presets/astrocade/fastsprites.c new file mode 100644 index 00000000..b5a2f297 --- /dev/null +++ b/presets/astrocade/fastsprites.c @@ -0,0 +1,87 @@ + +//#resource "astrocade.inc" +#include "aclib.h" +//#link "aclib.c" +#include "acbios.h" +//#link "acbios.s" +//#link "acfast.s" +//#link "hdr_autostart.s" + +#includeCould not import " + githuburl + ".
" + e); }); } function _loginToGithub(e) { getGithubService().login().then(() => { alertInfo("You are signed in to Github."); + }).catch( (e) => { + alertError("Could not sign in.
" + e); }); } @@ -1180,6 +1182,7 @@ function getDebugExprExamples() : string { var s = ''; if (cpu.PC) s += "c.PC == 0x" + hex(cpu.PC) + "\n"; if (cpu.SP) s += "c.SP < 0x" + hex(cpu.SP) + "\n"; + if (cpu['HL']) s += "c.HL == 0x4000\n"; if (platform.readAddress) s += "this.readAddress(0x1234) == 0x0\n"; if (platform.readVRAMAddress) s += "this.readVRAMAddress(0x1234) != 0x80\n"; if (platform['getRasterScanline']) s += "this.getRasterScanline() > 222\n"; @@ -1641,7 +1644,9 @@ function installErrorHandler() { setDebugButtonState("pause", "stopped"); // TODO? } else { // send exception msg to GA - var msg = msgevent + " (" + line + ":" + col + "): " + error + " - " + url; + var msg = msgstr; + if (typeof error == 'string') msg += ": " + error; + if (line) msg += " (" + line + ":" + col + ")"; if (msg.length > 256) { msg = msg.substring(0, 256); } if (ga) ga('send', 'exception', { 'exDescription': msg, @@ -1910,6 +1915,8 @@ function convertLegacyVCS(store) { } } +// HTTPS REDIRECT + const useHTTPSCookieName = "__use_https"; function setHTTPSCookie(val : number) {