PiStorm interaction device changes, fixes and additions

This commit is contained in:
beeanyew 2021-09-09 14:01:18 +02:00
parent 1b5f967dfc
commit c4efbbb4c9
9 changed files with 239 additions and 12 deletions

View File

@ -39,6 +39,11 @@ enum pistorm_dev_cmds {
PI_CMD_RTG_SCALING = 0x0200, // [W] Set RTG scaling mode
PI_CMD_RTG_SCALE_FILTER = 0x0202, // [W] Set RTG scale filter
PI_CMD_SHOW_CLUT_CURSOR = 0x0204, // [W] Show or hide CLUT mouse cursor
PI_CMD_SET_CLUT_CURSOR = 0x0206, // [W] Set CLUT mouse cursor data
PI_CMD_COPYRECT_EX_MASK = 0x0208, // [W] Same as copyrect_ex, except with a mask color for transparent pixels.
PI_CMD_FILLRECT = 0x020A, // [W] Fills a memory rect with a color value.
PI_CMD_QBASIC = 0x0FFC, // QBasic
PI_CMD_NIBBLES = 0x0FFE, // Nibbles

View File

@ -156,10 +156,12 @@ void set_pistorm_devcfg_filename(char *filename) {
void handle_pistorm_dev_write(uint32_t addr_, uint32_t val, uint8_t type) {
uint32_t addr = (addr_ & 0xFFFF);
pi_cmd_result = PI_RES_OK;
switch((addr)) {
case PI_DBG_MSG:
// Output debug message based on value written and data in val/str registers.
// TODO: Output debug message based on value written and data in val/str registers.
DEBUG("[PISTORM-DEV] Write to DBG_MSG: %d (%.8X)\n", val, val);
break;
case PI_DBG_VAL1: case PI_DBG_VAL2: case PI_DBG_VAL3: case PI_DBG_VAL4:
case PI_DBG_VAL5: case PI_DBG_VAL6: case PI_DBG_VAL7: case PI_DBG_VAL8:
@ -173,7 +175,7 @@ void handle_pistorm_dev_write(uint32_t addr_, uint32_t val, uint8_t type) {
case PI_BYTE1: case PI_BYTE2: case PI_BYTE3: case PI_BYTE4:
case PI_BYTE5: case PI_BYTE6: case PI_BYTE7: case PI_BYTE8:
DEBUG("[PISTORM-DEV] Set BYTE %d to %d ($%.2X)\n", addr - PI_BYTE1, (val & 0xFF), (val & 0xFF));
//DEBUG("[PISTORM-DEV] Set BYTE %d to %d ($%.2X)\n", addr - PI_BYTE1, (val & 0xFF), (val & 0xFF));
pi_byte[addr - PI_BYTE1] = (val & 0xFF);
break;
case PI_WORD1: case PI_WORD2: case PI_WORD3: case PI_WORD4:
@ -182,15 +184,15 @@ void handle_pistorm_dev_write(uint32_t addr_, uint32_t val, uint8_t type) {
break;
case PI_WORD5: case PI_WORD6: case PI_WORD7: case PI_WORD8:
case PI_WORD9: case PI_WORD10: case PI_WORD11: case PI_WORD12:
//DEBUG("[PISTORM-DEV] Set WORD %d to %d ($%.4X)\n", (addr - PI_WORD5) / 2, (val & 0xFFFF), (val & 0xFFFF));
pi_word[(addr - PI_WORD5) / 2] = (val & 0xFFFF);
//DEBUG("[PISTORM-DEV] Set WORD %d to %d ($%.4X)\n", ((addr - PI_WORD5) / 2) + 4, (val & 0xFFFF), (val & 0xFFFF));
pi_word[((addr - PI_WORD5) / 2) + 4] = (val & 0xFFFF);
break;
case PI_LONGWORD1: case PI_LONGWORD2: case PI_LONGWORD3: case PI_LONGWORD4:
//DEBUG("[PISTORM-DEV] Set LONGWORD %d to %d ($%.8X)\n", (addr - PI_LONGWORD1) / 4, val, val);
pi_longword[(addr - PI_LONGWORD1) / 4] = val;
break;
case PI_STR1: case PI_STR2: case PI_STR3: case PI_STR4:
DEBUG("[PISTORM-DEV] Set STRING POINTER %d to $%.8X\n", (addr - PI_STR1) / 4, val);
//DEBUG("[PISTORM-DEV] Set STRING POINTER %d to $%.8X\n", (addr - PI_STR1) / 4, val);
pi_string[(addr - PI_STR1) / 4] = val;
break;
case PI_PTR1: case PI_PTR2: case PI_PTR3: case PI_PTR4:
@ -220,12 +222,15 @@ void handle_pistorm_dev_write(uint32_t addr_, uint32_t val, uint8_t type) {
DEBUG("CopyMemQuick.\n");
if ((pi_ptr[0] & 0x03) != 0) {
DEBUG("[!!!PISTORM-DEV] CopyMemQuick src not aligned: %.8X\n", pi_ptr[0]);
break;
}
if (pi_ptr[1] & 0x03) {
DEBUG("[!!!PISTORM-DEV] CopyMemQuick dst not aligned: %.8X\n", pi_ptr[1]);
break;
}
if (val & 0x03) {
DEBUG("[!!!PISTORM-DEV] CopyMemQuick size not aligned: %.8X\n", val);
break;
}
// Fallthrough
case PI_CMD_MEMCPY:
@ -243,10 +248,12 @@ void handle_pistorm_dev_write(uint32_t addr_, uint32_t val, uint8_t type) {
if (cfg->map_type[dst] == MAPTYPE_ROM)
break;
if (dst != -1 && src != -1) {
//DEBUG("super memcpy\n");
uint8_t *src_ptr = &cfg->map_data[src][(pi_ptr[0] - cfg->map_offset[src])];
uint8_t *dst_ptr = &cfg->map_data[dst][(pi_ptr[1] - cfg->map_offset[dst])];
memcpy(dst_ptr, src_ptr, val);
} else {
//DEBUG("slow memcpy\n");
uint8_t tmp = 0;
uint16_t tmps = 0;
for (uint32_t i = 0; i < val; i++) {
@ -293,10 +300,10 @@ void handle_pistorm_dev_write(uint32_t addr_, uint32_t val, uint8_t type) {
case PI_CMD_COPYRECT:
case PI_CMD_COPYRECT_EX:
if (pi_ptr[0] == 0 || pi_ptr[1] == 0) {
printf("[PISTORM-DEV] COPYRECT/EX from/to null pointer not allowed. Aborting.\n");
DEBUG("[PISTORM-DEV] COPYRECT/EX from/to null pointer not allowed. Aborting.\n");
pi_cmd_result = PI_RES_INVALIDVALUE;
} else if (pi_word[2] == 0 || pi_word[3] == 0) {
printf("[PISTORM-DEV] COPYRECT/EX called with a width/height of 0. Aborting.\n");
DEBUG("[PISTORM-DEV] COPYRECT/EX called with a width/height of 0. Aborting.\n");
pi_cmd_result = PI_RES_INVALIDVALUE;
} else {
int32_t src = get_mapped_item_by_address(cfg, pi_ptr[0]);
@ -312,6 +319,11 @@ void handle_pistorm_dev_write(uint32_t addr_, uint32_t val, uint8_t type) {
uint8_t *dst_ptr = &cfg->map_data[dst][(pi_ptr[1] - cfg->map_offset[dst])];
if (addr == PI_CMD_COPYRECT_EX) {
/*DEBUG("COPYRECT_EX:\n");
DEBUG("Src pitch: %d Dst Pitch: %d:\n", pi_word[0], pi_word[1]);
DEBUG("Width: %d Height: %d:\n", pi_word[2], pi_word[3]);
DEBUG("Src X: %d Src Y: %d:\n", pi_word[4], pi_word[5]);
DEBUG("Dst X: %d Dst Y: %d:\n", pi_word[6], pi_word[7]);*/
// Adjust pointers in the case of available src/dst coordinates.
src_ptr += pi_word[4] + (pi_word[5] * pi_word[0]);
dst_ptr += pi_word[6] + (pi_word[7] * pi_word[1]);
@ -346,6 +358,103 @@ void handle_pistorm_dev_write(uint32_t addr_, uint32_t val, uint8_t type) {
}
}
break;
case PI_CMD_COPYRECT_EX_MASK:
if (pi_ptr[0] == 0 || pi_ptr[1] == 0) {
DEBUG("[PISTORM-DEV] COPYRECT_EX_MASK from/to null pointer not allowed. Aborting.\n");
pi_cmd_result = PI_RES_INVALIDVALUE;
} else if (pi_word[2] == 0 || pi_word[3] == 0) {
DEBUG("[PISTORM-DEV] COPYRECT_EX_MASK called with a width/height of 0. Aborting.\n");
pi_cmd_result = PI_RES_INVALIDVALUE;
} else {
/*DEBUG("COPYRECT_EX_MASK:\n");
DEBUG("Src pitch: %d Dst Pitch: %d:\n", pi_word[0], pi_word[1]);
DEBUG("Width: %d Height: %d:\n", pi_word[2], pi_word[3]);
DEBUG("Src X: %d Src Y: %d:\n", pi_word[4], pi_word[5]);
DEBUG("Dst X: %d Dst Y: %d:\n", pi_word[6], pi_word[7]);
DEBUG("Mask color: %d (%.2X)\n", pi_byte[0], pi_byte[0]);*/
int32_t src = get_mapped_item_by_address(cfg, pi_ptr[0]);
int32_t dst = get_mapped_item_by_address(cfg, pi_ptr[1]);
if (dst != -1 && src != -1) {
uint8_t *src_ptr = &cfg->map_data[src][(pi_ptr[0] - cfg->map_offset[src])];
uint8_t *dst_ptr = &cfg->map_data[dst][(pi_ptr[1] - cfg->map_offset[dst])];
src_ptr += pi_word[4] + (pi_word[5] * pi_word[0]);
dst_ptr += pi_word[6] + (pi_word[7] * pi_word[1]);
for (int y = 0; y < pi_word[3]; y++) {
for (int x = 0; x < pi_word[2]; x++) {
if (src_ptr[x] != pi_byte[0]) {
dst_ptr[x] = src_ptr[x];
}
}
src_ptr += pi_word[0];
dst_ptr += pi_word[1];
}
} else {
uint32_t src_offset = 0, dst_offset = 0;
uint8_t tmp = 0;
src_offset += pi_word[4] + (pi_word[5] * pi_word[0]);
dst_offset += pi_word[6] + (pi_word[7] * pi_word[1]);
for (uint32_t y = 0; y < pi_word[3]; y++) {
for (uint32_t x = 0; x < pi_word[2]; x++) {
if (src == -1) tmp = (unsigned char)m68k_read_memory_8(pi_ptr[0] + src_offset + x);
else tmp = cfg->map_data[src][(pi_ptr[0] + src_offset + x) - cfg->map_offset[src]];
if (tmp != pi_byte[0]) {
if (dst == -1) m68k_write_memory_8(pi_ptr[1] + dst_offset + x, tmp);
else cfg->map_data[dst][(pi_ptr[1] + dst_offset + x) - cfg->map_offset[dst]] = tmp;
}
}
src_offset += pi_word[0];
dst_offset += pi_word[1];
}
}
}
break;
case PI_CMD_FILLRECT:
if (pi_ptr[1] == 0) {
DEBUG("[PISTORM-DEV] FILLRECT to null pointer not allowed. Aborting.\n");
pi_cmd_result = PI_RES_INVALIDVALUE;
} else if (pi_word[2] == 0 || pi_word[3] == 0) {
DEBUG("[PISTORM-DEV] FILLRECT called with a width/height of 0. Aborting.\n");
pi_cmd_result = PI_RES_INVALIDVALUE;
} else {
int32_t dst = get_mapped_item_by_address(cfg, pi_ptr[1]);
/*DEBUG("FILLRECT:\n");
DEBUG("Dst Pitch: %d:\n", pi_word[1]);
DEBUG("Width: %d Height: %d:\n", pi_word[2], pi_word[3]);
DEBUG("Dst X: %d Dst Y: %d:\n", pi_word[6], pi_word[7]);
DEBUG("Color: %d (%.8X):\n", pi_longword[0], pi_longword[0]);*/
uint8_t tmp = (unsigned char)pi_longword[0];
if (dst != -1) {
uint8_t *dst_ptr = &cfg->map_data[dst][(pi_ptr[1] - cfg->map_offset[dst])];
dst_ptr += pi_word[6] + (pi_word[7] * pi_word[1]);
for (int y = 0; y < pi_word[3]; y++) {
memset(dst_ptr, tmp, pi_word[2]);
dst_ptr += pi_word[1];
}
} else {
uint32_t dst_offset = 0;
dst_offset += pi_word[6] + (pi_word[7] * pi_word[1]);
for (uint32_t y = 0; y < pi_word[3]; y++) {
for (uint32_t x = 0; x < pi_word[2]; x++) {
if (dst == -1) m68k_write_memory_8(pi_ptr[1] + dst_offset + x, tmp);
else cfg->map_data[dst][(pi_ptr[1] + dst_offset + x) - cfg->map_offset[dst]] = tmp;
}
dst_offset += pi_word[1];
}
}
}
break;
case PI_CMD_SHOWFPS: rtg_show_fps((uint8_t)val); break;
case PI_CMD_PALETTEDEBUG: rtg_palette_debug((uint8_t)val); break;
@ -381,6 +490,17 @@ void handle_pistorm_dev_write(uint32_t addr_, uint32_t val, uint8_t type) {
DEBUG("[PISTORM-DEV] Write to RTG_SCALE_FILTER: %d\n", val);
rtg_set_scale_filter(val);
break;
case PI_CMD_SHOW_CLUT_CURSOR:
//DEBUG("[PISTORM-DEV] Write to SHOW_CLUT_CURSOR: %d\n", val);
rtg_show_clut_cursor(val);
break;
case PI_CMD_SET_CLUT_CURSOR: {
//DEBUG("[PISTORM-DEV] Write to SET_CLUT_CURSOR: %d\n", val);
uint8_t *bmp = get_mapped_data_pointer_by_address(cfg, pi_ptr[0]);
uint8_t *pal = get_mapped_data_pointer_by_address(cfg, pi_ptr[1]);
rtg_set_clut_cursor(bmp, (uint32_t *)pal, (int16_t)pi_word[0], (int16_t)pi_word[1], pi_word[2], pi_word[3], pi_word[4]);
break;
}
case PI_CMD_NETSTATUS:
DEBUG("[PISTORM-DEV] Write to NETSTATUS: %d\n", val);

View File

@ -160,6 +160,43 @@ void pi_copyrect_ex(unsigned char *dst, unsigned char *src,
WRITESHORT(PI_CMD_COPYRECT_EX, 1);
}
// Masked extended memory copyrect, for skipping transparent pixels of palette index `mask_color`.
void pi_copyrect_ex_mask(unsigned char *dst, unsigned char *src,
unsigned short src_pitch, unsigned short dst_pitch,
unsigned short src_x, unsigned short src_y,
unsigned short dst_x, unsigned short dst_y,
unsigned short w, unsigned short h, unsigned char mask_color) {
WRITELONG(PI_PTR1, (unsigned int)src);
WRITELONG(PI_PTR2, (unsigned int)dst);
WRITESHORT(PI_WORD1, src_pitch);
WRITESHORT(PI_WORD2, dst_pitch);
WRITESHORT(PI_WORD3, w);
WRITESHORT(PI_WORD4, h);
WRITESHORT(PI_WORD5, src_x);
WRITESHORT(PI_WORD6, src_y);
WRITESHORT(PI_WORD7, dst_x);
WRITESHORT(PI_WORD8, dst_y);
WRITEBYTE(PI_BYTE1, (unsigned char)mask_color);
WRITESHORT(PI_CMD_COPYRECT_EX_MASK, 1);
}
// Memory fillrect, for clearing a section of a buffer to a specific color.
void pi_fill_rect(unsigned char *dst, unsigned short pitch,
unsigned short x, unsigned short y, unsigned short w, unsigned short h, unsigned int color) {
WRITELONG(PI_PTR2, (unsigned int)dst);
WRITESHORT(PI_WORD2, pitch);
WRITESHORT(PI_WORD3, w);
WRITESHORT(PI_WORD4, h);
WRITESHORT(PI_WORD7, x);
WRITESHORT(PI_WORD8, y);
WRITELONG(PI_LONGWORD1, color);
WRITESHORT(PI_CMD_FILLRECT, 1);
}
// Set scale mode for the RTG, no additional arguments required
void pi_set_rtg_scale_mode(unsigned short scale_mode) {
WRITESHORT(PI_CMD_RTG_SCALING, scale_mode);
@ -179,6 +216,24 @@ void pi_set_rtg_scale_filter(unsigned short scale_filter) {
WRITESHORT(PI_CMD_RTG_SCALE_FILTER, scale_filter);
}
// Show or hide the special separate CLUT (palette) mouse cursor
void pi_show_clut_mouse_cursor(unsigned char show) {
WRITESHORT(PI_CMD_SHOW_CLUT_CURSOR, show);
}
// Set up the data for the separate CLUT mouse cursor.
// pal is a pointer to 3*256 bytes of 8-bit color components, BGR.
void pi_set_clut_mouse_cursor(short hot_x, short hot_y, unsigned short w, unsigned short h, const void *bmp, unsigned int key_color, unsigned char *pal_pointer) {
WRITELONG(PI_PTR1, (unsigned int)bmp);
WRITELONG(PI_PTR2, (unsigned int)pal_pointer);
WRITELONG(PI_WORD1, hot_x);
WRITELONG(PI_WORD2, hot_y);
WRITELONG(PI_WORD3, w);
WRITELONG(PI_WORD4, h);
WRITELONG(PI_WORD5, key_color);
WRITESHORT(PI_CMD_SET_CLUT_CURSOR, 1);
}
// PiSCSI stuff
// TODO: There's currently no way to read back what drives are mounted at which SCSI index.
unsigned short pi_piscsi_map_drive(char *filename, unsigned char index) {

View File

@ -32,6 +32,8 @@ unsigned short pi_memcpy(unsigned char *dst, unsigned char *src, unsigned int si
unsigned short pi_memset(unsigned char *dst, unsigned char val, unsigned int size);
void pi_copyrect(unsigned char *dst, unsigned char *src, unsigned short src_pitch, unsigned short dst_pitch, unsigned short w, unsigned short h);
void pi_copyrect_ex(unsigned char *dst, unsigned char *src, unsigned short src_pitch, unsigned short dst_pitch, unsigned short src_x, unsigned short src_y, unsigned short dst_x, unsigned short dst_y, unsigned short w, unsigned short h);
void pi_copyrect_ex_mask(unsigned char *dst, unsigned char *src, unsigned short src_pitch, unsigned short dst_pitch, unsigned short src_x, unsigned short src_y, unsigned short dst_x, unsigned short dst_y, unsigned short w, unsigned short h, unsigned char mask_color);
void pi_fill_rect(unsigned char *dst, unsigned short pitch, unsigned short x, unsigned short y, unsigned short w, unsigned short h, unsigned int color);
unsigned int pi_get_fb(void);
void pi_set_rtg_scale_mode(unsigned short scale_mode);
void pi_set_rtg_scale_rect(unsigned short scale_mode, signed short x1, signed short y1, signed short x2, signed short y2);
@ -46,3 +48,6 @@ unsigned short pi_remap_extrom(char *filename);
unsigned short pi_shutdown_pi(unsigned short shutdown_code);
unsigned short pi_confirm_shutdown(unsigned short shutdown_code);
void pi_show_clut_mouse_cursor(unsigned char show);
void pi_set_clut_mouse_cursor(short hot_x, short hot_y, unsigned short w, unsigned short h, const void *bmp, unsigned int key_color, unsigned char *pal_pointer);

View File

@ -111,7 +111,7 @@ int __stdargs main (int argc, char *argv[]) {
printf("File %s not found on the Pi side.\n", argv[2]);
} else {
unsigned int filesize = tmpvalue;
unsigned char *dest = malloc(filesize);
unsigned char *dest = calloc(filesize, 1);
if (dest == NULL) {
printf("Failed to allocate memory buffer for file. Aborting file transfer.\n");

View File

@ -39,7 +39,9 @@ extern uint16_t rtg_offset_x, rtg_offset_y;
uint32_t cur_rtg_frame = 0;
static pthread_t thread_id;
static uint8_t mouse_cursor_enabled = 0, cursor_image_updated = 0, updating_screen = 0, debug_palette = 0, show_fps = 0, palette_updated = 0;
static uint8_t mouse_cursor_enabled = 0, cursor_image_updated = 0;
static uint8_t clut_cursor_enabled = 0, clut_image_updated = 0;
static uint8_t updating_screen = 0, debug_palette = 0, show_fps = 0, palette_updated = 0;
static uint8_t mouse_cursor_w = 16, mouse_cursor_h = 16;
static int16_t mouse_cursor_x = 0, mouse_cursor_y = 0;
static int16_t mouse_cursor_x_adj = 0, mouse_cursor_y_adj = 0;
@ -64,6 +66,7 @@ static uint32_t palette[256];
static uint32_t cursor_palette[256];
uint32_t cursor_data[256 * 256];
uint32_t clut_cursor_texture_data[256 * 256];
void rtg_update_screen() {}
@ -316,7 +319,7 @@ reinit_raylib:;
break;
}
if (mouse_cursor_enabled) {
if (mouse_cursor_enabled || clut_cursor_enabled) {
float mc_x = mouse_cursor_x - rtg_offset_x + mouse_cursor_x_adj;
float mc_y = mouse_cursor_y - rtg_offset_y + mouse_cursor_y_adj;
Rectangle cursor_srcrect = { 0, 0, mouse_cursor_w, mouse_cursor_h };
@ -351,7 +354,10 @@ reinit_raylib:;
UpdateTexture(raylib_texture, &data->memory[*data->addr]);
}
if (cursor_image_updated) {
UpdateTexture(raylib_cursor_texture, cursor_data);
if (clut_cursor_enabled)
UpdateTexture(raylib_cursor_texture, clut_cursor_texture_data);
else
UpdateTexture(raylib_cursor_texture, cursor_data);
cursor_image_updated = 0;
}
if (palette_updated) {
@ -444,6 +450,41 @@ void rtg_shutdown_display() {
display_enabled = 0xFF;
}
void rtg_show_clut_cursor(uint8_t show) {
if (clut_cursor_enabled != show) {
while (rtg_on && !updating_screen)
usleep(0);
cursor_image_updated = 1;
}
clut_cursor_enabled = show;
}
void rtg_set_clut_cursor(uint8_t *bmp, uint32_t *pal, int16_t offs_x, int16_t offs_y, uint16_t w, uint16_t h, uint8_t mask_color) {
if (bmp == NULL) {
memset(clut_cursor_texture_data, 0x00, (256 * 256) * sizeof(uint32_t));
cursor_image_updated = 1;
}
if (bmp != NULL && pal != NULL) {
memset(clut_cursor_texture_data, 0x00, (256 * 256) * sizeof(uint32_t));
mouse_cursor_w = w;
mouse_cursor_h = h;
mouse_cursor_x_adj = -offs_x;
mouse_cursor_y_adj = -offs_y;
for (uint8_t y = 0; y < mouse_cursor_h; y++) {
for (uint8_t x = 0; x < mouse_cursor_w; x++) {
uint8_t clut_index = bmp[x + (y * w)];
if (bmp[x + (y * w)] != mask_color) {
uint32_t *col = (uint32_t *)((uint8_t *)pal + (clut_index *3));
clut_cursor_texture_data[x + (y * 256)] = (*col | 0xFF000000);
}
}
}
while (rtg_on && !updating_screen)
usleep(0);
cursor_image_updated = 1;
}
}
void rtg_enable_mouse_cursor(uint8_t enable) {
mouse_cursor_enabled = enable;
}
@ -451,7 +492,6 @@ void rtg_enable_mouse_cursor(uint8_t enable) {
void rtg_set_mouse_cursor_pos(int16_t x, int16_t y) {
mouse_cursor_x = x;
mouse_cursor_y = y;
//printf("Set mouse cursor pos to %d, %d.\n", x, y);
}
static uint8_t clut_cursor_data[256*256];

View File

@ -28,6 +28,8 @@ void rtg_set_scale_mode(uint16_t scale_mode);
uint16_t rtg_get_scale_mode();
void rtg_set_scale_rect(uint16_t scale_mode, int16_t x1, int16_t y1, int16_t x2, int16_t y2);
void rtg_set_scale_filter(uint16_t _filter_mode);
void rtg_show_clut_cursor(uint8_t show);
void rtg_set_clut_cursor(uint8_t *bmp, uint32_t *pal, int16_t offs_x, int16_t offs_y, uint16_t w, uint16_t h, uint8_t mask_color);
uint16_t rtg_get_scale_filter();
void rtg_palette_debug(uint8_t enable);