|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator
3: *
1.1.1.5 root 4: * Hardfile emulation
1.1 root 5: *
1.1.1.5 root 6: * Copyright 1995 Bernd Schmidt
1.1 root 7: */
8:
9: #include "sysconfig.h"
10: #include "sysdeps.h"
11:
12: #include "options.h"
13: #include "memory.h"
14: #include "custom.h"
15: #include "newcpu.h"
16: #include "disk.h"
1.1.1.8 root 17: #include "traps.h"
1.1 root 18: #include "autoconf.h"
1.1.1.2 root 19: #include "execlib.h"
1.1.1.9 ! root 20: #include "filesys.h"
! 21:
! 22: #define CMD_INVALID 0
! 23: #define CMD_RESET 1
! 24: #define CMD_READ 2
! 25: #define CMD_WRITE 3
! 26: #define CMD_UPDATE 4
! 27: #define CMD_CLEAR 5
! 28: #define CMD_STOP 6
! 29: #define CMD_START 7
! 30: #define CMD_FLUSH 8
! 31: #define CMD_MOTOR 9
! 32: #define CMD_SEEK 10
! 33: #define CMD_FORMAT 11
! 34: #define CMD_REMOVE 12
! 35: #define CMD_CHANGENUM 13
! 36: #define CMD_CHANGESTATE 14
! 37: #define CMD_PROTSTATUS 15
! 38: #define CMD_GETDRIVETYPE 18
! 39: #define CMD_GETNUMTRACKS 19
! 40: #define CMD_ADDCHANGEINT 20
! 41: #define CMD_REMCHANGEINT 21
! 42: #define CMD_GETGEOMETRY 22
! 43:
! 44: /* Trackdisk64 support */
! 45: #define TD_READ64 24
! 46: #define TD_WRITE64 25
! 47: #define TD_SEEK64 26
! 48: #define TD_FORMAT64 27
! 49:
! 50: /* New Style Devices (NSD) support */
! 51: #define DRIVE_NEWSTYLE 0x4E535459L /* 'NSTY' */
! 52: #define NSCMD_DEVICEQUERY 0x4000
! 53: #define NSCMD_TD_READ64 0xc000
! 54: #define NSCMD_TD_WRITE64 0xc001
! 55: #define NSCMD_TD_SEEK64 0xc002
! 56: #define NSCMD_TD_FORMAT64 0xc003
1.1 root 57:
58: static int opencount = 0;
59:
1.1.1.9 ! root 60: static uae_u32 nscmd_cmd;
! 61:
! 62: int hdf_read (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len)
! 63: {
! 64: int result = 0;
! 65:
! 66: if (fseek (hfd->fd, offset, SEEK_SET) != 0)
! 67: return 0;
! 68: do {
! 69: int t = fread (buffer, 1, len, hfd->fd);
! 70: result += t;
! 71: len -= t;
! 72: if (t == 0)
! 73: return result;
! 74: } while (len > 0);
! 75: return result;
! 76: }
! 77:
! 78: int hdf_write (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len)
! 79: {
! 80: int result = 0;
! 81:
! 82: if (fseek (hfd->fd, offset, SEEK_SET) != 0)
! 83: return 0;
! 84: do {
! 85: int t = fwrite (buffer, 1, len, hfd->fd);
! 86: result += t;
! 87: len -= t;
! 88: if (t == 0)
! 89: return result;
! 90: } while (len > 0);
! 91: return result;
! 92: }
! 93:
! 94: static uae_u64 cmd_readx (struct hardfiledata *hfd, uae_u8 *dataptr, uae_u64 offset, uae_u64 len)
! 95: {
! 96: return hdf_read (hfd, dataptr, offset, len);
! 97: }
! 98: static uae_u64 cmd_read (struct hardfiledata *hfd, uaecptr dataptr, uae_u64 offset, uae_u64 len)
! 99: {
! 100: addrbank *bank_data = &get_mem_bank (dataptr);
! 101: if (!bank_data || !bank_data->check (dataptr, len))
! 102: return 0;
! 103: return cmd_readx (hfd, bank_data->xlateaddr (dataptr), offset, len);
! 104: }
! 105: static uae_u64 cmd_writex (struct hardfiledata *hfd, uae_u8 *dataptr, uae_u64 offset, uae_u64 len)
! 106: {
! 107: return hdf_write (hfd, dataptr, offset, len);
! 108: }
! 109:
! 110: static uae_u64 cmd_write (struct hardfiledata *hfd, uaecptr dataptr, uae_u64 offset, uae_u64 len)
! 111: {
! 112: addrbank *bank_data = &get_mem_bank (dataptr);
! 113: if (!bank_data || !bank_data->check (dataptr, len))
! 114: return 0;
! 115: return cmd_writex (hfd, bank_data->xlateaddr (dataptr), offset, len);
! 116: }
! 117:
1.1.1.8 root 118: static uae_u32 hardfile_open (TrapContext *dummy)
1.1 root 119: {
1.1.1.8 root 120: uaecptr tmp1 = m68k_areg (regs, 1); /* IOReq */
1.1 root 121:
122: /* Check unit number */
1.1.1.3 root 123: if (get_hardfile_data (m68k_dreg (regs, 0))) {
1.1 root 124: opencount++;
1.1.1.8 root 125: put_word (m68k_areg (regs, 6)+32, get_word (m68k_areg (regs, 6)+32) + 1);
1.1.1.4 root 126: put_long (tmp1 + 24, m68k_dreg (regs, 0)); /* io_Unit */
127: put_byte (tmp1 + 31, 0); /* io_Error */
128: put_byte (tmp1 + 8, 7); /* ln_type = NT_REPLYMSG */
1.1 root 129: return 0;
130: }
131:
1.1.1.4 root 132: put_long (tmp1 + 20, (uae_u32)-1);
133: put_byte (tmp1 + 31, (uae_u8)-1);
1.1.1.3 root 134: return (uae_u32)-1;
1.1 root 135: }
136:
1.1.1.8 root 137: static uae_u32 hardfile_close (TrapContext *dummy)
1.1 root 138: {
139: opencount--;
1.1.1.8 root 140: put_word (m68k_areg (regs, 6) + 32, get_word (m68k_areg (regs, 6) + 32) - 1);
1.1 root 141:
1.1.1.2 root 142: return 0;
1.1 root 143: }
144:
1.1.1.8 root 145: static uae_u32 hardfile_expunge (TrapContext *dummy)
1.1 root 146: {
147: return 0; /* Simply ignore this one... */
148: }
149:
1.1.1.8 root 150: static uae_u32 hardfile_beginio (TrapContext *dummy)
1.1 root 151: {
1.1.1.9 ! root 152: uae_u32 request, len, dataptr, offset, actual = 0, cmd;
1.1.1.8 root 153: uae_u32 retval = m68k_dreg (regs, 0);
1.1.1.3 root 154: int unit;
155: struct hardfiledata *hfd;
1.1 root 156:
1.1.1.9 ! root 157: request = m68k_areg (regs, 1);
! 158: unit = get_long (request + 24);
1.1.1.3 root 159: #undef DEBUGME
160: #ifdef DEBUGME
161: printf ("hardfile: unit = %d\n", unit);
1.1.1.9 ! root 162: printf ("hardfile: request = %08lx\n", (unsigned long)request);
! 163: printf ("hardfile: cmd = %d\n", (int)get_word (request + 28));
1.1.1.3 root 164: #endif
165: hfd = get_hardfile_data (unit);
166:
1.1.1.9 ! root 167: put_byte (request + 8, NT_MESSAGE);
! 168: put_byte (request + 31, 0); /* no error yet */
! 169: cmd = get_word (request + 28); /* io_Command */
! 170: /* put_byte (request + 30, get_byte (request + 30) & ~1);*/
! 171: dataptr = get_long (request + 40);
! 172:
! 173: switch (cmd) {
1.1.1.2 root 174: case CMD_READ:
1.1 root 175: if (dataptr & 1)
176: goto bad_command;
1.1.1.9 ! root 177: offset = get_long (request + 44);
1.1 root 178: if (offset & 511)
179: goto bad_command;
1.1.1.9 ! root 180: len = get_long (request + 36); /* io_Length */
! 181: if (len & 511)
1.1 root 182: goto bad_command;
1.1.1.9 ! root 183: if (len + offset > (uae_u32)hfd->size)
1.1 root 184: goto bad_command;
185:
1.1.1.9 ! root 186: actual = (uae_u32)cmd_read (hfd, dataptr, offset, len);
! 187: put_long (request + 32, actual);
1.1 root 188: break;
189:
1.1.1.2 root 190: case CMD_WRITE:
1.1.1.9 ! root 191: case CMD_FORMAT:
1.1 root 192: if (dataptr & 1)
193: goto bad_command;
1.1.1.9 ! root 194: offset = get_long (request + 44);
1.1 root 195: if (offset & 511)
196: goto bad_command;
1.1.1.9 ! root 197: len = get_long (request + 36); /* io_Length */
! 198: if (len & 511)
1.1 root 199: goto bad_command;
1.1.1.9 ! root 200: if (len + offset > (uae_u32)hfd->size)
1.1 root 201: goto bad_command;
202:
1.1.1.9 ! root 203: actual = (uae_u32)cmd_write (hfd, dataptr, offset, len);
! 204: put_long (request + 32, actual); /* set io_Actual */
1.1 root 205: break;
206:
207: bad_command:
208: break;
209:
1.1.1.9 ! root 210: case NSCMD_DEVICEQUERY:
! 211: put_long (dataptr + 4, 16); /* size */
! 212: put_word (dataptr + 8, 5); /* NSDEVTYPE_TRACKDISK */
! 213: put_word (dataptr + 10, 0);
! 214: put_long (dataptr + 12, nscmd_cmd);
! 215: put_long (request + 32, 16);
! 216: break;
! 217:
! 218: case CMD_GETDRIVETYPE:
1.1.1.3 root 219: printf ("Shouldn't happen\n");
1.1.1.9 ! root 220: put_long (request + 32, 1); /* not exactly a 3.5" drive, but... */
1.1 root 221: break;
222:
1.1.1.9 ! root 223: case CMD_GETNUMTRACKS:
1.1.1.3 root 224: printf ("Shouldn't happen 2\n");
1.1.1.9 ! root 225: put_long (request + 32, 0);
1.1 root 226: break;
227:
228: /* Some commands that just do nothing and return zero */
1.1.1.2 root 229: case CMD_UPDATE:
230: case CMD_CLEAR:
1.1 root 231: case 9: /* Motor */
232: case 10: /* Seek */
233: case 12: /* Remove */
234: case 13: /* ChangeNum */
235: case 14: /* ChangeStatus */
236: case 15: /* ProtStatus */
237: case 20: /* AddChangeInt */
238: case 21: /* RemChangeInt */
1.1.1.9 ! root 239: put_long (request + 32, 0); /* io_Actual */
1.1 root 240: retval = 0;
241: break;
242:
243: default:
244: /* Command not understood. */
1.1.1.9 ! root 245: put_byte (request + 31, (uae_u8)-3); /* io_Error */
1.1 root 246: retval = 0;
247: break;
248: }
1.1.1.3 root 249: #if 0
1.1.1.9 ! root 250: if ((get_byte (request + 30) & 1) == 0) {
1.1 root 251: /* Not IOF_QUICK -- need to ReplyMsg */
1.1.1.9 ! root 252: m68k_areg (regs, 1) = request;
1.1.1.8 root 253: CallLib (get_long (4), -378);
1.1 root 254: }
1.1.1.3 root 255: #endif
1.1 root 256: return retval;
257: }
258:
1.1.1.8 root 259: static uae_u32 hardfile_abortio (TrapContext *dummy)
1.1 root 260: {
1.1.1.3 root 261: return (uae_u32)-3;
1.1 root 262: }
263:
1.1.1.4 root 264: void hardfile_install (void)
1.1 root 265: {
1.1.1.4 root 266: uae_u32 functable, datatable;
1.1.1.3 root 267: uae_u32 initcode, openfunc, closefunc, expungefunc;
268: uae_u32 beginiofunc, abortiofunc;
1.1 root 269:
1.1.1.4 root 270: ROM_hardfile_resname = ds ("uaehf.device");
271: ROM_hardfile_resid = ds ("UAE hardfile.device 0.2");
1.1 root 272:
1.1.1.9 ! root 273: nscmd_cmd = here ();
! 274: dw (CMD_READ);
! 275: dw (CMD_WRITE);
! 276: dw (CMD_FORMAT);
! 277: dw (NSCMD_DEVICEQUERY);
! 278: dw (CMD_GETDRIVETYPE);
! 279: dw (CMD_CLEAR);
! 280: dw (CMD_UPDATE);
! 281: dw (CMD_MOTOR);
! 282: dw (CMD_SEEK);
! 283: dw (CMD_CHANGENUM);
! 284: dw (CMD_CHANGESTATE);
! 285: dw (CMD_PROTSTATUS);
! 286: dw (CMD_ADDCHANGEINT);
! 287: dw (CMD_REMCHANGEINT);
! 288: dw (0);
! 289:
1.1 root 290: /* initcode */
1.1.1.3 root 291: #if 0
1.1.1.4 root 292: initcode = here ();
293: calltrap (deftrap (hardfile_init)); dw (RTS);
1.1.1.3 root 294: #else
295: initcode = filesys_initcode;
296: #endif
1.1 root 297: /* Open */
1.1.1.4 root 298: openfunc = here ();
299: calltrap (deftrap (hardfile_open)); dw (RTS);
1.1 root 300:
301: /* Close */
1.1.1.4 root 302: closefunc = here ();
303: calltrap (deftrap (hardfile_close)); dw (RTS);
1.1 root 304:
305: /* Expunge */
1.1.1.4 root 306: expungefunc = here ();
307: calltrap (deftrap (hardfile_expunge)); dw (RTS);
1.1 root 308:
309: /* BeginIO */
1.1.1.4 root 310: beginiofunc = here ();
311: calltrap (deftrap (hardfile_beginio));
1.1.1.3 root 312: dw (0x48E7); dw (0x8002); /* movem.l d0/a6,-(a7) */
313: dw (0x0829); dw (0); dw (30); /* btst #0,30(a1) */
314: dw (0x6608); /* bne.b +8 */
315: dw (0x2C78); dw (0x0004); /* move.l 4,a6 */
316: dw (0x4EAE); dw (-378); /* jsr ReplyMsg(a6) */
317: dw (0x4CDF); dw (0x4001); /* movem.l (a7)+,d0/a6 */
1.1.1.4 root 318: dw (RTS);
1.1 root 319:
320: /* AbortIO */
1.1.1.4 root 321: abortiofunc = here ();
322: calltrap (deftrap (hardfile_abortio)); dw (RTS);
1.1 root 323:
324: /* FuncTable */
1.1.1.4 root 325: functable = here ();
326: dl (openfunc); /* Open */
327: dl (closefunc); /* Close */
328: dl (expungefunc); /* Expunge */
329: dl (EXPANSION_nullfunc); /* Null */
330: dl (beginiofunc); /* BeginIO */
331: dl (abortiofunc); /* AbortIO */
332: dl (0xFFFFFFFFul); /* end of table */
1.1 root 333:
334: /* DataTable */
1.1.1.4 root 335: datatable = here ();
336: dw (0xE000); /* INITBYTE */
337: dw (0x0008); /* LN_TYPE */
338: dw (0x0300); /* NT_DEVICE */
339: dw (0xC000); /* INITLONG */
340: dw (0x000A); /* LN_NAME */
341: dl (ROM_hardfile_resname);
342: dw (0xE000); /* INITBYTE */
343: dw (0x000E); /* LIB_FLAGS */
344: dw (0x0600); /* LIBF_SUMUSED | LIBF_CHANGED */
345: dw (0xD000); /* INITWORD */
346: dw (0x0014); /* LIB_VERSION */
347: dw (0x0004); /* 0.4 */
348: dw (0xD000);
349: dw (0x0016); /* LIB_REVISION */
350: dw (0x0000);
351: dw (0xC000);
352: dw (0x0018); /* LIB_IDSTRING */
353: dl (ROM_hardfile_resid);
354: dw (0x0000); /* end of table */
355:
356: ROM_hardfile_init = here ();
357: dl (0x00000100); /* ??? */
358: dl (functable);
359: dl (datatable);
360: dl (initcode);
1.1 root 361: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.