openMSX
RomNettouYakyuu.cc
Go to the documentation of this file.
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 #include "Rom.hh"
43 #include "FileOperations.hh"
44 #include "SamplePlayer.hh"
45 #include "serialize.hh"
46 #include "memory.hh"
47 
48 namespace openmsx {
49 
50 RomNettouYakyuu::RomNettouYakyuu(const DeviceConfig& config, std::unique_ptr<Rom> rom_)
51  : Rom8kBBlocks(config, std::move(rom_))
52  , samplePlayer(make_unique<SamplePlayer>(
53  "Nettou Yakyuu-DAC",
54  "Jaleco Moero!! Nettou Yakuu '88 DAC", config,
55  FileOperations::stripExtension(rom->getFilename()) + '_',
56  16, "nettou_yakyuu/nettou_yakyuu_"))
57 {
59 }
60 
62 {
63 }
64 
66 {
67  // ASCII8 behaviour
68  setUnmapped(0);
69  setUnmapped(1);
70  for (int i = 2; i < 6; i++) {
71  setRom(i, 0);
72  redirectToSamplePlayer[i - 2] = false;
73  }
74  setUnmapped(6);
75  setUnmapped(7);
76 
77  samplePlayer->reset();
78 }
79 
80 void RomNettouYakyuu::writeMem(word address, byte value, EmuTime::param /*time*/)
81 {
82  if ((address < 0x4000) || (0xC000 <= address)) return;
83 
84  // mapper stuff, like ASCII8
85  if ((0x6000 <= address) && (address < 0x8000)) {
86  // calculate region in switch zone
87  byte region = (address >> 11) & 3;
88  redirectToSamplePlayer[region] = (value & 0x80) != 0;
89  if (redirectToSamplePlayer[region]) {
90  setUnmapped(region + 2);
91  } else {
92  setRom(region + 2, value);
93  }
94  return;
95  }
96 
97  // sample player stuff
98  if (!redirectToSamplePlayer[(address >> 13) - 2]) {
99  // region not redirected to sample player
100  return;
101  }
102 
103  // bit 7==0: reset
104  if (!(value & 0x80)) {
105  samplePlayer->reset();
106  return;
107  }
108 
109  // bit 6==1: set no retrigger, don't alter playing sample
110  if (value & 0x40) {
111  samplePlayer->stopRepeat();
112  return;
113  }
114 
115  samplePlayer->repeat(value & 0xF);
116 }
117 
119 {
120  return nullptr;
121 }
122 
123 template<typename Archive>
124 void RomNettouYakyuu::serialize(Archive& ar, unsigned /*version*/)
125 {
126  ar.template serializeBase<Rom8kBBlocks>(*this);
127  ar.serialize("SamplePlayer", *samplePlayer);
128  ar.serialize("redirectToSamplePlayer", redirectToSamplePlayer);
129 }
131 REGISTER_MSXDEVICE(RomNettouYakyuu, "RomNettouYakyuu");
132 
133 } // namespace openmsx
void setRom(byte region, int block)
Selects a block of the ROM image for reading in a certain region.
Definition: RomBlocks.cc:89
REGISTER_MSXDEVICE(DebugDevice,"DebugDevice")
void writeMem(word address, byte value, EmuTime::param time) override
Write a given byte to a given location at a certain time to this device.
static param dummy()
Definition: EmuTime.hh:21
unsigned char byte
8 bit unsigned integer
Definition: openmsx.hh:27
byte * getWriteCacheLine(word address) const override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for writing...
STL namespace.
void serialize(Archive &ar, unsigned version)
string_ref getFilename(string_ref path)
Returns the file portion of a path name.
void reset(EmuTime::param time) override
This method is called on reset.
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:7
unsigned short word
16 bit unsigned integer
Definition: openmsx.hh:32
string_ref stripExtension(string_ref path)
Returns the path without extension.
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
Definition: serialize.hh:802
void setUnmapped(byte region)
Select 'unmapped' memory for this region.
Definition: RomBlocks.cc:76
std::unique_ptr< T > make_unique()
Definition: memory.hh:27
RomNettouYakyuu(const DeviceConfig &config, std::unique_ptr< Rom > rom)