c64: update presets

This commit is contained in:
Steven Hugg 2022-07-20 14:32:47 -05:00
parent c4fcf51e55
commit d99260c87e
16 changed files with 437 additions and 241 deletions

View File

@ -5,7 +5,7 @@ SYMBOLS {
__LOADADDR__: type = import;
__EXEHDR__: type = import;
__STACKSIZE__: type = weak, value = $0800; # 2k stack
__HIMEM__: type = weak, value = $D000;
__HIMEM__: type = weak, value = $8000;
}
MEMORY {
ZP: file = "", define = yes, start = $0002, size = $001A;
@ -15,6 +15,7 @@ MEMORY {
SIDFILE: file = %O, define = yes, start = $1000, size = $1000, fill = yes;
MAIN: file = %O, define = yes, start = $2000, size = __HIMEM__ - $2000;
BSS: file = "", start = __ONCE_RUN__, size = __HIMEM__ - __STACKSIZE__ - __ONCE_RUN__;
VICBANK: file = %O, start = $8000, size = $4000;
}
SEGMENTS {
ZEROPAGE: load = ZP, type = zp;
@ -29,6 +30,7 @@ SEGMENTS {
INIT: load = MAIN, type = rw;
ONCE: load = MAIN, type = ro, define = yes;
BSS: load = BSS, type = bss, define = yes;
VICBANK: load = MAIN, type = ro, optional = yes;
}
FEATURES {
CONDES: type = constructor,

View File

@ -5,6 +5,16 @@
#include <c64.h>
#include <joystick.h>
//#resource "c64-sid.cfg"
#define CFGFILE c64-sid.cfg
//#resource "sidmusic1.bin"
//#link "sidplaysfx.ca65"
#include "sidplaysfx.h"
//#link "rasterirq.ca65"
#include "rasterirq.h"
#include "bcd.h"
//#link "bcd.c"
@ -17,13 +27,6 @@
#include "sprites.h"
//#link "sprites.c"
//#resource "c64-sid.cfg"
#define CFGFILE c64-sid.cfg
//#resource "sidmusic1.bin"
//#link "sidplaysfx.ca65"
#include "sidplaysfx.h"
// indices of sound effects
#define SND_JUMP 0
#define SND_HIT 2
@ -755,6 +758,16 @@ void play_scene() {
blimp_pickup_scene();
}
// main display list
void game_displaylist(void) {
VIC.bordercolor = 2;
sid_update();
VIC.bordercolor = 0;
// DLIST_NEXT(42);
// VIC.bordercolor = 3;
DLIST_RESTART(20);
}
// main program
void main() {
byte i;
@ -767,14 +780,16 @@ void main() {
sprite_shape(hidbuf, 32+i, SPRITE_DATA[i]);
}
sprshad.spr_mcolor = 0xff;
sprshad.spr_mcolor0 = 0x0f;
sprshad.spr_mcolor1 = 0x00;
VIC.spr_mcolor0 = 0x0f;
VIC.spr_mcolor1 = 0x00;
// select character set 2
VIC.addr = 0x15;
// start scrolling @ bottom of level
origin_y = START_ORIGIN_Y;
// install joystick
joy_install (joy_static_stddrv);
// setup display list
DLIST_SETUP(game_displaylist);
// main game loop
while (1) {
make_floors();

View File

@ -7,6 +7,7 @@ Start
sei ; turn off interrupts
ldy #0
sty $d020 ; reset border color
Loop
lda Message,y ; load message byte
beq EOM ; 0 = end of string

View File

@ -0,0 +1,86 @@
USE_INTERRUPTOR = 0
.segment "DATA"
StartDlist: .word NullDlist-1
NextDlist: .word NullDlist-1
.segment "CODE"
.global _dlist_setup
.global DLIST_IRQ_NEXT
.global DLIST_IRQ_RESTART
.if USE_INTERRUPTOR
.interruptor DLIST_IRQ
.endif
_dlist_setup:
SEI ; set interrupt bit, make the CPU ignore interrupt requests
sta StartDlist+0 ; save XA as pointer to start of dlist
stx StartDlist+1
LDA #%01111111 ; switch off interrupt signals from CIA-1
STA $DC0D
AND $D011 ; clear most significant bit of VIC's raster register
STA $D011
LDA $DC0D ; acknowledge pending interrupts from CIA-1
LDA $DD0D ; acknowledge pending interrupts from CIA-2
LDA #252 ; set rasterline where interrupt shall occur
STA $D012
.if !USE_INTERRUPTOR
LDA #<DLIST_IRQ ; set interrupt vectors, pointing to interrupt service routine below
STA $0314
LDA #>DLIST_IRQ
STA $0315
.endif
LDA #%00000001 ; enable raster interrupt signals from VIC
STA $D01A
cli
rts
DLIST_IRQ:
DLIST_CALL:
lda NextDlist+1
pha
lda NextDlist+0
pha
rts
DLIST_IRQ_RESTART:
sta $d012
lda StartDlist+0
sta NextDlist+0
lda StartDlist+1
sta NextDlist+1
bne DLIST_ACK
DLIST_IRQ_STOP:
lda #0 ; disable raster interrupt signals from VIC
sta $D01A
bne DLIST_ACK
DLIST_IRQ_NEXT:
sta $d012
pla
sta NextDlist+0
pla
sta NextDlist+1
DLIST_ACK:
ASL $D019 ; acknowledge the interrupt by clearing the VIC's interrupt flag
.if USE_INTERRUPTOR
clc
rts
.else
JMP $EA31 ; jump into KERNAL's standard interrupt service routine to handle keyboard scan, cursor display etc.
.endif
NullDlist:
lda #252
jmp DLIST_IRQ_RESTART

19
presets/c64/rasterirq.h Normal file
View File

@ -0,0 +1,19 @@
#ifndef _RASTERIRQ_H
#define _RASTERIRQ_H
void dlist_setup(void* ptr);
#define DLIST_SETUP(func) \
dlist_setup(((char*)func)-1)
#define DLIST_NEXT(line) \
__A__ = line; \
asm ("jsr DLIST_IRQ_NEXT");
#define DLIST_RESTART(line) \
__A__ = line; \
asm ("jmp DLIST_IRQ_RESTART");
#endif

View File

@ -8,183 +8,92 @@
#include <stdint.h>
#include <joystick.h>
typedef uint8_t byte;
typedef uint16_t word;
typedef int8_t sbyte;
#include "common.h"
//#link "common.c"
#define COLS 40
#define ROWS 25
#include "scrolling.h"
//#link "scrolling.c"
void raster_wait(unsigned char line) {
while (VIC.rasterline < line) ;
}
#include "sprites.h"
//#link "sprites.c"
void wait_vblank() {
raster_wait(255); // TODO
}
sbyte scroll_fine_x;
sbyte scroll_fine_y;
byte origin_x;
byte origin_y;
byte curbuf;
byte* scrnbuf[2]; // screen buffer(s)
byte tempbuf[COLS*ROWS];
void draw_cell(byte x, byte y) {
static void draw_cell(word ofs, byte x, byte y) {
byte xx = x + origin_x;
byte yy = y + origin_y;
byte ch = xx ^ yy;
word ofs = x+y*COLS;
scrnbuf[curbuf][ofs] = ch; // character
tempbuf[ofs] = ch; // color
hidbuf[ofs] = ch; // character
colorbuf[ofs] = ch; // color
}
void scroll_draw_column(byte col) {
byte y;
word ofs = col;
for (y=0; y<ROWS; y++) {
draw_cell(col, y);
draw_cell(ofs, col, y);
ofs += COLS;
}
}
void scroll_draw_row(byte row) {
byte x;
word ofs = row * COLS;
for (x=0; x<COLS; x++) {
draw_cell(x, row);
draw_cell(ofs, x, row);
++ofs;
}
}
void scroll_update_regs() {
VIC.ctrl1 = (VIC.ctrl1 & 0xf8) | scroll_fine_y;
VIC.ctrl2 = (VIC.ctrl2 & 0xf8) | scroll_fine_x;
}
void scroll_swap() {
// swap hidden and visible buffers
curbuf ^= 1;
// wait for vblank and update registers
wait_vblank();
scroll_update_regs();
VIC.addr = (VIC.addr & 0xf) | (curbuf ? 0x00 : 0x10);
}
void scroll_copy() {
// copy temp buf to color ram
memcpy(COLOR_RAM, tempbuf, COLS*ROWS);
// copy visible buffer to hidden buffer
memcpy(scrnbuf[curbuf], scrnbuf[curbuf^1], COLS*ROWS);
}
// TODO: left and up can be faster, b/c we can copy color ram downward
void scroll_left() {
memcpy(scrnbuf[curbuf], scrnbuf[curbuf^1]+1, COLS*ROWS-1);
++origin_x;
memcpy(tempbuf, COLOR_RAM+1, COLS*ROWS-1);
scroll_draw_column(COLS-1);
scroll_swap();
scroll_copy();
}
void scroll_up() {
memcpy(scrnbuf[curbuf], scrnbuf[curbuf^1]+COLS, COLS*(ROWS-1));
++origin_y;
memcpy(tempbuf, COLOR_RAM+COLS, COLS*(ROWS-1));
scroll_draw_row(ROWS-1);
scroll_swap();
scroll_copy();
}
void scroll_right() {
memcpy(scrnbuf[curbuf]+1, scrnbuf[curbuf^1], COLS*ROWS-1);
--origin_x;
memcpy(tempbuf+1, COLOR_RAM, COLS*ROWS-1);
scroll_draw_column(0);
scroll_swap();
scroll_copy();
}
void scroll_down() {
memcpy(scrnbuf[curbuf]+COLS, scrnbuf[curbuf^1], COLS*(ROWS-1));
--origin_y;
memcpy(tempbuf+COLS, COLOR_RAM, COLS*(ROWS-1));
scroll_draw_row(0);
scroll_swap();
scroll_copy();
}
void scroll_horiz(sbyte delta_x) {
scroll_fine_x += delta_x;
while (scroll_fine_x < 0) {
scroll_fine_x += 8;
scroll_left();
}
while (scroll_fine_x >= 8) {
scroll_fine_x -= 8;
scroll_right();
}
}
void scroll_vert(sbyte delta_y) {
scroll_fine_y += delta_y;
while (scroll_fine_y < 0) {
scroll_fine_y += 8;
scroll_up();
}
while (scroll_fine_y >= 8) {
scroll_fine_y -= 8;
scroll_down();
}
}
void scroll_setup() {
scroll_fine_x = 0;
scroll_fine_y = 0;
origin_x = 0x80;
origin_y = 0x80;
curbuf = 0;
// get screen buffer addresses
scrnbuf[0] = (byte*) 0x8000;
scrnbuf[1] = (byte*) 0x8400;
// copy existing text to screen 0
memcpy(scrnbuf[0], (byte*)0x400, COLS*ROWS);
// copy screen 1 to screen 0
memcpy(scrnbuf[1], scrnbuf[0], COLS*ROWS);
// set VIC bank ($4000-$7FFF)
// https://www.c64-wiki.com/wiki/VIC_bank
CIA2.pra = 0x01;
VIC.ctrl1 = 0x10; // 24 lines
VIC.ctrl2 = 0x00; // 38 columns
}
/*{w:24,h:21,bpp:1,brev:1}*/
const char SPRITE1[3*21] = {
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
};
void main(void) {
sbyte n =0;
byte n = 0;
clrscr();
printf("\r\n\r\n\r\n Hello World!");
printf("\r\n\r\n\r\n This is how we scroll");
printf("\r\n\r\n\r\n But color RAM can't move");
printf("\r\n\r\n\r\n So we have to use a temp buffer");
printf("\r\n\r\n\r\n And copy it just in time");
// setup scrolling library
scroll_setup();
// setup sprite library and copy sprite to VIC bank
sprite_clear();
sprite_shape(hidbuf, 32, SPRITE1);
// install the joystick driver
joy_install (joy_static_stddrv);
// infinite loop
while (1) {
static char speed = 1;
// get joystick bits
char joy = joy_read(0);
// speed up scrolling while button pressed
speed = JOY_BTN_1(joy) ? 2 : 1;
// move sprite based on arrow keys
if (JOY_LEFT(joy)) scroll_horiz(-1);
if (JOY_UP(joy)) scroll_vert(-1);
if (JOY_RIGHT(joy)) scroll_horiz(1);
if (JOY_DOWN(joy)) scroll_vert(1);
// update regs
if (JOY_LEFT(joy)) scroll_horiz(-speed);
if (JOY_UP(joy)) scroll_vert(-speed);
if (JOY_RIGHT(joy)) scroll_horiz(speed);
if (JOY_DOWN(joy)) scroll_vert(speed);
// animate sprite in shadow sprite ram
sprite_draw(0, n++, 70, 32);
// wait for vblank
wait_vblank();
scroll_update_regs();
// update scroll registers
// and swap screens if we must
scroll_update();
// then update sprite registers
sprite_update(visbuf);
}
}

View File

@ -17,26 +17,29 @@
#include "sprites.h"
//#link "sprites.c"
static void draw_cell(byte x, byte y) {
static void draw_cell(word ofs, byte x, byte y) {
byte xx = x + origin_x;
byte yy = y + origin_y;
byte ch = xx ^ yy;
word ofs = x+y*COLS;
hidbuf[ofs] = ch; // character
colorbuf[ofs] = ch; // color
}
void scroll_draw_column(byte col) {
byte y;
word ofs = col;
for (y=0; y<ROWS; y++) {
draw_cell(col, y);
draw_cell(ofs, col, y);
ofs += COLS;
}
}
void scroll_draw_row(byte row) {
byte x;
word ofs = row * COLS;
for (x=0; x<COLS; x++) {
draw_cell(x, row);
draw_cell(ofs, x, row);
++ofs;
}
}
@ -51,15 +54,42 @@ const char SPRITE1[3*21] = {
0x00,0x3E,0x00,0x00,0x3E,0x00,0x00,0x1C,0x00
};
int playerx = 0;
int playery = 0;
int camerax = 0;
int cameray = 0;
void update_player() {
sprite_draw(0, playerx-camerax+160, playery-cameray+140, 32);
}
void camera_follow(byte moving) {
int dx, dy;
dx = camerax - playerx;
dy = cameray - playery;
if (moving && abs(dx) < 32 && abs(dy) < 32) return;
dx >>= 4;
dy >>= 4;
if (dx) {
if (dx > 8) dx = 8;
else if (dx < -8) dx = -8;
camerax -= dx;
scroll_horiz(dx);
}
if (dy) {
if (dy > 8) dy = 8;
else if (dy < -8) dy = -8;
cameray -= dy;
scroll_vert(dy);
}
}
void main(void) {
byte n = 0;
clrscr();
printf("\r\n\r\n\r\n Hello World!");
printf("\r\n\r\n\r\n This is how we scroll");
printf("\r\n\r\n\r\n But color RAM can't move");
printf("\r\n\r\n\r\n So we have to use a temp buffer");
printf("\r\n\r\n\r\n And copy it just in time");
printf("\r\n\r\n\r\n Use the joystick to move");
printf("\r\n\r\n\r\n And the camera will follow");
// setup scrolling library
scroll_setup();
@ -67,30 +97,39 @@ void main(void) {
// setup sprite library and copy sprite to VIC bank
sprite_clear();
sprite_shape(hidbuf, 32, SPRITE1);
sprshad.spr_color[0] = 13;
// install the joystick driver
joy_install (joy_static_stddrv);
// infinite loop
while (1) {
static char speed = 1;
while (1) {
static char speed;
static char joy;
static bool slowframe = false;
// get joystick bits
char joy = joy_read(0);
joy = joy_read(0);
// speed up scrolling while button pressed
speed = JOY_BTN_1(joy) ? 2 : 1;
speed = JOY_BTN_1(joy) ? 3 : 1;
// if we copied screen memory last frame,
// double speed of player for this frame
if (slowframe) speed *= 2;
// move sprite based on arrow keys
if (JOY_LEFT(joy)) scroll_horiz(-speed);
if (JOY_UP(joy)) scroll_vert(-speed);
if (JOY_RIGHT(joy)) scroll_horiz(speed);
if (JOY_DOWN(joy)) scroll_vert(speed);
if (JOY_LEFT(joy)) playerx -= speed;
if (JOY_RIGHT(joy)) playerx += speed;
if (JOY_UP(joy)) playery -= speed;
if (JOY_DOWN(joy)) playery += speed;
// move the camera?
camera_follow(joy);
slowframe = swap_needed;
// animate sprite in shadow sprite ram
sprite_draw(0, n++, 70, 32);
update_player();
// wait for vblank
wait_vblank();
// then update sprite registers
sprite_update(visbuf);
// update scroll registers
// and swap screens if we must
scroll_update();
// then update sprite registers
sprite_update(visbuf);
}
}

View File

@ -11,53 +11,124 @@ byte* hidbuf;
byte* visbuf;
byte colorbuf[COLS*ROWS];
byte swap_needed;
byte copy_needed;
//
void scroll_swap(void) {
byte* tmp;
// set VIC bank address
VIC.addr = (VIC.addr & 0xf) | (((word)hidbuf >> 8) << 2);
// swap hidden and visible buffers
tmp = hidbuf;
hidbuf = visbuf;
visbuf = tmp;
// set VIC bank address
VIC.addr = (VIC.addr & 0xf) | (((word)visbuf >> 8) << 2);
}
void scroll_copy(void) {
// copy temp buf to color ram
void copy_color_ram_slow() {
memcpy(COLOR_RAM, colorbuf, COLS*ROWS);
// copy visible buffer to hidden buffer
}
void copy_color_ram_fast() {
// fast copy loop for upper 1/2 of color ram
asm("ldy #0");
asm("@loop:");
asm("lda %v,y", colorbuf);
asm("sta $d800,y");
asm("lda %v + $100,y", colorbuf);
asm("sta $d900,y");
asm("iny");
asm("bne @loop");
// second loop for lower 1/2 of color ram
asm("@loop2:");
asm("lda %v + $200,y", colorbuf);
asm("sta $da00,y");
asm("lda %v + $300,y", colorbuf);
asm("sta $db00,y");
asm("@skip: iny");
asm("bne @loop2");
}
void copy_to_hidden_buffer_slow() {
memcpy(hidbuf, visbuf, COLS*ROWS);
}
void copy_to_hidden_buffer_fast() {
// self-modifying code
asm("ldy %v+1", visbuf);
asm("sty @loop+2+6*0");
asm("iny");
asm("sty @loop+2+6*1");
asm("iny");
asm("sty @loop+2+6*2");
asm("iny");
asm("sty @skip-1-3");
asm("ldy %v+1", hidbuf);
asm("sty @loop+5+6*0");
asm("iny");
asm("sty @loop+5+6*1");
asm("iny");
asm("sty @loop+5+6*2");
asm("iny");
asm("sty @skip-1");
// fast copy loop
asm("ldy #0");
asm("@loop:");
asm("lda $8000,y");
asm("sta $8000,y");
asm("lda $8100,y");
asm("sta $8100,y");
asm("lda $8200,y");
asm("sta $8200,y");
asm("cpy #$e8");
asm("bcs @skip");
asm("lda $8300,y");
asm("sta $8300,y");
asm("@skip: iny");
asm("bne @loop");
}
void copy_if_needed() {
if (copy_needed) {
copy_to_hidden_buffer_fast();
copy_needed = false;
}
}
void scroll_update(void) {
VIC.ctrl1 = (VIC.ctrl1 & 0xf8) | scroll_fine_y;
VIC.ctrl2 = (VIC.ctrl2 & 0xf8) | scroll_fine_x;
if (swap_needed) {
scroll_swap();
scroll_copy();
swap_needed = 0;
copy_color_ram_fast();
swap_needed = false;
copy_needed = true;
} else {
copy_if_needed();
}
}
void scroll_left(void) {
memcpy(hidbuf, hidbuf+1, COLS*ROWS-1);
memcpy(colorbuf, colorbuf+1, COLS*ROWS-1);
copy_if_needed();
memmove(hidbuf, hidbuf+1, COLS*ROWS-1);
memmove(colorbuf, colorbuf+1, COLS*ROWS-1);
++origin_x;
scroll_draw_column(COLS-1);
swap_needed = true;
VIC.bordercolor = 0;
}
void scroll_up(void) {
memcpy(hidbuf, hidbuf+COLS, COLS*(ROWS-1));
memcpy(colorbuf, colorbuf+COLS, COLS*(ROWS-1));
copy_if_needed();
memmove(hidbuf, hidbuf+COLS, COLS*(ROWS-1));
memmove(colorbuf, colorbuf+COLS, COLS*(ROWS-1));
++origin_y;
scroll_draw_row(ROWS-1);
swap_needed = true;
}
void scroll_right(void) {
copy_if_needed();
memmove(hidbuf+1, hidbuf, COLS*ROWS-1);
memmove(colorbuf+1, colorbuf, COLS*ROWS-1);
--origin_x;
@ -66,6 +137,7 @@ void scroll_right(void) {
}
void scroll_down(void) {
copy_if_needed();
memmove(hidbuf+COLS, hidbuf, COLS*(ROWS-1));
memmove(colorbuf+COLS, colorbuf, COLS*(ROWS-1));
--origin_y;
@ -101,19 +173,22 @@ void scroll_setup(void) {
scroll_fine_x = scroll_fine_y = 0;
origin_x = origin_y = 0x80;
swap_needed = true;
copy_needed = true;
// get screen buffer addresses
// setup screen buffer addresses
hidbuf = (byte*) 0x8000;
visbuf = (byte*) 0x8400;
// copy existing text to screen 0
// copy existing screen contents to hidden buffer
memcpy(hidbuf, (byte*)0x400, COLS*ROWS);
// copy screen 1 to screen 0
// copy also to hidden buffer
memcpy(visbuf, hidbuf, COLS*ROWS);
// set VIC bank ($4000-$7FFF)
// set VIC bank ($8000-$BFFF)
// https://www.c64-wiki.com/wiki/VIC_bank
CIA2.pra = 0x01;
// set up 24 line / 38 column mode to hide edges
VIC.ctrl1 &= ~0x08; // 24 lines
VIC.ctrl2 &= ~0x08; // 38 columns
}

View File

@ -23,7 +23,7 @@ void scroll_setup(void);
void scroll_horiz(sbyte delta_x);
void scroll_vert(sbyte delta_y);
// call this after vblank
// call this right after vblank
void scroll_update(void);
// caller must implement these two

View File

@ -12,7 +12,6 @@
//#link "sidplaysfx.ca65"
#include "sidplaysfx.h"
void main(void) {
clrscr();
cursor(0);
@ -27,6 +26,6 @@ void main(void) {
sid_sfx(joy & 3);
}
waitvsync();
//sid_update();
sid_update();
}
}

View File

@ -2,6 +2,10 @@
; music and SFX from GoatTracker 2 sample files
; http://sourceforge.net/projects/goattracker2
.segment "DATA"
_sid_playing: .byte $00
.segment "SIDFILE"
.incbin "sidmusic1.bin"
@ -9,13 +13,17 @@
.segment "LOWCODE"
.global _sid_init, _sid_update, _sid_sfx
.global _sid_start
.global _sid_start, _sid_stop, _sid_playing
_sid_init:
jmp $1000
_sid_update:
bit _sid_playing
bpl @noplay
jmp $1003
@noplay:
rts
_sid_sfx:
tax
@ -24,36 +32,14 @@ _sid_sfx:
ldx #$0e ;Channel index in X
jmp $1006 ;(0, 7 or 14)
SID_IRQ:
jsr $1003
ASL $D019 ; acknowledge the interrupt by clearing the VIC's interrupt flag
JMP $EA31 ; jump into KERNAL's standard interrupt service routine to handle keyboard scan, cursor display etc.
_sid_start:
SEI ; set interrupt bit, make the CPU ignore interrupt requests
LDA #%01111111 ; switch off interrupt signals from CIA-1
STA $DC0D
AND $D011 ; clear most significant bit of VIC's raster register
STA $D011
LDA $DC0D ; acknowledge pending interrupts from CIA-1
LDA $DD0D ; acknowledge pending interrupts from CIA-2
LDA #210 ; set rasterline where interrupt shall occur
STA $D012
LDA #<SID_IRQ ; set interrupt vectors, pointing to interrupt service routine below
STA $0314
LDA #>SID_IRQ
STA $0315
LDA #%00000001 ; enable raster interrupt signals from VIC
STA $D01A
CLI ; clear interrupt flag, allowing the CPU to respond to interrupt requests
RTS
lda #$80
bne skipstop
_sid_stop:
lda #$00
skipstop:
sta _sid_playing
rts
sfxtbllo: .byte <arpeggio2
.byte <arpeggio1

View File

@ -43,7 +43,7 @@ void move_sprites(void) {
byte i;
for (i=0; i<8; i++) {
//VIC.bordercolor = i;
sprite_draw(i, (xpos[i]>>7)+0x80, (ypos[i]>>8)+0x80, 32);
sprite_draw(i, (xpos[i]>>7)+0x80, (ypos[i]>>8)+0x80, 255);
// update position
xpos[i] += xvel[i];
ypos[i] += yvel[i];
@ -134,12 +134,12 @@ void main(void) {
// setup sprite library and copy sprite to VIC bank
sprite_clear();
sprite_shape((void*)0x400, 32/2, SPRITEMC);
sprite_shape((void*)0x0, 255, SPRITEMC);
// set colors
sprshad.spr_mcolor = 0xff;
sprshad.spr_mcolor0 = 4;
sprshad.spr_mcolor1 = 7;
VIC.spr_mcolor0 = 4;
VIC.spr_mcolor1 = 7;
// set sprite initial positions
init_sprites();

View File

@ -8,18 +8,16 @@ void sprite_clear(void) {
memset(&sprshad, 0, sizeof(sprshad));
}
void sprite_update(char* vicbank) {
memcpy(vicbank + 0x3f8, sprshad.spr_shapes, 8);
VIC.spr_ena = sprshad.spr_ena;
VIC.spr_hi_x = sprshad.spr_hi_x;
void sprite_update(char* screenmem) {
memcpy(screenmem + 0x3f8, sprshad.spr_shapes, 8);
memcpy(VIC.spr_pos, sprshad.spr_pos, 16);
memcpy(VIC.spr_color, sprshad.spr_color, 8);
VIC.spr_ena = sprshad.spr_ena;
VIC.spr_hi_x = sprshad.spr_hi_x;
VIC.spr_exp_x = sprshad.spr_exp_x;
VIC.spr_exp_y = sprshad.spr_exp_y;
VIC.spr_bg_prio = sprshad.spr_bg_prio;
VIC.spr_mcolor = sprshad.spr_mcolor;
VIC.spr_mcolor0 = sprshad.spr_mcolor0;
VIC.spr_mcolor1 = sprshad.spr_mcolor1;
}
void sprite_shape(char* vicbank, byte index, const char* sprite_data) {

View File

@ -6,26 +6,24 @@
#define DEFAULT_SCREEN ((void*)0x400)
typedef struct {
byte spr_ena; /* Enable sprites */
byte spr_hi_x; /* High bits of X coordinate */
byte spr_exp_x; /* Expand sprites in X dir */
byte spr_exp_y; /* Expand sprites in Y dir */
byte spr_bg_prio; /* Priority to background */
byte spr_mcolor; /* Sprite multicolor bits */
byte spr_mcolor0; /* Color 0 for multicolor sprites */
byte spr_mcolor1; /* Color 1 for multicolor sprites */
byte spr_color[8]; /* Colors for the sprites */
struct {
byte x; /* X coordinate */
byte y; /* Y coordinate */
} spr_pos[8];
byte spr_hi_x; /* High bits of X coordinate */
byte spr_ena; /* Enable sprites */
byte spr_exp_y; /* Expand sprites in Y dir */
byte spr_bg_prio; /* Priority to background */
byte spr_mcolor; /* Sprite multicolor bits */
byte spr_exp_x; /* Expand sprites in X dir */
byte spr_color[8]; /* Colors for the sprites */
byte spr_shapes[8]; /* sprite shapes */
} SpriteShadow;
extern SpriteShadow sprshad;
void sprite_clear(void);
void sprite_update(char* screenram);
void sprite_update(char* screenmem);
void sprite_shape(char* vicbank, byte index, const char* sprite_data);
void sprite_draw(byte i, word x, byte y, byte shape);
byte sprite_get_closest_collision(byte i, byte spr_coll);

View File

@ -0,0 +1,69 @@
#include <stdio.h>
#include <conio.h>
#include <c64.h>
#include <cbm_petscii_charmap.h>
#include "common.h"
//#link "rasterirq.ca65"
#include "rasterirq.h"
//#link "sprites.c"
#include "sprites.h"
/*{w:24,h:21,bpp:1,brev:1}*/
const char spriteshape[3*21] = {
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
};
void dlist_example(void) {
static byte i = 0;
VIC.bordercolor = 6;
VIC.bordercolor = 5;
VIC.ctrl1 = 0x18;
DLIST_NEXT(150);
// VIC.ctrl1 = 5 | 0x18;
VIC.bordercolor = 2;
DLIST_NEXT(0xf9);
VIC.ctrl1 = 0x10;
VIC.bordercolor = 3;
DLIST_NEXT(0xfc);
VIC.ctrl1 = 0x18;
VIC.bordercolor = 4;
DLIST_RESTART(30);
}
void main(void) {
byte i;
clrscr();
sprite_clear();
sprite_shape((void*)0x400, 32/2, spriteshape);
// set colors
sprshad.spr_exp_x = 0xff;
for (i=0; i<8; i++) {
sprshad.spr_color[i] = i+3;
sprite_draw(i, i*38+24, 248, 32);
}
// TODO: can't do in IRQ
DLIST_SETUP(dlist_example);
while (1) {
sprshad.spr_pos[0].y += 1;
sprite_update(DEFAULT_SCREEN);
printf("Hello World! ");
}
}

View File

@ -129,9 +129,9 @@ export function assembleCA65(step: BuildStep): BuildStepResult {
}
execMain(step, CA65, args);
if (errors.length) {
// TODO?
let listings : CodeListingMap = {};
listings[step.path] = { lines:[], text:getWorkFileAsString(step.path) };
// TODO? change extension to .lst
//listings[step.path] = { lines:[], text:getWorkFileAsString(step.path) };
return { errors, listings };
}
objout = FS.readFile(objpath, { encoding: 'binary' });