]> git.sesse.net Git - pistorm/blob - Gayle.c
- Added support for A4000 IDE on A4000 ROMs to boot the hd0.img
[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 "ide.h"
20 #include "platforms/amiga/amiga-registers.h"
21
22
23 //#define GSTATUS 0xda201c
24 //#define GCLOW   0xda2010
25 //#define GDH   0xda2018
26
27 // Gayle Addresses
28 //#define GAYLE_IDE_BASE_A1200 0xDA0000 //8 bit base
29 #define GAYLE_IDE_BASE_A1200 0xDA2000 //16bit base
30 #define GAYLE_IDE_BASE_A4000 0xDD2020
31
32 // Gayle IDE Reads
33 #define GERROR 0xda2004   // Error
34 #define GSTATUS 0xda201C  // Status
35 #define GERROR_A4000 GAYLE_IDE_BASE_A4000 + 0x06   // Error
36 #define GSTATUS_A4000 GAYLE_IDE_BASE_A4000 + 0x1E  // Status
37
38 // Gayle IDE Writes
39 #define GFEAT 0xda2004  // Write : Feature
40 #define GCMD 0xda201c   // Write : Command
41 #define GFEAT_A4000 GAYLE_IDE_BASE_A4000 + 0x06  // Write : Feature
42 #define GCMD_A4000 GAYLE_IDE_BASE_A4000 + 0x1E   // Write : Command
43 #define GMODEREG0_A4000 0x0DD1020   // D31, PIO modes (00,01,10)
44 #define GMODEREG1_A4000 0x0DD1022   // D31, (MSB)
45
46 // Gayle IDE RW
47 #define GDATA 0xda2000     // Data - 16 bit
48 #define GSECTCNT 0xda2008  // SectorCount
49 #define GSECTNUM 0xda200c  // SectorNumber
50 #define GCYLLOW 0xda2010   // CylinderLow
51 #define GCYLHIGH 0xda2014  // CylinderHigh
52 #define GDEVHEAD 0xda2018  // Device/Head
53 #define GCTRL 0xda3018     // Control
54
55 #define GDATA_A4000 GAYLE_IDE_BASE_A4000     // Data
56 #define GSECTCNT_A4000 GAYLE_IDE_BASE_A4000 + 0x0a  // SectorCount
57 #define GSECTNUM_A4000 GAYLE_IDE_BASE_A4000 + 0x0e  // SectorNumber
58 #define GCYLLOW_A4000 GAYLE_IDE_BASE_A4000 + 0x12   // CylinderLow
59 #define GCYLHIGH_A4000 GAYLE_IDE_BASE_A4000 + 0x16  // CylinderHigh
60 #define GDEVHEAD_A4000 GAYLE_IDE_BASE_A4000 + 0x1a  // Device/Head
61 #define GCTRL_A4000 GAYLE_IDE_BASE_A4000 + 0x101a     // Control
62
63 // Gayle Ident
64 #define GIDENT 0xDE1000
65
66 // Gayle IRQ/CC
67 #define GCS 0xDA8000   // Card Control
68 #define GIRQ 0xDA9000  // IRQ
69 #define GINT 0xDAA000  // Int enable
70 #define GCONF 0xDAB000  // Gayle Config
71
72 // For A4000 there's no need to populate other areas, just GIRQ
73 #define GIRQ_A4000 GAYLE_IDE_BASE_A4000 + 0x1000  // IRQ  0xDD3020
74
75 /* DA8000 */
76 #define GAYLE_CS_IDE 0x80   /* IDE int status */
77 #define GAYLE_CS_CCDET 0x40 /* credit card detect */
78 #define GAYLE_CS_BVD1 0x20  /* battery voltage detect 1 */
79 #define GAYLE_CS_SC 0x20    /* credit card status change */
80 #define GAYLE_CS_BVD2 0x10  /* battery voltage detect 2 */
81 #define GAYLE_CS_DA 0x10    /* digital audio */
82 #define GAYLE_CS_WR 0x08    /* write enable (1 == enabled) */
83 #define GAYLE_CS_BSY 0x04   /* credit card busy */
84 #define GAYLE_CS_IRQ 0x04   /* interrupt request */
85 #define GAYLE_CS_DAEN 0x02  /* enable digital audio */
86 #define GAYLE_CS_DIS 0x01   /* disable PCMCIA slot */
87
88 /* DA9000 */
89 #define GAYLE_IRQ_IDE 0x80
90 #define GAYLE_IRQ_CCDET 0x40 /* credit card detect */
91 #define GAYLE_IRQ_BVD1 0x20  /* battery voltage detect 1 */
92 #define GAYLE_IRQ_SC 0x20    /* credit card status change */
93 #define GAYLE_IRQ_BVD2 0x10  /* battery voltage detect 2 */
94 #define GAYLE_IRQ_DA 0x10    /* digital audio */
95 #define GAYLE_IRQ_WR 0x08    /* write enable (1 == enabled) */
96 #define GAYLE_IRQ_BSY 0x04   /* credit card busy */
97 #define GAYLE_IRQ_IRQ 0x04   /* interrupt request */
98 #define GAYLE_IRQ_RESET 0x02 /* reset machine after CCDET change */
99 #define GAYLE_IRQ_BERR 0x01  /* generate bus error after CCDET change */
100
101 /* DAA000 */
102 #define GAYLE_INT_IDE 0x80     /* IDE interrupt enable */
103 #define GAYLE_INT_CCDET 0x40   /* credit card detect change enable */
104 #define GAYLE_INT_BVD1 0x20    /* battery voltage detect 1 change enable */
105 #define GAYLE_INT_SC 0x20      /* credit card status change enable */
106 #define GAYLE_INT_BVD2 0x10    /* battery voltage detect 2 change enable */
107 #define GAYLE_INT_DA 0x10      /* digital audio change enable */
108 #define GAYLE_INT_WR 0x08      /* write enable change enabled */
109 #define GAYLE_INT_BSY 0x04     /* credit card busy */
110 #define GAYLE_INT_IRQ 0x04     /* credit card interrupt request */
111 #define GAYLE_INT_BVD_LEV 0x02 /* BVD int level, 0=lev2,1=lev6 */
112 #define GAYLE_INT_BSY_LEV 0x01 /* BSY int level, 0=lev2,1=lev6 */
113
114 #define GAYLE_MAX_HARDFILES 8
115
116 int counter;
117 static uint8_t gayle_irq, gayle_int, gayle_cs, gayle_cs_mask, gayle_cfg;
118 static struct ide_controller *ide0;
119 int fd;
120
121 uint8_t gary_cfg0 = 0x00;
122 uint8_t gary_cfg1 = 0x00;
123 uint8_t gary_cfg2 = 0x00;
124 uint8_t gary_cfg3 = 0x00;
125 uint8_t gary_cfg4 = 0x00;
126 uint8_t gary_cfg5 = 0x00;
127
128 uint8_t gayle_a4k = 0xA0;
129 uint16_t gayle_a4k_irq;
130 uint8_t ramsey_cfg = 0x08;
131 static uint8_t ramsey_id = RAMSEY_REV7;
132
133 char *hdd_image_file[GAYLE_MAX_HARDFILES];
134
135 void set_hard_drive_image_file_amiga(uint8_t index, char *filename) {
136   if (hdd_image_file[index] != NULL)
137     free(hdd_image_file[index]);
138   hdd_image_file[index] = calloc(1, strlen(filename) + 1);
139   strcpy(hdd_image_file[index], filename);
140 }
141
142 void InitGayle(void) {
143   if (!hdd_image_file[0]) {
144     hdd_image_file[0] = calloc(1, 64);
145     sprintf(hdd_image_file[0], "hd0.img");
146   }
147
148   ide0 = ide_allocate("cf");
149   fd = open(hdd_image_file[0], O_RDWR);
150   if (fd == -1) {
151     printf("HDD Image %s failed open\n", hdd_image_file[0]);
152   } else {
153     ide_attach(ide0, 0, fd);
154     ide_reset_begin(ide0);
155     printf("HDD Image %s attached\n", hdd_image_file[0]);
156   }
157 }
158
159 uint8_t CheckIrq(void) {
160   uint8_t irq;
161   /* skipping gayle_int check makes A4000 ROMs IDE work at decent speed  */
162   irq = ide0->drive->intrq;
163   return irq;
164 }
165
166 void writeGayleB(unsigned int address, unsigned int value) {
167   if (address == GFEAT || address == GFEAT_A4000) {
168     ide_write8(ide0, ide_feature_w, value);
169     return;
170   }
171   if (address == GCMD || address == GCMD_A4000) {
172     ide_write8(ide0, ide_command_w, value);
173     return;
174   }
175   if (address == GSECTCNT || address == GSECTCNT_A4000) {
176     ide_write8(ide0, ide_sec_count, value);
177     return;
178   }
179   if (address == GSECTNUM || address == GSECTNUM_A4000) {
180     ide_write8(ide0, ide_sec_num, value);
181     return;
182   }
183   if (address == GCYLLOW || address == GCYLLOW_A4000) {
184     ide_write8(ide0, ide_cyl_low, value);
185     return;
186   }
187   if (address == GCYLHIGH || address == GCYLHIGH_A4000) {
188     ide_write8(ide0, ide_cyl_hi, value);
189     return;
190   }
191   if (address == GDEVHEAD || address == GDEVHEAD_A4000) {
192     ide_write8(ide0, ide_dev_head, value);
193     return;
194   }
195   if (address == GCTRL || address == GCTRL_A4000) {
196     ide_write8(ide0, ide_devctrl_w, value);
197     return;
198   }
199
200   if (address == GIDENT) {
201     counter = 0;
202     printf("Write Byte to Gayle Ident 0x%06x (0x%06x)\n",address,value);
203     return;
204   }
205
206   if (address == 0xDD203A) {
207     printf("Write Byte to 0xDD203A Gayle 0x%06x (0x%06x)\n",address,value);
208     gayle_a4k = value;
209      return;
210    }
211
212   if (address == GIRQ || address == GIRQ_A4000) {
213     //printf("Write Byte to Gayle GIRQ 0x%06x (0x%06x)\n",address,value);
214     gayle_irq = (gayle_irq & value) & (value & (GAYLE_IRQ_RESET | GAYLE_IRQ_BERR));
215     return;
216   }
217
218   if (address == GCS) {
219     printf("Write Byte to Gayle GCS 0x%06x (0x%06x)\n", address, value);
220     gayle_cs_mask = value & ~3;
221     gayle_cs &= ~3;
222     gayle_cs |= value & 3;
223     return;
224   }
225
226   if (address == GINT) {
227     printf("Write Byte to Gayle GINT 0x%06x (0x%06x)\n", address, value);
228     gayle_int = value;
229     return;
230   }
231
232   if (address == GCONF) {
233     printf("Write Byte to Gayle GCONF 0x%06x (0x%06x)\n", address, value);
234     gayle_cfg = value;
235     return;
236   }
237
238   if (address == RAMSEY_REG) {
239     printf("Write Byte to RAMSEY_REG Space 0x%06x (0x%06x)\n", address, value);
240     ramsey_cfg = value & 0x0f;
241     return;
242   }
243
244   printf("Write Byte to Gayle Space 0x%06x (0x%06x)\n", address, value);
245 }
246
247 void writeGayle(unsigned int address, unsigned int value) {
248   if (address == GDATA || address == GDATA_A4000) {
249     ide_write16(ide0, ide_data, value);
250     return;
251   }
252
253   if (address == GIRQ_A4000) {
254     gayle_a4k_irq = value;
255     return;
256   }
257
258   printf("Write Word to Gayle Space 0x%06x (0x%06x)\n", address, value);
259 }
260
261 void writeGayleL(unsigned int address, unsigned int value) {
262   printf("Write Long to Gayle Space 0x%06x (0x%06x)\n", address, value);
263 }
264
265 uint8_t readGayleB(unsigned int address) {
266   if (address == GERROR || address == GERROR_A4000) {
267     return ide_read8(ide0, ide_error_r);
268   }
269   if (address == GSTATUS || address == GSTATUS_A4000) {
270     return ide_read8(ide0, ide_status_r);
271   }
272
273   if (address == GSECTCNT || address == GSECTCNT_A4000) {
274     return ide_read8(ide0, ide_sec_count);
275   }
276
277   if (address == GSECTNUM || address == GSECTNUM_A4000) {
278     return ide_read8(ide0, ide_sec_num);
279   }
280
281   if (address == GCYLLOW || address == GCYLLOW_A4000) {
282     return ide_read8(ide0, ide_cyl_low);
283   }
284
285   if (address == GCYLHIGH || address == GCYLHIGH_A4000) {
286     return ide_read8(ide0, ide_cyl_hi);
287   }
288
289   if (address == GDEVHEAD || address == GDEVHEAD_A4000) {
290     return ide_read8(ide0, ide_dev_head);
291   }
292
293   if (address == GCTRL || address == GCTRL_A4000) {
294     return ide_read8(ide0, ide_altst_r);
295   }
296
297   if (address == 0xDD203A) {
298     printf("Write Byte to 0xDD203A Gayle 0x%06x (0x%06x)\n",address, gayle_a4k);
299     return gayle_a4k;
300   }
301
302   if (address == GIDENT) {
303     uint8_t val;
304     // printf("Read Byte from Gayle Ident 0x%06x (0x%06x)\n",address,counter);
305     if (counter == 0 || counter == 1 || counter == 3) {
306       val = 0x80;  // 80; to enable gayle
307     } else {
308       val = 0x00;
309     }
310     counter++;
311     return val;
312   }
313
314   if (address == GARY_REG5) {
315     uint8_t val;
316     printf("Read Byte from GARY Ident 0x%06x (0x%06x)\n",address,counter);
317     if (counter == 0 || counter == 1 || counter == 3) {
318       val = 0x80;  // 80; to enable GARY
319     } else {
320       val = 0x00;
321     }
322     counter++;
323     return val;
324   }
325
326
327   if (address == GIRQ || address == GIRQ_A4000) {
328     //printf("Read Byte From GIRQ Space 0x%06x\n",gayle_irq);
329     return 0x80;//gayle_irq;
330 /*
331     uint8_t irq;
332     irq = ide0->drive->intrq;
333
334     if (irq == 1) {
335       // printf("IDE IRQ: %x\n",irq);
336       return 0x80;  // gayle_irq;
337     }
338
339     return 0;
340 */ 
341  }
342
343   if (address == GCS) {
344     printf("Read Byte From GCS Space 0x%06x\n", 0x1234);
345     uint8_t v;
346     v = gayle_cs_mask | gayle_cs;
347     return v;
348   }
349
350   if (address == GINT) {
351     printf("Read Byte From GINT Space 0x%06x\n",gayle_int);
352     return gayle_int;
353   }
354
355   if (address == GCONF) {
356     printf("Read Byte From GCONF Space 0x%06x\n", gayle_cfg & 0x0f);
357     return gayle_cfg & 0x0f;
358   }
359
360   if (address == GARY_REG0) {
361     printf("Read Byte From GARY_REG Space 0x%06x (0x%06x)\n", address, gary_cfg0 & 0x80);
362     return gary_cfg0;
363   }
364   if (address == GARY_REG1) {
365     printf("Read Byte From GARY_REG Space 0x%06x (0x%06x)\n", address, gary_cfg1 & 0x80);
366     return gary_cfg1;
367   }
368   if (address == GARY_REG2) {
369     printf("Read Byte From GARY_REG Space 0x%06x (0x%06x)\n", address, gary_cfg2 & 0x80);
370     return gary_cfg2;
371   }
372   if (address == GARY_REG3) {
373     printf("Read Byte From GARY_REG Space 0x%06x (0x%06x)\n", address, gary_cfg3 & 0x80);
374     return gary_cfg3;
375   }
376   if (address == GARY_REG4) {
377     printf("Read Byte From GARY_REG Space 0x%06x (0x%06x)\n", address, gary_cfg4 & 0x80);
378     return gary_cfg4;
379   }
380   if (address == GARY_REG5) {
381     printf("Read Byte From GARY_REG Space 0x%06x (0x%06x)\n", address, gary_cfg5 & 0x80);
382     return gary_cfg5;
383   }
384
385   if (address == RAMSEY_REG) {
386     printf("Read Byte From RAMSEY_REG Space 0x%06x (0x%06x)\n", address, ramsey_cfg & 0x0f);
387     return ramsey_cfg;
388   }
389
390   if (address == RAMSEY_ID) {
391     printf("Read Byte From RAMSEY_ID Space 0x%06x (0x%06x)\n", address, ramsey_id & 0x0f);
392     return ramsey_id;
393   }
394
395   printf("Read Byte From Gayle Space 0x%06x\n", address);
396   return 0xFF;
397 }
398
399 uint16_t readGayle(unsigned int address) {
400   if (address == GDATA || address == GDATA_A4000) {
401     uint16_t value;
402     value = ide_read16(ide0, ide_data);
403     //  value = (value << 8) | (value >> 8);
404     return value;
405   }
406   if (address == GIRQ_A4000) {
407     //printf("Read Word From GIRQ_A4000 Space 0x%06x\n", address);
408     gayle_a4k_irq = 0x8000;
409     return 0x80FF;
410   }
411   printf("Read Word From Gayle Space 0x%06x\n", address);
412   return 0x8000;
413 }
414
415 uint32_t readGayleL(unsigned int address) {
416   printf("Read Long From Gayle Space 0x%06x\n", address);
417   return 0x8000;
418 }