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"
30 uint8_t ramsey_cfg = 0x08;
31 static uint8_t ramsey_id = RAMSEY_REV7;
34 static uint8_t gayle_irq, gayle_cs, gayle_cs_mask, gayle_cfg;
35 static struct ide_controller *ide0;
38 uint8_t rtc_type = RTC_TYPE_RICOH;
40 char *hdd_image_file[GAYLE_MAX_HARDFILES];
42 uint8_t cdtv_mode = 0;
43 unsigned char cdtv_sram[32 * SIZE_KILO];
45 uint8_t gayle_a4k = 0xA0;
46 uint16_t gayle_a4k_irq = 0;
47 uint8_t gayle_a4k_int = 0;
48 uint8_t gayle_int = 0;
50 uint32_t gayle_ide_mask = ~GDATA;
51 uint32_t gayle_ide_base = GDATA;
52 uint8_t gayle_ide_adj = 0;
54 struct ide_controller *get_ide(int index) {
59 void adjust_gayle_4000() {
60 gayle_ide_base = GAYLE_IDE_BASE_A4000;
65 void adjust_gayle_1200() {
69 void set_hard_drive_image_file_amiga(uint8_t index, char *filename) {
70 if (hdd_image_file[index] != NULL)
71 free(hdd_image_file[index]);
72 hdd_image_file[index] = calloc(1, strlen(filename) + 1);
73 strcpy(hdd_image_file[index], filename);
76 void InitGayle(void) {
77 if (!hdd_image_file[0]) {
78 hdd_image_file[0] = calloc(1, 64);
79 sprintf(hdd_image_file[0], "hd0.img");
82 ide0 = ide_allocate("cf");
83 fd = open(hdd_image_file[0], O_RDWR);
85 printf("HDD Image %s failed open\n", hdd_image_file[0]);
87 ide_attach(ide0, 0, fd);
88 ide_reset_begin(ide0);
89 printf("HDD Image %s attached\n", hdd_image_file[0]);
93 uint8_t CheckIrq(void) {
96 if (gayle_int & (1 << 7)) {
97 irq = ide0->drive->intrq;
99 // printf("IDE IRQ: %x\n",irq);
105 static uint8_t ide_action = 0;
107 void writeGayleB(unsigned int address, unsigned int value) {
108 if (address >= gayle_ide_base) {
109 switch ((address - gayle_ide_base) - gayle_ide_adj) {
111 ide_action = ide_feature_w;
114 ide_action = ide_command_w;
116 case GSECTCOUNT_OFFSET:
117 ide_action = ide_sec_count;
119 case GSECTNUM_OFFSET:
120 ide_action = ide_sec_num;
123 ide_action = ide_cyl_low;
125 case GCYLHIGH_OFFSET:
126 ide_action = ide_cyl_hi;
128 case GDEVHEAD_OFFSET:
129 ide_action = ide_dev_head;
132 ide_action = ide_devctrl_w;
134 case GIRQ_4000_OFFSET:
135 gayle_a4k_irq = value;
137 gayle_irq = (gayle_irq & value) | (value & (GAYLE_IRQ_RESET | GAYLE_IRQ_BERR));
142 ide_write8(ide0, ide_action, value);
149 printf("Write bye to A4000 Gayle: %.2X\n", value);
159 ramsey_cfg = value & 0x0F;
165 gayle_cs_mask = value & ~3;
167 gayle_cs |= value & 3;
171 if ((address & GAYLEMASK) == CLOCKBASE) {
172 if ((address & CLOCKMASK) >= 0x8000) {
174 //printf("[CDTV] BYTE write to SRAM @%.8X (%.8X): %.2X\n", (address & CLOCKMASK) - 0x8000, address, value);
175 cdtv_sram[(address & CLOCKMASK) - 0x8000] = value;
179 //printf("Byte write to RTC.\n");
180 put_rtc_byte(address, value, rtc_type);
184 printf("Write Byte to Gayle Space 0x%06x (0x%06x)\n", address, value);
187 void writeGayle(unsigned int address, unsigned int value) {
188 if (address - gayle_ide_base == GDATA_OFFSET) {
189 ide_write16(ide0, ide_data, value);
193 if (address == GIRQ_A4000) {
194 gayle_a4k_irq = value;
198 if ((address & GAYLEMASK) == CLOCKBASE) {
199 if ((address & CLOCKMASK) >= 0x8000) {
201 //printf("[CDTV] WORD write to SRAM @%.8X (%.8X): %.4X\n", (address & CLOCKMASK) - 0x8000, address, htobe16(value));
202 ((short *) ((size_t)(cdtv_sram + (address & CLOCKMASK) - 0x8000)))[0] = htobe16(value);
206 //printf("Word write to RTC.\n");
207 put_rtc_byte(address + 1, (value & 0xFF), rtc_type);
208 put_rtc_byte(address, (value >> 8), rtc_type);
212 printf("Write Word to Gayle Space 0x%06x (0x%06x)\n", address, value);
215 void writeGayleL(unsigned int address, unsigned int value) {
216 if ((address & GAYLEMASK) == CLOCKBASE) {
217 if ((address & CLOCKMASK) >= 0x8000) {
219 //printf("[CDTV] LONGWORD write to SRAM @%.8X (%.8X): %.8X\n", (address & CLOCKMASK) - 0x8000, address, htobe32(value));
220 ((int *) (size_t)(cdtv_sram + (address & CLOCKMASK) - 0x8000))[0] = htobe32(value);
224 //printf("Longword write to RTC.\n");
225 put_rtc_byte(address + 3, (value & 0xFF), rtc_type);
226 put_rtc_byte(address + 2, ((value & 0x0000FF00) >> 8), rtc_type);
227 put_rtc_byte(address + 1, ((value & 0x00FF0000) >> 16), rtc_type);
228 put_rtc_byte(address, (value >> 24), rtc_type);
232 printf("Write Long to Gayle Space 0x%06x (0x%06x)\n", address, value);
235 uint8_t readGayleB(unsigned int address) {
236 uint8_t ide_action = 0;
238 if (address >= gayle_ide_base) {
239 switch ((address - gayle_ide_base) - gayle_ide_adj) {
241 ide_action = ide_error_r;
244 ide_action = ide_status_r;
246 case GSECTCOUNT_OFFSET:
247 ide_action = ide_sec_count;
249 case GSECTNUM_OFFSET:
250 ide_action = ide_sec_num;
253 ide_action = ide_cyl_low;
255 case GCYLHIGH_OFFSET:
256 ide_action = ide_cyl_hi;
258 case GDEVHEAD_OFFSET:
259 ide_action = ide_dev_head;
262 ide_action = ide_altst_r;
264 case GIRQ_4000_OFFSET:
267 //gayle_irq = (gayle_irq & value) | (value & (GAYLE_IRQ_RESET | GAYLE_IRQ_BERR));
271 return ide_read8(ide0, ide_action);
278 if (counter == 0 || counter == 1 || counter == 3) {
279 val = 0x80; // 80; to enable gayle
289 return gayle_cfg & 0x0f;
292 v = gayle_cs_mask | gayle_cs;
295 // This seems incorrect, GARY_REG3 is the same as GIDENT, and the A4000
296 // service manual says that Gary is accessible in the address range $DFC000 to $DFFFFF.
300 return gary_cfg[address - GARY_REG0];
305 return gary_cfg[address - GARY_REG4];
310 case GARY_REG5: { // This makes no sense.
312 if (counter == 0 || counter == 1 || counter == 3) {
313 val = 0x80; // 80; to enable GARY
321 // This can't be correct, as this is the same address as GDEVHEAD on the A4000 Gayle.
322 //printf("Read Byte from Gayle A4k: %.2X\n", gayle_a4k);
326 if ((address & GAYLEMASK) == CLOCKBASE) {
327 if ((address & CLOCKMASK) >= 0x8000) {
329 //printf("[CDTV] BYTE read from SRAM @%.8X (%.8X): %.2X\n", (address & CLOCKMASK) - 0x8000, address, cdtv_sram[(address & CLOCKMASK) - 0x8000]);
330 return cdtv_sram[(address & CLOCKMASK) - 0x8000];
334 //printf("Byte read from RTC.\n");
335 return get_rtc_byte(address, rtc_type);
338 printf("Read Byte From Gayle Space 0x%06x\n", address);
342 uint16_t readGayle(unsigned int address) {
343 if (address - gayle_ide_base == GDATA_OFFSET) {
345 value = ide_read16(ide0, ide_data);
346 // value = (value << 8) | (value >> 8);
350 if (address == GIRQ_A4000) {
351 gayle_a4k_irq = 0x8000;
355 if ((address & GAYLEMASK) == CLOCKBASE) {
356 if ((address & CLOCKMASK) >= 0x8000) {
358 //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]));
359 return be16toh( (( unsigned short *) (size_t)(cdtv_sram + (address & CLOCKMASK) - 0x8000))[0]);
363 //printf("Word read from RTC.\n");
364 return ((get_rtc_byte(address, rtc_type) << 8) | (get_rtc_byte(address + 1, rtc_type)));
367 printf("Read Word From Gayle Space 0x%06x\n", address);
371 uint32_t readGayleL(unsigned int address) {
372 if ((address & GAYLEMASK) == CLOCKBASE) {
373 if ((address & CLOCKMASK) >= 0x8000) {
375 //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]));
376 return be32toh( (( unsigned int *) (size_t)(cdtv_sram + (address & CLOCKMASK) - 0x8000))[0]);
380 //printf("Longword read from RTC.\n");
381 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)));
384 printf("Read Long From Gayle Space 0x%06x\n", address);