]> Shamusworld >> Repos - virtualjaguar/blob - src/cdrom.cpp
3b6b4748a5e056f2580e601a79be33cbf83138a7
[virtualjaguar] / src / cdrom.cpp
1 //
2 // CD handler
3 //
4 // by David Raingeard
5 // GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Caz (BeOS)
6 // Cleanups/fixes by James L. Hammons
7 //
8
9 #include "m68k.h"
10 #include "cdrom.h"
11
12
13 #define CDROM_LOG                                                                       // For CDROM logging, obviously
14
15 /*
16 BUTCH     equ  $DFFF00          ; base of Butch=interrupt control register, R/W
17 DSCNTRL   equ  BUTCH+4          ; DSA control register, R/W
18 DS_DATA   equ  BUTCH+$A         ; DSA TX/RX data, R/W
19 I2CNTRL   equ  BUTCH+$10        ; i2s bus control register, R/W
20 SBCNTRL   equ  BUTCH+$14        ; CD subcode control register, R/W
21 SUBDATA   equ  BUTCH+$18        ; Subcode data register A
22 SUBDATB   equ  BUTCH+$1C        ; Subcode data register B
23 SB_TIME   equ  BUTCH+$20        ; Subcode time and compare enable (D24)
24 FIFO_DATA equ  BUTCH+$24        ; i2s FIFO data
25 I2SDAT1   equ  BUTCH+$24        ; i2s FIFO data
26 I2SDAT2   equ  BUTCH+$28        ; i2s FIFO data
27 2C = ?
28
29 ;
30 ; Butch's hardware registers
31 ;
32 ;BUTCH     equ  $DFFF00         ;base of Butch=interrupt control register, R/W
33 ;
34 ;  When written (Long):
35 ;
36 ;  bit0 - set to enable interrupts
37 ;  bit1 - enable CD data FIFO half full interrupt
38 ;  bit2 - enable CD subcode frame-time interrupt (@ 2x spped = 7ms.)
39 ;  bit3 - enable pre-set subcode time-match found interrupt
40 ;  bit4 - CD module command transmit buffer empty interrupt
41 ;  bit5 - CD module command receive buffer full
42 ;  bit6 - CIRC failure interrupt
43 ;
44 ;  bit7-31  reserved, set to 0 
45 ;
46 ;  When read (Long):
47 ;
48 ;  bit0-8 reserved
49 ;
50 ;  bit9  - CD data FIFO half-full flag pending
51 ;  bit10 - Frame pending
52 ;  bit11 - Subcode data pending
53 ;  bit12 - Command to CD drive pending (trans buffer empty if 1)
54 ;  bit13 - Response from CD drive pending (rec buffer full if 1)
55 ;  bit14 - CD uncorrectable data error pending
56 ;
57 ;   Offsets from BUTCH
58 ;
59 O_DSCNTRL   equ  4              ; DSA control register, R/W
60 O_DS_DATA   equ  $A             ; DSA TX/RX data, R/W
61 ;
62 O_I2CNTRL   equ  $10            ; i2s bus control register, R/W
63 ;
64 ;  When read:
65 ;
66 ;  b0 - I2S data from drive is ON if 1
67 ;  b1 - I2S path to Jerry is ON if 1
68 ;  b2 - reserved
69 ;  b3 - host bus width is 16 if 1, else 32
70 ;  b4 - FIFO state is not empty if 1
71 ;
72 O_SBCNTRL   equ  $14            ; CD subcode control register, R/W
73 O_SUBDATA   equ  $18            ; Subcode data register A
74 O_SUBDATB   equ  $1C            ; Subcode data register B
75 O_SB_TIME   equ  $20            ; Subcode time and compare enable (D24)
76 O_FIFODAT   equ  $24            ; i2s FIFO data
77 O_I2SDAT2   equ  $28            ; i2s FIFO data (old)
78 */
79 char * BReg[11] = { "BUTCH", "DSCNTRL", "DS_DATA", "I2CNTRL", "SBCNTRL", "SUBDATA", "SUBDATB",
80         "SB_TIME", "FIFO_DATA", "I2SDAT1", "I2SDAT2" };
81 extern char * whoName[9];
82
83
84 static uint8 cdrom_ram[0x100];
85 static uint16 cdrom_cmd = 0;
86
87
88 void cdrom_init(void)
89 {
90 }
91
92 void cdrom_reset(void)
93 {
94         memset(cdrom_ram, 0x00, 0x100);
95         cdrom_cmd = 0;
96 }
97
98 void cdrom_done(void)
99 {
100 }
101
102 //
103 // CD-ROM memory access functions
104 //
105
106 uint8 CDROMReadByte(uint32 offset, uint32 who/*=UNKNOWN*/)
107 {
108 #ifdef CDROM_LOG
109         if ((offset & 0xFF) < 11 * 4)
110                 WriteLog("[%s] ", BReg[(offset & 0xFF) / 4]);
111         WriteLog("CDROM: %s reading byte $%02X from $%08X [68K PC=$%08X]\n", whoName[who], offset, cdrom_ram[offset & 0xFF], m68k_get_reg(NULL, M68K_REG_PC));
112 #endif
113         return cdrom_ram[offset & 0xFF];
114 }
115
116 uint16 CDROMReadWord(uint32 offset, uint32 who/*=UNKNOWN*/)
117 {
118         offset &= 0xFF;
119
120         uint16 data = 0x0000;
121         
122         if (offset == 0x00) 
123                 data = 0x0000;
124         else if (offset == 0x02) 
125                 data = 0x2000;
126         else if (offset == 0x0A) 
127         {
128                 if (cdrom_cmd == 0x7001)
129                         data = cdrom_cmd;
130                 else
131                         data = 0x0400;
132         }
133         else
134                 data = (cdrom_ram[offset+0] << 8) | cdrom_ram[offset+1];
135
136 //Returning $00000008 seems to cause it to use the starfield. Dunno why.
137 //Temp, for testing...
138 //Very interesting...! Seems to control sumthin' or other...
139 /*if (offset == 0x2C || offset == 0x2E)
140         data = 0xFFFF;//*/
141 if (offset == 0x2C)
142         data = 0x0000;
143 if (offset == 0x2E)
144         data = 0x0008;//*/ // $0000 000F ($B) works, but not $0000 00001... or $7
145
146 #ifdef CDROM_LOG
147         if ((offset & 0xFF) < 11 * 4)
148                 WriteLog("[%s] ", BReg[(offset & 0xFF) / 4]);
149         WriteLog("CDROM: %s reading word $%04X from $%08X [68K PC=$%08X]\n", whoName[who], data, offset, m68k_get_reg(NULL, M68K_REG_PC));
150 #endif
151         return data;
152 }
153
154 void CDROMWriteByte(uint32 offset, uint8 data, uint32 who/*=UNKNOWN*/)
155 {
156         offset &= 0xFF;
157         cdrom_ram[offset] = data;
158
159 #ifdef CDROM_LOG
160         if ((offset & 0xFF) < 11 * 4)
161                 WriteLog("[%s] ", BReg[(offset & 0xFF) / 4]);
162         WriteLog("CDROM: %s writing byte $%02X at $%08X [68K PC=$%08X]\n", whoName[who], data, offset, m68k_get_reg(NULL, M68K_REG_PC));
163 #endif
164 }
165
166 void CDROMWriteWord(uint32 offset, uint16 data, uint32 who/*=UNKNOWN*/)
167 {
168         offset &= 0xFF;
169         cdrom_ram[offset+0] = (data >> 8) & 0xFF;
170         cdrom_ram[offset+1] = data & 0xFF;
171                 
172         // command register
173 /*
174         if (offset==0x0A)
175         {
176                 cdrom_cmd=data;
177                 if ((data&0xff00)==0x1500)
178                 {
179                         WriteLog("CDROM: setting mode 0x%.2x\n",data&0xff);
180                         return;
181                 }
182                 if (data==0x7001)
183                 {
184                         uint32 offset=cdrom_ram[0x00];
185                         offset<<=8;
186                         offset|=cdrom_ram[0x01];
187                         offset<<=8;
188                         offset|=cdrom_ram[0x02];
189                         offset<<=8;
190                         offset|=cdrom_ram[0x03];
191
192                         uint32 size=cdrom_ram[0x04];
193                         offset<<=8;
194                         offset|=cdrom_ram[0x05];
195                         
196                         WriteLog("CDROM: READ(0x%.8x, 0x%.4x) [68k pc=0x%.8x]\n", offset, size, m68k_get_reg(NULL, M68K_REG_PC));
197                         return;
198                 }
199                 else
200                         WriteLog("CDROM: unknown command 0x%.4x\n",data);
201         }
202 //*/
203 #ifdef CDROM_LOG
204         if ((offset & 0xFF) < 11 * 4)
205                 WriteLog("[%s] ", BReg[(offset & 0xFF) / 4]);
206         WriteLog("CDROM: %s writing word $%04X at $%08X [68K PC=$%08X]\n", whoName[who], data, offset, m68k_get_reg(NULL, M68K_REG_PC));
207 #endif
208 }