initial wiz support (vcs and nes)

This commit is contained in:
Steven Hugg 2021-03-04 08:20:00 -06:00
parent f3ed9191ee
commit 5ee1c7e8a3
18 changed files with 5048 additions and 1 deletions

139
presets/nes/hello.wiz Normal file
View 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
View File

@ -0,0 +1,2 @@
bank rom @ 0xF000 : [constdata; 4096];
bank ram @ 0x80 : [vardata; 128];

33
presets/vcs/random.wiz Normal file
View 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;
}
}
}

View 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];
}

View File

@ -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";
}

View File

@ -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;
}

View File

@ -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) {

View File

@ -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

View File

@ -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

File diff suppressed because it is too large Load Diff

202
src/worker/fs/fssmlrc.js Normal file
View 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);
}
})();

View 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

Binary file not shown.

208
src/worker/fs/fswiz.js Normal file
View 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);
}
})();

View 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

File diff suppressed because one or more lines are too long

BIN
src/worker/wasm/wiz.wasm Normal file

Binary file not shown.

View File

@ -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) {