this repo has no description
at main 149 lines 3.9 kB view raw
1/* 2 SCSIEMDV.c 3 4 Copyright (C) 2004 Philip Cummins, Paul C. Pratt 5 6 You can redistribute this file and/or modify it under the terms 7 of version 2 of the GNU General Public License as published by 8 the Free Software Foundation. You should have received a copy 9 of the license along with this file; see the file COPYING. 10 11 This file is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 license for more details. 15*/ 16 17/* 18 Small Computer System Interface EMulated DeVice 19 20 Emulates the SCSI found in the Mac Plus. 21 22 This code adapted from "SCSI.c" in vMac by Philip Cummins. 23*/ 24 25/* NCR5380 chip emulation by Yoav Shadmi, 1998 */ 26 27#include "PICOMMON.h" 28#include "MINEM68K.h" 29 30#include "SCSIEMDV.h" 31 32#define scsiRd 0x00 33#define scsiWr 0x01 34 35#define sCDR 0x00 /* current scsi data register (r/o) */ 36#define sODR 0x00 /* output data register (w/o) */ 37#define sICR 0x02 /* initiator command register (r/w) */ 38#define sMR 0x04 /* mode register (r/w) */ 39#define sTCR 0x06 /* target command register (r/w) */ 40#define sCSR 0x08 /* current SCSI bus status (r/o) */ 41#define sSER 0x08 /* select enable register (w/o) */ 42#define sBSR 0x0A /* bus and status register (r/o) */ 43#define sDMAtx 0x0A /* start DMA send (w/o) */ 44#define sIDR 0x0C /* input data register (r/o) */ 45#define sTDMArx 0x0C /* start DMA target receive (w/o) */ 46#define sRESET 0x0E /* reset parity/interrupt (r/o) */ 47#define sIDMArx 0x0E /* start DMA initiator receive (w/o) */ 48 49#define kSCSI_Size 0x00010 50 51LOCALVAR ui3b SCSI[kSCSI_Size]; 52 53GLOBALPROC SCSI_Reset(void) 54{ 55 int i; 56 57 for (i = 0; i < kSCSI_Size; i++) { 58 SCSI[i] = 0; 59 } 60} 61 62LOCALPROC SCSI_BusReset(void) 63{ 64 SCSI[scsiRd + sCDR] = 0; 65 SCSI[scsiWr + sODR] = 0; 66 SCSI[scsiRd + sICR] = 0x80; 67 SCSI[scsiWr + sICR] &= 0x80; 68 SCSI[scsiRd + sMR] &= 0x40; 69 SCSI[scsiWr + sMR] &= 0x40; 70 SCSI[scsiRd + sTCR] = 0; 71 SCSI[scsiWr + sTCR] = 0; 72 SCSI[scsiRd + sCSR] = 0x80; 73 SCSI[scsiWr + sSER] = 0; 74 SCSI[scsiRd + sBSR] = 0x10; 75 SCSI[scsiWr + sDMAtx] = 0; 76 SCSI[scsiRd + sIDR] = 0; 77 SCSI[scsiWr + sTDMArx] = 0; 78 SCSI[scsiRd + sRESET] = 0; 79 SCSI[scsiWr + sIDMArx] = 0; 80#if 0 81 SCSI[scsiRd + sODR + dackWr] = 0; 82 SCSI[scsiWr + sIDR + dackRd] = 0; 83#endif 84 85 /* The missing piece of the puzzle.. :) */ 86 put_ram_word(0xb22, get_ram_word(0xb22) | 0x8000); 87} 88 89LOCALPROC SCSI_Check(void) 90{ 91 /* 92 The arbitration select/reselect scenario 93 [stub.. doesn't really work...] 94 */ 95 if ((SCSI[scsiWr + sODR] >> 7) == 1) { 96 /* Check if the Mac tries to be an initiator */ 97 if ((SCSI[scsiWr + sMR] & 1) == 1) { 98 /* the Mac set arbitration in progress */ 99 /* 100 stub! tell the mac that there 101 is arbitration in progress... 102 */ 103 SCSI[scsiRd + sICR] |= 0x40; 104 /* ... that we didn't lose arbitration ... */ 105 SCSI[scsiRd + sICR] &= ~ 0x20; 106 /* 107 ... and that there isn't a higher priority ID present... 108 */ 109 SCSI[scsiRd + sCDR] = 0x00; 110 111 /* 112 ... the arbitration and selection/reselection is 113 complete. the initiator tries to connect to the SCSI 114 device, fails and returns after timeout. 115 */ 116 } 117 } 118 119 /* check the chip registers, AS SET BY THE CPU */ 120 if ((SCSI[scsiWr + sICR] >> 7) == 1) { 121 /* Check Assert RST */ 122 SCSI_BusReset(); 123 } else { 124 SCSI[scsiRd + sICR] &= ~ 0x80; 125 SCSI[scsiRd + sCSR] &= ~ 0x80; 126 } 127 128 if ((SCSI[scsiWr + sICR] >> 2) == 1) { 129 /* Check Assert SEL */ 130 SCSI[scsiRd + sCSR] |= 0x02; 131 SCSI[scsiRd + sBSR] = 0x10; 132 } else { 133 SCSI[scsiRd + sCSR] &= ~ 0x02; 134 } 135} 136 137GLOBALFUNC ui5b SCSI_Access(ui5b Data, blnr WriteMem, CPTR addr) 138{ 139 if (addr < (kSCSI_Size / 2)) { 140 addr *= 2; 141 if (WriteMem) { 142 SCSI[addr + 1] = Data; 143 SCSI_Check(); 144 } else { 145 Data = SCSI[addr]; 146 } 147 } 148 return Data; 149}