enmirage: fixed and updated to load and play via MIDI, panel controls hooked up [Tim Lindner]

This commit is contained in:
tim lindner 2021-06-03 11:26:19 -07:00 committed by GitHub
parent 69844e3993
commit 0ec76fc818
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 590 additions and 158 deletions

View File

@ -114,6 +114,9 @@ DEFINE_DEVICE_TYPE(EPSON_SD_621L, epson_sd_621l, "epson_sd_621l", "EPSON SD-621L
DEFINE_DEVICE_TYPE(EPSON_SD_680L, epson_sd_680l, "epson_sd_680l", "EPSON SD-680L Mini-Floppy Disk Drive")
#endif
// Panasonic 3.5" drive
DEFINE_DEVICE_TYPE(PANA_JU_363, pana_ju_363, "pana_ju_363", "Panasonic JU-363 Flexible Disk Drive")
// Sony 3.5" drives
DEFINE_DEVICE_TYPE(SONY_OA_D31V, sony_oa_d31v, "sony_oa_d31v", "Sony OA-D31V Micro Floppydisk Drive")
DEFINE_DEVICE_TYPE(SONY_OA_D32W, sony_oa_d32w, "sony_oa_d32w", "Sony OA-D32W Micro Floppydisk Drive")
@ -741,7 +744,7 @@ uint32_t floppy_image_device::flux_screen_update(screen_device &device, bitmap_r
}
ppi++;
}
}
}
} else {
for(int y = cliprect.min_y; y <= cliprect.max_y; y++) {
flux_per_pixel_info *ppi = m_flux_per_pixel_infos.data() + y * flux_screen_sx + cliprect.min_x;
@ -2509,6 +2512,39 @@ void epson_sd_321::setup_characteristics()
variants.push_back(floppy_image::DSDD);
}
//-------------------------------------------------
// 3.5" Panasonic Flexible Disk Drive JU-363
//
// track to track: 3 ms
// settling time: 15 ms
// motor start time: 500 ms
// transfer rate: 250 Kbits/s
//
//-------------------------------------------------
pana_ju_363::pana_ju_363(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
floppy_image_device(mconfig, PANA_JU_363, tag, owner, clock)
{
}
pana_ju_363::~pana_ju_363()
{
}
void pana_ju_363::setup_characteristics()
{
form_factor = floppy_image::FF_35;
tracks = 84;
sides = 2;
dskchg_writable = true;
set_rpm(300);
variants.push_back(floppy_image::SSSD);
variants.push_back(floppy_image::SSDD);
variants.push_back(floppy_image::DSDD);
}
//-------------------------------------------------
// Sony OA-D31V
//

View File

@ -333,6 +333,7 @@ DECLARE_FLOPPY_IMAGE_DEVICE(FLOPPY_8_DSDD, floppy_8_dsdd, "floppy_8"
DECLARE_FLOPPY_IMAGE_DEVICE(EPSON_SMD_165, epson_smd_165, "floppy_3_5")
DECLARE_FLOPPY_IMAGE_DEVICE(EPSON_SD_320, epson_sd_320, "floppy_5_25")
DECLARE_FLOPPY_IMAGE_DEVICE(EPSON_SD_321, epson_sd_321, "floppy_5_25")
DECLARE_FLOPPY_IMAGE_DEVICE(PANA_JU_363, pana_ju_363, "floppy_3_5")
DECLARE_FLOPPY_IMAGE_DEVICE(SONY_OA_D31V, sony_oa_d31v, "floppy_3_5")
DECLARE_FLOPPY_IMAGE_DEVICE(SONY_OA_D32W, sony_oa_d32w, "floppy_3_5")
DECLARE_FLOPPY_IMAGE_DEVICE(SONY_OA_D32V, sony_oa_d32v, "floppy_3_5")

View File

@ -80,7 +80,7 @@ void esq8img_format::find_size(io_generic *io, int &track_count, int &head_count
head_count = 1;
sector_count = 6;
if (size == 5632 * 80)
if(size == 5632 * 80)
{
return;
}
@ -95,6 +95,7 @@ int esq8img_format::identify(io_generic *io, uint32_t form_factor, const std::ve
if(track_count)
return 50;
return 0;
}
@ -105,8 +106,9 @@ bool esq8img_format::load(io_generic *io, uint32_t form_factor, const std::vecto
uint8_t sectdata[(5*1024) + 512];
desc_s sectors[6];
for(int i=0; i<sector_count; i++) {
if (i < 5)
for(int i=0; i<sector_count; i++)
{
if(i < 5)
{
sectors[i].data = sectdata + (1024*i); // 5 1024 byte sectors
sectors[i].size = 1024;
@ -138,6 +140,7 @@ bool esq8img_format::load(io_generic *io, uint32_t form_factor, const std::vecto
bool esq8img_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image)
{
uint64_t file_offset = 0;
int track_count, head_count, sector_count;
get_geometry_mfm_pc(image, 2000, track_count, head_count, sector_count);
@ -151,13 +154,30 @@ bool esq8img_format::save(io_generic *io, const std::vector<uint32_t> &variants,
if(sector_count != 6)
sector_count = 6;
uint8_t sectdata[10*512];
int track_size = (5*1024) + 512;
for(int track=0; track < track_count; track++)
{
for(int head=0; head < head_count; head++)
{
auto bitstream = generate_bitstream_from_track(track, head, 2000, image);
auto sectors = extract_sectors_from_bitstream_mfm_pc(bitstream);
int sector_expected_size;
for(int track=0; track < track_count; track++) {
for(int head=0; head < head_count; head++) {
get_track_data_mfm_pc(track, head, image, 2000, 512, sector_count, sectdata);
io_generic_write(io, sectdata, (track*head_count + head)*track_size, track_size);
for(int sector = 0; sector < sector_count; sector++)
{
if(sector < 5)
sector_expected_size = 1024;
else
sector_expected_size = 512;
if(sectors[sector].size() != sector_expected_size)
{
osd_printf_error("esq8img_format: track %d, sector %d invalid size: %d\n", track, sector, sectors[sector].size());
return false;
}
io_generic_write(io, sectors[sector].data(), file_offset, sector_expected_size);
file_offset += sector_expected_size;
}
}
}

View File

@ -1,85 +1,135 @@
// license:BSD-3-Clause
// copyright-holders:R. Belmont
// copyright-holders:R. Belmont, tim lindner
/***************************************************************************
drivers/mirage.c
drivers/enmirage.c
Ensoniq Mirage Sampler
Preliminary driver by R. Belmont
Ensoniq Mirage Sampler
Preliminary driver by R. Belmont
Fleshed out by tim lindner
Map for Mirage:
0000-7fff: 32k window on 128k of sample RAM
8000-bfff: main RAM
c000-dfff: optional expansion RAM
e100-e101: 6850 UART (for MIDI)
e200-e2ff: 6522 VIA
e408-e40f: filter cut-off frequency
e410-e417: filter resonance
e418-e41f: multiplexer address pre-set
e800-e803: WD1770 FDC
ec00-ecef: ES5503 "DOC" sound chip
f000-ffff: boot ROM
Models:
DSK-8: Pratt-Reed keyboard (early 1984)
DSK-8: Fatar keyboard (late 1984)
DMS-8: Rack mount (1985)
DSK-1: Unweighted keyboard, stereo output (1986)
NMI: IRQ from WD1772
IRQ: DRQ from WD1772 wire-ORed with IRQ from ES5503 wire-ORed with IRQ from VIA6522
FIRQ: IRQ from 6850 UART
M6809 Map for Mirage:
0000-7fff: 32k window on 128k of sample RAM
8000-bfff: main RAM
c000-dfff: optional expansion RAM
e100-e101: 6850 UART (for MIDI)
e200-e2ff: 6522 VIA
e400-e407: write to both filters
e408-e40f: filter cut-off frequency
e410-e417: filter resonance
e418-e41f: DAC pre-set
e800-e803: WD1770 FDC
ec00-ecef: ES5503 "DOC" sound chip
f000-ffff: boot ROM
LED / switch matrix:
M6809 Interrupts:
NMI: IRQ from WD1772
IRQ: wired-ORed: DRQ from WD1772, IRQ from ES5503, IRQ from VIA6522, IRQ from cartridge
FIRQ: IRQ from 6850 UART
A B C D E F G DP
ROW 0: LOAD UPPER LOAD LOWER SAMPLE UPPER PLAY SEQ LOAD SEQ SAVE SEQ REC SEQ SAMPLE LOWER
ROW 1: 3 6 9 5 8 0 2 Enter
ROW 2: 1 4 7 up arrow PARAM dn arrow VALUE CANCEL
L. AN: SEG A SEG B SEG C SEG D SEG E SEG F SEG G SEG DP (decimal point)
R. AN: SEG A SEG B SEG C SEG D SEG E SEG F SEG G SEG DP
LED / switch matrix:
Column number in VIA port A bits 0-2 is converted to discrete lines by a 74LS145.
Port A bit 3 is right anode, bit 4 is left anode
ROW 0 is read on VIA port A bit 5, ROW 1 in port A bit 6, and ROW 2 in port A bit 7.
A B C D E F G DP
ROW 0: LOAD UPPER LOAD LOWER SAMPLE UPPER PLAY SEQ LOAD SEQ SAVE SEQ REC SEQ SAMPLE LOWER
ROW 1: 3 6 9 5 8 0 2 Enter
ROW 2: 1 4 7 up arrow PARAM dn arrow VALUE CANCEL
L. AN: SEG A SEG B SEG C SEG D SEG E SEG F SEG G SEG DP (decimal point)
R. AN: SEG A SEG B SEG C SEG D SEG E SEG F SEG G SEG DP
Keyboard models talk to the R6500 through the VIA shifter: CA2 is handshake, CB1 is shift clock, CB2 is shift data.
This is unconnected on the rackmount version.
Column number in VIA port A bits 0-2 is converted to discrete lines by a 74LS145.
Port A bit 3 is right anode, bit 4 is left anode
ROW 0 is read on VIA port A bit 5, ROW 1 in port A bit 6, and ROW 2 in port A bit 7.
Keyboard models talk to the R6500/11 through the VIA shifter: CA2 is handshake, CB1 is shift clock,
CB2 is shift data.
This is unconnected on the rackmount version.
Unimplemented:
* Four Pole Low-Pass Voltage Controlled Filter section
* External sync signal
* Foot pedal
* ADC feedback
* Piano keyboard controller
* Expansion connector
* Stereo output
***************************************************************************/
#include "emu.h"
#include "bus/midi/midi.h"
#include "cpu/m6809/m6809.h"
#include "imagedev/floppy.h"
#include "machine/6850acia.h"
#include "machine/6522via.h"
#include "machine/wd_fdc.h"
#include "formats/esq8_dsk.h"
#include "imagedev/cassette.h"
#include "imagedev/floppy.h"
#include "machine/6522via.h"
#include "machine/6850acia.h"
#include "machine/clock.h"
#include "machine/input_merger.h"
#include "machine/wd_fdc.h"
#include "sound/es5503.h"
#include "video/pwm.h"
#include "speaker.h"
#include "video/pwm.h"
#include "mirage.lh"
#include "enmirage.lh"
#define LOG_ADC_READ (1U << 1)
#define LOG_FILTER_WRITE (1U << 2)
#define VERBOSE (0)
//#define VERBOSE (LOG_ADC_READ)
//#define VERBOSE (LOG_ADC_READ|LOG_FILTER_WRITE)
#include "logmacro.h"
#define LOGADCREAD(...) LOGMASKED(LOG_ADC_READ, __VA_ARGS__)
#define LOGFILTERWRITE(...) LOGMASKED(LOG_FILTER_WRITE, __VA_ARGS__)
#define PITCH_TAG "pitch"
#define MOD_TAG "mod"
class enmirage_state : public driver_device
{
public:
enmirage_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_display(*this, "display"),
m_fdc(*this, "wd1772"),
m_floppy_connector(*this, "wd1772:0"),
m_via(*this, "via6522")
driver_device(mconfig, type, tag)
, m_maincpu(*this, "maincpu")
, m_sample_ram(*this, "sampleram", 1024 * 128, ENDIANNESS_BIG)
, m_sample_bank(*this, "samplebank")
, m_display(*this, "display")
, m_fdc(*this, "wd1772")
, m_floppy_connector(*this, "wd1772:0")
, m_via(*this, "via6522")
, m_irq_merge(*this, "irqmerge")
, m_cassette(*this, "cassette")
, m_acia(*this, "acia6850")
, m_wheel(*this, {PITCH_TAG, MOD_TAG})
, m_key(*this, {"pb5", "pb6", "pb7"})
{
}
void mirage(machine_config &config);
void enmirage_es5503_map(address_map &map);
void init_mirage();
private:
DECLARE_INPUT_CHANGED_MEMBER(input_changed);
static void floppy_formats(format_registration &fr);
protected:
virtual void machine_start() override;
void coefficients_w(offs_t offset, uint8_t data);
private:
void update_keypad_matrix();
uint8_t mirage_via_read_portb();
void mirage_via_write_porta(uint8_t data);
void mirage_via_write_portb(uint8_t data);
DECLARE_WRITE_LINE_MEMBER(mirage_doc_irq);
uint8_t mirage_adc_read();
void mirage_map(address_map &map);
@ -87,12 +137,25 @@ private:
virtual void machine_reset() override;
required_device<mc6809e_device> m_maincpu;
memory_share_creator<uint8_t> m_sample_ram;
required_memory_bank m_sample_bank;
required_device<pwm_display_device> m_display;
required_device<wd1772_device> m_fdc;
required_device<floppy_connector> m_floppy_connector;
required_device<via6522_device> m_via;
required_device<input_merger_device> m_irq_merge;
required_device<cassette_image_device> m_cassette;
required_device<acia6850_device> m_acia;
int last_sndram_bank;
required_ioport_array<2> m_wheel;
required_ioport_array<3> m_key;
int m_mux_value;
int m_key_col_select;
/* temporary audio data -- used to get past startup filter calibration -- remove when filters are implemented */
const uint8_t m_wave[34] = {0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x69};
int m_wave_index;
};
void enmirage_state::floppy_formats(format_registration &fr)
@ -103,68 +166,173 @@ void enmirage_state::floppy_formats(format_registration &fr)
static void ensoniq_floppies(device_slot_interface &device)
{
device.option_add("35dd", FLOPPY_35_DD);
}
WRITE_LINE_MEMBER(enmirage_state::mirage_doc_irq)
{
// m_maincpu->set_input_line(M6809_IRQ_LINE, state);
device.option_add("35dd", PANA_JU_363);
}
uint8_t enmirage_state::mirage_adc_read()
{
return 0x00;
uint8_t value;
switch(m_mux_value & 0x03)
{
case 0:
// value = m_cassette->input(); /* compressed and mixed input: audio in and ES 5503 (TODO) */
value = m_wave[m_wave_index]; /* fake data to get past filter calibration (remove when filter implemented) */
LOGADCREAD("%s, 5503 sample: channel: compressed input, data: $%02x\n", machine().describe_context(), value);
if(++m_wave_index == 34) m_wave_index = 0;
break;
case 1:
value = m_cassette->input(); /* line level and mixed input: audio in and ES 5503 (TODO) */
LOGADCREAD("%s, 5503 sample: channel: line input, data: $%02x\n", machine().describe_context(), value);
break;
case 2:
value = m_wheel[0]->read(); /* pitch wheel */
LOGADCREAD("%s, 5503 sample: channel: pitch wheel, data: $%02x\n", machine().describe_context(), value);
break;
case 3:
value = m_wheel[1]->read(); /* mod wheel */
LOGADCREAD("%s, 5503 sample: channel: mod wheel, data: $%02x\n", machine().describe_context(), value);
break;
}
return value;
}
void enmirage_state::machine_start()
{
save_item(NAME(m_mux_value));
save_item(NAME(m_key_col_select));
save_item(NAME(m_wave_index));
m_sample_bank->configure_entries(0, 4, m_sample_ram, 0x8000);
}
void enmirage_state::machine_reset()
{
last_sndram_bank = 0;
membank("sndbank")->set_base(memregion("es5503")->base() );
m_sample_bank->set_entry(0);
m_mux_value = 0;
m_wave_index = 0;
}
void enmirage_state::mirage_map(address_map &map)
{
map(0x0000, 0x7fff).bankrw("sndbank"); // 32k window on 128k of wave RAM
map(0x8000, 0xbfff).ram(); // main RAM
map(0xc000, 0xdfff).ram(); // expansion RAM
map(0x0000, 0x7fff).bankrw("samplebank"); // 32k window on 128k of sample RAM
map(0x8000, 0xbfff).ram(); // main RAM
map(0xc000, 0xdfff).ram(); // expansion RAM
map(0xe100, 0xe101).rw("acia6850", FUNC(acia6850_device::read), FUNC(acia6850_device::write));
map(0xe200, 0xe2ff).m(m_via, FUNC(via6522_device::map));
map(0xe400, 0xe4ff).noprw();
map(0xe400, 0xe41f).w(FUNC(enmirage_state::coefficients_w));
map(0xe800, 0xe803).rw(m_fdc, FUNC(wd1772_device::read), FUNC(wd1772_device::write));
map(0xec00, 0xecef).rw("es5503", FUNC(es5503_device::read), FUNC(es5503_device::write));
map(0xf000, 0xffff).rom().region("osrom", 0);
}
void enmirage_state::coefficients_w(offs_t offset, uint8_t data)
{
uint8_t channel = offset & 0x07;
uint8_t filter_input = (offset >> 3) & 0x03;
LOGFILTERWRITE("%s, filter update: channel: %d, data: $%02x (%s%s%s%s)\n",
machine().describe_context(),
channel,
data,
(filter_input & 0x01) == 0 ? "VF" : "", /* cut-off frequency */
(filter_input & 0x03) == 0 ? " and " : "",
(filter_input & 0x02) == 0 ? "VQ" : "", /* filter resonance */
(filter_input & 0x03) == 0x03 ? "preload dac" : "");
}
// port A:
// bits 5/6/7 keypad rows 0/1/2 return
INPUT_CHANGED_MEMBER(enmirage_state::input_changed)
{
update_keypad_matrix();
}
void enmirage_state::update_keypad_matrix()
{
uint8_t value;
value = ((m_key[0]->read() >> m_key_col_select) & 0x01) << 5;
value |= ((m_key[1]->read() >> m_key_col_select) & 0x01) << 6;
value |= ((m_key[2]->read() >> m_key_col_select) & 0x01) << 7;
m_via->write_pa(value);
}
// port B:
// bit 6: IN disk load
// bit 5: IN Q Chip sync
uint8_t enmirage_state::mirage_via_read_portb()
{
uint8_t value = m_via->read_pb();
floppy_image_device *floppy = m_floppy_connector ? m_floppy_connector->get_device() : nullptr;
if (floppy)
{
if (floppy->dskchg_r())
value |= 0x40;
else
value &= ~0x40;
}
return value;
}
// port A: front panel
// bits 0-2: column select from 0-7
// bits 3/4 = right and left LED enable
// bits 5/6/7 keypad rows 0/1/2 return
// bits 0/1/2: dual purpose (0 to 7 lines, though a 74LS145 decoder):
// keyboard matrix column select
// 7 segment display driver
// bits 3/4 = right and left 7 segment display enable
// bits 5/6/7 = Keyboard matrix row sense from 0 to 2
void enmirage_state::mirage_via_write_porta(uint8_t data)
{
u8 segdata = data & 7;
m_display->matrix(((data >> 3) & 3) ^ 3, (1<<segdata));
uint8_t new_select = (data & 0x07);
if (m_key_col_select != new_select)
{
m_key_col_select = new_select;
update_keypad_matrix();
}
}
// port B:
// bit 7: OUT UART clock
// bit 4: OUT disk enable (motor on?)
// bit 3: OUT sample/play
// bit 2: OUT mic line/in
// bit 1: OUT upper/lower bank (64k halves)
// bit 0: OUT bank 0/bank 1 (32k halves)
// bit 7: OUT UART clock
// bit 4: OUT disk select, motor on, and 6500/11 reset
// bit 3: OUT sample/play
// bit 2: OUT mic line/in
// bit 1: OUT upper/lower bank (64k halves)
// bit 0: OUT bank 0/bank 1 (32k quarters)
void enmirage_state::mirage_via_write_portb(uint8_t data)
{
int bank = 0;
// handle sound RAM bank switching
bank = (data & 2) ? (64*1024) : 0;
bank += (data & 1) ? (32*1024) : 0;
if (bank != last_sndram_bank)
{
last_sndram_bank = bank;
membank("sndbank")->set_base(memregion("es5503")->base() + bank);
}
bank = data & 0x03;
m_sample_bank->set_entry(bank);
// handle floppy motor on
floppy_image_device *floppy = m_floppy_connector->get_device();
if (floppy)
floppy->mon_w(data & 0x10 ? 1 : 0);
// handle 6500/11 reset (TODO)
// record audio input mixer position
m_mux_value = (data >> 2) & 0x03;
// handle acia clock
// this bit is set by the internal via timer
int clock = (data >> 7) & 0x01;
m_acia->write_txc(clock);
m_acia->write_rxc(clock);
}
void enmirage_state::enmirage_es5503_map(address_map &map)
{
map(0x00000, 0x1ffff).ram().share("sampleram");
}
void enmirage_state::mirage(machine_config &config)
@ -172,40 +340,88 @@ void enmirage_state::mirage(machine_config &config)
MC6809E(config, m_maincpu, 2000000);
m_maincpu->set_addrmap(AS_PROGRAM, &enmirage_state::mirage_map);
SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right();
es5503_device &es5503(ES5503(config, "es5503", 7000000));
es5503.set_channels(2);
es5503.irq_func().set(FUNC(enmirage_state::mirage_doc_irq));
es5503.adc_func().set(FUNC(enmirage_state::mirage_adc_read));
es5503.add_route(0, "lspeaker", 1.0);
es5503.add_route(1, "rspeaker", 1.0);
INPUT_MERGER_ANY_HIGH(config, m_irq_merge).output_handler().set_inputline(m_maincpu, M6809_IRQ_LINE);
// <0> via6522
// <1> wd1772
// <2> es5502
// <3> cartridge connector (TODO)
MOS6522(config, m_via, 1000000);
SPEAKER(config, "speaker").front_center();
CASSETTE(config, m_cassette);
m_cassette->set_default_state(CASSETTE_PLAY | CASSETTE_MOTOR_DISABLED | CASSETTE_SPEAKER_ENABLED);
m_cassette->add_route(ALL_OUTPUTS, "speaker", 1.0);
es5503_device &es5503(ES5503(config, "es5503", 8000000));
es5503.set_channels(8);
es5503.set_addrmap(0, &enmirage_state::enmirage_es5503_map);
es5503.irq_func().set(m_irq_merge, FUNC(input_merger_device::in_w<2>));
es5503.adc_func().set(FUNC(enmirage_state::mirage_adc_read));
es5503.add_route(ALL_OUTPUTS, "speaker", 1.0);
MOS6522(config, m_via, 3000000);
m_via->writepa_handler().set(FUNC(enmirage_state::mirage_via_write_porta));
m_via->readpb_handler().set(FUNC(enmirage_state::mirage_via_read_portb));
m_via->writepb_handler().set(FUNC(enmirage_state::mirage_via_write_portb));
m_via->irq_handler().set_inputline(m_maincpu, M6809_IRQ_LINE);
m_via->irq_handler().set(m_irq_merge, FUNC(input_merger_device::in_w<0>));
PWM_DISPLAY(config, m_display).set_size(2, 8);
m_display->set_segmask(0x3, 0xff);
config.set_default_layout(layout_mirage);
config.set_default_layout(layout_enmirage);
acia6850_device &acia6850(ACIA6850(config, "acia6850", 0));
acia6850.irq_handler().set_inputline(m_maincpu, M6809_FIRQ_LINE);
ACIA6850(config, m_acia).txd_handler().set("mdout", FUNC(midi_port_device::write_txd));
m_acia->irq_handler().set_inputline(m_maincpu, M6809_FIRQ_LINE);
MIDI_PORT(config, "mdin", midiin_slot, "midiin").rxd_handler().set(m_acia, FUNC(acia6850_device::write_rxd));
MIDI_PORT(config, "mdout", midiout_slot, "midiout");
WD1772(config, m_fdc, 8000000);
m_fdc->intrq_wr_callback().set_inputline(m_maincpu, INPUT_LINE_NMI);
m_fdc->drq_wr_callback().set_inputline(m_maincpu, M6809_IRQ_LINE);
m_fdc->drq_wr_callback().set(m_irq_merge, FUNC(input_merger_device::in_w<1>));
FLOPPY_CONNECTOR(config, "wd1772:0", ensoniq_floppies, "35dd", enmirage_state::floppy_formats);
FLOPPY_CONNECTOR(config, "wd1772:0", ensoniq_floppies, "35dd", enmirage_state::floppy_formats).enable_sound(true);
// This clock allows the CPU to keep in sync with the sound chip - may not be used in the firmware
clock_device &es5503_ca3_clock(CLOCK(config, "ca3_clock", XTAL(8'000'000) / 16));
es5503_ca3_clock.signal_handler().set(m_via, FUNC(via6522_device::write_pb5));
}
static INPUT_PORTS_START( mirage )
static INPUT_PORTS_START(mirage)
PORT_START("pb5") /* KEY ROW 0 */
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Load Upper") PORT_CODE(KEYCODE_A) PORT_CHANGED_MEMBER(DEVICE_SELF, enmirage_state, input_changed, 0)
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Load Lower") PORT_CODE(KEYCODE_B) PORT_CHANGED_MEMBER(DEVICE_SELF, enmirage_state, input_changed, 0)
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Sample Upper") PORT_CODE(KEYCODE_C) PORT_CHANGED_MEMBER(DEVICE_SELF, enmirage_state, input_changed, 0)
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Play Sequence") PORT_CODE(KEYCODE_D) PORT_CHANGED_MEMBER(DEVICE_SELF, enmirage_state, input_changed, 0)
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Load Sequence") PORT_CODE(KEYCODE_E) PORT_CHANGED_MEMBER(DEVICE_SELF, enmirage_state, input_changed, 0)
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Save Sequence") PORT_CODE(KEYCODE_F) PORT_CHANGED_MEMBER(DEVICE_SELF, enmirage_state, input_changed, 0)
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Record Sequence") PORT_CODE(KEYCODE_G) PORT_CHANGED_MEMBER(DEVICE_SELF, enmirage_state, input_changed, 0)
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Sample Lower") PORT_CODE(KEYCODE_H) PORT_CHANGED_MEMBER(DEVICE_SELF, enmirage_state, input_changed, 0)
PORT_START("pb6") /* KEY ROW 1 */
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("3") PORT_CODE(KEYCODE_3) PORT_CHANGED_MEMBER(DEVICE_SELF, enmirage_state, input_changed, 0)
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("6") PORT_CODE(KEYCODE_6) PORT_CHANGED_MEMBER(DEVICE_SELF, enmirage_state, input_changed, 0)
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("9") PORT_CODE(KEYCODE_9) PORT_CHANGED_MEMBER(DEVICE_SELF, enmirage_state, input_changed, 0)
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("5") PORT_CODE(KEYCODE_5) PORT_CHANGED_MEMBER(DEVICE_SELF, enmirage_state, input_changed, 0)
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("8") PORT_CODE(KEYCODE_8) PORT_CHANGED_MEMBER(DEVICE_SELF, enmirage_state, input_changed, 0)
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("0/Prog") PORT_CODE(KEYCODE_0) PORT_CHANGED_MEMBER(DEVICE_SELF, enmirage_state, input_changed, 0)
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("2") PORT_CODE(KEYCODE_2) PORT_CHANGED_MEMBER(DEVICE_SELF, enmirage_state, input_changed, 0)
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Enter") PORT_CODE(KEYCODE_ENTER) PORT_CHANGED_MEMBER(DEVICE_SELF, enmirage_state, input_changed, 0)
PORT_START("pb7") /* KEY ROW 2 */
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("1") PORT_CODE(KEYCODE_1) PORT_CHANGED_MEMBER(DEVICE_SELF, enmirage_state, input_changed, 0)
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("4") PORT_CODE(KEYCODE_4) PORT_CHANGED_MEMBER(DEVICE_SELF, enmirage_state, input_changed, 0)
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("7") PORT_CODE(KEYCODE_7) PORT_CHANGED_MEMBER(DEVICE_SELF, enmirage_state, input_changed, 0)
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("On/Up") PORT_CODE(KEYCODE_UP) PORT_CHANGED_MEMBER(DEVICE_SELF, enmirage_state, input_changed, 0)
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Param") PORT_CODE(KEYCODE_I) PORT_CHANGED_MEMBER(DEVICE_SELF, enmirage_state, input_changed, 0)
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Off/Down") PORT_CODE(KEYCODE_DOWN) PORT_CHANGED_MEMBER(DEVICE_SELF, enmirage_state, input_changed, 0)
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Value") PORT_CODE(KEYCODE_J) PORT_CHANGED_MEMBER(DEVICE_SELF, enmirage_state, input_changed, 0)
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Cancel") PORT_CODE(KEYCODE_K) PORT_CHANGED_MEMBER(DEVICE_SELF, enmirage_state, input_changed, 0)
PORT_START(PITCH_TAG)
PORT_BIT(0xff, 0x7f, IPT_PADDLE) PORT_NAME("Pitch Wheel") PORT_SENSITIVITY(100) PORT_KEYDELTA(10) PORT_MINMAX(0x00,0xff) PORT_CODE_INC(KEYCODE_4_PAD) PORT_CODE_DEC(KEYCODE_1_PAD) PORT_PLAYER(1)
PORT_START(MOD_TAG)
PORT_BIT(0xff, 0x7f, IPT_PADDLE) PORT_NAME("Mod Wheel") PORT_SENSITIVITY(100) PORT_KEYDELTA(10) PORT_MINMAX(0x00,0xff) PORT_CODE_INC(KEYCODE_6_PAD) PORT_CODE_DEC(KEYCODE_3_PAD) PORT_PLAYER(1)
INPUT_PORTS_END
ROM_START( enmirage )
ROM_START(enmirage)
ROM_REGION(0x1000, "osrom", 0)
ROM_LOAD( "mirage.bin", 0x0000, 0x1000, CRC(9fc7553c) SHA1(ec6ea5613eeafd21d8f3a7431a35a6ff16eed56d) )
ROM_LOAD("mirage.bin", 0x0000, 0x1000, CRC(9fc7553c) SHA1(ec6ea5613eeafd21d8f3a7431a35a6ff16eed56d))
ROM_REGION(0x20000, "es5503", ROMREGION_ERASE)
ROM_END
@ -216,31 +432,7 @@ void enmirage_state::init_mirage()
if (floppy)
{
m_fdc->set_floppy(floppy);
floppy->ss_w(0);
}
// port A: front panel
m_via->write_pa0(0);
m_via->write_pa1(0);
m_via->write_pa2(0);
m_via->write_pa3(0);
m_via->write_pa4(0);
m_via->write_pa5(0);
m_via->write_pa6(0);
m_via->write_pa7(0);
// port B:
// bit 6: IN FDC disk ready
// bit 5: IN 5503 sync (?)
m_via->write_pb0(0);
m_via->write_pb1(0);
m_via->write_pb2(0);
m_via->write_pb3(0);
m_via->write_pb4(0);
m_via->write_pb5(1);
m_via->write_pb6(0); // how to determine if a disk is inserted?
m_via->write_pb7(0);
}
CONS( 1984, enmirage, 0, 0, mirage, mirage, enmirage_state, init_mirage, "Ensoniq", "Mirage", MACHINE_NOT_WORKING )
CONS(1984, enmirage, 0, 0, mirage, mirage, enmirage_state, init_mirage, "Ensoniq", "Mirage DMS-8", MACHINE_NOT_WORKING)

View File

@ -0,0 +1,210 @@
<?xml version="1.0"?>
<!--
license:CC0
copyright-holders:tim lindner
-->
<mamelayout version="2">
<!-- Backgrounds -->
<element name="background"><rect><color red="0.243" green="0.203" blue="0.164" /></rect></element>
<element name="lcd_background"><rect><color red="0.360" green="0.274" blue="0.180" /></rect></element>
<!-- Labels -->
<element name="label_1"> <text string="1"></text></element>
<element name="label_2"> <text string="2"></text></element>
<element name="label_3"> <text string="3"></text></element>
<element name="label_Rec"> <text string="Rec"></text></element>
<element name="label_Upper"> <text string="Upper"></text></element>
<element name="label_4"> <text string="4"></text></element>
<element name="label_5"> <text string="5"></text></element>
<element name="label_6"> <text string="6"></text></element>
<element name="label_Play"> <text string="Play"></text></element>
<element name="label_Lower"> <text string="Lower"></text></element>
<element name="label_Param"> <text string="Param"></text></element>
<element name="label_Value"> <text string="Value"></text></element>
<element name="label_7"> <text string="7"></text></element>
<element name="label_8"> <text string="8"></text></element>
<element name="label_9"> <text string="9"></text></element>
<element name="label_Load"> <text string="Load"></text></element>
<element name="label_Off"> <text string="Off/&#9662;"></text></element>
<element name="label_On"> <text string="On/&#9650;"></text></element>
<element name="label_Cancel"> <text string="Cancel"></text></element>
<element name="label_0"> <text string="0/Prog"></text></element>
<element name="label_Enter"> <text string="Enter"></text></element>
<element name="label_Save"> <text string="Save"></text></element>
<element name="label_CONTROL"> <text string="CONTROL"></text></element>
<element name="label_SELECT"> <text string="SELECT"></text></element>
<element name="label_SEQ"> <text string="SEQ"></text></element>
<element name="label_SAMPLE"> <text string="SAMPLE"></text></element>
<element name="label_LOAD"> <text string="LOAD"></text></element>
<!-- Buttons -->
<element name="button_yellow"><rect><color red="0.996" green="0.874" blue="0.016" /></rect></element>
<element name="button_grey"><rect><color red="0.5" green="0.5" blue="0.5" /></rect></element>
<element name="button_black"><rect><color red="0" green="0" blue="0" /></rect></element>
<element name="button_white"><rect><color red="0.978" green="0.888" blue="0.825" /></rect></element>
<element name="led_segement" defstate="0">
<rect state="0"><color red="0.85" green="0.87" blue="0.36" alpha="0.1" /></rect>
<rect state="1"><color red="0.85" green="0.87" blue="0.36" /></rect>
</element>
<element name="led_indicator" defstate="0">
<disk state="0"><color red="0.85" green="0.87" blue="0.36" alpha="0.1" /></disk>
<disk state="1"><color red="0.85" green="0.87" blue="0.36" /></disk>
</element>
<view name="Default Layout">
<bounds left="0" top="0" right="1000" bottom="437" />
<!-- bezel -->
<element ref="background">
<bounds x="0" y="0" width="1000" height="437" />
</element>
<element ref="lcd_background">
<bounds x="54" y="64" width="127" height="87" />
</element>
<!-- Buttons, row 1 -->
<element name="button_1" ref="button_yellow" inputtag="pb7" inputmask="0x01"><bounds x="282" y="46" width="44" height="24" /></element>
<element name="button_2" ref="button_yellow" inputtag="pb6" inputmask="0x40"><bounds x="375" y="46" width="44" height="24" /></element>
<element name="button_3" ref="button_yellow" inputtag="pb6" inputmask="0x01"><bounds x="468" y="46" width="44" height="24" /></element>
<element name="button_Rec" ref="button_grey" inputtag="pb5" inputmask="0x40"><bounds x="597" y="46" width="44" height="24" /></element>
<element name="button_Sample_Upper" ref="button_black" inputtag="pb5" inputmask="0x04"><bounds x="724" y="46" width="44" height="24" /></element>
<element name="button_Load_Upper" ref="button_white" inputtag="pb5" inputmask="0x01"><bounds x="895" y="46" width="44" height="24" /></element>
<!-- Buttons, row 2 -->
<element name="button_4" ref="button_yellow" inputtag="pb7" inputmask="0x02"><bounds x="282" y="139" width="44" height="24" /></element>
<element name="button_5" ref="button_yellow" inputtag="pb6" inputmask="0x08"><bounds x="375" y="139" width="44" height="24" /></element>
<element name="button_6" ref="button_grey" inputtag="pb6" inputmask="0x02"><bounds x="468" y="139" width="44" height="24" /></element>
<element name="button_Play" ref="button_grey" inputtag="pb5" inputmask="0x08"><bounds x="597" y="139" width="44" height="24" /></element>
<element name="button_Sample_Lower" ref="button_black" inputtag="pb5" inputmask="0x80"><bounds x="724" y="139" width="44" height="24" /></element>
<element name="button_Load_Lower" ref="button_white" inputtag="pb5" inputmask="0x02"><bounds x="895" y="139" width="44" height="24" /></element>
<!-- Buttons, row 3 -->
<element name="button_Param" ref="button_grey" inputtag="pb7" inputmask="0x10"><bounds x="38" y="232" width="44" height="24" /></element>
<element name="button_Value" ref="button_grey" inputtag="pb7" inputmask="0x40"><bounds x="149" y="232" width="44" height="24" /></element>
<element name="button_7" ref="button_grey" inputtag="pb7" inputmask="0x04"><bounds x="282" y="232" width="44" height="24" /></element>
<element name="button_8" ref="button_grey" inputtag="pb6" inputmask="0x10"><bounds x="375" y="232" width="44" height="24" /></element>
<element name="button_9" ref="button_grey" inputtag="pb6" inputmask="0x04"><bounds x="468" y="232" width="44" height="24" /></element>
<element name="button_Load" ref="button_grey" inputtag="pb5" inputmask="0x10"><bounds x="597" y="232" width="44" height="24" /></element>
<!-- Buttons, row 4 -->
<element name="button_Off/Down" ref="button_grey" inputtag="pb7" inputmask="0x20"><bounds x="38" y="325" width="44" height="24" /></element>
<element name="button_On/Up" ref="button_grey" inputtag="pb7" inputmask="0x08"><bounds x="149" y="325" width="44" height="24" /></element>
<element name="button_Cancel" ref="button_grey" inputtag="pb7" inputmask="0x80"><bounds x="282" y="325" width="44" height="24" /></element>
<element name="button_0/Prog" ref="button_white" inputtag="pb6" inputmask="0x20"><bounds x="375" y="325" width="44" height="24" /></element>
<element name="button_Enter" ref="button_grey" inputtag="pb6" inputmask="0x80"><bounds x="468" y="325" width="44" height="24" /></element>
<element name="button_Save" ref="button_grey" inputtag="pb5" inputmask="0x20"><bounds x="597" y="325" width="44" height="24" /></element>
<!-- Lines -->
<element ref="button_white"><bounds x="281" y="82" width="659" height="6" /></element>
<element ref="button_white"><bounds x="281" y="175" width="659" height="6" /></element>
<element ref="button_white"><bounds x="34" y="268" width="649" height="6" /></element>
<element ref="button_white"><bounds x="0" y="361" width="939" height="6" /></element>11
<element ref="button_white"><bounds x="38" y="367" width="155" height="6" /></element>
<element ref="button_white"><bounds x="282" y="367" width="230" height="6" /></element>
<element ref="button_white"><bounds x="597" y="367" width="44" height="6" /></element>
<element ref="button_white"><bounds x="711" y="367" width="71" height="6" /></element>
<element ref="button_white"><bounds x="895" y="367" width="44" height="6" /></element>
<element ref="button_white"><bounds x="60" y="149" width="3" height="29" /></element>
<element ref="button_white"><bounds x="123" y="149" width="3" height="29" /></element>
<element ref="button_white"><bounds x="38" y="175" width="44" height="3" /></element>
<element ref="button_white"><bounds x="123" y="175" width="75" height="3" /></element>
<!-- Labels, row 1 -->
<element ref="label_1"><bounds x="269" y="12" width="71" height="22" /></element>
<element ref="label_2"><bounds x="362" y="12" width="71" height="22" /></element>
<element ref="label_3"><bounds x="455" y="12" width="71" height="22" /></element>
<element ref="label_Rec"><bounds x="584" y="12" width="71" height="22" /></element>
<element ref="label_Upper"><bounds x="711" y="12" width="71" height="22" /></element>
<element ref="label_Upper"><bounds x="882" y="12" width="71" height="22" /></element>
<!-- Labels, row 2 -->
<element ref="label_4"><bounds x="269" y="105" width="71" height="22" /></element>
<element ref="label_5"><bounds x="362" y="105" width="71" height="22" /></element>
<element ref="label_6"><bounds x="455" y="105" width="71" height="22" /></element>
<element ref="label_Play"><bounds x="584" y="105" width="71" height="22" /></element>
<element ref="label_Lower"><bounds x="711" y="105" width="71" height="22" /></element>
<element ref="label_Lower"><bounds x="882" y="105" width="71" height="22" /></element>
<!-- Labels, row 3 -->
<element ref="label_Param"><bounds x="24" y="198" width="71" height="22" /></element>
<element ref="label_Value"><bounds x="136" y="198" width="71" height="22" /></element>
<element ref="label_7"><bounds x="269" y="198" width="71" height="22" /></element>
<element ref="label_8"><bounds x="362" y="198" width="71" height="22" /></element>
<element ref="label_9"><bounds x="455" y="198" width="71" height="22" /></element>
<element ref="label_Load"><bounds x="584" y="198" width="71" height="22" /></element>
<!-- Labels, row 4 -->
<element ref="label_Off"><bounds x="24" y="291" width="71" height="22" /></element>
<element ref="label_On"><bounds x="136" y="291" width="71" height="22" /></element>
<element ref="label_Cancel"><bounds x="269" y="291" width="71" height="22" /></element>
<element ref="label_0"><bounds x="362" y="291" width="71" height="22" /></element>
<element ref="label_Enter"><bounds x="455" y="291" width="71" height="22" /></element>
<element ref="label_Save"><bounds x="584" y="291" width="71" height="22" /></element>
<!-- Labels, row 5 -->
<element ref="label_CONTROL"><bounds x="58" y="374" width="111" height="22" /></element>
<element ref="label_SELECT"><bounds x="362" y="374" width="71" height="22" /></element>
<element ref="label_SEQ"><bounds x="584" y="374" width="71" height="22" /></element>
<element ref="label_SAMPLE"><bounds x="711" y="374" width="71" height="22" /></element>
<element ref="label_LOAD"><bounds x="882" y="374" width="71" height="22" /></element>
<!-- hand built LEDs, left side-->
<element name="0.0" ref="led_segement">
<bounds left="76" top="75" right="100" bottom="81" />
</element>
<element name="0.1" ref="led_segement">
<bounds left="101" top="78" right="107" bottom="107" />
</element>
<element name="0.2" ref="led_segement">
<bounds left="101" top="108" right="107" bottom="137" />
</element>
<element name="0.3" ref="led_segement">
<bounds left="76" top="132" right="100" bottom="138" />
</element>
<element name="0.4" ref="led_segement">
<bounds left="69" top="108" right="75" bottom="137" />
</element>
<element name="0.5" ref="led_segement">
<bounds left="69" top="78" right="75" bottom="107" />
</element>
<element name="0.6" ref="led_segement">
<bounds left="76" top="105" right="100" bottom="111" />
</element>
<element name="0.7" ref="led_indicator">
<bounds left="59" top="138" right="67" bottom="146" />
</element>
<!-- hand built LEDs, right side-->
<element name="1.0" ref="led_segement">
<bounds left="139" top="75" right="163" bottom="81" />
</element>
<element name="1.1" ref="led_segement">
<bounds left="164" top="78" right="170" bottom="107" />
</element>
<element name="1.2" ref="led_segement">
<bounds left="164" top="108" right="170" bottom="137" />
</element>
<element name="1.3" ref="led_segement">
<bounds left="139" top="132" right="163" bottom="138" />
</element>
<element name="1.4" ref="led_segement">
<bounds left="132" top="108" right="138" bottom="137" />
</element>
<element name="1.5" ref="led_segement">
<bounds left="132" top="78" right="138" bottom="107" />
</element>
<element name="1.6" ref="led_segement">
<bounds left="139" top="105" right="163" bottom="111" />
</element>
<element name="1.7" ref="led_indicator">
<bounds left="122" top="138" right="130" bottom="146" />
</element>
</view>
</mamelayout>

View File

@ -1,27 +0,0 @@
<?xml version="1.0"?>
<!--
license:CC0
copyright-holders:R. Belmont
-->
<mamelayout version="2">
<element name="digit" defstate="0">
<led7seg>
<color red="0.85" green="0.87" blue="0.36" />
</led7seg>
</element>
<view name="Default Layout">
<bounds left="0" top="0" right="42" bottom="28" />
<!-- LEDs -->
<element name="digit0" ref="digit">
<bounds left="2" top="0" right="20" bottom="23" />
</element>
<element name="digit1" ref="digit">
<bounds left="22" top="0" right="40" bottom="23" />
</element>
</view>
</mamelayout>