|
|
1.1 ! root 1: #include "main.h" ! 2: #include "configuration.h" ! 3: #include "m68000.h" ! 4: #include "sysdeps.h" ! 5: #include "nbic.h" ! 6: ! 7: #define LOG_NEXTBUS_LEVEL LOG_NONE ! 8: ! 9: /* NeXTbus and NeXTbus Interface Chip emulation */ ! 10: ! 11: /* NBIC Registers */ ! 12: ! 13: struct { ! 14: Uint32 control; ! 15: Uint32 id; ! 16: Uint8 intstatus; ! 17: Uint8 intmask; ! 18: } nbic; ! 19: ! 20: ! 21: /* Control: 0x02020000 (rw), only non-Turbo */ ! 22: #define NBIC_CTRL_IGNSID0 0x10000000 /* Ignore slot ID bit 0 */ ! 23: #define NBIC_CTRL_STFWD 0x08000000 /* Store forward */ ! 24: #define NBIC_CTRL_RMCOL 0x04000000 /* Read modify cycle collision */ ! 25: ! 26: /* ID: 0x02020004 (w), 0xF0FFFFFx (r), only non-Turbo */ ! 27: #define NBIC_ID_VALID 0x80000000 ! 28: #define NBIC_ID_M_MASK 0x7FFF0000 /* Manufacturer ID */ ! 29: #define NBIC_ID_B_MASK 0x0000FFFF /* Board ID */ ! 30: ! 31: /* Interrupt: 0xF0FFFFE8 (r) */ ! 32: #define NBIC_INT_STATUS 0x80 ! 33: ! 34: /* Interrupt mask: 0xF0FFFFEC (rw) */ ! 35: #define NBIC_INT_MASK 0x80 ! 36: ! 37: ! 38: /* Register access functions */ ! 39: static Uint8 nbic_control_read0(Uint32 addr) { ! 40: Log_Printf(LOG_WARN, "[NBIC] Control (byte 0) read at %08X",addr); ! 41: return (nbic.control>>24); ! 42: } ! 43: static Uint8 nbic_control_read1(Uint32 addr) { ! 44: Log_Printf(LOG_WARN, "[NBIC] Control (byte 1) read at %08X",addr); ! 45: return (nbic.control>>16); ! 46: } ! 47: static Uint8 nbic_control_read2(Uint32 addr) { ! 48: Log_Printf(LOG_WARN, "[NBIC] Control (byte 2) read at %08X",addr); ! 49: return (nbic.control>>8); ! 50: } ! 51: static Uint8 nbic_control_read3(Uint32 addr) { ! 52: Log_Printf(LOG_WARN, "[NBIC] Control (byte 3) read at %08X",addr); ! 53: return nbic.control; ! 54: } ! 55: ! 56: static void nbic_control_write0(Uint32 addr, Uint8 val) { ! 57: Log_Printf(LOG_WARN, "[NBIC] Control (byte 0) write %02X at %08X",val,addr); ! 58: nbic.control &= 0x00FFFFFF; ! 59: nbic.control |= (val&0xFF)<<24; ! 60: } ! 61: static void nbic_control_write1(Uint32 addr, Uint8 val) { ! 62: Log_Printf(LOG_WARN, "[NBIC] Control (byte 1) write %02X at %08X",val,addr); ! 63: nbic.control &= 0xFF00FFFF; ! 64: nbic.control |= (val&0xFF)<<16; ! 65: } ! 66: static void nbic_control_write2(Uint32 addr, Uint8 val) { ! 67: Log_Printf(LOG_WARN, "[NBIC] Control (byte 2) write %02X at %08X",val,addr); ! 68: nbic.control &= 0xFFFF00FF; ! 69: nbic.control |= (val&0xFF)<<8; ! 70: } ! 71: static void nbic_control_write3(Uint32 addr, Uint8 val) { ! 72: Log_Printf(LOG_WARN, "[NBIC] Control (byte 3) write %02X at %08X",val,addr); ! 73: nbic.control &= 0xFFFFFF00; ! 74: nbic.control |= val&0xFF; ! 75: } ! 76: ! 77: ! 78: static Uint8 nbic_id_read0(Uint32 addr) { ! 79: Log_Printf(LOG_WARN, "[NBIC] ID (byte 0) read at %08X",addr); ! 80: return (nbic.id>>24); ! 81: } ! 82: static Uint8 nbic_id_read1(Uint32 addr) { ! 83: Log_Printf(LOG_WARN, "[NBIC] ID (byte 1) read at %08X",addr); ! 84: return (nbic.id>>16); ! 85: } ! 86: static Uint8 nbic_id_read2(Uint32 addr) { ! 87: Log_Printf(LOG_WARN, "[NBIC] ID (byte 2) read at %08X",addr); ! 88: return (nbic.id>>8); ! 89: } ! 90: static Uint8 nbic_id_read3(Uint32 addr) { ! 91: Log_Printf(LOG_WARN, "[NBIC] ID (byte 3) read at %08X",addr); ! 92: return nbic.id; ! 93: } ! 94: ! 95: static void nbic_id_write0(Uint32 addr, Uint8 val) { ! 96: Log_Printf(LOG_WARN, "[NBIC] ID (byte 0) write %02X at %08X",val,addr); ! 97: nbic.id &= 0x00FFFFFF; ! 98: nbic.id |= (val&0xFF)<<24; ! 99: } ! 100: static void nbic_id_write1(Uint32 addr, Uint8 val) { ! 101: Log_Printf(LOG_WARN, "[NBIC] ID (byte 1) write %02X at %08X",val,addr); ! 102: nbic.id &= 0xFF00FFFF; ! 103: nbic.id |= (val&0xFF)<<16; ! 104: } ! 105: static void nbic_id_write2(Uint32 addr, Uint8 val) { ! 106: Log_Printf(LOG_WARN, "[NBIC] ID (byte 2) write %02X at %08X",val,addr); ! 107: nbic.id &= 0xFFFF00FF; ! 108: nbic.id |= (val&0xFF)<<8; ! 109: } ! 110: static void nbic_id_write3(Uint32 addr, Uint8 val) { ! 111: Log_Printf(LOG_WARN, "[NBIC] ID (byte 3) write %02X at %08X",val,addr); ! 112: nbic.id &= 0xFFFFFF00; ! 113: nbic.id |= val&0xFF; ! 114: } ! 115: ! 116: static Uint8 nbic_intstatus_read(Uint32 addr) { ! 117: Log_Printf(LOG_WARN, "[NBIC] Interrupt status read at %08X",addr); ! 118: return nbic.intstatus; ! 119: } ! 120: ! 121: static Uint8 nbic_intmask_read(Uint32 addr) { ! 122: Log_Printf(LOG_WARN, "[NBIC] Interrupt mask read at %08X",addr); ! 123: return nbic.intmask; ! 124: } ! 125: static void nbic_intmask_write(Uint32 addr, Uint8 val) { ! 126: Log_Printf(LOG_WARN, "[NBIC] Interrupt mask write %02X at %08X",val,addr); ! 127: nbic.intmask = val; ! 128: } ! 129: ! 130: static Uint8 nbic_zero_read(Uint32 addr) { ! 131: Log_Printf(LOG_WARN, "[NBIC] zero read at %08X",addr); ! 132: return 0; ! 133: } ! 134: static void nbic_zero_write(Uint32 addr, Uint8 val) { ! 135: Log_Printf(LOG_WARN, "[NBIC] zero write %02X at %08X",val,addr); ! 136: } ! 137: ! 138: static Uint8 nbic_bus_error_read(Uint32 addr) { ! 139: Log_Printf(LOG_WARN, "[NBIC] bus error read at %08X",addr); ! 140: M68000_BusError(addr, 1); ! 141: return 0; ! 142: } ! 143: static void nbic_bus_error_write(Uint32 addr, Uint8 val) { ! 144: Log_Printf(LOG_WARN, "[NBIC] bus error write at %08X",addr); ! 145: M68000_BusError(addr, 0); ! 146: } ! 147: ! 148: ! 149: /* Direct register access */ ! 150: static Uint8 (*nbic_read_reg[8])(Uint32) = { ! 151: nbic_control_read0, nbic_control_read1, nbic_control_read2, nbic_control_read3, ! 152: nbic_bus_error_read, nbic_bus_error_read, nbic_bus_error_read, nbic_bus_error_read ! 153: }; ! 154: ! 155: static void (*nbic_write_reg[8])(Uint32, Uint8) = { ! 156: nbic_control_write0, nbic_control_write1, nbic_control_write2, nbic_control_write3, ! 157: nbic_id_write0, nbic_id_write1, nbic_id_write2, nbic_id_write3 ! 158: }; ! 159: ! 160: ! 161: Uint32 nbic_reg_lget(Uint32 addr) { ! 162: Uint32 val = 0; ! 163: ! 164: if (addr&3) { ! 165: Log_Printf(LOG_WARN, "[NBIC] Unaligned access at %08X.",addr); ! 166: abort(); ! 167: } ! 168: ! 169: if ((addr&0x0000FFFF)>7) { ! 170: nbic_bus_error_read(addr); ! 171: } else { ! 172: val = nbic_read_reg[addr&7](addr)<<24; ! 173: val |= nbic_read_reg[(addr&7)+1](addr+1)<<16; ! 174: val |= nbic_read_reg[(addr&7)+2](addr+2)<<8; ! 175: val |= nbic_read_reg[(addr&7)+3](addr+3); ! 176: } ! 177: ! 178: return val; ! 179: } ! 180: ! 181: Uint32 nbic_reg_wget(uaecptr addr) { ! 182: Uint32 val = 0; ! 183: ! 184: if (addr&1) { ! 185: Log_Printf(LOG_WARN, "[NBIC] Unaligned access at %08X.",addr); ! 186: abort(); ! 187: } ! 188: ! 189: if ((addr&0x0000FFFF)>7) { ! 190: nbic_bus_error_read(addr); ! 191: } else { ! 192: val = nbic_read_reg[addr&7](addr)<<8; ! 193: val |= nbic_read_reg[(addr&7)+1](addr); ! 194: } ! 195: ! 196: return val; ! 197: } ! 198: ! 199: Uint32 nbic_reg_bget(uaecptr addr) { ! 200: if ((addr&0x0000FFFF)>7) { ! 201: return nbic_bus_error_read(addr); ! 202: } else { ! 203: return nbic_read_reg[addr&7](addr); ! 204: } ! 205: } ! 206: ! 207: void nbic_reg_lput(uaecptr addr, Uint32 l) { ! 208: if (addr&3) { ! 209: Log_Printf(LOG_WARN, "[NBIC] Unaligned access at %08X.",addr); ! 210: abort(); ! 211: } ! 212: ! 213: if ((addr&0x0000FFFF)>7) { ! 214: nbic_bus_error_write(addr,0); ! 215: } else { ! 216: nbic_write_reg[addr&7](addr,l>>24); ! 217: nbic_write_reg[(addr&7)+1](addr,l>>16); ! 218: nbic_write_reg[(addr&7)+2](addr,l>>8); ! 219: nbic_write_reg[(addr&7)+3](addr,l); ! 220: } ! 221: } ! 222: ! 223: void nbic_reg_wput(uaecptr addr, Uint32 w) { ! 224: if (addr&1) { ! 225: Log_Printf(LOG_WARN, "[NBIC] Unaligned access at %08X.",addr); ! 226: abort(); ! 227: } ! 228: ! 229: if ((addr&0x0000FFFF)>7) { ! 230: nbic_bus_error_write(addr,0); ! 231: } else { ! 232: nbic_write_reg[addr&7](addr,w>>8); ! 233: nbic_write_reg[(addr&7)+1](addr,w); ! 234: } ! 235: } ! 236: ! 237: void nbic_reg_bput(uaecptr addr, Uint32 b) { ! 238: if ((addr&0x0000FFFF)>7) { ! 239: nbic_bus_error_write(addr,0); ! 240: } else { ! 241: nbic_write_reg[addr&7](addr,b); ! 242: } ! 243: } ! 244: ! 245: ! 246: /* NeXTbus CPU board slot space access */ ! 247: static Uint8 (*nbic_read_cpu_slot[32])(Uint32) = { ! 248: nbic_bus_error_read, nbic_bus_error_read, nbic_bus_error_read, nbic_bus_error_read, ! 249: nbic_bus_error_read, nbic_bus_error_read, nbic_bus_error_read, nbic_bus_error_read, ! 250: nbic_intstatus_read, nbic_zero_read, nbic_zero_read, nbic_zero_read, ! 251: nbic_intmask_read, nbic_zero_read, nbic_zero_read, nbic_zero_read, ! 252: ! 253: nbic_id_read0, nbic_zero_read, nbic_zero_read, nbic_zero_read, ! 254: nbic_id_read1, nbic_zero_read, nbic_zero_read, nbic_zero_read, ! 255: nbic_id_read2, nbic_zero_read, nbic_zero_read, nbic_zero_read, ! 256: nbic_id_read3, nbic_zero_read, nbic_zero_read, nbic_zero_read, ! 257: }; ! 258: ! 259: static void (*nbic_write_cpu_slot[32])(Uint32, Uint8) = { ! 260: nbic_bus_error_write, nbic_bus_error_write, nbic_bus_error_write, nbic_bus_error_write, ! 261: nbic_bus_error_write, nbic_bus_error_write, nbic_bus_error_write, nbic_bus_error_write, ! 262: nbic_bus_error_write, nbic_bus_error_write, nbic_bus_error_write, nbic_bus_error_write, ! 263: nbic_intmask_write, nbic_zero_write, nbic_zero_write, nbic_zero_write, ! 264: ! 265: nbic_bus_error_write, nbic_bus_error_write, nbic_bus_error_write, nbic_bus_error_write, ! 266: nbic_bus_error_write, nbic_bus_error_write, nbic_bus_error_write, nbic_bus_error_write, ! 267: nbic_bus_error_write, nbic_bus_error_write, nbic_bus_error_write, nbic_bus_error_write, ! 268: nbic_bus_error_write, nbic_bus_error_write, nbic_bus_error_write, nbic_bus_error_write ! 269: }; ! 270: ! 271: Uint32 nb_cpu_slot_lget(Uint32 addr) { ! 272: Uint32 val = 0; ! 273: ! 274: if (addr&3) { ! 275: Log_Printf(LOG_WARN, "[NBIC] Unaligned access at %08X.",addr); ! 276: abort(); ! 277: } ! 278: ! 279: if ((addr&0x00FFFFFF)<0x00FFFFE8) { ! 280: nbic_bus_error_read(addr); ! 281: } else { ! 282: val = nbic_read_cpu_slot[addr&0x1F](addr)<<24; ! 283: val |= nbic_read_cpu_slot[(addr&0x1F)+1](addr+1)<<16; ! 284: val |= nbic_read_cpu_slot[(addr&0x1F)+2](addr+2)<<8; ! 285: val |= nbic_read_cpu_slot[(addr&0x1F)+3](addr+3); ! 286: } ! 287: ! 288: return val; ! 289: } ! 290: ! 291: Uint16 nb_cpu_slot_wget(Uint32 addr) { ! 292: Uint32 val = 0; ! 293: ! 294: if (addr&1) { ! 295: Log_Printf(LOG_WARN, "[NBIC] Unaligned access at %08X.",addr); ! 296: abort(); ! 297: } ! 298: ! 299: if ((addr&0x00FFFFFF)<0x00FFFFE8) { ! 300: nbic_bus_error_read(addr); ! 301: } else { ! 302: val = nbic_read_cpu_slot[addr&0x1F](addr)<<8; ! 303: val |= nbic_read_cpu_slot[(addr&0x1F)+1](addr+1)<<16; ! 304: } ! 305: ! 306: return val; ! 307: } ! 308: ! 309: Uint8 nb_cpu_slot_bget(Uint32 addr) { ! 310: if ((addr&0x00FFFFFF)<0x00FFFFE8) { ! 311: return nbic_bus_error_read(addr); ! 312: } else { ! 313: return nbic_read_cpu_slot[addr&0x1F](addr); ! 314: } ! 315: } ! 316: ! 317: void nb_cpu_slot_lput(Uint32 addr, Uint32 l) { ! 318: if (addr&3) { ! 319: Log_Printf(LOG_WARN, "[NBIC] Unaligned access at %08X.",addr); ! 320: abort(); ! 321: } ! 322: ! 323: if ((addr&0x00FFFFFF)<0x00FFFFE8) { ! 324: nbic_bus_error_write(addr,0); ! 325: } else { ! 326: nbic_write_cpu_slot[addr&0x1F](addr,l>>24); ! 327: nbic_write_cpu_slot[(addr&0x1F)+1](addr,l>>16); ! 328: nbic_write_cpu_slot[(addr&0x1F)+2](addr,l>>8); ! 329: nbic_write_cpu_slot[(addr&0x1F)+3](addr,l); ! 330: } ! 331: } ! 332: ! 333: void nb_cpu_slot_wput(Uint32 addr, Uint16 w) { ! 334: if (addr&1) { ! 335: Log_Printf(LOG_WARN, "[NBIC] Unaligned access at %08X.",addr); ! 336: abort(); ! 337: } ! 338: ! 339: if ((addr&0x00FFFFFF)<0x00FFFFE8) { ! 340: nbic_bus_error_write(addr,0); ! 341: } else { ! 342: nbic_write_cpu_slot[addr&0x1F](addr,w>>8); ! 343: nbic_write_cpu_slot[(addr&0x1F)+1](addr,w); ! 344: } ! 345: } ! 346: ! 347: void nb_cpu_slot_bput(Uint32 addr, Uint8 b) { ! 348: if ((addr&0x00FFFFFF)<0x00FFFFE8) { ! 349: nbic_bus_error_write(addr,0); ! 350: } else { ! 351: nbic_write_cpu_slot[addr&0x1F](addr,b); ! 352: } ! 353: } ! 354: ! 355: ! 356:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.