xref: /haiku/src/system/boot/platform/atari_m68k/toscalls.h (revision b46615c55ad2c8fe6de54412055a0713da3d610a)
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 /* Milan specific video constants */
401 #define MI_MAGIC	0x4d49
402 #define CMD_GETMODE		0
403 #define CMD_SETMODE		1
404 #define CMD_GETINFO		2
405 #define CMD_ALLOCPAGE	3
406 #define CMD_FREEPAGE	4
407 #define CMD_FLIPPAGE	5
408 #define CMD_ALLOCMEM	6
409 #define CMD_FREEMEM		7
410 #define CMD_SETADR		8
411 #define CMD_ENUMMODES	9
412 #define ENUMMODE_EXIT	0
413 #define ENUMMODE_CONT	1
414 /* scrFlags */
415 #define SCRINFO_OK	1
416 /* scrFormat */
417 #define INTERLEAVE_PLANES	0
418 #define STANDARD_PLANES		1
419 #define PACKEDPIX_PLANES	2
420 /* bitFlags */
421 #define STANDARD_BITS	1
422 #define FALCON_BITS		2
423 #define INTEL_BITS		8
424 
425 
426 #ifndef __ASSEMBLER__
427 
428 /* Milan specific video stuff */
429 typedef struct screeninfo {
430 	int32	size;
431 	int32	devID;
432 	char	name[64];
433 	int32	scrFlags;
434 	int32	frameadr;
435 	int32	scrHeight;
436 	int32	scrWidth;
437 	int32	virtHeight;
438 	int32	virtWidth;
439 	int32	scrPlanes;
440 	int32	scrColors;
441 	int32	lineWrap;
442 	int32	planeWrap;
443 	int32	scrFormat;
444 	int32	scrClut;
445 	/*
446 	int32	redBits;
447 	...
448 	*/
449 } SCREENINFO;
450 
451 
452 //extern int32 xbios(uint16 nr, ...);
453 
454 
455 #define Initmous(mode, param, vec) toscallWPP(XBIOS_TRAP, 0, (int16)mode, (void *)param, (void *)vec)
456 #define Physbase() (void *)toscallV(XBIOS_TRAP, 2)
457 #define Logbase() (void *)toscallV(XBIOS_TRAP, 3)
458 #define Getrez() toscallV(XBIOS_TRAP, 4)
459 #define Setscreen(log, phys, mode) toscallPPWW(XBIOS_TRAP, 5, (void *)log, (void *)phys, (int16)mode, (int16)0)
460 #define SetscreenM(log, phys, command) toscallPPWW(XBIOS_TRAP, 5, (void *)log, (void *)phys, (int16)MI_MAGIC, (int16)command)
461 #define VsetScreen(log, phys, mode, modecode) toscallPPWW(XBIOS_TRAP, 5, (void *)log, (void *)phys, (int16)mode, (int16)modecode)
462 #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)
463 //#define Mfpint() toscallV(XBIOS_TRAP, 13, )
464 #define Rsconf(speed, flow, ucr, rsr, tsr, scr) toscallWWWWWW(XBIOS_TRAP, 15, (int16)speed, (int16)flow, (int16)ucr, (int16)rsr, (int16)tsr, (int16)scr)
465 //#define Keytbl(unshift, shift, caps) (KEYTAB *)toscallPPP(XBIOS_TRAP, 16, (char *)unshift, (char *)shift, (char *)caps)
466 #define Random() toscallV(XBIOS_TRAP, 17)
467 #define Gettime() (uint32)toscallV(XBIOS_TRAP, 23)
468 #define Jdisint(intno) toscallW(XBIOS_TRAP, 26, (int16)intno)
469 #define Jenabint(intno) toscallW(XBIOS_TRAP, 27, (int16)intno)
470 #define Supexec(func) toscallP(XBIOS_TRAP, 38, (void *)func)
471 #define Puntaes() toscallV(XBIOS_TRAP, 39)
472 #define DMAread(sect, count, buf, dev) toscallLWPW(XBIOS_TRAP, 42, (int32)sect, (int16)count, (void *)buf, (int16)dev)
473 #define DMAwrite(sect, count, buf, dev) toscallWPLW(XBIOS_TRAP, 43, (int32)sect, (int16)count, (void *)buf, (int16)dev)
474 #define NVMaccess(op, start, count, buffer) toscallWWWP(XBIOS_TRAP, 46, (int16)op, (int16)start, (int16)count, (char *)buffer)
475 #define VsetMode(mode) toscallW(XBIOS_TRAP, 88, (int16)mode)
476 #define VgetMonitor() toscallV(XBIOS_TRAP, 89)
477 #define mon_type() toscallV(XBIOS_TRAP, 89)
478 #define VgetSize(mode) toscallW(XBIOS_TRAP, 91, (int16)mode)
479 #define VsetRGB(index, count, array) toscallWWP(XBIOS_TRAP, 93, (int16)index, (int16)count, (void *)array)
480 #define Locksnd() toscallV(XBIOS_TRAP, 128)
481 #define Unlocksnd() toscallV(XBIOS_TRAP, 129)
482 
483 #endif /* __ASSEMBLER__ */
484 
485 /*
486  * Atari GEMDOS calls
487  */
488 
489 #define SUP_USER		0
490 #define SUP_SUPER		1
491 
492 
493 #ifdef __ASSEMBLER__
494 #define SUP_SET			0
495 #define SUP_INQUIRE		1
496 #else
497 
498 //extern int32 gemdos(uint16 nr, ...);
499 
500 #define SUP_SET			(void *)0
501 #define SUP_INQUIRE		(void *)1
502 
503 // official names
504 #define Pterm0() toscallV(GEMDOS_TRAP, 0)
505 #define Cconin() toscallV(GEMDOS_TRAP, 1)
506 #define Super(s) toscallP(GEMDOS_TRAP, 0x20, s)
507 #define Pterm(retcode) toscallW(GEMDOS_TRAP, 76, (int16)retcode)
508 
509 #endif /* __ASSEMBLER__ */
510 
511 #ifndef __ASSEMBLER__
512 
513 /*
514  * MetaDOS XBIOS calls
515  */
516 
517 //#define _DISABLE	0
518 
519 #ifndef __ASSEMBLER__
520 
521 #define Metainit(buf) toscallP(XBIOS_TRAP, 48, (void *)buf)
522 #define Metaopen(drive, p) toscall>P(XBIOS_TRAP, 48, (void *)buf)
523 #define Metaclose(drive) toscallW(XBIOS_TRAP, 50, (int16)drive)
524 #define Metagettoc(drive, flag, p) toscallW(XBIOS_TRAP, 62, (int16)drive, (int16)flag, (void *)p)
525 #define Metadiscinfo(drive, p) toscallWP(XBIOS_TRAP, 63, (int16)drive, (void *)p)
526 #define Metaioctl(drive, magic, op, buf) toscallWLWP(XBIOS_TRAP, 55, (int16)drive, (int32)magic, (int16)op, )
527 //#define Meta(drive) toscallW(XBIOS_TRAP, 50, (int16)drive)
528 //#define Meta(drive) toscallW(XBIOS_TRAP, 50, (int16)drive)
529 //#define Meta(drive) toscallW(XBIOS_TRAP, 50, (int16)drive)
530 
531 #endif /* __ASSEMBLER__ */
532 
533 /*
534  * XHDI support
535  * see http://toshyp.atari.org/010008.htm
536  */
537 
538 #define XHDI_COOKIE 'XHDI'
539 #define XHDI_MAGIC 0x27011992
540 //#define XHDI_CLOBBER_LIST "" /* only d0 */
541 #define XHDI_CLOBBER_LIST "d1", "d2", "a0", "a1", "a2"
542 
543 #define XH_TARGET_STOPPABLE		0x00000001L
544 #define XH_TARGET_REMOVABLE		0x00000002L
545 #define XH_TARGET_LOCKABLE		0x00000004L
546 #define XH_TARGET_EJECTABLE		0x00000008L
547 #define XH_TARGET_LOCKED		0x20000000L
548 #define XH_TARGET_STOPPED		0x40000000L
549 #define XH_TARGET_RESERVED		0x80000000L
550 
551 #ifndef __ASSEMBLER__
552 
553 /* pointer to the XHDI dispatch function */
554 extern void *gXHDIEntryPoint;
555 
556 extern status_t init_xhdi(void);
557 
558 /* movem should not needed, but just to be safe. */
559 
560 /* void (no) arg */
561 #define xhdicallV(callnr)						\
562 ({												\
563 	register int32 retvalue __asm__("d0");		\
564 												\
565 	__asm__ volatile							\
566 	("/* xhdicall(" #callnr ") */\n"			\
567 	"	movem.l	%%d3-%%d7/%%a3-%%a6,-(%%sp)\n"		\
568 	"	move.w	%[calln],-(%%sp)\n"				\
569 	"	jbsr	(%[entry])\n"						\
570 	"	add.l	#2,%%sp\n"						\
571 	"	movem.l	(%%sp)+,%%d3-%%d7/%%a3-%%a6\n"		\
572 	: "=r"(retvalue)	/* output */			\
573 	:							/* input */		\
574 	  [entry]"a"(gXHDIEntryPoint),				\
575 	  [calln]"i"(callnr)						\
576 	: XHDI_CLOBBER_LIST /* clobbered regs */	\
577 	);											\
578 	retvalue;									\
579 })
580 
581 #define xhdicallW(callnr, p1)					\
582 ({												\
583 	register int32 retvalue __asm__("d0");		\
584 	int16 _p1 = (int16)(p1);					\
585 												\
586 	__asm__ volatile							\
587 	("/* xhdicall(" #callnr ") */\n"			\
588 	"	movem.l	%%d3-%%d7/%%a3-%%a6,-(%%sp)\n"		\
589 	"	move.w	%1,-(%%sp) \n"					\
590 	"	move.w	%[calln],-(%%sp)\n"				\
591 	"	jbsr	(%[entry])\n"						\
592 	"	add.l	#4,%%sp \n"						\
593 	"	movem.l	(%%sp)+,%%d3-%%d7/%%a3-%%a6\n"		\
594 	: "=r"(retvalue)	/* output */			\
595 	: "r"(_p1),			/* input */				\
596 	  [entry]"a"(gXHDIEntryPoint),				\
597 	  [calln]"i"(callnr)						\
598 	: XHDI_CLOBBER_LIST /* clobbered regs */	\
599 	);											\
600 	retvalue;									\
601 })
602 
603 #define xhdicallWWL(callnr, p1, p2, p3)					\
604 ({												\
605 	register int32 retvalue __asm__("d0");		\
606 	int16 _p1 = (int16)(p1);					\
607 	int16 _p2 = (int16)(p2);					\
608 	int32 _p3 = (int32)(p3);					\
609 												\
610 	__asm__ volatile							\
611 	("/* xhdicall(" #callnr ") */\n"			\
612 	"	movem.l	%%d3-%%d7/%%a3-%%a6,-(%%sp)\n"		\
613 	"	move.l	%3,-(%%sp) \n"					\
614 	"	move.w	%2,-(%%sp) \n"					\
615 	"	move.w	%1,-(%%sp) \n"					\
616 	"	move.w	%[calln],-(%%sp)\n"				\
617 	"	jbsr	(%[entry])\n"						\
618 	"	add.l	#10,%%sp \n"						\
619 	"	movem.l	(%%sp)+,%%d3-%%d7/%%a3-%%a6\n"		\
620 	: "=r"(retvalue)	/* output */			\
621 	: "r"(_p1), "r"(_p2),				\
622 	  "r"(_p3),			/* input */	\
623 	  [entry]"a"(gXHDIEntryPoint),				\
624 	  [calln]"i"(callnr)						\
625 	: XHDI_CLOBBER_LIST /* clobbered regs */	\
626 	);											\
627 	retvalue;									\
628 })
629 
630 #define xhdicallWWLL(callnr, p1, p2, p3, p4)					\
631 ({												\
632 	register int32 retvalue __asm__("d0");		\
633 	int16 _p1 = (int16)(p1);					\
634 	int16 _p2 = (int16)(p2);					\
635 	int32 _p3 = (int32)(p3);					\
636 	int32 _p4 = (int32)(p4);					\
637 												\
638 	__asm__ volatile							\
639 	("/* xhdicall(" #callnr ") */\n"			\
640 	"	movem.l	%%d3-%%d7/%%a3-%%a6,-(%%sp)\n"		\
641 	"	move.l	%4,-(%%sp) \n"					\
642 	"	move.l	%3,-(%%sp) \n"					\
643 	"	move.w	%2,-(%%sp) \n"					\
644 	"	move.w	%1,-(%%sp) \n"					\
645 	"	move.w	%[calln],-(%%sp)\n"				\
646 	"	jbsr	(%[entry])\n"						\
647 	"	add.l	#14,%%sp \n"						\
648 	"	movem.l	(%%sp)+,%%d3-%%d7/%%a3-%%a6\n"		\
649 	: "=r"(retvalue)	/* output */			\
650 	: "r"(_p1), "r"(_p2),				\
651 	  "r"(_p3), "r"(_p4),	/* input */	\
652 	  [entry]"a"(gXHDIEntryPoint),				\
653 	  [calln]"i"(callnr)						\
654 	: XHDI_CLOBBER_LIST /* clobbered regs */	\
655 	);											\
656 	retvalue;									\
657 })
658 
659 #define xhdicallWWLLL(callnr, p1, p2, p3, p4, p5)					\
660 ({												\
661 	register int32 retvalue __asm__("d0");		\
662 	int16 _p1 = (int16)(p1);					\
663 	int16 _p2 = (int16)(p2);					\
664 	int32 _p3 = (int32)(p3);					\
665 	int32 _p4 = (int32)(p4);					\
666 	int32 _p5 = (int32)(p5);					\
667 												\
668 	__asm__ volatile							\
669 	("/* xhdicall(" #callnr ") */\n"			\
670 	"	movem.l	%%d3-%%d7/%%a3-%%a6,-(%%sp)\n"		\
671 	"	move.l	%5,-(%%sp) \n"					\
672 	"	move.l	%4,-(%%sp) \n"					\
673 	"	move.l	%3,-(%%sp) \n"					\
674 	"	move.w	%2,-(%%sp) \n"					\
675 	"	move.w	%1,-(%%sp) \n"					\
676 	"	move.w	%[calln],-(%%sp)\n"				\
677 	"	jbsr	(%[entry])\n"						\
678 	"	add.l	#18,%%sp \n"						\
679 	"	movem.l	(%%sp)+,%%d3-%%d7/%%a3-%%a6\n"		\
680 	: "=r"(retvalue)	/* output */			\
681 	: "r"(_p1), "r"(_p2),				\
682 	  "r"(_p3), "r"(_p4),				\
683 	  "r"(_p5),			/* input */	\
684 	  [entry]"a"(gXHDIEntryPoint),				\
685 	  [calln]"i"(callnr)						\
686 	: XHDI_CLOBBER_LIST /* clobbered regs */	\
687 	);											\
688 	retvalue;									\
689 })
690 
691 #define xhdicallWLLLL(callnr, p1, p2, p3, p4, p5)					\
692 ({												\
693 	register int32 retvalue __asm__("d0");		\
694 	int16 _p1 = (int16)(p1);					\
695 	int32 _p2 = (int32)(p2);					\
696 	int32 _p3 = (int32)(p3);					\
697 	int32 _p4 = (int32)(p4);					\
698 	int32 _p5 = (int32)(p5);					\
699 												\
700 	__asm__ volatile							\
701 	("/* xhdicall(" #callnr ") */\n"			\
702 	"	movem.l	%%d3-%%d7/%%a3-%%a6,-(%%sp)\n"		\
703 	"	move.l	%5,-(%%sp) \n"					\
704 	"	move.l	%4,-(%%sp) \n"					\
705 	"	move.l	%3,-(%%sp) \n"					\
706 	"	move.l	%2,-(%%sp) \n"					\
707 	"	move.w	%1,-(%%sp) \n"					\
708 	"	move.w	%[calln],-(%%sp)\n"				\
709 	"	jbsr	(%[entry])\n"						\
710 	"	add.l	#20,%%sp \n"						\
711 	"	movem.l	(%%sp)+,%%d3-%%d7/%%a3-%%a6\n"		\
712 	: "=r"(retvalue)	/* output */			\
713 	: "r"(_p1), "r"(_p2),				\
714 	  "r"(_p3), "r"(_p4),				\
715 	  "r"(_p5),			/* input */	\
716 	  [entry]"a"(gXHDIEntryPoint),				\
717 	  [calln]"i"(callnr)						\
718 	: XHDI_CLOBBER_LIST /* clobbered regs */	\
719 	);											\
720 	retvalue;									\
721 })
722 
723 #define xhdicallWWWLWL(callnr, p1, p2, p3, p4, p5, p6)					\
724 ({												\
725 	register int32 retvalue __asm__("d0");		\
726 	int16 _p1 = (int16)(p1);					\
727 	int16 _p2 = (int16)(p2);					\
728 	int16 _p3 = (int16)(p3);					\
729 	int32 _p4 = (int32)(p4);					\
730 	int16 _p5 = (int16)(p5);					\
731 	int32 _p6 = (int32)(p6);					\
732 												\
733 	__asm__ volatile							\
734 	("/* xhdicall(" #callnr ") */\n"			\
735 	"	movem.l	%%d3-%%d7/%%a3-%%a6,-(%%sp)\n"		\
736 	"	move.l	%6,-(%%sp) \n"					\
737 	"	move.w	%5,-(%%sp) \n"					\
738 	"	move.l	%4,-(%%sp) \n"					\
739 	"	move.w	%3,-(%%sp) \n"					\
740 	"	move.w	%2,-(%%sp) \n"					\
741 	"	move.w	%1,-(%%sp) \n"					\
742 	"	move.w	%[calln],-(%%sp)\n"				\
743 	"	jbsr	(%[entry])\n"						\
744 	"	add.l	#18,%%sp \n"						\
745 	"	movem.l	(%%sp)+,%%d3-%%d7/%%a3-%%a6\n"		\
746 	: "=r"(retvalue)	/* output */			\
747 	: "r"(_p1), "r"(_p2),				\
748 	  "r"(_p3), "r"(_p4),				\
749 	  "r"(_p5), "r"(_p6),		/* input */	\
750 	  [entry]"a"(gXHDIEntryPoint),				\
751 	  [calln]"i"(callnr)						\
752 	: XHDI_CLOBBER_LIST /* clobbered regs */	\
753 	);											\
754 	retvalue;									\
755 })
756 
757 #define xhdicallWWP(callnr, p1, p2, p3) \
758 	xhdicallWWL(callnr, p1, p2, (int32)(p3))
759 #define xhdicallWWPP(callnr, p1, p2, p3, p4) \
760 	xhdicallWWLL(callnr, p1, p2, (int32)(p3), (int32)(p4))
761 #define xhdicallWWPPP(callnr, p1, p2, p3, p4, p5) \
762 	xhdicallWWLLL(callnr, p1, p2, (int32)(p3), (int32)(p4), (int32)(p5))
763 #define xhdicallWPPPP(callnr, p1, p2, p3, p4, p5) \
764 	xhdicallWLLLL(callnr, p1, (uint32)(p2), (int32)(p3), (int32)(p4), (int32)(p5))
765 #define xhdicallWWWLWP(callnr, p1, p2, p3, p4, p5, p6) \
766 	xhdicallWWWLWL(callnr, p1, p2, p3, (uint32)(p4), p5, (uint32)(p6))
767 #define xhdicallWWWPWP(callnr, p1, p2, p3, p4, p5, p6) \
768 	xhdicallWWWLWL(callnr, p1, p2, p3, (int32)(p4), p5, (uint32)(p6))
769 
770 #define XHGetVersion() (uint16)xhdicallV(0)
771 #define XHInqTarget(major, minor, blocksize, flags, pname) xhdicallWWPPP(1, (uint16)major, (uint16)minor, (uint32 *)(blocksize), (uint32 *)flags, (char *)pname)
772 //XHReserve 2
773 //#define XHLock() 3
774 //#define XHStop() 4
775 #define XHEject(major, minor, doeject, key) xhdicallWWWW(5, (uint16)major, (uint16)minor, (uint16)doeject, (uint16)key)
776 #define XHDrvMap() xhdicallV(6)
777 #define XHInqDev(dev,major,minor,startsect,bpb) xhdicallWPPPP(7,dev,(uint16 *)major,(uint16 *)minor,(uint32 *)startsect,(struct tos_bpb *)bpb)
778 //XHInqDriver 8
779 //XHNewCookie 9
780 #define XHReadWrite(major, minor, rwflags, recno, count, buf) xhdicallWWWLWP(10, (uint16)major, (uint16)minor, (uint16)rwflags, (uint32)recno, (uint16)count, (void *)buf)
781 #define XHInqTarget2(major, minor, bsize, flags, pname, pnlen) xhdicallWWPPPW(11, (uint16)major, (uint16)minor, (uint32 *)bsize, (uint32 *)flags, (char *)pname, (uint16)pnlen)
782 //XHInqDev2 12
783 //XHDriverSpecial 13
784 #define XHGetCapacity(major, minor, blocks, blocksize) xhdicallWWPP(14, (uint16)major, (uint16)minor, (uint32 *)blocks, (uint32 *)blocksize)
785 //#define XHMediumChanged() 15
786 //XHMiNTInfo 16
787 //XHDosLimits 17
788 #define XHLastAccess(major, minor, ms) xhdicallWWP(18, major, minor, (uint32 *)ms)
789 //SHReaccess 19
790 
791 #endif /* __ASSEMBLER__ */
792 
793 
794 /*
795  * error mapping
796  * in debug.c
797  */
798 
799 extern status_t toserror(int32 err);
800 extern status_t xhdierror(int32 err);
801 extern void dump_tos_cookies(void);
802 
803 /*
804  * Cookie Jar access
805  */
806 
807 typedef struct tos_cookie {
808 	uint32 cookie;
809 	union {
810 		int32 ivalue;
811 		void *pvalue;
812 	};
813 } tos_cookie;
814 
815 #define COOKIE_JAR (*((const tos_cookie **)TOSVAR_p_cookies))
816 
817 static inline const tos_cookie *tos_find_cookie(uint32 what)
818 {
819 	const tos_cookie *c = COOKIE_JAR;
820 	while (c && (c->cookie)) {
821 		if (c->cookie == what)
822 			return c;
823 		c++;
824 	}
825 	return NULL;
826 }
827 
828 /*
829  * OSHEADER access
830  */
831 
832 typedef struct tos_osheader {
833 	uint16 os_entry;
834 	uint16 os_version;
835 	void *reseth;
836 	struct tos_osheader *os_beg;
837 	void *os_end;
838 	void *os_rsv1;
839 	void *os_magic;
840 	uint32 os_date;
841 	uint32 os_conf;
842 	//uint32/16? os_dosdate;
843 	// ... more stuff we don't care about
844 } tos_osheader;
845 
846 #define tos_sysbase ((const struct tos_osheader **)0x4F2)
847 
848 static inline const struct tos_osheader *tos_get_osheader()
849 {
850 	if (!(*tos_sysbase))
851 		return NULL;
852 	return (*tos_sysbase)->os_beg;
853 }
854 
855 #endif /* __ASSEMBLER__ */
856 
857 /*
858  * ARAnyM Native Features
859  */
860 
861 #define NF_COOKIE	0x5f5f4e46L	//'__NF'
862 #define NF_MAGIC	0x20021021L
863 
864 #ifndef __ASSEMBLER__
865 
866 typedef struct {
867 	uint32 magic;
868 	uint32 (*nfGetID) (const char *);
869 	int32 (*nfCall) (uint32 ID, ...);
870 } NatFeatCookie;
871 
872 extern NatFeatCookie *gNatFeatCookie;
873 extern uint32 gDebugPrintfNatFeatID;
874 
875 static inline NatFeatCookie *nat_features(void)
876 {
877 	const struct tos_cookie *c;
878 	if (gNatFeatCookie == (void *)-1)
879 		return NULL;
880 	if (gNatFeatCookie)
881 		return gNatFeatCookie;
882 	c = tos_find_cookie(NF_COOKIE);
883 	if (c) {
884 		gNatFeatCookie = (NatFeatCookie *)c->pvalue;
885 		if (gNatFeatCookie && gNatFeatCookie->magic == NF_MAGIC) {
886 			return gNatFeatCookie;
887 		}
888 	}
889 	gNatFeatCookie = (NatFeatCookie *)-1;
890 	return NULL;
891 }
892 
893 extern status_t init_nat_features(void);
894 
895 static inline int32 nat_feat_getid(const char *name)
896 {
897 	NatFeatCookie *c = nat_features();
898 	if (!c)
899 		return 0;
900 	return c->nfGetID(name);
901 }
902 
903 #define nat_feat_call(id, code, a...) \
904 ({						\
905 	int32 ret = -1;				\
906 	NatFeatCookie *c = nat_features();	\
907 	if (c)					\
908 		ret = c->nfCall(id | code, ##a);	\
909 	ret;					\
910 })
911 
912 extern void nat_feat_debugprintf(const char *str);
913 
914 extern int nat_feat_get_bootdrive(void);
915 extern status_t nat_feat_get_bootargs(char *str, long size);
916 
917 #endif /* __ASSEMBLER__ */
918 
919 /*
920  * Drive API used by the bootsector
921  * gBootDriveAPI is set to one of those
922  * not all are implemented
923  */
924 #define ATARI_BOOT_DRVAPI_UNKNOWN 0
925 #define ATARI_BOOT_DRVAPI_FLOPPY  1   // Floprd()
926 #define ATARI_BOOT_DRVAPI_BIOS    2   // Rwabs()
927 #define ATARI_BOOT_DRVAPI_XBIOS   3   // DMAread()
928 #define ATARI_BOOT_DRVAPI_XHDI    4   // XHReadWrite()
929 #define ATARI_BOOT_DRVAPI_METADOS 5   // Metaread()
930 
931 #ifdef __cplusplus
932 }
933 #endif
934 
935 #endif /* _TOSCALLS_H */
936