mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2025-02-09 02:31:21 +00:00
c64: update presets
This commit is contained in:
parent
c4fcf51e55
commit
d99260c87e
@ -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,
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
86
presets/c64/rasterirq.ca65
Normal file
86
presets/c64/rasterirq.ca65
Normal 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
19
presets/c64/rasterirq.h
Normal 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
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
69
presets/c64/spritesinborder.c
Normal file
69
presets/c64/spritesinborder.c
Normal 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! ");
|
||||
}
|
||||
}
|
@ -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' });
|
||||
|
Loading…
x
Reference in New Issue
Block a user