5 // Created by Matt Parsons on 06/03/2019.
6 // Copyright © 2019 Matt Parsons. All rights reserved.
9 // Write Byte to Gayle Space 0xda9000 (0x0000c3)
10 // Read Byte From Gayle Space 0xda9000
11 // Read Byte From Gayle Space 0xdaa000
20 #include "platforms/amiga/amiga-registers.h"
23 //#define GSTATUS 0xda201c
24 //#define GCLOW 0xda2010
25 //#define GDH 0xda2018
28 //#define GAYLE_IDE_BASE_A1200 0xDA0000 //8 bit base
29 #define GAYLE_IDE_BASE_A1200 0xDA2000 //16bit base
30 #define GAYLE_IDE_BASE_A4000 0xDD2020
33 #define GERROR 0xda2004 // Error
34 #define GSTATUS 0xda201C // Status
35 #define GERROR_A4000 GAYLE_IDE_BASE_A4000 + 0x06 // Error
36 #define GSTATUS_A4000 GAYLE_IDE_BASE_A4000 + 0x1E // Status
39 #define GFEAT 0xda2004 // Write : Feature
40 #define GCMD 0xda201c // Write : Command
41 #define GFEAT_A4000 GAYLE_IDE_BASE_A4000 + 0x06 // Write : Feature
42 #define GCMD_A4000 GAYLE_IDE_BASE_A4000 + 0x1E // Write : Command
43 #define GMODEREG0_A4000 0x0DD1020 // D31, PIO modes (00,01,10)
44 #define GMODEREG1_A4000 0x0DD1022 // D31, (MSB)
47 #define GDATA 0xda2000 // Data - 16 bit
48 #define GSECTCNT 0xda2008 // SectorCount
49 #define GSECTNUM 0xda200c // SectorNumber
50 #define GCYLLOW 0xda2010 // CylinderLow
51 #define GCYLHIGH 0xda2014 // CylinderHigh
52 #define GDEVHEAD 0xda2018 // Device/Head
53 #define GCTRL 0xda3018 // Control
55 #define GDATA_A4000 GAYLE_IDE_BASE_A4000 // Data
56 #define GSECTCNT_A4000 GAYLE_IDE_BASE_A4000 + 0x0a // SectorCount
57 #define GSECTNUM_A4000 GAYLE_IDE_BASE_A4000 + 0x0e // SectorNumber
58 #define GCYLLOW_A4000 GAYLE_IDE_BASE_A4000 + 0x12 // CylinderLow
59 #define GCYLHIGH_A4000 GAYLE_IDE_BASE_A4000 + 0x16 // CylinderHigh
60 #define GDEVHEAD_A4000 GAYLE_IDE_BASE_A4000 + 0x1a // Device/Head
61 #define GCTRL_A4000 GAYLE_IDE_BASE_A4000 + 0x101a // Control
64 #define GIDENT 0xDE1000
67 #define GCS 0xDA8000 // Card Control
68 #define GIRQ 0xDA9000 // IRQ
69 #define GINT 0xDAA000 // Int enable
70 #define GCONF 0xDAB000 // Gayle Config
72 // For A4000 there's no need to populate other areas, just GIRQ
73 #define GIRQ_A4000 GAYLE_IDE_BASE_A4000 + 0x1000 // IRQ 0xDD3020
76 #define GAYLE_CS_IDE 0x80 /* IDE int status */
77 #define GAYLE_CS_CCDET 0x40 /* credit card detect */
78 #define GAYLE_CS_BVD1 0x20 /* battery voltage detect 1 */
79 #define GAYLE_CS_SC 0x20 /* credit card status change */
80 #define GAYLE_CS_BVD2 0x10 /* battery voltage detect 2 */
81 #define GAYLE_CS_DA 0x10 /* digital audio */
82 #define GAYLE_CS_WR 0x08 /* write enable (1 == enabled) */
83 #define GAYLE_CS_BSY 0x04 /* credit card busy */
84 #define GAYLE_CS_IRQ 0x04 /* interrupt request */
85 #define GAYLE_CS_DAEN 0x02 /* enable digital audio */
86 #define GAYLE_CS_DIS 0x01 /* disable PCMCIA slot */
89 #define GAYLE_IRQ_IDE 0x80
90 #define GAYLE_IRQ_CCDET 0x40 /* credit card detect */
91 #define GAYLE_IRQ_BVD1 0x20 /* battery voltage detect 1 */
92 #define GAYLE_IRQ_SC 0x20 /* credit card status change */
93 #define GAYLE_IRQ_BVD2 0x10 /* battery voltage detect 2 */
94 #define GAYLE_IRQ_DA 0x10 /* digital audio */
95 #define GAYLE_IRQ_WR 0x08 /* write enable (1 == enabled) */
96 #define GAYLE_IRQ_BSY 0x04 /* credit card busy */
97 #define GAYLE_IRQ_IRQ 0x04 /* interrupt request */
98 #define GAYLE_IRQ_RESET 0x02 /* reset machine after CCDET change */
99 #define GAYLE_IRQ_BERR 0x01 /* generate bus error after CCDET change */
102 #define GAYLE_INT_IDE 0x80 /* IDE interrupt enable */
103 #define GAYLE_INT_CCDET 0x40 /* credit card detect change enable */
104 #define GAYLE_INT_BVD1 0x20 /* battery voltage detect 1 change enable */
105 #define GAYLE_INT_SC 0x20 /* credit card status change enable */
106 #define GAYLE_INT_BVD2 0x10 /* battery voltage detect 2 change enable */
107 #define GAYLE_INT_DA 0x10 /* digital audio change enable */
108 #define GAYLE_INT_WR 0x08 /* write enable change enabled */
109 #define GAYLE_INT_BSY 0x04 /* credit card busy */
110 #define GAYLE_INT_IRQ 0x04 /* credit card interrupt request */
111 #define GAYLE_INT_BVD_LEV 0x02 /* BVD int level, 0=lev2,1=lev6 */
112 #define GAYLE_INT_BSY_LEV 0x01 /* BSY int level, 0=lev2,1=lev6 */
114 #define GAYLE_MAX_HARDFILES 8
117 static uint8_t gayle_irq, gayle_int, gayle_cs, gayle_cs_mask, gayle_cfg;
118 static struct ide_controller *ide0;
121 uint8_t gary_cfg0 = 0x00;
122 uint8_t gary_cfg1 = 0x00;
123 uint8_t gary_cfg2 = 0x00;
124 uint8_t gary_cfg3 = 0x00;
125 uint8_t gary_cfg4 = 0x00;
126 uint8_t gary_cfg5 = 0x00;
128 uint8_t gayle_a4k = 0xA0;
129 uint16_t gayle_a4k_irq;
130 uint8_t ramsey_cfg = 0x08;
131 static uint8_t ramsey_id = RAMSEY_REV7;
133 char *hdd_image_file[GAYLE_MAX_HARDFILES];
135 void set_hard_drive_image_file_amiga(uint8_t index, char *filename) {
136 if (hdd_image_file[index] != NULL)
137 free(hdd_image_file[index]);
138 hdd_image_file[index] = calloc(1, strlen(filename) + 1);
139 strcpy(hdd_image_file[index], filename);
142 void InitGayle(void) {
143 if (!hdd_image_file[0]) {
144 hdd_image_file[0] = calloc(1, 64);
145 sprintf(hdd_image_file[0], "hd0.img");
148 ide0 = ide_allocate("cf");
149 fd = open(hdd_image_file[0], O_RDWR);
151 printf("HDD Image %s failed open\n", hdd_image_file[0]);
153 ide_attach(ide0, 0, fd);
154 ide_reset_begin(ide0);
155 printf("HDD Image %s attached\n", hdd_image_file[0]);
159 uint8_t CheckIrq(void) {
161 /* skipping gayle_int check makes A4000 ROMs IDE work at decent speed */
162 irq = ide0->drive->intrq;
166 void writeGayleB(unsigned int address, unsigned int value) {
167 if (address == GFEAT || address == GFEAT_A4000) {
168 ide_write8(ide0, ide_feature_w, value);
171 if (address == GCMD || address == GCMD_A4000) {
172 ide_write8(ide0, ide_command_w, value);
175 if (address == GSECTCNT || address == GSECTCNT_A4000) {
176 ide_write8(ide0, ide_sec_count, value);
179 if (address == GSECTNUM || address == GSECTNUM_A4000) {
180 ide_write8(ide0, ide_sec_num, value);
183 if (address == GCYLLOW || address == GCYLLOW_A4000) {
184 ide_write8(ide0, ide_cyl_low, value);
187 if (address == GCYLHIGH || address == GCYLHIGH_A4000) {
188 ide_write8(ide0, ide_cyl_hi, value);
191 if (address == GDEVHEAD || address == GDEVHEAD_A4000) {
192 ide_write8(ide0, ide_dev_head, value);
195 if (address == GCTRL || address == GCTRL_A4000) {
196 ide_write8(ide0, ide_devctrl_w, value);
200 if (address == GIDENT) {
202 printf("Write Byte to Gayle Ident 0x%06x (0x%06x)\n",address,value);
206 if (address == 0xDD203A) {
207 printf("Write Byte to 0xDD203A Gayle 0x%06x (0x%06x)\n",address,value);
212 if (address == GIRQ || address == GIRQ_A4000) {
213 //printf("Write Byte to Gayle GIRQ 0x%06x (0x%06x)\n",address,value);
214 gayle_irq = (gayle_irq & value) & (value & (GAYLE_IRQ_RESET | GAYLE_IRQ_BERR));
218 if (address == GCS) {
219 printf("Write Byte to Gayle GCS 0x%06x (0x%06x)\n", address, value);
220 gayle_cs_mask = value & ~3;
222 gayle_cs |= value & 3;
226 if (address == GINT) {
227 printf("Write Byte to Gayle GINT 0x%06x (0x%06x)\n", address, value);
232 if (address == GCONF) {
233 printf("Write Byte to Gayle GCONF 0x%06x (0x%06x)\n", address, value);
238 if (address == RAMSEY_REG) {
239 printf("Write Byte to RAMSEY_REG Space 0x%06x (0x%06x)\n", address, value);
240 ramsey_cfg = value & 0x0f;
244 printf("Write Byte to Gayle Space 0x%06x (0x%06x)\n", address, value);
247 void writeGayle(unsigned int address, unsigned int value) {
248 if (address == GDATA || address == GDATA_A4000) {
249 ide_write16(ide0, ide_data, value);
253 if (address == GIRQ_A4000) {
254 gayle_a4k_irq = value;
258 printf("Write Word to Gayle Space 0x%06x (0x%06x)\n", address, value);
261 void writeGayleL(unsigned int address, unsigned int value) {
262 printf("Write Long to Gayle Space 0x%06x (0x%06x)\n", address, value);
265 uint8_t readGayleB(unsigned int address) {
266 if (address == GERROR || address == GERROR_A4000) {
267 return ide_read8(ide0, ide_error_r);
269 if (address == GSTATUS || address == GSTATUS_A4000) {
270 return ide_read8(ide0, ide_status_r);
273 if (address == GSECTCNT || address == GSECTCNT_A4000) {
274 return ide_read8(ide0, ide_sec_count);
277 if (address == GSECTNUM || address == GSECTNUM_A4000) {
278 return ide_read8(ide0, ide_sec_num);
281 if (address == GCYLLOW || address == GCYLLOW_A4000) {
282 return ide_read8(ide0, ide_cyl_low);
285 if (address == GCYLHIGH || address == GCYLHIGH_A4000) {
286 return ide_read8(ide0, ide_cyl_hi);
289 if (address == GDEVHEAD || address == GDEVHEAD_A4000) {
290 return ide_read8(ide0, ide_dev_head);
293 if (address == GCTRL || address == GCTRL_A4000) {
294 return ide_read8(ide0, ide_altst_r);
297 if (address == 0xDD203A) {
298 printf("Write Byte to 0xDD203A Gayle 0x%06x (0x%06x)\n",address, gayle_a4k);
302 if (address == GIDENT) {
304 // printf("Read Byte from Gayle Ident 0x%06x (0x%06x)\n",address,counter);
305 if (counter == 0 || counter == 1 || counter == 3) {
306 val = 0x80; // 80; to enable gayle
314 if (address == GARY_REG5) {
316 printf("Read Byte from GARY Ident 0x%06x (0x%06x)\n",address,counter);
317 if (counter == 0 || counter == 1 || counter == 3) {
318 val = 0x80; // 80; to enable GARY
327 if (address == GIRQ || address == GIRQ_A4000) {
328 //printf("Read Byte From GIRQ Space 0x%06x\n",gayle_irq);
329 return 0x80;//gayle_irq;
332 irq = ide0->drive->intrq;
335 // printf("IDE IRQ: %x\n",irq);
336 return 0x80; // gayle_irq;
343 if (address == GCS) {
344 printf("Read Byte From GCS Space 0x%06x\n", 0x1234);
346 v = gayle_cs_mask | gayle_cs;
350 if (address == GINT) {
351 printf("Read Byte From GINT Space 0x%06x\n",gayle_int);
355 if (address == GCONF) {
356 printf("Read Byte From GCONF Space 0x%06x\n", gayle_cfg & 0x0f);
357 return gayle_cfg & 0x0f;
360 if (address == GARY_REG0) {
361 printf("Read Byte From GARY_REG Space 0x%06x (0x%06x)\n", address, gary_cfg0 & 0x80);
364 if (address == GARY_REG1) {
365 printf("Read Byte From GARY_REG Space 0x%06x (0x%06x)\n", address, gary_cfg1 & 0x80);
368 if (address == GARY_REG2) {
369 printf("Read Byte From GARY_REG Space 0x%06x (0x%06x)\n", address, gary_cfg2 & 0x80);
372 if (address == GARY_REG3) {
373 printf("Read Byte From GARY_REG Space 0x%06x (0x%06x)\n", address, gary_cfg3 & 0x80);
376 if (address == GARY_REG4) {
377 printf("Read Byte From GARY_REG Space 0x%06x (0x%06x)\n", address, gary_cfg4 & 0x80);
380 if (address == GARY_REG5) {
381 printf("Read Byte From GARY_REG Space 0x%06x (0x%06x)\n", address, gary_cfg5 & 0x80);
385 if (address == RAMSEY_REG) {
386 printf("Read Byte From RAMSEY_REG Space 0x%06x (0x%06x)\n", address, ramsey_cfg & 0x0f);
390 if (address == RAMSEY_ID) {
391 printf("Read Byte From RAMSEY_ID Space 0x%06x (0x%06x)\n", address, ramsey_id & 0x0f);
395 printf("Read Byte From Gayle Space 0x%06x\n", address);
399 uint16_t readGayle(unsigned int address) {
400 if (address == GDATA || address == GDATA_A4000) {
402 value = ide_read16(ide0, ide_data);
403 // value = (value << 8) | (value >> 8);
406 if (address == GIRQ_A4000) {
407 //printf("Read Word From GIRQ_A4000 Space 0x%06x\n", address);
408 gayle_a4k_irq = 0x8000;
411 printf("Read Word From Gayle Space 0x%06x\n", address);
415 uint32_t readGayleL(unsigned int address) {
416 printf("Read Long From Gayle Space 0x%06x\n", address);