9 #include "piscsi-enums.h"
10 #include "../../../config_file/config_file.h"
11 #include "../../../gpio/gpio.h"
13 // Comment this line to restore debug output:
16 struct piscsi_dev devs[8];
17 uint8_t piscsi_cur_drive = 0;
18 uint32_t piscsi_u32[4];
19 uint32_t piscsi_rom_size = 0;
20 uint8_t *piscsi_rom_ptr;
22 extern unsigned char ac_piscsi_rom[];
24 static const char *op_type_names[4] = {
32 for (int i = 0; i < 8; i++) {
34 devs[i].c = devs[i].h = devs[i].s = 0;
37 FILE *in = fopen("./platforms/amiga/piscsi/piscsi.rom", "rb");
39 printf("[PISCSI] Could not open PISCSI Boot ROM file for reading.\n");
40 ac_piscsi_rom[20] = 0;
41 ac_piscsi_rom[21] = 0;
42 ac_piscsi_rom[22] = 0;
43 ac_piscsi_rom[23] = 0;
46 fseek(in, 0, SEEK_END);
47 piscsi_rom_size = ftell(in);
48 fseek(in, 0, SEEK_SET);
49 piscsi_rom_ptr = malloc(piscsi_rom_size);
50 fread(piscsi_rom_ptr, piscsi_rom_size, 1, in);
52 printf("[PISCSI] Loaded Boot ROM.\n");
55 void piscsi_map_drive(char *filename, uint8_t index) {
57 printf("[PISCSI] Drive index %d out of range.\nUnable to map file %s to drive.\n", index, filename);
61 int32_t tmp_fd = open(filename, O_RDWR);
63 printf("[PISCSI] Failed to open file %s, could not map drive %d.\n", filename, index);
67 struct piscsi_dev *d = &devs[index];
69 uint64_t file_size = lseek(tmp_fd, 0, SEEK_END);
70 lseek(tmp_fd, 0, SEEK_SET);
71 printf("[PISCSI] Map %d: [%s] - %llu bytes.\n", index, filename, file_size);
74 d->c = (file_size / 512) / (d->s * d->h);
75 printf("[PISCSI] CHS: %d %d %d\n", d->c, d->h, d->s);
80 void piscsi_unmap_drive(uint8_t index) {
81 if (devs[index].fd != -1) {
82 printf("[PISCSI] Unmapped drive %d.\n", index);
83 close (devs[index].fd);
88 extern struct emulator_config *cfg;
89 extern void stop_cpu_emulation(uint8_t disasm_cur);
91 void handle_piscsi_write(uint32_t addr, uint32_t val, uint8_t type) {
94 struct piscsi_dev *d = &devs[piscsi_cur_drive];
96 switch (addr & 0xFFFF) {
99 printf ("[PISCSI] BUG: Attempted read from unmapped drive %d.\n", piscsi_cur_drive);
102 printf("[PISCSI] %d byte READ from block %d to address %.8X\n", piscsi_u32[1], piscsi_u32[0], piscsi_u32[2]);
103 r = get_mapped_item_by_address(cfg, piscsi_u32[2]);
104 if (r != -1 && cfg->map_type[r] == MAPTYPE_RAM) {
105 printf("[PISCSI] \"DMA\" Read goes to mapped range %d.\n", r);
106 lseek(d->fd, (piscsi_u32[0] * 512), SEEK_SET);
107 read(d->fd, cfg->map_data[r] + piscsi_u32[2] - cfg->map_offset[r], piscsi_u32[1]);
110 printf("[PISCSI] No mapped range found for read.\n");
112 lseek(d->fd, (piscsi_u32[0] * 512), SEEK_SET);
113 for (int i = 0; i < piscsi_u32[1]; i++) {
116 write8(piscsi_u32[2] + i, (uint32_t)c);
121 case PISCSI_CMD_WRITE:
123 printf ("[PISCSI] BUG: Attempted write to unmapped drive %d.\n", piscsi_cur_drive);
126 printf("[PISCSI] %d byte WRITE to block %d to address %.8X\n", piscsi_u32[1], piscsi_u32[0], piscsi_u32[2]);
127 r = get_mapped_item_by_address(cfg, piscsi_u32[2]);
129 printf("[PISCSI] \"DMA\" Write comes from mapped range %d.\n", r);
130 lseek(d->fd, (piscsi_u32[0] * 512), SEEK_SET);
131 write(d->fd, cfg->map_data[r] + piscsi_u32[2] - cfg->map_offset[r], piscsi_u32[1]);
134 printf("[PISCSI] No mapped range found for write.\n");
136 lseek(d->fd, (piscsi_u32[0] * 512), SEEK_SET);
137 for (int i = 0; i < piscsi_u32[1]; i++) {
139 c = read8(piscsi_u32[2] + i);
145 case PISCSI_CMD_ADDR1:
147 printf("[PISCSI] Write to ADDR1: %.8x\n", piscsi_u32[0]);
149 case PISCSI_CMD_ADDR2:
151 printf("[PISCSI] Write to ADDR2: %.8x\n", piscsi_u32[1]);
153 case PISCSI_CMD_ADDR3:
155 printf("[PISCSI] Write to ADDR3: %.8x\n", piscsi_u32[2]);
157 case PISCSI_CMD_ADDR4:
159 printf("[PISCSI] Write to ADDR4: %.8x\n", piscsi_u32[3]);
161 case PISCSI_CMD_DRVNUM:
163 if (val < 10) // Kludge for GiggleDisk
164 piscsi_cur_drive = val;
165 else if (val >= 10 && val % 10 != 0)
166 piscsi_cur_drive = 255;
168 piscsi_cur_drive = val / 10;
171 piscsi_cur_drive = val;
172 printf("[PISCSI] (%s) Drive number set to %d (%d)\n", op_type_names[type], piscsi_cur_drive, val);
174 case PISCSI_CMD_DEBUGME:
175 printf("[PISCSI] DebugMe triggered.\n");
176 stop_cpu_emulation(1);
178 case PISCSI_CMD_DRIVER: {
179 printf("[PISCSI] Driver copy/patch called, destination address %.8X.\n", val);
180 int r = get_mapped_item_by_address(cfg, val);
182 uint32_t addr = val - cfg->map_offset[r];
183 uint32_t rt_offs = 0;
184 uint8_t *dst_data = cfg->map_data[r];
185 memcpy(dst_data + addr, piscsi_rom_ptr + 0x400, 0x3C00);
187 uint32_t base_offs = be32toh(*((uint32_t *)&dst_data[addr + 0x170])) + 2;
188 rt_offs = val + 0x16E;
189 printf ("Offset 1: %.8X -> %.8X\n", base_offs, rt_offs);
190 *((uint32_t *)&dst_data[addr + 0x170]) = htobe32(rt_offs);
192 uint32_t offs = be32toh(*((uint32_t *)&dst_data[addr + 0x174]));
193 printf ("Offset 2: %.8X -> %.8X\n", offs, (offs - base_offs) + rt_offs);
194 *((uint32_t *)&dst_data[addr + 0x174]) = htobe32((offs - base_offs) + rt_offs);
196 dst_data[addr + 0x178] |= 0x07;
198 offs = be32toh(*((uint32_t *)&dst_data[addr + 0x17C]));
199 printf ("Offset 3: %.8X -> %.8X\n", offs, (offs - base_offs) + rt_offs);
200 *((uint32_t *)&dst_data[addr + 0x17C]) = htobe32((offs - base_offs) + rt_offs);
202 offs = be32toh(*((uint32_t *)&dst_data[addr + 0x180]));
203 printf ("Offset 4: %.8X -> %.8X\n", offs, (offs - base_offs) + rt_offs);
204 *((uint32_t *)&dst_data[addr + 0x180]) = htobe32((offs - base_offs) + rt_offs);
206 offs = be32toh(*((uint32_t *)&dst_data[addr + 0x184]));
207 printf ("Offset 5: %.8X -> %.8X\n", offs, (offs - base_offs) + rt_offs);
208 *((uint32_t *)&dst_data[addr + 0x184]) = htobe32((offs - base_offs) + rt_offs);
212 for (int i = 0; i < 0x3C00; i++) {
213 uint8_t src = piscsi_rom_ptr[0x400 + i];
214 write8(addr + i, src);
220 printf("[PISCSI] Unhandled %s register write to %.8X: %d\n", op_type_names[type], addr, val);
225 uint8_t piscsi_diag_area[] = {
236 uint8_t fastata_diag_area[] = {
247 uint8_t piscsi_diag_read;
251 uint32_t handle_piscsi_read(uint32_t addr, uint8_t type) {
253 uint8_t *diag_area = piscsi_diag_area;
255 if ((addr & 0xFFFF) >= PISCSI_CMD_ROM) {
256 uint32_t romoffs = (addr & 0xFFFF) - PISCSI_CMD_ROM;
257 /*if (romoffs < 14 && !piscsi_diag_read) {
258 printf("[PISCSI] %s read from DiagArea @$%.4X: ", op_type_names[type], romoffs);
262 v = diag_area[romoffs];
266 v = *((uint16_t *)&diag_area[romoffs]);
269 case OP_TYPE_LONGWORD:
270 v = (*((uint16_t *)&diag_area[romoffs]) << 16) | *((uint16_t *)&diag_area[romoffs + 2]);
271 //v = *((uint32_t *)&diag_area[romoffs]);
276 piscsi_diag_read = 1;
279 if (romoffs < (piscsi_rom_size + PIB)) {
280 printf("[PISCSI] %s read from Boot ROM @$%.4X (%.8X): ", op_type_names[type], romoffs, addr);
284 v = piscsi_rom_ptr[romoffs - PIB];
288 v = be16toh(*((uint16_t *)&piscsi_rom_ptr[romoffs - PIB]));
291 case OP_TYPE_LONGWORD:
292 //v = (*((uint16_t *)&piscsi_rom_ptr[romoffs - 14]) << 16) | *((uint16_t *)&piscsi_rom_ptr[romoffs - 12]);
293 v = be32toh(*((uint32_t *)&piscsi_rom_ptr[romoffs - PIB]));
302 switch (addr & 0xFFFF) {
303 case PISCSI_CMD_DRVTYPE:
304 if (devs[piscsi_cur_drive].fd == -1) {
305 printf("[PISCSI] %s Read from DRVTYPE %d, drive not attached.\n", op_type_names[type], piscsi_cur_drive);
308 printf("[PISCSI] %s Read from DRVTYPE %d, drive attached.\n", op_type_names[type], piscsi_cur_drive);
311 case PISCSI_CMD_DRVNUM:
312 return piscsi_cur_drive;
314 case PISCSI_CMD_CYLS:
315 printf("[PISCSI] %s Read from CYLS %d: %d\n", op_type_names[type], piscsi_cur_drive, devs[piscsi_cur_drive].c);
316 return devs[piscsi_cur_drive].c;
318 case PISCSI_CMD_HEADS:
319 printf("[PISCSI] %s Read from HEADS %d: %d\n", op_type_names[type], piscsi_cur_drive, devs[piscsi_cur_drive].h);
320 return devs[piscsi_cur_drive].h;
322 case PISCSI_CMD_SECS:
323 printf("[PISCSI] %s Read from SECS %d: %d\n", op_type_names[type], piscsi_cur_drive, devs[piscsi_cur_drive].s);
324 return devs[piscsi_cur_drive].s;
326 case PISCSI_CMD_BLOCKS: {
327 uint32_t blox = devs[piscsi_cur_drive].fs / 512;
328 printf("[PISCSI] %s Read from BLOCKS %d: %d\n", op_type_names[type], piscsi_cur_drive, (uint32_t)(devs[piscsi_cur_drive].fs / 512));
329 printf("fs: %lld (%d)\n", devs[piscsi_cur_drive].fs, blox);
334 printf("[PISCSI] Unhandled %s register read from %.8X\n", op_type_names[type], addr);
341 void piscsi_block_op(uint8_t type, uint8_t num, uint32_t dest, uint32_t len) {
342 if (type || num || dest || len) {}