From: beeanyew Date: Tue, 5 Jan 2021 02:01:12 +0000 (+0100) Subject: Dysfunctional SDL2 RTG output X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=fa52466319c77fd595a147b1a0c102e5e2a4f20a;p=pistorm Dysfunctional SDL2 RTG output --- diff --git a/Makefile b/Makefile index edb8135..3ac9fba 100644 --- a/Makefile +++ b/Makefile @@ -14,6 +14,7 @@ MAINFILES = emulator.c \ platforms/amiga/Gayle.c \ platforms/amiga/gayle-ide/ide.c \ platforms/amiga/rtg/rtg.c \ + platforms/amiga/rtg/rtg-output.c \ platforms/shared/rtc.c MUSASHIFILES = m68kcpu.c softfloat/softfloat.c @@ -32,7 +33,7 @@ EXEPATH = ./ CC = gcc WARNINGS = -Wall -Wextra -pedantic CFLAGS = $(WARNINGS) -march=armv7 -O3 -LFLAGS = $(WARNINGS) +LFLAGS = $(WARNINGS) -lSDL2 TARGET = $(EXENAME)$(EXE) diff --git a/emulator.c b/emulator.c index f9c1295..c6bf30c 100644 --- a/emulator.c +++ b/emulator.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "m68k.h" #include "main.h" #include "platforms/platforms.h" @@ -137,6 +138,22 @@ int main(int argc, char *argv[]) { } } + // Initialize SDL. + printf("Initializing SDL2...\n"); + if (SDL_Init(0) < 0) { + printf("Failed to initialize SDL2.\n"); + } + else { + printf("Initializing SDL2 Video...\n"); + if (SDL_Init(SDL_INIT_VIDEO) < 0) { + printf("Failed to initialize SDL2 Video. Trying again.\n"); + if (SDL_Init(SDL_INIT_VIDEO) < 0) { + printf("Failed to initialize SDL2 Video again. Dying.\n"); + } + } + printf("Initialized SDL2 Video.\n"); + } + keyboard_fd = open(keyboard_file, O_RDONLY | O_NONBLOCK); if (keyboard_fd == -1) { printf("Failed to open keyboard event source.\n"); diff --git a/platforms/amiga/Gayle.c b/platforms/amiga/Gayle.c index 1bbba36..39f552f 100644 --- a/platforms/amiga/Gayle.c +++ b/platforms/amiga/Gayle.c @@ -29,69 +29,12 @@ //#define GCLOW 0xda2010 //#define GDH 0xda2018 -// Gayle Addresses - -// Gayle IDE Reads -#define GERROR 0xda2004 // Error -#define GSTATUS 0xda201c // Status -// Gayle IDE Writes -#define GFEAT 0xda2004 // Write : Feature -#define GCMD 0xda201c // Write : Command -// Gayle IDE RW -#define GDATA 0xda2000 // Data -#define GSECTCNT 0xda2008 // SectorCount -#define GSECTNUM 0xda200c // SectorNumber -#define GCYLLOW 0xda2010 // CylinderLow -#define GCYLHIGH 0xda2014 // CylinderHigh -#define GDEVHEAD 0xda2018 // Device/Head -#define GCTRL 0xda3018 // Control -// Gayle Ident -#define GIDENT 0xDE1000 - -// Gayle IRQ/CC -#define GCS 0xDA8000 // Card Control -#define GIRQ 0xDA9000 // IRQ -#define GINT 0xDAA000 // Int enable -#define GCONF 0xDAB000 // Gayle Config - -/* DA8000 */ -#define GAYLE_CS_IDE 0x80 /* IDE int status */ -#define GAYLE_CS_CCDET 0x40 /* credit card detect */ -#define GAYLE_CS_BVD1 0x20 /* battery voltage detect 1 */ -#define GAYLE_CS_SC 0x20 /* credit card status change */ -#define GAYLE_CS_BVD2 0x10 /* battery voltage detect 2 */ -#define GAYLE_CS_DA 0x10 /* digital audio */ -#define GAYLE_CS_WR 0x08 /* write enable (1 == enabled) */ -#define GAYLE_CS_BSY 0x04 /* credit card busy */ -#define GAYLE_CS_IRQ 0x04 /* interrupt request */ -#define GAYLE_CS_DAEN 0x02 /* enable digital audio */ -#define GAYLE_CS_DIS 0x01 /* disable PCMCIA slot */ - -/* DA9000 */ -#define GAYLE_IRQ_IDE 0x80 -#define GAYLE_IRQ_CCDET 0x40 /* credit card detect */ -#define GAYLE_IRQ_BVD1 0x20 /* battery voltage detect 1 */ -#define GAYLE_IRQ_SC 0x20 /* credit card status change */ -#define GAYLE_IRQ_BVD2 0x10 /* battery voltage detect 2 */ -#define GAYLE_IRQ_DA 0x10 /* digital audio */ -#define GAYLE_IRQ_WR 0x08 /* write enable (1 == enabled) */ -#define GAYLE_IRQ_BSY 0x04 /* credit card busy */ -#define GAYLE_IRQ_IRQ 0x04 /* interrupt request */ -#define GAYLE_IRQ_RESET 0x02 /* reset machine after CCDET change */ -#define GAYLE_IRQ_BERR 0x01 /* generate bus error after CCDET change */ - -/* DAA000 */ -#define GAYLE_INT_IDE 0x80 /* IDE interrupt enable */ -#define GAYLE_INT_CCDET 0x40 /* credit card detect change enable */ -#define GAYLE_INT_BVD1 0x20 /* battery voltage detect 1 change enable */ -#define GAYLE_INT_SC 0x20 /* credit card status change enable */ -#define GAYLE_INT_BVD2 0x10 /* battery voltage detect 2 change enable */ -#define GAYLE_INT_DA 0x10 /* digital audio change enable */ -#define GAYLE_INT_WR 0x08 /* write enable change enabled */ -#define GAYLE_INT_BSY 0x04 /* credit card busy */ -#define GAYLE_INT_IRQ 0x04 /* credit card interrupt request */ -#define GAYLE_INT_BVD_LEV 0x02 /* BVD int level, 0=lev2,1=lev6 */ -#define GAYLE_INT_BSY_LEV 0x01 /* BSY int level, 0=lev2,1=lev6 */ +uint8_t gary_cfg[8]; + +uint8_t gayle_a4k = 0xA0; +uint16_t gayle_a4k_irq; +uint8_t ramsey_cfg = 0x08; +static uint8_t ramsey_id = RAMSEY_REV7; int counter; static uint8_t gayle_irq, gayle_cs, gayle_cs_mask, gayle_cfg; @@ -107,11 +50,24 @@ unsigned char cdtv_sram[32 * SIZE_KILO]; uint8_t gayle_int; +uint32_t gayle_ide_mask = ~GDATA; +uint32_t gayle_ide_base = GDATA; +uint8_t gayle_ide_adj = 0; + struct ide_controller *get_ide(int index) { //if (index) {} return ide0; } +void adjust_gayle_4000() { + gayle_ide_base = GDATA_A4000; + gayle_ide_adj = 2; +} + +void adjust_gayle_1200() { + +} + void set_hard_drive_image_file_amiga(uint8_t index, char *filename) { if (hdd_image_file[index] != NULL) free(hdd_image_file[index]); @@ -148,71 +104,69 @@ uint8_t CheckIrq(void) { return 0; } -void writeGayleB(unsigned int address, unsigned int value) { - if (address == GFEAT) { - ide_write8(ide0, ide_feature_w, value); - return; - } - if (address == GCMD) { - ide_write8(ide0, ide_command_w, value); - return; - } - if (address == GSECTCNT) { - ide_write8(ide0, ide_sec_count, value); - return; - } - if (address == GSECTNUM) { - ide_write8(ide0, ide_sec_num, value); - return; - } - if (address == GCYLLOW) { - ide_write8(ide0, ide_cyl_low, value); - return; - } - if (address == GCYLHIGH) { - ide_write8(ide0, ide_cyl_hi, value); - return; - } - if (address == GDEVHEAD) { - ide_write8(ide0, ide_dev_head, value); - return; - } - if (address == GCTRL) { - ide_write8(ide0, ide_devctrl_w, value); - return; - } - - if (address == GIDENT) { - counter = 0; - // printf("Write Byte to Gayle Ident 0x%06x (0x%06x)\n",address,value); - return; - } - - if (address == GIRQ) { - // printf("Write Byte to Gayle GIRQ 0x%06x (0x%06x)\n",address,value); - gayle_irq = (gayle_irq & value) | (value & (GAYLE_IRQ_RESET | GAYLE_IRQ_BERR)); - - return; - } +static uint8_t ide_action = 0; - if (address == GCS) { - printf("Write Byte to Gayle GCS 0x%06x (0x%06x)\n", address, value); - gayle_cs_mask = value & ~3; - gayle_cs &= ~3; - gayle_cs |= value & 3; - return; - } - - if (address == GINT) { - printf("Write Byte to Gayle GINT 0x%06x (0x%06x)\n", address, value); - gayle_int = value; +void writeGayleB(unsigned int address, unsigned int value) { + if (address >= gayle_ide_base) { + switch (address - gayle_ide_base + gayle_ide_adj) { + case GFEAT_OFFSET: + ide_action = ide_feature_w; + goto idewrite8; + case GCMD_OFFSET: + ide_action = ide_command_w; + goto idewrite8; + case GSECTCOUNT_OFFSET: + ide_action = ide_sec_count; + goto idewrite8; + case GSECTNUM_OFFSET: + ide_action = ide_sec_num; + goto idewrite8; + case GCYLLOW_OFFSET: + ide_action = ide_cyl_low; + goto idewrite8; + case GCYLHIGH_OFFSET: + ide_action = ide_cyl_hi; + goto idewrite8; + case GDEVHEAD_OFFSET: + ide_action = ide_dev_head; + goto idewrite8; + case GCTRL_OFFSET: + ide_action = ide_devctrl_w; + goto idewrite8; + case GIRQ_4000_OFFSET: + gayle_a4k_irq = value; + case GIRQ_OFFSET: + gayle_irq = (gayle_irq & value) | (value & (GAYLE_IRQ_RESET | GAYLE_IRQ_BERR)); + return; + } + goto skip_idewrite8; +idewrite8:; + ide_write8(ide0, ide_action, value); return; +skip_idewrite8:; } - if (address == GCONF) { - printf("Write Byte to Gayle GCONF 0x%06x (0x%06x)\n", address, value); - gayle_cfg = value; - return; + switch (address) { + case 0xDD203A: + gayle_a4k = value; + return; + case GIDENT: + counter = 0; + return; + case GCONF: + gayle_cfg = value; + return; + case RAMSEY_REG: + ramsey_cfg = value & 0x0F; + return; + case GINT: + gayle_int = value; + return; + case GCS: + gayle_cs_mask = value & ~3; + gayle_cs &= ~3; + gayle_cs |= value & 3; + return; } if ((address & GAYLEMASK) == CLOCKBASE) { @@ -232,11 +186,16 @@ void writeGayleB(unsigned int address, unsigned int value) { } void writeGayle(unsigned int address, unsigned int value) { - if (address == GDATA) { + if (address - gayle_ide_base == GDATA_OFFSET) { ide_write16(ide0, ide_data, value); return; } + if (address == GIRQ_A4000) { + gayle_a4k_irq = value; + return; + } + if ((address & GAYLEMASK) == CLOCKBASE) { if ((address & CLOCKMASK) >= 0x8000) { if (cdtv_mode) { @@ -275,35 +234,94 @@ void writeGayleL(unsigned int address, unsigned int value) { } uint8_t readGayleB(unsigned int address) { - if (address == GERROR) { - return ide_read8(ide0, ide_error_r); - } - if (address == GSTATUS) { - return ide_read8(ide0, ide_status_r); - } - - if (address == GSECTCNT) { - return ide_read8(ide0, ide_sec_count); - } - - if (address == GSECTNUM) { - return ide_read8(ide0, ide_sec_num); - } - - if (address == GCYLLOW) { - return ide_read8(ide0, ide_cyl_low); - } - - if (address == GCYLHIGH) { - return ide_read8(ide0, ide_cyl_hi); - } - - if (address == GDEVHEAD) { - return ide_read8(ide0, ide_dev_head); - } - - if (address == GCTRL) { - return ide_read8(ide0, ide_altst_r); + uint8_t ide_action = 0; + + if (address >= gayle_ide_base + gayle_ide_adj) { + switch (address - gayle_ide_base) { + case GERROR_OFFSET: + ide_action = ide_error_r; + goto ideread8; + case GSTATUS_OFFSET: + ide_action = ide_status_r; + goto ideread8; + case GSECTCOUNT_OFFSET: + ide_action = ide_sec_count; + goto ideread8; + case GSECTNUM_OFFSET: + ide_action = ide_sec_num; + goto ideread8; + case GCYLLOW_OFFSET: + ide_action = ide_cyl_low; + goto ideread8; + case GCYLHIGH_OFFSET: + ide_action = ide_cyl_hi; + goto ideread8; + case GDEVHEAD_OFFSET: + ide_action = ide_dev_head; + goto ideread8; + case GCTRL_OFFSET: + ide_action = ide_altst_r; + goto ideread8; + case GIRQ_4000_OFFSET: + case GIRQ_OFFSET: + return 0x80; + //gayle_irq = (gayle_irq & value) | (value & (GAYLE_IRQ_RESET | GAYLE_IRQ_BERR)); + } + goto skip_ideread8; +ideread8:; + return ide_read8(ide0, ide_action); +skip_ideread8:; + } + + switch (address) { + case GIDENT: { + uint8_t val; + // printf("Read Byte from Gayle Ident 0x%06x (0x%06x)\n",address,counter); + if (counter == 0 || counter == 1 || counter == 3) { + val = 0x80; // 80; to enable gayle + } else { + val = 0x00; + } + counter++; + return val; + } + case GINT: + return gayle_int; + case GCONF: + return gayle_cfg & 0x0f; + case GCS: { + uint8_t v; + v = gayle_cs_mask | gayle_cs; + return v; + } + // This seems incorrect, GARY_REG3 is the same as GIDENT, and the A4000 + // service manual says that Gary is accessible in the address range $DFC000 to $DFFFFF. + case GARY_REG0: + case GARY_REG1: + case GARY_REG2: + return gary_cfg[address - GARY_REG0]; + break; + //case GARY_REG3: + case GARY_REG4: + //case GARY_REG5: + return gary_cfg[address - GARY_REG3]; + case RAMSEY_ID: + return ramsey_id; + case RAMSEY_REG: + return ramsey_cfg; + case GARY_REG5: { // This makes no sense. + uint8_t val; + printf("Read Byte from GARY Ident 0x%06x (0x%06x)\n",address,counter); + if (counter == 0 || counter == 1 || counter == 3) { + val = 0x80; // 80; to enable GARY + } else { + val = 0x00; + } + counter++; + return val; + } + case 0xDD203A: + return gayle_a4k; } if ((address & GAYLEMASK) == CLOCKBASE) { @@ -318,64 +336,23 @@ uint8_t readGayleB(unsigned int address) { return get_rtc_byte(address, rtc_type); } - if (address == GIDENT) { - uint8_t val; - // printf("Read Byte from Gayle Ident 0x%06x (0x%06x)\n",address,counter); - if (counter == 0 || counter == 1 || counter == 3) { - val = 0x80; // 80; to enable gayle - } else { - val = 0x00; - } - counter++; - return val; - } - - if (address == GIRQ) { - // printf("Read Byte From GIRQ Space 0x%06x\n",gayle_irq); - - return 0x80;//gayle_irq; -/* - uint8_t irq; - irq = ide0->drive->intrq; - - if (irq == 1) { - // printf("IDE IRQ: %x\n",irq); - return 0x80; // gayle_irq; - } - - return 0; -*/ - } - - if (address == GCS) { - printf("Read Byte From GCS Space 0x%06x\n", 0x1234); - uint8_t v; - v = gayle_cs_mask | gayle_cs; - return v; - } - - if (address == GINT) { - // printf("Read Byte From GINT Space 0x%06x\n",gayle_int); - return gayle_int; - } - - if (address == GCONF) { - printf("Read Byte From GCONF Space 0x%06x\n", gayle_cfg & 0x0f); - return gayle_cfg & 0x0f; - } - printf("Read Byte From Gayle Space 0x%06x\n", address); return 0xFF; } uint16_t readGayle(unsigned int address) { - if (address == GDATA) { + if (address - gayle_ide_base == GDATA_OFFSET) { uint16_t value; value = ide_read16(ide0, ide_data); // value = (value << 8) | (value >> 8); return value; } + if (address == GIRQ_A4000) { + gayle_a4k_irq = 0x8000; + return 0x80FF; + } + if ((address & GAYLEMASK) == CLOCKBASE) { if ((address & CLOCKMASK) >= 0x8000) { if (cdtv_mode) { diff --git a/platforms/amiga/Gayle.h b/platforms/amiga/Gayle.h index 2bcb9c3..69e65b4 100644 --- a/platforms/amiga/Gayle.h +++ b/platforms/amiga/Gayle.h @@ -24,4 +24,108 @@ uint16_t readGayle(unsigned int address); uint32_t readGayleL(unsigned int address); struct ide_controller *get_ide(int index); + +// Gayle Addresses +#define GAYLE_IDE_BASE_A1200 0xDA2000 //16bit base +#define GAYLE_IDE_BASE_A4000 0xDD2020 + +// Gayle IDE Reads +#define GERROR 0xda2004 // Error +#define GSTATUS 0xda201C // Status +#define GERROR_A4000 GAYLE_IDE_BASE_A4000 + 0x06 // Error +#define GSTATUS_A4000 GAYLE_IDE_BASE_A4000 + 0x1E // Status + +// Gayle IDE read offsets +#define GERROR_OFFSET 0x04 +#define GSTATUS_OFFSET 0x1C +// Gayle IDE write offsets +#define GFEAT_OFFSET 0x04 +#define GCMD_OFFSET 0x1C +// Gayle IDE RW offsets +#define GDATA_OFFSET 0x00 +#define GSECTCOUNT_OFFSET 0x08 +#define GSECTNUM_OFFSET 0x0C +#define GCYLLOW_OFFSET 0x10 +#define GCYLHIGH_OFFSET 0x14 +#define GDEVHEAD_OFFSET 0x18 +#define GCTRL_OFFSET 0x1018 +#define GIRQ_OFFSET 0x7000 +#define GIRQ_4000_OFFSET 0x0FFE + +// Gayle IDE Writes +#define GFEAT 0xda2004 // Write : Feature +#define GCMD 0xda201c // Write : Command +#define GFEAT_A4000 GAYLE_IDE_BASE_A4000 + 0x06 // Write : Feature +#define GCMD_A4000 GAYLE_IDE_BASE_A4000 + 0x1E // Write : Command +#define GMODEREG0_A4000 0x0DD1020 // D31, PIO modes (00,01,10) +#define GMODEREG1_A4000 0x0DD1022 // D31, (MSB) + +// Gayle IDE RW +#define GDATA 0xda2000 // Data - 16 bit +#define GSECTCNT 0xda2008 // SectorCount +#define GSECTNUM 0xda200c // SectorNumber +#define GCYLLOW 0xda2010 // CylinderLow +#define GCYLHIGH 0xda2014 // CylinderHigh +#define GDEVHEAD 0xda2018 // Device/Head +#define GCTRL 0xda3018 // Control + +#define GDATA_A4000 GAYLE_IDE_BASE_A4000 // Data +#define GSECTCNT_A4000 GAYLE_IDE_BASE_A4000 + 0x0a // SectorCount +#define GSECTNUM_A4000 GAYLE_IDE_BASE_A4000 + 0x0e // SectorNumber +#define GCYLLOW_A4000 GAYLE_IDE_BASE_A4000 + 0x12 // CylinderLow +#define GCYLHIGH_A4000 GAYLE_IDE_BASE_A4000 + 0x16 // CylinderHigh +#define GDEVHEAD_A4000 GAYLE_IDE_BASE_A4000 + 0x1a // Device/Head +#define GCTRL_A4000 GAYLE_IDE_BASE_A4000 + 0x101a // Control + +// For A4000 there's no need to populate other areas, just GIRQ +#define GIRQ_A4000 GAYLE_IDE_BASE_A4000 + 0x1000 // IRQ 0xDD3020 + +// Gayle Ident +#define GIDENT 0xDE1000 + +// Gayle IRQ/CC +#define GCS 0xDA8000 // Card Control +#define GIRQ 0xDA9000 // IRQ +#define GINT 0xDAA000 // Int enable +#define GCONF 0xDAB000 // Gayle Config + +/* DA8000 */ +#define GAYLE_CS_IDE 0x80 /* IDE int status */ +#define GAYLE_CS_CCDET 0x40 /* credit card detect */ +#define GAYLE_CS_BVD1 0x20 /* battery voltage detect 1 */ +#define GAYLE_CS_SC 0x20 /* credit card status change */ +#define GAYLE_CS_BVD2 0x10 /* battery voltage detect 2 */ +#define GAYLE_CS_DA 0x10 /* digital audio */ +#define GAYLE_CS_WR 0x08 /* write enable (1 == enabled) */ +#define GAYLE_CS_BSY 0x04 /* credit card busy */ +#define GAYLE_CS_IRQ 0x04 /* interrupt request */ +#define GAYLE_CS_DAEN 0x02 /* enable digital audio */ +#define GAYLE_CS_DIS 0x01 /* disable PCMCIA slot */ + +/* DA9000 */ +#define GAYLE_IRQ_IDE 0x80 +#define GAYLE_IRQ_CCDET 0x40 /* credit card detect */ +#define GAYLE_IRQ_BVD1 0x20 /* battery voltage detect 1 */ +#define GAYLE_IRQ_SC 0x20 /* credit card status change */ +#define GAYLE_IRQ_BVD2 0x10 /* battery voltage detect 2 */ +#define GAYLE_IRQ_DA 0x10 /* digital audio */ +#define GAYLE_IRQ_WR 0x08 /* write enable (1 == enabled) */ +#define GAYLE_IRQ_BSY 0x04 /* credit card busy */ +#define GAYLE_IRQ_IRQ 0x04 /* interrupt request */ +#define GAYLE_IRQ_RESET 0x02 /* reset machine after CCDET change */ +#define GAYLE_IRQ_BERR 0x01 /* generate bus error after CCDET change */ + +/* DAA000 */ +#define GAYLE_INT_IDE 0x80 /* IDE interrupt enable */ +#define GAYLE_INT_CCDET 0x40 /* credit card detect change enable */ +#define GAYLE_INT_BVD1 0x20 /* battery voltage detect 1 change enable */ +#define GAYLE_INT_SC 0x20 /* credit card status change enable */ +#define GAYLE_INT_BVD2 0x10 /* battery voltage detect 2 change enable */ +#define GAYLE_INT_DA 0x10 /* digital audio change enable */ +#define GAYLE_INT_WR 0x08 /* write enable change enabled */ +#define GAYLE_INT_BSY 0x04 /* credit card busy */ +#define GAYLE_INT_IRQ 0x04 /* credit card interrupt request */ +#define GAYLE_INT_BVD_LEV 0x02 /* BVD int level, 0=lev2,1=lev6 */ +#define GAYLE_INT_BSY_LEV 0x01 /* BSY int level, 0=lev2,1=lev6 */ + #endif /* Gayle_h */ diff --git a/platforms/amiga/amiga-platform.c b/platforms/amiga/amiga-platform.c index acdb424..8a36cc6 100644 --- a/platforms/amiga/amiga-platform.c +++ b/platforms/amiga/amiga-platform.c @@ -1,6 +1,7 @@ #include #include #include +#include #include "../platforms.h" #include "amiga-autoconf.h" #include "amiga-registers.h" @@ -9,6 +10,7 @@ int handle_register_read_amiga(unsigned int addr, unsigned char type, unsigned int *val); int handle_register_write_amiga(unsigned int addr, unsigned int value, unsigned char type); +int init_rtg_data(); extern int ac_z2_done; extern int ac_z2_pic_count; @@ -153,6 +155,26 @@ void adjust_ranges_amiga(struct emulator_config *cfg) { int setup_platform_amiga(struct emulator_config *cfg) { printf("Performing setup for Amiga platform.\n"); + + if (strlen(cfg->platform->subsys)) { + printf("Subsystem is [%s]\n", cfg->platform->subsys); + if (strcmp(cfg->platform->subsys, "4000") == 0 || strcmp(cfg->platform->subsys, "3000") == 0) { + printf("Adjusting Gayle accesses for A3000/4000 Kickstart.\n"); + adjust_gayle_4000(); + } + else if (strcmp(cfg->platform->subsys, "1200") == 0 || strcmp(cfg->platform->subsys, "cd32") == 0) { + printf("Adjusting Gayle accesses for A1200/CD32 Kickstart.\n"); + adjust_gayle_1200(); + } + else if (strcmp(cfg->platform->subsys, "cdtv") == 0) { + printf("Configuring platform for CDTV emulation.\n"); + cdtv_mode = 1; + rtc_type = RTC_TYPE_MSM; + } + } + else + printf("No sub system specified.\n"); + // Look for Z2 autoconf Fast RAM by id int index = get_named_mapped_item(cfg, z2_autoconf_id); more_z2_fast:; @@ -261,9 +283,13 @@ void setvar_amiga(struct emulator_config *cfg, char *var, char *val) { cdtv_mode = 1; } if (strcmp(var, "rtg") == 0) { - printf("[AMIGA] RTG Enabled.\n"); - rtg_enabled = 1; - adjust_ranges_amiga(cfg); + if (init_rtg_data()) { + printf("[AMIGA] RTG Enabled.\n"); + rtg_enabled = 1; + adjust_ranges_amiga(cfg); + } + else + printf("[AMIGA} Failed to enable RTG.\n"); } if (strcmp(var, "rtc_type") == 0) { if (val && strlen(val) != 0) { @@ -316,5 +342,8 @@ void create_platform_amiga(struct platform_config *cfg, char *subsys) { if (subsys) { cfg->subsys = malloc(strlen(subsys) + 1); strcpy(cfg->subsys, subsys); + for (int i = 0; i < strlen(cfg->subsys); i++) { + cfg->subsys[i] = tolower(cfg->subsys[i]); + } } } diff --git a/platforms/amiga/amiga-registers.h b/platforms/amiga/amiga-registers.h index fb6e285..78042e7 100644 --- a/platforms/amiga/amiga-registers.h +++ b/platforms/amiga/amiga-registers.h @@ -3,6 +3,9 @@ void set_hard_drive_image_file_amiga(uint8_t index, char *filename); int custom_read_amiga(struct emulator_config *cfg, unsigned int addr, unsigned int *val, unsigned char type); int custom_write_amiga(struct emulator_config *cfg, unsigned int addr, unsigned int val, unsigned char type); +void adjust_gayle_4000(); +void adjust_gayle_1200(); + #define GAYLEBASE 0xD80000 #define GAYLESIZE 0x070000 #define GAYLEMASK 0xDF0000 @@ -10,3 +13,18 @@ int custom_write_amiga(struct emulator_config *cfg, unsigned int addr, unsigned #define CLOCKBASE 0xDC0000 #define CLOCKSIZE 0x010000 #define CLOCKMASK 0x00FFFF + +/* GARY ADDRESSES */ +#define GARY_REG0 0xDE0000 +#define GARY_REG1 0xDE0001 +#define GARY_REG2 0xDE0002 +#define GARY_REG3 0xDE1000 +#define GARY_REG4 0xDE1001 +#define GARY_REG5 0xDE1002 + +/* RAMSEY ADDRESSES */ +#define RAMSEY_REG 0xDE0003 /* just a nibble, it should return 0x08 for defaults with 16MB */ +#define RAMSEY_ID 0xDE0043 /* Either 0x0D or 0x0F (most recent version) */ +/* RAMSEY TYPES */ +#define RAMSEY_REV4 0x0D +#define RAMSEY_REV7 0x0F \ No newline at end of file diff --git a/platforms/amiga/rtg/rtg-output.c b/platforms/amiga/rtg/rtg-output.c new file mode 100644 index 0000000..3b8ddb7 --- /dev/null +++ b/platforms/amiga/rtg/rtg-output.c @@ -0,0 +1,139 @@ +#include +#include +#include +#include +#include + +#define RTG_INIT_ERR(a) { printf(a); *data->running = 0; } + +uint8_t busy = 0, rtg_on = 0; +extern uint8_t *rtg_mem; +extern uint32_t framebuffer_addr; + +extern uint16_t rtg_display_width, rtg_display_height; +extern uint16_t rtg_display_format; +extern uint16_t rtg_pitch, rtg_total_rows; +extern uint16_t rtg_offset_x, rtg_offset_y; + +static pthread_t thread_id; + +struct rtg_shared_data { + uint16_t *width, *height; + uint16_t *format, *pitch; + uint16_t *offset_x, *offset_y; + uint8_t *memory; + uint32_t *addr; + uint8_t *running; +}; + +SDL_Window *win = NULL; +SDL_Renderer *renderer = NULL; +SDL_Texture *img = NULL; + +struct rtg_shared_data rtg_share_data; + +void rtg_update_screen() { + struct rtg_shared_data *data = &rtg_share_data; + + //printf("RTG thread running\n"); + //fflush(stdout); + + //while (*data->running) { + //printf("We in da loop?\n"); + //busy = 1; + SDL_UpdateTexture(img, NULL, &data->memory[*data->addr + (*data->offset_x << *data->format) + (*data->offset_y * *data->pitch)], *data->pitch); + //busy = 0; + SDL_RenderClear(renderer); + SDL_RenderCopy(renderer, img, NULL, NULL); + SDL_RenderPresent(renderer); + //sleep(0); + //} + + //SDL_Quit(); + //printf("RTG thread exited somewhat peacefully.\n"); + + //return args; +} + +void rtg_set_clut_entry(uint8_t index, uint8_t r, uint8_t g, uint8_t b) { + +} + +void rtg_init_display() { + int err; + rtg_on = 1; + + rtg_share_data.format = &rtg_display_format; + rtg_share_data.width = &rtg_display_width; + rtg_share_data.height = &rtg_display_height; + rtg_share_data.pitch = &rtg_pitch; + rtg_share_data.offset_x = &rtg_offset_x; + rtg_share_data.offset_y = &rtg_offset_y; + rtg_share_data.memory = rtg_mem; + rtg_share_data.running = &rtg_on; + rtg_share_data.addr = &framebuffer_addr; + struct rtg_shared_data *data = &rtg_share_data; + + printf("Creating %dx%d SDL2 window...\n", *data->width, *data->height); + fflush(stdout); + win = SDL_CreateWindow("Pistorm RTG", 0, 0, *data->width, *data->height, 0); + if (!win) { + RTG_INIT_ERR("Failed create SDL2 window.\n"); + fflush(stdout); + goto death; + } + else { + printf("Created %dx%d window.\n", *data->width, *data->height); + fflush(stdout); + } + + printf("Creating SDL2 renderer...\n"); + fflush(stdout); + renderer = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED); + if (!renderer) { + RTG_INIT_ERR("Failed create SDL2 renderer.\n"); + fflush(stdout); + goto death; + } + else { + printf("Created SDL2 renderer.\n"); + fflush(stdout); + } + + printf("Creating SDL2 texture...\n"); + fflush(stdout); + img = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_TARGET, *data->width, *data->height); + if (!img) { + RTG_INIT_ERR("Failed create SDL2 texture.\n"); + fflush(stdout); + goto death; + } + else { + printf("Created %dx%d texture.\n", *data->width, *data->height); + fflush(stdout); + } + + /*err = pthread_create(&thread_id, NULL, &rtgThread, (void *)&rtg_share_data); + if (err != 0) { + rtg_on = 0; + printf("can't create RTG thread :[%s]", strerror(err)); + } + else { + printf("RTG Thread created successfully\n");*/ + printf("RTG display enabled.\n"); + //} + death:; +} + +void rtg_shutdown_display() { + //void *balf; + printf("RTG display disabled.\n"); + //while(rtg_on) { + rtg_on = 0; + //sleep(0); + //} + + if (img) SDL_DestroyTexture(img); + if (renderer) SDL_DestroyRenderer(renderer); + if (win) SDL_DestroyWindow(win); +} diff --git a/platforms/amiga/rtg/rtg.c b/platforms/amiga/rtg/rtg.c index e26cabf..4fce959 100644 --- a/platforms/amiga/rtg/rtg.c +++ b/platforms/amiga/rtg/rtg.c @@ -1,11 +1,13 @@ #include #include #include +#include +#include +#include #include "rtg.h" #include "../../../config_file/config_file.h" static uint16_t palette[256]; -static uint8_t rtg_mem[64 * SIZE_MEGA]; // FIXME static uint8_t rtg_u8[4]; static uint16_t rtg_x[3], rtg_y[3]; @@ -13,16 +15,19 @@ static uint16_t rtg_format; static uint32_t rtg_address[2]; static uint32_t rtg_rgb[2]; -static uint8_t rtg_enabled; +static uint8_t display_enabled; uint16_t rtg_display_width, rtg_display_height; uint16_t rtg_display_format; uint16_t rtg_pitch, rtg_total_rows; uint16_t rtg_offset_x, rtg_offset_y; +uint8_t *rtg_mem; // FIXME + uint32_t framebuffer_addr; static void handle_rtg_command(uint32_t cmd); +static struct timespec f1, f2; static const char *op_type_names[OP_TYPE_NUM] = { "BYTE", @@ -38,6 +43,19 @@ static const char *rtg_format_names[RTGFMT_NUM] = { "15BPP RGB (555)", }; +int init_rtg_data() { + rtg_mem = calloc(1, 32 * SIZE_MEGA); + if (!rtg_mem) { + printf("Failed to allocate RTG video memory.\n"); + return 0; + } + + return 1; +} + +extern uint8_t busy, rtg_on; +void rtg_update_screen(); + unsigned int rtg_read(uint32_t address, uint8_t mode) { //printf("%s read from RTG: %.8X\n", op_type_names[mode], address); if (address >= PIGFX_REG_SIZE) { @@ -61,6 +79,19 @@ unsigned int rtg_read(uint32_t address, uint8_t mode) { return 0; } +struct timespec diff(struct timespec start, struct timespec end) +{ + struct timespec temp; + if ((end.tv_nsec-start.tv_nsec)<0) { + temp.tv_sec = end.tv_sec-start.tv_sec-1; + temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec; + } else { + temp.tv_sec = end.tv_sec-start.tv_sec; + temp.tv_nsec = end.tv_nsec-start.tv_nsec; + } + return temp; +} + void rtg_write(uint32_t address, uint32_t value, uint8_t mode) { //printf("%s write to RTG: %.8X (%.8X)\n", op_type_names[mode], address, value); if (address >= PIGFX_REG_SIZE) { @@ -138,6 +169,14 @@ void rtg_write(uint32_t address, uint32_t value, uint8_t mode) { } } + if (rtg_on) { + clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &f2); + if (diff(f1,f2).tv_nsec / 1000000.0 > 100.00) { + rtg_update_screen(); + f1 = f2; + } + } + return; } @@ -162,7 +201,7 @@ static void handle_rtg_command(uint32_t cmd) { break; case RTGCMD_SETPAN: //printf("Command: SetPan.\n"); - framebuffer_addr = rtg_address[0]; + framebuffer_addr = rtg_address[0] - (PIGFX_RTG_BASE + PIGFX_REG_SIZE); rtg_offset_x = rtg_x[1]; rtg_offset_y = rtg_y[1]; rtg_pitch = (rtg_x[0] << rtg_display_format); @@ -173,25 +212,53 @@ static void handle_rtg_command(uint32_t cmd) { case RTGCMD_SETCLUT: { //printf("Command: SetCLUT.\n"); //printf("Set palette entry %d to %d, %d, %d\n", rtg_u8[0], rtg_u8[1], rtg_u8[2], rtg_u8[3]); - int r = (int)((float)rtg_u8[1] / 255.0f * 31.0f); + /*int r = (int)((float)rtg_u8[1] / 255.0f * 31.0f); int g = (int)((float)rtg_u8[2] / 255.0f * 63.0f); int b = (int)((float)rtg_u8[3] / 255.0f * 31.0f); - palette[rtg_u8[0]] = ((r & 0x1F) << 11) | ((g & 0x3F) << 6) | ((b & 0x1F) << 6); + palette[rtg_u8[0]] = ((r & 0x1F) << 11) | ((g & 0x3F) << 6) | (b & 0x1F);*/ + rtg_set_clut_entry(rtg_u8[0], rtg_u8[1], rtg_u8[2], rtg_u8[3]); break; } case RTGCMD_SETDISPLAY: + // I remeber wrongs. //printf("Command: SetDisplay.\n"); - if (rtg_enabled != rtg_u8[1]) { - //printf("RTG Display %s\n", (rtg_u8[1]) ? "enabled" : "disabled"); - rtg_enabled = rtg_u8[1]; - //if (rtg_enabled) - //printf("%dx%d pixels\n", rtg_display_width, rtg_display_height); - } break; case RTGCMD_ENABLE: case RTGCMD_SETSWITCH: - // Implementing this command only matters if the Pi is to pass through the analog (or digital) - // native video, otherwise this does nothing. + if (display_enabled != rtg_u8[1]) { + //printf("RTG Display %s\n", (rtg_u8[1]) ? "enabled" : "disabled"); + display_enabled = rtg_u8[1]; + if (display_enabled) { + rtg_init_display(); + clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &f1); + } + else + rtg_shutdown_display(); + } + break; + case RTGCMD_FILLRECT: + rtg_fillrect(rtg_x[0], rtg_y[0], rtg_x[1], rtg_y[1], rtg_rgb[0], rtg_x[2], rtg_format, 0xFF); + break; + } +} + +void rtg_fillrect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint32_t color, uint16_t pitch, uint16_t format, uint8_t mask) { + if (mask) {} + switch(format) { + case RTGFMT_8BIT: + break; + case RTGFMT_RBG565: { + uint16_t *ptr = (uint16_t *)&rtg_mem[framebuffer_addr + (x << format) + (y * pitch)]; + for (int xs = 0; xs < w; xs++) { + ptr[xs] = (color >> 16); + } + for (int ys = 1; ys < h; ys++) { + ptr += (rtg_pitch >> format); + memcpy(ptr, (void *)(size_t)(ptr - (rtg_pitch >> format)), rtg_pitch); + } + break; + } + case RTGFMT_RGB32: break; } } diff --git a/platforms/amiga/rtg/rtg.h b/platforms/amiga/rtg/rtg.h index c90276d..0265e1a 100644 --- a/platforms/amiga/rtg/rtg.h +++ b/platforms/amiga/rtg/rtg.h @@ -31,6 +31,7 @@ enum rtg_cmds { RTGCMD_ENABLE, RTGCMD_SETDISPLAY, RTGCMD_SETSWITCH, + RTGCMD_FILLRECT, }; enum rtg_formats { @@ -43,3 +44,8 @@ enum rtg_formats { void rtg_write(uint32_t address, uint32_t value, uint8_t mode); unsigned int rtg_read(uint32_t address, uint8_t mode); +void rtg_set_clut_entry(uint8_t index, uint8_t r, uint8_t g, uint8_t b); +void rtg_init_display(); +void rtg_shutdown_display(); + +void rtg_fillrect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint32_t color, uint16_t pitch, uint16_t format, uint8_t mask); \ No newline at end of file diff --git a/platforms/amiga/rtg/rtg_driver_amiga/build.bat b/platforms/amiga/rtg/rtg_driver_amiga/build.bat new file mode 100644 index 0000000..1c6688e --- /dev/null +++ b/platforms/amiga/rtg/rtg_driver_amiga/build.bat @@ -0,0 +1,2 @@ +vc +aos68k -nostdlib -I$VBCC/targets/m68k-amigaos/include2 -c99 -O2 -o pigfx020.card pigfx.c -ldebug -lamiga -cpu=68020 +vc +aos68k -nostdlib -I$VBCC/targets/m68k-amigaos/include2 -c99 -O2 -o pigfx030.card pigfx.c -ldebug -lamiga -cpu=68030 diff --git a/platforms/amiga/rtg/rtg_driver_amiga/pigfx.c b/platforms/amiga/rtg/rtg_driver_amiga/pigfx.c index 88aae6c..05d0108 100644 --- a/platforms/amiga/rtg/rtg_driver_amiga/pigfx.c +++ b/platforms/amiga/rtg/rtg_driver_amiga/pigfx.c @@ -52,6 +52,7 @@ enum rtg_cmds { RTGCMD_ENABLE, RTGCMD_SETDISPLAY, RTGCMD_SETSWITCH, + RTGCMD_FILLRECT, }; enum rtg_formats { @@ -112,6 +113,8 @@ void SetReadPlane (__REGA0(struct BoardInfo *b), __REGD0(UBYTE plane)); void WaitVerticalSync (__REGA0(struct BoardInfo *b), __REGD0(BOOL toggle)); +void FillRect (__REGA0(struct BoardInfo *b), __REGA1(struct RenderInfo *r), __REGD0(WORD x), __REGD1(WORD y), __REGD2(WORD w), __REGD3(WORD h), __REGD4(ULONG color), __REGD5(UBYTE mask), __REGD7(RGBFTYPE format)); + static ULONG LibStart(void) { return(-1); } @@ -333,7 +336,7 @@ int InitCard(__REGA0(struct BoardInfo* b)) { //b->BlitPlanar2Chunky = (void *)NULL; //b->BlitPlanar2Direct = (void *)NULL; - //b->FillRect = (void *)NULL; + b->FillRect = (void *)FillRect; //b->InvertRect = (void *)NULL; //b->BlitRect = (void *)NULL; //b->BlitTemplate = (void *)NULL; @@ -396,8 +399,8 @@ BOOL SetSwitch (__REGA0(struct BoardInfo *b), __REGD0(BOOL enabled)) { setswitch = enabled; if (old_setswitch != enabled) { - //WRITEBYTE(RTG_U81, (unsigned char)enabled); - //WRITESHORT(RTG_COMMAND, RTGCMD_SETSWITCH); + WRITEBYTE(RTG_U81, (unsigned char)enabled); + WRITESHORT(RTG_COMMAND, RTGCMD_SETSWITCH); } return old_setswitch; @@ -516,3 +519,19 @@ void SetReadPlane (__REGA0(struct BoardInfo *b), __REGD0(UBYTE plane)) { void WaitVerticalSync (__REGA0(struct BoardInfo *b), __REGD0(BOOL toggle)) { // I don't know why this one has a bool in D0, but it isn't used for anything. } + +void FillRect (__REGA0(struct BoardInfo *b), __REGA1(struct RenderInfo *r), __REGD0(WORD x), __REGD1(WORD y), __REGD2(WORD w), __REGD3(WORD h), __REGD4(ULONG color), __REGD5(UBYTE mask), __REGD7(RGBFTYPE format)) { + if (!r) + return; + if (mask != 0xFF) + b->FillRectDefault(b, r, x, y, w, h, color, mask, format); + + WRITESHORT(RTG_FORMAT, rgbf_to_rtg[format]); + WRITESHORT(RTG_X1, x); + WRITESHORT(RTG_X2, w); + WRITESHORT(RTG_Y1, y); + WRITESHORT(RTG_Y2, h); + WRITELONG(RTG_RGB1, color); + WRITESHORT(RTG_X3, r->BytesPerRow); + WRITESHORT(RTG_COMMAND, RTGCMD_FILLRECT); +} \ No newline at end of file diff --git a/platforms/amiga/rtg/rtg_driver_amiga/pigfx020.card b/platforms/amiga/rtg/rtg_driver_amiga/pigfx020.card index 56b6775..a842ce6 100644 Binary files a/platforms/amiga/rtg/rtg_driver_amiga/pigfx020.card and b/platforms/amiga/rtg/rtg_driver_amiga/pigfx020.card differ diff --git a/platforms/amiga/rtg/rtg_driver_amiga/pigfx030.card b/platforms/amiga/rtg/rtg_driver_amiga/pigfx030.card index 56b6775..a842ce6 100644 Binary files a/platforms/amiga/rtg/rtg_driver_amiga/pigfx030.card and b/platforms/amiga/rtg/rtg_driver_amiga/pigfx030.card differ