mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-12-26 22:31:14 +00:00
c64: .wiz
This commit is contained in:
parent
483675fded
commit
fc432a3bbf
127
presets/c64/c64.wiz
Normal file
127
presets/c64/c64.wiz
Normal file
@ -0,0 +1,127 @@
|
||||
|
||||
struct CoordXY {
|
||||
x : u8,
|
||||
y : u8
|
||||
}
|
||||
|
||||
struct SIDVoice {
|
||||
freq : u16, /* Frequency */
|
||||
pw : u16, /* Pulse width */
|
||||
ctrl : u16, /* Control register */
|
||||
ad : u16, /* Attack/decay */
|
||||
sr : u16 /* Sustain/release */
|
||||
}
|
||||
|
||||
typealias SpriteData : [u8; 64];
|
||||
|
||||
union VICBank {
|
||||
spritedata : [SpriteData; 256],
|
||||
data : [u8; 0x4000]
|
||||
}
|
||||
|
||||
namespace c64 {
|
||||
extern var colorram @ 0xD800 : [u8; 0x400];
|
||||
|
||||
namespace color {
|
||||
let BLACK = 0x00;
|
||||
let WHITE = 0x01;
|
||||
let RED = 0x02;
|
||||
let CYAN = 0x03;
|
||||
let PURPLE = 0x04;
|
||||
let GREEN = 0x05;
|
||||
let BLUE = 0x06;
|
||||
let YELLOW = 0x07;
|
||||
let ORANGE = 0x08;
|
||||
let BROWN = 0x09;
|
||||
let LIGHTRED = 0x0A;
|
||||
let GRAY1 = 0x0B;
|
||||
let GRAY2 = 0x0C;
|
||||
let LIGHTGREEN = 0x0D;
|
||||
let LIGHTBLUE = 0x0E;
|
||||
let GRAY3 = 0x0F;
|
||||
}
|
||||
|
||||
namespace vic {
|
||||
namespace sprite {
|
||||
extern var pos @ 0xD000 : [CoordXY; 8];
|
||||
extern var coord @ 0xD000 : [u8; 16];
|
||||
extern var hi_x @ 0xD010 : u8;
|
||||
extern var enable @ 0xD015 : u8;
|
||||
extern var expand_y @ 0xD017 : u8;
|
||||
extern var priority @ 0xD01B : u8;
|
||||
extern var multicolor @ 0xD01C : u8;
|
||||
extern var expand_x @ 0xD01D : u8;
|
||||
extern var coll @ 0xD01E : u8;
|
||||
extern var coll_bg @ 0xD01F : u8;
|
||||
extern var mcolor @ 0xD025 : [u8; 2];
|
||||
extern var color @ 0xD027 : [u8; 8];
|
||||
}
|
||||
extern var control1 @ 0xD011 : u8;
|
||||
extern var rasterline @ 0xD012 : u8;
|
||||
extern var lightpen @ 0xD013 : CoordXY;
|
||||
extern var control2 @ 0xD016 : u8;
|
||||
extern var mem @ 0xD018 : u8;
|
||||
extern var irr @ 0xD019 : u8;
|
||||
extern var imr @ 0xD01A : u8;
|
||||
extern var bordercolor @ 0xD020 : u8;
|
||||
extern var bgcolor @ 0xD021 : [u8; 4];
|
||||
}
|
||||
|
||||
namespace sid {
|
||||
extern writeonly v1 @ 0xd400 : [SIDVoice; 3];
|
||||
|
||||
extern writeonly flt_freq @ 0xd415 : u16;/* Filter frequency */
|
||||
extern writeonly flt_ctrl @ 0xd417 : u8; /* Filter control register */
|
||||
extern writeonly amp @ 0xd418 : u8; /* Amplitude */
|
||||
extern writeonly ad1 @ 0xd419 : u8; /* A/D converter 1 */
|
||||
extern writeonly ad2 @ 0xd41a : u8; /* A/D converter 2 */
|
||||
extern writeonly noise @ 0xd41b : u8; /* Noise generator */
|
||||
extern const read3 @ 0xd41c : u8; /* Value of voice 3 */
|
||||
}
|
||||
|
||||
namespace cia1 {
|
||||
// CIA1 Registers
|
||||
extern writeonly port_a @ 0xDC00 : u8;
|
||||
extern const port_b @ 0xDC01 : u8;
|
||||
extern writeonly data_direction_a @ 0xDC02 : u8;
|
||||
extern writeonly data_direction_b @ 0xDC03 : u8;
|
||||
extern const timer_a_lo @ 0xDC04 : u8;
|
||||
extern const timer_a_hi @ 0xDC05 : u8;
|
||||
extern const timer_b_lo @ 0xDC06 : u8;
|
||||
extern const timer_b_hi @ 0xDC07 : u8;
|
||||
extern const sdr @ 0xDC0C : u8;
|
||||
extern const icr @ 0xDC0D : u8;
|
||||
extern const cra @ 0xDC0E : u8;
|
||||
extern const crb @ 0xDC0F : u8;
|
||||
}
|
||||
|
||||
namespace cia2 {
|
||||
// CIA2 Registers
|
||||
extern writeonly port_a @ 0xDD00 : u8;
|
||||
extern const port_b @ 0xDD01 : u8;
|
||||
extern writeonly data_direction_a @ 0xDD02 : u8;
|
||||
extern writeonly data_direction_b @ 0xDD03 : u8;
|
||||
extern const timer_a_lo @ 0xDD04 : u8;
|
||||
extern const timer_a_hi @ 0xDD05 : u8;
|
||||
extern const timer_b_lo @ 0xDD06 : u8;
|
||||
extern const timer_b_hi @ 0xDD07 : u8;
|
||||
extern const sdr @ 0xDD0C : u8;
|
||||
extern const icr @ 0xDD0D : u8;
|
||||
extern const cra @ 0xDD0E : u8;
|
||||
extern const crb @ 0xDD0F : u8;
|
||||
}
|
||||
|
||||
namespace kernal {
|
||||
let ioinit = 0xFDA3 as func;
|
||||
let rantam = 0xFD50 as func;
|
||||
let restor = 0xFD15 as func;
|
||||
let cint = 0xFF5B as func;
|
||||
let scnkey = 0xEA87 as func;
|
||||
let chrin = 0xF157 as func : u8 in a;
|
||||
let chrout = 0xF1CA as func(char : u8 in a);
|
||||
let screen = 0xE505 as func : u16 in xy;
|
||||
let plot_save = 0xE50A as func(save : bool in carry) : u16 in xy;
|
||||
let plot_restore = 0xE50A as func(x : u8 in x, y : u8 in y, save : bool in carry);
|
||||
}
|
||||
}
|
||||
|
181
presets/c64/hello.wiz
Normal file
181
presets/c64/hello.wiz
Normal file
@ -0,0 +1,181 @@
|
||||
|
||||
|
||||
import "c64.wiz";
|
||||
|
||||
bank zeropage @ 0x02 : [vardata; 254];
|
||||
bank stackpage @ 0x100 : [vardata; 256];
|
||||
bank textscrn @ 0x400 : [vardata; 0x400];
|
||||
bank ram @ 0x2000 : [vardata; 0x7800];
|
||||
bank prghdr @ 0x7ff : [prgdata; 0x2];
|
||||
bank prg @ 0x801 : [varinitdata; 0x7000];
|
||||
|
||||
in textscrn {
|
||||
var scrn: [u8; 40*25];
|
||||
var _unused: [u8; 16];
|
||||
var spriteptr: [u8; 8];
|
||||
}
|
||||
|
||||
extern var vicbank @ 0x0000 : VICBank;
|
||||
|
||||
// PRG file header
|
||||
in prghdr {
|
||||
const prgstart : u16 = 0x801;
|
||||
}
|
||||
|
||||
// BASIC header
|
||||
in prg {
|
||||
namespace prgheader {
|
||||
const nextline = &BASIC_END;
|
||||
const linenum : u16 = 10;
|
||||
const sysstmt = "\x9e 2062\0";
|
||||
BASIC_END:
|
||||
const hdrend : u16 = 0;
|
||||
}
|
||||
PRG_START:
|
||||
/*
|
||||
c64.kernal.ioinit();
|
||||
c64.kernal.rantam();
|
||||
c64.kernal.restor();
|
||||
c64.kernal.cint();
|
||||
*/
|
||||
c64.vic.bordercolor = a = c64.color.ORANGE;
|
||||
c64.kernal.chrout('A');
|
||||
for x in 0..250 {
|
||||
// scrn[x] = a = x;
|
||||
// (&scrn[40*8])[x] = a = x;
|
||||
// (0x600 as *u8)[x] = a = x;
|
||||
(&scrn[40*12])[x] = a = message[x] + 0xc0;
|
||||
}
|
||||
for x in 0..255 {
|
||||
a = message[x];
|
||||
break if zero;
|
||||
a += 0xc0;
|
||||
(&scrn[40*20])[x] = a;
|
||||
}
|
||||
upandaway();
|
||||
return;
|
||||
|
||||
const message = "HELLO WORLD!\0";
|
||||
|
||||
const SPRITE : [u8; 3*21] = [
|
||||
/*{w:24,h:21,bpp:1,brev:1}*/
|
||||
0x00,0x7F,0x00,0x01,0xFF,0xC0,0x03,0xFF,0xE0,
|
||||
0x03,0xE7,0xE0,0x07,0xD9,0xF0,0x07,0xDF,0xF0,
|
||||
0x07,0xD9,0xF0,0x03,0xE7,0xE0,0x03,0xFF,0xE0,
|
||||
0x03,0xFF,0xE0,0x02,0xFF,0xA0,0x01,0x7F,0x40,
|
||||
0x01,0x3E,0x40,0x00,0x9C,0x80,0x00,0x9C,0x80,
|
||||
0x00,0x49,0x00,0x00,0x49,0x00,0x00,0x3E,0x00,
|
||||
0x00,0x3E,0x00,0x00,0x3E,0x00,0x00,0x1C,0x00
|
||||
];
|
||||
|
||||
const yValues : [u8] = [
|
||||
32, 35, 38, 41, 44, 47, 49, 52,
|
||||
54, 56, 58, 60, 61, 62, 63, 63,
|
||||
64, 63, 63, 62, 61, 60, 58, 56,
|
||||
54, 52, 49, 47, 44, 41, 38, 35,
|
||||
32, 28, 25, 22, 19, 16, 14, 11,
|
||||
9, 7, 5, 3, 2, 1, 0, 0,
|
||||
0, 0, 0, 1, 2, 3, 5, 7,
|
||||
9, 11, 14, 16, 19, 22, 25, 28
|
||||
];
|
||||
|
||||
const pwr2 : [u8] = [
|
||||
0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80
|
||||
];
|
||||
|
||||
in zeropage {
|
||||
var b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15 : u8;
|
||||
var w0 @ &b0, w2 @ &b2, w4 @ &b4, w6 @ &b6, w8 @ &b8, w10 @ &b10 : u16;
|
||||
var ptr0 @ &b0, ptr2 @ &b2, ptr4 @ &b4, ptr6 @ &b6, ptr8 @ &b8, ptr10 @ &b10 : *u8;
|
||||
}
|
||||
|
||||
inline func rasterWait(line : u8 in a) {
|
||||
while (c64.vic.rasterline < line) { }
|
||||
}
|
||||
|
||||
func upandaway() {
|
||||
//unsigned char n, t;
|
||||
//int rx, x;
|
||||
//char sx, msb;
|
||||
var xp : u16 in w0;
|
||||
var rx : u16 in w2;
|
||||
var msb : u8 in b4;
|
||||
let sprdata = &vicbank.spritedata[13] as *u8;
|
||||
|
||||
c64.vic.bgcolor[0] = a = 3;
|
||||
nointerrupt = true; // clear interrupts to avoid glitching
|
||||
|
||||
for y in 0..(sizeof(typeof(SPRITE)) - 1) {
|
||||
sprdata[y] = a = SPRITE[y];
|
||||
//POKE(832 + n, sprite[n]);
|
||||
}
|
||||
c64.vic.sprite.enable = a = 255;
|
||||
for x in 0..7 {
|
||||
spriteptr[x] = a = 13;
|
||||
y = a = x<<1;
|
||||
c64.vic.sprite.coord[y] = a = 50;
|
||||
y ++;
|
||||
c64.vic.sprite.coord[y] = a = 50;
|
||||
//POKE(2040 + t, 13); // Set sprite x data from 13th block for all sprites
|
||||
}
|
||||
do {
|
||||
<:xp = a = 0;
|
||||
>:xp = a = 0;
|
||||
//while (xp < 550) {
|
||||
while (true) {
|
||||
<:xp = a = <:xp + 1;
|
||||
>:xp = a = >:xp +# 0;
|
||||
msb = a = 0; // MSB of X coordinates
|
||||
// Wait until raster hits position 250 before drawing upper sprites
|
||||
rasterWait(250);
|
||||
// Set border color, which indicates the raster position
|
||||
c64.vic.bordercolor = a = 1;
|
||||
<:rx = a = <:xp;
|
||||
>:rx = a = >:xp;
|
||||
for x in 0..7 {
|
||||
<:rx = a = <:rx - 24;
|
||||
>:rx = a = >:rx -# 0;
|
||||
//if (rx >= 0 && rx < 366)
|
||||
if (true) {
|
||||
// if (rx > 255)
|
||||
a = >:rx;
|
||||
if (!zero) {
|
||||
// Set MSB of x coordinate for sprite if x position > 255
|
||||
a = msb;
|
||||
a |= pwr2[x];
|
||||
msb = a;
|
||||
}
|
||||
y = a = x<<1;
|
||||
c64.vic.sprite.coord[y] = a = <:rx;
|
||||
// Y position is an indirect Sinus function of X, using array
|
||||
// index for retrieving the Y value
|
||||
y = a = <:rx & 63;
|
||||
a = yValues[y] + 40;
|
||||
push(a);
|
||||
y = a = (x<<1) + 1;
|
||||
a = pop();
|
||||
c64.vic.sprite.coord[y] = a;
|
||||
} else {
|
||||
c64.vic.sprite.pos[y].x = 0;
|
||||
}
|
||||
}
|
||||
c64.vic.sprite.hi_x = a = msb; // Set MSB of x coordinate
|
||||
// Wait until raster hits position 135 before drawing lower sprites
|
||||
rasterWait(135);
|
||||
c64.vic.bordercolor = a = 2; // Set border color
|
||||
for x in 0..7 {
|
||||
// Add 128 to current sprite Y position
|
||||
y = a = (x<<1) + 1;
|
||||
c64.vic.sprite.coord[y] = a = c64.vic.sprite.coord[y]+128;
|
||||
}
|
||||
cmp(a = >:xp, >:550);
|
||||
if (zero) {
|
||||
cmp(a = <:xp, <:550);
|
||||
break if zero;
|
||||
}
|
||||
}
|
||||
} while (true);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
@ -1,7 +1,10 @@
|
||||
|
||||
// ported from
|
||||
// https://odensskjegg.home.blog/2018/12/29/recreating-the-commodore-64-user-guide-code-samples-in-cc65-part-three-sprites/
|
||||
|
||||
#include "common.h"
|
||||
//#include "common.h"
|
||||
#include <peekpoke.h>
|
||||
#include <c64.h>
|
||||
|
||||
/*{w:24,h:21,bpp:1,brev:1}*/
|
||||
const char sprite[3*21] = {
|
||||
@ -15,7 +18,7 @@ const char sprite[3*21] = {
|
||||
};
|
||||
|
||||
// Pre-calculated sinus values
|
||||
const char yValues[] = {
|
||||
const char yValues[64] = {
|
||||
32, 35, 38, 41, 44, 47, 49, 52,
|
||||
54, 56, 58, 60, 61, 62, 63, 63,
|
||||
64, 63, 63, 62, 61, 60, 58, 56,
|
||||
@ -31,58 +34,66 @@ void rasterWait(unsigned char line) {
|
||||
while (VIC.rasterline < line) ;
|
||||
}
|
||||
|
||||
const char LUT[8] = { 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80 };
|
||||
|
||||
int main (void)
|
||||
{
|
||||
unsigned char n, t;
|
||||
int rx, x;
|
||||
char sx, msb;
|
||||
unsigned char msb;
|
||||
|
||||
VIC.bgcolor0 = 3;
|
||||
VIC.bgcolor0 = COLOR_CYAN; // set background color
|
||||
__asm__("SEI"); // clear interrupts to avoid glitching
|
||||
|
||||
// Set 13th sprite bitmap
|
||||
for (n = 0 ; n < sizeof(sprite) ; n++) {
|
||||
POKE(832 + n, sprite[n]);
|
||||
}
|
||||
// enable all sprites
|
||||
VIC.spr_ena = 255;
|
||||
// Set all sprite pointers to 13th sprite
|
||||
for (t = 0 ; t < 8 ; t++) {
|
||||
POKE(2040 + t, 13); // Set sprite x data from 13th block for all sprites
|
||||
POKE(2040 + t, 13);
|
||||
}
|
||||
do {
|
||||
// loop forever
|
||||
while(1) {
|
||||
for (x = 0 ; x < 550; x++) {
|
||||
msb = 0; // MSB of X coordinates
|
||||
// MSB of each sprite's X coordinate (i.e. if X >= 256)
|
||||
msb = 0;
|
||||
// Wait until raster hits position 250 before drawing upper sprites
|
||||
rasterWait(250);
|
||||
// Set border color, which indicates the raster position
|
||||
VIC.bordercolor = 1;
|
||||
VIC.bordercolor = COLOR_RED;
|
||||
rx = x;
|
||||
// iterate over all 8 sprites
|
||||
for (t = 0 ; t < 8 ; t++) {
|
||||
VIC.bordercolor = t;
|
||||
rx -= 24;
|
||||
if (rx >= 0 && rx < 366) {
|
||||
// Usually I would calculate the sprite X coordinate using
|
||||
// the expression sx = rx % 256, but bitwise operation is
|
||||
// significant faster
|
||||
sx = rx & 255;
|
||||
if (rx > 255) {
|
||||
// Set MSB of x coordinate for sprite if x position > 255
|
||||
msb |= 1 << t;
|
||||
if (x >= 256) {
|
||||
msb |= LUT[t]; // look up 1 << t
|
||||
}
|
||||
VIC.spr_pos[t].x = sx;
|
||||
VIC.spr_pos[t].x = x;
|
||||
// Y position is an indirect Sinus function of X, using array
|
||||
// index for retrieving the Y value
|
||||
VIC.spr_pos[t].y = yValues[sx & 63] + 40;
|
||||
VIC.spr_pos[t].y = yValues[x & 63] + 40;
|
||||
} else {
|
||||
VIC.spr_pos[t].x = 0;
|
||||
}
|
||||
}
|
||||
VIC.spr_hi_x = msb; // Set MSB of x coordinate
|
||||
// Set MSB of x coordinate
|
||||
VIC.spr_hi_x = msb;
|
||||
// Wait until raster hits position 135 before drawing lower sprites
|
||||
VIC.bordercolor = COLOR_BLUE;
|
||||
rasterWait(135);
|
||||
VIC.bordercolor = 2; // Set border color
|
||||
VIC.bordercolor = COLOR_RED;
|
||||
// Add 128 to current sprite Y positions
|
||||
for (t = 0 ; t < 8 ; t++) {
|
||||
// Add 128 to current sprite Y position
|
||||
VIC.spr_pos[t].y += 128;
|
||||
}
|
||||
}
|
||||
} while (1);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -13,4 +13,4 @@ class MyHTTPRequestHandler(http.server.SimpleHTTPRequestHandler):
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
http.server.test(HandlerClass=MyHTTPRequestHandler)
|
||||
http.server.test(HandlerClass=MyHTTPRequestHandler, port=8000)
|
||||
|
@ -28,6 +28,7 @@ const C64_PRESETS = [
|
||||
//{id:'sidtune.dasm', name:'Tiny SID Tune (ASM)'},
|
||||
{id:'siddemo.c', name:'SID Player Demo'},
|
||||
{id:'climber.c', name:'Climber Game'},
|
||||
{id:'hello.wiz', name:'Hello Wiz (Wiz)'},
|
||||
];
|
||||
|
||||
const C64_MEMORY_MAP = { main:[
|
||||
|
Loading…
Reference in New Issue
Block a user