mirror of
https://github.com/captain-amygdala/pistorm.git
synced 2026-04-28 12:48:00 +00:00
Dysfunctional SDL2 RTG output
This commit is contained in:
3
Makefile
3
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)
|
||||
|
||||
|
||||
17
emulator.c
17
emulator.c
@@ -14,6 +14,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <SDL2/SDL.h>
|
||||
#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");
|
||||
|
||||
@@ -29,69 +29,12 @@
|
||||
//#define GCLOW 0xda2010
|
||||
//#define GDH 0xda2018
|
||||
|
||||
// Gayle Addresses
|
||||
uint8_t gary_cfg[8];
|
||||
|
||||
// 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 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;
|
||||
}
|
||||
|
||||
static uint8_t ide_action = 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);
|
||||
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 == 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;
|
||||
}
|
||||
|
||||
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;
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
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:;
|
||||
}
|
||||
|
||||
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);
|
||||
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) {
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
139
platforms/amiga/rtg/rtg-output.c
Normal file
139
platforms/amiga/rtg/rtg-output.c
Normal file
@@ -0,0 +1,139 @@
|
||||
#include <SDL2/SDL.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
@@ -1,11 +1,13 @@
|
||||
#include <stdint.h>
|
||||
#include <endian.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
2
platforms/amiga/rtg/rtg_driver_amiga/build.bat
Normal file
2
platforms/amiga/rtg/rtg_driver_amiga/build.bat
Normal file
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user