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