mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-12-17 10:30:00 +00:00
initial wiz support (vcs and nes)
This commit is contained in:
parent
f3ed9191ee
commit
5ee1c7e8a3
139
presets/nes/hello.wiz
Normal file
139
presets/nes/hello.wiz
Normal file
@ -0,0 +1,139 @@
|
||||
|
||||
bank zeropage @ 0x00 : [vardata; 256];
|
||||
bank stack @ 0x100 : [vardata; 256];
|
||||
bank ram @ 0x200 : [vardata; 1536];
|
||||
bank prg @ 0x8000 : [constdata; 32768];
|
||||
bank chr : [chrdata; 8192];
|
||||
|
||||
import "nes";
|
||||
|
||||
in zeropage {
|
||||
var b0, b1, b2, b3, b4, b5, b6, b7 : u8;
|
||||
var ptr0 @ &b0, ptr2 @ &b2 : *u8;
|
||||
}
|
||||
|
||||
in prg {
|
||||
func main() {
|
||||
// Disable decimal arithmetic (though not actually supported on 2A03 anyway)
|
||||
decimal = false;
|
||||
// Disable interrupts.
|
||||
nointerrupt = true;
|
||||
// Prepare stack.
|
||||
s = x = 0xFF;
|
||||
|
||||
// Turn off rendering.
|
||||
nes.ppu.control = x = 0;
|
||||
nes.ppu.mask = x;
|
||||
// Disable DMC interrupts.
|
||||
nes.apu.frame_counter = a = nes.apu.FRAME_COUNTER_IRQ_DISABLE;
|
||||
|
||||
// Wait for the PPU to be ready to use, which takes 2 vertical blanks.
|
||||
do {
|
||||
do {} while !nes.ppu.status$7;
|
||||
x++;
|
||||
} while x != 2;
|
||||
|
||||
// Read PPU status to reset the PPU high/low latch.
|
||||
a = nes.ppu.status;
|
||||
// Now setup the PPU for copying to the nametable.
|
||||
nes.ppu.address = a = >:nes.ppu.ADDRESS_NAMETABLE_DATA;
|
||||
nes.ppu.address = a = <:nes.ppu.ADDRESS_NAMETABLE_DATA;
|
||||
// Clear the nametable.
|
||||
x = >:nes.ppu.NAMETABLE_SIZE * 2;
|
||||
do {
|
||||
y = 0;
|
||||
do {
|
||||
nes.ppu.data = a;
|
||||
y++;
|
||||
} while !zero;
|
||||
|
||||
x--;
|
||||
} while !zero;
|
||||
|
||||
// Read PPU status to reset the PPU high/low latch.
|
||||
a = nes.ppu.status;
|
||||
// Now setup the PPU for copying to the palette.
|
||||
nes.ppu.address = a = >:nes.ppu.ADDRESS_PALETTE_DATA;
|
||||
nes.ppu.address = a = <:nes.ppu.ADDRESS_PALETTE_DATA;
|
||||
// Clear the palette.
|
||||
x = 0;
|
||||
do {
|
||||
nes.ppu.data = a = palette[x++];
|
||||
} while x != palette.len;
|
||||
|
||||
{
|
||||
let START_X = 10;
|
||||
let START_Y = 13;
|
||||
let TILE_ADDRESS = nes.ppu.ADDRESS_NAMETABLE_DATA + START_Y * 32 + START_X;
|
||||
|
||||
// Read PPU status to reset the PPU high/low latch.
|
||||
a = nes.ppu.status;
|
||||
// Now setup the PPU for copying to the nametable.
|
||||
nes.ppu.address = a = >:TILE_ADDRESS;
|
||||
nes.ppu.address = a = <:TILE_ADDRESS;
|
||||
// Copy the message.
|
||||
x = 0;
|
||||
while {
|
||||
a = message[y];
|
||||
} && !zero {
|
||||
y++;
|
||||
nes.ppu.data = a;
|
||||
}
|
||||
}
|
||||
|
||||
a = nes.ppu.status;
|
||||
nes.ppu.scroll = a = 0;
|
||||
nes.ppu.scroll = a;
|
||||
|
||||
// We're finally ready to show the screen!
|
||||
nes.ppu.control = a = nes.ppu.CONTROL_NMI;
|
||||
nes.ppu.mask = a = nes.ppu.MASK_LEFTMOST_BG | nes.ppu.MASK_RENDER_BG;
|
||||
|
||||
// Enable interrupts.
|
||||
nointerrupt = false;
|
||||
|
||||
while true {}
|
||||
}
|
||||
|
||||
#[nmi] func draw() {
|
||||
push(a);
|
||||
a = x; push(a);
|
||||
a = y; push(a);
|
||||
a = nes.ppu.status;
|
||||
nes.ppu.scroll = a = 0;
|
||||
nes.ppu.scroll = a;
|
||||
y = a = pop();
|
||||
x = a = pop();
|
||||
a = pop();
|
||||
}
|
||||
|
||||
#[irq] func scanline() {
|
||||
push(a);
|
||||
a = x; push(a);
|
||||
a = y; push(a);
|
||||
y = a = pop();
|
||||
x = a = pop();
|
||||
a = pop();
|
||||
}
|
||||
|
||||
const message = "HELLO WORLD\0";
|
||||
|
||||
const palette : [u8] = [
|
||||
// Tiles
|
||||
0x0F, 0x00, 0x10, 0x30,
|
||||
0x0F, 0x00, 0x10, 0x30,
|
||||
0x0F, 0x00, 0x10, 0x30,
|
||||
0x0F, 0x00, 0x10, 0x30,
|
||||
// Sprites
|
||||
0x0F, 0x00, 0x10, 0x30,
|
||||
0x0F, 0x00, 0x10, 0x30,
|
||||
0x0F, 0x00, 0x10, 0x30,
|
||||
0x0F, 0x00, 0x10, 0x30
|
||||
];
|
||||
|
||||
const @ 0xFFFA = [draw, main, scanline];
|
||||
}
|
||||
|
||||
in chr {
|
||||
const = embed "hello_tiles.chr";
|
||||
}
|
2
presets/vcs/banks.wiz
Normal file
2
presets/vcs/banks.wiz
Normal file
@ -0,0 +1,2 @@
|
||||
bank rom @ 0xF000 : [constdata; 4096];
|
||||
bank ram @ 0x80 : [vardata; 128];
|
33
presets/vcs/random.wiz
Normal file
33
presets/vcs/random.wiz
Normal file
@ -0,0 +1,33 @@
|
||||
import "banks";
|
||||
|
||||
// Random Number Library
|
||||
//
|
||||
// Uses a Galois Linear Feedback Shift Register to generate random numbers.
|
||||
// http://en.wikipedia.org/wiki/Linear_feedback_shift_register#Galois_LFSRs
|
||||
//
|
||||
// [random.lo] and [random.hi] must be defined in RAM somewhere.
|
||||
namespace random {
|
||||
in ram {
|
||||
var lo : u8;
|
||||
var hi : u8;
|
||||
}
|
||||
|
||||
// The polynomial value is taken from here:
|
||||
// http://users.ece.cmu.edu/~koopman/lfsr/16.txt
|
||||
let LSFR_POLYNOMIAL = 0x845F;
|
||||
|
||||
// Get a pseudorandom 16-bit number.
|
||||
// Precondition:
|
||||
// random.lo, random.hi are currently seeded to some non-zero value.
|
||||
// Return:
|
||||
// random.lo, random.hi = result
|
||||
func next() {
|
||||
random.hi = random.hi >>> 1;
|
||||
random.lo = random.lo >>>># 1;
|
||||
|
||||
if carry {
|
||||
random.lo = a = random.lo ^ LSFR_POLYNOMIAL as u8;
|
||||
random.hi = a = random.hi ^ (LSFR_POLYNOMIAL >> 8) as u8;
|
||||
}
|
||||
}
|
||||
}
|
702
presets/vcs/wiz/finalduck.wiz
Normal file
702
presets/vcs/wiz/finalduck.wiz
Normal file
@ -0,0 +1,702 @@
|
||||
import "vcs";
|
||||
import "banks";
|
||||
|
||||
in ram {
|
||||
var t0, t1, t2, t3, t4, t5, t6, t7 : u8;
|
||||
|
||||
var joy : u8;
|
||||
var fire : [u8; 2];
|
||||
var unpress : [u8; 2];
|
||||
var score : [u8; 2];
|
||||
var water_color : u8;
|
||||
|
||||
namespace winner {
|
||||
var x, y : u8;
|
||||
}
|
||||
|
||||
namespace voice {
|
||||
var index : [u8; 2];
|
||||
var length : [u8; 2];
|
||||
}
|
||||
|
||||
namespace game {
|
||||
let SCORE_X = 50;
|
||||
let START_X = 30;
|
||||
let START_Y = 40;
|
||||
let WINNER_X = 45;
|
||||
let WINNER_X2 = 160 - 45 + 5;
|
||||
let LEFT_EDGE = 16;
|
||||
let RIGHT_EDGE = 160 - 16;
|
||||
let COLOR_WATER_START = 0xA2;
|
||||
let COLOR_P1 = 0xFF;
|
||||
let COLOR_P2 = 0x8F;
|
||||
let COLOR_BREAD = 0x28;
|
||||
|
||||
let DETUNE_P2 = 2;
|
||||
}
|
||||
|
||||
namespace sprite {
|
||||
let PLAYER1 = 0;
|
||||
let PLAYER2 = 1;
|
||||
let MISSILE1 = 2;
|
||||
let MISSILE2 = 3;
|
||||
let BALL = 4;
|
||||
let COUNT = 5;
|
||||
|
||||
var x : [u8; COUNT];
|
||||
var y : [u8; COUNT];
|
||||
var data : [u8; COUNT];
|
||||
var gfx_ptr : [*const u8; COUNT];
|
||||
}
|
||||
|
||||
namespace player1 {
|
||||
let index = sprite.PLAYER1;
|
||||
|
||||
var x @ &sprite.x[index] : u8;
|
||||
var y @ &sprite.y[index] : u8;
|
||||
var reflect @ &sprite.data[index] : u8;
|
||||
var gfx_ptr @ &sprite.gfx_ptr[index] : *const u8;
|
||||
}
|
||||
|
||||
namespace player2 {
|
||||
let index = sprite.PLAYER2;
|
||||
|
||||
var x @ &sprite.x[index] : u8;
|
||||
var y @ &sprite.y[index] : u8;
|
||||
var reflect @ &sprite.data[index] : u8;
|
||||
var gfx_ptr @ &sprite.gfx_ptr[index] : *const u8;
|
||||
}
|
||||
|
||||
namespace missile1 {
|
||||
let index = sprite.MISSILE1;
|
||||
|
||||
var x @ &sprite.x[index] : u8;
|
||||
var y @ &sprite.y[index] : u8;
|
||||
var speed @ &sprite.data[index] : u8;
|
||||
var gfx_ptr @ &sprite.gfx_ptr[index] : *const u8;
|
||||
}
|
||||
|
||||
namespace missile2 {
|
||||
let index = sprite.MISSILE2;
|
||||
|
||||
var x @ &sprite.x[index] : u8;
|
||||
var y @ &sprite.y[index] : u8;
|
||||
var speed @ &sprite.data[index] : u8;
|
||||
var gfx_ptr @ &sprite.gfx_ptr[index] : *const u8;
|
||||
}
|
||||
|
||||
namespace ball {
|
||||
let index = sprite.BALL;
|
||||
|
||||
var x @ &sprite.x[index] : u8;
|
||||
var y @ &sprite.y[index] : u8;
|
||||
var gfx_ptr @ &sprite.gfx_ptr[index] : *const u8;
|
||||
}
|
||||
}
|
||||
|
||||
in rom {
|
||||
import "random";
|
||||
|
||||
func main() {
|
||||
nointerrupt = true;
|
||||
decimal = false;
|
||||
s = x = 0xFF;
|
||||
a = 0;
|
||||
|
||||
vcs.pattern.missile1 = a;
|
||||
vcs.pattern.missile2 = a;
|
||||
vcs.pattern.player1 = a;
|
||||
vcs.pattern.player2 = a;
|
||||
vcs.pattern.playfield1 = a;
|
||||
vcs.pattern.playfield2 = a;
|
||||
vcs.pattern.playfield3 = a;
|
||||
vcs.color.bg = a;
|
||||
vcs.color.fg = a;
|
||||
vcs.color.player1 = a = game.COLOR_P1;
|
||||
vcs.color.player2 = a = game.COLOR_P2;
|
||||
vcs.color.fg = a = game.COLOR_BREAD;
|
||||
vcs.color.bg = a = 0x00;
|
||||
vcs.control.player1 = a = vcs.control.PLAYER_SINGLE | vcs.control.MISSILE_4PX;
|
||||
vcs.control.player2 = a = vcs.control.PLAYER_SINGLE | vcs.control.MISSILE_4PX;
|
||||
vcs.control.playfield = a = vcs.control.BALL_4PX;
|
||||
|
||||
player1.x = a = game.START_X;
|
||||
player1.y = a = game.START_Y;
|
||||
player1.reflect = a = vcs.reflect.ENABLE;
|
||||
player2.x = a = 160 - player1.x;
|
||||
player2.y = a = game.START_Y;
|
||||
player2.reflect = a = player1.reflect ^ vcs.reflect.ENABLE;
|
||||
ball.x = a = 84;
|
||||
ball.y = a = game.START_Y;
|
||||
missile1.x = a = 30;
|
||||
missile1.y = a = 200;
|
||||
missile1.speed = a = 0;
|
||||
missile2.x = a = 160 - 30;
|
||||
missile2.y = a = 200;
|
||||
missile2.speed = a = 0;
|
||||
water_color = a = game.COLOR_WATER_START;
|
||||
vcs.hmove.clear = a;
|
||||
|
||||
score[0] = a = 0;
|
||||
score[1] = a = 0;
|
||||
voice.length[0] = a = 0;
|
||||
voice.length[1] = a = 0;
|
||||
winner.x = a = game.WINNER_X;
|
||||
winner.y = a = 8;
|
||||
|
||||
a = vcs.timer.value;
|
||||
if zero {
|
||||
a += 1;
|
||||
}
|
||||
|
||||
random.lo = a;
|
||||
random.hi = a;
|
||||
|
||||
voice.index[0] = a = &sfx.intro as u8;
|
||||
voice.length[0] = a = sfx.intro.len;
|
||||
|
||||
while true {
|
||||
vcs.sync.vsync = a = vcs.sync.VSYNC_START;
|
||||
inline for let i in 1 .. 3 {
|
||||
vcs.sync.wsync = a;
|
||||
}
|
||||
vcs.timer.set64 = a = 43;
|
||||
vcs.sync.vsync = a = 0;
|
||||
|
||||
vcs.io.ddr_a = a = 0;
|
||||
joy = a = vcs.io.port_a;
|
||||
fire[0] = a = vcs.io.triggers[0] & vcs.io.TRIGGER_JOY_FIRE;
|
||||
fire[1] = a = vcs.io.triggers[1] & vcs.io.TRIGGER_JOY_FIRE;
|
||||
|
||||
random.next();
|
||||
|
||||
a = ball.y;
|
||||
if a >= 100 {
|
||||
spawn_bread();
|
||||
} else {
|
||||
x = sprite.PLAYER1;
|
||||
move_player_sprite();
|
||||
joy = a = joy << 4;
|
||||
x = sprite.PLAYER2;
|
||||
move_player_sprite();
|
||||
x = sprite.MISSILE1;
|
||||
move_missile_sprite();
|
||||
x = sprite.MISSILE2;
|
||||
move_missile_sprite();
|
||||
}
|
||||
|
||||
inline for let i in 0 .. 1 {
|
||||
a = voice.length[i];
|
||||
if !zero {
|
||||
x = voice.index[i];
|
||||
vcs.audio.volumes[i] = a = sfx.volume_data[x];
|
||||
vcs.audio.frequencies[i] = a = ((sfx.data[x] & 0xF0) >>> 4) + (i * game.DETUNE_P2);
|
||||
vcs.audio.tones[i] = a = sfx.data[x] & 0x0F;
|
||||
voice.index[i]++;
|
||||
voice.length[i]--;
|
||||
} else {
|
||||
vcs.audio.volumes[i] = a = 0;
|
||||
}
|
||||
}
|
||||
|
||||
<:player1.gfx_ptr = a = score[0] << 3;
|
||||
>:player1.gfx_ptr = a = >:&graphic.digits;
|
||||
<:player2.gfx_ptr = a = score[1] << 3;
|
||||
>:player2.gfx_ptr = a = >:&graphic.digits;
|
||||
<:ball.gfx_ptr = a = <:&graphic.dot - winner.y;
|
||||
>:ball.gfx_ptr = a = >:&graphic.dot -# 0;
|
||||
<:missile1.gfx_ptr = a = <:&graphic.dot - missile1.y;
|
||||
>:missile1.gfx_ptr = a = >:&graphic.dot -# 0;
|
||||
<:missile2.gfx_ptr = a = <:&graphic.dot - missile2.y;
|
||||
>:missile2.gfx_ptr = a = >:&graphic.dot -# 0;
|
||||
|
||||
do { a = vcs.timer.value; } while !zero;
|
||||
vcs.sync.vblank = a = 0;
|
||||
a = game.SCORE_X;
|
||||
x = sprite.PLAYER1;
|
||||
position_sprite();
|
||||
a = 160 - game.SCORE_X;
|
||||
x = sprite.PLAYER2;
|
||||
position_sprite();
|
||||
a = winner.x;
|
||||
x = sprite.BALL;
|
||||
position_sprite();
|
||||
vcs.sync.wsync = a;
|
||||
vcs.reflect.player1 = a = 0;
|
||||
vcs.reflect.player2 = a;
|
||||
|
||||
x = 0;
|
||||
do {
|
||||
vcs.sync.wsync = a;
|
||||
x++;
|
||||
vcs.sync.wsync = a;
|
||||
y = a = x >>> 1;
|
||||
vcs.pattern.player1 = a = player1.gfx_ptr[y];
|
||||
vcs.pattern.player2 = a = player2.gfx_ptr[y];
|
||||
vcs.pattern.ball = a = ball.gfx_ptr[y];
|
||||
x++;
|
||||
|
||||
vcs.sync.wsync = a;
|
||||
} while x < 16;
|
||||
|
||||
push(a = x);
|
||||
|
||||
x = 0;
|
||||
do {
|
||||
a = sprite.x[x];
|
||||
position_sprite();
|
||||
x++;
|
||||
} while x != sprite.COUNT;
|
||||
|
||||
<:player1.gfx_ptr = a = <:&graphic.duck - player1.y;
|
||||
>:player1.gfx_ptr = a = >:&graphic.duck -# 0;
|
||||
<:player2.gfx_ptr = a = <:&graphic.duck - player2.y;
|
||||
>:player2.gfx_ptr = a = >:&graphic.duck -# 0;
|
||||
<:ball.gfx_ptr = a = <:&graphic.dot - ball.y;
|
||||
>:ball.gfx_ptr = a = >:&graphic.dot -# 0;
|
||||
vcs.sync.wsync = a;
|
||||
vcs.color.bg = a = water_color;
|
||||
vcs.reflect.player1 = a = player1.reflect;
|
||||
vcs.reflect.player2 = a = player2.reflect;
|
||||
|
||||
x = a = pop();
|
||||
|
||||
do {
|
||||
vcs.sync.wsync = a;
|
||||
y = a = x >>> 1;
|
||||
|
||||
vcs.pattern.player1 = a = player1.gfx_ptr[y];
|
||||
vcs.pattern.player2 = a = player2.gfx_ptr[y];
|
||||
vcs.pattern.ball = a = ball.gfx_ptr[y];
|
||||
|
||||
vcs.sync.wsync = a;
|
||||
vcs.pattern.missile1 = a = missile1.gfx_ptr[y];
|
||||
vcs.pattern.missile2 = a = missile2.gfx_ptr[y];
|
||||
|
||||
x++;
|
||||
x++;
|
||||
} while x < 187;
|
||||
|
||||
vcs.sync.wsync = a;
|
||||
a = 0;
|
||||
vcs.pattern.player1 = a;
|
||||
vcs.pattern.player2 = a;
|
||||
vcs.pattern.missile1 = a;
|
||||
vcs.pattern.missile2 = a;
|
||||
vcs.pattern.ball = a;
|
||||
vcs.pattern.playfield1 = a;
|
||||
vcs.pattern.playfield2 = a;
|
||||
vcs.pattern.playfield3 = a;
|
||||
vcs.color.bg = a;
|
||||
vcs.sync.vblank = a = vcs.sync.VBLANK_RESET_TRIGGER | vcs.sync.VBLANK_START;
|
||||
inline for let i in 1 .. 30 {
|
||||
vcs.sync.wsync = a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Arguments:
|
||||
// a = position
|
||||
func position_sprite() {
|
||||
vcs.hmove.clear = a;
|
||||
vcs.sync.wsync = a;
|
||||
|
||||
carry = true;
|
||||
do {
|
||||
a -#= 15;
|
||||
} while carry;
|
||||
|
||||
y = a;
|
||||
vcs.hmove.players[x] = a = ((&fine_adjust as u16 - 0xF1) as *u8)[y];
|
||||
vcs.reset.players[x] = a;
|
||||
vcs.sync.wsync = a;
|
||||
vcs.hmove.apply = a;
|
||||
inline for let i in 1 .. 6 {
|
||||
nop();
|
||||
}
|
||||
}
|
||||
|
||||
// Arguments:
|
||||
// x = sprite index
|
||||
func move_player_sprite() {
|
||||
y = joy;
|
||||
if { a = y & vcs.io.PORT_A_JOY_LEFT; } && zero {
|
||||
a = sprite.x[x] - 1;
|
||||
if a < game.LEFT_EDGE {
|
||||
a = game.LEFT_EDGE;
|
||||
}
|
||||
sprite.x[x] = a;
|
||||
sprite.data[x] = a = 0;
|
||||
} else if { a = y & vcs.io.PORT_A_JOY_RIGHT; } && zero {
|
||||
a = sprite.x[x] + 1;
|
||||
if a >= game.RIGHT_EDGE {
|
||||
a = game.RIGHT_EDGE;
|
||||
}
|
||||
sprite.x[x] = a;
|
||||
sprite.data[x] = a = vcs.reflect.ENABLE;
|
||||
}
|
||||
|
||||
if { a = y & vcs.io.PORT_A_JOY_UP; } && zero {
|
||||
sprite.y[x] = a = sprite.y[x] - 1;
|
||||
if !carry {
|
||||
sprite.y[x] = a = 94;
|
||||
}
|
||||
} else if { a = y & vcs.io.PORT_A_JOY_DOWN; } && zero {
|
||||
a = sprite.y[x] + 1;
|
||||
if a >= 94 {
|
||||
sprite.y[x] = a = 0;
|
||||
}
|
||||
sprite.y[x] = a;
|
||||
}
|
||||
|
||||
if { a = fire[x]; } && zero {
|
||||
if { a = unpress[x]; } && zero {
|
||||
unpress[x] = a = 1;
|
||||
check_bread();
|
||||
if { a = t5; } && zero {
|
||||
shoot_missile();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
unpress[x] = a = 0;
|
||||
}
|
||||
|
||||
check_enemy_missile();
|
||||
}
|
||||
|
||||
// Arguments:
|
||||
// x = sprite index
|
||||
func move_missile_sprite() {
|
||||
a = sprite.data[x];
|
||||
if !zero {
|
||||
a = sprite.x[x] + sprite.data[x];
|
||||
if a < game.LEFT_EDGE {
|
||||
sprite.y[x] = a = 200;
|
||||
sprite.data[x] = a = 0;
|
||||
} else if a >= game.RIGHT_EDGE {
|
||||
sprite.y[x] = a = 200;
|
||||
sprite.data[x] = a = 0;
|
||||
} else {
|
||||
sprite.x[x] = a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func spawn_bread() {
|
||||
random.next();
|
||||
a = random.lo;
|
||||
goto spawn_failed if a < 32;
|
||||
goto spawn_failed if a >= 160 - 32;
|
||||
ball.x = a;
|
||||
|
||||
a = random.hi;
|
||||
goto spawn_failed if a < 28;
|
||||
goto spawn_failed if a >= 84;
|
||||
ball.y = a;
|
||||
|
||||
return;
|
||||
|
||||
spawn_failed:
|
||||
ball.y = a = 200;
|
||||
}
|
||||
|
||||
func check_bread() {
|
||||
t0 = a = ball.x + 8;
|
||||
t1 = a = sprite.x[x] + 17;
|
||||
t2 = a = ball.y + 6;
|
||||
t3 = a = sprite.y[x] + 8;
|
||||
|
||||
t5 = a = 0;
|
||||
if { a = sprite.x[x]; } && a < t0 {
|
||||
if { a = ball.x + 2; } && a < t1 {
|
||||
if { a = sprite.y[x] + 1; } && a < t2 {
|
||||
if { a = ball.y; } && a < t3 {
|
||||
t5 = a = 1;
|
||||
ball.y = a = 200;
|
||||
|
||||
if { a = score[x]; } && a < 9 {
|
||||
score[x]++;
|
||||
voice.index[x] = a = &sfx.score as u8;
|
||||
voice.length[x] = a = sfx.score.len;
|
||||
} else {
|
||||
score[0] = a = 0;
|
||||
score[1] = a = 0;
|
||||
sprite.x[0] = a = game.START_X;
|
||||
sprite.y[0] = a = game.START_Y;
|
||||
sprite.x[1] = a = 160 - game.START_X;
|
||||
sprite.y[1] = a = game.START_Y;
|
||||
|
||||
random.next();
|
||||
a = random.lo & 0xF0 | 0x2;
|
||||
if a == water_color {
|
||||
a = a + 0x10;
|
||||
}
|
||||
water_color = a;
|
||||
|
||||
winner.y = a = 0;
|
||||
winner.x = a = game.WINNER_X;
|
||||
if x == 1 {
|
||||
winner.x = a = game.WINNER_X2;
|
||||
}
|
||||
|
||||
voice.index[x] = a = &sfx.win as u8;
|
||||
voice.length[x] = a = sfx.win.len;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func shoot_missile() {
|
||||
y = a = x + 2;
|
||||
if { a = sprite.data[y]; } && !zero {
|
||||
return;
|
||||
}
|
||||
|
||||
voice.index[x] = a = &sfx.shoot as u8;
|
||||
voice.length[x] = a = sfx.shoot.len;
|
||||
|
||||
sprite.x[y] = a = sprite.x[x];
|
||||
sprite.y[y] = a = sprite.y[x] + 1;
|
||||
if { a = sprite.data[x]; } && zero {
|
||||
a = (0x4 ^ 0xFF) + 1;
|
||||
} else {
|
||||
a = 0x4;
|
||||
}
|
||||
sprite.data[y] = a;
|
||||
}
|
||||
|
||||
func check_enemy_missile() {
|
||||
y = a = x ^ 1 + 2;
|
||||
t0 = a = sprite.x[y] + 8;
|
||||
t1 = a = sprite.x[x] + 17;
|
||||
t2 = a = sprite.y[y] + 6;
|
||||
t3 = a = sprite.y[x] + 14;
|
||||
|
||||
t5 = a = 0;
|
||||
^if { a = sprite.x[x]; } && a < t0 {
|
||||
if { a = sprite.x[y] + 2; } && a < t1 {
|
||||
if { a = sprite.y[x] + 1; } && a < t2 {
|
||||
if { a = sprite.y[y]; } && a < t3 {
|
||||
t5 = a = 1;
|
||||
|
||||
a = sprite.x[x] + sprite.data[y] + sprite.data[y] + sprite.data[y] + sprite.data[y];
|
||||
if a < game.LEFT_EDGE {
|
||||
a = game.LEFT_EDGE;
|
||||
} else if a >= game.RIGHT_EDGE {
|
||||
a = game.RIGHT_EDGE;
|
||||
}
|
||||
sprite.x[x] = a;
|
||||
|
||||
voice.index[x] = a = &sfx.hurt as u8;
|
||||
voice.length[x] = a = sfx.hurt.len;
|
||||
|
||||
random.next();
|
||||
t6 = a = random.lo & 0x7 + 4;
|
||||
if { a = random.hi & 0x1; } && zero {
|
||||
sprite.y[x] = a = sprite.y[x] + t6;
|
||||
} else {
|
||||
sprite.y[x] = a = sprite.y[x] - t6;
|
||||
}
|
||||
|
||||
sprite.y[y] = a = 200;
|
||||
sprite.data[y] = a = 0;
|
||||
if { a = score[x]; } && a != 0 {
|
||||
if { a = random.hi & 0x6; } && zero {
|
||||
score[x]--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace graphic {
|
||||
let DOT_PATTERN = [
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2
|
||||
];
|
||||
let DUCK_PATTERN = [
|
||||
0b00011100_u8,
|
||||
0b00101010_u8,
|
||||
0b00101010_u8,
|
||||
0b11111110_u8,
|
||||
0b00011100_u8,
|
||||
0b00111111_u8,
|
||||
0b00111111_u8,
|
||||
0b00011110_u8,
|
||||
];
|
||||
|
||||
const @ 0xF600 : [u8] = [0u8; 256];
|
||||
const dot @ 0xF700 : [u8] = DOT_PATTERN ~ [0u8; 256 - DOT_PATTERN.len];
|
||||
|
||||
const @ 0xF800 : [u8] = [0u8; 256];
|
||||
const duck @ 0xF900 : [u8] = DUCK_PATTERN ~ [0u8; 256 - DUCK_PATTERN.len];
|
||||
|
||||
const digits @ 0xFA00 : [u8] = [
|
||||
0b00111000,
|
||||
0b01000100,
|
||||
0b01000100,
|
||||
0b01000100,
|
||||
0b01000100,
|
||||
0b01000100,
|
||||
0b00111000,
|
||||
0b00000000,
|
||||
|
||||
0b00010000,
|
||||
0b00110000,
|
||||
0b00010000,
|
||||
0b00010000,
|
||||
0b00010000,
|
||||
0b00010000,
|
||||
0b00111000,
|
||||
0b00000000,
|
||||
|
||||
0b00111000,
|
||||
0b01000100,
|
||||
0b00000100,
|
||||
0b00011000,
|
||||
0b00100000,
|
||||
0b01000000,
|
||||
0b01111100,
|
||||
0b00000000,
|
||||
|
||||
0b00111000,
|
||||
0b01000100,
|
||||
0b00000100,
|
||||
0b00011000,
|
||||
0b00000100,
|
||||
0b01000100,
|
||||
0b00111000,
|
||||
0b00000000,
|
||||
|
||||
0b01001000,
|
||||
0b01001000,
|
||||
0b01001000,
|
||||
0b01111100,
|
||||
0b00001000,
|
||||
0b00001000,
|
||||
0b00001000,
|
||||
0b00000000,
|
||||
|
||||
0b01111100,
|
||||
0b01000000,
|
||||
0b01000000,
|
||||
0b01111000,
|
||||
0b00000100,
|
||||
0b00000100,
|
||||
0b01111000,
|
||||
0b00000000,
|
||||
|
||||
0b00111000,
|
||||
0b01000000,
|
||||
0b01000000,
|
||||
0b01111000,
|
||||
0b01000100,
|
||||
0b01000100,
|
||||
0b00111000,
|
||||
0b00000000,
|
||||
|
||||
0b01111100,
|
||||
0b00000100,
|
||||
0b00001000,
|
||||
0b00001000,
|
||||
0b00010000,
|
||||
0b00010000,
|
||||
0b00010000,
|
||||
0b00000000,
|
||||
|
||||
0b00111000,
|
||||
0b01000100,
|
||||
0b01000100,
|
||||
0b00111000,
|
||||
0b01000100,
|
||||
0b01000100,
|
||||
0b00111000,
|
||||
0b00000000,
|
||||
|
||||
0b00111000,
|
||||
0b01000100,
|
||||
0b01000100,
|
||||
0b00111100,
|
||||
0b00000100,
|
||||
0b00001000,
|
||||
0b00110000,
|
||||
0b00000000,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
in rom @ 0xFB00 {
|
||||
const fine_adjust : [u8] = [
|
||||
0b01110000, 0b01100000, 0b01010000, 0b01000000, 0b00110000, 0b00100000, 0b00010000,
|
||||
0b00000000,
|
||||
0b11110000, 0b11100000, 0b11010000, 0b11000000, 0b10110000, 0b10100000, 0b10010000,
|
||||
];
|
||||
|
||||
namespace sfx {
|
||||
const volume_data : [u8] = [
|
||||
0xF, 0xF, 0xF, 0xF, 0xF, 0x7, 0x4, 0x0,
|
||||
0xF, 0xF, 0xF, 0xF, 0xF, 0x7, 0x4, 0x0,
|
||||
0xF, 0xF, 0xF, 0xF, 0x1, 0x1, 0x1, 0x1,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
in rom @ 0xFC00 {
|
||||
namespace sfx {
|
||||
let Bb8 = 0b0001;
|
||||
let E8 = 0b0010;
|
||||
let Bb7 = 0b0011;
|
||||
let G7 = 0b0100;
|
||||
let E7 = 0b0101;
|
||||
let Bb6 = 0b0111;
|
||||
let A6 = 0b1000;
|
||||
let G6 = 0b1001;
|
||||
let E6 = 0b1011;
|
||||
let C6 = 0b1110;
|
||||
let Bb5 = 0b1111;
|
||||
let NOTE(pitch, instrument, length) = [(pitch << 4) | instrument; length];
|
||||
let REST(length) = [0; length];
|
||||
|
||||
const data : [u8] = [];
|
||||
const shoot : [u8] = [((13 - i) << 4) | 0x7 for let i in 0 .. 7];
|
||||
const hurt : [u8] = [((((i / 2) >> 2) + ((i / 2) & 0xF) << 4) | 0x3) * (1 - i % 2) for let i in 0 .. 15];
|
||||
const score : [u8] = [(7 - i) << 4 | 0xC for let i in 1 .. 3] ~ [(i >> 1) << 4 | 0xC for let i in 1 .. 7];
|
||||
|
||||
let WIN_INSTRUMENT = 10;
|
||||
let INTRO_INSTRUMENT = 10;
|
||||
|
||||
const win : [u8] =
|
||||
NOTE(Bb6, WIN_INSTRUMENT, 4)
|
||||
~ NOTE(G6, WIN_INSTRUMENT, 8)
|
||||
~ NOTE(A6, WIN_INSTRUMENT, 8)
|
||||
~ NOTE(G6, WIN_INSTRUMENT, 8)
|
||||
~ NOTE(E7, WIN_INSTRUMENT, 8);
|
||||
|
||||
const intro : [u8] =
|
||||
NOTE(E7, INTRO_INSTRUMENT, 8)
|
||||
~ NOTE(Bb6, INTRO_INSTRUMENT, 8)
|
||||
~ NOTE(G6, INTRO_INSTRUMENT, 8)
|
||||
~ NOTE(A6, INTRO_INSTRUMENT, 8)
|
||||
~ NOTE(Bb6, INTRO_INSTRUMENT, 8)
|
||||
~ NOTE(E7, INTRO_INSTRUMENT, 8)
|
||||
~ NOTE(A6, INTRO_INSTRUMENT, 8)
|
||||
~ NOTE(Bb6, INTRO_INSTRUMENT, 8)
|
||||
~ NOTE(E6, INTRO_INSTRUMENT, 4)
|
||||
~ REST(4)
|
||||
~ NOTE(E6, INTRO_INSTRUMENT, 4)
|
||||
~ REST(4)
|
||||
~ NOTE(E7, INTRO_INSTRUMENT, 8);
|
||||
}
|
||||
}
|
||||
|
||||
in rom @ 0xFFFA {
|
||||
const = [main, main, main];
|
||||
}
|
||||
|
@ -418,6 +418,7 @@ export function getToolForFilename_6502(fn:string) : string {
|
||||
if (fn.endsWith(".ca65")) return "ca65";
|
||||
if (fn.endsWith(".dasm")) return "dasm";
|
||||
if (fn.endsWith(".acme")) return "acme";
|
||||
if (fn.endsWith(".wiz")) return "wiz";
|
||||
return "dasm"; // .a
|
||||
}
|
||||
|
||||
@ -593,6 +594,7 @@ export function getToolForFilename_z80(fn) : string {
|
||||
if (fn.endsWith(".ns")) return "naken";
|
||||
if (fn.endsWith(".scc")) return "sccz80";
|
||||
if (fn.endsWith(".z")) return "zmac";
|
||||
if (fn.endsWith(".wiz")) return "wiz";
|
||||
return "zmac";
|
||||
}
|
||||
|
||||
|
@ -119,6 +119,11 @@ export class CodeProject {
|
||||
while (m = re4.exec(text)) {
|
||||
this.pushAllFiles(files, m[2]);
|
||||
}
|
||||
// for wiz
|
||||
let re5 = /^\s*import\s+"(.+?)";/gmi;
|
||||
while (m = re5.exec(text)) {
|
||||
this.pushAllFiles(files, m[1] + ".wiz");
|
||||
}
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
@ -83,6 +83,7 @@ var TOOL_TO_SOURCE_STYLE = {
|
||||
'fastbasic': 'fastbasic',
|
||||
'basic': 'basic',
|
||||
'silice': 'verilog',
|
||||
'wiz': 'text/x-csrc',
|
||||
}
|
||||
|
||||
function gaEvent(category:string, action:string, label?:string, value?:string) {
|
||||
|
@ -42,6 +42,7 @@ const JSNES_PRESETS = [
|
||||
// {id:'scrollrt.dasm', name:'Line-by-line Scrolling (ASM)'},
|
||||
{id:'road.dasm', name:'3-D Road Demo (ASM)'},
|
||||
{id:'chase/game.c', name:'Shiru\'s Chase Game'},
|
||||
{id:'hello.wiz', name:'Hello (Wiz)'},
|
||||
];
|
||||
|
||||
/// JSNES
|
||||
|
@ -52,6 +52,7 @@ const VCS_PRESETS = [
|
||||
{id:'bb/sample.bas', name:'Sprite Test (batariBASIC)'},
|
||||
{id:'bb/FIFA1977.bas', name:'2P Soccer Game (batariBASIC)'},
|
||||
{id:'bb/duck_chase.bas', name:'Duck Chase (batariBASIC)'},
|
||||
{id:'wiz/finalduck.wiz', name:'Final Duck (Wiz)'},
|
||||
// {id:'bb/rblast106.bas', name:'Road Blasters (batariBASIC)'},
|
||||
];
|
||||
|
||||
@ -262,6 +263,7 @@ class VCSPlatform extends BasePlatform {
|
||||
return "\n" + dumpRAM(ram, 0x80, 0x80);
|
||||
}
|
||||
getToolForFilename(fn) {
|
||||
if (fn.endsWith(".wiz")) return "wiz";
|
||||
if (fn.endsWith(".bb") || fn.endsWith(".bas")) return "bataribasic";
|
||||
return "dasm";
|
||||
}
|
||||
|
3673
src/worker/fs/fssmlrc.data
Normal file
3673
src/worker/fs/fssmlrc.data
Normal file
File diff suppressed because it is too large
Load Diff
202
src/worker/fs/fssmlrc.js
Normal file
202
src/worker/fs/fssmlrc.js
Normal file
@ -0,0 +1,202 @@
|
||||
|
||||
var Module = typeof Module !== 'undefined' ? Module : {};
|
||||
|
||||
if (!Module.expectedDataFileDownloads) {
|
||||
Module.expectedDataFileDownloads = 0;
|
||||
}
|
||||
Module.expectedDataFileDownloads++;
|
||||
(function() {
|
||||
var loadPackage = function(metadata) {
|
||||
|
||||
var PACKAGE_PATH;
|
||||
if (typeof window === 'object') {
|
||||
PACKAGE_PATH = window['encodeURIComponent'](window.location.pathname.toString().substring(0, window.location.pathname.toString().lastIndexOf('/')) + '/');
|
||||
} else if (typeof location !== 'undefined') {
|
||||
// worker
|
||||
PACKAGE_PATH = encodeURIComponent(location.pathname.toString().substring(0, location.pathname.toString().lastIndexOf('/')) + '/');
|
||||
} else {
|
||||
throw 'using preloaded data can only be done on a web page or in a web worker';
|
||||
}
|
||||
var PACKAGE_NAME = '/home/pzp/8bitworkshop-compilers/output/fs/fssmlrc.data';
|
||||
var REMOTE_PACKAGE_BASE = 'fssmlrc.data';
|
||||
if (typeof Module['locateFilePackage'] === 'function' && !Module['locateFile']) {
|
||||
Module['locateFile'] = Module['locateFilePackage'];
|
||||
err('warning: you defined Module.locateFilePackage, that has been renamed to Module.locateFile (using your locateFilePackage for now)');
|
||||
}
|
||||
var REMOTE_PACKAGE_NAME = Module['locateFile'] ? Module['locateFile'](REMOTE_PACKAGE_BASE, '') : REMOTE_PACKAGE_BASE;
|
||||
|
||||
var REMOTE_PACKAGE_SIZE = metadata['remote_package_size'];
|
||||
var PACKAGE_UUID = metadata['package_uuid'];
|
||||
|
||||
function fetchRemotePackage(packageName, packageSize, callback, errback) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', packageName, true);
|
||||
xhr.responseType = 'arraybuffer';
|
||||
xhr.onprogress = function(event) {
|
||||
var url = packageName;
|
||||
var size = packageSize;
|
||||
if (event.total) size = event.total;
|
||||
if (event.loaded) {
|
||||
if (!xhr.addedTotal) {
|
||||
xhr.addedTotal = true;
|
||||
if (!Module.dataFileDownloads) Module.dataFileDownloads = {};
|
||||
Module.dataFileDownloads[url] = {
|
||||
loaded: event.loaded,
|
||||
total: size
|
||||
};
|
||||
} else {
|
||||
Module.dataFileDownloads[url].loaded = event.loaded;
|
||||
}
|
||||
var total = 0;
|
||||
var loaded = 0;
|
||||
var num = 0;
|
||||
for (var download in Module.dataFileDownloads) {
|
||||
var data = Module.dataFileDownloads[download];
|
||||
total += data.total;
|
||||
loaded += data.loaded;
|
||||
num++;
|
||||
}
|
||||
total = Math.ceil(total * Module.expectedDataFileDownloads/num);
|
||||
if (Module['setStatus']) Module['setStatus']('Downloading data... (' + loaded + '/' + total + ')');
|
||||
} else if (!Module.dataFileDownloads) {
|
||||
if (Module['setStatus']) Module['setStatus']('Downloading data...');
|
||||
}
|
||||
};
|
||||
xhr.onerror = function(event) {
|
||||
throw new Error("NetworkError for: " + packageName);
|
||||
}
|
||||
xhr.onload = function(event) {
|
||||
if (xhr.status == 200 || xhr.status == 304 || xhr.status == 206 || (xhr.status == 0 && xhr.response)) { // file URLs can return 0
|
||||
var packageData = xhr.response;
|
||||
callback(packageData);
|
||||
} else {
|
||||
throw new Error(xhr.statusText + " : " + xhr.responseURL);
|
||||
}
|
||||
};
|
||||
xhr.send(null);
|
||||
};
|
||||
|
||||
function handleError(error) {
|
||||
console.error('package error:', error);
|
||||
};
|
||||
|
||||
var fetchedCallback = null;
|
||||
var fetched = Module['getPreloadedPackage'] ? Module['getPreloadedPackage'](REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE) : null;
|
||||
|
||||
if (!fetched) fetchRemotePackage(REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE, function(data) {
|
||||
if (fetchedCallback) {
|
||||
fetchedCallback(data);
|
||||
fetchedCallback = null;
|
||||
} else {
|
||||
fetched = data;
|
||||
}
|
||||
}, handleError);
|
||||
|
||||
function runWithFS() {
|
||||
|
||||
function assert(check, msg) {
|
||||
if (!check) throw msg + new Error().stack;
|
||||
}
|
||||
Module['FS_createPath']('/', 'include', true, true);
|
||||
Module['FS_createPath']('/include', 'sys', true, true);
|
||||
Module['FS_createPath']('/', 'lib', true, true);
|
||||
|
||||
/** @constructor */
|
||||
function DataRequest(start, end, audio) {
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
this.audio = audio;
|
||||
}
|
||||
DataRequest.prototype = {
|
||||
requests: {},
|
||||
open: function(mode, name) {
|
||||
this.name = name;
|
||||
this.requests[name] = this;
|
||||
Module['addRunDependency']('fp ' + this.name);
|
||||
},
|
||||
send: function() {},
|
||||
onload: function() {
|
||||
var byteArray = this.byteArray.subarray(this.start, this.end);
|
||||
this.finish(byteArray);
|
||||
},
|
||||
finish: function(byteArray) {
|
||||
var that = this;
|
||||
|
||||
Module['FS_createDataFile'](this.name, null, byteArray, true, true, true); // canOwn this data in the filesystem, it is a slide into the heap that will never change
|
||||
Module['removeRunDependency']('fp ' + that.name);
|
||||
|
||||
this.requests[this.name] = null;
|
||||
}
|
||||
};
|
||||
|
||||
var files = metadata['files'];
|
||||
for (var i = 0; i < files.length; ++i) {
|
||||
new DataRequest(files[i]['start'], files[i]['end'], files[i]['audio']).open('GET', files[i]['filename']);
|
||||
}
|
||||
|
||||
|
||||
function processPackageData(arrayBuffer) {
|
||||
assert(arrayBuffer, 'Loading data file failed.');
|
||||
assert(arrayBuffer instanceof ArrayBuffer, 'bad input to processPackageData');
|
||||
var byteArray = new Uint8Array(arrayBuffer);
|
||||
var curr;
|
||||
|
||||
// copy the entire loaded file into a spot in the heap. Files will refer to slices in that. They cannot be freed though
|
||||
// (we may be allocating before malloc is ready, during startup).
|
||||
var ptr = Module['getMemory'](byteArray.length);
|
||||
Module['HEAPU8'].set(byteArray, ptr);
|
||||
DataRequest.prototype.byteArray = Module['HEAPU8'].subarray(ptr, ptr+byteArray.length);
|
||||
|
||||
var files = metadata['files'];
|
||||
for (var i = 0; i < files.length; ++i) {
|
||||
DataRequest.prototype.requests[files[i].filename].onload();
|
||||
}
|
||||
Module['removeRunDependency']('datafile_/home/pzp/8bitworkshop-compilers/output/fs/fssmlrc.data');
|
||||
|
||||
};
|
||||
Module['addRunDependency']('datafile_/home/pzp/8bitworkshop-compilers/output/fs/fssmlrc.data');
|
||||
|
||||
if (!Module.preloadResults) Module.preloadResults = {};
|
||||
|
||||
Module.preloadResults[PACKAGE_NAME] = {fromCache: false};
|
||||
if (fetched) {
|
||||
processPackageData(fetched);
|
||||
fetched = null;
|
||||
} else {
|
||||
fetchedCallback = processPackageData;
|
||||
}
|
||||
|
||||
}
|
||||
if (Module['calledRun']) {
|
||||
runWithFS();
|
||||
} else {
|
||||
if (!Module['preRun']) Module['preRun'] = [];
|
||||
Module["preRun"].push(runWithFS); // FS is not initialized yet, wait for it
|
||||
}
|
||||
|
||||
Module['removeRunDependency']('fssmlrc.js.metadata');
|
||||
}
|
||||
|
||||
function runMetaWithFS() {
|
||||
Module['addRunDependency']('fssmlrc.js.metadata');
|
||||
var REMOTE_METADATA_NAME = Module['locateFile'] ? Module['locateFile']('fssmlrc.js.metadata', '') : 'fssmlrc.js.metadata';
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.onreadystatechange = function() {
|
||||
if (xhr.readyState === 4 && xhr.status === 200) {
|
||||
loadPackage(JSON.parse(xhr.responseText));
|
||||
}
|
||||
}
|
||||
xhr.open('GET', REMOTE_METADATA_NAME, true);
|
||||
xhr.overrideMimeType('application/json');
|
||||
xhr.send(null);
|
||||
}
|
||||
|
||||
if (Module['calledRun']) {
|
||||
runMetaWithFS();
|
||||
} else {
|
||||
if (!Module['preRun']) Module['preRun'] = [];
|
||||
Module["preRun"].push(runMetaWithFS);
|
||||
}
|
||||
|
||||
})();
|
||||
|
1
src/worker/fs/fssmlrc.js.metadata
Normal file
1
src/worker/fs/fssmlrc.js.metadata
Normal file
@ -0,0 +1 @@
|
||||
{"files":[{"start":0,"audio":0,"end":522,"filename":"/include/assert.h"},{"start":522,"audio":0,"end":1759,"filename":"/include/unistd.h"},{"start":1759,"audio":0,"end":4372,"filename":"/include/stdio.h"},{"start":4372,"audio":0,"end":5268,"filename":"/include/string.h"},{"start":5268,"audio":0,"end":7695,"filename":"/include/math.h"},{"start":7695,"audio":0,"end":8001,"filename":"/include/iso646.h"},{"start":8001,"audio":0,"end":8941,"filename":"/include/locale.h"},{"start":8941,"audio":0,"end":9815,"filename":"/include/stddef.h"},{"start":9815,"audio":0,"end":11178,"filename":"/include/float.h"},{"start":11178,"audio":0,"end":12840,"filename":"/include/stdlib.h"},{"start":12840,"audio":0,"end":14537,"filename":"/include/time.h"},{"start":14537,"audio":0,"end":18063,"filename":"/include/stdint.h"},{"start":18063,"audio":0,"end":18427,"filename":"/include/ctype.h"},{"start":18427,"audio":0,"end":21774,"filename":"/include/inttypes.h"},{"start":21774,"audio":0,"end":22099,"filename":"/include/setjmp.h"},{"start":22099,"audio":0,"end":22551,"filename":"/include/stdarg.h"},{"start":22551,"audio":0,"end":23322,"filename":"/include/fcntl.h"},{"start":23322,"audio":0,"end":23734,"filename":"/include/signal.h"},{"start":23734,"audio":0,"end":23905,"filename":"/include/errno.h"},{"start":23905,"audio":0,"end":24658,"filename":"/include/limits.h"},{"start":24658,"audio":0,"end":25376,"filename":"/include/sys/types.h"},{"start":25376,"audio":0,"end":53574,"filename":"/include/sys/80186.h"},{"start":53574,"audio":0,"end":54223,"filename":"/include/sys/stat.h"},{"start":54223,"audio":0,"end":54878,"filename":"/include/sys/lng.h"},{"start":54878,"audio":0,"end":55151,"filename":"/lib/readme.txt"},{"start":55151,"audio":0,"end":56975,"filename":"/lib/dpstub.exe"},{"start":56975,"audio":0,"end":202839,"filename":"/lib/lcds.a"},{"start":202839,"audio":0,"end":520915,"filename":"/lib/lcdh.a"},{"start":520915,"audio":0,"end":809067,"filename":"/lib/lcdu.a"},{"start":809067,"audio":0,"end":1022023,"filename":"/lib/lcdp.a"}],"remote_package_size":1022023,"package_uuid":"90916e6e-fdba-4ba2-83ae-1084fa2fcfc9"}
|
BIN
src/worker/fs/fswiz.data
Normal file
BIN
src/worker/fs/fswiz.data
Normal file
Binary file not shown.
208
src/worker/fs/fswiz.js
Normal file
208
src/worker/fs/fswiz.js
Normal file
@ -0,0 +1,208 @@
|
||||
|
||||
var Module = typeof Module !== 'undefined' ? Module : {};
|
||||
|
||||
if (!Module.expectedDataFileDownloads) {
|
||||
Module.expectedDataFileDownloads = 0;
|
||||
}
|
||||
Module.expectedDataFileDownloads++;
|
||||
(function() {
|
||||
var loadPackage = function(metadata) {
|
||||
|
||||
var PACKAGE_PATH;
|
||||
if (typeof window === 'object') {
|
||||
PACKAGE_PATH = window['encodeURIComponent'](window.location.pathname.toString().substring(0, window.location.pathname.toString().lastIndexOf('/')) + '/');
|
||||
} else if (typeof location !== 'undefined') {
|
||||
// worker
|
||||
PACKAGE_PATH = encodeURIComponent(location.pathname.toString().substring(0, location.pathname.toString().lastIndexOf('/')) + '/');
|
||||
} else {
|
||||
throw 'using preloaded data can only be done on a web page or in a web worker';
|
||||
}
|
||||
var PACKAGE_NAME = '/home/pzp/8bitworkshop-compilers/output/fs/fswiz.data';
|
||||
var REMOTE_PACKAGE_BASE = 'fswiz.data';
|
||||
if (typeof Module['locateFilePackage'] === 'function' && !Module['locateFile']) {
|
||||
Module['locateFile'] = Module['locateFilePackage'];
|
||||
err('warning: you defined Module.locateFilePackage, that has been renamed to Module.locateFile (using your locateFilePackage for now)');
|
||||
}
|
||||
var REMOTE_PACKAGE_NAME = Module['locateFile'] ? Module['locateFile'](REMOTE_PACKAGE_BASE, '') : REMOTE_PACKAGE_BASE;
|
||||
|
||||
var REMOTE_PACKAGE_SIZE = metadata['remote_package_size'];
|
||||
var PACKAGE_UUID = metadata['package_uuid'];
|
||||
|
||||
function fetchRemotePackage(packageName, packageSize, callback, errback) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', packageName, true);
|
||||
xhr.responseType = 'arraybuffer';
|
||||
xhr.onprogress = function(event) {
|
||||
var url = packageName;
|
||||
var size = packageSize;
|
||||
if (event.total) size = event.total;
|
||||
if (event.loaded) {
|
||||
if (!xhr.addedTotal) {
|
||||
xhr.addedTotal = true;
|
||||
if (!Module.dataFileDownloads) Module.dataFileDownloads = {};
|
||||
Module.dataFileDownloads[url] = {
|
||||
loaded: event.loaded,
|
||||
total: size
|
||||
};
|
||||
} else {
|
||||
Module.dataFileDownloads[url].loaded = event.loaded;
|
||||
}
|
||||
var total = 0;
|
||||
var loaded = 0;
|
||||
var num = 0;
|
||||
for (var download in Module.dataFileDownloads) {
|
||||
var data = Module.dataFileDownloads[download];
|
||||
total += data.total;
|
||||
loaded += data.loaded;
|
||||
num++;
|
||||
}
|
||||
total = Math.ceil(total * Module.expectedDataFileDownloads/num);
|
||||
if (Module['setStatus']) Module['setStatus']('Downloading data... (' + loaded + '/' + total + ')');
|
||||
} else if (!Module.dataFileDownloads) {
|
||||
if (Module['setStatus']) Module['setStatus']('Downloading data...');
|
||||
}
|
||||
};
|
||||
xhr.onerror = function(event) {
|
||||
throw new Error("NetworkError for: " + packageName);
|
||||
}
|
||||
xhr.onload = function(event) {
|
||||
if (xhr.status == 200 || xhr.status == 304 || xhr.status == 206 || (xhr.status == 0 && xhr.response)) { // file URLs can return 0
|
||||
var packageData = xhr.response;
|
||||
callback(packageData);
|
||||
} else {
|
||||
throw new Error(xhr.statusText + " : " + xhr.responseURL);
|
||||
}
|
||||
};
|
||||
xhr.send(null);
|
||||
};
|
||||
|
||||
function handleError(error) {
|
||||
console.error('package error:', error);
|
||||
};
|
||||
|
||||
var fetchedCallback = null;
|
||||
var fetched = Module['getPreloadedPackage'] ? Module['getPreloadedPackage'](REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE) : null;
|
||||
|
||||
if (!fetched) fetchRemotePackage(REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE, function(data) {
|
||||
if (fetchedCallback) {
|
||||
fetchedCallback(data);
|
||||
fetchedCallback = null;
|
||||
} else {
|
||||
fetched = data;
|
||||
}
|
||||
}, handleError);
|
||||
|
||||
function runWithFS() {
|
||||
|
||||
function assert(check, msg) {
|
||||
if (!check) throw msg + new Error().stack;
|
||||
}
|
||||
Module['FS_createPath']('/', 'common', true, true);
|
||||
Module['FS_createPath']('/common', 'snes', true, true);
|
||||
Module['FS_createPath']('/common', 'gg', true, true);
|
||||
Module['FS_createPath']('/common', 'nes', true, true);
|
||||
Module['FS_createPath']('/common', 'msx', true, true);
|
||||
Module['FS_createPath']('/common', 'pce', true, true);
|
||||
Module['FS_createPath']('/common', 'gb', true, true);
|
||||
Module['FS_createPath']('/common', '2600', true, true);
|
||||
Module['FS_createPath']('/common', 'spc', true, true);
|
||||
|
||||
/** @constructor */
|
||||
function DataRequest(start, end, audio) {
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
this.audio = audio;
|
||||
}
|
||||
DataRequest.prototype = {
|
||||
requests: {},
|
||||
open: function(mode, name) {
|
||||
this.name = name;
|
||||
this.requests[name] = this;
|
||||
Module['addRunDependency']('fp ' + this.name);
|
||||
},
|
||||
send: function() {},
|
||||
onload: function() {
|
||||
var byteArray = this.byteArray.subarray(this.start, this.end);
|
||||
this.finish(byteArray);
|
||||
},
|
||||
finish: function(byteArray) {
|
||||
var that = this;
|
||||
|
||||
Module['FS_createDataFile'](this.name, null, byteArray, true, true, true); // canOwn this data in the filesystem, it is a slide into the heap that will never change
|
||||
Module['removeRunDependency']('fp ' + that.name);
|
||||
|
||||
this.requests[this.name] = null;
|
||||
}
|
||||
};
|
||||
|
||||
var files = metadata['files'];
|
||||
for (var i = 0; i < files.length; ++i) {
|
||||
new DataRequest(files[i]['start'], files[i]['end'], files[i]['audio']).open('GET', files[i]['filename']);
|
||||
}
|
||||
|
||||
|
||||
function processPackageData(arrayBuffer) {
|
||||
assert(arrayBuffer, 'Loading data file failed.');
|
||||
assert(arrayBuffer instanceof ArrayBuffer, 'bad input to processPackageData');
|
||||
var byteArray = new Uint8Array(arrayBuffer);
|
||||
var curr;
|
||||
|
||||
// copy the entire loaded file into a spot in the heap. Files will refer to slices in that. They cannot be freed though
|
||||
// (we may be allocating before malloc is ready, during startup).
|
||||
var ptr = Module['getMemory'](byteArray.length);
|
||||
Module['HEAPU8'].set(byteArray, ptr);
|
||||
DataRequest.prototype.byteArray = Module['HEAPU8'].subarray(ptr, ptr+byteArray.length);
|
||||
|
||||
var files = metadata['files'];
|
||||
for (var i = 0; i < files.length; ++i) {
|
||||
DataRequest.prototype.requests[files[i].filename].onload();
|
||||
}
|
||||
Module['removeRunDependency']('datafile_/home/pzp/8bitworkshop-compilers/output/fs/fswiz.data');
|
||||
|
||||
};
|
||||
Module['addRunDependency']('datafile_/home/pzp/8bitworkshop-compilers/output/fs/fswiz.data');
|
||||
|
||||
if (!Module.preloadResults) Module.preloadResults = {};
|
||||
|
||||
Module.preloadResults[PACKAGE_NAME] = {fromCache: false};
|
||||
if (fetched) {
|
||||
processPackageData(fetched);
|
||||
fetched = null;
|
||||
} else {
|
||||
fetchedCallback = processPackageData;
|
||||
}
|
||||
|
||||
}
|
||||
if (Module['calledRun']) {
|
||||
runWithFS();
|
||||
} else {
|
||||
if (!Module['preRun']) Module['preRun'] = [];
|
||||
Module["preRun"].push(runWithFS); // FS is not initialized yet, wait for it
|
||||
}
|
||||
|
||||
Module['removeRunDependency']('fswiz.js.metadata');
|
||||
}
|
||||
|
||||
function runMetaWithFS() {
|
||||
Module['addRunDependency']('fswiz.js.metadata');
|
||||
var REMOTE_METADATA_NAME = Module['locateFile'] ? Module['locateFile']('fswiz.js.metadata', '') : 'fswiz.js.metadata';
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.onreadystatechange = function() {
|
||||
if (xhr.readyState === 4 && xhr.status === 200) {
|
||||
loadPackage(JSON.parse(xhr.responseText));
|
||||
}
|
||||
}
|
||||
xhr.open('GET', REMOTE_METADATA_NAME, true);
|
||||
xhr.overrideMimeType('application/json');
|
||||
xhr.send(null);
|
||||
}
|
||||
|
||||
if (Module['calledRun']) {
|
||||
runMetaWithFS();
|
||||
} else {
|
||||
if (!Module['preRun']) Module['preRun'] = [];
|
||||
Module["preRun"].push(runMetaWithFS);
|
||||
}
|
||||
|
||||
})();
|
||||
|
1
src/worker/fs/fswiz.js.metadata
Normal file
1
src/worker/fs/fswiz.js.metadata
Normal file
@ -0,0 +1 @@
|
||||
{"remote_package_size":222931,"package_uuid":"138b64f7-0a64-4b41-bae4-c3b17a5945ff","files":[{"end":2959,"filename":"/common/snes/icd2.wiz","audio":0,"start":0},{"end":5901,"filename":"/common/snes/img2snes.py","audio":0,"start":2959},{"end":7500,"filename":"/common/snes/minirpg_sprites.png","audio":0,"start":5901},{"end":8103,"filename":"/common/snes/hello_tiles_compact.png","audio":0,"start":7500},{"end":9639,"filename":"/common/snes/hello_tiles_compact.chr","audio":0,"start":8103},{"end":10276,"filename":"/common/snes/hello_tiles.png","audio":0,"start":9639},{"end":18468,"filename":"/common/snes/hello_tiles.chr","audio":0,"start":10276},{"end":42055,"filename":"/common/snes/snes.wiz","audio":0,"start":18468},{"end":50247,"filename":"/common/snes/minirpg_sprites.chr","audio":0,"start":42055},{"end":56476,"filename":"/common/gg/sms.wiz","audio":0,"start":50247},{"end":58075,"filename":"/common/gg/minirpg_sprites.png","audio":0,"start":56476},{"end":58712,"filename":"/common/gg/hello_tiles.png","audio":0,"start":58075},{"end":61571,"filename":"/common/gg/img2gg8.py","audio":0,"start":58712},{"end":69763,"filename":"/common/gg/hello_tiles.chr","audio":0,"start":61571},{"end":73777,"filename":"/common/gg/img2gg16.py","audio":0,"start":69763},{"end":81969,"filename":"/common/gg/minirpg_sprites.chr","audio":0,"start":73777},{"end":86065,"filename":"/common/nes/scroller_tiles.chr","audio":0,"start":81969},{"end":87662,"filename":"/common/nes/minirpg_sprites.png","audio":0,"start":86065},{"end":88099,"filename":"/common/nes/hello_tiles.png","audio":0,"start":87662},{"end":90452,"filename":"/common/nes/img2chr.py","audio":0,"start":88099},{"end":94548,"filename":"/common/nes/hello_tiles.chr","audio":0,"start":90452},{"end":95391,"filename":"/common/nes/scroller_tiles.png","audio":0,"start":94548},{"end":96073,"filename":"/common/nes/bobble_tiles.png","audio":0,"start":95391},{"end":115162,"filename":"/common/nes/nes.wiz","audio":0,"start":96073},{"end":119258,"filename":"/common/nes/bobble_tiles.chr","audio":0,"start":115162},{"end":123354,"filename":"/common/nes/minirpg_sprites.chr","audio":0,"start":119258},{"end":125583,"filename":"/common/msx/img2msx16.py","audio":0,"start":123354},{"end":126076,"filename":"/common/msx/hello_tiles.png","audio":0,"start":125583},{"end":128124,"filename":"/common/msx/hello_tiles.chr","audio":0,"start":126076},{"end":130353,"filename":"/common/msx/img2msx8.py","audio":0,"start":128124},{"end":144050,"filename":"/common/msx/msx.wiz","audio":0,"start":130353},{"end":156730,"filename":"/common/pce/pce.wiz","audio":0,"start":144050},{"end":158329,"filename":"/common/pce/minirpg_sprites.png","audio":0,"start":156730},{"end":158966,"filename":"/common/pce/hello_tiles.png","audio":0,"start":158329},{"end":167158,"filename":"/common/pce/hello_tiles.chr","audio":0,"start":158966},{"end":170075,"filename":"/common/pce/img2pce8.py","audio":0,"start":167158},{"end":178267,"filename":"/common/pce/minirpg_sprites.chr","audio":0,"start":170075},{"end":181106,"filename":"/common/gb/bcd.wiz","audio":0,"start":178267},{"end":183925,"filename":"/common/gb/joy.wiz","audio":0,"start":181106},{"end":200923,"filename":"/common/gb/gb.wiz","audio":0,"start":183925},{"end":202249,"filename":"/common/gb/oam.wiz","audio":0,"start":200923},{"end":204600,"filename":"/common/gb/math.wiz","audio":0,"start":202249},{"end":207787,"filename":"/common/gb/sgb_util.wiz","audio":0,"start":204600},{"end":209229,"filename":"/common/gb/memory.wiz","audio":0,"start":207787},{"end":210279,"filename":"/common/gb/gbc_util.wiz","audio":0,"start":209229},{"end":216179,"filename":"/common/2600/vcs.wiz","audio":0,"start":210279},{"end":222931,"filename":"/common/spc/spc.wiz","audio":0,"start":216179}]}
|
22
src/worker/wasm/wiz.js
Normal file
22
src/worker/wasm/wiz.js
Normal file
File diff suppressed because one or more lines are too long
BIN
src/worker/wasm/wiz.wasm
Normal file
BIN
src/worker/wasm/wiz.wasm
Normal file
Binary file not shown.
@ -58,6 +58,8 @@ var PLATFORM_PARAMS = {
|
||||
code_size: 0xf000,
|
||||
data_start: 0x80,
|
||||
data_size: 0x80,
|
||||
wiz_rom_ext: '.a26',
|
||||
wiz_inc_dir: '2600'
|
||||
},
|
||||
'mw8080bw': {
|
||||
code_start: 0x0,
|
||||
@ -185,6 +187,7 @@ var PLATFORM_PARAMS = {
|
||||
'-D', 'NES_MIRRORING=0', // horizontal mirroring
|
||||
],
|
||||
extra_link_files: ['crt0.o', 'neslib2.lib', 'neslib2.cfg', 'nesbanked.cfg'],
|
||||
wiz_rom_ext: '.nes',
|
||||
},
|
||||
'apple2': {
|
||||
define: ['__APPLE2__'],
|
||||
@ -2673,7 +2676,6 @@ function compileBASIC(step:BuildStep) {
|
||||
}
|
||||
|
||||
function compileSilice(step:BuildStep) {
|
||||
// TODO: fastbasic-fp?
|
||||
loadNative("silice");
|
||||
var params = step.params;
|
||||
gatherFiles(step, {mainFilePath:"main.ice"});
|
||||
@ -2728,6 +2730,55 @@ function compileSilice(step:BuildStep) {
|
||||
};
|
||||
}
|
||||
|
||||
function compileWiz(step:BuildStep) {
|
||||
loadNative("wiz");
|
||||
var params = step.params;
|
||||
gatherFiles(step, {mainFilePath:"main.wiz"});
|
||||
var destpath = step.prefix + params.wiz_rom_ext;
|
||||
var errors : WorkerError[] = [];
|
||||
if (staleFiles(step, [destpath])) {
|
||||
var wiz = emglobal.wiz({
|
||||
instantiateWasm: moduleInstFn('wiz'),
|
||||
noInitialRun:true,
|
||||
print:print_fn,
|
||||
//test.wiz:2: error: expected statement, but got identifier `test`
|
||||
printErr:makeErrorMatcher(errors, /(.+?):(\d+):\s*(.+)/, 2, 3, step.path, 1),
|
||||
});
|
||||
var FS = wiz['FS'];
|
||||
setupFS(FS, 'wiz');
|
||||
populateFiles(step, FS);
|
||||
populateExtraFiles(step, FS, params.extra_compile_files);
|
||||
const FWDIR = '/share/common';
|
||||
var args = [
|
||||
'-o', destpath,
|
||||
'-I' + FWDIR + '/' + (params.wiz_inc_dir || step.platform),
|
||||
'-s', 'mlb',
|
||||
step.path];
|
||||
execMain(step, wiz, args);
|
||||
if (errors.length)
|
||||
return {errors:errors};
|
||||
var binout = FS.readFile(destpath, {encoding:'binary'});
|
||||
putWorkFile(destpath, binout);
|
||||
var dbgout = FS.readFile(step.prefix + '.mlb', {encoding:'utf8'});
|
||||
var symbolmap = {};
|
||||
for (var s of dbgout.split("\n")) {
|
||||
var toks = s.split(/:/);
|
||||
// P:A00-A4F:graphic_digits
|
||||
if (toks && toks.length >= 3) {
|
||||
var tokrange = toks[1].split('-');
|
||||
var start = parseInt(tokrange[0], 16);
|
||||
var sym = toks[2];
|
||||
symbolmap[sym] = start;
|
||||
}
|
||||
}
|
||||
return {
|
||||
output:binout, //.slice(0),
|
||||
errors:errors,
|
||||
symbolmap:symbolmap,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////
|
||||
|
||||
var TOOLS = {
|
||||
@ -2762,6 +2813,7 @@ var TOOLS = {
|
||||
'fastbasic': compileFastBasic,
|
||||
'basic': compileBASIC,
|
||||
'silice': compileSilice,
|
||||
'wiz': compileWiz,
|
||||
}
|
||||
|
||||
var TOOL_PRELOADFS = {
|
||||
@ -2786,6 +2838,7 @@ var TOOL_PRELOADFS = {
|
||||
'inform6': 'inform',
|
||||
'fastbasic': '65-atari8',
|
||||
'silice': 'Silice',
|
||||
'wiz': 'wiz',
|
||||
}
|
||||
|
||||
function applyDefaultErrorPath(errors:WorkerError[], path:string) {
|
||||
|
Loading…
Reference in New Issue
Block a user