|
|
1.1 ! root 1: /* NeXT system registers emulation */ ! 2: ! 3: #include <stdlib.h> ! 4: #include "main.h" ! 5: #include "ioMem.h" ! 6: #include "ioMemTables.h" ! 7: #include "video.h" ! 8: #include "configuration.h" ! 9: #include "sysdeps.h" ! 10: #include "m68000.h" ! 11: #include "sysReg.h" ! 12: #include "statusbar.h" ! 13: ! 14: ! 15: #define IO_SEG_MASK 0x1FFFF ! 16: ! 17: static Uint32 scr1=0x00000000; ! 18: static Uint32 turboscr1=0x00000000; ! 19: ! 20: static Uint8 scr2_0=0x00; ! 21: static Uint8 scr2_1=0x00; ! 22: static Uint8 scr2_2=0x80; ! 23: static Uint8 scr2_3=0x00; ! 24: ! 25: static Uint32 intStat=0x00000000; ! 26: static Uint32 intMask=0x00000000; ! 27: ! 28: ! 29: /* RTC NVRAM */ ! 30: ! 31: // file mon/nvram.h ! 32: // struct nvram_info { ! 33: // #define NI_RESET 9 ! 34: // u_int ni_reset : 4, ! 35: // #define SCC_ALT_CONS 0x08000000 ! 36: // ni_alt_cons : 1, ! 37: // #define ALLOW_EJECT 0x04000000 ! 38: // ni_allow_eject : 1, ! 39: // ni_vol_r : 6, ! 40: // ni_brightness : 6, ! 41: // #define HW_PWD 0x6 ! 42: // ni_hw_pwd : 4, ! 43: // ni_vol_l : 6, ! 44: // ni_spkren : 1, ! 45: // ni_lowpass : 1, ! 46: // #define BOOT_ANY 0x00000002 ! 47: // ni_boot_any : 1, ! 48: // #define ANY_CMD 0x00000001 ! 49: // ni_any_cmd : 1; ! 50: // #define NVRAM_HW_PASSWD 6 ! 51: // u_char ni_ep[NVRAM_HW_PASSWD]; ! 52: // #define ni_enetaddr ni_ep ! 53: // #define ni_hw_passwd ni_ep ! 54: // u_short ni_simm; /* 4 SIMMs, 4 bits per SIMM */ ! 55: // char ni_adobe[2]; ! 56: // u_char ni_pot[3]; ! 57: // u_char ni_new_clock_chip : 1, ! 58: // ni_auto_poweron : 1, ! 59: // ni_use_console_slot : 1, /* Console slot was set by user. */ ! 60: // ni_console_slot : 2, /* Preferred console dev slot>>1 */ ! 61: // ni_use_parity_mem : 1, /* Use parity RAM if available? */ ! 62: // : 2; ! 63: // #define NVRAM_BOOTCMD 12 ! 64: // char ni_bootcmd[NVRAM_BOOTCMD]; ! 65: // u_short ni_cksum; ! 66: // }; ! 67: ! 68: // #define N_brightness 0 ! 69: // #define N_volume_l 1 ! 70: // #define N_volume_r 2 ! 71: ! 72: /* nominal values during self test */ ! 73: // #define BRIGHT_NOM 20 ! 74: // #define VOL_NOM 0 ! 75: ! 76: /* bits in ni_pot[0] */ ! 77: #define POT_ON 0x01 ! 78: #define EXTENDED_POT 0x02 ! 79: #define LOOP_POT 0x04 ! 80: #define VERBOSE_POT 0x08 ! 81: #define TEST_DRAM_POT 0x10 ! 82: #define BOOT_POT 0x20 ! 83: #define TEST_MONITOR_POT 0x40 ! 84: ! 85: /* bits in byte 17 */ ! 86: #define NEW_CLOCK_CHIP 0x80 ! 87: #define AUTO_POWERON 0x40 ! 88: #define USE_CONSOLE_SLOT 0x20 ! 89: #define CONSOLE_SLOT 0x18 ! 90: #define USE_PARITY_MEM 0x40 ! 91: ! 92: /* bits in ni_simm (rtc ram byte 10 and 11) * ! 93: * -------- -----xxx bit 0 - 2: 1st simm: bit 1+2 define size, bit 3 defines page mode ! 94: * -------- --xxx--- bit 3 - 5: 2nd simm: bit 1+2 define size, bit 3 defines page mode ! 95: * -------x xx------ bit 6 - 8: 3rd simm: bit 1+2 define size, bit 3 defines page mode ! 96: * ----xxx- -------- bit 9 -11: 4th simm: bit 1+2 define size, bit 3 defines page mode ! 97: * xxxx---- -------- bit 12-15: defines parity, 1 bit for each simm (ignored on 68030) ! 98: */ ! 99: /* for 68030 and monochrome non-turbo systems */ ! 100: #define SIMM_EMPTY 0x0 ! 101: #define SIMM_16MB 0x1 /* Group of four 4 Mbyte SIMMs */ ! 102: #define SIMM_4MB 0x2 /* Group of four 1 Mbyte SIMMs */ ! 103: #define SIMM_1MB 0x3 /* Group of four 256 KByte SIMMs */ ! 104: #define SIMM_PAGE_MODE 0x4 /* SIMM type is page mode, else nibble mode */ ! 105: /* for all 68040 systems */ ! 106: #define SIMM_PARITY 0x8 /* SIMMs support parity */ ! 107: /* for non-turbo color systems */ ! 108: #define SIMM_8MB_C 0x1 /* Pair of 4 Mbyte SIMMs */ ! 109: #define SIMM_2MB_C 0x2 /* Pair of 1 Mbyte SIMMs */ ! 110: #define SIMM_EMPTY2 0x3 /* reserved */ ! 111: /* for turbo systems */ ! 112: #define SIMM_32MB_T 0x1 /* Pair of 16 or 32 MByte SIMMs (front or back) */ ! 113: #define SIMM_8MB_T 0x2 /* Pair of 4 or 8 MByte SIMMs (front or back) */ ! 114: #define SIMM_2MB_T 0x3 /* Pair of 1 or 2 MByte SIMMs (front or back) */ ! 115: ! 116: ! 117: /* RTC RAM */ ! 118: Uint8 rtc_ram[32]={ ! 119: 0x94,0x0f,0x40,0x00, // byte 0 - 3 ! 120: 0x00,0x00,0x00,0x00,0x00,0x00, // byte 4 - 9: hardware password, ethernet address (?) ! 121: 0x00,0x00, // byte 10, 11: simm type and size (4 simms, 4 bits per simm), see bits in ni_simm above ! 122: 0x00,0x00, // byte 12, 13: adobe (?) ! 123: 0x4b,0x00,0x00, // byte 14: POT, byte 15: oldest ..., byte 16: most recent selftest error code ! 124: 0x00, // byte 17: bit7:clock chip; 6:auto poweron; 5:enable console slot; 3,4:console slot; 2:parity mem ! 125: 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // byte 18 - 29: boot command ! 126: 0x0F,0x13 // byte 30, 31: checksum ! 127: }; ! 128: Uint8 read_rtc_ram(Uint8 position) { ! 129: return rtc_ram[position]; ! 130: } ! 131: ! 132: Uint8 rtc_ram_default[32]={ ! 133: 0x94,0x0f,0x40,0x00,0x00,0x00,0x00,0x00, ! 134: 0x00,0x00,0x00,0x00,0x00,0x00,0x4b,0x00, ! 135: 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ! 136: 0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x13 ! 137: }; ! 138: ! 139: /* ! 140: Uint8 rtc_ram[32]={ // values from nextcomputers.org forums ! 141: 0x94,0x0f,0x40,0x03,0x00,0x00,0x00,0x00, ! 142: 0x00,0x00,0xfb,0x6d,0x00,0x00,0x4b,0x00, ! 143: 0x41,0x00,0x20,0x00,0x00,0x00,0x00,0x00, ! 144: 0x00,0x00,0x00,0x00,0x00,0x00,0x84,0x7e ! 145: }; ! 146: */ ! 147: ! 148: /* ! 149: old value (boot to network diagnostics) ! 150: Uint8 rtc_ram[32]={ ! 151: 0x94,0x0f,0x40,0x00,0x00,0x00,0x00,0x00, ! 152: 0x00,0x00,0xfb,0x6d,0x00,0x00,0x7B,0x00, ! 153: 0x00,0x00,0x65,0x6e,0x00,0x00,0x00,0x00, ! 154: 0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x13 ! 155: }; ! 156: */ ! 157: ! 158: void nvram_init(void) { ! 159: /* Reset RTC RAM to default values */ ! 160: memcpy(rtc_ram, rtc_ram_default, sizeof(rtc_ram_default)); ! 161: ! 162: /* Build boot command */ ! 163: switch (ConfigureParams.Boot.nBootDevice) { ! 164: case BOOT_ROM: ! 165: rtc_ram[18] = 0x00; ! 166: rtc_ram[19] = 0x00; ! 167: break; ! 168: case BOOT_SCSI: ! 169: rtc_ram[18] = 's'; ! 170: rtc_ram[19] = 'd'; ! 171: break; ! 172: case BOOT_ETHERNET: ! 173: rtc_ram[18] = 'e'; ! 174: rtc_ram[19] = 'n'; ! 175: break; ! 176: case BOOT_MO: ! 177: rtc_ram[18] = 'o'; ! 178: rtc_ram[19] = 'd'; ! 179: break; ! 180: case BOOT_FLOPPY: ! 181: rtc_ram[18] = 'f'; ! 182: rtc_ram[19] = 'd'; ! 183: break; ! 184: ! 185: default: break; ! 186: } ! 187: ! 188: /* Copy ethernet address from ROM to RTC RAM */ ! 189: int i; ! 190: for (i = 0; i<6; i++) { ! 191: rtc_ram[i+4]=NEXTRom[i+8]; ! 192: } ! 193: ! 194: /* Build SIMM bytes (for now only valid on monochrome systems) */ ! 195: Uint16 SIMMconfig = 0x0000; ! 196: Uint8 simm[4]; ! 197: Uint8 parity = 0xF0; ! 198: if (ConfigureParams.System.bTurbo) { ! 199: for (i = 0; i<4; i++) { ! 200: switch (MemBank_Size[i]>>20) { ! 201: case 0: simm[i] = SIMM_EMPTY; parity &= ~(0x10<<i); break; ! 202: case 2: simm[i] = SIMM_2MB_T; break; ! 203: case 8: simm[i] = SIMM_8MB_T; break; ! 204: case 32: simm[i] = SIMM_32MB_T; break; ! 205: default: simm[i] = SIMM_EMPTY; break; ! 206: } ! 207: } ! 208: ! 209: } else if (ConfigureParams.System.bColor) { ! 210: for (i = 0; i<4; i++) { ! 211: switch (MemBank_Size[i]>>20) { ! 212: case 0: simm[i] = SIMM_EMPTY; parity &= ~(0x10<<i); break; ! 213: case 2: simm[i] = SIMM_2MB_C; break; ! 214: case 8: simm[i] = SIMM_8MB_C; break; ! 215: default: simm[i] = SIMM_EMPTY; break; ! 216: } ! 217: } ! 218: ! 219: } else { ! 220: for (i = 0; i<4; i++) { ! 221: switch (MemBank_Size[i]>>20) { ! 222: case 0: simm[i] = SIMM_EMPTY; parity &= ~(0x10<<i); break; ! 223: case 1: simm[i] = SIMM_1MB | SIMM_PAGE_MODE; break; ! 224: case 4: simm[i] = SIMM_4MB | SIMM_PAGE_MODE; break; ! 225: case 16: simm[i] = SIMM_16MB | SIMM_PAGE_MODE; break; ! 226: default: simm[i] = SIMM_EMPTY | SIMM_PAGE_MODE; break; ! 227: } ! 228: } ! 229: } ! 230: ! 231: SIMMconfig = ((parity&0xF0)<<8) | (simm[3]<<9) | (simm[2]<<6) | (simm[1]<<3) | simm[0]; ! 232: rtc_ram[10] = (SIMMconfig>>8)&0xFF; ! 233: rtc_ram[11] = SIMMconfig&0xFF; ! 234: ! 235: /* Build POT byte[0] */ ! 236: rtc_ram[14] = 0x00; ! 237: if (ConfigureParams.Boot.bEnableDRAMTest) ! 238: rtc_ram[14] |= TEST_DRAM_POT; ! 239: if (ConfigureParams.Boot.bEnablePot) ! 240: rtc_ram[14] |= POT_ON; ! 241: if (ConfigureParams.Boot.bEnableSoundTest) ! 242: rtc_ram[14] |= TEST_MONITOR_POT; ! 243: if (ConfigureParams.Boot.bEnableSCSITest) ! 244: rtc_ram[14] |= EXTENDED_POT; ! 245: if (ConfigureParams.Boot.bLoopPot) ! 246: rtc_ram[14] |= LOOP_POT; ! 247: if (ConfigureParams.Boot.bVerbose) ! 248: rtc_ram[14] |= VERBOSE_POT; ! 249: if (ConfigureParams.Boot.bExtendedPot) ! 250: rtc_ram[14] |= BOOT_POT; ! 251: ! 252: /* Set clock chip bit */ ! 253: switch (ConfigureParams.System.nRTC) { ! 254: case MCS1850: rtc_ram[17] |= NEW_CLOCK_CHIP; break; ! 255: case MC68HC68T1: rtc_ram[17] &= ~NEW_CLOCK_CHIP; break; ! 256: default: break; ! 257: } ! 258: ! 259: /* Re-calculate checksum */ ! 260: rtc_checksum(1); ! 261: } ! 262: ! 263: void rtc_checksum(int force) { ! 264: int sum,i; ! 265: sum=0; ! 266: for (i=0;i<30;i+=2) { ! 267: sum+=(rtc_ram[i]<<8)|(rtc_ram[i+1]); ! 268: if (sum>=0x10000) { ! 269: sum-=0x10000; ! 270: sum+=1; ! 271: } ! 272: } ! 273: ! 274: sum=0xFFFF-sum; ! 275: ! 276: if (force) { ! 277: rtc_ram[30]=(sum&0xFF00)>>8; ! 278: rtc_ram[31]=(sum&0xFF); ! 279: Log_Printf(LOG_WARN,"Forcing RTC checksum to %x %x",rtc_ram[30],rtc_ram[31]); ! 280: } else { ! 281: Log_Printf(LOG_WARN,"Check RTC checksum to %x %x %x %x", ! 282: rtc_ram[30],(sum&0xFF00)>>8, ! 283: rtc_ram[31],(sum&0xFF)); ! 284: } ! 285: } ! 286: ! 287: static char rtc_ram_info[1024]; ! 288: char * get_rtc_ram_info(void) { ! 289: char buf[256]; ! 290: int sum; ! 291: int i; ! 292: int ni_vol_l,ni_vol_r,ni_brightness; ! 293: int ni_hw_pwd,ni_spkren,ni_lowpass; ! 294: sprintf(buf,"Rtc info:\n"); ! 295: strcpy(rtc_ram_info,buf); ! 296: ! 297: // struct nvram_info { ! 298: // #define NI_RESET 9 ! 299: // u_int ni_reset : 4, ! 300: ! 301: sprintf(buf,"RTC RESET:x%1X ",rtc_ram[0]>>4); ! 302: strcat(rtc_ram_info,buf); ! 303: ! 304: // #define SCC_ALT_CONS 0x08000000 ! 305: // ni_alt_cons : 1, ! 306: if (rtc_ram[0]&0x08) strcat(rtc_ram_info,"ALT_CONS "); ! 307: // #define ALLOW_EJECT 0x04000000 ! 308: // ni_allow_eject : 1, ! 309: if (rtc_ram[0]&0x04) strcat(rtc_ram_info,"ALLOW_EJECT "); ! 310: // ni_vol_r : 6, ! 311: // ni_brightness : 6, ! 312: // #define HW_PWD 0x6 ! 313: // ni_hw_pwd : 4, ! 314: // ni_vol_l : 6, ! 315: // ni_spkren : 1, ! 316: // ni_lowpass : 1, ! 317: // #define BOOT_ANY 0x00000002 ! 318: // ni_boot_any : 1, ! 319: // #define ANY_CMD 0x00000001 ! 320: // ni_any_cmd : 1; ! 321: ! 322: ni_vol_r=(((rtc_ram[0]&0x3)<<4)|((rtc_ram[1]&0xF0)>>4)); ! 323: ni_brightness=(((rtc_ram[1]&0xF)<<2)|((rtc_ram[2]&0xC0)>>6)); ! 324: ni_vol_l=((rtc_ram[2]&0x3F)<<2); ! 325: ni_hw_pwd=(rtc_ram[3]&0xF0)>>4; ! 326: sprintf(buf,"VOL_R:x%1X BRIGHT:x%1X HWPWD:x%1X VOL_L:x%1X",ni_vol_r,ni_brightness,ni_vol_l,ni_hw_pwd); ! 327: strcat(rtc_ram_info,buf); ! 328: ! 329: if (rtc_ram[3]&0x08) strcat(rtc_ram_info,"SPK_ENABLE "); ! 330: if (rtc_ram[3]&0x04) strcat(rtc_ram_info,"LOW_PASS "); ! 331: if (rtc_ram[3]&0x02) strcat(rtc_ram_info,"BOOT_ANY "); ! 332: if (rtc_ram[3]&0x01) strcat(rtc_ram_info,"ANY_CMD "); ! 333: ! 334: ! 335: ! 336: // #define NVRAM_HW_PASSWD 6 ! 337: // u_char ni_ep[NVRAM_HW_PASSWD]; ! 338: ! 339: sprintf(buf,"NVRAM_HW_PASSWD:%2X %2X %2X %2X %2X %2X ",rtc_ram[4],rtc_ram[5],rtc_ram[6],rtc_ram[7],rtc_ram[8],rtc_ram[9]); ! 340: strcat(rtc_ram_info,buf); ! 341: // #define ni_enetaddr ni_ep ! 342: // #define ni_hw_passwd ni_ep ! 343: // u_short ni_simm; /* 4 SIMMs, 4 bits per SIMM */ ! 344: sprintf(buf,"SIMM:%1X %1X %1X %1X ",rtc_ram[10]>>4,rtc_ram[10]&0x0F,rtc_ram[11]>>4,rtc_ram[11]&0x0F); ! 345: strcat(rtc_ram_info,buf); ! 346: ! 347: ! 348: // char ni_adobe[2]; ! 349: sprintf(buf,"ADOBE:%2X %2X ",rtc_ram[12],rtc_ram[13]); ! 350: strcat(rtc_ram_info,buf); ! 351: ! 352: // u_char ni_pot[3]; ! 353: sprintf(buf,"POT:%2X %2X %2X ",rtc_ram[14],rtc_ram[15],rtc_ram[16]); ! 354: strcat(rtc_ram_info,buf); ! 355: ! 356: // u_char ni_new_clock_chip : 1, ! 357: // ni_auto_poweron : 1, ! 358: // ni_use_console_slot : 1, /* Console slot was set by user. */ ! 359: // ni_console_slot : 2, /* Preferred console dev slot>>1 */ ! 360: // ni_use_parity_mem : 1, /* Use parity RAM if available? */ ! 361: // : 2; ! 362: if (rtc_ram[17]&0x80) strcat(rtc_ram_info,"NEW_CLOCK_CHIP "); ! 363: if (rtc_ram[17]&0x40) strcat(rtc_ram_info,"AUTO_POWERON "); ! 364: if (rtc_ram[17]&0x20) strcat(rtc_ram_info,"CONSOLE_SLOT "); ! 365: ! 366: sprintf(buf,"console_slot:%X ",(rtc_ram[17]&0x18)>>3); ! 367: strcat(rtc_ram_info,buf); ! 368: ! 369: if (rtc_ram[17]&0x04) strcat(rtc_ram_info,"USE_PARITY "); ! 370: ! 371: ! 372: strcat(rtc_ram_info,"boot_command:"); ! 373: for (i=0;i<12;i++) { ! 374: if ((rtc_ram[18+i]>=0x20) && (rtc_ram[18+i]<=0x7F)) { ! 375: sprintf(buf,"%c",rtc_ram[18+i]); ! 376: strcat(rtc_ram_info,buf); ! 377: } ! 378: } ! 379: ! 380: strcat(rtc_ram_info," "); ! 381: sprintf(buf,"CKSUM:%2X %2X ",rtc_ram[30],rtc_ram[31]); ! 382: strcat(rtc_ram_info,buf); ! 383: ! 384: ! 385: sum=0; ! 386: for (i=0;i<30;i+=2) { ! 387: sum+=(rtc_ram[i]<<8)|(rtc_ram[i+1]); ! 388: if (sum>=0x10000) { sum-=0x10000; ! 389: sum+=1; ! 390: } ! 391: } ! 392: ! 393: sum=0xFFFF-sum; ! 394: ! 395: sprintf(buf,"CALC_CKSUM:%04X ",sum&0xFFFF); ! 396: strcat(rtc_ram_info,buf); ! 397: ! 398: // #define NVRAM_BOOTCMD 12 ! 399: // char ni_bootcmd[NVRAM_BOOTCMD]; ! 400: // u_short ni_cksum; ! 401: // }; ! 402: ! 403: return rtc_ram_info; ! 404: } ! 405: ! 406: ! 407: void SID_Read(void) { ! 408: Log_Printf(LOG_WARN,"SID read at $%08x PC=$%08x\n", IoAccessCurrentAddress,m68k_getpc()); ! 409: IoMem[IoAccessCurrentAddress & 0x1FFFF]=0x00; // slot ID 0 ! 410: } ! 411: ! 412: /* System Control Register 1 ! 413: * ! 414: * These values are valid for all non-Turbo systems: ! 415: * -------- -------- -------- ------xx bits 0:1 --> cpu speed ! 416: * -------- -------- -------- ----xx-- bits 2:3 --> reserved ! 417: * -------- -------- -------- --xx---- bits 4:5 --> main memory speed ! 418: * -------- -------- -------- xx------ bits 6:7 --> video memory speed ! 419: * -------- -------- ----xxxx -------- bits 8:11 --> board revision ! 420: * -------- -------- xxxx---- -------- bits 12:15 --> cpu type ! 421: * -------- xxxxxxxx -------- -------- bits 16:23 --> dma revision ! 422: * ----xxxx -------- -------- -------- bits 24:27 --> reserved ! 423: * xxxx---- -------- -------- -------- bits 28:31 --> slot id ! 424: * ! 425: * cpu speed: 0 = 40MHz, 1 = 20MHz, 2 = 25MHz, 3 = 33MHz ! 426: * main mem speed: 0 = 120ns, 1 = 100ns, 2 = 80ns, 3 = 60ns ! 427: * video mem speed: 0 = 120ns, 1 = 100ns, 2 = 80ns, 3 = 60ns ! 428: * board revision: for 030 Cube: ! 429: * 0 = DCD input inverted ! 430: * 1 = DCD polarity fixed ! 431: * 2 = must disable DSP mem before reset ! 432: * cpu type: 0 = NeXT Computer (68030) ! 433: * 1 = NeXTstation monochrome ! 434: * 2 = NeXTcube ! 435: * 3 = NeXTstation color ! 436: * 4 = all Turbo systems ! 437: * dma revision: 1 on all systems ? ! 438: * slot id: f on Turbo systems (cube too?), 0 on other systems ! 439: * ! 440: * ! 441: * These bits are always 0 on all Turbo systems: ! 442: * ----xxxx xxxxxxxx ----xxxx xxxxxxxx ! 443: */ ! 444: ! 445: /* for Slab 040: ! 446: * 0000 0000 0000 0001 0001 0000 0101 0010 ! 447: * 00 01 10 52 ! 448: * ! 449: * for Cube 030: ! 450: * 0000 0000 0000 0001 0000 0001 0101 0010 ! 451: * 00 01 01 52 ! 452: */ ! 453: #define SCR1_NEXT_COMPUTER 0x00010152 ! 454: #define SCR1_SLAB_MONO 0x00011052 ! 455: #define SCR1_SLAB_COLOR 0x00013052 ! 456: #define SCR1_CUBE 0x00012052 ! 457: #define SCR1_TURBO 0xF0004000 ! 458: ! 459: #define SCR1_CONST_MASK 0xFFFFFF00 ! 460: ! 461: void SCR_Reset(void) { ! 462: scr2_0=0x00; ! 463: scr2_1=0x00; ! 464: scr2_2=0x80; ! 465: scr2_3=0x00; ! 466: ! 467: intStat=0x00000000; ! 468: intMask=0x00000000; ! 469: ! 470: if (ConfigureParams.System.bTurbo) { ! 471: scr1 = SCR1_TURBO; ! 472: TurboSCR1_Reset(); ! 473: return; ! 474: } else { ! 475: switch (ConfigureParams.System.nMachineType) { ! 476: case NEXT_CUBE030: ! 477: scr1 = SCR1_NEXT_COMPUTER & SCR1_CONST_MASK; ! 478: break; ! 479: case NEXT_CUBE040: ! 480: scr1 = SCR1_CUBE & SCR1_CONST_MASK; ! 481: break; ! 482: case NEXT_STATION: ! 483: if (ConfigureParams.System.bColor) ! 484: scr1 = SCR1_SLAB_COLOR & SCR1_CONST_MASK; ! 485: else ! 486: scr1 = SCR1_SLAB_MONO & SCR1_CONST_MASK; ! 487: break; ! 488: default: ! 489: break; ! 490: } ! 491: } ! 492: ! 493: Uint8 cpu_speed = ((ConfigureParams.System.nCpuFreq/8)-1)%4; ! 494: Uint8 memory_speed; ! 495: switch (ConfigureParams.Memory.nMemorySpeed) { ! 496: case MEMORY_120NS: memory_speed = 0x00; break; ! 497: case MEMORY_100NS: memory_speed = 0x50; break; ! 498: case MEMORY_80NS: memory_speed = 0xA0; break; ! 499: case MEMORY_60NS: memory_speed = 0xF0; break; ! 500: default: Log_Printf(LOG_WARN, "SCR1 error: unknown memory speed\n"); break; ! 501: } ! 502: scr1 |= ((memory_speed&0xF0)|(cpu_speed&0x03)); ! 503: } ! 504: ! 505: void SCR1_Read0(void) ! 506: { ! 507: Log_Printf(LOG_WARN,"SCR1 read at $%08x PC=$%08x\n", IoAccessCurrentAddress,m68k_getpc()); ! 508: IoMem[IoAccessCurrentAddress&IO_SEG_MASK] = (scr1&0xFF000000)>>24; ! 509: } ! 510: void SCR1_Read1(void) ! 511: { ! 512: Log_Printf(LOG_WARN,"SCR1 read at $%08x PC=$%08x\n", IoAccessCurrentAddress,m68k_getpc()); ! 513: IoMem[IoAccessCurrentAddress&IO_SEG_MASK] = (scr1&0x00FF0000)>>16; ! 514: } ! 515: void SCR1_Read2(void) ! 516: { ! 517: Log_Printf(LOG_WARN,"SCR1 read at $%08x PC=$%08x\n", IoAccessCurrentAddress,m68k_getpc()); ! 518: IoMem[IoAccessCurrentAddress&IO_SEG_MASK] = (scr1&0x0000FF00)>>8; ! 519: } ! 520: void SCR1_Read3(void) ! 521: { ! 522: Log_Printf(LOG_WARN,"SCR1 read at $%08x PC=$%08x\n", IoAccessCurrentAddress,m68k_getpc()); ! 523: IoMem[IoAccessCurrentAddress&IO_SEG_MASK] = scr1&0x000000FF; ! 524: } ! 525: ! 526: ! 527: /* Additional System Control Register for Turbo systems: ! 528: * -------- -------- -------- -----?xx bits 0:2 --> cpu speed ! 529: * -------- -------- -------- --xx---- bits 4:5 --> main memory speed ! 530: * -------- -------- -------- xx------ bits 6:7 --> video memory speed ! 531: * -------- -------- xxxx---- -------- bits 8:11 --> cpu type ! 532: * xxxxxxxx xxxxxxxx ----xxxx ----?--- all other bits: 1 ! 533: * ! 534: * cpu speed: 7 = 33MHz? ! 535: * main mem speed: 0 = 120ns?, 1 = 100ns?, 2 = 70ns, 3 = 60ns ! 536: * video mem speed: 3 on all Turbo systems (60ns)? ! 537: * cpu type: 4 = NeXTstation turbo monochrome ! 538: * 5 = NeXTstation turbo color ! 539: */ ! 540: ! 541: #define TURBOSCR_FMASK 0xFFFF0F08 ! 542: ! 543: void TurboSCR1_Reset(void) { ! 544: Uint8 memory_speed; ! 545: Uint8 cpu_speed = 0x07; // 33 MHz ! 546: switch (ConfigureParams.Memory.nMemorySpeed) { ! 547: case MEMORY_120NS: memory_speed = 0xC0; break; ! 548: case MEMORY_100NS: memory_speed = 0xD0; break; ! 549: case MEMORY_80NS: memory_speed = 0xE0; break; ! 550: case MEMORY_60NS: memory_speed = 0xF0; break; ! 551: default: Log_Printf(LOG_WARN, "Turbo SCR1 error: unknown memory speed\n"); break; ! 552: } ! 553: turboscr1 = ((memory_speed&0xF0)|(cpu_speed&0x07)); ! 554: if (ConfigureParams.System.bColor) { ! 555: turboscr1 |= 0x5000; ! 556: } else { ! 557: turboscr1 |= 0x4000; ! 558: } ! 559: turboscr1 |= TURBOSCR_FMASK; ! 560: } ! 561: ! 562: void TurboSCR1_Read0(void) { ! 563: Log_Printf(LOG_WARN,"Turbo SCR1 read at $%08x PC=$%08x\n", IoAccessCurrentAddress,m68k_getpc()); ! 564: IoMem_WriteWord(IoAccessCurrentAddress&0x1FFFF, (turboscr1&0xFFFF0000)>>16); ! 565: } ! 566: void TurboSCR1_Read2(void) { ! 567: Log_Printf(LOG_WARN,"Turbo SCR1 read at $%08x PC=$%08x\n", IoAccessCurrentAddress,m68k_getpc()); ! 568: IoMem_WriteWord(IoAccessCurrentAddress&0x1FFFF, turboscr1&0x0000FFFF); ! 569: } ! 570: ! 571: ! 572: ! 573: /* System Control Register 2 ! 574: ! 575: s_dsp_reset : 1, ! 576: s_dsp_block_end : 1, ! 577: s_dsp_unpacked : 1, ! 578: s_dsp_mode_B : 1, ! 579: s_dsp_mode_A : 1, ! 580: s_remote_int : 1, ! 581: s_local_int : 2, ! 582: s_dram_256K : 4, ! 583: s_dram_1M : 4, ! 584: s_timer_on_ipl7 : 1, ! 585: s_rom_wait_states : 3, ! 586: s_rom_1M : 1, ! 587: s_rtdata : 1, ! 588: s_rtclk : 1, ! 589: s_rtce : 1, ! 590: s_rom_overlay : 1, ! 591: s_dsp_int_en : 1, ! 592: s_dsp_mem_en : 1, ! 593: s_reserved : 4, ! 594: s_led : 1; ! 595: ! 596: */ ! 597: ! 598: #define SCR2_SOFTINT2 0x02 ! 599: #define SCR2_SOFTINT1 0x01 ! 600: ! 601: #define SCR2_TIMERIPL7 0x80 ! 602: #define SCR2_RTDATA 0x04 ! 603: #define SCR2_RTCLK 0x02 ! 604: #define SCR2_RTCE 0x01 ! 605: ! 606: #define SCR2_LED 0x01 ! 607: #define SCR2_ROM 0x80 ! 608: ! 609: ! 610: void SCR2_Write0(void) ! 611: { ! 612: Uint8 old_scr2_0=scr2_0; ! 613: // Log_Printf(LOG_WARN,"SCR2 write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress,IoMem[IoAccessCurrentAddress & IO_SEG_MASK],m68k_getpc()); ! 614: scr2_0=IoMem[IoAccessCurrentAddress & 0x1FFFF]; ! 615: ! 616: if ((old_scr2_0&SCR2_SOFTINT1)!=(scr2_0&SCR2_SOFTINT1)) { ! 617: Log_Printf(LOG_WARN,"SCR2 SCR2_SOFTINT1 change at $%08x val=%x PC=$%08x\n", ! 618: IoAccessCurrentAddress,scr2_0&SCR2_SOFTINT1,m68k_getpc()); ! 619: if (scr2_0&SCR2_SOFTINT1) ! 620: set_interrupt(INT_SOFT1,SET_INT); ! 621: else ! 622: set_interrupt(INT_SOFT1,RELEASE_INT); ! 623: } ! 624: ! 625: if ((old_scr2_0&SCR2_SOFTINT2)!=(scr2_0&SCR2_SOFTINT2)) { ! 626: Log_Printf(LOG_WARN,"SCR2 SCR2_SOFTINT2 change at $%08x val=%x PC=$%08x\n", ! 627: IoAccessCurrentAddress,scr2_0&SCR2_SOFTINT2,m68k_getpc()); ! 628: if (scr2_0&SCR2_SOFTINT2) ! 629: set_interrupt(INT_SOFT2,SET_INT); ! 630: else ! 631: set_interrupt(INT_SOFT2,RELEASE_INT); ! 632: } ! 633: } ! 634: ! 635: void SCR2_Read0(void) ! 636: { ! 637: // Log_Printf(LOG_WARN,"SCR2 read at $%08x PC=$%08x\n", IoAccessCurrentAddress,m68k_getpc()); ! 638: IoMem[IoAccessCurrentAddress & 0x1FFFF]=scr2_0; ! 639: } ! 640: ! 641: void SCR2_Write1(void) ! 642: { ! 643: // Log_Printf(LOG_WARN,"SCR2 write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress,IoMem[IoAccessCurrentAddress & IO_SEG_MASK],m68k_getpc()); ! 644: scr2_1=IoMem[IoAccessCurrentAddress & 0x1FFFF]; ! 645: } ! 646: ! 647: void SCR2_Read1(void) ! 648: { ! 649: // Log_Printf(LOG_WARN,"SCR2 read at $%08x PC=$%08x\n", IoAccessCurrentAddress,m68k_getpc()); ! 650: IoMem[IoAccessCurrentAddress & 0x1FFFF]=scr2_1; ! 651: } ! 652: ! 653: void SCR2_Write2(void) ! 654: { ! 655: static int phase=0; ! 656: static bool burst=false; ! 657: static Uint8 rtc_command=0; ! 658: static Uint8 rtc_value=0; ! 659: static Uint8 rtc_return=0; ! 660: static Uint8 rtc_status=0x00; ! 661: static Uint8 rtc_ccr=0x00; ! 662: static Uint8 rtc_icr=0x00; ! 663: ! 664: static int day_in_week=0x02; ! 665: static int day=0x31; ! 666: static int month=0x12; ! 667: static int year=0x98; ! 668: static int century=0x19; ! 669: ! 670: ! 671: Uint8 old_scr2_2=scr2_2; ! 672: ! 673: scr2_2=IoMem[IoAccessCurrentAddress & 0x1FFFF]; ! 674: ! 675: if ((old_scr2_2&SCR2_TIMERIPL7)!=(scr2_2&SCR2_TIMERIPL7)) { ! 676: Log_Printf(LOG_WARN,"SCR2 TIMER IPL7 change at $%08x val=%x PC=$%08x\n", ! 677: IoAccessCurrentAddress,scr2_2&SCR2_TIMERIPL7,m68k_getpc()); ! 678: } ! 679: ! 680: // treat only if CE is set to 1 ! 681: if (scr2_2&SCR2_RTCE) { ! 682: if (phase==-1) {phase=0;} ! 683: ! 684: // if we are in going down clock... do something ! 685: if (((old_scr2_2&SCR2_RTCLK)!=(scr2_2&SCR2_RTCLK)) && ((scr2_2&SCR2_RTCLK)==0) ) { ! 686: if (phase<8) ! 687: rtc_command=(rtc_command<<1)|((scr2_2&SCR2_RTDATA)?1:0); ! 688: ! 689: // now reading or writing register (one bit at a time) ! 690: if ((phase>=8) && (phase<16)) { ! 691: rtc_value=(rtc_value<<1)|((scr2_2&SCR2_RTDATA)?1:0); ! 692: ! 693: // if we read RAM register, output RT_DATA bit ! 694: if (rtc_command<=0x1F) { ! 695: scr2_2=scr2_2&(~SCR2_RTDATA); ! 696: if (rtc_ram[rtc_command]&(0x80>>(phase-8))) ! 697: scr2_2|=SCR2_RTDATA; ! 698: rtc_return=(rtc_return<<1)|((scr2_2&SCR2_RTDATA)?1:0); ! 699: } ! 700: // read the status 0x30 ! 701: if (rtc_command==0x30) { ! 702: scr2_2=scr2_2&(~SCR2_RTDATA); ! 703: // for now status = 0x98 (new rtc + FTU) ! 704: if (rtc_status&(0x80>>(phase-8))) ! 705: scr2_2|=SCR2_RTDATA; ! 706: rtc_return=(rtc_return<<1)|((scr2_2&SCR2_RTDATA)?1:0); ! 707: } ! 708: // read the status 0x31 ! 709: if (rtc_command==0x31) { ! 710: scr2_2=scr2_2&(~SCR2_RTDATA); ! 711: if (rtc_ccr&(0x80>>(phase-8))) ! 712: scr2_2|=SCR2_RTDATA; ! 713: rtc_return=(rtc_return<<1)|((scr2_2&SCR2_RTDATA)?1:0); ! 714: } ! 715: // read the status 0x32 ! 716: if (rtc_command==0x32) { ! 717: scr2_2=scr2_2&(~SCR2_RTDATA); ! 718: if (rtc_icr&(0x80>>(phase-8))) ! 719: scr2_2|=SCR2_RTDATA; ! 720: rtc_return=(rtc_return<<1)|((scr2_2&SCR2_RTDATA)?1:0); ! 721: } ! 722: if ((rtc_command>=0x20) && (rtc_command<=0x2F)) { ! 723: unsigned char v; ! 724: static time_t t; ! 725: static struct tm * ts; ! 726: ! 727: scr2_2=scr2_2&(~SCR2_RTDATA); ! 728: // get time at once to avoid problems (in burst mode only). ! 729: if (!burst) { ! 730: t=time(NULL); ! 731: ts=localtime(&t); ! 732: burst=true; ! 733: } ! 734: v=0; ! 735: switch (rtc_command) { ! 736: case 0x20 : // seconds ! 737: v=(((ts->tm_sec)/10)<<4)|(ts->tm_sec%10); ! 738: break; ! 739: case 0x21 : //min ! 740: v=(((ts->tm_min)/10)<<4)|(ts->tm_min%10); ! 741: break; ! 742: case 0x22 : // hour ! 743: v=(((ts->tm_hour)/10)<<4)|(ts->tm_hour%10); ! 744: break; ! 745: case 0x23 : ! 746: v=day_in_week; ! 747: break; ! 748: case 0x24 : ! 749: v=day; ! 750: break; ! 751: case 0x25 : ! 752: v=month; ! 753: break; ! 754: case 0x26 : ! 755: v=year; ! 756: break; ! 757: case 0x27 : ! 758: v=century; ! 759: break; ! 760: } ! 761: if (v&(0x80>>(phase-8))) ! 762: scr2_2|=SCR2_RTDATA; ! 763: rtc_return=(rtc_return<<1)|((scr2_2&SCR2_RTDATA)?1:0); ! 764: } ! 765: ! 766: } // of read/write phase ! 767: ! 768: phase++; ! 769: if (phase==16) { ! 770: Log_Printf(LOG_WARN,"SCR2 RTC command complete %x %x %x at PC=$%08x\n", ! 771: rtc_command,rtc_value,rtc_return,m68k_getpc()); ! 772: if ((rtc_command>=0x80) && (rtc_command<=0x9F)) ! 773: rtc_ram[rtc_command-0x80]=rtc_value; ! 774: ! 775: // write to x31 register ! 776: if (rtc_command==0xB1) { ! 777: rtc_ccr=rtc_value; ! 778: ! 779: ! 780: // clear FTU ! 781: if (rtc_value & 0x04) { ! 782: rtc_status=rtc_status&(~0x18); ! 783: intStat=intStat&(~0x04); ! 784: } ! 785: ! 786: ! 787: } ! 788: // write to x32 register ! 789: if (rtc_command==0xB2) { ! 790: rtc_icr=rtc_value; ! 791: } ! 792: ! 793: if (rtc_command==0xA3) { ! 794: day_in_week=rtc_value; ! 795: } ! 796: if (rtc_command==0xA4) { ! 797: day=rtc_value; ! 798: } ! 799: if (rtc_command==0xA5) { ! 800: month=rtc_value; ! 801: } ! 802: if (rtc_command==0xA6) { ! 803: year=rtc_value; ! 804: } ! 805: if (rtc_command==0xA7) { ! 806: century=rtc_value; ! 807: } ! 808: ! 809: // burst mode ! 810: phase=8; ! 811: rtc_command++; ! 812: } // of phase==16 ! 813: } // of going down clock ! 814: } // of scr2_2&SCR2_RTCE ! 815: else { ! 816: // else end or abort ! 817: phase=-1; ! 818: rtc_command=0; ! 819: rtc_value=0; ! 820: burst=false; ! 821: } ! 822: ! 823: } ! 824: ! 825: void SCR2_Read2(void) ! 826: { ! 827: // Log_Printf(LOG_WARN,"SCR2 read at $%08x PC=$%08x\n", IoAccessCurrentAddress,m68k_getpc()); ! 828: // IoMem[IoAccessCurrentAddress & 0x1FFFF]=scr2_2 & (SCR2_RTDATA|SCR2_RTCLK|SCR2_RTCE)); // + data ! 829: IoMem[IoAccessCurrentAddress & 0x1FFFF]=scr2_2; ! 830: } ! 831: ! 832: int SCR_ROM_overlay=0; ! 833: ! 834: void SCR2_Write3(void) ! 835: { ! 836: Uint8 old_scr2_3=scr2_3; ! 837: // Log_Printf(LOG_WARN,"SCR2 write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress,IoMem[IoAccessCurrentAddress & IO_SEG_MASK],m68k_getpc()); ! 838: scr2_3=IoMem[IoAccessCurrentAddress & 0x1FFFF]; ! 839: if ((old_scr2_3&SCR2_ROM)!=(scr2_3&SCR2_ROM)) { ! 840: Log_Printf(LOG_WARN,"SCR2 ROM change at $%08x val=%x PC=$%08x\n", ! 841: IoAccessCurrentAddress,scr2_3&SCR2_ROM,m68k_getpc()); ! 842: SCR_ROM_overlay=scr2_3&SCR2_ROM; ! 843: } ! 844: if ((old_scr2_3&SCR2_LED)!=(scr2_3&SCR2_LED)) { ! 845: Log_Printf(LOG_WARN,"SCR2 LED change at $%08x val=%x PC=$%08x\n", ! 846: IoAccessCurrentAddress,scr2_3&SCR2_LED,m68k_getpc()); ! 847: Statusbar_SetSCR2Led(scr2_3&SCR2_LED); ! 848: } ! 849: } ! 850: ! 851: ! 852: void SCR2_Read3(void) ! 853: { ! 854: // Log_Printf(LOG_WARN,"SCR2 read at $%08x PC=$%08x\n", IoAccessCurrentAddress,m68k_getpc()); ! 855: IoMem[IoAccessCurrentAddress & 0x1FFFF]=scr2_3; ! 856: } ! 857: ! 858: ! 859: ! 860: /* Interrupt Status Register */ ! 861: ! 862: void IntRegStatRead(void) { ! 863: IoMem_WriteLong(IoAccessCurrentAddress & IO_SEG_MASK, intStat); ! 864: } ! 865: ! 866: void IntRegStatWrite(void) { ! 867: intStat = IoMem_ReadLong(IoAccessCurrentAddress & IO_SEG_MASK); ! 868: } ! 869: ! 870: void set_interrupt(Uint32 interrupt_val, Uint8 int_set_release) { ! 871: ! 872: Uint8 interrupt_level; ! 873: ! 874: if(int_set_release == SET_INT) { ! 875: intStat = intStat | interrupt_val; ! 876: } else { ! 877: intStat = intStat & ~interrupt_val; ! 878: } ! 879: ! 880: switch (interrupt_val) { ! 881: case INT_SOFT1: interrupt_level = 1; ! 882: break; ! 883: case INT_SOFT2: interrupt_level = 2; ! 884: break; ! 885: case INT_POWER: ! 886: case INT_KEYMOUSE: ! 887: case INT_MONITOR: ! 888: case INT_VIDEO: ! 889: case INT_DSP_L3: ! 890: case INT_PHONE: ! 891: case INT_SOUND_OVRUN: ! 892: case INT_EN_RX: ! 893: case INT_EN_TX: ! 894: case INT_PRINTER: ! 895: case INT_SCSI: ! 896: case INT_DISK: interrupt_level = 3; ! 897: break; ! 898: case INT_DSP_L4: interrupt_level = 4; ! 899: break; ! 900: case INT_BUS: ! 901: case INT_REMOTE: ! 902: case INT_SCC: interrupt_level = 5; ! 903: break; ! 904: case INT_R2M_DMA: ! 905: case INT_M2R_DMA: ! 906: case INT_DSP_DMA: ! 907: case INT_SCC_DMA: ! 908: case INT_SND_IN_DMA: ! 909: case INT_SND_OUT_DMA: ! 910: case INT_PRINTER_DMA: ! 911: case INT_DISK_DMA: ! 912: case INT_SCSI_DMA: ! 913: case INT_EN_RX_DMA: ! 914: case INT_EN_TX_DMA: ! 915: interrupt_level = 6; ! 916: break; ! 917: case INT_TIMER: ! 918: if (scr2_2&SCR2_TIMERIPL7) ! 919: interrupt_level = 7; ! 920: else ! 921: interrupt_level = 6; ! 922: break; ! 923: case INT_PFAIL: ! 924: case INT_NMI: interrupt_level = 7; ! 925: break; ! 926: default: interrupt_level = 0; ! 927: break; ! 928: } ! 929: ! 930: if ((interrupt_val & intMask)==0) { ! 931: Log_Printf(LOG_WARN,"[INT] interrupt is masked %04x mask %04x %s at %d",interrupt_val,intMask,__FILE__,__LINE__); ! 932: return; ! 933: } ! 934: ! 935: if(int_set_release == SET_INT) { ! 936: Log_Printf(LOG_DEBUG,"Interrupt Level: %i", interrupt_level); ! 937: M68000_Exception(((24+interrupt_level)*4), M68000_EXC_SRC_AUTOVEC); ! 938: } else { ! 939: // M68000_Exception(((24+0)*4), M68000_EXC_SRC_AUTOVEC); // release interrupt - does this work??? ! 940: } ! 941: } ! 942: ! 943: /* Interrupt Mask Register */ ! 944: ! 945: void IntRegMaskRead(void) { ! 946: IoMem_WriteLong(IoAccessCurrentAddress & IO_SEG_MASK,intMask); ! 947: } ! 948: ! 949: void IntRegMaskWrite(void) { ! 950: intMask = IoMem_ReadLong(IoAccessCurrentAddress & IO_SEG_MASK); ! 951: Log_Printf(LOG_WARN,"Interrupt mask: %08x", intMask); ! 952: } ! 953: ! 954: /* ! 955: * Hardclock internal interrupt ! 956: * ! 957: */ ! 958: ! 959: #define HARDCLOCK_ENABLE 0x80 ! 960: #define HARDCLOCK_LATCH 0x40 ! 961: ! 962: Uint8 hardclock_csr=0; ! 963: Uint8 hardclock1=0; ! 964: Uint8 hardclock0=0; ! 965: int pseudo_counter=0; ! 966: int latch_hardclock=0; ! 967: ! 968: void Hardclock_InterruptHandler ( void ) ! 969: { ! 970: CycInt_AcknowledgeInterrupt(); ! 971: if ((hardclock_csr&HARDCLOCK_ENABLE) && (latch_hardclock>0)) { ! 972: // Log_Printf(LOG_WARN,"[INT] throwing hardclock"); ! 973: set_interrupt(INT_TIMER,SET_INT); ! 974: CycInt_AddRelativeInterrupt(latch_hardclock*33, INT_CPU_CYCLE, INTERRUPT_HARDCLOCK); ! 975: pseudo_counter=latch_hardclock; ! 976: } ! 977: } ! 978: ! 979: ! 980: void HardclockRead0(void){ ! 981: IoMem[IoAccessCurrentAddress & 0x1FFFF]=(pseudo_counter>>8); ! 982: ; ! 983: // if (pseudo_counter>0) pseudo_counter--; ! 984: ! 985: Log_Printf(LOG_WARN,"[hardclock] read at $%08x val=%02x PC=$%08x", IoAccessCurrentAddress,IoMem[IoAccessCurrentAddress & 0x1FFFF],m68k_getpc()); ! 986: } ! 987: void HardclockRead1(void){ ! 988: IoMem[IoAccessCurrentAddress & 0x1FFFF]=pseudo_counter&0xff; ! 989: if (pseudo_counter>0) pseudo_counter--; ! 990: Log_Printf(LOG_WARN,"[hardclock] read at $%08x val=%02x PC=$%08x", IoAccessCurrentAddress,IoMem[IoAccessCurrentAddress & 0x1FFFF],m68k_getpc()); ! 991: } ! 992: ! 993: void HardclockWrite0(void){ ! 994: Log_Printf(LOG_WARN,"[hardclock] write at $%08x val=%02x PC=$%08x", IoAccessCurrentAddress,IoMem[IoAccessCurrentAddress & 0x1FFFF],m68k_getpc()); ! 995: hardclock0=IoMem[IoAccessCurrentAddress & 0x1FFFF]; ! 996: } ! 997: void HardclockWrite1(void){ ! 998: Log_Printf(LOG_WARN,"[hardclock] write at $%08x val=%02x PC=$%08x",IoAccessCurrentAddress,IoMem[IoAccessCurrentAddress & 0x1FFFF],m68k_getpc()); ! 999: hardclock1=IoMem[IoAccessCurrentAddress & 0x1FFFF]; ! 1000: } ! 1001: ! 1002: void HardclockWriteCSR(void) { ! 1003: Log_Printf(LOG_WARN,"[hardclock] write at $%08x val=%02x PC=$%08x", IoAccessCurrentAddress,IoMem[IoAccessCurrentAddress & 0x1FFFF],m68k_getpc()); ! 1004: hardclock_csr=IoMem[IoAccessCurrentAddress & 0x1FFFF]; ! 1005: if ((hardclock_csr&HARDCLOCK_LATCH)) { ! 1006: latch_hardclock=(hardclock0<<8)|hardclock1; ! 1007: pseudo_counter=latch_hardclock; ! 1008: } ! 1009: if ((hardclock_csr&HARDCLOCK_ENABLE) && (latch_hardclock>0)) { ! 1010: //CycInt_AddRelativeInterrupt(latch_hardclock*33, INT_CPU_CYCLE, INTERRUPT_HARDCLOCK); ! 1011: set_interrupt(INT_TIMER, SET_INT); ! 1012: } ! 1013: } ! 1014: void HardclockReadCSR(void) { ! 1015: IoMem[IoAccessCurrentAddress & 0x1FFFF]=hardclock_csr; ! 1016: // Log_Printf(LOG_WARN,"[hardclock] read at $%08x val=%02x PC=$%08x", IoAccessCurrentAddress,IoMem[IoAccessCurrentAddress & 0x1FFFF],m68k_getpc()); ! 1017: set_interrupt(INT_TIMER,RELEASE_INT); ! 1018: } ! 1019: ! 1020:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.