fix some things in vicdual and scramble; renamed konamisound

This commit is contained in:
Steven Hugg 2017-04-09 23:36:04 -04:00
parent 575943ea6a
commit 333636fe33
17 changed files with 347 additions and 171 deletions

View File

@ -207,7 +207,7 @@ div.bitmap_editor {
<!--<li><a class="dropdown-item" href="?platform=apple2" id="item_platform_apple2">Apple ][</a></li>-->
<li><a class="dropdown-item" href="?platform=mw8080bw" id="item_platform_mw8080bw">Midway 8080 B&amp;W</a></li>
<li><a class="dropdown-item" href="?platform=vicdual" id="item_platform_vicdual">VIC Dual</a></li>
<li><a class="dropdown-item" href="?platform=galaxian-scramble" id="item_platform_galaxian_scramble">Galaxian/Scramble</a></li>
<li><a class="dropdown-item" href="?platform=galaxian-scramble" id="item_platform_galaxian_scramble">Scramble hardware</a></li>
<li><a class="dropdown-item" href="?platform=vector-z80color" id="item_platform_vector_z80color">Atari Color Vector (Z80)</a></li>
<li><a class="dropdown-item" href="?platform=williams-z80" id="item_platform_williams_z80">Williams (Z80)</a></li>
<li><a class="dropdown-item" href="?platform=sound_williams-z80" id="item_platform_sound_williams_z80">Williams Sound (Z80)</a></li>

View File

@ -2,27 +2,29 @@
typedef unsigned char byte;
typedef unsigned short word;
typedef signed char sbyte;
byte __at (0x4800) vram[32][32];
struct {
byte scroll;
byte attrib;
} __at (0x5000) columns[32];
} __at (0x5000) vcolumns[32];
struct {
byte xpos;
byte code;
byte color;
byte ypos;
} __at (0x5040) sprites[8];
} __at (0x5040) vsprites[8];
struct {
byte unused1;
byte xpos;
byte unused2;
byte ypos;
} __at (0x5060) missiles[8];
} __at (0x5060) vmissiles[8];
byte __at (0x5080) xram[128];
@ -74,11 +76,18 @@ const char __at (0x5000) palette[32] = {
#define CHAR(ch) (ch-LOCHAR)
void memset_safe(void* _dest, char ch, word size) {
byte* dest = _dest;
while (size--) {
*dest++ = ch;
}
}
void clrscr() {
memset(vram, 0x10, sizeof(vram));
memset(columns, 0, sizeof(columns));
memset(sprites, 0, sizeof(sprites));
memset(missiles, 0, sizeof(missiles));
memset_safe(vram, 0x10, sizeof(vram));
memset_safe(vcolumns, 0, sizeof(vcolumns));
memset_safe(vsprites, 0, sizeof(vsprites));
memset_safe(vmissiles, 0, sizeof(vmissiles));
}
byte getchar(byte x, byte y) {
@ -104,7 +113,7 @@ void draw_all_chars() {
byte x = (i & 31);
byte y = (i >> 5) + 2;
putchar(x,y,i);
columns[y].attrib = frame+y;
vcolumns[y].attrib = frame+y;
//columns[y].scroll = frame;
} while (++i);
}
@ -119,10 +128,10 @@ void putshape(byte x, byte y, byte ofs) {
void draw_sprites(byte ofs, byte y) {
byte i;
byte x = 0;
columns[y].attrib = 1;
columns[y].scroll = 0;
columns[y+1].attrib = 1;
columns[y+1].scroll = 0;
vcolumns[y].attrib = 1;
vcolumns[y].scroll = 0;
vcolumns[y+1].attrib = 1;
vcolumns[y+1].scroll = 0;
for (i=0; i<8; i++) {
putshape(x, y, ofs);
x += 3;
@ -132,10 +141,10 @@ void draw_sprites(byte ofs, byte y) {
void draw_explosion(byte ofs, byte y) {
byte x;
columns[y].attrib = 2;
columns[y+1].attrib = 2;
columns[y+2].attrib = 2;
columns[y+3].attrib = 2;
vcolumns[y].attrib = 2;
vcolumns[y+1].attrib = 2;
vcolumns[y+2].attrib = 2;
vcolumns[y+3].attrib = 2;
for (x=0; x<4; x++) {
putshape(x*5, y, ofs+8);
putshape(x*5, y+2, ofs+12);
@ -148,10 +157,10 @@ void draw_explosion(byte ofs, byte y) {
void draw_missiles() {
byte i;
for (i=0; i<7; i++) {
missiles[i].ypos = i + 24;
missiles[i].xpos = i*16 + frame;
sprites[i].xpos = i*32 + frame;
sprites[i].ypos = i*24 + frame;
vmissiles[i].ypos = i + 24;
vmissiles[i].xpos = i*16 + frame;
vsprites[i].xpos = i*32 + frame;
vsprites[i].ypos = i*24 + frame;
}
}
@ -175,7 +184,7 @@ void main() {
draw_missiles();
putstring(7, 0, "HELLO@WORLD@123");
draw_corners();
columns[1].attrib = frame;
vcolumns[1].attrib = frame;
enable_stars = 0&0xff;
frame++;
watchdog++;

View File

@ -2,29 +2,28 @@
typedef unsigned char byte;
typedef unsigned short word;
typedef unsigned char sbyte;
byte __at (0x4800) vram[32][32];
struct {
byte scroll;
byte attrib;
} __at (0x5000) columns[32];
} __at (0x5000) vcolumns[32];
struct {
byte xpos;
byte code;
byte color;
byte ypos;
} __at (0x5040) sprites[8];
} __at (0x5040) vsprites[8];
struct {
signed char dx; // unused by h/w
byte unused1;
byte xpos;
signed char dy; // unused by h/w
byte unused2;
byte ypos;
} __at (0x5060) missiles[8];
byte __at (0x5080) xram[128];
} __at (0x5060) vmissiles[8];
byte __at (0x6801) enable_irq;
byte __at (0x6804) enable_stars;
@ -124,12 +123,15 @@ const char __at (0x5000) palette[32] = {
#define BLANK 0x10
void clrscr() {
memset(vram, BLANK, sizeof(vram));
void memset_safe(void* _dest, char ch, word size) {
byte* dest = _dest;
while (size--) {
*dest++ = ch;
}
}
byte getchar(byte x, byte y) {
return vram[29-x][y];
void clrscr() {
memset_safe(vram, BLANK, sizeof(vram));
}
volatile byte video_framecount; // actual framecount
@ -145,8 +147,6 @@ __asm
ld ix,#0
ld ix,#0
nop
nop
nop
__endasm;
}
@ -154,15 +154,19 @@ void rst_66() __interrupt {
video_framecount++;
}
byte getchar(byte x, byte y) {
return vram[29-x][y];
}
void putchar(byte x, byte y, byte ch) {
vram[29-x][y] = ch;
}
void clrobjs() {
byte i;
memset(columns, 0, 0x100);
memset_safe(vcolumns, 0, 0x100);
for (i=0; i<8; i++)
sprites[i].ypos = 64;
vsprites[i].ypos = 64;
}
void putstring(byte x, byte y, const char* string) {
@ -234,6 +238,13 @@ typedef struct {
byte returning;
} AttackingEnemy;
typedef struct {
signed char dx;
byte xpos;
signed char dy;
byte ypos;
} Missile;
#define ENEMIES_PER_ROW 8
#define ENEMY_ROWS 4
#define MAX_IN_FORMATION (ENEMIES_PER_ROW*ENEMY_ROWS)
@ -241,12 +252,15 @@ typedef struct {
FormationEnemy formation[MAX_IN_FORMATION];
AttackingEnemy attackers[MAX_ATTACKERS];
Missile missiles[8];
byte formation_offset_x;
signed char formation_direction;
byte current_row;
byte player_x;
const byte player_y = 232;
byte player_exploding;
byte enemy_exploding;
byte enemies_left;
word player_score;
word framecount;
@ -272,8 +286,8 @@ void setup_formation() {
void draw_row(byte row) {
byte i;
byte y = 4 + row * 2;
columns[y].attrib = 0x2;
columns[y].scroll = formation_offset_x;
vcolumns[y].attrib = 0x2;
vcolumns[y].scroll = formation_offset_x;
for (i=0; i<ENEMIES_PER_ROW; i++) {
byte x = i * 3;
byte shape = formation[i + row*ENEMIES_PER_ROW].shape;
@ -346,12 +360,12 @@ void draw_attacker(byte i) {
AttackingEnemy* a = &attackers[i];
if (a->findex) {
byte code = DIR_TO_CODE[a->dir & 31];
sprites[i].code = code + a->shape + 14;
sprites[i].xpos = a->x >> 8;
sprites[i].ypos = a->y >> 8;
sprites[i].color = 2;
vsprites[i].code = code + a->shape + 14;
vsprites[i].xpos = a->x >> 8;
vsprites[i].ypos = a->y >> 8;
vsprites[i].color = 2;
} else {
sprites[i].ypos = 255; // offscreen
vsprites[i].ypos = 255; // offscreen
}
}
@ -453,8 +467,8 @@ void formation_to_attacker(byte formation_index) {
}
void draw_player() {
columns[29].attrib = 1;
columns[30].attrib = 1;
vcolumns[29].attrib = 1;
vcolumns[30].attrib = 1;
vram[30][29] = 0x60;
vram[31][29] = 0x62;
vram[30][30] = 0x61;
@ -469,8 +483,8 @@ void move_player() {
missiles[7].xpos = player_x+8; // player X position
missiles[7].dy = 4; // player missile speed
}
columns[29].scroll = player_x;
columns[30].scroll = player_x;
vcolumns[29].scroll = player_x;
vcolumns[30].scroll = player_x;
}
void move_missiles() {
@ -484,22 +498,24 @@ void move_missiles() {
}
}
}
// copy all "shadow missiles" to video memory
memcpy(vmissiles, missiles, sizeof(missiles));
}
void blowup_at(byte x, byte y) {
sprites[6].color = 1;
sprites[6].code = 28;
sprites[6].xpos = x;
sprites[6].ypos = y;
vsprites[6].color = 1;
vsprites[6].code = 28;
vsprites[6].xpos = x;
vsprites[6].ypos = y;
enemy_exploding = 1;
}
void animate_enemy_explosion() {
if (sprites[6].ypos != 0xff) {
if (sprites[6].code == 31) {
sprites[6].ypos = 0xff;
} else {
sprites[6].code++;
}
if (enemy_exploding) {
// animate next frame
vsprites[6].code = 28 + enemy_exploding++;
if (enemy_exploding > 4)
enemy_exploding = 0; // hide explosion after 4 frames
}
}
@ -508,19 +524,19 @@ void animate_player_explosion() {
if (z <= 5) {
if (z == 5) {
// erase explosion
memset(&vram[29][28], BLANK, 4);
memset(&vram[30][28], BLANK, 4);
memset(&vram[31][28], BLANK, 4);
memset(&vram[0][28], BLANK, 4);
memset_safe(&vram[29][28], BLANK, 4);
memset_safe(&vram[30][28], BLANK, 4);
memset_safe(&vram[31][28], BLANK, 4);
memset_safe(&vram[0][28], BLANK, 4);
} else {
// draw explosion
z = 0xb0 + (z<<4);
columns[28].scroll = player_x;
columns[31].scroll = player_x;
columns[28].attrib = 2;
columns[29].attrib = 2;
columns[30].attrib = 2;
columns[31].attrib = 2;
vcolumns[28].scroll = player_x;
vcolumns[31].scroll = player_x;
vcolumns[28].attrib = 2;
vcolumns[29].attrib = 2;
vcolumns[30].attrib = 2;
vcolumns[31].attrib = 2;
vram[29][28] = z+0x0;
vram[29][29] = z+0x1;
vram[29][30] = z+0x4;
@ -632,8 +648,8 @@ void set_sounds() {
enable |= 0x1;
}
// enemy explosion sound
if (sprites[6].ypos != 0xff) {
set8910a(AY_PITCH_B_HI, sprites[6].code-30);
if (enemy_exploding) {
set8910a(AY_PITCH_B_HI, enemy_exploding);
set8910a(AY_ENV_VOL_B, 15);
enable |= 0x2;
}
@ -646,8 +662,9 @@ void set_sounds() {
// set diving sounds for spaceships
enable = 0;
for (i=0; i<3; i++) {
if (sprites[i].ypos >= 128) {
set8910b(AY_PITCH_A_LO+i, sprites[i].ypos);
byte y = attackers[i].y >> 8;
if (y >= 0x80) {
set8910b(AY_PITCH_A_LO+i, y);
set8910b(AY_ENV_VOL_A+i, 7);
enable |= 1<<i;
}
@ -656,7 +673,7 @@ void set_sounds() {
}
void wait_for_frame() {
while (video_framecount == (byte)(framecount)) ;
while (((video_framecount^framecount)&3) == 0);
}
void play_round() {
@ -672,6 +689,8 @@ void play_round() {
framecount = 0;
new_player_ship();
while (end_timer) {
enable_irq = 0;
enable_irq = 1;
if (player_exploding) {
if ((framecount & 7) == 1) {
animate_player_explosion();
@ -698,15 +717,19 @@ void play_round() {
framecount++;
watchdog++;
if (!enemies_left) end_timer--;
putchar(12,0,video_framecount&3);
putchar(13,0,framecount&3);
putchar(14,0,(video_framecount^framecount)&3);
wait_for_frame();
}
enable_irq = 0;
}
void main() {
clrscr();
clrobjs();
enable_stars = 0xff;
enable_irq = 1;
enable_irq = 0;
play_round();
main();
}

View File

@ -0,0 +1,93 @@
#include <string.h>
typedef unsigned char byte;
typedef signed char sbyte;
typedef unsigned short word;
__sfr __at (0x6) watchdog_strobe;
byte __at (0x2400) vidmem[224][32]; // 256x224x1 video memory
void main();
// start routine @ 0x0
// set stack pointer
void start() {
__asm
LD SP,#0x2400
DI
__endasm;
main();
}
/// GRAPHICS FUNCTIONS
void clrscr() {
memset(vidmem, 0, sizeof(vidmem));
}
inline void xor_pixel(byte x, byte y) {
byte* dest = &vidmem[x][y>>3];
*dest ^= 0x1 << (y&7);
}
void draw_vline(byte x, byte y1, byte y2) {
byte yb1 = y1/8;
byte yb2 = y2/8;
byte* dest = &vidmem[x][yb1];
signed char nbytes = yb2 - yb1;
*dest++ ^= 0xff << (y1&7);
if (nbytes > 0) {
while (--nbytes > 0) {
*dest++ ^= 0xff;
}
*dest ^= 0xff >> (~y2&7);
} else {
*--dest ^= 0xff << ((y2+1)&7);
}
}
#define LOCHAR 0x20
#define HICHAR 0x5e
const byte font8x8[HICHAR-LOCHAR+1][8] = {
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, { 0x00,0x00,0x00,0x79,0x79,0x00,0x00,0x00 }, { 0x00,0x70,0x70,0x00,0x00,0x70,0x70,0x00 }, { 0x14,0x7f,0x7f,0x14,0x14,0x7f,0x7f,0x14 }, { 0x00,0x12,0x3a,0x6b,0x6b,0x2e,0x24,0x00 }, { 0x00,0x63,0x66,0x0c,0x18,0x33,0x63,0x00 }, { 0x00,0x26,0x7f,0x59,0x59,0x77,0x27,0x05 }, { 0x00,0x00,0x00,0x10,0x30,0x60,0x40,0x00 }, { 0x00,0x00,0x1c,0x3e,0x63,0x41,0x00,0x00 }, { 0x00,0x00,0x41,0x63,0x3e,0x1c,0x00,0x00 }, { 0x08,0x2a,0x3e,0x1c,0x1c,0x3e,0x2a,0x08 }, { 0x00,0x08,0x08,0x3e,0x3e,0x08,0x08,0x00 }, { 0x00,0x00,0x00,0x03,0x03,0x00,0x00,0x00 }, { 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00 }, { 0x00,0x00,0x00,0x03,0x03,0x00,0x00,0x00 }, { 0x00,0x01,0x03,0x06,0x0c,0x18,0x30,0x20 }, { 0x00,0x3e,0x7f,0x49,0x51,0x7f,0x3e,0x00 }, { 0x00,0x01,0x11,0x7f,0x7f,0x01,0x01,0x00 }, { 0x00,0x23,0x67,0x45,0x49,0x79,0x31,0x00 }, { 0x00,0x22,0x63,0x49,0x49,0x7f,0x36,0x00 }, { 0x00,0x0c,0x0c,0x14,0x34,0x7f,0x7f,0x04 }, { 0x00,0x72,0x73,0x51,0x51,0x5f,0x4e,0x00 }, { 0x00,0x3e,0x7f,0x49,0x49,0x6f,0x26,0x00 }, { 0x00,0x60,0x60,0x4f,0x5f,0x70,0x60,0x00 }, { 0x00,0x36,0x7f,0x49,0x49,0x7f,0x36,0x00 }, { 0x00,0x32,0x7b,0x49,0x49,0x7f,0x3e,0x00 }, { 0x00,0x00,0x00,0x12,0x12,0x00,0x00,0x00 }, { 0x00,0x00,0x00,0x13,0x13,0x00,0x00,0x00 }, { 0x00,0x08,0x1c,0x36,0x63,0x41,0x41,0x00 }, { 0x00,0x14,0x14,0x14,0x14,0x14,0x14,0x00 }, { 0x00,0x41,0x41,0x63,0x36,0x1c,0x08,0x00 }, { 0x00,0x20,0x60,0x45,0x4d,0x78,0x30,0x00 }, { 0x00,0x3e,0x7f,0x41,0x59,0x79,0x3a,0x00 }, { 0x00,0x1f,0x3f,0x68,0x68,0x3f,0x1f,0x00 }, { 0x00,0x7f,0x7f,0x49,0x49,0x7f,0x36,0x00 }, { 0x00,0x3e,0x7f,0x41,0x41,0x63,0x22,0x00 }, { 0x00,0x7f,0x7f,0x41,0x63,0x3e,0x1c,0x00 }, { 0x00,0x7f,0x7f,0x49,0x49,0x41,0x41,0x00 }, { 0x00,0x7f,0x7f,0x48,0x48,0x40,0x40,0x00 }, { 0x00,0x3e,0x7f,0x41,0x49,0x6f,0x2e,0x00 }, { 0x00,0x7f,0x7f,0x08,0x08,0x7f,0x7f,0x00 }, { 0x00,0x00,0x41,0x7f,0x7f,0x41,0x00,0x00 }, { 0x00,0x02,0x03,0x41,0x7f,0x7e,0x40,0x00 }, { 0x00,0x7f,0x7f,0x1c,0x36,0x63,0x41,0x00 }, { 0x00,0x7f,0x7f,0x01,0x01,0x01,0x01,0x00 }, { 0x00,0x7f,0x7f,0x30,0x18,0x30,0x7f,0x7f }, { 0x00,0x7f,0x7f,0x38,0x1c,0x7f,0x7f,0x00 }, { 0x00,0x3e,0x7f,0x41,0x41,0x7f,0x3e,0x00 }, { 0x00,0x7f,0x7f,0x48,0x48,0x78,0x30,0x00 }, { 0x00,0x3c,0x7e,0x42,0x43,0x7f,0x3d,0x00 }, { 0x00,0x7f,0x7f,0x4c,0x4e,0x7b,0x31,0x00 }, { 0x00,0x32,0x7b,0x49,0x49,0x6f,0x26,0x00 }, { 0x00,0x40,0x40,0x7f,0x7f,0x40,0x40,0x00 }, { 0x00,0x7e,0x7f,0x01,0x01,0x7f,0x7e,0x00 }, { 0x00,0x7c,0x7e,0x03,0x03,0x7e,0x7c,0x00 }, { 0x00,0x7f,0x7f,0x06,0x0c,0x06,0x7f,0x7f }, { 0x00,0x63,0x77,0x1c,0x1c,0x77,0x63,0x00 }, { 0x00,0x70,0x78,0x0f,0x0f,0x78,0x70,0x00 }, { 0x00,0x43,0x47,0x4d,0x59,0x71,0x61,0x00 }, { 0x00,0x00,0x7f,0x7f,0x41,0x41,0x00,0x00 }, { 0x00,0x20,0x30,0x18,0x0c,0x06,0x03,0x01 }, { 0x00,0x00,0x41,0x41,0x7f,0x7f,0x00,0x00 }, { 0x00,0x08,0x18,0x3f,0x3f,0x18,0x08,0x00 }
};
void draw_char(char ch, byte x, byte y) {
byte i;
const byte* src = &font8x8[(ch-LOCHAR)][0];
byte* dest = &vidmem[x*8][y];
for (i=0; i<8; i++) {
*dest = *src;
dest += 32;
src += 1;
}
}
void draw_string(const char* str, byte x, byte y) {
do {
byte ch = *str++;
if (!ch) break;
draw_char(ch, x, y);
x++;
} while (1);
}
////
void draw_font() {
byte i=LOCHAR;
do {
draw_char(i, i&15, 31-(i>>4));
draw_vline(i, i, i*2);
xor_pixel(i*15, i);
} while (++i != HICHAR);
}
void main() {
clrscr();
draw_font();
draw_string("HELLO WORLD", 0, 0);
while (1) watchdog_strobe = 0;
}

File diff suppressed because one or more lines are too long

View File

@ -23,6 +23,7 @@ byte __at (0xe800) tileram[256][8];
#define COIN1 (input3 & 0x8)
#define START1 !(input2 & 0x10)
#define START2 !(input3 & 0x20)
#define TIMER500HZ (input2 & 0x8)
// GAME DATA
@ -54,9 +55,11 @@ __endasm;
////////
void wait_for_vsync() {
while ((input1 & 0x8) != 0) ; // wait for VSYNC end
while ((input1 & 0x8) == 0) ; // wait for VSYNC start
void delay(byte msec) {
while (msec--) {
while (TIMER500HZ != 0) ;
while (TIMER500HZ == 0) ;
}
}
#define LOCHAR 0x0
@ -173,8 +176,7 @@ void flash_colliders() {
for (i=0; i<60; i++) {
if (players[0].collided) players[0].head_attr ^= 0x80;
if (players[1].collided) players[1].head_attr ^= 0x80;
wait_for_vsync();
wait_for_vsync();
delay(5);
draw_player(0);
draw_player(1);
palette = i;
@ -186,7 +188,7 @@ void make_move() {
byte i;
for (i=0; i<FRAMES_PER_MOVE; i++) {
human_control(0);
wait_for_vsync();
delay(10);
}
ai_control(1);
// if players collide, 2nd player gets the point

View File

@ -13,6 +13,7 @@ __sfr __at (0x3) input3;
__sfr __at (0x1) ay8910_reg;
__sfr __at (0x2) ay8910_data;
__sfr __at (0x8) assert_coin_status;
__sfr __at (0x40) palette;
byte __at (0xe000) cellram[28][32];
@ -23,10 +24,10 @@ byte __at (0xe800) tileram[256][8];
#define UP1 !(input1 & 0x40)
#define DOWN1 !(input1 & 0x80)
#define FIRE1 !(input2 & 0x20)
#define COIN1 (input3 & 0x8)
#define START1 !(input2 & 0x10)
#define START2 !(input3 & 0x20)
#define VSYNC (input1 & 0x8)
#define TIMER500HZ (input2 & 0x8)
#define COIN1 (input3 & 0x8)
// GAME DATA
@ -106,11 +107,22 @@ word rand() {
return lfsr;
}
void wait_for_vsync() {
while (VSYNC != 0) lfsr++; // wait for VSYNC end
while (VSYNC == 0) lfsr++; // wait for VSYNC start
void delay(byte msec) {
while (msec--) {
while (TIMER500HZ != 0) lfsr++;
while (TIMER500HZ == 0) lfsr++;
}
}
#define PE(fg,bg) (((fg)<<5) | ((bg)<<1))
const byte __at (0x4000) color_prom[32] = {
PE(7,0),PE(3,0),PE(1,0),PE(3,0),PE(6,0),PE(3,0),PE(2,0),PE(6,0),
PE(7,0),PE(3,0),PE(1,0),PE(3,0),PE(6,0),PE(3,0),PE(2,0),PE(6,0),
PE(7,0),PE(3,0),PE(1,0),PE(3,0),PE(6,0),PE(3,0),PE(2,0),PE(6,0),
PE(7,0),PE(3,0),PE(1,0),PE(3,0),PE(6,0),PE(3,0),PE(2,0),PE(6,0),
};
#define LOCHAR 0x0
#define HICHAR 0xff
@ -265,8 +277,7 @@ void flash_colliders() {
for (i=0; i<60; i++) {
if (players[0].collided) players[0].head_attr ^= 0x80;
if (players[1].collided) players[1].head_attr ^= 0x80;
wait_for_vsync();
wait_for_vsync();
delay(5);
draw_player(&players[0]);
draw_player(&players[1]);
palette = i;
@ -282,7 +293,7 @@ void make_move() {
byte i;
for (i=0; i<frames_per_move; i++) {
human_control(&players[0]);
wait_for_vsync();
delay(10);
}
ai_control(&players[0]);
ai_control(&players[1]);
@ -307,13 +318,12 @@ void declare_winner(byte winner) {
byte i;
for (i=0; i<10; i++) {
draw_box(i,i,27-i,29-i,BOX_CHARS);
wait_for_vsync();
delay(10);
}
putstring(10,16,"WINNER:");
putstring(10,13,"PLAYER ");
putchar(10+7, 13, CHAR('1')+winner);
for (i=0; i<250; i++)
wait_for_vsync();
delay(250);
slide_right();
attract = 1;
}
@ -374,6 +384,7 @@ void test_ram() {
}
void main() {
assert_coin_status = 1;
if (COIN1) {
credits++;
} else {

View File

@ -1,30 +0,0 @@
<?php
$OUTDIR = $_SERVER['DOCUMENT_ROOT'] . '/.storage';
$filename = $_POST['filename'];
$text = $_POST['text'];
if (!$filename || !$text) {
http_response_code(400);
die;
}
$rec = array(
'filename' => $filename,
'text' => $text,
);
$json = json_encode($rec);
$hash = md5($json);
$outfn = "$OUTDIR/$hash";
$result = file_put_contents($outfn, $json);
if (!$result) {
http_response_code(500);
die;
}
header('Content-Type: text/json');
echo json_encode(array('key' => $hash));
?>

View File

@ -19,9 +19,9 @@ var GALAXIAN_KEYCODE_MAP = makeKeycodeMap([
var SCRAMBLE_KEYCODE_MAP = makeKeycodeMap([
[Keys.VK_UP, 0, -0x1], // P1
[Keys.VK_SHIFT, 0, -0x2], // bomb
[Keys.VK_SHIFT, 0, -0x2], // fire
[Keys.VK_7, 0, -0x4], // credit
[Keys.VK_SPACE, 0, -0x8], // fire
[Keys.VK_SPACE, 0, -0x8], // bomb
[Keys.VK_RIGHT, 0, -0x10],
[Keys.VK_LEFT, 0, -0x20],
[Keys.VK_6, 0, -0x40],
@ -205,8 +205,8 @@ var GalaxianPlatform = function(mainElement, options) {
read: new AddressDecoder([
[0x0000, 0x3fff, 0, function(a) { return rom ? rom[a] : null; }],
[0x4000, 0x47ff, 0x7ff, function(a) { return ram.mem[a]; }],
[0x4800, 0x4fff, 0x3ff, function(a) { return vram.mem[a]; }],
[0x5000, 0x5fff, 0xff, function(a) { return oram.mem[a]; }],
// [0x4800, 0x4fff, 0x3ff, function(a) { return vram.mem[a]; }],
// [0x5000, 0x5fff, 0xff, function(a) { return oram.mem[a]; }],
[0x7000, 0x7000, 0, function(a) { watchdog_counter = INITIAL_WATCHDOG; }],
[0x7800, 0x7800, 0, function(a) { watchdog_counter = INITIAL_WATCHDOG; }],
//[0x8000, 0x820f, 0, function(a) { return noise(); }], // TODO: remove
@ -224,7 +224,7 @@ var GalaxianPlatform = function(mainElement, options) {
[0x4000, 0x47ff, 0x7ff, function(a,v) { ram.mem[a] = v; }],
[0x4800, 0x4fff, 0x3ff, function(a,v) { vram.mem[a] = v; }],
[0x5000, 0x5fff, 0xff, function(a,v) { oram.mem[a] = v; }],
[0x6801, 0x6801, 0, function(a,v) { interruptEnabled = 1; }],
[0x6801, 0x6801, 0, function(a,v) { interruptEnabled = v & 1; /*console.log(a,v,cpu.getPC().toString(16));*/ }],
[0x6802, 0x6802, 0, function(a,v) { /* TODO: coin counter */ }],
[0x6803, 0x6803, 0, function(a,v) { /* TODO: backgroundColor = (v & 1) ? 0xFF000056 : 0xFF000000; */ }],
[0x6804, 0x6804, 0, function(a,v) { starsEnabled = v & 1; }],
@ -323,7 +323,7 @@ var GalaxianPlatform = function(mainElement, options) {
this.loadROM = function(title, data) {
rom = padBytes(data, romSize);
// palette is at 0x3800-0x381f by default
palette = new Uint32Array(new ArrayBuffer(32*4));
for (var i=0; i<32; i++) {
var b = rom[palBase+i];

View File

@ -3,8 +3,9 @@
// http://www.computerarcheology.com/Arcade/
var MW8080BW_PRESETS = [
{id:'game2.c', name:'Shoot-em-up Game'},
{id:'gfxtest.c', name:'Graphics Test'},
{id:'shifter.c', name:'Sprite w/ Bit Shifter'},
{id:'game2.c', name:'Cosmic Impalas'},
];
var Midway8080BWPlatform = function(mainElement) {

View File

@ -26,12 +26,11 @@ var KonamiSoundPlatform = function(mainElement) {
ram = new RAM(0x400);
membus = {
read: new AddressDecoder([
[0x0000, 0x3fff, 0x1fff, function(a) { return rom ? rom[a] : null; }],
[0x0000, 0x3fff, 0x3fff, function(a) { return rom ? rom[a] : null; }],
[0x4000, 0x5fff, 0x3ff, function(a) { return ram.mem[a]; }]
]),
write: new AddressDecoder([
[0x4000, 0x5fff, 0x3ff, function(a,v) { ram.mem[a] = v; }],
[0x6000, 0x6fff, 0, function(a,v) { }],
]),
isContended: function() { return false; },
};
@ -40,7 +39,7 @@ var KonamiSoundPlatform = function(mainElement) {
if (addr & 0x40) {
if (psgRegister == 0xf) { // timer
var bit = (cpu.getTstates() / cpuCyclesPerTimer) & 1;
return bit << 3;
return bit ? 0xff : 0x00; // 0x00, 0x10, 0x20, 0x30, 0x40, 0x90, 0xa0, 0xb0, 0xa0, 0xd0
}
return psg.readRegister(psgRegister) & 0xff;
}
@ -142,4 +141,4 @@ var KonamiSoundPlatform = function(mainElement) {
}
}
PLATFORMS['konamisound'] = KonamiSoundPlatform;
PLATFORMS['sound_konami'] = KonamiSoundPlatform;

View File

@ -21,13 +21,15 @@ var VicDualPlatform = function(mainElement) {
var XTAL = 15468000.0;
var scanlinesPerFrame = 0x106;
var vblankStart = 0xe0;
var vsyncStart = 0xec;
var vsyncEnd = 0xf0;
var cpuFrequency = XTAL/8;
var hsyncFrequency = XTAL/3/scanlinesPerFrame;
var vsyncFrequency = hsyncFrequency/0x148;
var cpuCyclesPerLine = cpuFrequency/hsyncFrequency;
var timerFrequency = 500; // TODO
var timerFrequency = 500; // input 2 bit 0x8
var cyclesPerTimerTick = cpuFrequency / (2 * timerFrequency);
var reset_disable = false;
var reset_disable_timer;
var framestats;
@ -115,7 +117,7 @@ var VicDualPlatform = function(mainElement) {
write: function(addr, val) {
if (addr & 0x1) { psg.selectRegister(val & 0xf); }; // audio 1
if (addr & 0x2) { psg.setData(val); }; // audio 2
if (addr & 0x8) { }; // coin status
if (addr & 0x8) { }; // TODO: assert coin status
if (addr & 0x40) { palbank = val & 3; }; // palette
}
};
@ -146,9 +148,11 @@ var VicDualPlatform = function(mainElement) {
var debugCond = self.getDebugCallback();
var targetTstates = cpu.getTstates();
for (var sl=0; sl<scanlinesPerFrame; sl++) {
inputs[2] &= ~0x8;
inputs[2] |= ((cpu.getTstates() / cyclesPerTimerTick) & 1) << 3;
drawScanline(pixels, sl);
targetTstates += cpuCyclesPerLine;
if (sl == vsyncStart) inputs[1] |= 0x8;
if (sl == vblankStart) inputs[1] |= 0x8;
if (sl == vsyncEnd) inputs[1] &= ~0x8;
if (debugCond) {
while (cpu.getTstates() < targetTstates) {
@ -165,7 +169,7 @@ var VicDualPlatform = function(mainElement) {
}
this.loadROM = function(title, data) {
rom = padBytes(data, 0x4000);
rom = padBytes(data, 0x4040);
self.reset();
}

View File

@ -9,7 +9,7 @@ var PLATFORM_PARAMS = {
},
'vicdual': {
code_start: 0x0,
code_size: 0x4000,
code_size: 0x4020,
data_start: 0xe400,
data_size: 0x400,
},

27
tools/mw8080/Makefile Normal file
View File

@ -0,0 +1,27 @@
all: cp437.mw8080.c c64.mw8080.c baddies-horiz.rot.c scrappy.rot.c
cp437.mw8080.c: ../cp437-8x8.bdf
python ../parsebdf8.py $< -f -r -C > $@
c64.mw8080.c: ../c64.bdf
python ../parsebdf8.py $< -f -r -C -s 32 -e 94 > $@
%.h:
cat $* | hexdump -v -e '"\n" 128/1 "0x%02x,"'
%.c: %.pbm
python ../pbm_to_c.py $< > $@
#%.rot.pbm: %.pbm
# convert $< -transpose -bordercolor white -border 4x4 $@
baddies-horiz.rot.pbm: ../baddies-horiz.png
convert $< +dither -brightness-contrast 50x50 -fill black -transpose -negate $@
scrappy.rot.pbm: ../scrappy48x64.pbm
convert $< -transpose -bordercolor white -border 4x4 $@

View File

@ -1,12 +1,30 @@
#!/usr/bin/python
import sys,string
import sys,string,argparse
height = 8
lochar = 0x20 #48
hichar = 0x5e #57
lochar = 0
hichar = 255
#lochar = 0x20 #48
#hichar = 0x5e #57
parser = argparse.ArgumentParser()
parser.add_argument('-s', '--start', type=int, default=0, help="index of first character")
parser.add_argument('-e', '--end', type=int, default=255, help="index of last character")
parser.add_argument('-H', '--height', type=int, default=8, help="character height")
parser.add_argument('-i', '--invert', action="store_true", help="invert bits")
parser.add_argument('-r', '--rotate', action="store_true", help="rotate bits (vertical)")
parser.add_argument('-f', '--flip', action="store_true", help="flip bits (horizontal)")
outfmtgroup = parser.add_mutually_exclusive_group()
outfmtgroup.add_argument("-A", "--asmhex", action="store_true", help="DASM-compatible hex")
outfmtgroup.add_argument("-C", "--carray", action="store_true", help="Nested C array")
outfmtgroup.add_argument("-F", "--flatcarray", action="store_true", help="Flat C array")
parser.add_argument('bdffile', help="BDF bitmap file")
args = parser.parse_args()
height = args.height
lochar = args.start
hichar = args.end
invert = args.invert
flip = args.flip
rotate = args.rotate
chars = {}
inbitmap = 0
@ -28,7 +46,7 @@ with open(sys.argv[1],'r') as f:
bytes.insert(0,0)
assert(len(bytes) == height)
bytes.reverse()
print chord,bytes
#print chord,bytes
chars[chord] = bytes
elif inbitmap and len(toks) == 1:
byte = int(toks[0],16)
@ -37,40 +55,44 @@ with open(sys.argv[1],'r') as f:
# output font table
x = 0
output = []
invoutput = []
revoutput = []
rotoutput = []
rot2output = []
for ch in range(lochar,hichar+1):
bytes = chars.get(ch)
#bytes = bytes + [0]
if not bytes:
bytes = [0] * height
if flip:
bytes.reverse()
if rotate:
rotbytes = [0] * height
for x in range(0,height):
for y in range(0,height):
rotbytes[-1-x] |= (((bytes[-1-y]>>x)&1)<<y)
bytes = rotbytes
#rotoutput[-7+x] |= (((output[-1-y]>>x)&1)<<y)
#rotoutput[-1-x] |= (((output[-1-y]>>x)&1)<<y)
#rot2output[-1-x] |= (((output[-7+y]>>x)&1)<<y)
for b in bytes:
output.append(b)
invoutput.append(b ^ 0xff)
rotoutput.append(0)
rot2output.append(0)
for i in range(0,8):
revoutput.append(bytes[7-i])
for x in range(0,height):
for y in range(0,height):
#rotoutput[-7+x] |= (((output[-1-y]>>x)&1)<<y)
rotoutput[-1-x] |= (((output[-1-y]>>x)&1)<<y)
rot2output[-1-x] |= (((output[-7+y]>>x)&1)<<y)
def tohex(v):
return '%02x'%v
def tohex2(v):
return '0x%02x'%v
for arr in [output,revoutput,invoutput,rotoutput,rot2output]:
print '\thex ' + string.join(map(tohex,arr),'')
print string.join(map(tohex2,arr),',')
for i in range(0,len(output),height):
print '{', string.join(map(tohex2,arr[i:i+height]),','), '},',
print
print
for arr in [output]:
if args.asmhex:
print '\thex ' + string.join(map(tohex,arr),'')
if args.carray:
print "static char FONT[%d][%d] = {" % (hichar-lochar+1, height)
for i in range(0,len(output),height):
print '{', string.join(map(tohex2,arr[i:i+height]),','), '},',
print
print "};"
if args.flatcarray:
print "static char FONT[%d] = {" % ((hichar-lochar+1) * height)
print string.join(map(tohex2,arr),',')
print "}";
print len(output),len(invoutput),len(rotoutput),len(rot2output)

View File

@ -1,6 +1,6 @@
#!/usr/bin/python
import sys, struct
import sys
# reverse byte
def rev(n):

13
tools/vicdual/Makefile Normal file
View File

@ -0,0 +1,13 @@
all: cp437.vicdual.c c64.vicdual.c
cp437.vicdual.c: ../cp437-8x8.bdf
python ../parsebdf8.py $< -r -C > $@
c64.vicdual.c: ../c64.bdf
python ../parsebdf8.py $< -r -C > $@
%.h:
cat $* | hexdump -v -e '"\n" 128/1 "0x%02x,"'