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
22 #include "../shared/rtc.h"
23 #include "../../config_file/config_file.h"
25 #include "gayle-ide/ide.h"
26 #include "amiga-registers.h"
28 //#define GSTATUS 0xda201c
29 //#define GCLOW 0xda2010
30 //#define GDH 0xda2018
35 #define GERROR 0xda2004 // Error
36 #define GSTATUS 0xda201c // Status
38 #define GFEAT 0xda2004 // Write : Feature
39 #define GCMD 0xda201c // Write : Command
41 #define GDATA 0xda2000 // Data
42 #define GSECTCNT 0xda2008 // SectorCount
43 #define GSECTNUM 0xda200c // SectorNumber
44 #define GCYLLOW 0xda2010 // CylinderLow
45 #define GCYLHIGH 0xda2014 // CylinderHigh
46 #define GDEVHEAD 0xda2018 // Device/Head
47 #define GCTRL 0xda3018 // Control
49 #define GIDENT 0xDE1000
52 #define GCS 0xDA8000 // Card Control
53 #define GIRQ 0xDA9000 // IRQ
54 #define GINT 0xDAA000 // Int enable
55 #define GCONF 0xDAB000 // Gayle Config
58 #define GAYLE_CS_IDE 0x80 /* IDE int status */
59 #define GAYLE_CS_CCDET 0x40 /* credit card detect */
60 #define GAYLE_CS_BVD1 0x20 /* battery voltage detect 1 */
61 #define GAYLE_CS_SC 0x20 /* credit card status change */
62 #define GAYLE_CS_BVD2 0x10 /* battery voltage detect 2 */
63 #define GAYLE_CS_DA 0x10 /* digital audio */
64 #define GAYLE_CS_WR 0x08 /* write enable (1 == enabled) */
65 #define GAYLE_CS_BSY 0x04 /* credit card busy */
66 #define GAYLE_CS_IRQ 0x04 /* interrupt request */
67 #define GAYLE_CS_DAEN 0x02 /* enable digital audio */
68 #define GAYLE_CS_DIS 0x01 /* disable PCMCIA slot */
71 #define GAYLE_IRQ_IDE 0x80
72 #define GAYLE_IRQ_CCDET 0x40 /* credit card detect */
73 #define GAYLE_IRQ_BVD1 0x20 /* battery voltage detect 1 */
74 #define GAYLE_IRQ_SC 0x20 /* credit card status change */
75 #define GAYLE_IRQ_BVD2 0x10 /* battery voltage detect 2 */
76 #define GAYLE_IRQ_DA 0x10 /* digital audio */
77 #define GAYLE_IRQ_WR 0x08 /* write enable (1 == enabled) */
78 #define GAYLE_IRQ_BSY 0x04 /* credit card busy */
79 #define GAYLE_IRQ_IRQ 0x04 /* interrupt request */
80 #define GAYLE_IRQ_RESET 0x02 /* reset machine after CCDET change */
81 #define GAYLE_IRQ_BERR 0x01 /* generate bus error after CCDET change */
84 #define GAYLE_INT_IDE 0x80 /* IDE interrupt enable */
85 #define GAYLE_INT_CCDET 0x40 /* credit card detect change enable */
86 #define GAYLE_INT_BVD1 0x20 /* battery voltage detect 1 change enable */
87 #define GAYLE_INT_SC 0x20 /* credit card status change enable */
88 #define GAYLE_INT_BVD2 0x10 /* battery voltage detect 2 change enable */
89 #define GAYLE_INT_DA 0x10 /* digital audio change enable */
90 #define GAYLE_INT_WR 0x08 /* write enable change enabled */
91 #define GAYLE_INT_BSY 0x04 /* credit card busy */
92 #define GAYLE_INT_IRQ 0x04 /* credit card interrupt request */
93 #define GAYLE_INT_BVD_LEV 0x02 /* BVD int level, 0=lev2,1=lev6 */
94 #define GAYLE_INT_BSY_LEV 0x01 /* BSY int level, 0=lev2,1=lev6 */
97 static uint8_t gayle_irq, gayle_cs, gayle_cs_mask, gayle_cfg;
98 static struct ide_controller *ide0;
101 uint8_t rtc_type = RTC_TYPE_RICOH;
103 char *hdd_image_file[GAYLE_MAX_HARDFILES];
105 uint8_t cdtv_mode = 0;
106 unsigned char cdtv_sram[32 * SIZE_KILO];
110 struct ide_controller *get_ide(int index) {
115 void set_hard_drive_image_file_amiga(uint8_t index, char *filename) {
116 if (hdd_image_file[index] != NULL)
117 free(hdd_image_file[index]);
118 hdd_image_file[index] = calloc(1, strlen(filename) + 1);
119 strcpy(hdd_image_file[index], filename);
122 void InitGayle(void) {
123 if (!hdd_image_file[0]) {
124 hdd_image_file[0] = calloc(1, 64);
125 sprintf(hdd_image_file[0], "hd0.img");
128 ide0 = ide_allocate("cf");
129 fd = open(hdd_image_file[0], O_RDWR);
131 printf("HDD Image %s failed open\n", hdd_image_file[0]);
133 ide_attach(ide0, 0, fd);
134 ide_reset_begin(ide0);
135 printf("HDD Image %s attached\n", hdd_image_file[0]);
139 uint8_t CheckIrq(void) {
142 if (gayle_int & (1 << 7)) {
143 irq = ide0->drive->intrq;
145 // printf("IDE IRQ: %x\n",irq);
151 void writeGayleB(unsigned int address, unsigned int value) {
152 if (address == GFEAT) {
153 ide_write8(ide0, ide_feature_w, value);
156 if (address == GCMD) {
157 ide_write8(ide0, ide_command_w, value);
160 if (address == GSECTCNT) {
161 ide_write8(ide0, ide_sec_count, value);
164 if (address == GSECTNUM) {
165 ide_write8(ide0, ide_sec_num, value);
168 if (address == GCYLLOW) {
169 ide_write8(ide0, ide_cyl_low, value);
172 if (address == GCYLHIGH) {
173 ide_write8(ide0, ide_cyl_hi, value);
176 if (address == GDEVHEAD) {
177 ide_write8(ide0, ide_dev_head, value);
180 if (address == GCTRL) {
181 ide_write8(ide0, ide_devctrl_w, value);
185 if (address == GIDENT) {
187 // printf("Write Byte to Gayle Ident 0x%06x (0x%06x)\n",address,value);
191 if (address == GIRQ) {
192 // printf("Write Byte to Gayle GIRQ 0x%06x (0x%06x)\n",address,value);
193 gayle_irq = (gayle_irq & value) | (value & (GAYLE_IRQ_RESET | GAYLE_IRQ_BERR));
198 if (address == GCS) {
199 printf("Write Byte to Gayle GCS 0x%06x (0x%06x)\n", address, value);
200 gayle_cs_mask = value & ~3;
202 gayle_cs |= value & 3;
206 if (address == GINT) {
207 printf("Write Byte to Gayle GINT 0x%06x (0x%06x)\n", address, value);
212 if (address == GCONF) {
213 printf("Write Byte to Gayle GCONF 0x%06x (0x%06x)\n", address, value);
218 if ((address & GAYLEMASK) == CLOCKBASE) {
219 if ((address & CLOCKMASK) >= 0x8000) {
221 //printf("[CDTV] BYTE write to SRAM @%.8X (%.8X): %.2X\n", (address & CLOCKMASK) - 0x8000, address, value);
222 cdtv_sram[(address & CLOCKMASK) - 0x8000] = value;
226 //printf("Byte write to RTC.\n");
227 put_rtc_byte(address, value, rtc_type);
231 printf("Write Byte to Gayle Space 0x%06x (0x%06x)\n", address, value);
234 void writeGayle(unsigned int address, unsigned int value) {
235 if (address == GDATA) {
236 ide_write16(ide0, ide_data, value);
240 if ((address & GAYLEMASK) == CLOCKBASE) {
241 if ((address & CLOCKMASK) >= 0x8000) {
243 //printf("[CDTV] WORD write to SRAM @%.8X (%.8X): %.4X\n", (address & CLOCKMASK) - 0x8000, address, htobe16(value));
244 ((short *) ((size_t)(cdtv_sram + (address & CLOCKMASK) - 0x8000)))[0] = htobe16(value);
248 //printf("Word write to RTC.\n");
249 put_rtc_byte(address + 1, (value & 0xFF), rtc_type);
250 put_rtc_byte(address, (value >> 8), rtc_type);
254 printf("Write Word to Gayle Space 0x%06x (0x%06x)\n", address, value);
257 void writeGayleL(unsigned int address, unsigned int value) {
258 if ((address & GAYLEMASK) == CLOCKBASE) {
259 if ((address & CLOCKMASK) >= 0x8000) {
261 //printf("[CDTV] LONGWORD write to SRAM @%.8X (%.8X): %.8X\n", (address & CLOCKMASK) - 0x8000, address, htobe32(value));
262 ((int *) (size_t)(cdtv_sram + (address & CLOCKMASK) - 0x8000))[0] = htobe32(value);
266 //printf("Longword write to RTC.\n");
267 put_rtc_byte(address + 3, (value & 0xFF), rtc_type);
268 put_rtc_byte(address + 2, ((value & 0x0000FF00) >> 8), rtc_type);
269 put_rtc_byte(address + 1, ((value & 0x00FF0000) >> 16), rtc_type);
270 put_rtc_byte(address, (value >> 24), rtc_type);
274 printf("Write Long to Gayle Space 0x%06x (0x%06x)\n", address, value);
277 uint8_t readGayleB(unsigned int address) {
278 if (address == GERROR) {
279 return ide_read8(ide0, ide_error_r);
281 if (address == GSTATUS) {
282 return ide_read8(ide0, ide_status_r);
285 if (address == GSECTCNT) {
286 return ide_read8(ide0, ide_sec_count);
289 if (address == GSECTNUM) {
290 return ide_read8(ide0, ide_sec_num);
293 if (address == GCYLLOW) {
294 return ide_read8(ide0, ide_cyl_low);
297 if (address == GCYLHIGH) {
298 return ide_read8(ide0, ide_cyl_hi);
301 if (address == GDEVHEAD) {
302 return ide_read8(ide0, ide_dev_head);
305 if (address == GCTRL) {
306 return ide_read8(ide0, ide_altst_r);
309 if ((address & GAYLEMASK) == CLOCKBASE) {
310 if ((address & CLOCKMASK) >= 0x8000) {
312 //printf("[CDTV] BYTE read from SRAM @%.8X (%.8X): %.2X\n", (address & CLOCKMASK) - 0x8000, address, cdtv_sram[(address & CLOCKMASK) - 0x8000]);
313 return cdtv_sram[(address & CLOCKMASK) - 0x8000];
317 //printf("Byte read from RTC.\n");
318 return get_rtc_byte(address, rtc_type);
321 if (address == GIDENT) {
323 // printf("Read Byte from Gayle Ident 0x%06x (0x%06x)\n",address,counter);
324 if (counter == 0 || counter == 1 || counter == 3) {
325 val = 0x80; // 80; to enable gayle
333 if (address == GIRQ) {
334 // printf("Read Byte From GIRQ Space 0x%06x\n",gayle_irq);
336 return 0x80;//gayle_irq;
339 irq = ide0->drive->intrq;
342 // printf("IDE IRQ: %x\n",irq);
343 return 0x80; // gayle_irq;
350 if (address == GCS) {
351 printf("Read Byte From GCS Space 0x%06x\n", 0x1234);
353 v = gayle_cs_mask | gayle_cs;
357 if (address == GINT) {
358 // printf("Read Byte From GINT Space 0x%06x\n",gayle_int);
362 if (address == GCONF) {
363 printf("Read Byte From GCONF Space 0x%06x\n", gayle_cfg & 0x0f);
364 return gayle_cfg & 0x0f;
367 printf("Read Byte From Gayle Space 0x%06x\n", address);
371 uint16_t readGayle(unsigned int address) {
372 if (address == GDATA) {
374 value = ide_read16(ide0, ide_data);
375 // value = (value << 8) | (value >> 8);
379 if ((address & GAYLEMASK) == CLOCKBASE) {
380 if ((address & CLOCKMASK) >= 0x8000) {
382 //printf("[CDTV] WORD read from SRAM @%.8X (%.8X): %.4X\n", (address & CLOCKMASK) - 0x8000, address, be16toh( (( unsigned short *) (size_t)(cdtv_sram + (address & CLOCKMASK) - 0x8000))[0]));
383 return be16toh( (( unsigned short *) (size_t)(cdtv_sram + (address & CLOCKMASK) - 0x8000))[0]);
387 //printf("Word read from RTC.\n");
388 return ((get_rtc_byte(address, rtc_type) << 8) | (get_rtc_byte(address + 1, rtc_type)));
391 printf("Read Word From Gayle Space 0x%06x\n", address);
395 uint32_t readGayleL(unsigned int address) {
396 if ((address & GAYLEMASK) == CLOCKBASE) {
397 if ((address & CLOCKMASK) >= 0x8000) {
399 //printf("[CDTV] LONGWORD read from SRAM @%.8X (%.8X): %.8X\n", (address & CLOCKMASK) - 0x8000, address, be32toh( (( unsigned short *) (size_t)(cdtv_sram + (address & CLOCKMASK) - 0x8000))[0]));
400 return be32toh( (( unsigned int *) (size_t)(cdtv_sram + (address & CLOCKMASK) - 0x8000))[0]);
404 //printf("Longword read from RTC.\n");
405 return ((get_rtc_byte(address, rtc_type) << 24) | (get_rtc_byte(address + 1, rtc_type) << 16) | (get_rtc_byte(address + 2, rtc_type) << 8) | (get_rtc_byte(address + 3, rtc_type)));
408 printf("Read Long From Gayle Space 0x%06x\n", address);