|
|
1.1 ! root 1: #include "main.h" ! 2: #include "configuration.h" ! 3: #include "m68000.h" ! 4: #include "sysdeps.h" ! 5: #include "sysReg.h" ! 6: #include "adb.h" ! 7: ! 8: ! 9: /* Apple Desktop Bus emulation */ ! 10: ! 11: #define LOG_ADB_LEVEL LOG_DEBUG ! 12: ! 13: ! 14: /* ADB registers */ ! 15: ! 16: struct { ! 17: Uint32 intstatus; ! 18: Uint32 intmask; ! 19: Uint32 config; ! 20: Uint32 status; ! 21: Uint32 command; ! 22: Uint32 bitcount; ! 23: Uint32 data0; ! 24: Uint32 data1; ! 25: } adb; ! 26: ! 27: #define ADB_INTSTATUS 0x00 /* rw */ ! 28: #define ADB_INTMASK 0x08 /* rw */ ! 29: #define ADB_SETINT 0x10 /* w */ ! 30: #define ADB_CONFIG 0x18 /* rw */ ! 31: #define ADB_CTRL 0x20 /* w */ ! 32: #define ADB_STATUS 0x28 /* r */ ! 33: #define ADB_CMD 0x30 /* rw */ ! 34: #define ADB_COUNT 0x38 /* rw */ ! 35: ! 36: #define ADB_DATA0 0x80 /* rw */ ! 37: #define ADB_DATA1 0x88 /* rw */ ! 38: ! 39: ! 40: /* ADB interrupt registers */ ! 41: #define ADB_INT_REJECT 0x01 ! 42: #define ADB_INT_POLLSTOP 0x02 ! 43: #define ADB_INT_ACCESS 0x04 ! 44: #define ADB_INT_RESET 0x08 ! 45: ! 46: /* ADB configuration register */ ! 47: #define ADB_CONF_SYSTEM 0x01 ! 48: #define ADB_CONF_WATCHDOG 0x02 ! 49: ! 50: /* ADB control register */ ! 51: #define ADB_CTRL_EN_POLL 0x01 ! 52: #define ADB_CTRL_DIS_POLL 0x02 ! 53: #define ADB_CTRL_XMIT_CMD 0x04 ! 54: #define ADB_CTRL_RESET_ADB 0x08 ! 55: #define ADB_CTRL_RESET_WD 0x10 ! 56: ! 57: /* ADB status register */ ! 58: #define ADB_STAT_CONFLICT 0x01 ! 59: #define ADB_STAT_REQUEST 0x02 ! 60: #define ADB_STAT_TIMEOUT 0x04 ! 61: #define ADB_STAT_DATAPEND 0x08 ! 62: #define ADB_STAT_RESET 0x10 ! 63: #define ADB_STAT_ACCESS 0x20 ! 64: #define ADB_STAT_POLL_EN 0x40 ! 65: #define ADB_STAT_POLL_OV 0x80 ! 66: ! 67: /* ADB command register */ ! 68: #define ADB_CMD_REG_MASK 0x03 ! 69: #define ADB_CMD_CMD_MASK 0x0C ! 70: #define ADB_CMD_ADDR_MASK 0xF0 ! 71: ! 72: /* ADB bit count register */ ! 73: #define ADB_CNT_MASK 0x7F ! 74: ! 75: ! 76: static void adb_interrupt(Uint32 intr) { ! 77: adb.intstatus |= intr; ! 78: if (intr&adb.intmask) { ! 79: set_interrupt(INT_DISK, SET_INT); ! 80: } ! 81: } ! 82: ! 83: static Uint32 adb_intstatus_read(Uint32 addr) { ! 84: Log_Printf(LOG_ADB_LEVEL, "[ADB] Interrupt status read at $%08X val=$%08X",addr,adb.intstatus); ! 85: return adb.intstatus; ! 86: } ! 87: ! 88: static void adb_intstatus_write(Uint32 addr, Uint32 val) { ! 89: Log_Printf(LOG_ADB_LEVEL, "[ADB] Interrupt status write at $%08X val=$%08X",addr,val); ! 90: adb.intstatus &= ~val; ! 91: if (!(adb.intstatus&adb.intmask)) { ! 92: set_interrupt(INT_DISK, RELEASE_INT); ! 93: } ! 94: } ! 95: ! 96: static Uint32 adb_intmask_read(Uint32 addr) { ! 97: Log_Printf(LOG_ADB_LEVEL, "[ADB] Interrupt mask read at $%08X val=$%08X",addr,adb.intmask); ! 98: return adb.intmask; ! 99: } ! 100: ! 101: static void adb_intmask_write(Uint32 addr, Uint32 val) { ! 102: Log_Printf(LOG_ADB_LEVEL, "[ADB] Interrupt mask write at $%08X val=$%08X",addr,val); ! 103: adb.intmask = val; ! 104: if (adb.intstatus&adb.intmask) { ! 105: set_interrupt(INT_DISK, SET_INT); ! 106: } else { ! 107: set_interrupt(INT_DISK, RELEASE_INT); ! 108: } ! 109: } ! 110: ! 111: static void adb_setint_write(Uint32 addr, Uint32 val) { ! 112: Log_Printf(LOG_ADB_LEVEL, "[ADB] Set interrupt write at $%08X val=$%08X",addr,val); ! 113: adb.intstatus |= val; ! 114: if (adb.intstatus&adb.intmask) { ! 115: set_interrupt(INT_DISK, SET_INT); ! 116: } ! 117: } ! 118: ! 119: static Uint32 adb_config_read(Uint32 addr) { ! 120: Log_Printf(LOG_ADB_LEVEL, "[ADB] Configuration read at $%08X val=$%08X",addr,adb.config); ! 121: return adb.config; ! 122: } ! 123: ! 124: static void adb_config_write(Uint32 addr, Uint32 val) { ! 125: Log_Printf(LOG_ADB_LEVEL, "[ADB] Configuration write at $%08X val=$%08X",addr,val); ! 126: adb.config = val; ! 127: } ! 128: ! 129: static void adb_control_write(Uint32 addr, Uint32 val) { ! 130: Log_Printf(LOG_ADB_LEVEL, "[ADB] Control write at $%08X val=$%08X",addr,val); ! 131: ! 132: if (val&ADB_CTRL_RESET_ADB) { ! 133: adb.status &= ~ADB_STAT_POLL_EN; ! 134: adb_interrupt(ADB_INT_RESET); ! 135: } ! 136: if (val&ADB_CTRL_XMIT_CMD) { ! 137: if (adb.status&(ADB_STAT_RESET/*|ADB_STAT_POLL_EN*/|ADB_STAT_ACCESS)) { ! 138: adb_interrupt(ADB_INT_REJECT); ! 139: } else { ! 140: adb.status |= ADB_STAT_TIMEOUT; ! 141: if (1/*!(adb.status&ADB_STAT_POLL_EN)*/) { ! 142: adb_interrupt(ADB_INT_ACCESS); ! 143: } ! 144: } ! 145: } ! 146: if (val&ADB_CTRL_DIS_POLL) { ! 147: adb.status &= ~ADB_STAT_POLL_EN; ! 148: } ! 149: if (val&ADB_CTRL_EN_POLL) { ! 150: if (adb.status&(ADB_STAT_RESET|ADB_STAT_ACCESS) && !(adb.status&ADB_STAT_POLL_EN)) { ! 151: adb_interrupt(ADB_INT_REJECT); ! 152: } else { ! 153: adb.status |= ADB_STAT_POLL_EN; ! 154: } ! 155: } ! 156: } ! 157: ! 158: static Uint32 adb_status_read(Uint32 addr) { ! 159: Log_Printf(LOG_ADB_LEVEL, "[ADB] Status read at $%08X val=$%08X",addr,adb.status); ! 160: return adb.status; ! 161: } ! 162: ! 163: static Uint32 adb_command_read(Uint32 addr) { ! 164: Log_Printf(LOG_ADB_LEVEL, "[ADB] Command read at $%08X val=$%08X",addr,adb.command); ! 165: return adb.command; ! 166: } ! 167: ! 168: static void adb_command_write(Uint32 addr, Uint32 val) { ! 169: Log_Printf(LOG_ADB_LEVEL, "[ADB] Command write at $%08X val=$%08X",addr,val); ! 170: adb.command = val; ! 171: } ! 172: ! 173: static Uint32 adb_bitcount_read(Uint32 addr) { ! 174: Log_Printf(LOG_ADB_LEVEL, "[ADB] Bitcount read at $%08X val=$%08X",addr,adb.bitcount); ! 175: return adb.bitcount; ! 176: } ! 177: ! 178: static void adb_bitcount_write(Uint32 addr, Uint32 val) { ! 179: Log_Printf(LOG_ADB_LEVEL, "[ADB] Bitcount write at $%08X val=$%08X",addr,val); ! 180: adb.bitcount = val; ! 181: } ! 182: ! 183: static Uint32 adb_data0_read(Uint32 addr) { ! 184: Log_Printf(LOG_ADB_LEVEL, "[ADB] Data0 read at $%08X val=$%08X",addr,adb.data0); ! 185: return adb.data0; ! 186: } ! 187: ! 188: static void adb_data0_write(Uint32 addr, Uint32 val) { ! 189: Log_Printf(LOG_ADB_LEVEL, "[ADB] Data0 write at $%08X val=$%08X",addr,val); ! 190: adb.data0 = val; ! 191: } ! 192: ! 193: static Uint32 adb_data1_read(Uint32 addr) { ! 194: Log_Printf(LOG_ADB_LEVEL, "[ADB] Data1 read at $%08X val=$%08X",addr,adb.data1); ! 195: return adb.data1; ! 196: } ! 197: ! 198: static void adb_data1_write(Uint32 addr, Uint32 val) { ! 199: Log_Printf(LOG_ADB_LEVEL, "[ADB] Data1 write at $%08X val=$%08X",addr,val); ! 200: adb.data1 = val; ! 201: } ! 202: ! 203: ! 204: static Uint32 adb_read_register(Uint32 addr) { ! 205: switch (addr&0xFF) { ! 206: case ADB_INTSTATUS: ! 207: return adb_intstatus_read(addr); ! 208: case ADB_INTMASK: ! 209: return adb_intmask_read(addr); ! 210: case ADB_CONFIG: ! 211: return adb_config_read(addr); ! 212: case ADB_STATUS: ! 213: return adb_status_read(addr); ! 214: case ADB_CMD: ! 215: return adb_command_read(addr); ! 216: case ADB_COUNT: ! 217: return adb_bitcount_read(addr); ! 218: case ADB_DATA0: ! 219: return adb_data0_read(addr); ! 220: case ADB_DATA1: ! 221: return adb_data1_read(addr); ! 222: ! 223: default: ! 224: Log_Printf(LOG_WARN, "[ADB] Illegal read at $%08X",addr); ! 225: M68000_BusError(addr, 1); ! 226: return 0; ! 227: } ! 228: } ! 229: ! 230: static void adb_write_register(Uint32 addr, Uint32 val) { ! 231: switch (addr&0xFF) { ! 232: case ADB_INTSTATUS: ! 233: adb_intstatus_write(addr, val); ! 234: break; ! 235: case ADB_INTMASK: ! 236: adb_intmask_write(addr, val); ! 237: break; ! 238: case ADB_SETINT: ! 239: adb_setint_write(addr, val); ! 240: break; ! 241: case ADB_CONFIG: ! 242: adb_config_write(addr, val); ! 243: break; ! 244: case ADB_CTRL: ! 245: adb_control_write(addr, val); ! 246: break; ! 247: case ADB_CMD: ! 248: adb_command_write(addr, val); ! 249: break; ! 250: case ADB_COUNT: ! 251: adb_bitcount_write(addr, val); ! 252: break; ! 253: case ADB_DATA0: ! 254: adb_data0_write(addr, val); ! 255: break; ! 256: case ADB_DATA1: ! 257: adb_data1_write(addr, val); ! 258: break; ! 259: ! 260: default: ! 261: Log_Printf(LOG_WARN, "[ADB] Illegal write at $%08X",addr); ! 262: M68000_BusError(addr, 0); ! 263: break; ! 264: } ! 265: } ! 266: ! 267: ! 268: ! 269: Uint32 adb_lget(Uint32 addr) { ! 270: Log_Printf(LOG_WARN, "[ADB] lget at $%08X",addr); ! 271: return adb_read_register(addr); ! 272: } ! 273: ! 274: Uint16 adb_wget(Uint32 addr) { ! 275: Uint8 shift; ! 276: Log_Printf(LOG_WARN, "[ADB] wget at $%08X",addr); ! 277: ! 278: shift = (2-(addr&2))*8; ! 279: addr &= ~3; ! 280: return (adb_read_register(addr)>>shift)&0xFFFF; ! 281: } ! 282: ! 283: Uint8 adb_bget(Uint32 addr) { ! 284: Uint8 shift; ! 285: Log_Printf(LOG_WARN, "[ADB] bget at $%08X",addr); ! 286: ! 287: shift = (3-(addr&3))*8; ! 288: addr &= ~3; ! 289: return (adb_read_register(addr)>>shift)&0xFF; ! 290: } ! 291: ! 292: void adb_lput(Uint32 addr, Uint32 l) { ! 293: Log_Printf(LOG_WARN, "[ADB] lput at $%08X",addr); ! 294: adb_write_register(addr, l); ! 295: } ! 296: ! 297: void adb_wput(Uint32 addr, Uint16 w) { ! 298: Log_Printf(LOG_WARN, "[ADB] illegal wput at $%08X -> bus error",addr); ! 299: M68000_BusError(addr, 0); ! 300: } ! 301: ! 302: void adb_bput(Uint32 addr, Uint8 b) { ! 303: Log_Printf(LOG_WARN, "[ADB] illegal bput at $%08X -> bus error",addr); ! 304: M68000_BusError(addr, 0); ! 305: } ! 306: ! 307: void ADB_Reset(void) { ! 308: Log_Printf(LOG_WARN, "[ADB] Reset"); ! 309: adb.intstatus = 0; ! 310: adb.intmask = 0; ! 311: adb.config = 0; ! 312: adb.command = 0; ! 313: adb.status = 0; ! 314: adb.bitcount = 0; ! 315: adb.data0 = 0; ! 316: adb.data1 = 0; ! 317: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.