MagiC PC knows two interfaces with which one can call up functions of the Windows system.
0. General remarks
MPS = Magic_Programmier_Schnittstelle = MagiC programmer's interface
Files of the demo example:
| mps_base.def | The export list of the DLL, DO NOT ALTER! |
| mps_base.h | Definition of the MPS interface, DO NOT ALTER! |
| mps_base.cpp | Basic functions of the DLL, DO NOT ALTER! |
| mps_demo.h | Definitions for the demo-DLL |
| mps_demo.cpp | The MPS_functions of the demo-DLL |
| testmps.s | Motorola - Example for calling the MPS functions of the demo |
To develop your own MPS_DLLs, please use mps_base.def, mps_base.h and mps_base.cpp unaltered. You can alter/supplement mps_demo.h and mps_demo.cpp. In particular, please choose your own DLL_ID in mps_demo.h for differentiation from other MPS_DLLs.
I. Concept
Windows-side one can use dynamic link libraries (DLLs) to establish any number of functions (called 'MPS_functions' in the following) which can be called within MagiC PC (Motorola-side).
In the start-up phase MagiC PC attempts to load and start all DLLs in the MPS subdirectory. For this MagiC PC calls three functions to be exported from the DLL (in this order):
All functions declared in 2) can be called via special opcodes on the Motorola side. See part IV for more about the call.
II. Functions of the DLL to be exported ('Basic functions')
An MPS_DLL must export exactly 3 C functions under fixed ordinal numbers (these are also called basic functions): (see mfp_base.def, mfp_base.cpp, mfp_base.h)
typedef struct {
DWORD sizeof_str; // Size of MPS_magicinfo
DWORD magic_version; // e.g. 0x010001
DWORD magic_date; // e.g. 19960815 (ascending)
BYTE is_demo; // Is it a demo version?
BYTE uu1, uu2, uu3; // Still unused, 0
BYTE *(*intel_adr)(DWORD motadr); // Convert address Motorola -> Intel
BYTE *(*intel_ptr)(DWORD motptr); // Convert pointer Motorola -> Intel (NULL stays NULL!)
WORD (*swap_word)(WORD w); // Swap one WORD
DWORD (*swap_long)(DWORD dw); // Swap one LONGword
} MPS_magicinfo;
III. The freely definable MPS_functions of a DLL:
MPS_functions basically have the form:
void function_blabla( MPS_motregs *motregs )
motregs here points to a list of the Motorola registers d0-a7. The contents of the registers is already in the correct Intel byte order. The Motorola registers may also have new values written to them.
With mps_get_functionlist the DLL passes the list of addresses of all such MPS_functions. The function numbers correspond to the position of the function within the list. If a number is to remain free, then its address is passed as 0xffffffff (= -1). See also mps_demo.cpp.
IV. Motorola-side call
MPS_functions are called by a Motorola-side 8-byte opcode:
dc.w $4fbf * 2 bytes: Do not alter!
dc.l DLL_ID * 4 bytes: DLL-specific DLL_ID
dc.w Fkt_no. * 2 bytes: Function number
DLL_ID is the DLL_ID (4 bytes!) passed via mps_get_functionlist. Function number is the position of the function in the function list passed by mps_get_functionlist (count starts at 0).
V. Miscellaneous
| DLL_ID | Program name | Author |
| 0x003f5c66 | MPCTime | Robert Weiß |
| 0x2053434B | MPCSTiK | Dan Ackerman |
| 0x21342812 | Draconis Windows Sockets | |
| 0x44594a01 | In2Cat | Dimitri Junker |
| 0x44594a02 | Win_Lnk | Dimitri Junker |
| 0x50475752 | MPC_POWR | Emanuel Welter |
; ========================================================== ; Export definitions for MPS MagiC PC programmer's interface FS 15.08.96 ; ========================================================== ; ; !! DO NOT ALTER !! ; ================== EXPORTS mps_get_type @101 mps_get_functionlist @102 mps_magicinfo @103
// Tab size: 3
// Last change: 15.08.96
// Author: FS
// ------------------------------------------------------------------------------
//
// The MagiC PC programmer's interface
//
// mps_base.h: Basic include !! ADOPT UNALTERED !!
// =====================
#ifdef __cplusplus
extern "C" {
#endif
/* =========================================================================
The DLL functions freely definable by the user have the form:
void mps_function(MPS_motregs *r),
where r represents a pointer to the 16 Motorola registers, so:
*/
typedef struct { // MPS_motregs = The Motorola registers
long d0,d1,d2,d3,d4,d5,d6,d7;
long a0,a1,a2,a3,a4,a5,a6,a7;
} MPS_motregs;
// MPS_fuptr = Pointer to a MPS_function:
typedef void (*MPS_fuptr)(MPS_motregs *);
/* ======================================================================
The DLL basic function mps_info is passed the following info block
MPS_infostr:
*/
typedef struct {
DWORD sizeof_str; // Size of MPS_infostr
DWORD magic_version; // e.g. 0x010001
DWORD magic_date; // e.g. 19960815 (ascending)
BYTE is_demo; // Is it a demo-version?
BYTE uu1, uu2, uu3; // Still unused, 0
BYTE *(*intel_adr)(DWORD motadr); // Convert address Motorola -> Intel
BYTE *(*intel_ptr)(DWORD motptr); // Convert pointer Motorola -> Intel (NULL stays NULL!)
WORD (*swap_word)(WORD w); // Swap one WORD
DWORD (*swap_long)(DWORD dw); // Swap one LONGword
} MPS_magicinfo;
// =============== 3 basic functions to be exported: ==================
//
int mps_get_type(); // @@101
int mps_get_functionlist(DWORD *mps_dll_id,MPS_fuptr **p_functionslist); // @@102
void mps_magicinfo(MPS_magicinfo *is); // @@103
//
// See also mps_base.cpp, mps_base.def
#ifdef __cplusplus
}
#endif
See also: MagiC PC interface
// Tab size: 3
// Last change: 15.08.96
// Author: FS
// ------------------------------------------------------------------------------
// Demo example for (!nolink [MagiC]) PC programmer's interface (MPS)
//
// Part 1: Basic functions, adopt UNCHANGED!
// =======
//
// ------------------------------------------------------------------------------
#include "windows.h"
#include "mps_base.h"
#include "mps_demo.h"
//
// The following 3 basic functions must be exported by the DLL:
//
// 1) Basic function @101: Type query
// ---------------------
int mps_get_type()
// ----------------
{
return(0x4701); // Must return this value
}
// 2) Basic function @102: MagiC PC requests ID and function list
// -----------------------
int mps_get_functionlist(DWORD *mps_dll_id,MPS_fuptr **p_functionslist)
// ------------------------
{
*mps_dll_id = DLL_ID; // User-defined ID, see mps_demo.h
*p_functionslist = my_funclist; // Enter pointer to function list
return(1);
}
// 3) Basic function @103: MagiC PC passes MPS_magicinfo to the DLL
// -----------------------
void mps_magicinfo(MPS_magicinfo *is)
// -------------
{
m_info = *is; // Remember
}
//
// END basic functions -------------------------------------------------------
//
See also: MagiC PC interface
// Tab size: 3
// Last change: 15.08.96
// Author: FS
// ------------------------------------------------------------------------------
// Demo example for MagiC PC programmer's interface (MPS)
//
// Part 2: User-defined functions, change DLL_ID to your own value !!!
// =======
//
// ------------------------------------------------------------------------------
#define DLL_ID 0x01020304 // Change to your own value
// !! Values with bit 31 set are
// reserved for Appl.Systems.
// ID reservation: Apply to
// Appl. Systems (Herr Hoffmann)!
extern MPS_fuptr my_funclist[]; // Function list in the demo-DLL
extern MPS_magicinfo m_info; // Is adopted by MagiC PC
See also: MagiC PC interface
// Tab size: 3
// Last change: 15.08.96
// Author: FS
// ------------------------------------------------------------------------------
// Demo example for (!nolink [MagiC]) PC programmer's interface (MPS)
//
// Parl 2: User-defined functions, freely alterable
// =======
//
// ------------------------------------------------------------------------------
#include "windows.h"
#include "mps_base.h"
#include "mps_demo.h"
MPS_magicinfo m_info; // Global for the DLL
//
// List of the user-defined functions (alter/extend as required):
// ------------------------------------------------------------------
static void demo_0(MPS_motregs *r);
static void demo_1(MPS_motregs *r);
static void demo_3(MPS_motregs *r);
static void copy_string(MPS_motregs *r);
MPS_fuptr my_funclist[] = {
demo_0, // Demo function 0
demo_1, // Demo function 1
(MPS_fuptr) -1, // -1 (i.e function No.2 not defined)
demo_3, // Demo function 3
copy_string, // Demo function 4
NULL // !! A NULL-entry at list end !!
} ;
// ******************************************************************
//
// Here the user-defined functions:
// ================================
//
// Demo_0 only returns the value 1 in d0:
//
static void demo_0(MPS_motregs *r)
// ----------------------
{
r->d0 = 1; // Demo-0 sets d0 to 1
return;
}
// Demo_1 adds the registers d1 and d2; result to d0:
//
static void demo_1(MPS_motregs *r)
// ----------------------
{
r->d0 = r->d1 + r->d2;
return;
}
// Demo_3 does nothing at all!
//
static void demo_3(MPS_motregs *r)
// ----------------------
{
return;
}
// Demo routine_4 copy_string copies a string to Motorola address space:
// -----------
// a0: Destination address,
// d0: Maximum number of characters (incl. 0)
//
static void copy_string(MPS_motregs *r)
// -----------------------
{
static char string[] = "This is a demo-text of copy_string(..)";
int i, nchmax;
char *dest;
nchmax = (int) r->d0;
dest = (char *) (*m_info.intel_ptr)(r->a0);
if (nchmax<=0 || dest==NULL) return; // Invalid?
for (i=0; i<nchmax; i++) {
if ((dest[i] = string[i])==0)
return;
}
dest[nchmax-1] = 0; // Too long->truncate
return;
}
See also: MagiC PC interface
* FS 15.08.96
*
* ===========================================================
* Sample for the call of the MPS functions from Motorola side
* ===========================================================
*
* Source Windows-side:
* --------------------
* mps_base.cpp, mps_demo.cpp
*
mps_code .equ $4fbf * !! DO NOT ALTER !!
DLL_ID .equ $01020304 * Enter own DLL_ID here
* -------------------------------------- 60 bytes buffer
bufsize .equ 60
.bss
.even
buffer: ds.w bufsize
* --------------------------------------
*
* ------------------- Here we go: -----------------------------------
*
.text
.globl _main
_main:
moveq #-1,d0 * d0 to -1 (for testing)
* =========================== * Call function 0 (Demo_0):
dc.w mps_code * = $4fbf
dc.l DLL_ID * = Own DLL_ID
dc.w 0 * Function number (here 0)
* ===========================
cmpi.l #1,d0 * Should return 1
bne finish
* Example for call with parameters (copy_string)
* ----------------------------------
movea.l #buffer,a0 * Pointer to buffer for string
move.l #bufsize,d0 * Max. string length (incl.0-byte)
* =========================== * Call function 4 (copy_string):
dc.w mps_code * = $4fbf
dc.l DLL_ID * = Own DLL_ID
dc.w 4 * Function number (here 4)
* ===========================
bsr put_line * Output line (a0)
finish:
bsr wait * Wait for keypress
rts
*
* --------------------- END main routine _main -----------------------
*
* ------------------------ Output line (a0) --------------------------
put_line:
moveq #13,d0
bsr put_char
moveq #10,d0
put_lnext:
bsr put_char
move.b (a0)+,d0
bne put_lnext
rts
* ------------------------ Output chatacter d0 -----------------------
put_char:
movem.l d0-d2/a0-a2,-(sp)
move.w d0,-(sp)
move.w #2,-(sp)
move.w #3,-(sp)
trap #13
addq.l #6,sp
movem.l (sp)+,d0-d2/a0-a2
rts
* -------------------------- Wait for keypress -----------------------
wait:
move.w #2,-(sp)
move.w #2,-(sp)
trap #13
addq.l #4,sp
rts
See also: MagiC PC interface
| $0001 | long emu_version:
| ||||||||||||||||||
| $0002 | long emu_enquire: Obtains diverse information
bisher definiert:
| ||||||||||||||||||
| $0003 | void emu_getexepath: Obtains the full path (including drive,
without MAGIC_PC.EXE)
| ||||||||||||||||||
| $0004 | int emu_install_newvdi: | ||||||||||||||||||
| $0010 | void dw_addline: ! As of 03.97 Output text in new line in the debug window
| ||||||||||||||||||
| $0011 | void dw_addtext: ! As of 03.97 Output text in debug window
| ||||||||||||||||||
| $0011 | void dw_formtxt: ! As of 03.97 Output text sprintf-like in debug window
| ||||||||||||||||||
| $0031 | int printer_open ! As of 03.97 printer_open Opens the standard printer and starts a new document
| ||||||||||||||||||
| $0032 | int printer_close ! As of 03.97 printer_close Terminates the previously opened document and closes the printer
| ||||||||||||||||||
| $0033 | int printer_write ! As of 03.97
| ||||||||||||||||||
| $0040 | DWORD getTickCount ! As of 03.97
| ||||||||||||||||||
| $0041 | DWORD getDrivePath ! ab 02.99 The function obtains the Windows path for a MagiC drive | ||||||||||||||||||
| $0042 | DWORD setClipboardDir ! ab 02.99
Beispiel: movea.l stringadr,a0 *
dc.w $43bf,$0042 * mec1, call function $42
tst.l d0 * -1: Function not implemented
jl nichtimplementiert
| ||||||||||||||||||
| $0043 | long getMouseWheel
Beispiel: moveq #1,d0 * Reset position after readout
dc.w $43bf,$0043 * mec1, call function $43
tst.l d0 * Position altered since last reset
je no_action
<d0.l verarbeiten>
| ||||||||||||||||||
| $0045 | long setCompiler ! As of 17.06.99
|