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