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
21 //#define GSTATUS 0xda201c
22 //#define GCLOW 0xda2010
23 //#define GDH 0xda2018
28 #define GERROR 0xda2004 // Error
29 #define GSTATUS 0xda201c // Status
31 #define GFEAT 0xda2004 // Write : Feature
32 #define GCMD 0xda201c // Write : Command
34 #define GDATA 0xda2000 // Data
35 #define GSECTCNT 0xda2008 // SectorCount
36 #define GSECTNUM 0xda200c // SectorNumber
37 #define GCYLLOW 0xda2010 // CylinderLow
38 #define GCYLHIGH 0xda2014 // CylinderHigh
39 #define GDEVHEAD 0xda2018 // Device/Head
40 #define GCTRL 0xda3018 // Control
42 #define GIDENT 0xDE1000
45 #define GCS 0xDA8000 // Card Control
46 #define GIRQ 0xDA9000 // IRQ
47 #define GINT 0xDAA000 // Int enable
48 #define GCONF 0xDAB00 // Gayle Config
51 #define GAYLE_CS_IDE 0x80 /* IDE int status */
52 #define GAYLE_CS_CCDET 0x40 /* credit card detect */
53 #define GAYLE_CS_BVD1 0x20 /* battery voltage detect 1 */
54 #define GAYLE_CS_SC 0x20 /* credit card status change */
55 #define GAYLE_CS_BVD2 0x10 /* battery voltage detect 2 */
56 #define GAYLE_CS_DA 0x10 /* digital audio */
57 #define GAYLE_CS_WR 0x08 /* write enable (1 == enabled) */
58 #define GAYLE_CS_BSY 0x04 /* credit card busy */
59 #define GAYLE_CS_IRQ 0x04 /* interrupt request */
60 #define GAYLE_CS_DAEN 0x02 /* enable digital audio */
61 #define GAYLE_CS_DIS 0x01 /* disable PCMCIA slot */
64 #define GAYLE_IRQ_IDE 0x80
65 #define GAYLE_IRQ_CCDET 0x40 /* credit card detect */
66 #define GAYLE_IRQ_BVD1 0x20 /* battery voltage detect 1 */
67 #define GAYLE_IRQ_SC 0x20 /* credit card status change */
68 #define GAYLE_IRQ_BVD2 0x10 /* battery voltage detect 2 */
69 #define GAYLE_IRQ_DA 0x10 /* digital audio */
70 #define GAYLE_IRQ_WR 0x08 /* write enable (1 == enabled) */
71 #define GAYLE_IRQ_BSY 0x04 /* credit card busy */
72 #define GAYLE_IRQ_IRQ 0x04 /* interrupt request */
73 #define GAYLE_IRQ_RESET 0x02 /* reset machine after CCDET change */
74 #define GAYLE_IRQ_BERR 0x01 /* generate bus error after CCDET change */
77 #define GAYLE_INT_IDE 0x80 /* IDE interrupt enable */
78 #define GAYLE_INT_CCDET 0x40 /* credit card detect change enable */
79 #define GAYLE_INT_BVD1 0x20 /* battery voltage detect 1 change enable */
80 #define GAYLE_INT_SC 0x20 /* credit card status change enable */
81 #define GAYLE_INT_BVD2 0x10 /* battery voltage detect 2 change enable */
82 #define GAYLE_INT_DA 0x10 /* digital audio change enable */
83 #define GAYLE_INT_WR 0x08 /* write enable change enabled */
84 #define GAYLE_INT_BSY 0x04 /* credit card busy */
85 #define GAYLE_INT_IRQ 0x04 /* credit card interrupt request */
86 #define GAYLE_INT_BVD_LEV 0x02 /* BVD int level, 0=lev2,1=lev6 */
87 #define GAYLE_INT_BSY_LEV 0x01 /* BSY int level, 0=lev2,1=lev6 */
89 #define GAYLE_MAX_HARDFILES 8
92 static uint8_t gayle_irq, gayle_int, gayle_cs, gayle_cs_mask, gayle_cfg;
93 static struct ide_controller *ide0;
96 char *hdd_image_file[GAYLE_MAX_HARDFILES];
98 void set_hard_drive_image_file_amiga(uint8_t index, char *filename) {
99 if (hdd_image_file[index] != NULL)
100 free(hdd_image_file[index]);
101 hdd_image_file[index] = calloc(1, strlen(filename) + 1);
102 strcpy(hdd_image_file[index], filename);
105 void InitGayle(void) {
106 if (!hdd_image_file[0]) {
107 hdd_image_file[0] = calloc(1, 64);
108 sprintf(hdd_image_file[0], "hd0.img");
111 ide0 = ide_allocate("cf");
112 fd = open(hdd_image_file[0], O_RDWR);
114 printf("HDD Image %s failed open\n", hdd_image_file[0]);
116 ide_attach(ide0, 0, fd);
117 ide_reset_begin(ide0);
118 printf("HDD Image %s attached\n", hdd_image_file[0]);
122 uint8_t CheckIrq(void) {
125 if (gayle_int & (1 << 7)) {
126 irq = ide0->drive->intrq;
128 // printf("IDE IRQ: %x\n",irq);
134 void writeGayleB(unsigned int address, unsigned int value) {
135 if (address == GFEAT) {
136 ide_write8(ide0, ide_feature_w, value);
139 if (address == GCMD) {
140 ide_write8(ide0, ide_command_w, value);
143 if (address == GSECTCNT) {
144 ide_write8(ide0, ide_sec_count, value);
147 if (address == GSECTNUM) {
148 ide_write8(ide0, ide_sec_num, value);
151 if (address == GCYLLOW) {
152 ide_write8(ide0, ide_cyl_low, value);
155 if (address == GCYLHIGH) {
156 ide_write8(ide0, ide_cyl_hi, value);
159 if (address == GDEVHEAD) {
160 ide_write8(ide0, ide_dev_head, value);
163 if (address == GCTRL) {
164 ide_write8(ide0, ide_devctrl_w, value);
168 if (address == GIDENT) {
170 // printf("Write Byte to Gayle Ident 0x%06x (0x%06x)\n",address,value);
174 if (address == GIRQ) {
175 // printf("Write Byte to Gayle GIRQ 0x%06x (0x%06x)\n",address,value);
176 gayle_irq = (gayle_irq & value) | (value & (GAYLE_IRQ_RESET | GAYLE_IRQ_BERR));
181 if (address == GCS) {
182 printf("Write Byte to Gayle GCS 0x%06x (0x%06x)\n", address, value);
183 gayle_cs_mask = value & ~3;
185 gayle_cs |= value & 3;
189 if (address == GINT) {
190 printf("Write Byte to Gayle GINT 0x%06x (0x%06x)\n", address, value);
195 if (address == GCONF) {
196 printf("Write Byte to Gayle GCONF 0x%06x (0x%06x)\n", address, value);
201 printf("Write Byte to Gayle Space 0x%06x (0x%06x)\n", address, value);
204 void writeGayle(unsigned int address, unsigned int value) {
205 if (address == GDATA) {
206 ide_write16(ide0, ide_data, value);
210 printf("Write Word to Gayle Space 0x%06x (0x%06x)\n", address, value);
213 void writeGayleL(unsigned int address, unsigned int value) {
214 printf("Write Long to Gayle Space 0x%06x (0x%06x)\n", address, value);
217 uint8_t readGayleB(unsigned int address) {
218 if (address == GERROR) {
219 return ide_read8(ide0, ide_error_r);
221 if (address == GSTATUS) {
222 return ide_read8(ide0, ide_status_r);
225 if (address == GSECTCNT) {
226 return ide_read8(ide0, ide_sec_count);
229 if (address == GSECTNUM) {
230 return ide_read8(ide0, ide_sec_num);
233 if (address == GCYLLOW) {
234 return ide_read8(ide0, ide_cyl_low);
237 if (address == GCYLHIGH) {
238 return ide_read8(ide0, ide_cyl_hi);
241 if (address == GDEVHEAD) {
242 return ide_read8(ide0, ide_dev_head);
245 if (address == GCTRL) {
246 return ide_read8(ide0, ide_altst_r);
249 if (address == GIDENT) {
251 // printf("Read Byte from Gayle Ident 0x%06x (0x%06x)\n",address,counter);
252 if (counter == 0 || counter == 1 || counter == 3) {
253 val = 0x80; // 80; to enable gayle
261 if (address == GIRQ) {
262 // printf("Read Byte From GIRQ Space 0x%06x\n",gayle_irq);
264 return 0x80;//gayle_irq;
267 irq = ide0->drive->intrq;
270 // printf("IDE IRQ: %x\n",irq);
271 return 0x80; // gayle_irq;
278 if (address == GCS) {
279 printf("Read Byte From GCS Space 0x%06x\n", 0x1234);
281 v = gayle_cs_mask | gayle_cs;
285 if (address == GINT) {
286 // printf("Read Byte From GINT Space 0x%06x\n",gayle_int);
290 if (address == GCONF) {
291 printf("Read Byte From GCONF Space 0x%06x\n", gayle_cfg & 0x0f);
292 return gayle_cfg & 0x0f;
295 printf("Read Byte From Gayle Space 0x%06x\n", address);
299 uint16_t readGayle(unsigned int address) {
300 if (address == GDATA) {
302 value = ide_read16(ide0, ide_data);
303 // value = (value << 8) | (value >> 8);
307 printf("Read Word From Gayle Space 0x%06x\n", address);
311 uint32_t readGayleL(unsigned int address) {
312 printf("Read Long From Gayle Space 0x%06x\n", address);