event_cdda_delay_stop = -1;
// ToDo: larger buffer for later VMs.
- buffer = new FIFO(8192);
+ databuffer = new FIFO(8192);
cdda_status = CDDA_OFF;
is_cue = false;
fio_img = NULL;
delete fio_img;
}
- if(buffer != NULL) {
- buffer->release();
- delete buffer;
- buffer = NULL;
+ if(databuffer != NULL) {
+ databuffer->release();
+ delete databuffer;
+ databuffer = NULL;
}
if(status_queue != NULL) {
status_queue->release();
void TOWNS_CDROM::set_dma_intr(bool val)
{
- out_debug_log(_T("set_dma_intr(%s) MASK=%s stat_reply_intr = %s"),
- (val) ? _T("true ") : _T("false"),
- (dma_intr_mask) ? _T("ON ") : _T("OFF"),
- (stat_reply_intr) ? _T("ON ") : _T("OFF"));
+// out_debug_log(_T("set_dma_intr(%s) MASK=%s stat_reply_intr = %s"),
+// (val) ? _T("true ") : _T("false"),
+// (dma_intr_mask) ? _T("ON ") : _T("OFF"),
+// (stat_reply_intr) ? _T("ON ") : _T("OFF"));
if(val) {
// At least, DMA interrupt mask is needed (by TownsOS v.1.1) 20200511 K.O
if(stat_reply_intr) {
void TOWNS_CDROM::set_mcu_intr(bool val)
{
- out_debug_log(_T("set_mcu_intr(%s) MASK=%s stat_reply_intr = %s"),
- (val) ? _T("true ") : _T("false"),
- (mcu_intr_mask) ? _T("ON ") : _T("OFF"),
- (stat_reply_intr) ? _T("ON ") : _T("OFF"));
+// out_debug_log(_T("set_mcu_intr(%s) MASK=%s stat_reply_intr = %s"),
+// (val) ? _T("true ") : _T("false"),
+// (mcu_intr_mask) ? _T("ON ") : _T("OFF"),
+// (stat_reply_intr) ? _T("ON ") : _T("OFF"));
if(stat_reply_intr) {
// if(!(mcu_intr_mask)) {
mcu_intr = val;
// By DMA/TC, EOT.
case SIG_TOWNS_CDROM_DMAINT:
if((data & mask) != 0) {
- if(dma_transfer_phase) {
+// if(dma_transfer_phase) {
+#if 1
+// if(read_length <= 0) {
+// clear_event(event_next_sector);
+// clear_event(event_seek_completed);
+ if(!(dma_intr_mask)) {
+ dma_intr = true;
+ mcu_intr = false;
+ dma_transfer_phase = false;
+ write_signals(&outputs_mcuint, 0xffffffff);
+ } else {
+// mcu_intr = true;
+ mcu_intr = false;
+ dma_intr = true;
+ if(read_length > 0) {
+ mcu_ready = true;
+ }
+ dma_transfer_phase = false;
+ if(stat_reply_intr) write_signals(&outputs_mcuint, 0xffffffff);
+ }
+ if(read_length <= 0) {
clear_event(event_drq);
clear_event(event_next_sector);
clear_event(event_seek_completed);
+ status_read_done(req_status);
+ out_debug_log(_T("EOT(SIGNAL/DMA"));
+ } else {
+// clear_event(event_next_sector);
+// clear_event(event_seek_completed);
dma_transfer_phase = false;
-// set_dma_intr(true);
- if(read_length <= 0) {
- status_read_done(true);
-// set_dma_intr(true);
-// set_status(true, 0, TOWNS_CD_STATUS_READ_DONE, 0x00, 0x00, 0x00);
-// register_event(this, EVENT_CDROM_DMA_EOT, 2500.0, false, &event_next_sector);
- out_debug_log(_T("EOT(DMA)"));
- } else {
-// dma_transfer_phase = false;
- set_dma_intr(true);
-// set_dma_intr(true);
- register_event(this, EVENT_CDROM_NEXT_SECTOR, 10.0, false, &event_next_sector);
-// event_callback(EVENT_CDROM_NEXT_SECTOR, 0);
- }
-
+ out_debug_log(_T("NEXT(SIGNAL/DMA)"));
+// if((event_seek_completed < 0) && (event_next_sector < 0)) {
+// register_event(this, EVENT_CDROM_NEXT_SECTOR, 6000.0, false, &event_next_sector);
+// }
}
+#endif
}
break;
default:
// From Towns Linux 2.2
// But, some software (i.e. Star Cruiser II) failes to loading at 300uS.
// May need *at least* 1000uS. - 20200517 K.O
-// register_event(this, EVENT_CDROM_DELAY_READY, 1000.0, false, &event_delay_ready);
- register_event(this, EVENT_CDROM_DELAY_READY, 2000.0, false, &event_delay_ready);
+ register_event(this, EVENT_CDROM_DELAY_READY, 1000.0, false, &event_delay_ready);
+// register_event(this, EVENT_CDROM_DELAY_READY, 2000.0, false, &event_delay_ready);
}
void TOWNS_CDROM::set_delay_ready2()
s = 2;
f = 0;
int32_t lba = ((m * (60 * 75)) + (s * 75) + f) - 150;
- status_accept(1, 0x00, 0x00);
+ if(lba < 0) lba = 0;
out_debug_log(_T("CMD SEEK(%02X) M S F = %d %d %d LBA=%d"), command,
TO_BCD(m), TO_BCD(s), TO_BCD(f), lba
);
+ double usec = get_seek_time(lba);
+ if(usec < 10.0) usec = 10.0;
+ clear_event(event_seek);
+ register_event(this, EVENT_CDROM_SEEK, usec, false, &event_seek);
+// status_accept(1, 0x00, 0x00);
+// set_status(req_status, 0, TOWNS_CD_STATUS_SEEK_COMPLETED, 0x00, 0x00, 0x00);
}
break;
case CDROM_COMMAND_READ_MODE2: // 01h
uint32_t TOWNS_CDROM::read_dma_io8(uint32_t addr)
{
- data_reg = (uint8_t)(buffer->read() & 0xff);
-// if(buffer->empty()) {
+ data_reg = (uint8_t)(databuffer->read() & 0xff);
+// if(databuffer->empty()) {
// clear_event(event_drq);
// dma_transfer_phase = false;
// }
void TOWNS_CDROM::read_cdrom()
{
// read_pos = 0;
+// databuffer->clear();
if(!(is_device_ready())) {
out_debug_log(_T("DEVICE NOT READY"));
status_not_ready(false);
// double usec = 5.0e3; // From TSUGARU
// read_buffer(logical_block_size());
register_event(this, EVENT_CDROM_SEEK_COMPLETED, usec, false, &event_seek_completed);
+// register_event(this, EVENT_CDROM_NEXT_SECTOR, usec, false, &event_seek_completed);
if(req_status) {
set_status(req_status, 2, 0x00, 0x00, 0x00, 0x00);
} else {
}
event_cdda_delay_play = -1;
access = true;
- buffer->clear();
+ databuffer->clear();
if(prefetch_audio_sectors(1) != 1) {
set_cdda_status(CDDA_OFF);
set_subq();
case EVENT_CDROM_SEEK:
{
event_seek = -1;
-// set_status(true, 0, TOWNS_CD_STATUS_SEEK_COMPLETED, 0x00, 0x00, 0x00);
- status_accept(1, 0x00, 0x00);
-// media_changed = false;
+ status_accept(1, 0x00, 0x00);
+// set_status(req_status, 0, TOWNS_CD_STATUS_SEEK_COMPLETED, 0x00, 0x00, 0x00);
}
break;
case EVENT_CDROM_SEEK_COMPLETED:
//read_pos = 0;
clear_event(event_next_sector);
if(read_length > 0) {
+ out_debug_log(_T("READ DATA SIZE=%d BUFFER COUNT=%d"), logical_block_size(), databuffer->count());
if(read_length >= logical_block_size()) {
read_buffer(logical_block_size());
} else {
read_buffer(read_length);
}
+// status_data_ready(true);
}
- register_event(this, EVENT_CDROM_NEXT_SECTOR,
- (1.0e6 / ((double)transfer_speed * 150.0e3)) * ((double)physical_block_size()), // OK?
-// 5.0e3, // From TSUGARU
- false, &event_next_sector);
+// if((cdrom_prefetch) || (pio_transfer)) {
+ register_event(this, EVENT_CDROM_NEXT_SECTOR,
+// (1.0e6 / ((double)transfer_speed * 150.0e3)) * ((double)physical_block_size()), // OK?
+ 5.0e3, // From TSUGARU
+ false, &event_next_sector);
+// }
break;
case EVENT_CDROM_NEXT_SECTOR:
event_next_sector = -1;
clear_event(event_seek_completed);
// BIOS FDDFCh(0FC0h:01FCh)-
- //pio_transfer_phase = false;
- //dma_transfer_phase = false;
if(pio_transfer) {
if(read_length <= 0) {
out_debug_log(_T("EOT"));
+ pio_transfer_phase = false;
+ dma_transfer_phase = false;
status_read_done(true);
-// set_status(true, 0, TOWNS_CD_STATUS_READ_DONE, 0x00, 0x00, 0x00);
set_dma_intr(true);
break;
}
}
-// pio_transfer_phase = pio_transfer;
-// dma_transfer_phase = dma_transfer;
-// if(read_length > 0) {
- if(((cdrom_prefetch) && (buffer->left() >= logical_block_size())) ||
- (buffer->empty())) {
+/* if(!(dma_transfer) && !(pio_transfer)) {
+ status_queue->clear();
+ status_data_ready(false);
+ mcu_intr = true;
+ dma_intr = false;
+ dma_transfer_phase = false;
+ } else */
+ if(((cdrom_prefetch) && (databuffer->left() >= logical_block_size())) ||
+ ((databuffer->empty()) && (read_length > 0))) {
+// if(/*(databuffer->left() >= logical_block_size()) &&*/ (read_length > 0)) {
out_debug_log(_T("READ NEXT SECTOR"));
+ pio_transfer_phase = pio_transfer;
+ dma_transfer_phase = dma_transfer;
if(pio_transfer) {
set_status(true, 0, TOWNS_CD_STATUS_CMD_ABEND, 0x00, 0x00, 0x00); // OK?
set_dma_intr(true);
} else {
status_data_ready(true);
-// set_status(true, 0, TOWNS_CD_STATUS_DATA_READY, 0x00, 0x00, 0x00);
- //set_dma_intr(true);
}
- pio_transfer_phase = pio_transfer;
- dma_transfer_phase = dma_transfer;
register_event(this, EVENT_CDROM_SEEK_COMPLETED,
- (1.0e6 / ((double)transfer_speed * 150.0e3)) * /*16.0*/ 1.0, // OK?
- false, &event_seek_completed);
- }
+ (1.0e6 / ((double)transfer_speed * 150.0e3)) * /*16.0*/ 1.0, // OK?
+ false, &event_seek_completed);
+ } else if(read_length > 0) {
+ // Polling to buffer empty.
+ register_event(this, EVENT_CDROM_NEXT_SECTOR,
+ (1.0e6 / ((double)transfer_speed * 150.0e3)) * 16.0, // OK?
+ false, &event_next_sector);
+ }
break;
case EVENT_CDROM_DMA_EOT:
event_next_sector = -1;
break;
case EVENT_CDROM_DRQ:
// ToDo: Buffer OVERFLOW at PIO mode.
- if(dma_transfer_phase) {
+ if((dma_transfer_phase) && !(databuffer->empty())) {
write_signals(&outputs_drq, 0xffffffff);
}
//read_pos++;
{
if(!(mounted())) {
status_not_ready(false);
- return;
+ return false;
}
if(media_changed) {
status_media_changed(false);
- return;
+ return false;
}
uint32_t offset = (uint32_t)(position % physical_block_size());
int n_length = length;
for(int i = 0; i < tmp_length; i++) {
if((offset >= noffset) && (offset < (noffset + logical_block_size()))) {
int value = tmp_buffer[i];
- buffer->write(value);
+ databuffer->write(value);
// is_data_in = false;
length--;
read_length--;
// Kick DRQ
+#if 1
if(event_drq < 0) {
if(dma_transfer) {
- out_debug_log(_T("KICK DRQ"));
- register_event(this, EVENT_CDROM_DRQ, 1.0e6 / ((double)transfer_speed * 150.0e3 * 2.0), true, &event_drq);
+// out_debug_log(_T("KICK DRQ"));
+ register_event(this, EVENT_CDROM_DRQ, 1.0e6 / ((double)transfer_speed * 150.0e3 ), true, &event_drq);
}
}
+#endif
}
position++;
offset = (offset + 1) % physical_block_size();
}
// read 16bit 2ch samples in the cd-da buffer, called 44100 times/sec
pair16_t sample_l, sample_r;
- if(buffer->count() >= 4) {
- sample_l.b.l = buffer->read();
- sample_l.b.h = buffer->read();
- sample_r.b.l = buffer->read();
- sample_r.b.h = buffer->read();
+ if(databuffer->count() >= 4) {
+ sample_l.b.l = databuffer->read();
+ sample_l.b.h = databuffer->read();
+ sample_r.b.l = databuffer->read();
+ sample_r.b.h = databuffer->read();
cdda_sample_l = sample_l.sw;
cdda_sample_r = sample_r.sw;
} else {
seek_relative_frame_in_image(cdda_loading_frame);
}
cdda_playing_frame = cdda_loading_frame;
- if(buffer->count() <= physical_block_size()) {
+ if(databuffer->count() <= physical_block_size()) {
// Kick prefetch
if(event_next_sector < 0) {
// TMP: prefetch 2 sectors
}
int bytes = 0;
for(int i = 0; i < (2352 * n_sectors); i += 2) {
- if(buffer->full()) {
+ if(databuffer->full()) {
break; // Buffer full
}
if(config.swap_audio_byteorder[0]) {
- buffer->write(((int)tmpbuf[i + 1]) & 0xff);
- buffer->write(((int)tmpbuf[i + 0]) & 0xff);
+ databuffer->write(((int)tmpbuf[i + 1]) & 0xff);
+ databuffer->write(((int)tmpbuf[i + 0]) & 0xff);
} else {
- buffer->write(((int)tmpbuf[i + 0]) & 0xff);
- buffer->write(((int)tmpbuf[i + 1]) & 0xff);
+ databuffer->write(((int)tmpbuf[i + 0]) & 0xff);
+ databuffer->write(((int)tmpbuf[i + 1]) & 0xff);
}
bytes += 2;
}
// Notify to release bus.
write_signals(&outputs_mcuint, 0x00000000);
if(status == CDDA_OFF) {
- buffer->clear();
+ databuffer->clear();
cdda_buffer_ptr = 0;
read_sectors = 0;
cdda_repeat_count = -1; // OK?
media_changed = false;
- buffer->clear();
+ databuffer->clear();
status_queue->clear();
latest_command = 0x00;
if(is_cue) {
val = val | ((mcu_intr) ? 0x80 : 0x00);
val = val | ((dma_intr) ? 0x40 : 0x00);
val = val | ((pio_transfer_phase) ? 0x20 : 0x00);
-// val = val | ((d_dmac->read_signal(SIG_UPD71071_IS_TRANSFERING + 3) !=0) ? 0x10 : 0x00); // USING DMAC ch.3
val = val | ((dma_transfer_phase) ? 0x10 : 0x00); // USING DMAC ch.3
val = val | ((has_status) ? 0x02 : 0x00);
val = val | ((mcu_ready) ? 0x01 : 0x00);
val = read_status();
break;
case 0x04:
- if(pio_transfer_phase) {
- val = (buffer->read() & 0xff);
+ if((pio_transfer_phase) && (pio_transfer)) {
+ val = (databuffer->read() & 0xff);
data_reg = val;
+ if((databuffer->empty()) && (read_length <= 0)) {
+ pio_transfer_phase = false;
+ status_read_done(true);
+ }
}
break;
case 0x0c: // Subq code
w_regs[addr & 0x0f] = data;
switch(addr & 0x0f) {
case 0x00: // Master control register
- out_debug_log(_T("PORT 04C0h <- %02X"), data);
+ //out_debug_log(_T("PORT 04C0h <- %02X"), data);
mcu_intr_mask = ((data & 0x02) == 0) ? true : false;
dma_intr_mask = ((data & 0x01) == 0) ? true : false;
if((data & 0x80) != 0) {
/*if(mcu_intr) */set_mcu_intr(false);
-
+#if 0
switch(latest_command & 0x9f) {
case CDROM_COMMAND_READ_MODE2:
case CDROM_COMMAND_READ_MODE1:
case CDROM_COMMAND_READ_RAW:
if((read_length > 0) && (event_next_sector < 0) && (event_seek_completed < 0)) {
- if(((cdrom_prefetch) && (buffer->left() >= logical_block_size())) ||
- (buffer->empty())) {
+ if(((cdrom_prefetch) && (databuffer->left() >= logical_block_size())) ||
+ (databuffer->empty())) {
register_event(this, EVENT_CDROM_SEEK_COMPLETED,
(1.0e6 / ((double)transfer_speed * 150.0e3)) * 16.0, // OK?
false, &event_seek_completed);
}
break;
}
+#endif
}
if((data & 0x40) != 0) {
/*if(dma_intr) */set_dma_intr(false);
}
break;
case 0x02: // Command
- out_debug_log(_T("PORT 04C2h <- %02X"), data);
+ //out_debug_log(_T("PORT 04C2h <- %02X"), data);
if(mcu_ready) {
stat_reply_intr = ((data & 0x40) != 0) ? true : false;
req_status = ((data & 0x20) != 0) ? true : false;
}
// dma_transfer_phase = dma_transfer;
// pio_transfer_phase = pio_transfer;
- out_debug_log(_T("SET TRANSFER NODE to %02X"), data);
+#if 1
+ if((dma_transfer) && !(dma_transfer_phase)) {
+ dma_transfer_phase = true;
+// clear_event(event_drq);
+// if(!(databuffer->empty())) {
+// out_debug_log(_T("KICK DRQ"));
+// register_event(this, EVENT_CDROM_DRQ, 1.0e6 / ((double)transfer_speed * 150.0e3), true, &event_drq);
+// }
+ }
+#endif
+ //out_debug_log(_T("SET TRANSFER MODE to %02X"), data);
break;
}
}
void TOWNS_CDROM::write_debug_data8(uint32_t addr, uint32_t data)
{
uint32_t nmask = 0x2000 - 1; // ToDo: Will change
- buffer->write_not_push(addr & nmask, data & 0xff);
+ databuffer->write_not_push(addr & nmask, data & 0xff);
}
uint32_t TOWNS_CDROM::read_debug_data8(uint32_t addr)
{
uint32_t nmask = 0x2000 - 1; // ToDo: Will change
- return buffer->read_not_remove(addr & nmask) & 0xff;
+ return databuffer->read_not_remove(addr & nmask) & 0xff;
}
my_stprintf_s(buffer, buffer_len,
_T("TRANSFER MODE=%s %s\n")
_T("MCU INT=%s DMA INT=%s TRANSFER PHASE:%s %s HAS_STATUS=%s MCU=%s\n")
- _T("TRACK=%d LBA=%d READ LENGTH=%d\n")
+ _T("TRACK=%d LBA=%d READ LENGTH=%d DATA QUEUE=%d\n")
_T("CMD=%02X PARAM=%s PTR=%d\n")
_T("EXTRA STATUS=%d STATUS COUNT=%d QUEUE_VALUE=%s\n")
_T("REGS RAW VALUES=%s\n")
, (pio_transfer_phase) ? _T("PIO") : _T(" ")
, (dma_transfer_phase) ? _T("DMA") : _T(" ")
, (has_status) ? _T("ON ") : _T("OFF"), (mcu_ready) ? _T("ON ") : _T("OFF")
- , current_track, position / physical_block_size(), read_length
+ , current_track, position / physical_block_size(), read_length, databuffer->count()
, latest_command, param, param_ptr
, extra_status, status_queue->count(), stat
, regs
if(!state_fio->StateCheckInt32(this_device_id)) {
return false;
}
- if(!(buffer->process_state((void *)state_fio, loading))) {
+ if(!(databuffer->process_state((void *)state_fio, loading))) {
return false;
}
if(!(status_queue->process_state((void *)state_fio, loading))) {