Annotation of previous/src/esp.c, revision 1.1

1.1     ! root        1: /* Emulation of NCR53C90(A)
        !             2:  Includes informations from QEMU-NeXT
        !             3:  */
        !             4: 
        !             5: #include "ioMem.h"
        !             6: #include "ioMemTables.h"
        !             7: #include "m68000.h"
        !             8: #include "configuration.h"
        !             9: #include "esp.h"
        !            10: #include "sysReg.h"
        !            11: #include "dma.h"
        !            12: #include "scsi.h"
        !            13: 
        !            14: #define LOG_SCSI_LEVEL LOG_DEBUG
        !            15: 
        !            16: 
        !            17: #define IO_SEG_MASK    0x1FFFF
        !            18: 
        !            19: typedef enum {
        !            20:     DISCONNECTED,
        !            21:     RESELECTABLE,
        !            22:     SELECTING,
        !            23:     INITIATOR,
        !            24:     DISABLINGSEL,
        !            25:     COMPLETING,
        !            26:     DMAING,
        !            27:     ACCEPTINGMSG,
        !            28:     SENDINGMSG,
        !            29:     PADDING,
        !            30:     GETTINGMSG,
        !            31:     GETTINGLUN,
        !            32:     IGNOREILLCMD
        !            33: } SCSI_STATE;
        !            34: 
        !            35: SCSI_STATE state;
        !            36: 
        !            37: /* SCSI DMA Command/Status Registers */
        !            38: Uint8 csr_value0;
        !            39: Uint8 csr_value1;
        !            40: 
        !            41: /* ESP Registers */
        !            42: Uint8 readtranscountl;
        !            43: Uint8 readtranscounth;
        !            44: Uint8 writetranscountl;
        !            45: Uint8 writetranscounth;
        !            46: Uint8 fifo;
        !            47: Uint8 command;
        !            48: Uint8 status;
        !            49: Uint8 selectbusid;
        !            50: Uint8 intstatus;
        !            51: Uint8 selecttimeout;
        !            52: Uint8 seqstep;
        !            53: Uint8 syncperiod;
        !            54: Uint8 fifoflags;
        !            55: Uint8 syncoffset;
        !            56: Uint8 configuration;
        !            57: Uint8 clockconv;
        !            58: Uint8 esptest;
        !            59: 
        !            60: /* ESP Status Variables */
        !            61: Uint8 irq_status;
        !            62: Uint8 mode_dma;
        !            63: 
        !            64: /* ESP FIFO */
        !            65: #define ESP_FIFO_SIZE 16
        !            66: Uint8 esp_fifo[ESP_FIFO_SIZE];
        !            67: Uint8 fifo_read_ptr;
        !            68: Uint8 fifo_write_ptr;
        !            69: 
        !            70: /* Command buffer */
        !            71: #define SCSI_CMD_BUF_SIZE 16
        !            72: Uint8 commandbuf[SCSI_CMD_BUF_SIZE];
        !            73: int command_len;
        !            74: 
        !            75: 
        !            76: /* Experimental */
        !            77: 
        !            78: //Uint32 dma;
        !            79: Uint32 do_cmdvar;
        !            80: Uint32 dma_counter;
        !            81: Uint32 data_len;
        !            82: Uint32 dma_left;
        !            83: Uint32 cmdlen;
        !            84: Uint32 async_len;
        !            85: Uint8 *async_buf;
        !            86: int dma_enabled = 1;
        !            87: void (*dma_cb);
        !            88: 
        !            89: static bool no_target=false;
        !            90: static int bus_id_command=0;
        !            91: 
        !            92: 
        !            93: void SCSI_CSR0_Read(void) {
        !            94:     IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = csr_value0;
        !            95:        Log_Printf(LOG_SCSI_LEVEL,"SCSI DMA control read at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
        !            96: }
        !            97: 
        !            98: void SCSI_CSR0_Write(void) {
        !            99:     Log_Printf(LOG_SCSI_LEVEL,"SCSI DMA control write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
        !           100:     csr_value0 = IoMem[IoAccessCurrentAddress & IO_SEG_MASK];
        !           101:         
        !           102:     if ((csr_value0 & 0x04) == 0x04) {
        !           103:         Log_Printf(LOG_SCSI_LEVEL, "flush FIFO\n");
        !           104:     }
        !           105:     if ((csr_value0 & 0x01) == 0x01) {
        !           106:         Log_Printf(LOG_SCSI_LEVEL, "scsi chip is WD33C92\n");
        !           107:     } else {
        !           108:         Log_Printf(LOG_SCSI_LEVEL, "scsi chip is NCR53C90\n");
        !           109:     }
        !           110:     if ((csr_value0 & 0x02) == 0x02) {
        !           111:         Log_Printf(LOG_SCSI_LEVEL, "reset scsi chip\n");
        !           112:         esp_reset_hard();
        !           113:     }
        !           114:     if ((csr_value0 & 0x08) == 0x08) {
        !           115:         Log_Printf(LOG_SCSI_LEVEL, "dma from scsi to mem\n");
        !           116:     }
        !           117:     if ((csr_value0 & 0x10) == 0x10) {
        !           118:         // set_interrupt(INT_SCSI_DMA, SET_INT);
        !           119:         // esp_raise_irq(); 
        !           120:         Log_Printf(LOG_SCSI_LEVEL, "mode DMA\n");
        !           121:     }else{
        !           122:         // set_interrupt(INT_SCSI_DMA, RELEASE_INT);
        !           123:         //esp_lower_irq();
        !           124:         Log_Printf(LOG_SCSI_LEVEL, "mode PIO\n");
        !           125:     }
        !           126:     if ((csr_value0 & 0x20) == 0x20) {
        !           127:         Log_Printf(LOG_SCSI_LEVEL, "interrupt enable");
        !           128:     }
        !           129:     switch (csr_value0 & 0xC0) {
        !           130:         case 0x00:
        !           131:             Log_Printf(LOG_SCSI_LEVEL, "10 MHz clock\n");
        !           132:             break;
        !           133:         case 0x40:
        !           134:             Log_Printf(LOG_SCSI_LEVEL, "12.5 MHz clock\n");
        !           135:             break;
        !           136:         case 0xC0:
        !           137:             Log_Printf(LOG_SCSI_LEVEL, "16.6 MHz clock\n");
        !           138:             break;
        !           139:         case 0x80:
        !           140:             Log_Printf(LOG_SCSI_LEVEL, "20 MHz clock\n");
        !           141:             break;
        !           142:         default:
        !           143:             break;
        !           144:     }
        !           145: }
        !           146: 
        !           147: void SCSI_CSR1_Read(void) {
        !           148:     
        !           149:     /*
        !           150:      * dma fifo status register
        !           151:      */
        !           152: #define        S5RDMAS_STATE           0xc0    /* DMA/SCSI bank state */
        !           153: #define        S5RDMAS_D0S0            0x00    /* DMA rdy for bank 0, SCSI in bank 0 */
        !           154: #define        S5RDMAS_D0S1            0x40    /* DMA req for bank 0, SCSI in bank 1 */
        !           155: #define        S5RDMAS_D1S1            0x80    /* DMA rdy for bank 1, SCSI in bank 1 */
        !           156: #define        S5RDMAS_D1S0            0xc0    /* DMA req for bank 1, SCSI in bank 0 */
        !           157: #define        S5RDMAS_OUTFIFOMASK     0x38    /* output fifo byte (INVERTED) */
        !           158: #define        S5RDMAS_INFIFOMASK      0x07    /* input fifo byte (INVERTED) */
        !           159:     
        !           160: #define        S5RDMA_FIFOALIGNMENT    4       /* mass storage chip buffer size */
        !           161: 
        !           162:     
        !           163:     IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = 0x80;
        !           164:        Log_Printf(LOG_SCSI_LEVEL,"SCSI DMA FIFO status read at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
        !           165: }
        !           166: 
        !           167: void SCSI_CSR1_Write(void) {
        !           168:        Log_Printf(LOG_SCSI_LEVEL,"SCSI DMA FIFO status write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
        !           169:     csr_value1 = IoMem[IoAccessCurrentAddress & IO_SEG_MASK];
        !           170: }
        !           171: 
        !           172: 
        !           173: /* ESP Registers */
        !           174: 
        !           175: void SCSI_TransCountL_Read(void) { // 0x02014000
        !           176:     IoMem[IoAccessCurrentAddress & IO_SEG_MASK]=readtranscountl;
        !           177:        Log_Printf(LOG_SCSI_LEVEL,"ESP TransCountL read at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
        !           178: }
        !           179: 
        !           180: void SCSI_TransCountL_Write(void) {
        !           181:     writetranscountl=IoMem[IoAccessCurrentAddress & IO_SEG_MASK];
        !           182:        Log_Printf(LOG_SCSI_LEVEL,"ESP TransCountL write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
        !           183: }
        !           184: 
        !           185: void SCSI_TransCountH_Read(void) { // 0x02014001
        !           186:     IoMem[IoAccessCurrentAddress & IO_SEG_MASK]=readtranscounth;
        !           187:        Log_Printf(LOG_SCSI_LEVEL,"ESP TransCoundH read at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
        !           188: }
        !           189: 
        !           190: void SCSI_TransCountH_Write(void) {
        !           191:     writetranscounth=IoMem[IoAccessCurrentAddress & IO_SEG_MASK];
        !           192:        Log_Printf(LOG_SCSI_LEVEL,"ESP TransCountH write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
        !           193: }
        !           194: 
        !           195: void SCSI_FIFO_Read(void) { // 0x02014002
        !           196:     if ((fifo_write_ptr - fifo_read_ptr) > 0) {
        !           197:         IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = esp_fifo[fifo_read_ptr];
        !           198:         Log_Printf(LOG_SCSI_LEVEL,"ESP FIFO read at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
        !           199:         Log_Printf(LOG_WARN,"ESP FIFO Read, size = %i, val=%02x", fifo_write_ptr - fifo_read_ptr, IoMem[IoAccessCurrentAddress & IO_SEG_MASK]);
        !           200:         fifo_read_ptr++;
        !           201:         fifoflags = fifoflags - 1;
        !           202: //        esp_raise_irq();
        !           203:     } else {
        !           204:         IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = 0x00;
        !           205:         Log_Printf(LOG_WARN, "ESP FIFO is empty!\n");
        !           206:     } 
        !           207: }
        !           208: 
        !           209: void SCSI_FIFO_Write(void) {
        !           210:     esp_fifo[fifo_write_ptr] = IoMem[IoAccessCurrentAddress & IO_SEG_MASK];
        !           211:     fifo_write_ptr++;
        !           212:     fifoflags = fifoflags + 1;
        !           213:     Log_Printf(LOG_SCSI_LEVEL,"ESP FIFO write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
        !           214:     
        !           215:     if (fifo_write_ptr > (ESP_FIFO_SIZE - 1)) {
        !           216:         Log_Printf(LOG_SCSI_LEVEL, "ESP FIFO overflow! Resetting FIFO!\n");
        !           217:         esp_flush_fifo();
        !           218:     }
        !           219:     Log_Printf(LOG_SCSI_LEVEL,"ESP FIFO size = %i", fifo_write_ptr - fifo_read_ptr);
        !           220: }
        !           221: 
        !           222: void SCSI_Command_Read(void) { // 0x02014003
        !           223:     IoMem[IoAccessCurrentAddress & IO_SEG_MASK]=command;
        !           224:        Log_Printf(LOG_SCSI_LEVEL,"ESP Command read at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
        !           225: }
        !           226: 
        !           227: void SCSI_Command_Write(void) {
        !           228:     command=IoMem[IoAccessCurrentAddress & IO_SEG_MASK];
        !           229:        Log_Printf(LOG_SCSI_LEVEL,"ESP Command write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
        !           230:     
        !           231:     if (command & CMD_DMA) {
        !           232:         readtranscountl = writetranscountl;
        !           233:         readtranscounth = writetranscounth;
        !           234:         status &= ~STAT_TC;
        !           235:         mode_dma = 1;
        !           236:     } else {
        !           237:         mode_dma = 0;
        !           238:     }
        !           239:     
        !           240:     if ((command & CMD_CMD) != CMD_NOP)
        !           241:        status = (status&STAT_MASK)|STAT_CD;
        !           242:     
        !           243:     switch (command & CMD_CMD) {
        !           244:             /* Miscellaneous */
        !           245:         case CMD_NOP:
        !           246:             Log_Printf(LOG_SCSI_LEVEL, "ESP Command: NOP\n");
        !           247:            // status = (status&STAT_MASK)|STAT_ST;
        !           248:             break;
        !           249:         case CMD_FLUSH:
        !           250:             Log_Printf(LOG_SCSI_LEVEL,"ESP Command: flush FIFO\n");
        !           251:             esp_flush_fifo();
        !           252:            status = (status&STAT_MASK)|STAT_ST;
        !           253:             break;
        !           254:         case CMD_RESET:
        !           255:             Log_Printf(LOG_SCSI_LEVEL,"ESP Command: reset chip\n");
        !           256:             esp_reset_hard();
        !           257:             break;
        !           258:         case CMD_BUSRESET:
        !           259:             //Reset all Devices on SCSI bus
        !           260:             Log_Printf(LOG_WARN, "ESP Command: reset SCSI bus\n");
        !           261:             esp_reset_soft();
        !           262:             if (!(configuration & CFG1_RESREPT)) {
        !           263:                 intstatus = INTR_RST;
        !           264:                 status = (status&STAT_MASK)|STAT_MI;
        !           265:                seqstep = 0;
        !           266:                 Log_Printf(LOG_SCSI_LEVEL,"Bus Reset raising IRQ configuration=%x\n",configuration);
        !           267:                 //esp_raise_irq(); // temporary disabled for experiment! moved to read config reg.
        !           268:             } else 
        !           269:                 Log_Printf(LOG_SCSI_LEVEL,"Bus Reset not interrupting configuration=%x\n",configuration);
        !           270:             break;
        !           271:             /* Disconnected */
        !           272:         case CMD_SEL:
        !           273:             Log_Printf(LOG_SCSI_LEVEL, "ESP Command: select without ATN sequence\n");
        !           274:            //abort();
        !           275:             handle_satn(); // enabled for experiment!
        !           276:             break;
        !           277:         case CMD_SELATN:
        !           278:             Log_Printf(LOG_SCSI_LEVEL, "ESP Command: select with ATN sequence\n");
        !           279:             handle_satn();
        !           280:             break;
        !           281:         case CMD_SELATNS:
        !           282:             Log_Printf(LOG_SCSI_LEVEL, "ESP Command: select with ATN and stop sequence\n");
        !           283:            abort();
        !           284:             break;
        !           285:         case CMD_ENSEL:
        !           286:             Log_Printf(LOG_WARN, "ESP Command: enable selection/reselection no_target=%x intstatus=%x status=%x seqstep=%x",
        !           287:                        no_target,intstatus,status,seqstep);
        !           288:             if (no_target) {
        !           289:                 Log_Printf(LOG_SCSI_LEVEL, "ESP retry timeout");
        !           290:                 intstatus = INTR_RESEL;
        !           291:                seqstep = SEQ_SELTIMEOUT;
        !           292:             } else {
        !           293:                 Log_Printf(LOG_WARN, "Reselect: target %i, lun %i\n", SCSIcommand.target, SCSIcommand.lun);
        !           294:                 status = (status&STAT_MASK)|STAT_MI;
        !           295:                 intstatus = INTR_RESEL|INTR_FC;
        !           296:                 esp_fifo[0] = (1<<SCSIcommand.target); // target bit
        !           297:                 esp_fifo[1] = 0x80|(SCSIcommand.lun&0x07); // identify message (identifymask|(lun&lun_mask))
        !           298:                 fifoflags = 2;
        !           299:                 fifo_write_ptr = 2;
        !           300:                 fifo_read_ptr = 0;
        !           301: //                esp_raise_irq();
        !           302:             }
        !           303:             break;
        !           304:         case CMD_DISSEL:
        !           305:             Log_Printf(LOG_SCSI_LEVEL, "ESP Command: disable selection/reselection\n");
        !           306:             intstatus = INTR_FC;
        !           307:             esp_raise_irq();
        !           308:             break;
        !           309:             /* Initiator */
        !           310:         case CMD_TI:
        !           311:             Log_Printf(LOG_SCSI_LEVEL, "ESP Command: transfer information\n");
        !           312:             handle_ti();
        !           313:            esp_raise_irq();
        !           314:             break;
        !           315:         case CMD_ICCS:
        !           316:             Log_Printf(LOG_SCSI_LEVEL, "ESP Command: initiator command complete sequence\n");
        !           317:             write_response();
        !           318:             intstatus = INTR_FC;
        !           319:             status = (status&STAT_MASK)|STAT_MI;
        !           320:             esp_raise_irq();
        !           321:             break;
        !           322:         case CMD_MSGACC:
        !           323:             Log_Printf(LOG_SCSI_LEVEL, "ESP Command: message accepted\n");
        !           324:             status = (status&STAT_MASK)|STAT_ST;          
        !           325:             intstatus = INTR_BS;
        !           326:             seqstep = SEQ_0;
        !           327:             fifoflags = 0x00;
        !           328:             esp_raise_irq();
        !           329:             break;            
        !           330:         case CMD_PAD:
        !           331:             Log_Printf(LOG_SCSI_LEVEL, "ESP Command: transfer pad\n");
        !           332:             status = STAT_TC | STAT_DI;
        !           333:             intstatus = INTR_FC;
        !           334:             seqstep = SEQ_0;
        !           335:             esp_raise_irq();
        !           336:             break;
        !           337:         case CMD_SATN:
        !           338:             Log_Printf(LOG_SCSI_LEVEL, "ESP Command: set ATN\n");
        !           339:             break;
        !           340:             /* Target */
        !           341:         case CMD_SEMSG:
        !           342:         case CMD_SESTAT:
        !           343:         case CMD_SEDAT:
        !           344:         case CMD_DISSEQ:
        !           345:         case CMD_TERMSEQ:
        !           346:         case CMD_TCCS:
        !           347:         case CMD_RMSGSEQ:
        !           348:         case CMD_RCOMM:
        !           349:         case CMD_RDATA:
        !           350:         case CMD_RCSEQ:
        !           351: 
        !           352:             status = (status&STAT_MASK)|STAT_ST;          
        !           353:             intstatus = INTR_ILL;
        !           354:             seqstep = SEQ_0;
        !           355:             fifoflags = 0x00;
        !           356:             esp_raise_irq();
        !           357:             Log_Printf(LOG_WARN, "ESP Command: Target commands not supported!\n");
        !           358:             break;
        !           359:         case CMD_DIS:
        !           360: 
        !           361: 
        !           362:             Log_Printf(LOG_WARN, "ESP Command: DISCONNECT !\n");
        !           363:             status = (status&STAT_MASK)|STAT_ST;          
        !           364:             intstatus = INTR_DC; 
        !           365:             seqstep = SEQ_0;
        !           366:             break;
        !           367: 
        !           368:             
        !           369:         default:
        !           370:             Log_Printf(LOG_WARN, "ESP Command: Illegal command!\n");
        !           371:             intstatus |= INTR_ILL;
        !           372:             break;
        !           373:     }
        !           374: }
        !           375: 
        !           376: void SCSI_Status_Read(void) { // 0x02014004
        !           377:     IoMem[IoAccessCurrentAddress & IO_SEG_MASK]=status;
        !           378:        Log_Printf(LOG_SCSI_LEVEL,"ESP Status read at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
        !           379: }
        !           380: 
        !           381: void SCSI_SelectBusID_Write(void) {
        !           382:     selectbusid=IoMem[IoAccessCurrentAddress & IO_SEG_MASK];
        !           383:        Log_Printf(LOG_SCSI_LEVEL,"ESP SelectBusID write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
        !           384:        no_target=false;
        !           385: }
        !           386: 
        !           387: void SCSI_IntStatus_Read(void) { // 0x02014005
        !           388:     IoMem[IoAccessCurrentAddress & IO_SEG_MASK]=intstatus;
        !           389:     Log_Printf(LOG_SCSI_LEVEL,"ESP IntStatus read at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
        !           390:     
        !           391:     if (irq_status == 1) {
        !           392:             intstatus = 0x00;
        !           393:             status &= ~(STAT_VGC | STAT_PE | STAT_GE );
        !           394:             seqstep = SEQ_0;
        !           395:             esp_lower_irq();
        !           396:     }
        !           397: }
        !           398: 
        !           399: void SCSI_SelectTimeout_Write(void) {
        !           400:     selecttimeout=IoMem[IoAccessCurrentAddress & IO_SEG_MASK];
        !           401:        Log_Printf(LOG_SCSI_LEVEL,"ESP SelectTimeout write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
        !           402: }
        !           403: 
        !           404: void SCSI_SeqStep_Read(void) { // 0x02014006
        !           405:     IoMem[IoAccessCurrentAddress & IO_SEG_MASK]=seqstep;
        !           406:        Log_Printf(LOG_SCSI_LEVEL,"ESP SeqStep read at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
        !           407: }
        !           408: 
        !           409: void SCSI_SyncPeriod_Write(void) {
        !           410:     syncperiod=IoMem[IoAccessCurrentAddress & IO_SEG_MASK];
        !           411:        Log_Printf(LOG_SCSI_LEVEL,"ESP SyncPeriod write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
        !           412: }
        !           413: 
        !           414: void SCSI_FIFOflags_Read(void) { // 0x02014007
        !           415:     IoMem[IoAccessCurrentAddress & IO_SEG_MASK]=fifoflags;
        !           416:        Log_Printf(LOG_WARN,"ESP FIFOflags read at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
        !           417: }
        !           418: 
        !           419: void SCSI_SyncOffset_Write(void) {
        !           420:     syncoffset=IoMem[IoAccessCurrentAddress & IO_SEG_MASK];
        !           421:        Log_Printf(LOG_SCSI_LEVEL,"ESP SyncOffset write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
        !           422: }
        !           423: 
        !           424: void SCSI_Configuration_Read(void) { // 0x02014008
        !           425:     IoMem[IoAccessCurrentAddress & IO_SEG_MASK]=configuration;
        !           426:        Log_Printf(LOG_SCSI_LEVEL,"ESP Configuration read at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
        !           427:     esp_raise_irq(); // experimental!
        !           428: }
        !           429: 
        !           430: void SCSI_Configuration_Write(void) {
        !           431:     configuration=IoMem[IoAccessCurrentAddress & IO_SEG_MASK];
        !           432:        Log_Printf(LOG_SCSI_LEVEL,"ESP Configuration write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
        !           433: }
        !           434: 
        !           435: void SCSI_ClockConv_Write(void) { // 0x02014009
        !           436:     IoMem[IoAccessCurrentAddress & IO_SEG_MASK]=clockconv;
        !           437:        Log_Printf(LOG_SCSI_LEVEL,"ESP ClockConv write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
        !           438: }
        !           439: 
        !           440: void SCSI_Test_Write(void) { // 0x0201400a
        !           441:     esptest=IoMem[IoAccessCurrentAddress & IO_SEG_MASK];
        !           442:        Log_Printf(LOG_SCSI_LEVEL,"ESP Test write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
        !           443: }
        !           444: 
        !           445: /* System reads this register to check if we use old or new SCSI controller.
        !           446:  * Return 0 to report old chip. */
        !           447: void SCSI_Conf2_Read(void) { // 0x0201400b
        !           448:     if (ConfigureParams.System.nSCSI == NCR53C90)
        !           449:         IoMem[IoAccessCurrentAddress&IO_SEG_MASK] = 0x00;
        !           450: }
        !           451: 
        !           452: 
        !           453: /* Functions */
        !           454: 
        !           455: void esp_reset_hard(void) {
        !           456:     Log_Printf(LOG_WARN, "ESP hard reset\n");
        !           457:     /* hard reset */
        !           458:     clockconv = 0x02;
        !           459:     configuration &= ~0xF8; // clear chip test mode, parity enable, parity test, scsi request/int disable, slow cable mode
        !           460:     syncperiod = 0x05;
        !           461:     syncoffset = 0x00;
        !           462:     intstatus = 0x00;
        !           463:     status &= ~(STAT_VGC | STAT_PE | STAT_GE); // need valid group code bit? clear transfer complete aka valid group code, parity error, gross error
        !           464:     esp_flush_fifo();
        !           465:     esp_lower_irq();
        !           466:     esp_reset_soft();
        !           467: }
        !           468: 
        !           469: void esp_reset_soft(void) {
        !           470:     status &= ~STAT_TC; // clear transfer count zero
        !           471:     
        !           472:     /* incomplete, need to work on everything below this point */
        !           473:     
        !           474:     dma_cb = NULL; // clear DMA interface - how to do this?
        !           475:     mode_dma = 0;
        !           476:     readtranscountl = 0x00;
        !           477:     readtranscounth = 0x00;
        !           478:     writetranscountl = 0x00;
        !           479:     writetranscounth = 0x00;
        !           480: 
        !           481:     seqstep = 0x00;
        !           482: 
        !           483:     command = 0x00;
        !           484:     selectbusid = 0x00;
        !           485:     selecttimeout= 0x00;
        !           486:     fifoflags = 0x00;
        !           487:     esptest = 0x00;
        !           488: }
        !           489: 
        !           490: void esp_raise_irq(void) {
        !           491:     if(!(status & STAT_INT)) {
        !           492:         status |= STAT_INT;
        !           493:         irq_status = 1;
        !           494:         
        !           495:         set_interrupt(INT_SCSI, SET_INT);
        !           496:         
        !           497:         //Log_Printf(LOG_SCSI_LEVEL, "Raise IRQ\n");
        !           498:         char s[16];
        !           499:         switch (state) {
        !           500:             case DISCONNECTED: sprintf(s, "disconntected"); break;
        !           501:             case RESELECTABLE: sprintf(s, "reselectable"); break;
        !           502:             case SELECTING: sprintf(s, "selecting"); break;
        !           503:             case INITIATOR: sprintf(s, "initiator"); break;
        !           504:             case DISABLINGSEL: sprintf(s, "diablingsel"); break;
        !           505:             case COMPLETING: sprintf(s, "completing"); break;
        !           506:             case DMAING: sprintf(s, "dmaing"); break;
        !           507:             case ACCEPTINGMSG: sprintf(s, "acceptingmsg"); break;
        !           508:             case SENDINGMSG: sprintf(s, "sendingmsg"); break;
        !           509:             case PADDING: sprintf(s, "padding"); break;
        !           510:             case GETTINGMSG: sprintf(s, "gettingmsg"); break;
        !           511:             case GETTINGLUN: sprintf(s, "gettinglun"); break;
        !           512:             case IGNOREILLCMD: sprintf(s, "ignoreillcmd"); break;
        !           513:             default: sprintf(s, "unknown"); break;
        !           514:         }
        !           515: //        Log_Printf(LOG_WARN, "Raise IRQ: state: %s\n", s);
        !           516:         Log_Printf(LOG_WARN, "Raise IRQ:");
        !           517:         switch (status&STAT_MI) {
        !           518:             case STAT_DO: sprintf(s, "data out"); break;
        !           519:             case STAT_DI: sprintf(s, "data in"); break;
        !           520:             case STAT_CD: sprintf(s, "command"); break;
        !           521:             case STAT_ST: sprintf(s, "status"); break;
        !           522:             case STAT_MI: sprintf(s, "msg in"); break;
        !           523:             case STAT_MO: sprintf(s, "msg out"); break;
        !           524:             default: sprintf(s, "unknown"); break;
        !           525:         }
        !           526:         Log_Printf(LOG_WARN, "Status: %02x (phase: %s, %s%s)\n", status, s,
        !           527:                    status&STAT_TC?"transfer complete":"",
        !           528:                    status&STAT_INT?", interrupt":"");
        !           529:         Log_Printf(LOG_WARN, "Sequence Step: %02x\n", seqstep);
        !           530:         Log_Printf(LOG_WARN, "Interrupt Status: %02x (%s%s%s%s%s%s%s%s)\n", intstatus,
        !           531:                    intstatus&INTR_RST?"bus reset, ":"",
        !           532:                    intstatus&INTR_BS?"bus service, ":"",
        !           533:                    intstatus&INTR_DC?"disconnected, ":"",
        !           534:                    intstatus&INTR_FC?"function compl, ":"",
        !           535:                    intstatus&INTR_ILL?"illegal comm, ":"",
        !           536:                    intstatus&INTR_RESEL?"reselected, ":"",
        !           537:                    intstatus&INTR_SEL?"selected, ":"",
        !           538:                    intstatus&INTR_SELATN?"selected w ATN":"");
        !           539:     }
        !           540: }
        !           541: 
        !           542: void esp_lower_irq(void) {
        !           543:     if (status & STAT_INT) {
        !           544:         status &= ~STAT_INT;
        !           545:         irq_status = 0;
        !           546:         
        !           547:         set_interrupt(INT_SCSI, RELEASE_INT);
        !           548:         
        !           549:         Log_Printf(LOG_SCSI_LEVEL, "Lower IRQ\n");
        !           550:     }
        !           551: }
        !           552: 
        !           553: void esp_flush_fifo(void) {
        !           554:     fifo_read_ptr = 0;
        !           555:     fifo_write_ptr = 0;
        !           556:     esp_fifo[0] = 0;
        !           557:     fifoflags &= 0xE0;
        !           558: }
        !           559: 
        !           560: Uint32 get_cmd (void) {
        !           561:     
        !           562:     if(mode_dma == 1) {
        !           563:         command_len = readtranscountl | (readtranscounth << 8);
        !           564:         //dma_memory_read(command_len);
        !           565:         memcpy(commandbuf, dma_read_buffer, command_len);
        !           566:     } else {
        !           567:         command_len = fifo_write_ptr - fifo_read_ptr;
        !           568:         memcpy(commandbuf, esp_fifo, command_len);
        !           569:         
        !           570:         esp_flush_fifo();
        !           571:     }
        !           572:     Log_Printf(LOG_SCSI_LEVEL, "get_cmd: len %i", command_len);
        !           573:     
        !           574:     return command_len;
        !           575: }
        !           576: 
        !           577: void do_cmd(void) {
        !           578:     Uint8 busid = selectbusid;
        !           579:     do_busid_cmd(busid);
        !           580: }
        !           581: 
        !           582: void handle_satn(void) {
        !           583:     Uint8 scsi_command_group;
        !           584:     
        !           585:     get_cmd(); // make get_cmd void function?
        !           586:     // clear valid command status
        !           587:     status &= ~STAT_VGC;
        !           588: 
        !           589:     /* Decode command to determine the command group and thus the
        !           590:      * length of the incoming command. Set "valid group code" bit
        !           591:      * in status register if the group is 0, 1, 5, 6, or 7 (group
        !           592:      * 2 is also valid on NCR53C90A).
        !           593:      */
        !           594:     scsi_command_group = (commandbuf[1] & 0xE0) >> 5;
        !           595:     if(scsi_command_group < 3 || scsi_command_group > 4) {
        !           596:         if(ConfigureParams.System.nSCSI == NCR53C90 && scsi_command_group == 2) {
        !           597:             Log_Printf(LOG_WARN, "Invalid command group %i on NCR53C90\n", scsi_command_group);
        !           598:         } else {
        !           599:             status |= STAT_VGC;
        !           600:         }
        !           601:     } else {
        !           602:         Log_Printf(LOG_WARN, "Invalid command group %i on NCR53C90A\n", scsi_command_group);
        !           603:     }
        !           604: 
        !           605:     if (command_len != 0)
        !           606:         do_cmd();
        !           607: }
        !           608: 
        !           609: void do_busid_cmd(Uint8 busid) {
        !           610:     int lun,lun2;
        !           611:     int target = busid & BUSID_DID;
        !           612:     Log_Printf(LOG_SCSI_LEVEL, "do_busid_cmd: busid $%02x",busid);
        !           613: 
        !           614:     lun = (commandbuf[0]&0x07);
        !           615:     
        !           616:     scsi_command_analyzer(commandbuf, command_len, target,lun);
        !           617:     data_len = SCSIcommand.transfer_data_len;
        !           618: 
        !           619:     if ((target >= ESP_MAX_DEVS) || (SCSIcommand.timeout==true)) { // experimental
        !           620:     Log_Printf(LOG_SCSI_LEVEL, "No target found !! Target %d Lun %d raise irq %s at %d",target,lun,__FILE__,__LINE__);
        !           621:         intstatus = INTR_DC;
        !           622:         seqstep = 0x00;//SEQ_SELTIMEOUT;
        !           623:         status = (status&STAT_MASK)|STAT_MI; // seems weird... http://permalink.gmane.org/gmane.os.netbsd.ports.next68k/305
        !           624:         no_target=true;
        !           625:         esp_raise_irq();
        !           626:        return;
        !           627:     }
        !           628: 
        !           629:     if (SCSIcommand.nodevice==true) { // experimental
        !           630:     Log_Printf(LOG_SCSI_LEVEL, "No device found !! Target %d Lun %d raise irq %s at %d",target,lun,__FILE__,__LINE__);
        !           631:        
        !           632:         status = (status&STAT_MASK)|STAT_ST;
        !           633:         intstatus = INTR_BS|INTR_FC;//INTR_DC;
        !           634:         seqstep = SEQ_CD;//SEQ_SELTIMEOUT;
        !           635:         esp_raise_irq();
        !           636:         return;
        !           637:     }
        !           638:     
        !           639:     status = (status&STAT_MASK)| STAT_ST;
        !           640: 
        !           641:     if (data_len != 0) {
        !           642:         Log_Printf(LOG_SCSI_LEVEL, "executing command\n");
        !           643:         status = STAT_TC;
        !           644:         
        !           645:         dma_left = 0;
        !           646:         dma_counter = 0;
        !           647:         
        !           648:         if(SCSIcommand.transferdirection_todevice == 0) {
        !           649:             Log_Printf(LOG_SCSI_LEVEL, "DATA IN\n");
        !           650:             status = (status&STAT_MASK)| STAT_DI;
        !           651:         } else {
        !           652:             Log_Printf(LOG_SCSI_LEVEL, "DATA OUT\n");
        !           653:             status = (status&STAT_MASK)| STAT_DO;
        !           654:         }
        !           655:     esp_transfer_data();
        !           656:     }
        !           657:     
        !           658:     intstatus = INTR_BS | INTR_FC;
        !           659:     seqstep = SEQ_CD;
        !           660:     
        !           661:     esp_raise_irq();   
        !           662: }
        !           663: 
        !           664: 
        !           665: void esp_transfer_data(void) {
        !           666:     Log_Printf(LOG_SCSI_LEVEL, "transfer %d/%d\n", dma_left, data_len);
        !           667:     
        !           668: //    async_len = len;
        !           669: //    async_buf = scsi_req_get_buf(req);
        !           670:     if(dma_left) {
        !           671:         esp_do_dma();
        !           672:     } else if(dma_counter != 0 && data_len <= 0) {
        !           673:         esp_dma_done();
        !           674:     }
        !           675: }
        !           676: 
        !           677: 
        !           678: void esp_do_dma(void) {
        !           679:     
        !           680:     Log_Printf(LOG_SCSI_LEVEL, "call esp_do_dma\n");
        !           681: 
        !           682:     Uint32 len;
        !           683:     int to_device;
        !           684:     
        !           685:     Uint32 dma_translen; // experimental
        !           686:     dma_translen = readtranscountl | (readtranscounth << 8); // experimental
        !           687:     Log_Printf(LOG_SCSI_LEVEL, "call dma_write\n"); // experimental
        !           688:     dma_memory_write(dma_write_buffer, dma_translen, CHANNEL_SCSI);//experimental !!
        !           689: 
        !           690:     
        !           691:     to_device = SCSIcommand.transferdirection_todevice;
        !           692:     
        !           693:     len = dma_left;
        !           694:     
        !           695:     if(do_cmdvar){
        !           696:         abort();
        !           697:     }
        !           698:     if(async_len == 0) {
        !           699: 
        !           700:     }
        !           701:     if(len > async_len) {
        !           702:         len = async_len;
        !           703:     }
        !           704:     if(to_device) {
        !           705: //        dma_memory_read(async_buf, len);
        !           706:     } else { 
        !           707: //        dma_memory_write(async_buf, len);
        !           708:     }
        !           709:     
        !           710:     dma_left -= len;
        !           711:     async_buf += len;
        !           712:     async_len -= len;
        !           713:     
        !           714:     if(to_device)
        !           715:         data_len += len;
        !           716:     else
        !           717:         data_len -= len;
        !           718:     
        !           719:     if(async_len == 0) {
        !           720: //        scsi_req_continue(current_req);
        !           721:         
        !           722:         if (to_device || dma_left != 0 || (fifo_write_ptr - fifo_read_ptr) == 0) {
        !           723: //            return;
        !           724:         }
        !           725:     }
        !           726:     esp_dma_done();
        !           727: }
        !           728: 
        !           729: void esp_dma_done(void) {
        !           730:     Log_Printf(LOG_SCSI_LEVEL, "call esp_dma_done\n");
        !           731:     status = (status&STAT_MASK)|STAT_ST;
        !           732:     status |= STAT_TC;
        !           733:     intstatus = INTR_BS;
        !           734:     seqstep = 0;
        !           735:     fifoflags = 0;
        !           736:     readtranscountl = 0;
        !           737:     readtranscounth = 0;
        !           738: }
        !           739: 
        !           740: 
        !           741: // transfer information
        !           742: void handle_ti(void){
        !           743:     Uint32 dma_len, min_len;
        !           744:     
        !           745:     dma_len = readtranscountl | (readtranscounth << 8);
        !           746:     
        !           747:     if(dma_len == 0) {
        !           748:         dma_len = 0x10000;
        !           749:     }
        !           750:     
        !           751:     dma_counter = dma_len;
        !           752:     
        !           753:     if(do_cmdvar)
        !           754:         min_len = (dma_len < 32) ? dma_len : 32;
        !           755:     else
        !           756:         min_len = (dma_len > data_len) ? dma_len : data_len;
        !           757:     Log_Printf(LOG_SCSI_LEVEL, "Transfer Information len %d\n", min_len);
        !           758:     
        !           759:     if(mode_dma) {
        !           760:         dma_left = min_len;
        !           761:         status &= ~STAT_TC;
        !           762:         esp_do_dma();
        !           763:     }else if(do_cmdvar){
        !           764:         Log_Printf(LOG_SCSI_LEVEL, "Command len: %i\n",cmdlen);
        !           765:         data_len = 0;
        !           766:         cmdlen = 0;
        !           767:         do_cmdvar = 0;
        !           768:         do_cmd();
        !           769:         return;
        !           770:     }
        !           771: }
        !           772: 
        !           773: void esp_command_complete (void) {
        !           774:     Log_Printf(LOG_SCSI_LEVEL, "SCSI Command complete\n");
        !           775:     if (data_len != 0)
        !           776:         Log_Printf(LOG_SCSI_LEVEL, "SCSI Command completed unexpectedly\n");
        !           777:     data_len = 0;
        !           778:     dma_left = 0;
        !           779:     async_len = 0;
        !           780:     
        !           781: //    if(status) {
        !           782: //        Log_Printf(LOG_SCSI_LEVEL, "Command failed\n");
        !           783: //    }
        !           784: //  status = status; return status, not status register!!
        !           785:     status = STAT_ST;
        !           786:     seqstep = SEQ_0;
        !           787:     if(mode_dma)    
        !           788:        esp_dma_done();
        !           789: }
        !           790: 
        !           791: void write_response(void) {
        !           792:     Log_Printf(LOG_SCSI_LEVEL, "Transfer status: $%02x\n", SCSIcommand.returnCode);
        !           793:     esp_fifo[0] = SCSIcommand.returnCode; // status
        !           794:     esp_fifo[1] = 0x00; // message
        !           795:     
        !           796:     if(mode_dma == 1) {
        !           797:         dma_memory_write(esp_fifo, 2, CHANNEL_SCSI);
        !           798:         status = (status & STAT_MASK) | STAT_TC | STAT_ST;
        !           799:         intstatus = INTR_BS | INTR_FC;
        !           800:         seqstep = SEQ_CD;
        !           801:     } else {
        !           802:         status = (status & STAT_MASK) | STAT_ST;
        !           803:         fifo_read_ptr = 0;
        !           804:         fifo_write_ptr = 2;
        !           805:         fifoflags = (fifoflags & 0xE0) | 2;
        !           806:     }
        !           807: }

unix.superglobalmegacorp.com

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