From cdc04a9cd54760356ceee0fce3db44e049daad44 Mon Sep 17 00:00:00 2001 From: Steven Hugg Date: Thu, 6 Jun 2019 15:40:31 -0400 Subject: [PATCH] astrocade: use aclib.s not aclib.c, rainbow, rotate; use AstroLibre --- Makefile | 3 ++ presets/astrocade-bios/bios.c | 27 +++++++++++-- presets/astrocade-bios/gfx.c | 23 +++++++---- presets/astrocade-bios/test1.s | 8 +++- presets/astrocade/acfast.s | 43 ++++++++++++++++++-- presets/astrocade/aclib.c | 26 ------------ presets/astrocade/aclib.h | 6 +++ presets/astrocade/aclib.s | 37 +++++++++++++++++ presets/astrocade/cosmic.c | 2 +- presets/astrocade/fastsprites.c | 5 ++- presets/astrocade/hello.c | 21 ++++++++-- presets/astrocade/lines.c | 3 +- presets/astrocade/music.c | 3 +- presets/astrocade/rainbow.c | 50 +++++++++++++++++++++++ presets/astrocade/rotate.c | 70 +++++++++++++++++++++++++++++++++ presets/astrocade/skeleton.sdcc | 2 +- presets/astrocade/sprites.c | 3 +- presets/astrocade/vsync.c | 2 +- src/platform/astrocade.ts | 46 ++++++++++++++++++---- src/ui.ts | 1 + 20 files changed, 318 insertions(+), 63 deletions(-) delete mode 100644 presets/astrocade/aclib.c create mode 100644 presets/astrocade/aclib.s create mode 100644 presets/astrocade/rainbow.c create mode 100644 presets/astrocade/rotate.c diff --git a/Makefile b/Makefile index 6a2c8cb9..016d7630 100644 --- a/Makefile +++ b/Makefile @@ -29,3 +29,6 @@ tsweb: ifconfig | grep inet $(TSC) -w & python3 scripts/serveit.py 2>> http.out + +astrolibre.b64.txt: astrolibre.rom + lzg -9 $< | base64 -w 0 > $@ diff --git a/presets/astrocade-bios/bios.c b/presets/astrocade-bios/bios.c index 56dd2c7b..76481938 100644 --- a/presets/astrocade-bios/bios.c +++ b/presets/astrocade-bios/bios.c @@ -149,7 +149,7 @@ void DECCTS(ContextBlock *ctx) { // INTERPRETER void INTPC(ContextBlock *ctx) { - while (ctx->params[0] != 2) { // 2 = exit + while (ctx->params[0] > 2) { // 0,2 = exit SYSCALL(ctx); } ctx->params++; // skip EXIT opcode @@ -303,6 +303,25 @@ void RANGED(ContextBlock *ctx) { } } +void INDEXB(ContextBlock *ctx) { + word addr = _HL + _A; + _HL = addr; + _A = *((byte*)addr); +} + +void INDEXW(ContextBlock *ctx) { + word addr = _HL + _A*2; + _HL = addr; + _DE = *((word*)addr); +} + +void INDEXN(ContextBlock *ctx) { + byte ofs = _C; + word addr = _HL + ofs/2; + byte val = *((byte*)addr); + _A = (ofs & 1) ? (val>>4) : (val&0xf); +} + // input extern const byte KCTASC_TABLE[25]; @@ -394,11 +413,11 @@ const SysCallEntry SYSCALL_TABLE[64] = { { &PAWS, REG_B }, { &NOOP, REG_E|REG_D|REG_C }, // DISTIM { &NOOP, REG_HL }, // INCSCR - { &NOOP, REG_C|REG_HL }, // INDEXN + { &INDEXN, REG_C|REG_HL }, // INDEXN { &NOOP, REG_HL }, // STOREN /* 90 */ - { &NOOP, REG_A|REG_HL }, // INDEXW - { &NOOP, REG_A|REG_HL }, // INDEXB + { &INDEXW, REG_A|REG_HL }, // INDEXW + { &INDEXB, REG_A|REG_HL }, // INDEXB { &MOVE, REG_DE|REG_BC|REG_HL }, { &NOOP, 0 }, // SHIFTU { &BCDADD, REG_DE|REG_B|REG_HL }, diff --git a/presets/astrocade-bios/gfx.c b/presets/astrocade-bios/gfx.c index d74eb330..5aac54e2 100644 --- a/presets/astrocade-bios/gfx.c +++ b/presets/astrocade-bios/gfx.c @@ -6,17 +6,24 @@ #define LOCHAR 0x20 #define HICHAR 0x63 +const byte LMASK[4] = {0xff, 0x3f, 0x0f, 0x03}; + static void hline(byte x1, byte x2, byte y, byte pattern) { byte xb1 = x1/4; byte xb2 = x2/4; - byte* dest = &vmagic[y][xb1]; - signed char nbytes = xb2 - xb1; - hw_magic = M_SHIFT(x1) | M_XOR; - while (--nbytes > 0) { - *dest++ = pattern; + byte* dest = &vidmem[y][xb1]; + byte mask = LMASK[x1&3]; + if (xb1 == xb2) { + mask &= ~LMASK[x2&3]; + } + *dest = *dest & ~mask | (mask & pattern); + if (xb1 != xb2) { + dest++; + while (++xb1 < xb2) { + *dest++ = pattern; + } + *dest = *dest & LMASK[x2&3] | (~LMASK[x2&3] & pattern); } - if (x2&3) *dest = 0; - // TODO } // Fill rect (E,D,C,B) color A @@ -181,11 +188,11 @@ void DISNUM(ContextBlock *ctx) { // write pattern (E,D,C,B) magic A @ HL void WRIT(ContextBlock *ctx) { - byte magic = _A; byte w = _C; byte h = _B; byte x = _E; byte y = _D; + byte magic = _A | (x & 3); // add X shift byte* src = (byte*) _HL; byte* dest = &vmagic[y][0]; // destination address byte xb = (magic & M_FLOP) ? (39-(x>>2)) : (x>>2); diff --git a/presets/astrocade-bios/test1.s b/presets/astrocade-bios/test1.s index ed5ce57d..782b0179 100644 --- a/presets/astrocade-bios/test1.s +++ b/presets/astrocade-bios/test1.s @@ -58,7 +58,13 @@ _main: .db 72 .db 100 .db 4 - .db 0xa5 + .db 0xaa + DO RECTAN + .db 6 + .db 74 + .db 100 + .db 4 + .db 0x55 DO WRITR .db 50 .db 80 diff --git a/presets/astrocade/acfast.s b/presets/astrocade/acfast.s index 900e49f8..c53f4484 100644 --- a/presets/astrocade/acfast.s +++ b/presets/astrocade/acfast.s @@ -1,5 +1,8 @@ - +; FAST SPRITE ROUTINES FOR ASTROCADE +; fast_sprite_8: 8 (2 bytes) by H pixels, unexpanded +; fast_sprite_16: 16 (4 bytes) by H pixels, unexpanded +; Pattern format: bytewidth height data... .area _CODE_ACFAST ;void fast_sprite_8(const byte* src, byte* dst) { @@ -7,7 +10,7 @@ _fast_sprite_8: push ix ld ix,#0 - add ix,sp + add ix,sp ; IX = arg pointer ld l,4(ix) ; src (HL) ld h,5(ix) ld e,6(ix) ; dst (DE) @@ -16,7 +19,7 @@ _fast_sprite_8: ld c,(hl) ; load height -> C sla c ; C *= 2 ld b,#0 ; B always 0 (BC < 256) - inc hl ; move to pattern bytes + inc hl ; move HL to pattern start 001$: ldi ldi ; copy 2 bytes src to dst @@ -32,3 +35,37 @@ _fast_sprite_8: 002$: pop ix ret + +;void fast_sprite_16(const byte* src, byte* dst) { +.globl _fast_sprite_16 +_fast_sprite_16: + push ix + ld ix,#0 + add ix,sp ; IX = arg pointer + 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 + sla c ; C *= 4 + ld b,#0 ; B always 0 (BC < 256) + inc hl ; move HL to pattern start +001$: + ldi + ldi + ldi + ldi ; copy 4 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,#36 ; 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.c b/presets/astrocade/aclib.c deleted file mode 100644 index c079292f..00000000 --- a/presets/astrocade/aclib.c +++ /dev/null @@ -1,26 +0,0 @@ - -#include -#include "aclib.h" - -#pragma opt_code_speed - -// 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; -} - -// 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] -__endasm; -} - diff --git a/presets/astrocade/aclib.h b/presets/astrocade/aclib.h index 7e87e11b..e6ee3f62 100644 --- a/presets/astrocade/aclib.h +++ b/presets/astrocade/aclib.h @@ -78,4 +78,10 @@ byte __at (0x4000) vidmem[VTOTAL][VBWIDTH]; void set_palette(byte palette[8]) __z88dk_fastcall; // palette in reverse order void set_sound_registers(byte regs[8]) __z88dk_fastcall; // in reverse too +// INTERRUPTS + +typedef void (*t_interrupt_handler)(void) __interrupt; + +void set_interrupt_vector(t_interrupt_handler*ih) __z88dk_fastcall; + #endif diff --git a/presets/astrocade/aclib.s b/presets/astrocade/aclib.s new file mode 100644 index 00000000..1387b0a8 --- /dev/null +++ b/presets/astrocade/aclib.s @@ -0,0 +1,37 @@ + + .include "astrocade.inc" + +;;; C functions + + .area _CODE_ACLIB + +; 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 { +.globl _set_palette +_set_palette: + ld bc,#0x80b ; B -> 8, C -> 0xb + otir ; write C bytes from HL to port[B] + ret + +; 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 { +.globl _set_sound_registers +_set_sound_registers: + ld bc,#0x818 ; B -> 8, C -> 0x18 + otir ; write C bytes from HL to port[B] + ret + +; set interrupt vector +; pass address of 16-bit pointer to routine +.globl _set_interrupt_vector +_set_interrupt_vector: + di + ld a,l + out (INFBK),a + ld a,h ; upper 8 bits of address + ld i,a ; -> I + im 2 ; mode 2 + ei ; enable interrupts + ret diff --git a/presets/astrocade/cosmic.c b/presets/astrocade/cosmic.c index 95a64dff..007e8699 100644 --- a/presets/astrocade/cosmic.c +++ b/presets/astrocade/cosmic.c @@ -11,7 +11,7 @@ #include "acbios.h" //#link "acbios.s" #include "aclib.h" -//#link "aclib.c" +//#link "aclib.s" #include "acextra.h" //#link "acextra.c" //#link "hdr_autostart.s" diff --git a/presets/astrocade/fastsprites.c b/presets/astrocade/fastsprites.c index b5a2f297..933d9aa8 100644 --- a/presets/astrocade/fastsprites.c +++ b/presets/astrocade/fastsprites.c @@ -1,7 +1,7 @@ //#resource "astrocade.inc" #include "aclib.h" -//#link "aclib.c" +//#link "aclib.s" #include "acbios.h" //#link "acbios.s" //#link "acfast.s" @@ -26,6 +26,7 @@ const byte SPRITE[] = { }; extern void fast_sprite_8(const byte* pattern, byte* dst); +extern void fast_sprite_16(const byte* pattern, byte* dst); #define MAX_SPRITES 8 @@ -69,7 +70,7 @@ void main(void) { // fill array for (i=0; i +#include + +#pragma opt_code_speed + +// we have a special interrupt handler that sets +// palette colors every 4 lines +byte linenum = 0; + +void inthandler(void) __interrupt { + byte i = linenum; + hw_col0l = i; + hw_col1l = i+1; + hw_col2l = i+2; + hw_col3l = i+3; + i += 4; + if (i > 200) i = 0; + hw_inlin = i; + linenum = i; +} + +// pointer to the interrupt handler +const t_interrupt_handler const intvector = &inthandler; + +// patterns to fill each 4-line scanline group +const byte FILLPATS[4] = { 0x00, 0x55, 0xaa, 0xff }; + +void main(void) { + // fill screen with colors 0-3 every 4 scanlines + for (byte i=0; i<89; i++) { + memset(&vidmem[i], FILLPATS[i&3], 40); + } + // set our custom interrupt vector + set_interrupt_vector(&intvector); + // set screen height + // set horizontal color split (position / 4) + // set interrupt status (on) + SYS_SETOUT(89*2, 20, 0x8); + // infinite loop + // let the interrupt handler do the work + while (1) ; +} diff --git a/presets/astrocade/rotate.c b/presets/astrocade/rotate.c new file mode 100644 index 00000000..119f4177 --- /dev/null +++ b/presets/astrocade/rotate.c @@ -0,0 +1,70 @@ + +//#resource "astrocade.inc" +#include "aclib.h" +//#link "aclib.s" +//#link "hdr_autostart.s" +#include "acbios.h" +//#link "acbios.s" + +#include +#include + +/*{pal:"astrocade",layout:"astrocade"}*/ +const byte palette[8] = { + 0x77, 0xD4, 0x35, 0x01, + 0x07, 0xD4, 0x35, 0x01, +}; + +const byte BALL[] = { + 0, 0, // x and y offset + 1, 4, // width (bytes) and height (lines) + /*{w:4,h:4,bpp:2,brev:1}*/ + 0xA0, + 0xD0, + 0xC4, + 0xC1 +}; + +void draw_pattern(byte x) { + vmagic[0][x] = BALL[4]; + vmagic[1][x] = BALL[5]; + vmagic[2][x] = BALL[6]; + vmagic[3][x] = BALL[7]; +} + +void draw_pattern_inv(byte x) { + vmagic[3][x] = BALL[4]; + vmagic[2][x] = BALL[5]; + vmagic[1][x] = BALL[6]; + vmagic[0][x] = BALL[7]; +} + +void main(void) { + // setup palette + set_palette(palette); + // set screen height + // set horizontal color split (position / 4) + // set interrupt status + SYS_SETOUT(89*2, 23, 0); + // clear screen + SYS_FILL(0x4000, 89*40, 0); + // draw pattern + hw_magic = M_ROTATE; + draw_pattern(0); + draw_pattern(2); + // draw pattern flopped + hw_magic = M_ROTATE|M_FLOP; + draw_pattern(4); + draw_pattern(6); + // draw pattern + hw_magic = M_ROTATE; + draw_pattern_inv(8); + draw_pattern_inv(10); + // draw pattern flopped + hw_magic = M_ROTATE|M_FLOP; + draw_pattern_inv(12); + draw_pattern_inv(14); + + while (1) { + } +} diff --git a/presets/astrocade/skeleton.sdcc b/presets/astrocade/skeleton.sdcc index aeea7431..7ebd0a78 100644 --- a/presets/astrocade/skeleton.sdcc +++ b/presets/astrocade/skeleton.sdcc @@ -1,7 +1,7 @@ //#resource "astrocade.inc" #include "aclib.h" -//#link "aclib.c" +//#link "aclib.s" #include "acbios.h" //#link "acbios.s" //#link "hdr_autostart.s" diff --git a/presets/astrocade/sprites.c b/presets/astrocade/sprites.c index a08d13d9..e9991e0e 100644 --- a/presets/astrocade/sprites.c +++ b/presets/astrocade/sprites.c @@ -1,8 +1,9 @@ #include +//#resource "astrocade.inc" #include "aclib.h" -//#link "aclib.c" +//#link "aclib.s" #include "acbios.h" //#link "acbios.c" #include "acextra.h" diff --git a/presets/astrocade/vsync.c b/presets/astrocade/vsync.c index f7bac6d3..0dccd5b4 100644 --- a/presets/astrocade/vsync.c +++ b/presets/astrocade/vsync.c @@ -3,7 +3,7 @@ //#resource "astrocade.inc" #include "aclib.h" -//#link "aclib.c" +//#link "aclib.s" #include "acbios.h" //#link "acbios.s" //#link "hdr_autostart.s" diff --git a/src/platform/astrocade.ts b/src/platform/astrocade.ts index 2a22ae60..e49e1374 100644 --- a/src/platform/astrocade.ts +++ b/src/platform/astrocade.ts @@ -15,7 +15,10 @@ const ASTROCADE_PRESETS = [ {id:'lines.c', name:'Lines'}, {id:'sprites.c', name:'Sprites'}, {id:'vsync.c', name:'Sprites w/ VSYNC'}, + {id:'fastsprites.c', name:'Fast Sprites'}, {id:'music.c', name:'Music'}, + {id:'rotate.c', name:'Rotate Op'}, + {id:'rainbow.c', name:'Rainbow'}, {id:'cosmic.c', name:'Cosmic Impalas Game'}, ]; @@ -94,6 +97,8 @@ const _BallyAstrocadePlatform = function(mainElement, arcade) { var palette = new Uint32Array(8); var refreshlines = 0; var vidactive = false; + var rotdata = new Uint8Array(4); + var rotcount = 0; function ramwrite(a:number, v:number) { ram.mem[a] = v; @@ -129,11 +134,27 @@ const _BallyAstrocadePlatform = function(mainElement, arcade) { v = v2; xplower = !xplower; } - // shift - var sh = (magicop & 3) << 1; - var v2 = (v >> sh) | shift2; - shift2 = (v << (8-sh)) & 0xff; - v = v2; + // rotate + if (magicop & 0x4) { + if (rotcount & 4) { + // drain buffer + var sh = 2 * (~rotcount & 3); + v = (((rotdata[3] >> sh) & 3) << 6) | + (((rotdata[2] >> sh) & 3) << 4) | + (((rotdata[1] >> sh) & 3) << 2) | + (((rotdata[0] >> sh) & 3) << 0); + } else { + // fill buffer + rotdata[rotcount & 3] = v; + } + rotcount++; + } else { + // shift + var sh = (magicop & 3) << 1; + var v2 = (v >> sh) | shift2; + shift2 = (v << (8-sh)) & 0xff; + v = v2; + } // flop if (magicop & 0x40) { v = @@ -187,7 +208,8 @@ const _BallyAstrocadePlatform = function(mainElement, arcade) { start = function() { ram = new RAM(arcade ? 0x5000 : 0x1000); - bios = padBytes(ASTROCADE_MINIMAL_BIOS, 0x2000); + //bios = padBytes(ASTROCADE_MINIMAL_BIOS, 0x2000); + bios = padBytes(new lzgmini().decode(stringToByteArray(atob(ASTROLIBRE_BIOS_LZG))), 0x2000); if (!arcade) { // game console membus = { @@ -264,7 +286,8 @@ const _BallyAstrocadePlatform = function(mainElement, arcade) { break; case 0xc: // magic register magicop = val; - shift2 = 0; // TODO? + shift2 = 0; + rotcount = 0; xplower = false; break; case 0xd: // INFBK (interrupt feedback) @@ -384,6 +407,8 @@ const _BallyAstrocadePlatform = function(mainElement, arcade) { inlin = state.inlin; infbk = state.infbk; verbl = state.verbl; + rotcount = state.rotcount; + rotdata.set(state.rotdata); this.scanline = state.sl; this.loadControlsState(state); refreshall(); @@ -403,6 +428,8 @@ const _BallyAstrocadePlatform = function(mainElement, arcade) { inlin: inlin, infbk: infbk, verbl: verbl, + rotcount: rotcount, + rotdata: rotdata.slice(0), sl: this.scanline, }; } @@ -557,7 +584,10 @@ for (var i=0; i<256; i++) { */ var ASTROCADE_MINIMAL_BIOS = [ 0xf3, 0x21, 0x00, 0x20, 0x7e, 0xfe, 0x55, 0xca, 0x0d, 0x00, 0xc3, 0x00, 0x20, - 0x31, 0xce, 0x4f, 0xcd, 0x84, 0x02, 0x21, 0x05, 0x20, 0x7e, 0x23, 0x66, 0x6f, + 0x31, 0xce, 0x4f, + 0x21, 0x05, 0x20, 0x7e, 0x23, 0x66, 0x6f, 0xe9, ]; +var ASTROLIBRE_BIOS_LZG = `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`; + diff --git a/src/ui.ts b/src/ui.ts index cb0857e7..727a2bb8 100644 --- a/src/ui.ts +++ b/src/ui.ts @@ -1751,6 +1751,7 @@ function startPlatform() { // start platform and load file replaceURLState(); platform.start(); + // TODO: ordering of loads? loadBIOSFromProject(); initProject(); loadProject(qs['file']);