|
|
1.1 root 1: /*
2: Hatari - gemdos.c
3:
4: This file is distributed under the GNU Public License, version 2 or at
5: your option any later version. Read the file gpl.txt for details.
6:
7: GEMDOS intercept routines.
8: These are used mainly for hard drive redirection of high level file routines.
9:
10: Now case is handled by using glob. See the function
11: GemDOS_CreateHardDriveFileName for that. It also knows about symlinks.
12: A filename is recognized on its eight first characters, do don't try to
13: push this too far, or you'll get weirdness ! (But I can even run programs
14: directly from a mounted cd in lower cases, so I guess it's working well !).
15: */
16:
17: #include <time.h>
18: #include <ctype.h>
19: #include <SDL.h>
20: #include <SDL_endian.h>
21:
22: #include <sys/stat.h>
23: #include <dirent.h>
24: #include <unistd.h>
25:
26: #include "main.h"
27: #include "../m68000.h"
28: #include "hostcall.h"
29: #include "screen.h"
30: #include "audio.h"
31: #include "input.h"
32: #include "keymap.h"
33: #include "shortcut.h"
34:
35: /*
36: GEMDOS error codes, See 'The Atari Compendium' D.3
37: Call_Fread, Fwrite, etc should return these.
38: */
39: #define GEMDOS_EOK 0 // OK
40: #define GEMDOS_ERROR -1 // Generic error
41: #define GEMDOS_EDRVNR -2 // Drive not ready
42: #define GEMDOS_EUNCMD -3 // Unknown command
43: #define GEMDOS_E_CRC -4 // CRC error
44: #define GEMDOS_EBADRQ -5 // Bad request
45: #define GEMDOS_E_SEEK -6 // Seek error
46: #define GEMDOS_EMEDIA -7 // Unknown media
47: #define GEMDOS_ESECNF -8 // Sector not found
48: #define GEMDOS_EPAPER -9 // Out of paper
49: #define GEMDOS_EWRITF -10 // Write fault
50: #define GEMDOS_EREADF -11 // Read fault
51: #define GEMDOS_EWRPRO -12 // Device is write protected
52: #define GEMDOS_E_CHNG -14 // Media change detected
53: #define GEMDOS_EUNDEV -15 // Unknown device
54: #define GEMDOS_EINVFN -32 // Invalid function
55: #define GEMDOS_EFILNF -33 // File not found
56: #define GEMDOS_EPTHNF -34 // Path not found
57: #define GEMDOS_ENHNDL -35 // No more handles
58: #define GEMDOS_EACCDN -36 // Access denied
59: #define GEMDOS_EIHNDL -37 // Invalid handle
60: #define GEMDOS_ENSMEM -39 // Insufficient memory
61: #define GEMDOS_EIMBA -40 // Invalid memory block address
62: #define GEMDOS_EDRIVE -46 // Invalid drive specification
63: #define GEMDOS_ENSAME -48 // Cross device rename
64: #define GEMDOS_ENMFIL -49 // No more files
65: #define GEMDOS_ELOCKED -58 // Record is already locked
66: #define GEMDOS_ENSLOCK -59 // Invalid lock removal request
67: #define GEMDOS_ERANGE -64 // Range error
68: #define GEMDOS_EINTRN -65 // Internal error
69: #define GEMDOS_EPLFMT -66 // Invalid program load format
70: #define GEMDOS_EGSBF -67 // Memory block growth failure
71: #define GEMDOS_ELOOP -80 // Too many symbolic links
72: #define GEMDOS_EMOUNT -200 // Mount point crossed (indicator)
73:
74: void Call_Memset ()
75: {
76: int adr, count;
77: unsigned long Params;
78:
79: Params = GetReg (REG_A7);
80: Params -= SIZE_WORD;
81:
82: count = STMemory_ReadLong (Params+SIZE_WORD);
83: adr = STMemory_ReadLong (Params+SIZE_WORD+SIZE_LONG);
84:
85: if (use_renderer == R_OLD) {
86: memset (STRam+adr, 0, count);
87: } else {
88: memset (STRam+adr, 255, count);
89: }
90: fe2_bgcol = 0;
91: }
92:
93: void Call_MemsetBlue ()
94: {
95: int adr, count;
96: unsigned long Params;
97:
98: Params = GetReg (REG_A7);
99: Params -= SIZE_WORD;
100:
101: count = STMemory_ReadLong (Params+SIZE_WORD);
102: adr = STMemory_ReadLong (Params+SIZE_WORD+SIZE_LONG);
103: if (use_renderer == R_OLD) {
104: memset (STRam+adr, 0xe, count);
105: } else {
106: memset (STRam+adr, 255, count);
107: }
108: fe2_bgcol = 0xe;
109: }
110:
111: void Call_Memcpy ()
112: {
113: int dest, src, count;
114: unsigned long Params;
115:
116: Params = GetReg (REG_A7);
117: Params -= SIZE_WORD;
118:
119:
120: dest = STMemory_ReadLong (Params + SIZE_WORD);
121: src = STMemory_ReadLong (Params + SIZE_WORD + SIZE_LONG);
122: count = STMemory_ReadLong (Params + SIZE_WORD + 2*SIZE_LONG);
123:
124: memcpy (STRam+dest, STRam+src, count);
125: }
126:
127: static const char mouse_bmp[256] = {
128: 0, 0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
129: 0,15, 0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
130: 0,15,15, 0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
131: 0,15,15,15, 0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
132: 0,15,15,15,15, 0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
133: 0,15,15,15,15,15, 0,-1,-1,-1,-1,-1,-1,-1,-1,-1,
134: 0,15,15,15,15, 0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
135: 0,15,15,15,15, 0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
136: 0,15, 0,15,15,15, 0,-1,-1,-1,-1,-1,-1,-1,-1,-1,
137: 0, 0,-1, 0,15,15, 0,-1,-1,-1,-1,-1,-1,-1,-1,-1,
138: -1,-1,-1, 0,15,15,15, 0,-1,-1,-1,-1,-1,-1,-1,-1,
139: -1,-1,-1,-1, 0,15,15, 0,-1,-1,-1,-1,-1,-1,-1,-1,
140: -1,-1,-1,-1, 0,15,15,15, 0,-1,-1,-1,-1,-1,-1,-1,
141: -1,-1,-1,-1,-1, 0,15, 0,-1,-1,-1,-1,-1,-1,-1,-1,
142: -1,-1,-1,-1,-1,-1, 0,-1,-1,-1,-1,-1,-1,-1,-1,-1,
143: -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
144: };
145:
146: Uint8 under_mouse[256];
147:
148: void Call_BlitCursor ()
149: {
150: #if 0
151: int x, y, adr, org_x, org_y;
152: Uint8 *pixbase, *pix;
153: const char *bmp;
154: Uint8 *save;
155: unsigned long Params;
156:
157: Params = GetReg (REG_A7);
158: Params -= SIZE_WORD;
159:
160: org_x = STMemory_ReadLong (Params+SIZE_WORD);
161: org_y = STMemory_ReadLong (Params+SIZE_WORD+SIZE_LONG);
162: adr = STMemory_ReadLong (Params+SIZE_WORD+2*SIZE_LONG);
163:
164: pixbase = STRam + adr + (org_y*SCREENBYTES_LINE) + org_x;
165: bmp = mouse_bmp;
166: save = under_mouse;
167:
168: for (y=0; y<16; y++) {
169: if (y + org_y > SCREEN_HEIGHT_HBL) break;
170: pix = pixbase;
171: pixbase += SCREENBYTES_LINE;
172: for (x=0; x<16; x++, pix++, bmp++, save++) {
173: if (x+org_x >= SCREENBYTES_LINE) continue;
174: *save = *pix;
175: if (*bmp != -1) *pix = *bmp;
176: }
177: }
178: #endif /* 0 */
179: /* in screen.h */
180: mouse_shown = 1;
181: }
182:
183: void Call_RestoreUnderCursor ()
184: {
185: #if 0
186: int x, y, adr, org_x, org_y;
187: Uint8 *pixbase, *pix;
188: char *bmp;
189: unsigned long Params;
190:
191: Params = GetReg (REG_A7);
192: Params -= SIZE_WORD;
193:
194: org_x = STMemory_ReadLong (Params+SIZE_WORD);
195: org_y = STMemory_ReadLong (Params+SIZE_WORD+SIZE_LONG);
196: adr = STMemory_ReadLong (Params+SIZE_WORD+2*SIZE_LONG);
197:
198: pixbase = STRam + adr + (org_y*SCREENBYTES_LINE) + org_x;
199: bmp = under_mouse;
200:
201: for (y=0; y<16; y++) {
202: if (y + org_y > SCREEN_HEIGHT_HBL) break;
203: pix = pixbase;
204: pixbase += SCREENBYTES_LINE;
205: for (x=0; x<16; x++, pix++, bmp++) {
206: if (x+org_x >= SCREENBYTES_LINE) continue;
207: if (*bmp != -1) *pix = *bmp;
208: }
209: }
210: #endif /* 0 */
211: }
212:
213: void Call_PutPix ()
214: {
215: int col, org_x, scr;
216: char *pix;
217: unsigned long Params;
218:
219: Params = GetReg (REG_A7);
220: Params -= SIZE_WORD;
221:
222: col = STMemory_ReadWord (Params+SIZE_WORD)>>2;
223: org_x = (unsigned short) GetReg (REG_D4);
224: scr = GetReg (REG_A3);
225:
226: /* hack to fix screen line. frontier's logic still thinks
227: * there are 160 bytes per line */
228: /* which screen buffer it is based on */
229: if (scr & 0x100000) {
230: scr -= 0x100000;
231: scr *= 2;
232: scr += 0x100000;
233: } else {
234: scr -= 0xf0000;
235: scr *= 2;
236: scr += 0xf0000;
237: }
238: pix = (char *)STRam + scr + org_x;
239: *pix = col;
240: return;
241: }
242:
243: void Call_FillLine ()
244: {
245: int org_x,len,scr,col;
246: char *pix;
247: unsigned long Params;
248:
249: Params = GetReg (REG_A7);
250: Params -= SIZE_WORD;
251:
252:
253: col = STMemory_ReadWord (Params+SIZE_WORD)>>2;
254: org_x = (unsigned short) GetReg (REG_D4);
255: len = (~GetReg (REG_D5)) & 0xffff;
256: scr = GetReg (REG_A3);
257:
258: /* hack to fix screen line. frontier's logic still thinks
259: * there are 160 bytes per line */
260: /* which screen buffer it is based on */
261: if (scr & 0x100000) {
262: scr -= 0x100000;
263: scr *= 2;
264: scr += 0x100000;
265: } else {
266: scr -= 0xf0000;
267: scr *= 2;
268: scr += 0xf0000;
269: }
270: pix = (char *)STRam + scr;
271: org_x = SCREENBYTES_LINE;
272: while (org_x--) {
273: *pix = col;
274: pix++;
275: }
276: }
277:
278: /*
279: * This is used by the scanner code to draw object stalks
280: * which are below the plane of the scanner.
281: * The mask d7 indicates which pixels in the plane to set,
282: * and they are set if their current colour is zero.
283: *
284: * This implementation isn't the way the function is really
285: * supposed to be implemented (colour and draw mask was
286: * combined in d6 but the colour mask is wrong now for
287: * non-planar screen).
288: */
289: void Call_BackHLine ()
290: {
291: int i,scr,col,bitfield;
292: char *pix;
293: unsigned long Params;
294:
295: Params = GetReg (REG_A7);
296: Params -= SIZE_WORD;
297:
298:
299: col = STMemory_ReadWord (Params+SIZE_WORD)>>2;
300: scr = GetReg (REG_A3);
301: bitfield = (unsigned short) GetReg (REG_D7);
302:
303: /* hack to fix screen line. frontier's logic still thinks
304: * there are 160 bytes per line */
305: /* which screen buffer it is based on */
306: if (scr & 0x100000) {
307: scr -= 0x100000;
308: scr *= 2;
309: scr += 0x100000;
310: } else {
311: scr -= 0xf0000;
312: scr *= 2;
313: scr += 0xf0000;
314: }
315: pix = STRam + scr;
316: for (i=15; i>=0; i--) {
317: if ((bitfield & (1<<i)) && (*pix == 0)) *pix = col;
318: pix++;
319: }
320: }
321:
322: void Call_OldHLine ()
323: {
324: int org_x,len,scr,col;
325: char *pix;
326: unsigned long Params;
327:
328: Params = GetReg (REG_A7);
329: Params -= SIZE_WORD;
330:
331:
332: col = STMemory_ReadWord (Params+SIZE_WORD)>>2;
333: //printf ("col=%d, d4=%d, (idx) d5=%d, (scr_line) a3=%p\n", col, Regs[REG_D4]&0xffff, Regs[REG_D5]&0xffff, (void*)Regs[REG_A3]);
334: org_x = (unsigned short) GetReg (REG_D4);
335: len = (unsigned short) GetReg (REG_D5);
336: scr = GetReg (REG_A3);
337:
338: /* hack to fix screen line. frontier's logic still thinks
339: * there are 160 bytes per line */
340: /* which screen buffer it is based on */
341: if (scr & 0x100000) {
342: scr -= 0x100000;
343: scr *= 2;
344: scr += 0x100000;
345: } else {
346: scr -= 0xf0000;
347: scr *= 2;
348: scr += 0xf0000;
349: }
350: len = len/2;
351: /* horizontal line */
352: pix = STRam + scr + org_x;
353: while (len--) {
354: *pix = col;
355: pix++;
356: }
357: }
358:
359: void Call_HLine ()
360: {
361: int org_x,len,scr,col;
362: char *pix;
363:
364: col = (GetReg(REG_D1) & 0xffff)>>2;
365: org_x = GetReg(REG_D4) & 0xffff;
366: len = GetReg(REG_D5) & 0xffff;
367: scr = GetReg(REG_A3);
368:
369: /* horizontal line */
370: pix = STRam + scr + org_x;
371: while (len--) {
372: *pix = col;
373: pix++;
374: }
375: }
376:
377: /*
378: * Blits frontier format 4-plane thingy
379: */
380: void Call_BlitBmp ()
381: {
382: int width, height, org_x, org_y, bmp, scr;
383: char *bmp_pix, *scr_pix, *ybase;
384: int xpoo, i, ypoo, plane_incr;
385:
386: short word0, word1, word2, word3;
387: unsigned long Params;
388:
389: Params = GetReg (REG_A7);
390: Params -= SIZE_WORD;
391:
392:
393:
394: width = STMemory_ReadWord (Params+SIZE_WORD);
395: height = STMemory_ReadWord (Params+SIZE_WORD*2);
396: org_x = STMemory_ReadWord (Params+SIZE_WORD*3);
397: org_y = STMemory_ReadWord (Params+SIZE_WORD*4);
398: bmp = STMemory_ReadLong (Params+SIZE_WORD*5);
399: scr = STMemory_ReadLong (Params+SIZE_WORD*5 + SIZE_LONG);
400:
401: /* width is in words (width/16) */
402: //printf ("Blit %dx%d to %d,%d, bmp 0x%x, scr 0x%x.\n", width, height, org_x, org_y, bmp, scr);
403: bmp_pix = STRam + bmp + 4;
404: ybase = STRam + scr + (org_y*SCREENBYTES_LINE) + org_x;
405:
406: /* These checks were in the original blit routine */
407: if (org_x < 0) return;
408: if (org_y < 0) return;
409: if (height > 200) return;
410: if (width > 320) return;
411:
412: plane_incr = 2*height*width;
413:
414: ypoo = height;
415: while (ypoo--) {
416: scr_pix = (char *)ybase;
417: ybase += SCREENBYTES_LINE;
418: for (xpoo = width; xpoo; xpoo--) {
419: word0 = SDL_SwapBE16 (*((short*)bmp_pix));
420: bmp_pix += plane_incr;
421: word1 = SDL_SwapBE16 (*((short*)bmp_pix));
422: bmp_pix += plane_incr;
423: word2 = SDL_SwapBE16 (*((short*)bmp_pix));
424: bmp_pix += plane_incr;
425: word3 = SDL_SwapBE16 (*((short*)bmp_pix));
426:
427: for (i=0; i<16; i++) {
428: *scr_pix = (word0 >> (15-i))&0x1;
429: *scr_pix |= ((word1 >> (15-i))&0x1)<<1;
430: *scr_pix |= ((word2 >> (15-i))&0x1)<<2;
431: *scr_pix |= ((word3 >> (15-i))&0x1)<<3;
432: scr_pix++;
433: }
434: bmp_pix -= 3*plane_incr;
435: bmp_pix += 2;
436: }
437: }
438: #if 0
439: glDisable (GL_DEPTH_TEST);
440: glMatrixMode (GL_PROJECTION);
441: glPushMatrix ();
442: glLoadIdentity ();
443: glOrtho (0, 320, 0, 200, -1, 1);
444:
445: glMatrixMode (GL_MODELVIEW);
446: glPushMatrix ();
447: glLoadIdentity ();
448:
449: printf ("%d,%d %dx%d\n", org_x, org_y, width*16, height);
450: glTranslated (org_x, 0, 0);
451:
452: glBegin (GL_TRIANGLE_STRIP);
453: glColor3f (0.0f, 0.0f, 1.0f);
454: glVertex2i (0, 0);
455: glVertex2i (width*16, 0);
456: glVertex2i (0, height);
457: glVertex2i (width*16, height);
458: glEnd ();
459:
460: glMatrixMode (GL_PROJECTION);
461: glPopMatrix ();
462: glMatrixMode (GL_MODELVIEW);
463: glPopMatrix ();
464: glEnable (GL_DEPTH_TEST);
465: #endif
466: }
467:
468: #define SCR_W 320
469:
470: void Call_DrawStrShadowed ()
471: {
472: unsigned char *str;
473:
474: str = GetReg (REG_A0) + STRam;
475:
476: SetReg (REG_D1, DrawStr (
477: GetReg (REG_D1), GetReg (REG_D2),
478: GetReg (REG_D0), str, TRUE));
479: }
480:
481: void Call_DrawStr ()
482: {
483: unsigned char *str;
484:
485: str = GetReg (REG_A0) + STRam;
486:
487: SetReg (REG_D1, DrawStr (
488: GetReg (REG_D1), GetReg (REG_D2),
489: GetReg (REG_D0), str, FALSE));
490: }
491:
492: void Call_SetMainPalette ()
493: {
494: Uint32 pal_ptr;
495: int i;
496: unsigned long Params;
497:
498: Params = GetReg (REG_A7);
499: Params -= SIZE_WORD;
500:
501:
502: pal_ptr = STMemory_ReadLong (Params+SIZE_WORD);
503:
504: for (i=0; i<16; i++) {
505: MainPalette[i] = STMemory_ReadWord (pal_ptr);
506: //printf ("%hx ", MainPalette[i]);
507: pal_ptr+=2;
508: }
509: //printf ("\n");
510: }
511:
512: void Call_SetCtrlPalette ()
513: {
514: Uint32 pal_ptr;
515: int i;
516: unsigned long Params;
517:
518: Params = GetReg (REG_A7);
519: Params -= SIZE_WORD;
520:
521:
522: pal_ptr = STMemory_ReadLong (Params+SIZE_WORD);
523:
524: for (i=0; i<16; i++) {
525: CtrlPalette[i] = STMemory_ReadWord (pal_ptr);
526: pal_ptr+=2;
527: }
528: }
529:
530: int len_working_ext_pal;
531: unsigned short working_ext_pal[240];
532:
533: void Call_InformScreens ()
534: {
535: unsigned long Params;
536:
537: Params = GetReg (REG_A7);
538: Params -= SIZE_WORD;
539:
540: physcreen2 = STMemory_ReadLong (Params+SIZE_WORD);
541: logscreen2 = STMemory_ReadLong (Params+SIZE_WORD+SIZE_LONG);
542: physcreen = STMemory_ReadLong (Params+SIZE_WORD+2*SIZE_LONG);
543: logscreen = STMemory_ReadLong (Params+SIZE_WORD+3*SIZE_LONG);
544: }
545:
546: /* also copies the extended palette into main palette */
547: void Call_SetScreenBase ()
548: {
549: int i;
550: unsigned long Params;
551:
552: Params = GetReg (REG_A7);
553: Params -= SIZE_WORD;
554:
555: VideoBase = STMemory_ReadLong (Params+SIZE_WORD);
556: VideoRaster = STRam + VideoBase;
557:
558: for (i=0; i<len_working_ext_pal; i++) {
559: MainPalette[16+i] = working_ext_pal[i];
560: }
561: len_main_palette = 16 + len_working_ext_pal;
562: }
563:
564: void Call_MakeExtPalette ()
565: {
566: int col_list, len, col_idx, col_val, i;
567: unsigned long Params;
568:
569: Params = GetReg (REG_A7);
570: Params -= SIZE_WORD;
571:
572:
573: col_list = STMemory_ReadLong (Params+SIZE_WORD);
574:
575: len = STMemory_ReadWord (col_list) >> 2;
576: len_working_ext_pal = len;
577: col_list+=2;
578: //printf ("%d colours.\n", len+2);
579: for (i=0; i<len; i++) {
580: col_val = STMemory_ReadWord (col_list);
581: working_ext_pal[i] = col_val;
582: col_list += 2;
583: col_idx = STMemory_ReadWord (col_list);
584: /* offset dynamic colours into extended palette
585: * range (colours 16+) */
586: col_idx += 16<<2;
587: STMemory_WriteWord (col_list, col_idx);
588: col_list += 2;
589: }
590: }
591: void Call_DumpRegs ()
592: {
593: int i;
594: printf ("D: ");
595: for (i=0; i<8; i++) {
596: printf ("$%x ", GetReg (i));
597: } printf ("\n");
598: printf ("A: ");
599: for (i=0; i<8; i++) {
600: printf ("$%x ", GetReg (i+8));
601: } printf ("\n");
602: }
603:
604:
605: void Call_DumpDebug ()
606: {
607: int i, j;
608: printf ("Debug info. PC @ 68k line %d.\n", line_no);
609:
610: Call_DumpRegs ();
611:
612: printf ("Stack:");
613: j = GetReg (15);
614: for (i=0; i<8; i++) {
615: j+=4;
616: printf (" $%x", STMemory_ReadLong (j));
617: }
618: putchar ('\n');
619: }
620:
621:
622: /* mouse pos in d3,d4 */
623: void Call_NotifyMousePos ()
624: {
625: #if 0
626: int x, y;
627:
628: x = GetReg (REG_D3) & 0xffff;
629: y = GetReg (REG_D4) & 0xffff;
630:
631: x *= ScreenDraw.MouseScale;
632: y *= ScreenDraw.MouseScale;
633:
634: SDL_EventState (SDL_MOUSEMOTION, SDL_DISABLE);
635: SDL_WarpMouse (x, y);
636: SDL_EventState (SDL_MOUSEMOTION, SDL_ENABLE);
637: SDL_ShowCursor (SDL_ENABLE);
638: #endif /* 0 */
639: }
640:
641: static void Call_Idle ()
642: {
643: SDL_Delay (0);
644: }
645:
646: void Call_HostUpdate ()
647: {
648: /* Clear any key presses which are due to be de-bounced (held for one ST frame) */
649: Keymap_DebounceAllKeys();
650: /* Check 'Function' keys, so if press F12 we update screen correctly to Window! */
651: ShortCut_CheckKeys();
652: /* And handle any messages, check for quit message */
653: Main_EventHandler(); /* Process messages, set 'bQuitProgram' if user tries to quit */
654: /* Pass NULL interrupt function to quit cleanly */
655: //if (bQuitProgram) Int_AddAbsoluteInterrupt(4, 0L);
656: }
657:
658: /* d0.b = exception number, a0 = handler. */
659: static void SetExceptionHandler ()
660: {
661: /* only 32 handlers */
662: exception_handlers[GetReg(0) & 31] = GetReg (8);
663: }
664:
665: int DumpMess (int pos, int line)
666: {
667: if (GetXFlag ()) putchar ('X');
668: if (GetZFlag ()) putchar ('Z');
669: if (GetNFlag ()) putchar ('N');
670: if (GetVFlag ()) putchar ('V');
671: if (GetCFlag ()) putchar ('C');
672: return 0;
673: printf (" $%x $%x $%x $%x $%x $%x $%x $%x*$%x $%x $%x $%x $%x $%x $%x $%x:%d\n",
674: GetReg (0),
675: GetReg (1),
676: GetReg (2),
677: GetReg (3),
678: GetReg (4),
679: GetReg (5),
680: GetReg (6),
681: GetReg (7),
682: GetReg (8),
683: GetReg (9),
684: GetReg (10),
685: GetReg (11),
686: GetReg (12),
687: GetReg (13),
688: GetReg (14),
689: GetReg (15),line_no);
690: }
691: static int _X, _Z, _N, _V, _C;
692: static int PrevRegs[16];
693:
694: int changed ()
695: {
696: int i;
697: if (GetXFlag () != _X) return 1;
698: if (GetZFlag () != _Z) return 1;
699: if (GetNFlag () != _N) return 1;
700: if (GetVFlag () != _V) return 1;
701: if (GetCFlag () != _C) return 1;
702: for (i=0; i<16; i++) {
703: if (PrevRegs[i] != GetReg (i)) return 1;
704: }
705: return 0;
706: }
707:
708: void DumpRegsChanged ()
709: {
710: int i;
711:
712: //if (!changed ()) return;
713:
714: _X = GetXFlag ();
715: _Z = GetZFlag ();
716: _V = GetVFlag ();
717: _N = GetNFlag ();
718: _C = GetCFlag ();
719:
720: if (_X) putchar ('X');
721: if (_Z) putchar ('Z');
722: if (_N) putchar ('N');
723: if (_V) putchar ('V');
724: if (_C) putchar ('C');
725:
726: for (i=0; i<16; i++) {
727: if (PrevRegs[i] != GetReg (i)) {
728: printf (" %c%d:%x->%x", (i<8?'d':'a'), (i<8?i:i-8), PrevRegs[i], GetReg (i));
729: PrevRegs[i] = GetReg (i);
730: }
731: }
732: printf (" @%d\n", line_no);
733: }
734:
735: static void Call_Fdelete ()
736: {
737: int p, i;
738: char filename[64];
739:
740: p = GetReg (REG_D1);
741: for (i=0; ; i++) {
742: filename[i] = STMemory_ReadByte (p++);
743: if (!filename[i]) break;
744: }
745:
746: SetReg (REG_D0, remove (filename));
747: }
748:
749: static void Call_Fwrite ()
750: {
751: int p, i;
752: int pBuf = GetReg (REG_A4);
753: int len = GetReg (REG_D7);
754: char filename[64];
755: FILE *f;
756:
757: p = GetReg (REG_D1);
758: for (i=0; ; i++) {
759: filename[i] = STMemory_ReadByte (p++);
760: if (!filename[i]) break;
761: }
762:
763: if (!(f = fopen (filename, "wb"))) {
764: SetReg (REG_D0, 0);
765: } else {
766: SetReg (REG_D0, fwrite (STRam+pBuf, 1, len, f));
767: fclose (f);
768: }
769: }
770:
771: static void Call_Fread ()
772: {
773: int p, i;
774: int pBuf = GetReg (REG_A4);
775: int len = GetReg (REG_D7);
776: char filename[64];
777: FILE *f;
778:
779: p = GetReg (REG_D1);
780: for (i=0; ; i++) {
781: filename[i] = STMemory_ReadByte (p++);
782: if (!filename[i]) break;
783: }
784:
785: if (!(f = fopen (filename, "rb"))) {
786: SetReg (REG_D0, 0);
787: } else {
788: SetReg (REG_D0, fread (STRam+pBuf, 1, len, f));
789: fclose (f);
790: }
791: }
792:
793: #include <dirent.h>
794: static DIR *poodir;
795:
796: static char cur_dir[1024];
797:
798: static void Call_Fopendir ()
799: {
800: int p, i;
801: char name[64];
802:
803: p = GetReg (REG_A2);
804: for (i=0; ; i++) {
805: name[i] = STMemory_ReadByte (p++);
806: if (!name[i]) break;
807: }
808:
809: strncpy (cur_dir, name, 1024);
810:
811: poodir = opendir (name);
812: if (poodir) {
813: struct dirent *dent;
814: /* skip '.' and '..' */
815: dent = readdir (poodir);
816: dent = readdir (poodir);
817: SetReg (REG_D0, 0);
818: } else {
819: SetReg (REG_D0, -1);
820: }
821: }
822:
823: static void Call_Fclosedir ()
824: {
825: closedir (poodir);
826: }
827:
828: /* make sure fe2.s is allocating enough space at a0... */
829: #define MAX_FILENAME_LEN 14
830:
831: static void Call_Freaddir ()
832: {
833: int p, i, attribs, len;
834: char name[MAX_FILENAME_LEN];
835: /* filename into buffer (a0), attributes d2, len d1 */
836: char full_path_shit[1024];
837: struct stat _stat;
838: struct dirent *dent = readdir (poodir);
839: if (dent == NULL) {
840: SetReg (REG_D0, -1);
841: return;
842: }
843: strncpy (name, dent->d_name, MAX_FILENAME_LEN);
844: name[MAX_FILENAME_LEN-1] = '\0';
845:
846: strncpy (full_path_shit, cur_dir, 1024);
847: strncat (full_path_shit, "/", 1024);
848: strncat (full_path_shit, dent->d_name, 1024);
849: stat (full_path_shit, &_stat);
850:
851: len = _stat.st_size;
852: attribs = (S_ISDIR (_stat.st_mode) ? 0x10 : 0);
853:
854: p = GetReg (REG_A0);
855: for (i=0; i<MAX_FILENAME_LEN; i++) {
856: STMemory_WriteByte (p++, name[i]);
857: }
858: SetReg (REG_D2, attribs);
859: SetReg (REG_D1, len);
860: SetReg (REG_D0, 0);
861: }
862:
863: HOSTCALL hcalls [] = {
864: &SetExceptionHandler,
865: &Call_Memset, /* 0x1 */
866: &Call_MemsetBlue, /* 0x2 */
867: &Call_BlitCursor, /* 0x3 */
868: &Call_RestoreUnderCursor, /* 0x4 */
869: &Call_BlitBmp, /* 0x5 */
870: &Call_OldHLine, /* 0x6 */
871: &Call_HostUpdate, /* 0x7 */
872: &Call_Memcpy, /* 0x8 */
873: &Call_PutPix, /* 0x9 */
874: &Call_BackHLine, /* 0xa */
875: &Call_FillLine, /* 0xb */
876: &Call_SetMainPalette, /* 0xc */
877: &Call_SetCtrlPalette, /* 0xd */
878: &Call_SetScreenBase, /* 0xe */
879: NULL, /* 0xf */
880: &Call_DumpRegs, /* 0x10 */
881: &Call_MakeExtPalette, /* 0x11 */
882: &Call_PlaySFX, /* 0x12 */
883: &Call_GetMouseInput, /* 0x13 */
884: &Call_GetKeyboardEvent, /* 0x14 */
885: NULL, /* 0x15 */
886: &Call_HLine, /* 0x16 */
887: NULL, /* 0x17 */
888: &Call_NotifyMousePos, /* 0x18 */
889: &Call_InformScreens, /* 0x19 */
890: NULL,
891: &Call_DrawStrShadowed, /* 0x1b */
892: &Call_DrawStr, /* 0x1c */
893: &Call_PlayMusic, /* 0x1d */
894: &Call_StopMusic, /* 0x1e */
895: &Call_Idle, /* 0x1f */
896: &Call_DumpDebug, /* 0x20 */
897: &Call_IsMusicPlaying,
898: &Call_Fread, /* 0x22 */
899: &Call_Fwrite,
900: &Call_Fdelete,
901: &Call_Fopendir, /* 0x25 */
902: &Call_Freaddir,
903: &Call_Fclosedir,
904: NULL,
905: NULL,
906: NULL,
907: NULL,
908: NULL,
909: NULL,
910: NULL,
911: NULL,
912: NULL, /* 0x30 */
913: NULL,
914: NULL,
915: NULL,
916: NULL,
917: NULL,
918: NULL,
919: NULL,
920: NULL,
921: NULL,
922: NULL,
923: NULL,
924: NULL,
925: NULL,
926: NULL,
927: NULL,
928: NULL, /* 0x40 */
929: NULL,
930: NULL,
931: NULL,
932: NULL,
933: NULL,
934: NULL,
935: NULL,
936: NULL,
937: NULL,
938: NULL,
939: NULL,
940: NULL,
941: NULL,
942: NULL,
943: NULL,
944: NULL, /* 0x50 */
945: NULL,
946: NULL,
947: NULL,
948: NULL,
949: NULL,
950: NULL,
951: NULL,
952: NULL,
953: NULL,
954: NULL,
955: NULL,
956: NULL,
957: NULL,
958: NULL,
959: NULL,
960: Nu_PutTriangle, /* 0x60 */
961: Nu_PutQuad,
962: Nu_PutLine,
963: Nu_PutPoint,
964: Nu_PutTwinklyCircle,
965: Nu_PutColoredPoint,
966: Nu_PutBezierLine,
967: Nu_ComplexStart,
968: Nu_ComplexSNext,
969: Nu_ComplexSBegin,
970: Nu_ComplexEnd,
971: Nu_3DViewInit,
972: Nu_InsertZNode,
973: Nu_ComplexStartInner,
974: Nu_ComplexBezier,
975: Nu_DrawScreen,
976: Nu_PutTeardrop,
977: Nu_PutCircle,
978: Nu_PutOval,
979: Nu_IsGLRenderer,
980: Nu_GLClearArea,
981: Nu_QueueDrawStr,
982: Nu_PutCylinder,
983: Nu_PutBlob,
984: Nu_PutPlanet
985: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.