this repo has no description
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}