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