xref: /haiku/src/system/boot/platform/atari_m68k/toscalls.h (revision b06a48ab8f30b45916a9c157b992827779182163)
1 /*
2  * Copyright 2007, Haiku, Inc. All Rights Reserved.
3  * Distributed under the terms of the MIT license.
4  *
5  * Author:
6  *		François Revol, revol@free.fr.
7  */
8 
9 #ifndef _TOSCALLS_H
10 #define _TOSCALLS_H
11 
12 #ifdef __cplusplus
13 extern "C" {
14 #endif
15 
16 #ifndef __ASSEMBLER__
17 #include <OS.h>
18 
19 /* TOS calls use 16 bit param alignment, so we must generate the calls ourselves.
20  * We then use asm macros, one for each possible arg type and count.
21  * cf. how mint does it in sys/mint/arch/asm_misc.h
22  */
23 //#if __GNUC__ >= 3
24 #define TOS_CLOBBER_LIST "d1", "d2", "a0", "a1", "a2"
25 //#else
26 //#error fixme
27 //#endif
28 
29 /* void (no) arg */
30 #define toscallV(trapnr, callnr)				\
31 ({												\
32 	register int32 retvalue __asm__("d0");		\
33 												\
34 	__asm__ volatile							\
35 	("/* toscall(" #trapnr ", " #callnr ") */\n"	\
36 	"	move.w	%[calln],-(%%sp)\n"				\
37 	"	trap	%[trapn]\n"						\
38 	"	add.l	#2,%%sp\n"						\
39 	: "=r"(retvalue)	/* output */			\
40 	: [trapn]"i"(trapnr),[calln]"i"(callnr) 	\
41 									/* input */	\
42 	: TOS_CLOBBER_LIST /* clobbered regs */		\
43 	);											\
44 	retvalue;									\
45 })
46 
47 #define toscallW(trapnr, callnr, p1)			\
48 ({												\
49 	register int32 retvalue __asm__("d0");		\
50 	int16 _p1 = (int16)(p1);					\
51 												\
52 	__asm__ volatile							\
53 	("/* toscall(" #trapnr ", " #callnr ") */\n"	\
54 	"	move.w	%1,-(%%sp) \n"					\
55 	"	move.w	%[calln],-(%%sp)\n"				\
56 	"	trap	%[trapn]\n"						\
57 	"	add.l	#4,%%sp \n"						\
58 	: "=r"(retvalue)			/* output */	\
59 	: "r"(_p1),						/* input */	\
60 	  [trapn]"i"(trapnr),[calln]"i"(callnr)		\
61 	: TOS_CLOBBER_LIST /* clobbered regs */		\
62 	);											\
63 	retvalue;									\
64 })
65 
66 #define toscallL(trapnr, callnr, p1)			\
67 ({							\
68 	register int32 retvalue __asm__("d0");		\
69 	int32 _p1 = (int32)(p1);			\
70 							\
71 	__asm__ volatile				\
72 	(/*"; toscall(" #trapnr ", " #callnr ")"*/"\n	\
73 		move.l	%1,-(%%sp) \n			\
74 		move.w	%[calln],-(%%sp)\n		\
75 		trap	%[trapn]\n			\
76 		add.l	#6,%%sp \n "			\
77 	: "=r"(retvalue)	/* output */		\
78 	: "r"(_p1),			/* input */	\
79 	  [trapn]"i"(trapnr),[calln]"i"(callnr)		\
80 	: TOS_CLOBBER_LIST /* clobbered regs */		\
81 	);						\
82 	retvalue;					\
83 })
84 
85 #define toscallWW(trapnr, callnr, p1, p2)		\
86 ({							\
87 	register int32 retvalue __asm__("d0");		\
88 	int16 _p1 = (int16)(p1);			\
89 	int16 _p2 = (int16)(p2);			\
90 							\
91 	__asm__ volatile				\
92 	(/*"; toscall(" #trapnr ", " #callnr ")"*/"\n	\
93 		move.w	%2,-(%%sp) \n			\
94 		move.w	%1,-(%%sp) \n			\
95 		move.w	%[calln],-(%%sp)\n		\
96 		trap	%[trapn]\n			\
97 		add.l	#6,%%sp \n "			\
98 	: "=r"(retvalue)	/* output */		\
99 	: "r"(_p1), "r"(_p2),		/* input */	\
100 	  [trapn]"i"(trapnr),[calln]"i"(callnr)		\
101 	: TOS_CLOBBER_LIST /* clobbered regs */		\
102 	);						\
103 	retvalue;					\
104 })
105 
106 #define toscallWLWWWL(trapnr, callnr, p1, p2, p3, p4, p5, p6)	\
107 ({							\
108 	register int32 retvalue __asm__("d0");		\
109 	int16 _p1 = (int16)(p1);			\
110 	int32 _p2 = (int32)(p2);			\
111 	int16 _p3 = (int16)(p3);			\
112 	int16 _p4 = (int16)(p4);			\
113 	int16 _p5 = (int16)(p5);			\
114 	int32 _p6 = (int32)(p6);			\
115 							\
116 	__asm__ volatile				\
117 	(/*"; toscall(" #trapnr ", " #callnr ")"*/"\n	\
118 		move.l	%6,-(%%sp) \n			\
119 		move.w	%5,-(%%sp) \n			\
120 		move.w	%4,-(%%sp) \n			\
121 		move.w	%3,-(%%sp) \n			\
122 		move.l	%2,-(%%sp) \n			\
123 		move.w	%1,-(%%sp) \n			\
124 		move.w	%[calln],-(%%sp)\n		\
125 		trap	%[trapn]\n			\
126 		add.l	#18,%%sp \n "			\
127 	: "=r"(retvalue)	/* output */		\
128 	: "r"(_p1), "r"(_p2),				\
129 	  "r"(_p3), "r"(_p4),				\
130 	  "r"(_p5), "r"(_p6),		/* input */	\
131 	  [trapn]"i"(trapnr),[calln]"i"(callnr)		\
132 	: TOS_CLOBBER_LIST /* clobbered regs */		\
133 	);						\
134 	retvalue;					\
135 })
136 
137 /* pointer versions */
138 #define toscallP(trapnr, callnr, a) toscallL(trapnr, callnr, (int32)a)
139 #define toscallWPWWWL(trapnr, callnr, p1, p2, p3, p4, p5, p6) \
140 	toscallWLWWWL(trapnr, callnr, p1, (int32)p2, p3, p4, p5, p6)
141 
142 
143 
144 
145 #endif /* __ASSEMBLER__ */
146 
147 #ifdef __ASSEMBLER__
148 #define _TOSV_P(a) a
149 #define _TOSV_L(a) a
150 #define _TOSV_W(a) a
151 #define _TOSV_B(a) a
152 #else
153 #define _TOSV_P(a) ((void **)a)
154 #define _TOSV_L(a) ((uint32 *)a)
155 #define _TOSV_W(a) ((uint16 *)a)
156 #define _TOSV_B(a) ((uint8 *)a)
157 #endif
158 
159 /*
160  * TOS Variables
161  * only relevant ones,
162  * see toshyp.atari.org/003004.htm
163  */
164 #define TOSVAR_autopath	_TOSV_P(0x4ca)
165 #define TOSVAR_bootdev	_TOSV_W(0x446)
166 #define TOSVAR_dskbufp	_TOSV_P(0x4c6)
167 #define TOSVAR_drvbits	_TOSV_L(0x4c2)
168 #define TOSVAR_frclock	_TOSV_L(0x466)
169 #define TOSVAR_hz_200	_TOSV_L(0x4ba)
170 #define TOSVAR_membot	_TOSV_L(0x432)
171 #define TOSVAR_memtop	_TOSV_L(0x436)
172 #define TOSVAR_nflops	_TOSV_W(0x4a6)
173 #define TOSVAR_p_cookies	_TOSV_P(0x5A0)
174 #define TOSVAR_sysbase	_TOSV_P(0x4f2)
175 #define TOSVAR_timr_ms	_TOSV_W(0x442)
176 #define TOSVAR_v_bas_ad	_TOSV_P(0x44e)
177 #define TOSVAR_vbclock	_TOSV_L(0x462)
178 #define TOSVARphystop	_TOSV_L(0x42e)
179 #define TOSVARramtop	_TOSV_L(0x5a4)
180 #define TOSVARramvalid	_TOSV_L(0x5a8)
181 #define TOSVARramvalid_MAGIC 0x1357bd13
182 
183 
184 #define BIOS_TRAP	13
185 #define XBIOS_TRAP	14
186 #define GEMDOS_TRAP	1
187 
188 /*
189  * Atari BIOS calls
190  */
191 
192 /* those are used by asm code too */
193 
194 #define DEV_PRINTER	0
195 #define DEV_AUX	1
196 #define DEV_CON	2
197 #define DEV_CONSOLE	2
198 #define DEV_MIDI	3
199 #define DEV_IKBD	4
200 #define DEV_RAW	5
201 
202 #define K_RSHIFT	0x01
203 #define K_LSHIFT	0x02
204 #define K_CTRL	0x04
205 #define K_ALT	0x08
206 #define K_CAPSLOCK	0x10
207 #define K_CLRHOME	0x20
208 #define K_INSERT	0x40
209 
210 #define RW_READ			0x00
211 #define RW_WRITE		0x01
212 #define RW_NOMEDIACH	0x02
213 #define RW_NORETRY		0x04
214 #define RW_NOTRANSLATE	0x08
215 
216 #ifndef __ASSEMBLER__
217 
218 //extern int32 bios(uint16 nr, ...);
219 
220 // cf. http://www.fortunecity.com/skyscraper/apple/308/html/bios.htm
221 
222 struct tos_bpb {
223 	int16 recsiz;
224 	int16 clsiz;
225 	int16 clsizb;
226 	int16 rdlen;
227 	int16 fsiz;
228 	int16 fatrec;
229 	int16 datrec;
230 	int16 numcl;
231 	int16 bflags;
232 };
233 
234 struct tos_pun_info {
235 	int16 puns;
236 	uint8 pun[16];
237 	int32 part_start[16]; // unsigned ??
238 	uint32 p_cookie;
239 	struct tos_pun_info *p_cooptr; // points to itself
240 	uint16 p_version;
241 	uint16 p_max_sector;
242 	int32 reserved[16];
243 };
244 #define PUN_INFO ((struct tos_pun_info *)0x516L)
245 
246 
247 //#define Getmpb() toscallV(BIOS_TRAP, 0)
248 #define Bconstat(dev) toscallW(BIOS_TRAP, 1, (uint16)dev)
249 #define Bconin(dev) toscallW(BIOS_TRAP, 2, (uint16)dev)
250 #define Bconout(dev, chr) toscallWW(BIOS_TRAP, 3, (uint16)dev, (uint16)chr)
251 #define Rwabs(mode, buf, count, recno, dev, lrecno) toscallWPWWWL(BIOS_TRAP, 4, (int16)mode, (void *)buf, (int16)count, (int16)recno, (uint16)dev, (int32)lrecno)
252 //#define Setexc() toscallV(BIOS_TRAP, 5, )
253 #define Tickcal() toscallV(BIOS_TRAP, 6)
254 #define Getbpb(dev) (struct tos_bpb *)toscallW(BIOS_TRAP, 7, (uint16)dev)
255 #define Bcostat(dev) toscallW(BIOS_TRAP, 8, (uint16)dev)
256 #define Mediach(dev) toscallW(BIOS_TRAP, 9, (int16)dev)
257 #define Drvmap() (uint32)toscallV(BIOS_TRAP, 10)
258 #define Kbshift(mode) toscallW(BIOS_TRAP, 11, (uint16)mode)
259 
260 /* handy shortcut */
261 static inline int Bconput(int16 handle, const char *string)
262 {
263 	int i, col, err;
264 	for (i = 0, col = 0; string[i]; i++, col++) {
265 		if (string[i] == '\n') {
266 			Bconout(handle, '\r');
267 			col = 0;
268 		}
269 		/* hard wrap at 80 col as the ST console emulation doesn't do this. */
270 		if (col == 80) {
271 			Bconout(handle, '\r');
272 			Bconout(handle, '\n');
273 			col = 0;
274 		}
275 		err = Bconout(handle, string[i]);
276 		if (err < 0)
277 			break;
278 	}
279 	return i;
280 }
281 
282 static inline int Bconputs(int16 handle, const char *string)
283 {
284 	int err = Bconput(handle, string);
285 	Bconout(handle, '\r');
286 	Bconout(handle, '\n');
287 	return err;
288 }
289 
290 #endif /* __ASSEMBLER__ */
291 
292 /*
293  * Atari XBIOS calls
294  */
295 
296 #define IM_DISABLE	0
297 #define IM_RELATIVE	1
298 #define IM_ABSOLUTE	2
299 #define IM_KEYCODE	4
300 
301 #define NVM_READ	0
302 #define NVM_WRITE	1
303 #define NVM_RESET	2
304 // unofficial
305 #define NVM_R_SEC	0
306 #define NVM_R_MIN	2
307 #define NVM_R_HOUR	4
308 #define NVM_R_MDAY	7
309 #define NVM_R_MON	8	/*+- 1*/
310 #define NVM_R_YEAR	9
311 #define NVM_R_VIDEO	29
312 
313 #define VM_INQUIRE	-1
314 
315 #ifndef __ASSEMBLER__
316 
317 //extern int32 xbios(uint16 nr, ...);
318 
319 
320 #define Initmous(mode, param, vec) toscallWPP(XBIOS_TRAP, 0, (int16)mode, (void *)param, (void *)vec)
321 #define Physbase() (void *)toscallV(XBIOS_TRAP, 2)
322 #define Logbase() (void *)toscallV(XBIOS_TRAP, 3)
323 //#define Getrez() toscallV(XBIOS_TRAP, 4)
324 #define Setscreen(log, phys, mode) toscallPPW(XBIOS_TRAP, 5, (void *)log, (void *)phys, (int16)mode)
325 #define VsetScreen(log, phys, mode, modecode) toscallPPW(XBIOS_TRAP, 5, (void *)log, (void *)phys, (int16)mode)
326 //#define Mfpint() toscallV(XBIOS_TRAP, 13, )
327 #define Rsconf(speed, flow, ucr, rsr, tsr, scr) toscallWWWWWW(XBIOS_TRAP, 15, (int16)speed, (int16)flow, (int16)ucr, (int16)rsr, (int16)tsr, (int16)scr)
328 //#define Keytbl(unshift, shift, caps) (KEYTAB *)toscallPPP(XBIOS_TRAP, 16, (char *)unshift, (char *)shift, (char *)caps)
329 #define Random() toscallV(XBIOS_TRAP, 17)
330 #define Gettime() (uint32)toscallV(XBIOS_TRAP, 23)
331 #define Jdisint(intno) toscallW(XBIOS_TRAP, 26, (int16)intno)
332 #define Jenabint(intno) toscallW(XBIOS_TRAP, 27, (int16)intno)
333 #define Supexec(func) toscallP(XBIOS_TRAP, 38, (void *)func)
334 //#define Puntaes() toscallV(XBIOS_TRAP, 39)
335 #define DMAread(sect, count, buf, dev) toscallLWPW(XBIOS_TRAP, 42, (int32)sect, (int16)count, (void *)buf, (int16)dev)
336 #define DMAwrite(sect, count, buf, dev) toscallWPLW(XBIOS_TRAP, 43, (int32)sect, (int16)count, (void *)buf, (int16)dev)
337 #define NVMaccess(op, start, count, buffer) toscallWWWP(XBIOS_TRAP, 46, (int16)op, (int16)start, (int16)count, (char *)buffer)
338 #define VsetMode(mode) toscallW(XBIOS_TRAP, 88, (int16)mode)
339 #define VgetMonitor() toscallV(XBIOS_TRAP, 89)
340 #define Locksnd() toscallV(XBIOS_TRAP, 128)
341 #define Unlocksnd() toscallV(XBIOS_TRAP, 129)
342 
343 #endif /* __ASSEMBLER__ */
344 
345 /*
346  * Atari GEMDOS calls
347  */
348 
349 #define SUP_USER		0
350 #define SUP_SUPER		1
351 
352 
353 #ifdef __ASSEMBLER__
354 #define SUP_SET			0
355 #define SUP_INQUIRE		1
356 #else
357 
358 //extern int32 gemdos(uint16 nr, ...);
359 
360 #define SUP_SET			(void *)0
361 #define SUP_INQUIRE		(void *)1
362 
363 // official names
364 #define Pterm0() toscallV(GEMDOS_TRAP, 0)
365 #define Cconin() toscallV(GEMDOS_TRAP, 1)
366 #define Super(s) toscallP(GEMDOS_TRAP, 0x20, s)
367 #define Pterm(retcode) toscallW(GEMDOS_TRAP, 76, (int16)retcode)
368 
369 #endif /* __ASSEMBLER__ */
370 
371 #ifndef __ASSEMBLER__
372 
373 /*
374  * MetaDOS XBIOS calls
375  */
376 
377 //#define _DISABLE	0
378 
379 #ifndef __ASSEMBLER__
380 
381 #define Metainit(buf) toscallP(XBIOS_TRAP, 48, (void *)buf)
382 #define Metaopen(drive, p) toscall>P(XBIOS_TRAP, 48, (void *)buf)
383 #define Metaclose(drive) toscallW(XBIOS_TRAP, 50, (int16)drive)
384 #define Metagettoc(drive, flag, p) toscallW(XBIOS_TRAP, 62, (int16)drive, (int16)flag, (void *)p)
385 #define Metadiscinfo(drive, p) toscallWP(XBIOS_TRAP, 63, (int16)drive, (void *)p)
386 #define Metaioctl(drive, magic, op, buf) toscallWLWP(XBIOS_TRAP, 55, (int16)drive, (int32)magic, (int16)op, )
387 //#define Meta(drive) toscallW(XBIOS_TRAP, 50, (int16)drive)
388 //#define Meta(drive) toscallW(XBIOS_TRAP, 50, (int16)drive)
389 //#define Meta(drive) toscallW(XBIOS_TRAP, 50, (int16)drive)
390 
391 #endif /* __ASSEMBLER__ */
392 
393 /*
394  * XHDI support
395  * see http://toshyp.atari.org/010008.htm
396  */
397 
398 #define XHDI_COOKIE 'XHDI'
399 #define XHDI_MAGIC 0x27011992
400 //#define XHDI_CLOBBER_LIST "" /* only d0 */
401 #define XHDI_CLOBBER_LIST "d1", "d2", "a0", "a1", "a2"
402 
403 #define XH_TARGET_STOPPABLE		0x00000001L
404 #define XH_TARGET_REMOVABLE		0x00000002L
405 #define XH_TARGET_LOCKABLE		0x00000004L
406 #define XH_TARGET_EJECTABLE		0x00000008L
407 #define XH_TARGET_LOCKED		0x20000000L
408 #define XH_TARGET_STOPPED		0x40000000L
409 #define XH_TARGET_RESERVED		0x80000000L
410 
411 #ifndef __ASSEMBLER__
412 
413 /* pointer to the XHDI dispatch function */
414 extern void *gXHDIEntryPoint;
415 
416 extern status_t init_xhdi(void);
417 
418 /* movem should not needed, but just to be safe. */
419 
420 /* void (no) arg */
421 #define xhdicallV(callnr)						\
422 ({												\
423 	register int32 retvalue __asm__("d0");		\
424 												\
425 	__asm__ volatile							\
426 	("/* xhdicall(" #callnr ") */\n"			\
427 	"	movem.l	%%d3-%%d7/%%a3-%%a6,-(%%sp)\n"		\
428 	"	move.w	%[calln],-(%%sp)\n"				\
429 	"	jbsr	(%[entry])\n"						\
430 	"	add.l	#2,%%sp\n"						\
431 	"	movem.l	(%%sp)+,%%d3-%%d7/%%a3-%%a6\n"		\
432 	: "=r"(retvalue)	/* output */			\
433 	:							/* input */		\
434 	  [entry]"a"(gXHDIEntryPoint),				\
435 	  [calln]"i"(callnr)						\
436 	: XHDI_CLOBBER_LIST /* clobbered regs */	\
437 	);											\
438 	retvalue;									\
439 })
440 
441 #define xhdicallW(callnr, p1)					\
442 ({												\
443 	register int32 retvalue __asm__("d0");		\
444 	int16 _p1 = (int16)(p1);					\
445 												\
446 	__asm__ volatile							\
447 	("/* xhdicall(" #callnr ") */\n"			\
448 	"	movem.l	%%d3-%%d7/%%a3-%%a6,-(%%sp)\n"		\
449 	"	move.w	%1,-(%%sp) \n"					\
450 	"	move.w	%[calln],-(%%sp)\n"				\
451 	"	jbsr	(%[entry])\n"						\
452 	"	add.l	#4,%%sp \n"						\
453 	"	movem.l	(%%sp)+,%%d3-%%d7/%%a3-%%a6\n"		\
454 	: "=r"(retvalue)	/* output */			\
455 	: "r"(_p1),			/* input */				\
456 	  [entry]"a"(gXHDIEntryPoint),				\
457 	  [calln]"i"(callnr)						\
458 	: XHDI_CLOBBER_LIST /* clobbered regs */	\
459 	);											\
460 	retvalue;									\
461 })
462 
463 #define xhdicallWWL(callnr, p1, p2, p3)					\
464 ({												\
465 	register int32 retvalue __asm__("d0");		\
466 	int16 _p1 = (int16)(p1);					\
467 	int16 _p2 = (int16)(p2);					\
468 	int32 _p3 = (int32)(p3);					\
469 												\
470 	__asm__ volatile							\
471 	("/* xhdicall(" #callnr ") */\n"			\
472 	"	movem.l	%%d3-%%d7/%%a3-%%a6,-(%%sp)\n"		\
473 	"	move.l	%3,-(%%sp) \n"					\
474 	"	move.w	%2,-(%%sp) \n"					\
475 	"	move.w	%1,-(%%sp) \n"					\
476 	"	move.w	%[calln],-(%%sp)\n"				\
477 	"	jbsr	(%[entry])\n"						\
478 	"	add.l	#10,%%sp \n"						\
479 	"	movem.l	(%%sp)+,%%d3-%%d7/%%a3-%%a6\n"		\
480 	: "=r"(retvalue)	/* output */			\
481 	: "r"(_p1), "r"(_p2),				\
482 	  "r"(_p3),			/* input */	\
483 	  [entry]"a"(gXHDIEntryPoint),				\
484 	  [calln]"i"(callnr)						\
485 	: XHDI_CLOBBER_LIST /* clobbered regs */	\
486 	);											\
487 	retvalue;									\
488 })
489 
490 #define xhdicallWWLL(callnr, p1, p2, p3, p4)					\
491 ({												\
492 	register int32 retvalue __asm__("d0");		\
493 	int16 _p1 = (int16)(p1);					\
494 	int16 _p2 = (int16)(p2);					\
495 	int32 _p3 = (int32)(p3);					\
496 	int32 _p4 = (int32)(p4);					\
497 												\
498 	__asm__ volatile							\
499 	("/* xhdicall(" #callnr ") */\n"			\
500 	"	movem.l	%%d3-%%d7/%%a3-%%a6,-(%%sp)\n"		\
501 	"	move.l	%4,-(%%sp) \n"					\
502 	"	move.l	%3,-(%%sp) \n"					\
503 	"	move.w	%2,-(%%sp) \n"					\
504 	"	move.w	%1,-(%%sp) \n"					\
505 	"	move.w	%[calln],-(%%sp)\n"				\
506 	"	jbsr	(%[entry])\n"						\
507 	"	add.l	#14,%%sp \n"						\
508 	"	movem.l	(%%sp)+,%%d3-%%d7/%%a3-%%a6\n"		\
509 	: "=r"(retvalue)	/* output */			\
510 	: "r"(_p1), "r"(_p2),				\
511 	  "r"(_p3), "r"(_p4),	/* input */	\
512 	  [entry]"a"(gXHDIEntryPoint),				\
513 	  [calln]"i"(callnr)						\
514 	: XHDI_CLOBBER_LIST /* clobbered regs */	\
515 	);											\
516 	retvalue;									\
517 })
518 
519 #define xhdicallWWLLL(callnr, p1, p2, p3, p4, p5)					\
520 ({												\
521 	register int32 retvalue __asm__("d0");		\
522 	int16 _p1 = (int16)(p1);					\
523 	int16 _p2 = (int16)(p2);					\
524 	int32 _p3 = (int32)(p3);					\
525 	int32 _p4 = (int32)(p4);					\
526 	int32 _p5 = (int32)(p5);					\
527 												\
528 	__asm__ volatile							\
529 	("/* xhdicall(" #callnr ") */\n"			\
530 	"	movem.l	%%d3-%%d7/%%a3-%%a6,-(%%sp)\n"		\
531 	"	move.l	%5,-(%%sp) \n"					\
532 	"	move.l	%4,-(%%sp) \n"					\
533 	"	move.l	%3,-(%%sp) \n"					\
534 	"	move.w	%2,-(%%sp) \n"					\
535 	"	move.w	%1,-(%%sp) \n"					\
536 	"	move.w	%[calln],-(%%sp)\n"				\
537 	"	jbsr	(%[entry])\n"						\
538 	"	add.l	#18,%%sp \n"						\
539 	"	movem.l	(%%sp)+,%%d3-%%d7/%%a3-%%a6\n"		\
540 	: "=r"(retvalue)	/* output */			\
541 	: "r"(_p1), "r"(_p2),				\
542 	  "r"(_p3), "r"(_p4),				\
543 	  "r"(_p5),			/* input */	\
544 	  [entry]"a"(gXHDIEntryPoint),				\
545 	  [calln]"i"(callnr)						\
546 	: XHDI_CLOBBER_LIST /* clobbered regs */	\
547 	);											\
548 	retvalue;									\
549 })
550 
551 #define xhdicallWLLLL(callnr, p1, p2, p3, p4, p5)					\
552 ({												\
553 	register int32 retvalue __asm__("d0");		\
554 	int16 _p1 = (int16)(p1);					\
555 	int32 _p2 = (int32)(p2);					\
556 	int32 _p3 = (int32)(p3);					\
557 	int32 _p4 = (int32)(p4);					\
558 	int32 _p5 = (int32)(p5);					\
559 												\
560 	__asm__ volatile							\
561 	("/* xhdicall(" #callnr ") */\n"			\
562 	"	movem.l	%%d3-%%d7/%%a3-%%a6,-(%%sp)\n"		\
563 	"	move.l	%5,-(%%sp) \n"					\
564 	"	move.l	%4,-(%%sp) \n"					\
565 	"	move.l	%3,-(%%sp) \n"					\
566 	"	move.l	%2,-(%%sp) \n"					\
567 	"	move.w	%1,-(%%sp) \n"					\
568 	"	move.w	%[calln],-(%%sp)\n"				\
569 	"	jbsr	(%[entry])\n"						\
570 	"	add.l	#20,%%sp \n"						\
571 	"	movem.l	(%%sp)+,%%d3-%%d7/%%a3-%%a6\n"		\
572 	: "=r"(retvalue)	/* output */			\
573 	: "r"(_p1), "r"(_p2),				\
574 	  "r"(_p3), "r"(_p4),				\
575 	  "r"(_p5),			/* input */	\
576 	  [entry]"a"(gXHDIEntryPoint),				\
577 	  [calln]"i"(callnr)						\
578 	: XHDI_CLOBBER_LIST /* clobbered regs */	\
579 	);											\
580 	retvalue;									\
581 })
582 
583 #define xhdicallWWWLWL(callnr, p1, p2, p3, p4, p5, p6)					\
584 ({												\
585 	register int32 retvalue __asm__("d0");		\
586 	int16 _p1 = (int16)(p1);					\
587 	int16 _p2 = (int16)(p2);					\
588 	int16 _p3 = (int16)(p3);					\
589 	int32 _p4 = (int32)(p4);					\
590 	int16 _p5 = (int16)(p5);					\
591 	int32 _p6 = (int32)(p6);					\
592 												\
593 	__asm__ volatile							\
594 	("/* xhdicall(" #callnr ") */\n"			\
595 	"	movem.l	%%d3-%%d7/%%a3-%%a6,-(%%sp)\n"		\
596 	"	move.l	%6,-(%%sp) \n"					\
597 	"	move.w	%5,-(%%sp) \n"					\
598 	"	move.l	%4,-(%%sp) \n"					\
599 	"	move.w	%3,-(%%sp) \n"					\
600 	"	move.w	%2,-(%%sp) \n"					\
601 	"	move.w	%1,-(%%sp) \n"					\
602 	"	move.w	%[calln],-(%%sp)\n"				\
603 	"	jbsr	(%[entry])\n"						\
604 	"	add.l	#18,%%sp \n"						\
605 	"	movem.l	(%%sp)+,%%d3-%%d7/%%a3-%%a6\n"		\
606 	: "=r"(retvalue)	/* output */			\
607 	: "r"(_p1), "r"(_p2),				\
608 	  "r"(_p3), "r"(_p4),				\
609 	  "r"(_p5), "r"(_p6),		/* input */	\
610 	  [entry]"a"(gXHDIEntryPoint),				\
611 	  [calln]"i"(callnr)						\
612 	: XHDI_CLOBBER_LIST /* clobbered regs */	\
613 	);											\
614 	retvalue;									\
615 })
616 
617 #define xhdicallWWP(callnr, p1, p2, p3) \
618 	xhdicallWWL(callnr, p1, p2, (int32)(p3))
619 #define xhdicallWWPP(callnr, p1, p2, p3, p4) \
620 	xhdicallWWLL(callnr, p1, p2, (int32)(p3), (int32)(p4))
621 #define xhdicallWWPPP(callnr, p1, p2, p3, p4, p5) \
622 	xhdicallWWLLL(callnr, p1, p2, (int32)(p3), (int32)(p4), (int32)(p5))
623 #define xhdicallWPPPP(callnr, p1, p2, p3, p4, p5) \
624 	xhdicallWLLLL(callnr, p1, (uint32)(p2), (int32)(p3), (int32)(p4), (int32)(p5))
625 #define xhdicallWWWLWP(callnr, p1, p2, p3, p4, p5, p6) \
626 	xhdicallWWWLWL(callnr, p1, p2, p3, (uint32)(p4), p5, (uint32)(p6))
627 #define xhdicallWWWPWP(callnr, p1, p2, p3, p4, p5, p6) \
628 	xhdicallWWWLWL(callnr, p1, p2, p3, (int32)(p4), p5, (uint32)(p6))
629 
630 #define XHGetVersion() (uint16)xhdicallV(0)
631 #define XHInqTarget(major, minor, blocksize, flags, pname) xhdicallWWPPP(1, (uint16)major, (uint16)minor, (uint32 *)(blocksize), (uint32 *)flags, (char *)pname)
632 //XHReserve 2
633 //#define XHLock() 3
634 //#define XHStop() 4
635 #define XHEject(major, minor, doeject, key) xhdicallWWWW(5, (uint16)major, (uint16)minor, (uint16)doeject, (uint16)key)
636 #define XHDrvMap() xhdicallV(6)
637 #define XHInqDev(dev,major,minor,startsect,bpb) xhdicallWPPPP(7,dev,(uint16 *)major,(uint16 *)minor,(uint32 *)startsect,(struct tos_bpb *)bpb)
638 //XHInqDriver 8
639 //XHNewCookie 9
640 #define XHReadWrite(major, minor, rwflags, recno, count, buf) xhdicallWWWLWP(10, (uint16)major, (uint16)minor, (uint16)rwflags, (uint32)recno, (uint16)count, (void *)buf)
641 #define XHInqTarget2(major, minor, bsize, flags, pname, pnlen) xhdicallWWPPPW(11, (uint16)major, (uint16)minor, (uint32 *)bsize, (uint32 *)flags, (char *)pname, (uint16)pnlen)
642 //XHInqDev2 12
643 //XHDriverSpecial 13
644 #define XHGetCapacity(major, minor, blocks, blocksize) xhdicallWWPP(14, (uint16)major, (uint16)minor, (uint32 *)blocks, (uint32 *)blocksize)
645 //#define XHMediumChanged() 15
646 //XHMiNTInfo 16
647 //XHDosLimits 17
648 #define XHLastAccess(major, minor, ms) xhdicallWWP(18, major, minor, (uint32 *)ms)
649 //SHReaccess 19
650 
651 #endif /* __ASSEMBLER__ */
652 
653 
654 /*
655  * error mapping
656  * in debug.c
657  */
658 
659 extern status_t toserror(int32 err);
660 extern status_t xhdierror(int32 err);
661 extern void dump_tos_cookies(void);
662 
663 /*
664  * Cookie Jar access
665  */
666 
667 typedef struct tos_cookie {
668 	uint32 cookie;
669 	union {
670 		int32 ivalue;
671 		void *pvalue;
672 	};
673 } tos_cookie;
674 
675 #define COOKIE_JAR (*((const tos_cookie **)TOSVAR_p_cookies))
676 
677 static inline const tos_cookie *tos_find_cookie(uint32 what)
678 {
679 	const tos_cookie *c = COOKIE_JAR;
680 	while (c && (c->cookie)) {
681 		if (c->cookie == what)
682 			return c;
683 		c++;
684 	}
685 	return NULL;
686 }
687 
688 /*
689  * OSHEADER access
690  */
691 
692 typedef struct tos_osheader {
693 	uint16 os_entry;
694 	uint16 os_version;
695 	void *reseth;
696 	struct tos_osheader *os_beg;
697 	void *os_end;
698 	void *os_rsv1;
699 	void *os_magic;
700 	uint32 os_date;
701 	uint32 os_conf;
702 	//uint32/16? os_dosdate;
703 	// ... more stuff we don't care about
704 } tos_osheader;
705 
706 #define tos_sysbase ((const struct tos_osheader **)0x4F2)
707 
708 static inline const struct tos_osheader *tos_get_osheader()
709 {
710 	if (!(*tos_sysbase))
711 		return NULL;
712 	return (*tos_sysbase)->os_beg;
713 }
714 
715 #endif /* __ASSEMBLER__ */
716 
717 /*
718  * ARAnyM Native Features
719  */
720 
721 #define NF_COOKIE	0x5f5f4e46L	//'__NF'
722 #define NF_MAGIC	0x20021021L
723 
724 #ifndef __ASSEMBLER__
725 
726 typedef struct {
727 	uint32 magic;
728 	uint32 (*nfGetID) (const char *);
729 	int32 (*nfCall) (uint32 ID, ...);
730 } NatFeatCookie;
731 
732 extern NatFeatCookie *gNatFeatCookie;
733 extern uint32 gDebugPrintfNatFeatID;
734 
735 static inline NatFeatCookie *nat_features(void)
736 {
737 	const struct tos_cookie *c;
738 	if (gNatFeatCookie == (void *)-1)
739 		return NULL;
740 	if (gNatFeatCookie)
741 		return gNatFeatCookie;
742 	c = tos_find_cookie(NF_COOKIE);
743 	if (c) {
744 		gNatFeatCookie = (NatFeatCookie *)c->pvalue;
745 		if (gNatFeatCookie && gNatFeatCookie->magic == NF_MAGIC) {
746 			return gNatFeatCookie;
747 		}
748 	}
749 	gNatFeatCookie = (NatFeatCookie *)-1;
750 	return NULL;
751 }
752 
753 extern status_t init_nat_features(void);
754 
755 static inline int32 nat_feat_getid(const char *name)
756 {
757 	NatFeatCookie *c = nat_features();
758 	if (!c)
759 		return 0;
760 	return c->nfGetID(name);
761 }
762 
763 #define nat_feat_call(id, code, a...) \
764 ({						\
765 	int32 ret = -1;				\
766 	NatFeatCookie *c = nat_features();	\
767 	if (c)					\
768 		ret = c->nfCall(id | code, a);	\
769 	ret;					\
770 })
771 
772 extern void nat_feat_debugprintf(const char *str);
773 
774 #endif /* __ASSEMBLER__ */
775 
776 #ifdef __cplusplus
777 }
778 #endif
779 
780 #endif /* _TOSCALLS_H */
781