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