Get PIN64 code to function correctly. (nw)

This commit is contained in:
MooglyGuy 2017-02-02 01:46:15 +01:00
parent 68090e5606
commit af39fe7816
3 changed files with 431 additions and 265 deletions

View File

@ -1197,7 +1197,7 @@ void n64_rdp::disassemble(char* buffer)
uint64_t cmd[32];
const uint32_t length = m_cmd_ptr * 4;
const uint32_t length = m_cmd_ptr * 8;
if (length < 8)
{
sprintf(buffer, "ERROR: length = %d\n", length);
@ -2469,6 +2469,8 @@ void n64_rdp::cmd_load_tlut(uint64_t w1)
fatalerror("Load tlut: tl=%d, th=%d\n",tl,th);
}
m_capture.data_begin();
const int32_t count = ((sh >> 2) - (sl >> 2) + 1) << 2;
switch (m_misc_state.m_ti_size)
@ -2488,6 +2490,7 @@ void n64_rdp::cmd_load_tlut(uint64_t w1)
if (dststart < 2048)
{
dst[dststart] = U_RREADIDX16(srcstart);
m_capture.data_block()->put16(dst[dststart]);
dst[dststart + 1] = dst[dststart];
dst[dststart + 2] = dst[dststart];
dst[dststart + 3] = dst[dststart];
@ -2500,6 +2503,8 @@ void n64_rdp::cmd_load_tlut(uint64_t w1)
default: fatalerror("RDP: load_tlut: size = %d\n", m_misc_state.m_ti_size);
}
m_capture.data_end();
m_tiles[tilenum].sth = rgbaint_t(m_tiles[tilenum].sh, m_tiles[tilenum].sh, m_tiles[tilenum].th, m_tiles[tilenum].th);
m_tiles[tilenum].stl = rgbaint_t(m_tiles[tilenum].sl, m_tiles[tilenum].sl, m_tiles[tilenum].tl, m_tiles[tilenum].tl);
}
@ -2553,6 +2558,8 @@ void n64_rdp::cmd_load_block(uint64_t w1)
const uint32_t src = (m_misc_state.m_ti_address >> 1) + (tl * tiwinwords) + slinwords;
m_capture.data_begin();
if (dxt != 0)
{
int32_t j = 0;
@ -2577,6 +2584,12 @@ void n64_rdp::cmd_load_block(uint64_t w1)
tc[((ptr + 1) ^ t) & 0x7ff] = U_RREADIDX16(srcptr + 1);
tc[((ptr + 2) ^ t) & 0x7ff] = U_RREADIDX16(srcptr + 2);
tc[((ptr + 3) ^ t) & 0x7ff] = U_RREADIDX16(srcptr + 3);
m_capture.data_block()->put16(U_RREADIDX16(srcptr));
m_capture.data_block()->put16(U_RREADIDX16(srcptr+1));
m_capture.data_block()->put16(U_RREADIDX16(srcptr+2));
m_capture.data_block()->put16(U_RREADIDX16(srcptr+3));
j += dxt;
}
}
@ -2605,6 +2618,10 @@ void n64_rdp::cmd_load_block(uint64_t w1)
tc[ptr] = ((first >> 8) << 8) | (sec >> 8);
tc[ptr | 0x400] = ((first & 0xff) << 8) | (sec & 0xff);
m_capture.data_block()->put16(U_RREADIDX16(srcptr));
m_capture.data_block()->put16(U_RREADIDX16(srcptr+1));
m_capture.data_block()->put16(U_RREADIDX16(srcptr+2));
m_capture.data_block()->put16(U_RREADIDX16(srcptr+3));
j += dxt;
}
}
@ -2626,6 +2643,11 @@ void n64_rdp::cmd_load_block(uint64_t w1)
tc[ptr] = U_RREADIDX16(srcptr + 2);
tc[ptr | 0x400] = U_RREADIDX16(srcptr + 3);
m_capture.data_block()->put16(U_RREADIDX16(srcptr));
m_capture.data_block()->put16(U_RREADIDX16(srcptr+1));
m_capture.data_block()->put16(U_RREADIDX16(srcptr+2));
m_capture.data_block()->put16(U_RREADIDX16(srcptr+3));
j += dxt;
}
}
@ -2643,6 +2665,11 @@ void n64_rdp::cmd_load_block(uint64_t w1)
tc[((ptr + 1) ^ WORD_ADDR_XOR) & 0x7ff] = U_RREADIDX16(srcptr + 1);
tc[((ptr + 2) ^ WORD_ADDR_XOR) & 0x7ff] = U_RREADIDX16(srcptr + 2);
tc[((ptr + 3) ^ WORD_ADDR_XOR) & 0x7ff] = U_RREADIDX16(srcptr + 3);
m_capture.data_block()->put16(U_RREADIDX16(srcptr));
m_capture.data_block()->put16(U_RREADIDX16(srcptr+1));
m_capture.data_block()->put16(U_RREADIDX16(srcptr+2));
m_capture.data_block()->put16(U_RREADIDX16(srcptr+3));
}
}
else if (tile[tilenum].format == FORMAT_YUV)
@ -2661,6 +2688,11 @@ void n64_rdp::cmd_load_block(uint64_t w1)
sec = U_RREADIDX16(srcptr + 3);
tc[ptr] = ((first >> 8) << 8) | (sec >> 8);
tc[ptr | 0x400] = ((first & 0xff) << 8) | (sec & 0xff);
m_capture.data_block()->put16(U_RREADIDX16(srcptr));
m_capture.data_block()->put16(U_RREADIDX16(srcptr+1));
m_capture.data_block()->put16(U_RREADIDX16(srcptr+2));
m_capture.data_block()->put16(U_RREADIDX16(srcptr+3));
}
}
else
@ -2675,11 +2707,18 @@ void n64_rdp::cmd_load_block(uint64_t w1)
ptr = ((tb + (i << 1) + 1) ^ WORD_ADDR_XOR) & 0x3ff;
tc[ptr] = U_RREADIDX16(srcptr + 2);
tc[ptr | 0x400] = U_RREADIDX16(srcptr + 3);
m_capture.data_block()->put16(U_RREADIDX16(srcptr));
m_capture.data_block()->put16(U_RREADIDX16(srcptr+1));
m_capture.data_block()->put16(U_RREADIDX16(srcptr+2));
m_capture.data_block()->put16(U_RREADIDX16(srcptr+3));
}
}
tile[tilenum].th = tl;
}
m_capture.data_end();
m_tiles[tilenum].sth = rgbaint_t(m_tiles[tilenum].sh, m_tiles[tilenum].sh, m_tiles[tilenum].th, m_tiles[tilenum].th);
m_tiles[tilenum].stl = rgbaint_t(m_tiles[tilenum].sl, m_tiles[tilenum].sl, m_tiles[tilenum].tl, m_tiles[tilenum].tl);
}
@ -2715,6 +2754,8 @@ void n64_rdp::cmd_load_tile(uint64_t w1)
topad = 0; // ????
*/
m_capture.data_begin();
switch (m_misc_state.m_ti_size)
{
case PIXEL_SIZE_8BIT:
@ -2731,7 +2772,9 @@ void n64_rdp::cmd_load_tile(uint64_t w1)
for (int32_t i = 0; i < width; i++)
{
tc[((tline + i) ^ xorval8) & 0xfff] = U_RREADADDR8(src + s + i);
const uint8_t data = U_RREADADDR8(src + s + i);
m_capture.data_block()->put8(data);
tc[((tline + i) ^ xorval8) & 0xfff] = data;
}
}
break;
@ -2752,8 +2795,10 @@ void n64_rdp::cmd_load_tile(uint64_t w1)
for (int32_t i = 0; i < width; i++)
{
uint32_t taddr = (tline + i) ^ xorval16;
tc[taddr & 0x7ff] = U_RREADIDX16(src + s + i);
const uint32_t taddr = (tline + i) ^ xorval16;
const uint16_t data = U_RREADIDX16(src + s + i);
m_capture.data_block()->put16(data);
tc[taddr & 0x7ff] = data;
}
}
}
@ -2770,6 +2815,7 @@ void n64_rdp::cmd_load_tile(uint64_t w1)
{
uint32_t taddr = ((tline + i) ^ xorval8) & 0x7ff;
uint16_t yuvword = U_RREADIDX16(src + s + i);
m_capture.data_block()->put16(yuvword);
get_tmem8()[taddr] = yuvword >> 8;
get_tmem8()[taddr | 0x800] = yuvword & 0xff;
}
@ -2792,6 +2838,7 @@ void n64_rdp::cmd_load_tile(uint64_t w1)
for (int32_t i = 0; i < width; i++)
{
uint32_t c = U_RREADIDX32(src + s + i);
m_capture.data_block()->put32(c);
uint32_t ptr = ((tline + i) ^ xorval32cur) & 0x3ff;
tc16[ptr] = c >> 16;
tc16[ptr | 0x400] = c & 0xffff;
@ -2803,6 +2850,8 @@ void n64_rdp::cmd_load_tile(uint64_t w1)
default: fatalerror("RDP: load_tile: size = %d\n", m_misc_state.m_ti_size);
}
m_capture.data_end();
m_tiles[tilenum].sth = rgbaint_t(m_tiles[tilenum].sh, m_tiles[tilenum].sh, m_tiles[tilenum].th, m_tiles[tilenum].th);
m_tiles[tilenum].stl = rgbaint_t(m_tiles[tilenum].sl, m_tiles[tilenum].sl, m_tiles[tilenum].tl, m_tiles[tilenum].tl);
}
@ -3018,6 +3067,8 @@ void n64_rdp::process_command_list()
//fatalerror("rdp_process_list: not enough rdp command data: cur = %d, ptr = %d, expected = %d\n", m_cmd_cur, m_cmd_ptr, s_rdp_command_length[cmd]);
}
m_capture.command(&m_cmd_data[m_cmd_cur], s_rdp_command_length[cmd] / 8);
if (LOG_RDP_EXECUTION)
{
char string[4000];

View File

@ -7,9 +7,8 @@
// pin64_fileutil_t members
void pin64_fileutil_t::write(FILE* file, uint32_t data)
{
if (file == nullptr)
void pin64_fileutil_t::write(FILE* file, uint32_t data) {
if (!file)
return;
uint8_t temp(data >> 24);
@ -25,38 +24,40 @@ void pin64_fileutil_t::write(FILE* file, uint32_t data)
fwrite(&temp, 1, 1, file);
}
void pin64_fileutil_t::write(FILE* file, const uint8_t* data, uint32_t size)
{
if (file == nullptr)
void pin64_fileutil_t::write(FILE* file, const uint8_t* data, uint32_t size) {
if (!file)
return;
fwrite(data, 1, size, file);
}
// pin64_block_t members
void pin64_block_t::put8(uint8_t data)
{
// pin64_data_t members
void pin64_data_t::put8(uint8_t data) {
m_data.push_back(data);
m_offset++;
}
void pin64_block_t::put16(uint16_t data)
{
void pin64_data_t::put16(uint16_t data) {
put8((uint8_t)(data >> 8));
put8((uint8_t)data);
}
void pin64_block_t::put32(uint32_t data)
{
void pin64_data_t::put32(uint32_t data) {
put16((uint16_t)(data >> 16));
put16((uint16_t)data);
}
uint8_t pin64_block_t::get8()
{
void pin64_data_t::put64(uint64_t data) {
put32((uint32_t)(data >> 32));
put32((uint32_t)data);
}
uint8_t pin64_data_t::get8() {
if (m_offset >= m_data.size())
fatalerror("PIN64: Call to get8() at end of block (requested offset %x, size %x)\n", m_offset, (uint32_t)m_data.size());
fatalerror("PIN64: Call to pin64_data_t::get8() at end of block (requested offset %x, size %x)\n", m_offset, (uint32_t)m_data.size());
uint8_t ret = m_data[m_offset];
m_offset++;
@ -64,192 +65,161 @@ uint8_t pin64_block_t::get8()
return ret;
}
uint16_t pin64_block_t::get16()
{
uint16_t ret = 0;
ret |= get8() << 8;
ret |= get8();
return ret;
uint16_t pin64_data_t::get16() {
uint16_t ret = (uint16_t)get8() << 8;
return ret | get8();
}
uint32_t pin64_block_t::get32()
{
uint32_t ret = 0;
ret |= get16() << 16;
ret |= get16();
return ret;
uint32_t pin64_data_t::get32() {
uint32_t ret = (uint32_t)get16() << 16;
return ret | get16();
}
uint8_t pin64_block_t::get8(uint32_t offset, bool update_current)
{
update_offset(offset, update_current);
uint64_t pin64_data_t::get64() {
uint64_t ret = (uint64_t)get32() << 32;
return ret | get32();
}
uint8_t pin64_data_t::get8(uint32_t offset, bool temp_access) {
update_offset(offset, temp_access);
uint8_t ret = get8();
m_offset = m_old_offset;
return ret;
}
uint16_t pin64_block_t::get16(uint32_t offset, bool update_current)
{
update_offset(offset, update_current);
uint16_t pin64_data_t::get16(uint32_t offset, bool temp_access) {
update_offset(offset, temp_access);
uint16_t ret = get16();
m_offset = m_old_offset;
return ret;
}
uint32_t pin64_block_t::get32(uint32_t offset, bool update_current)
{
update_offset(offset, update_current);
uint32_t pin64_data_t::get32(uint32_t offset, bool temp_access) {
update_offset(offset, temp_access);
uint32_t ret = get32();
m_offset = m_old_offset;
return ret;
}
uint32_t pin64_block_t::data_size()
{
return m_data.size();
uint64_t pin64_data_t::get64(uint32_t offset, bool temp_access) {
update_offset(offset, temp_access);
uint32_t ret = get64();
m_offset = m_old_offset;
return ret;
}
uint32_t pin64_block_t::size()
{
return sizeof(uint32_t) * 2 + data_size();
}
void pin64_block_t::clear()
{
reset();
m_crc32 = 0;
m_data.clear();
}
void pin64_block_t::reset()
{
void pin64_data_t::reset() {
m_old_offset = 0;
m_offset = 0;
}
void pin64_block_t::finalize()
{
if (m_data.size() > 0)
m_crc32 = util::crc32_creator::simple(&m_data[0], m_data.size());
else
m_crc32 = ~0;
void pin64_data_t::clear() {
reset();
m_data.clear();
}
void pin64_block_t::write(FILE* file)
{
pin64_fileutil_t::write(file, m_crc32);
pin64_fileutil_t::write(file, m_data.size());
if (m_data.size() > 0)
pin64_fileutil_t::write(file, &m_data[0], m_data.size());
}
void pin64_block_t::update_offset(uint32_t offset, bool update_current)
{
void pin64_data_t::update_offset(uint32_t offset, bool update_current) {
m_old_offset = (update_current ? offset : m_offset);
m_offset = offset;
}
// pin64_frame_t members
const uint8_t pin64_t::pin64_frame_t::FRAME_ID[8] = { 'P', 'I', 'N', '6', '4', 'F', 'R', 'M' };
pin64_t::pin64_frame_t::~pin64_frame_t()
{
clear();
// pin64_block_t members
void pin64_block_t::finalize() {
if (m_data.size() > 0)
m_crc32 = util::crc32_creator::simple(m_data.bytes(), m_data.size());
else
m_crc32 = ~0;
m_data.reset();
}
uint32_t pin64_t::pin64_frame_t::size()
{
return header_size() + directory_size() + blocks_size() + m_commands.size();
void pin64_block_t::clear() {
m_crc32 = 0;
m_data.clear();
}
uint32_t pin64_t::pin64_frame_t::header_size()
{
return sizeof(uint8_t) * 8 // "PIN64FRM"
+ sizeof(uint32_t) // total file size
+ sizeof(uint32_t) // start of directory data
+ sizeof(uint32_t) // start of block data
+ sizeof(uint32_t); // start of command data
}
void pin64_block_t::print() {
printf(" CRC32: %08x\n", (uint32_t)m_crc32); fflush(stdout);
printf(" Data Size: %08x\n", (uint32_t)m_data.size()); fflush(stdout);
printf(" Data: "); fflush(stdout);
uint32_t pin64_t::pin64_frame_t::directory_size()
{
return m_blocks.size() * sizeof(uint32_t);
}
const uint32_t data_size = m_data.size();
const uint32_t row_count = (data_size + 31) / 32;
const uint8_t* bytes = m_data.bytes();
for (uint32_t row = 0; row < row_count; row++) {
const uint32_t row_index = row * 32;
const uint32_t data_remaining = data_size - row_index;
const uint32_t col_count = (data_remaining > 32 ? 32 : data_remaining);
for (uint32_t col = 0; col < col_count; col++)
printf("%02x ", bytes[row_index + col]); fflush(stdout);
uint32_t pin64_t::pin64_frame_t::blocks_size()
{
uint32_t block_size = 0;
for (pin64_block_t* block : m_blocks)
block_size += block->size();
return block_size;
}
pin64_block_t* pin64_t::pin64_frame_t::start_block()
{
m_blocks.push_back(new pin64_block_t());
return m_blocks[m_blocks.size() - 1];
}
void pin64_t::pin64_frame_t::write(FILE* file) {
const uint32_t size_total = size();
const uint32_t size_header = header_size();
const uint32_t size_dir = directory_size();
const uint32_t size_blocks = blocks_size();
std::vector<uint32_t> directory;
fill_directory(directory);
pin64_fileutil_t::write(file, FRAME_ID, 8);
pin64_fileutil_t::write(file, size_total);
pin64_fileutil_t::write(file, size_header);
pin64_fileutil_t::write(file, size_header + size_dir);
pin64_fileutil_t::write(file, size_header + size_dir + size_blocks);
for (uint32_t entry : directory)
pin64_fileutil_t::write(file, entry);
for (pin64_block_t* block : m_blocks)
block->write(file);
m_commands.write(file);
}
void pin64_t::pin64_frame_t::fill_directory(std::vector<uint32_t>& directory) {
uint32_t offset = header_size() + directory_size();
for (pin64_block_t* block : m_blocks) {
directory.push_back(offset);
offset += block->size();
if (row == (row_count - 1)) {
printf("\n"); fflush(stdout);
} else {
printf("\n "); fflush(stdout);
}
}
printf("\n"); fflush(stdout);
}
void pin64_t::pin64_frame_t::clear() {
for (pin64_block_t* block : m_blocks)
delete block;
void pin64_command_block_t::print() {
printf(" CRC32: %08x\n", (uint32_t)m_crc32); fflush(stdout);
printf(" Data Size: %08x\n", (uint32_t)m_data.size()); fflush(stdout);
m_blocks.clear();
m_commands.clear();
uint32_t cmd_index = 0;
while (m_data.offset() < m_data.size()) {
printf(" Command %d:\n", cmd_index); fflush(stdout);
const uint32_t cmd_size(m_data.get32());
printf(" Packet Data Size: %d words\n", cmd_size); fflush(stdout);
printf(" Packet Data: "); fflush(stdout);
for (int i = 0; i < cmd_size; i++) {
const uint64_t cmd_entry(m_data.get64());
printf("%08x%08x\n", uint32_t(cmd_entry >> 32), (uint32_t)cmd_entry); fflush(stdout);
m_current_block = nullptr;
if (i < (cmd_size - 1))
printf(" ");
}
const uint8_t data_flag(m_data.get8());
bool data_block_present(data_flag != 0);
printf(" Data Block Present: %02x (%s)\n", data_flag, data_block_present ? "Yes" : "No"); fflush(stdout);
if (data_block_present) {
printf(" Data Block CRC32: %08x\n", m_data.get32()); fflush(stdout);
}
cmd_index++;
}
m_data.reset();
};
void pin64_block_t::write(FILE* file) {
pin64_fileutil_t::write(file, m_crc32);
pin64_fileutil_t::write(file, m_data.size());
if (m_data.size() > 0)
pin64_fileutil_t::write(file, m_data.bytes(), m_data.size());
}
pin64_block_t** pin64_t::pin64_frame_t::blocks() {
return (m_blocks.size() == 0) ? nullptr : &m_blocks[0];
uint32_t pin64_block_t::size() {
return sizeof(uint32_t) // data CRC32
+ sizeof(uint32_t) // data size
+ m_data.size(); // data
}
// pin64_t members
const uint8_t pin64_t::CAP_ID[8] = { 'P', 'I', 'N', '6', '4', 'C', 'A', 'P' };
pin64_t::~pin64_t()
{
pin64_t::~pin64_t() {
if (m_capture_file != nullptr)
finish();
@ -261,7 +231,7 @@ void pin64_t::start(int frames)
if (m_capture_index == ~0)
init_capture_index();
if (m_capture_file != nullptr)
if (m_capture_file)
fatalerror("PIN64: Call to start() while already capturing\n");
char name_buf[256];
@ -284,89 +254,195 @@ void pin64_t::finish() {
clear();
}
pin64_t::pin64_frame_t* pin64_t::start_frame()
{
pin64_command_block_t* pin64_t::start_command_block() {
if (!m_capture_file)
return nullptr;
m_frames.push_back(new pin64_frame_t());
return m_frames[m_frames.size() - 1];
if (m_current_cmdblock)
m_current_cmdblock->finalize();
m_cmdblocks.push_back(new pin64_command_block_t());
return m_cmdblocks[m_cmdblocks.size() - 1];
}
void pin64_t::play(int index)
{
}
void pin64_t::mark_frame(running_machine& machine) {
if (m_capture_file) {
if (m_frames.size() == m_capture_frames) {
if (m_cmdblocks.size() == m_capture_frames && m_capture_frames > 0) {
finish();
} else {
m_current_frame = start_frame();
m_current_cmdblock = start_command_block();
}
}
if (machine.input().code_pressed_once(KEYCODE_N) && !m_capture_file) {
start(1);
machine.popmessage("Capturing PIN64 snapshot to pin64_%d.cap", m_capture_index - 1);
} else if (machine.input().code_pressed_once(KEYCODE_M)) {
if (m_capture_file) {
finish();
machine.popmessage("Done recording.");
} else {
start();
machine.popmessage("Recording PIN64 movie to pin64_%d.cap", m_capture_index - 1);
}
}
}
uint32_t pin64_t::size()
{
return header_size() + directory_size() + frames_size();
void pin64_t::command(uint64_t* cmd_data, uint32_t size) {
if (!capturing())
return;
if (!m_current_cmdblock)
return;
m_current_cmdblock->data()->put32(size);
for (uint32_t i = 0 ; i < size; i++)
m_current_cmdblock->data()->put64(cmd_data[i]);
const uint8_t cmd_byte((cmd_data[0] >> 56) & 0x3f);
if (cmd_byte == 0x30 || cmd_byte == 0x33 || cmd_byte == 0x34)
m_current_cmdblock->data()->put8(0xff);
else
m_current_cmdblock->data()->put8(0x00);
}
uint32_t pin64_t::header_size()
{
void pin64_t::data_begin() {
if (!capturing() || !m_current_cmdblock)
return;
m_blocks.push_back(new pin64_block_t());
m_current_block = m_blocks[m_blocks.size() - 1];
}
pin64_data_t* pin64_t::data_block() {
if (!capturing() || !m_current_cmdblock)
return &m_dummy_data;
return m_current_block->data();
}
void pin64_t::data_end() {
if (!capturing() || !m_current_cmdblock)
return;
m_current_block->finalize();
m_current_cmdblock->data()->put32(m_current_block->crc32());
const uint32_t last_index = m_blocks.size() - 1;
if (m_blocks.size() > 1) {
int i = 0;
for (i = 0; i < last_index; i++) {
if (m_blocks[i]->crc32() == block().crc32()) {
break;
}
}
if (i != last_index) {
m_blocks.erase(m_blocks.begin() + last_index);
}
}
}
uint32_t pin64_t::size() {
return header_size() + sizeof(uint32_t) * (m_blocks.size() + m_cmdblocks.size() + 2) + blocks_size() + cmdblocks_size();
}
uint32_t pin64_t::header_size() {
return sizeof(uint8_t) * 8 // "PIN64CAP"
+ sizeof(uint32_t) // total file size
+ sizeof(uint32_t) // start of directory data
+ sizeof(uint32_t); // start of frame data
+ sizeof(uint32_t) // start of data block directory data
+ sizeof(uint32_t) // start of command-list directory data
+ sizeof(uint32_t) // start of data blocks
+ sizeof(uint32_t); // start of command list
}
uint32_t pin64_t::directory_size()
{
return m_frames.size() * sizeof(uint32_t);
uint32_t pin64_t::blocks_size() {
uint32_t block_size = 0;
for (pin64_block_t* block : m_blocks)
block_size += block->size();
return block_size;
}
uint32_t pin64_t::frames_size()
{
uint32_t frames_size = 0;
for (pin64_frame_t* frame : m_frames)
frames_size += frame->size();
uint32_t pin64_t::cmdblocks_size() {
uint32_t cmdblock_size = 0;
for (pin64_command_block_t* cmdblock : m_cmdblocks)
cmdblock_size += cmdblock->size();
return frames_size;
return cmdblock_size;
}
void pin64_t::print() {
printf("Total Size: %9x bytes\n", size()); fflush(stdout);
printf("Header Size: %9x bytes\n", header_size()); fflush(stdout);
printf("Cmdlist Dir Size: %9x bytes\n", uint32_t(m_cmdblocks.size() * sizeof(uint32_t))); fflush(stdout);
printf("Datablk Dir Size: %9x bytes\n", uint32_t(m_blocks.size() * sizeof(uint32_t))); fflush(stdout);
printf("Cmdlist Size: %9x bytes\n", cmdblocks_size()); fflush(stdout);
printf("Datablk Size: %9x bytes\n", blocks_size()); fflush(stdout);
printf("Command-List Count: %d\n", (uint32_t)m_cmdblocks.size()); fflush(stdout);
for (int i = 0; i < m_cmdblocks.size(); i++) {
printf(" List %d:\n", i); fflush(stdout);
m_cmdblocks[i]->print();
if (i == (m_cmdblocks.size() - 1))
printf("\n"); fflush(stdout);
}
printf("\nData Block Count: %d\n", (uint32_t)m_blocks.size()); fflush(stdout);
for (int i = 0; i < m_blocks.size(); i++) {
printf(" Block %d:\n", i); fflush(stdout);
m_blocks[i]->print();
if (i == (m_blocks.size() - 1))
printf("\n"); fflush(stdout);
}
}
void pin64_t::write(FILE* file) {
const uint32_t size_total = size();
const uint32_t size_header = header_size();
const uint32_t size_dir = directory_size();
const uint32_t size_frames = frames_size();
std::vector<uint32_t> directory;
fill_directory(directory);
const uint32_t size_block_dir = uint32_t((m_blocks.size() + 1) * sizeof(uint32_t));
const uint32_t size_cmdblock_dir = uint32_t((m_cmdblocks.size() + 1) * sizeof(uint32_t));
const uint32_t size_blocks_dir = blocks_size();
pin64_fileutil_t::write(file, CAP_ID, 8);
pin64_fileutil_t::write(file, size_total);
pin64_fileutil_t::write(file, size_header);
pin64_fileutil_t::write(file, size_header + size_dir);
pin64_fileutil_t::write(file, size_header + size_dir + size_frames);
pin64_fileutil_t::write(file, size_header + size_block_dir);
pin64_fileutil_t::write(file, size_header + size_block_dir + size_cmdblock_dir);
pin64_fileutil_t::write(file, size_header + size_block_dir + size_cmdblock_dir + size_blocks_dir);
for (uint32_t entry : directory)
pin64_fileutil_t::write(file, entry);
write_block_directory(file);
write_cmdblock_directory(file);
for (pin64_frame_t* frame : m_frames)
frame->write(file);
for (pin64_block_t* block : m_blocks)
block->write(file);
for (pin64_command_block_t* block : m_cmdblocks)
block->write(file);
}
void pin64_t::fill_directory(std::vector<uint32_t>& directory) {
uint32_t offset = header_size() + directory_size();
for (pin64_frame_t* frame : m_frames) {
directory.push_back(offset);
offset += frame->size();
void pin64_t::write_block_directory(FILE* file) {
pin64_fileutil_t::write(file, m_blocks.size());
uint32_t offset(header_size() + (m_blocks.size() + m_cmdblocks.size() + 2));
for (pin64_block_t* block : m_blocks) {
pin64_fileutil_t::write(file, offset);
offset += block->size();
}
}
void pin64_t::write_cmdblock_directory(FILE* file) {
pin64_fileutil_t::write(file, m_cmdblocks.size());
uint32_t offset(header_size() + (m_blocks.size() + m_cmdblocks.size() + 2) * sizeof(uint32_t) + blocks_size());
for (pin64_command_block_t* block : m_cmdblocks) {
pin64_fileutil_t::write(file, offset);
offset += block->size();
}
}
@ -376,11 +452,17 @@ void pin64_t::clear() {
m_capture_file = nullptr;
}
for (pin64_frame_t* frame : m_frames)
delete frame;
for (pin64_block_t* block : m_blocks)
delete block;
m_frames.clear();
m_current_frame = nullptr;
m_blocks.clear();
m_current_block = nullptr;
for (pin64_command_block_t* block : m_cmdblocks)
delete block;
m_cmdblocks.clear();
m_current_cmdblock = nullptr;
}
void pin64_t::init_capture_index()
@ -390,17 +472,13 @@ void pin64_t::init_capture_index()
m_capture_index = 0;
do
{
do {
sprintf(name_buf, CAP_NAME, m_capture_index);
FILE* temp = fopen(name_buf, "rb");
if (temp == nullptr)
{
if (temp == nullptr) {
break;
}
else
{
} else {
fclose(temp);
m_capture_index++;
}

View File

@ -10,55 +10,101 @@
#include "emu.h"
class pin64_fileutil_t
{
class pin64_fileutil_t {
public:
static void write(FILE* file, uint32_t data);
static void write(FILE* file, const uint8_t* data, uint32_t size);
};
class pin64_block_t
{
class pin64_command_t {
public:
pin64_block_t()
: m_crc32{ 0 }
, m_offset(0)
, m_old_offset(0)
{ }
std::vector<uint8_t> data;
};
void put8(uint8_t data);
void put16(uint16_t data);
void put32(uint32_t data);
class pin64_data_t {
public:
pin64_data_t()
: m_offset(0)
, m_old_offset(0) { }
void clear();
void finalize();
void reset();
void clear();
void write(FILE* file);
// setters
virtual void put8(uint8_t data);
virtual void put16(uint16_t data);
virtual void put32(uint32_t data);
virtual void put64(uint64_t data);
// getters
uint8_t get8();
uint8_t get8(uint32_t offset, bool update_current = true);
uint16_t get16();
uint16_t get16(uint32_t offset, bool update_current = true);
uint32_t get32();
uint32_t get32(uint32_t offset, bool update_current = true);
util::crc32_t crc32() const { return m_crc32; }
uint8_t* bytes() { return &m_data[0]; }
uint32_t data_size();
uint32_t size();
virtual uint8_t get8();
virtual uint8_t get8(uint32_t offset, bool temp_access = false);
virtual uint16_t get16();
virtual uint16_t get16(uint32_t offset, bool temp_access = false);
virtual uint32_t get32();
virtual uint32_t get32(uint32_t offset, bool temp_access = false);
virtual uint64_t get64();
virtual uint64_t get64(uint32_t offset, bool temp_access = false);
virtual uint32_t offset() { return m_offset; }
uint8_t* bytes() { return (m_data.size() > 0) ? &m_data[0] : nullptr; }
uint32_t size() { return m_data.size(); }
private:
void update_offset(uint32_t offset, bool update_current = true);
void update_offset(uint32_t offset, bool temp_access = false);
util::crc32_t m_crc32;
protected:
std::vector<uint8_t> m_data;
uint32_t m_offset;
uint32_t m_old_offset;
};
class pin64_dummy_data_t : public pin64_data_t {
public:
void put8(uint8_t data) override { }
void put16(uint16_t data) override { }
void put32(uint32_t data) override { }
void put64(uint64_t data) override { }
uint8_t get8() override { return 0; }
uint8_t get8(uint32_t offset, bool update_current = true) override { return 0; }
uint16_t get16() override { return 0; }
uint16_t get16(uint32_t offset, bool update_current = true) override { return 0; }
uint32_t get32() override { return 0; }
uint32_t get32(uint32_t offset, bool update_current = true) override { return 0; }
uint64_t get64() override { return 0; }
uint64_t get64(uint32_t offset, bool update_current = true) override { return 0; }
uint32_t offset() override { return 0; }
};
class pin64_block_t {
public:
pin64_block_t()
: m_crc32{0} { }
virtual ~pin64_block_t() { }
void finalize();
void clear();
virtual void print();
void write(FILE* file);
// getters
uint32_t size();
pin64_data_t* data() { return &m_data; }
util::crc32_t crc32() const { return m_crc32; }
protected:
util::crc32_t m_crc32;
pin64_data_t m_data;
};
class pin64_command_block_t : public pin64_block_t {
public:
void print() override;
};
class pin64_t
{
public:
@ -66,67 +112,58 @@ public:
: m_capture_file(nullptr)
, m_capture_index(~0)
, m_capture_frames(0)
, m_current_frame(nullptr)
, m_current_block(nullptr)
, m_current_cmdblock(nullptr)
, m_playing(false)
{ }
~pin64_t();
void start(int frames = 0);
void finish();
void mark_frame(running_machine& machine);
void clear();
void print();
void mark_frame(running_machine& machine);
void play(int index);
void command(uint64_t* cmd_data, uint32_t size);
void data_begin();
pin64_data_t* data_block();
pin64_block_t& block() { return *m_blocks[m_blocks.size() - 1]; }
void data_end();
bool capturing() const { return m_capture_file != nullptr; }
bool playing() const { return m_playing; }
uint32_t size();
private:
class pin64_frame_t {
public:
pin64_frame_t() { }
~pin64_frame_t();
uint32_t size();
pin64_block_t* start_block();
void write(FILE* file);
void clear();
pin64_block_t& commands() { return m_commands; }
pin64_block_t** blocks();
private:
uint32_t header_size();
uint32_t directory_size();
uint32_t blocks_size();
void fill_directory(std::vector<uint32_t>& directory);
pin64_block_t* m_current_block;
std::vector<pin64_block_t*> m_blocks;
pin64_block_t m_commands;
static const uint8_t FRAME_ID[8];
};
pin64_command_block_t* start_command_block();
void write(FILE* file);
pin64_t::pin64_frame_t* start_frame();
uint32_t header_size();
uint32_t directory_size();
uint32_t frames_size();
uint32_t blocks_size();
uint32_t cmdblocks_size();
void fill_directory(std::vector<uint32_t>& directory);
void write_block_directory(FILE* file);
void write_cmdblock_directory(FILE* file);
void init_capture_index();
FILE *m_capture_file;
int32_t m_capture_index;
int m_capture_frames;
pin64_frame_t* m_current_frame;
std::vector<pin64_frame_t*> m_frames;
pin64_block_t* m_current_block;
std::vector<pin64_block_t*> m_blocks;
pin64_command_block_t* m_current_cmdblock;
std::vector<pin64_command_block_t*> m_cmdblocks;
bool m_playing;
pin64_dummy_data_t m_dummy_data;
static const uint8_t CAP_ID[8];
};