]> git.sesse.net Git - pistorm/blob - Gayle.c
Update config_file.h, emulator.c, and amiga-platform.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 uint8_t cdtv_mode = 0;
106 unsigned char cdtv_sram[32 * SIZE_KILO];
107
108 void set_hard_drive_image_file_amiga(uint8_t index, char *filename) {
109   if (hdd_image_file[index] != NULL)
110     free(hdd_image_file[index]);
111   hdd_image_file[index] = calloc(1, strlen(filename) + 1);
112   strcpy(hdd_image_file[index], filename);
113 }
114
115 void InitGayle(void) {
116   if (!hdd_image_file[0]) {
117     hdd_image_file[0] = calloc(1, 64);
118     sprintf(hdd_image_file[0], "hd0.img");
119   }
120
121   ide0 = ide_allocate("cf");
122   fd = open(hdd_image_file[0], O_RDWR);
123   if (fd == -1) {
124     printf("HDD Image %s failed open\n", hdd_image_file[0]);
125   } else {
126     ide_attach(ide0, 0, fd);
127     ide_reset_begin(ide0);
128     printf("HDD Image %s attached\n", hdd_image_file[0]);
129   }
130 }
131
132 uint8_t CheckIrq(void) {
133   uint8_t irq;
134
135   if (gayle_int & (1 << 7)) {
136     irq = ide0->drive->intrq;
137     //  if (irq==0)
138     //  printf("IDE IRQ: %x\n",irq);
139     return irq;
140   };
141   return 0;
142 }
143
144 void writeGayleB(unsigned int address, unsigned int value) {
145   if (address == GFEAT) {
146     ide_write8(ide0, ide_feature_w, value);
147     return;
148   }
149   if (address == GCMD) {
150     ide_write8(ide0, ide_command_w, value);
151     return;
152   }
153   if (address == GSECTCNT) {
154     ide_write8(ide0, ide_sec_count, value);
155     return;
156   }
157   if (address == GSECTNUM) {
158     ide_write8(ide0, ide_sec_num, value);
159     return;
160   }
161   if (address == GCYLLOW) {
162     ide_write8(ide0, ide_cyl_low, value);
163     return;
164   }
165   if (address == GCYLHIGH) {
166     ide_write8(ide0, ide_cyl_hi, value);
167     return;
168   }
169   if (address == GDEVHEAD) {
170     ide_write8(ide0, ide_dev_head, value);
171     return;
172   }
173   if (address == GCTRL) {
174     ide_write8(ide0, ide_devctrl_w, value);
175     return;
176   }
177
178   if (address == GIDENT) {
179     counter = 0;
180     // printf("Write Byte to Gayle Ident 0x%06x (0x%06x)\n",address,value);
181     return;
182   }
183
184   if (address == GIRQ) {
185     //   printf("Write Byte to Gayle GIRQ 0x%06x (0x%06x)\n",address,value);
186     gayle_irq = (gayle_irq & value) | (value & (GAYLE_IRQ_RESET | GAYLE_IRQ_BERR));
187
188     return;
189   }
190
191   if (address == GCS) {
192     printf("Write Byte to Gayle GCS 0x%06x (0x%06x)\n", address, value);
193     gayle_cs_mask = value & ~3;
194     gayle_cs &= ~3;
195     gayle_cs |= value & 3;
196     return;
197   }
198
199   if (address == GINT) {
200     printf("Write Byte to Gayle GINT 0x%06x (0x%06x)\n", address, value);
201     gayle_int = value;
202     return;
203   }
204
205   if (address == GCONF) {
206     printf("Write Byte to Gayle GCONF 0x%06x (0x%06x)\n", address, value);
207     gayle_cfg = value;
208     return;
209   }
210
211   if ((address & GAYLEMASK) == CLOCKBASE) {
212     if ((address & CLOCKMASK) >= 0x8000) {
213       if (cdtv_mode) {
214         cdtv_sram[(address & CLOCKMASK) - 0x8000] = value;
215       }
216       return;
217     }
218     put_rtc_byte(address, value, rtc_type);
219     return;
220   }
221
222   printf("Write Byte to Gayle Space 0x%06x (0x%06x)\n", address, value);
223 }
224
225 void writeGayle(unsigned int address, unsigned int value) {
226   if (address == GDATA) {
227     ide_write16(ide0, ide_data, value);
228     return;
229   }
230
231   if ((address & GAYLEMASK) == CLOCKBASE) {
232     if ((address & CLOCKMASK) >= 0x8000) {
233       if (cdtv_mode) {
234         ((short *) ((size_t)(cdtv_sram + (address & CLOCKMASK) - 0x8000)))[0] = htobe16(value);
235       }
236       return;
237     }
238     printf("Word write to RTC.\n");
239     put_rtc_byte(address, (value & 0xFF), rtc_type);
240     put_rtc_byte(address + 1, (value >> 8), rtc_type);
241     return;
242   }
243
244   printf("Write Word to Gayle Space 0x%06x (0x%06x)\n", address, value);
245 }
246
247 void writeGayleL(unsigned int address, unsigned int value) {
248   if ((address & GAYLEMASK) == CLOCKBASE) {
249     if ((address & CLOCKMASK) >= 0x8000) {
250       if (cdtv_mode) {
251         ((int *) (size_t)(cdtv_sram + (address & CLOCKMASK) - 0x8000))[0] = htobe32(value);
252       }
253       return;
254     }
255     printf("Longword write to RTC.\n");
256     put_rtc_byte(address, (value & 0xFF), rtc_type);
257     put_rtc_byte(address + 1, ((value & 0x0000FF00) >> 8), rtc_type);
258     put_rtc_byte(address + 2, ((value & 0x00FF0000) >> 16), rtc_type);
259     put_rtc_byte(address + 3, (value >> 24), rtc_type);
260     return;
261   }
262
263   printf("Write Long to Gayle Space 0x%06x (0x%06x)\n", address, value);
264 }
265
266 uint8_t readGayleB(unsigned int address) {
267   if (address == GERROR) {
268     return ide_read8(ide0, ide_error_r);
269   }
270   if (address == GSTATUS) {
271     return ide_read8(ide0, ide_status_r);
272   }
273
274   if (address == GSECTCNT) {
275     return ide_read8(ide0, ide_sec_count);
276   }
277
278   if (address == GSECTNUM) {
279     return ide_read8(ide0, ide_sec_num);
280   }
281
282   if (address == GCYLLOW) {
283     return ide_read8(ide0, ide_cyl_low);
284   }
285
286   if (address == GCYLHIGH) {
287     return ide_read8(ide0, ide_cyl_hi);
288   }
289
290   if (address == GDEVHEAD) {
291     return ide_read8(ide0, ide_dev_head);
292   }
293
294   if (address == GCTRL) {
295     return ide_read8(ide0, ide_altst_r);
296   }
297
298   if ((address & GAYLEMASK) == CLOCKBASE) {
299     if ((address & CLOCKMASK) >= 0x8000) {
300       if (cdtv_mode) {
301         return cdtv_sram[(address & CLOCKMASK) - 0x8000];
302       }
303       return 0;
304     }
305     return get_rtc_byte(address, rtc_type);
306   }
307
308   if (address == GIDENT) {
309     uint8_t val;
310     // printf("Read Byte from Gayle Ident 0x%06x (0x%06x)\n",address,counter);
311     if (counter == 0 || counter == 1 || counter == 3) {
312       val = 0x80;  // 80; to enable gayle
313     } else {
314       val = 0x00;
315     }
316     counter++;
317     return val;
318   }
319
320   if (address == GIRQ) {
321     //  printf("Read Byte From GIRQ Space 0x%06x\n",gayle_irq);
322
323     return 0x80;//gayle_irq;
324 /*
325     uint8_t irq;
326     irq = ide0->drive->intrq;
327
328     if (irq == 1) {
329       // printf("IDE IRQ: %x\n",irq);
330       return 0x80;  // gayle_irq;
331     }
332
333     return 0;
334 */ 
335  }
336
337   if (address == GCS) {
338     printf("Read Byte From GCS Space 0x%06x\n", 0x1234);
339     uint8_t v;
340     v = gayle_cs_mask | gayle_cs;
341     return v;
342   }
343
344   if (address == GINT) {
345     //  printf("Read Byte From GINT Space 0x%06x\n",gayle_int);
346     return gayle_int;
347   }
348
349   if (address == GCONF) {
350     printf("Read Byte From GCONF Space 0x%06x\n", gayle_cfg & 0x0f);
351     return gayle_cfg & 0x0f;
352   }
353
354   printf("Read Byte From Gayle Space 0x%06x\n", address);
355   return 0xFF;
356 }
357
358 uint16_t readGayle(unsigned int address) {
359   if (address == GDATA) {
360     uint16_t value;
361     value = ide_read16(ide0, ide_data);
362     //  value = (value << 8) | (value >> 8);
363     return value;
364   }
365
366   if ((address & GAYLEMASK) == CLOCKBASE) {
367     if ((address & CLOCKMASK) >= 0x8000) {
368       if (cdtv_mode) {
369
370         return be16toh( (( unsigned short *) (size_t)(cdtv_sram + (address & CLOCKMASK) - 0x8000))[0]);
371       }
372       return 0;
373     }
374     return ((get_rtc_byte(address, rtc_type) << 8) | (get_rtc_byte(address + 1, rtc_type)));
375   }
376
377   printf("Read Word From Gayle Space 0x%06x\n", address);
378   return 0x8000;
379 }
380
381 uint32_t readGayleL(unsigned int address) {
382   if ((address & GAYLEMASK) == CLOCKBASE) {
383     if ((address & CLOCKMASK) >= 0x8000) {
384       if (cdtv_mode) {
385         return be32toh( (( unsigned short *) (size_t)(cdtv_sram + (address & CLOCKMASK) - 0x8000))[0]);
386       }
387       return 0;
388     }
389     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)));
390   }
391
392   printf("Read Long From Gayle Space 0x%06x\n", address);
393   return 0x8000;
394 }