mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-01-13 18:30:21 +00:00
Added new MEGA65 DMA options (line drawing & spiral). Updated line drawing sample.
This commit is contained in:
parent
2702432332
commit
920e0011ba
@ -131,6 +131,8 @@ const char DMA_OPTION_TRANSPARENCY_DISABLE = 0x07;
|
||||
const char DMA_OPTION_FORMAT_F018A = 0x0a;
|
||||
// $0B = Use F018B list format
|
||||
const char DMA_OPTION_FORMAT_F018B = 0x0a;
|
||||
// $53 Enable ‘Shallan Spiral’ Mode
|
||||
const char DMA_OPTION_SPIRAL = 0x53;
|
||||
// $80 $xx = Set MB of source address
|
||||
const char DMA_OPTION_SRC_MB = 0x80;
|
||||
// $81 $xx = Set MB of destination address
|
||||
@ -145,4 +147,34 @@ const char DMA_OPTION_DEST_SKIPRATE_256TH = 0x84;
|
||||
const char DMA_OPTION_DEST_SKIPRATE = 0x85;
|
||||
// $86 $xx = Don't write to destination if byte value = $xx, and option $06 enabled
|
||||
const char DMA_OPTION_TRANSPARENCY_VALUE = 0x86;
|
||||
|
||||
// $87 Set X column bytes (LSB) for line drawing
|
||||
// The number of bytes needed to move to the next X column (8 pixels to the right)
|
||||
const char DMA_OPTION_LINE_XSTEP_LO = 0x87;
|
||||
// $88 Set X column bytes (MSB) for line drawing
|
||||
// The number of bytes needed to move to the next X column (8 pixels to the right)
|
||||
const char DMA_OPTION_LINE_XSTEP_HI = 0x88;
|
||||
// $89 Set Y row bytes (LSB) for line drawing
|
||||
// The number of bytes needed to move to the next Y row (1 pixel below)
|
||||
const char DMA_OPTION_LINE_YSTEP_LO = 0x89;
|
||||
// $8A Set Y row bytes (MSB) for line drawing
|
||||
// The number of bytes needed to move to the next Y row (1 pixel below)
|
||||
const char DMA_OPTION_LINE_YSTEP_HI = 0x8a;
|
||||
// $8B Slope (LSB) for line drawing
|
||||
const char DMA_OPTION_LINE_SLOPE_LO = 0x8b;
|
||||
// $8C Slope (MSB) for line drawing
|
||||
const char DMA_OPTION_LINE_SLOPE_HI = 0x8c;
|
||||
// $8D Slope accumulator initial fraction (LSB) for line drawing
|
||||
const char DMA_OPTION_LINE_SLOPE_INIT_LO = 0x8d;
|
||||
// $8E Slope accumulator initial fraction (MSB) for line drawing
|
||||
const char DMA_OPTION_LINE_SLOPE_INIT_HI = 0x8e;
|
||||
// $8F Line Drawing Mode enable and options (set in argument byte):
|
||||
// Bit 7 = enable line mode,
|
||||
// Bit 6 = select X or Y direction,
|
||||
// Bit 5 = slope is negative.
|
||||
const char DMA_OPTION_LINE_MODE = 0x8f;
|
||||
// Line Drawing Mode Bit 7 = enable line mode,
|
||||
const char DMA_OPTION_LINE_MODE_ENABLE = 0x80;
|
||||
// Line Drawing Mode Bit 6 = select X or Y direction,
|
||||
const char DMA_OPTION_LINE_MODE_DIRECTION_Y = 0x40;
|
||||
// Line Drawing Mode Bit 5 = slope is negative.
|
||||
const char DMA_OPTION_LINE_MODE_SLOPE_NEGATIVE = 0x20;
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Test hardware line drawing
|
||||
// Based on https://github.com/MEGA65/mega65-tools/blob/master/src/tests/test_290.c
|
||||
|
||||
#pragma target(mega65_remote)
|
||||
#pragma target(mega65)
|
||||
#include <mega65.h>
|
||||
#include <mega65-dma.h>
|
||||
#include <6502.h>
|
||||
@ -21,9 +21,36 @@ void lpoke(__zp unsigned long addr, char val) {
|
||||
}
|
||||
}
|
||||
|
||||
char line_dmalist[256];
|
||||
char slope_ofs, line_mode_ofs, cmd_ofs, count_ofs;
|
||||
char src_ofs, dst_ofs;
|
||||
// DMA command structure for drawing lines
|
||||
char line_dma_command[] = {
|
||||
DMA_OPTION_LINE_XSTEP_LO, (25*64 - 8) & 0xff, // Line X step bytes 64x25 = 1600
|
||||
DMA_OPTION_LINE_XSTEP_HI, (25*64 - 8) >> 8, // Line X step bytes 64x25 = 1600
|
||||
DMA_OPTION_LINE_SLOPE_LO, 0, // Line Slope
|
||||
DMA_OPTION_LINE_SLOPE_HI, 0, // Line Slope
|
||||
DMA_OPTION_LINE_MODE, 0, // Line Mode
|
||||
DMA_OPTION_FORMAT_F018A, // F018A list format
|
||||
DMA_OPTION_END, // end of options
|
||||
0, // DMA command
|
||||
0, 0, // Count of bytes to copy/fill
|
||||
0, 0, // Source address
|
||||
0, // Source bank
|
||||
0, 0, // Destination address
|
||||
0, // Destination bank
|
||||
0, 0 // Modulo value (unused)
|
||||
};
|
||||
|
||||
// Offset of the DMA line SLOPE
|
||||
const char LINE_DMA_COMMAND_SLOPE_OFFSET = 5;
|
||||
// Offset of the DMA line MODE
|
||||
const char LINE_DMA_COMMAND_MODE_OFFSET = 9;
|
||||
// Offset of the DMA command
|
||||
const char LINE_DMA_COMMAND_COMMAND_OFFSET = 12;
|
||||
// Offset of the DMA count
|
||||
const char LINE_DMA_COMMAND_COUNT_OFFSET = 13;
|
||||
// Offset of the DMA source
|
||||
const char LINE_DMA_COMMAND_SRC_OFFSET = 15;
|
||||
// Offset of the DMA destination
|
||||
const char LINE_DMA_COMMAND_DEST_OFFSET = 18;
|
||||
|
||||
void main() {
|
||||
|
||||
@ -43,38 +70,20 @@ void main() {
|
||||
|
||||
|
||||
|
||||
// Set up common structure of the DMA list
|
||||
char ofs = 0;
|
||||
// Screen layout is in vertical stripes, so we need only to setup the
|
||||
// X offset step. 64x25 =
|
||||
line_dmalist[ofs++] = 0x87;
|
||||
line_dmalist[ofs++] = (1600 - 8) & 0xff;
|
||||
line_dmalist[ofs++] = 0x88;
|
||||
line_dmalist[ofs++] = (1600 - 8) >> 8;
|
||||
line_dmalist[ofs++] = 0x8b;
|
||||
slope_ofs = ofs++; // remember where we have to put the slope in
|
||||
line_dmalist[ofs++] = 0x8c;
|
||||
ofs++;
|
||||
line_dmalist[ofs++] = 0x8f;
|
||||
line_mode_ofs = ofs++;
|
||||
line_dmalist[ofs++] = 0x0a; // F018A list format
|
||||
line_dmalist[ofs++] = 0x00; // end of options
|
||||
cmd_ofs = ofs++; // command byte
|
||||
count_ofs = ofs;
|
||||
ofs += 2;
|
||||
src_ofs = ofs;
|
||||
ofs += 3;
|
||||
dst_ofs = ofs;
|
||||
ofs += 3;
|
||||
line_dmalist[ofs++] = 0x00; // modulo
|
||||
line_dmalist[ofs++] = 0x00;
|
||||
//draw_line(160, 100, 0, 198, 1);
|
||||
|
||||
draw_line(160, 100, 319, 198, 1);
|
||||
|
||||
for(;;) ;
|
||||
|
||||
/*
|
||||
int x1 = 160;
|
||||
for(int x2=0;x2<320;x2+=11) {
|
||||
draw_line(x1, 100, x2, 198, 1);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -116,10 +125,9 @@ void graphics_mode(void) {
|
||||
POKE(0xD021, 0);
|
||||
|
||||
// Fill the graphics
|
||||
memset_dma256(0x0, 0x4, 0x0000, 0x00, 320*200);
|
||||
memset_dma256(0x0, 0x4, 0x0000, 0x055, 8*200);
|
||||
memset_dma256(0x0, 0x4, 0x0000+200*39*8, 0x055, 8*200);
|
||||
|
||||
memset_dma256(0x0, 0x4, 0x0000, 0x0b, 320*200);
|
||||
memset_dma256(0x0, 0x4, 0x0000, 0x0c, 8*200);
|
||||
memset_dma256(0x0, 0x4, 0x0000+200*39*8, 0x0c, 8*200);
|
||||
|
||||
}
|
||||
|
||||
@ -177,35 +185,35 @@ void draw_line(int x1, int y1, int x2, int y2, unsigned char colour)
|
||||
slope = (int)PEEK(0xD76A) + ((int)PEEK(0xD76B) << 8);
|
||||
|
||||
// Put slope into DMA options
|
||||
line_dmalist[slope_ofs] = (char)(slope & 0xff);
|
||||
line_dmalist[slope_ofs + 2] = (char)(slope >> 8);
|
||||
line_dma_command[LINE_DMA_COMMAND_SLOPE_OFFSET] = (char)(slope & 0xff);
|
||||
line_dma_command[LINE_DMA_COMMAND_SLOPE_OFFSET + 2] = (char)(slope >> 8);
|
||||
|
||||
// Load DMA dest address with the address of the first pixel
|
||||
addr = 0x40000 + (y1 << 3) + (x1 & 7) + (x1 >> 3) * 64 * 25l;
|
||||
line_dmalist[dst_ofs + 0] = <(<(addr));
|
||||
line_dmalist[dst_ofs + 1] = >(<(addr));
|
||||
line_dmalist[dst_ofs + 2] = <(>(addr));
|
||||
line_dma_command[LINE_DMA_COMMAND_DEST_OFFSET + 0] = <(<(addr));
|
||||
line_dma_command[LINE_DMA_COMMAND_DEST_OFFSET + 1] = >(<(addr));
|
||||
line_dma_command[LINE_DMA_COMMAND_DEST_OFFSET + 2] = <(>(addr));
|
||||
|
||||
// Source is the colour
|
||||
line_dmalist[src_ofs] = colour & 0xf;
|
||||
line_dma_command[LINE_DMA_COMMAND_SRC_OFFSET] = colour & 0xf;
|
||||
|
||||
// Count is number of pixels, i.e., dy.
|
||||
line_dmalist[count_ofs] = (char)(dy & 0xff);
|
||||
line_dmalist[count_ofs + 1] = (char)(dy >> 8);
|
||||
line_dma_command[LINE_DMA_COMMAND_COUNT_OFFSET] = (char)(dy & 0xff);
|
||||
line_dma_command[LINE_DMA_COMMAND_COUNT_OFFSET + 1] = (char)(dy >> 8);
|
||||
|
||||
// Command is FILL
|
||||
line_dmalist[cmd_ofs] = 0x03;
|
||||
line_dma_command[LINE_DMA_COMMAND_COMMAND_OFFSET] = 0x03;
|
||||
|
||||
// Line mode active, major axis is Y
|
||||
line_dmalist[line_mode_ofs] = 0x80 + 0x40 + (((x2 - x1) < 0) ? 0x20 : 0x00);
|
||||
line_dma_command[LINE_DMA_COMMAND_MODE_OFFSET] = 0x80 + 0x40 + (((x2 - x1) < 0) ? 0x20 : 0x00);
|
||||
|
||||
// snprintf(msg,41,"Y: (%d,%d) - (%d,%d) m=%04x",x1,y1,x2,y2,slope);
|
||||
// print_text(0,2,1,msg);
|
||||
|
||||
POKE(0xD020, 1);
|
||||
|
||||
POKE(0xD701, (char)(((unsigned int)(line_dmalist)) >> 8));
|
||||
POKE(0xD705, (char)(((unsigned int)(line_dmalist)) >> 0));
|
||||
POKE(0xD701, (char)(((unsigned int)(line_dma_command)) >> 8));
|
||||
POKE(0xD705, (char)(((unsigned int)(line_dma_command)) >> 0));
|
||||
|
||||
POKE(0xD020, 0);
|
||||
}
|
||||
@ -242,36 +250,36 @@ void draw_line(int x1, int y1, int x2, int y2, unsigned char colour)
|
||||
slope = (int)PEEK(0xD76A) + ((int)PEEK(0xD76B) << 8);
|
||||
|
||||
// Put slope into DMA options
|
||||
line_dmalist[slope_ofs] = (char)(slope & 0xff);
|
||||
line_dmalist[slope_ofs + 2] = (char)(slope >> 8);
|
||||
line_dma_command[LINE_DMA_COMMAND_SLOPE_OFFSET] = (char)(slope & 0xff);
|
||||
line_dma_command[LINE_DMA_COMMAND_SLOPE_OFFSET + 2] = (char)(slope >> 8);
|
||||
|
||||
// Load DMA dest address with the address of the first pixel
|
||||
addr = 0x40000 + (y1 << 3) + (x1 & 7) + (x1 >> 3) * 64 * 25;
|
||||
line_dmalist[dst_ofs + 0] = <(<(addr));
|
||||
line_dmalist[dst_ofs + 1] = >(<(addr));
|
||||
line_dmalist[dst_ofs + 2] = <(>(addr));
|
||||
line_dma_command[LINE_DMA_COMMAND_DEST_OFFSET + 0] = <(<(addr));
|
||||
line_dma_command[LINE_DMA_COMMAND_DEST_OFFSET + 1] = >(<(addr));
|
||||
line_dma_command[LINE_DMA_COMMAND_DEST_OFFSET + 2] = <(>(addr));
|
||||
|
||||
// Source is the colour
|
||||
line_dmalist[src_ofs] = colour & 0xf;
|
||||
line_dma_command[LINE_DMA_COMMAND_SRC_OFFSET] = colour & 0xf;
|
||||
|
||||
// Count is number of pixels, i.e., dy.
|
||||
line_dmalist[count_ofs] = (char)(dx & 0xff);
|
||||
line_dmalist[count_ofs + 1] = (char)(dx >> 8);
|
||||
line_dma_command[LINE_DMA_COMMAND_COUNT_OFFSET] = (char)(dx & 0xff);
|
||||
line_dma_command[LINE_DMA_COMMAND_COUNT_OFFSET + 1] = (char)(dx >> 8);
|
||||
|
||||
// Command is FILL
|
||||
line_dmalist[cmd_ofs] = 0x03;
|
||||
line_dma_command[LINE_DMA_COMMAND_COMMAND_OFFSET] = 0x03;
|
||||
|
||||
// Line mode active, major axis is X
|
||||
char line_mode = (((y2 - y1) < 0) ? 0x20 : 0x00);
|
||||
line_dmalist[line_mode_ofs] = 0x80 + 0x00 + line_mode;
|
||||
line_dma_command[LINE_DMA_COMMAND_MODE_OFFSET] = 0x80 + 0x00 + line_mode;
|
||||
|
||||
// snprintf(msg,41,"X: (%d,%d) - (%d,%d) m=%04x",x1,y1,x2,y2,slope);
|
||||
// print_text(0,2,1,msg);
|
||||
|
||||
POKE(0xD020, 1);
|
||||
|
||||
POKE(0xD701, (char)(((unsigned int)(line_dmalist)) >> 8));
|
||||
POKE(0xD705, (char)(((unsigned int)(line_dmalist)) >> 0));
|
||||
POKE(0xD701, (char)(((unsigned int)(line_dma_command)) >> 8));
|
||||
POKE(0xD705, (char)(((unsigned int)(line_dma_command)) >> 0));
|
||||
|
||||
POKE(0xD020, 0);
|
||||
}
|
||||
|
@ -13,7 +13,10 @@
|
||||
"printf.h": "c",
|
||||
"c64.h": "c",
|
||||
"sstream": "c",
|
||||
"functional": "c"
|
||||
"functional": "c",
|
||||
"mega65-dma.h": "c",
|
||||
"mega65.h": "c",
|
||||
"mega65-f018.h": "c"
|
||||
},
|
||||
"kickassembler.assemblerJar": "/Applications/KickAssembler/KickAss.jar"
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user