mirror of
https://github.com/BluestormDNA/ProjectPSX.git
synced 2025-04-02 10:52:34 -04:00
More CD reading opcodes and basic timing
This commit is contained in:
parent
4d441c6ff8
commit
3fae22d66e
1 changed files with 301 additions and 28 deletions
|
@ -8,35 +8,136 @@ namespace ProjectPSX.Devices {
|
||||||
|
|
||||||
private Queue<uint> parameterBuffer = new Queue<uint>(16);
|
private Queue<uint> parameterBuffer = new Queue<uint>(16);
|
||||||
private Queue<uint> responseBuffer = new Queue<uint>(16);
|
private Queue<uint> responseBuffer = new Queue<uint>(16);
|
||||||
private Queue<uint> dataBuffer = new Queue<uint>();
|
private Queue<byte> dataBuffer = new Queue<byte>();
|
||||||
private byte wantData;
|
private bool wantData;
|
||||||
|
private bool isBusy;
|
||||||
|
|
||||||
private byte IE; // InterruptEnableRegister
|
private byte IE; // InterruptEnableRegister
|
||||||
private byte IF; // InterruptFlagRegister
|
private byte IF; // InterruptFlagRegister
|
||||||
|
|
||||||
//private uint STATUS = 0x8;
|
private byte INDEX;
|
||||||
private uint INDEX;
|
private byte STAT;
|
||||||
|
//7 Play Playing CD-DA ;\only ONE of these bits can be set
|
||||||
|
//6 Seek Seeking; at a time(ie.Read/Play won't get
|
||||||
|
//5 Read Reading data sectors ;/set until after Seek completion)
|
||||||
|
//4 ShellOpen Once shell open(0=Closed, 1=Is/was Open)
|
||||||
|
//3 IdError(0=Okay, 1=GetID denied) (also set when Setmode.Bit4=1)
|
||||||
|
//2 SeekError(0=Okay, 1=Seek error) (followed by Error Byte)
|
||||||
|
//1 Spindle Motor(0=Motor off, or in spin-up phase, 1=Motor on)
|
||||||
|
//0 Error Invalid Command/parameters(followed by Error Byte)
|
||||||
|
|
||||||
|
private int Loc;
|
||||||
|
private int SeekL;
|
||||||
|
private int ReadN;
|
||||||
|
|
||||||
|
//Mode
|
||||||
|
//7 Speed(0 = Normal speed, 1 = Double speed)
|
||||||
|
//6 XA - ADPCM(0 = Off, 1 = Send XA - ADPCM sectors to SPU Audio Input)
|
||||||
|
//5 Sector Size(0 = 800h = DataOnly, 1 = 924h = WholeSectorExceptSyncBytes)
|
||||||
|
//4 Ignore Bit(0 = Normal, 1 = Ignore Sector Size and Setloc position)
|
||||||
|
//3 XA - Filter(0 = Off, 1 = Process only XA - ADPCM sectors that match Setfilter)
|
||||||
|
//2 Report(0 = Off, 1 = Enable Report - Interrupts for Audio Play)
|
||||||
|
//1 AutoPause(0 = Off, 1 = Auto Pause upon End of Track); for Audio Play
|
||||||
|
//0 CDDA(0 = Off, 1 = Allow to Read CD - DA Sectors; ignore missing EDC)
|
||||||
|
|
||||||
|
private bool isDoubleSpeed;
|
||||||
|
private bool XA_ADPCM;
|
||||||
|
private bool isSectorSizeRAW;
|
||||||
|
private bool isIgnoreBit;
|
||||||
|
private bool XA_Filter;
|
||||||
|
private bool isReport;
|
||||||
|
private bool isAutoPause;
|
||||||
|
private bool isCDDA;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private enum Mode {
|
||||||
|
Idle,
|
||||||
|
Seek,
|
||||||
|
Read,
|
||||||
|
Transfer
|
||||||
|
}
|
||||||
|
Mode mode = Mode.Idle;
|
||||||
|
|
||||||
|
private uint counter;
|
||||||
|
private Queue<byte> interruptQueue = new Queue<byte>();
|
||||||
|
|
||||||
|
private CD cd;
|
||||||
|
|
||||||
public CDROM(InterruptController InterruptController) {
|
public CDROM(InterruptController InterruptController) {
|
||||||
this.InterruptController = InterruptController;
|
this.InterruptController = InterruptController;
|
||||||
|
cd = new CD();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void tick(uint cycles) {
|
||||||
|
counter += cycles;
|
||||||
|
if (counter < 10000) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (interruptQueue.Count != 0 && IF == 0) {
|
||||||
|
Console.WriteLine("[CD INT] Queue is " + interruptQueue.Count + " Dequeue = IF | " + interruptQueue.Peek());
|
||||||
|
IF |= interruptQueue.Dequeue();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((IF & IE) != 0 && ((InterruptController.loadISTAT() & 0x4) != 0x4)) {
|
||||||
|
Console.WriteLine("[CD INT] Triggering " + IF.ToString("x8"));
|
||||||
|
InterruptController.set(Interrupt.CDROM);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (mode) {
|
||||||
|
case Mode.Idle:
|
||||||
|
if (counter < 4000 || interruptQueue.Count != 0) { //Await some cycles so interrupts are not triggered instant
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
counter = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Mode.Seek:
|
||||||
|
if (counter < 20000 || interruptQueue.Count != 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mode = Mode.Read; //???
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Mode.Read:
|
||||||
|
if (counter < 100000 || interruptQueue.Count != 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//i should trigger here and add loc...
|
||||||
|
responseBuffer.Enqueue(STAT);
|
||||||
|
interruptQueue.Enqueue(0x1);
|
||||||
|
counter = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Mode.Transfer:
|
||||||
|
if (counter < 10000 || interruptQueue.Count != 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if(dataBuffer.Count == 0)
|
||||||
|
//dataBuffer = new Queue<byte>(cd.read(Loc));
|
||||||
|
counter = 0;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public new uint load(Width w, uint addr) {
|
public new uint load(Width w, uint addr) {
|
||||||
switch (addr) {
|
switch (addr) {
|
||||||
case 0x1F801800: Console.WriteLine("[CDROM] [LOAD 00] STATUS = {0}", STATUS().ToString("x8")); return STATUS();
|
case 0x1F801800: Console.WriteLine("[CDROM] [L00] STATUS = {0}", STATUS().ToString("x8")); return STATUS();
|
||||||
case 0x1F801801: Console.WriteLine("[CDROM] [LOAD 01] RESPONSE"); return responseBuffer.Dequeue();
|
case 0x1F801801: Console.WriteLine("[CDROM] [L01] RESPONSE " + responseBuffer.Peek().ToString("x8")); return responseBuffer.Dequeue();
|
||||||
case 0x1F801802: Console.WriteLine("[CDROM] [LOAD 02] DATA"); return dataBuffer.Dequeue();
|
case 0x1F801802: Console.WriteLine("[CDROM] [L02] DATA"); return dataBuffer.Dequeue();
|
||||||
case 0x1F801803:
|
case 0x1F801803:
|
||||||
switch (INDEX) {
|
switch (INDEX) {
|
||||||
case 0:
|
case 0:
|
||||||
case 2:
|
case 2:
|
||||||
Console.WriteLine("[CDROM] [LOAD 03.0] IE: {0}", ((uint)(0xe0 | IE)).ToString("x8")); return (uint)(0xe0 | IE);
|
Console.WriteLine("[CDROM] [L03.0] IE: {0}", ((uint)(0xe0 | IE)).ToString("x8")); return (uint)(0xe0 | IE);
|
||||||
case 1:
|
case 1:
|
||||||
case 3:
|
case 3:
|
||||||
Console.WriteLine("[CDROM] [LOAD 03.1] IF: {0}", ((uint)(0xe0 | IF)).ToString("x8"));
|
Console.WriteLine("[CDROM] [L03.1] IF: {0}", ((uint)(0xe0 | IF)).ToString("x8")); return (uint)(0xe0 | IF);
|
||||||
Console.WriteLine("IF Loaded" + IF.ToString("x8"));
|
default: Console.WriteLine("[CDROM] [L03.X] Unimplemented"); return 0;
|
||||||
return (uint)(0xe0 | IF);
|
|
||||||
default: Console.WriteLine("[CDROM] [LOAD 03.X] Unimplemented"); return 0;
|
|
||||||
}
|
}
|
||||||
default: return 0;
|
default: return 0;
|
||||||
}
|
}
|
||||||
|
@ -45,26 +146,26 @@ namespace ProjectPSX.Devices {
|
||||||
public new void write(Width w, uint addr, uint value) {
|
public new void write(Width w, uint addr, uint value) {
|
||||||
switch (addr) {
|
switch (addr) {
|
||||||
case 0x1F801800:
|
case 0x1F801800:
|
||||||
Console.WriteLine("[CDROM] [WRITE 00] Index: {0}", value.ToString("x8"));
|
Console.WriteLine("[CDROM] [W00] I: {0}", value.ToString("x8"));
|
||||||
INDEX = value & 0x3;
|
//Console.ReadLine();
|
||||||
|
INDEX = (byte)(value & 0x3);
|
||||||
break;
|
break;
|
||||||
case 0x1F801801:
|
case 0x1F801801:
|
||||||
if (INDEX == 0) {
|
if (INDEX == 0) {
|
||||||
Console.WriteLine("[CDROM] [WRITE 01.0] Command: {0}", value.ToString("x8"));
|
Console.WriteLine("[CDROM] [W01.0] COMMAND: {0}", value.ToString("x8"));
|
||||||
ExecuteCommand(value);
|
ExecuteCommand(value);
|
||||||
} else {
|
} else {
|
||||||
Console.WriteLine("[CDROM] [Unhandled Write] Access: {0} Value: {1}", addr.ToString("x8"), value.ToString("x8"));
|
Console.WriteLine("[CDROM] [Unhandled Write] Index: {0} Access: {1} Value: {2}", INDEX.ToString("x8"), addr.ToString("x8"), value.ToString("x8"));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x1F801802:
|
case 0x1F801802:
|
||||||
switch (INDEX) {
|
switch (INDEX) {
|
||||||
case 0:
|
case 0:
|
||||||
Console.WriteLine("[CDROM] [WRITE 02.0] Parameter: {0}", value.ToString("x8"));
|
Console.WriteLine("[CDROM] [W02.0] Parameter: {0}", value.ToString("x8"));
|
||||||
parameterBuffer.Enqueue(value);
|
parameterBuffer.Enqueue(value);
|
||||||
Console.ReadLine();
|
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
Console.WriteLine("[CDROM] [WRITE 02.1] Set IE: {0}", value.ToString("x8"));
|
Console.WriteLine("[CDROM] [W02.1] Set IE: {0}", value.ToString("x8"));
|
||||||
IE = (byte)(value & 0x1F);
|
IE = (byte)(value & 0x1F);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -80,19 +181,24 @@ namespace ProjectPSX.Devices {
|
||||||
//5 SMEN Want Command Start Interrupt on Next Command(0 = No change, 1 = Yes)
|
//5 SMEN Want Command Start Interrupt on Next Command(0 = No change, 1 = Yes)
|
||||||
//6 BFWR...
|
//6 BFWR...
|
||||||
//7 BFRD Want Data(0 = No / Reset Data Fifo, 1 = Yes / Load Data Fifo)
|
//7 BFRD Want Data(0 = No / Reset Data Fifo, 1 = Yes / Load Data Fifo)
|
||||||
Console.WriteLine("[CDROM] [Write 03.0 Want Data] value {0}", (value & 0x80) != 0);
|
Console.WriteLine("[CDROM] [W03.0 Want Data] value {0}", (value & 0x80) != 0);
|
||||||
if((value & 0x80) != 0) {
|
if ((value & 0x80) != 0) {
|
||||||
|
Console.ForegroundColor = ConsoleColor.Red;
|
||||||
|
Console.WriteLine("[CDROM] [W03.0] Data Clear");
|
||||||
|
Console.ResetColor();
|
||||||
dataBuffer.Clear();
|
dataBuffer.Clear();
|
||||||
|
//interruptQueue.Clear();
|
||||||
|
//Console.ReadLine();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
Console.WriteLine("[CDROM] [Write 03.1] Set IF {0}", value.ToString("x8"));
|
Console.WriteLine("[CDROM] [W03.1] Set IF {0}", value.ToString("x8"));
|
||||||
IF &= (byte)~(value & 0x1F);
|
IF &= (byte)~(value & 0x1F);
|
||||||
if (value == 0x40) {
|
if (value == 0x40) {
|
||||||
Console.WriteLine("[CDROM] [Write 03.1 Parameter Buffer Clear] value {0}", value.ToString("x8"));
|
Console.WriteLine("[CDROM] [W03.1 Parameter Buffer Clear] value {0}", value.ToString("x8"));
|
||||||
parameterBuffer.Clear();
|
parameterBuffer.Clear();
|
||||||
}
|
}
|
||||||
Console.WriteLine("IF Writed" + IF.ToString("x8"));
|
//Console.WriteLine("IF Writed" + IF.ToString("x8"));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -108,11 +214,172 @@ namespace ProjectPSX.Devices {
|
||||||
|
|
||||||
private void ExecuteCommand(uint value) {
|
private void ExecuteCommand(uint value) {
|
||||||
switch (value) {
|
switch (value) {
|
||||||
|
case 0x01: getStat(); break;
|
||||||
|
case 0x02: setLoc(); break;
|
||||||
|
case 0x06: readN(); break;
|
||||||
|
case 0x09: pause(); break;
|
||||||
|
case 0x0A: init(); break;
|
||||||
|
case 0x0E: setMode(); break;
|
||||||
|
case 0x15: seekL(); break;
|
||||||
|
case 0x1A: getID(); break;
|
||||||
case 0x19: test(); break;
|
case 0x19: test(); break;
|
||||||
default: UnimplementedCDCommand(value); break;
|
default: UnimplementedCDCommand(value); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
STAT = 0x2;
|
||||||
|
|
||||||
|
responseBuffer.Enqueue(STAT);
|
||||||
|
interruptQueue.Enqueue(0x3);
|
||||||
|
|
||||||
|
responseBuffer.Enqueue(STAT);
|
||||||
|
interruptQueue.Enqueue(0x2);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void pause() {
|
||||||
|
//todo actual pause transfers
|
||||||
|
STAT = 0x2;
|
||||||
|
mode = Mode.Idle;
|
||||||
|
|
||||||
|
responseBuffer.Enqueue(STAT);
|
||||||
|
interruptQueue.Enqueue(0x3);
|
||||||
|
|
||||||
|
responseBuffer.Enqueue(STAT);
|
||||||
|
interruptQueue.Enqueue(0x2);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readN() {
|
||||||
|
//todo actual read
|
||||||
|
STAT = 0x2;
|
||||||
|
STAT |= 0x20;
|
||||||
|
|
||||||
|
responseBuffer.Enqueue(STAT);
|
||||||
|
interruptQueue.Enqueue(0x3);
|
||||||
|
|
||||||
|
mode = Mode.Read;
|
||||||
|
//isBusy = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setMode() {
|
||||||
|
//7 Speed(0 = Normal speed, 1 = Double speed)
|
||||||
|
//6 XA - ADPCM(0 = Off, 1 = Send XA - ADPCM sectors to SPU Audio Input)
|
||||||
|
//5 Sector Size(0 = 800h = DataOnly, 1 = 924h = WholeSectorExceptSyncBytes)
|
||||||
|
//4 Ignore Bit(0 = Normal, 1 = Ignore Sector Size and Setloc position)
|
||||||
|
//3 XA - Filter(0 = Off, 1 = Process only XA - ADPCM sectors that match Setfilter)
|
||||||
|
//2 Report(0 = Off, 1 = Enable Report - Interrupts for Audio Play)
|
||||||
|
//1 AutoPause(0 = Off, 1 = Auto Pause upon End of Track); for Audio Play
|
||||||
|
//0 CDDA(0 = Off, 1 = Allow to Read CD - DA Sectors; ignore missing EDC)
|
||||||
|
uint mode = parameterBuffer.Dequeue();
|
||||||
|
|
||||||
|
isDoubleSpeed = ((mode >> 7) & 0x1) == 1;
|
||||||
|
XA_ADPCM = ((mode >> 6) & 0x1) == 1;
|
||||||
|
isSectorSizeRAW = ((mode >> 5) & 0x1) == 1;
|
||||||
|
isIgnoreBit = ((mode >> 4) & 0x1) == 1;
|
||||||
|
XA_Filter = ((mode >> 3) & 0x1) == 1;
|
||||||
|
isReport = ((mode >> 2) & 0x1) == 1;
|
||||||
|
isAutoPause = ((mode >> 1) & 0x1) == 1;
|
||||||
|
isCDDA = (mode & 0x1) == 1;
|
||||||
|
|
||||||
|
Console.WriteLine("SPEED MODE >>>>>>>>>>>>>>>>>>>" + isDoubleSpeed);
|
||||||
|
Console.WriteLine("SECTOR SIZE >>>>>>>>>>>>>>>>>>>" + isSectorSizeRAW);
|
||||||
|
responseBuffer.Enqueue(STAT);
|
||||||
|
interruptQueue.Enqueue(0x3);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal uint getData() {
|
||||||
|
//Console.WriteLine("databufferCount" + dataBuffer.Count);
|
||||||
|
if (dataBuffer.Count == 0)
|
||||||
|
dataBuffer = new Queue<byte>(cd.read(isSectorSizeRAW, Loc++));
|
||||||
|
|
||||||
|
byte b0 = dataBuffer.Dequeue();
|
||||||
|
byte b1 = dataBuffer.Dequeue();
|
||||||
|
byte b2 = dataBuffer.Dequeue();
|
||||||
|
byte b3 = dataBuffer.Dequeue();
|
||||||
|
|
||||||
|
return (uint)(b3 << 24 | b2 << 16 | b1 << 8 | b0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void seekL() {
|
||||||
|
SeekL = Loc;
|
||||||
|
STAT |= 0x40; // seek
|
||||||
|
|
||||||
|
mode = Mode.Seek;
|
||||||
|
|
||||||
|
responseBuffer.Enqueue(STAT);
|
||||||
|
interruptQueue.Enqueue(0x3);
|
||||||
|
|
||||||
|
responseBuffer.Enqueue(STAT);
|
||||||
|
interruptQueue.Enqueue(0x2);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setLoc() {
|
||||||
|
int minute = DecToBcd((byte)parameterBuffer.Dequeue());
|
||||||
|
int second = DecToBcd((byte)parameterBuffer.Dequeue());
|
||||||
|
int sector = DecToBcd((byte)parameterBuffer.Dequeue());
|
||||||
|
|
||||||
|
//temporal bin hack to bypass cue parse - 2 secs
|
||||||
|
second -= 2;
|
||||||
|
|
||||||
|
//There are 75 sectors on a second
|
||||||
|
Loc = sector + (second * 75) + (minute * 60 * 75);
|
||||||
|
|
||||||
|
responseBuffer.Enqueue(STAT);
|
||||||
|
interruptQueue.Enqueue(0x3);
|
||||||
|
|
||||||
|
responseBuffer.Enqueue(STAT);
|
||||||
|
interruptQueue.Enqueue(0x2);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void getID() {
|
||||||
|
//No Disk INT3(stat) INT5(08h, 40h, 00h, 00h, 00h, 00h, 00h, 00h)
|
||||||
|
//STAT = 0x2; //0x40 seek
|
||||||
|
//responseBuffer.Enqueue(STAT);
|
||||||
|
//interruptQueue.Enqueue(0x3);
|
||||||
|
//
|
||||||
|
//responseBuffer.Enqueue(0x08);
|
||||||
|
//responseBuffer.Enqueue(0x40);
|
||||||
|
//responseBuffer.Enqueue(0x00);
|
||||||
|
//responseBuffer.Enqueue(0x00);
|
||||||
|
//
|
||||||
|
//responseBuffer.Enqueue(0x00);
|
||||||
|
//responseBuffer.Enqueue(0x00);
|
||||||
|
//responseBuffer.Enqueue(0x00);
|
||||||
|
//responseBuffer.Enqueue(0x00);
|
||||||
|
//interruptQueue.Enqueue(0x5);
|
||||||
|
|
||||||
|
//Door Open INT5(11h,80h) N/A
|
||||||
|
//STAT = 0x10; //Shell Open
|
||||||
|
//interruptQueue.Enqueue(0x5);
|
||||||
|
//
|
||||||
|
//responseBuffer.Enqueue(0x11);
|
||||||
|
//responseBuffer.Enqueue(0x80);
|
||||||
|
//responseBuffer.Enqueue(0x0);
|
||||||
|
//responseBuffer.Enqueue(0x0);
|
||||||
|
|
||||||
|
//Licensed: Mode2 INT3(stat) INT2(02h, 00h, 20h, 00h, 53h, 43h, 45h, 4xh)
|
||||||
|
STAT |= 0x40; //0x40 seek
|
||||||
|
responseBuffer.Enqueue(STAT);
|
||||||
|
interruptQueue.Enqueue(0x3);
|
||||||
|
|
||||||
|
responseBuffer.Enqueue(0x02);
|
||||||
|
responseBuffer.Enqueue(0x00);
|
||||||
|
responseBuffer.Enqueue(0x20);
|
||||||
|
responseBuffer.Enqueue(0x00);
|
||||||
|
|
||||||
|
responseBuffer.Enqueue(0x53); //S
|
||||||
|
responseBuffer.Enqueue(0x43); //C
|
||||||
|
responseBuffer.Enqueue(0x45); //E
|
||||||
|
responseBuffer.Enqueue(0x41); //A 0x41 (America) - I 0x49 (Japan) - E 0x45 (Europe)
|
||||||
|
interruptQueue.Enqueue(0x2);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void getStat() {
|
||||||
|
STAT = 0x2;
|
||||||
|
responseBuffer.Enqueue(STAT);
|
||||||
|
interruptQueue.Enqueue(0x3);
|
||||||
|
}
|
||||||
|
|
||||||
private void UnimplementedCDCommand(uint value) {
|
private void UnimplementedCDCommand(uint value) {
|
||||||
Console.WriteLine("[CDROM] Unimplemented CD Command " + value.ToString("x8"));
|
Console.WriteLine("[CDROM] Unimplemented CD Command " + value.ToString("x8"));
|
||||||
Console.ReadLine();
|
Console.ReadLine();
|
||||||
|
@ -126,9 +393,7 @@ namespace ProjectPSX.Devices {
|
||||||
responseBuffer.Enqueue(0x19);
|
responseBuffer.Enqueue(0x19);
|
||||||
responseBuffer.Enqueue(0xC0);
|
responseBuffer.Enqueue(0xC0);
|
||||||
|
|
||||||
//force ISTAT 4
|
interruptQueue.Enqueue(0x3);
|
||||||
IF |= 0x3;
|
|
||||||
InterruptController.set(Interrupt.CDROM);
|
|
||||||
break;
|
break;
|
||||||
default: Console.WriteLine("[CDROM] Unimplemented test command"); break;
|
default: Console.WriteLine("[CDROM] Unimplemented test command"); break;
|
||||||
}
|
}
|
||||||
|
@ -145,7 +410,7 @@ namespace ProjectPSX.Devices {
|
||||||
//7 BUSYSTS Command/ parameter transmission busy(1 = Busy)
|
//7 BUSYSTS Command/ parameter transmission busy(1 = Busy)
|
||||||
|
|
||||||
int stat = 0;
|
int stat = 0;
|
||||||
//stat |= busy() << 7;
|
stat |= isBusy ? 1 : 0 << 7;
|
||||||
stat |= dataBuffer_hasData() << 6;
|
stat |= dataBuffer_hasData() << 6;
|
||||||
stat |= responseBuffer_hasData() << 5;
|
stat |= responseBuffer_hasData() << 5;
|
||||||
stat |= parametterBuffer_hasSpace() << 4;
|
stat |= parametterBuffer_hasSpace() << 4;
|
||||||
|
@ -170,6 +435,14 @@ namespace ProjectPSX.Devices {
|
||||||
private int responseBuffer_hasData() {
|
private int responseBuffer_hasData() {
|
||||||
return (responseBuffer.Count > 0) ? 1 : 0;
|
return (responseBuffer.Count > 0) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int DecToBcd(byte val) {
|
||||||
|
return (((val / 10) << 4) | (val % 10));
|
||||||
|
}
|
||||||
|
|
||||||
|
int BcdToDec(byte bcd) {
|
||||||
|
return (((bcd >> 4) * 10) + (bcd & 0xF));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue