OXYGENHUB
◆ main openmsx / src / memory / RomNettouYakyuu.cc
3.7 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
1
// Based on information from hap/enen, published here:
2
// http://www.msx.org/forumtopicl8552.html
3
// and his implementation in blueMSX
4
//
5
// Jaleco - Moero!! Nettou Yakyuu '88, 256KB ROM, CRC32 68745C64
6
// NEC D7756C 146 sample player with internal 256Kbit ROM, undumped. Same
7
// samples as Famicom Moero!! Pro Yakyuu (Black/Red), recording available at
8
// http://home.planet.nl/~haps/segali_archive/
9
10
// 4*8KB pages at $4000-$BFFF, initialized to 0.
11
// Mapper chip is exactly the same as ASCII8, except for data bit 7:
12
// a:011ppxxx xxxxxxxx d:sxxbbbbb
13
// a:address, d:data, p: page, b:bank, x:don't care
14
// s:if set, page reads/writes redirect to sample player via a 74HC174, eg.
15
// write $80 to $7800 -> $A000-$BFFF = sample player I/O
16
17
// Sample player (datasheet, 690KB one on
18
// http://www.datasheetarchive.com/search.php?t=0&q=uPD7756 ):
19
// reads: always $FF (/BUSY not used)
20
// writes: d:rsxxiiii
21
// i:I0-I3 (sample number, latched on /ST rising edge when not playing)
22
// s:/ST (start), r:1=enable continuous rising edges to /ST (ORed with s),
23
// 0=falling edge to /RESET
24
// As I'm unable to measure, s and r bits pin setups are guessed from knowing
25
// the behaviour (examples underneath).
26
27
// examples:
28
// - $C0: nothing
29
// - $80: "strike, strike, strike, strike, ..."
30
// - $80, $C0: "strike"
31
// - $80, short delay, $00/$40: "stri"
32
// - $80, short delay, $81: "strike, ball, ball, ball, ball, ..."
33
34
// note: writes to sample player are ignored if on page $6000-$7FFF, possibly
35
// due to conflict with mapper chip, reads still return $FF though.
36
37
// regarding this implementation: part of the above behaviour is put in the
38
// sample player. It may be a good idea to move this behaviour to a more
39
// specialized class some time in the future.
40
41
#include "RomNettouYakyuu.hh"
42
43
#include "FileOperations.hh"
44
45
#include "serialize.hh"
46
#include "xrange.hh"
47
48
#include <algorithm>
49
50
namespace openmsx {
51
52
RomNettouYakyuu::RomNettouYakyuu(const DeviceConfig& config, Rom&& rom_)
53
	: Rom8kBBlocks(config, std::move(rom_))
54
	, samplePlayer(
55
		"Nettou Yakyuu-DAC",
56
		"Jaleco Moero!! Nettou Yakuu '88 DAC", config,
57
		strCat(FileOperations::stripExtension(rom.getFilename()), '_'),
58
		16, "nettou_yakyuu/nettou_yakyuu_")
59
{
60
	reset(EmuTime::dummy());
61
}
62
63
void RomNettouYakyuu::reset(EmuTime /*time*/)
64
{
65
	// ASCII8 behaviour
66
	setUnmapped(0);
67
	setUnmapped(1);
68
	for (auto i : xrange(2, 6)) {
69
		setRom(i, 0);
70
	}
71
	setUnmapped(6);
72
	setUnmapped(7);
73
74
	std::ranges::fill(redirectToSamplePlayer, false);
75
	samplePlayer.reset();
76
}
77
78
void RomNettouYakyuu::writeMem(uint16_t address, byte value, EmuTime /*time*/)
79
{
80
	if ((address < 0x4000) || (0xC000 <= address)) return;
81
82
	// mapper stuff, like ASCII8
83
	if ((0x6000 <= address) && (address < 0x8000)) {
84
		// calculate region in switch zone
85
		byte region = (address >> 11) & 3;
86
		redirectToSamplePlayer[region] = (value & 0x80) != 0;
87
		if (redirectToSamplePlayer[region]) {
88
			setUnmapped(region + 2);
89
		} else {
90
			setRom(region + 2, value);
91
		}
92
		return;
93
	}
94
95
	// sample player stuff
96
	if (!redirectToSamplePlayer[(address >> 13) - 2]) {
97
		// region not redirected to sample player
98
		return;
99
	}
100
101
	// bit 7==0: reset
102
	if (!(value & 0x80)) {
103
		samplePlayer.reset();
104
		return;
105
	}
106
107
	// bit 6==1: set no retrigger, don't alter playing sample
108
	if (value & 0x40) {
109
		samplePlayer.stopRepeat();
110
		return;
111
	}
112
113
	samplePlayer.repeat(value & 0xF);
114
}
115
116
byte* RomNettouYakyuu::getWriteCacheLine(uint16_t /*address*/)
117
{
118
	return nullptr;
119
}
120
121
template<typename Archive>
122
void RomNettouYakyuu::serialize(Archive& ar, unsigned /*version*/)
123
{
124
	ar.template serializeBase<Rom8kBBlocks>(*this);
125
	ar.serialize("SamplePlayer",           samplePlayer,
126
	             "redirectToSamplePlayer", redirectToSamplePlayer);
127
}
128
INSTANTIATE_SERIALIZE_METHODS(RomNettouYakyuu);
129
REGISTER_MSXDEVICE(RomNettouYakyuu, "RomNettouYakyuu");
130
131
} // namespace openmsx