From d8571d9f57f07faf692beb08ec1edf95124555fa Mon Sep 17 00:00:00 2001 From: Curt Coder Date: Thu, 6 Jun 2013 14:00:58 +0000 Subject: [PATCH] (MESS) ep64: Modernized the Enterprise 64/128 driver. [Curt Coder] --- .gitattributes | 14 +- hash/ep64_cart.xml | 186 +++++ hash/ep64_cass.xml | 12 +- src/emu/imagedev/cassette.c | 2 +- src/lib/formats/ep64_dsk.c | 73 ++ src/lib/formats/ep64_dsk.h | 28 + src/lib/lib.mak | 1 + src/mess/audio/dave.c | 938 +++++++++++--------------- src/mess/audio/dave.h | 182 ++--- src/mess/drivers/{enterp.c => ep64.c} | 833 ++++++++++------------- src/mess/includes/ep64.h | 94 +++ src/mess/machine/ep64_exdos.c | 244 +++++++ src/mess/machine/ep64_exdos.h | 65 ++ src/mess/machine/ep64exp.c | 88 +++ src/mess/machine/ep64exp.h | 150 ++++ src/mess/mess.mak | 6 +- src/mess/video/{epnick.c => nick.c} | 385 +++++++---- src/mess/video/{epnick.h => nick.h} | 87 ++- 18 files changed, 2129 insertions(+), 1259 deletions(-) create mode 100644 hash/ep64_cart.xml create mode 100644 src/lib/formats/ep64_dsk.c create mode 100644 src/lib/formats/ep64_dsk.h rename src/mess/drivers/{enterp.c => ep64.c} (51%) create mode 100644 src/mess/includes/ep64.h create mode 100644 src/mess/machine/ep64_exdos.c create mode 100644 src/mess/machine/ep64_exdos.h create mode 100644 src/mess/machine/ep64exp.c create mode 100644 src/mess/machine/ep64exp.h rename src/mess/video/{epnick.c => nick.c} (68%) rename src/mess/video/{epnick.h => nick.h} (54%) diff --git a/.gitattributes b/.gitattributes index 96b39a3a28b..614a2159f9d 100644 --- a/.gitattributes +++ b/.gitattributes @@ -87,6 +87,7 @@ hash/dim68k.xml svneol=native#text/xml hash/ec1841.xml svneol=native#text/xml hash/einstein.xml svneol=native#text/xml hash/electron_cart.xml svneol=native#text/xml +hash/ep64_cart.xml svneol=native#text/xml hash/ep64_cass.xml svneol=native#text/xml hash/ep64_flop.xml svneol=native#text/xml hash/famicom_flop.xml svneol=native#text/xml @@ -2007,6 +2008,8 @@ src/lib/formats/dim_dsk.c svneol=native#text/plain src/lib/formats/dim_dsk.h svneol=native#text/plain src/lib/formats/dsk_dsk.c svneol=native#text/plain src/lib/formats/dsk_dsk.h svneol=native#text/plain +src/lib/formats/ep64_dsk.c svneol=native#text/plain +src/lib/formats/ep64_dsk.h svneol=native#text/plain src/lib/formats/esq16_dsk.c svneol=native#text/plain src/lib/formats/esq16_dsk.h svneol=native#text/plain src/lib/formats/esq8_dsk.c svneol=native#text/plain @@ -6119,7 +6122,7 @@ src/mess/drivers/electron.c svneol=native#text/plain src/mess/drivers/elekscmp.c svneol=native#text/plain src/mess/drivers/elf.c svneol=native#text/plain src/mess/drivers/elwro800.c svneol=native#text/plain -src/mess/drivers/enterp.c svneol=native#text/plain +src/mess/drivers/ep64.c svneol=native#text/plain src/mess/drivers/esq1.c svneol=native#text/plain src/mess/drivers/esq5505.c svneol=native#text/plain src/mess/drivers/esqkt.c svneol=native#text/plain @@ -6568,6 +6571,7 @@ src/mess/includes/einstein.h svneol=native#text/plain src/mess/includes/electron.h svneol=native#text/plain src/mess/includes/elf.h svneol=native#text/plain src/mess/includes/enterp.h svneol=native#text/plain +src/mess/includes/ep64.h svneol=native#text/plain src/mess/includes/eti660.h svneol=native#text/plain src/mess/includes/europc.h svneol=native#text/plain src/mess/includes/exp85.h svneol=native#text/plain @@ -7280,6 +7284,10 @@ src/mess/machine/egret.c svneol=native#text/plain src/mess/machine/egret.h svneol=native#text/plain src/mess/machine/einstein.c svneol=native#text/plain src/mess/machine/electron.c svneol=native#text/plain +src/mess/machine/ep64_exdos.c svneol=native#text/plain +src/mess/machine/ep64_exdos.h svneol=native#text/plain +src/mess/machine/ep64exp.c svneol=native#text/plain +src/mess/machine/ep64exp.h svneol=native#text/plain src/mess/machine/epson_sio.c svneol=native#text/plain src/mess/machine/epson_sio.h svneol=native#text/plain src/mess/machine/esqpanel.c svneol=native#text/plain @@ -8079,8 +8087,6 @@ src/mess/video/dgn_beta.c svneol=native#text/plain src/mess/video/ef9345.c svneol=native#text/plain src/mess/video/ef9345.h svneol=native#text/plain src/mess/video/electron.c svneol=native#text/plain -src/mess/video/epnick.c svneol=native#text/plain -src/mess/video/epnick.h svneol=native#text/plain src/mess/video/fm7.c svneol=native#text/plain src/mess/video/fmtowns.c svneol=native#text/plain src/mess/video/galaxy.c svneol=native#text/plain @@ -8143,6 +8149,8 @@ src/mess/video/nes.c svneol=native#text/plain src/mess/video/newbrain.c svneol=native#text/plain src/mess/video/newport.c svneol=native#text/plain src/mess/video/newport.h svneol=native#text/plain +src/mess/video/nick.c svneol=native#text/plain +src/mess/video/nick.h svneol=native#text/plain src/mess/video/nubus_48gc.c svneol=native#text/plain src/mess/video/nubus_48gc.h svneol=native#text/plain src/mess/video/nubus_cb264.c svneol=native#text/plain diff --git a/hash/ep64_cart.xml b/hash/ep64_cart.xml new file mode 100644 index 00000000000..db5eb3ced2a --- /dev/null +++ b/hash/ep64_cart.xml @@ -0,0 +1,186 @@ + + + + + + BASIC (v2.1) + 198? + Intelligent Software + + + + + + + + + + BASIC (v1.0) + 198? + Enterprise Computers + + + + + + + + + + + BASIC (v1.1) + 198? + Enterprise Computers + + + + + + + + + + BASIC (v2.1, Alt) + 198? + Intelligent Software + + + + + + + + + + EPDOS (v1.7) + 198? + Haluska, Laszlo + + + + + + + + + + EX-DOS EPROM + 198? + Enterprise Computers + + + + + + + + + + EXDos BASIC + FORTH + 198? + Enterprise Computers + + + + + + + + + + Forth + 198? + Enterprise Computers + + + + + + + + + + HiSoft Pascal Enterprise (v1.01) + 1985 + HiSoft + + + + + + + + + + HP Enterprise (v1.01) + 1985 + HiSoft + + + + + + + + + + Turbo AsMon (v1.5) + 198? + Sandor Gyangy + + + + + + + + + + Turbo EXDOS+ISDOS + 198? + Zoltan Nemeth + + + + + + + + + + UELISP (v0.6) + 198? + Enterprise Computers + + + + + + + + + + ZozoTools (v1.8) + 198? + Zoltan Nemeth + + + + + + + + + + brd + 198? + <unknown> + + + + + + + + + diff --git a/hash/ep64_cass.xml b/hash/ep64_cass.xml index ce361955ea7..2e3c42a2239 100644 --- a/hash/ep64_cass.xml +++ b/hash/ep64_cass.xml @@ -3,9 +3,9 @@ - 3D Starfighter + 3D Star Fighter 198? - <unknown> + Code Masters @@ -17,7 +17,7 @@ Airwolf 198? - <unknown> + Elite @@ -27,9 +27,9 @@ - Nodes - 198? - <unknown> + Nodes of Yesod + 1985 + Odin Computer Graphics diff --git a/src/emu/imagedev/cassette.c b/src/emu/imagedev/cassette.c index 15f45fdf31c..03b7527a72b 100644 --- a/src/emu/imagedev/cassette.c +++ b/src/emu/imagedev/cassette.c @@ -24,7 +24,7 @@ const cassette_interface default_cassette_interface = cassette_default_formats, NULL, CASSETTE_PLAY, - NULL, + "cass", NULL }; diff --git a/src/lib/formats/ep64_dsk.c b/src/lib/formats/ep64_dsk.c new file mode 100644 index 00000000000..f24afe02fc9 --- /dev/null +++ b/src/lib/formats/ep64_dsk.c @@ -0,0 +1,73 @@ +/*************************************************************************** + + Copyright Olivier Galibert + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name 'MAME' nor the names of its contributors may be + used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +****************************************************************************/ + +/********************************************************************* + + formats/ep64_dsk.c + + Enterprise Sixty Four disk image format + +*********************************************************************/ + +#include "emu.h" +#include "formats/ep64_dsk.h" + +ep64_format::ep64_format() : wd177x_format(formats) +{ +} + +const char *ep64_format::name() const +{ + return "ep64"; +} + +const char *ep64_format::description() const +{ + return "Enteprise Sixty Four disk image"; +} + +const char *ep64_format::extensions() const +{ + return "img"; +} + +// Unverified gap sizes +const ep64_format::format ep64_format::formats[] = { + { /* 720K 3 1/2 inch double density */ + floppy_image::FF_35, floppy_image::DSDD, floppy_image::MFM, + 2000, 9, 80, 2, 512, {}, 1, {}, 100, 22, 84 + }, + {} +}; + +const floppy_format_type FLOPPY_EP64_FORMAT = &floppy_image_format_creator; diff --git a/src/lib/formats/ep64_dsk.h b/src/lib/formats/ep64_dsk.h new file mode 100644 index 00000000000..aca14ff6af4 --- /dev/null +++ b/src/lib/formats/ep64_dsk.h @@ -0,0 +1,28 @@ +/********************************************************************* + + formats/ep64_dsk.h + + Enterprise Sixty Four disk image format + +*********************************************************************/ + +#ifndef EP64_DSK_H_ +#define EP64_DSK_H_ + +#include "wd177x_dsk.h" + +class ep64_format : public wd177x_format { +public: + ep64_format(); + + virtual const char *name() const; + virtual const char *description() const; + virtual const char *extensions() const; + +private: + static const format formats[]; +}; + +extern const floppy_format_type FLOPPY_EP64_FORMAT; + +#endif diff --git a/src/lib/lib.mak b/src/lib/lib.mak index 6e4031ea96e..d3ba9168eff 100644 --- a/src/lib/lib.mak +++ b/src/lib/lib.mak @@ -129,6 +129,7 @@ FORMATSOBJS = \ $(LIBOBJ)/formats/dfi_dsk.o \ $(LIBOBJ)/formats/dim_dsk.o \ $(LIBOBJ)/formats/dsk_dsk.o \ + $(LIBOBJ)/formats/ep64_dsk.o \ $(LIBOBJ)/formats/esq8_dsk.o \ $(LIBOBJ)/formats/esq16_dsk.o \ $(LIBOBJ)/formats/fdi_dsk.o \ diff --git a/src/mess/audio/dave.c b/src/mess/audio/dave.c index d3d29e24f7e..0f44a63c27a 100644 --- a/src/mess/audio/dave.c +++ b/src/mess/audio/dave.c @@ -1,87 +1,99 @@ /********************************************************************** - "Dave" Sound Chip + Intelligent Designs DAVE emulation - DAVE SOUND CHIP FOUND IN ENTERPRISE - - working: - - - pure tone - - sampled sounds - - 1 kHz, 50 Hz and 1 Hz ints - - external ints (int1 and int2) - not correct speed yet + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. **********************************************************************/ -#include "emu.h" -#include "audio/dave.h" +#include "dave.h" -/*************************************************************************** - MACROS / CONSTANTS -***************************************************************************/ + +//************************************************************************** +// MACROS / CONSTANTS +//************************************************************************** + +#define LOG 0 #define STEP 0x08000 -/*************************************************************************** - IMPLEMENTATION -***************************************************************************/ -const device_type DAVE = &device_creator; +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** -dave_sound_device::dave_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : device_t(mconfig, DAVE, "Dave", tag, owner, clock), - device_sound_interface(mconfig, *this) +const device_type DAVE = &device_creator; + + +DEVICE_ADDRESS_MAP_START( z80_program_map, 8, dave_device ) + AM_RANGE(0x0000, 0xffff) AM_READWRITE(program_r, program_w) +ADDRESS_MAP_END + +DEVICE_ADDRESS_MAP_START( z80_io_map, 8, dave_device ) + AM_RANGE(0x0000, 0xffff) AM_READWRITE(io_r, io_w) +ADDRESS_MAP_END + +static ADDRESS_MAP_START( program_map, DAVE_AS_PROGRAM, 8, dave_device ) +ADDRESS_MAP_END + +static ADDRESS_MAP_START( io_map, DAVE_AS_IO, 8, dave_device ) +ADDRESS_MAP_END + + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// dave_device - constructor +//------------------------------------------------- + +dave_device::dave_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, DAVE, "DAVE", tag, owner, clock), + device_memory_interface(mconfig, *this), + device_sound_interface(mconfig, *this), + m_program_space_config("program", ENDIANNESS_LITTLE, 8, 22, 0, *ADDRESS_MAP_NAME(program_map)), + m_io_space_config("I/O", ENDIANNESS_LITTLE, 8, 16, 0, *ADDRESS_MAP_NAME(io_map)), + m_write_irq(*this), + m_write_lh(*this), + m_write_rh(*this) { } -//------------------------------------------------- -// device_config_complete - perform any -// operations now that the configuration is -// complete -//------------------------------------------------- - -void dave_sound_device::device_config_complete() -{ - // inherit a copy of the static data - const dave_interface *intf = reinterpret_cast(static_config()); - if (intf != NULL) - *static_cast(this) = *intf; - - // or initialize to defaults if none provided - else - { - memset(&m_reg_r_cb, 0, sizeof(m_reg_r_cb)); - memset(&m_reg_w_cb, 0, sizeof(m_reg_w_cb)); - memset(&m_int_cb, 0, sizeof(m_int_cb)); - } -} //------------------------------------------------- // device_start - device-specific startup //------------------------------------------------- -void dave_sound_device::device_start() +void dave_device::device_start() { - m_reg_r.resolve(m_reg_r_cb, *this); - m_reg_w.resolve(m_reg_w_cb, *this); - m_int_callback.resolve(m_int_cb, *this); - - /* temp! */ - m_nick_virq = 0; - - /* initialise 1kHz timer */ - m_int_latch = 0; - m_int_input = 0; - m_int_enable = 0; - m_timer_irq = 0; - m_fifty_hz_state = 0; - m_one_khz_state = 0; - m_fifty_hz_count = DAVE_FIFTY_HZ_COUNTER_RELOAD; - m_one_hz_count = DAVE_ONE_HZ_COUNTER_RELOAD; - machine().scheduler().timer_pulse(attotime::from_hz(1000), timer_expired_delegate(FUNC(dave_sound_device::dave_1khz_callback),this)); + // resolve callbacks + m_write_irq.resolve_safe(); + m_write_lh.resolve_safe(); + m_write_rh.resolve_safe(); + + // allocate timers + m_timer_1hz = timer_alloc(TIMER_1HZ); + m_timer_1hz->adjust(attotime::from_hz(2), 0, attotime::from_hz(2)); + m_timer_50hz = timer_alloc(TIMER_50HZ); + m_timer_50hz->adjust(attotime::from_hz(2000), 0, attotime::from_hz(2000)); + + // state saving + save_item(NAME(m_segment)); + save_item(NAME(m_irq_status)); + save_item(NAME(m_irq_enable)); + save_item(NAME(m_period)); + save_item(NAME(m_count)); + save_item(NAME(m_level)); + save_item(NAME(m_level_or)); + save_item(NAME(m_level_and)); + save_item(NAME(m_mame_volumes)); + for (int i = 0; i < 3; i++) { m_period[i] = (STEP * machine().sample_rate()) / 125000; @@ -94,234 +106,354 @@ void dave_sound_device::device_start() /* 3 tone channels + 1 noise channel */ m_sound_stream_var = machine().sound().stream_alloc(*this, 0, 2, machine().sample_rate(), this); - - save_item(NAME(m_regs)); - save_item(NAME(m_int_latch)); - save_item(NAME(m_int_enable)); - save_item(NAME(m_int_input)); - save_item(NAME(m_int_irq)); - save_item(NAME(m_timer_irq)); - save_item(NAME(m_one_khz_state)); - save_item(NAME(m_one_hz_count)); - save_item(NAME(m_fifty_hz_state)); - save_item(NAME(m_fifty_hz_count)); - save_item(NAME(m_period)); - save_item(NAME(m_count)); - save_item(NAME(m_level)); - save_item(NAME(m_level_or)); - save_item(NAME(m_level_and)); - save_item(NAME(m_mame_volumes)); - save_item(NAME(m_nick_virq)); } + //------------------------------------------------- // device_reset - device-specific reset //------------------------------------------------- -void dave_sound_device::device_reset() +void dave_device::device_reset() { + m_write_irq(CLEAR_LINE); + + for (int i = 0; i < 4; i++) + m_segment[i] = 0; + + m_irq_status = 0; + m_irq_enable = 0; + for (int i = 0; i < 32; i++) m_regs[i] = 0; +} + + +//------------------------------------------------- +// device_timer - handler timer events +//------------------------------------------------- + +void dave_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +{ + switch (id) + { + case TIMER_1HZ: + m_irq_status ^= IRQ_1HZ_DIVIDER; + + if (m_irq_status & IRQ_1HZ_DIVIDER) + m_irq_status |= IRQ_1HZ_LATCH; + break; + + case TIMER_50HZ: + m_irq_status ^= IRQ_50HZ_DIVIDER; + + if (m_irq_status & IRQ_50HZ_DIVIDER) + m_irq_status |= IRQ_50HZ_LATCH; + break; + } + + update_interrupt(); +} + + +//------------------------------------------------- +// memory_space_config - return a description of +// any address spaces owned by this device +//------------------------------------------------- + +const address_space_config *dave_device::memory_space_config(address_spacenum spacenum) const +{ + switch (spacenum) + { + case DAVE_AS_PROGRAM: return &m_program_space_config; + case DAVE_AS_IO: return &m_io_space_config; + default: return NULL; + } +} + + +//------------------------------------------------- +// sound_stream_update - handle a stream update +//------------------------------------------------- + +void dave_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +{ + stream_sample_t *buffer1, *buffer2; + /* 0 = channel 0 left volume, 1 = channel 0 right volume, + 2 = channel 1 left volume, 3 = channel 1 right volume, + 4 = channel 2 left volume, 5 = channel 2 right volume + 6 = noise channel left volume, 7 = noise channel right volume */ + int output_volumes[8]; + int left_volume; + int right_volume; - address_space &space = machine().driver_data()->generic_space(); - reg_w(space, 0x10, 0); - reg_w(space, 0x11, 0); - reg_w(space, 0x12, 0); - reg_w(space, 0x13, 0); -} - - -/*------------------------------------------------- - dave_refresh_ints --------------------------------------------------*/ - -void dave_sound_device::refresh_ints() -{ - int int_wanted; - - logerror("int latch: %02x enable: %02x input: %02x\n", (int) m_int_latch, (int) m_int_enable, (int) m_int_input); - - int_wanted = ((m_int_enable << 1) & m_int_latch) != 0; - m_int_callback(int_wanted); -} - - -/*------------------------------------------------- - dave_refresh_selectable_int --------------------------------------------------*/ - -void dave_sound_device::refresh_selectable_int() -{ - /* update 1kHz/50Hz/tg latch and int input */ - switch ((m_regs[7]>>5) & 0x03) + //logerror("sound update!\n"); + + buffer1 = outputs[0]; + buffer2 = outputs[1]; + + while (samples) { - /* 1kHz */ - case 0: - m_int_latch &= ~(1<<1); - m_int_latch |= (m_int_irq >> 1) & 0x02; - - /* set int input state */ - m_int_input &= ~(1<<0); - m_int_input |= (m_one_khz_state & 0x01) << 0; - break; - - /* 50Hz */ - case 1: - m_int_latch &= ~(1<<1); - m_int_latch |= m_int_irq & 0x02; - - /* set int input state */ - m_int_input &= ~(1<<0); - m_int_input |= (m_fifty_hz_state & 0x01) << 0; - break; - - - default: - break; - } - - refresh_ints(); -} - - -/*------------------------------------------------- - dave_1khz_callback --------------------------------------------------*/ - -TIMER_CALLBACK_MEMBER(dave_sound_device::dave_1khz_callback) -{ - /* time over - want int */ - m_one_khz_state ^= 0x0ffffffff; - - /* lo-high transition causes int */ - if (m_one_khz_state != 0) - { - m_int_irq |= (1<<2); - } - - - /* update fifty Hz counter */ - m_fifty_hz_count--; - - if (m_fifty_hz_count == 0) - { - /* these two lines are temp here */ - m_nick_virq ^= 0x0ffffffff; - set_external_int_state(DAVE_INT1_ID, m_nick_virq); - - - m_fifty_hz_count = DAVE_FIFTY_HZ_COUNTER_RELOAD; - m_fifty_hz_state ^= 0x0ffffffff; - - if (m_fifty_hz_state != 0) + int vol[4]; + + /* vol[] keeps track of how long each square wave stays */ + /* in the 1 position during the sample period. */ + vol[0] = vol[1] = vol[2] = vol[3] = 0; + + for (int i = 0; i < 3; i++) { - m_int_irq |= (1<<1); + if ((m_regs[7] & (1 << i))==0) + { + if (m_level[i]) vol[i] += m_count[i]; + m_count[i] -= STEP; + /* Period[i] is the half period of the square wave. Here, in each */ + /* loop I add Period[i] twice, so that at the end of the loop the */ + /* square wave is in the same status (0 or 1) it was at the start. */ + /* vol[i] is also incremented by Period[i], since the wave has been 1 */ + /* exactly half of the time, regardless of the initial position. */ + /* If we exit the loop in the middle, Output[i] has to be inverted */ + /* and vol[i] incremented only if the exit status of the square */ + /* wave is 1. */ + while (m_count[i] <= 0) + { + m_count[i] += m_period[i]; + if (m_count[i] > 0) + { + m_level[i] ^= 0x0ffffffff; + if (m_level[i]) vol[i] += m_period[i]; + break; + } + m_count[i] += m_period[i]; + vol[i] += m_period[i]; + } + if (m_level[i]) + vol[i] -= m_count[i]; + } } + + /* update volume outputs */ + + /* setup output volumes for each channel */ + /* channel 0 */ + output_volumes[0] = ((m_level[0] & m_level_and[0]) | m_level_or[0]) & m_mame_volumes[0]; + output_volumes[1] = ((m_level[0] & m_level_and[1]) | m_level_or[1]) & m_mame_volumes[4]; + /* channel 1 */ + output_volumes[2] = ((m_level[1] & m_level_and[2]) | m_level_or[2]) & m_mame_volumes[1]; + output_volumes[3] = ((m_level[1] & m_level_and[3]) | m_level_or[3]) & m_mame_volumes[5]; + /* channel 2 */ + output_volumes[4] = ((m_level[2] & m_level_and[4]) | m_level_or[4]) & m_mame_volumes[2]; + output_volumes[5] = ((m_level[2] & m_level_and[5]) | m_level_or[5]) & m_mame_volumes[6]; + /* channel 3 */ + output_volumes[6] = ((m_level[3] & m_level_and[6]) | m_level_or[6]) & m_mame_volumes[3]; + output_volumes[7] = ((m_level[3] & m_level_and[7]) | m_level_or[7]) & m_mame_volumes[7]; + + left_volume = (output_volumes[0] + output_volumes[2] + output_volumes[4] + output_volumes[6])>>2; + right_volume = (output_volumes[1] + output_volumes[3] + output_volumes[5] + output_volumes[7])>>2; + + *(buffer1++) = left_volume; + *(buffer2++) = right_volume; + + samples--; } - - m_one_hz_count--; - - if (m_one_hz_count == 0) - { - /* reload counter */ - m_one_hz_count = DAVE_ONE_HZ_COUNTER_RELOAD; - - /* change state */ - m_int_input ^= (1<<2); - - if (m_int_input & (1<<2)) - { - /* transition from 0->1 */ - /* int requested */ - m_int_latch |=(1<<3); - } - } - - refresh_selectable_int(); } -/*------------------------------------------------- - dave_sound_w - used to update sound output - based on data writes --------------------------------------------------*/ +//------------------------------------------------- +// int1_w - interrupt 1 write +//------------------------------------------------- -WRITE8_MEMBER(dave_sound_device::sound_w) +WRITE_LINE_MEMBER( dave_device::int1_w ) { - /* update stream */ - m_sound_stream_var->update(); + if (!(m_irq_status & IRQ_INT1) && state) + m_irq_status |= IRQ_INT1_LATCH; - /* new write */ - switch (offset) + if (state) + m_irq_status |= IRQ_INT1; + else + m_irq_status &= ~IRQ_INT1; + + update_interrupt(); +} + + +//------------------------------------------------- +// int2_w - interrupt 2 write +//------------------------------------------------- + +WRITE_LINE_MEMBER( dave_device::int2_w ) +{ + if (!(m_irq_status & IRQ_INT2) && state) + m_irq_status |= IRQ_INT2_LATCH; + + if (state) + m_irq_status |= IRQ_INT2; + else + m_irq_status &= ~IRQ_INT2; + + update_interrupt(); +} + + +//------------------------------------------------- +// program_r - program space read +//------------------------------------------------- + +READ8_MEMBER( dave_device::program_r ) +{ + UINT8 segment = m_segment[offset >> 14]; + offset = (segment << 14) | (offset & 0x3fff); + + return m_addrspace[0]->read_byte(offset); +} + + +//------------------------------------------------- +// program_w - program space write +//------------------------------------------------- + +WRITE8_MEMBER( dave_device::program_w ) +{ + UINT8 segment = m_segment[offset >> 14]; + offset = (segment << 14) | (offset & 0x3fff); + + m_addrspace[0]->write_byte(offset, data); +} + + +//------------------------------------------------- +// io_r - I/O space read +//------------------------------------------------- + +READ8_MEMBER( dave_device::io_r ) +{ + UINT8 data = 0; + + switch (offset & 0xff) + { + case 0xa0: + case 0xa1: + case 0xa2: + case 0xa3: + case 0xa4: + case 0xa5: + case 0xa6: + case 0xa7: + case 0xa8: + case 0xa9: + case 0xaa: + case 0xab: + case 0xac: + case 0xad: + case 0xae: + case 0xaf: + case 0xb8: + case 0xb9: + case 0xba: + case 0xbb: + case 0xbc: + case 0xbd: + case 0xbe: + case 0xbf: + data = 0xff; + break; + + case 0xb0: case 0xb1: case 0xb2: case 0xb3: + data = m_segment[offset & 0x03]; + break; + + case 0xb4: + data = m_irq_status; + break; + + default: + data = m_addrspace[1]->read_byte(offset); + } + + return data; +} + + +//------------------------------------------------- +// io_w - I/O space write +//------------------------------------------------- + +WRITE8_MEMBER( dave_device::io_w ) +{ + switch (offset & 0xff) { /* channel 0 down-counter */ - case 0: - case 1: + case 0xa0: + case 0xa1: /* channel 1 down-counter */ - case 2: - case 3: + case 0xa2: + case 0xa3: /* channel 2 down-counter */ - case 4: - case 5: - { - int count = 0; - int channel_index = offset>>1; - - /* Fout = 125,000 / (n+1) Hz */ - - /* sample rate/clock */ - - - /* get down-count */ - switch (offset & 0x01) + case 0xa4: + case 0xa5: { - case 0: - { - count = (data & 0x0ff) | ((m_regs[offset + 1] & 0x0f)<<8); - } - break; + int count = 0; + int channel_index = offset>>1; - case 1: - { - count = (m_regs[offset - 1] & 0x0ff) | ((data & 0x0f)<<8); + /* Fout = 125,000 / (n+1) Hz */ + /* sample rate/clock */ + + + /* get down-count */ + switch (offset & 0x01) + { + case 0: + { + count = (data & 0x0ff) | ((m_regs[offset + 1] & 0x0f)<<8); + } + break; + + case 1: + { + count = (m_regs[offset - 1] & 0x0ff) | ((data & 0x0f)<<8); + + } + break; } - break; + + count++; + + + m_period[channel_index] = ((STEP * machine().sample_rate())/125000) * count; + + m_regs[offset & 0x01f] = data; } - - count++; - - - m_period[channel_index] = ((STEP * machine().sample_rate())/125000) * count; - - } - break; + break; /* channel 0 left volume */ - case 8: + case 0xa8: /* channel 1 left volume */ - case 9: + case 0xa9: /* channel 2 left volume */ - case 10: + case 0xaa: /* noise channel left volume */ - case 11: + case 0xab: /* channel 0 right volume */ - case 12: + case 0xac: /* channel 1 right volume */ - case 13: + case 0xad: /* channel 2 right volume */ - case 14: + case 0xae: /* noise channel right volume */ - case 15: - { - /* update mame version of volume from data written */ - /* 0x03f->0x07e00. Max is 0x07fff */ - /* I believe the volume is linear - to be checked! */ - m_mame_volumes[offset - 8] = (data & 0x03f) << 9; - } - break; + case 0xaf: + { + /* update mame version of volume from data written */ + /* 0x03f->0x07e00. Max is 0x07fff */ + /* I believe the volume is linear - to be checked! */ + m_mame_volumes[offset - 8] = (data & 0x03f) << 9; - case 7: + m_regs[offset & 0x01f] = data; + } + break; + + case 0xa6: + break; + + case 0xa7: { /* force => the value of this register is forced regardless of the wave state, @@ -330,30 +462,32 @@ WRITE8_MEMBER(dave_sound_device::sound_w) use => the volume value is dependant on the wave state and is included in the final volume calculation */ - logerror("selectable int "); + //logerror("selectable int "); switch ((data>>5) & 0x03) { case 0: { - logerror("1kHz\n"); + //logerror("1kHz\n"); + m_timer_50hz->adjust(attotime::from_hz(2000), 0, attotime::from_hz(2000)); } break; case 1: { - logerror("50Hz\n"); + //logerror("50Hz\n"); + m_timer_50hz->adjust(attotime::from_hz(100), 0, attotime::from_hz(100)); } break; case 2: { - logerror("tone channel 0\n"); + //logerror("tone channel 0\n"); } break; case 3: { - logerror("tone channel 1\n"); + //logerror("tone channel 1\n"); } break; } @@ -435,296 +569,42 @@ WRITE8_MEMBER(dave_sound_device::sound_w) m_level_or[7] = 0x000; m_level_and[7] = 0xffff; } + + m_regs[offset & 0x01f] = data; } break; - default: - break; - } -} + case 0xb0: case 0xb1: case 0xb2: case 0xb3: + m_segment[offset & 0x03] = data; - -/*------------------------------------------------- - dave_reg_w --------------------------------------------------*/ - -WRITE8_MEMBER( dave_sound_device::reg_w ) -{ - logerror("dave w: %04x %02x\n",offset,data); - - sound_w(space, offset, data, mem_mask); - - m_regs[offset & 0x01f] = data; - - switch (offset) - { - case 0x07: - refresh_selectable_int(); - break; - - case 0x014: - /* enabled ints */ - m_int_enable = data & 0x055; - /* clear latches */ - m_int_latch &=~(data & 0x0aa); - - /* reset 1kHz, 50Hz latch */ - if (data & (1<<1)) - { - m_int_irq = 0; - } - - /* refresh ints */ - refresh_ints(); - break; - - default: - break; - } - - m_reg_w(offset, data); -} - - -/*------------------------------------------------- - dave_set_reg --------------------------------------------------*/ - -void dave_sound_device::set_reg(offs_t offset, UINT8 data) -{ - m_regs[offset & 0x01f] = data; -} - - -/*------------------------------------------------- - dave_reg_r --------------------------------------------------*/ - -READ8_MEMBER( dave_sound_device::reg_r ) -{ - logerror("dave r: %04x\n",offset); - - m_reg_r(offset); - - switch (offset) - { - case 0x000: - case 0x001: - case 0x002: - case 0x003: - case 0x004: - case 0x005: - case 0x006: - case 0x007: - case 0x008: - case 0x009: - case 0x00a: - case 0x00b: - case 0x00c: - case 0x00d: - case 0x00e: - case 0x00f: - case 0x018: - case 0x019: - case 0x01a: - case 0x01b: - case 0x01c: - case 0x01d: - case 0x01e: - case 0x01f: - return 0x0ff; - - case 0x014: - return (m_int_latch & 0x0aa) | (m_int_input & 0x055); - - - default: - break; - } - - return m_regs[offset & 0x01f]; -} - - -/*------------------------------------------------- - dave_set_external_int_state - negative edge - triggered --------------------------------------------------*/ - -void dave_sound_device::set_external_int_state(int int_id, int state) -{ - switch (int_id) - { - /* connected to Nick virq */ - case DAVE_INT1_ID: - { - int previous_state; - - previous_state = m_int_input; - - m_int_input &= ~(1<<4); - - if (state) - { - m_int_input |= (1<<4); - } - - if ((previous_state ^ m_int_input) & (1<<4)) - { - /* changed state */ - - if (m_int_input & (1<<4)) - { - /* int request */ - m_int_latch |= (1<<5); - - refresh_ints(); - } - } - - } + m_regs[offset & 0x01f] = data; break; - case DAVE_INT2_ID: - { - int previous_state; + case 0xb4: + m_irq_enable = data; + m_irq_status &= ~(m_irq_enable & IRQ_LATCH); + update_interrupt(); - previous_state = m_int_input; - - m_int_input &= ~(1<<6); - - if (state) - { - m_int_input |= (1<<6); - } - - if ((previous_state ^ m_int_input) & (1<<6)) - { - /* changed state */ - - if (m_int_input & (1<<6)) - { - /* int request */ - m_int_latch |= (1<<7); - - refresh_ints(); - } - } - } + m_regs[offset & 0x01f] = data; break; - default: - break; + case 0xbf: + m_regs[offset & 0x01f] = data; + break; + + default: + m_addrspace[1]->write_byte(offset, data); } } -/* -Reg 4 READ: - -b7 = 1: INT2 latch set -b6 = INT2 input pin -b5 = 1: INT1 latch set -b4 = INT1 input pin -b3 = 1: 1Hz latch set -b2 = 1Hz input pin -b1 = 1: 1kHz/50Hz/TG latch set -b0 = 1kHz/50Hz/TG input - -Reg 4 WRITE: - -b7 = 1: Reset INT2 latch -b6 = 1: Enable INT2 -b5 = 1: Reset INT1 latch -b4 = 1: Enable INT1 -b3 = 1: Reset 1Hz interrupt latch -b2 = 1: Enable 1Hz interrupt -b1 = 1: Reset 1kHz/50Hz/TG latch -b0 = 1: Enable 1kHz/50Hz/TG latch -*/ - - //------------------------------------------------- -// sound_stream_update - handle a stream update +// update_interrupt - //------------------------------------------------- -void dave_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void dave_device::update_interrupt() { - stream_sample_t *buffer1, *buffer2; - /* 0 = channel 0 left volume, 1 = channel 0 right volume, - 2 = channel 1 left volume, 3 = channel 1 right volume, - 4 = channel 2 left volume, 5 = channel 2 right volume - 6 = noise channel left volume, 7 = noise channel right volume */ - int output_volumes[8]; - int left_volume; - int right_volume; - - //logerror("sound update!\n"); - - buffer1 = outputs[0]; - buffer2 = outputs[1]; - - while (samples) - { - int vol[4]; - - /* vol[] keeps track of how long each square wave stays */ - /* in the 1 position during the sample period. */ - vol[0] = vol[1] = vol[2] = vol[3] = 0; - - for (int i = 0; i < 3; i++) - { - if ((m_regs[7] & (1 << i))==0) - { - if (m_level[i]) vol[i] += m_count[i]; - m_count[i] -= STEP; - /* Period[i] is the half period of the square wave. Here, in each */ - /* loop I add Period[i] twice, so that at the end of the loop the */ - /* square wave is in the same status (0 or 1) it was at the start. */ - /* vol[i] is also incremented by Period[i], since the wave has been 1 */ - /* exactly half of the time, regardless of the initial position. */ - /* If we exit the loop in the middle, Output[i] has to be inverted */ - /* and vol[i] incremented only if the exit status of the square */ - /* wave is 1. */ - while (m_count[i] <= 0) - { - m_count[i] += m_period[i]; - if (m_count[i] > 0) - { - m_level[i] ^= 0x0ffffffff; - if (m_level[i]) vol[i] += m_period[i]; - break; - } - m_count[i] += m_period[i]; - vol[i] += m_period[i]; - } - if (m_level[i]) - vol[i] -= m_count[i]; - } - } - - /* update volume outputs */ - - /* setup output volumes for each channel */ - /* channel 0 */ - output_volumes[0] = ((m_level[0] & m_level_and[0]) | m_level_or[0]) & m_mame_volumes[0]; - output_volumes[1] = ((m_level[0] & m_level_and[1]) | m_level_or[1]) & m_mame_volumes[4]; - /* channel 1 */ - output_volumes[2] = ((m_level[1] & m_level_and[2]) | m_level_or[2]) & m_mame_volumes[1]; - output_volumes[3] = ((m_level[1] & m_level_and[3]) | m_level_or[3]) & m_mame_volumes[5]; - /* channel 2 */ - output_volumes[4] = ((m_level[2] & m_level_and[4]) | m_level_or[4]) & m_mame_volumes[2]; - output_volumes[5] = ((m_level[2] & m_level_and[5]) | m_level_or[5]) & m_mame_volumes[6]; - /* channel 3 */ - output_volumes[6] = ((m_level[3] & m_level_and[6]) | m_level_or[6]) & m_mame_volumes[3]; - output_volumes[7] = ((m_level[3] & m_level_and[7]) | m_level_or[7]) & m_mame_volumes[7]; - - left_volume = (output_volumes[0] + output_volumes[2] + output_volumes[4] + output_volumes[6])>>2; - right_volume = (output_volumes[1] + output_volumes[3] + output_volumes[5] + output_volumes[7])>>2; - - *(buffer1++) = left_volume; - *(buffer2++) = right_volume; - - samples--; - } + int state = ((m_irq_status & (m_irq_enable << 1)) & IRQ_LATCH) ? ASSERT_LINE : CLEAR_LINE; + + m_write_irq(state); } diff --git a/src/mess/audio/dave.h b/src/mess/audio/dave.h index 4bc28ec19f8..7df64b16008 100644 --- a/src/mess/audio/dave.h +++ b/src/mess/audio/dave.h @@ -1,112 +1,127 @@ /********************************************************************** - "Dave" Sound Chip + Intelligent Designs DAVE emulation + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. **********************************************************************/ -#ifndef __DAVE_H__ -#define __DAVE_H__ +#pragma once -#include "devcb.h" +#ifndef __DAVE__ +#define __DAVE__ + +#include "emu.h" -#define DAVE_INT_SELECTABLE 0 -#define DAVE_INT_1KHZ_50HZ_TG 1 -#define DAVE_INT_1HZ 2 -#define DAVE_INT_INT1 3 -#define DAVE_INT_INT2 4 -#define DAVE_FIFTY_HZ_COUNTER_RELOAD 20 -#define DAVE_ONE_HZ_COUNTER_RELOAD 1000 +///************************************************************************* +// MACROS / CONSTANTS +///************************************************************************* -/* id's of external ints */ -enum -{ - DAVE_INT1_ID, - DAVE_INT2_ID -}; +#define DAVE_AS_PROGRAM AS_0 +#define DAVE_AS_IO AS_1 -/*************************************************************************** - TYPE DEFINITIONS - ***************************************************************************/ -struct dave_interface -{ - devcb_read8 m_reg_r_cb; - devcb_write8 m_reg_w_cb; - devcb_write_line m_int_cb; -}; +///************************************************************************* +// INTERFACE CONFIGURATION MACROS +///************************************************************************* + +#define MCFG_DAVE_ADD(_tag, _clock, _irq, _program_map, _io_map) \ + MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") \ + MCFG_SOUND_ADD(_tag, DAVE, _clock) \ + MCFG_SOUND_ROUTE(0, "lspeaker", 1.0) \ + MCFG_SOUND_ROUTE(1, "rspeaker", 1.0) \ + MCFG_DEVICE_ADDRESS_MAP(DAVE_AS_PROGRAM, _program_map) \ + MCFG_DEVICE_ADDRESS_MAP(DAVE_AS_IO, _io_map) \ + downcast(device)->set_irq_callback(DEVCB2_##_irq); -/*************************************************************************** - MACROS / CONSTANTS -***************************************************************************/ -class dave_sound_device : public device_t, - public device_sound_interface, - public dave_interface +///************************************************************************* +// TYPE DEFINITIONS +///************************************************************************* + +// ======================> dave_device + +class dave_device : public device_t, + public device_memory_interface, + public device_sound_interface { public: - dave_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - ~dave_sound_device() {} + dave_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - DECLARE_WRITE8_MEMBER(reg_w); - DECLARE_READ8_MEMBER(reg_r); - void set_reg(offs_t offset, UINT8 data); + template void set_irq_callback(_irq irq) { m_write_irq.set_callback(irq); } + template void set_dac_callbacks(_lh lh, _rh rh) { + m_write_lh.set_callback(lh); + m_write_rh.set_callback(rh); + } + + virtual DECLARE_ADDRESS_MAP(z80_program_map, 8); + virtual DECLARE_ADDRESS_MAP(z80_io_map, 8); + + DECLARE_WRITE_LINE_MEMBER( int1_w ); + DECLARE_WRITE_LINE_MEMBER( int2_w ); protected: // device-level overrides - virtual void device_config_complete(); virtual void device_start(); virtual void device_reset(); + virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); + + // device_memory_interface overrides + virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const; // sound stream update overrides virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples); -private: - // internal state - devcb_resolved_read8 m_reg_r; - devcb_resolved_write8 m_reg_w; - devcb_resolved_write_line m_int_callback; + DECLARE_READ8_MEMBER( program_r ); + DECLARE_WRITE8_MEMBER( program_w ); + + DECLARE_READ8_MEMBER( io_r ); + DECLARE_WRITE8_MEMBER( io_w ); + +private: + enum + { + TIMER_1HZ, + TIMER_50HZ + }; + + enum + { + IRQ_50HZ_DIVIDER = 0x01, + IRQ_50HZ_LATCH = 0x02, + IRQ_1HZ_DIVIDER = 0x04, + IRQ_1HZ_LATCH = 0x08, + IRQ_INT1 = 0x10, + IRQ_INT1_LATCH = 0x20, + IRQ_INT2 = 0x40, + IRQ_INT2_LATCH = 0x80, + IRQ_LATCH = IRQ_INT2_LATCH | IRQ_INT1_LATCH | IRQ_1HZ_LATCH | IRQ_50HZ_LATCH + }; + + void update_interrupt(); + + const address_space_config m_program_space_config; + const address_space_config m_io_space_config; + + devcb2_write_line m_write_irq; + devcb2_write8 m_write_lh; + devcb2_write8 m_write_rh; + + UINT8 m_segment[4]; + + UINT8 m_irq_status; + UINT8 m_irq_enable; + + emu_timer *m_timer_1hz; + emu_timer *m_timer_50hz; - TIMER_CALLBACK_MEMBER(dave_1khz_callback); - DECLARE_WRITE8_MEMBER(sound_w); - void refresh_ints(); - void refresh_selectable_int(); - void set_external_int_state(int int_id, int state); - - UINT8 m_regs[32]; - - /* int latches (used by 1Hz, int1 and int2) */ - UINT32 m_int_latch; - /* int enables */ - UINT32 m_int_enable; - /* int inputs */ - UINT32 m_int_input; - - UINT32 m_int_irq; - - /* INTERRUPTS */ - - /* internal timer */ - /* bit 2: 1kHz timer irq */ - /* bit 1: 50kHz timer irq */ - int m_timer_irq; - /* 1khz timer - divided into 1kHz, 50Hz and 1Hz timer */ - //emu_timer *m_int_timer; - /* state of 1kHz timer */ - UINT32 m_one_khz_state; - /* state of 50Hz timer */ - UINT32 m_fifty_hz_state; - - /* counter used to trigger 50Hz from 1kHz timer */ - UINT32 m_fifty_hz_count; - /* counter used to trigger 1Hz from 1kHz timer */ - UINT32 m_one_hz_count; - - /* SOUND SYNTHESIS */ + UINT8 m_regs[32]; int m_period[4]; int m_count[4]; int m_level[4]; @@ -127,11 +142,12 @@ private: //int m_update_step; sound_stream *m_sound_stream_var; - - /* temp here */ - int m_nick_virq; }; + +// device type definition extern const device_type DAVE; -#endif /* __DAVE_H__ */ + + +#endif diff --git a/src/mess/drivers/enterp.c b/src/mess/drivers/ep64.c similarity index 51% rename from src/mess/drivers/enterp.c rename to src/mess/drivers/ep64.c index ceb89237cf5..dd471655e45 100644 --- a/src/mess/drivers/enterp.c +++ b/src/mess/drivers/ep64.c @@ -1,3 +1,12 @@ +/********************************************************************** + + Enterprise Sixty Four / One Two Eight emulation + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**********************************************************************/ + /* Enterprise Sixty Four / Enterprise One Two Eight @@ -106,42 +115,6 @@ Notes: (all IC's shown) Fire A6 B6 Up -Floppy Drive Controller PCB Layout ----------------------------------- - -INTELLIGENT SOFTWARE LTD DISK CONTROLLER -ISS1 - |--------------------------------------------| - | | - | | -|-| 7438 74LS273 WD1770 | -|I| | -|D| | -|C| EPROM.IC2| -|3| 74LS32 74LS02 74LS266 | -|4| 7438 | -|-| 74LS126 74LS10 74LS245 74LS266 | - | | - | | - |----------------------------||||||||||||||||| - |---------------| -Notes: (All IC's shown) - -This PCB plugs into the external expansion connector on the right side of the mainboard - - EPROM.IC2 - 16k x8-bit EPROM labelled 'EXDOS V1.0 P/N 08-60' (DIP28) - WD1770 - Western Digital WD1770 Floppy Drive Controller (DIP28) - 74LS02 - Quad 2-Input NOR Gate (DIP14) - 74LS10 - Triple 3-input NAND Gate (DIP14) - 74LS32 - Quad 2-Input Positive OR Gate (DIP14) - 7438 - Quad 2-input NAND Buffer (DIP14) - 74LS126 - Quad Bus Buffer (DIP14) - 74LS245 - Octal Bus Tranceiver with Tri-State Outputs (DIP20) - 74LS266 - Quad EXCLUSIVE-NOR Gate (DIP14) - 74LS273 - Octal D-Type Flip-Flop With Clear (DIP20) - IDC34 - IDC 34-way flat cable connector for floppy drive data cable - - Internal Memory Expansion PCB Layout ------------------------------------ @@ -163,349 +136,223 @@ Notes: (All IC's shown) */ -/****************************************************************************** - * Enterprise 128k driver - * - * Kevin Thacker 1999. - * - * James Boulton [EP help] - * Jean-Pierre Malisse [EP help] - * - * EP Hardware: Z80 (CPU), Dave (Sound Chip + I/O) - * Nick (Graphics), WD1772 (FDC). 128k ram. - * - * For an 8-bit machine, this kicks ass! A sound - * Chip which is as powerful, or more powerful than - * the C64 SID, and a graphics chip capable of some - * really nice graphics. Pity it doesn't have HW sprites! - ******************************************************************************/ - -#include "emu.h" -#include "cpu/z80/z80.h" -#include "machine/wd17xx.h" -#include "imagedev/flopdrv.h" -#include "formats/basicdsk.h" -#include "includes/enterp.h" - -#define ENTERPRISE_XTAL_X1 XTAL_8MHz - - -/*************************************************************************** - MEMORY / I/O -***************************************************************************/ - -void ep_state::enterprise_update_memory_page(address_space &space, offs_t page, int index) -{ - int start = (page - 1) * 0x4000; - int end = (page - 1) * 0x4000 + 0x3fff; - char page_num[10]; - sprintf(page_num,"bank%d",page); - - switch (index) - { - case 0x00: - case 0x01: - case 0x02: - case 0x03: - space.install_read_bank(start, end, page_num); - space.nop_write(start, end); - membank(page_num)->set_base(memregion("exos")->base() + (index * 0x4000)); - break; - - case 0x04: - case 0x05: - case 0x06: - case 0x07: - space.install_read_bank(start, end, page_num); - space.nop_write(start, end); - membank(page_num)->set_base(memregion("cartridges")->base() + ((index - 0x04) * 0x4000)); - break; - - case 0x20: - case 0x21: - space.install_read_bank(start, end, page_num); - space.nop_write(start, end); - membank(page_num)->set_base(memregion("exdos")->base() + ((index - 0x20) * 0x4000)); - break; - - case 0xf8: - case 0xf9: - case 0xfa: - case 0xfb: - /* additional 64k ram */ - if (m_ram->size() == 128*1024) - { - space.install_readwrite_bank(start, end, page_num); - membank(page_num)->set_base(m_ram->pointer() + (index - 0xf4) * 0x4000); - } - else - { - space.unmap_readwrite(start, end); - } - break; - - case 0xfc: - case 0xfd: - case 0xfe: - case 0xff: - /* basic 64k ram */ - space.install_readwrite_bank(start, end, page_num); - membank(page_num)->set_base(m_ram->pointer() + (index - 0xfc) * 0x4000); - break; - - default: - space.unmap_readwrite(start, end); - } -} - - -/* EP specific handling of dave register write */ -WRITE8_MEMBER(ep_state::enterprise_dave_reg_write) -{ - switch (offset) - { - case 0x10: - case 0x11: - case 0x12: - case 0x13: - enterprise_update_memory_page(m_maincpu->space(AS_PROGRAM), offset - 0x0f, data); - break; - - case 0x15: - keyboard_line = data & 15; - break; - } -} - - -READ8_MEMBER(ep_state::enterprise_dave_reg_read) -{ - switch (offset) - { - case 0x015: - /* read keyboard line */ - m_dave->set_reg(0x015, m_key[keyboard_line]->read()); - break; - - case 0x016: - { - int ExternalJoystickInputs; - int ExternalJoystickPortInput = m_joy->read(); - - if (keyboard_line <= 4) - { - ExternalJoystickInputs = ExternalJoystickPortInput>>(4-(keyboard_line)); - } - else - { - ExternalJoystickInputs = 1; - } - - m_dave->set_reg(0x016, (0x0fe | (ExternalJoystickInputs & 0x01))); - } - break; - - default: - break; - } - return 0; -} - -/* enterprise interface to dave - ok, so Dave chip is unique -to Enterprise. But these functions make it nice and easy to see -whats going on. */ -static const dave_interface enterprise_dave_interface = -{ - DEVCB_DRIVER_MEMBER(ep_state,enterprise_dave_reg_read), - DEVCB_DRIVER_MEMBER(ep_state,enterprise_dave_reg_write), - DEVCB_CPU_INPUT_LINE("maincpu", 0) -}; - - -void ep_state::machine_start() -{ - m_maincpu->set_input_line_vector(0, 0xff); - m_nick->set_vram(m_ram->pointer()); - - for (int i = 0; i < 10; i++) - { - char str[6]; - sprintf(str, "LINE%i", i); - m_key[i] = ioport(str); - } -} - -void ep_state::machine_reset() -{ - m_maincpu->set_input_line_vector(0, 0xff); -} - - -UINT32 ep_state::screen_update_enterp(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) -{ - m_nick->screen_update_epnick(screen, bitmap, cliprect); - return 0; -} - -// FIXME: Should this be here or in the Nick device?!? - -/* Enterprise has 256 colours, all may be on the screen at once! - the NICK_GET_RED8, NICK_GET_GREEN8, NICK_GET_BLUE8 macros - return a 8-bit colour value for the index specified. */ - -/* given a colour index in range 0..255 gives the Red component */ -#define NICK_GET_RED8(x) \ - (( \ - (BIT(x, 0) << 2) | \ - (BIT(x, 3) << 1) | \ - (BIT(x, 6) << 0) \ - ) << 5) - -/* given a colour index in range 0..255 gives the Red component */ -#define NICK_GET_GREEN8(x) \ - (( \ - (BIT(x, 1) << 2) | \ - (BIT(x, 4) << 1) | \ - (BIT(x, 7) << 0) \ - ) << 5) - -/* given a colour index in range 0..255 gives the Red component */ -#define NICK_GET_BLUE8(x) \ - (( \ - (BIT(x, 2) << 1) | \ - (BIT(x, 5) << 0) \ - ) << 6) - - -/* initial the palette */ -void ep_state::palette_init() -{ - for (int i = 0; i < 256; i++) - palette_set_color_rgb(machine(), i, NICK_GET_RED8(i), NICK_GET_GREEN8(i), NICK_GET_BLUE8(i)); -} - - -/*************************************************************************** - FLOPPY/EXDOS -***************************************************************************/ - -WRITE_LINE_MEMBER(ep_state::enterp_wd1770_intrq_w) -{ - if (state) - exdos_card_value |= 0x02; - else - exdos_card_value &= ~0x02; -} - -WRITE_LINE_MEMBER(ep_state::enterp_wd1770_drq_w) -{ - if (state) - exdos_card_value |= 0x80; - else - exdos_card_value &= ~0x80; -} - - -/* bit 0 - ?? - bit 1 - IRQ from WD1770 - bit 2 - ?? - bit 3 - ?? - bit 4 - ?? - bit 5 - ?? - bit 6 - Disk change signal from disk drive - bit 7 - DRQ from WD1770 -*/ -READ8_MEMBER(ep_state::exdos_card_r) -{ - return exdos_card_value; -} - - -/* bit 0 - select drive 0, - bit 1 - select drive 1, - bit 2 - select drive 2, - bit 3 - select drive 3 - bit 4 - side - bit 5 - mfm/fm select - bit 6 - disk change reset - bit 7 - in use -*/ -WRITE8_MEMBER(ep_state::exdos_card_w) -{ - device_t *fdc = machine().device("wd1770"); - - /* drive */ - if (BIT(data, 0)) wd17xx_set_drive(fdc, 0); - if (BIT(data, 1)) wd17xx_set_drive(fdc, 1); - if (BIT(data, 2)) wd17xx_set_drive(fdc, 2); - if (BIT(data, 3)) wd17xx_set_drive(fdc, 3); - - wd17xx_set_side(fdc, BIT(data, 4)); - wd17xx_dden_w(fdc, BIT(data, 5)); -} - -/*************************************************************************** - ADDRESS MAPS -***************************************************************************/ - -static ADDRESS_MAP_START( enterprise_mem, AS_PROGRAM, 8, ep_state ) - AM_RANGE(0x0000, 0x3fff) AM_RAMBANK("bank1") - AM_RANGE(0x4000, 0x7fff) AM_RAMBANK("bank2") - AM_RANGE(0x8000, 0xbfff) AM_RAMBANK("bank3") - AM_RANGE(0xc000, 0xffff) AM_RAMBANK("bank4") -ADDRESS_MAP_END - - -static ADDRESS_MAP_START( enterprise_io, AS_IO, 8, ep_state ) - ADDRESS_MAP_GLOBAL_MASK(0xff) - AM_RANGE(0x10, 0x13) AM_MIRROR(0x04) AM_DEVREADWRITE_LEGACY("wd1770", wd17xx_r, wd17xx_w) - AM_RANGE(0x18, 0x18) AM_MIRROR(0x04) AM_READWRITE(exdos_card_r, exdos_card_w) - AM_RANGE(0x80, 0x8f) AM_DEVWRITE("nick", nick_device, reg_w) - AM_RANGE(0xa0, 0xbf) AM_DEVREADWRITE("custom", dave_sound_device, reg_r, reg_w) -ADDRESS_MAP_END - - -/*************************************************************************** - INPUT PORTS -***************************************************************************/ - /* -Enterprise Keyboard Matrix - Bit -Line 0 1 2 3 4 5 6 7 -0 n \ b c v x z SHFT -1 h N/C g d f s a CTRL -2 u q y r t e w TAB -3 7 1 6 4 5 3 2 N/C -4 F4 F8 F3 F6 F5 F7 F2 F1 -5 8 N/C 9 - 0 ^ DEL N/C -6 j N/C k ; l : ] N/C -7 STOP DOWN RGHT UP HOLD LEFT RETN ALT -8 m ERSE , / . SHFT SPCE INS -9 i N/C o @ p [ N/C N/C + TODO: -N/C - Not connected or just dont know! + - POST RAM errors + - rewrite DAVE to output to discrete DAC + - rewrite NICK + - cassette + - external joysticks -2008-05 FP: -Notice that I updated the matrix above with the following new info: -l1:b1 is LOCK: you press it with CTRL to switch to Caps, you press it again to switch back - (you can also use it with ALT) -l3:b7 is ESC: you use it to exit from nested programs (e.g. if you start to write a program in BASIC, - then start EXDOS, you can use ESC to go back to BASIC without losing the program you were writing) + http://ep.homeserver.hu/Dokumentacio/Konyvek/ -According to pictures and manuals, there seem to be no more keys connected, so I label the remaining N/C -as IPT_UNUSED. - -Small note about natural keyboard support: currently -- "Lock" is mapped to 'F9' (it acts like a CAPSLOCK, but no IPT_TOGGLE) -- "Stop" is mapped to 'F10' -- "Hold" is mapped to 'F11' */ +#include "includes/ep64.h" + + + +//************************************************************************** +// READ/WRITE HANDLERS +//************************************************************************** + +//------------------------------------------------- +// rd0_r - +//------------------------------------------------- + +READ8_MEMBER( ep64_state::rd0_r ) +{ + UINT8 data = 0xff; + + switch (m_key) + { + case 0: data &= m_y0->read(); break; + case 1: data &= m_y1->read(); break; + case 2: data &= m_y2->read(); break; + case 3: data &= m_y3->read(); break; + case 4: data &= m_y4->read(); break; + case 5: data &= m_y5->read(); break; + case 6: data &= m_y6->read(); break; + case 7: data &= m_y7->read(); break; + case 8: data &= m_y8->read(); break; + case 9: data &= m_y9->read(); break; + } + + return data; +} + + +//------------------------------------------------- +// rd0_r - +//------------------------------------------------- + +WRITE8_MEMBER( ep64_state::wr0_w ) +{ + /* + + bit description + + 0 KEY A + 1 KEY B + 2 KEY C + 3 KEY D + 4 PRINTER _STB + 5 CASSETTE OUT + 6 REMOTE 1 + 7 REMOTE 2 + + */ + + // keyboard + m_key = data & 0x0f; + + // printer + m_centronics->strobe_w(!BIT(data, 4)); + + // cassette + m_cassette1->output(BIT(data, 5) ? -1.0 : +1.0); + m_cassette2->output(BIT(data, 5) ? -1.0 : +1.0); + + // cassette + m_cassette1->change_state(BIT(data, 6) ? CASSETTE_MOTOR_ENABLED : CASSETTE_MOTOR_DISABLED, CASSETTE_MASK_MOTOR); + m_cassette2->change_state(BIT(data, 7) ? CASSETTE_MOTOR_ENABLED : CASSETTE_MOTOR_DISABLED, CASSETTE_MASK_MOTOR); +} + + +//------------------------------------------------- +// rd1_r - +//------------------------------------------------- + +READ8_MEMBER( ep64_state::rd1_r ) +{ + /* + + bit description + + 0 KBJ + 1 KBK + 2 KBL + 3 PRINTER _RDY + 4 SERIAL/NET DATA IN + 5 SERIAL/NET STATUS IN + 6 CASSETTE IN + 7 ? + + */ + + UINT8 data = 0; + + // printer + data |= m_centronics->not_busy_r() << 3; + + // serial + data |= m_rs232->rx() << 4; + data |= m_rs232->cts_r() << 5; + + // cassette + data |= ((m_cassette1->input() < 0) || (m_cassette2->input() < 0)) << 6; + + return data; +} + + +//------------------------------------------------- +// wr2_w - +//------------------------------------------------- + +WRITE8_MEMBER( ep64_state::wr2_w ) +{ + /* + + bit description + + 0 SERIAL/NET DATA OUT + 1 SERIAL/NET STATUS OUT + 2 + 3 + 4 + 5 + 6 + 7 + + */ + + // serial + m_rs232->tx(!BIT(data, 0)); + m_rs232->rts_w(!BIT(data, 1)); +} + + + +//************************************************************************** +// ADDRESS MAPS +//************************************************************************** + +//------------------------------------------------- +// ADDRESS_MAP( ep64_mem ) +//------------------------------------------------- + +static ADDRESS_MAP_START( ep64_mem, AS_PROGRAM, 8, ep64_state ) + AM_RANGE(0x0000, 0xffff) AM_DEVICE(DAVE_TAG, dave_device, z80_program_map) +ADDRESS_MAP_END + + +//------------------------------------------------- +// ADDRESS_MAP( ep64_io ) +//------------------------------------------------- + +static ADDRESS_MAP_START( ep64_io, AS_IO, 8, ep64_state ) + AM_RANGE(0x0000, 0xffff) AM_DEVICE(DAVE_TAG, dave_device, z80_io_map) +ADDRESS_MAP_END + + +//------------------------------------------------- +// ADDRESS_MAP( dave_64k_mem ) +//------------------------------------------------- + +static ADDRESS_MAP_START( dave_64k_mem, DAVE_AS_PROGRAM, 8, ep64_state ) + AM_RANGE(0x000000, 0x007fff) AM_ROM AM_REGION(Z80_TAG, 0) + AM_RANGE(0x010000, 0x01ffff) AM_ROM AM_REGION("cart", 0) + AM_RANGE(0x3f0000, 0x3fffff) AM_DEVICE(NICK_TAG, nick_device, vram_map) +ADDRESS_MAP_END + + +//------------------------------------------------- +// ADDRESS_MAP( dave_128k_mem ) +//------------------------------------------------- + +static ADDRESS_MAP_START( dave_128k_mem, DAVE_AS_PROGRAM, 8, ep64_state ) + AM_IMPORT_FROM(dave_64k_mem) + AM_RANGE(0x3e0000, 0x3effff) AM_RAM +ADDRESS_MAP_END + + +//------------------------------------------------- +// ADDRESS_MAP( dave_io ) +//------------------------------------------------- + +static ADDRESS_MAP_START( dave_io, DAVE_AS_IO, 8, ep64_state ) + ADDRESS_MAP_GLOBAL_MASK(0xff) + AM_RANGE(0x80, 0x8f) AM_DEVICE(NICK_TAG, nick_device, vio_map) + AM_RANGE(0xb5, 0xb5) AM_READWRITE(rd0_r, wr0_w) + AM_RANGE(0xb6, 0xb6) AM_READ(rd1_r) AM_DEVWRITE(CENTRONICS_TAG, centronics_device, write) + AM_RANGE(0xb7, 0xb7) AM_WRITE(wr2_w) +ADDRESS_MAP_END + + + +//************************************************************************** +// INPUT PORTS +//************************************************************************** + +//------------------------------------------------- +// INPUT_PORTS( ep64 ) +//------------------------------------------------- static INPUT_PORTS_START( ep64 ) - PORT_START("LINE0") /* keyboard line 0 */ + PORT_START("Y0") PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N') PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_TILDE) PORT_CHAR('\\') PORT_CHAR('|') PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B') @@ -515,7 +362,7 @@ static INPUT_PORTS_START( ep64 ) PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z') PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) - PORT_START("LINE1") /* keyboard line 1 */ + PORT_START("Y1") PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H') PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("LOCK") PORT_CODE(KEYCODE_F9) PORT_CHAR(UCHAR_MAMEKEY(F9)) PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G') @@ -525,7 +372,7 @@ static INPUT_PORTS_START( ep64 ) PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A') PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_SHIFT_2) - PORT_START("LINE2") /* keyboard line 2 */ + PORT_START("Y2") PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U') PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q') PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y') @@ -535,7 +382,7 @@ static INPUT_PORTS_START( ep64 ) PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W') PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_TAB) PORT_CHAR('\t') - PORT_START("LINE3") /* keyboard line 3 */ + PORT_START("Y3") PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('\'') PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('&') @@ -545,7 +392,7 @@ static INPUT_PORTS_START( ep64 ) PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('"') PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_ESC) PORT_CHAR(UCHAR_MAMEKEY(ESC)) - PORT_START("LINE4") /* keyboard line 4 */ + PORT_START("Y4") PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4)) PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F8) PORT_CHAR(UCHAR_MAMEKEY(F8)) PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) @@ -555,7 +402,7 @@ static INPUT_PORTS_START( ep64 ) PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) - PORT_START("LINE5") /* keyboard line 5 */ + PORT_START("Y5") PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(') PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_UNUSED) PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')') @@ -565,7 +412,7 @@ static INPUT_PORTS_START( ep64 ) PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("ERASE") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) - PORT_START("LINE6") /* keyboard line 6 */ + PORT_START("Y6") PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J') PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_UNUSED) PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K') @@ -576,7 +423,7 @@ static INPUT_PORTS_START( ep64 ) PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) /* Notice that, in fact, ep128 only had the built-in joystick and no cursor arrow keys on the keyboard */ - PORT_START("LINE7") /* keyboard line 7 */ + PORT_START("Y7") PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("STOP") PORT_CODE(KEYCODE_END) PORT_CHAR(UCHAR_MAMEKEY(F10)) PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_DOWN) PORT_CODE(JOYCODE_Y_DOWN_SWITCH) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_RIGHT) PORT_CODE(JOYCODE_X_RIGHT_SWITCH) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) @@ -586,7 +433,7 @@ static INPUT_PORTS_START( ep64 ) PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("ALT") PORT_CODE(KEYCODE_LALT) PORT_CHAR(UCHAR_MAMEKEY(LALT)) - PORT_START("LINE8") /* keyboard line 8 */ + PORT_START("Y8") PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M') PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_DEL) PORT_CHAR(UCHAR_MAMEKEY(DEL)) PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') @@ -596,7 +443,7 @@ static INPUT_PORTS_START( ep64 ) PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_INSERT) PORT_CHAR(UCHAR_MAMEKEY(INSERT)) - PORT_START("LINE9") /* keyboard line 9 */ + PORT_START("Y9") PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_UNUSED) PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O') @@ -605,151 +452,173 @@ static INPUT_PORTS_START( ep64 ) PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR('[') PORT_CHAR('{') PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_UNUSED) PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) - - PORT_START("JOY1") /* external joystick 1 */ - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("EXTERNAL JOYSTICK 1 RIGHT") PORT_CODE(KEYCODE_RIGHT) PORT_CODE(JOYCODE_X_RIGHT_SWITCH) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("EXTERNAL JOYSTICK 1 LEFT") PORT_CODE(KEYCODE_LEFT) PORT_CODE(JOYCODE_X_LEFT_SWITCH) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("EXTERNAL JOYSTICK 1 DOWN") PORT_CODE(KEYCODE_DOWN) PORT_CODE(JOYCODE_Y_DOWN_SWITCH) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("EXTERNAL JOYSTICK 1 UP") PORT_CODE(KEYCODE_UP) PORT_CODE(JOYCODE_Y_UP_SWITCH) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("EXTERNAL JOYSTICK 1 FIRE") PORT_CODE(KEYCODE_SPACE) PORT_CODE(JOYCODE_BUTTON1) INPUT_PORTS_END -/*************************************************************************** - MACHINE DRIVERS -***************************************************************************/ -static const wd17xx_interface enterp_wd1770_interface = +//************************************************************************** +// DEVICE CONFIGURATION +//************************************************************************** + +//------------------------------------------------- +// rs232_port_interface rs232_intf +//------------------------------------------------- + +static const rs232_port_interface rs232_intf = { DEVCB_NULL, - DEVCB_DRIVER_LINE_MEMBER(ep_state,enterp_wd1770_intrq_w), - DEVCB_DRIVER_LINE_MEMBER(ep_state,enterp_wd1770_drq_w), - {FLOPPY_0, FLOPPY_1, FLOPPY_2, FLOPPY_3} + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + DEVCB_DEVICE_LINE_MEMBER(DAVE_TAG, dave_device, int2_w) }; -static LEGACY_FLOPPY_OPTIONS_START(enterprise) - LEGACY_FLOPPY_OPTION(enterprise, "dsk,img", "Enterprise disk image", basicdsk_identify_default, basicdsk_construct_default, NULL, - HEADS([2]) - TRACKS([80]) - SECTORS([9]) - SECTOR_LENGTH([512]) - FIRST_SECTOR_ID([1])) -LEGACY_FLOPPY_OPTIONS_END -static const floppy_interface enterprise_floppy_interface = +//------------------------------------------------- +// cassette_interface cass_intf +//------------------------------------------------- + +static const cassette_interface cass_intf = { - DEVCB_NULL, - DEVCB_NULL, - DEVCB_NULL, - DEVCB_NULL, - DEVCB_NULL, - FLOPPY_STANDARD_3_5_DSDD, - LEGACY_FLOPPY_OPTIONS_NAME(enterprise), - "floppy_3_5", + cassette_default_formats, + NULL, + (cassette_state)(CASSETTE_STOPPED | CASSETTE_MOTOR_DISABLED | CASSETTE_SPEAKER_MUTED), + "ep64_cass", NULL }; -static MACHINE_CONFIG_START( ep64, ep_state ) - /* basic machine hardware */ - MCFG_CPU_ADD("maincpu", Z80, ENTERPRISE_XTAL_X1/2) /* 4 MHz, generated by DAVE */ - MCFG_CPU_PROGRAM_MAP(enterprise_mem) - MCFG_CPU_IO_MAP(enterprise_io) - /* video hardware */ - MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_REFRESH_RATE(50) - MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */ - MCFG_SCREEN_SIZE(ENTERPRISE_SCREEN_WIDTH, ENTERPRISE_SCREEN_HEIGHT) - MCFG_SCREEN_VISIBLE_AREA(0, ENTERPRISE_SCREEN_WIDTH-1, 0, ENTERPRISE_SCREEN_HEIGHT-1) - MCFG_SCREEN_UPDATE_DRIVER(ep_state, screen_update_enterp) - MCFG_PALETTE_LENGTH(NICK_PALETTE_SIZE) +//************************************************************************** +// MACHINE INITIALIZATION +//************************************************************************** - MCFG_NICK_ADD("nick") +//------------------------------------------------- +// MACHINE_START( ep64 ) +//------------------------------------------------- - /* sound hardware */ - MCFG_SPEAKER_STANDARD_MONO("mono") - MCFG_SOUND_ADD("custom", DAVE, 0) - MCFG_DEVICE_CONFIG( enterprise_dave_interface ) - MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) +void ep64_state::machine_start() +{ + // state saving + save_item(NAME(m_key)); +} - MCFG_WD1770_ADD("wd1770", enterp_wd1770_interface ) - MCFG_LEGACY_FLOPPY_4_DRIVES_ADD(enterprise_floppy_interface) +//------------------------------------------------- +// MACHINE_RESET( ep64 ) +//------------------------------------------------- - /* internal ram */ +void ep64_state::machine_reset() +{ + m_dave->reset(); + m_nick->reset(); + + address_space &program = m_maincpu->space(AS_PROGRAM); + wr0_w(program, 0, 0); + m_centronics->write(0); + wr2_w(program, 0, 0); +} + + + +//************************************************************************** +// MACHINE CONFIGURATION +//************************************************************************** + +//------------------------------------------------- +// MACHINE_CONFIG( ep64 ) +//------------------------------------------------- + +static MACHINE_CONFIG_START( ep64, ep64_state ) + // basic machine hardware + MCFG_CPU_ADD(Z80_TAG, Z80, XTAL_8MHz/2) + MCFG_CPU_PROGRAM_MAP(ep64_mem) + MCFG_CPU_IO_MAP(ep64_io) + + // video hardware + MCFG_NICK_ADD(NICK_TAG, SCREEN_TAG, XTAL_8MHz, DEVWRITELINE(DAVE_TAG, dave_device, int1_w)) + + // sound hardware + MCFG_DAVE_ADD(DAVE_TAG, XTAL_8MHz, INPUTLINE(Z80_TAG, INPUT_LINE_IRQ0), dave_64k_mem, dave_io) + + // devices + MCFG_EP64_EXPANSION_BUS_SLOT_ADD(EP64_EXPANSION_BUS_TAG, DAVE_TAG, NULL) + MCFG_EP64_EXPANSION_BUS_CALLBACKS(INPUTLINE(Z80_TAG, INPUT_LINE_IRQ0), INPUTLINE(Z80_TAG, INPUT_LINE_NMI), INPUTLINE(Z80_TAG, Z80_INPUT_LINE_WAIT)) + MCFG_CENTRONICS_PRINTER_ADD(CENTRONICS_TAG, standard_centronics) + MCFG_RS232_PORT_ADD(RS232_TAG, rs232_intf, default_rs232_devices, NULL) + MCFG_CASSETTE_ADD(CASSETTE1_TAG, cass_intf) + MCFG_CASSETTE_ADD(CASSETTE2_TAG, cass_intf) + + // internal RAM MCFG_RAM_ADD(RAM_TAG) MCFG_RAM_DEFAULT_SIZE("64K") - // software list + // cartridge + MCFG_CARTSLOT_ADD("cart") + MCFG_CARTSLOT_EXTENSION_LIST("rom,bin") + MCFG_CARTSLOT_NOT_MANDATORY + MCFG_CARTSLOT_INTERFACE("ep64_cart") + + // software lists + MCFG_SOFTWARE_LIST_ADD("cart_list", "ep64_cart") MCFG_SOFTWARE_LIST_ADD("cass_list", "ep64_cass") MCFG_SOFTWARE_LIST_ADD("flop_list", "ep64_flop") MACHINE_CONFIG_END + +//------------------------------------------------- +// MACHINE_CONFIG( ep128 ) +//------------------------------------------------- + static MACHINE_CONFIG_DERIVED( ep128, ep64 ) - /* internal ram */ + MCFG_DEVICE_MODIFY(DAVE_TAG) + MCFG_DEVICE_ADDRESS_MAP(AS_0, dave_128k_mem) + + // internal RAM MCFG_RAM_MODIFY(RAM_TAG) MCFG_RAM_DEFAULT_SIZE("128K") MACHINE_CONFIG_END -/*************************************************************************** - ROM DEFINITIONS -***************************************************************************/ + +//************************************************************************** +// ROMS +//************************************************************************** + +//------------------------------------------------- +// ROM( ep64 ) +//------------------------------------------------- ROM_START( ep64 ) - ROM_REGION(0x8000, "exos", 0) - ROM_LOAD("9256ds-0038_enter05-23-a.u2", 0x0000, 0x8000, CRC(d421795f) SHA1(6033a0535136c40c47137e4d1cd9273c06d5fdff)) + ROM_REGION( 0x8000, Z80_TAG, 0 ) + ROM_LOAD( "9256ds-0038_enter05-23-a.u2", 0x0000, 0x8000, CRC(d421795f) SHA1(6033a0535136c40c47137e4d1cd9273c06d5fdff) ) - /* 4 cartridge slots */ - ROM_REGION(0x10000, "cartridges", 0) - ROM_LOAD("basic20.rom", 0x0000, 0x4000, CRC(d62e4fb7) SHA1(36e12c4ea782ca769225178f61b55bc9a9afb927)) - ROM_FILL(0x4000, 0xc000, 0xff) - - ROM_REGION(0x8000, "exdos", 0) - ROM_LOAD("exdos13.rom", 0x0000, 0x8000, CRC(d1d7e157) SHA1(31c8be089526aa8aa019c380cdf51ddd3ee76454)) + ROM_REGION( 0x10000, "cart", 0 ) + ROM_CART_LOAD( "cart", 0x00000, 0x10000, ROM_MIRROR ) ROM_END +#define rom_phc64 rom_ep64 + + +//------------------------------------------------- +// ROM( ep128 ) +//------------------------------------------------- + ROM_START( ep128 ) - ROM_REGION(0x10000, "exos", 0) - ROM_SYSTEM_BIOS(0, "exos21", "EXOS 2.1") - ROMX_LOAD("9256ds-0019_enter08-45-a.u2", 0x0000, 0x8000, CRC(982a3b44) SHA1(55315b20fecb4441a07ee4bc5dc7153f396e0a2e), ROM_BIOS(1)) - ROM_FILL(0x8000, 0x8000, 0xff) - ROM_SYSTEM_BIOS(1, "exos22", "EXOS 2.2 (unofficial)") - ROMX_LOAD("exos22.rom", 0x0000, 0x10000, CRC(c82e699f) SHA1(40cda9573e0c20e6287d27105759e23b9025fa52), ROM_BIOS(2)) - ROM_SYSTEM_BIOS(2, "exos23", "EXOS 2.3 (unofficial)") - ROMX_LOAD("exos23.rom", 0x0000, 0x10000, CRC(24838410) SHA1(c6241e1c248193108ce38b9a8e9dd33972cf47ba), ROM_BIOS(3)) - ROM_SYSTEM_BIOS(3, "exos231", "EXOS 2.31 (unofficial)") - ROMX_LOAD("exos231.rom", 0x0000, 0x10000, CRC(d0ecee0d) SHA1(bd0ff3c46f57c88b82b71b0d94a8bda18ea9bafe), ROM_BIOS(4)) + ROM_REGION( 0x8000, Z80_TAG, 0 ) + ROM_LOAD( "9256ds-0019_enter08-45-a.u2", 0x0000, 0x8000, CRC(982a3b44) SHA1(55315b20fecb4441a07ee4bc5dc7153f396e0a2e) ) - /* 4 cartridge slots */ - ROM_REGION(0x10000, "cartridges", 0) - ROM_LOAD("9128ds-0237_enter08-46-a.u1", 0x0000, 0x4000, CRC(683cf455) SHA1(50a548d1df3ea86f9b5fa669afd8ff124050e776)) /* BASIC V2.1 */ - ROM_FILL(0x4000, 0xc000, 0xff) - - ROM_REGION(0x8000, "exdos", 0) - ROM_LOAD("exdos13.rom", 0x0000, 0x8000, CRC(d1d7e157) SHA1(31c8be089526aa8aa019c380cdf51ddd3ee76454)) + ROM_REGION( 0x10000, "cart", 0 ) + ROM_CART_LOAD( "cart", 0x00000, 0x10000, ROM_MIRROR ) ROM_END -ROM_START( phc64 ) - ROM_REGION(0x8000, "exos", 0) - ROM_LOAD("9256ds-0038_enter05-23-a.u2", 0x0000, 0x8000, CRC(d421795f) SHA1(6033a0535136c40c47137e4d1cd9273c06d5fdff)) - /* 4 cartridge slots */ - ROM_REGION(0x10000, "cartridges", 0) - ROM_LOAD("basic20.rom", 0x0000, 0x4000, CRC(d62e4fb7) SHA1(36e12c4ea782ca769225178f61b55bc9a9afb927)) - ROM_LOAD("brd.rom", 0x4000, 0x4000, CRC(f45a7454) SHA1(096c91fad6a4d10323cd67e133b3ebc5c50e2bb2)) - ROM_FILL(0x8000, 0x8000, 0xff) - ROM_REGION(0x8000, "exdos", 0) - ROM_LOAD("exdos13.rom", 0x0000, 0x8000, CRC(d1d7e157) SHA1(31c8be089526aa8aa019c380cdf51ddd3ee76454)) -ROM_END +//************************************************************************** +// SYSTEM DRIVERS +//************************************************************************** -/*************************************************************************** - GAME DRIVERS -***************************************************************************/ - -/* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME */ -COMP( 1985, ep64, 0, 0, ep64, ep64, driver_device, 0, "Enterprise Computers", "Enterprise Sixty Four", GAME_IMPERFECT_SOUND ) -COMP( 1985, ep128, ep64, 0, ep128, ep64, driver_device, 0, "Enterprise Computers", "Enterprise One Two Eight", GAME_IMPERFECT_SOUND ) -COMP( 1985, phc64, ep64, 0, ep64, ep64, driver_device, 0, "Hegener & Glaser", "Mephisto PHC 64", GAME_IMPERFECT_SOUND ) \ No newline at end of file +// YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS +COMP( 1985, ep64, 0, 0, ep64, ep64, driver_device, 0, "Enterprise Computers", "Enterprise Sixty Four", GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND ) +COMP( 1985, phc64, ep64, 0, ep64, ep64, driver_device, 0, "Hegener & Glaser", "Mephisto PHC 64 (Germany)", GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND ) +COMP( 1986, ep128, ep64, 0, ep128, ep64, driver_device, 0, "Enterprise Computers", "Enterprise One Two Eight", GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND ) diff --git a/src/mess/includes/ep64.h b/src/mess/includes/ep64.h new file mode 100644 index 00000000000..39e522d7cbd --- /dev/null +++ b/src/mess/includes/ep64.h @@ -0,0 +1,94 @@ +/********************************************************************** + + Enterprise Sixty Four / One Two Eight emulation + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**********************************************************************/ + +#pragma once + +#ifndef __EP64__ +#define __EP64__ + +#include "emu.h" +#include "audio/dave.h" +#include "cpu/z80/z80.h" +#include "imagedev/cartslot.h" +#include "imagedev/cassette.h" +#include "machine/ctronics.h" +#include "machine/ep64exp.h" +#include "machine/ram.h" +#include "machine/serial.h" +#include "video/nick.h" + +#define Z80_TAG "u1" +#define DAVE_TAG "u3" +#define NICK_TAG "u4" +#define CENTRONICS_TAG "centronics" +#define RS232_TAG "rs232" +#define CASSETTE1_TAG "cassette1" +#define CASSETTE2_TAG "cassette2" +#define SCREEN_TAG "screen" + +class ep64_state : public driver_device +{ +public: + ep64_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag), + m_maincpu(*this, Z80_TAG), + m_dave(*this, DAVE_TAG), + m_nick(*this, NICK_TAG), + m_centronics(*this, CENTRONICS_TAG), + m_rs232(*this, RS232_TAG), + m_cassette1(*this, CASSETTE1_TAG), + m_cassette2(*this, CASSETTE2_TAG), + m_ram(*this, RAM_TAG), + m_rom(*this, Z80_TAG), + m_y0(*this, "Y0"), + m_y1(*this, "Y1"), + m_y2(*this, "Y2"), + m_y3(*this, "Y3"), + m_y4(*this, "Y4"), + m_y5(*this, "Y5"), + m_y6(*this, "Y6"), + m_y7(*this, "Y7"), + m_y8(*this, "Y8"), + m_y9(*this, "Y9") + { } + + required_device m_maincpu; + required_device m_dave; + required_device m_nick; + required_device m_centronics; + required_device m_rs232; + required_device m_cassette1; + required_device m_cassette2; + required_device m_ram; + required_memory_region m_rom; + required_ioport m_y0; + required_ioport m_y1; + required_ioport m_y2; + required_ioport m_y3; + required_ioport m_y4; + required_ioport m_y5; + required_ioport m_y6; + required_ioport m_y7; + required_ioport m_y8; + required_ioport m_y9; + + virtual void machine_start(); + virtual void machine_reset(); + + DECLARE_READ8_MEMBER( rd0_r ); + DECLARE_WRITE8_MEMBER( wr0_w ); + DECLARE_READ8_MEMBER( rd1_r ); + DECLARE_WRITE8_MEMBER( wr1_w ); + DECLARE_READ8_MEMBER( rd2_r ); + DECLARE_WRITE8_MEMBER( wr2_w ); + + UINT8 m_key; +}; + +#endif diff --git a/src/mess/machine/ep64_exdos.c b/src/mess/machine/ep64_exdos.c new file mode 100644 index 00000000000..5e0af1283a3 --- /dev/null +++ b/src/mess/machine/ep64_exdos.c @@ -0,0 +1,244 @@ +/********************************************************************** + + Intelligent Software EXDOS Disk Controller Module emulation + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**********************************************************************/ + +/* + +Floppy Drive Controller PCB Layout +---------------------------------- + +INTELLIGENT SOFTWARE LTD DISK CONTROLLER +ISS1 + |--------------------------------------------| + | | + | | +|-| 7438 74LS273 WD1770 | +|I| | +|D| | +|C| EPROM.IC2| +|3| 74LS32 74LS02 74LS266 | +|4| 7438 | +|-| 74LS126 74LS10 74LS245 74LS266 | + | | + | | + |----------------------------||||||||||||||||| + |---------------| +Notes: (All IC's shown) + +This PCB plugs into the external expansion connector on the right side of the mainboard + + EPROM.IC2 - 16k x8-bit EPROM labelled 'EXDOS V1.0 P/N 08-60' (DIP28) + WD1770 - Western Digital WD1770 Floppy Drive Controller (DIP28) + 74LS02 - Quad 2-Input NOR Gate (DIP14) + 74LS10 - Triple 3-input NAND Gate (DIP14) + 74LS32 - Quad 2-Input Positive OR Gate (DIP14) + 7438 - Quad 2-input NAND Buffer (DIP14) + 74LS126 - Quad Bus Buffer (DIP14) + 74LS245 - Octal Bus Tranceiver with Tri-State Outputs (DIP20) + 74LS266 - Quad EXCLUSIVE-NOR Gate (DIP14) + 74LS273 - Octal D-Type Flip-Flop With Clear (DIP20) + IDC34 - IDC 34-way flat cable connector for floppy drive data cable + +*/ + +#include "ep64_exdos.h" + + + +//************************************************************************** +// MACROS/CONSTANTS +//************************************************************************** + +#define WD1770_TAG "u1" + + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +const device_type EP64_EXDOS = &device_creator; + + +//------------------------------------------------- +// ROM( ep64_exdos ) +//------------------------------------------------- + +ROM_START( ep64_exdos ) + ROM_REGION( 0x8000, "rom", 0 ) + ROM_LOAD( "exdos13.rom", 0x0000, 0x8000, CRC(d1d7e157) SHA1(31c8be089526aa8aa019c380cdf51ddd3ee76454) ) +ROM_END + + +//------------------------------------------------- +// rom_region - device-specific ROM region +//------------------------------------------------- + +const rom_entry *ep64_exdos_device::device_rom_region() const +{ + return ROM_NAME( ep64_exdos ); +} + + +//------------------------------------------------- +// SLOT_INTERFACE( ep64_exdos_floppies ) +//------------------------------------------------- + +FLOPPY_FORMATS_MEMBER( ep64_exdos_device::floppy_formats ) + FLOPPY_EP64_FORMAT +FLOPPY_FORMATS_END + +static SLOT_INTERFACE_START( ep64_exdos_floppies ) + SLOT_INTERFACE( "35dd", FLOPPY_35_DD ) +SLOT_INTERFACE_END + + +//------------------------------------------------- +// MACHINE_CONFIG_FRAGMENT( ep64_exdos ) +//------------------------------------------------- + +static MACHINE_CONFIG_FRAGMENT( ep64_exdos ) + MCFG_WD1770x_ADD(WD1770_TAG, XTAL_8MHz) + + MCFG_FLOPPY_DRIVE_ADD(WD1770_TAG":0", ep64_exdos_floppies, "35dd", ep64_exdos_device::floppy_formats) + MCFG_FLOPPY_DRIVE_ADD(WD1770_TAG":1", ep64_exdos_floppies, NULL, ep64_exdos_device::floppy_formats) + MCFG_FLOPPY_DRIVE_ADD(WD1770_TAG":2", ep64_exdos_floppies, NULL, ep64_exdos_device::floppy_formats) + MCFG_FLOPPY_DRIVE_ADD(WD1770_TAG":3", ep64_exdos_floppies, NULL, ep64_exdos_device::floppy_formats) +MACHINE_CONFIG_END + + +//------------------------------------------------- +// machine_config_additions - device-specific +// machine configurations +//------------------------------------------------- + +machine_config_constructor ep64_exdos_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( ep64_exdos ); +} + + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// ep64_exdos_device - constructor +//------------------------------------------------- + +ep64_exdos_device::ep64_exdos_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, EP64_EXDOS, "EXDOS", tag, owner, clock, "ep64_exdos", __FILE__), + device_ep64_expansion_bus_card_interface(mconfig, *this), + m_fdc(*this, WD1770_TAG), + m_floppy0(*this, WD1770_TAG":0"), + m_floppy1(*this, WD1770_TAG":1"), + m_floppy2(*this, WD1770_TAG":2"), + m_floppy3(*this, WD1770_TAG":3"), + m_floppy(NULL), + m_rom(*this, "rom") +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void ep64_exdos_device::device_start() +{ + m_slot->program().install_rom(0x080000, 0x087fff, 0, 0, m_rom->base()); + + m_slot->io().install_readwrite_handler(0x10, 0x13, 0, 0x04, READ8_DEVICE_DELEGATE(wd_fdc_t, m_fdc, read), WRITE8_DEVICE_DELEGATE(wd_fdc_t, m_fdc, write)); + m_slot->io().install_readwrite_handler(0x18, 0x18, 0, 0x04, READ8_DELEGATE(ep64_exdos_device, read), WRITE8_DELEGATE(ep64_exdos_device, write)); +} + + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void ep64_exdos_device::device_reset() +{ + m_fdc->reset(); + + m_floppy = NULL; + m_fdc->set_floppy(m_floppy); + m_fdc->dden_w(0); +} + + +//------------------------------------------------- +// read - +//------------------------------------------------- + +READ8_MEMBER( ep64_exdos_device::read ) +{ + /* + + bit description + + 0 + 1 INTRQ + 2 + 3 + 4 + 5 + 6 DCHG + 7 DRQ + + */ + + UINT8 data = 0; + + data |= m_fdc->intrq_r(); + data |= m_fdc->drq_r() << 7; + + data |= (m_floppy ? m_floppy->dskchg_r() : 1) << 6; + + return data; +} + + +//------------------------------------------------- +// write - +//------------------------------------------------- + +WRITE8_MEMBER( ep64_exdos_device::write ) +{ + /* + + bit description + + 0 SELECT 0 + 1 SELECT 1 + 2 SELECT 2 + 3 SELECT 3 + 4 SIDE 1 + 5 _DDEN + 6 DISK CHANGE RESET + 7 IN USE + + */ + + m_floppy = NULL; + + if (BIT(data, 0)) m_floppy = m_floppy0->get_device(); + if (BIT(data, 1)) m_floppy = m_floppy1->get_device(); + if (BIT(data, 2)) m_floppy = m_floppy2->get_device(); + if (BIT(data, 3)) m_floppy = m_floppy3->get_device(); + + m_fdc->set_floppy(m_floppy); + + if (m_floppy) + { + m_floppy->ss_w(BIT(data, 4)); + } + + m_fdc->dden_w(BIT(data, 5)); +} diff --git a/src/mess/machine/ep64_exdos.h b/src/mess/machine/ep64_exdos.h new file mode 100644 index 00000000000..18f1561e288 --- /dev/null +++ b/src/mess/machine/ep64_exdos.h @@ -0,0 +1,65 @@ +/********************************************************************** + + Intelligent Software EXDOS Disk Controller Module emulation + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**********************************************************************/ + +#pragma once + +#ifndef __EP64_EXDOS__ +#define __EP64_EXDOS__ + +#include "emu.h" +#include "formats/ep64_dsk.h" +#include "machine/ep64exp.h" +#include "machine/wd_fdc.h" + + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> ep64_exdos_device + +class ep64_exdos_device : public device_t, + public device_ep64_expansion_bus_card_interface +{ +public: + // construction/destruction + ep64_exdos_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // optional information overrides + virtual const rom_entry *device_rom_region() const; + virtual machine_config_constructor device_mconfig_additions() const; + + DECLARE_READ8_MEMBER( read ); + DECLARE_WRITE8_MEMBER( write ); + + DECLARE_FLOPPY_FORMATS( floppy_formats ); + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + +private: + required_device m_fdc; + required_device m_floppy0; + required_device m_floppy1; + required_device m_floppy2; + required_device m_floppy3; + floppy_image_device *m_floppy; + required_memory_region m_rom; +}; + + +// device type definition +extern const device_type EP64_EXDOS; + + + +#endif diff --git a/src/mess/machine/ep64exp.c b/src/mess/machine/ep64exp.c new file mode 100644 index 00000000000..c359cdcc010 --- /dev/null +++ b/src/mess/machine/ep64exp.c @@ -0,0 +1,88 @@ +/********************************************************************** + + Enterprise Sixty Four / One Two Eight Expansion Bus emulation + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**********************************************************************/ + +#include "ep64exp.h" + + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +const device_type EP64_EXPANSION_BUS_SLOT = &device_creator; + + + +//************************************************************************** +// DEVICE EP64_EXPANSION_BUS CARD INTERFACE +//************************************************************************** + +//------------------------------------------------- +// device_ep64_expansion_bus_card_interface - constructor +//------------------------------------------------- + +device_ep64_expansion_bus_card_interface::device_ep64_expansion_bus_card_interface(const machine_config &mconfig, device_t &device) + : device_slot_card_interface(mconfig, device) +{ + m_slot = dynamic_cast(device.owner()); +} + + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// ep64_expansion_bus_slot_device - constructor +//------------------------------------------------- + +ep64_expansion_bus_slot_device::ep64_expansion_bus_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, EP64_EXPANSION_BUS_SLOT, "Enterprise Sixty Four expansion bus slot", tag, owner, clock), + device_slot_interface(mconfig, *this), + m_write_irq(*this), + m_write_nmi(*this), + m_write_wait(*this) +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void ep64_expansion_bus_slot_device::device_start() +{ + m_dave = dynamic_cast(m_owner->subdevice(m_dave_tag)); + m_card = dynamic_cast(get_card_device()); + + // resolve callbacks + m_write_irq.resolve_safe(); + m_write_nmi.resolve_safe(); + m_write_wait.resolve_safe(); +} + + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void ep64_expansion_bus_slot_device::device_reset() +{ + if (m_card) get_card_device()->reset(); +} + + +//------------------------------------------------- +// SLOT_INTERFACE( ep64_expansion_bus_cards ) +//------------------------------------------------- + +SLOT_INTERFACE_START( ep64_expansion_bus_cards ) + SLOT_INTERFACE("exdos", EP64_EXDOS) +SLOT_INTERFACE_END diff --git a/src/mess/machine/ep64exp.h b/src/mess/machine/ep64exp.h new file mode 100644 index 00000000000..8169d1d9eee --- /dev/null +++ b/src/mess/machine/ep64exp.h @@ -0,0 +1,150 @@ +/********************************************************************** + + Enterprise Sixty Four / One Two Eight Expansion Bus emulation + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +********************************************************************** + + LH SOUND IN B1 A1 RH SOUND IN + _WR B2 A2 _RFSH + _IORQ B3 A3 _RD + +17V* B4 A4 +17V* + _NMI B5 A5 _MREQ + A9 B6 A6 A8 + A11 B7 A7 A10 + A13 B8 A8 A12 + A15 B9 A9 A14 + A1 B10 A10 A0 + A3 B11 A11 A2 + A5 B12 A12 A4 + A7 B13 A13 A6 + D1 B14 A14 D0 + D3 B15 A15 D2 + D5 B16 A16 D4 + D7 B17 A17 D6 + _INT B18 A18 _RESET + GND B19 A19 _WAIT + GND B20 A20 _M1 + GND B21 A21 1M + GND B22 A22 phi + GND B23 A23 8M + EC1 B24 A24 EC0 + EC3 B25 A25 EC2 + A16 B26 A26 _EXTC + A18 B27 A27 A17 + A20 B28 A28 A19 + 14M B29 A29 A21 + VSYNC B30 A30 _LOCATE + _EXP B31 A31 GND + GND B32 A32 HSYNC + +9V B33 A33 +9V + +**********************************************************************/ + +#pragma once + +#ifndef __EP64_EXPANSION_BUS__ +#define __EP64_EXPANSION_BUS__ + +#include "emu.h" +#include "audio/dave.h" + + + +//************************************************************************** +// MACROS / CONSTANTS +//************************************************************************** + +#define EP64_EXPANSION_BUS_TAG "exp" + + + +//************************************************************************** +// INTERFACE CONFIGURATION MACROS +//************************************************************************** + +#define MCFG_EP64_EXPANSION_BUS_SLOT_ADD(_tag, _dave_tag, _def_slot) \ + MCFG_DEVICE_ADD(_tag, EP64_EXPANSION_BUS_SLOT, 0) \ + MCFG_DEVICE_SLOT_INTERFACE(ep64_expansion_bus_cards, _def_slot, false) \ + downcast(device)->set_dave_tag(_dave_tag); + +#define MCFG_EP64_EXPANSION_BUS_CALLBACKS(_irq, _nmi, _wait) \ + downcast(device)->set_irq_callback(DEVCB2_##_irq); \ + downcast(device)->set_nmi_callback(DEVCB2_##_nmi); \ + downcast(device)->set_wait_callback(DEVCB2_##_wait); + + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> ep64_expansion_bus_slot_device + +class device_ep64_expansion_bus_card_interface; + +class ep64_expansion_bus_slot_device : public device_t, + public device_slot_interface +{ + friend class device_ep64_expansion_bus_card_interface; + +public: + // construction/destruction + ep64_expansion_bus_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + void set_dave_tag(const char* dave_tag) { m_dave_tag = dave_tag; } + template void set_irq_callback(_irq irq) { m_write_irq.set_callback(irq); } + template void set_nmi_callback(_nmi nmi) { m_write_nmi.set_callback(nmi); } + template void set_wait_callback(_wait wait) { m_write_wait.set_callback(wait); } + + DECLARE_WRITE_LINE_MEMBER( irq_w ) { m_write_irq(state); } + DECLARE_WRITE_LINE_MEMBER( nmi_w ) { m_write_nmi(state); } + DECLARE_WRITE_LINE_MEMBER( wait_w ) { m_write_wait(state); } + + address_space& program() { return m_dave->space(DAVE_AS_PROGRAM); } + address_space& io() { return m_dave->space(DAVE_AS_IO); } + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + +private: + devcb2_write_line m_write_irq; + devcb2_write_line m_write_nmi; + devcb2_write_line m_write_wait; + + const char *m_dave_tag; + dave_device *m_dave; + + device_ep64_expansion_bus_card_interface *m_card; +}; + + +// ======================> device_ep64_expansion_bus_card_interface + +class device_ep64_expansion_bus_card_interface : public device_slot_card_interface +{ +public: + // construction/destruction + device_ep64_expansion_bus_card_interface(const machine_config &mconfig, device_t &device); + +protected: + ep64_expansion_bus_slot_device *m_slot; +}; + + +// device type definition +extern const device_type EP64_EXPANSION_BUS_SLOT; + + +// slot devices +#include "machine/ep64_exdos.h" + +SLOT_INTERFACE_EXTERN( ep64_expansion_bus_cards ); + + + +#endif diff --git a/src/mess/mess.mak b/src/mess/mess.mak index 8608b994c3f..f32bdaf221d 100644 --- a/src/mess/mess.mak +++ b/src/mess/mess.mak @@ -1462,9 +1462,11 @@ $(MESSOBJ)/intel.a: \ $(MESS_DRIVERS)/rex6000.o \ $(MESSOBJ)/intelgnt.a: \ + $(MESS_DRIVERS)/ep64.o \ $(MESS_AUDIO)/dave.o \ - $(MESS_VIDEO)/epnick.o \ - $(MESS_DRIVERS)/enterp.o \ + $(MESS_VIDEO)/nick.o \ + $(MESS_MACHINE)/ep64exp.o \ + $(MESS_MACHINE)/ep64_exdos.o\ $(MESSOBJ)/interton.a: \ $(MESS_AUDIO)/vc4000.o \ diff --git a/src/mess/video/epnick.c b/src/mess/video/nick.c similarity index 68% rename from src/mess/video/epnick.c rename to src/mess/video/nick.c index 33826f12a2c..86b0a75ed71 100644 --- a/src/mess/video/epnick.c +++ b/src/mess/video/nick.c @@ -1,20 +1,21 @@ -/***************************************************************************** - * - * video/epnick.c - * - * Nick Graphics Chip - found in Enterprise - * - * this is a display list graphics chip, with bitmap, - * character and attribute graphics modes. Each entry in the - * display list defines a char line, with variable number of - * scanlines. Colour modes are 2,4, 16 and 256 colour. - * Nick has 256 colours, 3 bits for R and G, with 2 bits for Blue. - * It's a nice and flexible graphics processor.......... - * - ****************************************************************************/ +/********************************************************************** -#include "emu.h" -#include "video/epnick.h" + Intelligent Designs NICK emulation + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**********************************************************************/ + +#include "nick.h" + + + +//************************************************************************** +// MACROS / CONSTANTS +//************************************************************************** + +#define LOG 0 /* colour mode types */ #define NICK_2_COLOUR_MODE 0 @@ -60,40 +61,105 @@ #define ADDR_CH128(x,y) (((x & 0x01ff)<<7) | (y & 0x07f)) #define ADDR_CH64(x,y) (((x & 0x03ff)<<6) | (y & 0x03f)) +/* No of highest resolution pixels per "clock" */ +#define NICK_PIXELS_PER_CLOCK 16 + +/* "clocks" per line */ +#define NICK_TOTAL_CLOCKS_PER_LINE 64 + +/* Enterprise has 256 colours, all may be on the screen at once! + the NICK_GET_RED8, NICK_GET_GREEN8, NICK_GET_BLUE8 macros + return a 8-bit colour value for the index specified. */ + +/* given a colour index in range 0..255 gives the Red component */ +#define NICK_GET_RED8(x) \ + (( \ + (BIT(x, 0) << 2) | \ + (BIT(x, 3) << 1) | \ + (BIT(x, 6) << 0) \ + ) << 5) + +/* given a colour index in range 0..255 gives the Red component */ +#define NICK_GET_GREEN8(x) \ + (( \ + (BIT(x, 1) << 2) | \ + (BIT(x, 4) << 1) | \ + (BIT(x, 7) << 0) \ + ) << 5) + +/* given a colour index in range 0..255 gives the Red component */ +#define NICK_GET_BLUE8(x) \ + (( \ + (BIT(x, 2) << 1) | \ + (BIT(x, 5) << 0) \ + ) << 6) + + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** const device_type NICK = &device_creator; + +DEVICE_ADDRESS_MAP_START( vram_map, 8, nick_device ) + AM_RANGE(0x0000, 0xffff) AM_READWRITE(vram_r, vram_w) +ADDRESS_MAP_END + +DEVICE_ADDRESS_MAP_START( vio_map, 8, nick_device ) + AM_RANGE(0x00, 0x00) AM_WRITE(fixbias_w) + AM_RANGE(0x01, 0x01) AM_WRITE(border_w) + AM_RANGE(0x02, 0x02) AM_WRITE(lpl_w) + AM_RANGE(0x03, 0x03) AM_WRITE(lph_w) +ADDRESS_MAP_END + +static ADDRESS_MAP_START( nick_map, AS_0, 8, nick_device ) + AM_RANGE(0x0000, 0xffff) AM_RAM +ADDRESS_MAP_END + + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + //------------------------------------------------- -// stic_device - constructor +// nick_device - constructor //------------------------------------------------- -nick_device::nick_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : - device_t(mconfig, NICK, "Nick Graphics Chip", tag, owner, clock, "epnick", __FILE__), - m_videoram(NULL) +nick_device::nick_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, NICK, "NICK", tag, owner, clock), + device_memory_interface(mconfig, *this), + m_space_config("vram", ENDIANNESS_LITTLE, 8, 16, 0, *ADDRESS_MAP_NAME(nick_map)), + m_write_virq(*this) { } -//------------------------------------------------- -// ~stic_device - destructor -//------------------------------------------------- - -nick_device::~nick_device() -{ -} - //------------------------------------------------- // device_start - device-specific startup //------------------------------------------------- void nick_device::device_start() { - machine().primary_screen->register_screen_bitmap(m_bitmap); - + screen_device *screen = machine().first_screen(); + + screen->register_screen_bitmap(m_bitmap); calc_visible_clocks(ENTERPRISE_SCREEN_WIDTH); - bitmap_ind16 m_bitmap; - + // initialize palette + for (int i = 0; i < 256; i++) + palette_set_color_rgb(machine(), i, NICK_GET_RED8(i), NICK_GET_GREEN8(i), NICK_GET_BLUE8(i)); + + // resolve callbacks + m_write_virq.resolve_safe(); + + // allocate timers + m_timer_scanline = timer_alloc(); + m_timer_scanline->adjust(screen->time_until_pos(0, 0), 0, screen->scan_period()); + + // state saving save_item(NAME(m_scanline_count)); save_item(NAME(m_FIXBIAS)); save_item(NAME(m_BORDER)); @@ -118,8 +184,15 @@ void nick_device::device_start() } +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + void nick_device::device_reset() -{ +{ + m_write_virq(CLEAR_LINE); + m_virq = 0; + for (int i = 0; i < 256; i++) { int pen_index; @@ -130,9 +203,116 @@ void nick_device::device_reset() pen_index = (BIT(i, 7) << 0) | (BIT(i, 3) << 1) | (BIT(i, 5) << 2) | (BIT(i, 1) << 3); m_pen_idx_16col[i] = pen_index; } - - //m_BORDER = 0; - //m_FIXBIAS = 0; + + m_scanline_count = 0; +} + + +//------------------------------------------------- +// device_timer - handler timer events +//------------------------------------------------- + +void nick_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +{ + int scanline = machine().first_screen()->vpos(); + + if (scanline < ENTERPRISE_SCREEN_HEIGHT) + { + /* set write address for line */ + m_dest = &m_bitmap.pix16(scanline); + m_dest_pos = 0; + m_dest_max_pos = m_bitmap.width(); + + /* write line */ + do_line(); + } +} + + +//------------------------------------------------- +// memory_space_config - return a description of +// any address spaces owned by this device +//------------------------------------------------- + +const address_space_config *nick_device::memory_space_config(address_spacenum spacenum) const +{ + return (spacenum == 0) ? &m_space_config : NULL; +} + + +//------------------------------------------------- +// update_screen - update screen +//------------------------------------------------- + +UINT32 nick_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + copybitmap(bitmap, m_bitmap, 0, 0, 0, 0, cliprect); + + return 0; +} + + +//------------------------------------------------- +// vram_r - video RAM read +//------------------------------------------------- + +READ8_MEMBER( nick_device::vram_r ) +{ + return m_addrspace[0]->read_byte(offset); +} + + +//------------------------------------------------- +// vram_w - video RAM write +//------------------------------------------------- + +WRITE8_MEMBER( nick_device::vram_w ) +{ + m_addrspace[0]->write_byte(offset, data); +} + + +//------------------------------------------------- +// fixbias_w - +//------------------------------------------------- + +WRITE8_MEMBER( nick_device::fixbias_w ) +{ + m_FIXBIAS = data; +} + + +//------------------------------------------------- +// border_w - +//------------------------------------------------- + +WRITE8_MEMBER( nick_device::border_w ) +{ + m_BORDER = data; +} + + +//------------------------------------------------- +// lpl_w - +//------------------------------------------------- + +WRITE8_MEMBER( nick_device::lpl_w ) +{ + m_LPL = m_reg[2] = data; + + update_lpt(); +} + + +//------------------------------------------------- +// lph_w - +//------------------------------------------------- + +WRITE8_MEMBER( nick_device::lph_w ) +{ + m_LPH = m_reg[3] = data; + + update_lpt(); } @@ -146,13 +326,6 @@ void nick_device::write_pixel(int ci) } } - -/* No of highest resolution pixels per "clock" */ -#define NICK_PIXELS_PER_CLOCK 16 - -/* "clocks" per line */ -#define NICK_TOTAL_CLOCKS_PER_LINE 64 - /* we align based on the clocks */ void nick_device::calc_visible_clocks(int width) { @@ -572,10 +745,10 @@ void nick_device::do_pixel(int clocks_visible) for (int i = 0; i < clocks_visible; i++) { - buf1 = fetch_byte(m_LD1); + buf1 = m_addrspace[0]->read_byte(m_LD1); m_LD1++; - buf2 = fetch_byte(m_LD1); + buf2 = m_addrspace[0]->read_byte(m_LD1); m_LD1++; write_pixels(buf1, buf1); @@ -590,7 +763,7 @@ void nick_device::do_lpixel(int clocks_visible) for (int i = 0; i < clocks_visible; i++) { - buf1 = fetch_byte(m_LD1); + buf1 = m_addrspace[0]->read_byte(m_LD1); m_LD1++; write_pixels_lpixel(buf1, buf1); @@ -603,10 +776,10 @@ void nick_device::do_attr(int clocks_visible) for (int i = 0; i < clocks_visible; i++) { - buf1 = fetch_byte(m_LD1); + buf1 = m_addrspace[0]->read_byte(m_LD1); m_LD1++; - buf2 = fetch_byte(m_LD2); + buf2 = m_addrspace[0]->read_byte(m_LD2); m_LD2++; { @@ -624,9 +797,9 @@ void nick_device::do_ch256(int clocks_visible) for (int i = 0; i < clocks_visible; i++) { - buf1 = fetch_byte(m_LD1); + buf1 = m_addrspace[0]->read_byte(m_LD1); m_LD1++; - buf2 = fetch_byte(ADDR_CH256(m_LD2, buf1)); + buf2 = m_addrspace[0]->read_byte(ADDR_CH256(m_LD2, buf1)); write_pixels_lpixel(buf2, buf1); } @@ -638,9 +811,9 @@ void nick_device::do_ch128(int clocks_visible) for (int i = 0; i < clocks_visible; i++) { - buf1 = fetch_byte(m_LD1); + buf1 = m_addrspace[0]->read_byte(m_LD1); m_LD1++; - buf2 = fetch_byte(ADDR_CH128(m_LD2, buf1)); + buf2 = m_addrspace[0]->read_byte(ADDR_CH128(m_LD2, buf1)); write_pixels_lpixel(buf2, buf1); } @@ -652,9 +825,9 @@ void nick_device::do_ch64(int clocks_visible) for (int i = 0; i < clocks_visible; i++) { - buf1 = fetch_byte(m_LD1); + buf1 = m_addrspace[0]->read_byte(m_LD1); m_LD1++; - buf2 = fetch_byte(ADDR_CH64(m_LD2, buf1)); + buf2 = m_addrspace[0]->read_byte(ADDR_CH64(m_LD2, buf1)); write_pixels_lpixel(buf2, buf1); } @@ -777,22 +950,22 @@ void nick_device::reload_lpt() UINT32 LPT_Addr = ((m_LPL & 0x0ff) << 4) | ((m_LPH & 0x0f) << (8+4)); /* update internal LPT state */ - m_LPT.SC = fetch_byte(LPT_Addr); - m_LPT.MB = fetch_byte(LPT_Addr + 1); - m_LPT.LM = fetch_byte(LPT_Addr + 2); - m_LPT.RM = fetch_byte(LPT_Addr + 3); - m_LPT.LD1L = fetch_byte(LPT_Addr + 4); - m_LPT.LD1H = fetch_byte(LPT_Addr + 5); - m_LPT.LD2L = fetch_byte(LPT_Addr + 6); - m_LPT.LD2H = fetch_byte(LPT_Addr + 7); - m_LPT.COL[0] = fetch_byte(LPT_Addr + 8); - m_LPT.COL[1] = fetch_byte(LPT_Addr + 9); - m_LPT.COL[2] = fetch_byte(LPT_Addr + 10); - m_LPT.COL[3] = fetch_byte(LPT_Addr + 11); - m_LPT.COL[4] = fetch_byte(LPT_Addr + 12); - m_LPT.COL[5] = fetch_byte(LPT_Addr + 13); - m_LPT.COL[6] = fetch_byte(LPT_Addr + 14); - m_LPT.COL[7] = fetch_byte(LPT_Addr + 15); + m_LPT.SC = m_addrspace[0]->read_byte(LPT_Addr); + m_LPT.MB = m_addrspace[0]->read_byte(LPT_Addr + 1); + m_LPT.LM = m_addrspace[0]->read_byte(LPT_Addr + 2); + m_LPT.RM = m_addrspace[0]->read_byte(LPT_Addr + 3); + m_LPT.LD1L = m_addrspace[0]->read_byte(LPT_Addr + 4); + m_LPT.LD1H = m_addrspace[0]->read_byte(LPT_Addr + 5); + m_LPT.LD2L = m_addrspace[0]->read_byte(LPT_Addr + 6); + m_LPT.LD2H = m_addrspace[0]->read_byte(LPT_Addr + 7); + m_LPT.COL[0] = m_addrspace[0]->read_byte(LPT_Addr + 8); + m_LPT.COL[1] = m_addrspace[0]->read_byte(LPT_Addr + 9); + m_LPT.COL[2] = m_addrspace[0]->read_byte(LPT_Addr + 10); + m_LPT.COL[3] = m_addrspace[0]->read_byte(LPT_Addr + 11); + m_LPT.COL[4] = m_addrspace[0]->read_byte(LPT_Addr + 12); + m_LPT.COL[5] = m_addrspace[0]->read_byte(LPT_Addr + 13); + m_LPT.COL[6] = m_addrspace[0]->read_byte(LPT_Addr + 14); + m_LPT.COL[7] = m_addrspace[0]->read_byte(LPT_Addr + 15); } /* call here to render a line of graphics */ @@ -800,6 +973,16 @@ void nick_device::do_line() { UINT8 scanline; + m_write_virq((m_LPT.MB & NICK_MB_VIRQ) ? ASSERT_LINE : CLEAR_LINE); + + if (m_virq && !(m_LPT.MB & NICK_MB_VIRQ)) + { + screen_device *screen = machine().first_screen(); + m_timer_scanline->adjust(screen->time_until_pos(0, 0), 0, screen->scan_period()); + } + + m_virq = (m_LPT.MB & NICK_MB_VIRQ) ? 1 : 0; + if ((m_LPT.MB & NICK_MB_LPT_RELOAD)!=0) { /* reload LPT */ @@ -838,65 +1021,3 @@ void nick_device::do_line() reload_lpt(); } } - -WRITE8_MEMBER( nick_device::reg_w ) -{ - //mame_printf_info("Nick write %02x %02x\r\n",offset, data); - - /* write to a nick register */ - m_reg[offset & 0x0f] = data; - - if ((offset == 0x03) || (offset == 0x02)) - { - /* write LPH */ - - /* reload LPT base? */ - //if (NICK_RELOAD_LPT(data)) - { - /* reload LPT base pointer */ - m_LPL = m_reg[2]; - m_LPH = m_reg[3]; - - reload_lpt(); - } - } - - if (offset == 0x01) - { - m_BORDER = data; - } - - if (offset == 0x00) - { - m_FIXBIAS = data; - } -} - -void nick_device::do_screen(bitmap_ind16 &bm) -{ - int line = 0; - - do - { - /* set write address for line */ - m_dest = &bm.pix16(line); - m_dest_pos = 0; - m_dest_max_pos = bm.width(); - - /* write line */ - do_line(); - - /* next line */ - line++; - } - while (((m_LPT.MB & 0x080) == 0) && (line < ENTERPRISE_SCREEN_HEIGHT)); - -} - - -UINT32 nick_device::screen_update_epnick(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) -{ - do_screen(m_bitmap); - copybitmap(bitmap, m_bitmap, 0, 0, 0, 0, cliprect); - return 0; -} diff --git a/src/mess/video/epnick.h b/src/mess/video/nick.h similarity index 54% rename from src/mess/video/epnick.h rename to src/mess/video/nick.h index 0361097bee9..ebde5de0f88 100644 --- a/src/mess/video/epnick.h +++ b/src/mess/video/nick.h @@ -1,6 +1,35 @@ -#ifndef __EPNICK_H__ -#define __EPNICK_H__ +/********************************************************************** + Intelligent Designs NICK emulation + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**********************************************************************/ + +#pragma once + +#ifndef __NICK__ +#define __NICK__ + +#include "emu.h" + + + +///************************************************************************* +// INTERFACE CONFIGURATION MACROS +///************************************************************************* + +#define MCFG_NICK_ADD(_tag, _screen_tag, _clock, _virq) \ + MCFG_SCREEN_ADD(_screen_tag, RASTER) \ + MCFG_SCREEN_REFRESH_RATE(50) \ + MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) \ + MCFG_SCREEN_SIZE(ENTERPRISE_SCREEN_WIDTH, ENTERPRISE_SCREEN_HEIGHT) \ + MCFG_SCREEN_VISIBLE_AREA(0, ENTERPRISE_SCREEN_WIDTH-1, 0, ENTERPRISE_SCREEN_HEIGHT-1) \ + MCFG_SCREEN_UPDATE_DEVICE(_tag, nick_device, screen_update) \ + MCFG_DEVICE_ADD(_tag, NICK, _clock) \ + downcast(device)->set_virq_callback(DEVCB2_##_virq); \ + MCFG_PALETTE_LENGTH(256) /* there are 64us per line, although in reality @@ -12,6 +41,9 @@ #define ENTERPRISE_SCREEN_HEIGHT (35*8) +///************************************************************************* +// TYPE DEFINITIONS +///************************************************************************* /* Nick executes a Display list, in the form of a list of Line Parameter Tables, this is the form of the data */ @@ -29,24 +61,44 @@ struct LPT_ENTRY }; -class nick_device : public device_t +// ======================> nick_device + +class nick_device : public device_t, + public device_memory_interface { public: + // construction/destruction nick_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - virtual ~nick_device(); - void set_vram(UINT8 *vram) { m_videoram = vram; } - DECLARE_WRITE8_MEMBER(reg_w); + template void set_virq_callback(_virq virq) { m_write_virq.set_callback(virq); } - UINT32 screen_update_epnick(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + virtual DECLARE_ADDRESS_MAP(vram_map, 8); + virtual DECLARE_ADDRESS_MAP(vio_map, 8); + + UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); protected: // device-level overrides virtual void device_start(); virtual void device_reset(); + virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); + + // device_memory_interface overrides + virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const; + + DECLARE_READ8_MEMBER( vram_r ); + DECLARE_WRITE8_MEMBER( vram_w ); + + DECLARE_WRITE8_MEMBER( fixbias_w ); + DECLARE_WRITE8_MEMBER( border_w ); + DECLARE_WRITE8_MEMBER( lpl_w ); + DECLARE_WRITE8_MEMBER( lph_w ); + + address_space_config m_space_config; private: - inline UINT8 fetch_byte(UINT32 offs) { return m_videoram[offs & 0x0ffff]; } + devcb2_write_line m_write_virq; + void write_pixel(int ci); void calc_visible_clocks(int width); void init(); @@ -70,9 +122,6 @@ private: void update_lpt(); void reload_lpt(); void do_line(); - void do_screen(bitmap_ind16 &bm); - - bitmap_ind16 m_bitmap; /* horizontal position */ UINT8 horizontal_clock; @@ -104,22 +153,18 @@ private: UINT8 m_pen_idx_4col[256]; /* given a bit pattern, this will get the pen index */ UINT8 m_pen_idx_16col[256]; - - UINT8 *m_videoram; -}; + int m_virq; + + bitmap_ind16 m_bitmap; + + emu_timer *m_timer_scanline; +}; // device type definition extern const device_type NICK; -/*************************************************************************** - DEVICE CONFIGURATION MACROS - ***************************************************************************/ - -#define MCFG_NICK_ADD(_tag) \ - MCFG_DEVICE_ADD(_tag, NICK, 0) - #endif