]> git.sesse.net Git - pistorm/blob - Gayle.c
Clean up RTC and move it out of Gayle.c
[pistorm] / 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 #include "ide.h"
22 #include "config_file/config_file.h"
23 #include "platforms/amiga/amiga-registers.h"
24 #include "platforms/shared/rtc.h"
25
26 //#define GSTATUS 0xda201c
27 //#define GCLOW   0xda2010
28 //#define GDH   0xda2018
29
30 // Gayle Addresses
31
32 // Gayle IDE Reads
33 #define GERROR 0xda2004   // Error
34 #define GSTATUS 0xda201c  // Status
35 // Gayle IDE Writes
36 #define GFEAT 0xda2004  // Write : Feature
37 #define GCMD 0xda201c   // Write : Command
38 // Gayle IDE RW
39 #define GDATA 0xda2000     // Data
40 #define GSECTCNT 0xda2008  // SectorCount
41 #define GSECTNUM 0xda200c  // SectorNumber
42 #define GCYLLOW 0xda2010   // CylinderLow
43 #define GCYLHIGH 0xda2014  // CylinderHigh
44 #define GDEVHEAD 0xda2018  // Device/Head
45 #define GCTRL 0xda3018     // Control
46 // Gayle Ident
47 #define GIDENT 0xDE1000
48
49 // Gayle IRQ/CC
50 #define GCS 0xDA8000   // Card Control
51 #define GIRQ 0xDA9000  // IRQ
52 #define GINT 0xDAA000  // Int enable
53 #define GCONF 0xDAB000  // Gayle Config
54
55 /* DA8000 */
56 #define GAYLE_CS_IDE 0x80   /* IDE int status */
57 #define GAYLE_CS_CCDET 0x40 /* credit card detect */
58 #define GAYLE_CS_BVD1 0x20  /* battery voltage detect 1 */
59 #define GAYLE_CS_SC 0x20    /* credit card status change */
60 #define GAYLE_CS_BVD2 0x10  /* battery voltage detect 2 */
61 #define GAYLE_CS_DA 0x10    /* digital audio */
62 #define GAYLE_CS_WR 0x08    /* write enable (1 == enabled) */
63 #define GAYLE_CS_BSY 0x04   /* credit card busy */
64 #define GAYLE_CS_IRQ 0x04   /* interrupt request */
65 #define GAYLE_CS_DAEN 0x02  /* enable digital audio */
66 #define GAYLE_CS_DIS 0x01   /* disable PCMCIA slot */
67
68 /* DA9000 */
69 #define GAYLE_IRQ_IDE 0x80
70 #define GAYLE_IRQ_CCDET 0x40 /* credit card detect */
71 #define GAYLE_IRQ_BVD1 0x20  /* battery voltage detect 1 */
72 #define GAYLE_IRQ_SC 0x20    /* credit card status change */
73 #define GAYLE_IRQ_BVD2 0x10  /* battery voltage detect 2 */
74 #define GAYLE_IRQ_DA 0x10    /* digital audio */
75 #define GAYLE_IRQ_WR 0x08    /* write enable (1 == enabled) */
76 #define GAYLE_IRQ_BSY 0x04   /* credit card busy */
77 #define GAYLE_IRQ_IRQ 0x04   /* interrupt request */
78 #define GAYLE_IRQ_RESET 0x02 /* reset machine after CCDET change */
79 #define GAYLE_IRQ_BERR 0x01  /* generate bus error after CCDET change */
80
81 /* DAA000 */
82 #define GAYLE_INT_IDE 0x80     /* IDE interrupt enable */
83 #define GAYLE_INT_CCDET 0x40   /* credit card detect change enable */
84 #define GAYLE_INT_BVD1 0x20    /* battery voltage detect 1 change enable */
85 #define GAYLE_INT_SC 0x20      /* credit card status change enable */
86 #define GAYLE_INT_BVD2 0x10    /* battery voltage detect 2 change enable */
87 #define GAYLE_INT_DA 0x10      /* digital audio change enable */
88 #define GAYLE_INT_WR 0x08      /* write enable change enabled */
89 #define GAYLE_INT_BSY 0x04     /* credit card busy */
90 #define GAYLE_INT_IRQ 0x04     /* credit card interrupt request */
91 #define GAYLE_INT_BVD_LEV 0x02 /* BVD int level, 0=lev2,1=lev6 */
92 #define GAYLE_INT_BSY_LEV 0x01 /* BSY int level, 0=lev2,1=lev6 */
93
94 #define GAYLE_MAX_HARDFILES 8
95
96 int counter;
97 static uint8_t gayle_irq, gayle_int, 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 void set_hard_drive_image_file_amiga(uint8_t index, char *filename) {
106   if (hdd_image_file[index] != NULL)
107     free(hdd_image_file[index]);
108   hdd_image_file[index] = calloc(1, strlen(filename) + 1);
109   strcpy(hdd_image_file[index], filename);
110 }
111
112 void InitGayle(void) {
113   if (!hdd_image_file[0]) {
114     hdd_image_file[0] = calloc(1, 64);
115     sprintf(hdd_image_file[0], "hd0.img");
116   }
117
118   ide0 = ide_allocate("cf");
119   fd = open(hdd_image_file[0], O_RDWR);
120   if (fd == -1) {
121     printf("HDD Image %s failed open\n", hdd_image_file[0]);
122   } else {
123     ide_attach(ide0, 0, fd);
124     ide_reset_begin(ide0);
125     printf("HDD Image %s attached\n", hdd_image_file[0]);
126   }
127 }
128
129 uint8_t CheckIrq(void) {
130   uint8_t irq;
131
132   if (gayle_int & (1 << 7)) {
133     irq = ide0->drive->intrq;
134     //  if (irq==0)
135     //  printf("IDE IRQ: %x\n",irq);
136     return irq;
137   };
138   return 0;
139 }
140
141 void writeGayleB(unsigned int address, unsigned int value) {
142   if (address == GFEAT) {
143     ide_write8(ide0, ide_feature_w, value);
144     return;
145   }
146   if (address == GCMD) {
147     ide_write8(ide0, ide_command_w, value);
148     return;
149   }
150   if (address == GSECTCNT) {
151     ide_write8(ide0, ide_sec_count, value);
152     return;
153   }
154   if (address == GSECTNUM) {
155     ide_write8(ide0, ide_sec_num, value);
156     return;
157   }
158   if (address == GCYLLOW) {
159     ide_write8(ide0, ide_cyl_low, value);
160     return;
161   }
162   if (address == GCYLHIGH) {
163     ide_write8(ide0, ide_cyl_hi, value);
164     return;
165   }
166   if (address == GDEVHEAD) {
167     ide_write8(ide0, ide_dev_head, value);
168     return;
169   }
170   if (address == GCTRL) {
171     ide_write8(ide0, ide_devctrl_w, value);
172     return;
173   }
174
175   if (address == GIDENT) {
176     counter = 0;
177     // printf("Write Byte to Gayle Ident 0x%06x (0x%06x)\n",address,value);
178     return;
179   }
180
181   if (address == GIRQ) {
182     //   printf("Write Byte to Gayle GIRQ 0x%06x (0x%06x)\n",address,value);
183     gayle_irq = (gayle_irq & value) | (value & (GAYLE_IRQ_RESET | GAYLE_IRQ_BERR));
184
185     return;
186   }
187
188   if (address == GCS) {
189     printf("Write Byte to Gayle GCS 0x%06x (0x%06x)\n", address, value);
190     gayle_cs_mask = value & ~3;
191     gayle_cs &= ~3;
192     gayle_cs |= value & 3;
193     return;
194   }
195
196   if (address == GINT) {
197     printf("Write Byte to Gayle GINT 0x%06x (0x%06x)\n", address, value);
198     gayle_int = value;
199     return;
200   }
201
202   if (address == GCONF) {
203     printf("Write Byte to Gayle GCONF 0x%06x (0x%06x)\n", address, value);
204     gayle_cfg = value;
205     return;
206   }
207
208   if ((address & GAYLEMASK) == CLOCKBASE) {
209     if ((address & CLOCKMASK) >= 0x8000) {
210       printf("Byte write to CDTV SRAM?\n");
211       return;
212     }
213     put_rtc_byte(address, value, rtc_type);
214     return;
215   }
216
217   printf("Write Byte to Gayle Space 0x%06x (0x%06x)\n", address, value);
218 }
219
220 void writeGayle(unsigned int address, unsigned int value) {
221   if (address == GDATA) {
222     ide_write16(ide0, ide_data, value);
223     return;
224   }
225
226   if ((address & GAYLEMASK) == CLOCKBASE) {
227     if ((address & CLOCKMASK) >= 0x8000) {
228       printf("Word write to CDTV SRAM?\n");
229       return;
230     }
231     printf("Word write to RTC.\n");
232     put_rtc_byte(address, (value & 0xFF), rtc_type);
233     put_rtc_byte(address + 1, (value >> 8), rtc_type);
234     return;
235   }
236
237   printf("Write Word to Gayle Space 0x%06x (0x%06x)\n", address, value);
238 }
239
240 void writeGayleL(unsigned int address, unsigned int value) {
241   if ((address & GAYLEMASK) == CLOCKBASE) {
242     if ((address & CLOCKMASK) >= 0x8000) {
243       printf("Longword write to CDTV SRAM?\n");
244       return;
245     }
246     printf("Longword write to RTC.\n");
247     put_rtc_byte(address, (value & 0xFF), rtc_type);
248     put_rtc_byte(address + 1, ((value & 0x0000FF00) >> 8), rtc_type);
249     put_rtc_byte(address + 2, ((value & 0x00FF0000) >> 16), rtc_type);
250     put_rtc_byte(address + 3, (value >> 24), rtc_type);
251     return;
252   }
253
254   printf("Write Long to Gayle Space 0x%06x (0x%06x)\n", address, value);
255 }
256
257 uint8_t readGayleB(unsigned int address) {
258   if (address == GERROR) {
259     return ide_read8(ide0, ide_error_r);
260   }
261   if (address == GSTATUS) {
262     return ide_read8(ide0, ide_status_r);
263   }
264
265   if (address == GSECTCNT) {
266     return ide_read8(ide0, ide_sec_count);
267   }
268
269   if (address == GSECTNUM) {
270     return ide_read8(ide0, ide_sec_num);
271   }
272
273   if (address == GCYLLOW) {
274     return ide_read8(ide0, ide_cyl_low);
275   }
276
277   if (address == GCYLHIGH) {
278     return ide_read8(ide0, ide_cyl_hi);
279   }
280
281   if (address == GDEVHEAD) {
282     return ide_read8(ide0, ide_dev_head);
283   }
284
285   if (address == GCTRL) {
286     return ide_read8(ide0, ide_altst_r);
287   }
288
289   if ((address & GAYLEMASK) == CLOCKBASE) {
290     if ((address & CLOCKMASK) >= 0x8000) {
291       printf("Byte read from CDTV SRAM?\n");
292       return 0;
293     }
294     return get_rtc_byte(address, rtc_type);
295   }
296
297   if (address == GIDENT) {
298     uint8_t val;
299     // printf("Read Byte from Gayle Ident 0x%06x (0x%06x)\n",address,counter);
300     if (counter == 0 || counter == 1 || counter == 3) {
301       val = 0x80;  // 80; to enable gayle
302     } else {
303       val = 0x00;
304     }
305     counter++;
306     return val;
307   }
308
309   if (address == GIRQ) {
310     //  printf("Read Byte From GIRQ Space 0x%06x\n",gayle_irq);
311
312     return 0x80;//gayle_irq;
313 /*
314     uint8_t irq;
315     irq = ide0->drive->intrq;
316
317     if (irq == 1) {
318       // printf("IDE IRQ: %x\n",irq);
319       return 0x80;  // gayle_irq;
320     }
321
322     return 0;
323 */ 
324  }
325
326   if (address == GCS) {
327     printf("Read Byte From GCS Space 0x%06x\n", 0x1234);
328     uint8_t v;
329     v = gayle_cs_mask | gayle_cs;
330     return v;
331   }
332
333   if (address == GINT) {
334     //  printf("Read Byte From GINT Space 0x%06x\n",gayle_int);
335     return gayle_int;
336   }
337
338   if (address == GCONF) {
339     printf("Read Byte From GCONF Space 0x%06x\n", gayle_cfg & 0x0f);
340     return gayle_cfg & 0x0f;
341   }
342
343   printf("Read Byte From Gayle Space 0x%06x\n", address);
344   return 0xFF;
345 }
346
347 uint16_t readGayle(unsigned int address) {
348   if (address == GDATA) {
349     uint16_t value;
350     value = ide_read16(ide0, ide_data);
351     //  value = (value << 8) | (value >> 8);
352     return value;
353   }
354
355   if ((address & GAYLEMASK) == CLOCKBASE) {
356     if ((address & CLOCKMASK) >= 0x8000) {
357       printf("Word read from CDTV SRAM?\n");
358       return 0;
359     }
360     return ((get_rtc_byte(address, rtc_type) << 8) | (get_rtc_byte(address + 1, rtc_type)));
361   }
362
363   printf("Read Word From Gayle Space 0x%06x\n", address);
364   return 0x8000;
365 }
366
367 uint32_t readGayleL(unsigned int address) {
368   if ((address & GAYLEMASK) == CLOCKBASE) {
369     if ((address & CLOCKMASK) >= 0x8000) {
370       printf("Longword read from CDTV SRAM?\n");
371       return 0;
372     }
373     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)));
374   }
375
376   printf("Read Long From Gayle Space 0x%06x\n", address);
377   return 0x8000;
378 }