summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/machine/m6502_vtscr.cpp
blob: 5c7c9168cb8b95f2d20f4fe4ce0c50807c246a12 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
// license:BSD-3-Clause
// copyright-holders:David Shah
/***************************************************************************

    m6502_vtscr.cpp

    6502 with VRT VTxx instruction scrambling

    Scrambling in newer NES-based VTxx systems (FC pocket, etc) seems to be
    enabled with a write of 5 to 0x411E, then is activated at the next jump?
    When enabled, opcodes are to be XORed with 0xA1

    Another form of scrambling is used in the VRT VT1682, this is not yet
    implemented at all in MAME (it's used for the MiWi2 and InterAct consoles).
    This is simpler, permanently activated and consists of swapping opcode bits
    7 and 2.

***************************************************************************/

#include "emu.h"
#include "m6502_vtscr.h"

DEFINE_DEVICE_TYPE(M6502_VTSCR, m6502_vtscr, "m6502_vtscr", "M6502 with VTxx scrambling")

m6502_vtscr::m6502_vtscr(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
	m6502_device(mconfig, M6502_VTSCR, tag, owner, clock)
{
}

void m6502_vtscr::device_start()
{
	mintf = std::make_unique<mi_decrypt>();
	set_scramble(false);
	init();
}

void m6502_vtscr::set_next_scramble(bool scr)
{
	downcast<mi_decrypt &>(*mintf).m_next_scramble = scr;
}

void m6502_vtscr::set_scramble(bool scr)
{
	downcast<mi_decrypt &>(*mintf).m_next_scramble = scr;
	downcast<mi_decrypt &>(*mintf).m_scramble_en = scr;
}


void m6502_vtscr::device_reset()
{
	set_scramble(false);
	m6502_device::device_reset();
}

bool m6502_vtscr::mi_decrypt::toggle_scramble(uint8_t op) {
	return (op == 0x4C) || (op == 0x00) || (op == 0x6C);
}


uint8_t m6502_vtscr::mi_decrypt::read_sync(uint16_t adr)
{
	uint8_t res = cache->read_byte(adr);
	if(m_scramble_en)
	{
		res = descramble(res);
	}

	if(toggle_scramble(res))
	{
		m_scramble_en = m_next_scramble;
	}
	return res;
}

uint8_t m6502_vtscr::mi_decrypt::descramble(uint8_t op)
{
	return op ^ 0xA1;
}

std::unique_ptr<util::disasm_interface> m6502_vtscr::create_disassembler()
{
	return std::make_unique<disassembler>(downcast<mi_decrypt *>(mintf.get()));
}

m6502_vtscr::disassembler::disassembler(mi_decrypt *mi) : mintf(mi)
{
}

u32 m6502_vtscr::disassembler::interface_flags() const
{
	return SPLIT_DECRYPTION;
}

u8 m6502_vtscr::disassembler::decrypt8(u8 value, offs_t pc, bool opcode) const
{
	return opcode && mintf->m_scramble_en ? mintf->descramble(value) : value;
}