HFS.java
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28: package xeij;
29:
30: import java.awt.event.*;
31: import java.io.*;
32: import java.lang.*;
33: import java.util.*;
34: import javax.swing.*;
35:
36: public class HFS {
37:
38: public static final boolean HFS_DEBUG_TRACE = false;
39: public static final boolean HFS_DEBUG_FILE_INFO = false;
40:
41: public static final boolean HFS_REPORT_INCOMPATIBLE_COMMAND = false;
42:
43:
44: public static final boolean HFS_COMMAND_TRACE = false;
45: public static boolean hfsCommandTraceOn;
46:
47:
48: public static final boolean HFS_USE_THREAD = true;
49: public static final long HFS_THREAD_DELAY = 0L;
50: public static java.util.Timer hfsTimer;
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80: public static final int HFS_STATE_IDLE = 0;
81: public static final int HFS_STATE_X68K = 1;
82: public static final int HFS_STATE_HOST = 2;
83: public static final int HFS_STATE_BUSY = 3;
84: public static final int HFS_STATE_DONE = 4;
85: public static int hfsState;
86:
87:
88: public static final boolean HFS_BUFFER_TRACE = false;
89: public static final int HFS_BUFFER_SIZE = 1024 * 64;
90:
91:
92:
93:
94: public static final int HFS_BUFFER_STEP = 128;
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121: public static final int HFS_ADDRESS = 0x00e9f020;
122: public static final int HFS_BOOT_HANDLE = HFS_ADDRESS + 0;
123: public static final int HFS_INSTALL_HANDLE = HFS_ADDRESS + 4;
124: public static final int HFS_INSTALL_PARAMETER = HFS_ADDRESS + 8;
125: public static final int HFS_HUMAN68K_MAGIC = HFS_ADDRESS + 12;
126: public static final int HFS_BOOT_ROUTINE = HFS_ADDRESS + 20;
127: public static final int HFS_INSTALL_ROUTINE = HFS_ADDRESS + 24;
128: public static final int HFS_MAGIC = HFS_ADDRESS + 28;
129: public static final int HFS_ROM_SIZE = 32;
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144: public static final int HFS_NEXT_DEVICE = 0;
145: public static final int HFS_DEVICE_TYPE = 4;
146: public static final int HFS_STRATEGY_HANDLE = 6;
147: public static final int HFS_INTERRUPT_HANDLE = 10;
148: public static final int HFS_DEVICE_NAME = 14;
149: public static final int HFS_DRIVE_NUMBER = 22;
150: public static final int HFS_STRATEGY_ROUTINE = 24;
151: public static final int HFS_INTERRUPT_ROUTINE = 28;
152: public static final int HFS_DEVICE_SIZE = 32;
153:
154:
155: public static final int HFS_MIN_UNITS = 1;
156: public static final int HFS_MAX_UNITS = 16;
157: public static final String HFS_DUMMY_UNIT_NAME = "*HFS*";
158: public static final HFUnit[] hfsUnitArray = new HFUnit[HFS_MAX_UNITS];
159: public static int hfsBootUnit;
160: public static final int[] hfsDeviceUnitArray = new int[HFS_MAX_UNITS];
161: public static int hfsDeviceUnitCount;
162:
163:
164: public static JMenu hfsMenu;
165:
166:
167: public static javax.swing.filechooser.FileFilter hfsFileFilter;
168:
169:
170: public static OpenDialog hfsOpenDialog;
171: public static int hfsOpenUnit;
172: public static ArrayList<File[]> hfsOpenHistory;
173:
174:
175: public static int hfsDeviceHeader;
176: public static int hfsRequestHeader;
177: public static int hfsRequest1Number;
178: public static int hfsRequest2Command;
179: public static int hfsRequest13Mode;
180: public static int hfsRequest14Namests;
181: public static int hfsRequest18Param;
182: public static int hfsRequest22Fcb;
183: public static int hfsRequest3Error;
184: public static int hfsRequest18Result;
185: public static HFUnit hfsRequestUnit;
186:
187:
188:
189: public static final boolean HFS_USE_TWENTY_ONE = false;
190: public static final int HFS_TW_VERBOSE_MODE = 1 << 31;
191: public static final int HFS_TW_CASE_SENSITIVE = 1 << 30;
192: public static final int HFS_TW_SPECIAL_CHARACTER = 1 << 29;
193: public static final int HFS_TW_MULTI_PERIOD = 1 << 28;
194: public static final int HFS_TW_NOT_TWENTY_ONE = 1 << 27;
195: public static final int HFS_TW_DISABLE_PRINTER_ECHO = 1 << 26;
196: public static final int HFS_TW_USE_SYSROOT = 1 << 25;
197: public static final int HFS_TW_WARN_CASE_MISMATCH = 1 << 24;
198: public static final int HFS_TW_USE_STRONG_SYSROOT = 1 << 23;
199:
200:
201: public static int hfsTwentyOneOption;
202:
203:
204: public static final boolean HFS_UTF8_WARNING = true;
205: public static boolean hfsUTF8WarningOn;
206: public static HashSet<String> hfsUTF8WarningSet;
207:
208:
209:
210:
211:
212: public static void hfsInit () {
213:
214:
215: if (HFS_COMMAND_TRACE) {
216: hfsCommandTraceOn = false;
217: }
218:
219:
220: if (HFS_USE_THREAD) {
221: hfsTimer = new java.util.Timer ();
222: }
223:
224:
225: if (HFS_USE_TWENTY_ONE) {
226: hfsTwentyOneOption = 0;
227: }
228:
229:
230:
231: hfsFileFilter = new javax.swing.filechooser.FileFilter () {
232: @Override public boolean accept (File file) {
233: if (file.isDirectory ()) {
234: return true;
235: }
236: String path = file.getPath ();
237: if (hfsIsInserted (path)) {
238: return false;
239: }
240: return true;
241: }
242: @Override public String getDescription () {
243: return (Multilingual.mlnJapanese ?
244: "ルートになるディレクトリまたはそこにあるかも知れないファイル" :
245: "Directory to be the root or files that may be found there");
246: }
247: };
248:
249:
250: hfsOpenDialog = null;
251: hfsOpenUnit = 0;
252: hfsOpenHistory = new ArrayList<File[]> ();
253: for (int i = JFileChooser2.MAXIMUM_HISTORY_COUNT - 1; 0 <= i; i--) {
254: hfsAddHistory (JFileChooser2.pathsToFiles (Settings.sgsGetString ("hfhistory" + i)));
255: }
256:
257:
258:
259: hfsBootUnit = 0;
260:
261: hfsDeviceUnitCount = 0;
262: for (int u = 0; u < HFS_MAX_UNITS; u++) {
263: HFUnit unit = hfsUnitArray[u] = new HFUnit (u);
264: if (u < HFS_MIN_UNITS) {
265: unit.connect (false);
266: }
267: }
268:
269:
270: for (int u = 0; u < HFS_MAX_UNITS; u++) {
271: HFUnit unit = hfsUnitArray[u];
272: String path = Settings.sgsGetString ("hf" + u);
273: boolean userWriteProtect = false;
274: if (path.toUpperCase ().endsWith (":R")) {
275: path = path.substring (0, path.length () - 2);
276: userWriteProtect = true;
277: }
278: boolean hostWriteProtect = !new File (path).canWrite ();
279: if (path.length () != 0) {
280: unit.connect (true);
281: if (unit.insert (path,
282: userWriteProtect || hostWriteProtect)) {
283: hfsAddHistory (new File (path).getAbsoluteFile ());
284: }
285: }
286: }
287: if (HFS_UTF8_WARNING) {
288: hfsUTF8WarningOn = Settings.sgsGetOnOff ("utf8warning");
289: hfsUTF8WarningSet = new HashSet<String> ();
290: }
291:
292:
293: hfsMenu = ComponentFactory.createMenu ("HFS");
294: ComponentFactory.addComponents (
295: hfsMenu,
296: ComponentFactory.createHorizontalBox (
297: Multilingual.mlnText (ComponentFactory.createLabel ("Host file system"),
298: "ja", "ホストファイルシステム")),
299: ComponentFactory.createHorizontalSeparator ()
300: );
301: for (HFUnit unit : hfsUnitArray) {
302: hfsMenu.add (unit.getMenuBox ());
303: }
304: if (HFS_UTF8_WARNING) {
305: ComponentFactory.addComponents (
306: hfsMenu,
307: ComponentFactory.createHorizontalSeparator (),
308: Multilingual.mlnText (
309: ComponentFactory.createCheckBoxMenuItem (hfsCommandTraceOn, "UTF-8 warning", new ActionListener () {
310: @Override public void actionPerformed (ActionEvent ae) {
311: hfsUTF8WarningOn = ((JCheckBoxMenuItem) ae.getSource ()).isSelected ();
312: }
313: }),
314: "ja", "UTF-8 警告")
315: );
316: }
317: if (HFS_COMMAND_TRACE) {
318: ComponentFactory.addComponents (
319: hfsMenu,
320: ComponentFactory.createHorizontalSeparator (),
321: Multilingual.mlnText (
322: ComponentFactory.createCheckBoxMenuItem (hfsCommandTraceOn, "HFS command trace", new ActionListener () {
323: @Override public void actionPerformed (ActionEvent ae) {
324: hfsCommandTraceOn = ((JCheckBoxMenuItem) ae.getSource ()).isSelected ();
325: }
326: }),
327: "ja", "HFS コマンドトレース")
328: );
329: }
330:
331:
332: MainMemory.mmrWl (HFS_BOOT_HANDLE, HFS_BOOT_ROUTINE);
333: MainMemory.mmrWl (HFS_INSTALL_HANDLE, HFS_INSTALL_ROUTINE);
334: MainMemory.mmrWl (HFS_INSTALL_PARAMETER, 0);
335: MainMemory.mmrWl (HFS_HUMAN68K_MAGIC, 'H' << 24 | 'u' << 16 | 'm' << 8 | 'a');
336: MainMemory.mmrWl (HFS_HUMAN68K_MAGIC + 4, 'n' << 24 | '6' << 16 | '8' << 8 | 'k');
337: MainMemory.mmrWl (HFS_BOOT_ROUTINE, XEiJ.EMX_OPCODE_HFSBOOT << 16 | 0x4e75);
338: MainMemory.mmrWl (HFS_INSTALL_ROUTINE, XEiJ.EMX_OPCODE_HFSINST << 16 | 0x4e75);
339: MainMemory.mmrWl (HFS_MAGIC, 'J' << 24 | 'H' << 16 | 'F' << 8 | 'S');
340:
341: hfsState = HFS_STATE_IDLE;
342:
343: }
344:
345:
346:
347:
348:
349: public static void hfsTini () {
350:
351: if (HFS_USE_THREAD) {
352: if (hfsTimer != null) {
353: hfsTimer.schedule (new TimerTask () {
354: @Override public void run () {
355: for (HFUnit unit : hfsUnitArray) {
356: unit.hfuTini ();
357: }
358: hfsTimer.cancel ();
359: hfsTimer = null;
360: }
361: }, HFS_THREAD_DELAY);
362: try {
363: while (hfsTimer != null) {
364: Thread.sleep (10L);
365: }
366: } catch (InterruptedException ie) {
367: }
368: }
369: } else {
370: for (HFUnit unit : hfsUnitArray) {
371: unit.hfuTini ();
372: }
373: }
374:
375:
376:
377: if (hfsOpenDialog != null) {
378: Settings.sgsPutOnOff ("hfreadonly", hfsOpenDialog.getReadOnly ());
379: Settings.sgsPutOnOff ("hfappreboot", hfsOpenDialog.getReboot ());
380: ArrayList<String> pathsList = hfsOpenDialog.getHistory ();
381: int n = pathsList.size ();
382: for (int i = 0; i < n; i++) {
383: Settings.sgsPutString ("hfhistory" + i, pathsList.get (i));
384: }
385: for (int i = n; i < HFS_MAX_UNITS; i++) {
386: Settings.sgsPutString ("hfhistory" + i, "");
387: }
388: }
389:
390:
391: for (int u = 0; u < HFS_MAX_UNITS; u++) {
392: AbstractUnit unit = hfsUnitArray[u];
393: Settings.sgsPutString (
394: "hf" + u,
395: unit.abuConnected && unit.abuInserted ?
396: unit.abuWriteProtected ? unit.abuPath + ":R" : unit.abuPath :
397: "");
398: }
399:
400: if (HFS_UTF8_WARNING) {
401: Settings.sgsPutOnOff ("utf8warning", hfsUTF8WarningOn);
402: }
403:
404: }
405:
406:
407:
408: public static boolean hfsIsInserted (String path) {
409: for (HFUnit unit : hfsUnitArray) {
410: if (unit != null &&
411: unit.abuConnected &&
412: unit.abuInserted &&
413: unit.abuPath.equals (path)) {
414: return true;
415: }
416: }
417: return false;
418: }
419:
420:
421:
422:
423: public static void hfsReset () {
424: for (HFUnit unit : hfsUnitArray) {
425: unit.hfuTini ();
426: }
427: }
428:
429:
430:
431: public static boolean hfsIPLBoot () {
432: return hfsUnitArray[hfsBootUnit].hfuIPLBoot ();
433: }
434:
435:
436:
437:
438:
439:
440:
441:
442:
443:
444:
445:
446:
447:
448:
449:
450:
451:
452: public static void hfsInstall () throws M68kException {
453: if (XEiJ.regRn[2] != 0) {
454: XEiJ.regRn[2] = -1;
455: } else {
456: XEiJ.regRn[2] = 1;
457: int a1 = XEiJ.regRn[9];
458: hfsDeviceHeader = a1;
459: MC68060.mmuWriteLongData (a1 + HFS_NEXT_DEVICE, -1, XEiJ.regSRS);
460: MC68060.mmuWriteWordData (a1 + HFS_DEVICE_TYPE, 0x2000, XEiJ.regSRS);
461: MC68060.mmuWriteLongData (a1 + HFS_STRATEGY_HANDLE, a1 + HFS_STRATEGY_ROUTINE, XEiJ.regSRS);
462: MC68060.mmuWriteLongData (a1 + HFS_INTERRUPT_HANDLE, a1 + HFS_INTERRUPT_ROUTINE, XEiJ.regSRS);
463: MC68060.mmuWriteLongData (a1 + HFS_DEVICE_NAME, 0x01 << 24 | 'X' << 16 | 'E' << 8 | 'I', XEiJ.regSRS);
464: MC68060.mmuWriteLongData (a1 + HFS_DEVICE_NAME + 4, 'J' << 24 | 'H' << 16 | 'F' << 8 | 'S', XEiJ.regSRS);
465: MC68060.mmuWriteLongData (a1 + HFS_STRATEGY_ROUTINE, XEiJ.EMX_OPCODE_HFSSTR << 16 | 0x4e75, XEiJ.regSRS);
466: MC68060.mmuWriteLongData (a1 + HFS_INTERRUPT_ROUTINE, XEiJ.EMX_OPCODE_HFSINT << 16 | 0x4e75, XEiJ.regSRS);
467: }
468: }
469:
470:
471:
472: public static void hfsStrategy () throws M68kException {
473: hfsRequestHeader = XEiJ.regRn[13];
474:
475: if (false && HFS_DEBUG_TRACE) {
476: System.out.printf ("hfsStrategy\n");
477: System.out.printf (" hfsRequestHeader = %08x\n", hfsRequestHeader);
478: }
479:
480: }
481:
482:
483:
484:
485: public static boolean hfsInterrupt () throws M68kException {
486:
487: if (false && HFS_DEBUG_TRACE) {
488: System.out.printf ("hfsInterrupt\n");
489: System.out.printf (" hfsRequestHeader = %08x\n", hfsRequestHeader);
490: System.out.printf (" hfsState = %d\n", hfsState);
491: }
492:
493: int a5 = hfsRequestHeader;
494:
495: if (hfsState == HFS_STATE_IDLE) {
496:
497: if (HFS_DEBUG_TRACE) {
498: int number = MC68060.mmuPeekByteZeroData (a5 + 1, XEiJ.regSRS);
499: int command = MC68060.mmuPeekByteZeroData (a5 + 2, XEiJ.regSRS);
500: int mode = MC68060.mmuPeekByteZeroData (a5 + 13, XEiJ.regSRS);
501: int namests = MC68060.mmuPeekLongData (a5 + 14, XEiJ.regSRS);
502: int param = MC68060.mmuPeekLongData (a5 + 18, XEiJ.regSRS);
503: int fcb = MC68060.mmuPeekLongData (a5 + 22, XEiJ.regSRS);
504: if (!(hfsRequest2Command == 0x57 ||
505: hfsRequest2Command == 0x4c && param == 1)) {
506: for (int i = 0; i < 26; i++) {
507: System.out.printf (" %02x", MC68060.mmuPeekByteZeroData (a5 + i, XEiJ.regSRS));
508: }
509: System.out.println ();
510: System.out.printf (" Number: %02x\n", number);
511: System.out.printf (" Command: %02x\n", command);
512: System.out.printf (" Mode: %02x\n", mode);
513: System.out.printf (" Namests: %08x:", namests);
514: for (int i = 0; i < 88; i++) {
515: System.out.printf (" %02x", MC68060.mmuPeekByteZeroData (namests + i, XEiJ.regSRS));
516: }
517: System.out.println ();
518: System.out.printf (" Param: %08x\n", param);
519: System.out.printf (" Fcb: %08x:", fcb);
520: for (int i = 0; i < 96; i++) {
521: System.out.printf (" %02x", MC68060.mmuPeekByteZeroData (fcb + i, XEiJ.regSRS));
522: }
523: System.out.println ();
524: }
525: }
526:
527:
528:
529: hfsRequest1Number = MC68060.mmuReadByteZeroData (a5 + 1, XEiJ.regSRS);
530: hfsRequest2Command = MC68060.mmuReadByteZeroData (a5 + 2, XEiJ.regSRS) & 0x7f;
531: hfsRequest13Mode = MC68060.mmuReadByteZeroData (a5 + 13, XEiJ.regSRS);
532: hfsRequest14Namests = MC68060.mmuReadLongData (a5 + 14, XEiJ.regSRS);
533: hfsRequest18Param = MC68060.mmuReadLongData (a5 + 18, XEiJ.regSRS);
534: hfsRequest22Fcb = MC68060.mmuReadLongData (a5 + 22, XEiJ.regSRS);
535: hfsRequest3Error = 0;
536: hfsRequest18Result = 0;
537:
538: if (hfsRequest2Command == 0x40) {
539:
540:
541:
542:
543:
544:
545:
546:
547:
548:
549:
550:
551:
552:
553:
554:
555:
556:
557:
558:
559:
560:
561:
562:
563:
564:
565:
566:
567:
568:
569:
570:
571:
572: if (HFS_COMMAND_TRACE && hfsCommandTraceOn) {
573: int pc = MainMemory.mmrGetLevelZeroPC ();
574: System.out.println (LabeledAddress.lblSearch (new StringBuilder (), pc).toString ());
575: System.out.printf ("%08x initialize(internaldrive=0x%02,param=0x%08x)\n",
576: pc, hfsRequest22Fcb >>> 24, hfsRequest18Param);
577: }
578: MC68060.mmuWriteByteData (a5 + 2, 0x00, XEiJ.regSRS);
579:
580:
581:
582: hfsDeviceUnitCount = 0;
583: int bootUnit = -1;
584: for (int u = 0; u < HFS_MAX_UNITS; u++) {
585: if (hfsUnitArray[u].isConnected ()) {
586: if (u == hfsBootUnit) {
587: bootUnit = hfsDeviceUnitCount;
588: }
589: hfsDeviceUnitArray[hfsDeviceUnitCount++] = u;
590: }
591: }
592: if (hfsDeviceUnitCount > 0 && bootUnit >= 0) {
593: MC68060.mmuWriteByteData (a5 + 13, hfsDeviceUnitCount, XEiJ.regSRS);
594: MC68060.mmuWriteLongData (a5 + 14, hfsDeviceHeader + 34, XEiJ.regSRS);
595: MC68060.mmuWriteByteData (a5 + 22, 1 + bootUnit, XEiJ.regSRS);
596: } else {
597: hfsRequest3Error = HFUnit.DEV_ABORT | HFUnit.DEV_INVALID_UNIT_NUMBER;
598: hfsRequest18Result = -1;
599: }
600: hfsState = HFS_STATE_DONE;
601:
602: } else {
603:
604: if (hfsRequest1Number < hfsDeviceUnitCount) {
605:
606: hfsRequestUnit = hfsUnitArray[hfsDeviceUnitArray[hfsRequest1Number]];
607: hfsState = HFS_STATE_X68K;
608: hfsRequestUnit.hfuCall ();
609: } else {
610: hfsRequest3Error = HFUnit.DEV_ABORT | HFUnit.DEV_INVALID_UNIT_NUMBER;
611: hfsRequest18Result = -1;
612: hfsState = HFS_STATE_DONE;
613: }
614:
615: }
616:
617: }
618:
619: if (HFS_USE_THREAD) {
620: while (hfsState != HFS_STATE_DONE) {
621: if (hfsState == HFS_STATE_X68K) {
622: hfsRequestUnit.hfuCallX68k ();
623: if (hfsState == HFS_STATE_X68K) {
624: return true;
625: }
626: }
627: if (hfsState == HFS_STATE_HOST) {
628: hfsState = HFS_STATE_BUSY;
629: if (hfsTimer != null) {
630: hfsTimer.schedule (new TimerTask () {
631: @Override public void run () {
632: hfsRequestUnit.hfuCallHost ();
633: }
634: }, HFS_THREAD_DELAY);
635: }
636: }
637:
638: if (hfsState == HFS_STATE_BUSY) {
639: return true;
640: }
641: }
642: } else {
643: while (hfsState != HFS_STATE_DONE) {
644: while (hfsState == HFS_STATE_X68K) {
645: hfsRequestUnit.hfuCallX68k ();
646: }
647: if (hfsState == HFS_STATE_HOST) {
648: hfsState = HFS_STATE_BUSY;
649: }
650: if (hfsState == HFS_STATE_BUSY) {
651: hfsRequestUnit.hfuCallHost ();
652: }
653: }
654: }
655:
656: if (HFS_COMMAND_TRACE && hfsCommandTraceOn) {
657: System.out.printf ("\terror=0x%04x,result=0x%08x\n", hfsRequest3Error, hfsRequest18Result);
658: }
659:
660: MC68060.mmuWriteByteData (a5 + 3, hfsRequest3Error, XEiJ.regSRS);
661: MC68060.mmuWriteByteData (a5 + 4, hfsRequest3Error >> 8, XEiJ.regSRS);
662: MC68060.mmuWriteLongData (a5 + 18, hfsRequest18Result, XEiJ.regSRS);
663:
664: hfsState = HFS_STATE_IDLE;
665: return false;
666: }
667:
668: static class OpenDialog extends AbstractOpenDialog {
669: public OpenDialog () {
670: super (XEiJ.frmFrame,
671: "Host file system directory to assign Human68k drives",
672: "Human68k のドライブを割り当てるホストファイルシステムのディレクトリ",
673: true,
674: hfsFileFilter);
675: }
676: @Override public void openFiles (File[] files, boolean reboot) {
677: hfsOpenFiles (files, reboot);
678: }
679: }
680:
681:
682:
683: public static void hfsOpenFiles (File[] list, boolean reset) {
684: boolean success = true;
685: for (int u = hfsOpenUnit, k = 0; k < list.length; ) {
686: if (HFS_MAX_UNITS <= u) {
687: success = false;
688: break;
689: }
690: HFUnit unit = hfsUnitArray[u];
691: if (!unit.abuConnected) {
692: u++;
693: continue;
694: }
695: File file = list[k++];
696: if (!file.isDirectory ()) {
697: file = file.getParentFile ();
698: if (file == null || !file.isDirectory ()) {
699: success = false;
700: continue;
701: }
702: }
703: if (!unit.insert (file.getPath (),
704: hfsOpenDialog.getReadOnly () || !file.canWrite ())) {
705: success = false;
706: continue;
707: }
708: u++;
709: }
710: if (success) {
711: hfsAddHistory (list);
712: if (reset) {
713: hfsBootUnit = hfsOpenUnit;
714: XEiJ.mpuReset (0xa000, HFS_BOOT_HANDLE);
715: }
716: }
717: }
718:
719:
720:
721:
722: public static void hfsAddHistory (File file) {
723: hfsAddHistory (new File[] { file });
724: }
725:
726:
727:
728: public static void hfsAddHistory (File[] files) {
729: if (hfsOpenDialog == null) {
730: hfsOpenHistory.add (files);
731: } else {
732: hfsOpenDialog.addHistory (files);
733: }
734: }
735:
736:
737:
738:
739:
740: public void hfsCheckTwentyOneOption () {
741: hfsTwentyOneOption = 0;
742: if (HFS_USE_TWENTY_ONE) {
743: int a = MainMemory.mmrTwentyOneOptionAddress;
744: if (0 < a) {
745: hfsTwentyOneOption = MC68060.mmuPeekLongData (a, 1);
746: }
747: }
748: }
749:
750:
751:
752:
753:
754:
755:
756:
757:
758:
759:
760:
761:
762:
763:
764:
765:
766:
767:
768:
769:
770:
771:
772:
773:
774:
775:
776:
777:
778:
779:
780:
781:
782:
783:
784:
785:
786:
787:
788:
789:
790:
791:
792:
793:
794:
795:
796:
797:
798:
799:
800:
801:
802:
803:
804:
805:
806:
807:
808:
809:
810:
811:
812:
813:
814:
815:
816:
817:
818:
819:
820:
821:
822:
823:
824:
825:
826:
827: public static class HFUnit extends AbstractUnit {
828:
829:
830:
831:
832:
833: public static final int DEV_IGNORE = 0x4000;
834: public static final int DEV_RETRY = 0x2000;
835: public static final int DEV_ABORT = 0x1000;
836:
837: public static final int DEV_INVALID_UNIT_NUMBER = 0x0001;
838: public static final int DEV_INSERT_MEDIA = 0x0002;
839: public static final int DEV_UNKNOWN_COMMAND = 0x0003;
840: public static final int DEV_CRC_ERROR = 0x0004;
841: public static final int DEV_MANEGEMENT_AREA_BROKEN = 0x0005;
842: public static final int DEV_SEEK_ERROR = 0x0006;
843: public static final int DEV_INVALID_MEDIA = 0x0007;
844: public static final int DEV_SECTOR_NOT_FOUND = 0x0008;
845: public static final int DEV_PRINTER_NOT_CONNECTED = 0x0009;
846: public static final int DEV_WRITE_ERROR = 0x000a;
847: public static final int DEV_READ_ERROR = 0x000b;
848: public static final int DEV_MISCELLANEOUS_ERROR = 0x000c;
849: public static final int DEV_UNPROTECT_MEDIA = 0x000d;
850: public static final int DEV_CANNOT_WRITE = 0x000e;
851: public static final int DEV_FILE_SHARING_VIOLATION = 0x000f;
852:
853:
854:
855: public static final int DOS_INVALID_FUNCTION = -1;
856: public static final int DOS_FILE_NOT_FOUND = -2;
857: public static final int DOS_DIRECTORY_NOT_FOUND = -3;
858: public static final int DOS_TOO_MANY_HANDLES = -4;
859: public static final int DOS_NOT_A_FILE = -5;
860: public static final int DOS_HANDLE_IS_NOT_OPENED = -6;
861: public static final int DOS_BROKEN_MEMORY_CHAIN = -7;
862: public static final int DOS_NOT_ENOUGH_MEMORY = -8;
863: public static final int DOS_INVALID_MEMORY_CHAIN = -9;
864: public static final int DOS_INVALID_ENVIRONMENT = -10;
865: public static final int DOS_ABNORMAL_X_FILE = -11;
866: public static final int DOS_INVALID_ACCESS_MODE = -12;
867: public static final int DOS_ILLEGAL_FILE_NAME = -13;
868: public static final int DOS_INVALID_PARAMETER = -14;
869: public static final int DOS_ILLEGAL_DRIVE_NUMBER = -15;
870: public static final int DOS_CURRENT_DIRECTORY = -16;
871: public static final int DOS_CANNOT_IOCTRL = -17;
872: public static final int DOS_NO_MORE_FILES = -18;
873: public static final int DOS_CANNOT_WRITE = -19;
874: public static final int DOS_DIRECTORY_EXISTS = -20;
875: public static final int DOS_RM_NONEMPTY_DIRECTORY = -21;
876: public static final int DOS_MV_NONEMPTY_DIRECTORY = -22;
877: public static final int DOS_DISK_FULL = -23;
878: public static final int DOS_DIRECTORY_FULL = -24;
879: public static final int DOS_SEEK_OVER_EOF = -25;
880: public static final int DOS_ALREADY_SUPERVISOR = -26;
881: public static final int DOS_THREAD_EXISTS = -27;
882: public static final int DOS_COMMUNICATION_FAILED = -28;
883: public static final int DOS_TOO_MANY_THREADS = -29;
884: public static final int DOS_NOT_ENOUGH_LOCK_AREA = -32;
885: public static final int DOS_FILE_IS_LOCKED = -33;
886: public static final int DOS_OPENED_HANDLE_EXISTS = -34;
887: public static final int DOS_FILE_EXISTS = -80;
888:
889:
890:
891: private static final int HFU_FILES_MAGIC = '*' << 24 | 'H' << 16 | 'F' << 8 | 'S';
892:
893: public String hfuRootPath;
894:
895:
896: public HashMap<Integer,ArrayDeque<byte[]>> hfuFilesBufferToArrayDeque;
897: public int hfuFilesBufferCounter;
898:
899:
900: public class HFHandle {
901: public int hfhFcb;
902: public File hfhFile;
903: public RandomAccessFile hfhRaf;
904: public byte[] hfhBuffer;
905: public long hfhStart;
906: public long hfhEnd;
907: public boolean hfhDirty;
908: public HFHandle (int fcb, File file, RandomAccessFile raf) {
909: hfhFcb = fcb;
910: hfhFile = file;
911: hfhRaf = raf;
912: hfhBuffer = new byte[HFS_BUFFER_SIZE];
913: hfhStart = 0L;
914: hfhEnd = 0L;
915: hfhDirty = false;
916: }
917: @Override public String toString () {
918: return String.format ("HFHandle{fcb:0x%08x,file:\"%s\",start:%d,end:%d,dirty:%b}", hfhFcb, hfhFile.toString (), hfhStart, hfhEnd, hfhDirty);
919: }
920: }
921: public HashMap<Integer,HFHandle> hfuFcbToHandle;
922: public LinkedList<HFHandle> hfuClosedHandle;
923: public HFHandle hfuNewHandle (int fcb, File file, RandomAccessFile raf) {
924: HFHandle handle = hfuClosedHandle.pollFirst ();
925: if (handle == null) {
926: return new HFHandle (fcb, file, raf);
927: }
928: handle.hfhFcb = fcb;
929: handle.hfhFile = file;
930: handle.hfhRaf = raf;
931: Arrays.fill (handle.hfhBuffer, (byte) 0);
932: handle.hfhStart = 0L;
933: handle.hfhEnd = 0L;
934: handle.hfhDirty = false;
935: return handle;
936: }
937: public void hfuRecycleHandle (HFHandle handle) {
938: hfuClosedHandle.push (handle);
939: }
940:
941:
942: public final byte[] hfuTargetNameArray1 = new byte[88];
943: public final byte[] hfuTargetNameArray2 = new byte[88];
944: public String hfuTargetName1;
945: public String hfuTargetName2;
946: public long hfuTargetLastModified;
947: public int hfuTargetOpenMode;
948: public HFHandle hfuTargetHandle;
949: public long hfuTargetPosition;
950: public long hfuTargetFileSize;
951: public long hfuTargetLength;
952: public long hfuTargetAddress;
953: public long hfuTargetTransferred;
954: public long hfuTargetTotalSpace;
955: public long hfuTargetFreeSpace;
956:
957:
958:
959: public HFUnit (int number) {
960: super (number);
961: hfuRootPath = null;
962: hfuFilesBufferToArrayDeque = new HashMap<Integer,ArrayDeque<byte[]>> ();
963: hfuFilesBufferCounter = 0;
964: hfuFcbToHandle = new HashMap<Integer,HFHandle> ();
965: hfuClosedHandle = new LinkedList<HFHandle> ();
966: }
967:
968:
969:
970:
971:
972: public void hfuTini () {
973: for (HFHandle handle : hfuFcbToHandle.values ()) {
974: RandomAccessFile raf = handle.hfhRaf;
975:
976: if (handle.hfhDirty) {
977: if (HFS_BUFFER_TRACE) {
978: System.out.printf ("delaywrite(fcb=0x%08x,name=\"%s\",start=0x%08x,end=0x%08x)\n", handle.hfhFcb, handle.hfhFile.toString(), handle.hfhStart, handle.hfhEnd);
979: }
980: try {
981: raf.seek (handle.hfhStart);
982: } catch (IOException ioe) {
983: System.out.println ((Multilingual.mlnJapanese ? "シークエラー: " : "Seek error: ") + handle.toString ());
984: }
985: try {
986: raf.write (handle.hfhBuffer, 0, (int) (handle.hfhEnd - handle.hfhStart));
987: } catch (IOException ioe) {
988: System.out.println ((Multilingual.mlnJapanese ? "遅延書き込みに失敗しました: " : "Delayed write failed: ") + handle.toString ());
989: }
990: handle.hfhDirty = false;
991: }
992: try {
993: raf.close ();
994: } catch (IOException ioe) {
995: System.out.println ((Multilingual.mlnJapanese ? "クローズエラー: " : "Close error: ") + handle.toString ());
996: }
997: }
998: hfuFcbToHandle.clear ();
999: hfuFilesBufferToArrayDeque.clear ();
1000:
1001: }
1002:
1003:
1004:
1005:
1006:
1007:
1008:
1009:
1010: public boolean hfuIPLBoot () {
1011: if (!abuConnected) {
1012: return false;
1013: }
1014:
1015: byte[] rr = XEiJ.rscGetResource ("HUMAN.SYS");
1016: if (rr == null ||
1017: ByteArray.byaRwz (rr, 0x00) != ('H' << 8 | 'U') ||
1018: ByteArray.byaRls (rr, 0x04) != 0x00006800 ||
1019: ByteArray.byaRls (rr, 0x08) != 0x00006800) {
1020: return false;
1021: }
1022: int textData = ByteArray.byaRls (rr, 0x0c) + ByteArray.byaRls (rr, 0x10);
1023: int bssCommStack = ByteArray.byaRls (rr, 0x14);
1024: System.arraycopy (rr, 0x40, MainMemory.mmrM8, 0x00006800, textData);
1025: Arrays.fill (MainMemory.mmrM8, 0x00006800 + textData, 0x00006800 + textData + bssCommStack, (byte) 0);
1026: return true;
1027: }
1028:
1029:
1030:
1031: @Override protected boolean eject () {
1032: String path = abuPath;
1033: if (!super.eject ()) {
1034: return false;
1035: }
1036: if (path.length () != 0) {
1037: hfsAddHistory (new File (path).getAbsoluteFile ());
1038: System.out.println (Multilingual.mlnJapanese ?
1039: path + " を hf" + abuNumber + " から切り離しました" :
1040: path + " was ejected from hf" + abuNumber);
1041: }
1042: return true;
1043: }
1044:
1045:
1046:
1047: @Override protected boolean open () {
1048: if (!super.open ()) {
1049: return false;
1050: }
1051: hfsOpenUnit = abuNumber;
1052: if (hfsOpenDialog == null) {
1053: hfsOpenDialog = new OpenDialog ();
1054: hfsOpenDialog.setReadOnly (Settings.sgsGetOnOff ("hfreadonly"));
1055: hfsOpenDialog.setReboot (Settings.sgsGetOnOff ("hfappreboot"));
1056: for (File[] files : hfsOpenHistory) {
1057: hfsOpenDialog.addHistory (files);
1058: }
1059: hfsOpenHistory.clear ();
1060: }
1061: hfsOpenDialog.rescanCurrentDirectory ();
1062: XEiJ.pnlExitFullScreen (true);
1063: hfsOpenDialog.setVisible (true);
1064: return true;
1065: }
1066:
1067:
1068:
1069: @Override protected boolean load (String path) {
1070: File file = new File (path).getAbsoluteFile ();
1071: if (!file.isDirectory ()) {
1072: file = file.getParentFile ();
1073: if (file == null || !file.isDirectory ()) {
1074: return false;
1075: }
1076: }
1077: hfuRootPath = file.getAbsolutePath ();
1078: hfsAddHistory (new File (path).getAbsoluteFile ());
1079: System.out.println (Multilingual.mlnJapanese ?
1080: hfuRootPath + " を hf" + abuNumber + " に接続しました" :
1081: hfuRootPath + " was inserted in hf" + abuNumber);
1082: return true;
1083: }
1084:
1085:
1086:
1087: public void hfuCall () throws M68kException {
1088: switch (hfsRequest2Command) {
1089: case 0x41:
1090: hfuCallChdir ();
1091: break;
1092: case 0x42:
1093: hfuCallMkdir ();
1094: break;
1095: case 0x43:
1096: hfuCallRmdir ();
1097: break;
1098: case 0x44:
1099: hfuCallRename ();
1100: break;
1101: case 0x45:
1102: hfuCallDelete ();
1103: break;
1104: case 0x46:
1105: hfuCallChmod ();
1106: break;
1107: case 0x47:
1108: hfuCallFiles ();
1109: break;
1110: case 0x48:
1111: hfuCallNfiles ();
1112: break;
1113: case 0x49:
1114: hfuCallCreateNewfile ();
1115: break;
1116: case 0x4a:
1117: hfuCallOpen ();
1118: break;
1119: case 0x4b:
1120: hfuCallClose ();
1121: break;
1122: case 0x4c:
1123: hfuCallRead ();
1124: break;
1125: case 0x4d:
1126: hfuCallWrite ();
1127: break;
1128: case 0x4e:
1129: hfuCallSeek ();
1130: break;
1131: case 0x4f:
1132: hfuCallFiledate ();
1133: break;
1134: case 0x50:
1135: hfuCallDskfre ();
1136: break;
1137: case 0x51:
1138: hfuCallDrvctrl ();
1139: break;
1140: case 0x52:
1141: hfuCallGetdpb ();
1142: break;
1143: case 0x53:
1144: hfuCallDiskred ();
1145: break;
1146: case 0x54:
1147: hfuCallDiskwrt ();
1148: break;
1149: case 0x55:
1150: hfuCallSpecialCtrl ();
1151: break;
1152: case 0x56:
1153: hfuCallFflush ();
1154: break;
1155: case 0x57:
1156: hfuCallMediacheck ();
1157: break;
1158: case 0x58:
1159: hfuCallLock ();
1160: break;
1161: default:
1162: hfsRequest3Error = DEV_ABORT | DEV_UNKNOWN_COMMAND;
1163: hfsRequest18Result = -1;
1164: hfsState = HFS_STATE_DONE;
1165: }
1166: }
1167:
1168:
1169:
1170: public void hfuCallX68k () throws M68kException {
1171: switch (hfsRequest2Command) {
1172:
1173:
1174:
1175:
1176:
1177:
1178:
1179:
1180:
1181:
1182:
1183:
1184:
1185:
1186:
1187:
1188:
1189:
1190:
1191:
1192: case 0x47:
1193: hfuCallFilesX68k ();
1194: break;
1195:
1196:
1197:
1198:
1199:
1200: case 0x49:
1201: hfuCallCreateNewfileX68k ();
1202: break;
1203: case 0x4a:
1204: hfuCallOpenX68k ();
1205: break;
1206: case 0x4b:
1207: hfuCallCloseX68k ();
1208: break;
1209: case 0x4c:
1210: hfuCallReadX68k ();
1211: break;
1212: case 0x4d:
1213: hfuCallWriteX68k ();
1214: break;
1215:
1216:
1217:
1218:
1219:
1220:
1221:
1222:
1223: case 0x50:
1224: hfuCallDskfreX68k ();
1225: break;
1226:
1227:
1228:
1229:
1230:
1231:
1232:
1233:
1234:
1235:
1236:
1237:
1238:
1239:
1240:
1241:
1242:
1243:
1244:
1245:
1246:
1247:
1248:
1249:
1250:
1251:
1252: }
1253: }
1254:
1255:
1256:
1257: public void hfuCallHost () {
1258: switch (hfsRequest2Command) {
1259: case 0x41:
1260: hfuCallChdirHost ();
1261: break;
1262: case 0x42:
1263: hfuCallMkdirHost ();
1264: break;
1265: case 0x43:
1266: hfuCallRmdirHost ();
1267: break;
1268: case 0x44:
1269: hfuCallRenameHost ();
1270: break;
1271: case 0x45:
1272: hfuCallDeleteHost ();
1273: break;
1274: case 0x46:
1275: hfuCallChmodHost ();
1276: break;
1277: case 0x47:
1278: hfuCallFilesHost ();
1279: break;
1280:
1281:
1282:
1283:
1284:
1285: case 0x49:
1286: hfuCallCreateNewfileHost ();
1287: break;
1288: case 0x4a:
1289: hfuCallOpenHost ();
1290: break;
1291: case 0x4b:
1292: hfuCallCloseHost ();
1293: break;
1294: case 0x4c:
1295: hfuCallReadHost ();
1296: break;
1297: case 0x4d:
1298: hfuCallWriteHost ();
1299: break;
1300:
1301:
1302:
1303:
1304:
1305:
1306:
1307:
1308: case 0x50:
1309: hfuCallDskfreHost ();
1310: break;
1311:
1312:
1313:
1314:
1315:
1316:
1317:
1318:
1319:
1320:
1321:
1322:
1323:
1324:
1325:
1326:
1327:
1328: case 0x56:
1329: hfuCallFflushHost ();
1330: break;
1331:
1332:
1333:
1334:
1335:
1336:
1337:
1338:
1339: }
1340: }
1341:
1342:
1343:
1344:
1345:
1346:
1347:
1348:
1349:
1350:
1351:
1352:
1353:
1354:
1355:
1356:
1357:
1358: public void hfuCallChdir () throws M68kException {
1359: hfuTargetName1 = hfuNamestsToPath (hfsRequest14Namests, false);
1360: if (hfuTargetName1 == null) {
1361: hfsRequest18Result = DOS_ILLEGAL_FILE_NAME;
1362: hfsState = HFS_STATE_DONE;
1363: return;
1364: }
1365: if (HFS_COMMAND_TRACE && hfsCommandTraceOn) {
1366: int pc = MainMemory.mmrGetLevelZeroPC ();
1367: System.out.println (LabeledAddress.lblSearch (new StringBuilder (), pc).toString ());
1368: System.out.printf ("%08x chdir(name=\"%s\")\n",
1369: pc, hfuTargetName1);
1370: }
1371: if (!abuInserted) {
1372: hfsRequest3Error = DEV_RETRY | DEV_ABORT | DEV_INSERT_MEDIA;
1373: hfsRequest18Result = -1;
1374: hfsState = HFS_STATE_DONE;
1375: return;
1376: }
1377: hfsRequest18Result = 0;
1378: hfsState = HFS_STATE_HOST;
1379: }
1380:
1381:
1382: public void hfuCallChdirHost () {
1383: File file1 = new File (hfuTargetName1);
1384: hfsRequest18Result = (!file1.isDirectory () || file1.list() == null ? DOS_DIRECTORY_NOT_FOUND :
1385: 0);
1386: hfsState = HFS_STATE_DONE;
1387: }
1388:
1389:
1390:
1391:
1392:
1393:
1394:
1395:
1396:
1397:
1398:
1399:
1400:
1401:
1402:
1403:
1404: public void hfuCallMkdir () throws M68kException {
1405: hfuTargetName1 = hfuNamestsToPath (hfsRequest14Namests);
1406: if (hfuTargetName1 == null) {
1407: hfsRequest18Result = DOS_ILLEGAL_FILE_NAME;
1408: hfsState = HFS_STATE_DONE;
1409: return;
1410: }
1411: if (HFS_COMMAND_TRACE && hfsCommandTraceOn) {
1412: int pc = MainMemory.mmrGetLevelZeroPC ();
1413: System.out.println (LabeledAddress.lblSearch (new StringBuilder (), pc).toString ());
1414: System.out.printf ("%08x mkdir(name=\"%s\")\n",
1415: pc, hfuTargetName1);
1416: }
1417: if (!abuInserted) {
1418: hfsRequest3Error = DEV_RETRY | DEV_ABORT | DEV_INSERT_MEDIA;
1419: hfsRequest18Result = -1;
1420: hfsState = HFS_STATE_DONE;
1421: return;
1422: }
1423: if (abuWriteProtected) {
1424: hfsRequest3Error = DEV_IGNORE | DEV_RETRY | DEV_ABORT | DEV_CANNOT_WRITE;
1425: hfsRequest18Result = -1;
1426: hfsState = HFS_STATE_DONE;
1427: return;
1428: }
1429: hfsRequest18Result = 0;
1430: hfsState = HFS_STATE_HOST;
1431: }
1432:
1433:
1434: public void hfuCallMkdirHost () {
1435: try {
1436: File file1 = new File (hfuTargetName1);
1437: hfsRequest18Result = (!file1.mkdir () ? DOS_DIRECTORY_EXISTS :
1438: 0);
1439: } catch (Exception e) {
1440: hfsRequest18Result = DOS_CANNOT_WRITE;
1441: }
1442: hfsState = HFS_STATE_DONE;
1443: }
1444:
1445:
1446:
1447:
1448:
1449:
1450:
1451:
1452:
1453:
1454:
1455:
1456:
1457:
1458:
1459:
1460: public void hfuCallRmdir () throws M68kException {
1461: hfuTargetName1 = hfuNamestsToPath (hfsRequest14Namests);
1462: if (hfuTargetName1 == null) {
1463: hfsRequest18Result = DOS_ILLEGAL_FILE_NAME;
1464: hfsState = HFS_STATE_DONE;
1465: return;
1466: }
1467: if (HFS_COMMAND_TRACE && hfsCommandTraceOn) {
1468: int pc = MainMemory.mmrGetLevelZeroPC ();
1469: System.out.println (LabeledAddress.lblSearch (new StringBuilder (), pc).toString ());
1470: System.out.printf ("%08x rmdir(name=\"%s\")\n",
1471: pc, hfuTargetName1);
1472: }
1473: if (!abuInserted) {
1474: hfsRequest3Error = DEV_RETRY | DEV_ABORT | DEV_INSERT_MEDIA;
1475: hfsRequest18Result = -1;
1476: hfsState = HFS_STATE_DONE;
1477: return;
1478: }
1479: if (abuWriteProtected) {
1480: hfsRequest3Error = DEV_IGNORE | DEV_RETRY | DEV_ABORT | DEV_CANNOT_WRITE;
1481: hfsRequest18Result = -1;
1482: hfsState = HFS_STATE_DONE;
1483: return;
1484: }
1485: hfsRequest18Result = 0;
1486: hfsState = HFS_STATE_HOST;
1487: }
1488:
1489:
1490: public void hfuCallRmdirHost () {
1491: try {
1492: File file1 = new File (hfuTargetName1);
1493: hfsRequest18Result = (!file1.isDirectory () ? DOS_DIRECTORY_NOT_FOUND :
1494: !file1.canWrite () ? DOS_CANNOT_WRITE :
1495: !file1.delete () ? DOS_RM_NONEMPTY_DIRECTORY :
1496: 0);
1497: } catch (Exception e) {
1498: hfsRequest18Result = DOS_CANNOT_WRITE;
1499: }
1500: hfsState = HFS_STATE_DONE;
1501: }
1502:
1503:
1504:
1505:
1506:
1507:
1508:
1509:
1510:
1511:
1512:
1513:
1514:
1515:
1516:
1517:
1518:
1519: public void hfuCallRename () throws M68kException {
1520: hfuTargetName1 = hfuNamestsToPath (hfsRequest14Namests);
1521: if (hfuTargetName1 == null) {
1522: hfsRequest18Result = DOS_ILLEGAL_FILE_NAME;
1523: hfsState = HFS_STATE_DONE;
1524: return;
1525: }
1526: hfuTargetName2 = hfuNamestsToPath (hfsRequest18Param);
1527: if (hfuTargetName2 == null) {
1528: hfsRequest18Result = DOS_ILLEGAL_FILE_NAME;
1529: hfsState = HFS_STATE_DONE;
1530: return;
1531: }
1532: if (HFS_COMMAND_TRACE && hfsCommandTraceOn) {
1533: int pc = MainMemory.mmrGetLevelZeroPC ();
1534: System.out.println (LabeledAddress.lblSearch (new StringBuilder (), pc).toString ());
1535: System.out.printf ("%08x rename(from=\"%s\",to=\"%s\")\n",
1536: pc, hfuTargetName1, hfuTargetName2);
1537: }
1538: if (!abuInserted) {
1539: hfsRequest3Error = DEV_RETRY | DEV_ABORT | DEV_INSERT_MEDIA;
1540: hfsRequest18Result = -1;
1541: hfsState = HFS_STATE_DONE;
1542: return;
1543: }
1544: if (abuWriteProtected) {
1545: hfsRequest3Error = DEV_IGNORE | DEV_RETRY | DEV_ABORT | DEV_CANNOT_WRITE;
1546: hfsRequest18Result = -1;
1547: hfsState = HFS_STATE_DONE;
1548: return;
1549: }
1550: hfsRequest18Result = 0;
1551: hfsState = HFS_STATE_HOST;
1552: }
1553:
1554:
1555: public void hfuCallRenameHost () {
1556: try {
1557: File file1 = new File (hfuTargetName1);
1558: File file2 = new File (hfuTargetName2);
1559: hfsRequest18Result = (!file1.exists () ? DOS_FILE_NOT_FOUND :
1560: !file1.renameTo (file2) ? file1.isFile () ? DOS_CANNOT_WRITE : DOS_MV_NONEMPTY_DIRECTORY :
1561: 0);
1562: } catch (Exception e) {
1563: hfsRequest18Result = DOS_CANNOT_WRITE;
1564: }
1565: hfsState = HFS_STATE_DONE;
1566: }
1567:
1568:
1569:
1570:
1571:
1572:
1573:
1574:
1575:
1576:
1577:
1578:
1579:
1580:
1581:
1582: public void hfuCallDelete () throws M68kException {
1583: hfuTargetName1 = hfuNamestsToPath (hfsRequest14Namests);
1584: if (hfuTargetName1 == null) {
1585: hfsRequest18Result = DOS_ILLEGAL_FILE_NAME;
1586: hfsState = HFS_STATE_DONE;
1587: return;
1588: }
1589: if (HFS_COMMAND_TRACE && hfsCommandTraceOn) {
1590: int pc = MainMemory.mmrGetLevelZeroPC ();
1591: System.out.println (LabeledAddress.lblSearch (new StringBuilder (), pc).toString ());
1592: System.out.printf ("%08x delete(name=\"%s\")\n",
1593: pc, hfuTargetName1);
1594: }
1595: if (!abuInserted) {
1596: hfsRequest3Error = DEV_RETRY | DEV_ABORT | DEV_INSERT_MEDIA;
1597: hfsRequest18Result = -1;
1598: hfsState = HFS_STATE_DONE;
1599: return;
1600: }
1601: if (abuWriteProtected) {
1602: hfsRequest3Error = DEV_IGNORE | DEV_RETRY | DEV_ABORT | DEV_CANNOT_WRITE;
1603: hfsRequest18Result = -1;
1604: hfsState = HFS_STATE_DONE;
1605: return;
1606: }
1607: hfsRequest18Result = 0;
1608: hfsState = HFS_STATE_HOST;
1609: }
1610:
1611:
1612: public void hfuCallDeleteHost () {
1613: try {
1614: File file1 = new File (hfuTargetName1);
1615: hfsRequest18Result = (!file1.isFile () ? DOS_FILE_NOT_FOUND :
1616: !file1.canWrite () ? DOS_CANNOT_WRITE :
1617: !file1.delete () ? DOS_CANNOT_WRITE :
1618: 0);
1619: } catch (Exception e) {
1620: hfsRequest18Result = DOS_CANNOT_WRITE;
1621: }
1622: hfsState = HFS_STATE_DONE;
1623: }
1624:
1625:
1626:
1627:
1628:
1629:
1630:
1631:
1632:
1633:
1634:
1635:
1636:
1637:
1638:
1639: public void hfuCallChmod () throws M68kException {
1640: hfuTargetName1 = hfuNamestsToPath (hfsRequest14Namests);
1641: if (hfuTargetName1 == null) {
1642: hfsRequest18Result = DOS_ILLEGAL_FILE_NAME;
1643: hfsState = HFS_STATE_DONE;
1644: return;
1645: }
1646: if (HFS_COMMAND_TRACE && hfsCommandTraceOn) {
1647: int pc = MainMemory.mmrGetLevelZeroPC ();
1648: System.out.println (LabeledAddress.lblSearch (new StringBuilder (), pc).toString ());
1649: System.out.printf ("%08x chmod(name=\"%s\",mode=0x%02x)\n",
1650: pc, hfuTargetName1, hfsRequest13Mode);
1651: }
1652: if (!abuInserted) {
1653: hfsRequest3Error = DEV_RETRY | DEV_ABORT | DEV_INSERT_MEDIA;
1654: hfsRequest18Result = -1;
1655: hfsState = HFS_STATE_DONE;
1656: return;
1657: }
1658: if (hfsRequest13Mode != 255 && abuWriteProtected) {
1659: hfsRequest3Error = DEV_IGNORE | DEV_RETRY | DEV_ABORT | DEV_CANNOT_WRITE;
1660: hfsRequest18Result = -1;
1661: hfsState = HFS_STATE_DONE;
1662: return;
1663: }
1664: hfsRequest18Result = 0;
1665: hfsState = HFS_STATE_HOST;
1666: }
1667:
1668:
1669: public void hfuCallChmodHost () {
1670: File file1 = new File (hfuTargetName1);
1671: if (!file1.exists ()) {
1672: hfsRequest18Result = DOS_FILE_NOT_FOUND;
1673: } else if (hfsRequest13Mode == 255) {
1674: hfsRequest18Result = ((file1.isFile () ? HumanMedia.HUM_ARCHIVE : 0) |
1675: (file1.isDirectory () ? HumanMedia.HUM_DIRECTORY : 0) |
1676: (file1.isHidden () ? HumanMedia.HUM_HIDDEN : 0) |
1677: (!file1.canWrite () ? HumanMedia.HUM_READONLY : 0));
1678: } else {
1679: hfsRequest18Result = 0;
1680: boolean oldReadonly = !file1.canWrite ();
1681: boolean newReadonly = (hfsRequest13Mode & HumanMedia.HUM_READONLY) != 0;
1682: if (oldReadonly != newReadonly) {
1683: try {
1684: if (!file1.setWritable (!newReadonly)) {
1685: hfsRequest18Result = DOS_CANNOT_WRITE;
1686: }
1687: } catch (Exception e) {
1688: hfsRequest18Result = DOS_CANNOT_WRITE;
1689: }
1690: }
1691: if (false) {
1692: boolean oldHidden = file1.isHidden ();
1693: boolean newHidden = (hfsRequest13Mode & HumanMedia.HUM_HIDDEN) != 0;
1694: if (oldHidden != newHidden) {
1695: hfsRequest18Result = DOS_CANNOT_WRITE;
1696: }
1697: if ((hfsRequest13Mode & HumanMedia.HUM_VOLUME) != 0) {
1698: hfsRequest18Result = DOS_CANNOT_WRITE;
1699: }
1700: }
1701: }
1702: hfsState = HFS_STATE_DONE;
1703: }
1704:
1705:
1706:
1707:
1708:
1709:
1710:
1711:
1712:
1713:
1714:
1715:
1716:
1717:
1718:
1719:
1720:
1721:
1722:
1723:
1724:
1725:
1726:
1727:
1728:
1729:
1730:
1731:
1732:
1733:
1734:
1735:
1736:
1737:
1738:
1739:
1740:
1741:
1742:
1743:
1744:
1745:
1746:
1747:
1748:
1749:
1750:
1751:
1752:
1753:
1754:
1755:
1756: public void hfuCallFiles () throws M68kException {
1757:
1758: byte[] w = hfuTargetNameArray1;
1759: MC68060.mmuReadByteArray (hfsRequest14Namests, w, 0, 88, XEiJ.regSRS);
1760: String dirName = hfuTargetName1 = hfuNamestsToPath (w, false);
1761: if (hfuTargetName1 == null) {
1762: hfsRequest18Result = DOS_ILLEGAL_FILE_NAME;
1763: hfsState = HFS_STATE_DONE;
1764: return;
1765: }
1766: if (HFS_COMMAND_TRACE && hfsCommandTraceOn) {
1767: int pc = MainMemory.mmrGetLevelZeroPC ();
1768: System.out.println (LabeledAddress.lblSearch (new StringBuilder (), pc).toString ());
1769: System.out.printf ("%08x files(name=\"%s\",mode=0x%02x)\n",
1770: pc, dirName, hfsRequest13Mode);
1771: }
1772: if (!abuInserted) {
1773: hfsRequest3Error = DEV_RETRY | DEV_ABORT | DEV_INSERT_MEDIA;
1774: hfsRequest18Result = -1;
1775: hfsState = HFS_STATE_DONE;
1776: return;
1777: }
1778: hfsRequest18Result = 0;
1779: hfsState = HFS_STATE_HOST;
1780: }
1781:
1782:
1783: public void hfuCallFilesHost () {
1784: byte[] w = hfuTargetNameArray1;
1785: String dirName = hfuTargetName1;
1786: File parent = new File (dirName);
1787:
1788: String[] children = parent.list ();
1789: if (children == null) {
1790: hfsRequest18Result = DOS_DIRECTORY_NOT_FOUND;
1791: hfsState = HFS_STATE_DONE;
1792: return;
1793: }
1794:
1795:
1796:
1797:
1798:
1799:
1800:
1801:
1802:
1803:
1804:
1805:
1806:
1807:
1808: for (int i = 21; i <= 28; i++) {
1809: w[i] = w[67 - 21 + i];
1810: }
1811: if (w[74] == '?' && w[78] == '\0') {
1812: for (int i = 29; i <= 38; i++) {
1813: w[i] = '?';
1814: }
1815: } else {
1816: for (int i = 29; i <= 38; i++) {
1817: w[i] = w[78 - 29 + i];
1818: }
1819: }
1820: for (int i = 38; i >= 21 && (w[i] == '\0' || w[i] == ' '); i--) {
1821: w[i] = '\0';
1822: }
1823: for (int i = 39; i <= 41; i++) {
1824: w[i] = w[75 - 39 + i];
1825: }
1826: for (int i = 41; i >= 39 && (w[i] == '\0' || w[i] == ' '); i--) {
1827: w[i] = '\0';
1828: }
1829:
1830: for (int i = 21; i <= 41; i++) {
1831: int c = w[i] & 255;
1832: if ('A' <= c && c <= 'Z') {
1833: w[i] = (byte) (c | 0x20);
1834: } else if (0x81 <= c && c <= 0x9f || 0xe0 <= c && c <= 0xef) {
1835: i++;
1836: }
1837: }
1838:
1839: boolean isRoot = dirName.equals (hfuRootPath);
1840: boolean humansysRequired = isRoot;
1841: boolean commandxRequired = isRoot;
1842: ArrayDeque<byte[]> deque = new ArrayDeque<byte[]> ();
1843: if (isRoot) {
1844: if ((hfsRequest13Mode & HumanMedia.HUM_VOLUME) != 0 &&
1845: w[21] == '?' && w[39] == '?') {
1846:
1847: int l = dirName.length ();
1848: while (2 <= l &&
1849: (dirName.charAt (l - 1) == '/' ||
1850: dirName.charAt (l - 1) == '\\' ||
1851: (dirName.charAt (l - 1) == '.' &&
1852: (dirName.charAt (l - 2) == '/' ||
1853: dirName.charAt (l - 2) == '\\')))) {
1854: l--;
1855: }
1856: byte[] b = new byte[32];
1857:
1858:
1859:
1860:
1861:
1862: hfuFileInfo (parent, b);
1863: b[0] = HumanMedia.HUM_VOLUME;
1864: b[5] = b[6] = b[7] = b[8] = 0;
1865: int k = 9;
1866: for (int i = 0; i < l; i++) {
1867: int c = CharacterCode.chrCharToSJIS[dirName.charAt (i)];
1868: if (c < 0x0100) {
1869: if (9 + 21 < k + 1) {
1870: k = 0;
1871: break;
1872: }
1873: b[k++] = (byte) c;
1874: } else {
1875: if (9 + 21 < k + 2) {
1876: k = 0;
1877: break;
1878: }
1879: b[k++] = (byte) (c >> 8);
1880: b[k++] = (byte) c;
1881: }
1882: }
1883: if (k == 0) {
1884: k = 9;
1885:
1886: for (int i = 0; i < l; i++) {
1887: int c = CharacterCode.chrCharToSJIS[dirName.charAt (i)];
1888: if (c < 0x0100) {
1889: if (9 + 5 < k + 1) {
1890: break;
1891: }
1892: b[k++] = (byte) c;
1893: } else {
1894: if (9 + 5 < k + 2) {
1895: break;
1896: }
1897: b[k++] = (byte) (c >> 8);
1898: b[k++] = (byte) c;
1899: }
1900: }
1901:
1902: b[k++] = (byte) '_';
1903:
1904: int j = 9 + 21;
1905: for (int i = l - 1; 0 <= i; i--) {
1906: int c = CharacterCode.chrCharToSJIS[dirName.charAt (i)];
1907: if (c < 0x0100) {
1908: if (j - 1 < k) {
1909: break;
1910: }
1911: b[--j] = (byte) c;
1912: } else {
1913: if (j - 2 < k) {
1914: break;
1915: }
1916: b[--j] = (byte) c;
1917: b[--j] = (byte) (c >> 8);
1918: }
1919: }
1920: if (k < j) {
1921: while (j < 9 + 21) {
1922: b[k++] = b[j++];
1923: }
1924: } else {
1925: k = 9 + 21;
1926: }
1927: }
1928: for (int i = k; i <= 31; i++) {
1929: b[i] = '\0';
1930: }
1931: if (b[27] != '\0') {
1932: b[30] = b[29];
1933: b[29] = b[28];
1934: b[28] = b[27];
1935: b[27] = (byte) '.';
1936: }
1937: if (HFS_DEBUG_FILE_INFO) {
1938: System.out.print ("FILES ");
1939: hfuPrintFileInfo (b);
1940: }
1941:
1942: deque.addLast (b);
1943: }
1944: }
1945: childrenLoop:
1946: for (String childName : children) {
1947: int l = childName.length ();
1948: if (l == 0) {
1949: continue childrenLoop;
1950: }
1951:
1952: boolean isHumansys = false;
1953: boolean isCommandx = false;
1954: if (isRoot) {
1955: if (childName.equals (".") || childName.equals ("..")) {
1956: continue childrenLoop;
1957: }
1958: isHumansys = childName.equalsIgnoreCase ("HUMAN.SYS");
1959: if (isHumansys) {
1960: humansysRequired = false;
1961: }
1962: isCommandx = childName.equalsIgnoreCase ("COMMAND.X");
1963: if (isCommandx) {
1964: commandxRequired = false;
1965: }
1966: }
1967:
1968:
1969:
1970:
1971:
1972: byte[] b = new byte[32];
1973:
1974:
1975:
1976:
1977:
1978: int k = 9;
1979: for (int i = 0; i < l; i++) {
1980: int c = CharacterCode.chrCharToSJIS[childName.charAt (i)];
1981: if (c <= 0x1f ||
1982: c == '/' || c == '\\' ||
1983: (c == '-' && i == 0) ||
1984: c == '"' || c == '\'' ||
1985:
1986: c == ',' ||
1987: c == ';' || c == '<' || c == '=' || c == '>' ||
1988: c == '[' || c == ']' ||
1989: c == '|') {
1990: continue childrenLoop;
1991: }
1992: if (c < 0x0100) {
1993: if (k >= 31) {
1994: continue childrenLoop;
1995: }
1996: b[k++] = (byte) c;
1997: } else {
1998: if (k >= 30) {
1999: continue childrenLoop;
2000: }
2001: b[k++] = (byte) (c >> 8);
2002: b[k++] = (byte) c;
2003: }
2004: }
2005: for (int i = k; i <= 31; i++) {
2006: b[i] = '\0';
2007: }
2008:
2009:
2010:
2011:
2012:
2013:
2014:
2015:
2016: int m = (b[k - 1] == '.' ? k :
2017: k >= 9 + 3 && b[k - 2] == '.' ? k - 2 :
2018: k >= 9 + 4 && b[k - 3] == '.' ? k - 3 :
2019: k >= 9 + 5 && b[k - 4] == '.' ? k - 4 :
2020: k);
2021: if (m > 9 + 18) {
2022: continue childrenLoop;
2023: }
2024: {
2025: int i = 0;
2026: for (int j = 9; j < m; j++) {
2027: w[i++] = b[j];
2028: }
2029: while (i <= 17) {
2030: w[i++] = '\0';
2031: }
2032: for (int j = m + 1; j < k; j++) {
2033: w[i++] = b[j];
2034: }
2035: while (i <= 20) {
2036: w[i++] = '\0';
2037: }
2038: }
2039:
2040:
2041:
2042:
2043:
2044:
2045:
2046:
2047:
2048:
2049:
2050: {
2051: int f = 0x20;
2052: for (int i = 0; i <= 20; i++) {
2053: int c = w[i] & 255;
2054: int d = w[21 + i] & 255;
2055: if (d != '?' && ('A' <= c && c <= 'Z' ? c | f : c) != d) {
2056: continue childrenLoop;
2057: }
2058: f = f != 0x00 && (0x81 <= c && c <= 0x9f || 0xe0 <= c && c <= 0xef) ? 0x00 : 0x20;
2059: }
2060: }
2061:
2062: File file = new File (parent, childName);
2063: if (0xffffffffL < file.length ()) {
2064: continue childrenLoop;
2065: }
2066: hfuFileInfo (file, b);
2067: if (isHumansys) {
2068: b[0] |= HumanMedia.HUM_SYSTEM;
2069: }
2070: if (HFS_DEBUG_FILE_INFO) {
2071: System.out.print ("FILES ");
2072: hfuPrintFileInfo (b);
2073: }
2074: if ((b[0] & hfsRequest13Mode) == 0) {
2075: continue childrenLoop;
2076: }
2077:
2078: deque.addLast (b);
2079: }
2080: if (false) {
2081: if (isRoot) {
2082: if (humansysRequired) {
2083:
2084: }
2085: if (commandxRequired) {
2086:
2087: }
2088: }
2089: }
2090: if (deque.isEmpty ()) {
2091: hfsRequest18Result = DOS_FILE_NOT_FOUND;
2092: hfsState = HFS_STATE_DONE;
2093: return;
2094: }
2095: hfuFilesBufferCounter++;
2096: hfuFilesBufferToArrayDeque.put (hfuFilesBufferCounter, deque);
2097: hfsRequest18Result = 0;
2098: hfsState = HFS_STATE_X68K;
2099: }
2100:
2101:
2102: public void hfuCallFilesX68k () throws M68kException {
2103: MC68060.mmuWriteLongData (hfsRequest18Param + 2, HFU_FILES_MAGIC, XEiJ.regSRS);
2104: MC68060.mmuWriteLongData (hfsRequest18Param + 6, hfuFilesBufferCounter, XEiJ.regSRS);
2105:
2106:
2107: int key = hfuFilesBufferCounter;
2108: ArrayDeque<byte[]> deque = hfuFilesBufferToArrayDeque.get (key);
2109: if (deque == null) {
2110: hfsRequest18Result = DOS_NO_MORE_FILES;
2111: hfsState = HFS_STATE_DONE;
2112: return;
2113: }
2114: byte[] b = deque.pollFirst ();
2115: MC68060.mmuWriteByteArray (hfsRequest18Param + 21, b, 0, 32, XEiJ.regSRS);
2116: if (deque.isEmpty ()) {
2117: MC68060.mmuWriteLongData (hfsRequest18Param + 2, 0, XEiJ.regSRS);
2118: MC68060.mmuWriteLongData (hfsRequest18Param + 6, 0, XEiJ.regSRS);
2119: hfuFilesBufferToArrayDeque.remove (key);
2120: }
2121: hfsRequest18Result = 0;
2122: hfsState = HFS_STATE_DONE;
2123: }
2124:
2125:
2126:
2127:
2128:
2129:
2130:
2131:
2132:
2133:
2134:
2135:
2136:
2137:
2138:
2139: public void hfuCallNfiles () throws M68kException {
2140: if (HFS_COMMAND_TRACE && hfsCommandTraceOn) {
2141: int pc = MainMemory.mmrGetLevelZeroPC ();
2142: System.out.println (LabeledAddress.lblSearch (new StringBuilder (), pc).toString ());
2143: System.out.printf ("%08x nfiles()\n",
2144: pc);
2145: }
2146: if (!abuInserted) {
2147: hfsRequest3Error = DEV_RETRY | DEV_ABORT | DEV_INSERT_MEDIA;
2148: hfsRequest18Result = -1;
2149: hfsState = HFS_STATE_DONE;
2150: return;
2151: }
2152: if (MC68060.mmuReadLongData (hfsRequest18Param + 2, XEiJ.regSRS) != HFU_FILES_MAGIC) {
2153: hfsRequest18Result = DOS_NO_MORE_FILES;
2154: hfsState = HFS_STATE_DONE;
2155: return;
2156: }
2157: int key = MC68060.mmuReadLongData (hfsRequest18Param + 6, XEiJ.regSRS);
2158: ArrayDeque<byte[]> deque = hfuFilesBufferToArrayDeque.get (key);
2159: if (deque == null) {
2160: hfsRequest18Result = DOS_NO_MORE_FILES;
2161: hfsState = HFS_STATE_DONE;
2162: return;
2163: }
2164: byte[] b = deque.pollFirst ();
2165: MC68060.mmuWriteByteArray (hfsRequest18Param + 21, b, 0, 32, XEiJ.regSRS);
2166: if (deque.isEmpty ()) {
2167: MC68060.mmuWriteLongData (hfsRequest18Param + 2, 0, XEiJ.regSRS);
2168: MC68060.mmuWriteLongData (hfsRequest18Param + 6, 0, XEiJ.regSRS);
2169: hfuFilesBufferToArrayDeque.remove (key);
2170: }
2171: hfsRequest18Result = 0;
2172: hfsState = HFS_STATE_DONE;
2173: }
2174:
2175:
2176:
2177:
2178:
2179:
2180:
2181:
2182:
2183:
2184:
2185:
2186:
2187:
2188:
2189:
2190:
2191:
2192: public void hfuCallCreateNewfile () throws M68kException {
2193: byte[] w = hfuTargetNameArray1;
2194: MC68060.mmuReadByteArray (hfsRequest14Namests, w, 0, 88, XEiJ.regSRS);
2195: hfuTargetName1 = hfuNamestsToPath (w, true);
2196: if (hfuTargetName1 == null) {
2197: hfsRequest18Result = DOS_ILLEGAL_FILE_NAME;
2198: hfsState = HFS_STATE_DONE;
2199: return;
2200: }
2201: if (HFS_COMMAND_TRACE && hfsCommandTraceOn) {
2202: int pc = MainMemory.mmrGetLevelZeroPC ();
2203: System.out.println (LabeledAddress.lblSearch (new StringBuilder (), pc).toString ());
2204: System.out.printf ("%08x %s(fcb=0x%08x,name=\"%s\",mode=0x%02x)\n",
2205: pc, hfsRequest18Param == 0 ? "newfile" : "create", hfsRequest22Fcb, hfuTargetName1, hfsRequest13Mode);
2206: }
2207: if (!abuInserted) {
2208: hfsRequest3Error = DEV_RETRY | DEV_ABORT | DEV_INSERT_MEDIA;
2209: hfsRequest18Result = -1;
2210: hfsState = HFS_STATE_DONE;
2211: return;
2212: }
2213: if (abuWriteProtected) {
2214: hfsRequest3Error = DEV_IGNORE | DEV_RETRY | DEV_ABORT | DEV_CANNOT_WRITE;
2215: hfsRequest18Result = -1;
2216: hfsState = HFS_STATE_DONE;
2217: return;
2218: }
2219: hfsRequest18Result = 0;
2220: hfsState = HFS_STATE_HOST;
2221: }
2222:
2223:
2224: public void hfuCallCreateNewfileHost () {
2225: byte[] b = hfuTargetNameArray2;
2226: File file = new File (hfuTargetName1);
2227: if (file.exists ()) {
2228: if (hfsRequest18Param == 0) {
2229: hfsRequest18Result = DOS_FILE_EXISTS;
2230: hfsState = HFS_STATE_DONE;
2231: return;
2232: }
2233:
2234:
2235:
2236: if (file.isDirectory () ||
2237: !file.delete ()) {
2238: hfsRequest18Result = DOS_CANNOT_WRITE;
2239: hfsState = HFS_STATE_DONE;
2240: return;
2241: }
2242: }
2243: RandomAccessFile raf;
2244: try {
2245: raf = new RandomAccessFile (file, "rw");
2246: } catch (IOException ioe) {
2247: hfsRequest18Result = DOS_CANNOT_WRITE;
2248: hfsState = HFS_STATE_DONE;
2249: return;
2250: }
2251: if (hfuFcbToHandle.isEmpty ()) {
2252: prevent ();
2253: }
2254: hfuFileInfo (file, b);
2255: if (HFS_DEBUG_FILE_INFO) {
2256: System.out.print ("CREATE ");
2257: hfuPrintFileInfo (b);
2258: }
2259: int fcb = hfsRequest22Fcb;
2260: HFHandle handle = hfuTargetHandle = hfuNewHandle (fcb, file, raf);
2261: hfuFcbToHandle.put (fcb, handle);
2262: hfsRequest18Result = 0;
2263: hfsState = HFS_STATE_X68K;
2264: }
2265:
2266:
2267: public void hfuCallCreateNewfileX68k () throws M68kException {
2268: HFHandle handle = hfuTargetHandle;
2269: int fcb = handle.hfhFcb;
2270: byte[] w = hfuTargetNameArray1;
2271: byte[] b = hfuTargetNameArray2;
2272:
2273:
2274:
2275:
2276:
2277:
2278:
2279:
2280:
2281:
2282:
2283:
2284:
2285:
2286:
2287:
2288:
2289:
2290: for (int i = 0; i < 8 + 3; i++) {
2291: MC68060.mmuWriteByteData (fcb + 36 + i, w[67 + i], XEiJ.regSRS);
2292: }
2293: MC68060.mmuWriteByteData (fcb + 47, b[0], XEiJ.regSRS);
2294: for (int i = 0; i < 10; i++) {
2295: MC68060.mmuWriteByteData (fcb + 48 + i, w[78 + i], XEiJ.regSRS);
2296: }
2297: MC68060.mmuWriteLongData (fcb + 58, ByteArray.byaRls (b, 1), XEiJ.regSRS);
2298: MC68060.mmuWriteWordData (fcb + 62, 0, XEiJ.regSRS);
2299: MC68060.mmuWriteLongData (fcb + 64, ByteArray.byaRls (b, 5), XEiJ.regSRS);
2300: hfsRequest18Result = 0;
2301: hfsState = HFS_STATE_DONE;
2302: }
2303:
2304:
2305:
2306:
2307:
2308:
2309:
2310:
2311:
2312:
2313:
2314:
2315:
2316:
2317:
2318: public void hfuCallOpen () throws M68kException {
2319: byte[] w = hfuTargetNameArray1;
2320: MC68060.mmuReadByteArray (hfsRequest14Namests, w, 0, 88, XEiJ.regSRS);
2321: hfuTargetName1 = hfuNamestsToPath (w, true);
2322: if (hfuTargetName1 == null) {
2323: hfsRequest18Result = DOS_ILLEGAL_FILE_NAME;
2324: hfsState = HFS_STATE_DONE;
2325: return;
2326: }
2327: int fcb = hfsRequest22Fcb;
2328: hfuTargetOpenMode = MC68060.mmuReadByteZeroData (fcb + 14, XEiJ.regSRS);
2329: if (HFS_COMMAND_TRACE && hfsCommandTraceOn) {
2330: int pc = MainMemory.mmrGetLevelZeroPC ();
2331: System.out.println (LabeledAddress.lblSearch (new StringBuilder (), pc).toString ());
2332: System.out.printf ("%08x open(fcb=0x%08x,name=\"%s\",mode=0x%02x)\n",
2333: pc, hfsRequest22Fcb, hfuTargetName1, hfuTargetOpenMode);
2334: }
2335: if (!abuInserted) {
2336: hfsRequest3Error = DEV_RETRY | DEV_ABORT | DEV_INSERT_MEDIA;
2337: hfsRequest18Result = -1;
2338: hfsState = HFS_STATE_DONE;
2339: return;
2340: }
2341: if (hfuTargetOpenMode != 0 && abuWriteProtected) {
2342: hfsRequest3Error = DEV_IGNORE | DEV_RETRY | DEV_ABORT | DEV_CANNOT_WRITE;
2343: hfsRequest18Result = -1;
2344: hfsState = HFS_STATE_DONE;
2345: return;
2346: }
2347: hfsRequest18Result = 0;
2348: hfsState = HFS_STATE_HOST;
2349: }
2350:
2351:
2352: public void hfuCallOpenHost () {
2353: byte[] b = hfuTargetNameArray2;
2354: File file = new File (hfuTargetName1);
2355:
2356:
2357:
2358:
2359: if (!file.exists ()) {
2360: hfsRequest18Result = DOS_FILE_NOT_FOUND;
2361: hfsState = HFS_STATE_DONE;
2362: return;
2363: }
2364: if (0xffffffffL < file.length ()) {
2365: hfsRequest18Result = DOS_FILE_NOT_FOUND;
2366: hfsState = HFS_STATE_DONE;
2367: return;
2368: }
2369: hfuFileInfo (file, b);
2370: if (HFS_DEBUG_FILE_INFO) {
2371: System.out.print ("OPEN ");
2372: hfuPrintFileInfo (b);
2373: }
2374: RandomAccessFile raf;
2375: try {
2376: raf = new RandomAccessFile (file, hfuTargetOpenMode == 0 ? "r" : "rw");
2377: if (HFS_UTF8_WARNING &&
2378: hfsUTF8WarningOn &&
2379: !hfsUTF8WarningSet.contains (hfuTargetName1)) {
2380: hfsUTF8WarningSet.add (hfuTargetName1);
2381:
2382: int ll = (int) Math.min (4096, file.length ());
2383: byte[] bb = new byte[ll];
2384: int kk = 0;
2385: while (kk < ll) {
2386: int tt = raf.read (bb, kk, ll - kk);
2387: if (tt < 0) {
2388: break;
2389: }
2390: kk += tt;
2391: }
2392: raf.seek (0);
2393: if (!hfuUTF8WarningTest (bb, kk)) {
2394: System.out.println ("The character encoding of " + hfuTargetName1 + " is UTF-8, not SJIS.");
2395: }
2396: }
2397: } catch (IOException ioe) {
2398: hfsRequest18Result = DOS_FILE_NOT_FOUND;
2399: hfsState = HFS_STATE_DONE;
2400: return;
2401: }
2402: if (hfuFcbToHandle.isEmpty ()) {
2403: prevent ();
2404: }
2405: int fcb = hfsRequest22Fcb;
2406: HFHandle handle = hfuTargetHandle = hfuNewHandle (fcb, file, raf);
2407: hfuFcbToHandle.put (fcb, handle);
2408: hfsRequest18Result = 0;
2409: hfsState = HFS_STATE_X68K;
2410: }
2411:
2412:
2413:
2414: private static boolean hfuUTF8WarningTest (byte[] b, int k) {
2415:
2416:
2417:
2418:
2419:
2420: for (int i = 0; i < k; i++) {
2421: int c = b[i] & 0xff;
2422: if (c <= 0x7f) {
2423: if (c != 0x00) {
2424: continue;
2425: }
2426: } else if (c <= 0xbf) {
2427: } else if (c <= 0xdf) {
2428: int d = i + 1 < k ? b[i + 1] & 0xff : -1;
2429: if (d == -1 || (0x80 <= d && d <= 0xbf)) {
2430: i++;
2431: continue;
2432: }
2433: } else if (c <= 0xef) {
2434: int d = i + 1 < k ? b[i + 1] & 0xff : -1;
2435: int e = i + 2 < k ? b[i + 2] & 0xff : -1;
2436: if ((d == -1 || (0x80 <= d && d <= 0xbf)) &&
2437: (e == -1 || (0x80 <= e && e <= 0xbf))) {
2438: i += 2;
2439: continue;
2440: }
2441: } else if (c <= 0xf7) {
2442: int d = i + 1 < k ? b[i + 1] & 0xff : -1;
2443: int e = i + 2 < k ? b[i + 2] & 0xff : -1;
2444: int f = i + 3 < k ? b[i + 3] & 0xff : -1;
2445: if ((d == -1 || (0x80 <= d && d <= 0xbf)) &&
2446: (e == -1 || (0x80 <= e && e <= 0xbf)) &&
2447: (f == -1 || (0x80 <= f && f <= 0xbf))) {
2448: i += 3;
2449: continue;
2450: }
2451: } else {
2452: }
2453: return true;
2454: }
2455:
2456:
2457:
2458:
2459:
2460: for (int i = 0; i < k; i++) {
2461: int c = b[i] & 0xff;
2462: if ((0x00 <= c && c <= 0x7f) ||
2463: (0xa0 <= c && c <= 0xdf)) {
2464: if (c != 0x00) {
2465: continue;
2466: }
2467: } else if (c == 0x80 ||
2468: (0xf0 <= c && c <= 0xf5)) {
2469: if (k <= i + 1 || b[i + 1] != 0x00) {
2470: i++;
2471: continue;
2472: }
2473: } else if ((0x81 <= c && c <= 0x9f) ||
2474: (0xe0 <= c && c <= 0xef)) {
2475: int d = i + 1 < k ? b[i + 1] & 0xff : -1;
2476: if (d == -1 || (0x40 <= d && d <= 0xfc && d != 0x7f)) {
2477: i++;
2478: continue;
2479: }
2480: } else {
2481: }
2482: return false;
2483: }
2484: return true;
2485: }
2486:
2487:
2488: public void hfuCallOpenX68k () throws M68kException {
2489: HFHandle handle = hfuTargetHandle;
2490: int fcb = handle.hfhFcb;
2491: byte[] w = hfuTargetNameArray1;
2492: byte[] b = hfuTargetNameArray2;
2493:
2494:
2495:
2496:
2497:
2498:
2499:
2500:
2501:
2502:
2503:
2504:
2505:
2506:
2507:
2508:
2509:
2510:
2511: for (int i = 0; i < 8 + 3; i++) {
2512: MC68060.mmuWriteByteData (fcb + 36 + i, w[67 + i], XEiJ.regSRS);
2513: }
2514: MC68060.mmuWriteByteData (fcb + 47, b[0], XEiJ.regSRS);
2515: for (int i = 0; i < 10; i++) {
2516: MC68060.mmuWriteByteData (fcb + 48 + i, w[78 + i], XEiJ.regSRS);
2517: }
2518: MC68060.mmuWriteLongData (fcb + 58, ByteArray.byaRls (b, 1), XEiJ.regSRS);
2519: MC68060.mmuWriteWordData (fcb + 62, 0, XEiJ.regSRS);
2520: MC68060.mmuWriteLongData (fcb + 64, ByteArray.byaRls (b, 5), XEiJ.regSRS);
2521: hfsRequest18Result = 0;
2522: hfsState = HFS_STATE_DONE;
2523: }
2524:
2525:
2526:
2527:
2528:
2529:
2530:
2531:
2532:
2533:
2534:
2535:
2536:
2537:
2538:
2539: public void hfuCallClose () throws M68kException {
2540: if (HFS_COMMAND_TRACE && hfsCommandTraceOn) {
2541: int pc = MainMemory.mmrGetLevelZeroPC ();
2542: System.out.println (LabeledAddress.lblSearch (new StringBuilder (), pc).toString ());
2543: System.out.printf ("%08x close(fcb=0x%08x)\n",
2544: pc, hfsRequest22Fcb);
2545: }
2546: if (!abuInserted) {
2547: hfsRequest3Error = DEV_RETRY | DEV_ABORT | DEV_INSERT_MEDIA;
2548: hfsRequest18Result = -1;
2549: hfsState = HFS_STATE_DONE;
2550: return;
2551: }
2552: int fcb = hfsRequest22Fcb;
2553: HFHandle handle = hfuTargetHandle = hfuFcbToHandle.remove (fcb);
2554: if (handle == null) {
2555:
2556: hfsRequest18Result = 0;
2557: hfsState = HFS_STATE_DONE;
2558: return;
2559: }
2560: hfsRequest18Result = 0;
2561: hfsState = HFS_STATE_HOST;
2562: }
2563:
2564:
2565: public void hfuCallCloseHost () {
2566: HFHandle handle = hfuTargetHandle;
2567: if (hfsRequest18Result != 0) {
2568: File file = handle.hfhFile;
2569: if (!file.setLastModified (hfuTargetLastModified)) {
2570: System.out.println ((Multilingual.mlnJapanese ? "最終更新日時を設定できません: " : "Could not set last modified date and time: ") + handle.toString ());
2571: }
2572: if (hfuFcbToHandle.isEmpty ()) {
2573: allow ();
2574: }
2575: hfuRecycleHandle (handle);
2576: handle = hfuTargetHandle = null;
2577: hfsRequest18Result = 0;
2578: hfsState = HFS_STATE_DONE;
2579: return;
2580: }
2581: RandomAccessFile raf = handle.hfhRaf;
2582:
2583: if (handle.hfhDirty) {
2584: if (HFS_BUFFER_TRACE) {
2585: System.out.printf ("delaywrite(fcb=0x%08x,name=\"%s\",start=0x%08x,end=0x%08x)\n", handle.hfhFcb, handle.hfhFile.toString(), handle.hfhStart, handle.hfhEnd);
2586: }
2587: try {
2588: handle.hfhRaf.seek (handle.hfhStart);
2589: } catch (IOException ioe) {
2590: System.out.println ((Multilingual.mlnJapanese ? "シークエラー: " : "Seek error: ") + handle.toString ());
2591: }
2592: try {
2593: handle.hfhRaf.write (handle.hfhBuffer, 0, (int) (handle.hfhEnd - handle.hfhStart));
2594: } catch (IOException ioe) {
2595: System.out.println ((Multilingual.mlnJapanese ? "遅延書き込みに失敗しました: " : "Delayed write failed: ") + handle.toString ());
2596: }
2597: handle.hfhDirty = false;
2598: }
2599: try {
2600: raf.close ();
2601: } catch (IOException ioe) {
2602: System.out.println ((Multilingual.mlnJapanese ? "クローズエラー: " : "Close error: ") + handle.toString ());
2603: }
2604: hfsRequest18Result = 0;
2605: hfsState = HFS_STATE_X68K;
2606: }
2607:
2608:
2609: public void hfuCallCloseX68k () throws M68kException {
2610: HFHandle handle = hfuTargetHandle;
2611: int fcb = handle.hfhFcb;
2612: if ((MC68060.mmuReadByteZeroData (fcb + 14, XEiJ.regSRS) & 15) == 0) {
2613: if (hfuFcbToHandle.isEmpty ()) {
2614: allow ();
2615: }
2616: hfuRecycleHandle (handle);
2617: handle = hfuTargetHandle = null;
2618: hfsRequest18Result = 0;
2619: hfsState = HFS_STATE_DONE;
2620: return;
2621: }
2622: if ((MC68060.mmuReadByteZeroData (fcb + 1, XEiJ.regSRS) & 0x40) != 0) {
2623: hfuTargetLastModified = System.currentTimeMillis ();
2624: } else {
2625: int time = MC68060.mmuReadWordZeroData (fcb + 58, XEiJ.regSRS);
2626: int date = MC68060.mmuReadWordZeroData (fcb + 60, XEiJ.regSRS);
2627: hfuTargetLastModified = DnT.dntCmilYearMontMdayHourMinuSeco (
2628: (date >> 9) + 1980, date >> 5 & 15, date & 31,
2629: time >> 11, time >> 5 & 63, (time & 31) << 1) - RP5C15.rtcCmilGap;
2630: }
2631: hfsRequest18Result = 1;
2632: hfsState = HFS_STATE_HOST;
2633: }
2634:
2635:
2636:
2637:
2638:
2639:
2640:
2641:
2642:
2643:
2644:
2645:
2646:
2647:
2648:
2649: public void hfuCallRead () throws M68kException {
2650: if (HFS_BUFFER_TRACE || (HFS_COMMAND_TRACE && hfsCommandTraceOn)) {
2651: int pc = MainMemory.mmrGetLevelZeroPC ();
2652: System.out.println (LabeledAddress.lblSearch (new StringBuilder (), pc).toString ());
2653: System.out.printf ("%08x read(fcb=0x%08x,address=0x%08x,length=0x%08x)\n",
2654: pc, hfsRequest22Fcb, hfsRequest14Namests, hfsRequest18Param);
2655: }
2656: if (!abuInserted) {
2657: hfsRequest3Error = DEV_RETRY | DEV_ABORT | DEV_INSERT_MEDIA;
2658: hfsRequest18Result = -1;
2659: hfsState = HFS_STATE_DONE;
2660: return;
2661: }
2662: int fcb = hfsRequest22Fcb;
2663: HFHandle handle = hfuTargetHandle = hfuFcbToHandle.get (fcb);
2664: if (handle == null) {
2665: hfsRequest18Result = DOS_HANDLE_IS_NOT_OPENED;
2666: hfsState = HFS_STATE_DONE;
2667: return;
2668: }
2669: hfuTargetLength = hfsRequest18Param & 0xffffffffL;
2670: if (HFS_BUFFER_TRACE) {
2671: System.out.printf ("length=%d\n", hfuTargetLength);
2672: }
2673: hfuTargetPosition = MC68060.mmuReadLongData (fcb + 6, XEiJ.regSRS) & 0xffffffffL;
2674: if (HFS_BUFFER_TRACE) {
2675: System.out.printf ("position=%d\n", hfuTargetPosition);
2676: }
2677: hfuTargetFileSize = MC68060.mmuReadLongData (fcb + 64, XEiJ.regSRS) & 0xffffffffL;
2678: if (HFS_BUFFER_TRACE) {
2679: System.out.printf ("fileSize=%d\n", hfuTargetFileSize);
2680: }
2681: hfuTargetLength = Math.min (hfuTargetLength, hfuTargetFileSize - hfuTargetPosition);
2682: if (HFS_BUFFER_TRACE) {
2683: System.out.printf ("length=%d\n", hfuTargetLength);
2684: }
2685: if (hfuTargetLength == 0L) {
2686: hfsRequest18Result = 0;
2687: hfsState = HFS_STATE_DONE;
2688: return;
2689: }
2690: hfuTargetAddress = hfsRequest14Namests & 0xffffffffL;
2691: if (HFS_BUFFER_TRACE) {
2692: System.out.printf ("address=0x%08x\n", hfuTargetAddress);
2693: }
2694: hfuTargetTransferred = 0L;
2695: if (HFS_BUFFER_TRACE) {
2696: System.out.printf ("transferred=%d\n", hfuTargetTransferred);
2697: }
2698:
2699:
2700:
2701:
2702:
2703:
2704:
2705:
2706:
2707:
2708:
2709:
2710:
2711:
2712:
2713:
2714:
2715:
2716:
2717: if (hfuTargetFileSize == 0 ||
2718: (0 < handle.hfhEnd &&
2719: handle.hfhStart <= hfuTargetPosition && hfuTargetPosition < handle.hfhStart + HFS_BUFFER_SIZE)) {
2720:
2721: hfsRequest18Result = 0;
2722: hfsState = HFS_STATE_X68K;
2723: } else {
2724:
2725: hfsRequest18Result = 0;
2726: hfsState = HFS_STATE_HOST;
2727: }
2728: }
2729:
2730:
2731: public void hfuCallReadHost () {
2732: HFHandle handle = hfuTargetHandle;
2733: RandomAccessFile raf = handle.hfhRaf;
2734:
2735: if (handle.hfhDirty) {
2736: if (HFS_BUFFER_TRACE) {
2737: System.out.printf ("delaywrite(fcb=0x%08x,name=\"%s\",start=0x%08x,end=0x%08x)\n", handle.hfhFcb, handle.hfhFile.toString(), handle.hfhStart, handle.hfhEnd);
2738: }
2739: try {
2740: raf.seek (handle.hfhStart);
2741: } catch (IOException ioe) {
2742: System.out.println ((Multilingual.mlnJapanese ? "シークエラー: " : "Seek error: ") + handle.toString ());
2743: }
2744: try {
2745: raf.write (handle.hfhBuffer, 0, (int) (handle.hfhEnd - handle.hfhStart));
2746: } catch (IOException ioe) {
2747: System.out.println ((Multilingual.mlnJapanese ? "遅延書き込みに失敗しました: " : "Delayed write failed: ") + handle.toString ());
2748: }
2749: handle.hfhDirty = false;
2750: }
2751:
2752: int ll = (int) Math.min (HFS_BUFFER_SIZE,
2753: hfuTargetFileSize - hfuTargetPosition
2754: );
2755: int kk = 0;
2756: Arrays.fill (handle.hfhBuffer, (byte) 0);
2757: handle.hfhStart = hfuTargetPosition;
2758: handle.hfhEnd = hfuTargetPosition + ll;
2759: handle.hfhDirty = false;
2760: if (HFS_BUFFER_TRACE) {
2761: System.out.printf ("preread(fcb=0x%08x,name=\"%s\",start=0x%08x,end=0x%08x)\n", handle.hfhFcb, handle.hfhFile.toString(), handle.hfhStart, handle.hfhEnd);
2762: }
2763: if (0 < ll) {
2764: try {
2765: raf.seek (hfuTargetPosition);
2766: } catch (IOException ioe) {
2767: System.out.println ((Multilingual.mlnJapanese ? "シークエラー: " : "Seek error: ") + handle.toString ());
2768: }
2769: try {
2770: while (kk < ll) {
2771: int tt = raf.read (handle.hfhBuffer, kk, ll - kk);
2772: if (tt < 0) {
2773:
2774: hfsRequest18Result = -1;
2775: hfsState = HFS_STATE_DONE;
2776: return;
2777: }
2778: kk += tt;
2779: }
2780: } catch (IOException ioe) {
2781: System.out.println ((Multilingual.mlnJapanese ? "リードエラー: " : "Read error: ") + handle.toString ());
2782: hfsRequest18Result = -1;
2783: hfsState = HFS_STATE_DONE;
2784: return;
2785: }
2786: }
2787:
2788: hfsRequest18Result = 0;
2789: hfsState = HFS_STATE_X68K;
2790: }
2791:
2792:
2793: public void hfuCallReadX68k () throws M68kException {
2794: HFHandle handle = hfuTargetHandle;
2795: int fcb = handle.hfhFcb;
2796:
2797: long tt = Math.min (hfuTargetLength - hfuTargetTransferred,
2798: handle.hfhEnd - hfuTargetPosition
2799: );
2800: long t = Math.min (HFS_BUFFER_STEP, tt);
2801: if (HFS_BUFFER_TRACE) {
2802: System.out.printf ("t=%d\n", t);
2803: }
2804: MC68060.mmuWriteByteArray ((int) (hfuTargetAddress + hfuTargetTransferred),
2805: handle.hfhBuffer,
2806: (int) (hfuTargetPosition - handle.hfhStart),
2807: (int) t,
2808: XEiJ.regSRS);
2809: hfuTargetPosition += t;
2810: if (HFS_BUFFER_TRACE) {
2811: System.out.printf ("position=%d\n", hfuTargetPosition);
2812: }
2813: MC68060.mmuWriteLongData (fcb + 6, (int) hfuTargetPosition, XEiJ.regSRS);
2814: hfuTargetTransferred += t;
2815: if (HFS_BUFFER_TRACE) {
2816: System.out.printf ("transferred=%d\n", hfuTargetTransferred);
2817: }
2818: if (hfuTargetLength <= hfuTargetTransferred) {
2819: hfsRequest18Result = (int) hfuTargetTransferred;
2820: hfsState = HFS_STATE_DONE;
2821: return;
2822: }
2823: if (t < tt) {
2824:
2825: hfsRequest18Result = 0;
2826: hfsState = HFS_STATE_X68K;
2827: } else {
2828:
2829: hfsRequest18Result = 0;
2830: hfsState = HFS_STATE_HOST;
2831: }
2832: }
2833:
2834:
2835:
2836:
2837:
2838:
2839:
2840:
2841:
2842:
2843:
2844:
2845:
2846:
2847:
2848: public void hfuCallWrite () throws M68kException {
2849: if (HFS_BUFFER_TRACE || (HFS_COMMAND_TRACE && hfsCommandTraceOn)) {
2850: int pc = MainMemory.mmrGetLevelZeroPC ();
2851: System.out.println (LabeledAddress.lblSearch (new StringBuilder (), pc).toString ());
2852: System.out.printf ("%08x write(fcb=0x%08x,address=0x%08x,length=0x%08x)\n",
2853: pc, hfsRequest22Fcb, hfsRequest14Namests, hfsRequest18Param);
2854: }
2855: if (!abuInserted) {
2856: hfsRequest3Error = DEV_RETRY | DEV_ABORT | DEV_INSERT_MEDIA;
2857: hfsRequest18Result = -1;
2858: hfsState = HFS_STATE_DONE;
2859: return;
2860: }
2861: if (abuWriteProtected) {
2862: hfsRequest3Error = DEV_IGNORE | DEV_RETRY | DEV_ABORT | DEV_CANNOT_WRITE;
2863: hfsRequest18Result = -1;
2864: hfsState = HFS_STATE_DONE;
2865: return;
2866: }
2867: int fcb = hfsRequest22Fcb;
2868: HFHandle handle = hfuTargetHandle = hfuFcbToHandle.get (fcb);
2869: if (handle == null) {
2870: hfsRequest18Result = DOS_HANDLE_IS_NOT_OPENED;
2871: hfsState = HFS_STATE_DONE;
2872: return;
2873: }
2874: hfuTargetLength = hfsRequest18Param & 0xffffffffL;
2875: if (HFS_BUFFER_TRACE) {
2876: System.out.printf ("length=%d\n", hfuTargetLength);
2877: }
2878: hfuTargetPosition = MC68060.mmuReadLongData (fcb + 6, XEiJ.regSRS) & 0xffffffffL;
2879: if (HFS_BUFFER_TRACE) {
2880: System.out.printf ("position=%d\n", hfuTargetPosition);
2881: }
2882: hfuTargetFileSize = MC68060.mmuReadLongData (fcb + 64, XEiJ.regSRS) & 0xffffffffL;
2883: if (HFS_BUFFER_TRACE) {
2884: System.out.printf ("fileSize=%d\n", hfuTargetFileSize);
2885: }
2886: if (hfuTargetLength == 0L) {
2887: if (hfuTargetFileSize <= hfuTargetPosition) {
2888: hfsRequest18Result = 0;
2889: hfsState = HFS_STATE_DONE;
2890: return;
2891: }
2892: MC68060.mmuWriteLongData (fcb + 64, (int) hfuTargetPosition, XEiJ.regSRS);
2893: hfsRequest18Result = 1;
2894: hfsState = HFS_STATE_HOST;
2895: return;
2896: }
2897: if (0xffffffffL < hfuTargetPosition + hfuTargetLength) {
2898: hfuTargetLength = 0xffffffffL - hfuTargetPosition;
2899: if (HFS_BUFFER_TRACE) {
2900: System.out.printf ("length=%d\n", hfuTargetLength);
2901: }
2902: if (hfuTargetLength == 0L) {
2903: hfsRequest18Result = 0;
2904: hfsState = HFS_STATE_DONE;
2905: return;
2906: }
2907: }
2908: hfuTargetAddress = hfsRequest14Namests & 0xffffffffL;
2909: if (HFS_BUFFER_TRACE) {
2910: System.out.printf ("address=0x%08x\n", hfuTargetAddress);
2911: }
2912: hfuTargetTransferred = 0L;
2913: if (HFS_BUFFER_TRACE) {
2914: System.out.printf ("transferred=%d\n", hfuTargetTransferred);
2915: }
2916:
2917:
2918:
2919:
2920:
2921:
2922:
2923:
2924:
2925:
2926:
2927:
2928:
2929:
2930:
2931:
2932:
2933:
2934:
2935: if (hfuTargetFileSize == 0 ||
2936: (0 < handle.hfhEnd &&
2937: handle.hfhStart <= hfuTargetPosition && hfuTargetPosition < handle.hfhStart + HFS_BUFFER_SIZE)) {
2938:
2939: hfsRequest18Result = 0;
2940: hfsState = HFS_STATE_X68K;
2941: } else {
2942:
2943: hfsRequest18Result = 0;
2944: hfsState = HFS_STATE_HOST;
2945: }
2946: }
2947:
2948:
2949: public void hfuCallWriteHost () {
2950: HFHandle handle = hfuTargetHandle;
2951: RandomAccessFile raf = handle.hfhRaf;
2952: if (hfsRequest18Result != 0) {
2953: if (handle.hfhStart <= hfuTargetPosition && hfuTargetPosition < handle.hfhEnd) {
2954:
2955: Arrays.fill (handle.hfhBuffer, (int) (hfuTargetPosition - handle.hfhStart), (int) (handle.hfhEnd - handle.hfhStart), (byte) 0);
2956: handle.hfhEnd = hfuTargetPosition;
2957: if (HFS_BUFFER_TRACE) {
2958: System.out.printf ("truncate(fcb=0x%08x,name=\"%s\",start=0x%08x,end=0x%08x)\n", handle.hfhFcb, handle.hfhFile.toString(), handle.hfhStart, handle.hfhEnd);
2959: }
2960: }
2961: try {
2962: raf.seek (hfuTargetPosition);
2963: } catch (IOException ioe) {
2964: System.out.println ((Multilingual.mlnJapanese ? "シークエラー: " : "Seek error: ") + handle.toString ());
2965: }
2966:
2967: try {
2968: raf.setLength (hfuTargetPosition);
2969: } catch (IOException ioe) {
2970: System.out.println ((Multilingual.mlnJapanese ? "ファイルの長さを設定できません: " : "Could not set length of file: ") + handle.toString ());
2971: hfsRequest18Result = -1;
2972: hfsState = HFS_STATE_DONE;
2973: return;
2974: }
2975: hfsRequest18Result = 0;
2976: hfsState = HFS_STATE_DONE;
2977: return;
2978: }
2979:
2980: if (handle.hfhDirty) {
2981: if (HFS_BUFFER_TRACE) {
2982: System.out.printf ("delaywrite(fcb=0x%08x,name=\"%s\",start=0x%08x,end=0x%08x)\n", handle.hfhFcb, handle.hfhFile.toString(), handle.hfhStart, handle.hfhEnd);
2983: }
2984: try {
2985: raf.seek (handle.hfhStart);
2986: } catch (IOException ioe) {
2987: System.out.println ((Multilingual.mlnJapanese ? "シークエラー: " : "Seek error: ") + handle.toString ());
2988: }
2989: try {
2990: raf.write (handle.hfhBuffer, 0, (int) (handle.hfhEnd - handle.hfhStart));
2991: } catch (IOException ioe) {
2992: System.out.println ((Multilingual.mlnJapanese ? "遅延書き込みに失敗しました: " : "Delayed write failed: ") + handle.toString ());
2993: }
2994: handle.hfhDirty = false;
2995: }
2996:
2997: int ll = (int) Math.min (HFS_BUFFER_SIZE,
2998: hfuTargetFileSize - hfuTargetPosition
2999: );
3000: int kk = 0;
3001: Arrays.fill (handle.hfhBuffer, (byte) 0);
3002: handle.hfhStart = hfuTargetPosition;
3003: handle.hfhEnd = hfuTargetPosition + ll;
3004: handle.hfhDirty = false;
3005: if (HFS_BUFFER_TRACE) {
3006: System.out.printf ("preread(fcb=0x%08x,name=\"%s\",start=0x%08x,end=0x%08x)\n", handle.hfhFcb, handle.hfhFile.toString(), handle.hfhStart, handle.hfhEnd);
3007: }
3008: if (0 < ll) {
3009: try {
3010: raf.seek (hfuTargetPosition);
3011: } catch (IOException ioe) {
3012: System.out.println ((Multilingual.mlnJapanese ? "シークエラー: " : "Seek error: ") + handle.toString ());
3013: }
3014: try {
3015: while (kk < ll) {
3016: int tt = raf.read (handle.hfhBuffer, kk, ll - kk);
3017: if (tt < 0) {
3018:
3019: hfsRequest18Result = -1;
3020: hfsState = HFS_STATE_DONE;
3021: return;
3022: }
3023: kk += tt;
3024: }
3025: } catch (IOException ioe) {
3026: System.out.println ((Multilingual.mlnJapanese ? "リードエラー: " : "Read error: ") + handle.toString ());
3027: hfsRequest18Result = -1;
3028: hfsState = HFS_STATE_DONE;
3029: return;
3030: }
3031: }
3032:
3033: hfsRequest18Result = 0;
3034: hfsState = HFS_STATE_X68K;
3035: }
3036:
3037:
3038: public void hfuCallWriteX68k () throws M68kException {
3039: HFHandle handle = hfuTargetHandle;
3040: int fcb = handle.hfhFcb;
3041:
3042: long tt = Math.min (hfuTargetLength - hfuTargetTransferred,
3043: handle.hfhStart + HFS_BUFFER_SIZE - hfuTargetPosition
3044: );
3045: long t = Math.min (HFS_BUFFER_STEP, tt);
3046: if (HFS_BUFFER_TRACE) {
3047: System.out.printf ("t=%d\n", t);
3048: }
3049: MC68060.mmuReadByteArray ((int) (hfuTargetAddress + hfuTargetTransferred),
3050: handle.hfhBuffer,
3051: (int) (hfuTargetPosition - handle.hfhStart),
3052: (int) t,
3053: XEiJ.regSRS);
3054: handle.hfhEnd = Math.max (handle.hfhEnd, hfuTargetPosition + t);
3055: handle.hfhDirty = true;
3056: if (HFS_BUFFER_TRACE) {
3057: System.out.printf ("written(fcb=0x%08x,name=\"%s\",start=0x%08x,end=0x%08x,dirty=%b)\n", handle.hfhFcb, handle.hfhFile.toString(), handle.hfhStart, handle.hfhEnd, handle.hfhDirty);
3058: }
3059: hfuTargetPosition += t;
3060: if (HFS_BUFFER_TRACE) {
3061: System.out.printf ("position=%d\n", hfuTargetPosition);
3062: }
3063: MC68060.mmuWriteLongData (fcb + 6, (int) hfuTargetPosition, XEiJ.regSRS);
3064: if (hfuTargetFileSize < hfuTargetPosition) {
3065: hfuTargetFileSize = hfuTargetPosition;
3066: if (HFS_BUFFER_TRACE) {
3067: System.out.printf ("fileSize=%d\n", hfuTargetFileSize);
3068: }
3069: MC68060.mmuWriteLongData (fcb + 64, (int) hfuTargetFileSize, XEiJ.regSRS);
3070: }
3071: hfuTargetTransferred += t;
3072: if (HFS_BUFFER_TRACE) {
3073: System.out.printf ("transferred=%d\n", hfuTargetTransferred);
3074: }
3075: if (hfuTargetLength <= hfuTargetTransferred) {
3076: hfsRequest18Result = (int) hfuTargetTransferred;
3077: hfsState = HFS_STATE_DONE;
3078: return;
3079: }
3080: if (t < tt) {
3081:
3082: hfsRequest18Result = 0;
3083: hfsState = HFS_STATE_X68K;
3084: } else {
3085:
3086: hfsRequest18Result = 0;
3087: hfsState = HFS_STATE_HOST;
3088: }
3089: }
3090:
3091:
3092:
3093:
3094:
3095:
3096:
3097:
3098:
3099:
3100:
3101:
3102:
3103:
3104:
3105: public void hfuCallSeek () throws M68kException {
3106: if (HFS_COMMAND_TRACE && hfsCommandTraceOn) {
3107: int pc = MainMemory.mmrGetLevelZeroPC ();
3108: System.out.println (LabeledAddress.lblSearch (new StringBuilder (), pc).toString ());
3109: System.out.printf ("%08x seek(fcb=0x%08x,offset=0x%08x,mode=0x%02x)\n",
3110: pc, hfsRequest22Fcb, hfsRequest18Param, hfsRequest13Mode);
3111: }
3112: if (!abuInserted) {
3113: hfsRequest3Error = DEV_RETRY | DEV_ABORT | DEV_INSERT_MEDIA;
3114: hfsRequest18Result = -1;
3115: hfsState = HFS_STATE_DONE;
3116: return;
3117: }
3118: int mode = hfsRequest13Mode;
3119: long offset64 = (long) hfsRequest18Param;
3120: int fcb = hfsRequest22Fcb;
3121: HFHandle handle = hfuFcbToHandle.get (fcb);
3122: if (handle == null) {
3123: hfsRequest18Result = DOS_HANDLE_IS_NOT_OPENED;
3124: hfsState = HFS_STATE_DONE;
3125: return;
3126: }
3127: long current64 = (long) MC68060.mmuReadLongData (fcb + 6, XEiJ.regSRS);
3128: long end64 = (long) MC68060.mmuReadLongData (fcb + 64, XEiJ.regSRS);
3129:
3130: current64 = current64 & 0x00000000ffffffffL;
3131:
3132: end64 = end64 & 0x00000000ffffffffL;
3133: if (mode == 0) {
3134:
3135: offset64 = offset64 & 0x00000000ffffffffL;
3136:
3137: current64 = offset64;
3138: } else if (mode == 1) {
3139:
3140: offset64 = ((offset64 + 0x0000000080000000L) & 0x00000000ffffffffL) - 0x0000000080000000L;
3141:
3142: current64 = current64 + offset64;
3143: } else if (mode == 2) {
3144:
3145: offset64 = ((offset64 - 0x0000000000000001L) & 0x00000000ffffffffL) - 0x00000000ffffffffL;
3146:
3147: current64 = end64 + offset64;
3148: } else {
3149:
3150: hfsRequest18Result = DOS_INVALID_PARAMETER;
3151: hfsState = HFS_STATE_DONE;
3152: return;
3153: }
3154: if (current64 < 0x0000000000000000L || end64 < current64) {
3155:
3156: hfsRequest18Result = DOS_SEEK_OVER_EOF;
3157: hfsState = HFS_STATE_DONE;
3158: return;
3159: }
3160:
3161: MC68060.mmuWriteLongData (fcb + 6, (int) current64, XEiJ.regSRS);
3162:
3163: hfsRequest18Result = (int) current64;
3164: hfsState = HFS_STATE_DONE;
3165: }
3166:
3167:
3168:
3169:
3170:
3171:
3172:
3173:
3174:
3175:
3176:
3177:
3178:
3179:
3180:
3181:
3182: public void hfuCallFiledate () throws M68kException {
3183: if (HFS_COMMAND_TRACE && hfsCommandTraceOn) {
3184: int pc = MainMemory.mmrGetLevelZeroPC ();
3185: System.out.println (LabeledAddress.lblSearch (new StringBuilder (), pc).toString ());
3186: System.out.printf ("%08x filedate(fcb=0x%08x,datetime=0x%08x)\n",
3187: pc, hfsRequest22Fcb, hfsRequest18Param);
3188: }
3189: if (!abuInserted) {
3190: hfsRequest3Error = DEV_RETRY | DEV_ABORT | DEV_INSERT_MEDIA;
3191: hfsRequest18Result = -1;
3192: hfsState = HFS_STATE_DONE;
3193: return;
3194: }
3195: int fcb = hfsRequest22Fcb;
3196: int datetime = hfsRequest18Param;
3197: if (datetime == 0) {
3198: datetime = (MC68060.mmuReadWordZeroData (fcb + 60, XEiJ.regSRS) << 16 |
3199: MC68060.mmuReadWordZeroData (fcb + 58, XEiJ.regSRS));
3200: } else {
3201:
3202:
3203:
3204: int time = datetime & 0xffff;
3205: int date = datetime >>> 16;
3206: MC68060.mmuWriteWordData (fcb + 58, time, XEiJ.regSRS);
3207: MC68060.mmuWriteWordData (fcb + 60, date, XEiJ.regSRS);
3208:
3209: int type = MC68060.mmuModifyByteSignData (fcb + 1, XEiJ.regSRS);
3210: if ((type & 0x40) != 0) {
3211: MC68060.mmuWriteByteData (fcb + 1, type & ~0x40, XEiJ.regSRS);
3212: }
3213: }
3214: hfsRequest18Result = datetime;
3215: hfsState = HFS_STATE_DONE;
3216: }
3217:
3218:
3219:
3220:
3221:
3222:
3223:
3224:
3225:
3226:
3227:
3228:
3229:
3230:
3231:
3232:
3233:
3234:
3235:
3236:
3237: public void hfuCallDskfre () throws M68kException {
3238: if (HFS_COMMAND_TRACE && hfsCommandTraceOn) {
3239: int pc = MainMemory.mmrGetLevelZeroPC ();
3240: System.out.println (LabeledAddress.lblSearch (new StringBuilder (), pc).toString ());
3241: System.out.printf ("%08x dskfre(buffer=0x%08x)\n",
3242: pc, hfsRequest14Namests);
3243: }
3244: if (!abuInserted) {
3245: hfsRequest3Error = DEV_RETRY | DEV_ABORT | DEV_INSERT_MEDIA;
3246: hfsRequest18Result = -1;
3247: hfsState = HFS_STATE_DONE;
3248: return;
3249: }
3250: hfsRequest18Result = 0;
3251: hfsState = HFS_STATE_HOST;
3252: }
3253:
3254:
3255: public void hfuCallDskfreHost () {
3256: File file = new File (hfuRootPath);
3257: hfuTargetTotalSpace = file.getTotalSpace ();
3258: hfuTargetFreeSpace = file.getFreeSpace ();
3259: hfsRequest18Result = 0;
3260: hfsState = HFS_STATE_X68K;
3261: }
3262:
3263:
3264: public void hfuCallDskfreX68k () throws M68kException {
3265: int totalSpace = (int) Math.min (0x7fffffffL, hfuTargetTotalSpace);
3266: int freeSpace = (int) Math.min (0x7fffffffL, hfuTargetFreeSpace);
3267: int clusterBit = Math.max (0, 7 - Integer.numberOfLeadingZeros (totalSpace));
3268: MC68060.mmuWriteWordData (hfsRequest14Namests, freeSpace >>> clusterBit + 10, XEiJ.regSRS);
3269: MC68060.mmuWriteWordData (hfsRequest14Namests + 2, totalSpace >>> clusterBit + 10, XEiJ.regSRS);
3270: MC68060.mmuWriteWordData (hfsRequest14Namests + 4, 1 << clusterBit, XEiJ.regSRS);
3271: MC68060.mmuWriteWordData (hfsRequest14Namests + 6, 1 << 10, XEiJ.regSRS);
3272: hfsRequest18Result = freeSpace;
3273: hfsState = HFS_STATE_DONE;
3274:
3275: }
3276:
3277:
3278:
3279:
3280:
3281:
3282:
3283:
3284:
3285:
3286:
3287:
3288:
3289:
3290:
3291:
3292:
3293:
3294:
3295:
3296:
3297:
3298:
3299:
3300: public void hfuCallDrvctrl () throws M68kException {
3301: if (HFS_COMMAND_TRACE && hfsCommandTraceOn) {
3302: int pc = MainMemory.mmrGetLevelZeroPC ();
3303: System.out.println (LabeledAddress.lblSearch (new StringBuilder (), pc).toString ());
3304: System.out.printf ("%08x drvctrl(mode=0x%02x,param=0x%08x)\n",
3305: pc, hfsRequest13Mode, hfsRequest14Namests);
3306: }
3307: switch (hfsRequest13Mode) {
3308: case 1:
3309: if (hfuFcbToHandle.isEmpty ()) {
3310: eject ();
3311: }
3312: break;
3313: case 2:
3314: prevent ();
3315: break;
3316: case 3:
3317: if (hfuFcbToHandle.isEmpty ()) {
3318: allow ();
3319: }
3320: break;
3321: }
3322: MC68060.mmuWriteByteData (hfsRequestHeader + 13,
3323: (abuInserted ? ABU_INSERTED : 0) |
3324: (abuWriteProtected ? ABU_WRITE_PROTECTED : 0) |
3325: (abuBuffered ? ABU_BUFFERED : 0) |
3326: (abuEjectPrevented ? ABU_EJECT_PREVENTED : 0), XEiJ.regSRS);
3327: hfsRequest18Result = 0;
3328: hfsState = HFS_STATE_DONE;
3329: }
3330:
3331:
3332:
3333:
3334:
3335:
3336:
3337:
3338:
3339:
3340:
3341:
3342:
3343:
3344:
3345:
3346:
3347:
3348:
3349:
3350:
3351:
3352:
3353:
3354:
3355:
3356:
3357:
3358:
3359:
3360:
3361:
3362:
3363:
3364:
3365:
3366:
3367:
3368:
3369: public void hfuCallGetdpb () throws M68kException {
3370: if (HFS_REPORT_INCOMPATIBLE_COMMAND ||
3371: (HFS_COMMAND_TRACE && hfsCommandTraceOn)) {
3372: int pc = MainMemory.mmrGetLevelZeroPC ();
3373: System.out.println (LabeledAddress.lblSearch (new StringBuilder (), pc).toString ());
3374: System.out.printf ("%08x getdpb(buffer=0x%08x)\n",
3375: pc, hfsRequest14Namests);
3376: }
3377: MC68060.mmuWriteLongData (hfsRequest14Namests , 0, XEiJ.regSRS);
3378: MC68060.mmuWriteLongData (hfsRequest14Namests + 4, 0, XEiJ.regSRS);
3379: MC68060.mmuWriteLongData (hfsRequest14Namests + 8, 0, XEiJ.regSRS);
3380: MC68060.mmuWriteLongData (hfsRequest14Namests + 12, 0, XEiJ.regSRS);
3381: hfsRequest18Result = 0;
3382: hfsState = HFS_STATE_DONE;
3383: }
3384:
3385:
3386:
3387:
3388:
3389:
3390:
3391:
3392:
3393:
3394:
3395:
3396:
3397:
3398:
3399: public void hfuCallDiskred () throws M68kException {
3400: if (HFS_REPORT_INCOMPATIBLE_COMMAND ||
3401: (HFS_COMMAND_TRACE && hfsCommandTraceOn)) {
3402: int pc = MainMemory.mmrGetLevelZeroPC ();
3403: System.out.println (LabeledAddress.lblSearch (new StringBuilder (), pc).toString ());
3404: System.out.printf ("%08x diskred(buffer=0x%08x,start=0x%08x,count=0x%08x,mediabyte=0x%02x)\n",
3405: pc, hfsRequest14Namests, hfsRequest22Fcb, hfsRequest18Param, hfsRequest13Mode);
3406: }
3407: int l = hfsRequest18Param << 10;
3408: for (int i = 0; i < l; i += 4) {
3409: MC68060.mmuWriteLongData (hfsRequest14Namests + i, 0, XEiJ.regSRS);
3410: }
3411: hfsRequest18Result = 0;
3412: hfsState = HFS_STATE_DONE;
3413: }
3414:
3415:
3416:
3417:
3418:
3419:
3420:
3421:
3422:
3423:
3424:
3425:
3426:
3427:
3428:
3429: public void hfuCallDiskwrt () throws M68kException {
3430: if (HFS_REPORT_INCOMPATIBLE_COMMAND ||
3431: (HFS_COMMAND_TRACE && hfsCommandTraceOn)) {
3432: int pc = MainMemory.mmrGetLevelZeroPC ();
3433: System.out.println (LabeledAddress.lblSearch (new StringBuilder (), pc).toString ());
3434: System.out.printf ("%08x diskwrt(buffer=0x%08x,start=0x%08x,count=0x%08x,mediabyte=0x%02x)\n",
3435: pc, hfsRequest14Namests, hfsRequest22Fcb, hfsRequest18Param, hfsRequest13Mode);
3436: }
3437: hfsRequest18Result = 0;
3438: hfsState = HFS_STATE_DONE;
3439: }
3440:
3441:
3442:
3443:
3444:
3445:
3446:
3447:
3448:
3449:
3450:
3451:
3452:
3453:
3454:
3455:
3456:
3457: public void hfuCallSpecialCtrl () throws M68kException {
3458: if (HFS_REPORT_INCOMPATIBLE_COMMAND ||
3459: (HFS_COMMAND_TRACE && hfsCommandTraceOn)) {
3460: int pc = MainMemory.mmrGetLevelZeroPC ();
3461: System.out.println (LabeledAddress.lblSearch (new StringBuilder (), pc).toString ());
3462: System.out.printf ("%08x ioctrl(command=0x%08x,param=0x%08x)\n",
3463: pc, hfsRequest18Param, hfsRequest14Namests);
3464: }
3465:
3466: hfsRequest18Result = DOS_CANNOT_IOCTRL;
3467: hfsState = HFS_STATE_DONE;
3468: }
3469:
3470:
3471:
3472:
3473:
3474:
3475:
3476:
3477:
3478:
3479:
3480:
3481:
3482:
3483:
3484: public void hfuCallFflush () throws M68kException {
3485: if (HFS_COMMAND_TRACE && hfsCommandTraceOn) {
3486: int pc = MainMemory.mmrGetLevelZeroPC ();
3487: System.out.println (LabeledAddress.lblSearch (new StringBuilder (), pc).toString ());
3488: System.out.printf ("%08x fflush()\n",
3489: pc);
3490: }
3491: hfsRequest18Result = 0;
3492: hfsState = HFS_STATE_HOST;
3493: }
3494:
3495:
3496: public void hfuCallFflushHost () {
3497: for (HFHandle handle : hfuFcbToHandle.values ()) {
3498:
3499: if (handle.hfhDirty) {
3500: if (HFS_BUFFER_TRACE) {
3501: System.out.printf ("delaywrite(fcb=0x%08x,name=\"%s\",start=0x%08x,end=0x%08x)\n", handle.hfhFcb, handle.hfhFile.toString(), handle.hfhStart, handle.hfhEnd);
3502: }
3503: RandomAccessFile raf = handle.hfhRaf;
3504: try {
3505: raf.seek (handle.hfhStart);
3506: } catch (IOException ioe) {
3507: System.out.println ((Multilingual.mlnJapanese ? "シークエラー: " : "Seek error: ") + handle.toString ());
3508: }
3509: try {
3510: raf.write (handle.hfhBuffer, 0, (int) (handle.hfhEnd - handle.hfhStart));
3511: } catch (IOException ioe) {
3512: System.out.println ((Multilingual.mlnJapanese ? "遅延書き込みに失敗しました: " : "Delayed write failed: ") + handle.toString ());
3513: }
3514: handle.hfhDirty = false;
3515: }
3516: handle.hfhStart = 0L;
3517: handle.hfhEnd = 0L;
3518: }
3519: hfsRequest18Result = 0;
3520: hfsState = HFS_STATE_DONE;
3521: }
3522:
3523:
3524:
3525:
3526:
3527:
3528:
3529:
3530:
3531:
3532:
3533:
3534:
3535:
3536:
3537: public void hfuCallMediacheck () throws M68kException {
3538: if (HFS_COMMAND_TRACE && hfsCommandTraceOn) {
3539: int pc = MainMemory.mmrGetLevelZeroPC ();
3540: System.out.println (LabeledAddress.lblSearch (new StringBuilder (), pc).toString ());
3541: System.out.printf ("%08x mediacheck()\n",
3542: pc);
3543: }
3544: hfsRequest18Result = hasBeenEjected () ? -1 : 0;
3545: hfsState = HFS_STATE_DONE;
3546: }
3547:
3548:
3549:
3550:
3551:
3552:
3553:
3554:
3555:
3556:
3557:
3558:
3559:
3560:
3561:
3562: public void hfuCallLock () throws M68kException {
3563: if (HFS_REPORT_INCOMPATIBLE_COMMAND ||
3564: (HFS_COMMAND_TRACE && hfsCommandTraceOn)) {
3565: int pc = MainMemory.mmrGetLevelZeroPC ();
3566: System.out.println (LabeledAddress.lblSearch (new StringBuilder (), pc).toString ());
3567: System.out.printf ("%08x %s(fcb=0x%08x,offset=0x%08x,length=0x%08x)\n",
3568: pc, hfsRequest13Mode == 0 ? "lock" : "unlock", hfsRequest22Fcb, hfsRequest18Param, hfsRequest14Namests);
3569: }
3570: if (true) {
3571: hfsRequest18Result = -1;
3572: } else {
3573: hfsRequest18Result = 0;
3574: }
3575: hfsState = HFS_STATE_DONE;
3576: }
3577:
3578:
3579:
3580:
3581:
3582:
3583:
3584:
3585:
3586:
3587: private void hfuFileInfo (File file, byte[] b) {
3588:
3589: b[0] = (byte) ((file.isFile () ? HumanMedia.HUM_ARCHIVE : 0) |
3590: (file.isDirectory () ? HumanMedia.HUM_DIRECTORY : 0) |
3591: (file.isHidden () ? HumanMedia.HUM_HIDDEN : 0) |
3592: (!file.canWrite () ? HumanMedia.HUM_READONLY : 0));
3593:
3594: long dttm = DnT.dntDttmCmil (file.lastModified () + RP5C15.rtcCmilGap);
3595:
3596: int time = DnT.dntHourDttm (dttm) << 11 | DnT.dntMinuDttm (dttm) << 5 | DnT.dntSecoDttm (dttm) >> 1;
3597: b[1] = (byte) (time >> 8);
3598: b[2] = (byte) time;
3599:
3600: int date = DnT.dntYearDttm (dttm) - 1980 << 9 | DnT.dntMontDttm (dttm) << 5 | DnT.dntMdayDttm (dttm);
3601: b[3] = (byte) (date >> 8);
3602: b[4] = (byte) date;
3603:
3604: int size = (int) Math.min (0xffffffffL, file.length ());
3605: b[5] = (byte) (size >> 24);
3606: b[6] = (byte) (size >> 16);
3607: b[7] = (byte) (size >> 8);
3608: b[8] = (byte) size;
3609: }
3610:
3611:
3612:
3613:
3614:
3615:
3616:
3617:
3618: public void hfuPrintFileInfo (byte[] b) {
3619: StringBuilder sb = new StringBuilder ();
3620:
3621: int attr = b[0] & 255;
3622: sb.append ((attr & HumanMedia.HUM_EXECUTABLE) != 0 ? 'e' : '-');
3623: sb.append ((attr & HumanMedia.HUM_LINK ) != 0 ? 'l' : '-');
3624: sb.append ((attr & HumanMedia.HUM_ARCHIVE ) != 0 ? 'a' : '-');
3625: sb.append ((attr & HumanMedia.HUM_DIRECTORY ) != 0 ? 'd' : '-');
3626: sb.append ((attr & HumanMedia.HUM_VOLUME ) != 0 ? 'v' : '-');
3627: sb.append ((attr & HumanMedia.HUM_SYSTEM ) != 0 ? 's' : '-');
3628: sb.append ((attr & HumanMedia.HUM_HIDDEN ) != 0 ? 'h' : '-');
3629: sb.append ((attr & HumanMedia.HUM_READONLY ) != 0 ? 'r' : '-');
3630: sb.append (" ");
3631:
3632: int date = (char) (b[3] << 8 | b[4] & 255);
3633: XEiJ.fmtSB02u (XEiJ.fmtSB02u (XEiJ.fmtSB04u (sb, (date >>> 9) + 1980).append ('-'), date >>> 5 & 15).append ('-'), date & 31);
3634: sb.append (" ");
3635:
3636: int time = (char) (b[1] << 8 | b[2] & 255);
3637: XEiJ.fmtSB02u (XEiJ.fmtSB02u (XEiJ.fmtSB02u (sb, time >>> 11).append (':'), time >>> 5 & 63).append (':'), time << 1 & 63);
3638: sb.append (" ");
3639:
3640: if ((attr & HumanMedia.HUM_DIRECTORY) != 0) {
3641: sb.append (" <dir>");
3642: } else if ((attr & HumanMedia.HUM_VOLUME) != 0) {
3643: sb.append (" <vol>");
3644: } else {
3645: int size = (b[5] << 8 | b[6] & 255) << 16 | (char) (b[7] << 8 | b[8] & 255);
3646: XEiJ.fmtSBnd (sb, 10, size);
3647: }
3648: sb.append (" ");
3649:
3650: int l = b.length;
3651: for (int i = 9; i < l; i++) {
3652: int s = b[i] & 255;
3653: char c;
3654: if (0x81 <= s && s <= 0x9f || 0xe0 <= s && s <= 0xef) {
3655: int t = i + 1 < l ? b[i + 1] & 255 : 0;
3656: if (0x40 <= t && t != 0x7f && t <= 0xfc) {
3657: c = CharacterCode.chrSJISToChar[s << 8 | t];
3658: if (c == 0) {
3659: c = '※';
3660: }
3661: i++;
3662: } else {
3663: c = '.';
3664: }
3665: } else {
3666: c = CharacterCode.chrSJISToChar[s];
3667: if (c < 0x20 || c == 0x7f) {
3668: c = '.';
3669: }
3670: }
3671: sb.append (c);
3672: }
3673: System.out.println (sb.toString ());
3674: }
3675:
3676:
3677:
3678:
3679:
3680:
3681:
3682:
3683:
3684:
3685:
3686:
3687:
3688:
3689:
3690:
3691:
3692:
3693:
3694:
3695:
3696: private String hfuNamestsToPath (int namests) throws M68kException {
3697: byte[] w = new byte[88];
3698: MC68060.mmuReadByteArray (namests, w, 0, 88, XEiJ.regSRS);
3699: return hfuNamestsToPath (w, true);
3700: }
3701: private String hfuNamestsToPath (int namests, boolean full) throws M68kException {
3702: byte[] w = new byte[88];
3703: MC68060.mmuReadByteArray (namests, w, 0, 88, XEiJ.regSRS);
3704: return hfuNamestsToPath (w, full);
3705: }
3706: private String hfuNamestsToPath (byte[] ns, boolean full) throws M68kException {
3707: if (HFS_COMMAND_TRACE && hfsCommandTraceOn) {
3708: StringBuilder sb = new StringBuilder ();
3709: sb.append ("\"");
3710: for (int i = 0; i < 88; i++) {
3711: if (i == 2 || i == 67 || i == 75 || i == 78) {
3712: sb.append ("\"+\"");
3713: }
3714: int c = ns[i] & 0xff;
3715: if (c == '\b') {
3716: sb.append ("\\b");
3717: } else if (c == '\f') {
3718: sb.append ("\\f");
3719: } else if (c == '\n') {
3720: sb.append ("\\n");
3721: } else if (c == '\r') {
3722: sb.append ("\\r");
3723: } else if (c == '\t') {
3724: sb.append ("\\t");
3725: } else if (c == '\0') {
3726: sb.append ("\\0");
3727: } else if (0x20 <= c && c <= 0x7e) {
3728: sb.append ((char) c);
3729: } else {
3730: sb.append (String.format ("\\x%02x", c));
3731: }
3732: }
3733: sb.append ("\"");
3734: String s = sb.toString ();
3735: int pc = MainMemory.mmrGetLevelZeroPC ();
3736: System.out.printf ("%08x hfuNamestsToPath(ns=%s,full=%b)\n", pc, s, full);
3737: }
3738: byte[] bb = new byte[88];
3739: int k = 0;
3740: for (int i = 2; i < 67; ) {
3741: for (; i < 67 && ns[i] == 0x09; i++) {
3742: }
3743: if (i >= 67 || ns[i] == 0x00) {
3744: break;
3745: }
3746: bb[k++] = 0x2f;
3747: for (; i < 67 && ns[i] != 0x00 && ns[i] != 0x09; i++) {
3748: bb[k++] = ns[i];
3749: }
3750: }
3751: if (full) {
3752: bb[k++] = 0x2f;
3753: for (int i = 67; i < 75; i++) {
3754: bb[k++] = ns[i];
3755: }
3756: for (int i = 78; i < 88; i++) {
3757: bb[k++] = ns[i];
3758: }
3759: for (; k > 0 && bb[k - 1] == 0x00; k--) {
3760: }
3761: for (; k > 0 && bb[k - 1] == 0x20; k--) {
3762: }
3763: bb[k++] = 0x2e;
3764: for (int i = 75; i < 78; i++) {
3765: bb[k++] = ns[i];
3766: }
3767: for (; k > 0 && bb[k - 1] == 0x20; k--) {
3768: }
3769: for (; k > 0 && bb[k - 1] == 0x2e; k--) {
3770: }
3771: }
3772: StringBuilder sb = new StringBuilder (hfuRootPath);
3773: int h = 0x00;
3774: int dot = 0;
3775: for (int i = 0; i < k; i++) {
3776: int l = bb[i] & 255;
3777: if (h != 0x00 && 0x40 <= l && l != 0x7f && l <= 0xfc) {
3778: int c = CharacterCode.chrSJISToChar[h << 8 | l];
3779: if (c != 0x0000) {
3780: sb.append ((char) c);
3781: } else {
3782: XEiJ.fmtHex2 (XEiJ.fmtHex2 (sb.append ('%'), h).append ('%'), l);
3783: }
3784: h = 0x00;
3785: dot |= 2;
3786: } else {
3787: if (h != 0x00) {
3788: XEiJ.fmtHex2 (sb.append ('%'), h);
3789: h = 0x00;
3790: }
3791: if (0x81 <= l && l <= 0x9f || 0xe0 <= l && l <= 0xef) {
3792: h = l;
3793: } else {
3794: int c = CharacterCode.chrSJISToChar[l];
3795: if (0x20 <= c && c != 0x7f) {
3796: sb.append ((char) c);
3797: } else {
3798: XEiJ.fmtHex2 (sb.append ('%'), l);
3799: }
3800: if (c == '/') {
3801: if (dot == 1) {
3802: return null;
3803: }
3804: dot = 0;
3805: } else if (c == '.') {
3806: dot |= 1;
3807: } else {
3808: dot |= 2;
3809: }
3810: }
3811: }
3812: }
3813: if (h != 0x00) {
3814: XEiJ.fmtHex2 (sb.append ('%'), h);
3815: }
3816: if (dot == 1) {
3817: return null;
3818: }
3819: return sb.toString ();
3820: }
3821:
3822: }
3823:
3824:
3825:
3826: }
3827:
3828:
3829: