]> git.sesse.net Git - pistorm/blob - platforms/amiga/amiga-autoconf.c
Add license information to source
[pistorm] / platforms / amiga / amiga-autoconf.c
1 // SPDX-License-Identifier: MIT
2
3 #include "platforms/platforms.h"
4 #include "amiga-autoconf.h"
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8
9 #define Z2_Z2      0xC
10 #define Z2_FAST    0x2
11 #define Z2_BOOTROM 0x1
12
13 static unsigned char ac_fast_ram_rom[] = {
14     Z2_Z2 | Z2_FAST, AC_MEM_SIZE_8MB,       // 00/02, link into memory free list, 8 MB
15     0x6, 0x9,                               // 06/09, product id
16     0x8, 0x0,                               // 08/0a, preference to 8 MB space
17     0x0, 0x0,                               // 0c/0e, reserved
18     0x0, 0x7, 0xD, 0xB,                     // 10/12/14/16, mfg id
19     0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x2, 0x0, // 18/.../26, serial
20     0x0, 0x0, 0x0, 0x0,                     // Optional BOOT ROM vector
21 };
22
23 unsigned char ac_piscsi_rom[] = {
24     Z2_Z2 | Z2_BOOTROM, AC_MEM_SIZE_64KB,   // 00/01, Z2, bootrom, 64 KB
25     0x6, 0xA,                               // 06/0A, product id
26     0x0, 0x0,                               // 00/0a, any space where it fits
27     0x0, 0x0,                               // 0c/0e, reserved
28     0x0, 0x7, 0xD, 0xB,                     // 10/12/14/16, mfg id
29     0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x2, 0x1, // 18/.../26, serial
30     0x4, 0x0, 0x0, 0x0,                     // Optional BOOT ROM vector
31 };
32
33 static unsigned char ac_a314_rom[] = {
34     0xc, AC_MEM_SIZE_64KB,                  // 00/02, 64 kB
35     0xa, 0x3,                               // 04/06, product id
36     0x0, 0x0,                               // 08/0a, any space okay
37     0x0, 0x0,                               // 0c/0e, reserved
38     0x0, 0x7, 0xd, 0xb,                     // 10/12/14/16, mfg id
39     0xa, 0x3, 0x1, 0x4, 0x0, 0x0, 0x0, 0x0, // 18/.../26, serial
40     0x0, 0x0, 0x0, 0x0,                     // Optional BOOT ROM vector
41 };
42
43 int ac_z2_current_pic = 0;
44 int ac_z2_pic_count = 0;
45 int ac_z2_done = 0;
46 int ac_z2_type[AC_PIC_LIMIT];
47 int ac_z2_index[AC_PIC_LIMIT];
48 unsigned int ac_base[AC_PIC_LIMIT];
49
50 int ac_z3_current_pic = 0;
51 int ac_z3_pic_count = 0;
52 int ac_z3_done = 0;
53 int ac_z3_type[AC_PIC_LIMIT];
54 int ac_z3_index[AC_PIC_LIMIT];
55
56 uint32_t piscsi_base = 0;
57 extern uint8_t *piscsi_rom_ptr;
58
59 unsigned char get_autoconf_size(int size) {
60   if (size == 8 * SIZE_MEGA)
61     return AC_MEM_SIZE_8MB;
62   if (size == 4 * SIZE_MEGA)
63     return AC_MEM_SIZE_4MB;
64   if (size == 2 * SIZE_MEGA)
65     return AC_MEM_SIZE_2MB;
66   else
67     return AC_MEM_SIZE_64KB;
68 }
69
70 unsigned char get_autoconf_size_ext(int size) {
71   if (size == 16 * SIZE_MEGA)
72     return AC_MEM_SIZE_EXT_16MB;
73   if (size == 32 * SIZE_MEGA)
74     return AC_MEM_SIZE_EXT_32MB;
75   if (size == 64 * SIZE_MEGA)
76     return AC_MEM_SIZE_EXT_64MB;
77   if (size == 128 * SIZE_MEGA)
78     return AC_MEM_SIZE_EXT_128MB;
79   if (size == 256 * SIZE_MEGA)
80     return AC_MEM_SIZE_EXT_256MB;
81   if (size == 512 * SIZE_MEGA)
82     return AC_MEM_SIZE_EXT_512MB;
83   if (size == 1024 * SIZE_MEGA)
84     return AC_MEM_SIZE_EXT_1024MB;
85   else
86     return AC_MEM_SIZE_EXT_64MB;
87 }
88
89 extern void adjust_ranges_amiga(struct emulator_config *cfg);
90
91 unsigned int autoconfig_read_memory_z3_8(struct emulator_config *cfg, unsigned int address) {
92   int index = ac_z3_index[ac_z3_current_pic];
93   unsigned char val = 0;
94
95   if ((address & 0xFF) >= AC_Z3_REG_RES50 && (address & 0xFF) <= AC_Z3_REG_RES7C) {
96     val = 0;
97   }
98   else {
99     switch(address & 0xFF) {
100       case AC_Z3_REG_ER_TYPE:
101         val |= BOARDTYPE_Z3;
102         if (cfg->map_type[index] == MAPTYPE_RAM)
103           val |= BOARDTYPE_FREEMEM;
104         if (cfg->map_size[index] > 8 * SIZE_MEGA)
105           val |= get_autoconf_size_ext(cfg->map_size[index]);
106         else
107           val |= get_autoconf_size(cfg->map_size[index]);
108         if (ac_z3_current_pic + 1 < ac_z3_pic_count)
109           val |= BOARDTYPE_LINKED;
110         // Pre-invert this value, since it's the only value not physically complemented
111         // for Zorro III.
112         val ^= 0xFF;
113         break;
114       case AC_Z3_REG_ER_PRODUCT:
115         // 1.1... maybe...
116         val = 0x11;
117         break;
118       case AC_Z3_REG_ER_FLAGS:
119         if (cfg->map_type[index] == MAPTYPE_RAM)
120           val |= Z3_FLAGS_MEMORY;
121         if (cfg->map_size[index] > 8 * SIZE_MEGA)
122           val |= Z3_FLAGS_EXTENSION;
123         val |= Z3_FLAGS_RESERVED;
124         // Bottom four bits are zero, useless unles you want really odd RAM sizes.
125         break;
126       // Manufacturer ID low/high bytes.
127       case AC_Z3_REG_MAN_LO:
128         val = PISTORM_MANUF_ID & 0x00FF;
129         break;
130       case AC_Z3_REG_MAN_HI:
131         val = (PISTORM_MANUF_ID >> 8);
132         break;
133       case AC_Z3_REG_SER_BYTE0:
134       case AC_Z3_REG_SER_BYTE1:
135       case AC_Z3_REG_SER_BYTE2:
136       case AC_Z3_REG_SER_BYTE3:
137         // Expansion board serial assigned by manufacturer.
138         val = 0;
139         break;
140       case AC_Z3_REG_INIT_DIAG_VEC_LO:
141       case AC_Z3_REG_INIT_DIAG_VEC_HI:
142         // 16-bit offset to boot ROM in assigned memory range.
143         val = 0;
144         break;
145       // Additional reserved/unused registers.
146       case AC_Z3_REG_ER_RES03:
147       case AC_Z3_REG_ER_RES0D:
148       case AC_Z3_REG_ER_RES0E:
149       case AC_Z3_REG_ER_RES0F:
150       case AC_Z3_REG_ER_Z2_INT:
151         val = 0;
152         break;
153       default:
154         val = 0;
155         break;
156     }
157   }
158   //printf("Read byte %d from Z3 autoconf for PIC %d (%.2X).\n", address, ac_z3_current_pic, val);
159   return (address & 0x100) ? (val << 4) ^ 0xFF : (val & 0xF0) ^ 0xFF;
160 }
161
162 int nib_latch = 0;
163
164 void autoconfig_write_memory_z3_8(struct emulator_config *cfg, unsigned int address, unsigned int value) {
165   int index = ac_z3_index[ac_z3_current_pic];
166   unsigned char val = (unsigned char)value;
167   int done = 0;
168
169   switch(address & 0xFF) {
170     case AC_Z3_REG_WR_ADDR_LO:
171       if (nib_latch) {
172         ac_base[ac_z3_current_pic] = (ac_base[ac_z3_current_pic] & 0xFF0F0000) | ((val & 0xF0) << 16);
173         nib_latch = 0;
174       }
175       else
176         ac_base[ac_z3_current_pic] = (ac_base[ac_z3_current_pic] & 0xFF000000) | (val << 16);
177       break;
178     case AC_Z3_REG_WR_ADDR_HI:
179       if (nib_latch) {
180         ac_base[ac_z3_current_pic] = (ac_base[ac_z3_current_pic] & 0x0FFF0000) | ((val & 0xF0) << 24);
181         nib_latch = 0;
182       }
183       ac_base[ac_z3_current_pic] = (ac_base[ac_z3_current_pic] & 0x00FF0000) | (val << 24);
184       done = 1;
185       break;
186     case AC_Z3_REG_WR_ADDR_NIB_LO:
187       ac_base[ac_z3_current_pic] = (ac_base[ac_z3_current_pic] & 0xFFF00000) | ((val & 0xF0) << 12);
188       nib_latch = 1;
189       break;
190     case AC_Z3_REG_WR_ADDR_NIB_HI:
191       ac_base[ac_z3_current_pic] = (ac_base[ac_z3_current_pic] & 0xF0FF0000) | ((val & 0xF0) << 20);
192       nib_latch = 1;
193       break;
194     case AC_Z3_REG_SHUTUP:
195       //printf("Write to Z3 shutup register for PIC %d.\n", ac_z3_current_pic);
196       done = 1;
197       break;
198     default:
199       break;
200   }
201
202   if (done) {
203     nib_latch = 0;
204     printf("Address of Z3 autoconf RAM assigned to $%.8x [B]\n", ac_base[ac_z3_current_pic]);
205     cfg->map_offset[index] = ac_base[ac_z3_current_pic];
206     cfg->map_high[index] = cfg->map_offset[index] + cfg->map_size[index];
207     m68k_add_ram_range(cfg->map_offset[index], cfg->map_high[index], cfg->map_data[index]);
208     ac_z3_current_pic++;
209     if (ac_z3_current_pic == ac_z3_pic_count) {
210       ac_z3_done = 1;
211       adjust_ranges_amiga(cfg);
212     }
213   }
214
215   return;
216 }
217
218 void autoconfig_write_memory_z3_16(struct emulator_config *cfg, unsigned int address, unsigned int value) {
219   int index = ac_z3_index[ac_z3_current_pic];
220   unsigned short val = (unsigned short)value;
221   int done = 0;
222
223   switch(address & 0xFF) {
224     case AC_Z3_REG_WR_ADDR_HI:
225       // This is, as far as I know, the only register it should write a 16-bit value to.
226       ac_base[ac_z3_current_pic] = (ac_base[ac_z3_current_pic] & 0x00000000) | (val << 16);
227       done = 1;
228       break;
229     default:
230       printf("Unknown WORD write to Z3 autoconf address $%.2X", address & 0xFF);
231       //stop_cpu_emulation();
232       break;
233   }
234
235   if (done) {
236     printf("Address of Z3 autoconf RAM assigned to $%.8x [W]\n", ac_base[ac_z3_current_pic]);
237     cfg->map_offset[index] = ac_base[ac_z3_current_pic];
238     cfg->map_high[index] = cfg->map_offset[index] + cfg->map_size[index];
239     m68k_add_ram_range(cfg->map_offset[index], cfg->map_high[index], cfg->map_data[index]);
240     ac_z3_current_pic++;
241     if (ac_z3_current_pic == ac_z3_pic_count)
242       ac_z3_done = 1;
243   }
244
245   return;
246 }
247
248 unsigned int autoconfig_read_memory_8(struct emulator_config *cfg, unsigned int address) {
249   unsigned char *rom = NULL;
250   unsigned char val = 0;
251
252   switch(ac_z2_type[ac_z2_current_pic]) {
253     case ACTYPE_MAPFAST_Z2:
254       rom = ac_fast_ram_rom;
255       break;
256     case ACTYPE_A314:
257       rom = ac_a314_rom;
258       break;
259     case ACTYPE_PISCSI:
260       rom = ac_piscsi_rom;
261       break;
262     default:
263       return 0;
264       break;
265   }
266
267
268   if ((address & 1) == 0 && (address / 2) < (int)sizeof(ac_fast_ram_rom)) {
269     if (ac_z2_type[ac_z2_current_pic] == ACTYPE_MAPFAST_Z2 && address / 2 == 1) {
270       val = get_autoconf_size(cfg->map_size[ac_z2_index[ac_z2_current_pic]]);
271       if (ac_z2_current_pic + 1 < ac_z2_pic_count)
272         val |= BOARDTYPE_LINKED;
273     }
274     else
275       val = rom[address / 2];
276     //printf("Read byte %d from Z2 autoconf for PIC %d (%.2X).\n", address/2, ac_z2_current_pic, val);
277   }
278   val <<= 4;
279   if (address != 0 && address != 2 && address != 0x40 && address != 0x42)
280     val ^= 0xff;
281
282   return (unsigned int)val;
283 }
284
285 void autoconfig_write_memory_8(struct emulator_config *cfg, unsigned int address, unsigned int value) {
286   int done = 0;
287   int index = ac_z2_index[ac_z2_current_pic];
288
289   unsigned int *base = NULL;
290
291   switch(ac_z2_type[ac_z2_current_pic]) {
292     case ACTYPE_MAPFAST_Z2:
293       base = &ac_base[ac_z2_current_pic];
294       break;
295     case ACTYPE_A314:
296       //base = &a314_base;
297       break;
298     case ACTYPE_PISCSI:
299       base = &piscsi_base;
300       break;
301     default:
302       break;
303   }
304
305   if (!base) {
306     //printf("Failed to set up the base for autoconfig PIC %d.\n", ac_z2_current_pic);
307     done = 1;
308   }
309   else {
310     if (address == 0x4a) {  // base[19:16]
311       *base = (value & 0xf0) << (16 - 4);
312     } else if (address == 0x48) {  // base[23:20]
313       *base &= 0xff0fffff;
314       *base |= (value & 0xf0) << (20 - 4);
315
316       if (ac_z2_type[ac_z2_current_pic] == ACTYPE_MAPFAST_Z2) { // fast ram
317         //a314_set_mem_base_size(*base, cfg->map_size[ac_index[ac_z2_current_pic]]);
318       }
319       done = 1;
320     } else if (address == 0x4c) {  // shut up
321       //printf("Write to Z2 shutup register for PIC %d.\n", ac_z2_current_pic);
322       done = 1;
323     }
324   }
325
326   if (done) {
327     switch (ac_z2_type[ac_z2_current_pic]) {
328       case ACTYPE_MAPFAST_Z2:
329         cfg->map_offset[index] = ac_base[ac_z2_current_pic];
330         cfg->map_high[index] = cfg->map_offset[index] + cfg->map_size[index];
331         printf("Address of Z2 autoconf RAM assigned to $%.8x\n", ac_base[ac_z2_current_pic]);
332         m68k_add_ram_range(cfg->map_offset[index], cfg->map_high[index], cfg->map_data[index]);
333         printf("Z2 PIC %d at $%.8lX-%.8lX, Size: %d MB\n", ac_z2_current_pic, cfg->map_offset[index], cfg->map_high[index], cfg->map_size[index] / SIZE_MEGA);
334         break;
335       case ACTYPE_PISCSI:
336         printf("PiSCSI Z2 device assigned to $%.8x\n", piscsi_base);
337         //m68k_add_rom_range(piscsi_base + (16 * SIZE_KILO), piscsi_base + (32 * SIZE_KILO), piscsi_rom_ptr);
338         break;
339       default:
340         break;
341     }
342     ac_z2_current_pic++;
343     if (ac_z2_current_pic == ac_z2_pic_count) {
344       ac_z2_done = 1;
345       adjust_ranges_amiga(cfg);
346     }
347   }
348 }