|
|
1.1 root 1: /*
2: * UAE - The U*nix Amiga Emulator
1.1.1.3 root 3: *
1.1 root 4: * UAE Library v0.1
1.1.1.3 root 5: *
1.1 root 6: * (c) 1996 Tauno Taipaleenmaki <[email protected]>
7: *
1.1.1.3 root 8: * Change UAE parameters and other stuff from inside the emulation.
1.1 root 9: */
10:
11: #include "sysconfig.h"
12: #include "sysdeps.h"
13:
14: #include <assert.h>
15: #include <string.h>
16:
17: #include "config.h"
18: #include "options.h"
1.1.1.3 root 19: #include "threaddep/penguin.h"
20: #include "uae.h"
21: #include "include/memory.h"
1.1 root 22: #include "custom.h"
1.1.1.2 root 23: #include "readcpu.h"
1.1 root 24: #include "newcpu.h"
25: #include "xwin.h"
26: #include "autoconf.h"
27: #include "disk.h"
1.1.1.3 root 28: #include "debug.h"
29: #include "gensound.h"
30: #include "picasso96.h"
1.1 root 31:
32: /*
33: * Returns UAE Version
34: */
1.1.1.4 root 35: static uae_u32 emulib_GetVersion (void)
1.1 root 36: {
1.1.1.3 root 37: return version;
1.1 root 38: }
39:
40: /*
41: * Resets your amiga
42: */
1.1.1.4 root 43: static uae_u32 emulib_HardReset (void)
1.1 root 44: {
1.1.1.3 root 45: uae_reset();
46: return 0;
1.1 root 47: }
48:
1.1.1.4 root 49: static uae_u32 emulib_Reset (void)
1.1 root 50: {
1.1.1.3 root 51: uae_reset();
52: return 0;
1.1 root 53: }
54:
55: /*
56: * Enables SOUND
57: */
1.1.1.3 root 58: static uae_u32 emulib_EnableSound (uae_u32 val)
1.1 root 59: {
1.1.1.3 root 60: if (!sound_available || currprefs.produce_sound == 2)
1.1 root 61: return 0;
62:
1.1.1.3 root 63: currprefs.produce_sound = val;
1.1 root 64: return 1;
65: }
66:
67: /*
68: * Enables FAKE JOYSTICK
69: */
1.1.1.3 root 70: static uae_u32 emulib_EnableJoystick (uae_u32 val)
1.1 root 71: {
1.1.1.5 root 72: currprefs.jport0 = val & 255;
73: currprefs.jport1 = (val >> 8) & 255;
1.1 root 74: return 1;
75: }
76:
77: /*
78: * Sets the framerate
79: */
1.1.1.3 root 80: static uae_u32 emulib_SetFrameRate (uae_u32 val)
1.1 root 81: {
1.1.1.3 root 82: if (val == 0)
1.1 root 83: return 0;
1.1.1.3 root 84: else if (val > 20)
1.1 root 85: return 0;
86: else {
1.1.1.6 ! root 87: currprefs.gfx_framerate = val;
1.1 root 88: return 1;
89: }
90: }
91:
92: /*
93: * Changes keyboard language settings
94: */
1.1.1.3 root 95: static uae_u32 emulib_ChangeLanguage (uae_u32 which)
1.1 root 96: {
1.1.1.3 root 97: if (which > 5)
1.1 root 98: return 0;
99: else {
1.1.1.3 root 100: switch (which) {
1.1 root 101: case 0:
1.1.1.3 root 102: currprefs.keyboard_lang = KBD_LANG_US;
1.1 root 103: break;
104: case 1:
1.1.1.3 root 105: currprefs.keyboard_lang = KBD_LANG_DE;
1.1 root 106: break;
107: case 2:
1.1.1.3 root 108: currprefs.keyboard_lang = KBD_LANG_SE;
1.1 root 109: break;
110: case 3:
1.1.1.3 root 111: currprefs.keyboard_lang = KBD_LANG_FR;
1.1 root 112: break;
113: case 4:
1.1.1.3 root 114: currprefs.keyboard_lang = KBD_LANG_IT;
1.1 root 115: break;
1.1.1.2 root 116: case 5:
1.1.1.3 root 117: currprefs.keyboard_lang = KBD_LANG_ES;
1.1.1.2 root 118: break;
1.1 root 119: default:
120: break;
121: }
122: return 1;
123: }
124: }
125:
1.1.1.3 root 126: /* The following ones don't work as we never realloc the arrays... */
1.1 root 127: /*
1.1.1.3 root 128: * Changes chip memory size
1.1 root 129: * (reboots)
130: */
1.1.1.3 root 131: static uae_u32 emulib_ChgCMemSize (uae_u32 memsize)
1.1 root 132: {
1.1.1.3 root 133: if (memsize != 0x80000 && memsize != 0x100000 &&
1.1 root 134: memsize != 0x200000) {
135: memsize = 0x200000;
1.1.1.4 root 136: fprintf (stderr, "Unsupported chipmem size!\n");
1.1 root 137: }
1.1.1.2 root 138: m68k_dreg(regs, 0) = 0;
1.1.1.3 root 139:
1.1.1.4 root 140: currprefs.chipmem_size = memsize;
1.1.1.3 root 141: uae_reset();
1.1 root 142: return 1;
143: }
144:
145: /*
1.1.1.3 root 146: * Changes slow memory size
1.1 root 147: * (reboots)
148: */
1.1.1.3 root 149: static uae_u32 emulib_ChgSMemSize (uae_u32 memsize)
1.1 root 150: {
1.1.1.3 root 151: if (memsize != 0x80000 && memsize != 0x100000 &&
152: memsize != 0x180000 && memsize != 0x1C0000) {
153: memsize = 0;
1.1.1.4 root 154: fprintf (stderr, "Unsupported bogomem size!\n");
1.1.1.3 root 155: }
1.1 root 156:
1.1.1.3 root 157: m68k_dreg(regs, 0) = 0;
1.1.1.4 root 158: currprefs.bogomem_size = memsize;
159: uae_reset ();
1.1.1.3 root 160: return 1;
1.1 root 161: }
162:
163: /*
1.1.1.3 root 164: * Changes fast memory size
165: * (reboots)
1.1 root 166: */
1.1.1.3 root 167: static uae_u32 emulib_ChgFMemSize (uae_u32 memsize)
1.1 root 168: {
1.1.1.3 root 169: if (memsize != 0x100000 && memsize != 0x200000 &&
170: memsize != 0x400000 && memsize != 0x800000) {
171: memsize = 0;
1.1.1.4 root 172: fprintf (stderr, "Unsupported fastmem size!\n");
1.1.1.3 root 173: }
174: m68k_dreg(regs, 0) = 0;
1.1.1.4 root 175: currprefs.fastmem_size = memsize;
176: uae_reset ();
1.1.1.3 root 177: return 0;
1.1 root 178: }
179:
180: /*
181: * Inserts a disk
182: */
1.1.1.4 root 183: static uae_u32 emulib_InsertDisk (uaecptr name, uae_u32 drive)
1.1 root 184: {
1.1.1.3 root 185: int i = 0;
186: char real_name[256];
187:
1.1 root 188: if (drive > 3)
189: return 0;
190:
1.1.1.3 root 191: while ((real_name[i] = get_byte (name + i)) != 0 && i++ != 254)
192: ;
1.1 root 193:
1.1.1.3 root 194: if (i == 255)
195: return 0; /* ENAMETOOLONG */
1.1 root 196:
1.1.1.3 root 197: strcpy (changed_prefs.df[drive], real_name);
1.1 root 198:
1.1.1.3 root 199: return 1;
1.1 root 200: }
201:
202: /*
203: * Exits the emulator
204: */
1.1.1.4 root 205: static uae_u32 emulib_ExitEmu (void)
1.1 root 206: {
1.1.1.3 root 207: uae_quit ();
208: return 1;
1.1 root 209: }
210:
211: /*
212: * Gets UAE Configuration
213: */
1.1.1.4 root 214: static uae_u32 emulib_GetUaeConfig (uaecptr place)
1.1 root 215: {
1.1.1.3 root 216: int i,j;
1.1 root 217:
1.1.1.4 root 218: put_long (place, version);
219: put_long (place + 4, allocated_chipmem);
220: put_long (place + 8, allocated_bogomem);
221: put_long (place + 12, allocated_fastmem);
1.1.1.6 ! root 222: put_long (place + 16, currprefs.gfx_framerate);
1.1.1.4 root 223: put_long (place + 20, currprefs.produce_sound);
1.1.1.5 root 224: put_long (place + 24, currprefs.jport0 | (currprefs.jport1 << 8));
1.1.1.4 root 225: put_long (place + 28, currprefs.keyboard_lang);
226: if (disk_empty (0))
227: put_byte (place + 32, 0);
1.1.1.3 root 228: else
1.1.1.4 root 229: put_byte (place + 32, 1);
230: if (disk_empty (1))
231: put_byte (place + 33, 0);
1.1.1.3 root 232: else
1.1.1.4 root 233: put_byte (place + 33, 1);
1.1.1.3 root 234: if (disk_empty(2))
1.1.1.4 root 235: put_byte (place + 34, 0);
1.1.1.3 root 236: else
1.1.1.4 root 237: put_byte (place + 34, 1);
1.1.1.3 root 238: if (disk_empty(3))
1.1.1.4 root 239: put_byte (place + 35, 0);
1.1.1.3 root 240: else
1.1.1.4 root 241: put_byte (place + 35, 1);
1.1.1.3 root 242:
243: for (i = 0; i < 256; i++) {
1.1.1.4 root 244: put_byte ((place + 36 + i), currprefs.df[0][i]);
245: put_byte ((place + 36 + i + 256), currprefs.df[1][i]);
246: put_byte ((place + 36 + i + 512), currprefs.df[2][i]);
247: put_byte ((place + 36 + i + 768), currprefs.df[3][i]);
1.1.1.3 root 248: }
249: return 1;
1.1 root 250: }
251:
252: /*
253: * Sets UAE Configuration
1.1.1.3 root 254: *
1.1 root 255: * NOT IMPLEMENTED YET
256: */
1.1.1.4 root 257: static uae_u32 emulib_SetUaeConfig (uaecptr place)
1.1 root 258: {
1.1.1.3 root 259: return 1;
1.1 root 260: }
261:
262: /*
263: * Gets the name of the disk in the given drive
264: */
1.1.1.4 root 265: static uae_u32 emulib_GetDisk (uae_u32 drive, uaecptr name)
1.1 root 266: {
267: int i;
1.1.1.3 root 268: if (drive > 3)
1.1 root 269: return 0;
270:
1.1.1.3 root 271: for (i = 0;i < 256; i++) {
272: put_byte (name + i, currprefs.df[drive][i]);
1.1 root 273: }
274: return 1;
275: }
276:
277: /*
278: * Enter debugging state
279: */
1.1.1.4 root 280: static uae_u32 emulib_Debug (void)
1.1 root 281: {
1.1.1.3 root 282: activate_debugger ();
1.1 root 283: return 1;
284: }
285:
1.1.1.3 root 286: /* We simply find the first "text" hunk, get the offset of its actual code segment (20 bytes away)
287: * and add that offset to the base address of the object. Now we've got code to execute.
288: *
289: * @@@ Brian: does anything actually use this yet?
1.1.1.5 root 290: * @@@ Bernd: Not yet. It needs to get much better. Should spawn off a seperate task to handle the
291: * function, and then somehow "signal" the Amiga caller that completion or error has
292: * occurred. I don't know how to do that, so right now it is a synchronous call. Yuck!
293: * Would be nice to implement jpg decompression functionality for the Amiga which used
294: * the UAE Host to do all the work, for example.
295: * @@@ Brian: I disabled it to prevent people from starting to use it - if that happens, we're
296: * stuck with this.
1.1.1.3 root 297: */
298: static uae_u32 FindFunctionInObject (uae_u8 *objectptr)
1.1 root 299: {
1.1.1.3 root 300: uae_u8 *text_hdr;
301: uae_u8 offset;
302: text_hdr = (uae_u8 *)strstr ("text", (char *)objectptr);
303: if (text_hdr != 0) {
304: offset = *(text_hdr + 19);
305: return (uae_u32)(objectptr + offset);
306: }
307: return 0;
1.1 root 308: }
309:
1.1.1.3 root 310: #define CREATE_NATIVE_FUNC_PTR uae_u32 (* native_func)( uae_u32, uae_u32, uae_u32, uae_u32, uae_u32, uae_u32, uae_u32, \
311: uae_u32, uae_u32, uae_u32, uae_u32, uae_u32, uae_u32)
312: #define SET_NATIVE_FUNC(x) native_func = (uae_u32 (*)(uae_u32, uae_u32, uae_u32, uae_u32, uae_u32, uae_u32, uae_u32, uae_u32, uae_u32, uae_u32, uae_u32, uae_u32, uae_u32))(x)
313: #define CALL_NATIVE_FUNC( d1,d2,d3,d4,d5,d6,d7,a1,a2,a3,a4,a5,a6 ) if(native_func) native_func( d1,d2,d3,d4,d5,d6,d7,a1,a2,a3,a4,a5,a6 )
314: /* A0 - Contains a ptr to the native .obj data. This ptr is Amiga-based. */
315: /* We simply find the first function in this .obj data, and execute it. */
1.1.1.4 root 316: static uae_u32 emulib_ExecuteNativeCode (void)
1.1.1.3 root 317: {
1.1.1.5 root 318: #if 0
1.1.1.3 root 319: uaecptr object_AAM = m68k_areg( regs, 0 );
320: uae_u32 d1 = m68k_dreg( regs, 1 );
321: uae_u32 d2 = m68k_dreg( regs, 2 );
322: uae_u32 d3 = m68k_dreg( regs, 3 );
323: uae_u32 d4 = m68k_dreg( regs, 4 );
324: uae_u32 d5 = m68k_dreg( regs, 5 );
325: uae_u32 d6 = m68k_dreg( regs, 6 );
326: uae_u32 d7 = m68k_dreg( regs, 7 );
327: uae_u32 a1 = m68k_areg( regs, 1 );
328: uae_u32 a2 = m68k_areg( regs, 2 );
329: uae_u32 a3 = m68k_areg( regs, 3 );
330: uae_u32 a4 = m68k_areg( regs, 4 );
331: uae_u32 a5 = m68k_areg( regs, 5 );
332: uae_u32 a6 = m68k_areg( regs, 6 );
333:
334: uae_u8* object_UAM = NULL;
335: CREATE_NATIVE_FUNC_PTR;
336:
337: if( get_mem_bank( object_AAM ).check( object_AAM, 1 ) )
338: object_UAM = get_mem_bank( object_AAM).xlateaddr( object_AAM );
339:
340: if( object_UAM )
341: {
342: SET_NATIVE_FUNC( FindFunctionInObject( object_UAM ) );
343: CALL_NATIVE_FUNC( d1, d2, d3, d4, d5, d6, d7, a1, a2, a3, a4, a5, a6);
344: }
345: return 1;
1.1.1.5 root 346: #endif
347: return 0;
1.1.1.3 root 348: }
349:
350: static uae_u32 uaelib_demux (void)
1.1 root 351: {
1.1.1.3 root 352: #define ARG0 (get_long (m68k_areg (regs, 7) + 4))
353: #define ARG1 (get_long (m68k_areg (regs, 7) + 8))
354: #define ARG2 (get_long (m68k_areg (regs, 7) + 12))
355: #define ARG3 (get_long (m68k_areg (regs, 7) + 16))
356:
357: switch (ARG0) {
358: case 0: return emulib_GetVersion ();
359: case 1: return emulib_GetUaeConfig (ARG1);
360: case 2: return emulib_SetUaeConfig (ARG1);
361: case 3: return emulib_HardReset ();
362: case 4: return emulib_Reset ();
363: case 5: return emulib_InsertDisk (ARG1, ARG2);
364: case 6: return emulib_EnableSound (ARG1);
365: case 7: return emulib_EnableJoystick (ARG1);
366: case 8: return emulib_SetFrameRate (ARG1);
367: case 9: return emulib_ChgCMemSize (ARG1);
368: case 10: return emulib_ChgSMemSize (ARG1);
369: case 11: return emulib_ChgFMemSize (ARG1);
370: case 12: return emulib_ChangeLanguage (ARG1);
371: /* The next call brings bad luck */
372: case 13: return emulib_ExitEmu ();
373: case 14: return emulib_GetDisk (ARG1, ARG2);
374: case 15: return emulib_Debug ();
375:
376: #ifdef PICASSO96
1.1.1.4 root 377: case 16: return picasso_FindCard ();
378: case 17: return picasso_FillRect ();
379: case 18: return picasso_SetSwitch ();
380: case 19: return picasso_SetColorArray ();
381: case 20: return picasso_SetDAC ();
382: case 21: return picasso_SetGC ();
383: case 22: return picasso_SetPanning ();
384: case 23: return picasso_CalculateBytesPerRow ();
385: case 24: return picasso_BlitPlanar2Chunky ();
386: case 25: return picasso_BlitRect ();
387: case 26: return picasso_SetDisplay ();
388: case 27: return picasso_BlitTemplate ();
389: case 28: return picasso_BlitRectNoMaskComplete ();
390: case 29: return picasso_InitCard ();
391: case 30: return picasso_BlitPattern ();
392: case 31: return picasso_InvertRect ();
393: case 32: return picasso_BlitPlanar2Direct ();
394: case 34: return picasso_WaitVerticalSync ();
395: case 35: return allocated_gfxmem ? 1 : 0;
1.1.1.3 root 396: #endif
1.1 root 397:
1.1.1.4 root 398: case 69: return emulib_ExecuteNativeCode ();
1.1 root 399: }
400: return 0;
401: }
402:
403: /*
404: * Installs the UAE LIBRARY
405: */
1.1.1.4 root 406: void emulib_install (void)
1.1 root 407: {
1.1.1.3 root 408: uaecptr a = here ();
409: org (0xF0FF60);
410: calltrap (deftrap (uaelib_demux));
411: dw (RTS);
412: org (a);
1.1 root 413: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.