mirror of
https://github.com/JaCzekanski/Avocado.git
synced 2024-06-02 19:27:41 -04:00
cdrom: delayed interrupts
This commit is contained in:
parent
34a0f6560d
commit
4d309c90e9
|
@ -48,14 +48,14 @@ void CDROM::handleSector() {
|
|||
auto posInTrack = pos - disc->getTrackStart(track);
|
||||
|
||||
postInterrupt(1);
|
||||
writeResponse(stat._reg); // stat
|
||||
writeResponse(bcd::toBcd(track)); // track
|
||||
writeResponse(0x01); // index
|
||||
writeResponse(stat._reg); // stat
|
||||
writeResponse(bcd::toBcd(track)); // track
|
||||
writeResponse(0x01); // index
|
||||
writeResponse(bcd::toBcd(posInTrack.mm)); // minute (disc) <<< invalid
|
||||
writeResponse(bcd::toBcd(posInTrack.ss) | 0x80); // second (disc) <<< invalid
|
||||
writeResponse(bcd::toBcd(posInTrack.ff)); // sector (disc)
|
||||
writeResponse(bcd::toBcd(0)); // peaklo
|
||||
writeResponse(bcd::toBcd(0)); // peakhi
|
||||
writeResponse(bcd::toBcd(0)); // peaklo
|
||||
writeResponse(bcd::toBcd(0)); // peakhi
|
||||
|
||||
if (verbose) {
|
||||
fmt::print("CDROM:CDDA report -> ({})\n", dumpFifo(interruptQueue.peek().response));
|
||||
|
@ -135,21 +135,25 @@ void CDROM::handleSector() {
|
|||
}
|
||||
|
||||
void CDROM::step(int cycles) {
|
||||
static int intCycles = 0;
|
||||
|
||||
readcnt += cycles;
|
||||
intCycles += cycles;
|
||||
busyFor -= cycles;
|
||||
|
||||
if (!interruptQueue.is_empty()) {
|
||||
interruptQueue.ref().delay -= cycles;
|
||||
|
||||
if (interruptQueue.peek().delay <= 0) {
|
||||
status.transmissionBusy = 0;
|
||||
|
||||
if (intCycles >= 300) {
|
||||
intCycles -= 300;
|
||||
status.transmissionBusy = 0;
|
||||
if (!interruptQueue.is_empty()) {
|
||||
if ((interruptEnable & 7) & (interruptQueue.peek().irq & 7)) {
|
||||
sys->interrupt->trigger(interrupt::CDROM);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (busyFor < 0) {
|
||||
status.transmissionBusy = 0;
|
||||
}
|
||||
|
||||
const int sectorsPerSecond = mode.speed ? 150 : 75;
|
||||
const int cyclesPerSector = timing::CPU_CLOCK / sectorsPerSecond;
|
||||
for (int i = 0; i < readcnt / cyclesPerSector; i++) {
|
||||
|
@ -210,7 +214,9 @@ uint8_t CDROM::read(uint32_t address) {
|
|||
if (status.index == 1 || status.index == 3) { // Interrupt flags
|
||||
uint8_t _status = 0b11100000;
|
||||
if (!interruptQueue.is_empty()) {
|
||||
_status |= interruptQueue.peek().irq & 7;
|
||||
if (interruptQueue.peek().delay <= 0) {
|
||||
_status |= interruptQueue.peek().irq & 7;
|
||||
}
|
||||
}
|
||||
if (verbose == 2) fmt::print("CDROM: R INTF: 0x{:02x}\n", _status);
|
||||
return _status;
|
||||
|
@ -315,6 +321,7 @@ void CDROM::handleCommand(uint8_t cmd) {
|
|||
break;
|
||||
}
|
||||
|
||||
busyFor = 1000;
|
||||
CDROM_params.clear();
|
||||
status.transmissionBusy = 1;
|
||||
status.xaFifoEmpty = 0;
|
||||
|
|
|
@ -41,7 +41,7 @@ class CDROM {
|
|||
void setShell(bool opened) {
|
||||
shellOpen = opened;
|
||||
|
||||
setMode(Mode::None);
|
||||
setMode(Mode::None);
|
||||
if (opened) {
|
||||
motor = false;
|
||||
}
|
||||
|
@ -100,10 +100,11 @@ class CDROM {
|
|||
uint8_t irq;
|
||||
fifo<uint8_t, 16> response;
|
||||
bool ack;
|
||||
int delay;
|
||||
|
||||
template <class Archive>
|
||||
void serialize(Archive& ar) {
|
||||
ar(irq, response, ack);
|
||||
ar(irq, response, ack, delay);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -165,7 +166,15 @@ class CDROM {
|
|||
return param;
|
||||
}
|
||||
|
||||
void postInterrupt(int irq) { interruptQueue.add(irq_response_t{.irq = (uint8_t)irq, .response = {}}); }
|
||||
int busyFor = 0;
|
||||
|
||||
void postInterrupt(int irq, int delay = 50000) {
|
||||
interruptQueue.add(irq_response_t{
|
||||
.irq = (uint8_t)irq, //
|
||||
.response = {}, //
|
||||
.delay = delay //
|
||||
});
|
||||
}
|
||||
|
||||
std::string dumpFifo(const FIFO& f);
|
||||
std::pair<int16_t, int16_t> mixSample(std::pair<int16_t, int16_t> sample);
|
||||
|
@ -193,10 +202,20 @@ class CDROM {
|
|||
uint8_t read(uint32_t address);
|
||||
void write(uint32_t address, uint8_t data);
|
||||
|
||||
void setShell(bool opened) { stat.setShell(opened); }
|
||||
void setShell(bool opened) {
|
||||
stat.setShell(opened);
|
||||
|
||||
if (opened) {
|
||||
if (disc) {
|
||||
postInterrupt(0x05, 1000);
|
||||
writeResponse(0x16);
|
||||
writeResponse(0x08);
|
||||
}
|
||||
}
|
||||
}
|
||||
bool getShell() const { return stat.getShell(); }
|
||||
void ackMoreData() {
|
||||
postInterrupt(1);
|
||||
postInterrupt(1, 0);
|
||||
writeResponse(stat._reg);
|
||||
}
|
||||
|
||||
|
|
|
@ -17,11 +17,17 @@ void CDROM::cmdSetloc() {
|
|||
uint8_t sector = bcd::toBinary(readParam());
|
||||
|
||||
seekSector = sector + (second * 75) + (minute * 60 * 75);
|
||||
|
||||
postInterrupt(3);
|
||||
writeResponse(stat._reg);
|
||||
|
||||
if (verbose) fmt::print("CDROM: cmdSetloc(min = {}, sec = {}, sect = {})\n", minute, second, sector);
|
||||
|
||||
if (!discPresent()) {
|
||||
postInterrupt(5);
|
||||
writeResponse(0x11);
|
||||
writeResponse(0x80);
|
||||
return;
|
||||
}
|
||||
|
||||
postInterrupt(3, 2000);
|
||||
writeResponse(stat._reg);
|
||||
}
|
||||
|
||||
void CDROM::cmdPlay() {
|
||||
|
@ -29,7 +35,7 @@ void CDROM::cmdPlay() {
|
|||
disc::Position pos;
|
||||
if (!CDROM_params.is_empty()) {
|
||||
int track = readParam(); // param or setloc used
|
||||
if (track >= (int)disc->getTrackCount()) {
|
||||
if (track > (int)disc->getTrackCount()) {
|
||||
fmt::print("CDROM: Invalid PLAY track parameter ({})\n", track);
|
||||
return;
|
||||
}
|
||||
|
@ -50,14 +56,20 @@ void CDROM::cmdPlay() {
|
|||
}
|
||||
|
||||
void CDROM::cmdReadN() {
|
||||
readSector = seekSector;
|
||||
if (verbose) fmt::print("CDROM: cmdReadN\n");
|
||||
|
||||
if (!discPresent()) {
|
||||
postInterrupt(5);
|
||||
writeResponse(0x11);
|
||||
writeResponse(0x80);
|
||||
return;
|
||||
}
|
||||
|
||||
readSector = seekSector;
|
||||
stat.setMode(StatusCode::Mode::Reading);
|
||||
|
||||
postInterrupt(3);
|
||||
postInterrupt(3, 5000);
|
||||
writeResponse(stat._reg);
|
||||
|
||||
if (verbose) fmt::print("CDROM: cmdReadN\n");
|
||||
}
|
||||
|
||||
void CDROM::cmdMotorOn() {
|
||||
|
@ -98,7 +110,7 @@ void CDROM::cmdPause() {
|
|||
}
|
||||
|
||||
void CDROM::cmdInit() {
|
||||
postInterrupt(3);
|
||||
postInterrupt(3, 0x13ce);
|
||||
writeResponse(stat._reg);
|
||||
|
||||
stat.motor = 1;
|
||||
|
@ -142,7 +154,7 @@ void CDROM::cmdSetmode() {
|
|||
|
||||
mode._reg = setmode;
|
||||
|
||||
postInterrupt(3);
|
||||
postInterrupt(3, 2000);
|
||||
writeResponse(stat._reg);
|
||||
|
||||
if (verbose) fmt::print("CDROM: cmdSetmode(0x{:02x})\n", setmode);
|
||||
|
@ -177,9 +189,7 @@ void CDROM::cmdSeekP() {
|
|||
postInterrupt(3);
|
||||
writeResponse(stat._reg);
|
||||
|
||||
stat.setMode(StatusCode::Mode::Seeking);
|
||||
|
||||
postInterrupt(2);
|
||||
postInterrupt(2, 500000);
|
||||
writeResponse(stat._reg);
|
||||
|
||||
stat.setMode(StatusCode::Mode::None);
|
||||
|
@ -222,7 +232,7 @@ void CDROM::cmdGetlocL() {
|
|||
}
|
||||
|
||||
void CDROM::cmdGetlocP() {
|
||||
postInterrupt(3);
|
||||
postInterrupt(3, 1000);
|
||||
writeResponse(lastQ.data[0]); // track
|
||||
writeResponse(lastQ.data[1]); // index
|
||||
writeResponse(lastQ.data[2]); // minute (track)
|
||||
|
@ -284,17 +294,24 @@ void CDROM::cmdGetTD() {
|
|||
}
|
||||
|
||||
void CDROM::cmdSeekL() {
|
||||
if (verbose) fmt::print("CDROM: cmdSeekL\n");
|
||||
|
||||
readSector = seekSector;
|
||||
|
||||
postInterrupt(3);
|
||||
if (!discPresent()) {
|
||||
postInterrupt(5);
|
||||
writeResponse(0x11);
|
||||
writeResponse(0x80);
|
||||
return;
|
||||
}
|
||||
|
||||
postInterrupt(3, 5000);
|
||||
writeResponse(stat._reg);
|
||||
|
||||
stat.setMode(StatusCode::Mode::Seeking);
|
||||
|
||||
postInterrupt(2);
|
||||
postInterrupt(2, 500000);
|
||||
writeResponse(stat._reg);
|
||||
|
||||
if (verbose) fmt::print("CDROM: cmdSeekL\n");
|
||||
stat.setMode(StatusCode::Mode::None);
|
||||
}
|
||||
|
||||
void CDROM::cmdTest() {
|
||||
|
@ -396,7 +413,7 @@ void CDROM::cmdReadS() {
|
|||
audio.clear();
|
||||
stat.setMode(StatusCode::Mode::Reading);
|
||||
|
||||
postInterrupt(3);
|
||||
postInterrupt(3, 500);
|
||||
writeResponse(stat._reg);
|
||||
|
||||
if (verbose) fmt::print("CDROM: cmdReadS\n");
|
||||
|
|
Loading…
Reference in a new issue