LC89515: Difference between revisions

From NeoGeo Development Wiki
Jump to navigation Jump to search
No edit summary
(Registers and commands)
 
Line 1: Line 1:
[[File:cd2_lc89515.jpg|right|thumb|Sanyo LC89515 chip found on a CDM3-2 board.]]
[[File:cd2_lc89515.jpg|right|thumb|Sanyo LC89515 chip found on a CDM3-2 board.]]


CD-1 Host and error corrector. Used to [[Loading files|load files]] in CD systems.
Sanyo CD-ROM host and error correction chip, also known as RCHIP. Used to [[Loading files|load files]] in CD systems. It uses a 64KiB RAM buffer (2 32KiB RAM chips), which is able to store up to 27 CD-ROM sectors.


==Datasheet==
DMA copy speed from buffer to [[DRAM]]s can go up to 2.3MiB/s (16.9344MHz / 7 ?)


Incomplete official datasheet: [[http://www.datasheetcatalog.org/datasheet/sanyo/LC89515.pdf]]
The NeoGeo CD does not use the C2 pointer error correction.
LC89510 (with register definitions): [[http://www.datasheetarchive.com/LC8951-datasheet.html#]]


Complete datasheet: [[http://megadrive.org/~elbarto/md/Docs/Official%20Sega%20CD%20Manual/LC8951/]]
The NeoGeo [[CDZ]] uses the {{Chipname|LC89513}}.


==Notes==
=Datasheet=


If CD command FIFO is not empty, status FIFO[1] = 15 (busy ?).
Complete datasheet: [[https://www.megadrive.org/elbarto/megacd/Official%20Sega%20CD%20Manual/LC8951/]]


*Command 0: Nop ?
=Pinout=
*Command 1:
CDEmuStop();
NeoCDAssyStatus = 0x0E;
*Command 2:
status FIFO[1]=command FIFO[3]
**0:
UINT8* ChannelData = CDEmuReadQChannel();


NeoCDCommsStatusFIFO[2] = ChannelData[1] / 10;
[[File:Lc89515.png]]
NeoCDCommsStatusFIFO[3] = ChannelData[1] % 10;


NeoCDCommsStatusFIFO[4] = ChannelData[2] / 10;
=Registers=
NeoCDCommsStatusFIFO[5] = ChannelData[2] % 10;


NeoCDCommsStatusFIFO[6] = ChannelData[3] / 10;
Registers access is done through {{Reg|$FF0101}} and {{Reg|$FF0103}}.
NeoCDCommsStatusFIFO[7] = ChannelData[3] % 10;
NeoCDCommsStatusFIFO[8] = ChannelData[7];
**1:
UINT8* ChannelData = CDEmuReadQChannel();


NeoCDCommsStatusFIFO[2] = ChannelData[4] / 10;
Read and writes auto-increments the register address except from register #0. After register #15, the address loops back to #0.
NeoCDCommsStatusFIFO[3] = ChannelData[4] % 10;


NeoCDCommsStatusFIFO[4] = ChannelData[5] / 10;
{|class="wikitable
NeoCDCommsStatusFIFO[5] = ChannelData[5] % 10;
! ||colspan=2|Read||colspan=2|Write
|-
!#||Name||Definition||Name||Definition
|-
|0
|COMIN
|Command FIFO input (unused in NeoGeo CD ?)
|SBOUT
|Status byte output (unused in NeoGeo CD ?)
|-
|1
|IFSTAT
|{{8BitRegister|/CMDI|1|/DTEI|1|/DECI|1|1|1|/DTBSY|1|/STBSY|1|/DTEN|1|/STEN|1}}
|IFCTRL
|{{8BitRegister|CMDIEN|1|DTEIEN|1|DECIEN|1|/CMDBK|1|/DTWAI|1|/STWAI|1|/DOUTEN|1|/SOUTEN|1}}
|-
|2
|DBCL
|colspan=3|Data byte counter 8 LSBs
|-
|3
|DBCH
|{{8BitRegister|DTEI|4|Data byte counter 4 MSBs|4}}
|DBCH
|{{8BitRegister|-|4|Data byte counter 4 MSBs|4}}
|-
|4
|HEAD0
|
{|class="wikitable
|SHDREN=0||SHDREN=1
|-
|Header minutes||Subheader file #
|}
|DACL
|Data start address 8 LSBs
|-
|5
|HEAD1
|
{|class="wikitable
|SHDREN=0||SHDREN=1
|-
|Header seconds||Subheader channel #
|}
|DACH
|Data start address 8 MSBs
|-
|6
|HEAD2
|
{|class="wikitable
|SHDREN=0||SHDREN=1
|-
|Header frames||Subheader submode #
|}
|DTTRG
|Any write triggers a transfer start
|-
|7
|HEAD3
|
{|class="wikitable
|SHDREN=0||SHDREN=1
|-
|Header mode (01)||Subheader coding info
|}
|DTACK
|Any write acknowledges the transfer interrupt
|-
|8
|PTL
|Last decoded sector address 8 LSBs
|WAL
|Pointer to start of data to be loaded 8 LSBs
|-
|9
|PTH
|Last decoded sector address 8 MSBs
|WAH
|Pointer to start of data to be loaded 8 MSBs
|-
|10
|WAL
|Pointer to start of data to be loaded 8 LSBs
|CTRL0
|{{8BitRegister|DCEN|1|EDCRQ|1|E01RQ|1|AUTORQ|1|ERAMRQ|1|WRRQ|1|QRQ|1|PRQ|1}}
|-
|11
|WAH
|Pointer to start of data to be loaded 8 MSBs
|CTRL1
|{{8BitRegister|SYIEN|1|SYDEN|1|DSCREN|1|COWREN|1|MODRQ|1|FORMRQ|1|-|1|SHDREN|1}}
|-
|12
|STAT0
|{{8BitRegister|CRCOK|1|ILSYNC|1|NOSYNC|1|LBLK|1|WSHORT|1|SBLK|1|ERABLK|1|UCEBLK|1}}
|PTL
|Pointer to start of data to be decoded 8 MSBs
|-
|13
|STAT1
|{{8BitRegister|MINERA|1|SECERA|1|BLKERA|1|MODERA|1|SH0ERA|1|SH1ERA|1|SH2ERA|1|SH3ERA|1}}
Error flags for HEAD0~HEAD3
|PTH
|Pointer to start of data to be decoded 8 LSBs
|-
|14
|STAT2
|{{8BitRegister|-|4|MODE|1|FORM|1|-|2}}
|Unused
|
|-
|15
|STAT3
|{{8BitRegister|/VALST|1|WLONG|1|-|6}}
|RESET
|
|}


NeoCDCommsStatusFIFO[6] = ChannelData[6] / 10;
=Notes=
NeoCDCommsStatusFIFO[7] = ChannelData[6] % 10;


NeoCDCommsStatusFIFO[8] = ChannelData[7];
If CD command FIFO is not empty, status FIFO[1] = 15 (busy ?).
**2:
UINT8* ChannelData = CDEmuReadQChannel();


NeoCDCommsStatusFIFO[2] = ChannelData[0] / 10;
* Command 0: Nop ?
NeoCDCommsStatusFIFO[3] = ChannelData[0] % 10;
* Command 1:
 
<pre>
 
CDEmuStop();
NeoCDCommsStatusFIFO[8] = ChannelData[7];
NeoCDAssyStatus = 0x0E;
**3:
</pre>
UINT8* TOCEntry = CDEmuReadTOC(-2);
* Command 2:
 
<pre>
NeoCDCommsStatusFIFO[2] = TOCEntry[0] / 10;
status FIFO[1]=command FIFO[3]
NeoCDCommsStatusFIFO[3] = TOCEntry[0] % 10;
</pre>
 
** 0: Read Q subcode first 6 digits
NeoCDCommsStatusFIFO[4] = TOCEntry[1] / 10;
Data in FIFO[2~7] & FIFO[8]
NeoCDCommsStatusFIFO[5] = TOCEntry[1] % 10;
** 1: Read Q subcode next 6 digits
 
Data in FIFO[2~7] & FIFO[8]
NeoCDCommsStatusFIFO[6] = TOCEntry[2] / 10;
** 2: Read Q subcode last 2 digits
NeoCDCommsStatusFIFO[7] = TOCEntry[2] % 10;
Data in FIFO[2~3] & FIFO[8]
**4:
** 3: Read subcode TOC -2?
UINT8* TOCEntry = CDEmuReadTOC(-1);
Data in FIFO[2~7]
 
** 4: Read subcode TOC -1?
NeoCDCommsStatusFIFO[2] = TOCEntry[0] / 10;
Data in FIFO[2~5]
NeoCDCommsStatusFIFO[3] = TOCEntry[0] % 10;
** 5: Read TOC from track in FIFO[4~5]
 
Data in FIFO[2~7] & FIFO[8]
NeoCDCommsStatusFIFO[4] = TOCEntry[1] / 10;
<pre>
NeoCDCommsStatusFIFO[5] = TOCEntry[1] % 10;
// bit 3 of the 1st minutes digit indicates a data track
**5:
if (TOCEntry[3] & 4) {
NeoCDTrack = NeoCDCommsCommandFIFO[4] * 10 + NeoCDCommsCommandFIFO[5];
NeoCDCommsStatusFIFO[6] |= 8;
 
}
UINT8* TOCEntry = CDEmuReadTOC(NeoCDTrack);
</pre>
 
** 6: Read Q subcode status ?
NeoCDCommsStatusFIFO[2] = TOCEntry[0] / 10;
Data in FIFO[8] only
NeoCDCommsStatusFIFO[3] = TOCEntry[0] % 10;
** 7: Clear FIFO ?
 
FIFO[3] = 5
NeoCDCommsStatusFIFO[4] = TOCEntry[1] / 10;
* 3: Switch mode according to reg. #10 bit 2
NeoCDCommsStatusFIFO[5] = TOCEntry[1] % 10;
MSF set in FIFO[2~3]. Starts reading disc.
 
* 4: Pasue
NeoCDCommsStatusFIFO[6] = TOCEntry[2] / 10;
* 5:
NeoCDCommsStatusFIFO[7] = TOCEntry[2] % 10;
<pre>
 
NeoCDAssyStatus = 4;
// bit 3 of the 1st minutes digit indicates a data track
bNeoCDLoadSector = false;
if (TOCEntry[3] & 4) {
</pre>
NeoCDCommsStatusFIFO[6] |= 8;
* 7:
}
<pre>
 
NeoCDAssyStatus = 1;
NeoCDCommsStatusFIFO[8] = NeoCDTrack % 10;
bNeoCDLoadSector = true;
**6:
</pre>
UINT8* ChannelData = CDEmuReadQChannel();
 
NeoCDCommsStatusFIFO[8] = ChannelData[7];
**7:
NeoCDCommsStatusFIFO[2] = 0;
NeoCDCommsStatusFIFO[3] = 5;
 
NeoCDCommsStatusFIFO[4] = 0;
NeoCDCommsStatusFIFO[5] = 0;
 
NeoCDCommsStatusFIFO[6] = 0;
NeoCDCommsStatusFIFO[7] = 0;
*3:
if (LC8951RegistersW[10] & 4) {
 
if (CDEmuGetStatus() == playing) {
bprintf(PRINT_ERROR, _T("*** Switching CD mode to CD-ROM while in audio mode!(PC: 0x%06X)\n"), SekGetPC(-1));
}
 
NeoCDSectorLBA  = NeoCDCommsCommandFIFO[2] * (10 * CD_FRAMES_MINUTE);
NeoCDSectorLBA += NeoCDCommsCommandFIFO[3] * ( 1 * CD_FRAMES_MINUTE);
NeoCDSectorLBA += NeoCDCommsCommandFIFO[4] * (10 * CD_FRAMES_SECOND);
NeoCDSectorLBA += NeoCDCommsCommandFIFO[5] * ( 1 * CD_FRAMES_SECOND);
NeoCDSectorLBA += NeoCDCommsCommandFIFO[6] * (10                  );
NeoCDSectorLBA += NeoCDCommsCommandFIFO[7] * ( 1                  );
 
NeoCDSectorLBA -= CD_FRAMES_PREGAP;
 
CDEmuStartRead();
} else {
 
if (CDEmuGetStatus() == reading) {
bprintf(PRINT_ERROR, _T("*** Switching CD mode to audio while in CD-ROM mode!(PC: 0x%06X)\n"), SekGetPC(-1));
}
 
CDEmuPlay((NeoCDCommsCommandFIFO[2] * 10) + NeoCDCommsCommandFIFO[3], (NeoCDCommsCommandFIFO[4] * 10) + NeoCDCommsCommandFIFO[5], (NeoCDCommsCommandFIFO[6] * 10) + NeoCDCommsCommandFIFO[7]);
}
*4:CDEmuPause();
*6: NeoCDAssyStatus = 4;
bNeoCDLoadSector = false;
*7: NeoCDAssyStatus = 1;
bNeoCDLoadSector = true;
 
==Pinout==
 
[[File:Lc89515.png]]


[[Category:Chips]]
[[Category:Chips]]

Latest revision as of 16:21, 10 February 2017

Sanyo LC89515 chip found on a CDM3-2 board.

Sanyo CD-ROM host and error correction chip, also known as RCHIP. Used to load files in CD systems. It uses a 64KiB RAM buffer (2 32KiB RAM chips), which is able to store up to 27 CD-ROM sectors.

DMA copy speed from buffer to DRAMs can go up to 2.3MiB/s (16.9344MHz / 7 ?)

The NeoGeo CD does not use the C2 pointer error correction.

The NeoGeo CDZ uses the LC89513.

Datasheet

Complete datasheet: [[1]]

Pinout

Registers

Registers access is done through $FF0101 and $FF0103.

Read and writes auto-increments the register address except from register #0. After register #15, the address loops back to #0.

Read Write
# Name Definition Name Definition
0 COMIN Command FIFO input (unused in NeoGeo CD ?) SBOUT Status byte output (unused in NeoGeo CD ?)
1 IFSTAT
Bit 7 6 5 4 3 2 1 0
Def /CMDI /DTEI/DECI1/DTBSY/STBSY/DTEN/STEN
IFCTRL
Bit 7 6 5 4 3 2 1 0
Def CMDIEN DTEIENDECIEN/CMDBK/DTWAI/STWAI/DOUTEN/SOUTEN
2 DBCL Data byte counter 8 LSBs
3 DBCH
Bit 7 6 5 4 3 2 1 0
Def DTEI Data byte counter 4 MSBs
DBCH
Bit 7 6 5 4 3 2 1 0
Def - Data byte counter 4 MSBs
4 HEAD0
SHDREN=0 SHDREN=1
Header minutes Subheader file #
DACL Data start address 8 LSBs
5 HEAD1
SHDREN=0 SHDREN=1
Header seconds Subheader channel #
DACH Data start address 8 MSBs
6 HEAD2
SHDREN=0 SHDREN=1
Header frames Subheader submode #
DTTRG Any write triggers a transfer start
7 HEAD3
SHDREN=0 SHDREN=1
Header mode (01) Subheader coding info
DTACK Any write acknowledges the transfer interrupt
8 PTL Last decoded sector address 8 LSBs WAL Pointer to start of data to be loaded 8 LSBs
9 PTH Last decoded sector address 8 MSBs WAH Pointer to start of data to be loaded 8 MSBs
10 WAL Pointer to start of data to be loaded 8 LSBs CTRL0
Bit 7 6 5 4 3 2 1 0
Def DCEN EDCRQE01RQAUTORQERAMRQWRRQQRQPRQ
11 WAH Pointer to start of data to be loaded 8 MSBs CTRL1
Bit 7 6 5 4 3 2 1 0
Def SYIEN SYDENDSCRENCOWRENMODRQFORMRQ-SHDREN
12 STAT0
Bit 7 6 5 4 3 2 1 0
Def CRCOK ILSYNCNOSYNCLBLKWSHORTSBLKERABLKUCEBLK
PTL Pointer to start of data to be decoded 8 MSBs
13 STAT1
Bit 7 6 5 4 3 2 1 0
Def MINERA SECERABLKERAMODERASH0ERASH1ERASH2ERASH3ERA

Error flags for HEAD0~HEAD3

PTH Pointer to start of data to be decoded 8 LSBs
14 STAT2
Bit 7 6 5 4 3 2 1 0
Def - MODEFORM-
Unused
15 STAT3
Bit 7 6 5 4 3 2 1 0
Def /VALST WLONG-
RESET

Notes

If CD command FIFO is not empty, status FIFO[1] = 15 (busy ?).

  • Command 0: Nop ?
  • Command 1:
CDEmuStop();
NeoCDAssyStatus = 0x0E;
  • Command 2:
status FIFO[1]=command FIFO[3]
    • 0: Read Q subcode first 6 digits

Data in FIFO[2~7] & FIFO[8]

    • 1: Read Q subcode next 6 digits

Data in FIFO[2~7] & FIFO[8]

    • 2: Read Q subcode last 2 digits

Data in FIFO[2~3] & FIFO[8]

    • 3: Read subcode TOC -2?

Data in FIFO[2~7]

    • 4: Read subcode TOC -1?

Data in FIFO[2~5]

    • 5: Read TOC from track in FIFO[4~5]

Data in FIFO[2~7] & FIFO[8]

// bit 3 of the 1st minutes digit indicates a data track
if (TOCEntry[3] & 4) {
	NeoCDCommsStatusFIFO[6] |= 8;
}
    • 6: Read Q subcode status ?

Data in FIFO[8] only

    • 7: Clear FIFO ?

FIFO[3] = 5

  • 3: Switch mode according to reg. #10 bit 2

MSF set in FIFO[2~3]. Starts reading disc.

  • 4: Pasue
  • 5:
NeoCDAssyStatus = 4;
bNeoCDLoadSector = false;
  • 7:
NeoCDAssyStatus = 1;
bNeoCDLoadSector = true;