]> git.sesse.net Git - pistorm/commitdiff
Dysfunctional SDL2 RTG output
authorbeeanyew <beeanyew@gmail.com>
Tue, 5 Jan 2021 02:01:12 +0000 (03:01 +0100)
committerbeeanyew <beeanyew@gmail.com>
Tue, 5 Jan 2021 02:01:12 +0000 (03:01 +0100)
13 files changed:
Makefile
emulator.c
platforms/amiga/Gayle.c
platforms/amiga/Gayle.h
platforms/amiga/amiga-platform.c
platforms/amiga/amiga-registers.h
platforms/amiga/rtg/rtg-output.c [new file with mode: 0644]
platforms/amiga/rtg/rtg.c
platforms/amiga/rtg/rtg.h
platforms/amiga/rtg/rtg_driver_amiga/build.bat [new file with mode: 0644]
platforms/amiga/rtg/rtg_driver_amiga/pigfx.c
platforms/amiga/rtg/rtg_driver_amiga/pigfx020.card
platforms/amiga/rtg/rtg_driver_amiga/pigfx030.card

index edb8135615efd6fe461467e967138224c5d2ee3c..3ac9fba365cc2911adf7ea92afdb24434e0e2060 100644 (file)
--- 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)
 
index f9c1295e5c133bf4ba097abf3cc6d79a9c49c7f3..c6bf30cbcd3717ebe8dd3a38480080f729070ba3 100644 (file)
@@ -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");
index 1bbba361bb929f6af15b3290170f067d405f4cde..39f552ff626eb19a970950a74640164c3b98c99f 100644 (file)
 //#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) {
index 2bcb9c3cd5a4a6bd5f23366ff1544762179f00e7..69e65b421860790895463f360cb6ff06db07b0a1 100644 (file)
@@ -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 */
index acdb4245e0631174c782cc2a68448fd5a39cd3bc..8a36cc64cacefe02c339208c63d374ed0eaf84ac 100644 (file)
@@ -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]);
+        }
     }
 }
index fb6e2858e9834828065fbfdf22fef2f009538d22..78042e76ba7d68b8cb1992838a2ea3b9fc28f375 100644 (file)
@@ -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 (file)
index 0000000..3b8ddb7
--- /dev/null
@@ -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);
+}
index e26cabfbc040a85cd43216f1de93a917b60973a4..4fce959f0c86a4202b454b66c1eb6d9b65b0852c 100644 (file)
@@ -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;
     }
 }
index c90276dcc520d9cffb54dd343f4cf9a6d40703d3..0265e1a7291b3d58ef243fde88e7a971123a1932 100644 (file)
@@ -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 (file)
index 0000000..1c6688e
--- /dev/null
@@ -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
index 88aae6c4fee1778cc6698495b7f94cb7c69bd4cf..05d010867b7f40efc71786a3e15c2419f4284870 100644 (file)
@@ -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
index 56b677546ba031c3f795376907d4d45497a91c8c..a842ce6798c2461545afaf4c4ca7f5fd26011175 100644 (file)
Binary files a/platforms/amiga/rtg/rtg_driver_amiga/pigfx020.card and b/platforms/amiga/rtg/rtg_driver_amiga/pigfx020.card differ
index 56b677546ba031c3f795376907d4d45497a91c8c..a842ce6798c2461545afaf4c4ca7f5fd26011175 100644 (file)
Binary files a/platforms/amiga/rtg/rtg_driver_amiga/pigfx030.card and b/platforms/amiga/rtg/rtg_driver_amiga/pigfx030.card differ