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
34 uint8_t gayle_a4k = 0xA0;
35 uint16_t gayle_a4k_irq;
36 uint8_t ramsey_cfg = 0x08;
37 static uint8_t ramsey_id = RAMSEY_REV7;
40 static uint8_t gayle_irq, gayle_cs, gayle_cs_mask, gayle_cfg;
41 static struct ide_controller *ide0;
44 uint8_t rtc_type = RTC_TYPE_RICOH;
46 char *hdd_image_file[GAYLE_MAX_HARDFILES];
48 uint8_t cdtv_mode = 0;
49 unsigned char cdtv_sram[32 * SIZE_KILO];
53 uint32_t gayle_ide_mask = ~GDATA;
54 uint32_t gayle_ide_base = GDATA;
55 uint8_t gayle_ide_adj = 0;
57 struct ide_controller *get_ide(int index) {
62 void adjust_gayle_4000() {
63 gayle_ide_base = GDATA_A4000;
67 void adjust_gayle_1200() {
71 void set_hard_drive_image_file_amiga(uint8_t index, char *filename) {
72 if (hdd_image_file[index] != NULL)
73 free(hdd_image_file[index]);
74 hdd_image_file[index] = calloc(1, strlen(filename) + 1);
75 strcpy(hdd_image_file[index], filename);
78 void InitGayle(void) {
79 if (!hdd_image_file[0]) {
80 hdd_image_file[0] = calloc(1, 64);
81 sprintf(hdd_image_file[0], "hd0.img");
84 ide0 = ide_allocate("cf");
85 fd = open(hdd_image_file[0], O_RDWR);
87 printf("HDD Image %s failed open\n", hdd_image_file[0]);
89 ide_attach(ide0, 0, fd);
90 ide_reset_begin(ide0);
91 printf("HDD Image %s attached\n", hdd_image_file[0]);
95 uint8_t CheckIrq(void) {
98 if (gayle_int & (1 << 7)) {
99 irq = ide0->drive->intrq;
101 // printf("IDE IRQ: %x\n",irq);
107 static uint8_t ide_action = 0;
109 void writeGayleB(unsigned int address, unsigned int value) {
110 if (address >= gayle_ide_base) {
111 switch (address - gayle_ide_base + gayle_ide_adj) {
113 ide_action = ide_feature_w;
116 ide_action = ide_command_w;
118 case GSECTCOUNT_OFFSET:
119 ide_action = ide_sec_count;
121 case GSECTNUM_OFFSET:
122 ide_action = ide_sec_num;
125 ide_action = ide_cyl_low;
127 case GCYLHIGH_OFFSET:
128 ide_action = ide_cyl_hi;
130 case GDEVHEAD_OFFSET:
131 ide_action = ide_dev_head;
134 ide_action = ide_devctrl_w;
136 case GIRQ_4000_OFFSET:
137 gayle_a4k_irq = value;
139 gayle_irq = (gayle_irq & value) | (value & (GAYLE_IRQ_RESET | GAYLE_IRQ_BERR));
144 ide_write8(ide0, ide_action, value);
160 ramsey_cfg = value & 0x0F;
166 gayle_cs_mask = value & ~3;
168 gayle_cs |= value & 3;
172 if ((address & GAYLEMASK) == CLOCKBASE) {
173 if ((address & CLOCKMASK) >= 0x8000) {
175 //printf("[CDTV] BYTE write to SRAM @%.8X (%.8X): %.2X\n", (address & CLOCKMASK) - 0x8000, address, value);
176 cdtv_sram[(address & CLOCKMASK) - 0x8000] = value;
180 //printf("Byte write to RTC.\n");
181 put_rtc_byte(address, value, rtc_type);
185 printf("Write Byte to Gayle Space 0x%06x (0x%06x)\n", address, value);
188 void writeGayle(unsigned int address, unsigned int value) {
189 if (address - gayle_ide_base == GDATA_OFFSET) {
190 ide_write16(ide0, ide_data, value);
194 if (address == GIRQ_A4000) {
195 gayle_a4k_irq = value;
199 if ((address & GAYLEMASK) == CLOCKBASE) {
200 if ((address & CLOCKMASK) >= 0x8000) {
202 //printf("[CDTV] WORD write to SRAM @%.8X (%.8X): %.4X\n", (address & CLOCKMASK) - 0x8000, address, htobe16(value));
203 ((short *) ((size_t)(cdtv_sram + (address & CLOCKMASK) - 0x8000)))[0] = htobe16(value);
207 //printf("Word write to RTC.\n");
208 put_rtc_byte(address + 1, (value & 0xFF), rtc_type);
209 put_rtc_byte(address, (value >> 8), rtc_type);
213 printf("Write Word to Gayle Space 0x%06x (0x%06x)\n", address, value);
216 void writeGayleL(unsigned int address, unsigned int value) {
217 if ((address & GAYLEMASK) == CLOCKBASE) {
218 if ((address & CLOCKMASK) >= 0x8000) {
220 //printf("[CDTV] LONGWORD write to SRAM @%.8X (%.8X): %.8X\n", (address & CLOCKMASK) - 0x8000, address, htobe32(value));
221 ((int *) (size_t)(cdtv_sram + (address & CLOCKMASK) - 0x8000))[0] = htobe32(value);
225 //printf("Longword write to RTC.\n");
226 put_rtc_byte(address + 3, (value & 0xFF), rtc_type);
227 put_rtc_byte(address + 2, ((value & 0x0000FF00) >> 8), rtc_type);
228 put_rtc_byte(address + 1, ((value & 0x00FF0000) >> 16), rtc_type);
229 put_rtc_byte(address, (value >> 24), rtc_type);
233 printf("Write Long to Gayle Space 0x%06x (0x%06x)\n", address, value);
236 uint8_t readGayleB(unsigned int address) {
237 uint8_t ide_action = 0;
239 if (address >= gayle_ide_base + gayle_ide_adj) {
240 switch (address - gayle_ide_base) {
242 ide_action = ide_error_r;
245 ide_action = ide_status_r;
247 case GSECTCOUNT_OFFSET:
248 ide_action = ide_sec_count;
250 case GSECTNUM_OFFSET:
251 ide_action = ide_sec_num;
254 ide_action = ide_cyl_low;
256 case GCYLHIGH_OFFSET:
257 ide_action = ide_cyl_hi;
259 case GDEVHEAD_OFFSET:
260 ide_action = ide_dev_head;
263 ide_action = ide_altst_r;
265 case GIRQ_4000_OFFSET:
268 //gayle_irq = (gayle_irq & value) | (value & (GAYLE_IRQ_RESET | GAYLE_IRQ_BERR));
272 return ide_read8(ide0, ide_action);
279 // printf("Read Byte from Gayle Ident 0x%06x (0x%06x)\n",address,counter);
280 if (counter == 0 || counter == 1 || counter == 3) {
281 val = 0x80; // 80; to enable gayle
291 return gayle_cfg & 0x0f;
294 v = gayle_cs_mask | gayle_cs;
297 // This seems incorrect, GARY_REG3 is the same as GIDENT, and the A4000
298 // service manual says that Gary is accessible in the address range $DFC000 to $DFFFFF.
302 return gary_cfg[address - GARY_REG0];
307 return gary_cfg[address - GARY_REG3];
312 case GARY_REG5: { // This makes no sense.
314 printf("Read Byte from GARY Ident 0x%06x (0x%06x)\n",address,counter);
315 if (counter == 0 || counter == 1 || counter == 3) {
316 val = 0x80; // 80; to enable GARY
327 if ((address & GAYLEMASK) == CLOCKBASE) {
328 if ((address & CLOCKMASK) >= 0x8000) {
330 //printf("[CDTV] BYTE read from SRAM @%.8X (%.8X): %.2X\n", (address & CLOCKMASK) - 0x8000, address, cdtv_sram[(address & CLOCKMASK) - 0x8000]);
331 return cdtv_sram[(address & CLOCKMASK) - 0x8000];
335 //printf("Byte read from RTC.\n");
336 return get_rtc_byte(address, rtc_type);
339 printf("Read Byte From Gayle Space 0x%06x\n", address);
343 uint16_t readGayle(unsigned int address) {
344 if (address - gayle_ide_base == GDATA_OFFSET) {
346 value = ide_read16(ide0, ide_data);
347 // value = (value << 8) | (value >> 8);
351 if (address == GIRQ_A4000) {
352 gayle_a4k_irq = 0x8000;
356 if ((address & GAYLEMASK) == CLOCKBASE) {
357 if ((address & CLOCKMASK) >= 0x8000) {
359 //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]));
360 return be16toh( (( unsigned short *) (size_t)(cdtv_sram + (address & CLOCKMASK) - 0x8000))[0]);
364 //printf("Word read from RTC.\n");
365 return ((get_rtc_byte(address, rtc_type) << 8) | (get_rtc_byte(address + 1, rtc_type)));
368 printf("Read Word From Gayle Space 0x%06x\n", address);
372 uint32_t readGayleL(unsigned int address) {
373 if ((address & GAYLEMASK) == CLOCKBASE) {
374 if ((address & CLOCKMASK) >= 0x8000) {
376 //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]));
377 return be32toh( (( unsigned int *) (size_t)(cdtv_sram + (address & CLOCKMASK) - 0x8000))[0]);
381 //printf("Longword read from RTC.\n");
382 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)));
385 printf("Read Long From Gayle Space 0x%06x\n", address);