]> git.sesse.net Git - pistorm/blob - platforms/amiga/piscsi/piscsi.c
[WIP] PiSCSI, Pi-NET and some other things
[pistorm] / platforms / amiga / piscsi / piscsi.c
1 #include <stdio.h>
2 #include <stdint.h>
3 #include <fcntl.h>
4 #include <unistd.h>
5 #include <endian.h>
6 #include "piscsi.h"
7 #include "piscsi-enums.h"
8 #include "../../../config_file/config_file.h"
9 #include "../../../gpio/gpio.h"
10
11 struct piscsi_dev devs[8];
12 uint8_t piscsi_cur_drive = 0;
13 uint32_t piscsi_u32[4];
14
15 static const char *op_type_names[4] = {
16     "BYTE",
17     "WORD",
18     "LONGWORD",
19     "MEM",
20 };
21
22 void piscsi_init() {
23     for (int i = 0; i < 8; i++) {
24         devs[i].fd = -1;
25         devs[i].c = devs[i].h = devs[i].s = 0;
26     }
27 }
28
29 void piscsi_map_drive(char *filename, uint8_t index) {
30     if (index > 7) {
31         printf("[PISCSI] Drive index %d out of range.\nUnable to map file %s to drive.\n", index, filename);
32         return;
33     }
34
35     int32_t tmp_fd = open(filename, O_RDWR);
36     if (tmp_fd == -1) {
37         printf("[PISCSI] Failed to open file %s, could not map drive %d.\n", filename, index);
38         return;
39     }
40
41     struct piscsi_dev *d = &devs[index];
42
43     uint64_t file_size = lseek(tmp_fd, 0, SEEK_END);
44     lseek(tmp_fd, 0, SEEK_SET);
45     printf("[PISCSI] Map %d: [%s] - %llu bytes.\n", index, filename, file_size);
46     d->h = 64;
47     d->s = 63;
48     d->c = (file_size / 512) / (d->s * d->h);
49     printf("[PISCSI] CHS: %d %d %d\n", d->c, d->h, d->s);
50     d->fs = file_size;
51     d->fd = tmp_fd;
52 }
53
54 void piscsi_unmap_drive(uint8_t index) {
55     if (devs[index].fd != -1) {
56         printf("[PISCSI] Unmapped drive %d.\n", index);
57         close (devs[index].fd);
58         devs[index].fd = -1;
59     }
60 }
61
62 extern struct emulator_config *cfg;
63
64 void handle_piscsi_write(uint32_t addr, uint32_t val, uint8_t type) {
65     int32_t r;
66
67     struct piscsi_dev *d = &devs[piscsi_cur_drive];
68
69     switch (addr & 0xFFFF) {
70         case PISCSI_CMD_READ:
71             if (d->fd == -1) {
72                 printf ("[PISCSI] BUG: Attempted read from unmapped drive %d.\n", piscsi_cur_drive);
73                 break;
74             }
75             printf("[PISCSI] %d byte READ from block %d to address %.8X\n", piscsi_u32[1], piscsi_u32[0], piscsi_u32[2]);
76             r = get_mapped_item_by_address(cfg, piscsi_u32[2]);
77             if (r != -1 && cfg->map_type[r] == MAPTYPE_RAM) {
78                 printf("[PISCSI] \"DMA\" Read goes to mapped range %d.\n", r);
79                 lseek(d->fd, (piscsi_u32[0] * 512), SEEK_SET);
80                 read(d->fd, cfg->map_data[r] + piscsi_u32[2] - cfg->map_offset[r], piscsi_u32[1]);
81             }
82             else {
83                 printf("[PISCSI] No mapped range found for read.\n");
84                 uint8_t c = 0;
85                 lseek(d->fd, (piscsi_u32[0] * 512), SEEK_SET);
86                 for (int i = 0; i < piscsi_u32[1]; i++) {
87                     read(d->fd, &c, 1);
88 #ifndef FAKESTORM
89                     write8(piscsi_u32[2] + i, (uint32_t)c);
90 #endif
91                 }
92             }
93             break;
94         case PISCSI_CMD_WRITE:
95             if (d->fd == -1) {
96                 printf ("[PISCSI] BUG: Attempted write to unmapped drive %d.\n", piscsi_cur_drive);
97                 break;
98             }
99             printf("[PISCSI] %d byte WRITE to block %d to address %.8X\n", piscsi_u32[1], piscsi_u32[0], piscsi_u32[2]);
100             r = get_mapped_item_by_address(cfg, piscsi_u32[2]);
101             if (r != -1) {
102                 printf("[PISCSI] \"DMA\" Write comes from mapped range %d.\n", r);
103                 lseek(d->fd, (piscsi_u32[0] * 512), SEEK_SET);
104                 write(d->fd, cfg->map_data[r] + piscsi_u32[2] - cfg->map_offset[r], piscsi_u32[1]);
105             }
106             else {
107                 printf("[PISCSI] No mapped range found for write.\n");
108                 uint8_t c = 0;
109                 lseek(d->fd, (piscsi_u32[0] * 512), SEEK_SET);
110                 for (int i = 0; i < piscsi_u32[1]; i++) {
111 #ifndef FAKESTORM
112                     c = read8(piscsi_u32[2] + i);
113 #endif
114                     write(d->fd, &c, 1);
115                 }
116             }
117             break;
118         case PISCSI_CMD_ADDR1:
119             piscsi_u32[0] = val;
120             printf("[PISCSI] Write to ADDR1: %.8x\n", piscsi_u32[0]);
121             break;
122         case PISCSI_CMD_ADDR2:
123             piscsi_u32[1] = val;
124             printf("[PISCSI] Write to ADDR2: %.8x\n", piscsi_u32[1]);
125             break;
126         case PISCSI_CMD_ADDR3:
127             piscsi_u32[2] = val;
128             printf("[PISCSI] Write to ADDR3: %.8x\n", piscsi_u32[2]);
129             break;
130         case PISCSI_CMD_ADDR4:
131             piscsi_u32[3] = val;
132             printf("[PISCSI] Write to ADDR4: %.8x\n", piscsi_u32[3]);
133             break;
134         case PISCSI_CMD_DRVNUM:
135             if (val != 0) {
136                 if (val < 10) // Kludge for GiggleDisk
137                     piscsi_cur_drive = val;
138                 else if (val >= 10 && val % 10 != 0)
139                     piscsi_cur_drive = 255;
140                 else
141                     piscsi_cur_drive = val / 10;
142             }
143             else
144                 piscsi_cur_drive = val;
145             printf("[PISCSI] (%s) Drive number set to %d (%d)\n", op_type_names[type], piscsi_cur_drive, val);
146             break;
147         default:
148             printf("[PISCSI] Unhandled %s register write to %.8X: %d\n", op_type_names[type], addr, val);
149             break;
150     }
151 }
152
153 uint32_t handle_piscsi_read(uint32_t addr, uint8_t type) {
154     if (type) {}
155     
156     switch (addr & 0xFFFF) {
157         case PISCSI_CMD_DRVTYPE:
158             if (devs[piscsi_cur_drive].fd == -1) {
159                 printf("[PISCSI] %s Read from DRVTYPE %d, drive not attached.\n", op_type_names[type], piscsi_cur_drive);
160                 return 0;
161             }
162             printf("[PISCSI] %s Read from DRVTYPE %d, drive attached.\n", op_type_names[type], piscsi_cur_drive);
163             return 1;
164             break;
165         case PISCSI_CMD_DRVNUM:
166             return piscsi_cur_drive;
167             break;
168         case PISCSI_CMD_CYLS:
169             printf("[PISCSI] %s Read from CYLS %d: %d\n", op_type_names[type], piscsi_cur_drive, devs[piscsi_cur_drive].c);
170             return devs[piscsi_cur_drive].c;
171             break;
172         case PISCSI_CMD_HEADS:
173             printf("[PISCSI] %s Read from HEADS %d: %d\n", op_type_names[type], piscsi_cur_drive, devs[piscsi_cur_drive].h);
174             return devs[piscsi_cur_drive].h;
175             break;
176         case PISCSI_CMD_SECS:
177             printf("[PISCSI] %s Read from SECS %d: %d\n", op_type_names[type], piscsi_cur_drive, devs[piscsi_cur_drive].s);
178             return devs[piscsi_cur_drive].s;
179             break;
180         case PISCSI_CMD_BLOCKS: {
181             uint32_t blox = devs[piscsi_cur_drive].fs / 512;
182             printf("[PISCSI] %s Read from BLOCKS %d: %d\n", op_type_names[type], piscsi_cur_drive, (uint32_t)(devs[piscsi_cur_drive].fs / 512));
183             printf("fs: %lld (%d)\n", devs[piscsi_cur_drive].fs, blox);
184             return blox;
185             break;
186         }
187         default:
188             printf("[PISCSI] Unhandled %s register read from %.8X\n", op_type_names[type], addr);
189             break;
190     }
191
192     return 0;
193 }
194
195 void piscsi_block_op(uint8_t type, uint8_t num, uint32_t dest, uint32_t len) {
196     if (type || num || dest || len) {}
197 }