1 /* 2 Just a dummy. No BIOS services are required in the kernel. 3 */ 4 5 #include <arch_platform.h> 6 7 #include <new> 8 9 #include <KernelExport.h> 10 11 #include <boot/kernel_args.h> 12 #include <arch/cpu.h> 13 //#include <platform/openfirmware/openfirmware.h> 14 #include <platform/atari_m68k/MFP.h> 15 #include <real_time_clock.h> 16 #include <util/kernel_cpp.h> 17 18 #include "debugger_keymaps.h" 19 20 #define MFP0_BASE 0xFFFFFA00 21 #define MFP1_BASE 0xFFFFFA80 22 23 #define MFP0_VECTOR_BASE 64 24 #define MFP1_VECTOR_BASE (MFP0_VECTOR_BASE+16) 25 // ? 26 #define SCC_C0_VECTOR_BASE (MFP1_VECTOR_BASE+16) 27 // ?? 28 #define SCC_C1_VECTOR_BASE (0x1BC/4) 29 30 #define IKBD_BASE 0xFFFFFC00 31 #define IKBD_CTRL 0 32 #define IKBD_DATA 2 33 #define IKBD_STATUS_READ_BUFFER_FULL 0x01 34 35 // keyboard scancodes, very much like PC ones 36 // see 37 // http://www.classiccmp.org/dunfield/atw800/h/atw800k.jpg 38 // ST Mag Nr 57 page 55 39 enum keycodes { 40 LEFT_SHIFT = 42, 41 RIGHT_SHIFT = 54, 42 43 LEFT_CONTROL = 29, 44 45 LEFT_ALT = 56, 46 47 CURSOR_LEFT = 75, 48 CURSOR_RIGHT = 77, 49 CURSOR_UP = 72, 50 CURSOR_DOWN = 80, 51 CURSOR_HOME = 71, 52 CURSOR_END = 79, // not on real atari keyboard 53 PAGE_UP = 73, // not on real atari keyboard XXX remap Help ? 54 PAGE_DOWN = 81, // not on real atari keyboard XXX remap Undo ? 55 56 DELETE = 83, 57 F12 = 88, // but it's shifted 58 59 }; 60 61 #define in8(a) (*(volatile uint8 *)(a)) 62 #define out8(a, v) (*(volatile uint8 *)(a) = v) 63 64 65 namespace BPrivate { 66 67 //class MfpPIC; 68 69 // #pragma mark - Atari (Falcon) 70 71 72 class M68KAtari : public M68KPlatform { 73 public: 74 class MFP { 75 public: 76 MFP(uint32 base, int vector); 77 ~MFP(); 78 79 uint32 Base() const { return fBase; }; 80 int Vector() const { return fVector; }; 81 82 void EnableIOInterrupt(int irq); 83 void DisableIOInterrupt(int irq); 84 bool AcknowledgeIOInterrupt(int irq); 85 86 private: 87 uint32 fBase; 88 int fVector; 89 }; 90 91 M68KAtari(); 92 virtual ~M68KAtari(); 93 94 virtual status_t Init(struct kernel_args *kernelArgs); 95 virtual status_t InitSerialDebug(struct kernel_args *kernelArgs); 96 virtual status_t InitPostVM(struct kernel_args *kernelArgs); 97 virtual status_t InitPIC(struct kernel_args *kernelArgs); 98 virtual status_t InitRTC(struct kernel_args *kernelArgs, 99 struct real_time_data *data); 100 virtual status_t InitTimer(struct kernel_args *kernelArgs); 101 102 virtual char BlueScreenGetChar(); 103 104 virtual char SerialDebugGetChar(); 105 virtual void SerialDebugPutChar(char c); 106 107 virtual void EnableIOInterrupt(int irq); 108 virtual void DisableIOInterrupt(int irq); 109 virtual bool AcknowledgeIOInterrupt(int irq); 110 111 virtual void SetHardwareRTC(uint32 seconds); 112 virtual uint32 GetHardwareRTC(); 113 114 virtual void SetHardwareTimer(bigtime_t timeout); 115 virtual void ClearHardwareTimer(void); 116 117 virtual void ShutDown(bool reboot); 118 119 private: 120 MFP *MFPForIrq(int irq); 121 int fRTC; 122 123 MFP *fMFP[2]; 124 125 // native features (ARAnyM emulator) 126 uint32 (*nfGetID)(const char *name); 127 int32 (*nfCall)(uint32 ID, ...); 128 char *nfPage; 129 uint32 nfDebugPrintfID; 130 131 }; 132 133 134 } // namespace BPrivate 135 136 using BPrivate::M68KAtari; 137 138 139 // #pragma mark - M68KAtari::MFP 140 141 142 static char sMFP0Buffer[sizeof(M68KAtari::MFP)]; 143 static char sMFP1Buffer[sizeof(M68KAtari::MFP)]; 144 145 // constructor 146 M68KAtari::MFP::MFP(uint32 base, int vector) 147 { 148 fBase = base; 149 fVector = vector; 150 } 151 152 153 M68KAtari::MFP::~MFP() 154 { 155 } 156 157 #warning M68K: use enable or mark register ? 158 159 void 160 M68KAtari::MFP::EnableIOInterrupt(int irq) 161 { 162 uint8 bit = 1 << (irq % 8); 163 // I*B[0] is vector+0, I*A[0] is vector+8 164 uint32 reg = Base() + ((irq > 8) ? (MFP_IERA) : (MFP_IERB)); 165 uint8 val = in8(reg); 166 if (val & bit == 0) { 167 val |= bit; 168 out8(reg, val); 169 } 170 } 171 172 173 void 174 M68KAtari::MFP::DisableIOInterrupt(int irq) 175 { 176 uint8 bit = 1 << (irq % 8); 177 // I*B[0] is vector+0, I*A[0] is vector+8 178 uint32 reg = Base() + ((irq > 8) ? (MFP_IERA) : (MFP_IERB)); 179 uint8 val = in8(reg); 180 if (val & bit) { 181 val &= ~bit; 182 out8(reg, val); 183 } 184 } 185 186 187 bool 188 M68KAtari::MFP::AcknowledgeIOInterrupt(int irq) 189 { 190 uint8 bit = 1 << (irq % 8); 191 // I*B[0] is vector+0, I*A[0] is vector+8 192 uint32 reg = Base() + ((irq > 8) ? (MFP_ISRA) : (MFP_ISRB)); 193 uint8 val = in8(reg); 194 if (val & bit) { 195 val &= ~bit; 196 out8(reg, val); 197 return true; 198 } 199 return false; 200 } 201 202 203 // #pragma mark - M68KAtari 204 205 206 // constructor 207 M68KAtari::M68KAtari() 208 : M68KPlatform(B_ATARI_PLATFORM, M68K_PLATFORM_ATARI), 209 fRTC(-1) 210 { 211 } 212 213 214 // destructor 215 M68KAtari::~M68KAtari() 216 { 217 } 218 219 220 status_t 221 M68KAtari::Init(struct kernel_args *kernelArgs) 222 { 223 fMFP[0] = NULL; 224 fMFP[1] = NULL; 225 226 nfGetID = 227 kernelArgs->arch_args.plat_args.atari.nat_feat.nf_get_id; 228 nfCall = 229 kernelArgs->arch_args.plat_args.atari.nat_feat.nf_call; 230 nfPage = (char *) 231 kernelArgs->arch_args.plat_args.atari.nat_feat.nf_page; 232 233 return B_OK; 234 } 235 236 237 status_t 238 M68KAtari::InitSerialDebug(struct kernel_args *kernelArgs) 239 { 240 nfDebugPrintfID = 241 kernelArgs->arch_args.plat_args.atari.nat_feat.nf_dprintf_id; 242 243 #warning M68K: add real serial debug output someday 244 245 //out8(IKBD_BASE+IKBD_DATA, 0x11); 246 247 return B_OK; 248 } 249 250 251 status_t 252 M68KAtari::InitPostVM(struct kernel_args *kernelArgs) 253 { 254 #if 0 255 add_debugger_command("of_exit", &debug_command_of_exit, 256 "Exit to the Open Firmware prompt. No way to get back into the OS!"); 257 add_debugger_command("of_enter", &debug_command_of_enter, 258 "Enter a subordinate Open Firmware interpreter. Quitting it returns " 259 "to KDL."); 260 #endif 261 return B_NO_INIT; 262 return B_OK; 263 } 264 265 266 status_t 267 M68KAtari::InitPIC(struct kernel_args *kernelArgs) 268 { 269 panic("WRITEME"); 270 fMFP[0] = new(sMFP0Buffer) M68KAtari::MFP(MFP0_BASE, MFP0_VECTOR_BASE); 271 //if (kernelArgs->arch_args.machine == /*TT*/) { 272 fMFP[1] = new(sMFP1Buffer) M68KAtari::MFP(MFP1_BASE, MFP1_VECTOR_BASE); 273 //} 274 return B_NO_INIT; 275 } 276 277 278 status_t 279 M68KAtari::InitRTC(struct kernel_args *kernelArgs, 280 struct real_time_data *data) 281 { 282 panic("WRITEME"); 283 return B_NO_INIT; 284 return B_OK; 285 } 286 287 288 status_t 289 M68KAtari::InitTimer(struct kernel_args *kernelArgs) 290 { 291 panic("WRITEME"); 292 return B_NO_INIT; 293 } 294 295 296 char 297 M68KAtari::BlueScreenGetChar() 298 { 299 /* polling the keyboard, similar to code in keyboard 300 * driver, but without using an interrupt 301 * taken almost straight from x86 code 302 * XXX: maybe use the keymap from the _AKP cookie instead ? 303 */ 304 static bool shiftPressed = false; 305 static bool controlPressed = false; 306 static bool altPressed = false; 307 static uint8 special = 0; 308 static uint8 special2 = 0; 309 uint8 key = 0; 310 311 if (special & 0x80) { 312 special &= ~0x80; 313 return '['; 314 } 315 if (special != 0) { 316 key = special; 317 special = 0; 318 return key; 319 } 320 if (special2 != 0) { 321 key = special2; 322 special2 = 0; 323 return key; 324 } 325 326 while (true) { 327 uint8 status = in8(IKBD_BASE+IKBD_CTRL); 328 329 if ((status & IKBD_STATUS_READ_BUFFER_FULL) == 0) { 330 // no data in keyboard buffer 331 spin(200); 332 //kprintf("no key\n"); 333 continue; 334 } 335 336 spin(200); 337 key = in8(IKBD_BASE+IKBD_DATA); 338 /* 339 kprintf("key: %02x, %sshift %scontrol %salt\n", 340 key, 341 shiftPressed?"":"!", 342 controlPressed?"":"!", 343 altPressed?"":"!"); 344 */ 345 346 if (key & 0x80) { 347 // key up 348 switch (key & ~0x80) { 349 case LEFT_SHIFT: 350 case RIGHT_SHIFT: 351 shiftPressed = false; 352 break; 353 case LEFT_CONTROL: 354 controlPressed = false; 355 break; 356 case LEFT_ALT: 357 altPressed = false; 358 break; 359 } 360 } else { 361 // key down 362 switch (key) { 363 case LEFT_SHIFT: 364 case RIGHT_SHIFT: 365 shiftPressed = true; 366 break; 367 368 case LEFT_CONTROL: 369 controlPressed = true; 370 break; 371 372 case LEFT_ALT: 373 altPressed = true; 374 break; 375 376 // start escape sequence for cursor movement 377 case CURSOR_UP: 378 special = 0x80 | 'A'; 379 return '\x1b'; 380 case CURSOR_DOWN: 381 special = 0x80 | 'B'; 382 return '\x1b'; 383 case CURSOR_RIGHT: 384 special = 0x80 | 'C'; 385 return '\x1b'; 386 case CURSOR_LEFT: 387 special = 0x80 | 'D'; 388 return '\x1b'; 389 case CURSOR_HOME: 390 special = 0x80 | 'H'; 391 return '\x1b'; 392 case CURSOR_END: 393 special = 0x80 | 'F'; 394 return '\x1b'; 395 case PAGE_UP: 396 special = 0x80 | '5'; 397 special2 = '~'; 398 return '\x1b'; 399 case PAGE_DOWN: 400 special = 0x80 | '6'; 401 special2 = '~'; 402 return '\x1b'; 403 404 405 case DELETE: 406 if (controlPressed && altPressed) 407 arch_cpu_shutdown(true); 408 409 special = 0x80 | '3'; 410 special2 = '~'; 411 return '\x1b'; 412 413 default: 414 if (controlPressed) { 415 char c = kShiftedKeymap[key]; 416 if (c >= 'A' && c <= 'Z') 417 return 0x1f & c; 418 } 419 420 if (altPressed) 421 return kAltedKeymap[key]; 422 423 return shiftPressed 424 ? kShiftedKeymap[key] : kUnshiftedKeymap[key]; 425 } 426 } 427 } 428 } 429 430 431 char 432 M68KAtari::SerialDebugGetChar() 433 { 434 //WRITEME 435 return BlueScreenGetChar(); 436 //return 0; 437 } 438 439 440 void 441 M68KAtari::SerialDebugPutChar(char c) 442 { 443 if (nfCall && nfDebugPrintfID) { 444 #if 0 445 static char buffer[2] = { '\0', '\0' }; 446 buffer[0] = c; 447 448 nfCall(nfDebugPrintfID /*| 0*/, buffer); 449 #endif 450 nfPage[0] = c; 451 nfPage[1] = '\0'; 452 nfCall(nfDebugPrintfID /*| 0*/, nfPage); 453 } 454 455 #warning M68K: WRITEME 456 // real serial 457 //panic("WRITEME"); 458 } 459 460 461 void 462 M68KAtari::EnableIOInterrupt(int irq) 463 { 464 MFP *mfp = MFPForIrq(irq); 465 466 if (mfp) 467 mfp->EnableIOInterrupt(irq - mfp->Vector()); 468 } 469 470 471 void 472 M68KAtari::DisableIOInterrupt(int irq) 473 { 474 MFP *mfp = MFPForIrq(irq); 475 476 if (mfp) 477 mfp->DisableIOInterrupt(irq - mfp->Vector()); 478 } 479 480 481 bool 482 M68KAtari::AcknowledgeIOInterrupt(int irq) 483 { 484 MFP *mfp = MFPForIrq(irq); 485 486 if (mfp) 487 return mfp->AcknowledgeIOInterrupt(irq - mfp->Vector()); 488 return false; 489 } 490 491 void 492 M68KAtari::SetHardwareRTC(uint32 seconds) 493 { 494 } 495 496 497 uint32 498 M68KAtari::GetHardwareRTC() 499 { 500 return 0; 501 } 502 503 504 void 505 M68KAtari::SetHardwareTimer(bigtime_t timeout) 506 { 507 } 508 509 510 void 511 M68KAtari::ClearHardwareTimer(void) 512 { 513 } 514 515 516 void 517 M68KAtari::ShutDown(bool reboot) 518 { 519 panic("Bombs!"); 520 panic("WRITEME"); 521 } 522 523 524 M68KAtari::MFP * 525 M68KAtari::MFPForIrq(int irq) 526 { 527 int i; 528 529 for (i = 0; i < 2; i++) { 530 if (fMFP[i]) { 531 if (irq >= fMFP[i]->Vector() && irq < fMFP[i]->Vector() + 16) 532 return fMFP[i]; 533 } 534 } 535 return NULL; 536 } 537 538 539 // static buffer for constructing the actual M68KPlatform 540 static char *sM68KPlatformBuffer[sizeof(M68KAtari)]; 541 #warning PTR HERE ??? 542 543 544 M68KPlatform *instanciate_m68k_platform_atari() 545 { 546 return new(sM68KPlatformBuffer) M68KAtari; 547 } 548