|
|
1.1 ! root 1: /* NeXT DMA Emulation ! 2: * Contains informations from QEMU-NeXT ! 3: * NeXT DMA consists of 12 channel processors with 128 bytes internal buffer for each channel ! 4: * 12 channels: SCSI, Sound in, Sound out, Optical disk, Printer, SCC, DSP, ! 5: * Ethernet transmit, Ethernet receive, Video, Memory to register, Register to memory ! 6: */ ! 7: ! 8: #include "ioMem.h" ! 9: #include "ioMemTables.h" ! 10: #include "m68000.h" ! 11: #include "esp.h" ! 12: #include "sysReg.h" ! 13: #include "dma.h" ! 14: #include "configuration.h" ! 15: #include "ethernet.h" ! 16: ! 17: ! 18: #define LOG_DMA_LEVEL LOG_WARN ! 19: ! 20: #define IO_SEG_MASK 0x1FFFF ! 21: ! 22: /* read CSR bits */ ! 23: #define DMA_ENABLE 0x01000000 /* enable dma transfer */ ! 24: #define DMA_SUPDATE 0x02000000 /* single update */ ! 25: #define DMA_COMPLETE 0x08000000 /* current dma has completed */ ! 26: #define DMA_BUSEXC 0x10000000 /* bus exception occurred */ ! 27: /* write CSR bits */ ! 28: #define DMA_SETENABLE 0x00010000 /* set enable */ ! 29: #define DMA_SETSUPDATE 0x00020000 /* set single update */ ! 30: #define DMA_M2DEV 0x00000000 /* dma from mem to dev */ ! 31: #define DMA_DEV2M 0x00040000 /* dma from dev to mem */ ! 32: #define DMA_CLRCOMPLETE 0x00080000 /* clear complete conditional */ ! 33: #define DMA_RESET 0x00100000 /* clr cmplt, sup, enable */ ! 34: #define DMA_INITBUF 0x00200000 /* initialize DMA buffers */ ! 35: ! 36: ! 37: /* Read and write CSR bits for 68030 based NeXT Computer. ! 38: * We convert these to 68040 values before using in functions. ! 39: * read CSR bits * ! 40: #define DMA_ENABLE 0x01 ! 41: #define DMA_SUPDATE 0x02 ! 42: #define DMA_COMPLETE 0x08 ! 43: #define DMA_BUSEXC 0x10 ! 44: * write CSR bits * ! 45: #define DMA_SETENABLE 0x01 ! 46: #define DMA_SETSUPDATE 0x02 ! 47: #define DMA_M2DEV 0x00 ! 48: #define DMA_DEV2M 0x04 ! 49: #define DMA_CLRCOMPLETE 0x08 ! 50: #define DMA_RESET 0x10 ! 51: #define DMA_INITBUF 0x20 ! 52: */ ! 53: ! 54: ! 55: ! 56: /* DMA registers */ ! 57: ! 58: typedef struct { ! 59: Uint32 csr; ! 60: Uint32 saved_next; ! 61: Uint32 saved_limit; ! 62: Uint32 saved_start; ! 63: Uint32 saved_stop; ! 64: Uint32 next; ! 65: Uint32 limit; ! 66: Uint32 start; ! 67: Uint32 stop; ! 68: Uint32 init; ! 69: Uint32 size; ! 70: } DMA_CONTROL; ! 71: ! 72: DMA_CONTROL dma[16]; ! 73: ! 74: ! 75: ! 76: int get_channel(Uint32 address) { ! 77: int channel = address&IO_SEG_MASK; ! 78: switch (channel) { ! 79: case 0x010: printf("channel SCSI:\n"); return CHANNEL_SCSI; break; ! 80: case 0x040: printf("channel Sound Out:\n"); return CHANNEL_SOUNDOUT; break; ! 81: case 0x050: printf("channel MO Disk:\n"); return CHANNEL_DISK; break; ! 82: case 0x080: printf("channel Sound in:\n"); return CHANNEL_SOUNDIN; break; ! 83: case 0x090: printf("channel Printer:\n"); return CHANNEL_PRINTER; break; ! 84: case 0x0c0: printf("channel SCC:\n"); return CHANNEL_SCC; break; ! 85: case 0x0d0: printf("channel DSP:\n"); return CHANNEL_DSP; break; ! 86: case 0x110: printf("channel Ethernet Tx:\n"); return CHANNEL_EN_TX; break; ! 87: case 0x150: printf("channel Ethernet Rx:\n"); return CHANNEL_EN_RX; break; ! 88: case 0x180: printf("channel Video:\n"); return CHANNEL_VIDEO; break; ! 89: case 0x1d0: printf("channel M2R:\n"); return CHANNEL_M2R; break; ! 90: case 0x1c0: printf("channel R2M:\n"); return CHANNEL_R2M; break; ! 91: ! 92: default: ! 93: Log_Printf(LOG_DMA_LEVEL, "Unknown DMA channel!\n"); ! 94: return -1; ! 95: break; ! 96: } ! 97: } ! 98: ! 99: int get_interrupt_type(int channel) { ! 100: switch (channel) { ! 101: case CHANNEL_SCSI: return INT_SCSI_DMA; break; ! 102: case CHANNEL_SOUNDOUT: return INT_SND_OUT_DMA; break; ! 103: case CHANNEL_DISK: return INT_DISK_DMA; break; ! 104: case CHANNEL_SOUNDIN: return INT_SND_IN_DMA; break; ! 105: case CHANNEL_PRINTER: return INT_PRINTER_DMA; break; ! 106: case CHANNEL_SCC: return INT_SCC_DMA; break; ! 107: case CHANNEL_DSP: return INT_DSP_DMA; break; ! 108: case CHANNEL_EN_TX: return INT_EN_TX_DMA; break; ! 109: case CHANNEL_EN_RX: return INT_EN_RX_DMA; break; ! 110: case CHANNEL_VIDEO: return 0; break; // no interrupt? CHECK THIS ! 111: case CHANNEL_M2R: return INT_M2R_DMA; break; ! 112: case CHANNEL_R2M: return INT_R2M_DMA; break; ! 113: ! 114: default: ! 115: Log_Printf(LOG_DMA_LEVEL, "Unknown DMA interrupt!\n"); ! 116: return 0; ! 117: break; ! 118: } ! 119: } ! 120: ! 121: void DMA_CSR_Read(void) { // 0x02000010, length of register is byte on 68030 based NeXT Computer ! 122: int channel = get_channel(IoAccessCurrentAddress); ! 123: if(ConfigureParams.System.nMachineType == NEXT_CUBE030) { // for 68030 based NeXT Computer ! 124: IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = dma[channel].csr >> 24; ! 125: Log_Printf(LOG_DMA_LEVEL,"DMA CSR read at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].csr >> 24, m68k_getpc()); ! 126: } else { ! 127: IoMem_WriteLong(IoAccessCurrentAddress & IO_SEG_MASK, dma[channel].csr); ! 128: Log_Printf(LOG_DMA_LEVEL,"DMA CSR read at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].csr, m68k_getpc()); ! 129: } ! 130: } ! 131: ! 132: void DMA_CSR_Write(void) { ! 133: int channel = get_channel(IoAccessCurrentAddress); ! 134: int interrupt = get_interrupt_type(channel); ! 135: Uint32 writecsr; ! 136: if(ConfigureParams.System.nMachineType == NEXT_CUBE030) { // for 68030 based NeXT Computer ! 137: writecsr = IoMem[IoAccessCurrentAddress & IO_SEG_MASK] << 16; ! 138: Log_Printf(LOG_DMA_LEVEL,"DMA CSR write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, writecsr >> 16, m68k_getpc()); ! 139: } else { ! 140: writecsr = IoMem_ReadLong(IoAccessCurrentAddress & IO_SEG_MASK); ! 141: Log_Printf(LOG_DMA_LEVEL,"DMA CSR write at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, writecsr, m68k_getpc()); ! 142: } ! 143: ! 144: if(writecsr & DMA_DEV2M) { ! 145: if(ConfigureParams.System.nMachineType == NEXT_CUBE030) { ! 146: dma[channel].csr |= (0x04 << 24); // use 8 bit DMA_DEV2M value for 68030 based NeXT Computer ! 147: } else { ! 148: dma[channel].csr |= DMA_DEV2M; ! 149: } ! 150: Log_Printf(LOG_DMA_LEVEL,"DMA from dev to mem"); ! 151: } else { ! 152: Log_Printf(LOG_DMA_LEVEL,"DMA from mem to dev"); ! 153: } ! 154: if(writecsr & DMA_SETENABLE) { ! 155: dma[channel].csr |= DMA_ENABLE; ! 156: Log_Printf(LOG_DMA_LEVEL,"DMA enable transfer"); ! 157: if ((channel == CHANNEL_EN_TX) && !(writecsr&DMA_DEV2M)) { ! 158: Ethernet_Transmit(); // Ethernet Transmit ! 159: } ! 160: } ! 161: if(writecsr & DMA_SETSUPDATE) { ! 162: dma[channel].csr |= DMA_SUPDATE; ! 163: Log_Printf(LOG_DMA_LEVEL,"DMA set single update"); ! 164: } ! 165: if(writecsr & DMA_CLRCOMPLETE) { ! 166: dma[channel].csr &= ~DMA_COMPLETE; ! 167: Log_Printf(LOG_DMA_LEVEL,"DMA clear complete conditional"); ! 168: ! 169: set_interrupt(interrupt, RELEASE_INT); // also somewhat experimental... ! 170: } ! 171: if(writecsr & DMA_RESET) { ! 172: dma[channel].csr &= ~(DMA_COMPLETE | DMA_SUPDATE | DMA_ENABLE | DMA_DEV2M); ! 173: Log_Printf(LOG_WARN,"DMA reset"); ! 174: ! 175: set_interrupt(interrupt, RELEASE_INT); // also somewhat experimental... ! 176: } ! 177: if(writecsr & DMA_INITBUF) { // needs to be filled ! 178: Log_Printf(LOG_DMA_LEVEL,"DMA initialize buffers"); ! 179: } ! 180: } ! 181: ! 182: void DMA_Saved_Next_Read(void) { // 0x02004000 ! 183: int channel = get_channel(IoAccessCurrentAddress-0x3FF0); ! 184: IoMem_WriteLong(IoAccessCurrentAddress & IO_SEG_MASK, dma[channel].saved_next); ! 185: Log_Printf(LOG_DMA_LEVEL,"DMA SNext read at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].saved_next, m68k_getpc()); ! 186: } ! 187: ! 188: void DMA_Saved_Next_Write(void) { ! 189: int channel = get_channel(IoAccessCurrentAddress-0x3FF0); ! 190: dma[channel].saved_next = IoMem_ReadLong(IoAccessCurrentAddress & IO_SEG_MASK); ! 191: Log_Printf(LOG_DMA_LEVEL,"DMA SNext write at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].saved_next, m68k_getpc()); ! 192: } ! 193: ! 194: void DMA_Saved_Limit_Read(void) { // 0x02004004 ! 195: int channel = get_channel(IoAccessCurrentAddress-0x3FF4); ! 196: IoMem_WriteLong(IoAccessCurrentAddress & IO_SEG_MASK, dma[channel].saved_limit); ! 197: Log_Printf(LOG_DMA_LEVEL,"DMA SLimit read at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].saved_limit, m68k_getpc()); ! 198: } ! 199: ! 200: void DMA_Saved_Limit_Write(void) { ! 201: int channel = get_channel(IoAccessCurrentAddress-0x3FF4); ! 202: dma[channel].saved_limit = IoMem_ReadLong(IoAccessCurrentAddress & IO_SEG_MASK); ! 203: Log_Printf(LOG_DMA_LEVEL,"DMA SLimit write at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].saved_limit, m68k_getpc()); ! 204: } ! 205: ! 206: void DMA_Saved_Start_Read(void) { // 0x02004008 ! 207: int channel = get_channel(IoAccessCurrentAddress-0x3FF8); ! 208: IoMem_WriteLong(IoAccessCurrentAddress & IO_SEG_MASK, dma[channel].saved_start); ! 209: Log_Printf(LOG_DMA_LEVEL,"DMA SStart read at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].saved_start, m68k_getpc()); ! 210: } ! 211: ! 212: void DMA_Saved_Start_Write(void) { ! 213: int channel = get_channel(IoAccessCurrentAddress-0x3FF8); ! 214: dma[channel].saved_start = IoMem_ReadLong(IoAccessCurrentAddress & IO_SEG_MASK); ! 215: Log_Printf(LOG_DMA_LEVEL,"DMA SStart write at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].saved_start, m68k_getpc()); ! 216: } ! 217: ! 218: void DMA_Saved_Stop_Read(void) { // 0x0200400c ! 219: int channel = get_channel(IoAccessCurrentAddress-0x3FFC); ! 220: IoMem_WriteLong(IoAccessCurrentAddress & IO_SEG_MASK, dma[channel].saved_stop); ! 221: Log_Printf(LOG_DMA_LEVEL,"DMA SStop read at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].saved_stop, m68k_getpc()); ! 222: } ! 223: ! 224: void DMA_Saved_Stop_Write(void) { ! 225: int channel = get_channel(IoAccessCurrentAddress-0x3FFC); ! 226: dma[channel].saved_stop = IoMem_ReadLong(IoAccessCurrentAddress & IO_SEG_MASK); ! 227: Log_Printf(LOG_DMA_LEVEL,"DMA SStop write at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].saved_stop, m68k_getpc()); ! 228: } ! 229: ! 230: void DMA_Next_Read(void) { // 0x02004010 ! 231: int channel = get_channel(IoAccessCurrentAddress-0x4000); ! 232: IoMem_WriteLong(IoAccessCurrentAddress & IO_SEG_MASK, dma[channel].next); ! 233: Log_Printf(LOG_DMA_LEVEL,"DMA Next read at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].next, m68k_getpc()); ! 234: } ! 235: ! 236: void DMA_Next_Write(void) { ! 237: int channel = get_channel(IoAccessCurrentAddress-0x4000); ! 238: dma[channel].next = IoMem_ReadLong(IoAccessCurrentAddress & IO_SEG_MASK); ! 239: Log_Printf(LOG_DMA_LEVEL,"DMA Next write at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].next, m68k_getpc()); ! 240: } ! 241: ! 242: void DMA_Limit_Read(void) { // 0x02004014 ! 243: int channel = get_channel(IoAccessCurrentAddress-0x4004); ! 244: IoMem_WriteLong(IoAccessCurrentAddress & IO_SEG_MASK, dma[channel].limit); ! 245: Log_Printf(LOG_DMA_LEVEL,"DMA Limit read at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].limit, m68k_getpc()); ! 246: } ! 247: ! 248: void DMA_Limit_Write(void) { ! 249: int channel = get_channel(IoAccessCurrentAddress-0x4004); ! 250: dma[channel].limit = IoMem_ReadLong(IoAccessCurrentAddress & IO_SEG_MASK); ! 251: Log_Printf(LOG_DMA_LEVEL,"DMA Limit write at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].limit, m68k_getpc()); ! 252: } ! 253: ! 254: void DMA_Start_Read(void) { // 0x02004018 ! 255: int channel = get_channel(IoAccessCurrentAddress-0x4008); ! 256: IoMem_WriteLong(IoAccessCurrentAddress & IO_SEG_MASK, dma[channel].start); ! 257: Log_Printf(LOG_DMA_LEVEL,"DMA Start read at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].start, m68k_getpc()); ! 258: } ! 259: ! 260: void DMA_Start_Write(void) { ! 261: int channel = get_channel(IoAccessCurrentAddress-0x4008); ! 262: dma[channel].start = IoMem_ReadLong(IoAccessCurrentAddress & IO_SEG_MASK); ! 263: Log_Printf(LOG_DMA_LEVEL,"DMA Start write at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].start, m68k_getpc()); ! 264: } ! 265: ! 266: void DMA_Stop_Read(void) { // 0x0200401c ! 267: int channel = get_channel(IoAccessCurrentAddress-0x400C); ! 268: IoMem_WriteLong(IoAccessCurrentAddress & IO_SEG_MASK, dma[channel].stop); ! 269: Log_Printf(LOG_DMA_LEVEL,"DMA Stop read at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].stop, m68k_getpc()); ! 270: } ! 271: ! 272: void DMA_Stop_Write(void) { ! 273: int channel = get_channel(IoAccessCurrentAddress-0x400C); ! 274: dma[channel].stop = IoMem_ReadLong(IoAccessCurrentAddress & IO_SEG_MASK); ! 275: Log_Printf(LOG_DMA_LEVEL,"DMA Stop write at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].stop, m68k_getpc()); ! 276: } ! 277: ! 278: void DMA_Init_Read(void) { // 0x02004210 ! 279: int channel = get_channel(IoAccessCurrentAddress-0x4200); ! 280: IoMem_WriteLong(IoAccessCurrentAddress & IO_SEG_MASK, dma[channel].init); ! 281: Log_Printf(LOG_DMA_LEVEL,"DMA Init read at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].init, m68k_getpc()); ! 282: } ! 283: ! 284: void DMA_Init_Write(void) { ! 285: int channel = get_channel(IoAccessCurrentAddress-0x4200); ! 286: dma[channel].init = IoMem_ReadLong(IoAccessCurrentAddress & IO_SEG_MASK); ! 287: Log_Printf(LOG_DMA_LEVEL,"DMA Init write at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].init, m68k_getpc()); ! 288: } ! 289: ! 290: void DMA_Size_Read(void) { // 0x02004214 ! 291: int channel = get_channel(IoAccessCurrentAddress-0x4204); ! 292: IoMem_WriteLong(IoAccessCurrentAddress & IO_SEG_MASK, dma[channel].size); ! 293: Log_Printf(LOG_DMA_LEVEL,"DMA Size read at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].size, m68k_getpc()); ! 294: } ! 295: ! 296: void DMA_Size_Write(void) { ! 297: int channel = get_channel(IoAccessCurrentAddress-0x4204); ! 298: dma[channel].size = IoMem_ReadLong(IoAccessCurrentAddress & IO_SEG_MASK); ! 299: Log_Printf(LOG_DMA_LEVEL,"DMA Size write at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].size, m68k_getpc()); ! 300: } ! 301: ! 302: ! 303: ! 304: /* DMA Functions */ ! 305: ! 306: /*void copy_to_scsidma_buffer(Uint8 device_outbuf[], int outbuf_size) { ! 307: memcpy(dma_buffer, device_outbuf, outbuf_size); ! 308: }*/ ! 309: ! 310: /*void dma_clear_memory(Uint32 datalength) { ! 311: Uint32 start_addr; ! 312: Uint32 end_addr; ! 313: ! 314: if(dma_init == 0) ! 315: start_addr = dma_next; ! 316: else ! 317: start_addr = dma_init; ! 318: ! 319: end_addr = start_addr + datalength; ! 320: ! 321: NEXTMemory_Clear(start_addr, end_addr); ! 322: }*/ ! 323: ! 324: void dma_memory_read(Uint8 *buf, Uint32 *size, int channel) { ! 325: Uint32 base_addr; ! 326: Uint8 align = 16; ! 327: Uint32 size_count = 0; ! 328: Uint32 read_addr; ! 329: int interrupt = get_interrupt_type(channel); ! 330: ! 331: if ((channel == CHANNEL_EN_TX) && !ConfigureParams.System.bTurbo) ! 332: *size = (dma[channel].limit&0x0FFFFFFF) - (dma[channel].init&0x0FFFFFFF); ! 333: else ! 334: *size = (dma[channel].limit&0x0FFFFFFF) - (dma[channel].next&0x0FFFFFFF); ! 335: ! 336: if(channel == CHANNEL_EN_RX || channel == CHANNEL_EN_TX) ! 337: align = 32; ! 338: ! 339: // if((*size % align) != 0) { ! 340: // *size -= *size % align; ! 341: // *size += align; ! 342: // } ! 343: ! 344: if(dma[channel].init == 0) ! 345: base_addr = dma[channel].next; ! 346: else ! 347: base_addr = dma[channel].init; ! 348: ! 349: Log_Printf(LOG_WARN, "[DMA] Read from mem: at $%08x, %i bytes",base_addr, *size); ! 350: for (size_count = 0; size_count < *size; size_count++) { ! 351: read_addr = base_addr + size_count; ! 352: buf[size_count] = NEXTMemory_ReadByte(read_addr); ! 353: } ! 354: printf("READ FROM MEMORY: %02x\n", buf[0]); ! 355: ! 356: dma[channel].csr |= DMA_COMPLETE | DMA_SUPDATE; ! 357: ! 358: set_interrupt(interrupt, SET_INT); ! 359: } ! 360: ! 361: ! 362: void dma_memory_write(Uint8 *buf, Uint32 size, int channel) { ! 363: Uint32 base_addr, tail_addr; ! 364: Uint8 align = 16; ! 365: Uint32 size_count = 0; ! 366: Uint32 write_addr; ! 367: Uint32 dma_tail = 0; ! 368: int interrupt = get_interrupt_type(channel); ! 369: ! 370: if(channel == CHANNEL_EN_RX || channel == CHANNEL_EN_TX) ! 371: align = 32; ! 372: ! 373: // if((size % align) != 0) { ! 374: // size -= size % align; ! 375: // size += align; ! 376: // } ! 377: ! 378: ! 379: if(dma[channel].init == 0) { ! 380: base_addr = dma[channel].next; ! 381: dma_tail = 0; ! 382: } else { ! 383: base_addr = dma[channel].init; ! 384: ! 385: /* If the transfer size is greater than (limit - init): ! 386: * Copy residual bytes to physical addresses at start. */ ! 387: if (size > (dma[channel].limit - dma[channel].init)) { ! 388: tail_addr = dma[channel].start; ! 389: dma_tail = size - (dma[channel].limit - dma[channel].init); ! 390: size = (dma[channel].limit - dma[channel].init); ! 391: Log_Printf(LOG_WARN, "[DMA] Residual bytes: %i", dma_tail); ! 392: } ! 393: } ! 394: ! 395: Log_Printf(LOG_WARN, "[DMA] Write to mem: at $%08x, %i bytes",base_addr,size); ! 396: for (size_count = 0; size_count < size; size_count++) { ! 397: write_addr = base_addr + size_count; ! 398: NEXTMemory_WriteByte(write_addr, buf[size_count]); ! 399: } ! 400: ! 401: /* If there are residual bytes, copy them to physical addresses starting ! 402: * at "start". */ ! 403: ! 404: if (dma_tail) { ! 405: Log_Printf(LOG_WARN, "[DMA] Write residual bytes at $%08x, %i bytes",tail_addr,dma_tail); ! 406: for (size_count = 0; size_count < dma_tail; size_count++) { ! 407: write_addr = tail_addr + size_count; ! 408: NEXTMemory_WriteByte(write_addr, buf[size+size_count]); ! 409: } ! 410: } ! 411: ! 412: ! 413: /* Test read/write */ ! 414: Log_Printf(LOG_DMA_LEVEL, "DMA Write Test: $%02x,$%02x,$%02x,$%02x\n", NEXTMemory_ReadByte(base_addr),NEXTMemory_ReadByte(base_addr+16),NEXTMemory_ReadByte(base_addr+32),NEXTMemory_ReadByte(base_addr+384)); ! 415: // NEXTMemory_WriteByte(base_addr, 0x77); ! 416: // Uint8 testvar = NEXTMemory_ReadByte(base_addr); ! 417: // Log_Printf(LOG_DMA_LEVEL, "Write Test: $%02x at $%08x", testvar, base_addr); ! 418: ! 419: dma[channel].init = 0; ! 420: ! 421: /* saved limit is checked to calculate packet size ! 422: by both the rom and netbsd */ ! 423: dma[channel].saved_limit = dma[channel].next + size; ! 424: dma[channel].saved_next = dma[channel].next; ! 425: ! 426: if(!(dma[channel].csr & DMA_SUPDATE)||(channel==CHANNEL_EN_RX)) { // Ethernet: this needs to be checked! ! 427: dma[channel].next = dma[channel].start; ! 428: dma[channel].limit = dma[channel].stop; ! 429: } ! 430: ! 431: dma[channel].csr |= DMA_COMPLETE; ! 432: ! 433: set_interrupt(interrupt, SET_INT); ! 434: // set_interrupt(INT_SCSI_DMA, RELEASE_INT); ! 435: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.