mirror of
https://github.com/holub/mame
synced 2025-10-05 08:41:31 +03:00
Get PIN64 code to function correctly. (nw)
This commit is contained in:
parent
68090e5606
commit
af39fe7816
@ -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];
|
||||
|
@ -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++;
|
||||
}
|
||||
|
@ -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];
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user