Annotation of previous/src/dma.c, revision 1.1.1.2

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:         }
1.1.1.2 ! root      160: #if 1 /* hack for nextstep 0.8 */
        !           161:     if(ConfigureParams.System.nMachineType == NEXT_CUBE030) { // for 68030 based NeXT Computer
        !           162:         if ((channel == CHANNEL_R2M) || (channel == CHANNEL_M2R)) {
        !           163:             dma[channel].csr = DMA_COMPLETE;
        !           164:             set_interrupt(interrupt, SET_INT);
        !           165:         }
        !           166:     }
        !           167: #endif
1.1       root      168:     }
                    169:     if(writecsr & DMA_SETSUPDATE) {
                    170:         dma[channel].csr |= DMA_SUPDATE;
                    171:         Log_Printf(LOG_DMA_LEVEL,"DMA set single update");
                    172:     }
                    173:     if(writecsr & DMA_CLRCOMPLETE) {
                    174:         dma[channel].csr &= ~DMA_COMPLETE;
                    175:         Log_Printf(LOG_DMA_LEVEL,"DMA clear complete conditional");
                    176: 
                    177:        set_interrupt(interrupt, RELEASE_INT); // also somewhat experimental...
                    178:     }
                    179:     if(writecsr & DMA_RESET) {
                    180:         dma[channel].csr &= ~(DMA_COMPLETE | DMA_SUPDATE | DMA_ENABLE | DMA_DEV2M);
                    181:         Log_Printf(LOG_WARN,"DMA reset");
                    182:         
                    183:        set_interrupt(interrupt, RELEASE_INT); // also somewhat experimental...
                    184:     }
                    185:     if(writecsr & DMA_INITBUF) { // needs to be filled
                    186:         Log_Printf(LOG_DMA_LEVEL,"DMA initialize buffers");
                    187:     }
                    188: }
                    189: 
                    190: void DMA_Saved_Next_Read(void) { // 0x02004000
                    191:     int channel = get_channel(IoAccessCurrentAddress-0x3FF0);
                    192:     IoMem_WriteLong(IoAccessCurrentAddress & IO_SEG_MASK, dma[channel].saved_next);
                    193:        Log_Printf(LOG_DMA_LEVEL,"DMA SNext read at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].saved_next, m68k_getpc());
                    194: }
                    195: 
                    196: void DMA_Saved_Next_Write(void) {
                    197:     int channel = get_channel(IoAccessCurrentAddress-0x3FF0);
                    198:     dma[channel].saved_next = IoMem_ReadLong(IoAccessCurrentAddress & IO_SEG_MASK);
                    199:     Log_Printf(LOG_DMA_LEVEL,"DMA SNext write at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].saved_next, m68k_getpc());
                    200: }
                    201: 
                    202: void DMA_Saved_Limit_Read(void) { // 0x02004004
                    203:     int channel = get_channel(IoAccessCurrentAddress-0x3FF4);
                    204:     IoMem_WriteLong(IoAccessCurrentAddress & IO_SEG_MASK, dma[channel].saved_limit);
                    205:        Log_Printf(LOG_DMA_LEVEL,"DMA SLimit read at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].saved_limit, m68k_getpc());
                    206: }
                    207: 
                    208: void DMA_Saved_Limit_Write(void) {
                    209:     int channel = get_channel(IoAccessCurrentAddress-0x3FF4);
                    210:     dma[channel].saved_limit = IoMem_ReadLong(IoAccessCurrentAddress & IO_SEG_MASK);
                    211:     Log_Printf(LOG_DMA_LEVEL,"DMA SLimit write at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].saved_limit, m68k_getpc());
                    212: }
                    213: 
                    214: void DMA_Saved_Start_Read(void) { // 0x02004008
                    215:     int channel = get_channel(IoAccessCurrentAddress-0x3FF8);
                    216:     IoMem_WriteLong(IoAccessCurrentAddress & IO_SEG_MASK, dma[channel].saved_start);
                    217:        Log_Printf(LOG_DMA_LEVEL,"DMA SStart read at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].saved_start, m68k_getpc());
                    218: }
                    219: 
                    220: void DMA_Saved_Start_Write(void) {
                    221:     int channel = get_channel(IoAccessCurrentAddress-0x3FF8);
                    222:     dma[channel].saved_start = IoMem_ReadLong(IoAccessCurrentAddress & IO_SEG_MASK);
                    223:     Log_Printf(LOG_DMA_LEVEL,"DMA SStart write at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].saved_start, m68k_getpc());
                    224: }
                    225: 
                    226: void DMA_Saved_Stop_Read(void) { // 0x0200400c
                    227:     int channel = get_channel(IoAccessCurrentAddress-0x3FFC);
                    228:     IoMem_WriteLong(IoAccessCurrentAddress & IO_SEG_MASK, dma[channel].saved_stop);
                    229:        Log_Printf(LOG_DMA_LEVEL,"DMA SStop read at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].saved_stop, m68k_getpc());
                    230: }
                    231: 
                    232: void DMA_Saved_Stop_Write(void) {
                    233:     int channel = get_channel(IoAccessCurrentAddress-0x3FFC);
                    234:     dma[channel].saved_stop = IoMem_ReadLong(IoAccessCurrentAddress & IO_SEG_MASK);
                    235:     Log_Printf(LOG_DMA_LEVEL,"DMA SStop write at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].saved_stop, m68k_getpc());
                    236: }
                    237: 
                    238: void DMA_Next_Read(void) { // 0x02004010
                    239:     int channel = get_channel(IoAccessCurrentAddress-0x4000);
                    240:     IoMem_WriteLong(IoAccessCurrentAddress & IO_SEG_MASK, dma[channel].next);
                    241:        Log_Printf(LOG_DMA_LEVEL,"DMA Next read at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].next, m68k_getpc());
1.1.1.2 ! root      242:     /* Experimental! Release interrupt here */
        !           243:     int interrupt = get_interrupt_type(channel);
        !           244:     set_interrupt(interrupt, RELEASE_INT); // also somewhat experimental...
1.1       root      245: }
                    246: 
                    247: void DMA_Next_Write(void) {
                    248:     int channel = get_channel(IoAccessCurrentAddress-0x4000);
                    249:     dma[channel].next = IoMem_ReadLong(IoAccessCurrentAddress & IO_SEG_MASK);
                    250:     Log_Printf(LOG_DMA_LEVEL,"DMA Next write at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].next, m68k_getpc());
                    251: }
                    252: 
                    253: void DMA_Limit_Read(void) { // 0x02004014
                    254:     int channel = get_channel(IoAccessCurrentAddress-0x4004);
                    255:     IoMem_WriteLong(IoAccessCurrentAddress & IO_SEG_MASK, dma[channel].limit);
                    256:        Log_Printf(LOG_DMA_LEVEL,"DMA Limit read at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].limit, m68k_getpc());
                    257: }
                    258: 
                    259: void DMA_Limit_Write(void) {
                    260:     int channel = get_channel(IoAccessCurrentAddress-0x4004);
                    261:     dma[channel].limit = IoMem_ReadLong(IoAccessCurrentAddress & IO_SEG_MASK);
                    262:     Log_Printf(LOG_DMA_LEVEL,"DMA Limit write at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].limit, m68k_getpc());
                    263: }
                    264: 
                    265: void DMA_Start_Read(void) { // 0x02004018
                    266:     int channel = get_channel(IoAccessCurrentAddress-0x4008);
                    267:     IoMem_WriteLong(IoAccessCurrentAddress & IO_SEG_MASK, dma[channel].start);
                    268:        Log_Printf(LOG_DMA_LEVEL,"DMA Start read at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].start, m68k_getpc());
                    269: }
                    270: 
                    271: void DMA_Start_Write(void) {
                    272:     int channel = get_channel(IoAccessCurrentAddress-0x4008);
                    273:     dma[channel].start = IoMem_ReadLong(IoAccessCurrentAddress & IO_SEG_MASK);
                    274:     Log_Printf(LOG_DMA_LEVEL,"DMA Start write at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].start, m68k_getpc());
                    275: }
                    276: 
                    277: void DMA_Stop_Read(void) { // 0x0200401c
                    278:     int channel = get_channel(IoAccessCurrentAddress-0x400C);
                    279:     IoMem_WriteLong(IoAccessCurrentAddress & IO_SEG_MASK, dma[channel].stop);
                    280:        Log_Printf(LOG_DMA_LEVEL,"DMA Stop read at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].stop, m68k_getpc());
                    281: }
                    282: 
                    283: void DMA_Stop_Write(void) {
                    284:     int channel = get_channel(IoAccessCurrentAddress-0x400C);
                    285:     dma[channel].stop = IoMem_ReadLong(IoAccessCurrentAddress & IO_SEG_MASK);
                    286:     Log_Printf(LOG_DMA_LEVEL,"DMA Stop write at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].stop, m68k_getpc());
                    287: }
                    288: 
                    289: void DMA_Init_Read(void) { // 0x02004210
                    290:     int channel = get_channel(IoAccessCurrentAddress-0x4200);
                    291:     IoMem_WriteLong(IoAccessCurrentAddress & IO_SEG_MASK, dma[channel].init);
                    292:        Log_Printf(LOG_DMA_LEVEL,"DMA Init read at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].init, m68k_getpc());
                    293: }
                    294: 
                    295: void DMA_Init_Write(void) {
                    296:     int channel = get_channel(IoAccessCurrentAddress-0x4200);
                    297:     dma[channel].init = IoMem_ReadLong(IoAccessCurrentAddress & IO_SEG_MASK);
                    298:     Log_Printf(LOG_DMA_LEVEL,"DMA Init write at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].init, m68k_getpc());
                    299: }
                    300: 
                    301: void DMA_Size_Read(void) { // 0x02004214
                    302:     int channel = get_channel(IoAccessCurrentAddress-0x4204);
                    303:     IoMem_WriteLong(IoAccessCurrentAddress & IO_SEG_MASK, dma[channel].size);
                    304:        Log_Printf(LOG_DMA_LEVEL,"DMA Size read at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].size, m68k_getpc());
                    305: }
                    306: 
                    307: void DMA_Size_Write(void) {
                    308:     int channel = get_channel(IoAccessCurrentAddress-0x4204);
                    309:     dma[channel].size = IoMem_ReadLong(IoAccessCurrentAddress & IO_SEG_MASK);
                    310:     Log_Printf(LOG_DMA_LEVEL,"DMA Size write at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].size, m68k_getpc());
                    311: }
                    312: 
                    313: 
                    314: 
                    315: /* DMA Functions */
                    316: 
                    317: /*void copy_to_scsidma_buffer(Uint8 device_outbuf[], int outbuf_size) {
                    318:     memcpy(dma_buffer, device_outbuf, outbuf_size);
                    319: }*/
                    320: 
                    321: /*void dma_clear_memory(Uint32 datalength) {
                    322:     Uint32 start_addr;
                    323:     Uint32 end_addr;
                    324:     
                    325:     if(dma_init == 0)
                    326:         start_addr = dma_next;
                    327:     else
                    328:         start_addr = dma_init;
                    329:     
                    330:     end_addr = start_addr + datalength;
                    331:     
                    332:     NEXTMemory_Clear(start_addr, end_addr);
                    333: }*/
                    334: 
                    335: void dma_memory_read(Uint8 *buf, Uint32 *size, int channel) {
                    336:     Uint32 base_addr;
                    337:     Uint8 align = 16;
                    338:     Uint32 size_count = 0;
                    339:     Uint32 read_addr;
                    340:     int interrupt = get_interrupt_type(channel);
                    341:     
                    342:     if ((channel == CHANNEL_EN_TX) && !ConfigureParams.System.bTurbo)
                    343:         *size = (dma[channel].limit&0x0FFFFFFF) - (dma[channel].init&0x0FFFFFFF);
                    344:     else
                    345:         *size = (dma[channel].limit&0x0FFFFFFF) - (dma[channel].next&0x0FFFFFFF);
                    346:     
                    347:     if(channel == CHANNEL_EN_RX || channel == CHANNEL_EN_TX)
                    348:         align = 32;
                    349:     
                    350: //    if((*size % align) != 0) {
                    351: //        *size -= *size % align;
                    352: //        *size += align;
                    353: //    }
                    354:     
                    355:     if(dma[channel].init == 0)
                    356:         base_addr = dma[channel].next;
                    357:     else
                    358:         base_addr = dma[channel].init;
                    359:     
                    360:     Log_Printf(LOG_WARN, "[DMA] Read from mem: at $%08x, %i bytes",base_addr, *size);
                    361:     for (size_count = 0; size_count < *size; size_count++) {
                    362:         read_addr = base_addr + size_count;
                    363:         buf[size_count] = NEXTMemory_ReadByte(read_addr);
                    364:     }
                    365:     printf("READ FROM MEMORY: %02x\n", buf[0]);
                    366: 
                    367:     dma[channel].csr |= DMA_COMPLETE | DMA_SUPDATE;
                    368:     
                    369:     set_interrupt(interrupt, SET_INT);
                    370: }
                    371: 
                    372: 
                    373: void dma_memory_write(Uint8 *buf, Uint32 size, int channel) {
                    374:     Uint32 base_addr, tail_addr;
                    375:     Uint8 align = 16;
                    376:     Uint32 size_count = 0;
                    377:     Uint32 write_addr;
                    378:     Uint32 dma_tail = 0;
                    379:     int interrupt = get_interrupt_type(channel);
                    380:     
                    381:     if(channel == CHANNEL_EN_RX || channel == CHANNEL_EN_TX)
                    382:         align = 32;
                    383:         
                    384: //    if((size % align) != 0) {
                    385: //        size -= size % align;
                    386: //        size += align;
                    387: //    }
                    388: 
                    389:     
                    390:     if(dma[channel].init == 0) {
                    391:         base_addr = dma[channel].next;
                    392:         dma_tail = 0;
                    393:     } else {
                    394:         base_addr = dma[channel].init;
                    395:         
                    396:         /* If the transfer size is greater than (limit - init):
                    397:          * Copy residual bytes to physical addresses at start. */
                    398:         if (size > (dma[channel].limit - dma[channel].init)) {
                    399:             tail_addr = dma[channel].start;
                    400:             dma_tail = size - (dma[channel].limit - dma[channel].init);
                    401:             size = (dma[channel].limit - dma[channel].init);
                    402:             Log_Printf(LOG_WARN, "[DMA] Residual bytes: %i", dma_tail);
                    403:         }
                    404:     }
                    405: 
                    406:     Log_Printf(LOG_WARN, "[DMA] Write to mem: at $%08x, %i bytes",base_addr,size);
                    407:     for (size_count = 0; size_count < size; size_count++) {
                    408:         write_addr = base_addr + size_count;
                    409:         NEXTMemory_WriteByte(write_addr, buf[size_count]);
                    410:     }
                    411:     
                    412:     /* If there are residual bytes, copy them to physical addresses starting
                    413:      * at "start". */
                    414:     
                    415:     if (dma_tail) {
                    416:         Log_Printf(LOG_WARN, "[DMA] Write residual bytes at $%08x, %i bytes",tail_addr,dma_tail);
                    417:         for (size_count = 0; size_count < dma_tail; size_count++) {
                    418:             write_addr = tail_addr + size_count;
                    419:             NEXTMemory_WriteByte(write_addr, buf[size+size_count]);
                    420:         }
                    421:     }
                    422: 
                    423:     
                    424:     /* Test read/write */
                    425:     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));
                    426: //    NEXTMemory_WriteByte(base_addr, 0x77);
                    427: //    Uint8 testvar = NEXTMemory_ReadByte(base_addr);
                    428: //    Log_Printf(LOG_DMA_LEVEL, "Write Test: $%02x at $%08x", testvar, base_addr);
                    429:     
                    430:     dma[channel].init = 0;
                    431:     
                    432:     /* saved limit is checked to calculate packet size
                    433:      by both the rom and netbsd */ 
                    434:     dma[channel].saved_limit = dma[channel].next + size;
                    435:     dma[channel].saved_next  = dma[channel].next;
                    436:     
                    437:     if(!(dma[channel].csr & DMA_SUPDATE)||(channel==CHANNEL_EN_RX)) { // Ethernet: this needs to be checked!
                    438:         dma[channel].next = dma[channel].start;
                    439:         dma[channel].limit = dma[channel].stop;
                    440:     }
                    441: 
                    442:     dma[channel].csr |= DMA_COMPLETE;
                    443:     
                    444:     set_interrupt(interrupt, SET_INT);
                    445: //    set_interrupt(INT_SCSI_DMA, RELEASE_INT);
                    446: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.