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