harness: map-precedence calibration (last-wins proven) + layered address probes

This commit is contained in:
SDD committed 2026-10-16 10:11:47 +03:00
1 parent 7030f2068d
commit b2e0448001
2 files changed
+22823

No files matched your search

+22735
View File
File diff suppressed because it is too large. Load diff
+88
View File
@@ -159,6 +159,23 @@ private:
bool m_dumped_vram = false;
optional_shared_ptr<u16> m_vram;
// VT1200_CAL=<path>
// Address-unit and map-precedence calibration. Registers a PROXY over:
// (a) a low-RAM slice 0x00000000-0x0000FFFF -- functionally identical to
// RAM (a backing array) but logging. If this logs, later entries win
// over earlier ones and handlers can be layered; if it never logs,
// earlier entries win.
// (b) three candidate encodings of the video region, to discover which one
// the blitter actually addresses.
// All registered at the END of program_map so precedence is unambiguous.
FILE *m_cal_log = nullptr;
std::map<std::pair<u32, u32>, u32> m_cal_seen;
std::vector<u16> m_cal_ram;
int m_cal_ram_lo = 0;
u16 cal_r(offs_t off);
void cal_w(offs_t off, u16 data);
void log_cal(const char *tag, char kind, u32 addr);
// VT1200_LOG_UNMAPPED=<path>
// A catch-all mapping over the whole address space, registered FIRST so every
// real region added afterwards takes precedence. Anything the firmware
@@ -260,6 +277,13 @@ void vt1200_state::machine_start()
"# address units are the address-map's; firmware operand = addr << 4\n");
}
if (const char *p = getenv("VT1200_CAL"))
{
m_cal_log = fopen(p, "w");
if (m_cal_log)
fprintf(m_cal_log, "# tag kind addr pc -- address-unit / precedence calibration\n");
}
logerror("vt1200: board model=%s busy_ticks=%s busy_w2=%s busy_w3=%s dma_ticks=%s switch=%s log=%s render=%d dump=%ld\n",
getenv("VT1200_BOARD_MODEL") ? getenv("VT1200_BOARD_MODEL") : "off",
getenv("VT1200_BOARD_BUSY_TICKS") ? getenv("VT1200_BOARD_BUSY_TICKS") : "0",
@@ -270,6 +294,55 @@ void vt1200_state::machine_start()
m_log ? "on" : "off", m_render ? 1 : 0, m_dump_frame);
}
void vt1200_state::log_cal(const char *tag, char kind, u32 addr)
{
if (!m_cal_log)
return;
const u32 p = (u32)m_maincpu->state_int(TMS34010_PC);
auto key = std::make_pair(addr, ((p << 8) | (u8)kind));
if (m_cal_seen.find(key) == m_cal_seen.end())
{
m_cal_seen.emplace(key, 1);
fprintf(m_cal_log, "%s %c %08X pc=%08X\n", tag, kind, addr, p);
fflush(m_cal_log);
}
}
static const char *cal_tag(u32 addr)
{
if (addr >= 0x00400000 && addr <= 0x00400fff) return "VID-A";
if (addr >= 0x00040000 && addr <= 0x00040fff) return "VID-B";
if (addr >= 0x00004000 && addr <= 0x00004fff) return "VID-C";
// Catch-all address 0x400000 (reported in bits) divided by 8:
if (addr >= 0x00080000 && addr <= 0x00080fff) return "VID-D";
if (addr >= 0x00020000 && addr <= 0x00020fff) return "VID-E";
return "ABOVE2M";
}
u16 vt1200_state::cal_r(offs_t off)
{
const u32 addr = (u32)off;
if (addr < 0x10000)
{
log_cal("RAMSLICE", 'R', addr);
return m_cal_ram[addr];
}
log_cal(cal_tag(addr), 'R', addr);
return 0;
}
void vt1200_state::cal_w(offs_t off, u16 data)
{
const u32 addr = (u32)off;
if (addr < 0x10000)
{
log_cal("RAMSLICE", 'W', addr);
m_cal_ram[addr] = data;
return;
}
log_cal(cal_tag(addr), 'W', addr);
}
void vt1200_state::machine_reset()
{
if (m_log)
@@ -344,6 +417,21 @@ void vt1200_state::program_map(address_map &map)
map(0xbf200000, 0xbfffffff).rom().region("maincpu", 0);
map(0xff200000, 0xffffffff).rom().region("maincpu", 0);
// Calibration probes. Registered last so precedence is unambiguous.
if (getenv("VT1200_CAL"))
{
m_cal_ram.assign(0x10000, 0);
map(0x00000000, 0x0000ffff).rw(FUNC(vt1200_state::cal_r), FUNC(vt1200_state::cal_w));
map(0x00400000, 0x00400fff).rw(FUNC(vt1200_state::cal_r), FUNC(vt1200_state::cal_w));
map(0x00040000, 0x00040fff).rw(FUNC(vt1200_state::cal_r), FUNC(vt1200_state::cal_w));
map(0x00004000, 0x00004fff).rw(FUNC(vt1200_state::cal_r), FUNC(vt1200_state::cal_w));
map(0x00080000, 0x00080fff).rw(FUNC(vt1200_state::cal_r), FUNC(vt1200_state::cal_w));
map(0x00020000, 0x00020fff).rw(FUNC(vt1200_state::cal_r), FUNC(vt1200_state::cal_w));
// Broad net: everything above 2 MiB that we do not already map. RAM
// rarely reaches here, so a log-only proxy is survivable.
map(0x00200000, 0x01ffffff).rw(FUNC(vt1200_state::cal_r), FUNC(vt1200_state::cal_w));
}
// Undecoded board windows. Left unmapped unless an experiment asks for
// them, so the default behaviour is unchanged.
if (getenv("VT1200_BOARD_RAM"))