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

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: }

unix.superglobalmegacorp.com

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