1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2025-01-14 09:30:57 +00:00

Added a naive double sine xy-plotter.

This commit is contained in:
jespergravgaard 2021-04-04 18:32:56 +02:00
parent 0598d6548a
commit ce41782240
6 changed files with 113 additions and 32 deletions

View File

@ -0,0 +1,9 @@
ldy #0
clc
lda #<{c1}
adc ({z2}),y
sta {m1}
iny
lda #>{c1}
adc ({z2}),y
sta {m1}+1

View File

@ -0,0 +1,11 @@
ldy #0
clc
lda #<{c1}
adc ({z1}),y
pha
iny
lda #>{c1}
adc ({z1}),y
sta {z1}+1
pla
sta {z1}

View File

@ -0,0 +1,7 @@
lda #<{c1}
clc
adc {m2}
sta {m1}
lda #>{c1}
adc {m2}+1
sta {m1}+1

View File

@ -5,7 +5,7 @@
"start_address": "0x080d", "start_address": "0x080d",
"cpu": "MEGA45GS02", "cpu": "MEGA45GS02",
"interrupt": "rom_min_c64", "interrupt": "rom_min_c64",
"emulator": "m65 -l /dev/cu.usbserial-251633005A061 -F -r -4", "emulator": "m65.osx -l /dev/cu.usbserial-251633005A061 -F -r -4",
"defines": { "defines": {
"__MEGA65__": 1, "__MEGA65__": 1,
"__MEGA65_C64__": 1 "__MEGA65_C64__": 1

View File

@ -5,7 +5,7 @@
"start_address": "0x2017", "start_address": "0x2017",
"cpu": "MEGA45GS02", "cpu": "MEGA45GS02",
"interrupt": "rom_min_mega65", "interrupt": "rom_min_mega65",
"emulator": "m65 -l /dev/cu.usbserial-251633005A061 -F -r", "emulator": "m65.osx -l /dev/cu.usbserial-251633005A061 -F -r",
"defines": { "defines": {
"__MEGA65__": 1 "__MEGA65__": 1
} }

View File

@ -1,4 +1,4 @@
// A pretty simple sine plotter // A pretty simple double sine plotter
#pragma target(mega65_remote) #pragma target(mega65_remote)
#include <mega65.h> #include <mega65.h>
@ -42,6 +42,9 @@ void main() {
memoryRemap(0x00,0,0); memoryRemap(0x00,0,0);
// Fast CPU, M65 IO // Fast CPU, M65 IO
POKE(0,65); POKE(0,65);
// Disable Kernal & Basic
*PROCPORT_DDR = PROCPORT_DDR_MEMORY_MASK;
*PROCPORT = PROCPORT_RAM_IO;
// Enable MEGA65 features // Enable MEGA65 features
VICIV->KEY = VICIV_KEY_M65_A; VICIV->KEY = VICIV_KEY_M65_A;
VICIV->KEY = VICIV_KEY_M65_B; VICIV->KEY = VICIV_KEY_M65_B;
@ -52,12 +55,6 @@ void main() {
VICIV->CONTROLC |= VICIV_VFAST; VICIV->CONTROLC |= VICIV_VFAST;
graphics_mode(); graphics_mode();
// initialize sine index
char idx = 0;
for(unsigned int i=0;i<320;i++) {
sin_idx[i] = idx;
idx += 11;
}
// Initialize plotter // Initialize plotter
init_plot(); init_plot();
@ -66,29 +63,55 @@ void main() {
while(VICIV->RASTER!=0xe3) ; while(VICIV->RASTER!=0xe3) ;
// White border and background // White border and background
VICIV->BORDER_COLOR = RED; VICIV->BORDER_COLOR = RED;
// Switch buffer
buffer ^=1;
// Select charset
if(buffer==0) {
VICIV->CHARPTR_LOLO = LOBYTE(GRAPHICS1);
VICIV->CHARPTR_LOHI = HIBYTE(GRAPHICS1);
VICIV->CHARPTR_HILO = 0;
graphics_render = GRAPHICS2;
} else {
VICIV->CHARPTR_LOLO = LOBYTE(GRAPHICS2);
VICIV->CHARPTR_LOHI = HIBYTE(GRAPHICS2);
VICIV->CHARPTR_HILO = 0;
graphics_render = GRAPHICS1;
}
// Clear the graphics // Clear the graphics
memset_dma256(0x0, 0x0, 0x6000, 0x00, 40*25*8); memset_dma(graphics_render, 0x00, 40*25*8);
VICIV->BORDER_COLOR = WHITE; VICIV->BORDER_COLOR = WHITE;
// Render some dots // Render some dots
render_dots(); render_dots();
// Black border and background // Black border and background
VICIV->BORDER_COLOR = BLACK; VICIV->BORDER_COLOR = BLUE;
} }
} }
// 0: show GRAPHICS1, render to GRAPHICS2
// 1: show GRAPHICS2, render to GRAPHICS1
volatile char buffer = 0;
// The graphics being rendered to
char * volatile graphics_render = GRAPHICS1;
// Sine idx for each plot // Sine idx for each plot
char sin_idx[320]; volatile unsigned int sin_x1_idx;
volatile unsigned int sin_x2_idx;
volatile unsigned int sin_y1_idx;
volatile unsigned int sin_y2_idx;
// Graphics bit // Graphics bit
char GFX_BIT[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }; char GFX_BIT[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
// Pointer to graphics for (x, 0) // Offset to graphics for (x, 0)
char * GFX_PTR[320]; unsigned int GFX_OFFSET[320];
void init_plot() { void init_plot() {
char * gfx = GRAPHICS; unsigned int gfx = 0;
for(unsigned int i=0; i<320;i++) { for(unsigned int i=0; i<320;i++) {
GFX_PTR[i] = gfx; GFX_OFFSET[i] = gfx;
if((i&7)==7) if((i&7)==7)
gfx +=200; gfx +=200;
} }
@ -96,27 +119,58 @@ void init_plot() {
// Do a single plot on the canvas // Do a single plot on the canvas
void plot(unsigned int x, char y) { void plot(unsigned int x, char y) {
char * gfx = GFX_PTR[x] + y; char * gfx = graphics_render + GFX_OFFSET[x] + y;
*gfx |= GFX_BIT[x&7]; *gfx |= GFX_BIT[x&7];
} }
void render_dots() { void render_dots() {
// Plot some dots // Plot some dots
for(unsigned int i=0;i<320;i++) { unsigned int idx_x1 = sin_x1_idx;
char idx = sin_idx[i]++; sin_x1_idx += 1; if(sin_x1_idx>SINX1_SIZE) sin_x1_idx -=SINX1_SIZE;
plot(i, SINE[idx]); unsigned int idx_x2 = sin_x2_idx;
sin_x2_idx -= 1; if(sin_x2_idx>SINX2_SIZE) sin_x2_idx +=SINX2_SIZE;
unsigned int idx_y1 = sin_y1_idx;
sin_y1_idx -= 1; if(sin_y1_idx>SINY1_SIZE) sin_y1_idx +=SINY1_SIZE;
unsigned int idx_y2 = sin_y2_idx;
sin_y2_idx += 1; if(sin_y2_idx>SINY2_SIZE) sin_y2_idx -=SINY2_SIZE;
for(unsigned int i=0;i<1536;i++) {
plot(SINX1[idx_x1]+SINX2[idx_x2], SINY1[idx_y1]+SINY2[idx_y2]);
idx_x1 -= 11; if(idx_x1>SINX1_SIZE) idx_x1 += SINX1_SIZE;
idx_x2 += 3; if(idx_x2>SINX2_SIZE) idx_x2 -= SINX2_SIZE;
idx_y1 += 9; if(idx_y1>SINY1_SIZE) idx_y1 -= SINY1_SIZE;
idx_y2 -= 5; if(idx_y2>SINY2_SIZE) idx_y2 += SINY2_SIZE;
} }
} }
// Sine table // Sine table
char SINE[0x200] = kickasm {{ const unsigned int SINY1_SIZE = 733;
.fill $200, round(99.5+99.5*sin(toRadians(360*i/256))) char SINY1[SINY1_SIZE+256] = kickasm {{
.fill 733+256, round(66.5+66.5*sin(toRadians(360*i/733)))
}}; }};
const unsigned int SINY2_SIZE = 317;
char SINY2[SINY2_SIZE+256] = kickasm {{
.fill 317+256, round(33+33*sin(toRadians(360*i/317)))
}};
const unsigned int SINX1_SIZE = 1613;
unsigned int SINX1[SINX1_SIZE+256] = kickasm {{
.fillword 1613+256, round(99.5+99.5*sin(toRadians(360*i/1613)))
}};
const unsigned int SINX2_SIZE = 547;
unsigned int SINX2[SINX2_SIZE+256] = kickasm {{
.fillword 547+256, round(60+60*sin(toRadians(360*i/547)))
}};
// Address of the screen // Address of the screen
char * const SCREEN = 0xc000; char * const SCREEN = 0xc000;
// // Absolute address of the graphics // // Absolute address of graphics buffer 1
char * const GRAPHICS = 0x6000; char * const GRAPHICS1 = 0x6000;
// // Absolute address of graphics buffer 2
char * const GRAPHICS2 = 0xa000;
void graphics_mode(void) { void graphics_mode(void) {
// 16-bit text mode // 16-bit text mode
@ -129,13 +183,13 @@ void graphics_mode(void) {
VICIV->CHARSTEP_HI = 0; VICIV->CHARSTEP_HI = 0;
// Draw 40 chars per row // Draw 40 chars per row
VICIV->CHRCOUNT = 40; VICIV->CHRCOUNT = 40;
// Put 2KB screen // Select 2KB screen
VICIV->SCRNPTR_LOLO = LOBYTE(SCREEN); VICIV->SCRNPTR_LOLO = LOBYTE(SCREEN);
VICIV->SCRNPTR_LOHI = HIBYTE(SCREEN); VICIV->SCRNPTR_LOHI = HIBYTE(SCREEN);
VICIV->SCRNPTR_HILO = 0x00; VICIV->SCRNPTR_HILO = 0x00;
// Put charset // Select charset
VICIV->CHARPTR_LOLO = LOBYTE(GRAPHICS); VICIV->CHARPTR_LOLO = LOBYTE(GRAPHICS1);
VICIV->CHARPTR_LOHI = HIBYTE(GRAPHICS); VICIV->CHARPTR_LOHI = HIBYTE(GRAPHICS1);
VICIV->CHARPTR_HILO = 0; VICIV->CHARPTR_HILO = 0;
// Layout screen so that graphics data comes from $40000 -- $4FFFF // Layout screen so that graphics data comes from $40000 -- $4FFFF
@ -164,8 +218,8 @@ void graphics_mode(void) {
VICIV->BG_COLOR = 0; VICIV->BG_COLOR = 0;
// Clear the graphics // Clear the graphics
memset_dma256(0x0, 0x0, 0x6000, 0x00, 40*25*8); memset_dma(GRAPHICS1, 0x00, 40*25*8);
//memset_dma256(0x0, 0x0, 0x6000, 0xff, 25*8); memset_dma(GRAPHICS2, 0x00, 40*25*8);
//memset_dma256(0x0, 0x0, 0x6000+25*39*8, 0xff, 25*8);
}
}