astrocade: updated presets, added memory bus contention, palette layout

This commit is contained in:
Steven Hugg 2019-05-26 21:54:37 -04:00
parent 8e19a65968
commit c93ba6fd75
22 changed files with 371 additions and 86 deletions

View File

@ -0,0 +1,95 @@
.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
jp _main ; jump to test program
.endif
FoundSentinel:
ld SP,#0x4fce ; position stack below BIOS vars
call _bios_init ; misc. bios init routines
ld HL,#0x2005 ; cartridge start vector
ld A,(HL)
inc HL
ld H,(HL)
ld L,A
jp (HL) ; jump to cart start vector
SYSCALL38:
.org 0x38
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
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
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
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

View File

@ -13,6 +13,7 @@
PrgName: DB "HELLO, WORLDS!"; String
DB 0 ; ... which must be followed by 0
PrgStart: DI ; Disable interrupts
; db $ed,$ff
SYSTEM INTPC ; Begin interpreter mode
DO SETOUT ; Set output ports
DB 100*2 ; ... with VBLANK line set to line 100

View File

@ -9,6 +9,17 @@ void clrscr() {
memset(vidmem, 0, VHEIGHT*VBWIDTH); // clear page 1
}
// set entire palette at once (8 bytes to port 0xb)
// bytes in array should be in reverse
void set_palette(byte palette[8]) __naked {
palette;
__asm
ld bc,#0x80b ; B -> 8, C -> 0xb
otir ; write C bytes to B
ret ; return
__endasm;
}
// draw vertical line
void vline(byte x, byte y1, byte y2, byte col, byte op) {
byte xb = x>>2; // divide x by 4
@ -33,33 +44,31 @@ void render_sprite(const byte* src, byte x, byte y, byte op) {
byte i,j;
byte w = *src++; // get width from 1st byte of sprite
byte h = *src++; // get height from 2nd byte of sprite
byte xb = x>>2; // divide x by 4
byte* dest = &vmagic[y][xb]; // destination address
byte* dest = &vmagic[y][x>>2];// destination address
hw_magic = M_SHIFT(x) | op; // set magic register
for (j=0; j<h; j++) {
EXIT_CLIPDEST(dest);
for (i=0; i<w; i++) {
*dest++ = *src++;
}
*dest = 0; // rest of shifted byte
dest += VBWIDTH-w; // dest address to next scanline
// y clipping off bottom
if (y+h >= VHEIGHT) {
if (y >= VHEIGHT) return;
h = VHEIGHT-y;
}
}
// erase a sprite
void erase_sprite(const byte* src, byte x, byte y) {
byte i,j;
byte w = *src++; // get width from 1st byte of sprite
byte h = *src++; // get height from 2nd byte of sprite
byte xb = x>>2; // divide x by 4
byte* dest = &vidmem[y][xb]; // destination address
for (j=0; j<h; j++) {
EXIT_CLIPDEST(dest);
for (i=0; i<w; i++) {
*dest++ = 0;
// memory copy loop
if (op != M_ERASE) {
for (j=0; j<h; j++) {
for (i=0; i<w; i++) {
*dest++ = *src++;
}
*dest = 0; // rest of shifted byte
dest += VBWIDTH-w; // dest address to next scanline
}
// erase sprite loop
} else {
for (j=0; j<h; j++) {
for (i=0; i<w; i++) {
*dest++ = 0;
}
*dest = 0; // rest of shifted byte
dest += VBWIDTH-w; // dest address to next scanline
}
*dest = 0; // rest of shifted byte
dest += VBWIDTH-w; // dest address to next scanline
}
}
@ -79,8 +88,12 @@ void draw_char(byte ch, byte x, byte y, byte op) {
EXIT_CLIPDEST(dest);
*dest++ = b; // expand lower nibble -> 1st byte
*dest++ = b; // expand upper nibble -> 2nd byte
*dest++ = 0; // leftover -> 3rd byte
*dest = 0; // reset upper/lower flag
if (x & 3) {
*dest++ = 0; // leftover -> 3rd byte
*dest = 0; // reset upper/lower flag
} else {
dest++;
}
dest += VBWIDTH-3; // we incremented 3 bytes for this line
}
}
@ -89,7 +102,7 @@ void draw_string(const char* str, byte x, byte y) {
do {
byte ch = *str++;
if (!ch) break;
draw_char(ch, x, y, M_MOVE);
draw_char(ch, x, y, M_XOR);
x += 8;
} while (1);
}
@ -105,24 +118,24 @@ void draw_bcd_word(word bcd, byte x, byte y, byte op) {
}
// add two 16-bit BCD values
word bcd_add(word a, word b) {
word bcd_add(word a, word b) __naked {
a; b; // to avoid warning
__asm
ld hl,#4
add hl,sp
ld iy,#2
add iy,sp
ld a,0 (iy)
add a, (hl)
daa
ld c,a
ld a,1 (iy)
inc hl
adc a, (hl)
daa
ld b,a
ld l, c
ld h, b
push ix
ld ix,#0
add ix,sp
ld a,4 (ix)
add a, 6 (ix)
daa
ld c,a
ld a,5 (ix)
adc a, 7 (ix)
daa
ld b,a
ld l, c
ld h, b
pop ix
ret
__endasm;
}

View File

@ -2,11 +2,14 @@
#ifndef _ACLIB_H
#define _ACLIB_H
// convenient type definitions
typedef unsigned char byte;
typedef signed char sbyte;
typedef unsigned short word;
typedef enum { false, true } bool;
/// HARDWARE
/// registers
__sfr __at(0x00) hw_col0r; // palette 0
__sfr __at(0x01) hw_col1r;
@ -24,10 +27,12 @@ __sfr __at(0x19) hw_xpand; // expander register
__sfr __at(0x08) hw_intst; // intercept test feedback
__sfr __at(0x10) hw_p1ctrl; // player controls
__sfr __at(0x11) hw_p2ctrl; // player controls
__sfr __at(0x12) hw_p3ctrl; // player controls
__sfr __at(0x13) hw_p4ctrl; // player controls
__sfr __at(0x10) hw_p1ctrl; // player 1 controls
__sfr __at(0x11) hw_p2ctrl; // player 2 controls
__sfr __at(0x12) hw_p3ctrl; // player 3 controls
__sfr __at(0x13) hw_p4ctrl; // player 4 controls
// flags
#define M_SHIFT0 0x00
#define M_SHIFT1 0x01
@ -40,14 +45,19 @@ __sfr __at(0x13) hw_p4ctrl; // player controls
#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 VHEIGHT 89 // number of scanlines
#define VTOTAL 102 // number of total scanlines
#define VHEIGHT 89 // number of scanlines in use
#define VBWIDTH 40 // number of bytes per scanline
#define PIXWIDTH 160 // 4 pixels per byte
byte __at (0x0000) vmagic[VHEIGHT][VBWIDTH];
byte __at (0x4000) vidmem[VHEIGHT][VBWIDTH];
// magic register active area
byte __at (0x0000) vmagic[VTOTAL][VBWIDTH];
// regular frame buffer RAM
byte __at (0x4000) vidmem[VTOTAL][VBWIDTH];
// font constants
#define LOCHAR 32
#define HICHAR 127
#define FONT_BWIDTH 1
@ -56,13 +66,15 @@ byte __at (0x4000) vidmem[VHEIGHT][VBWIDTH];
/// GRAPHICS FUNCTIONS
void clrscr();
void set_palette(byte palette[8]); // palette in reverse order
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);
void erase_sprite(const byte* src, byte x, byte y);
void draw_char(byte ch, byte x, byte y, byte op);
void draw_string(const char* str, byte x, byte y);
void draw_bcd_word(word bcd, byte x, byte y, byte op);
word bcd_add(word a, word b);
#define erase_sprite(src,x,y) render_sprite(src,x,y,M_ERASE);
#endif

View File

@ -21,17 +21,17 @@
const byte player_bitmap[] =
{3,14,/*{w:12,h:16,bpp:2,brev:1}*/0x00,0x3C,0x00,0x00,0x18,0x00,0x00,0x3C,0x00,0x00,0x18,0x00,0x04,0x18,0x20,0x0C,0x3C,0x30,0x3C,0x3C,0x3C,0x1F,0xE7,0xF4,0x1F,0x66,0xF4,0x17,0xE7,0xE4,0x17,0xE7,0xE4,0x1C,0x7E,0x34,0x1C,0xFF,0x34,0x3C,0x18,0x3C,0x0C,0x18,0x30,0x04,0x18,0x20};
const byte bomb_bitmap[] =
{1,5,/*{w:8,h:5,bpp:2,brev:1}*/0x88,0x55,0x77,0x55,0x88};
{1,5,/*{w:4,h:5,bpp:2,brev:1}*/0x88,0x55,0x77,0x55,0x88};
const byte bullet_bitmap[] =
{1,5,/*{w:8,h:5,bpp:2,brev:1}*/0x14,0x28,0x14,0x14,0x28};
{1,5,/*{w:4,h:5,bpp:2,brev:1}*/0x14,0x28,0x14,0x14,0x28};
const byte enemy1_bitmap[] =
{2,8,/*{w:16,h:8,bpp:2,brev:1}*/0x00,0x00,0x70,0x38,0xF8,0x7C,0xFC,0xFC,0xFE,0xFC,0xFE,0xFF,0xFC,0xFF,0xF8,0x7F,0xF0,0x3F,0x88,0x47,0xF0,0x3F,0xF0,0x3F,0xD0,0x2F,0x8C,0xC7,0x48,0x48,0x80,0x04};
{2,8,/*{w:8,h:8,bpp:2,brev:1}*/0x00,0x00,0x70,0x38,0xF8,0x7C,0xFC,0xFC,0xFE,0xFC,0xFE,0xFF,0xFC,0xFF,0xF8,0x7F,0xF0,0x3F,0x88,0x47,0xF0,0x3F,0xF0,0x3F,0xD0,0x2F,0x8C,0xC7,0x48,0x48,0x80,0x04};
const byte enemy2_bitmap[] =
{2,8,/*{w:16,h:8,bpp:2,brev:1}*/0x00,0x00,0x30,0x0C,0x14,0x28,0x2E,0x74,0x08,0x10,0x20,0x04,0xE0,0x07,0xD0,0x0B,0xB0,0x0D,0xB2,0x4D,0x19,0x98,0x8E,0x71,0x82,0x41,0xB1,0x8D,0x59,0x9A,0x4A,0x52};
{2,8,/*{w:8,h:8,bpp:2,brev:1}*/0x00,0x00,0x30,0x0C,0x14,0x28,0x2E,0x74,0x08,0x10,0x20,0x04,0xE0,0x07,0xD0,0x0B,0xB0,0x0D,0xB2,0x4D,0x19,0x98,0x8E,0x71,0x82,0x41,0xB1,0x8D,0x59,0x9A,0x4A,0x52};
const byte enemy3_bitmap[] =
{2,8,/*{w:16,h:8,bpp:2,brev:1}*/0x00,0x00,0x00,0x00,0x04,0x20,0x05,0xA0,0x05,0xA0,0x25,0xA4,0xA7,0xE5,0xF7,0xEF,0xF7,0xEF,0xFE,0x7F,0xFC,0x3F,0xBC,0x3D,0xE4,0x27,0x20,0x00,0x00,0x00,0x00,0x00};
{2,8,/*{w:8,h:8,bpp:2,brev:1}*/0x00,0x00,0x00,0x00,0x04,0x20,0x05,0xA0,0x05,0xA0,0x25,0xA4,0xA7,0xE5,0xF7,0xEF,0xF7,0xEF,0xFE,0x7F,0xFC,0x3F,0xBC,0x3D,0xE4,0x27,0x20,0x00,0x00,0x00,0x00,0x00};
const byte enemy4_bitmap[] =
{2,8,/*{w:16,h:8,bpp:2,brev:1}*/0x00,0x00,0x00,0x00,0xF0,0x0F,0xF8,0x1F,0xD8,0x1B,0xF8,0x1F,0xF8,0x1F,0xF8,0x1F,0xF0,0x0F,0xA8,0x15,0xCC,0x33,0xE8,0x17,0x66,0x66,0x33,0xCC,0x61,0x86,0x40,0x02};
{2,8,/*{w:8,h:8,bpp:2,brev:1}*/0x00,0x00,0x00,0x00,0xF0,0x0F,0xF8,0x1F,0xD8,0x1B,0xF8,0x1F,0xF8,0x1F,0xF8,0x1F,0xF0,0x0F,0xA8,0x15,0xCC,0x33,0xE8,0x17,0x66,0x66,0x33,0xCC,0x61,0x86,0x40,0x02};
const byte* const enemy_bitmaps[4] = {
enemy1_bitmap,
@ -88,7 +88,7 @@ void draw_lives() {
byte i;
byte n = lives;
byte y = 0;
byte x = PIXWIDTH-4*5;
byte x = PIXWIDTH-4*6;
hw_xpand = XPAND_COLORS(0, COLOR_SCORE);
for (i=0; i<MAXLIVES; i++) {
draw_char(i<n?'|':' ', x, y, M_MOVE);

32
presets/astrocade/hello.c Normal file
View File

@ -0,0 +1,32 @@
#include "aclib.h"
//#link "aclib.c"
//#link "acheader.s"
#include <stdlib.h>
#include <string.h>
/*{pal:"astrocade",layout:"astrocade"}*/
const byte palette[8] = {
0x06, 0x62, 0xF1, 0x04,
0x07, 0xD4, 0x35, 0x00,
};
void setup_registers() {
// setup colors
set_palette(palette);
// horizontal palette split
hw_horcb = 12;
// height of screen
hw_verbl = VHEIGHT*2;
}
void main() {
setup_registers();
clrscr();
hw_xpand = XPAND_COLORS(0, 2);
draw_string("Hello, World!", 2, 0);
// infinite loop
while (1) {
}
}

View File

@ -10,7 +10,6 @@
; > Version 2.6 - March 2, 2004 - as seen on BallyAlley.com
; > Version 3.0 - 2009
; > Version 3.01 - Changed "FonT BASE character" comment
; > (also patched for latest zmac with default args)
; >
; > This file contains the equates and macros that Bally
; > programs require for assembly. This file has been

50
presets/astrocade/lines.c Normal file
View File

@ -0,0 +1,50 @@
#include "aclib.h"
//#link "aclib.c"
//#link "acheader.s"
#include <stdlib.h>
#include <string.h>
void draw_line(int x0, int y0, int x1, int y1, byte color) {
int dx = abs(x1-x0);
int sx = x0<x1 ? 1 : -1;
int dy = abs(y1-y0);
int sy = y0<y1 ? 1 : -1;
int err = (dx>dy ? dx : -dy)>>1;
int e2;
for(;;) {
pixel(x0, y0, color, M_XOR);
if (x0==x1 && y0==y1) break;
e2 = err;
if (e2 > -dx) { err -= dy; x0 += sx; }
if (e2 < dy) { err += dx; y0 += sy; }
}
}
/*{pal:"astrocade",layout:"astrocade"}*/
const byte palette[8] = {
0x06, 0x62, 0xF1, 0x04,
0x07, 0xD4, 0x35, 0x00,
};
void setup_registers() {
set_palette(palette);
// horizontal palette split
hw_horcb = 20;
// height of screen
hw_verbl = VHEIGHT*2;
}
void main() {
setup_registers();
clrscr();
hw_xpand = XPAND_COLORS(0, 2);
draw_string("Hello, Lines!", 2, 80);
draw_line(0, 0, 159, 95, 1);
// infinite loop
srand(1);
while(1) {
draw_line(rand()%159, rand()%79, rand()%159, rand()%79, rand()&3);
}
}

View File

@ -1,8 +1,29 @@
#include "aclib.h"
//#link "aclib.c"
//#link "acheader.s"
#include <stdlib.h>
#include <string.h>
void main() {
memset((void*)0x4000, 0, 0xe00); // clear screen, avoid vars and stack (1e00-1fff)
void setup_registers() {
// setup colors
hw_col0r = 0x00;
hw_col1r = 0x2f;
hw_col2r = 0xef;
hw_col3r = 0xaf;
// horizontal palette split
hw_horcb = 12;
// height of screen
hw_verbl = VHEIGHT*2;
}
void main() {
setup_registers();
clrscr();
hw_xpand = XPAND_COLORS(0, 2);
draw_string("Hello, World!", 2, 0);
// infinite loop
while (1) {
}
}

View File

@ -0,0 +1,34 @@
#include <string.h>
#include "aclib.h"
//#link "aclib.c"
//#link "acheader.s"
const byte player_bitmap[] =
{3,14,/*{w:12,h:16,bpp:2,brev:1}*/0x00,0x3C,0x00,0x00,0x18,0x00,0x00,0x3C,0x00,0x00,0x18,0x00,0x04,0x18,0x20,0x0C,0x3C,0x30,0x3C,0x3C,0x3C,0x1F,0xE7,0xF4,0x1F,0x66,0xF4,0x17,0xE7,0xE4,0x17,0xE7,0xE4,0x1C,0x7E,0x34,0x1C,0xFF,0x34,0x3C,0x18,0x3C,0x0C,0x18,0x30,0x04,0x18,0x20};
/*{pal:"astrocade",layout:"astrocade"}*/
const byte palette[8] = {
0x06, 0x62, 0xF1, 0x04,
0x07, 0xD4, 0x35, 0x00,
};
void setup_registers() {
set_palette(palette);
hw_horcb = 0;
hw_verbl = VHEIGHT*2;
}
void main() {
byte x,y;
x=10;
y=10;
setup_registers();
clrscr();
while (1) {
render_sprite(player_bitmap, x, y, M_MOVE);
x++;
y++;
}
}

View File

@ -118,6 +118,8 @@ export interface Preset {
export interface MemoryBus {
read : (address:number) => number;
write : (address:number, value:number) => void;
contend?: (address:number, cycles:number) => number;
isContended?: (address:number) => boolean;
}
export type DebugCondition = () => boolean;
@ -508,6 +510,12 @@ export function BusProbe(bus : MemoryBus) {
}
bus.write(a,v);
}
this.contend = function(addr,cyc) {
return bus.contend(addr,cyc);
}
this.isContended = function(addr) {
return bus.isContended(addr);
}
}
export abstract class BaseZ80Platform extends BaseDebugPlatform {
@ -515,10 +523,9 @@ export abstract class BaseZ80Platform extends BaseDebugPlatform {
_cpu;
probe;
newCPU(membus : MemoryBus, iobus : MemoryBus) {
newCPU(membus : MemoryBus, iobus : MemoryBus, z80opts? : {}) {
this.probe = new BusProbe(membus);
var z80opts = {};
this._cpu = buildZ80(z80opts)({
this._cpu = buildZ80(z80opts || {})({
display: {},
memory: this.probe,
ioBus: iobus

View File

@ -299,7 +299,8 @@ var PREDEF_PALETTES = {
0x003814,0x003814, 0x1c5c34,0x1c5c34, 0x387c50,0x387c50, 0x50986c,0x50986c, 0x68b484,0x68b484, 0x7ccc9c,0x7ccc9c, 0x90e4b4,0x90e4b4, 0xa4fcc8,0xa4fcc8,
0x00302c,0x00302c, 0x1c504c,0x1c504c, 0x347068,0x347068, 0x4c8c84,0x4c8c84, 0x64a89c,0x64a89c, 0x78c0b4,0x78c0b4, 0x88d4cc,0x88d4cc, 0x9cece0,0x9cece0,
0x002844,0x002844, 0x184864,0x184864, 0x306884,0x306884, 0x4484a0,0x4484a0, 0x589cb8,0x589cb8, 0x6cb4d0,0x6cb4d0, 0x7ccce8,0x7ccce8, 0x8ce0fc,0x8ce0fc
]
],
'astrocade':[0,2368548,4737096,7171437,9539985,11974326,14342874,16777215,12255269,14680137,16716142,16725394,16734903,16744155,16753663,16762879,11534409,13959277,16318866,16721334,16730842,16740095,16749311,16758783,10420330,12779662,15138995,16718039,16727291,16736767,16745983,16755199,8847495,11206827,13631696,15994612,16724735,16733951,16743423,16752639,6946975,9306307,11731175,14092287,16461055,16732415,16741631,16751103,4784304,7143637,9568505,11929087,14297599,16731647,16741119,16750335,2425019,4784352,7209215,9570047,12004095,14372863,16741375,16750847,191,2359523,4718847,7146495,9515263,11949311,14318079,16752127,187,224,2294015,4658431,7092735,9461247,11895551,14264063,176,213,249,2367999,4736511,7105279,9539327,11908095,159,195,3303,209151,2577919,4946431,7380735,9749247,135,171,7888,17140,681983,3050495,5484543,7853311,106,3470,12723,22231,31483,1548031,3916799,6285311,73,8557,17810,27318,36570,373759,2742271,5176575,4389,13641,23150,32402,41911,51163,2026495,4456447,9472,18724,27976,37485,46737,56246,1834970,4194303,14080,23296,32803,42055,51564,60816,2031541,4456409,18176,27648,36864,46116,55624,392556,2752401,5177269,21760,30976,40192,49667,58919,1572683,3932016,6291348,24320,33536,43008,52224,716810,3079982,5504851,7864183,25856,35328,44544,250368,2619136,4980503,7405371,9764703,26624,35840,45312,2413824,4782336,7143173,9568041,11927374,26112,35584,2338560,4707328,7141376,9502464,11927326,14286659,24832,2393344,4762112,7196160,9564928,11992832,14352155,16711487,2447360,4815872,7250176,9618688,12052992,14417664,16776990,16777027,4803328,7172096,9606144,11974912,14343424,16776965,16777001,16777038,6962176,9330688,11764992,14133504,16502272,16773655,16777019,16777055,8858112,11226880,13660928,16029440,16759818,16769070,16777043,16777079,10426112,12794624,15163392,16745475,16754727,16764235,16773488,16777108,11534848,13969152,16337664,16740388,16749640,16759148,16768401,16777141,12255232,14684928,16725795,16735047,16744556,16753808,16763317,16772569],
};
var PREDEF_LAYOUTS : {[id:string]:PixelEditorPaletteLayout} = {
@ -314,6 +315,10 @@ var PREDEF_LAYOUTS : {[id:string]:PixelEditorPaletteLayout} = {
['Sprite 2', 0x19, 3],
['Sprite 3', 0x1d, 3]
],
'astrocade':[
['Left', 0x04, -4],
['Right', 0x00, -4]
],
};
/////
@ -587,7 +592,6 @@ function dedupPalette(cols : UintArray) : Uint32Array {
}
export class PaletteFormatToRGB extends PixNode {
words : UintArray;
rgbimgs : Uint32Array[];
palette : Uint32Array;

View File

@ -11,6 +11,9 @@ const ASTROCADE_PRESETS = [
{id:'01-helloworlds.asm', name:'Hello World'},
{id:'02-telephone.asm', name:'Telephone'},
{id:'03-horcbpal.asm', name:'Paddle Demo'},
{id:'hello.c', name:'Hello World'},
{id:'lines.c', name:'Lines'},
{id:'sprites.c', name:'Sprites'},
{id:'cosmic.c', name:'Cosmic Impalas Game'},
];
@ -68,7 +71,7 @@ const _BallyAstrocadePlatform = function(mainElement, arcade) {
const sheight = arcade ? 204 : 102;
const swbytes = Math.floor(swidth / 4);
const cpuFrequency = 1789000;
const cpuCyclesPerLine = cpuFrequency/(60*sheight); // TODO: wait states?
const cpuCyclesPerLine = cpuFrequency/(60*262);
const INITIAL_WATCHDOG = 256;
const PIXEL_ON = 0xffeeeeee;
const PIXEL_OFF = 0xff000000;
@ -90,6 +93,7 @@ const _BallyAstrocadePlatform = function(mainElement, arcade) {
palette[i] = ASTROCADE_PALETTE[i];
var refreshlines = 0;
var vidactive = false;
function ramwrite(a:number, v:number) {
ram.mem[a] = v;
@ -176,6 +180,8 @@ const _BallyAstrocadePlatform = function(mainElement, arcade) {
}
class BallyAstrocadePlatform extends BaseZ80Platform implements Platform {
scanline : number;
getPresets() {
return ASTROCADE_PRESETS;
@ -196,7 +202,10 @@ const _BallyAstrocadePlatform = function(mainElement, arcade) {
[0x4000, 0x4fff, 0xfff, ramwrite],
[0x0000, 0x3fff, 0x3fff, magicwrite],
]),
isContended: function() { return false; },
// TODO: correct values?
// TODO: no contention on hblank
isContended: () => { return true; },
contend: () => { return vidactive ? 1 : 0; },
};
} else {
// arcade game
@ -211,10 +220,17 @@ const _BallyAstrocadePlatform = function(mainElement, arcade) {
[0xd000, 0xdfff, 0xfff, function(a,v) { ramwrite(a+0x4000, v); } ], // static RAM
[0x0000, 0x3fff, 0x3fff, magicwrite],
]),
isContended: function() { return false; },
isContended: () => { return true; },
contend: () => { return vidactive ? 1 : 0; },
};
}
iobus = {
isULAPort: function(addr) {
return false; // TODO?
},
contend: function(addr) {
return 0; // TODO?
},
read: function(addr) {
addr &= 0x1f;
var rtn = inputs[addr];
@ -285,7 +301,7 @@ const _BallyAstrocadePlatform = function(mainElement, arcade) {
}
}
};
cpu = this.newCPU(membus, iobus);
cpu = this.newCPU(membus, iobus, {applyContention:true});
audio = new MasterAudio();
psg = new AstrocadeAudio(audio);
video = new RasterVideo(mainElement,swidth,sheight,{});
@ -308,13 +324,14 @@ const _BallyAstrocadePlatform = function(mainElement, arcade) {
advance(novideo : boolean) {
this.loadControls();
for (var sl=0; sl<sheight; sl++) {
//console.log(sl, hex(cpu.getPC(),4), cpu.saveState());
this.runCPU(cpu, cpuCyclesPerLine);
for (var sl=0; sl<131; sl++) {
this.scanline = sl;
vidactive = sl < verbl;
this.runCPU(cpu, cpuCyclesPerLine*2); // TODO?
if (sl == inlin && (inmod & 0x8)) {
this.requestInterrupt(cpu, infbk);
}
if (refreshlines>0) {
if (sl < sheight && refreshlines>0) {
refreshline(sl);
refreshlines--;
}
@ -329,6 +346,8 @@ const _BallyAstrocadePlatform = function(mainElement, arcade) {
}
*/
}
getRasterScanline() { return this.scanline; }
loadROM(title, data) {
rom = padBytes(data, arcade ? 0xb000 : 0x2000);
@ -476,7 +495,7 @@ for (var i=0; i<256; i++) {
0004 7E [ 7] 198 LD A,(HL) ; A <- mem[0x2000]
0005 FE 55 [ 7] 199 CP #0x55 ; found sentinel byte? ($55)
0007 CA 0D 00 [10] 200 JP Z,FoundSentinel ; yes, load program
000A C3 AB 0E [10] 201 JP _main ; jump to test program
000A C3 00 20 [10] 201 JP _main ; jump to test program
000D 202 FoundSentinel:
000D 31 CE 4F [10] 203 LD SP,#0x4fce ; position stack below BIOS vars
0010 CD 84 02 [17] 204 CALL _bios_init ; misc. bios init routines
@ -488,7 +507,7 @@ for (var i=0; i<256; i++) {
001A E9 [ 4] 210 JP (HL) ; jump to cart start vector
*/
var ASTROCADE_MINIMAL_BIOS = [
0xf3, 0x21, 0x00, 0x20, 0x7e, 0xfe, 0x55, 0xca, 0x0d, 0x00, 0xc3, 0xab, 0x0e,
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,
0xe9,
];

View File

@ -32,7 +32,6 @@ var Base_Z80Platform = function(mainElement) {
write: newAddressDecoder([
[0x8000, 0xffff, 0x7fff, function(a,v) { ram.mem[a] = v; }],
]),
isContended: function() { return false; },
};
this.readAddress = membus.read;
iobus = {

View File

@ -89,7 +89,6 @@ const _ColecoVisionPlatform = function(mainElement) {
write: newAddressDecoder([
[0x6000, 0x7fff, 0x3ff, function(a,v) { ram.mem[a] = v; }],
]),
isContended: function() { return false; },
};
iobus = {
read: function(addr) {

View File

@ -249,7 +249,6 @@ const _GalaxianPlatform = function(mainElement, options) {
//[0x8200, 0x8203, 0, function(a,v){ /* PPI 1 */ }],
//[0, 0xffff, 0, function(a,v) { console.log(hex(a),hex(v)); }]
]),
isContended: function() { return false; },
};
} else {
inputs = [0xe,0x8,0x0];

View File

@ -78,7 +78,6 @@ class MSXPlatform extends BasicZ80ScanlinePlatform implements Platform {
let slot = this.slots[slotnum];
if (slot) slot.write(a, v);
},
isContended: () => { return false; },
};
}

View File

@ -62,7 +62,6 @@ class Midway8080BWPlatform extends BasicZ80ScanlinePlatform implements Platform
//if (displayPCs) displayPCs[a] = cpu.getPC(); // save program counter
}],
]),
isContended: function() { return false; },
};
}

View File

@ -78,7 +78,6 @@ class SG1000Platform extends BasicZ80ScanlinePlatform implements Platform {
write: newAddressDecoder([
[0xc000, 0xffff, 0x3ff, (a,v) => { this.ram[a] = v; }],
]),
isContended: () => { return false; },
};
}

View File

@ -72,7 +72,6 @@ var WilliamsSoundPlatform = function(mainElement) {
write: newAddressDecoder([
[0x4000, 0x7fff, 0x3ff, function(a,v) { ram.mem[a] = v; }],
]),
isContended: function() { return false; },
};
iobus = {
read: function(addr) {

View File

@ -136,7 +136,6 @@ class VicDualPlatform extends BasicZ80ScanlinePlatform implements Platform {
write: newAddressDecoder([
[0x8000, 0xffff, 0x0fff, (a, v) => { this.ram[a] = v; }],
]),
isContended: () => { return false; },
};
}

View File

@ -955,6 +955,10 @@ export class AssetEditorView implements ProjectView, pixed.EditorContext {
if (len == matchlen) {
var rgbs = palette.slice(start, start+len);
result.push({node:node, name:name, palette:rgbs});
} else if (-len == matchlen) { // reverse order
var rgbs = palette.slice(start, start-len);
rgbs.reverse();
result.push({node:node, name:name, palette:rgbs});
} else if (len+1 == matchlen) {
var rgbs = new Uint32Array(matchlen);
rgbs[0] = palette[0];
@ -1107,8 +1111,10 @@ export class AssetEditorView implements ProjectView, pixed.EditorContext {
var arow = $('<tr/>').appendTo(atable);
$('<td/>').text(name).appendTo(arow);
var inds = [];
for (var k=start; k<start+len; k++)
for (var k=start; k<start+Math.abs(len); k++)
inds.push(k);
if (len < 0)
inds.reverse();
inds.forEach( (i) => {
var cell = $('<td/>').addClass('asset_cell asset_editable').appendTo(arow);
updateCell(cell, i);