Annotation of previous/src/dma.c, revision 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.