]> git.sesse.net Git - pistorm/blob - platforms/amiga/Gayle.c
1bbba361bb929f6af15b3290170f067d405f4cde
[pistorm] / platforms / amiga / Gayle.c
1 //
2 //  Gayle.c
3 //  Omega
4 //
5 //  Created by Matt Parsons on 06/03/2019.
6 //  Copyright © 2019 Matt Parsons. All rights reserved.
7 //
8
9 // Write Byte to Gayle Space 0xda9000 (0x0000c3)
10 // Read Byte From Gayle Space 0xda9000
11 // Read Byte From Gayle Space 0xdaa000
12
13 #include "Gayle.h"
14 #include <fcntl.h>
15 #include <stdio.h>
16 #include <string.h>
17 #include <stdlib.h>
18 #include <unistd.h>
19 #include <time.h>
20 #include <endian.h>
21
22 #include "../shared/rtc.h"
23 #include "../../config_file/config_file.h"
24
25 #include "gayle-ide/ide.h"
26 #include "amiga-registers.h"
27
28 //#define GSTATUS 0xda201c
29 //#define GCLOW   0xda2010
30 //#define GDH   0xda2018
31
32 // Gayle Addresses
33
34 // Gayle IDE Reads
35 #define GERROR 0xda2004   // Error
36 #define GSTATUS 0xda201c  // Status
37 // Gayle IDE Writes
38 #define GFEAT 0xda2004  // Write : Feature
39 #define GCMD 0xda201c   // Write : Command
40 // Gayle IDE RW
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
48 // Gayle Ident
49 #define GIDENT 0xDE1000
50
51 // Gayle IRQ/CC
52 #define GCS 0xDA8000   // Card Control
53 #define GIRQ 0xDA9000  // IRQ
54 #define GINT 0xDAA000  // Int enable
55 #define GCONF 0xDAB000  // Gayle Config
56
57 /* DA8000 */
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 */
69
70 /* DA9000 */
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 */
82
83 /* DAA000 */
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 */
95
96 int counter;
97 static uint8_t gayle_irq, gayle_cs, gayle_cs_mask, gayle_cfg;
98 static struct ide_controller *ide0;
99 int fd;
100
101 uint8_t rtc_type = RTC_TYPE_RICOH;
102
103 char *hdd_image_file[GAYLE_MAX_HARDFILES];
104
105 uint8_t cdtv_mode = 0;
106 unsigned char cdtv_sram[32 * SIZE_KILO];
107
108 uint8_t gayle_int;
109
110 struct ide_controller *get_ide(int index) {
111   //if (index) {}
112   return ide0;
113 }
114
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);
120 }
121
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");
126   }
127
128   ide0 = ide_allocate("cf");
129   fd = open(hdd_image_file[0], O_RDWR);
130   if (fd == -1) {
131     printf("HDD Image %s failed open\n", hdd_image_file[0]);
132   } else {
133     ide_attach(ide0, 0, fd);
134     ide_reset_begin(ide0);
135     printf("HDD Image %s attached\n", hdd_image_file[0]);
136   }
137 }
138
139 uint8_t CheckIrq(void) {
140   uint8_t irq;
141
142   if (gayle_int & (1 << 7)) {
143     irq = ide0->drive->intrq;
144     //  if (irq==0)
145     //  printf("IDE IRQ: %x\n",irq);
146     return irq;
147   };
148   return 0;
149 }
150
151 void writeGayleB(unsigned int address, unsigned int value) {
152   if (address == GFEAT) {
153     ide_write8(ide0, ide_feature_w, value);
154     return;
155   }
156   if (address == GCMD) {
157     ide_write8(ide0, ide_command_w, value);
158     return;
159   }
160   if (address == GSECTCNT) {
161     ide_write8(ide0, ide_sec_count, value);
162     return;
163   }
164   if (address == GSECTNUM) {
165     ide_write8(ide0, ide_sec_num, value);
166     return;
167   }
168   if (address == GCYLLOW) {
169     ide_write8(ide0, ide_cyl_low, value);
170     return;
171   }
172   if (address == GCYLHIGH) {
173     ide_write8(ide0, ide_cyl_hi, value);
174     return;
175   }
176   if (address == GDEVHEAD) {
177     ide_write8(ide0, ide_dev_head, value);
178     return;
179   }
180   if (address == GCTRL) {
181     ide_write8(ide0, ide_devctrl_w, value);
182     return;
183   }
184
185   if (address == GIDENT) {
186     counter = 0;
187     // printf("Write Byte to Gayle Ident 0x%06x (0x%06x)\n",address,value);
188     return;
189   }
190
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));
194
195     return;
196   }
197
198   if (address == GCS) {
199     printf("Write Byte to Gayle GCS 0x%06x (0x%06x)\n", address, value);
200     gayle_cs_mask = value & ~3;
201     gayle_cs &= ~3;
202     gayle_cs |= value & 3;
203     return;
204   }
205
206   if (address == GINT) {
207     printf("Write Byte to Gayle GINT 0x%06x (0x%06x)\n", address, value);
208     gayle_int = value;
209     return;
210   }
211
212   if (address == GCONF) {
213     printf("Write Byte to Gayle GCONF 0x%06x (0x%06x)\n", address, value);
214     gayle_cfg = value;
215     return;
216   }
217
218   if ((address & GAYLEMASK) == CLOCKBASE) {
219     if ((address & CLOCKMASK) >= 0x8000) {
220       if (cdtv_mode) {
221         //printf("[CDTV] BYTE write to SRAM @%.8X (%.8X): %.2X\n", (address & CLOCKMASK) - 0x8000, address, value);
222         cdtv_sram[(address & CLOCKMASK) - 0x8000] = value;
223       }
224       return;
225     }
226     //printf("Byte write to RTC.\n");
227     put_rtc_byte(address, value, rtc_type);
228     return;
229   }
230
231   printf("Write Byte to Gayle Space 0x%06x (0x%06x)\n", address, value);
232 }
233
234 void writeGayle(unsigned int address, unsigned int value) {
235   if (address == GDATA) {
236     ide_write16(ide0, ide_data, value);
237     return;
238   }
239
240   if ((address & GAYLEMASK) == CLOCKBASE) {
241     if ((address & CLOCKMASK) >= 0x8000) {
242       if (cdtv_mode) {
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);
245       }
246       return;
247     }
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);
251     return;
252   }
253
254   printf("Write Word to Gayle Space 0x%06x (0x%06x)\n", address, value);
255 }
256
257 void writeGayleL(unsigned int address, unsigned int value) {
258   if ((address & GAYLEMASK) == CLOCKBASE) {
259     if ((address & CLOCKMASK) >= 0x8000) {
260       if (cdtv_mode) {
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);
263       }
264       return;
265     }
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);
271     return;
272   }
273
274   printf("Write Long to Gayle Space 0x%06x (0x%06x)\n", address, value);
275 }
276
277 uint8_t readGayleB(unsigned int address) {
278   if (address == GERROR) {
279     return ide_read8(ide0, ide_error_r);
280   }
281   if (address == GSTATUS) {
282     return ide_read8(ide0, ide_status_r);
283   }
284
285   if (address == GSECTCNT) {
286     return ide_read8(ide0, ide_sec_count);
287   }
288
289   if (address == GSECTNUM) {
290     return ide_read8(ide0, ide_sec_num);
291   }
292
293   if (address == GCYLLOW) {
294     return ide_read8(ide0, ide_cyl_low);
295   }
296
297   if (address == GCYLHIGH) {
298     return ide_read8(ide0, ide_cyl_hi);
299   }
300
301   if (address == GDEVHEAD) {
302     return ide_read8(ide0, ide_dev_head);
303   }
304
305   if (address == GCTRL) {
306     return ide_read8(ide0, ide_altst_r);
307   }
308
309   if ((address & GAYLEMASK) == CLOCKBASE) {
310     if ((address & CLOCKMASK) >= 0x8000) {
311       if (cdtv_mode) {
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];
314       }
315       return 0;
316     }
317     //printf("Byte read from RTC.\n");
318     return get_rtc_byte(address, rtc_type);
319   }
320
321   if (address == GIDENT) {
322     uint8_t val;
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
326     } else {
327       val = 0x00;
328     }
329     counter++;
330     return val;
331   }
332
333   if (address == GIRQ) {
334     //  printf("Read Byte From GIRQ Space 0x%06x\n",gayle_irq);
335
336     return 0x80;//gayle_irq;
337 /*
338     uint8_t irq;
339     irq = ide0->drive->intrq;
340
341     if (irq == 1) {
342       // printf("IDE IRQ: %x\n",irq);
343       return 0x80;  // gayle_irq;
344     }
345
346     return 0;
347 */ 
348  }
349
350   if (address == GCS) {
351     printf("Read Byte From GCS Space 0x%06x\n", 0x1234);
352     uint8_t v;
353     v = gayle_cs_mask | gayle_cs;
354     return v;
355   }
356
357   if (address == GINT) {
358     //  printf("Read Byte From GINT Space 0x%06x\n",gayle_int);
359     return gayle_int;
360   }
361
362   if (address == GCONF) {
363     printf("Read Byte From GCONF Space 0x%06x\n", gayle_cfg & 0x0f);
364     return gayle_cfg & 0x0f;
365   }
366
367   printf("Read Byte From Gayle Space 0x%06x\n", address);
368   return 0xFF;
369 }
370
371 uint16_t readGayle(unsigned int address) {
372   if (address == GDATA) {
373     uint16_t value;
374     value = ide_read16(ide0, ide_data);
375     //  value = (value << 8) | (value >> 8);
376     return value;
377   }
378
379   if ((address & GAYLEMASK) == CLOCKBASE) {
380     if ((address & CLOCKMASK) >= 0x8000) {
381       if (cdtv_mode) {
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]);
384       }
385       return 0;
386     }
387     //printf("Word read from RTC.\n");
388     return ((get_rtc_byte(address, rtc_type) << 8) | (get_rtc_byte(address + 1, rtc_type)));
389   }
390
391   printf("Read Word From Gayle Space 0x%06x\n", address);
392   return 0x8000;
393 }
394
395 uint32_t readGayleL(unsigned int address) {
396   if ((address & GAYLEMASK) == CLOCKBASE) {
397     if ((address & CLOCKMASK) >= 0x8000) {
398       if (cdtv_mode) {
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]);
401       }
402       return 0;
403     }
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)));
406   }
407
408   printf("Read Long From Gayle Space 0x%06x\n", address);
409   return 0x8000;
410 }