diff options
Diffstat (limited to 'src/mame/drivers/mindset.cpp')
-rw-r--r-- | src/mame/drivers/mindset.cpp | 564 |
1 files changed, 417 insertions, 147 deletions
diff --git a/src/mame/drivers/mindset.cpp b/src/mame/drivers/mindset.cpp index 22bb020e444..d8fafdf6f8f 100644 --- a/src/mame/drivers/mindset.cpp +++ b/src/mame/drivers/mindset.cpp @@ -7,12 +7,172 @@ #include "imagedev/floppy.h" #include "machine/upd765.h" #include "formats/pc_dsk.h" +#include "sound/dac.h" +#include "sound/volt_reg.h" #include "screen.h" #include "speaker.h" #include "mindset.lh" + +class mindset_module_interface: public device_t { +public: + virtual void map(address_map &map) = 0; + +protected: + mindset_module_interface(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); +}; + +mindset_module_interface::mindset_module_interface(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, type, tag, owner, clock) +{ +} + +class mindset_module: public device_t, + public device_slot_interface +{ +public: + template <typename T> + mindset_module(const machine_config &mconfig, const char *tag, device_t *owner, T &&opts, const char *dflt, bool fixed = false) + : mindset_module(mconfig, tag, owner, 0) + { + option_reset(); + opts(*this); + set_default_option(dflt); + set_fixed(fixed); + } + mindset_module(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); + virtual ~mindset_module() = default; + + void map(address_space &space, offs_t base); + +protected: + virtual void device_validity_check(validity_checker &valid) const override; + virtual void device_start() override; +}; + +DEFINE_DEVICE_TYPE(MINDSET_MODULE, mindset_module, "mindset_module", "MINDSET module") + +mindset_module::mindset_module(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, MINDSET_MODULE, tag, owner, clock), + device_slot_interface(mconfig, *this) +{ +} + +void mindset_module::device_validity_check(validity_checker &valid) const +{ + device_t *const carddev = get_card_device(); + if (carddev && !dynamic_cast<mindset_module_interface *>(carddev)) + osd_printf_error("Card device %s (%s) does not implement mindset_module_interface\n", carddev->tag(), carddev->name()); +} + +void mindset_module::device_start() +{ +} + +void mindset_module::map(address_space &space, offs_t base) +{ + mindset_module_interface *module = dynamic_cast<mindset_module_interface *>(get_card_device()); + if(module) + space.install_device(base, base+0x3f, *module, &mindset_module_interface::map); +} + + +class mindset_sound_module: public mindset_module_interface { +public: + mindset_sound_module(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); + virtual ~mindset_sound_module() = default; + + virtual void map(address_map &map) override; + +protected: + virtual const tiny_rom_entry *device_rom_region() const override; + virtual void device_add_mconfig(machine_config &config) override; + virtual void device_start() override; + virtual void device_reset() override; + +private: + u8 m_p1, m_p2; + + required_device<i8042_device> m_soundcpu; + required_device<dac_byte_interface> m_dac; + + void p1_w(u8 data); + void p2_w(u8 data); + void update_dac(); +}; + +DEFINE_DEVICE_TYPE(MINDSET_SOUND_MODULE, mindset_sound_module, "mindset_sound_module", "MINDSET stereo sound module") + +mindset_sound_module::mindset_sound_module(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + mindset_module_interface(mconfig, MINDSET_SOUND_MODULE, tag, owner, clock), + m_soundcpu(*this, "soundcpu"), + m_dac(*this, "dac") +{ +} + +void mindset_sound_module::device_start() +{ + save_item(NAME(m_p1)); + save_item(NAME(m_p2)); +} + +void mindset_sound_module::device_reset() +{ + m_p1 = 0x80; + m_p2 = 0; + m_dac->write(0x80); +} + +void mindset_sound_module::update_dac() +{ + // The p1 dac has the waveform (idle at 0x80), while the p2 one is used for the global volume (mute at 0x00, max at 0xff) + m_dac->write((s8(m_p1-0x80)*m_p2/255 + 0x80) & 0xff); +} + +void mindset_sound_module::p1_w(u8 data) +{ + m_p1 = data; + update_dac(); +} + +void mindset_sound_module::p2_w(u8 data) +{ + m_p2 = data; + update_dac(); +} + +void mindset_sound_module::map(address_map &map) +{ + map(0x00, 0x03).rw(m_soundcpu, FUNC(i8042_device::upi41_master_r), FUNC(i8042_device::upi41_master_w)).umask16(0x00ff); + map(0x00, 0x00).lr8("id", []() -> u8 { return 0x13; }); +} + +ROM_START(mindset_sound_module) + ROM_REGION(0x0800, "soundcpu", 0) + ROM_LOAD("253006-001.u16", 0, 0x800, CRC(7bea5edd) SHA1(30cdc0dedaa5246f4952df452a99ca22e3cd0636)) +ROM_END + +const tiny_rom_entry *mindset_sound_module::device_rom_region() const +{ + return ROM_NAME(mindset_sound_module); +} + +void mindset_sound_module::device_add_mconfig(machine_config &config) +{ + I8042(config, m_soundcpu, 12_MHz_XTAL/2); + m_soundcpu->p1_out_cb().set(FUNC(mindset_sound_module::p1_w)); + m_soundcpu->p2_out_cb().set(FUNC(mindset_sound_module::p2_w)); + + SPEAKER(config, "rspeaker").front_right(); + DAC_8BIT_R2R(config, m_dac, 0).add_route(ALL_OUTPUTS, "rspeaker", 0.5); + voltage_regulator_device &vref(VOLTAGE_REGULATOR(config, "vref")); + vref.add_route(0, m_dac, 1.0, DAC_VREF_POS_INPUT); + vref.add_route(0, m_dac, -1.0, DAC_VREF_NEG_INPUT); +} + + class mindset_state: public driver_device { public: @@ -36,30 +196,32 @@ protected: output_finder<> m_red_led; output_finder<> m_yellow_led; output_finder<> m_green_led; + required_device<dac_byte_interface> m_dac; + required_device_array<mindset_module, 6> m_modules; - memory_access_cache<1, 0, ENDIANNESS_LITTLE> *m_gcos; + memory_access_cache<1, 0, ENDIANNESS_LITTLE> *m_gcps; floppy_image_device *m_floppy[2]; u32 m_palette[16]; bool m_genlock[16]; u16 m_dispctrl, m_screenpos, m_intpos, m_intaddr, m_fdc_dma_count; - u8 m_kbd_p1, m_kbd_p2, m_borderidx; + u8 m_kbd_p1, m_kbd_p2, m_borderidx, m_snd_p1, m_snd_p2; u8 m_mouse_last_read[2], m_mouse_counter[2]; bool m_fdc_intext, m_fdc_int, m_fdc_drq, m_trap_int, m_trap_drq; u16 m_trap_data[8]; u32 m_trap_pos, m_trap_len; - static u16 gco_blend_0(u16, u16); - static u16 gco_blend_1(u16, u16); - static u16 gco_blend_2(u16, u16); - static u16 gco_blend_3(u16, u16); - static u16 gco_blend_4(u16, u16); - static u16 gco_blend_5(u16, u16); - static u16 gco_blend_6(u16, u16); - static u16 gco_blend_7(u16, u16); + static u16 gcp_blend_0(u16, u16); + static u16 gcp_blend_1(u16, u16); + static u16 gcp_blend_2(u16, u16); + static u16 gcp_blend_3(u16, u16); + static u16 gcp_blend_4(u16, u16); + static u16 gcp_blend_5(u16, u16); + static u16 gcp_blend_6(u16, u16); + static u16 gcp_blend_7(u16, u16); - static u16 (*const gco_blend[8])(u16, u16); + static u16 (*const gcp_blend[8])(u16, u16); static inline u16 msk(int bit) { return (1U << bit) - 1; } static inline u16 sw(u16 data) { return (data >> 8) | (data << 8); } @@ -70,7 +232,7 @@ protected: void display_mode(); void blit(u16 packet_seg, u16 packet_adr); - void gco_w(u16); + void gcp_w(u16); u16 dispctrl_r(); void dispctrl_w(u16 data); u16 dispreg_r(); @@ -106,6 +268,7 @@ protected: template<int floppy> void floppy_led_cb(floppy_image_device *, int state); u16 keyscan(); + void update_dac(); u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); @@ -137,7 +300,9 @@ mindset_state::mindset_state(const machine_config &mconfig, device_type type, co m_floppy_leds(*this, "drive%u_led", 0U), m_red_led(*this, "red_led"), m_yellow_led(*this, "yellow_led"), - m_green_led(*this, "green_led") + m_green_led(*this, "green_led"), + m_dac(*this, "dac"), + m_modules(*this, "m%d", 0U) { } @@ -153,7 +318,7 @@ void mindset_state::machine_start() m_yellow_led.resolve(); m_green_led.resolve(); - m_gcos = m_maincpu->space(AS_PROGRAM).cache<1, 0, ENDIANNESS_LITTLE>(); + m_gcps = m_maincpu->space(AS_PROGRAM).cache<1, 0, ENDIANNESS_LITTLE>(); for(int i=0; i<2; i++) m_floppy[i] = m_fdco[i]->get_device(); @@ -182,10 +347,17 @@ void mindset_state::machine_start() save_item(NAME(m_borderidx)); save_item(NAME(m_mouse_last_read)); save_item(NAME(m_mouse_counter)); + save_item(NAME(m_snd_p1)); + save_item(NAME(m_snd_p2)); } void mindset_state::machine_reset() { + auto &space = m_maincpu->space(AS_IO); + space.unmap_readwrite(0x8080, 0x81ff); + for(int i=0; i<6; i++) + m_modules[i]->map(space, 0x8080 + 0x40*i); + m_fdc_intext = m_fdc_int = m_trap_int = m_fdc_drq = m_trap_drq = false; m_trap_pos = m_trap_len = 0; memset(m_trap_data, 0, sizeof(m_trap_data)); @@ -195,6 +367,9 @@ void mindset_state::machine_reset() m_kbd_p1 = m_kbd_p2 = m_borderidx = 0; memset(m_mouse_last_read, 0, sizeof(m_mouse_last_read)); memset(m_mouse_counter, 0, sizeof(m_mouse_counter)); + m_snd_p1 = 0x80; + m_snd_p2 = 0; + m_dac->write(0x80); } int mindset_state::sys_t0_r() @@ -231,10 +406,10 @@ void mindset_state::sys_p2_w(u8 data) { m_maincpu->int3_w(!(data & 0x80)); m_red_led = !BIT(data, 2); - m_yellow_led = !BIT(data, 1); - m_green_led = !BIT(data, 0); + m_yellow_led = !BIT(data, 0); + m_green_led = !BIT(data, 1); // logerror("power %s\n", data & 0x40 ? - // logerror("SYS: write p2 %02x\n", data); + logerror("SYS: write p2 %02x\n", data); } void mindset_state::kbd_p1_w(u8 data) @@ -259,15 +434,22 @@ int mindset_state::kbd_t1_r() return keyscan() & 0x100; } +void mindset_state::update_dac() +{ + // The p1 dac has the waveform (idle at 0x80), while the p2 one is used for the global volume (mute at 0x00, max at 0xff) + m_dac->write((s8(m_snd_p1-0x80)*m_snd_p2/255 + 0x80) & 0xff); +} + void mindset_state::snd_p1_w(u8 data) { - if(data != 0x80) - logerror("snd p1 %02x\n", data); + m_snd_p1 = data; + update_dac(); } void mindset_state::snd_p2_w(u8 data) { - // logerror("snd p2 %02x\n", data); + m_snd_p2 = data; + update_dac(); } u16 mindset_state::keyscan() @@ -425,7 +607,6 @@ u32 mindset_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, co int dx = ((m_screenpos >> 8) & 15) * (751 - 640) / 15; int dy = ((m_screenpos >> 12) & 15) * (480 - 400) / 15; - if(ibm_mode) { if(large_pixels) { static int palind[4] = { 0, 1, 4, 5 }; @@ -470,17 +651,18 @@ u32 mindset_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, co if(!interleave) { switch(pixels_per_byte_order) { case 0: { - for(int field=0; field<2; field++) { - const u16 *src = bank; - for(u32 y=0; y<200; y++) { - u32 *dest = &bitmap.pix32(2*y+field+dy, dx); - for(u32 x=0; x<320; x+=4) { - u16 sv = sw(*src++); - for(u32 xx=0; xx<4; xx++) { - u32 color = m_palette[(sv >> (12-4*xx)) & 15]; - *dest++ = color; - *dest++ = color; - } + const u16 *src = bank; + for(u32 y=0; y<200; y++) { + u32 *dest0 = &bitmap.pix32(2*y+dy, dx); + u32 *dest1 = &bitmap.pix32(2*y+1+dy, dx); + for(u32 x=0; x<320; x+=4) { + u16 sv = sw(*src++); + for(u32 xx=0; xx<4; xx++) { + u32 color = m_palette[(sv >> (12-4*xx)) & 15]; + *dest0++ = color; + *dest0++ = color; + *dest1++ = color; + *dest1++ = color; } } } @@ -488,34 +670,70 @@ u32 mindset_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, co } case 1: { static int palind[4] = { 0, 1, 4, 5 }; - for(int field=0; field<2; field++) { - const u16 *src = bank; - for(u32 y=0; y<200; y++) { - u32 *dest = &bitmap.pix32(2*y+field+dy, dx); - for(u32 x=0; x<320; x+=8) { - u16 sv = sw(*src++); - for(u32 xx=0; xx<8; xx++) { - u32 color = m_palette[palind[(sv >> (14-2*xx)) & 3]]; - *dest++ = color; - *dest++ = color; - } + const u16 *src = bank; + for(u32 y=0; y<200; y++) { + u32 *dest0 = &bitmap.pix32(2*y+dy, dx); + u32 *dest1 = &bitmap.pix32(2*y+1+dy, dx); + for(u32 x=0; x<320; x+=8) { + u16 sv = sw(*src++); + for(u32 xx=0; xx<8; xx++) { + u32 color = m_palette[palind[(sv >> (14-2*xx)) & 3]]; + *dest0++ = color; + *dest0++ = color; + *dest1++ = color; + *dest1++ = color; } } } return 0; } case 2: { - for(int field=0; field<2; field++) { - const u16 *src = bank; - for(u32 y=0; y<200; y++) { - u32 *dest = &bitmap.pix32(2*y+field+dy, dx); - for(u32 x=0; x<320; x+=16) { - u16 sv = sw(*src++); - for(u32 xx=0; xx<16; xx++) { - u32 color = m_palette[(sv >> (15-xx)) & 1]; - *dest++ = color; - *dest++ = color; - } + const u16 *src = bank; + for(u32 y=0; y<200; y++) { + u32 *dest0 = &bitmap.pix32(2*y+dy, dx); + u32 *dest1 = &bitmap.pix32(2*y+1+dy, dx); + for(u32 x=0; x<320; x+=16) { + u16 sv = sw(*src++); + for(u32 xx=0; xx<16; xx++) { + u32 color = m_palette[(sv >> (15-xx)) & 1]; + *dest0++ = color; + *dest0++ = color; + *dest1++ = color; + *dest1++ = color; + } + } + } + return 0; + } + } + } else { + switch(pixels_per_byte_order) { + case 0: { + const u16 *src = bank; + for(u32 y=0; y<400; y++) { + u32 *dest = &bitmap.pix32(y+dy, dx); + for(u32 x=0; x<320; x+=4) { + u16 sv = sw(*src++); + for(u32 xx=0; xx<4; xx++) { + u32 color = m_palette[(sv >> (12-4*xx)) & 15]; + *dest++ = color; + *dest++ = color; + } + } + } + return 0; + } + case 1: { + static int palind[4] = { 0, 1, 4, 5 }; + const u16 *src = bank; + for(u32 y=0; y<400; y++) { + u32 *dest = &bitmap.pix32(y+dy, dx); + for(u32 x=0; x<320; x+=8) { + u16 sv = sw(*src++); + for(u32 xx=0; xx<8; xx++) { + u32 color = m_palette[palind[(sv >> (14-2*xx)) & 3]]; + *dest++ = color; + *dest++ = color; } } } @@ -528,17 +746,16 @@ u32 mindset_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, co switch(pixels_per_byte_order) { case 0: { static int palind[4] = { 0, 4, 8, 12 }; - for(int field=0; field<2; field++) { - m_palette[1] = 0xffffff; - const u16 *src = bank; - for(u32 y=0; y<200; y++) { - u32 *dest = &bitmap.pix32(2*y+field+dy, dx); - for(u32 x=0; x<640; x+=8) { - u16 sv = sw(*src++); - for(u32 xx=0; xx<8; xx++) { - u32 color = m_palette[palind[(sv >> (14-2*xx)) & 3]]; - *dest++ = color; - } + const u16 *src = bank; + for(u32 y=0; y<200; y++) { + u32 *dest0 = &bitmap.pix32(2*y+dy, dx); + u32 *dest1 = &bitmap.pix32(2*y+1+dy, dx); + for(u32 x=0; x<640; x+=8) { + u16 sv = sw(*src++); + for(u32 xx=0; xx<8; xx++) { + u32 color = m_palette[palind[(sv >> (14-2*xx)) & 3]]; + *dest0++ = color; + *dest1++ = color; } } } @@ -546,22 +763,36 @@ u32 mindset_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, co } case 1: { static int palind[4] = { 0, 4 }; - for(int field=0; field<2; field++) { - const u16 *src = bank; - for(u32 y=0; y<200; y++) { - u32 *dest = &bitmap.pix32(2*y+field+dy, dx); - for(u32 x=0; x<640; x+=16) { - u16 sv = sw(*src++); - for(u32 xx=0; xx<16; xx++) { - u32 color = m_palette[palind[(sv >> (15-xx)) & 1]]; - *dest++ = color; - } + const u16 *src = bank; + for(u32 y=0; y<200; y++) { + u32 *dest0 = &bitmap.pix32(2*y+dy, dx); + u32 *dest1 = &bitmap.pix32(2*y+1+dy, dx); + for(u32 x=0; x<640; x+=16) { + u16 sv = sw(*src++); + for(u32 xx=0; xx<16; xx++) { + u32 color = m_palette[palind[(sv >> (15-xx)) & 1]]; + *dest0++ = color; + *dest1++ = color; } } } return 0; } } + } else { + static int palind[4] = { 0, 4 }; + const u16 *src = bank; + for(u32 y=0; y<400; y++) { + u32 *dest = &bitmap.pix32(y+dy, dx); + for(u32 x=0; x<640; x+=16) { + u16 sv = sw(*src++); + for(u32 xx=0; xx<16; xx++) { + u32 color = m_palette[palind[(sv >> (15-xx)) & 1]]; + *dest++ = color; + } + } + } + return 0; } } @@ -573,104 +804,123 @@ u32 mindset_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, co return 0; } -u16 mindset_state::gco_blend_0(u16 src, u16) +u16 mindset_state::gcp_blend_0(u16 src, u16) { return src; } -u16 mindset_state::gco_blend_1(u16 src, u16 dst) +u16 mindset_state::gcp_blend_1(u16 src, u16 dst) { return src & dst; } -u16 mindset_state::gco_blend_2(u16 src, u16 dst) +u16 mindset_state::gcp_blend_2(u16 src, u16 dst) { return src | dst; } -u16 mindset_state::gco_blend_3(u16 src, u16 dst) +u16 mindset_state::gcp_blend_3(u16 src, u16 dst) { return src ^ dst; } -u16 mindset_state::gco_blend_4(u16 src, u16) +u16 mindset_state::gcp_blend_4(u16 src, u16) { return ~src; } -u16 mindset_state::gco_blend_5(u16 src, u16 dst) +u16 mindset_state::gcp_blend_5(u16 src, u16 dst) { return (~src) & dst; } -u16 mindset_state::gco_blend_6(u16 src, u16 dst) +u16 mindset_state::gcp_blend_6(u16 src, u16 dst) { return (~src) | dst; } -u16 mindset_state::gco_blend_7(u16 src, u16 dst) +u16 mindset_state::gcp_blend_7(u16 src, u16 dst) { return (~src) ^ dst; } -u16 (*const mindset_state::gco_blend[8])(u16, u16) = { - gco_blend_0, - gco_blend_1, - gco_blend_2, - gco_blend_3, - gco_blend_4, - gco_blend_5, - gco_blend_6, - gco_blend_7 +u16 (*const mindset_state::gcp_blend[8])(u16, u16) = { + gcp_blend_0, + gcp_blend_1, + gcp_blend_2, + gcp_blend_3, + gcp_blend_4, + gcp_blend_5, + gcp_blend_6, + gcp_blend_7 }; void mindset_state::blit(u16 packet_seg, u16 packet_adr) { - u16 mode = sw(m_gcos->read_word((packet_seg << 4) + ((packet_adr + 0) & 0xffff))); - u16 src_adr = sw(m_gcos->read_word((packet_seg << 4) + ((packet_adr + 2) & 0xffff))); - u16 src_sft = sw(m_gcos->read_word((packet_seg << 4) + ((packet_adr + 4) & 0xffff))); - u16 dst_adr = sw(m_gcos->read_word((packet_seg << 4) + ((packet_adr + 6) & 0xffff))); - u16 dst_sft = sw(m_gcos->read_word((packet_seg << 4) + ((packet_adr + 8) & 0xffff))); - u16 width = sw(m_gcos->read_word((packet_seg << 4) + ((packet_adr + 10) & 0xffff))); - u16 height = sw(m_gcos->read_word((packet_seg << 4) + ((packet_adr + 12) & 0xffff))); - u16 sy = sw(m_gcos->read_word((packet_seg << 4) + ((packet_adr + 14) & 0xffff))); - u16 dy = sw(m_gcos->read_word((packet_seg << 4) + ((packet_adr + 16) & 0xffff))); - u16 rmask = sw(m_gcos->read_word((packet_seg << 4) + ((packet_adr + 18) & 0xffff))); - u16 src_seg = sw(m_gcos->read_word((packet_seg << 4) + ((packet_adr + 20) & 0xffff))); - u16 dst_seg = sw(m_gcos->read_word((packet_seg << 4) + ((packet_adr + 22) & 0xffff))); - u16 wmask = sw(m_gcos->read_word((packet_seg << 4) + ((packet_adr + 24) & 0xffff))); - u16 kmask = sw(m_gcos->read_word((packet_seg << 4) + ((packet_adr + 26) & 0xffff))); + u16 mode = sw(m_gcps->read_word((packet_seg << 4) + ((packet_adr + 0) & 0xffff))); + u16 src_adr = sw(m_gcps->read_word((packet_seg << 4) + ((packet_adr + 2) & 0xffff))); + u16 src_sft = sw(m_gcps->read_word((packet_seg << 4) + ((packet_adr + 4) & 0xffff))); + u16 dst_adr = sw(m_gcps->read_word((packet_seg << 4) + ((packet_adr + 6) & 0xffff))); + u16 dst_sft = sw(m_gcps->read_word((packet_seg << 4) + ((packet_adr + 8) & 0xffff))); + u16 width = sw(m_gcps->read_word((packet_seg << 4) + ((packet_adr + 10) & 0xffff))); + u16 height = sw(m_gcps->read_word((packet_seg << 4) + ((packet_adr + 12) & 0xffff))); + u16 sy = sw(m_gcps->read_word((packet_seg << 4) + ((packet_adr + 14) & 0xffff))); + u16 dy = sw(m_gcps->read_word((packet_seg << 4) + ((packet_adr + 16) & 0xffff))); + u16 rmask = sw(m_gcps->read_word((packet_seg << 4) + ((packet_adr + 18) & 0xffff))); + u16 src_seg = sw(m_gcps->read_word((packet_seg << 4) + ((packet_adr + 20) & 0xffff))); + u16 dst_seg = sw(m_gcps->read_word((packet_seg << 4) + ((packet_adr + 22) & 0xffff))); + u16 wmask = sw(m_gcps->read_word((packet_seg << 4) + ((packet_adr + 24) & 0xffff))); + u16 kmask = sw(m_gcps->read_word((packet_seg << 4) + ((packet_adr + 26) & 0xffff))); + + // -f-w wnpi ktxm mm-- + // f = fast (pure word copy) + // w = pixel width (1/2/4/8 bits) + // n = invert collision flag (unimplemented) + // p = pattern fill (used by fill_dest_buffer) + // i/f = increment source / don't (used by blt_copy_word) + // t/o = transparent/opaque + // k = detect collision (unimplemented) + // x = go right to left (unimplemented) + // m = blending mode + if(1) - logerror("GCO: p src %04x:%04x.%x dst %04x:%04x.%x sz %xx%x step %x:%x mask %04x:%04x k %x:%x mode %c%c%c%d%c%d%c%c%c\n", src_seg, src_adr, src_sft, dst_seg, dst_adr, dst_sft, width, height, sy, dy, rmask, wmask, (kmask >> 8) & 15, kmask & 15, - mode & 0x80 ? 'k' : '-', - mode & 0x40 ? 't' : 'o', - mode & 0x20 ? 'x' : '-', - (mode >> 2) & 7, + logerror("GCP: p src %04x:%04x.%x dst %04x:%04x.%x sz %xx%x step %x:%x mask %04x:%04x k %x:%x mode %c%d%c%c%c%c%c%c%d\n", src_seg, src_adr, src_sft, dst_seg, dst_adr, dst_sft, width, height, sy, dy, rmask, wmask, (kmask >> 8) & 15, kmask & 15, mode & 0x4000 ? 'f' : '-', (mode >> 11) & 3, mode & 0x400 ? 'n' : '-', mode & 0x200 ? 'p' : '-', - mode & 0x100 ? 'i' : 'f'); - - // k = detect collision (unimplemented) - // t/o = transparent/opaque - // x = go right to left (unimplemented) - // f = fast (no idea what it means) - // n = invert collision flag (unimplemented) - // p = pattern fill (used by fill_dest_buffer) - // i/f = increment source / don't (used by blt_copy_word) + mode & 0x100 ? 'i' : 'f', + mode & 0x80 ? 'k' : '-', + mode & 0x40 ? 't' : 'o', + mode & 0x20 ? 'x' : '-', + (mode >> 2) & 7); if(mode & 0x200) { // pattern fill - u16 src = m_gcos->read_word((src_seg << 4) + src_adr); + u16 src = m_gcps->read_word((src_seg << 4) + src_adr); for(u16 w=0; w != width/2; w++) { - m_gcos->write_word((dst_seg << 4) + dst_adr, src); + m_gcps->write_word((dst_seg << 4) + dst_adr, src); dst_adr += 2; } + } else if(mode & 0x4000) { + // fast mode + u32 nw = (width+15) >> 4; + for(u32 y=0; y<height; y++) { + u16 src_cadr = src_adr; + u16 dst_cadr = dst_adr; + for(u32 w=0; w!=nw; w++) { + m_gcps->write_word((dst_seg << 4) + dst_cadr, m_gcps->read_word((src_seg << 4) + src_cadr)); + src_cadr += 2; + dst_cadr += 2; + } + src_adr += sy; + dst_adr += dy; + } + } else { - auto blend = gco_blend[(mode >> 2) & 7]; + auto blend = gcp_blend[(mode >> 2) & 7]; // Need to rotate rmask depending on the shifts too u16 awmask = ((wmask << 16) | wmask) >> (15 - dst_sft); @@ -703,43 +953,43 @@ void mindset_state::blit(u16 packet_seg, u16 packet_adr) u16 nw1 = nw; u32 srcs = 0; if(preload) { - srcs = sw(m_gcos->read_word((src_seg << 4) + src_cadr)) << src_do_sft; + srcs = sw(m_gcps->read_word((src_seg << 4) + src_cadr)) << src_do_sft; if(mode & 0x100) src_cadr += 2; } do { - srcs = (srcs << 16) | (sw(m_gcos->read_word((src_seg << 4) + src_cadr)) << src_do_sft); + srcs = (srcs << 16) | (sw(m_gcps->read_word((src_seg << 4) + src_cadr)) << src_do_sft); u16 src = (srcs >> dst_do_sft) & rmask; - u16 dst = sw(m_gcos->read_word((dst_seg << 4) + dst_cadr)); + u16 dst = sw(m_gcps->read_word((dst_seg << 4) + dst_cadr)); u16 res = blend(src, dst); if(mode & 0x40) { u16 tmask; - switch((mode >> 10) & 3) { + switch((mode >> 11) & 3) { case 0: - tmask = dst; + tmask = src; break; case 1: - tmask = ((dst & 0xaaaa) >> 1) | (dst & 0x5555); - tmask = tmask * 0x3; + tmask = (src >> 1) | src; + tmask = (tmask & 0x5555) * 0x3; break; case 2: - tmask = ((dst & 0xcccc) >> 2) | (dst & 0x3333); - tmask = ((dst & 0x2222) >> 1) | (dst & 0x1111); - tmask = tmask * 0xf; + tmask = (src >> 2) | src; + tmask = (tmask >> 1) | tmask; + tmask = (tmask & 0x1111) * 0xf; break; case 3: - tmask = ((dst & 0xf0f0) >> 4) | (dst & 0x0f0f); - tmask = ((dst & 0x0c0c) >> 2) | (dst & 0x0303); - tmask = ((dst & 0x0202) >> 1) | (dst & 0x0101); - tmask = tmask * 0xff; + tmask = (src >> 4) | src; + tmask = (tmask >> 2) | tmask; + tmask = (tmask >> 1) | tmask; + tmask = (tmask & 0x0101) * 0xff; break; } - cmask &= ~tmask; + cmask &= tmask; } res = (dst & ~cmask) | (res & cmask); - m_gcos->write_word((dst_seg << 4) + dst_cadr, sw(res)); + m_gcps->write_word((dst_seg << 4) + dst_cadr, sw(res)); if(mode & 0x100) src_cadr += 2; dst_cadr += 2; @@ -756,14 +1006,14 @@ void mindset_state::blit(u16 packet_seg, u16 packet_adr) } } -void mindset_state::gco_w(u16) +void mindset_state::gcp_w(u16) { - u16 packet_seg = sw(m_gcos->read_word(0xbfd7a)); - u16 packet_adr = sw(m_gcos->read_word(0xbfd78)); - u16 global_mode = sw(m_gcos->read_word(0xbfd76)); + u16 packet_seg = sw(m_gcps->read_word(0xbfd7a)); + u16 packet_adr = sw(m_gcps->read_word(0xbfd78)); + u16 global_mode = sw(m_gcps->read_word(0xbfd76)); if(0) - logerror("GCO: start %04x:%04x mode %04x (%05x)\n", packet_seg, packet_adr, global_mode, m_maincpu->pc()); + logerror("GCP: start %04x:%04x mode %04x (%05x)\n", packet_seg, packet_adr, global_mode, m_maincpu->pc()); switch(global_mode) { case 0x0005: @@ -773,7 +1023,7 @@ void mindset_state::gco_w(u16) } // 100 = done, 200 = done too???, 400 = collision? - m_gcos->write_word(0xbfd74, m_gcos->read_word(0xbfd74) | 0x0700); + m_gcps->write_word(0xbfd74, m_gcps->read_word(0xbfd74) | 0x0700); // Can trigger an irq, on mode & 2 (or is it 200?) (0x40 on 8282, ack on 0x41, which means the system 8042...) } @@ -891,15 +1141,17 @@ void mindset_state::maincpu_io(address_map &map) map(0x8060, 0x8060).r(m_fdc, FUNC(i8272a_device::msr_r)); map(0x8062, 0x8062).rw(m_fdc, FUNC(i8272a_device::fifo_r), FUNC(i8272a_device::fifo_w)); +#if 0 map(0x8080, 0x8080).lr8("id13", []() -> u8 { return 0x13; }); // sound map(0x80c0, 0x80c0).lr8("id3f", []() -> u8 { return 0x3f; }); // serial type 1, maybe? map(0x8100, 0x8100).lr8("id5f", []() -> u8 { return 0x5f; }); // serial type 2 map(0x8140, 0x8140).lr8("id70", []() -> u8 { return 0x70; }); // parallel printer, init writes 0x82 at +6 map(0x8180, 0x8180).lr8("rs232-id", []() -> u8 { return 0x73; }); // rs232 +#endif map(0x8280, 0x8283).rw(m_syscpu, FUNC(i8042_device::upi41_master_r), FUNC(i8042_device::upi41_master_w)).umask16(0x00ff); map(0x82a0, 0x82a3).rw(m_soundcpu, FUNC(i8042_device::upi41_master_r), FUNC(i8042_device::upi41_master_w)).umask16(0x00ff); - map(0x8300, 0x8301).w(FUNC(mindset_state::gco_w)); + map(0x8300, 0x8301).w(FUNC(mindset_state::gcp_w)); map(0x8320, 0x8321).rw(FUNC(mindset_state::dispreg_r), FUNC(mindset_state::dispreg_w)); map(0x8322, 0x8323).rw(FUNC(mindset_state::dispctrl_r), FUNC(mindset_state::dispctrl_w)); } @@ -909,6 +1161,11 @@ static void pc_dd_floppies(device_slot_interface &device) device.option_add("525dd", FLOPPY_525_DD); } +static void mindset_modules(device_slot_interface &device) +{ + device.option_add("stereo", MINDSET_SOUND_MODULE); +} + void mindset_state::mindset(machine_config &config) { config.m_perfect_cpu_quantum = ":syscpu"; @@ -955,6 +1212,19 @@ void mindset_state::mindset(machine_config &config) m_fdc->set_ready_line_connected(false); FLOPPY_CONNECTOR(config, m_fdco[0], pc_dd_floppies, "525dd", mindset_state::floppy_formats); FLOPPY_CONNECTOR(config, m_fdco[1], pc_dd_floppies, "525dd", mindset_state::floppy_formats); + + SPEAKER(config, "lspeaker").front_left(); + DAC_8BIT_R2R(config, m_dac, 0).add_route(ALL_OUTPUTS, "lspeaker", 0.5); + voltage_regulator_device &vref(VOLTAGE_REGULATOR(config, "vref")); + vref.add_route(0, m_dac, 1.0, DAC_VREF_POS_INPUT); + vref.add_route(0, m_dac, -1.0, DAC_VREF_NEG_INPUT); + + MINDSET_MODULE(config, "m0", mindset_modules, "stereo", false); + MINDSET_MODULE(config, "m1", mindset_modules, nullptr, false); + MINDSET_MODULE(config, "m2", mindset_modules, nullptr, false); + MINDSET_MODULE(config, "m3", mindset_modules, nullptr, false); + MINDSET_MODULE(config, "m4", mindset_modules, nullptr, false); + MINDSET_MODULE(config, "m5", mindset_modules, nullptr, false); } static INPUT_PORTS_START(mindset) @@ -1115,5 +1385,5 @@ ROM_START(mindset) ROM_LOAD("kbd_v3.0.bin", 0, 0x800, CRC(1c6aa433) SHA1(1d01dbda4730f26125ba2564a608c2f8ddfc05b3)) ROM_END -COMP( 1984, mindset, 0, 0, mindset, mindset, mindset_state, empty_init, "Mindset Corporation", "Mindset Video Production System", MACHINE_NOT_WORKING|MACHINE_NO_SOUND) +COMP( 1984, mindset, 0, 0, mindset, mindset, mindset_state, empty_init, "Mindset Corporation", "Mindset Video Production System", MACHINE_NOT_WORKING) |