diff options
Diffstat (limited to 'src/devices')
512 files changed, 12476 insertions, 6894 deletions
diff --git a/src/devices/bus/a2bus/a2bus.cpp b/src/devices/bus/a2bus/a2bus.cpp index ae5dbf82643..e09671f8f16 100644 --- a/src/devices/bus/a2bus/a2bus.cpp +++ b/src/devices/bus/a2bus/a2bus.cpp @@ -205,8 +205,6 @@ uint8_t a2bus_device::get_a2bus_nmi_mask() void a2bus_device::set_irq_line(int state, int slot) { - m_out_irq_cb(state); - if (state == CLEAR_LINE) { m_slot_irq_mask &= ~(1<<slot); @@ -215,6 +213,8 @@ void a2bus_device::set_irq_line(int state, int slot) { m_slot_irq_mask |= (1<<slot); } + + m_out_irq_cb(state); } void a2bus_device::set_nmi_line(int state, int slot) diff --git a/src/devices/bus/a2bus/a2hsscsi.cpp b/src/devices/bus/a2bus/a2hsscsi.cpp index 98c612dae78..20342e6fd14 100644 --- a/src/devices/bus/a2bus/a2hsscsi.cpp +++ b/src/devices/bus/a2bus/a2hsscsi.cpp @@ -2,7 +2,7 @@ // copyright-holders:R. Belmont /********************************************************************* - a2hsscsi.c + a2hsscsi.cpp Implementation of the Apple II High Speed SCSI Card @@ -101,7 +101,8 @@ a2bus_hsscsi_device::a2bus_hsscsi_device(const machine_config &mconfig, device_t device_t(mconfig, type, tag, owner, clock), device_a2bus_card_interface(mconfig, *this), m_ncr5380(*this, SCSI_5380_TAG), - m_scsibus(*this, SCSI_BUS_TAG), m_rom(nullptr), m_rambank(0), m_rombank(0), m_drq(0), m_bank(0), m_816block(false), m_c0ne(0), m_c0nf(0) + m_scsibus(*this, SCSI_BUS_TAG), m_rom(*this, SCSI_ROM_REGION), m_rambank(0), m_rombank(0), m_drq(0), m_bank(0), m_c0ne(0), m_c0nf(0), + m_dma_addr(0), m_dma_size(0) { } @@ -116,8 +117,6 @@ a2bus_hsscsi_device::a2bus_hsscsi_device(const machine_config &mconfig, const ch void a2bus_hsscsi_device::device_start() { - m_rom = machine().root_device().memregion(this->subtag(SCSI_ROM_REGION).c_str())->base(); - memset(m_ram, 0, 8192); save_item(NAME(m_ram)); @@ -125,15 +124,16 @@ void a2bus_hsscsi_device::device_start() save_item(NAME(m_rombank)); save_item(NAME(m_bank)); save_item(NAME(m_drq)); - save_item(NAME(m_816block)); + save_item(NAME(m_dma_addr)); + save_item(NAME(m_dma_size)); } void a2bus_hsscsi_device::device_reset() { m_rambank = 0; m_rombank = 0; + m_dma_addr = m_dma_size = 0; m_c0ne = m_c0nf = 0; - m_816block = false; } @@ -151,13 +151,35 @@ uint8_t a2bus_hsscsi_device::read_c0nx(uint8_t offset) case 3: case 4: case 5: - case 6: case 7: // logerror("Read 5380 @ %x\n", offset); return m_ncr5380->read(offset); - case 0xc: - return 0x00; // indicate watchdog? + case 6: + if (m_dma_control & 1) // pseudo-DMA? + { + return m_ncr5380->dma_r(); + } + else + { + //printf("Read 5380 PIO data (%s)\n", machine().describe_context().c_str()); + return m_ncr5380->read(offset); + } + + case 8: // DMA address low + return m_dma_addr & 0xff; + + case 9: // DMA address high + return (m_dma_addr >> 8) & 0xff; + + case 0xa: // DMA size low + return m_dma_size & 0xff; + + case 0xb: // DMA size high + return (m_dma_size >> 8) & 0xff; + + case 0xc: // DMA control + return m_dma_control; case 0xe: // code at cf32 wants to RMW this without killing the ROM bank return m_c0ne; @@ -166,7 +188,7 @@ uint8_t a2bus_hsscsi_device::read_c0nx(uint8_t offset) return m_c0nf; default: - logerror("Read c0n%x (%s)\n", offset, machine().describe_context()); + logerror("Read c0n%x (%s)\n", offset, machine().describe_context().c_str()); break; } @@ -182,7 +204,17 @@ void a2bus_hsscsi_device::write_c0nx(uint8_t offset, uint8_t data) { switch (offset) { - case 0: + case 0: // data out register; in PDMA mode, it's assumed this goes to DMA as reads do + if (m_dma_control & 1) + { + m_ncr5380->dma_w(data); + } + else + { + m_ncr5380->write(offset, data); + } + break; + case 1: case 2: case 3: @@ -193,25 +225,39 @@ void a2bus_hsscsi_device::write_c0nx(uint8_t offset, uint8_t data) // logerror("%02x to 5380 reg %x\n", data, offset); m_ncr5380->write(offset, data); break; -#if 0 + case 8: // DMA address low + //printf("%02x to DMA adr low\n", data); + m_dma_addr &= 0xff00; + m_dma_addr |= data; break; case 9: // DMA address high + //printf("%02x to DMA adr high\n", data); + m_dma_addr &= 0x00ff; + m_dma_addr |= (data << 8); break; case 0xa: // DMA count low + //printf("%02x to DMA count low\n", data); + m_dma_size &= 0xff00; + m_dma_size |= data; break; case 0xb: // DMA count high + //printf("%02x to DMA count high\n", data); + m_dma_size &= 0x00ff; + m_dma_size |= (data << 8); break; case 0xc: // DMA control + //printf("%02x to DMA control\n", data); + m_dma_control &= ~0x2b; // clear the read/write bits + m_dma_control |= (data & 0x2b); break; -#endif case 0xd: // DMA enable / reset - logerror("%02x to DMA enable/reset\n", data); + //printf("%02x to DMA enable/reset\n", data); if (data & 0x2) { // logerror("Resetting SCSI: %02x at %s\n", data, machine().describe_context()); @@ -222,17 +268,17 @@ void a2bus_hsscsi_device::write_c0nx(uint8_t offset, uint8_t data) case 0xe: m_c0ne = data; m_rombank = (data & 0x1f) * 0x400; - logerror("c0ne to %x (ROM bank %x)\n", data & 0x1f, m_rombank); + //logerror("c0ne to %x (ROM bank %x)\n", data & 0x1f, m_rombank); break; case 0xf: m_c0nf = data; m_rambank = (data & 0x7) * 0x400; - logerror("c0nf to %x (RAM bank %x)\n", data & 0x7, m_rambank); + //logerror("c0nf to %x (RAM bank %x)\n", data & 0x7, m_rambank); break; default: - logerror("Write %02x to c0n%x (%s)\n", data, offset, machine().describe_context()); + logerror("Write %02x to c0n%x (%s)\n", data, offset, machine().describe_context().c_str()); break; } } @@ -263,11 +309,6 @@ uint8_t a2bus_hsscsi_device::read_c800(uint16_t offset) if (offset < 0x400) { // logerror("Read RAM at %x = %02x\n", offset+m_rambank, m_ram[offset + m_rambank]); - if (m_816block) - { - return m_ncr5380->dma_r(); - } - return m_ram[offset + m_rambank]; } else @@ -284,18 +325,12 @@ void a2bus_hsscsi_device::write_c800(uint16_t offset, uint8_t data) if (offset < 0x400) { // logerror("%02x to RAM at %x\n", data, offset+m_rambank); - if (m_816block) - { - m_ncr5380->dma_w(data); - } - else - { - m_ram[offset + m_rambank] = data; - } + m_ram[offset + m_rambank] = data; } } WRITE_LINE_MEMBER( a2bus_hsscsi_device::drq_w ) { m_drq = (state ? 0x80 : 0x00); +// printf("DRQ to %d\n", state); } diff --git a/src/devices/bus/a2bus/a2hsscsi.h b/src/devices/bus/a2bus/a2hsscsi.h index 905de8b620d..36a5a9df15b 100644 --- a/src/devices/bus/a2bus/a2hsscsi.h +++ b/src/devices/bus/a2bus/a2hsscsi.h @@ -50,15 +50,16 @@ protected: required_device<ncr53c80_device> m_ncr5380; required_device<nscsi_bus_device> m_scsibus; + required_region_ptr<u8> m_rom; private: - uint8_t *m_rom; uint8_t m_ram[8192]; // 8 banks of 1024 bytes int m_rambank, m_rombank; uint8_t m_drq; uint8_t m_bank; - bool m_816block; + uint8_t m_dma_control; uint8_t m_c0ne, m_c0nf; + uint16_t m_dma_addr, m_dma_size; }; // device type definition diff --git a/src/devices/bus/a2bus/a2mcms.cpp b/src/devices/bus/a2bus/a2mcms.cpp index f9de57897f8..1ef164aff41 100644 --- a/src/devices/bus/a2bus/a2mcms.cpp +++ b/src/devices/bus/a2bus/a2mcms.cpp @@ -206,7 +206,7 @@ mcms_device::mcms_device(const machine_config &mconfig, const char *tag, device_ void mcms_device::device_start() { m_write_irq.resolve(); - m_stream = stream_alloc_legacy(0, 2, 31250); + m_stream = stream_alloc(0, 2, 31250); m_timer = timer_alloc(0, nullptr); m_clrtimer = timer_alloc(1, nullptr); m_enabled = false; @@ -252,20 +252,19 @@ void mcms_device::device_timer(emu_timer &timer, device_timer_id tid, int param, } } -void mcms_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void mcms_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - stream_sample_t *outL, *outR; int i, v; uint16_t wptr; int8_t sample; int32_t mixL, mixR; - outL = outputs[1]; - outR = outputs[0]; + auto &outL = outputs[1]; + auto &outR = outputs[0]; if (m_enabled) { - for (i = 0; i < samples; i++) + for (i = 0; i < outL.samples(); i++) { mixL = mixR = 0; @@ -286,16 +285,14 @@ void mcms_device::sound_stream_update_legacy(sound_stream &stream, stream_sample } } - outL[i] = (mixL * m_mastervol)>>9; - outR[i] = (mixR * m_mastervol)>>9; + outL.put_int(i, mixL * m_mastervol, 32768 << 9); + outR.put_int(i, mixR * m_mastervol, 32768 << 9); } } else { - for (i = 0; i < samples; i++) - { - outL[i] = outR[i] = 0; - } + outL.fill(0); + outR.fill(0); } } diff --git a/src/devices/bus/a2bus/a2mcms.h b/src/devices/bus/a2bus/a2mcms.h index 11e8b332ee0..487c6ddb7a7 100644 --- a/src/devices/bus/a2bus/a2mcms.h +++ b/src/devices/bus/a2bus/a2mcms.h @@ -42,7 +42,7 @@ protected: virtual void device_reset() override; virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: sound_stream *m_stream; diff --git a/src/devices/bus/a2bus/a2mockingboard.cpp b/src/devices/bus/a2bus/a2mockingboard.cpp index 167c7dc2f6f..c7f5fda534d 100644 --- a/src/devices/bus/a2bus/a2mockingboard.cpp +++ b/src/devices/bus/a2bus/a2mockingboard.cpp @@ -53,7 +53,7 @@ void a2bus_ayboard_device::add_common_devices(machine_config &config) SPEAKER(config, "lspeaker").front_left(); SPEAKER(config, "rspeaker").front_right(); AY8913(config, m_ay1, 1022727); - m_ay1->add_route(ALL_OUTPUTS, "lspeaker", 1.0); + m_ay1->add_route(ALL_OUTPUTS, "lspeaker", 0.5); } void a2bus_ayboard_device::device_add_mconfig(machine_config &config) @@ -61,7 +61,7 @@ void a2bus_ayboard_device::device_add_mconfig(machine_config &config) add_common_devices(config); AY8913(config, m_ay2, 1022727); - m_ay2->add_route(ALL_OUTPUTS, "rspeaker", 1.0); + m_ay2->add_route(ALL_OUTPUTS, "rspeaker", 0.5); } void a2bus_mockingboard_device::device_add_mconfig(machine_config &config) @@ -72,7 +72,7 @@ void a2bus_mockingboard_device::device_add_mconfig(machine_config &config) m_via1->cb2_handler().set(FUNC(a2bus_mockingboard_device::write_via1_cb2)); AY8913(config, m_ay2, 1022727); - m_ay2->add_route(ALL_OUTPUTS, "rspeaker", 1.0); + m_ay2->add_route(ALL_OUTPUTS, "rspeaker", 0.5); VOTRAX_SC01(config, m_sc01, 1022727); m_sc01->ar_callback().set(m_via1, FUNC(via6522_device::write_cb1)); @@ -92,9 +92,9 @@ void a2bus_phasor_device::device_add_mconfig(machine_config &config) AY8913(config, m_ay2, 1022727); AY8913(config, m_ay3, 1022727); AY8913(config, m_ay4, 1022727); - m_ay2->add_route(ALL_OUTPUTS, "lspeaker2", 1.0); - m_ay3->add_route(ALL_OUTPUTS, "rspeaker", 1.0); - m_ay4->add_route(ALL_OUTPUTS, "rspeaker2", 1.0); + m_ay2->add_route(ALL_OUTPUTS, "lspeaker2", 0.5); + m_ay3->add_route(ALL_OUTPUTS, "rspeaker", 0.5); + m_ay4->add_route(ALL_OUTPUTS, "rspeaker2", 0.5); } void a2bus_echoplus_device::device_add_mconfig(machine_config &config) @@ -102,7 +102,7 @@ void a2bus_echoplus_device::device_add_mconfig(machine_config &config) add_common_devices(config); AY8913(config, m_ay2, 1022727); - m_ay2->add_route(ALL_OUTPUTS, "rspeaker", 1.0); + m_ay2->add_route(ALL_OUTPUTS, "rspeaker", 0.5); SPEAKER(config, "echosp").front_center(); TMS5220(config, m_tms, 640000); @@ -414,16 +414,35 @@ void a2bus_phasor_device::via2_out_b(uint8_t data) } } +void a2bus_phasor_device::set_clocks() +{ + if (m_native) + { + m_ay1->set_clock(1022727*2); + m_ay2->set_clock(1022727*2); + m_ay3->set_clock(1022727*2); + m_ay4->set_clock(1022727*2); + } + else + { + m_ay1->set_clock(1022727); + m_ay2->set_clock(1022727); + m_ay3->set_clock(1022727); + m_ay4->set_clock(1022727); + } +} uint8_t a2bus_phasor_device::read_c0nx(uint8_t offset) { m_native = BIT(offset, 0); + set_clocks(); return 0xff; } void a2bus_phasor_device::write_c0nx(uint8_t offset, uint8_t data) { m_native = BIT(offset, 0); + set_clocks(); } uint8_t a2bus_echoplus_device::read_c0nx(uint8_t offset) diff --git a/src/devices/bus/a2bus/a2mockingboard.h b/src/devices/bus/a2bus/a2mockingboard.h index 6d4aa8e73af..44acff10006 100644 --- a/src/devices/bus/a2bus/a2mockingboard.h +++ b/src/devices/bus/a2bus/a2mockingboard.h @@ -97,6 +97,8 @@ protected: required_device<ay8913_device> m_ay4; private: + void set_clocks(); + bool m_native; }; diff --git a/src/devices/bus/a2bus/a2ultraterm.cpp b/src/devices/bus/a2bus/a2ultraterm.cpp index 7b6caa40624..e8d5972e4ec 100644 --- a/src/devices/bus/a2bus/a2ultraterm.cpp +++ b/src/devices/bus/a2bus/a2ultraterm.cpp @@ -304,11 +304,10 @@ void a2bus_videx160_device::write_c800(uint16_t offset, uint8_t data) MC6845_UPDATE_ROW( a2bus_videx160_device::crtc_update_row ) { - uint32_t *p = &bitmap.pix32(y); + uint32_t *p = &bitmap.pix(y); uint16_t chr_base = ra; - int i; - for ( i = 0; i < x_count; i++ ) + for ( int i = 0; i < x_count; i++ ) { uint16_t offset = ( ma + i ); uint8_t chr = m_ram[ offset ]; diff --git a/src/devices/bus/a2bus/a2videoterm.cpp b/src/devices/bus/a2bus/a2videoterm.cpp index b0fda659783..839fa19e74a 100644 --- a/src/devices/bus/a2bus/a2videoterm.cpp +++ b/src/devices/bus/a2bus/a2videoterm.cpp @@ -347,7 +347,7 @@ void a2bus_videx80_device::write_c800(uint16_t offset, uint8_t data) MC6845_UPDATE_ROW( a2bus_videx80_device::crtc_update_row ) { - uint32_t *p = &bitmap.pix32(y); + uint32_t *p = &bitmap.pix(y); uint16_t chr_base = ra; //( ra & 0x08 ) ? 0x800 | ( ra & 0x07 ) : ra; for (int i = 0; i < x_count; i++) diff --git a/src/devices/bus/a2bus/computereyes2.cpp b/src/devices/bus/a2bus/computereyes2.cpp index b8a80819023..b8dcab00373 100644 --- a/src/devices/bus/a2bus/computereyes2.cpp +++ b/src/devices/bus/a2bus/computereyes2.cpp @@ -196,22 +196,22 @@ void a2bus_computereyes2_device::write_c0nx(uint8_t offset, uint8_t data) m_x = m_y = 0; std::fill_n(m_a2_bitmap, 280*193, 0); - m_bitmap = &m_picture->get_bitmap(); - if (m_bitmap) + const bitmap_argb32 &bitmap = m_picture->get_bitmap(); + if (bitmap.valid()) { // convert arbitrary sized ARGB32 image to a 188x193 image with 256 levels of grayscale - double stepx = (double)m_bitmap->width() / 188.0; - double stepy = (double)m_bitmap->height() / 193.0; + double stepx = (double)bitmap.width() / 188.0; + double stepy = (double)bitmap.height() / 193.0; for (int y = 0; y < 193; y++) { for (int x = 0; x < 280; x++) { - u32 pixel = m_bitmap->pix((int)((double)y * stepy), (int)((double)x * stepx)); - double mono = ((0.2126 * (double)(((pixel>>16) & 0xff) / 255.0)) + - (0.7152 * (double)(((pixel>>8) & 0xff) / 255.0)) + - (0.0722 * (double)((pixel& 0xff) / 255.0))); - m_a2_bitmap[(y*280)+x] = (u8)(mono * 255.0); + u32 pixel = bitmap.pix(int((double)y * stepy), int((double)x * stepx)); + double mono = ((0.2126 * double(((pixel>>16) & 0xff) / 255.0)) + + (0.7152 * double(((pixel>>8) & 0xff) / 255.0)) + + (0.0722 * double((pixel& 0xff) / 255.0))); + m_a2_bitmap[(y*280)+x] = u8(mono * 255.0); } } } diff --git a/src/devices/bus/a2bus/computereyes2.h b/src/devices/bus/a2bus/computereyes2.h index 31856f08813..a69600b6de2 100644 --- a/src/devices/bus/a2bus/computereyes2.h +++ b/src/devices/bus/a2bus/computereyes2.h @@ -46,7 +46,6 @@ private: u8 m_a2_bitmap[280*193]; u8 m_threshold; bool m_bActive; - bitmap_argb32 *m_bitmap; }; // device type definition diff --git a/src/devices/bus/a2bus/mouse.cpp b/src/devices/bus/a2bus/mouse.cpp index 03b219cf72e..e5c2e7fcf84 100644 --- a/src/devices/bus/a2bus/mouse.cpp +++ b/src/devices/bus/a2bus/mouse.cpp @@ -299,17 +299,15 @@ void a2bus_mouse_device::mcu_port_c_w(uint8_t data) template <unsigned AXIS, u8 DIR, u8 CLK> void a2bus_mouse_device::update_axis() { - // read the axis + // read the axis and check for changes const int new_m = m_mousexy[AXIS]->read(); - - // did it change? int diff = new_m - m_last[AXIS]; // check for wrap if (diff > 0x80) - diff = 0x100 - diff; - if (diff < -0x80) - diff = -0x100 - diff; + diff -= 0x100; + else if (diff < -0x80) + diff += 0x100; m_count[AXIS] += diff; m_last[AXIS] = new_m; diff --git a/src/devices/bus/a2bus/sider.cpp b/src/devices/bus/a2bus/sider.cpp new file mode 100644 index 00000000000..d2722c8bb77 --- /dev/null +++ b/src/devices/bus/a2bus/sider.cpp @@ -0,0 +1,296 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont +/********************************************************************* + + sider.cpp + + Implementation of the First Class Peripherals / Advanced Tech Services / Xebec Sider cards + + Sider 1: based on Xebec SASI hardware, with Xebec firmware. Requires HDD with 256 byte sectors + and special formatting - not compatible with standard .po/.hdv type images. + + Sider 2: Same hardware, new firmware that's fully ProDOS compliant including 512 byte sectors. + Sectors are interleaved: the first byte is the byte that would be at 0, the second byte is the byte that would be at $100, + the third is the byte at $1, the fourth at $101, and so on. So this is also not compatible with standard images. + + This command-line program will convert a standard image to work with Sider 2. First parameter is the input filename, + second parameter is the output filename. No error checking is done, if the input file doesn't exist it'll probably crash. + + #include <stdio.h> + #include <stdlib.h> + #include <string.h> + + static char block[512]; + static char blockout[512]; + + int main(int argc, char *argv[]) + { + FILE *in, *out; + + in = fopen(argv[1], "rb"); + out = fopen(argv[2], "wb"); + + int len = 0; + fseek(in, 0, SEEK_END); + len = ftell(in); + fseek(in, 0, SEEK_SET); + + for (int bnum = 0; bnum < (len / 512); bnum++) + { + fread(block, 512, 1, in); + for (int byte = 0; byte < 256; byte++) + { + blockout[byte*2] = block[byte]; + blockout[(byte*2)+1] = block[byte+256]; + } + fwrite(blockout, 512, 1, out); + printf("block %d\n", bnum); + } + + fclose(out); + fclose(in); + return 0; + } + + -------------------------------------- + + $C0(n+8)X space: + $0: read state / write latch + $1: read data / write control + + State: + b3: /Busy + b4: /Message + b5: I/O + b6: C/D + b7: REQ + + Control: + b4: drive contents of output latch onto the SASI bus (reverse logic; latch is driven when this bit is clear) + b5: reset bus + b6: /BSY + b7: /SEL + +*********************************************************************/ + +#include "emu.h" +#include "sider.h" +#include "bus/scsi/scsihd.h" +#include "bus/scsi/s1410.h" + +/*************************************************************************** + PARAMETERS +***************************************************************************/ + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +DEFINE_DEVICE_TYPE(A2BUS_SIDER2, a2bus_sider2card_device, "a2sider2", "First Class Peripherals Sider 2 SASI Card") +DEFINE_DEVICE_TYPE(A2BUS_SIDER1, a2bus_sider1card_device, "a2sider1", "First Class Peripherals Sider 1 SASI Card") + +#define SASI_ROM_REGION "sasi_rom" + +ROM_START( sider2 ) + ROM_REGION(0x800, SASI_ROM_REGION, 0) + ROM_LOAD( "atsv22_a02a9baad2262a8a49ecea843f602124.bin", 0x000000, 0x000800, CRC(97773a0b) SHA1(8d0a5d6ce3b9a236771126033c4aba6c0cc5e704) ) +ROM_END + +ROM_START( sider1 ) + ROM_REGION(0x800, SASI_ROM_REGION, 0) + ROM_LOAD( "xebec-103684c-1986.bin", 0x000000, 0x000800, CRC(9e62e15f) SHA1(7f50b5e00cac4960204f50448a6e2d623b1a41e2) ) +ROM_END + +/*************************************************************************** + FUNCTION PROTOTYPES +***************************************************************************/ + +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- + +void a2bus_sider_device::device_add_mconfig(machine_config &config) +{ + NSCSI_BUS(config, m_sasibus); + NSCSI_CONNECTOR(config, "sasibus:0", default_scsi_devices, "s1410", false); + NSCSI_CONNECTOR(config, "sasibus:1", default_scsi_devices, nullptr, false); + NSCSI_CONNECTOR(config, "sasibus:2", default_scsi_devices, nullptr, false); + NSCSI_CONNECTOR(config, "sasibus:3", default_scsi_devices, nullptr, false); + NSCSI_CONNECTOR(config, "sasibus:4", default_scsi_devices, nullptr, false); + NSCSI_CONNECTOR(config, "sasibus:5", default_scsi_devices, nullptr, false); + NSCSI_CONNECTOR(config, "sasibus:6", default_scsi_devices, nullptr, false); + NSCSI_CONNECTOR(config, "sasibus:7", default_scsi_devices, "scsicb", true).option_add_internal("scsicb", NSCSI_CB); +} + +//------------------------------------------------- +// rom_region - device-specific ROM region +//------------------------------------------------- + +const tiny_rom_entry *a2bus_sider2card_device::device_rom_region() const +{ + return ROM_NAME( sider2 ); +} + +const tiny_rom_entry *a2bus_sider1card_device::device_rom_region() const +{ + return ROM_NAME( sider1 ); +} + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +a2bus_sider_device::a2bus_sider_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, type, tag, owner, clock), + device_a2bus_card_interface(mconfig, *this), + m_sasibus(*this, "sasibus"), + m_sasi(*this, "sasibus:7:scsicb"), + m_rom(*this, SASI_ROM_REGION), + m_latch(0xff), + m_control(0) +{ +} + +a2bus_sider2card_device::a2bus_sider2card_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + a2bus_sider_device(mconfig, A2BUS_SIDER2, tag, owner, clock) +{ +} + +a2bus_sider1card_device::a2bus_sider1card_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + a2bus_sider_device(mconfig, A2BUS_SIDER1, tag, owner, clock) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void a2bus_sider_device::device_start() +{ + save_item(NAME(m_latch)); + save_item(NAME(m_control)); +} + +void a2bus_sider_device::device_reset() +{ + m_latch = 0xff; + m_control = 0; +} + +/*------------------------------------------------- + read_c0nx - called for reads from this card's c0nx space +-------------------------------------------------*/ + +uint8_t a2bus_sider_device::read_c0nx(uint8_t offset) +{ + u8 rv = 0; + + switch (offset) + { + case 0: + // b3: /Busy + // b4: /Message + // b5: I/O + // b6: C/D + // b7: REQ + rv |= m_sasi->req_r() ? 0x80 : 0; + rv |= m_sasi->cd_r() ? 0x40 : 0; + rv |= m_sasi->io_r() ? 0x20 : 0; + rv |= m_sasi->msg_r() ? 0x10 : 0; + rv |= m_sasi->bsy_r() ? 0x08 : 0; + return rv; + + case 1: + rv = m_sasi->read(); + if ((m_sasi->req_r()) && (m_sasi->io_r())) + { + m_sasi->ack_w(1); + m_sasi->ack_w(0); + } + return rv; + + default: + logerror("Read c0n%x (%s)\n", offset, machine().describe_context().c_str()); + break; + } + + return 0xff; +} + + +/*------------------------------------------------- + write_c0nx - called for writes to this card's c0nx space +-------------------------------------------------*/ + +void a2bus_sider_device::write_c0nx(uint8_t offset, uint8_t data) +{ + switch (offset) + { + case 0: + m_latch = data; + if (!(m_control & 0x10)) + { + m_sasi->write(m_latch); + + if (m_sasi->req_r()) + { + m_sasi->ack_w(1); + m_sasi->write(0); // stop driving the data lines + m_sasi->ack_w(0); + } + } + break; + + case 1: +// b4: drive contents of output latch onto the SASI bus +// b5: reset bus +// b6: /BSY +// b7: /SEL (error in note on A2DP's schematic; BSY and SEL are the same polarity from the 6502's POV) + m_control = data; + m_sasi->sel_w((data & 0x80) ? 1 : 0); + m_sasi->bsy_w((data & 0x40) ? 1 : 0); + if (data & 0x20) + { + m_sasibus->reset(); + } + else if (!(data & 0x10)) + { + m_sasi->write(m_latch); + } + break; + + default: + logerror("Write %02x to c0n%x (%s)\n", data, offset, machine().describe_context().c_str()); + break; + } +} + +/*------------------------------------------------- + read_cnxx - called for reads from this card's cnxx space +-------------------------------------------------*/ + +uint8_t a2bus_sider_device::read_cnxx(uint8_t offset) +{ + // slot images at $700 + return m_rom[offset + 0x700]; +} + +void a2bus_sider_device::write_cnxx(uint8_t offset, uint8_t data) +{ +} + +/*------------------------------------------------- + read_c800 - called for reads from this card's c800 space +-------------------------------------------------*/ + +uint8_t a2bus_sider_device::read_c800(uint16_t offset) +{ + return m_rom[offset]; +} + +/*------------------------------------------------- + write_c800 - called for writes to this card's c800 space +-------------------------------------------------*/ +void a2bus_sider_device::write_c800(uint16_t offset, uint8_t data) +{ +} diff --git a/src/devices/bus/a2bus/sider.h b/src/devices/bus/a2bus/sider.h new file mode 100644 index 00000000000..6bb5ed3c036 --- /dev/null +++ b/src/devices/bus/a2bus/sider.h @@ -0,0 +1,71 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont +/********************************************************************* + + sider.h + + Implementation of the First Class Peripherals / Advanced Tech Services / Xebec Sider SASI Card + +*********************************************************************/ + +#ifndef MAME_BUS_A2BUS_SIDER_H +#define MAME_BUS_A2BUS_SIDER_H + +#pragma once + +#include "a2bus.h" +#include "bus/nscsi/devices.h" +#include "machine/nscsi_bus.h" +#include "machine/nscsi_cb.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class a2bus_sider_device: + public device_t, + public device_a2bus_card_interface +{ +protected: + a2bus_sider_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + + virtual void device_start() override; + virtual void device_reset() override; + virtual void device_add_mconfig(machine_config &config) override; + + // overrides of standard a2bus slot functions + virtual uint8_t read_c0nx(uint8_t offset) override; + virtual void write_c0nx(uint8_t offset, uint8_t data) override; + virtual uint8_t read_cnxx(uint8_t offset) override; + virtual void write_cnxx(uint8_t offset, uint8_t data) override; + virtual uint8_t read_c800(uint16_t offset) override; + virtual void write_c800(uint16_t offset, uint8_t data) override; + + required_device<nscsi_bus_device> m_sasibus; + required_device<nscsi_callback_device> m_sasi; + required_region_ptr<u8> m_rom; + +private: + u8 m_latch; + u8 m_control; +}; + +class a2bus_sider2card_device: public a2bus_sider_device +{ +public: + a2bus_sider2card_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + virtual const tiny_rom_entry *device_rom_region() const override; +}; + +class a2bus_sider1card_device: public a2bus_sider_device +{ +public: + a2bus_sider1card_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + virtual const tiny_rom_entry *device_rom_region() const override; +}; + +// device type definition +DECLARE_DEVICE_TYPE(A2BUS_SIDER2, a2bus_sider2card_device) +DECLARE_DEVICE_TYPE(A2BUS_SIDER1, a2bus_sider1card_device) + +#endif // MAME_BUS_A2BUS_SIDER_H diff --git a/src/devices/bus/a2gameio/computereyes.cpp b/src/devices/bus/a2gameio/computereyes.cpp index 1c587f54254..af597361c8e 100644 --- a/src/devices/bus/a2gameio/computereyes.cpp +++ b/src/devices/bus/a2gameio/computereyes.cpp @@ -82,23 +82,22 @@ WRITE_LINE_MEMBER(apple2_compeyes_device::an0_w) std::fill_n(m_a2_bitmap, 280*192, 0); - m_bitmap = &m_picture->get_bitmap(); - if (m_bitmap) + const bitmap_argb32 &bitmap = m_picture->get_bitmap(); + if (bitmap.valid()) { // convert arbitrary sized ARGB32 image to a 280x192 image with 256 levels of grayscale - double stepx = (double)m_bitmap->width() / 280.0; - double stepy = (double)m_bitmap->height() / 192.0; - + double stepx = (double)bitmap.width() / 280.0; + double stepy = (double)bitmap.height() / 192.0; for (int y = 0; y < 192; y++) { for (int x = 0; x < 280; x++) { - u32 pixel = m_bitmap->pix((int)((double)y * stepy), (int)((double)x * stepx)); - double mono = ((0.2126 * (double)(((pixel>>16) & 0xff) / 255.0)) + - (0.7152 * (double)(((pixel>>8) & 0xff) / 255.0)) + - (0.0722 * (double)((pixel& 0xff) / 255.0))); - m_a2_bitmap[(y*280)+x] = (u8)(mono * 255.0); + u32 pixel = bitmap.pix(int((double)y * stepy), int((double)x * stepx)); + double mono = ((0.2126 * double(((pixel>>16) & 0xff) / 255.0)) + + (0.7152 * double(((pixel>>8) & 0xff) / 255.0)) + + (0.0722 * double((pixel& 0xff) / 255.0))); + m_a2_bitmap[(y*280)+x] = u8(mono * 255.0); } } } diff --git a/src/devices/bus/a2gameio/computereyes.h b/src/devices/bus/a2gameio/computereyes.h index 6aef78796a6..9445ce4df25 100644 --- a/src/devices/bus/a2gameio/computereyes.h +++ b/src/devices/bus/a2gameio/computereyes.h @@ -41,7 +41,6 @@ private: required_device<picture_image_device> m_picture; int m_x, m_y, m_an1, m_an2, m_an3, m_level; u8 m_a2_bitmap[280*192]; - bitmap_argb32 *m_bitmap; }; // device type declaration diff --git a/src/devices/bus/acorn/system/vdu40.cpp b/src/devices/bus/acorn/system/vdu40.cpp index dcee8cd9b53..7bc8629ac35 100644 --- a/src/devices/bus/acorn/system/vdu40.cpp +++ b/src/devices/bus/acorn/system/vdu40.cpp @@ -93,7 +93,7 @@ void acorn_vdu40_device::device_reset() MC6845_UPDATE_ROW(acorn_vdu40_device::crtc_update_row) { - uint32_t *p = &bitmap.pix32(y); + uint32_t *p = &bitmap.pix(y); m_trom->lose_w(1); m_trom->lose_w(0); diff --git a/src/devices/bus/acorn/system/vdu80.cpp b/src/devices/bus/acorn/system/vdu80.cpp index 5cf995d8d3c..77bad0bf32c 100644 --- a/src/devices/bus/acorn/system/vdu80.cpp +++ b/src/devices/bus/acorn/system/vdu80.cpp @@ -172,7 +172,7 @@ void acorn_vdu80_device::device_reset() MC6845_UPDATE_ROW(acorn_vdu80_device::crtc_update_row) { uint8_t invert = BIT(m_links->read(), 1); - uint32_t *p = &bitmap.pix32(y); + uint32_t *p = &bitmap.pix(y); for (int column = 0; column < x_count; column++) { diff --git a/src/devices/bus/adamnet/adamnet.cpp b/src/devices/bus/adamnet/adamnet.cpp index 69b25ce30e7..18b91c4fb8c 100644 --- a/src/devices/bus/adamnet/adamnet.cpp +++ b/src/devices/bus/adamnet/adamnet.cpp @@ -113,7 +113,7 @@ void adamnet_device::device_stop() void adamnet_device::add_device(device_t *target) { - auto entry = global_alloc(daisy_entry(target)); + auto entry = new daisy_entry(target); entry->m_interface->m_bus = this; diff --git a/src/devices/bus/adamnet/ddp.cpp b/src/devices/bus/adamnet/ddp.cpp index 6e05689cb29..b4a17e909cd 100644 --- a/src/devices/bus/adamnet/ddp.cpp +++ b/src/devices/bus/adamnet/ddp.cpp @@ -58,7 +58,7 @@ void adam_digital_data_pack_device::adam_ddp_mem(address_map &map) map(0xf800, 0xffff).rom().region(M6801_TAG, 0); } -static const struct CassetteOptions adam_cassette_options = +static const cassette_image::Options adam_cassette_options = { 2, /* channels */ 16, /* bits per sample */ diff --git a/src/devices/bus/adamnet/kb.cpp b/src/devices/bus/adamnet/kb.cpp index a401dbfb335..046ceba61f4 100644 --- a/src/devices/bus/adamnet/kb.cpp +++ b/src/devices/bus/adamnet/kb.cpp @@ -134,7 +134,7 @@ static INPUT_PORTS_START( adam_kb ) PORT_START("Y5") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(') PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')') - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('\'') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('`') PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('+') PORT_CHAR('=') PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_TILDE) PORT_CHAR('^') PORT_CHAR('~') PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L') diff --git a/src/devices/bus/bbc/1mhzbus/1mhzbus.cpp b/src/devices/bus/bbc/1mhzbus/1mhzbus.cpp index 1246cb1902c..6fa98419abc 100644 --- a/src/devices/bus/bbc/1mhzbus/1mhzbus.cpp +++ b/src/devices/bus/bbc/1mhzbus/1mhzbus.cpp @@ -117,7 +117,7 @@ void bbc_1mhzbus_slot_device::jim_w(offs_t offset, uint8_t data) #include "ide.h" #include "ieee488.h" #include "m2000.h" -//#include "m5000.h" +#include "m5000.h" #include "sasi.h" #include "scsi.h" #include "multiform.h" @@ -137,7 +137,7 @@ void bbc_1mhzbus_devices(device_slot_interface &device) { //device.option_add("teletext", BBC_TELETEXT); /* Acorn ANE01 Teletext Adapter */ device.option_add("ieee488", BBC_IEEE488); /* Acorn ANK01 IEEE488 Interface */ - //device.option_add("m500", BBC_M500); /* Acorn ANV02 Music 500 */ + device.option_add("m500", BBC_M500); /* Acorn ANV02 Music 500 */ device.option_add("awhd", BBC_AWHD); /* Acorn Winchester Disc */ device.option_add("autoprom", BBC_AUTOPROM); /* ATPL AutoPrommer */ device.option_add("beebide", BBC_BEEBIDE); /* Sprow BeebIDE 16-bit */ @@ -147,6 +147,10 @@ void bbc_1mhzbus_devices(device_slot_interface &device) //device.option_add("videodig", BBC_VIDEODIG); /* Video Digitiser (RH Electronics) */ device.option_add("emrmidi", BBC_EMRMIDI); /* EMR Midi Interface */ //device.option_add("procyon", BBC_PROCYON); /* CST Procyon IEEE Interface */ + device.option_add("m2000", BBC_M2000); /* Hybrid Music 2000 Interface */ + device.option_add("m3000", BBC_M3000); /* Hybrid Music 3000 Expander */ + device.option_add("m5000", BBC_M5000); /* Hybrid Music 5000 Synthesiser */ + device.option_add("m87", BBC_M87); /* Peartree Music 87 Synthesiser */ device.option_add("multiform", BBC_MULTIFORM); /* PEDL Multiform Z80 */ device.option_add("opus3", BBC_OPUS3); /* Opus Challenger 3 */ device.option_add("pdram", BBC_PDRAM); /* Micro User Pull Down RAM */ @@ -160,13 +164,13 @@ void bbc_1mhzbus_devices(device_slot_interface &device) device.option_add("cc500", BBC_CC500); /* CTS Colour Card 500 */ //device.option_add("prisma3", BBC_PRISMA3); /* PRISMA-3 - Millipede 1989 */ device.option_add("sprite", BBC_SPRITE); /* Logotron Sprite Board */ + device.option_add_internal("cfa3000opt", CFA3000_OPT);/* Henson CFA 3000 Option Board */ } void bbcm_1mhzbus_devices(device_slot_interface &device) { //device.option_add("teletext", BBC_TELETEXT); /* Acorn ANE01 Teletext Adapter */ device.option_add("ieee488", BBC_IEEE488); /* Acorn ANK01 IEEE488 Interface */ - //device.option_add("m500", BBC_M500); /* Acorn ANV02 Music 500 */ device.option_add("awhd", BBC_AWHD); /* Acorn Winchester Disc */ device.option_add("beebide", BBC_BEEBIDE); /* Sprow BeebIDE 16-bit */ device.option_add("ide8", BBC_IDE8); /* RetroClinic BBC 8-bit IDE */ @@ -175,9 +179,9 @@ void bbcm_1mhzbus_devices(device_slot_interface &device) device.option_add("emrmidi", BBC_EMRMIDI); /* EMR Midi Interface */ //device.option_add("procyon", BBC_PROCYON); /* CST Procyon IEEE Interface */ device.option_add("m2000", BBC_M2000); /* Hybrid Music 2000 Interface */ - //device.option_add("m3000", BBC_M3000); /* Hybrid Music 3000 Expander */ - //device.option_add("m5000", BBC_M5000); /* Hybrid Music 5000 Synthesiser */ - //device.option_add("m87", BBC_M87); /* Peartree Music 87 Synthesiser */ + device.option_add("m3000", BBC_M3000); /* Hybrid Music 3000 Expander */ + device.option_add("m5000", BBC_M5000); /* Hybrid Music 5000 Synthesiser */ + device.option_add("m87", BBC_M87); /* Peartree Music 87 Synthesiser */ device.option_add("multiform", BBC_MULTIFORM); /* PEDL Multiform Z80 */ device.option_add("opusa", BBC_OPUSA); /* Opus Challenger ADFS */ device.option_add("pdram", BBC_PDRAM); /* Micro User Pull Down RAM */ diff --git a/src/devices/bus/bbc/1mhzbus/m5000.cpp b/src/devices/bus/bbc/1mhzbus/m5000.cpp new file mode 100644 index 00000000000..1844de74a0d --- /dev/null +++ b/src/devices/bus/bbc/1mhzbus/m5000.cpp @@ -0,0 +1,435 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +// thanks-to:Darren Izzard +/********************************************************************** + + Acorn ANV02 Music 500 + + http://chrisacorns.computinghistory.org.uk/8bit_Upgrades/Acorn_ANV02_Music500.html + + Hybrid Music 5000 Synthesiser + + https://www.retro-kit.co.uk/page.cfm/content/Hybrid-Music-5000-Synthesiser/ + http://chrisacorns.computinghistory.org.uk/8bit_Upgrades/Hybrid_Music5000.html + + Hybrid Music 3000 Expander + + https://www.retro-kit.co.uk/page.cfm/content/Hybrid-Music-3000-Expander/ + + Peartree Music 87 Synthesiser + + http://www.computinghistory.org.uk/det/4535/Peartree-Computers-Music-87-Synthesizer-(M500)/ + + TODO: + - convert to use DAC76 device + - add suitably patched version of Ample ROM + - add ROMs for Music 87 + +**********************************************************************/ + + +#include "emu.h" +#include "m5000.h" +#include "speaker.h" +#include "softlist_dev.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(HTMUSIC, htmusic_device, "htmusic", "Hybrid Technology Music System") + +DEFINE_DEVICE_TYPE(BBC_M500, bbc_m500_device, "bbc_m500", "Acorn Music 500"); +DEFINE_DEVICE_TYPE(BBC_M5000, bbc_m5000_device, "bbc_m5000", "Hybrid Music 5000 Synthesiser"); +DEFINE_DEVICE_TYPE(BBC_M3000, bbc_m3000_device, "bbc_m3000", "Hybrid Music 3000 Expander"); +DEFINE_DEVICE_TYPE(BBC_M87, bbc_m87_device, "bbc_m87", "Peartree Music 87 Synthesiser"); + + +//------------------------------------------------- +// ROM( m5000 ) +//------------------------------------------------- + +//ROM_START( m5000 ) + //ROM_REGION(0x4000, "exp_rom", 0) + // Each AMPLE Nucleus ROM has a unique identification code (ID) + //ROM_LOAD("ample_patch.rom", 0x0000, 0x4000, CRC(15bbd499) SHA1(ac90f403b3bde0cdaae68546799b94962bc00fcb)) +//ROM_END + + +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- + +void bbc_m500_device::add_common_devices(machine_config &config) +{ + SPEAKER(config, "lspeaker").front_left(); + SPEAKER(config, "rspeaker").front_right(); + + HTMUSIC(config, m_hybrid, 12_MHz_XTAL / 2); + m_hybrid->add_route(0, "lspeaker", 1.0); + m_hybrid->add_route(1, "rspeaker", 1.0); + + BBC_1MHZBUS_SLOT(config, m_1mhzbus, DERIVED_CLOCK(1, 1), bbc_1mhzbus_devices, nullptr); + m_1mhzbus->irq_handler().set(DEVICE_SELF_OWNER, FUNC(bbc_1mhzbus_slot_device::irq_w)); + m_1mhzbus->nmi_handler().set(DEVICE_SELF_OWNER, FUNC(bbc_1mhzbus_slot_device::nmi_w)); +} + +void bbc_m500_device::device_add_mconfig(machine_config &config) +{ + add_common_devices(config); + + SOFTWARE_LIST(config, "flop_ls_hybrid").set_original("bbc_flop_hybrid").set_filter("M500"); +} + +void bbc_m5000_device::device_add_mconfig(machine_config &config) +{ + add_common_devices(config); + + SOFTWARE_LIST(config, "flop_ls_hybrid").set_original("bbc_flop_hybrid").set_filter("M5000"); +} + +void bbc_m3000_device::device_add_mconfig(machine_config &config) +{ + add_common_devices(config); +} + +void bbc_m87_device::device_add_mconfig(machine_config &config) +{ + add_common_devices(config); + + SOFTWARE_LIST(config, "flop_ls_hybrid").set_original("bbc_flop_hybrid").set_filter("M87"); +} + + +//------------------------------------------------- +// rom_region - device-specific ROM region +//------------------------------------------------- + +//const tiny_rom_entry *bbc_m5000_device::device_rom_region() const +//{ + //return ROM_NAME( m5000 ); +//} + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// bbc_hybrid_device - constructor +//------------------------------------------------- + +bbc_m500_device::bbc_m500_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, type, tag, owner, clock) + , device_bbc_1mhzbus_interface(mconfig, *this) + , m_1mhzbus(*this, "1mhzbus") + , m_hybrid(*this, "hybrid") + , m_page(0) +{ +} + +bbc_m500_device::bbc_m500_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : bbc_m500_device(mconfig, BBC_M500, tag, owner, clock) +{ +} + +bbc_m5000_device::bbc_m5000_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : bbc_m500_device(mconfig, BBC_M5000, tag, owner, clock) +{ +} + +bbc_m3000_device::bbc_m3000_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : bbc_m500_device(mconfig, BBC_M3000, tag, owner, clock) +{ +} + +bbc_m87_device::bbc_m87_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : bbc_m500_device(mconfig, BBC_M87, tag, owner, clock) +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void bbc_m500_device::device_start() +{ + // register for save states + save_item(NAME(m_page)); +} + + +//************************************************************************** +// IMPLEMENTATION +//************************************************************************** + +uint8_t bbc_m500_device::fred_r(offs_t offset) +{ + return m_1mhzbus->fred_r(offset); +} + +void bbc_m500_device::fred_w(offs_t offset, uint8_t data) +{ + if (offset == 0xff) + { + m_page = data; + } + + m_1mhzbus->fred_w(offset, data); +} + +uint8_t bbc_m500_device::jim_r(offs_t offset) +{ + return m_1mhzbus->jim_r(offset); +} + +void bbc_m500_device::jim_w(offs_t offset, uint8_t data) +{ + if ((m_page & 0xf0) == 0x30) + { + uint8_t page = (m_page >> 1) & 7; + + m_hybrid->ram_w((page << 8) | offset, data); + } + + m_1mhzbus->jim_w(offset, data); +} + + +void bbc_m3000_device::jim_w(offs_t offset, uint8_t data) +{ + if ((m_page & 0xf0) == 0x50) + { + uint8_t page = (m_page >> 1) & 7; + + m_hybrid->ram_w((page << 8) | offset, data); + } + + m_1mhzbus->jim_w(offset, data); +} + + +//************************************************************************** +// HYBRID MUSIC IMPLEMENTATION +//************************************************************************** + +//------------------------------------------------- +// htmusic_device - constructor +//------------------------------------------------- + +htmusic_device::htmusic_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, HTMUSIC, tag, owner, clock) + , device_sound_interface(mconfig, *this) + , m_counter(0) + , m_c4d(0) + , m_sign(0) + , m_sam(0) + , m_disable(false) + , m_modulate(false) + , m_dsp_timer(nullptr) + , m_stream(nullptr) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void htmusic_device::device_start() +{ + // 12-bit antilog as per Am6070 datasheet + for (int i = 0; i < 128; i++) + m_antilog[i] = (uint16_t)(2 * (pow(2.0, i >> 4) * ((i & 15) + 16.5) - 16.5)); + + // create the stream + m_stream = stream_alloc(0, 2, clock() / 128); + + // allocate timer + m_dsp_timer = timer_alloc(0); + + // register for save states + save_item(NAME(m_wave_ram)); + save_item(NAME(m_phase_ram)); + save_item(NAME(m_counter)); + save_item(NAME(m_c4d)); + save_item(NAME(m_sign)); + save_item(NAME(m_disable)); + save_item(NAME(m_modulate)); + save_item(NAME(m_sam)); + save_item(NAME(m_sam_l)); + save_item(NAME(m_sam_r)); +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void htmusic_device::device_reset() +{ + // clear ram + memset(m_wave_ram, 0, sizeof(m_wave_ram)); + memset(m_phase_ram, 0, sizeof(m_phase_ram)); + + memset(m_sam_l, 0, sizeof(m_sam_l)); + memset(m_sam_r, 0, sizeof(m_sam_r)); + + // reset counter + m_counter = 0; + m_disable = false; + m_modulate = false; + + // start timer + m_dsp_timer->adjust(attotime::zero, 0, attotime::from_hz(clock())); +} + + +//------------------------------------------------- +// digital signal processor +//------------------------------------------------- + +#define I_CHAN(c) ((((c) & 0x1e) >> 1) + (((c) & 0x01) << 7) + 0x700) +#define I_FREQ(c) (I_CHAN(c)) +#define I_WAVESEL(c) (I_CHAN(c) + 0x50) +#define I_AMP(c) (I_CHAN(c) + 0x60) +#define I_CTL(c) (I_CHAN(c) + 0x70) +#define FREQ(c) ((m_wave_ram[I_FREQ(c) + 0x20] << 16) | (m_wave_ram[I_FREQ(c) + 0x10] << 8) | (m_wave_ram[I_FREQ(c)] & 0x7e)) +#define DISABLE(c) (BIT(m_wave_ram[I_FREQ(c)], 0)) +#define AMP(c) (m_wave_ram[I_AMP(c)]) +#define WAVESEL(c) (m_wave_ram[I_WAVESEL(c)] >> 4) +#define CTL(c) (m_wave_ram[I_CTL(c)]) +#define MODULATE(c) (BIT(CTL(c), 5)) +#define INVERT(c) (BIT(CTL(c), 4)) +#define PAN(c) (CTL(c) & 0x0f) + +void htmusic_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +{ + // 4-bit channel select + uint8_t channel = (m_counter >> 3) & 0x0f; + uint8_t c = (channel << 1) + (m_modulate ? 1 : 0); + + // 3-bit program counter + switch (m_counter & 0x07) + { + case 0: + m_stream->update(); + + m_disable = DISABLE(c); + break; + + case 1: + break; + + case 2: + // In the real hardware the disable bit works by forcing the + // phase accumulator to zero. + if (m_disable) + { + m_phase_ram[channel] = 0; + m_c4d = 0; + } + else + { + uint32_t sum = m_phase_ram[channel] + FREQ(c); + m_phase_ram[channel] = sum & 0xffffff; + // c4d is used for "Synchronization" e.g. the "Wha" instrument + m_c4d = sum >> 24; + } + break; + + case 3: + break; + + case 4: + break; + + case 5: + m_sam = m_wave_ram[(WAVESEL(c) << 7) + (m_phase_ram[channel] >> 17)]; + break; + + case 6: + // The amplitude operates in the log domain + // - m_sam holds the wave table output which is 1 bit sign and 7 bit magnitude + // - amp holds the amplitude which is 1 bit sign and 8 bit magnitude (0x00 being quite, 0x7f being loud) + // The real hardware combines these in a single 8 bit adder, as we do here. + // + // Consider a positive wav value (sign bit = 1) + // wav: (0x80 -> 0xFF) + amp: (0x00 -> 0x7F) => (0x80 -> 0x7E) + // values in the range 0x80...0xff are very small and clamped to zero + // + // Consider a negative wav value (sign bit = 0) + // wav: (0x00 -> 0x7F) + amp: (0x00 -> 0x7F) => (0x00 -> 0xFE) + // values in the range 0x00...0x7f are very small and clamped to zero + // + // In both cases: + // - zero clamping happens when the sign bit stays the same + // - the 7-bit result is in bits 0..6 + // + m_sign = m_sam & 0x80; + m_sam += AMP(c); + if ((m_sign ^ m_sam) & 0x80) + m_sam &= 0x7f; // sign bits being different is the normal case + else + m_sam = 0x00; // sign bits being the same indicates underflow so clamp to zero + break; + + case 7: + { + m_modulate = MODULATE(c) && (!!(m_sign) || !!(m_c4d)); + + // in the real hardware, inversion does not affect modulation + if (INVERT(c)) + m_sign ^= 0x80; + + // m_sam is an 8-bit log value + if (m_sign) + m_sam = m_antilog[m_sam]; // sign being 1 is positive + else + m_sam = -m_antilog[m_sam]; // sign being 0 is negative + + // m_sam is a 12-bit linear sample + uint8_t pan; + switch (PAN(c)) + { + case 8: case 9: case 10: pan = 6; break; + case 11: pan = 5; break; + case 12: pan = 4; break; + case 13: pan = 3; break; + case 14: pan = 2; break; + case 15: pan = 1; break; + default: pan = 0; break; + } + + // Apply panning. In the real hardware, a disabled channel is not actually + // forced to zero, but this seems harmless so leave in for now. + m_sam_l[channel] = m_disable ? 0 : ((m_sam * pan) / 6); + m_sam_r[channel] = m_disable ? 0 : ((m_sam * (6 - pan)) / 6); + break; + } + } + + m_counter++; +} + + +//------------------------------------------------- +// sound_stream_update - handle a stream update +//------------------------------------------------- + +void htmusic_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) +{ + // reset the output streams + outputs[0].fill(0); + outputs[1].fill(0); + + // iterate over channels and accumulate sample data + for (int channel = 0; channel < 16; channel++) + { + for (int sampindex = 0; sampindex < outputs[0].samples(); sampindex++) + { + outputs[0].add_int(sampindex, m_sam_l[channel], 8031 * 16); + outputs[1].add_int(sampindex, m_sam_r[channel], 8031 * 16); + } + } +} diff --git a/src/devices/bus/bbc/1mhzbus/m5000.h b/src/devices/bus/bbc/1mhzbus/m5000.h new file mode 100644 index 00000000000..d2507ab4abe --- /dev/null +++ b/src/devices/bus/bbc/1mhzbus/m5000.h @@ -0,0 +1,158 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Acorn ANV02 Music 500 + + http://chrisacorns.computinghistory.org.uk/8bit_Upgrades/Acorn_ANV02_Music500.html + + Hybrid Music 5000 Synthesiser + + https://www.retro-kit.co.uk/page.cfm/content/Hybrid-Music-5000-Synthesiser/ + http://chrisacorns.computinghistory.org.uk/8bit_Upgrades/Hybrid_Music5000.html + + Hybrid Music 3000 Expander + + https://www.retro-kit.co.uk/page.cfm/content/Hybrid-Music-3000-Expander/ + + Peartree Music 87 Synthesiser + + http://www.computinghistory.org.uk/det/4535/Peartree-Computers-Music-87-Synthesizer-(M500)/ + +**********************************************************************/ + + +#ifndef MAME_BUS_BBC_1MHZBUS_M5000_H +#define MAME_BUS_BBC_1MHZBUS_M5000_H + +#include "1mhzbus.h" + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> htmusic_device + +class htmusic_device : public device_t, public device_sound_interface +{ +public: + htmusic_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + void ram_w(offs_t offset, uint8_t data) { m_wave_ram[offset & 0x7ff] = data; } + + virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + + // sound stream update overrides + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; + +private: + uint16_t m_antilog[128]; + uint8_t m_wave_ram[0x800]; + uint32_t m_phase_ram[0x200]; + + uint8_t m_counter; + uint8_t m_c4d; + uint8_t m_sign; + int16_t m_sam; + bool m_disable; + bool m_modulate; + + int32_t m_sam_l[16]; + int32_t m_sam_r[16]; + + emu_timer *m_dsp_timer; + + sound_stream *m_stream; +}; + + +// ======================> bbc_m500_device + +class bbc_m500_device : public device_t, public device_bbc_1mhzbus_interface +{ +public: + // construction/destruction + bbc_m500_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + bbc_m500_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + + // device-level overrides + virtual void device_start() override; + + // optional information overrides + virtual void device_add_mconfig(machine_config &config) override; + + void add_common_devices(machine_config &config); + + virtual uint8_t fred_r(offs_t offset) override; + virtual void fred_w(offs_t offset, uint8_t data) override; + virtual uint8_t jim_r(offs_t offset) override; + virtual void jim_w(offs_t offset, uint8_t data) override; + + required_device<bbc_1mhzbus_slot_device> m_1mhzbus; + required_device<htmusic_device> m_hybrid; + + uint8_t m_page; +}; + + +// ======================> bbc_m5000_device + +class bbc_m5000_device : public bbc_m500_device +{ +public: + // construction/destruction + bbc_m5000_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + // optional information overrides + virtual void device_add_mconfig(machine_config &config) override; + //virtual const tiny_rom_entry *device_rom_region() const override; +}; + + +// ======================> bbc_m3000_device + +class bbc_m3000_device : public bbc_m500_device +{ +public: + // construction/destruction + bbc_m3000_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + // optional information overrides + virtual void device_add_mconfig(machine_config &config) override; + + virtual void jim_w(offs_t offset, uint8_t data) override; +}; + + +// ======================> bbc_m87_device + +class bbc_m87_device : public bbc_m500_device +{ +public: + // construction/destruction + bbc_m87_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + // optional information overrides + virtual void device_add_mconfig(machine_config &config) override; +}; + + +// device type definition +DECLARE_DEVICE_TYPE(BBC_M500, bbc_m500_device); +DECLARE_DEVICE_TYPE(BBC_M5000, bbc_m5000_device); +DECLARE_DEVICE_TYPE(BBC_M3000, bbc_m3000_device); +DECLARE_DEVICE_TYPE(BBC_M87, bbc_m87_device); + + +#endif /* MAME_BUS_BBC_1MHZBUS_M5000_H */ diff --git a/src/devices/bus/bbc/joyport/joyport.cpp b/src/devices/bus/bbc/joyport/joyport.cpp index 79f285b0670..26abb9678ef 100644 --- a/src/devices/bus/bbc/joyport/joyport.cpp +++ b/src/devices/bus/bbc/joyport/joyport.cpp @@ -40,12 +40,12 @@ device_bbc_joyport_interface::device_bbc_joyport_interface(const machine_config // bbcmc_joyport_slot_device - constructor //------------------------------------------------- -bbc_joyport_slot_device::bbc_joyport_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - device_t(mconfig, BBC_JOYPORT_SLOT, tag, owner, clock), - device_single_card_slot_interface(mconfig, *this), - m_device(nullptr), - m_cb1_handler(*this), - m_cb2_handler(*this) +bbc_joyport_slot_device::bbc_joyport_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, BBC_JOYPORT_SLOT, tag, owner, clock) + , device_single_card_slot_interface(mconfig, *this) + , m_device(nullptr) + , m_cb1_handler(*this) + , m_cb2_handler(*this) { } @@ -70,7 +70,6 @@ void bbc_joyport_slot_device::device_start() uint8_t bbc_joyport_slot_device::pb_r() { - // TODO: Joyport connected to PB0-PB4 only. PB5-PB7 are expansion port. if (m_device) return 0xe0 | m_device->pb_r(); else @@ -90,6 +89,28 @@ void bbc_joyport_slot_device::pb_w(uint8_t data) //------------------------------------------------- +// write_cb1 +//------------------------------------------------- + +void bbc_joyport_slot_device::write_cb1(int state) +{ + if (m_device) + m_device->write_cb1(state); +} + + +//------------------------------------------------- +// write_cb2 +//------------------------------------------------- + +void bbc_joyport_slot_device::write_cb2(int state) +{ + if (m_device) + m_device->write_cb2(state); +} + + +//------------------------------------------------- // SLOT_INTERFACE( bbc_joyport_devices ) //------------------------------------------------- diff --git a/src/devices/bus/bbc/joyport/joyport.h b/src/devices/bus/bbc/joyport/joyport.h index e2d44111995..15d81243d84 100644 --- a/src/devices/bus/bbc/joyport/joyport.h +++ b/src/devices/bus/bbc/joyport/joyport.h @@ -61,11 +61,15 @@ public: auto cb1_handler() { return m_cb1_handler.bind(); } auto cb2_handler() { return m_cb2_handler.bind(); } + // from slot DECLARE_WRITE_LINE_MEMBER(cb1_w) { m_cb1_handler(state); } DECLARE_WRITE_LINE_MEMBER(cb2_w) { m_cb2_handler(state); } + // from host uint8_t pb_r(); void pb_w(uint8_t data); + void write_cb1(int state); + void write_cb2(int state); protected: // device-level overrides @@ -86,6 +90,8 @@ class device_bbc_joyport_interface : public device_interface public: virtual uint8_t pb_r() { return 0xff; } virtual void pb_w(uint8_t data) { } + virtual void write_cb1(int state) { } + virtual void write_cb2(int state) { } protected: device_bbc_joyport_interface(const machine_config &mconfig, device_t &device); diff --git a/src/devices/bus/bbc/tube/tube_32016.cpp b/src/devices/bus/bbc/tube/tube_32016.cpp index 6a54665937d..f621cef4f07 100644 --- a/src/devices/bus/bbc/tube/tube_32016.cpp +++ b/src/devices/bus/bbc/tube/tube_32016.cpp @@ -38,10 +38,6 @@ DEFINE_DEVICE_TYPE(BBC_TUBE_32016L, bbc_tube_32016l_device, "bbc_tube_32016l", " void bbc_tube_32016_device::tube_32016_mem(address_map &map) { - map(0x000000, 0xffffff).rw(FUNC(bbc_tube_32016_device::read), FUNC(bbc_tube_32016_device::write)); - map(0xf00000, 0xf07fff).rom().region("rom", 0).mirror(0x0f8000); - map(0xf90000, 0xf90001).portr("CONFIG"); - map(0xfffff0, 0xffffff).rw("ula", FUNC(tube_device::parasite_r), FUNC(tube_device::parasite_w)).umask16(0x00ff); } //------------------------------------------------- @@ -76,36 +72,36 @@ ROM_END static INPUT_PORTS_START(tube_32016) PORT_START("CONFIG") - PORT_DIPNAME(0x80, 0x80, "H") PORT_DIPLOCATION("LKS:1") - PORT_DIPSETTING(0x80, "FPU") + PORT_DIPNAME(0x01, 0x01, "H") PORT_DIPLOCATION("LKS:1") + PORT_DIPSETTING(0x01, "FPU") PORT_DIPSETTING(0x00, "No FPU") - PORT_DIPNAME(0x40, 0x00, "G") PORT_DIPLOCATION("LKS:2") - PORT_DIPSETTING(0x40, "MMU") + PORT_DIPNAME(0x02, 0x00, "G") PORT_DIPLOCATION("LKS:2") + PORT_DIPSETTING(0x02, "MMU") PORT_DIPSETTING(0x00, "No MMU") - PORT_DIPNAME(0x20, 0x00, "F") PORT_DIPLOCATION("LKS:3") - PORT_DIPSETTING(0x20, "Reserved") + PORT_DIPNAME(0x04, 0x00, "F") PORT_DIPLOCATION("LKS:3") + PORT_DIPSETTING(0x04, "Reserved") PORT_DIPSETTING(0x00, "Reserved") - PORT_DIPNAME(0x10, 0x00, "E") PORT_DIPLOCATION("LKS:4") - PORT_DIPSETTING(0x10, "Reserved") + PORT_DIPNAME(0x08, 0x00, "E") PORT_DIPLOCATION("LKS:4") + PORT_DIPSETTING(0x08, "Reserved") PORT_DIPSETTING(0x00, "Reserved") - PORT_DIPNAME(0x08, 0x00, "D") PORT_DIPLOCATION("LKS:5") - PORT_DIPSETTING(0x08, "Reserved") + PORT_DIPNAME(0x10, 0x00, "D") PORT_DIPLOCATION("LKS:5") + PORT_DIPSETTING(0x10, "Reserved") PORT_DIPSETTING(0x00, "Reserved") - PORT_DIPNAME(0x04, 0x00, "C") PORT_DIPLOCATION("LKS:6") - PORT_DIPSETTING(0x04, "Reserved") + PORT_DIPNAME(0x20, 0x00, "C") PORT_DIPLOCATION("LKS:6") + PORT_DIPSETTING(0x20, "Reserved") PORT_DIPSETTING(0x00, "Reserved") - PORT_DIPNAME(0x02, 0x00, "B") PORT_DIPLOCATION("LKS:7") - PORT_DIPSETTING(0x02, "Reserved") + PORT_DIPNAME(0x40, 0x00, "B") PORT_DIPLOCATION("LKS:7") + PORT_DIPSETTING(0x40, "Reserved") PORT_DIPSETTING(0x00, "Reserved") - PORT_DIPNAME(0x01, 0x00, "A") PORT_DIPLOCATION("LKS:8") - PORT_DIPSETTING(0x01, "Reserved") + PORT_DIPNAME(0x80, 0x00, "A") PORT_DIPLOCATION("LKS:8") + PORT_DIPSETTING(0x80, "Reserved") PORT_DIPSETTING(0x00, "Reserved") INPUT_PORTS_END @@ -117,13 +113,16 @@ void bbc_tube_32016_device::device_add_mconfig(machine_config &config) { NS32016(config, m_maincpu, 12_MHz_XTAL / 2); m_maincpu->set_addrmap(AS_PROGRAM, &bbc_tube_32016_device::tube_32016_mem); + m_maincpu->set_fpu(m_ns32081); + + NS32081(config, m_ns32081, 12_MHz_XTAL / 2); TUBE(config, m_ula); m_ula->pnmi_handler().set_inputline(m_maincpu, INPUT_LINE_NMI); m_ula->pirq_handler().set_inputline(m_maincpu, INPUT_LINE_IRQ0); /* internal ram */ - RAM(config, m_ram).set_default_size("1M").set_extra_options("256K"); + RAM(config, m_ram).set_default_size("1M").set_extra_options("256K").set_default_value(0); /* software lists */ SOFTWARE_LIST(config, "flop_ls_32016").set_original("bbc_flop_32016"); @@ -137,7 +136,7 @@ void bbc_tube_32016l_device::device_add_mconfig(machine_config &config) m_maincpu->set_clock(16_MHz_XTAL / 2); /* internal ram */ - m_ram->set_default_size("4M"); + m_ram->set_default_size("4M").set_extra_options("1M").set_default_value(0); } //------------------------------------------------- @@ -175,10 +174,10 @@ bbc_tube_32016_device::bbc_tube_32016_device(const machine_config &mconfig, devi : device_t(mconfig, type, tag, owner, clock) , device_bbc_tube_interface(mconfig, *this) , m_maincpu(*this, "maincpu") + , m_ns32081(*this, "ns32081") , m_ula(*this, "ula") , m_ram(*this, "ram") , m_rom(*this, "rom") - , m_rom_enabled(true) { } @@ -198,7 +197,6 @@ bbc_tube_32016l_device::bbc_tube_32016l_device(const machine_config &mconfig, co void bbc_tube_32016_device::device_start() { - save_item(NAME(m_rom_enabled)); } //------------------------------------------------- @@ -207,7 +205,23 @@ void bbc_tube_32016_device::device_start() void bbc_tube_32016_device::device_reset() { - m_rom_enabled = true; + address_space &program = m_maincpu->space(AS_PROGRAM); + + // address map during booting + program.install_rom(0x000000, 0x007fff, 0xff8000, m_rom->base()); + + m_rom_shadow_tap = program.install_write_tap(0x000000, 0xffffff, "rom_shadow_w",[this](offs_t offset, u16 &data, u16 mem_mask) + { + // delete this tap + m_rom_shadow_tap->remove(); + + // address map after booting + m_maincpu->space(AS_PROGRAM).nop_readwrite(0x000000, 0xffffff); + m_maincpu->space(AS_PROGRAM).install_ram(0x000000, m_ram->mask(), 0x7fffff ^ m_ram->mask(), m_ram->pointer()); + m_maincpu->space(AS_PROGRAM).install_rom(0xf00000, 0xf07fff, 0x038000, m_rom->base()); + m_maincpu->space(AS_PROGRAM).install_read_port(0xf90000, 0xf90001, 0x00fffe, "CONFIG"); + m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0xfffff0, 0xffffff, read8sm_delegate(*m_ula, FUNC(tube_device::parasite_r)), write8sm_delegate(*m_ula, FUNC(tube_device::parasite_w)), 0xff); + }); } @@ -224,24 +238,3 @@ void bbc_tube_32016_device::host_w(offs_t offset, uint8_t data) { m_ula->host_w(offset, data); } - - -uint8_t bbc_tube_32016_device::read(offs_t offset) -{ - uint16_t data; - - if (m_rom_enabled) - data = m_rom->base()[offset & 0x7fff]; - else - data = m_ram->pointer()[offset & m_ram->mask()]; - - return data; -} - -void bbc_tube_32016_device::write(offs_t offset, uint8_t data) -{ - /* clear ROM select on first write */ - m_rom_enabled = false; - - m_ram->pointer()[offset & m_ram->mask()] = data; -} diff --git a/src/devices/bus/bbc/tube/tube_32016.h b/src/devices/bus/bbc/tube/tube_32016.h index 7e7753ae5f6..aa772e1369c 100644 --- a/src/devices/bus/bbc/tube/tube_32016.h +++ b/src/devices/bus/bbc/tube/tube_32016.h @@ -18,6 +18,7 @@ #include "tube.h" #include "cpu/ns32000/ns32000.h" +#include "machine/ns32081.h" #include "machine/ram.h" #include "machine/tube.h" @@ -51,16 +52,14 @@ protected: virtual void host_w(offs_t offset, uint8_t data) override; required_device<ns32016_device> m_maincpu; + required_device<ns32081_device> m_ns32081; required_device<tube_device> m_ula; required_device<ram_device> m_ram; required_memory_region m_rom; - uint8_t read(offs_t offset); - void write(offs_t offset, uint8_t data); + memory_passthrough_handler *m_rom_shadow_tap; void tube_32016_mem(address_map &map); - - bool m_rom_enabled; }; diff --git a/src/devices/bus/bbc/userport/lcd.cpp b/src/devices/bus/bbc/userport/lcd.cpp index cdc70bc35fe..f5f92270ca9 100644 --- a/src/devices/bus/bbc/userport/lcd.cpp +++ b/src/devices/bus/bbc/userport/lcd.cpp @@ -87,7 +87,7 @@ HD44780_PIXEL_UPDATE(bbc_lcd_device::lcd_pixel_update) } if (line < 4) - bitmap.pix16(line * (8 + 1) + y, pos * 6 + x) = state ? 1 : 2; + bitmap.pix(line * (8 + 1) + y, pos * 6 + x) = state ? 1 : 2; } } diff --git a/src/devices/bus/bbc/userport/m4000.cpp b/src/devices/bus/bbc/userport/m4000.cpp new file mode 100644 index 00000000000..910f2f8b3f1 --- /dev/null +++ b/src/devices/bus/bbc/userport/m4000.cpp @@ -0,0 +1,170 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Hybrid Music 4000 Keyboard (also known as ATPL Symphony) + + https://www.retro-kit.co.uk/page.cfm/content/Hybrid-Music-4000-Keyboard/ + http://chrisacorns.computinghistory.org.uk/8bit_Upgrades/Hybrid_Music4000.html + +**********************************************************************/ + + +#include "emu.h" +#include "m4000.h" + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(BBC_M4000, bbc_m4000_device, "bbc_m4000", "Hybrid Music 4000 Keyboard") + + +//------------------------------------------------- +// INPUT_PORTS( m4000 ) +//------------------------------------------------- + +static INPUT_PORTS_START( m4000 ) + PORT_START("KBLOCK_1") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("C2") + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("C2#") + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("D2") + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("D2#") + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("E2") + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("F2") + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("F2#") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("G2") + + PORT_START("KBLOCK_2") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("G2#") + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("A2") + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("A2#") + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("B2") + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("C3") + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("C3#") + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("D3") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("D3#") + + PORT_START("KBLOCK_3") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("E3") + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("F3") + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("F3#") + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("G3") + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("G3#") + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("A3") + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("A3#") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("B3") + + PORT_START("KBLOCK_4") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("C4") + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("C4#") + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("D4") + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("D4#") + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("E4") + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("F4") + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("F4#") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("G4") + + PORT_START("KBLOCK_5") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("G4#") + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("A4") + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("A4#") + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("B4") + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("C5") + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("C5#") + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("D5") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("D5#") + + PORT_START("KBLOCK_6") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("E5") + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("F5") + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("F5#") + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("G5") + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("G5#") + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("A5") + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("A5#") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("B5") + + PORT_START("KBLOCK_7") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("C6") + PORT_BIT(0xfe, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_START("KBLOCK_8") + PORT_BIT(0x7f, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Foot Switch") +INPUT_PORTS_END + + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +ioport_constructor bbc_m4000_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( m4000 ); +} + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// bbc_m4000_device - constructor +//------------------------------------------------- + +bbc_m4000_device::bbc_m4000_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, BBC_M4000, tag, owner, clock) + , device_bbc_userport_interface(mconfig, *this) + , m_kbd(*this, "KBLOCK_%u", 1) + , m_clk(0) + , m_dsb(0) + , m_out(0) +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void bbc_m4000_device::device_start() +{ + save_item(NAME(m_clk)); + save_item(NAME(m_dsb)); + save_item(NAME(m_out)); +} + + +//************************************************************************** +// IMPLEMENTATION +//************************************************************************** + +void bbc_m4000_device::write_cb1(int state) +{ + // 74hc164 + if (!m_clk && state) + { + m_out = (m_out << 1) | m_dsb; + } + m_clk = state; +} + +void bbc_m4000_device::write_cb2(int state) +{ + // 74hc164 + m_dsb = state; +} + +uint8_t bbc_m4000_device::pb_r() +{ + uint8_t data = 0xff; + + for (int block = 0; block < 8; block++) + { + if (!BIT(m_out, block)) + data = m_kbd[block]->read(); + } + + return data; +} diff --git a/src/devices/bus/bbc/userport/m4000.h b/src/devices/bus/bbc/userport/m4000.h new file mode 100644 index 00000000000..df9c5e556cf --- /dev/null +++ b/src/devices/bus/bbc/userport/m4000.h @@ -0,0 +1,58 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Hybrid Music 4000 Keyboard + + https://www.retro-kit.co.uk/page.cfm/content/Hybrid-Music-4000-Keyboard/ + http://chrisacorns.computinghistory.org.uk/8bit_Upgrades/Hybrid_Music4000.html + +**********************************************************************/ + + +#ifndef MAME_BUS_BBC_USERPORT_M4000_H +#define MAME_BUS_BBC_USERPORT_M4000_H + +#pragma once + +#include "userport.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> bbc_m4000_device + +class bbc_m4000_device : + public device_t, + public device_bbc_userport_interface +{ +public: + // construction/destruction + bbc_m4000_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + // device-level overrides + virtual void device_start() override; + + // optional information overrides + virtual ioport_constructor device_input_ports() const override; + + virtual uint8_t pb_r() override; + virtual void write_cb1(int state) override; + virtual void write_cb2(int state) override; + +private: + required_ioport_array<8> m_kbd; + + int m_clk; + int m_dsb; + uint8_t m_out; +}; + + +// device type definition +DECLARE_DEVICE_TYPE(BBC_M4000, bbc_m4000_device) + + +#endif // MAME_BUS_BBC_USERPORT_M4000_H diff --git a/src/devices/bus/bbc/userport/userport.cpp b/src/devices/bus/bbc/userport/userport.cpp index d312cc10d50..3091c04f816 100644 --- a/src/devices/bus/bbc/userport/userport.cpp +++ b/src/devices/bus/bbc/userport/userport.cpp @@ -51,12 +51,12 @@ device_bbc_userport_interface::~device_bbc_userport_interface() // bbc_userport_slot_device - constructor //------------------------------------------------- -bbc_userport_slot_device::bbc_userport_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - device_t(mconfig, BBC_USERPORT_SLOT, tag, owner, clock), - device_single_card_slot_interface<device_bbc_userport_interface>(mconfig, *this), - m_device(nullptr), - m_cb1_handler(*this), - m_cb2_handler(*this) +bbc_userport_slot_device::bbc_userport_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, BBC_USERPORT_SLOT, tag, owner, clock) + , device_single_card_slot_interface<device_bbc_userport_interface>(mconfig, *this) + , m_device(nullptr) + , m_cb1_handler(*this) + , m_cb2_handler(*this) { } @@ -101,6 +101,28 @@ void bbc_userport_slot_device::pb_w(uint8_t data) //------------------------------------------------- +// write_cb1 +//------------------------------------------------- + +void bbc_userport_slot_device::write_cb1(int state) +{ + if (m_device) + m_device->write_cb1(state); +} + + +//------------------------------------------------- +// write_cb2 +//------------------------------------------------- + +void bbc_userport_slot_device::write_cb2(int state) +{ + if (m_device) + m_device->write_cb2(state); +} + + +//------------------------------------------------- // SLOT_INTERFACE( bbc_userport_devices ) //------------------------------------------------- @@ -110,6 +132,7 @@ void bbc_userport_slot_device::pb_w(uint8_t data) //#include "digitiser.h" //#include "ev1.h" #include "lcd.h" +#include "m4000.h" #include "palext.h" #include "pointer.h" #include "usersplit.h" @@ -129,11 +152,11 @@ void bbc_userport_devices(device_slot_interface &device) //device.option_add("ev1", BBC_EV1); /* Micro-Robotics EV1 */ //device.option_add("hobbit", BBC_HOBBIT); /* Hobbit Floppy Tape System (Ikon) */ device.option_add("lcd", BBC_LCD); /* Sprow LCD Display */ + device.option_add("m4000", BBC_M4000); /* Hybrid Music 4000 Keyboard */ device.option_add("m512mouse", BBC_M512MOUSE); /* Acorn Mouse (provided with Master 512) */ device.option_add("tracker", BBC_TRACKER); /* Marconi RB2 Tracker Ball / Acorn Tracker Ball */ device.option_add("usersplit", BBC_USERSPLIT); /*User Port Splitter (Watford Electronics) */ //device.option_add("vci", BBC_VCI); /* Video Camera Interface (Data Harvest) */ device.option_add("voicebox", BBC_VOICEBOX); /* Robin Voice Box */ - //device.option_add("music4000", BBC_MUSIC4000); /* Hybrid Music 4000 Keyboard */ device.option_add_internal("cfa3000kbd", CFA3000_KBD);/* Henson CFA 3000 Keyboard */ } diff --git a/src/devices/bus/bbc/userport/userport.h b/src/devices/bus/bbc/userport/userport.h index c0a0b560eac..29374eb9058 100644 --- a/src/devices/bus/bbc/userport/userport.h +++ b/src/devices/bus/bbc/userport/userport.h @@ -61,11 +61,15 @@ public: auto cb1_handler() { return m_cb1_handler.bind(); } auto cb2_handler() { return m_cb2_handler.bind(); } + // from slot DECLARE_WRITE_LINE_MEMBER(cb1_w) { m_cb1_handler(state); } DECLARE_WRITE_LINE_MEMBER(cb2_w) { m_cb2_handler(state); } + // from host uint8_t pb_r(); void pb_w(uint8_t data); + void write_cb1(int state); + void write_cb2(int state); protected: // device-level overrides @@ -89,6 +93,8 @@ public: virtual uint8_t pb_r() { return 0xff; } virtual void pb_w(uint8_t data) { } + virtual void write_cb1(int state) { } + virtual void write_cb2(int state) { } protected: device_bbc_userport_interface(const machine_config &mconfig, device_t &device); diff --git a/src/devices/bus/bbc/userport/usersplit.cpp b/src/devices/bus/bbc/userport/usersplit.cpp index abe6ec155bf..520abaebdb9 100644 --- a/src/devices/bus/bbc/userport/usersplit.cpp +++ b/src/devices/bus/bbc/userport/usersplit.cpp @@ -98,6 +98,17 @@ void bbc_usersplit_device::pb_w(uint8_t data) m_userport[m_selected]->pb_w(data); } +void bbc_usersplit_device::write_cb1(int state) +{ + m_userport[m_selected]->write_cb1(state); +} + +void bbc_usersplit_device::write_cb2(int state) +{ + m_userport[m_selected]->write_cb2(state); +} + + WRITE_LINE_MEMBER(bbc_usersplit_device::cb1a_w) { if (m_selected == 0x00) diff --git a/src/devices/bus/bbc/userport/usersplit.h b/src/devices/bus/bbc/userport/usersplit.h index d10a31a3eb2..27ce11a9fde 100644 --- a/src/devices/bus/bbc/userport/usersplit.h +++ b/src/devices/bus/bbc/userport/usersplit.h @@ -40,6 +40,8 @@ protected: virtual uint8_t pb_r() override; virtual void pb_w(uint8_t data) override; + virtual void write_cb1(int state) override; + virtual void write_cb2(int state) override; private: DECLARE_WRITE_LINE_MEMBER(cb1a_w); diff --git a/src/devices/bus/bw2/ramcard.cpp b/src/devices/bus/bw2/ramcard.cpp index 48de6cffdec..b1e0bfe5bcf 100644 --- a/src/devices/bus/bw2/ramcard.cpp +++ b/src/devices/bus/bw2/ramcard.cpp @@ -90,15 +90,17 @@ void bw2_ramcard_device::device_reset() uint8_t bw2_ramcard_device::bw2_cd_r(offs_t offset, uint8_t data, int ram2, int ram3, int ram4, int ram5, int ram6) { - if (!ram2) + if (offset < 0x8000) { - data = m_rom->base()[offset & 0x3fff]; + if (!ram2) + { + data = m_rom->base()[offset & 0x3fff]; + } + else if (m_en && !ram5) + { + data = m_ram[(m_bank << 15) | offset]; + } } - else if (m_en && !ram5) - { - data = m_ram[(m_bank << 15) | offset]; - } - return data; } @@ -109,9 +111,12 @@ uint8_t bw2_ramcard_device::bw2_cd_r(offs_t offset, uint8_t data, int ram2, int void bw2_ramcard_device::bw2_cd_w(offs_t offset, uint8_t data, int ram2, int ram3, int ram4, int ram5, int ram6) { - if (m_en && !ram5) + if (offset < 0x8000) { - m_ram[(m_bank << 15) | offset] = data; + if (m_en && !ram5) + { + m_ram[(m_bank << 15) | offset] = data; + } } } diff --git a/src/devices/bus/c64/xl80.cpp b/src/devices/bus/c64/xl80.cpp index 8f0f35b523f..6bfa6e9d8cd 100644 --- a/src/devices/bus/c64/xl80.cpp +++ b/src/devices/bus/c64/xl80.cpp @@ -85,12 +85,12 @@ const tiny_rom_entry *c64_xl80_device::device_rom_region() const MC6845_UPDATE_ROW( c64_xl80_device::crtc_update_row ) { - const pen_t *pen = m_palette->pens(); + pen_t const *const pen = m_palette->pens(); for (int column = 0; column < x_count; column++) { - uint8_t code = m_ram[((ma + column) & 0x7ff)]; - uint16_t addr = (code << 3) | (ra & 0x07); + uint8_t const code = m_ram[((ma + column) & 0x7ff)]; + uint16_t const addr = (code << 3) | (ra & 0x07); uint8_t data = m_char_rom->base()[addr & 0x7ff]; if (column == cursor_x) @@ -100,10 +100,10 @@ MC6845_UPDATE_ROW( c64_xl80_device::crtc_update_row ) for (int bit = 0; bit < 8; bit++) { - int x = (column * 8) + bit; - int color = BIT(data, 7) && de; + int const x = (column * 8) + bit; + int const color = BIT(data, 7) && de; - bitmap.pix32(vbp + y, hbp + x) = pen[color]; + bitmap.pix(vbp + y, hbp + x) = pen[color]; data <<= 1; } diff --git a/src/devices/bus/cbmiec/cbmiec.cpp b/src/devices/bus/cbmiec/cbmiec.cpp index 98535963034..4ee8f287200 100644 --- a/src/devices/bus/cbmiec/cbmiec.cpp +++ b/src/devices/bus/cbmiec/cbmiec.cpp @@ -338,7 +338,7 @@ void cbm_iec_device::device_stop() void cbm_iec_device::add_device(cbm_iec_slot_device *slot, device_t *target) { - auto entry = global_alloc(daisy_entry(target)); + auto entry = new daisy_entry(target); entry->m_interface->m_slot = slot; entry->m_interface->m_bus = this; diff --git a/src/devices/bus/centronics/epson_lx810l.cpp b/src/devices/bus/centronics/epson_lx810l.cpp index 1d9c0ac8577..2744ea3e3ac 100644 --- a/src/devices/bus/centronics/epson_lx810l.cpp +++ b/src/devices/bus/centronics/epson_lx810l.cpp @@ -575,9 +575,9 @@ WRITE_LINE_MEMBER( epson_lx810l_device::co0_w ) */ if (m_real_cr_pos < m_bitmap.width()) { for (int i = 0; i < 9; i++) { - unsigned int y = bitmap_line(i); + unsigned int const y = bitmap_line(i); if ((m_printhead & (1<<(8-i))) != 0) - m_bitmap.pix32(y, m_real_cr_pos + CR_OFFSET) = 0x000000; + m_bitmap.pix(y, m_real_cr_pos + CR_OFFSET) = 0x000000; } } } diff --git a/src/devices/bus/coco/coco_ssc.cpp b/src/devices/bus/coco/coco_ssc.cpp index 63f6e90fcc5..3677010648f 100644 --- a/src/devices/bus/coco/coco_ssc.cpp +++ b/src/devices/bus/coco/coco_ssc.cpp @@ -130,7 +130,7 @@ namespace virtual void device_start() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: sound_stream* m_stream; @@ -535,25 +535,25 @@ cocossc_sac_device::cocossc_sac_device(const machine_config &mconfig, const char void cocossc_sac_device::device_start() { - m_stream = stream_alloc_legacy(1, 1, machine().sample_rate()); + m_stream = stream_alloc(1, 1, machine().sample_rate()); } //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void cocossc_sac_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void cocossc_sac_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - stream_sample_t const *src = inputs[0]; - stream_sample_t *dst = outputs[0]; + auto &src = inputs[0]; + auto &dst = outputs[0]; - double n = samples; + double n = dst.samples(); - while (samples--) + for (int sampindex = 0; sampindex < n; sampindex++) { - m_rms[m_index] += ( (double)*src * (double)*src ); - *dst++ = (*src++); + m_rms[m_index] += src.get(sampindex) * src.get(sampindex); + dst.put(sampindex, src.get(sampindex)); } m_rms[m_index] = m_rms[m_index] / n; @@ -576,7 +576,7 @@ bool cocossc_sac_device::sound_activity_circuit_output() average /= 16.0; - if( average > 10400.0 ) + if( average > 0.317 ) return true; return false; diff --git a/src/devices/bus/compis/hrg.cpp b/src/devices/bus/compis/hrg.cpp index 7aa8aa72f7e..1612729e706 100644 --- a/src/devices/bus/compis/hrg.cpp +++ b/src/devices/bus/compis/hrg.cpp @@ -51,11 +51,11 @@ void compis_uhrg_device::uhrg_map(address_map &map) UPD7220_DISPLAY_PIXELS_MEMBER( compis_hrg_device::display_pixels ) { - uint16_t i,gfx = m_video_ram[(address & 0x7fff) >> 1]; - const pen_t *pen = m_palette->pens(); + uint16_t const gfx = m_video_ram[(address & 0x7fff) >> 1]; + pen_t const *const pen = m_palette->pens(); - for(i=0; i<16; i++) - bitmap.pix32(y, x + i) = pen[BIT(gfx, i)]; + for(uint16_t i=0; i<16; i++) + bitmap.pix(y, x + i) = pen[BIT(gfx, i)]; } @@ -65,11 +65,11 @@ UPD7220_DISPLAY_PIXELS_MEMBER( compis_hrg_device::display_pixels ) UPD7220_DISPLAY_PIXELS_MEMBER( compis_uhrg_device::display_pixels ) { - uint16_t i,gfx = m_video_ram[(address & 0x1ffff) >> 1]; - const pen_t *pen = m_palette->pens(); + uint16_t const gfx = m_video_ram[(address & 0x1ffff) >> 1]; + pen_t const *const pen = m_palette->pens(); - for(i=0; i<16; i++) - bitmap.pix32(y, x + i) = pen[BIT(gfx, i)]; + for(uint16_t i=0; i<16; i++) + bitmap.pix(y, x + i) = pen[BIT(gfx, i)]; } diff --git a/src/devices/bus/comx35/clm.cpp b/src/devices/bus/comx35/clm.cpp index ebf7e1f271e..192e5989a36 100644 --- a/src/devices/bus/comx35/clm.cpp +++ b/src/devices/bus/comx35/clm.cpp @@ -104,8 +104,8 @@ MC6845_UPDATE_ROW( comx_clm_device::crtc_update_row ) { for (int column = 0; column < x_count; column++) { - uint8_t code = m_video_ram[((ma + column) & 0x7ff)]; - uint16_t addr = (code << 3) | (ra & 0x07); + uint8_t const code = m_video_ram[((ma + column) & 0x7ff)]; + uint16_t const addr = (code << 3) | (ra & 0x07); uint8_t data = m_char_rom->base()[addr & 0x7ff]; if (BIT(ra, 3) && column == cursor_x) @@ -115,9 +115,9 @@ MC6845_UPDATE_ROW( comx_clm_device::crtc_update_row ) for (int bit = 0; bit < 8; bit++) { - int x = (column * 8) + bit; + int const x = (column * 8) + bit; - bitmap.pix32(vbp + y, hbp + x) = m_palette->pen(BIT(data, 7) && de); + bitmap.pix(vbp + y, hbp + x) = m_palette->pen(BIT(data, 7) && de); data <<= 1; } diff --git a/src/devices/bus/ecbbus/grip.cpp b/src/devices/bus/ecbbus/grip.cpp index 88e3d2fe23b..659bab524ad 100644 --- a/src/devices/bus/ecbbus/grip.cpp +++ b/src/devices/bus/ecbbus/grip.cpp @@ -179,35 +179,33 @@ MC6845_UPDATE_ROW( ecb_grip21_device::crtc_update_row ) { for (int column = 0; column < x_count; column++) { - uint16_t address = (m_page << 12) | (((ma + column) & 0xfff) << 3) | (ra & 0x07); - uint8_t data = m_video_ram[address]; + uint16_t const address = (m_page << 12) | (((ma + column) & 0xfff) << 3) | (ra & 0x07); + uint8_t const data = m_video_ram[address]; for (int bit = 0; bit < 8; bit++) { - int x = (column * 8) + bit; - int color = (m_flash ? 0 : BIT(data, bit)) && de; + int const x = (column * 8) + bit; + int const color = (m_flash ? 0 : BIT(data, bit)) && de; - bitmap.pix32(vbp + y, hbp + x) = m_palette->pen(color); + bitmap.pix(vbp + y, hbp + x) = m_palette->pen(color); } } } /* MC6845_UPDATE_ROW( ecb_grip21_device::grip5_update_row ) { - const rgb_t *palette = m_palette->palette()->entry_list_raw(); - int column, bit; - - for (column = 0; column < x_count; column++) + rgb_t const *const palette = m_palette->palette()->entry_list_raw(); + for (int column = 0; column < x_count; column++) { - uint16_t address = (m_dpage << 12) | (((ma + column) & 0xfff) << 3) | (ra & 0x07); - uint8_t data = m_video_ram[address]; + uint16_t const address = (m_dpage << 12) | (((ma + column) & 0xfff) << 3) | (ra & 0x07); + uint8_t const data = m_video_ram[address]; - for (bit = 0; bit < 8; bit++) + for (int bit = 0; bit < 8; bit++) { - int x = (column * 8) + bit; - int color = m_flash ? 0 : BIT(data, bit); + int const x = (column * 8) + bit; + int const color = m_flash ? 0 : BIT(data, bit); - bitmap.pix32(y, x) = palette[color]; + bitmap.pix(y, x) = palette[color]; } } } @@ -217,7 +215,7 @@ MC6845_ON_UPDATE_ADDR_CHANGED( ecb_grip21_device::grip5_addr_changed ) } */ -static const int16_t speaker_levels[] = { -32768, 0, 32767, 0 }; +static const double speaker_levels[] = { -1.0, 0.0, 1.0, 0.0 }; //------------------------------------------------- // I8255A interface diff --git a/src/devices/bus/econet/econet.cpp b/src/devices/bus/econet/econet.cpp index f87850fe133..e9afc9c0d49 100644 --- a/src/devices/bus/econet/econet.cpp +++ b/src/devices/bus/econet/econet.cpp @@ -223,7 +223,7 @@ void econet_device::device_stop() void econet_device::add_device(device_t *target, int address) { - auto entry = global_alloc(daisy_entry(target)); + auto entry = new daisy_entry(target); entry->m_interface->m_econet = this; entry->m_interface->m_address = address; diff --git a/src/devices/bus/einstein/pipe/tk02.cpp b/src/devices/bus/einstein/pipe/tk02.cpp index b0cf5998131..74cd880e151 100644 --- a/src/devices/bus/einstein/pipe/tk02.cpp +++ b/src/devices/bus/einstein/pipe/tk02.cpp @@ -185,14 +185,14 @@ MC6845_UPDATE_ROW( tk02_device::crtc_update_row ) if (i == cursor_x) data ^= 0xff; - bitmap.pix32(y, i * 8 + 0) = pen[BIT(data, 7)]; - bitmap.pix32(y, i * 8 + 1) = pen[BIT(data, 6)]; - bitmap.pix32(y, i * 8 + 2) = pen[BIT(data, 5)]; - bitmap.pix32(y, i * 8 + 3) = pen[BIT(data, 4)]; - bitmap.pix32(y, i * 8 + 4) = pen[BIT(data, 3)]; - bitmap.pix32(y, i * 8 + 5) = pen[BIT(data, 2)]; - bitmap.pix32(y, i * 8 + 6) = pen[BIT(data, 1)]; - bitmap.pix32(y, i * 8 + 7) = pen[BIT(data, 0)]; + bitmap.pix(y, i * 8 + 0) = pen[BIT(data, 7)]; + bitmap.pix(y, i * 8 + 1) = pen[BIT(data, 6)]; + bitmap.pix(y, i * 8 + 2) = pen[BIT(data, 5)]; + bitmap.pix(y, i * 8 + 3) = pen[BIT(data, 4)]; + bitmap.pix(y, i * 8 + 4) = pen[BIT(data, 3)]; + bitmap.pix(y, i * 8 + 5) = pen[BIT(data, 2)]; + bitmap.pix(y, i * 8 + 6) = pen[BIT(data, 1)]; + bitmap.pix(y, i * 8 + 7) = pen[BIT(data, 0)]; } } diff --git a/src/devices/bus/electron/cart/ap5.cpp b/src/devices/bus/electron/cart/ap5.cpp index c65daf911d4..3deacaa655b 100644 --- a/src/devices/bus/electron/cart/ap5.cpp +++ b/src/devices/bus/electron/cart/ap5.cpp @@ -36,6 +36,8 @@ void electron_ap5_device::device_add_mconfig(machine_config &config) VIA6522(config, m_via, DERIVED_CLOCK(1, 16)); m_via->readpb_handler().set(m_userport, FUNC(bbc_userport_slot_device::pb_r)); m_via->writepb_handler().set(m_userport, FUNC(bbc_userport_slot_device::pb_w)); + m_via->cb1_handler().set(m_userport, FUNC(bbc_userport_slot_device::write_cb1)); + m_via->cb2_handler().set(m_userport, FUNC(bbc_userport_slot_device::write_cb2)); m_via->irq_handler().set(m_irqs, FUNC(input_merger_device::in_w<0>)); /* user port */ diff --git a/src/devices/bus/electron/mode7.cpp b/src/devices/bus/electron/mode7.cpp index 103c861c4ae..408b6a92300 100644 --- a/src/devices/bus/electron/mode7.cpp +++ b/src/devices/bus/electron/mode7.cpp @@ -195,7 +195,7 @@ void electron_mode7_device::expbus_w(offs_t offset, uint8_t data) MC6845_UPDATE_ROW(electron_mode7_device::crtc_update_row) { - uint32_t* p = &bitmap.pix32(y); + uint32_t* p = &bitmap.pix(y); m_trom->lose_w(1); m_trom->lose_w(0); diff --git a/src/devices/bus/electron/plus2.cpp b/src/devices/bus/electron/plus2.cpp index f0e28d73150..1e9d9d6591b 100644 --- a/src/devices/bus/electron/plus2.cpp +++ b/src/devices/bus/electron/plus2.cpp @@ -53,6 +53,8 @@ void electron_plus2_device::device_add_mconfig(machine_config &config) VIA6522(config, m_via, DERIVED_CLOCK(1, 16)); m_via->readpb_handler().set(m_userport, FUNC(bbc_userport_slot_device::pb_r)); m_via->writepb_handler().set(m_userport, FUNC(bbc_userport_slot_device::pb_w)); + m_via->cb1_handler().set(m_userport, FUNC(bbc_userport_slot_device::write_cb1)); + m_via->cb2_handler().set(m_userport, FUNC(bbc_userport_slot_device::write_cb2)); m_via->irq_handler().set(m_irqs, FUNC(input_merger_device::in_w<2>)); /* user port */ diff --git a/src/devices/bus/fmt_scsi/fmt121.cpp b/src/devices/bus/fmt_scsi/fmt121.cpp new file mode 100644 index 00000000000..34f784115a0 --- /dev/null +++ b/src/devices/bus/fmt_scsi/fmt121.cpp @@ -0,0 +1,150 @@ +// license:BSD-3-Clause +// copyright-holders:r09 +/**************************************************************************** + + Fujitsu FMT-121 SCSI Card + + An expansion card for the dedicated SCSI card slot on the FM Towns + Model 1 and 2 computers. It contains a Fujitsu MB673522U SCSI controller + and an external 50-pin Centronics connector. + + ||||||||||||||||||||| ++-------------------------| |-------------------------+ +| CN1 +-------------------+ | +| | +| 74LS04N | +| 74LS14N 74LS240N SN74LS06N | +| MB413 | +| MB463 | +| 74AS00N | +| +-----------+ | +| MB463 | | | +| | MB673522U | MB412 | +| +-----------+ | +| MB463 74LS240N | +| CN3 | +| .......................................... | +| . . | +| .......................................... | +| CN2 | +| +----------------------------------------+ | +| | | | ++--------------| |---------------+ + |||||||||||||||||||||||||||||||||||||||||| + + CN1: 30-pin MFC-30LFD DIP connector + CN2: 50-pin Centronics connector + CN3: solder pads for internal 50-pin connector (not present) + +****************************************************************************/ + +#include "emu.h" +#include "fmt121.h" + +#include "bus/scsi/scsi.h" +#include "bus/scsi/scsihd.h" + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +// device type definition +DEFINE_DEVICE_TYPE(FMT121, fmt121_device, "fmt121", "FMT-121 SCSI Card") + +//************************************************************************** +// DEVICE DEFINITION +//************************************************************************** + +//------------------------------------------------- +// fmt121_device - construction +//------------------------------------------------- + +fmt121_device::fmt121_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, FMT121, tag, owner, clock) + , fmt_scsi_card_interface(mconfig, *this) + , m_scsi_ctlr(*this, "fmscsi") +{ +} + + +//------------------------------------------------- +// device_add_mconfig - add device-specific +// machine configuration +//------------------------------------------------- + +void fmt121_device::device_add_mconfig(machine_config &config) +{ + scsi_port_device &scsi(SCSI_PORT(config, "scsi", 0)); + scsi.set_slot_device(1, "harddisk", SCSIHD, DEVICE_INPUT_DEFAULTS_NAME(SCSI_ID_0)); + scsi.set_slot_device(2, "harddisk", SCSIHD, DEVICE_INPUT_DEFAULTS_NAME(SCSI_ID_1)); + scsi.set_slot_device(3, "harddisk", SCSIHD, DEVICE_INPUT_DEFAULTS_NAME(SCSI_ID_2)); + scsi.set_slot_device(4, "harddisk", SCSIHD, DEVICE_INPUT_DEFAULTS_NAME(SCSI_ID_3)); + scsi.set_slot_device(5, "harddisk", SCSIHD, DEVICE_INPUT_DEFAULTS_NAME(SCSI_ID_4)); + + FMSCSI(config, m_scsi_ctlr, 0); + m_scsi_ctlr->set_scsi_port("scsi"); + m_scsi_ctlr->irq_handler().set(FUNC(fmt121_device::irq_w)); + m_scsi_ctlr->drq_handler().set(FUNC(fmt121_device::drq_w)); +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void fmt121_device::device_start() +{ +} + +//************************************************************************** +// FMT121 INTERFACE +//************************************************************************** + +//------------------------------------------------- +// fmt_scsi_read - I/O read access +//------------------------------------------------- + +u8 fmt121_device::fmt_scsi_read(offs_t offset) +{ + return m_scsi_ctlr->fmscsi_r(offset); +} + + +//------------------------------------------------- +// fmt_scsi_write - I/O write access +//------------------------------------------------- + +void fmt121_device::fmt_scsi_write(offs_t offset, u8 data) +{ + m_scsi_ctlr->fmscsi_w(offset, data); +} + +//------------------------------------------------- +// fmt_scsi_data_read - data read access +//------------------------------------------------- + +u8 fmt121_device::fmt_scsi_data_read() +{ + return m_scsi_ctlr->fmscsi_data_r(); +} + +//------------------------------------------------- +// fmt_scsi_data_write - data write access +//------------------------------------------------- + +void fmt121_device::fmt_scsi_data_write(u8 data) +{ + m_scsi_ctlr->fmscsi_data_w(data); +} + + +void fmt121_device::irq_w(int state) +{ + m_slot->irq_w(state); +} + + +void fmt121_device::drq_w(int state) +{ + m_slot->drq_w(state); +} diff --git a/src/devices/bus/fmt_scsi/fmt121.h b/src/devices/bus/fmt_scsi/fmt121.h new file mode 100644 index 00000000000..9b80b2c70f1 --- /dev/null +++ b/src/devices/bus/fmt_scsi/fmt121.h @@ -0,0 +1,50 @@ +// license:BSD-3-Clause +// copyright-holders:r09 + +#ifndef MAME_BUS_FMT_SCSI_FMT121_H +#define MAME_BUS_FMT_SCSI_FMT121_H + +#pragma once + +#include "fmt_scsi.h" + +#include "machine/fm_scsi.h" + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> fmt121_device + +class fmt121_device : public device_t, public fmt_scsi_card_interface +{ +public: + // device type constructor + fmt121_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + +protected: + // device-level overrides + virtual void device_add_mconfig(machine_config &config) override; + virtual void device_start() override; + + // fmt_scsi_card_interface overrides + virtual u8 fmt_scsi_read(offs_t offset) override; + virtual void fmt_scsi_write(offs_t offset, u8 data) override; + + virtual u8 fmt_scsi_data_read(void) override; + virtual void fmt_scsi_data_write(u8 data) override; + +private: + + required_device<fmscsi_device> m_scsi_ctlr; + + void irq_w(int state); + void drq_w(int state); + +}; + +// device type declaration +DECLARE_DEVICE_TYPE(FMT121, fmt121_device) + +#endif // MAME_BUS_FMT_SCSI_FMT121_H diff --git a/src/devices/bus/fmt_scsi/fmt_scsi.cpp b/src/devices/bus/fmt_scsi/fmt_scsi.cpp new file mode 100644 index 00000000000..b5d62fb3577 --- /dev/null +++ b/src/devices/bus/fmt_scsi/fmt_scsi.cpp @@ -0,0 +1,158 @@ +// license:BSD-3-Clause +// copyright-holders:r09 +/**************************************************************************** + + Fujitsu FM Towns SCSI card slot + + This is a dedicated 30-pin slot for the FMT-121 SCSI Card. It is only + present on the Model 1 and 2; all later models integrate the SCSI + controller directly on the motherboard. + +****************************************************************************/ + +#include "emu.h" +#include "fmt_scsi.h" + +#include "fmt121.h" + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +// device type definition +DEFINE_DEVICE_TYPE(FMT_SCSI_SLOT, fmt_scsi_slot_device, "fmt_scsi_slot", "FM Towns SCSI card slot") + +//************************************************************************** +// FMT_SCSI SLOT DEVICE +//************************************************************************** + +//------------------------------------------------- +// fmt_scsi_slot_device - construction +//------------------------------------------------- + +fmt_scsi_slot_device::fmt_scsi_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, FMT_SCSI_SLOT, tag, owner, clock) + , device_single_card_slot_interface<fmt_scsi_card_interface>(mconfig, *this) + , m_card(nullptr) + , m_irq_handler(*this) + , m_drq_handler(*this) +{ +} + + +//------------------------------------------------- +// device_resolve_objects - resolve objects that +// may be needed for other devices to set +// initial conditions at start time +//------------------------------------------------- + +void fmt_scsi_slot_device::device_resolve_objects() +{ + m_card = get_card_device(); + if (m_card != nullptr) + m_card->m_slot = this; +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void fmt_scsi_slot_device::device_start() +{ + m_irq_handler.resolve_safe(); + m_drq_handler.resolve_safe(); +} + + +//------------------------------------------------- +// read - I/O read access +//------------------------------------------------- + +u8 fmt_scsi_slot_device::read(address_space &space, offs_t offset) +{ + if (m_card) + return m_card->fmt_scsi_read(offset); + else + return space.unmap(); +} + + +//------------------------------------------------- +// write - I/O write access +//------------------------------------------------- + +void fmt_scsi_slot_device::write(offs_t offset, u8 data) +{ + if (m_card) + m_card->fmt_scsi_write(offset, data); +} + +//------------------------------------------------- +// data_read - data read access +//------------------------------------------------- + +u8 fmt_scsi_slot_device::data_read() +{ + if (m_card) + return m_card->fmt_scsi_data_read(); + else + return 0; +} + +//------------------------------------------------- +// data_write - data write access +//------------------------------------------------- + +void fmt_scsi_slot_device::data_write(u8 data) +{ + if (m_card) + m_card->fmt_scsi_data_write(data); +} + +void fmt_scsi_slot_device::irq_w(int state) +{ + m_irq_handler(state); +} + +void fmt_scsi_slot_device::drq_w(int state) +{ + m_drq_handler(state); +} + +//************************************************************************** +// FMT_SCSI CARD INTERFACE +//************************************************************************** + +//------------------------------------------------- +// fmt_scsi_card_interface - construction +//------------------------------------------------- + +fmt_scsi_card_interface::fmt_scsi_card_interface(const machine_config &mconfig, device_t &device) + : device_interface(device, "fmtscsicard") + , m_slot(nullptr) +{ +} + + +//------------------------------------------------- +// interface_pre_start - called before the +// device's own start function +//------------------------------------------------- + +void fmt_scsi_card_interface::interface_pre_start() +{ + if (!m_slot) + throw device_missing_dependencies(); +} + + +//------------------------------------------------- +// fmt_scsi_default_devices - add standard options +// for main slots +//------------------------------------------------- + +void fmt_scsi_default_devices(device_slot_interface &device) +{ + device.option_add("fmt121", FMT121); +} diff --git a/src/devices/bus/fmt_scsi/fmt_scsi.h b/src/devices/bus/fmt_scsi/fmt_scsi.h new file mode 100644 index 00000000000..549b1047f4c --- /dev/null +++ b/src/devices/bus/fmt_scsi/fmt_scsi.h @@ -0,0 +1,98 @@ +// license:BSD-3-Clause +// copyright-holders:r09 +/********************************************************************** + + Fujitsu FM Towns SCSI card slot + +**********************************************************************/ + +#ifndef MAME_BUS_FMT_SCSI_FMT_SCSI_H +#define MAME_BUS_FMT_SCSI_FMT_SCSI_H + +#pragma once + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// forward declarations +class fmt_scsi_card_interface; + +// ======================> fmt_scsi_slot_device + +class fmt_scsi_slot_device : public device_t, public device_single_card_slot_interface<fmt_scsi_card_interface> +{ + friend class fmt_scsi_card_interface; + +public: + // construction/destruction + template <typename T> + fmt_scsi_slot_device(machine_config const &mconfig, char const *tag, device_t *owner, T &&opts, char const *dflt) + : fmt_scsi_slot_device(mconfig, tag, owner, 0) + { + option_reset(); + opts(*this); + set_default_option(dflt); + set_fixed(false); + } + + fmt_scsi_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); + + auto irq_handler() { return m_irq_handler.bind(); } + auto drq_handler() { return m_drq_handler.bind(); } + + u8 read(address_space &space, offs_t offset); + void write(offs_t offset, u8 data); + + uint8_t data_read(void); + void data_write(uint8_t data); + + void irq_w(int state); + void drq_w(int state); + +protected: + // device-specific overrides + virtual void device_resolve_objects() override; + virtual void device_start() override; + +private: + fmt_scsi_card_interface *m_card; + + devcb_write_line m_irq_handler; + devcb_write_line m_drq_handler; + +}; + + +// ======================> fmt_scsi_card_interface + +class fmt_scsi_card_interface : public device_interface +{ + friend class fmt_scsi_slot_device; + +protected: + // construction/destruction + fmt_scsi_card_interface(const machine_config &mconfig, device_t &device); + + // required overrides + virtual u8 fmt_scsi_read(offs_t offset) = 0; + virtual void fmt_scsi_write(offs_t offset, u8 data) = 0; + + virtual u8 fmt_scsi_data_read(void) = 0; + virtual void fmt_scsi_data_write(u8 data) = 0; + + fmt_scsi_slot_device *m_slot; + +private: + virtual void interface_pre_start() override; + +}; + + +// device type definition +DECLARE_DEVICE_TYPE(FMT_SCSI_SLOT, fmt_scsi_slot_device) + +void fmt_scsi_default_devices(device_slot_interface &device); + +#endif // MAME_BUS_FMT_SCSI_FMT_SCSI_H diff --git a/src/devices/bus/gio64/newport.cpp b/src/devices/bus/gio64/newport.cpp index 1be643afddd..142947b4ae0 100644 --- a/src/devices/bus/gio64/newport.cpp +++ b/src/devices/bus/gio64/newport.cpp @@ -1302,7 +1302,7 @@ uint32_t newport_base_device::screen_update(screen_device &device, bitmap_rgb32 /* loop over rows and copy to the destination */ for (int y = cliprect.min_y, sy = y_start; y <= cliprect.max_y && sy < y_end; y++, sy++) { - uint32_t *dest = &bitmap.pix32(y, cliprect.min_x); + uint32_t *dest = &bitmap.pix(y, cliprect.min_x); const uint32_t *src_rgbci = m_rb2->rgbci(y); const uint32_t *src_cidaux = m_rb2->cidaux(y); diff --git a/src/devices/bus/hexbus/hexbus.cpp b/src/devices/bus/hexbus/hexbus.cpp index 0b8d7821cb6..53e8a40e7c0 100644 --- a/src/devices/bus/hexbus/hexbus.cpp +++ b/src/devices/bus/hexbus/hexbus.cpp @@ -224,18 +224,20 @@ uint8_t hexbus_device::read(int dir) hexbus_chained_device::hexbus_chained_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock): device_t(mconfig, type, tag, owner, clock), device_hexbus_interface(mconfig, *this), + m_hexbus_outbound(nullptr), m_enabled(false), m_myvalue(0xff) { m_hexbus_inbound = dynamic_cast<hexbus_device *>(owner); } -void hexbus_chained_device::device_start() +void hexbus_chained_device::device_resolve_objects() { - m_hexbus_outbound = static_cast<hexbus_device*>(subdevice("hexbus")); + m_hexbus_outbound = dynamic_cast<hexbus_device *>(subdevice("hexbus")); // Establish callback for inbound propagations - m_hexbus_outbound->set_chain_element(this); + if (m_hexbus_outbound != nullptr) + m_hexbus_outbound->set_chain_element(this); } /* diff --git a/src/devices/bus/hexbus/hexbus.h b/src/devices/bus/hexbus/hexbus.h index 76092c0f16f..7f39400974b 100644 --- a/src/devices/bus/hexbus/hexbus.h +++ b/src/devices/bus/hexbus/hexbus.h @@ -60,7 +60,7 @@ protected: void set_outbound_hexbus(hexbus_device *outbound) { m_hexbus_outbound = outbound; } - virtual void device_start() override; + virtual void device_resolve_objects() override; // Link to the inbound Hexbus (if not null, see Oso chip) hexbus_device *m_hexbus_inbound; diff --git a/src/devices/bus/hexbus/hx5102.cpp b/src/devices/bus/hexbus/hx5102.cpp index f9d2341456e..65f59e0a18a 100644 --- a/src/devices/bus/hexbus/hx5102.cpp +++ b/src/devices/bus/hexbus/hx5102.cpp @@ -121,7 +121,9 @@ void hx5102_device::memmap(address_map &map) */ void hx5102_device::crumap(address_map &map) { - map(0x17e0, 0x17ff).rw(FUNC(hx5102_device::cruread), FUNC(hx5102_device::cruwrite)); + map(0x17e0, 0x17ff).r(FUNC(hx5102_device::cruread)); + map(0x17e0, 0x17ef).w(m_crulatch[0], FUNC(ls259_device::write_d0)); + map(0x17f0, 0x17ff).w(m_crulatch[1], FUNC(ls259_device::write_d0)); } hx5102_device::hx5102_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock): @@ -140,6 +142,7 @@ hx5102_device::hx5102_device(const machine_config &mconfig, const char *tag, dev m_floppy_select_last(UNDEF), m_hexbus_ctrl(*this, IBC_TAG), m_floppy_ctrl(*this, FDC_TAG), + m_crulatch(*this, "crulatch%u", 0U), m_motormf(*this, MTRD_TAG), m_speedmf(*this, MTSPD_TAG), m_readyff(*this, READYFF_TAG), @@ -480,92 +483,81 @@ uint8_t hx5102_device::cruread(offs_t offset) /* CRU write access. */ -void hx5102_device::cruwrite(offs_t offset, uint8_t data) +WRITE_LINE_MEMBER(hx5102_device::nocomp_w) { - // LOG("Writing CRU address %04x: %x\n", 0x17e0 + (offset<<1), data); - switch (offset) - { - case 0: - // unused right now - LOGMASKED(LOG_CRU, "Set precompensation = %d\n", data); - break; - case 1: - if (data==1) - { - LOGMASKED(LOG_CRU, "Trigger motor monoflop\n"); - } - m_motormf->b_w(data); - break; - case 2: - LOGMASKED(LOG_CRU, "Set undefined CRU bit 2 to %d\n", data); - break; - case 3: - LOGMASKED(LOG_CRU, "Set step direction = %d\n", data); - if (m_current_floppy != nullptr) m_current_floppy->dir_w((data==0)? 1 : 0); - break; - case 4: - if (data==1) - { - LOGMASKED(LOG_CRU, "Assert DACK*\n"); - m_dacken = (data != 0); - } - break; - case 5: - if (data==1) - { - LOGMASKED(LOG_CRU, "Step pulse\n"); - } - if (m_current_floppy != nullptr) m_current_floppy->stp_w((data==0)? 1 : 0); - break; - case 6: - if (data==1) - { - LOGMASKED(LOG_CRU, "Start watchdog\n"); - } - m_speedmf->b_w(data); - break; - case 7: - if (data==0) - { - LOGMASKED(LOG_CRU, "Reset i8272A controller\n"); - m_floppy_ctrl->soft_reset(); - } - break; - case 8: - LOGMASKED(LOG_CRU, "Set drive select 0 to %d\n", data); - if (data == 1) m_floppy_select |= 1; - else m_floppy_select &= ~1; - break; - case 9: - LOGMASKED(LOG_CRU, "Set drive select 1 to %d\n", data); - if (data == 1) m_floppy_select |= 2; - else m_floppy_select &= ~2; - break; - case 10: - // External drive; not implemented - LOGMASKED(LOG_CRU, "Set drive select 2 to %d\n", data); - break; - case 11: - // External drive; not implemented - LOGMASKED(LOG_CRU, "Set drive select 3 to %d\n", data); - break; - case 12: - // External drive; not implemented - LOGMASKED(LOG_CRU, "Set auxiliary motor line to %d\n", data); - break; - case 13: - LOGMASKED(LOG_CRU, "Set CRU bit 13 to %d (unused)\n", data); - break; - case 14: - m_wait = (data!=0); - LOGMASKED(LOG_CRU, "READY circuit %s\n", m_wait? "active" : "inactive" ); - update_readyff_input(); - break; - case 15: - LOGMASKED(LOG_CRU, "Set CRU bit 15 to %d (unused)\n", data); - break; - } + // unused right now + LOGMASKED(LOG_CRU, "Set precompensation = %d\n", state); +} +WRITE_LINE_MEMBER(hx5102_device::diren_w) +{ + LOGMASKED(LOG_CRU, "Set step direction = %d\n", state); + if (m_current_floppy != nullptr) + m_current_floppy->dir_w((state==0)? 1 : 0); +} + +WRITE_LINE_MEMBER(hx5102_device::dacken_w) +{ + if (state==1) + LOGMASKED(LOG_CRU, "Assert DACK*\n"); + m_dacken = (state != 0); +} + +WRITE_LINE_MEMBER(hx5102_device::stepen_w) +{ + if (state==1) + LOGMASKED(LOG_CRU, "Step pulse\n"); + if (m_current_floppy != nullptr) + m_current_floppy->stp_w((state==0)? 1 : 0); +} + +WRITE_LINE_MEMBER(hx5102_device::ds1_w) +{ + LOGMASKED(LOG_CRU, "Set drive select 0 to %d\n", state); + if (state == 1) + m_floppy_select |= 1; + else + m_floppy_select &= ~1; + update_drive_select(); +} + +WRITE_LINE_MEMBER(hx5102_device::ds2_w) +{ + LOGMASKED(LOG_CRU, "Set drive select 1 to %d\n", state); + if (state == 1) + m_floppy_select |= 2; + else + m_floppy_select &= ~2; + update_drive_select(); +} + +WRITE_LINE_MEMBER(hx5102_device::ds3_w) +{ + // External drive; not implemented + LOGMASKED(LOG_CRU, "Set drive select 2 to %d\n", state); +} + +WRITE_LINE_MEMBER(hx5102_device::ds4_w) +{ + // External drive; not implemented + LOGMASKED(LOG_CRU, "Set drive select 3 to %d\n", state); +} + +WRITE_LINE_MEMBER(hx5102_device::aux_motor_w) +{ + // External drive; not implemented + LOGMASKED(LOG_CRU, "Set auxiliary motor line to %d\n", state); +} + +WRITE_LINE_MEMBER(hx5102_device::wait_w) +{ + m_wait = (state!=0); + LOGMASKED(LOG_CRU, "READY circuit %s\n", m_wait? "active" : "inactive" ); + update_readyff_input(); +} + +void hx5102_device::update_drive_select() +{ if (m_floppy_select != m_floppy_select_last) { if (m_floppy_select == 1) @@ -677,7 +669,7 @@ void hx5102_device::device_add_mconfig(machine_config& config) HEXBUS(config, "hexbus", 0, hexbus_options, nullptr); // TMS9995 CPU @ 12.0 MHz - TMS9995(config, m_flopcpu, XTAL(12'000'000)); + TMS9995(config, m_flopcpu, 12_MHz_XTAL); m_flopcpu->set_addrmap(AS_PROGRAM, &hx5102_device::memmap); m_flopcpu->set_addrmap(AS_IO, &hx5102_device::crumap); m_flopcpu->extop_cb().set(FUNC(hx5102_device::external_operation)); @@ -687,27 +679,41 @@ void hx5102_device::device_add_mconfig(machine_config& config) // Not connected: Select lines (DS0, DS1), Head load (HDL), VCO // Tied to 1: READY // Tied to 0: TC - I8272A(config, m_floppy_ctrl, 8'000'000, false); + I8272A(config, m_floppy_ctrl, 8_MHz_XTAL / 2, false); m_floppy_ctrl->intrq_wr_callback().set(FUNC(hx5102_device::fdc_irq_w)); m_floppy_ctrl->drq_wr_callback().set(FUNC(hx5102_device::fdc_drq_w)); FLOPPY_CONNECTOR(config, "d0", hx5102_drive, "525dd", hx5102_device::floppy_formats).enable_sound(true); FLOPPY_CONNECTOR(config, "d1", hx5102_drive, nullptr, hx5102_device::floppy_formats).enable_sound(true); + // Addressable latches + LS259(config, m_crulatch[0]); // U18 + m_crulatch[0]->q_out_cb<0>().set(FUNC(hx5102_device::nocomp_w)); + m_crulatch[0]->q_out_cb<1>().set(m_motormf, FUNC(ttl74123_device::b_w)); + m_crulatch[0]->q_out_cb<3>().set(FUNC(hx5102_device::diren_w)); + m_crulatch[0]->q_out_cb<4>().set(FUNC(hx5102_device::dacken_w)); + m_crulatch[0]->q_out_cb<5>().set(FUNC(hx5102_device::stepen_w)); + m_crulatch[0]->q_out_cb<6>().set(m_speedmf, FUNC(ttl74123_device::b_w)); + m_crulatch[0]->q_out_cb<7>().set(m_floppy_ctrl, FUNC(i8272a_device::reset_w)).invert(); + + LS259(config, m_crulatch[1]); // U10 + m_crulatch[1]->q_out_cb<0>().set(FUNC(hx5102_device::ds1_w)); + m_crulatch[1]->q_out_cb<1>().set(FUNC(hx5102_device::ds2_w)); + m_crulatch[1]->q_out_cb<2>().set(FUNC(hx5102_device::ds3_w)); + m_crulatch[1]->q_out_cb<3>().set(FUNC(hx5102_device::ds4_w)); + m_crulatch[1]->q_out_cb<4>().set(FUNC(hx5102_device::aux_motor_w)); + m_crulatch[1]->q_out_cb<6>().set(FUNC(hx5102_device::wait_w)); + // Monoflops - TTL74123(config, m_motormf, 0); + TTL74123(config, m_motormf, RES_K(200), CAP_U(47)); m_motormf->set_connection_type(TTL74123_GROUNDED); - m_motormf->set_resistor_value(RES_K(200)); - m_motormf->set_capacitor_value(CAP_U(47)); m_motormf->set_a_pin_value(0); m_motormf->set_b_pin_value(1); m_motormf->set_clear_pin_value(1); m_motormf->out_cb().set(FUNC(hx5102_device::motor_w)); - TTL74123(config, m_speedmf, 0); + TTL74123(config, m_speedmf, RES_K(200), CAP_U(10)); m_speedmf->set_connection_type(TTL74123_GROUNDED); - m_speedmf->set_resistor_value(RES_K(200)); - m_speedmf->set_capacitor_value(CAP_U(10)); m_speedmf->set_a_pin_value(0); m_speedmf->set_b_pin_value(1); m_speedmf->set_clear_pin_value(1); diff --git a/src/devices/bus/hexbus/hx5102.h b/src/devices/bus/hexbus/hx5102.h index 12f48dbe555..573c999ce3b 100644 --- a/src/devices/bus/hexbus/hx5102.h +++ b/src/devices/bus/hexbus/hx5102.h @@ -22,6 +22,7 @@ #include "machine/upd765.h" #include "machine/7474.h" #include "machine/74123.h" +#include "machine/74259.h" #include "machine/rescap.h" #include "machine/ram.h" #include "imagedev/floppy.h" @@ -71,7 +72,17 @@ private: DECLARE_WRITE_LINE_MEMBER(hsklatch_out); uint8_t cruread(offs_t offset); - void cruwrite(offs_t offset, uint8_t data); + DECLARE_WRITE_LINE_MEMBER(nocomp_w); + DECLARE_WRITE_LINE_MEMBER(diren_w); + DECLARE_WRITE_LINE_MEMBER(dacken_w); + DECLARE_WRITE_LINE_MEMBER(stepen_w); + DECLARE_WRITE_LINE_MEMBER(ds1_w); + DECLARE_WRITE_LINE_MEMBER(ds2_w); + DECLARE_WRITE_LINE_MEMBER(ds3_w); + DECLARE_WRITE_LINE_MEMBER(ds4_w); + DECLARE_WRITE_LINE_MEMBER(aux_motor_w); + DECLARE_WRITE_LINE_MEMBER(wait_w); + void update_drive_select(); // Operate the floppy motors bool m_motor_on; @@ -96,6 +107,7 @@ private: required_device<ibc_device> m_hexbus_ctrl; required_device<i8272a_device> m_floppy_ctrl; + required_device_array<ls259_device, 2> m_crulatch; required_device<ttl74123_device> m_motormf; required_device<ttl74123_device> m_speedmf; required_device<ttl7474_device> m_readyff; diff --git a/src/devices/bus/hp_dio/hp98543.cpp b/src/devices/bus/hp_dio/hp98543.cpp index bd96c95852d..eb73c56c6f4 100644 --- a/src/devices/bus/hp_dio/hp98543.cpp +++ b/src/devices/bus/hp_dio/hp98543.cpp @@ -235,7 +235,7 @@ uint32_t dio16_98543_device::screen_update(screen_device &screen, bitmap_rgb32 & } for (int y = 0; y < m_v_pix; y++) { - uint32_t *scanline = &bitmap.pix32(y); + uint32_t *scanline = &bitmap.pix(y); for (int x = 0; x < m_h_pix; x++) { uint8_t tmp = m_vram[y * m_h_pix + x]; diff --git a/src/devices/bus/hp_dio/hp98544.cpp b/src/devices/bus/hp_dio/hp98544.cpp index 842a7a78229..e5aced877d8 100644 --- a/src/devices/bus/hp_dio/hp98544.cpp +++ b/src/devices/bus/hp_dio/hp98544.cpp @@ -165,26 +165,20 @@ WRITE_LINE_MEMBER(dio16_98544_device::int_w) uint32_t dio16_98544_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - int startx, starty, endx, endy; - - if (!m_topcat->has_changed()) return UPDATE_HAS_NOT_CHANGED; for (int y = 0; y < m_v_pix; y++) { - uint32_t *scanline = &bitmap.pix32(y); + uint32_t *scanline = &bitmap.pix(y); for (int x = 0; x < m_h_pix; x++) { uint8_t tmp = m_vram[y * m_h_pix + x]; *scanline++ = tmp ? rgb_t(255,255,255) : rgb_t(0, 0, 0); } } + int startx, starty, endx, endy; m_topcat->get_cursor_pos(startx, starty, endx, endy); - - for (int y = starty; y <= endy; y++) { - uint32_t *scanline = &bitmap.pix32(y); - memset(scanline + startx, 0xff, (endx - startx) << 2); - } + bitmap.fill(rgb_t(255, 255, 255), rectangle(startx, endx, starty, endy)); return 0; } diff --git a/src/devices/bus/hp_dio/hp98550.cpp b/src/devices/bus/hp_dio/hp98550.cpp index 738926eae77..38f70d2d670 100644 --- a/src/devices/bus/hp_dio/hp98550.cpp +++ b/src/devices/bus/hp_dio/hp98550.cpp @@ -218,7 +218,7 @@ uint32_t dio32_98550_device::screen_update(screen_device &screen, bitmap_rgb32 & mask |= ce->plane_enabled(); for (int y = 0; y < m_v_pix; y++) { - uint32_t *scanline = &bitmap.pix32(y); + uint32_t *scanline = &bitmap.pix(y); for (int x = 0; x < m_h_pix; x++) { const int offset = y * m_fb_width +x; diff --git a/src/devices/bus/ieee488/ieee488.cpp b/src/devices/bus/ieee488/ieee488.cpp index bcbe20e0573..947aad2d1f7 100644 --- a/src/devices/bus/ieee488/ieee488.cpp +++ b/src/devices/bus/ieee488/ieee488.cpp @@ -164,7 +164,7 @@ void ieee488_device::device_stop() void ieee488_device::add_device(ieee488_slot_device *slot, device_t *target) { - auto entry = global_alloc(daisy_entry(target)); + auto entry = new daisy_entry(target); entry->m_interface->m_bus = this; entry->m_interface->m_slot = slot; diff --git a/src/devices/bus/iq151/grafik.cpp b/src/devices/bus/iq151/grafik.cpp index 304bcf87b43..497012cf2cd 100644 --- a/src/devices/bus/iq151/grafik.cpp +++ b/src/devices/bus/iq151/grafik.cpp @@ -178,7 +178,7 @@ void iq151_grafik_device::video_update(bitmap_ind16 &bitmap, const rectangle &cl { for (int ra = 0; ra < 8; ra++) { - bitmap.pix16(y, x*8 + ra) |= BIT(m_videoram[(32*8 -1 - y)*64 + x], ra); + bitmap.pix(y, x*8 + ra) |= BIT(m_videoram[(32*8 -1 - y)*64 + x], ra); } } } diff --git a/src/devices/bus/iq151/minigraf.cpp b/src/devices/bus/iq151/minigraf.cpp index d5bf2da1f8b..e0962048411 100644 --- a/src/devices/bus/iq151/minigraf.cpp +++ b/src/devices/bus/iq151/minigraf.cpp @@ -162,7 +162,7 @@ void iq151_minigraf_device::plotter_update(uint8_t control) // if pen is down draws a point if (m_pen) - m_paper->pix16(((PAPER_HEIGHT-PAPER_MAX_Y)/2) + m_posy, ((PAPER_WIDTH-PAPER_MAX_X)/2) + m_posx) = 1; + m_paper->pix(((PAPER_HEIGHT-PAPER_MAX_Y)/2) + m_posy, ((PAPER_WIDTH-PAPER_MAX_X)/2) + m_posx) = 1; m_control = control; } diff --git a/src/devices/bus/iq151/ms151a.cpp b/src/devices/bus/iq151/ms151a.cpp index 447c9f0d43a..651e82bfe6f 100644 --- a/src/devices/bus/iq151/ms151a.cpp +++ b/src/devices/bus/iq151/ms151a.cpp @@ -164,5 +164,5 @@ void iq151_ms151a_device::plotter_update(uint8_t offset, uint8_t data) // if pen is down draws a point if (m_pen) - m_paper->pix16(((PAPER_HEIGHT-PAPER_MAX_Y)/2) + m_posy, ((PAPER_WIDTH-PAPER_MAX_X)/2) + m_posx) = 1; + m_paper->pix(((PAPER_HEIGHT-PAPER_MAX_Y)/2) + m_posy, ((PAPER_WIDTH-PAPER_MAX_X)/2) + m_posx) = 1; } diff --git a/src/devices/bus/iq151/video32.cpp b/src/devices/bus/iq151/video32.cpp index fce21b963e9..2d3f75b66ed 100644 --- a/src/devices/bus/iq151/video32.cpp +++ b/src/devices/bus/iq151/video32.cpp @@ -126,7 +126,7 @@ void iq151_video32_device::video_update(bitmap_ind16 &bitmap, const rectangle &c { for (int ra = 0; ra < 8; ra++) { - uint16_t *p = &bitmap.pix16(sy++); + uint16_t *p = &bitmap.pix(sy++); for (int x = ma; x < ma + 32; x++) { diff --git a/src/devices/bus/iq151/video64.cpp b/src/devices/bus/iq151/video64.cpp index a965abbd19e..487bf63ca33 100644 --- a/src/devices/bus/iq151/video64.cpp +++ b/src/devices/bus/iq151/video64.cpp @@ -140,7 +140,7 @@ void iq151_video64_device::video_update(bitmap_ind16 &bitmap, const rectangle &c { for (int ra = 0; ra < 8; ra++) { - uint16_t *p = &bitmap.pix16(sy++); + uint16_t *p = &bitmap.pix(sy++); for (int x = ma; x < ma + 64; x++) { diff --git a/src/devices/bus/isa/aga.cpp b/src/devices/bus/isa/aga.cpp index 244fbc0bb66..81e6ba053fe 100644 --- a/src/devices/bus/isa/aga.cpp +++ b/src/devices/bus/isa/aga.cpp @@ -288,7 +288,7 @@ MC6845_UPDATE_ROW( isa8_aga_device::mda_text_inten_update_row ) { rgb_t const *const palette = m_palette->palette()->entry_list_raw(); uint8_t const *const videoram = m_videoram.get(); - uint32_t *p = &bitmap.pix32(y); + uint32_t *p = &bitmap.pix(y); uint16_t const chr_base = (ra & 0x08) ? 0x800 | (ra & 0x07) : ra; if (y == 0) logerror("mda_text_inten_update_row\n"); @@ -345,7 +345,7 @@ MC6845_UPDATE_ROW( isa8_aga_device::mda_text_blink_update_row ) { uint8_t const *const videoram = m_videoram.get(); rgb_t const *const palette = m_palette->palette()->entry_list_raw(); - uint32_t *p = &bitmap.pix32(y); + uint32_t *p = &bitmap.pix(y); uint16_t const chr_base = (ra & 0x08) ? 0x800 | (ra & 0x07) : ra; if (y == 0) logerror("mda_text_blink_update_row\n"); @@ -402,7 +402,7 @@ MC6845_UPDATE_ROW( isa8_aga_device::cga_text_inten_update_row ) { uint8_t const *const videoram = m_videoram.get(); rgb_t const *const palette = m_palette->palette()->entry_list_raw(); - uint32_t *p = &bitmap.pix32(y); + uint32_t *p = &bitmap.pix(y); if (y == 0) logerror("cga_text_inten_update_row\n"); for (int i = 0; i < x_count; i++) { @@ -431,7 +431,7 @@ MC6845_UPDATE_ROW( isa8_aga_device::cga_text_inten_alt_update_row ) { rgb_t const *const palette = m_palette->palette()->entry_list_raw(); uint8_t const *const videoram = m_videoram.get(); - uint32_t *p = &bitmap.pix32(y); + uint32_t *p = &bitmap.pix(y); if (y == 0) logerror("cga_text_inten_alt_update_row\n"); for (int i = 0; i < x_count; i++) { @@ -459,7 +459,7 @@ MC6845_UPDATE_ROW( isa8_aga_device::cga_text_blink_update_row ) { rgb_t const *const palette = m_palette->palette()->entry_list_raw(); uint8_t const *const videoram = m_videoram.get(); - uint32_t *p = &bitmap.pix32(y); + uint32_t *p = &bitmap.pix(y); for (int i = 0; i < x_count; i++) { uint16_t const offset = ((ma + i) << 1) & 0x3fff; @@ -491,7 +491,7 @@ MC6845_UPDATE_ROW( isa8_aga_device::cga_text_blink_alt_update_row ) { rgb_t const *const palette = m_palette->palette()->entry_list_raw(); uint8_t const *const videoram = m_videoram.get(); - uint32_t *p = &bitmap.pix32(y); + uint32_t *p = &bitmap.pix(y); if (y == 0) logerror("cga_text_blink_alt_update_row\n"); for (int i = 0; i < x_count; i++) { @@ -526,7 +526,7 @@ MC6845_UPDATE_ROW( isa8_aga_device::cga_gfx_4bppl_update_row ) { rgb_t const *const palette = m_palette->palette()->entry_list_raw(); uint8_t const *const videoram = m_videoram.get(); - uint32_t *p = &bitmap.pix32(y); + uint32_t *p = &bitmap.pix(y); if (y == 0) logerror("cga_gfx_4bppl_update_row\n"); for (int i = 0; i < x_count; i++) { @@ -551,7 +551,7 @@ MC6845_UPDATE_ROW( isa8_aga_device::cga_gfx_4bpph_update_row ) { uint8_t const *const videoram = m_videoram.get(); rgb_t const *const palette = m_palette->palette()->entry_list_raw(); - uint32_t *p = &bitmap.pix32(y); + uint32_t *p = &bitmap.pix(y); if (y == 0) logerror("cga_gfx_4bpph_update_row\n"); for (int i = 0; i < x_count; i++) { @@ -584,7 +584,7 @@ MC6845_UPDATE_ROW( isa8_aga_device::cga_gfx_2bpp_update_row ) { uint8_t const *const videoram = m_videoram.get(); rgb_t const *const palette = m_palette->palette()->entry_list_raw(); - uint32_t *p = &bitmap.pix32(y); + uint32_t *p = &bitmap.pix(y); //if (y == 0) logerror("cga_gfx_2bpp_update_row\n"); for (int i = 0; i < x_count; i++) { @@ -609,7 +609,7 @@ MC6845_UPDATE_ROW( isa8_aga_device::cga_gfx_1bpp_update_row ) { uint8_t const *const videoram = m_videoram.get(); rgb_t const *const palette = m_palette->palette()->entry_list_raw(); - uint32_t *p = &bitmap.pix32(y); + uint32_t *p = &bitmap.pix(y); uint8_t const fg = m_cga_color_select & 0x0f; if (y == 0) logerror("cga_gfx_1bpp_update_row\n"); diff --git a/src/devices/bus/isa/cga.cpp b/src/devices/bus/isa/cga.cpp index ff30f3690ad..52a0407f065 100644 --- a/src/devices/bus/isa/cga.cpp +++ b/src/devices/bus/isa/cga.cpp @@ -469,47 +469,43 @@ isa8_cga_superimpose_device::isa8_cga_superimpose_device(const machine_config &m template<bool blink, bool si, bool comp, bool alt, int width> MC6845_UPDATE_ROW( isa8_cga_device::cga_text ) { - uint8_t *videoram = &m_vram[m_start_offset]; - uint32_t *p = &bitmap.pix32(y); - const rgb_t *palette = m_palette->palette()->entry_list_raw(); - int i; + uint8_t const *const videoram = &m_vram[m_start_offset]; + uint32_t *p = &bitmap.pix(y); + rgb_t const *const palette = m_palette->palette()->entry_list_raw(); - if ( y == 0 ) CGA_LOG(1,"cga_text_8",("\n")); - for ( i = 0; i < x_count; i++ ) + if (y == 0) CGA_LOG(1,"cga_text_8",("\n")); + for (int i = 0; i < x_count; i++) { - uint16_t offset = ( ( ma + i ) << 1 ) & 0x3fff; - uint8_t chr = videoram[ offset ]; - uint8_t attr = videoram[ offset +1 ]; - uint8_t data = m_chr_gen[ chr * width + ra ]; + uint16_t const offset = ((ma + i) << 1) & 0x3fff; + uint8_t const chr = videoram[offset]; + uint8_t const attr = videoram[offset +1]; + uint8_t data = m_chr_gen[chr * width + ra]; uint16_t fg, bg; - uint8_t xi; - if ( comp ) + if (comp) { - fg = 0x10 + ( attr & 0x0F ); - bg = alt ? 0 : ( 0x10 + ( ( attr >> 4 ) & 0x07 ) ); + fg = 0x10 + (attr & 0x0f); + bg = alt ? 0 : (0x10 + ((attr >> 4) & 0x07)); } else { fg = attr & 0x0F; - bg = alt ? 0 : ( ( attr >> 4 ) & ( blink ? 0x07 : 0x0f ) ); + bg = alt ? 0 : ((attr >> 4) & (blink ? 0x07 : 0x0f)); } - if ( ( i == cursor_x ) && ( m_framecnt & 0x08 ) ) - data = 0xFF; - else if ( blink && ( attr & 0x80 ) && ( m_framecnt & 0x10 ) ) + if ((i == cursor_x) && (m_framecnt & 0x08)) + data = 0xff; + else if (blink && (attr & 0x80) && (m_framecnt & 0x10)) { data = 0x00; - bg = ( attr >> 4 ) & 0x07; + bg = (attr >> 4) & 0x07; } - for(xi=0;xi<8;xi++) + for (int xi = 0; xi < 8; xi++) { - uint8_t pen_data, dot; - - dot = (data & (1 << (7-xi))); - pen_data = dot ? fg : bg; - if(!si || (pen_data || dot)) + uint8_t const dot = (data & (1 << (7 - xi))); + uint8_t const pen_data = dot ? fg : bg; + if (!si || (pen_data || dot)) *p = palette[pen_data]; p++; } @@ -521,28 +517,29 @@ MC6845_UPDATE_ROW( isa8_cga_device::cga_text ) MC6845_UPDATE_ROW( isa8_cga_device::cga_gfx_4bppl_update_row ) { - uint8_t *videoram = &m_vram[m_start_offset]; - uint32_t *p = &bitmap.pix32(y); - const rgb_t *palette = m_palette->palette()->entry_list_raw(); - int i; + uint8_t const *const videoram = &m_vram[m_start_offset]; + uint32_t *p = &bitmap.pix(y); + rgb_t const *const palette = m_palette->palette()->entry_list_raw(); - if ( y == 0 ) CGA_LOG(1,"cga_gfx_4bppl_update_row",("\n")); - for ( i = 0; i < x_count; i++ ) + if (y == 0) CGA_LOG(1,"cga_gfx_4bppl_update_row",("\n")); + for (int i = 0; i < x_count; i++) { - uint16_t offset = ( ( ( ma + i ) << 1 ) & 0x1fff ) | ( ( y & 1 ) << 13 ); - uint8_t data = videoram[ offset ]; + uint16_t const offset = (((ma + i) << 1) & 0x1fff) | ((y & 1) << 13); + uint8_t data; + + data = videoram[offset]; - *p = palette[data >> 4]; p++; - *p = palette[data >> 4]; p++; - *p = palette[data & 0x0F]; p++; - *p = palette[data & 0x0F]; p++; + *p++ = palette[data >> 4]; + *p++ = palette[data >> 4]; + *p++ = palette[data & 0x0f]; + *p++ = palette[data & 0x0f]; - data = videoram[ offset + 1 ]; + data = videoram[offset + 1]; - *p = palette[data >> 4]; p++; - *p = palette[data >> 4]; p++; - *p = palette[data & 0x0F]; p++; - *p = palette[data & 0x0F]; p++; + *p++ = palette[data >> 4]; + *p++ = palette[data >> 4]; + *p++ = palette[data & 0x0f]; + *p++ = palette[data & 0x0f]; } } @@ -580,37 +577,37 @@ static const uint8_t yc_lut[16][8] = MC6845_UPDATE_ROW( isa8_cga_device::cga_gfx_4bpph_update_row ) { - uint8_t *videoram = &m_vram[m_start_offset]; - uint32_t *p = &bitmap.pix32(y); - const rgb_t *palette = m_palette->palette()->entry_list_raw(); - int i; - - if ( y == 0 ) CGA_LOG(1,"cga_gfx_4bpph_update_row",("\n")); + uint8_t const *const videoram = &m_vram[m_start_offset]; + uint32_t *p = &bitmap.pix(y); + rgb_t const *const palette = m_palette->palette()->entry_list_raw(); - for ( i = 0; i < x_count; i++ ) + if (y == 0) CGA_LOG(1,"cga_gfx_4bpph_update_row",("\n")); + for (int i = 0; i < x_count; i++) { - uint16_t offset = ( ( ( ma + i ) << 1 ) & 0x1fff ) | ( ( y & 1 ) << 13 ); - uint8_t data = videoram[ offset ]; - - *p = palette[data >> 4]; p++; - *p = palette[data >> 4]; p++; - *p = palette[data >> 4]; p++; - *p = palette[data >> 4]; p++; - *p = palette[data & 0x0F]; p++; - *p = palette[data & 0x0F]; p++; - *p = palette[data & 0x0F]; p++; - *p = palette[data & 0x0F]; p++; - - data = videoram[ offset + 1 ]; - - *p = palette[data >> 4]; p++; - *p = palette[data >> 4]; p++; - *p = palette[data >> 4]; p++; - *p = palette[data >> 4]; p++; - *p = palette[data & 0x0F]; p++; - *p = palette[data & 0x0F]; p++; - *p = palette[data & 0x0F]; p++; - *p = palette[data & 0x0F]; p++; + uint16_t const offset = (((ma + i) << 1) & 0x1fff) | ((y & 1) << 13); + uint8_t data; + + data = videoram[offset]; + + *p++ = palette[data >> 4]; + *p++ = palette[data >> 4]; + *p++ = palette[data >> 4]; + *p++ = palette[data >> 4]; + *p++ = palette[data & 0x0f]; + *p++ = palette[data & 0x0f]; + *p++ = palette[data & 0x0f]; + *p++ = palette[data & 0x0f]; + + data = videoram[offset + 1]; + + *p++ = palette[data >> 4]; + *p++ = palette[data >> 4]; + *p++ = palette[data >> 4]; + *p++ = palette[data >> 4]; + *p++ = palette[data & 0x0f]; + *p++ = palette[data & 0x0f]; + *p++ = palette[data & 0x0f]; + *p++ = palette[data & 0x0f]; } } @@ -623,28 +620,29 @@ MC6845_UPDATE_ROW( isa8_cga_device::cga_gfx_4bpph_update_row ) MC6845_UPDATE_ROW( isa8_cga_device::cga_gfx_2bpp_update_row ) { - uint8_t *videoram = &m_vram[m_start_offset]; - uint32_t *p = &bitmap.pix32(y); - const rgb_t *palette = m_palette->palette()->entry_list_raw(); - int i; + uint8_t const *const videoram = &m_vram[m_start_offset]; + uint32_t *p = &bitmap.pix(y); + rgb_t const *const palette = m_palette->palette()->entry_list_raw(); - if ( y == 0 ) CGA_LOG(1,"cga_gfx_2bpp_update_row",("\n")); - for ( i = 0; i < x_count; i++ ) + if (y == 0) CGA_LOG(1,"cga_gfx_2bpp_update_row",("\n")); + for (int i = 0; i < x_count; i++) { - uint16_t offset = ( ( ( ma + i ) << 1 ) & 0x1fff ) | ( ( ra & 1 ) << 13 ); - uint8_t data = videoram[ offset ]; + uint16_t const offset = (((ma + i) << 1) & 0x1fff) | ((ra & 1) << 13); + uint8_t data; + + data = videoram[offset]; - *p = palette[m_palette_lut_2bpp[ ( data >> 6 ) & 0x03 ]]; p++; - *p = palette[m_palette_lut_2bpp[ ( data >> 4 ) & 0x03 ]]; p++; - *p = palette[m_palette_lut_2bpp[ ( data >> 2 ) & 0x03 ]]; p++; - *p = palette[m_palette_lut_2bpp[ data & 0x03 ]]; p++; + *p++ = palette[m_palette_lut_2bpp[(data >> 6) & 0x03]]; + *p++ = palette[m_palette_lut_2bpp[(data >> 4) & 0x03]]; + *p++ = palette[m_palette_lut_2bpp[(data >> 2) & 0x03]]; + *p++ = palette[m_palette_lut_2bpp[ data & 0x03]]; - data = videoram[ offset+1 ]; + data = videoram[offset + 1]; - *p = palette[m_palette_lut_2bpp[ ( data >> 6 ) & 0x03 ]]; p++; - *p = palette[m_palette_lut_2bpp[ ( data >> 4 ) & 0x03 ]]; p++; - *p = palette[m_palette_lut_2bpp[ ( data >> 2 ) & 0x03 ]]; p++; - *p = palette[m_palette_lut_2bpp[ data & 0x03 ]]; p++; + *p++ = palette[m_palette_lut_2bpp[(data >> 6) & 0x03]]; + *p++ = palette[m_palette_lut_2bpp[(data >> 4) & 0x03]]; + *p++ = palette[m_palette_lut_2bpp[(data >> 2) & 0x03]]; + *p++ = palette[m_palette_lut_2bpp[ data & 0x03]]; } } @@ -658,37 +656,38 @@ MC6845_UPDATE_ROW( isa8_cga_device::cga_gfx_2bpp_update_row ) MC6845_UPDATE_ROW( isa8_cga_device::cga_gfx_1bpp_update_row ) { - uint8_t *videoram = &m_vram[m_start_offset]; - uint32_t *p = &bitmap.pix32(y); - const rgb_t *palette = m_palette->palette()->entry_list_raw(); - uint8_t fg = m_color_select & 0x0F; - int i; + uint8_t const *const videoram = &m_vram[m_start_offset]; + uint32_t *p = &bitmap.pix(y); + rgb_t const *const palette = m_palette->palette()->entry_list_raw(); + uint8_t const fg = m_color_select & 0x0f; - if ( y == 0 ) CGA_LOG(1,"cga_gfx_1bpp_update_row",("\n")); - for ( i = 0; i < x_count; i++ ) + if (y == 0) CGA_LOG(1,"cga_gfx_1bpp_update_row",("\n")); + for (int i = 0; i < x_count; i++) { - uint16_t offset = ( ( ( ma + i ) << 1 ) & 0x1fff ) | ( ( ra & 1 ) << 13 ); - uint8_t data = videoram[ offset ]; - - *p = palette[( data & 0x80 ) ? fg : 0]; p++; - *p = palette[( data & 0x40 ) ? fg : 0]; p++; - *p = palette[( data & 0x20 ) ? fg : 0]; p++; - *p = palette[( data & 0x10 ) ? fg : 0]; p++; - *p = palette[( data & 0x08 ) ? fg : 0]; p++; - *p = palette[( data & 0x04 ) ? fg : 0]; p++; - *p = palette[( data & 0x02 ) ? fg : 0]; p++; - *p = palette[( data & 0x01 ) ? fg : 0]; p++; - - data = videoram[ offset + 1 ]; - - *p = palette[( data & 0x80 ) ? fg : 0]; p++; - *p = palette[( data & 0x40 ) ? fg : 0]; p++; - *p = palette[( data & 0x20 ) ? fg : 0]; p++; - *p = palette[( data & 0x10 ) ? fg : 0]; p++; - *p = palette[( data & 0x08 ) ? fg : 0]; p++; - *p = palette[( data & 0x04 ) ? fg : 0]; p++; - *p = palette[( data & 0x02 ) ? fg : 0]; p++; - *p = palette[( data & 0x01 ) ? fg : 0]; p++; + uint16_t const offset = (((ma + i) << 1) & 0x1fff) | ((ra & 1) << 13); + uint8_t data; + + data = videoram[offset]; + + *p++ = palette[(data & 0x80) ? fg : 0]; + *p++ = palette[(data & 0x40) ? fg : 0]; + *p++ = palette[(data & 0x20) ? fg : 0]; + *p++ = palette[(data & 0x10) ? fg : 0]; + *p++ = palette[(data & 0x08) ? fg : 0]; + *p++ = palette[(data & 0x04) ? fg : 0]; + *p++ = palette[(data & 0x02) ? fg : 0]; + *p++ = palette[(data & 0x01) ? fg : 0]; + + data = videoram[offset + 1]; + + *p++ = palette[(data & 0x80) ? fg : 0]; + *p++ = palette[(data & 0x40) ? fg : 0]; + *p++ = palette[(data & 0x20) ? fg : 0]; + *p++ = palette[(data & 0x10) ? fg : 0]; + *p++ = palette[(data & 0x08) ? fg : 0]; + *p++ = palette[(data & 0x04) ? fg : 0]; + *p++ = palette[(data & 0x02) ? fg : 0]; + *p++ = palette[(data & 0x01) ? fg : 0]; } } @@ -961,205 +960,200 @@ void isa8_cga_device::io_write(offs_t offset, uint8_t data) // proc = cga_pgfx_4bpp; // -//static inline void pgfx_plot_unit_4bpp(bitmap_ind16 &bitmap, -// int x, int y, int offs) -//{ -// int color, values[2]; -// int i; -// -// if (cga.plantronics & 0x40) -// { -// values[0] = videoram[offs | 0x4000]; -// values[1] = videoram[offs]; -// } -// else -// { -// values[0] = videoram[offs]; -// values[1] = videoram[offs | 0x4000]; -// } -// for (i=3; i>=0; i--) -// { -// color = ((values[0] & 0x3) << 1) | -// ((values[1] & 2) >> 1) | -// ((values[1] & 1) << 3); -// bitmap.pix16(y, x+i) = Machine->pens[color]; -// values[0]>>=2; -// values[1]>>=2; -// } -//} -// -// -// +#if 0 +static inline void pgfx_plot_unit_4bpp(bitmap_ind16 &bitmap, int x, int y, int offs) +{ + int values[2]; + + if (cga.plantronics & 0x40) + { + values[0] = videoram[offs | 0x4000]; + values[1] = videoram[offs]; + } + else + { + values[0] = videoram[offs]; + values[1] = videoram[offs | 0x4000]; + } + for (int i = 3; i >= 0; i--) + { + int const color = + ((values[0] & 0x3) << 1) | + ((values[1] & 2) >> 1) | + ((values[1] & 1) << 3); + bitmap.pix(y, x + i) = Machine->pens[color]; + values[0] >>= 2; + values[1] >>= 2; + } +} +#endif + + ///*************************************************************************** // Draw graphics mode with 640x200 pixels (default) with 2 bits/pixel. // Even scanlines are from CGA_base + 0x0000, odd from CGA_base + 0x2000 // Second plane at CGA_base + 0x4000 / 0x6000 -//***************************************************************************/ -// -//static void cga_pgfx_4bpp(bitmap_ind16 &bitmap, struct mscrtc6845 *crtc) -//{ -// int i, sx, sy, sh; -// int offs = mscrtc6845_get_start(crtc)*2; -// int lines = mscrtc6845_get_char_lines(crtc); -// int height = mscrtc6845_get_char_height(crtc); -// int columns = mscrtc6845_get_char_columns(crtc)*2; -// -// for (sy=0; sy<lines; sy++,offs=(offs+columns)&0x1fff) -// { -// for (sh=0; sh<height; sh++, offs|=0x2000) -// { -// // char line 0 used as a12 line in graphic mode -// if (!(sh & 1)) -// { -// for (i=offs, sx=0; sx<columns; sx++, i=(i+1)&0x1fff) -// { -// pgfx_plot_unit_4bpp(bitmap, sx*4, sy*height+sh, i); -// } -// } -// else -// { -// for (i=offs|0x2000, sx=0; sx<columns; sx++, i=((i+1)&0x1fff)|0x2000) -// { -// pgfx_plot_unit_4bpp(bitmap, sx*4, sy*height+sh, i); -// } -// } -// } -// } -//} -// -// -// -//static inline void pgfx_plot_unit_2bpp(bitmap_ind16 &bitmap, -// int x, int y, const uint16_t *palette, int offs) -//{ -// int i; -// uint8_t bmap[2], values[2]; -// uint16_t *dest; -// -// if (cga.plantronics & 0x40) -// { -// values[0] = videoram[offs]; -// values[1] = videoram[offs | 0x4000]; -// } -// else -// { -// values[0] = videoram[offs | 0x4000]; -// values[1] = videoram[offs]; -// } -// bmap[0] = bmap[1] = 0; -// for (i=3; i>=0; i--) -// { -// bmap[0] = bmap[0] << 1; if (values[0] & 0x80) bmap[0] |= 1; -// bmap[0] = bmap[0] << 1; if (values[1] & 0x80) bmap[0] |= 1; -// bmap[1] = bmap[1] << 1; if (values[0] & 0x08) bmap[1] |= 1; -// bmap[1] = bmap[1] << 1; if (values[1] & 0x08) bmap[1] |= 1; -// values[0] = values[0] << 1; -// values[1] = values[1] << 1; -// } -// -// dest = &bitmap.pix16(y, x); -// *(dest++) = palette[(bmap[0] >> 6) & 0x03]; -// *(dest++) = palette[(bmap[0] >> 4) & 0x03]; -// *(dest++) = palette[(bmap[0] >> 2) & 0x03]; -// *(dest++) = palette[(bmap[0] >> 0) & 0x03]; -// *(dest++) = palette[(bmap[1] >> 6) & 0x03]; -// *(dest++) = palette[(bmap[1] >> 4) & 0x03]; -// *(dest++) = palette[(bmap[1] >> 2) & 0x03]; -// *(dest++) = palette[(bmap[1] >> 0) & 0x03]; -//} -// -// -// +//**************************************************************************** + +#if 0 +static void cga_pgfx_4bpp(bitmap_ind16 &bitmap, struct mscrtc6845 *crtc) +{ + int offs = mscrtc6845_get_start(crtc) * 2; + int const lines = mscrtc6845_get_char_lines(crtc); + int const height = mscrtc6845_get_char_height(crtc); + int columns = mscrtc6845_get_char_columns(crtc) * 2; + + for (int sy = 0; sy < lines; sy++, offs = (offs + columns) & 0x1fff) + { + for (int sh = 0; sh < height; sh++, offs |= 0x2000) + { + // char line 0 used as a12 line in graphic mode + if (!(sh & 1)) + { + for (int i = offs, sx = 0; sx < columns; sx++, i = (i + 1) & 0x1fff) + { + pgfx_plot_unit_4bpp(bitmap, sx * 4, sy * height + sh, i); + } + } + else + { + for (int i = offs | 0x2000, sx = 0; sx < columns; sx++, i = ((i + 1) & 0x1fff) | 0x2000) + { + pgfx_plot_unit_4bpp(bitmap, sx * 4, sy * height + sh, i); + } + } + } + } +} +#endif + + +#if 0 +static inline void pgfx_plot_unit_2bpp(bitmap_ind16 &bitmap, int x, int y, const uint16_t *palette, int offs) +{ + uint8_t values[2]; + if (cga.plantronics & 0x40) + { + values[0] = videoram[offs]; + values[1] = videoram[offs | 0x4000]; + } + else + { + values[0] = videoram[offs | 0x4000]; + values[1] = videoram[offs]; + } + uint8_t bmap[2] = { 0, 0 }; + for (int i = 3; i >= 0; i--) + { + bmap[0] = (bmap[0] << 1) | BIT(values[0], 7); + bmap[0] = (bmap[0] << 1) | BIT(values[1], 7); + bmap[1] = (bmap[1] << 1) | BIT(values[0], 3); + bmap[1] = (bmap[1] << 1) | BIT(values[1], 3); + values[0] <<= 1; + values[1] <<= 1; + } + + uint16_t *dest = &bitmap.pix(y, x); + *dest++ = palette[(bmap[0] >> 6) & 0x03]; + *dest++ = palette[(bmap[0] >> 4) & 0x03]; + *dest++ = palette[(bmap[0] >> 2) & 0x03]; + *dest++ = palette[(bmap[0] >> 0) & 0x03]; + *dest++ = palette[(bmap[1] >> 6) & 0x03]; + *dest++ = palette[(bmap[1] >> 4) & 0x03]; + *dest++ = palette[(bmap[1] >> 2) & 0x03]; + *dest++ = palette[(bmap[1] >> 0) & 0x03]; +} +#endif + + ///*************************************************************************** // Draw graphics mode with 320x200 pixels (default) with 2 bits/pixel. // Even scanlines are from CGA_base + 0x0000, odd from CGA_base + 0x2000 // cga fetches 2 byte per mscrtc6845 access (not modeled here)! -//***************************************************************************/ -// -//static void cga_pgfx_2bpp(bitmap_ind16 &bitmap, struct mscrtc6845 *crtc) -//{ -// int i, sx, sy, sh; -// int offs = mscrtc6845_get_start(crtc)*2; -// int lines = mscrtc6845_get_char_lines(crtc); -// int height = mscrtc6845_get_char_height(crtc); -// int columns = mscrtc6845_get_char_columns(crtc)*2; -// int colorset = cga.color_select & 0x3F; -// const uint16_t *palette; -// -// /* Most chipsets use bit 2 of the mode control register to -// * access a third palette. But not consistently. */ -// pc_cga_check_palette(); -// switch(CGA_CHIPSET) -// { -// /* The IBM Professional Graphics Controller behaves like -// * the PC1512, btw. */ -// case CGA_CHIPSET_PC1512: -// if ((colorset < 32) && (cga.mode_control & 4)) colorset += 64; -// break; -// -// case CGA_CHIPSET_IBM: -// case CGA_CHIPSET_PC200: -// case CGA_CHIPSET_ATI: -// case CGA_CHIPSET_PARADISE: -// if (cga.mode_control & 4) colorset = (colorset & 0x1F) + 64; -// break; -// } -// -// -// /* The fact that our palette is located in cga_colortable is a vestigial -// * aspect from when we were doing that ugly trick where drawgfx() would -// * handle graphics drawing. Truthfully, we should probably be using -// * palette_set_color_rgb() here and not doing the palette lookup in the loop -// */ -// palette = &cga_colortable[256*2 + 16*2] + colorset * 4; -// -// for (sy=0; sy<lines; sy++,offs=(offs+columns)&0x1fff) { -// -// for (sh=0; sh<height; sh++) -// { -// if (!(sh&1)) { // char line 0 used as a12 line in graphic mode -// for (i=offs, sx=0; sx<columns; sx++, i=(i+1)&0x1fff) -// { -// pgfx_plot_unit_2bpp(bitmap, sx*8, sy*height+sh, palette, i); -// } -// } -// else -// { -// for (i=offs|0x2000, sx=0; sx<columns; sx++, i=((i+1)&0x1fff)|0x2000) -// { -// pgfx_plot_unit_2bpp(bitmap, sx*8, sy*height+sh, palette, i); -// } -// } -// } -// } -//} +//**************************************************************************** + +#if 0 +static void cga_pgfx_2bpp(bitmap_ind16 &bitmap, struct mscrtc6845 *crtc) +{ + int offs = mscrtc6845_get_start(crtc) * 2; + int const lines = mscrtc6845_get_char_lines(crtc); + int const height = mscrtc6845_get_char_height(crtc); + int const columns = mscrtc6845_get_char_columns(crtc) * 2; + + /* Most chipsets use bit 2 of the mode control register to access a third palette. But not consistently. */ + int colorset = cga.color_select & 0x3f; + pc_cga_check_palette(); + switch (CGA_CHIPSET) + { + /* The IBM Professional Graphics Controller behaves like the PC1512, btw. */ + case CGA_CHIPSET_PC1512: + if ((colorset < 32) && (cga.mode_control & 4)) colorset += 64; + break; + + case CGA_CHIPSET_IBM: + case CGA_CHIPSET_PC200: + case CGA_CHIPSET_ATI: + case CGA_CHIPSET_PARADISE: + if (cga.mode_control & 4) colorset = (colorset & 0x1f) + 64; + break; + } + + /* The fact that our palette is located in cga_colortable is a vestigial + * aspect from when we were doing that ugly trick where drawgfx() would + * handle graphics drawing. Truthfully, we should probably be using + * palette_set_color_rgb() here and not doing the palette lookup in the loop + */ + uint16_t const *const palette = &cga_colortable[256*2 + 16*2] + colorset * 4; + + for (int sy = 0; sy < lines; sy++, offs = (offs + columns) & 0x1fff) + { + + for (int sh = 0; sh < height; sh++) + { + if (!(sh & 1)) // char line 0 used as a12 line in graphic mode + { + for (int i = offs, sx = 0; sx < columns; sx++, i = (i + 1) & 0x1fff) + { + pgfx_plot_unit_2bpp(bitmap, sx * 8, sy * height + sh, palette, i); + } + } + else + { + for (int i = offs | 0x2000, sx = 0; sx < columns; sx++, i= ((i + 1) & 0x1fff) | 0x2000) + { + pgfx_plot_unit_2bpp(bitmap, sx * 8, sy * height + sh, palette, i); + } + } + } + } +} +#endif MC6845_UPDATE_ROW( isa8_cga_pc1512_device::pc1512_gfx_4bpp_update_row ) { - uint8_t *videoram = &m_vram[m_start_offset]; - uint32_t *p = &bitmap.pix32(y); - const rgb_t *palette = m_palette->palette()->entry_list_raw(); - uint16_t offset_base = ra << 13; - int j; + uint8_t const *const videoram = &m_vram[m_start_offset]; + uint32_t *p = &bitmap.pix(y); + rgb_t const *const palette = m_palette->palette()->entry_list_raw(); + uint16_t const offset_base = ra << 13; - if ( y == 0 ) CGA_LOG(1,"pc1512_gfx_4bpp_update_row",("\n")); - for ( j = 0; j < x_count; j++ ) + if (y == 0) CGA_LOG(1,"pc1512_gfx_4bpp_update_row",("\n")); + for (int j = 0; j < x_count; j++) { - uint16_t offset = offset_base | ( ( ma + j ) & 0x1FFF ); - uint16_t i = ( m_color_select & 8 ) ? videoram[ isa8_cga_pc1512_device::vram_offset[3] | offset ] << 3 : 0; - uint16_t r = ( m_color_select & 4 ) ? videoram[ isa8_cga_pc1512_device::vram_offset[2] | offset ] << 2 : 0; - uint16_t g = ( m_color_select & 2 ) ? videoram[ isa8_cga_pc1512_device::vram_offset[1] | offset ] << 1 : 0; - uint16_t b = ( m_color_select & 1 ) ? videoram[ isa8_cga_pc1512_device::vram_offset[0] | offset ] : 0; - - *p = palette[( ( i & 0x400 ) | ( r & 0x200 ) | ( g & 0x100 ) | ( b & 0x80 ) ) >> 7]; p++; - *p = palette[( ( i & 0x200 ) | ( r & 0x100 ) | ( g & 0x080 ) | ( b & 0x40 ) ) >> 6]; p++; - *p = palette[( ( i & 0x100 ) | ( r & 0x080 ) | ( g & 0x040 ) | ( b & 0x20 ) ) >> 5]; p++; - *p = palette[( ( i & 0x080 ) | ( r & 0x040 ) | ( g & 0x020 ) | ( b & 0x10 ) ) >> 4]; p++; - *p = palette[( ( i & 0x040 ) | ( r & 0x020 ) | ( g & 0x010 ) | ( b & 0x08 ) ) >> 3]; p++; - *p = palette[( ( i & 0x020 ) | ( r & 0x010 ) | ( g & 0x008 ) | ( b & 0x04 ) ) >> 2]; p++; - *p = palette[( ( i & 0x010 ) | ( r & 0x008 ) | ( g & 0x004 ) | ( b & 0x02 ) ) >> 1]; p++; - *p = palette[ ( i & 0x008 ) | ( r & 0x004 ) | ( g & 0x002 ) | ( b & 0x01 ) ]; p++; + uint16_t const offset = offset_base | ((ma + j) & 0x1fff); + uint16_t const i = (m_color_select & 8) ? videoram[isa8_cga_pc1512_device::vram_offset[3] | offset] << 3 : 0; + uint16_t const r = (m_color_select & 4) ? videoram[isa8_cga_pc1512_device::vram_offset[2] | offset] << 2 : 0; + uint16_t const g = (m_color_select & 2) ? videoram[isa8_cga_pc1512_device::vram_offset[1] | offset] << 1 : 0; + uint16_t const b = (m_color_select & 1) ? videoram[isa8_cga_pc1512_device::vram_offset[0] | offset] : 0; + + *p++ = palette[((i & 0x400) | (r & 0x200) | (g & 0x100) | (b & 0x80) ) >> 7]; + *p++ = palette[((i & 0x200) | (r & 0x100) | (g & 0x080) | (b & 0x40) ) >> 6]; + *p++ = palette[((i & 0x100) | (r & 0x080) | (g & 0x040) | (b & 0x20) ) >> 5]; + *p++ = palette[((i & 0x080) | (r & 0x040) | (g & 0x020) | (b & 0x10) ) >> 4]; + *p++ = palette[((i & 0x040) | (r & 0x020) | (g & 0x010) | (b & 0x08) ) >> 3]; + *p++ = palette[((i & 0x020) | (r & 0x010) | (g & 0x008) | (b & 0x04) ) >> 2]; + *p++ = palette[((i & 0x010) | (r & 0x008) | (g & 0x004) | (b & 0x02) ) >> 1]; + *p++ = palette[ (i & 0x008) | (r & 0x004) | (g & 0x002) | (b & 0x01) ]; } } @@ -1500,31 +1494,38 @@ void isa8_wyse700_device::device_reset() uint32_t isa8_wyse700_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - if (m_control & 0x08) { - const rgb_t *palette = m_palette->palette()->entry_list_raw(); - uint8_t fg = m_color_select & 0x0F; + if (m_control & 0x08) + { + rgb_t const *const palette = m_palette->palette()->entry_list_raw(); + uint8_t const fg = m_color_select & 0x0F; uint32_t addr = 0; - for (int y = 0; y < 800; y++) { - uint8_t *src = &m_vram[addr]; + for (int y = 0; y < 800; y++) + { + uint8_t const *src = &m_vram[addr]; - if (y & 1) { + if (y & 1) + { src += 0x10000; addr += 160; } - for (int x = 0; x < (1280 / 8); x++) { + for (int x = 0; x < (1280 / 8); x++) + { uint8_t val = src[x]; - for (int i = 0; i < 8; i++) { - bitmap.pix32(y,x*8+i) = (val & 0x80) ? palette[fg] : palette[0x00]; + for (int i = 0; i < 8; i++) + { + bitmap.pix(y, x * 8 + i) = (val & 0x80) ? palette[fg] : palette[0x00]; val <<= 1; } } } - } else { + return 0; + } + else + { return isa8_cga_device::screen_update(screen, bitmap, cliprect); } - return 0; } @@ -1837,7 +1838,7 @@ uint8_t isa8_cga_m24_device::io_read(offs_t offset) MC6845_UPDATE_ROW(isa8_cga_m24_device::crtc_update_row) { - if(m_mode2 & 1) + if (m_mode2 & 1) { m24_gfx_1bpp_m24_update_row(bitmap, cliprect, ma, ra, y, x_count, cursor_x, de, hbp, vbp); return; @@ -1847,7 +1848,7 @@ MC6845_UPDATE_ROW(isa8_cga_m24_device::crtc_update_row) return; y = m_y; - if(m_y >= bitmap.height()) + if (m_y >= bitmap.height()) return; switch (m_update_row_type) @@ -1885,37 +1886,38 @@ MC6845_UPDATE_ROW(isa8_cga_m24_device::crtc_update_row) MC6845_UPDATE_ROW( isa8_cga_m24_device::m24_gfx_1bpp_m24_update_row ) { - uint8_t *videoram = &m_vram[m_start_offset]; - uint32_t *p = &bitmap.pix32(y); - const rgb_t *palette = m_palette->palette()->entry_list_raw(); - uint8_t fg = m_color_select & 0x0F; - int i; + uint8_t const *const videoram = &m_vram[m_start_offset]; + uint32_t *p = &bitmap.pix(y); + rgb_t const *const palette = m_palette->palette()->entry_list_raw(); + uint8_t const fg = m_color_select & 0x0f; - if ( y == 0 ) CGA_LOG(1,"m24_gfx_1bpp_m24_update_row",("\n")); - for ( i = 0; i < x_count; i++ ) + if (y == 0) CGA_LOG(1,"m24_gfx_1bpp_m24_update_row",("\n")); + for (int i = 0; i < x_count; i++) { - uint16_t offset = ( ( ( ma + i ) << 1 ) & 0x1fff ) | ( ( ra & 3 ) << 13 ); - uint8_t data = videoram[ offset ]; - - *p = palette[( data & 0x80 ) ? fg : 0]; p++; - *p = palette[( data & 0x40 ) ? fg : 0]; p++; - *p = palette[( data & 0x20 ) ? fg : 0]; p++; - *p = palette[( data & 0x10 ) ? fg : 0]; p++; - *p = palette[( data & 0x08 ) ? fg : 0]; p++; - *p = palette[( data & 0x04 ) ? fg : 0]; p++; - *p = palette[( data & 0x02 ) ? fg : 0]; p++; - *p = palette[( data & 0x01 ) ? fg : 0]; p++; - - data = videoram[ offset + 1 ]; - - *p = palette[( data & 0x80 ) ? fg : 0]; p++; - *p = palette[( data & 0x40 ) ? fg : 0]; p++; - *p = palette[( data & 0x20 ) ? fg : 0]; p++; - *p = palette[( data & 0x10 ) ? fg : 0]; p++; - *p = palette[( data & 0x08 ) ? fg : 0]; p++; - *p = palette[( data & 0x04 ) ? fg : 0]; p++; - *p = palette[( data & 0x02 ) ? fg : 0]; p++; - *p = palette[( data & 0x01 ) ? fg : 0]; p++; + uint16_t const offset = (((ma + i) << 1 ) & 0x1fff) | ((ra & 3) << 13); + uint8_t data; + + data = videoram[offset]; + + *p++ = palette[(data & 0x80) ? fg : 0]; + *p++ = palette[(data & 0x40) ? fg : 0]; + *p++ = palette[(data & 0x20) ? fg : 0]; + *p++ = palette[(data & 0x10) ? fg : 0]; + *p++ = palette[(data & 0x08) ? fg : 0]; + *p++ = palette[(data & 0x04) ? fg : 0]; + *p++ = palette[(data & 0x02) ? fg : 0]; + *p++ = palette[(data & 0x01) ? fg : 0]; + + data = videoram[offset + 1]; + + *p++ = palette[(data & 0x80) ? fg : 0]; + *p++ = palette[(data & 0x40) ? fg : 0]; + *p++ = palette[(data & 0x20) ? fg : 0]; + *p++ = palette[(data & 0x10) ? fg : 0]; + *p++ = palette[(data & 0x08) ? fg : 0]; + *p++ = palette[(data & 0x04) ? fg : 0]; + *p++ = palette[(data & 0x02) ? fg : 0]; + *p++ = palette[(data & 0x01) ? fg : 0]; } } diff --git a/src/devices/bus/isa/ega.cpp b/src/devices/bus/isa/ega.cpp index e3d75e4070a..45d169f3dff 100644 --- a/src/devices/bus/isa/ega.cpp +++ b/src/devices/bus/isa/ega.cpp @@ -783,7 +783,7 @@ WRITE_LINE_MEMBER( isa8_ega_device::vblank_changed ) CRTC_EGA_ROW_UPDATE( isa8_ega_device::pc_ega_graphics ) { - uint16_t *p = &bitmap.pix16(y); + uint16_t *p = &bitmap.pix(y); LOG("%s: y = %d, x_count = %d, ma = %d, ra = %d\n", FUNCNAME, y, x_count, ma, ra ); @@ -844,12 +844,11 @@ CRTC_EGA_ROW_UPDATE( isa8_ega_device::pc_ega_graphics ) CRTC_EGA_ROW_UPDATE( isa8_ega_device::pc_ega_text ) { - uint16_t *p = &bitmap.pix16(y); - int i; + uint16_t *p = &bitmap.pix(y); LOG("%s: y = %d, x_count = %d, ma = %d, ra = %d\n", FUNCNAME, y, x_count, ma, ra ); - for ( i = 0; i < x_count; i++ ) + for ( int i = 0; i < x_count; i++ ) { uint16_t offset = ma + i; uint8_t chr = m_plane[0][ offset ]; @@ -901,8 +900,6 @@ CRTC_EGA_ROW_UPDATE( isa8_ega_device::pc_ega_text ) void isa8_ega_device::change_mode() { - int clock, pixels; - m_video_mode = 0; /* Check for graphics mode */ @@ -938,8 +935,8 @@ void isa8_ega_device::change_mode() } /* Check for changes to the crtc input clock and number of pixels per clock */ - clock = ( ( m_misc_output & 0x0c ) ? 16257000 : 14318181 ); - pixels = ( ( m_sequencer.data[0x01] & 0x01 ) ? 8 : 9 ); + int clock = ( ( m_misc_output & 0x0c ) ? 16257000 : 14318181 ); + int pixels = ( ( m_sequencer.data[0x01] & 0x01 ) ? 8 : 9 ); if ( m_sequencer.data[0x01] & 0x08 ) { diff --git a/src/devices/bus/isa/eis_hgb107x.cpp b/src/devices/bus/isa/eis_hgb107x.cpp index 32aeac02c3e..25b16a38fe3 100644 --- a/src/devices/bus/isa/eis_hgb107x.cpp +++ b/src/devices/bus/isa/eis_hgb107x.cpp @@ -420,10 +420,6 @@ inline int isa8_epc_mda_device::get_yres() MC6845_UPDATE_ROW(isa8_epc_mda_device::crtc_update_row) { - uint32_t *p = &bitmap.pix32(y); - uint16_t chr_base = ra; - int i; - // Get som debug data from a couple of rows now and then if ( y < (16 * 0 + 0x20) && (m_framecnt & 0xff) == 0 ) { @@ -436,7 +432,7 @@ MC6845_UPDATE_ROW(isa8_epc_mda_device::crtc_update_row) { for (int i = 0; i < get_xres(); i++) { - bitmap.pix32(y, i) = rgb_t::black(); + bitmap.pix(y, i) = rgb_t::black(); } } @@ -449,14 +445,17 @@ MC6845_UPDATE_ROW(isa8_epc_mda_device::crtc_update_row) // Text modes using one of two 9x16 fonts in character rom else { + uint32_t *p = &bitmap.pix(y); + uint16_t chr_base = ra; + // Adjust row pointer if in monochrome text mode as we insert two scanlines per row of characters (see below) if (m_vmode & VM_MONO) { - p = &bitmap.pix32((y / 14) * 16 + y % 14); + p = &bitmap.pix((y / 14) * 16 + y % 14); } // Loop over each character in a row - for ( i = 0; i < x_count; i++ ) + for ( int i = 0; i < x_count; i++ ) { uint16_t offset = ( ( ma + i ) << 1 ) & 0x0FFF; uint8_t chr = m_videoram[ offset ]; @@ -555,14 +554,14 @@ MC6845_UPDATE_ROW(isa8_epc_mda_device::crtc_update_row) { if (chr >= 0xb3 && chr <= 0xdf) // Handle the meta graphics characters { - bitmap.pix32(row + 1, j + i * 9) = (*m_pal)[( data & (0x80 >> j) ) || (j == 8 && (data & 0x01)) ? fg : bg]; - bitmap.pix32(row + 2, j + i * 9) = (*m_pal)[( data & (0x80 >> j) ) || (j == 8 && (data & 0x01)) ? fg : bg]; + bitmap.pix(row + 1, j + i * 9) = (*m_pal)[( data & (0x80 >> j) ) || (j == 8 && (data & 0x01)) ? fg : bg]; + bitmap.pix(row + 2, j + i * 9) = (*m_pal)[( data & (0x80 >> j) ) || (j == 8 && (data & 0x01)) ? fg : bg]; } else { // Handle underline - bitmap.pix32(row + 1, j + i * 9) =(*m_pal)[( attr & ATTR_FOREG ) == ATTR_ULINE ? fg : bg]; - bitmap.pix32(row + 2, j + i * 9) = (*m_pal)[bg]; + bitmap.pix(row + 1, j + i * 9) =(*m_pal)[( attr & ATTR_FOREG ) == ATTR_ULINE ? fg : bg]; + bitmap.pix(row + 2, j + i * 9) = (*m_pal)[bg]; } } } diff --git a/src/devices/bus/isa/ex1280.cpp b/src/devices/bus/isa/ex1280.cpp index 84c8bb8d269..2d9153616e9 100644 --- a/src/devices/bus/isa/ex1280.cpp +++ b/src/devices/bus/isa/ex1280.cpp @@ -144,15 +144,15 @@ void isa16_ex1280_device::vram_w(offs_t offset, uint16_t data, uint16_t mem_mask TMS340X0_SCANLINE_RGB32_CB_MEMBER(isa16_ex1280_device::scanline_update) { - uint16_t *src = &m_vram[params->rowaddr << 8]; - uint32_t *dest = &bitmap.pix32(scanline); - const pen_t *pens = m_ramdac->pens(); + uint16_t const *const src = &m_vram[params->rowaddr << 8]; + uint32_t *const dest = &bitmap.pix(scanline); + pen_t const *const pens = m_ramdac->pens(); int coladdr = params->coladdr << 1; /* copy the non-blanked portions of this scanline */ for (int x = params->heblnk; x < params->hsblnk; x += 4) { - uint16_t pixels = src[coladdr++]; + uint16_t const pixels = src[coladdr++]; dest[x + 0] = pens[pixels & 0x0f]; dest[x + 1] = pens[(pixels >> 4) & 0x0f]; dest[x + 2] = pens[(pixels >> 8) & 0x0f]; diff --git a/src/devices/bus/isa/fdc.cpp b/src/devices/bus/isa/fdc.cpp index 0648a16a6e3..aab99b12ed5 100644 --- a/src/devices/bus/isa/fdc.cpp +++ b/src/devices/bus/isa/fdc.cpp @@ -45,10 +45,6 @@ isa8_fdc_device::isa8_fdc_device(const machine_config &mconfig, device_type type { } -void isa8_fdc_device::device_reset() -{ -} - WRITE_LINE_MEMBER( isa8_fdc_device::irq_w ) { m_isa->irq6_w(state ? ASSERT_LINE : CLEAR_LINE); @@ -80,7 +76,9 @@ void isa8_fdc_device::eop_w(int state) } -isa8_upd765_fdc_device::isa8_upd765_fdc_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : isa8_fdc_device(mconfig, type, tag, owner, clock) +isa8_upd765_fdc_device::isa8_upd765_fdc_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) + : isa8_fdc_device(mconfig, type, tag, owner, clock) + , dor(0x00) { } @@ -94,7 +92,11 @@ void isa8_upd765_fdc_device::device_start() irq = drq = false; fdc_irq = fdc_drq = false; - dor = 0x00; +} + +void isa8_upd765_fdc_device::device_reset() +{ + dor_w(0x00); } // Bits 0-1 select one of the 4 drives, but only if the associated @@ -109,7 +111,6 @@ void isa8_upd765_fdc_device::device_start() void isa8_upd765_fdc_device::dor_w(uint8_t data) { LOG("dor = %02x\n", data); - uint8_t pdor = dor; dor = data; for(int i=0; i<4; i++) @@ -124,8 +125,7 @@ void isa8_upd765_fdc_device::dor_w(uint8_t data) check_irq(); check_drq(); - if((pdor^dor) & 4) - m_fdc->soft_reset(); + m_fdc->reset_w(!BIT(dor, 2)); } uint8_t isa8_upd765_fdc_device::dor_r() diff --git a/src/devices/bus/isa/fdc.h b/src/devices/bus/isa/fdc.h index a0c872a28f0..d4321ca4210 100644 --- a/src/devices/bus/isa/fdc.h +++ b/src/devices/bus/isa/fdc.h @@ -34,9 +34,6 @@ protected: // construction/destruction isa8_fdc_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); - // device-level overrides - virtual void device_reset() override; - virtual uint8_t dack_r(int line) override; virtual void dack_w(int line, uint8_t data) override; virtual void dack_line_w(int line, int state) override; @@ -53,6 +50,7 @@ protected: // device-level overrides virtual void device_start() override; + virtual void device_reset() override; uint8_t dor_r(); void dor_w(uint8_t data); diff --git a/src/devices/bus/isa/gus.cpp b/src/devices/bus/isa/gus.cpp index a1c3f39612e..237211047a2 100644 --- a/src/devices/bus/isa/gus.cpp +++ b/src/devices/bus/isa/gus.cpp @@ -243,29 +243,26 @@ void gf1_device::device_timer(emu_timer &timer, device_timer_id id, int param, v } } -void gf1_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void gf1_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - int x,y; + int x; //uint32_t count; - stream_sample_t* outputl = outputs[0]; - stream_sample_t* outputr = outputs[1]; - memset( outputl, 0x00, samples * sizeof(*outputl) ); - memset( outputr, 0x00, samples * sizeof(*outputr) ); + auto &outputl = outputs[0]; + auto &outputr = outputs[1]; + + outputl.fill(0); + outputr.fill(0); for(x=0;x<32;x++) // for each voice { - stream_sample_t* left = outputl; - stream_sample_t* right = outputr; uint16_t vol = (m_volume_table[(m_voice[x].current_vol & 0xfff0) >> 4]); - for(y=samples-1; y>=0; y--) + for (int sampindex = 0; sampindex < outputl.samples(); sampindex++) { uint32_t current = m_voice[x].current_addr >> 9; // TODO: implement proper panning - (*left) += ((m_voice[x].sample) * (vol/8192.0)); - (*right) += ((m_voice[x].sample) * (vol/8192.0)); - left++; - right++; + outputl.add_int(sampindex, m_voice[x].sample * vol, 32768 * 8192); + outputr.add_int(sampindex, m_voice[x].sample * vol, 32768 * 8192); if((!(m_voice[x].voice_ctrl & 0x40)) && (m_voice[x].current_addr >= m_voice[x].end_addr) && !m_voice[x].rollover && !(m_voice[x].voice_ctrl & 0x01)) { if(m_voice[x].vol_ramp_ctrl & 0x04) @@ -403,7 +400,7 @@ void gf1_device::device_start() m_wave_ram.resize(1024*1024); memset(&m_wave_ram[0], 0, 1024*1024); - m_stream = stream_alloc_legacy(0,2,clock() / (14 * 16)); + m_stream = stream_alloc(0,2,clock() / (14 * 16)); // init timers m_timer1 = timer_alloc(ADLIB_TIMER1); diff --git a/src/devices/bus/isa/gus.h b/src/devices/bus/isa/gus.h index 3f637bee84d..be8dbbdbe2d 100644 --- a/src/devices/bus/isa/gus.h +++ b/src/devices/bus/isa/gus.h @@ -123,7 +123,7 @@ public: // optional information overrides virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; protected: // voice-specific registers diff --git a/src/devices/bus/isa/isa_cards.cpp b/src/devices/bus/isa/isa_cards.cpp index 72681cc249e..8f1232dcd13 100644 --- a/src/devices/bus/isa/isa_cards.cpp +++ b/src/devices/bus/isa/isa_cards.cpp @@ -49,6 +49,7 @@ #include "ultra24f.h" #include "tekram_dc820.h" #include "asc88.h" +#include "omti8621.h" // sound #include "adlib.h" @@ -225,4 +226,5 @@ void pc_isa16_cards(device_slot_interface &device) device.option_add("dc320e", TEKRAM_DC320E); // actually an EISA card device.option_add("dc820", TEKRAM_DC820); // actually an EISA card device.option_add("dc820b", TEKRAM_DC820B); // actually an EISA card + device.option_add("omti8621", ISA16_OMTI8621); } diff --git a/src/devices/bus/isa/mach32.cpp b/src/devices/bus/isa/mach32.cpp index 602147aa060..e9f4ad8d197 100644 --- a/src/devices/bus/isa/mach32.cpp +++ b/src/devices/bus/isa/mach32.cpp @@ -180,11 +180,8 @@ uint32_t mach32_device::screen_update(screen_device &screen, bitmap_rgb32 &bitma return 0; uint32_t src = (m_cursor_address & 0x000fffff) << 2; - uint32_t* dst; // destination pixel - uint8_t x,y,z; - uint32_t colour0; - uint32_t colour1; + uint32_t colour0, colour1; if(depth == 8) { colour0 = pen(m_cursor_colour0_b); @@ -197,18 +194,18 @@ uint32_t mach32_device::screen_update(screen_device &screen, bitmap_rgb32 &bitma } // draw hardware pointer (64x64 max) - for(y=0;y<64;y++) + for(uint8_t y=0;y<64;y++) { - dst = &bitmap.pix32(m_cursor_vertical + y, m_cursor_horizontal); - for(x=0;x<64;x+=8) + uint32_t *dst = &bitmap.pix(m_cursor_vertical + y, m_cursor_horizontal); + for(uint8_t x=0;x<64;x+=8) { - uint16_t bits = (vga.memory[(src+0) % vga.svga_intf.vram_size] | ((vga.memory[(src+1) % vga.svga_intf.vram_size]) << 8)); + uint16_t const bits = (vga.memory[(src+0) % vga.svga_intf.vram_size] | ((vga.memory[(src+1) % vga.svga_intf.vram_size]) << 8)); - for(z=0;z<8;z++) + for(uint8_t z=0;z<8;z++) { if(((z + x) > (m_cursor_offset_horizontal-1)) && (y < (63 - m_cursor_offset_vertical))) { - uint8_t val = (bits >> (z*2)) & 0x03; + uint8_t const val = (bits >> (z*2)) & 0x03; switch(val) { case 0: // cursor colour 0 diff --git a/src/devices/bus/isa/mda.cpp b/src/devices/bus/isa/mda.cpp index cf4a6aa3803..ae61e78e116 100644 --- a/src/devices/bus/isa/mda.cpp +++ b/src/devices/bus/isa/mda.cpp @@ -225,27 +225,26 @@ void isa8_mda_device::device_reset() ***************************************************************************/ MC6845_UPDATE_ROW( isa8_mda_device::mda_text_inten_update_row ) { - const rgb_t *palette = m_palette->palette()->entry_list_raw(); - uint32_t *p = &bitmap.pix32(y); - uint16_t chr_base = ( ra & 0x08 ) ? 0x800 | ( ra & 0x07 ) : ra; - int i; + rgb_t const *const palette = m_palette->palette()->entry_list_raw(); + uint32_t *p = &bitmap.pix(y); + uint16_t const chr_base = (ra & 0x08) ? 0x800 | (ra & 0x07) : ra; - if ( y == 0 ) LOGROW("%11.6f: %-24s\n", machine().time().as_double(), FUNCNAME); - for ( i = 0; i < x_count; i++ ) + if (y == 0) LOGROW("%11.6f: %-24s\n", machine().time().as_double(), FUNCNAME); + for (int i = 0; i < x_count; i++) { - uint16_t offset = ( ( ma + i ) << 1 ) & 0x0FFF; - uint8_t chr = m_videoram[ offset ]; - uint8_t attr = m_videoram[ offset + 1 ]; - uint8_t data = m_chr_gen[ chr_base + chr * 8 ]; - uint8_t fg = ( attr & 0x08 ) ? 3 : 2; + uint16_t const offset = ((ma + i) << 1) & 0x0fff; + uint8_t const chr = m_videoram[offset]; + uint8_t const attr = m_videoram[offset + 1]; + uint8_t data = m_chr_gen[chr_base + chr * 8]; + uint8_t fg = (attr & 0x08) ? 3 : 2; uint8_t bg = 0; - if ( ( attr & ~0x88 ) == 0 ) + if ((attr & ~0x88) == 0) { data = 0x00; } - switch( attr ) + switch (attr) { case 0x70: bg = 2; @@ -255,36 +254,36 @@ MC6845_UPDATE_ROW( isa8_mda_device::mda_text_inten_update_row ) bg = 2; fg = 1; break; - case 0xF0: + case 0xf0: bg = 3; fg = 0; break; - case 0xF8: + case 0xf8: bg = 3; fg = 1; break; } - if ( ( i == cursor_x && ( m_framecnt & 0x08 ) ) || ( attr & 0x07 ) == 0x01 ) + if ((i == cursor_x && (m_framecnt & 0x08)) || (attr & 0x07) == 0x01) { - data = 0xFF; + data = 0xff; } - *p = palette[( data & 0x80 ) ? fg : bg]; p++; - *p = palette[( data & 0x40 ) ? fg : bg]; p++; - *p = palette[( data & 0x20 ) ? fg : bg]; p++; - *p = palette[( data & 0x10 ) ? fg : bg]; p++; - *p = palette[( data & 0x08 ) ? fg : bg]; p++; - *p = palette[( data & 0x04 ) ? fg : bg]; p++; - *p = palette[( data & 0x02 ) ? fg : bg]; p++; - *p = palette[( data & 0x01 ) ? fg : bg]; p++; - if ( ( chr & 0xE0 ) == 0xC0 ) + *p++ = palette[(data & 0x80) ? fg : bg]; + *p++ = palette[(data & 0x40) ? fg : bg]; + *p++ = palette[(data & 0x20) ? fg : bg]; + *p++ = palette[(data & 0x10) ? fg : bg]; + *p++ = palette[(data & 0x08) ? fg : bg]; + *p++ = palette[(data & 0x04) ? fg : bg]; + *p++ = palette[(data & 0x02) ? fg : bg]; + *p++ = palette[(data & 0x01) ? fg : bg]; + if ((chr & 0xe0) == 0xc0) { - *p = palette[( data & 0x01 ) ? fg : bg]; p++; + *p++ = palette[(data & 0x01) ? fg : bg]; } else { - *p = palette[bg]; p++; + *p++ = palette[bg]; } } } @@ -298,75 +297,74 @@ MC6845_UPDATE_ROW( isa8_mda_device::mda_text_inten_update_row ) MC6845_UPDATE_ROW( isa8_mda_device::mda_text_blink_update_row ) { - const rgb_t *palette = m_palette->palette()->entry_list_raw(); - uint32_t *p = &bitmap.pix32(y); - uint16_t chr_base = ( ra & 0x08 ) ? 0x800 | ( ra & 0x07 ) : ra; - int i; + rgb_t const *const palette = m_palette->palette()->entry_list_raw(); + uint32_t *p = &bitmap.pix(y); + uint16_t const chr_base = (ra & 0x08) ? 0x800 | (ra & 0x07) : ra; - if ( y == 0 ) LOGROW("%11.6f: %-24s\n", machine().time().as_double(), FUNCNAME); - for ( i = 0; i < x_count; i++ ) + if (y == 0) LOGROW("%11.6f: %-24s\n", machine().time().as_double(), FUNCNAME); + for (int i = 0; i < x_count; i++) { - uint16_t offset = ( ( ma + i ) << 1 ) & 0x0FFF; - uint8_t chr = m_videoram[ offset ]; - uint8_t attr = m_videoram[ offset + 1 ]; - uint8_t data = m_chr_gen[ chr_base + chr * 8 ]; - uint8_t fg = ( attr & 0x08 ) ? 3 : 2; + uint16_t const offset = ((ma + i) << 1) & 0x0fff; + uint8_t const chr = m_videoram[offset]; + uint8_t const attr = m_videoram[offset + 1]; + uint8_t data = m_chr_gen[chr_base + chr * 8]; + uint8_t fg = (attr & 0x08) ? 3 : 2; uint8_t bg = 0; - if ( ( attr & ~0x88 ) == 0 ) + if ((attr & ~0x88) == 0) { data = 0x00; } - switch( attr ) + switch (attr) { case 0x70: - case 0xF0: + case 0xf0: bg = 2; fg = 0; break; case 0x78: - case 0xF8: + case 0xf8: bg = 2; fg = 1; break; } - if ( ( attr & 0x07 ) == 0x01 ) + if ((attr & 0x07) == 0x01) { - data = 0xFF; + data = 0xff; } - if ( i == cursor_x ) + if (i == cursor_x) { - if ( m_framecnt & 0x08 ) + if (m_framecnt & 0x08) { - data = 0xFF; + data = 0xff; } } else { - if ( ( attr & 0x80 ) && ( m_framecnt & 0x10 ) ) + if ((attr & 0x80) && (m_framecnt & 0x10)) { data = 0x00; } } - *p = palette[( data & 0x80 ) ? fg : bg]; p++; - *p = palette[( data & 0x40 ) ? fg : bg]; p++; - *p = palette[( data & 0x20 ) ? fg : bg]; p++; - *p = palette[( data & 0x10 ) ? fg : bg]; p++; - *p = palette[( data & 0x08 ) ? fg : bg]; p++; - *p = palette[( data & 0x04 ) ? fg : bg]; p++; - *p = palette[( data & 0x02 ) ? fg : bg]; p++; - *p = palette[( data & 0x01 ) ? fg : bg]; p++; - if ( ( chr & 0xE0 ) == 0xC0 ) + *p++ = palette[(data & 0x80) ? fg : bg]; + *p++ = palette[(data & 0x40) ? fg : bg]; + *p++ = palette[(data & 0x20) ? fg : bg]; + *p++ = palette[(data & 0x10) ? fg : bg]; + *p++ = palette[(data & 0x08) ? fg : bg]; + *p++ = palette[(data & 0x04) ? fg : bg]; + *p++ = palette[(data & 0x02) ? fg : bg]; + *p++ = palette[(data & 0x01) ? fg : bg]; + if ((chr & 0xe0) == 0xc0) { - *p = palette[( data & 0x01 ) ? fg : bg]; p++; + *p++ = palette[(data & 0x01) ? fg : bg]; } else { - *p = palette[bg]; p++; + *p++ = palette[bg]; } } } @@ -631,34 +629,36 @@ void isa8_hercules_device::device_reset() MC6845_UPDATE_ROW( isa8_hercules_device::hercules_gfx_update_row ) { - const rgb_t *palette = m_palette->palette()->entry_list_raw(); - uint32_t *p = &bitmap.pix32(y); - uint16_t gfx_base = ( ( m_mode_control & 0x80 ) ? 0x8000 : 0x0000 ) | ( ( ra & 0x03 ) << 13 ); - int i; - if ( y == 0 ) LOGROW("%11.6f: %-24s\n", machine().time().as_double(), FUNCNAME); - for ( i = 0; i < x_count; i++ ) + rgb_t const *const palette = m_palette->palette()->entry_list_raw(); + uint32_t *p = &bitmap.pix(y); + uint16_t const gfx_base = ((m_mode_control & 0x80) ? 0x8000 : 0x0000) | ((ra & 0x03) << 13); + + if (y == 0) LOGROW("%11.6f: %-24s\n", machine().time().as_double(), FUNCNAME); + for (int i = 0; i < x_count; i++) { - uint8_t data = m_videoram[ gfx_base + ( ( ma + i ) << 1 ) ]; - - *p = palette[( data & 0x80 ) ? 2 : 0]; p++; - *p = palette[( data & 0x40 ) ? 2 : 0]; p++; - *p = palette[( data & 0x20 ) ? 2 : 0]; p++; - *p = palette[( data & 0x10 ) ? 2 : 0]; p++; - *p = palette[( data & 0x08 ) ? 2 : 0]; p++; - *p = palette[( data & 0x04 ) ? 2 : 0]; p++; - *p = palette[( data & 0x02 ) ? 2 : 0]; p++; - *p = palette[( data & 0x01 ) ? 2 : 0]; p++; - - data = m_videoram[ gfx_base + ( ( ma + i ) << 1 ) + 1 ]; - - *p = palette[( data & 0x80 ) ? 2 : 0]; p++; - *p = palette[( data & 0x40 ) ? 2 : 0]; p++; - *p = palette[( data & 0x20 ) ? 2 : 0]; p++; - *p = palette[( data & 0x10 ) ? 2 : 0]; p++; - *p = palette[( data & 0x08 ) ? 2 : 0]; p++; - *p = palette[( data & 0x04 ) ? 2 : 0]; p++; - *p = palette[( data & 0x02 ) ? 2 : 0]; p++; - *p = palette[( data & 0x01 ) ? 2 : 0]; p++; + uint8_t data; + + data = m_videoram[gfx_base + ((ma + i) << 1)]; + + *p++ = palette[(data & 0x80) ? 2 : 0]; + *p++ = palette[(data & 0x40) ? 2 : 0]; + *p++ = palette[(data & 0x20) ? 2 : 0]; + *p++ = palette[(data & 0x10) ? 2 : 0]; + *p++ = palette[(data & 0x08) ? 2 : 0]; + *p++ = palette[(data & 0x04) ? 2 : 0]; + *p++ = palette[(data & 0x02) ? 2 : 0]; + *p++ = palette[(data & 0x01) ? 2 : 0]; + + data = m_videoram[gfx_base + ((ma + i) << 1) + 1]; + + *p++ = palette[(data & 0x80) ? 2 : 0]; + *p++ = palette[(data & 0x40) ? 2 : 0]; + *p++ = palette[(data & 0x20) ? 2 : 0]; + *p++ = palette[(data & 0x10) ? 2 : 0]; + *p++ = palette[(data & 0x08) ? 2 : 0]; + *p++ = palette[(data & 0x04) ? 2 : 0]; + *p++ = palette[(data & 0x02) ? 2 : 0]; + *p++ = palette[(data & 0x01) ? 2 : 0]; } } @@ -816,27 +816,26 @@ void isa8_ec1840_0002_device::device_reset() MC6845_UPDATE_ROW( isa8_ec1840_0002_device::mda_lowres_text_inten_update_row ) { - const rgb_t *palette = m_palette->palette()->entry_list_raw(); - uint32_t *p = &bitmap.pix32(y); - uint16_t chr_base = ra; - int i; + rgb_t const *const palette = m_palette->palette()->entry_list_raw(); + uint32_t *p = &bitmap.pix(y); + uint16_t const chr_base = ra; - if ( y == 0 ) LOGROW("%11.6f: %-24s\n", machine().time().as_double(), FUNCNAME); - for ( i = 0; i < x_count; i++ ) + if (y == 0) LOGROW("%11.6f: %-24s\n", machine().time().as_double(), FUNCNAME); + for (int i = 0; i < x_count; i++) { - uint16_t offset = ( ( ma + i ) << 1 ) & 0x0FFF; - uint8_t chr = m_videoram[ offset ]; - uint8_t attr = m_videoram[ offset + 1 ]; - uint8_t data = m_chr_gen[ (chr_base + chr * 16) << 1 ]; - uint8_t fg = ( attr & 0x08 ) ? 3 : 2; + uint16_t const offset = ((ma + i) << 1) & 0x0fff; + uint8_t const chr = m_videoram[offset]; + uint8_t const attr = m_videoram[offset + 1]; + uint8_t data = m_chr_gen[(chr_base + chr * 16) << 1]; + uint8_t fg = (attr & 0x08) ? 3 : 2; uint8_t bg = 0; - if ( ( attr & ~0x88 ) == 0 ) + if ((attr & ~0x88) == 0) { data = 0x00; } - switch( attr ) + switch (attr) { case 0x70: bg = 2; @@ -846,29 +845,29 @@ MC6845_UPDATE_ROW( isa8_ec1840_0002_device::mda_lowres_text_inten_update_row ) bg = 2; fg = 1; break; - case 0xF0: + case 0xf0: bg = 3; fg = 0; break; - case 0xF8: + case 0xf8: bg = 3; fg = 1; break; } - if ( ( i == cursor_x && ( m_framecnt & 0x08 ) ) || ( attr & 0x07 ) == 0x01 ) + if ((i == cursor_x && (m_framecnt & 0x08)) || (attr & 0x07) == 0x01) { - data = 0xFF; + data = 0xff; } - *p = palette[( data & 0x80 ) ? fg : bg]; p++; - *p = palette[( data & 0x40 ) ? fg : bg]; p++; - *p = palette[( data & 0x20 ) ? fg : bg]; p++; - *p = palette[( data & 0x10 ) ? fg : bg]; p++; - *p = palette[( data & 0x08 ) ? fg : bg]; p++; - *p = palette[( data & 0x04 ) ? fg : bg]; p++; - *p = palette[( data & 0x02 ) ? fg : bg]; p++; - *p = palette[( data & 0x01 ) ? fg : bg]; p++; + *p++ = palette[(data & 0x80) ? fg : bg]; + *p++ = palette[(data & 0x40) ? fg : bg]; + *p++ = palette[(data & 0x20) ? fg : bg]; + *p++ = palette[(data & 0x10) ? fg : bg]; + *p++ = palette[(data & 0x08) ? fg : bg]; + *p++ = palette[(data & 0x04) ? fg : bg]; + *p++ = palette[(data & 0x02) ? fg : bg]; + *p++ = palette[(data & 0x01) ? fg : bg]; } } @@ -880,68 +879,67 @@ MC6845_UPDATE_ROW( isa8_ec1840_0002_device::mda_lowres_text_inten_update_row ) MC6845_UPDATE_ROW( isa8_ec1840_0002_device::mda_lowres_text_blink_update_row ) { - const rgb_t *palette = m_palette->palette()->entry_list_raw(); - uint32_t *p = &bitmap.pix32(y); - uint16_t chr_base = ra; - int i; + rgb_t const *const palette = m_palette->palette()->entry_list_raw(); + uint32_t *p = &bitmap.pix(y); + uint16_t const chr_base = ra; - if ( y == 0 ) LOGROW("%11.6f: %-24s\n", machine().time().as_double(), FUNCNAME); - for ( i = 0; i < x_count; i++ ) + if (y == 0) LOGROW("%11.6f: %-24s\n", machine().time().as_double(), FUNCNAME); + for (int i = 0; i < x_count; i++) { - uint16_t offset = ( ( ma + i ) << 1 ) & 0x0FFF; - uint8_t chr = m_videoram[ offset ]; - uint8_t attr = m_videoram[ offset + 1 ]; - uint8_t data = m_chr_gen[ (chr_base + chr * 16) << 1 ]; - uint8_t fg = ( attr & 0x08 ) ? 3 : 2; + uint16_t const offset = ((ma + i) << 1) & 0x0fff; + uint8_t const chr = m_videoram[offset]; + uint8_t const attr = m_videoram[offset + 1]; + uint8_t data = m_chr_gen[(chr_base + chr * 16) << 1]; + uint8_t fg = (attr & 0x08) ? 3 : 2; uint8_t bg = 0; - if ( ( attr & ~0x88 ) == 0 ) + if ((attr & ~0x88) == 0) { data = 0x00; } - switch( attr ) + switch (attr) { case 0x70: - case 0xF0: + case 0xf0: bg = 2; fg = 0; break; case 0x78: - case 0xF8: + case 0xf8: bg = 2; fg = 1; break; } - if ( ( attr & 0x07 ) == 0x01 ) + if ((attr & 0x07) == 0x01) { - data = 0xFF; + data = 0xff; } - if ( i == cursor_x ) + if (i == cursor_x) { - if ( m_framecnt & 0x08 ) + if (m_framecnt & 0x08) { - data = 0xFF; + data = 0xff; } } else { - if ( ( attr & 0x80 ) && ( m_framecnt & 0x10 ) ) + if ((attr & 0x80) && (m_framecnt & 0x10)) { data = 0x00; } } - *p = palette[( data & 0x80 ) ? fg : bg]; p++; - *p = palette[( data & 0x40 ) ? fg : bg]; p++; - *p = palette[( data & 0x20 ) ? fg : bg]; p++; - *p = palette[( data & 0x10 ) ? fg : bg]; p++; - *p = palette[( data & 0x08 ) ? fg : bg]; p++; - *p = palette[( data & 0x04 ) ? fg : bg]; p++; - *p = palette[( data & 0x02 ) ? fg : bg]; p++; - *p = palette[( data & 0x01 ) ? fg : bg]; p++; + *p++ = palette[(data & 0x80) ? fg : bg]; + *p++ = palette[(data & 0x40) ? fg : bg]; + *p++ = palette[(data & 0x20) ? fg : bg]; + *p++ = palette[(data & 0x10) ? fg : bg]; + *p++ = palette[(data & 0x08) ? fg : bg]; + *p++ = palette[(data & 0x04) ? fg : bg]; + *p++ = palette[(data & 0x02) ? fg : bg]; + *p++ = palette[(data & 0x01) ? fg : bg]; } } diff --git a/src/devices/bus/isa/num9rev.cpp b/src/devices/bus/isa/num9rev.cpp index 07a35ee073c..632eb8b544b 100644 --- a/src/devices/bus/isa/num9rev.cpp +++ b/src/devices/bus/isa/num9rev.cpp @@ -36,7 +36,7 @@ UPD7220_DISPLAY_PIXELS_MEMBER( isa8_number_9_rev_device::hgdc_display_pixels ) color.set_r(pal->entry_color(m_ram[addr] | ((overlay & 0xf) << 8)).r()); color.set_g(pal->entry_color(m_ram[addr + 0x40000] | ((overlay & 0xf0) << 4)).g()); color.set_b(pal->entry_color(m_ram[addr + 0x80000] | (overlay & 0xf00)).b()); - bitmap.pix32(y, x + i) = color; + bitmap.pix(y, x + i) = color; } } else @@ -44,7 +44,7 @@ UPD7220_DISPLAY_PIXELS_MEMBER( isa8_number_9_rev_device::hgdc_display_pixels ) if(((address << 3) + 16) > (1024*1024)) return; for(int i = 0; i < 16; i++) - bitmap.pix32(y, x + i) = pal->entry_color(m_ram[(address << 4) + i]); + bitmap.pix(y, x + i) = pal->entry_color(m_ram[(address << 4) + i]); } } diff --git a/src/devices/bus/isa/omti8621.cpp b/src/devices/bus/isa/omti8621.cpp index 4c6225baa9f..e9c80e126d3 100644 --- a/src/devices/bus/isa/omti8621.cpp +++ b/src/devices/bus/isa/omti8621.cpp @@ -253,8 +253,15 @@ void omti8621_device::device_add_mconfig(machine_config &config) m_fdc->intrq_wr_callback().set(FUNC(omti8621_device::fdc_irq_w)); m_fdc->drq_wr_callback().set(FUNC(omti8621_device::fdc_drq_w)); FLOPPY_CONNECTOR(config, m_floppy[0], pc_hd_floppies, "525hd", omti8621_device::floppy_formats); -// Apollo workstations never have more then 1 floppy drive -// FLOPPY_CONNECTOR(config, m_floppy[1], pc_hd_floppies, nullptr, omti8621_device::floppy_formats); + FLOPPY_CONNECTOR(config, m_floppy[1], pc_hd_floppies, nullptr, omti8621_device::floppy_formats); +} + +void omti8621_apollo_device::device_add_mconfig(machine_config &config) +{ + omti8621_device::device_add_mconfig(config); + + // Apollo workstations never have more then 1 floppy drive + config.device_remove(OMTI_FDC_TAG":1"); } const tiny_rom_entry *omti8621_device::device_rom_region() const @@ -1326,8 +1333,7 @@ void omti8621_device::fd_moten_w(uint8_t data) m_moten = data; - if (!BIT(data, 2)) - m_fdc->soft_reset(); + m_fdc->reset_w(!BIT(data, 2)); for (int i = 0; i < 2; i++) { @@ -1342,8 +1348,11 @@ void omti8621_device::fd_moten_w(uint8_t data) void omti8621_device::fd_rate_w(uint8_t data) { - // Bit 1 = FD_MINI (TODO) - // Bit 0 = FD_RATE (TODO) + // Bit 1 = FD_MINI (connects to pin 3 of FDC9239) + // Bit 0 = FD_RATE (inverted output connects to pin 4 of 74F163) + u32 fdc_clk = (48_MHz_XTAL / (BIT(data, 0) ? 5 : 3) / (BIT(data, 1) ? 4 : 2)).value(); + m_fdc->set_unscaled_clock(fdc_clk); + m_fdc->set_rate(fdc_clk / 16); } void omti8621_device::fd_extra_w(uint8_t data) diff --git a/src/devices/bus/isa/omti8621.h b/src/devices/bus/isa/omti8621.h index d637eb57611..0308b61eee6 100644 --- a/src/devices/bus/isa/omti8621.h +++ b/src/devices/bus/isa/omti8621.h @@ -163,7 +163,9 @@ public: // get sector diskaddr of logical unit lun into data_buffer uint32_t get_sector(int32_t diskaddr, uint8_t *data_buffer, uint32_t length, uint8_t lun); + protected: + virtual void device_add_mconfig(machine_config &config) override; virtual const tiny_rom_entry *device_rom_region() const override; }; diff --git a/src/devices/bus/isa/pgc.cpp b/src/devices/bus/isa/pgc.cpp index 1366bc92dbc..f204333f9f2 100644 --- a/src/devices/bus/isa/pgc.cpp +++ b/src/devices/bus/isa/pgc.cpp @@ -401,14 +401,11 @@ uint8_t isa8_pgc_device::init_r() uint32_t isa8_pgc_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { - uint16_t *p; - uint8_t *v; - for (int y = 0; y < PGC_DISP_VERT; y++) { // XXX address translation happens in hardware - v = &m_vram[y * 1024]; - p = &bitmap.pix16(y + PGC_VERT_START, PGC_HORZ_START); + uint8_t const *v = &m_vram[y * 1024]; + uint16_t *p = &bitmap.pix(y + PGC_VERT_START, PGC_HORZ_START); for (int x = 0; x < PGC_DISP_HORZ; x++) { diff --git a/src/devices/bus/isa/trident.cpp b/src/devices/bus/isa/trident.cpp index 0d64df5ba27..5fc2d2d6d19 100644 --- a/src/devices/bus/isa/trident.cpp +++ b/src/devices/bus/isa/trident.cpp @@ -212,29 +212,22 @@ void trident_vga_device::device_reset() uint32_t trident_vga_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - uint8_t cur_mode; - svga_device::screen_update(screen,bitmap,cliprect); - cur_mode = pc_vga_choosevideomode(); + uint8_t const cur_mode = pc_vga_choosevideomode(); // draw hardware graphics cursor if(tri.cursor_ctrl & 0x80) // if cursor is enabled { - uint32_t src; - uint32_t* dst; - uint8_t val; - int x,y; - uint16_t cx = tri.cursor_x & 0x0fff; - uint16_t cy = tri.cursor_y & 0x0fff; - uint32_t bg_col; - uint32_t fg_col; - uint8_t cursor_size = (tri.cursor_ctrl & 0x01) ? 64 : 32; + uint16_t const cx = tri.cursor_x & 0x0fff; + uint16_t const cy = tri.cursor_y & 0x0fff; + uint8_t const cursor_size = (tri.cursor_ctrl & 0x01) ? 64 : 32; if(cur_mode == SCREEN_OFF || cur_mode == TEXT_MODE || cur_mode == MONO_MODE || cur_mode == CGA_MODE || cur_mode == EGA_MODE) return 0; // cursor only works in VGA or SVGA modes - src = tri.cursor_loc * 1024; // start address is in units of 1024 bytes + uint32_t src = tri.cursor_loc * 1024; // start address is in units of 1024 bytes + uint32_t bg_col, fg_col; if(cur_mode == RGB16_MODE) { bg_col = tri.cursor_bg; @@ -246,11 +239,11 @@ uint32_t trident_vga_device::screen_update(screen_device &screen, bitmap_rgb32 & fg_col = pen(tri.cursor_fg & 0xff); } - for(y=0;y<cursor_size;y++) + for(int y=0;y<cursor_size;y++) { uint8_t bitcount = 31; - dst = &bitmap.pix32(cy + y, cx); - for(x=0;x<cursor_size;x++) + uint32_t *const dst = &bitmap.pix(cy + y, cx); + for(int x=0;x<cursor_size;x++) { uint32_t bitb = (vga.memory[(src+3) % vga.svga_intf.vram_size] | ((vga.memory[(src+2) % vga.svga_intf.vram_size]) << 8) @@ -260,7 +253,7 @@ uint32_t trident_vga_device::screen_update(screen_device &screen, bitmap_rgb32 & | ((vga.memory[(src+6) % vga.svga_intf.vram_size]) << 8) | ((vga.memory[(src+5) % vga.svga_intf.vram_size]) << 16) | ((vga.memory[(src+4) % vga.svga_intf.vram_size]) << 24)); - val = (BIT(bita << 1,bitcount+1) << 1 | BIT(bitb,bitcount)); + uint8_t const val = (BIT(bita << 1,bitcount+1) << 1 | BIT(bitb,bitcount)); if(tri.cursor_ctrl & 0x40) { // X11 mode switch(val) diff --git a/src/devices/bus/macpds/pds_tpdfpd.cpp b/src/devices/bus/macpds/pds_tpdfpd.cpp index 833d1d3820f..6d9dd93b4ed 100644 --- a/src/devices/bus/macpds/pds_tpdfpd.cpp +++ b/src/devices/bus/macpds/pds_tpdfpd.cpp @@ -154,27 +154,23 @@ void macpds_sedisplay_device::device_timer(emu_timer &timer, device_timer_id tid uint32_t macpds_sedisplay_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - uint32_t *scanline; - int x, y; - uint8_t pixels, *vram; + uint8_t const *const vram = m_vram.get(); - vram = m_vram.get(); - - for (y = 0; y < 870; y++) + for (int y = 0; y < 870; y++) { - scanline = &bitmap.pix32(y); - for (x = 0; x < 640/8; x++) + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < 640/8; x++) { - pixels = vram[(y * (1024/8)) + (x^1)]; - - *scanline++ = m_palette[((pixels>>7)&0x1)^1]; - *scanline++ = m_palette[((pixels>>6)&0x1)^1]; - *scanline++ = m_palette[((pixels>>5)&0x1)^1]; - *scanline++ = m_palette[((pixels>>4)&0x1)^1]; - *scanline++ = m_palette[((pixels>>3)&0x1)^1]; - *scanline++ = m_palette[((pixels>>2)&0x1)^1]; - *scanline++ = m_palette[((pixels>>1)&0x1)^1]; - *scanline++ = m_palette[(pixels&1)^1]; + uint8_t const pixels = vram[(y * (1024/8)) + (x^1)]; + + *scanline++ = m_palette[BIT(~pixels, 7)]; + *scanline++ = m_palette[BIT(~pixels, 6)]; + *scanline++ = m_palette[BIT(~pixels, 5)]; + *scanline++ = m_palette[BIT(~pixels, 4)]; + *scanline++ = m_palette[BIT(~pixels, 3)]; + *scanline++ = m_palette[BIT(~pixels, 2)]; + *scanline++ = m_palette[BIT(~pixels, 1)]; + *scanline++ = m_palette[BIT(~pixels, 0)]; } } diff --git a/src/devices/bus/mtx/sdx.cpp b/src/devices/bus/mtx/sdx.cpp index e413e997f5b..09e7199ac53 100644 --- a/src/devices/bus/mtx/sdx.cpp +++ b/src/devices/bus/mtx/sdx.cpp @@ -417,7 +417,7 @@ MC6845_UPDATE_ROW(mtx_sdxcpm_device::crtc_update_row) int color = BIT(data, 7) ? fg : bg; - bitmap.pix32(y, x) = pen[de ? color : 0]; + bitmap.pix(y, x) = pen[de ? color : 0]; data <<= 1; } diff --git a/src/devices/bus/nasbus/avc.cpp b/src/devices/bus/nasbus/avc.cpp index f7bc8e95596..f4590b2ac3f 100644 --- a/src/devices/bus/nasbus/avc.cpp +++ b/src/devices/bus/nasbus/avc.cpp @@ -120,7 +120,7 @@ MC6845_UPDATE_ROW( nascom_avc_device::crtc_update_row ) } // plot the pixel - bitmap.pix32(y, x) = m_palette->pen_color((b << 2) | (g << 1) | (r << 0)); + bitmap.pix(y, x) = m_palette->pen_color((b << 2) | (g << 1) | (r << 0)); } } diff --git a/src/devices/bus/neogeo/prot_fatfury2.cpp b/src/devices/bus/neogeo/prot_fatfury2.cpp index c8e7151e6e8..b88d7b43ec1 100644 --- a/src/devices/bus/neogeo/prot_fatfury2.cpp +++ b/src/devices/bus/neogeo/prot_fatfury2.cpp @@ -41,7 +41,12 @@ uint16_t fatfury2_prot_device::protection_r(offs_t offset) m_pro_ct0->h_w(BIT(offset, 2)); u8 gad = m_pro_ct0->gad_r(); u8 gbd = m_pro_ct0->gbd_r(); - return (BIT(gbd, 0, 2) << 6) | (BIT(gbd, 2, 2) << 4) | (BIT(gad, 0, 2) << 6) | (BIT(gad, 2, 2) << 4); + /* + Data pin from PRO-CT0 + D0 D1 D2 D3 D4 D5 D6 D7 + GAD2 GAD3 GAD0 GAD1 GBD2 GBD3 GBD0 GBD1 + */ + return (BIT(gbd, 0, 2) << 6) | (BIT(gbd, 2, 2) << 4) | (BIT(gad, 0, 2) << 2) | (BIT(gad, 2, 2) << 0); } @@ -55,8 +60,13 @@ void fatfury2_prot_device::protection_w(offs_t offset, uint16_t data) m_pro_ct0->h_w(BIT(offset, 2)); // A3 // C16-31 = A4-A19, C0-C15 = D0-D15 - m_pro_ct0->c_w((u32(bitswap<16>(BIT(offset, 3, 16), 15, 13, 11, 9, 14, 12, 10, 8, 7, 5, 3, 1, 6, 4, 2, 0)) << 16) | - bitswap<16>(data, 15, 13, 11, 9, 14, 12, 10, 8, 7, 5, 3, 1, 6, 4, 2, 0)); + /* + Address/Data pin mapping into PRO-CT0 + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 C11 C12 C13 C14 C15 C16 C17 C18 C19 C20 C21 C22 C23 C24 C25 C26 C27 C28 C29 C30 C31 LOAD EVEN H + D0 D4 D1 D5 D2 D6 D3 D7 D8 D12 D9 D13 D10 D14 D11 D15 A4 A8 A5 A9 A6 A10 A7 A11 A12 A16 A13 A17 A14 A18 A15 A19 A1 A2 A3 + */ + m_pro_ct0->c_w((u32(bitswap<16>(BIT(offset, 3, 16), 15, 11, 14, 10, 13, 9, 12, 8, 7, 3, 6, 2, 5, 1, 4, 0)) << 16) | + u32(bitswap<16>(data, 15, 11, 14, 10, 13, 9, 12, 8, 7, 3, 6, 2, 5, 1, 4, 0))); // release /PORTOEL m_pro_ct0->clk_w(false); diff --git a/src/devices/bus/nscsi/hd.cpp b/src/devices/bus/nscsi/hd.cpp index 6c6543b409c..f4c74962d20 100644 --- a/src/devices/bus/nscsi/hd.cpp +++ b/src/devices/bus/nscsi/hd.cpp @@ -119,8 +119,15 @@ void nscsi_harddisk_device::scsi_command() LOG("command READ start=%08x blocks=%04x\n", lba, blocks); - scsi_data_in(2, blocks*bytes_per_sector); - scsi_status_complete(SS_GOOD); + if(hard_disk_read(harddisk, lba, block)) { + scsi_data_in(2, blocks*bytes_per_sector); + scsi_status_complete(SS_GOOD); + } + else + { + scsi_status_complete(SS_CHECK_CONDITION); + sense(false, SK_ILLEGAL_REQUEST, SK_ASC_INVALID_FIELD_IN_CDB); + } break; case SC_WRITE_6: @@ -468,8 +475,15 @@ void nscsi_harddisk_device::scsi_command() LOG("command READ EXTENDED start=%08x blocks=%04x\n",lba, blocks); - scsi_data_in(2, blocks*bytes_per_sector); - scsi_status_complete(SS_GOOD); + if(hard_disk_read(harddisk, lba, block)) { + scsi_data_in(2, blocks*bytes_per_sector); + scsi_status_complete(SS_GOOD); + } + else + { + scsi_status_complete(SS_CHECK_CONDITION); + sense(false, SK_ILLEGAL_REQUEST, SK_ASC_INVALID_FIELD_IN_CDB); + } break; case SC_WRITE_10: diff --git a/src/devices/bus/nubus/laserview.cpp b/src/devices/bus/nubus/laserview.cpp index 2c58b6e8dc3..7e802b58988 100644 --- a/src/devices/bus/nubus/laserview.cpp +++ b/src/devices/bus/nubus/laserview.cpp @@ -117,30 +117,26 @@ void nubus_laserview_device::device_reset() uint32_t nubus_laserview_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - uint32_t *scanline; - int x, y; - uint8_t pixels; - if (!m_vbl_disable) { raise_slot_irq(); } - for (y = 0; y < 600; y++) + for (int y = 0; y < 600; y++) { - scanline = &bitmap.pix32(y); - for (x = 0; x < 832/8; x++) + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < 832/8; x++) { - pixels = m_vram[(y * 104) + (BYTE4_XOR_BE(x)) + 0x20]; - - *scanline++ = m_palette[(pixels>>7)&1]; - *scanline++ = m_palette[(pixels>>6)&1]; - *scanline++ = m_palette[(pixels>>5)&1]; - *scanline++ = m_palette[(pixels>>4)&1]; - *scanline++ = m_palette[(pixels>>3)&1]; - *scanline++ = m_palette[(pixels>>2)&1]; - *scanline++ = m_palette[(pixels>>1)&1]; - *scanline++ = m_palette[(pixels&1)]; + uint8_t const pixels = m_vram[(y * 104) + (BYTE4_XOR_BE(x)) + 0x20]; + + *scanline++ = m_palette[BIT(pixels, 7)]; + *scanline++ = m_palette[BIT(pixels, 6)]; + *scanline++ = m_palette[BIT(pixels, 5)]; + *scanline++ = m_palette[BIT(pixels, 4)]; + *scanline++ = m_palette[BIT(pixels, 3)]; + *scanline++ = m_palette[BIT(pixels, 2)]; + *scanline++ = m_palette[BIT(pixels, 1)]; + *scanline++ = m_palette[BIT(pixels, 0)]; } } diff --git a/src/devices/bus/nubus/nubus_48gc.cpp b/src/devices/bus/nubus/nubus_48gc.cpp index 9105414f3e0..b9b831c6de2 100644 --- a/src/devices/bus/nubus/nubus_48gc.cpp +++ b/src/devices/bus/nubus/nubus_48gc.cpp @@ -12,6 +12,9 @@ #include "nubus_48gc.h" #include "screen.h" +#include <algorithm> + + #define VRAM_SIZE (0x200000) // 2 megs, maxed out #define GC48_SCREEN_NAME "48gc_screen" @@ -152,10 +155,7 @@ void jmfb_device::device_timer(emu_timer &timer, device_timer_id tid, int param, uint32_t jmfb_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - uint32_t *scanline, *base; - int x, y; - uint8_t *vram8 = &m_vram[0]; - uint8_t pixels; + uint8_t const *const vram8 = &m_vram[0xa00]; // first time? kick off the VBL timer if (!m_screen) @@ -164,37 +164,35 @@ uint32_t jmfb_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, m_timer->adjust(m_screen->time_until_pos(479, 0), 0); } - vram8 += 0xa00; - switch (m_mode) { case 0: // 1bpp - for (y = 0; y < m_yres; y++) + for (int y = 0; y < m_yres; y++) { - scanline = &bitmap.pix32(y); - for (x = 0; x < m_xres/8; x++) + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < m_xres/8; x++) { - pixels = vram8[(y * m_stride) + (BYTE4_XOR_BE(x))]; - - *scanline++ = m_palette[(pixels>>7)&1]; - *scanline++ = m_palette[(pixels>>6)&1]; - *scanline++ = m_palette[(pixels>>5)&1]; - *scanline++ = m_palette[(pixels>>4)&1]; - *scanline++ = m_palette[(pixels>>3)&1]; - *scanline++ = m_palette[(pixels>>2)&1]; - *scanline++ = m_palette[(pixels>>1)&1]; - *scanline++ = m_palette[pixels&1]; + uint8_t const pixels = vram8[(y * m_stride) + (BYTE4_XOR_BE(x))]; + + *scanline++ = m_palette[BIT(pixels, 7)]; + *scanline++ = m_palette[BIT(pixels, 6)]; + *scanline++ = m_palette[BIT(pixels, 5)]; + *scanline++ = m_palette[BIT(pixels, 4)]; + *scanline++ = m_palette[BIT(pixels, 3)]; + *scanline++ = m_palette[BIT(pixels, 2)]; + *scanline++ = m_palette[BIT(pixels, 1)]; + *scanline++ = m_palette[BIT(pixels, 0)]; } } break; case 1: // 2bpp - for (y = 0; y < m_yres; y++) + for (int y = 0; y < m_yres; y++) { - scanline = &bitmap.pix32(y); - for (x = 0; x < m_xres/4; x++) + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < m_xres/4; x++) { - pixels = vram8[(y * m_stride) + (BYTE4_XOR_BE(x))]; + uint8_t const pixels = vram8[(y * m_stride) + (BYTE4_XOR_BE(x))]; *scanline++ = m_palette[(pixels>>6)&0x3]; *scanline++ = m_palette[(pixels>>4)&0x3]; @@ -205,13 +203,12 @@ uint32_t jmfb_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, break; case 2: // 4 bpp - for (y = 0; y < m_yres; y++) + for (int y = 0; y < m_yres; y++) { - scanline = &bitmap.pix32(y); - - for (x = 0; x < m_xres/2; x++) + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < m_xres/2; x++) { - pixels = vram8[(y * m_stride) + (BYTE4_XOR_BE(x))]; + uint8_t const pixels = vram8[(y * m_stride) + (BYTE4_XOR_BE(x))]; *scanline++ = m_palette[(pixels>>4)&0xf]; *scanline++ = m_palette[pixels&0xf]; @@ -220,27 +217,22 @@ uint32_t jmfb_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, break; case 3: // 8 bpp - for (y = 0; y < m_yres; y++) + for (int y = 0; y < m_yres; y++) { - scanline = &bitmap.pix32(y); - - for (x = 0; x < m_xres; x++) + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < m_xres; x++) { - pixels = vram8[(y * m_stride) + (BYTE4_XOR_BE(x))]; + uint8_t const pixels = vram8[(y * m_stride) + (BYTE4_XOR_BE(x))]; *scanline++ = m_palette[pixels]; } } break; case 4: // 24 bpp - for (y = 0; y < m_yres; y++) + for (int y = 0; y < m_yres; y++) { - scanline = &bitmap.pix32(y); - base = (uint32_t *)&m_vram[y * m_stride]; - for (x = 0; x < m_xres; x++) - { - *scanline++ = *base++; - } + uint32_t const *base = (uint32_t *)&m_vram[y * m_stride]; + std::copy_n(base, m_xres, &bitmap.pix(y)); } break; } diff --git a/src/devices/bus/nubus/nubus_cb264.cpp b/src/devices/bus/nubus/nubus_cb264.cpp index db964ec2055..db1fd821a11 100644 --- a/src/devices/bus/nubus/nubus_cb264.cpp +++ b/src/devices/bus/nubus/nubus_cb264.cpp @@ -17,6 +17,9 @@ #include "nubus_cb264.h" #include "screen.h" +#include <algorithm> + + #define CB264_SCREEN_NAME "cb264_screen" #define CB264_ROM_REGION "cb264_rom" @@ -122,10 +125,6 @@ void nubus_cb264_device::device_reset() uint32_t nubus_cb264_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - uint32_t *scanline, *base; - int x, y; - uint8_t pixels; - if (!m_cb264_vbl_disable) { raise_slot_irq(); @@ -134,12 +133,12 @@ uint32_t nubus_cb264_device::screen_update(screen_device &screen, bitmap_rgb32 & switch (m_cb264_mode) { case 0: // 1 bpp - for (y = 0; y < 480; y++) + for (int y = 0; y < 480; y++) { - scanline = &bitmap.pix32(y); - for (x = 0; x < 640/8; x++) + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < 640/8; x++) { - pixels = m_vram[(y * 1024) + (BYTE4_XOR_BE(x))]; + uint8_t const pixels = m_vram[(y * 1024) + (BYTE4_XOR_BE(x))]; *scanline++ = m_palette[pixels&0x80]; *scanline++ = m_palette[(pixels<<1)&0x80]; @@ -154,12 +153,12 @@ uint32_t nubus_cb264_device::screen_update(screen_device &screen, bitmap_rgb32 & break; case 1: // 2 bpp (3f/7f/bf/ff) - for (y = 0; y < 480; y++) + for (int y = 0; y < 480; y++) { - scanline = &bitmap.pix32(y); - for (x = 0; x < 640/4; x++) + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < 640/4; x++) { - pixels = m_vram[(y * 1024) + (BYTE4_XOR_BE(x))]; + uint8_t const pixels = m_vram[(y * 1024) + (BYTE4_XOR_BE(x))]; *scanline++ = m_palette[pixels&0xc0]; *scanline++ = m_palette[(pixels<<2)&0xc0]; @@ -170,13 +169,12 @@ uint32_t nubus_cb264_device::screen_update(screen_device &screen, bitmap_rgb32 & break; case 2: // 4 bpp - for (y = 0; y < 480; y++) + for (int y = 0; y < 480; y++) { - scanline = &bitmap.pix32(y); - - for (x = 0; x < 640/2; x++) + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < 640/2; x++) { - pixels = m_vram[(y * 1024) + (BYTE4_XOR_BE(x))]; + uint8_t const pixels = m_vram[(y * 1024) + (BYTE4_XOR_BE(x))]; *scanline++ = m_palette[pixels&0xf0]; *scanline++ = m_palette[(pixels<<4)&0xf0]; @@ -185,13 +183,12 @@ uint32_t nubus_cb264_device::screen_update(screen_device &screen, bitmap_rgb32 & break; case 3: // 8 bpp - for (y = 0; y < 480; y++) + for (int y = 0; y < 480; y++) { - scanline = &bitmap.pix32(y); - - for (x = 0; x < 640; x++) + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < 640; x++) { - pixels = m_vram[(y * 1024) + (BYTE4_XOR_BE(x))]; + uint8_t const pixels = m_vram[(y * 1024) + (BYTE4_XOR_BE(x))]; *scanline++ = m_palette[pixels]; } } @@ -200,16 +197,11 @@ uint32_t nubus_cb264_device::screen_update(screen_device &screen, bitmap_rgb32 & case 4: // 24 bpp case 7: // ??? { - uint32_t *vram32 = (uint32_t *)&m_vram[0]; + uint32_t const *const vram32 = (uint32_t *)&m_vram[0]; - for (y = 0; y < 480; y++) + for (int y = 0; y < 480; y++) { - scanline = &bitmap.pix32(y); - base = &vram32[y * 1024]; - for (x = 0; x < 640; x++) - { - *scanline++ = *base++; - } + std::copy_n(&vram32[y * 1024], 640, &bitmap.pix(y)); } } break; diff --git a/src/devices/bus/nubus/nubus_m2hires.cpp b/src/devices/bus/nubus/nubus_m2hires.cpp index 851537685d2..e913c0cb0cb 100644 --- a/src/devices/bus/nubus/nubus_m2hires.cpp +++ b/src/devices/bus/nubus/nubus_m2hires.cpp @@ -137,41 +137,37 @@ void nubus_m2hires_device::device_timer(emu_timer &timer, device_timer_id tid, i uint32_t nubus_m2hires_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - uint32_t *scanline; - int x, y; - uint8_t pixels, *vram; - - vram = &m_vram[0x20]; + uint8_t const *const vram = &m_vram[0x20]; switch (m_mode) { case 0: // 1 bpp? - for (y = 0; y < 480; y++) + for (int y = 0; y < 480; y++) { - scanline = &bitmap.pix32(y); - for (x = 0; x < 640/8; x++) + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < 640/8; x++) { - pixels = vram[(y * 128) + (BYTE4_XOR_BE(x))]; - - *scanline++ = m_palette[((pixels>>7)&0x1)]; - *scanline++ = m_palette[((pixels>>6)&0x1)]; - *scanline++ = m_palette[((pixels>>5)&0x1)]; - *scanline++ = m_palette[((pixels>>4)&0x1)]; - *scanline++ = m_palette[((pixels>>3)&0x1)]; - *scanline++ = m_palette[((pixels>>2)&0x1)]; - *scanline++ = m_palette[((pixels>>1)&0x1)]; - *scanline++ = m_palette[(pixels&1)]; + uint8_t const pixels = vram[(y * 128) + (BYTE4_XOR_BE(x))]; + + *scanline++ = m_palette[BIT(pixels, 7)]; + *scanline++ = m_palette[BIT(pixels, 6)]; + *scanline++ = m_palette[BIT(pixels, 5)]; + *scanline++ = m_palette[BIT(pixels, 4)]; + *scanline++ = m_palette[BIT(pixels, 3)]; + *scanline++ = m_palette[BIT(pixels, 2)]; + *scanline++ = m_palette[BIT(pixels, 1)]; + *scanline++ = m_palette[BIT(pixels, 0)]; } } break; case 1: // 2 bpp - for (y = 0; y < 480; y++) + for (int y = 0; y < 480; y++) { - scanline = &bitmap.pix32(y); - for (x = 0; x < 640/4; x++) + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < 640/4; x++) { - pixels = vram[(y * 256) + (BYTE4_XOR_BE(x))]; + uint8_t const pixels = vram[(y * 256) + (BYTE4_XOR_BE(x))]; *scanline++ = m_palette[((pixels>>6)&3)]; *scanline++ = m_palette[((pixels>>4)&3)]; @@ -182,13 +178,13 @@ uint32_t nubus_m2hires_device::screen_update(screen_device &screen, bitmap_rgb32 break; case 2: // 4 bpp - for (y = 0; y < 480; y++) + for (int y = 0; y < 480; y++) { - scanline = &bitmap.pix32(y); + uint32_t *scanline = &bitmap.pix(y); - for (x = 0; x < 640/2; x++) + for (int x = 0; x < 640/2; x++) { - pixels = vram[(y * 512) + (BYTE4_XOR_BE(x))]; + uint8_t const pixels = vram[(y * 512) + (BYTE4_XOR_BE(x))]; *scanline++ = m_palette[((pixels&0xf0)>>4)]; *scanline++ = m_palette[(pixels&0xf)]; @@ -197,13 +193,13 @@ uint32_t nubus_m2hires_device::screen_update(screen_device &screen, bitmap_rgb32 break; case 3: // 8 bpp - for (y = 0; y < 480; y++) + for (int y = 0; y < 480; y++) { - scanline = &bitmap.pix32(y); + uint32_t *scanline = &bitmap.pix(y); - for (x = 0; x < 640; x++) + for (int x = 0; x < 640; x++) { - pixels = vram[(y * 1024) + (BYTE4_XOR_BE(x))]; + uint8_t const pixels = vram[(y * 1024) + (BYTE4_XOR_BE(x))]; *scanline++ = m_palette[pixels]; } } diff --git a/src/devices/bus/nubus/nubus_m2video.cpp b/src/devices/bus/nubus/nubus_m2video.cpp index f557d7631b0..60728d7dd15 100644 --- a/src/devices/bus/nubus/nubus_m2video.cpp +++ b/src/devices/bus/nubus/nubus_m2video.cpp @@ -139,21 +139,17 @@ void nubus_m2video_device::device_timer(emu_timer &timer, device_timer_id tid, i uint32_t nubus_m2video_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - uint32_t *scanline; - int x, y; - uint8_t pixels, *vram; - - vram = &m_vram[0x20]; + uint8_t const *const vram = &m_vram[0x20]; switch (m_mode) { case 0: // 1 bpp? - for (y = 0; y < 480; y++) + for (int y = 0; y < 480; y++) { - scanline = &bitmap.pix32(y); - for (x = 0; x < 640/8; x++) + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < 640/8; x++) { - pixels = vram[(y * 128) + (BYTE4_XOR_BE(x))]; + uint8_t const pixels = vram[(y * 128) + (BYTE4_XOR_BE(x))]; *scanline++ = m_palette[(pixels&0x80)]; *scanline++ = m_palette[((pixels<<1)&0x80)]; @@ -168,12 +164,12 @@ uint32_t nubus_m2video_device::screen_update(screen_device &screen, bitmap_rgb32 break; case 1: // 2 bpp - for (y = 0; y < 480; y++) + for (int y = 0; y < 480; y++) { - scanline = &bitmap.pix32(y); - for (x = 0; x < 640/4; x++) + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < 640/4; x++) { - pixels = vram[(y * 256) + (BYTE4_XOR_BE(x))]; + uint8_t const pixels = vram[(y * 256) + (BYTE4_XOR_BE(x))]; *scanline++ = m_palette[(pixels&0xc0)]; *scanline++ = m_palette[((pixels<<2)&0xc0)]; @@ -184,13 +180,12 @@ uint32_t nubus_m2video_device::screen_update(screen_device &screen, bitmap_rgb32 break; case 2: // 4 bpp - for (y = 0; y < 480; y++) + for (int y = 0; y < 480; y++) { - scanline = &bitmap.pix32(y); - - for (x = 0; x < 640/2; x++) + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < 640/2; x++) { - pixels = vram[(y * 512) + (BYTE4_XOR_BE(x))]; + uint8_t const pixels = vram[(y * 512) + (BYTE4_XOR_BE(x))]; *scanline++ = m_palette[(pixels&0xf0)]; *scanline++ = m_palette[((pixels&0x0f)<<4)]; @@ -199,13 +194,12 @@ uint32_t nubus_m2video_device::screen_update(screen_device &screen, bitmap_rgb32 break; case 3: // 8 bpp - for (y = 0; y < 480; y++) + for (int y = 0; y < 480; y++) { - scanline = &bitmap.pix32(y); - - for (x = 0; x < 640; x++) + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < 640; x++) { - pixels = vram[(y * 1024) + (BYTE4_XOR_BE(x))]; + uint8_t const pixels = vram[(y * 1024) + (BYTE4_XOR_BE(x))]; *scanline++ = m_palette[pixels]; } } diff --git a/src/devices/bus/nubus/nubus_radiustpd.cpp b/src/devices/bus/nubus/nubus_radiustpd.cpp index f6d152be059..89518f0d223 100644 --- a/src/devices/bus/nubus/nubus_radiustpd.cpp +++ b/src/devices/bus/nubus/nubus_radiustpd.cpp @@ -139,27 +139,23 @@ void nubus_radiustpd_device::device_timer(emu_timer &timer, device_timer_id tid, uint32_t nubus_radiustpd_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - uint32_t *scanline; - int x, y; - uint8_t pixels, *vram; + uint8_t const *const vram = &m_vram[0x200]; - vram = &m_vram[0x200]; - - for (y = 0; y < 880; y++) + for (int y = 0; y < 880; y++) { - scanline = &bitmap.pix32(y); - for (x = 0; x < 1152/8; x++) + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < 1152/8; x++) { - pixels = vram[(y * (1152/8)) + (BYTE4_XOR_BE(x))]; - - *scanline++ = m_palette[((pixels>>7)&0x1)]; - *scanline++ = m_palette[((pixels>>6)&0x1)]; - *scanline++ = m_palette[((pixels>>5)&0x1)]; - *scanline++ = m_palette[((pixels>>4)&0x1)]; - *scanline++ = m_palette[((pixels>>3)&0x1)]; - *scanline++ = m_palette[((pixels>>2)&0x1)]; - *scanline++ = m_palette[((pixels>>1)&0x1)]; - *scanline++ = m_palette[(pixels&1)]; + uint8_t const pixels = vram[(y * (1152/8)) + (BYTE4_XOR_BE(x))]; + + *scanline++ = m_palette[BIT(pixels, 7)]; + *scanline++ = m_palette[BIT(pixels, 6)]; + *scanline++ = m_palette[BIT(pixels, 5)]; + *scanline++ = m_palette[BIT(pixels, 4)]; + *scanline++ = m_palette[BIT(pixels, 3)]; + *scanline++ = m_palette[BIT(pixels, 2)]; + *scanline++ = m_palette[BIT(pixels, 1)]; + *scanline++ = m_palette[BIT(pixels, 0)]; } } diff --git a/src/devices/bus/nubus/nubus_spec8.cpp b/src/devices/bus/nubus/nubus_spec8.cpp index b7a29b6f537..6ca1f9f4489 100644 --- a/src/devices/bus/nubus/nubus_spec8.cpp +++ b/src/devices/bus/nubus/nubus_spec8.cpp @@ -144,21 +144,17 @@ void nubus_spec8s3_device::device_timer(emu_timer &timer, device_timer_id tid, i uint32_t nubus_spec8s3_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - uint32_t *scanline; - int x, y; - uint8_t pixels, *vram; - - vram = &m_vram[0x400]; + uint8_t const *const vram = &m_vram[0x400]; switch (m_mode) { case 0: // 1 bpp - for (y = 0; y < 768; y++) + for (int y = 0; y < 768; y++) { - scanline = &bitmap.pix32(y); - for (x = 0; x < 1024/8; x++) + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < 1024/8; x++) { - pixels = vram[(y * 512) + (BYTE4_XOR_BE(x))]; + uint8_t const pixels = vram[(y * 512) + (BYTE4_XOR_BE(x))]; *scanline++ = m_palette[pixels&0x80]; *scanline++ = m_palette[(pixels<<1)&0x80]; @@ -173,12 +169,12 @@ uint32_t nubus_spec8s3_device::screen_update(screen_device &screen, bitmap_rgb32 break; case 1: // 2 bpp - for (y = 0; y < 768; y++) + for (int y = 0; y < 768; y++) { - scanline = &bitmap.pix32(y); - for (x = 0; x < 1024/4; x++) + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < 1024/4; x++) { - pixels = vram[(y * 512) + (BYTE4_XOR_BE(x))]; + uint8_t const pixels = vram[(y * 512) + (BYTE4_XOR_BE(x))]; *scanline++ = m_palette[pixels&0xc0]; *scanline++ = m_palette[(pixels<<2)&0xc0]; @@ -189,13 +185,12 @@ uint32_t nubus_spec8s3_device::screen_update(screen_device &screen, bitmap_rgb32 break; case 2: // 4 bpp - for (y = 0; y < 768; y++) + for (int y = 0; y < 768; y++) { - scanline = &bitmap.pix32(y); - - for (x = 0; x < 1024/2; x++) + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < 1024/2; x++) { - pixels = vram[(y * 512) + (BYTE4_XOR_BE(x))]; + uint8_t const pixels = vram[(y * 512) + (BYTE4_XOR_BE(x))]; *scanline++ = m_palette[pixels&0xf0]; *scanline++ = m_palette[(pixels<<4)&0xf0]; @@ -204,13 +199,12 @@ uint32_t nubus_spec8s3_device::screen_update(screen_device &screen, bitmap_rgb32 break; case 3: // 8 bpp - for (y = 0; y < 768; y++) + for (int y = 0; y < 768; y++) { - scanline = &bitmap.pix32(y); - - for (x = 0; x < 1024; x++) + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < 1024; x++) { - pixels = vram[(y * 1024) + (BYTE4_XOR_BE(x))]; + uint8_t const pixels = vram[(y * 1024) + (BYTE4_XOR_BE(x))]; *scanline++ = m_palette[pixels]; } } diff --git a/src/devices/bus/nubus/nubus_specpdq.cpp b/src/devices/bus/nubus/nubus_specpdq.cpp index 891defaa336..c00938c6102 100644 --- a/src/devices/bus/nubus/nubus_specpdq.cpp +++ b/src/devices/bus/nubus/nubus_specpdq.cpp @@ -157,22 +157,18 @@ void nubus_specpdq_device::device_timer(emu_timer &timer, device_timer_id tid, i uint32_t nubus_specpdq_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - uint32_t *scanline; - int x, y; - uint8_t pixels, *vram; - // first time? kick off the VBL timer - vram = &m_vram[0x9000]; + uint8_t const *const vram = &m_vram[0x9000]; switch (m_mode) { case 0: // 1 bpp - for (y = 0; y < 844; y++) + for (int y = 0; y < 844; y++) { - scanline = &bitmap.pix32(y); - for (x = 0; x < 1152/8; x++) + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < 1152/8; x++) { - pixels = vram[(y * 512) + (BYTE4_XOR_BE(x))]; + uint8_t const pixels = vram[(y * 512) + (BYTE4_XOR_BE(x))]; *scanline++ = m_palette_val[(pixels&0x80)]; *scanline++ = m_palette_val[((pixels<<1)&0x80)]; @@ -187,12 +183,12 @@ uint32_t nubus_specpdq_device::screen_update(screen_device &screen, bitmap_rgb32 break; case 1: // 2 bpp - for (y = 0; y < 844; y++) + for (int y = 0; y < 844; y++) { - scanline = &bitmap.pix32(y); - for (x = 0; x < 1152/4; x++) + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < 1152/4; x++) { - pixels = vram[(y * 512) + (BYTE4_XOR_BE(x))]; + uint8_t const pixels = vram[(y * 512) + (BYTE4_XOR_BE(x))]; *scanline++ = m_palette_val[(pixels&0xc0)]; *scanline++ = m_palette_val[((pixels<<2)&0xc0)]; @@ -203,13 +199,12 @@ uint32_t nubus_specpdq_device::screen_update(screen_device &screen, bitmap_rgb32 break; case 2: // 4 bpp - for (y = 0; y < 844; y++) + for (int y = 0; y < 844; y++) { - scanline = &bitmap.pix32(y); - - for (x = 0; x < 1152/2; x++) + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < 1152/2; x++) { - pixels = vram[(y * 1024) + (BYTE4_XOR_BE(x))]; + uint8_t const pixels = vram[(y * 1024) + (BYTE4_XOR_BE(x))]; *scanline++ = m_palette_val[(pixels&0xf0)]; *scanline++ = m_palette_val[((pixels<<4)&0xf0)]; @@ -218,13 +213,12 @@ uint32_t nubus_specpdq_device::screen_update(screen_device &screen, bitmap_rgb32 break; case 3: // 8 bpp - for (y = 0; y < 844; y++) + for (int y = 0; y < 844; y++) { - scanline = &bitmap.pix32(y); - - for (x = 0; x < 1152; x++) + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < 1152; x++) { - pixels = vram[(y * 1152) + (BYTE4_XOR_BE(x))]; + uint8_t const pixels = vram[(y * 1152) + (BYTE4_XOR_BE(x))]; *scanline++ = m_palette_val[pixels]; } } diff --git a/src/devices/bus/nubus/nubus_vikbw.cpp b/src/devices/bus/nubus/nubus_vikbw.cpp index 1c25795cd45..18c94f9ba5b 100644 --- a/src/devices/bus/nubus/nubus_vikbw.cpp +++ b/src/devices/bus/nubus/nubus_vikbw.cpp @@ -117,30 +117,26 @@ void nubus_vikbw_device::device_reset() uint32_t nubus_vikbw_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - uint32_t *scanline; - int x, y; - uint8_t pixels; - if (!m_vbl_disable) { raise_slot_irq(); } - for (y = 0; y < 768; y++) + for (int y = 0; y < 768; y++) { - scanline = &bitmap.pix32(y); - for (x = 0; x < 1024/8; x++) + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < 1024/8; x++) { - pixels = m_vram[(y * 128) + (BYTE4_XOR_BE(x))]; - - *scanline++ = m_palette[(pixels>>7)&1]; - *scanline++ = m_palette[(pixels>>6)&1]; - *scanline++ = m_palette[(pixels>>5)&1]; - *scanline++ = m_palette[(pixels>>4)&1]; - *scanline++ = m_palette[(pixels>>3)&1]; - *scanline++ = m_palette[(pixels>>2)&1]; - *scanline++ = m_palette[(pixels>>1)&1]; - *scanline++ = m_palette[(pixels&1)]; + uint8_t const pixels = m_vram[(y * 128) + (BYTE4_XOR_BE(x))]; + + *scanline++ = m_palette[BIT(pixels, 7)]; + *scanline++ = m_palette[BIT(pixels, 6)]; + *scanline++ = m_palette[BIT(pixels, 5)]; + *scanline++ = m_palette[BIT(pixels, 4)]; + *scanline++ = m_palette[BIT(pixels, 3)]; + *scanline++ = m_palette[BIT(pixels, 2)]; + *scanline++ = m_palette[BIT(pixels, 1)]; + *scanline++ = m_palette[BIT(pixels, 0)]; } } diff --git a/src/devices/bus/nubus/nubus_wsportrait.cpp b/src/devices/bus/nubus/nubus_wsportrait.cpp index 2f56488bf48..9894e0d7906 100644 --- a/src/devices/bus/nubus/nubus_wsportrait.cpp +++ b/src/devices/bus/nubus/nubus_wsportrait.cpp @@ -137,42 +137,38 @@ void nubus_wsportrait_device::device_timer(emu_timer &timer, device_timer_id tid uint32_t nubus_wsportrait_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - uint32_t *scanline; - int x, y; - uint8_t pixels, *vram; - // first time? kick off the VBL timer - vram = &m_vram[0x80]; + uint8_t const *const vram = &m_vram[0x80]; switch (m_mode) { case 0: // 1 bpp? - for (y = 0; y < 870; y++) + for (int y = 0; y < 870; y++) { - scanline = &bitmap.pix32(y); - for (x = 0; x < 640/8; x++) + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < 640/8; x++) { - pixels = vram[(y * 128) + (BYTE4_XOR_BE(x))]; - - *scanline++ = m_palette[((pixels>>7)&0x1)]; - *scanline++ = m_palette[((pixels>>6)&0x1)]; - *scanline++ = m_palette[((pixels>>5)&0x1)]; - *scanline++ = m_palette[((pixels>>4)&0x1)]; - *scanline++ = m_palette[((pixels>>3)&0x1)]; - *scanline++ = m_palette[((pixels>>2)&0x1)]; - *scanline++ = m_palette[((pixels>>1)&0x1)]; - *scanline++ = m_palette[(pixels&1)]; + uint8_t const pixels = vram[(y * 128) + (BYTE4_XOR_BE(x))]; + + *scanline++ = m_palette[BIT(pixels, 7)]; + *scanline++ = m_palette[BIT(pixels, 6)]; + *scanline++ = m_palette[BIT(pixels, 5)]; + *scanline++ = m_palette[BIT(pixels, 4)]; + *scanline++ = m_palette[BIT(pixels, 3)]; + *scanline++ = m_palette[BIT(pixels, 2)]; + *scanline++ = m_palette[BIT(pixels, 1)]; + *scanline++ = m_palette[BIT(pixels, 0)]; } } break; case 1: // 2 bpp - for (y = 0; y < 480; y++) + for (int y = 0; y < 480; y++) { - scanline = &bitmap.pix32(y); - for (x = 0; x < 640/4; x++) + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < 640/4; x++) { - pixels = vram[(y * 256) + (BYTE4_XOR_BE(x))]; + uint8_t const pixels = vram[(y * 256) + (BYTE4_XOR_BE(x))]; *scanline++ = m_palette[((pixels>>6)&3)]; *scanline++ = m_palette[((pixels>>4)&3)]; @@ -183,13 +179,12 @@ uint32_t nubus_wsportrait_device::screen_update(screen_device &screen, bitmap_rg break; case 2: // 4 bpp - for (y = 0; y < 480; y++) + for (int y = 0; y < 480; y++) { - scanline = &bitmap.pix32(y); - - for (x = 0; x < 640/2; x++) + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < 640/2; x++) { - pixels = vram[(y * 512) + (BYTE4_XOR_BE(x))]; + uint8_t const pixels = vram[(y * 512) + (BYTE4_XOR_BE(x))]; *scanline++ = m_palette[((pixels&0xf0)>>4)]; *scanline++ = m_palette[(pixels&0xf)]; diff --git a/src/devices/bus/nubus/pds30_30hr.cpp b/src/devices/bus/nubus/pds30_30hr.cpp index 2fe4687fc44..dde2348abc6 100644 --- a/src/devices/bus/nubus/pds30_30hr.cpp +++ b/src/devices/bus/nubus/pds30_30hr.cpp @@ -139,41 +139,37 @@ void nubus_xceed30hr_device::device_timer(emu_timer &timer, device_timer_id tid, uint32_t nubus_xceed30hr_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - uint32_t *scanline; - int x, y; - uint8_t pixels, *vram; - - vram = &m_vram[1024]; + uint8_t const *const vram = &m_vram[1024]; switch (m_mode) { case 0: // 1 bpp? - for (y = 0; y < 480; y++) + for (int y = 0; y < 480; y++) { - scanline = &bitmap.pix32(y); - for (x = 0; x < 640/8; x++) + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < 640/8; x++) { - pixels = vram[(y * 1024) + (BYTE4_XOR_BE(x))]; - - *scanline++ = m_palette[(pixels>>7)&1]; - *scanline++ = m_palette[(pixels>>6)&1]; - *scanline++ = m_palette[(pixels>>5)&1]; - *scanline++ = m_palette[(pixels>>4)&1]; - *scanline++ = m_palette[(pixels>>3)&1]; - *scanline++ = m_palette[(pixels>>2)&1]; - *scanline++ = m_palette[(pixels>>1)&1]; - *scanline++ = m_palette[pixels&1]; + uint8_t const pixels = vram[(y * 1024) + (BYTE4_XOR_BE(x))]; + + *scanline++ = m_palette[BIT(pixels, 7)]; + *scanline++ = m_palette[BIT(pixels, 6)]; + *scanline++ = m_palette[BIT(pixels, 5)]; + *scanline++ = m_palette[BIT(pixels, 4)]; + *scanline++ = m_palette[BIT(pixels, 3)]; + *scanline++ = m_palette[BIT(pixels, 2)]; + *scanline++ = m_palette[BIT(pixels, 1)]; + *scanline++ = m_palette[BIT(pixels, 0)]; } } break; case 1: // 2 bpp - for (y = 0; y < 480; y++) + for (int y = 0; y < 480; y++) { - scanline = &bitmap.pix32(y); - for (x = 0; x < 640/4; x++) + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < 640/4; x++) { - pixels = vram[(y * 1024) + (BYTE4_XOR_BE(x))]; + uint8_t const pixels = vram[(y * 1024) + (BYTE4_XOR_BE(x))]; *scanline++ = m_palette[((pixels>>6)&3)]; *scanline++ = m_palette[((pixels>>4)&3)]; @@ -184,13 +180,12 @@ uint32_t nubus_xceed30hr_device::screen_update(screen_device &screen, bitmap_rgb break; case 2: // 4 bpp - for (y = 0; y < 480; y++) + for (int y = 0; y < 480; y++) { - scanline = &bitmap.pix32(y); - - for (x = 0; x < 640/2; x++) + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < 640/2; x++) { - pixels = vram[(y * 1024) + (BYTE4_XOR_BE(x))]; + uint8_t const pixels = vram[(y * 1024) + (BYTE4_XOR_BE(x))]; *scanline++ = m_palette[(pixels>>4)]; *scanline++ = m_palette[(pixels&0xf)]; @@ -199,13 +194,12 @@ uint32_t nubus_xceed30hr_device::screen_update(screen_device &screen, bitmap_rgb break; case 3: // 8 bpp - for (y = 0; y < 480; y++) + for (int y = 0; y < 480; y++) { - scanline = &bitmap.pix32(y); - - for (x = 0; x < 640; x++) + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < 640; x++) { - pixels = vram[(y * 1024) + (BYTE4_XOR_BE(x))]; + uint8_t const pixels = vram[(y * 1024) + (BYTE4_XOR_BE(x))]; *scanline++ = m_palette[pixels]; } } diff --git a/src/devices/bus/nubus/pds30_cb264.cpp b/src/devices/bus/nubus/pds30_cb264.cpp index aa0ca1df648..388aa5f54d5 100644 --- a/src/devices/bus/nubus/pds30_cb264.cpp +++ b/src/devices/bus/nubus/pds30_cb264.cpp @@ -10,6 +10,9 @@ #include "pds30_cb264.h" #include "screen.h" +#include <algorithm> + + #define CB264SE30_SCREEN_NAME "cb264_screen" #define CB264SE30_ROM_REGION "cb264_rom" @@ -133,21 +136,17 @@ void nubus_cb264se30_device::device_timer(emu_timer &timer, device_timer_id tid, uint32_t nubus_cb264se30_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - uint32_t *scanline; - int x, y; - uint8_t pixels, *vram; - - vram = &m_vram[8*1024]; + uint8_t const *const vram = &m_vram[8*1024]; switch (m_mode) { case 0: // 1 bpp? - for (y = 0; y < 480; y++) + for (int y = 0; y < 480; y++) { - scanline = &bitmap.pix32(y); - for (x = 0; x < 640/8; x++) + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < 640/8; x++) { - pixels = vram[(y * 1024) + (BYTE4_XOR_BE(x))]; + uint8_t const pixels = vram[(y * 1024) + (BYTE4_XOR_BE(x))]; *scanline++ = m_palette[(pixels&0x80)]; *scanline++ = m_palette[((pixels<<1)&0x80)]; @@ -162,12 +161,12 @@ uint32_t nubus_cb264se30_device::screen_update(screen_device &screen, bitmap_rgb break; case 1: // 2 bpp - for (y = 0; y < 480; y++) + for (int y = 0; y < 480; y++) { - scanline = &bitmap.pix32(y); - for (x = 0; x < 640/4; x++) + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < 640/4; x++) { - pixels = vram[(y * 1024) + (BYTE4_XOR_BE(x))]; + uint8_t const pixels = vram[(y * 1024) + (BYTE4_XOR_BE(x))]; *scanline++ = m_palette[(pixels&0xc0)]; *scanline++ = m_palette[((pixels<<2)&0xc0)]; @@ -178,13 +177,12 @@ uint32_t nubus_cb264se30_device::screen_update(screen_device &screen, bitmap_rgb break; case 2: // 4 bpp - for (y = 0; y < 480; y++) + for (int y = 0; y < 480; y++) { - scanline = &bitmap.pix32(y); - - for (x = 0; x < 640/2; x++) + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < 640/2; x++) { - pixels = vram[(y * 1024) + (BYTE4_XOR_BE(x))]; + uint8_t const pixels = vram[(y * 1024) + (BYTE4_XOR_BE(x))]; *scanline++ = m_palette[(pixels&0xf0)]; *scanline++ = m_palette[((pixels&0x0f)<<4)]; @@ -193,13 +191,12 @@ uint32_t nubus_cb264se30_device::screen_update(screen_device &screen, bitmap_rgb break; case 3: // 8 bpp - for (y = 0; y < 480; y++) + for (int y = 0; y < 480; y++) { - scanline = &bitmap.pix32(y); - - for (x = 0; x < 640; x++) + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < 640; x++) { - pixels = vram[(y * 1024) + (BYTE4_XOR_BE(x))]; + uint8_t const pixels = vram[(y * 1024) + (BYTE4_XOR_BE(x))]; *scanline++ = m_palette[pixels]; } } @@ -207,17 +204,11 @@ uint32_t nubus_cb264se30_device::screen_update(screen_device &screen, bitmap_rgb case 4: // 24 bpp { - uint32_t *vram32 = (uint32_t *)&m_vram[0]; - uint32_t *base; + uint32_t const *const vram32 = (uint32_t *)&m_vram[0]; - for (y = 0; y < 480; y++) + for (int y = 0; y < 480; y++) { - scanline = &bitmap.pix32(y); - base = &vram32[y * 1024]; - for (x = 0; x < 640; x++) - { - *scanline++ = *base++; - } + std::copy_n(&vram32[y * 1024], 640, &bitmap.pix(y)); } } break; diff --git a/src/devices/bus/nubus/pds30_mc30.cpp b/src/devices/bus/nubus/pds30_mc30.cpp index 20969a5a6b7..87992723319 100644 --- a/src/devices/bus/nubus/pds30_mc30.cpp +++ b/src/devices/bus/nubus/pds30_mc30.cpp @@ -13,6 +13,9 @@ #include "pds30_mc30.h" #include "screen.h" +#include <algorithm> + + #define XCEEDMC30_SCREEN_NAME "x30hr_screen" #define XCEEDMC30_ROM_REGION "x30hr_rom" @@ -135,41 +138,37 @@ void nubus_xceedmc30_device::device_timer(emu_timer &timer, device_timer_id tid, uint32_t nubus_xceedmc30_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - uint32_t *scanline; - int x, y; - uint8_t pixels, *vram; - - vram = &m_vram[4*1024]; + uint8_t const *const vram = &m_vram[4*1024]; switch (m_mode) { case 0: // 1 bpp? - for (y = 0; y < 480; y++) + for (int y = 0; y < 480; y++) { - scanline = &bitmap.pix32(y); - for (x = 0; x < 640/8; x++) + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < 640/8; x++) { - pixels = vram[(y * 1024) + (BYTE4_XOR_BE(x))]; - - *scanline++ = m_palette[(pixels>>7)&1]; - *scanline++ = m_palette[(pixels>>6)&1]; - *scanline++ = m_palette[(pixels>>5)&1]; - *scanline++ = m_palette[(pixels>>4)&1]; - *scanline++ = m_palette[(pixels>>3)&1]; - *scanline++ = m_palette[(pixels>>2)&1]; - *scanline++ = m_palette[(pixels>>1)&1]; - *scanline++ = m_palette[pixels&1]; + uint8_t const pixels = vram[(y * 1024) + (BYTE4_XOR_BE(x))]; + + *scanline++ = m_palette[BIT(pixels, 7)]; + *scanline++ = m_palette[BIT(pixels, 6)]; + *scanline++ = m_palette[BIT(pixels, 5)]; + *scanline++ = m_palette[BIT(pixels, 4)]; + *scanline++ = m_palette[BIT(pixels, 3)]; + *scanline++ = m_palette[BIT(pixels, 2)]; + *scanline++ = m_palette[BIT(pixels, 1)]; + *scanline++ = m_palette[BIT(pixels, 0)]; } } break; case 1: // 2 bpp - for (y = 0; y < 480; y++) + for (int y = 0; y < 480; y++) { - scanline = &bitmap.pix32(y); - for (x = 0; x < 640/4; x++) + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < 640/4; x++) { - pixels = vram[(y * 1024) + (BYTE4_XOR_BE(x))]; + uint8_t const pixels = vram[(y * 1024) + (BYTE4_XOR_BE(x))]; *scanline++ = m_palette[((pixels>>6)&3)]; *scanline++ = m_palette[((pixels>>4)&3)]; @@ -180,13 +179,13 @@ uint32_t nubus_xceedmc30_device::screen_update(screen_device &screen, bitmap_rgb break; case 2: // 4 bpp - for (y = 0; y < 480; y++) + for (int y = 0; y < 480; y++) { - scanline = &bitmap.pix32(y); + uint32_t *scanline = &bitmap.pix(y); - for (x = 0; x < 640/2; x++) + for (int x = 0; x < 640/2; x++) { - pixels = vram[(y * 1024) + (BYTE4_XOR_BE(x))]; + uint8_t const pixels = vram[(y * 1024) + (BYTE4_XOR_BE(x))]; *scanline++ = m_palette[(pixels>>4)]; *scanline++ = m_palette[(pixels&0xf)]; @@ -195,13 +194,13 @@ uint32_t nubus_xceedmc30_device::screen_update(screen_device &screen, bitmap_rgb break; case 3: // 8 bpp - for (y = 0; y < 480; y++) + for (int y = 0; y < 480; y++) { - scanline = &bitmap.pix32(y); + uint32_t *scanline = &bitmap.pix(y); - for (x = 0; x < 640; x++) + for (int x = 0; x < 640; x++) { - pixels = vram[(y * 1024) + (BYTE4_XOR_BE(x))]; + uint8_t const pixels = vram[(y * 1024) + (BYTE4_XOR_BE(x))]; *scanline++ = m_palette[pixels]; } } @@ -209,17 +208,11 @@ uint32_t nubus_xceedmc30_device::screen_update(screen_device &screen, bitmap_rgb case 4: // 24 bpp { - uint32_t *vram32 = (uint32_t *)vram; - uint32_t *base; + uint32_t const *const vram32 = (uint32_t *)vram; - for (y = 0; y < 480; y++) + for (int y = 0; y < 480; y++) { - scanline = &bitmap.pix32(y); - base = &vram32[y * 1024]; - for (x = 0; x < 640; x++) - { - *scanline++ = *base++; - } + std::copy_n(&vram32[y * 1024], 640, &bitmap.pix(y)); } } break; diff --git a/src/devices/bus/nubus/pds30_procolor816.cpp b/src/devices/bus/nubus/pds30_procolor816.cpp index b251a57c33c..83fd8512704 100644 --- a/src/devices/bus/nubus/pds30_procolor816.cpp +++ b/src/devices/bus/nubus/pds30_procolor816.cpp @@ -139,21 +139,17 @@ void nubus_procolor816_device::device_timer(emu_timer &timer, device_timer_id ti uint32_t nubus_procolor816_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - uint32_t *scanline; - int x, y; - uint8_t pixels, *vram; - - vram = &m_vram[4]; + uint8_t const *const vram = &m_vram[4]; switch (m_mode) { case 0: // 1 bpp? - for (y = 0; y < 480; y++) + for (int y = 0; y < 480; y++) { - scanline = &bitmap.pix32(y); - for (x = 0; x < 640/8; x++) + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < 640/8; x++) { - pixels = vram[(y * 640/8) + (BYTE4_XOR_BE(x))]; + uint8_t const pixels = vram[(y * 640/8) + (BYTE4_XOR_BE(x))]; *scanline++ = m_palette[(pixels&0x80)]; *scanline++ = m_palette[((pixels<<1)&0x80)]; @@ -168,12 +164,12 @@ uint32_t nubus_procolor816_device::screen_update(screen_device &screen, bitmap_r break; case 1: // 2 bpp - for (y = 0; y < 480; y++) + for (int y = 0; y < 480; y++) { - scanline = &bitmap.pix32(y); - for (x = 0; x < 640/4; x++) + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < 640/4; x++) { - pixels = vram[(y * 640/4) + (BYTE4_XOR_BE(x))]; + uint8_t const pixels = vram[(y * 640/4) + (BYTE4_XOR_BE(x))]; *scanline++ = m_palette[(pixels&0xc0)]; *scanline++ = m_palette[((pixels<<2)&0xc0)]; @@ -184,13 +180,12 @@ uint32_t nubus_procolor816_device::screen_update(screen_device &screen, bitmap_r break; case 2: // 4 bpp - for (y = 0; y < 480; y++) + for (int y = 0; y < 480; y++) { - scanline = &bitmap.pix32(y); - - for (x = 0; x < 640/2; x++) + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < 640/2; x++) { - pixels = vram[(y * 640/2) + (BYTE4_XOR_BE(x))]; + uint8_t const pixels = vram[(y * 640/2) + (BYTE4_XOR_BE(x))]; *scanline++ = m_palette[(pixels&0xf0)]; *scanline++ = m_palette[((pixels&0x0f)<<4)]; @@ -199,13 +194,12 @@ uint32_t nubus_procolor816_device::screen_update(screen_device &screen, bitmap_r break; case 3: // 8 bpp - for (y = 0; y < 480; y++) + for (int y = 0; y < 480; y++) { - scanline = &bitmap.pix32(y); - - for (x = 0; x < 640; x++) + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < 640; x++) { - pixels = vram[(y * 640) + (BYTE4_XOR_BE(x))]; + uint8_t const pixels = vram[(y * 640) + (BYTE4_XOR_BE(x))]; *scanline++ = m_palette[pixels]; } } @@ -213,16 +207,15 @@ uint32_t nubus_procolor816_device::screen_update(screen_device &screen, bitmap_r case 4: // 15 bpp { - uint16_t *vram16 = (uint16_t *)&m_vram[0]; - uint16_t pixels; + uint16_t const *const vram16 = (uint16_t *)&m_vram[0]; - for (y = 0; y < 480; y++) + for (int y = 0; y < 480; y++) { - scanline = &bitmap.pix32(y); - for (x = 0; x < 640; x++) + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < 640; x++) { - pixels = vram16[(y * 640) + (x^1)]; - *scanline++ = rgb_t(((pixels>>10) & 0x1f)<<3, ((pixels>>5) & 0x1f)<<3, (pixels & 0x1f)<<3); + uint16_t const pixels = vram16[(y * 640) + BYTE_XOR_BE(x)]; + *scanline++ = rgb_t(pal5bit((pixels>>10) & 0x1f), pal5bit((pixels>>5) & 0x1f), pal5bit(pixels & 0x1f)); } } } diff --git a/src/devices/bus/nubus/pds30_sigmalview.cpp b/src/devices/bus/nubus/pds30_sigmalview.cpp index c509b908064..e04e4b2e297 100644 --- a/src/devices/bus/nubus/pds30_sigmalview.cpp +++ b/src/devices/bus/nubus/pds30_sigmalview.cpp @@ -132,18 +132,14 @@ void nubus_lview_device::device_timer(emu_timer &timer, device_timer_id tid, int uint32_t nubus_lview_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - uint32_t *scanline; - int x, y; - uint8_t pixels, *vram; + uint8_t const *const vram = &m_vram[0x20]; - vram = &m_vram[0x20]; - - for (y = 0; y < 600; y++) + for (int y = 0; y < 600; y++) { - scanline = &bitmap.pix32(y); - for (x = 0; x < 832/8; x++) + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < 832/8; x++) { - pixels = vram[(y * (832/8)) + (BYTE4_XOR_BE(x))]; + uint8_t const pixels = vram[(y * (832/8)) + (BYTE4_XOR_BE(x))]; *scanline++ = m_palette[(pixels&0x80)]; *scanline++ = m_palette[((pixels<<1)&0x80)]; diff --git a/src/devices/bus/odyssey2/4in1.cpp b/src/devices/bus/odyssey2/4in1.cpp index f0eefac089b..dfadbf2c1ab 100644 --- a/src/devices/bus/odyssey2/4in1.cpp +++ b/src/devices/bus/odyssey2/4in1.cpp @@ -22,7 +22,7 @@ DEFINE_DEVICE_TYPE(O2_ROM_4IN1, o2_4in1_device, "o2_4in1", "Odyssey 2 Videopac 4 // o2_4in1_device - constructor //------------------------------------------------- -o2_4in1_device::o2_4in1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : +o2_4in1_device::o2_4in1_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, O2_ROM_4IN1, tag, owner, clock), device_o2_cart_interface(mconfig, *this) { } diff --git a/src/devices/bus/odyssey2/4in1.h b/src/devices/bus/odyssey2/4in1.h index 09cfa626b38..2840361bfe0 100644 --- a/src/devices/bus/odyssey2/4in1.h +++ b/src/devices/bus/odyssey2/4in1.h @@ -21,7 +21,7 @@ class o2_4in1_device : public device_t, { public: // construction/destruction - o2_4in1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + o2_4in1_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); protected: // device-level overrides diff --git a/src/devices/bus/odyssey2/chess.cpp b/src/devices/bus/odyssey2/chess.cpp index f954ca93340..6ff1ff76dd2 100644 --- a/src/devices/bus/odyssey2/chess.cpp +++ b/src/devices/bus/odyssey2/chess.cpp @@ -21,7 +21,7 @@ DEFINE_DEVICE_TYPE(O2_ROM_CHESS, o2_chess_device, "o2_chess", "Odyssey 2 Videopa // o2_chess_device - constructor //------------------------------------------------- -o2_chess_device::o2_chess_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : +o2_chess_device::o2_chess_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, O2_ROM_CHESS, tag, owner, clock), device_o2_cart_interface(mconfig, *this), m_maincpu(*this, "maincpu"), diff --git a/src/devices/bus/odyssey2/chess.h b/src/devices/bus/odyssey2/chess.h index d4e861e2a64..0b37c50684c 100644 --- a/src/devices/bus/odyssey2/chess.h +++ b/src/devices/bus/odyssey2/chess.h @@ -24,7 +24,7 @@ class o2_chess_device : public device_t, { public: // construction/destruction - o2_chess_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + o2_chess_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); protected: // device-level overrides diff --git a/src/devices/bus/odyssey2/homecomp.cpp b/src/devices/bus/odyssey2/homecomp.cpp index 352d0f2a452..23c6f6c31f7 100644 --- a/src/devices/bus/odyssey2/homecomp.cpp +++ b/src/devices/bus/odyssey2/homecomp.cpp @@ -30,7 +30,7 @@ DEFINE_DEVICE_TYPE(O2_ROM_HOMECOMP, o2_homecomp_device, "o2_homecomp", "Odyssey // o2_homecomp_device - constructor //------------------------------------------------- -o2_homecomp_device::o2_homecomp_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : +o2_homecomp_device::o2_homecomp_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, O2_ROM_HOMECOMP, tag, owner, clock), device_o2_cart_interface(mconfig, *this), m_maincpu(*this, "maincpu"), diff --git a/src/devices/bus/odyssey2/homecomp.h b/src/devices/bus/odyssey2/homecomp.h index f530cd36375..6ecc67f1184 100644 --- a/src/devices/bus/odyssey2/homecomp.h +++ b/src/devices/bus/odyssey2/homecomp.h @@ -25,7 +25,7 @@ class o2_homecomp_device : public device_t, { public: // construction/destruction - o2_homecomp_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + o2_homecomp_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); protected: // device-level overrides diff --git a/src/devices/bus/odyssey2/ktaa.cpp b/src/devices/bus/odyssey2/ktaa.cpp index 24d62c81796..4f1fba25153 100644 --- a/src/devices/bus/odyssey2/ktaa.cpp +++ b/src/devices/bus/odyssey2/ktaa.cpp @@ -18,7 +18,7 @@ DEFINE_DEVICE_TYPE(O2_ROM_KTAA, o2_ktaa_device, "o2_ktaa", "Odyssey 2 Homebrew K // o2_ktaa_device - constructor //------------------------------------------------- -o2_ktaa_device::o2_ktaa_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : +o2_ktaa_device::o2_ktaa_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, O2_ROM_KTAA, tag, owner, clock), device_o2_cart_interface(mconfig, *this) { } diff --git a/src/devices/bus/odyssey2/ktaa.h b/src/devices/bus/odyssey2/ktaa.h index e1ac477e445..53ce2296941 100644 --- a/src/devices/bus/odyssey2/ktaa.h +++ b/src/devices/bus/odyssey2/ktaa.h @@ -21,7 +21,7 @@ class o2_ktaa_device : public device_t, { public: // construction/destruction - o2_ktaa_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + o2_ktaa_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); protected: // device-level overrides diff --git a/src/devices/bus/odyssey2/rally.cpp b/src/devices/bus/odyssey2/rally.cpp index 7bdec3502b3..42dcdc0b26f 100644 --- a/src/devices/bus/odyssey2/rally.cpp +++ b/src/devices/bus/odyssey2/rally.cpp @@ -26,7 +26,7 @@ DEFINE_DEVICE_TYPE(O2_ROM_RALLY, o2_rally_device, "o2_rally", "Odyssey 2 Videopa // o2_rally_device - constructor //------------------------------------------------- -o2_rally_device::o2_rally_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : +o2_rally_device::o2_rally_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, O2_ROM_RALLY, tag, owner, clock), device_o2_cart_interface(mconfig, *this) { } diff --git a/src/devices/bus/odyssey2/rally.h b/src/devices/bus/odyssey2/rally.h index 81de2673ae6..8d359362dce 100644 --- a/src/devices/bus/odyssey2/rally.h +++ b/src/devices/bus/odyssey2/rally.h @@ -21,7 +21,7 @@ class o2_rally_device : public device_t, { public: // construction/destruction - o2_rally_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + o2_rally_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); protected: // device-level overrides diff --git a/src/devices/bus/odyssey2/rom.cpp b/src/devices/bus/odyssey2/rom.cpp index f54398914e3..12f8fa9b128 100644 --- a/src/devices/bus/odyssey2/rom.cpp +++ b/src/devices/bus/odyssey2/rom.cpp @@ -16,7 +16,7 @@ DEFINE_DEVICE_TYPE(O2_ROM_STD, o2_rom_device, "o2_rom", "Odyssey 2 Standard Cart // o2_rom_device - constructor //------------------------------------------------- -o2_rom_device::o2_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : +o2_rom_device::o2_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, O2_ROM_STD, tag, owner, clock), device_o2_cart_interface(mconfig, *this) { } diff --git a/src/devices/bus/odyssey2/rom.h b/src/devices/bus/odyssey2/rom.h index 74e742a38d8..204d96030ce 100644 --- a/src/devices/bus/odyssey2/rom.h +++ b/src/devices/bus/odyssey2/rom.h @@ -21,7 +21,7 @@ class o2_rom_device : public device_t, { public: // construction/destruction - o2_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + o2_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); protected: // device-level overrides diff --git a/src/devices/bus/odyssey2/slot.cpp b/src/devices/bus/odyssey2/slot.cpp index 2e020342366..5f0f30e2f35 100644 --- a/src/devices/bus/odyssey2/slot.cpp +++ b/src/devices/bus/odyssey2/slot.cpp @@ -50,7 +50,7 @@ device_o2_cart_interface::~device_o2_cart_interface() //------------------------------------------------- // o2_cart_slot_device - constructor //------------------------------------------------- -o2_cart_slot_device::o2_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +o2_cart_slot_device::o2_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, O2_CART_SLOT, tag, owner, clock) , device_image_interface(mconfig, *this) , device_single_card_slot_interface<device_o2_cart_interface>(mconfig, *this) @@ -148,7 +148,7 @@ image_init_result o2_cart_slot_device::call_load() } else { - uint32_t size = length(); + u32 size = length(); fread(m_cart->m_rom, size); m_type = (size == 0x4000) ? O2_RALLY : O2_STD; @@ -174,7 +174,7 @@ std::string o2_cart_slot_device::get_default_card_software(get_default_card_soft if (hook.image_file()) { const char *slot_string; - uint32_t size = hook.image_file()->size(); + u32 size = hook.image_file()->size(); int type = (size == 0x4000) ? O2_RALLY : O2_STD; slot_string = o2_get_slot(type); @@ -190,7 +190,7 @@ std::string o2_cart_slot_device::get_default_card_software(get_default_card_soft read_rom** -------------------------------------------------*/ -uint8_t o2_cart_slot_device::read_rom04(offs_t offset) +u8 o2_cart_slot_device::read_rom04(offs_t offset) { if (m_cart) return m_cart->read_rom04(offset); @@ -198,7 +198,7 @@ uint8_t o2_cart_slot_device::read_rom04(offs_t offset) return 0xff; } -uint8_t o2_cart_slot_device::read_rom0c(offs_t offset) +u8 o2_cart_slot_device::read_rom0c(offs_t offset) { if (m_cart) return m_cart->read_rom0c(offset); @@ -210,13 +210,13 @@ uint8_t o2_cart_slot_device::read_rom0c(offs_t offset) io -------------------------------------------------*/ -void o2_cart_slot_device::io_write(offs_t offset, uint8_t data) +void o2_cart_slot_device::io_write(offs_t offset, u8 data) { if (m_cart) m_cart->io_write(offset, data); } -uint8_t o2_cart_slot_device::io_read(offs_t offset) +u8 o2_cart_slot_device::io_read(offs_t offset) { if (m_cart) return m_cart->io_read(offset); diff --git a/src/devices/bus/odyssey2/slot.h b/src/devices/bus/odyssey2/slot.h index 0717ce973f2..4c65fafe01e 100644 --- a/src/devices/bus/odyssey2/slot.h +++ b/src/devices/bus/odyssey2/slot.h @@ -37,30 +37,30 @@ public: virtual ~device_o2_cart_interface(); // reading and writing - virtual uint8_t read_rom04(offs_t offset) { return 0xff; } - virtual uint8_t read_rom0c(offs_t offset) { return 0xff; } - virtual void write_p1(uint8_t data) { } - virtual void write_p2(uint8_t data) { } + virtual u8 read_rom04(offs_t offset) { return 0xff; } + virtual u8 read_rom0c(offs_t offset) { return 0xff; } + virtual void write_p1(u8 data) { } + virtual void write_p2(u8 data) { } - virtual void io_write(offs_t offset, uint8_t data) { } - virtual uint8_t io_read(offs_t offset) { return 0xff; } + virtual void io_write(offs_t offset, u8 data) { } + virtual u8 io_read(offs_t offset) { return 0xff; } virtual DECLARE_READ_LINE_MEMBER(t0_read) { return 0; } virtual int b_read() { return -1; } virtual void cart_init() { } // called after loading ROM - uint8_t* get_rom_base() { return m_rom ? &m_rom[0] : nullptr; } - uint32_t get_rom_size() { return m_rom ? m_rom.bytes() : 0; } + u8* get_rom_base() { return m_rom ? &m_rom[0] : nullptr; } + u32 get_rom_size() { return m_rom ? m_rom.bytes() : 0; } - uint8_t* get_voice_base() { return m_voice ? &m_voice[0] : nullptr; } - uint32_t get_voice_size() { return m_voice ? m_voice.bytes() : 0; } + u8* get_voice_base() { return m_voice ? &m_voice[0] : nullptr; } + u32 get_voice_size() { return m_voice ? m_voice.bytes() : 0; } protected: device_o2_cart_interface(const machine_config &mconfig, device_t &device); - optional_shared_ptr<uint8_t> m_rom; - optional_shared_ptr<uint8_t> m_exrom; - optional_shared_ptr<uint8_t> m_voice; + optional_shared_ptr<u8> m_rom; + optional_shared_ptr<u8> m_exrom; + optional_shared_ptr<u8> m_voice; }; @@ -82,7 +82,7 @@ public: set_fixed(false); } - o2_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); + o2_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); virtual ~o2_cart_slot_device(); // image-level overrides @@ -105,15 +105,15 @@ public: device_o2_cart_interface* cart() { return m_cart; } // reading and writing - uint8_t read_rom04(offs_t offset); - uint8_t read_rom0c(offs_t offset); - void io_write(offs_t offset, uint8_t data); - uint8_t io_read(offs_t offset); + u8 read_rom04(offs_t offset); + u8 read_rom0c(offs_t offset); + void io_write(offs_t offset, u8 data); + u8 io_read(offs_t offset); DECLARE_READ_LINE_MEMBER(t0_read) { if (m_cart) return m_cart->t0_read(); else return 0; } int b_read(); - void write_p1(uint8_t data) { if (m_cart) m_cart->write_p1(data); } - void write_p2(uint8_t data) { if (m_cart) m_cart->write_p2(data); } + void write_p1(u8 data) { if (m_cart) m_cart->write_p1(data); } + void write_p2(u8 data) { if (m_cart) m_cart->write_p2(data); } protected: // device-level overrides diff --git a/src/devices/bus/odyssey2/voice.cpp b/src/devices/bus/odyssey2/voice.cpp index f741946dfa0..927b8fcc05e 100644 --- a/src/devices/bus/odyssey2/voice.cpp +++ b/src/devices/bus/odyssey2/voice.cpp @@ -24,7 +24,7 @@ DEFINE_DEVICE_TYPE(O2_ROM_VOICE, o2_voice_device, "o2_voice", "Odyssey 2 The Voi // o2_voice_device - constructor //------------------------------------------------- -o2_voice_device::o2_voice_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : +o2_voice_device::o2_voice_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, O2_ROM_VOICE, tag, owner, clock), device_o2_cart_interface(mconfig, *this), m_speech(*this, "speech"), diff --git a/src/devices/bus/odyssey2/voice.h b/src/devices/bus/odyssey2/voice.h index 829267fd439..b717334149a 100644 --- a/src/devices/bus/odyssey2/voice.h +++ b/src/devices/bus/odyssey2/voice.h @@ -22,7 +22,7 @@ class o2_voice_device : public device_t, { public: // construction/destruction - o2_voice_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + o2_voice_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); virtual void cart_init() override; diff --git a/src/devices/bus/s100/dg640.cpp b/src/devices/bus/s100/dg640.cpp index 7f79983f17d..f6adb27cfa8 100644 --- a/src/devices/bus/s100/dg640.cpp +++ b/src/devices/bus/s100/dg640.cpp @@ -39,28 +39,26 @@ void dg640_device::device_start() uint32_t dg640_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { // attributes bit 0 = flash, bit 1 = lores. Also bit 7 of the character = reverse-video (text only). - uint8_t y,ra,chr,gfx,attr,inv,gfxbit; - uint16_t sy=0,ma=0,x; - bool flash; + uint16_t sy=0,ma=0; m_framecnt++; - for (y = 0; y < 16; y++) + for (uint8_t y = 0; y < 16; y++) { - for (ra = 0; ra < 16; ra++) + for (uint8_t ra = 0; ra < 16; ra++) { - uint16_t *p = &bitmap.pix16(sy++); + uint16_t *p = &bitmap.pix(sy++); - for (x = ma; x < ma + 64; x++) + for (uint16_t x = ma; x < ma + 64; x++) { - attr = m_p_attribram[x]; - chr = m_p_videoram[x]; - flash = BIT(m_framecnt, 4) & BIT(attr, 0); + uint8_t attr = m_p_attribram[x]; + uint8_t chr = m_p_videoram[x]; + bool flash = BIT(m_framecnt, 4) & BIT(attr, 0); if (BIT(attr, 1)) // lores gfx - can flash { if (flash) chr = 0; // blank part of flashing - gfxbit = (ra & 0x0c)>>1; + uint8_t gfxbit = (ra & 0x0c) >> 1; /* Display one line of a lores character (8 pixels) */ *p++ = BIT(chr, gfxbit); *p++ = BIT(chr, gfxbit); @@ -74,11 +72,11 @@ uint32_t dg640_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap } else { - gfx = 0; + uint8_t gfx = 0; if (!flash) { - inv = BIT(chr, 7) ? 0xff : 0; // text with bit 7 high is reversed + uint8_t inv = BIT(chr, 7) ? 0xff : 0; // text with bit 7 high is reversed chr &= 0x7f; gfx = inv; diff --git a/src/devices/bus/s100/polyvti.cpp b/src/devices/bus/s100/polyvti.cpp index 973e89c0693..242d13a8fe2 100644 --- a/src/devices/bus/s100/polyvti.cpp +++ b/src/devices/bus/s100/polyvti.cpp @@ -119,22 +119,22 @@ u32 poly_vti_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, { u8 r = b/5; if (l==0 && r==0) - bitmap.pix16(y*15+j, xpos+b ) = BIT(code,5) ? 0 : 1; + bitmap.pix(y*15+j, xpos+b ) = BIT(code,5) ? 0 : 1; if (l==0 && r==1) - bitmap.pix16(y*15+j, xpos+b ) = BIT(code,2) ? 0 : 1; + bitmap.pix(y*15+j, xpos+b ) = BIT(code,2) ? 0 : 1; if (l==1 && r==0) - bitmap.pix16(y*15+j, xpos+b ) = BIT(code,4) ? 0 : 1; + bitmap.pix(y*15+j, xpos+b ) = BIT(code,4) ? 0 : 1; if (l==1 && r==1) - bitmap.pix16(y*15+j, xpos+b ) = BIT(code,1) ? 0 : 1; + bitmap.pix(y*15+j, xpos+b ) = BIT(code,1) ? 0 : 1; if (l==2 && r==0) - bitmap.pix16(y*15+j, xpos+b ) = BIT(code,3) ? 0 : 1; + bitmap.pix(y*15+j, xpos+b ) = BIT(code,3) ? 0 : 1; if (l==2 && r==1) - bitmap.pix16(y*15+j, xpos+b ) = BIT(code,0) ? 0 : 1; + bitmap.pix(y*15+j, xpos+b ) = BIT(code,0) ? 0 : 1; } } } @@ -156,11 +156,11 @@ u32 poly_vti_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, } for (int b = 0; b < 7; b++) - bitmap.pix16(y*15+j, xpos+b ) = (l >> (6-b)) & 1; + bitmap.pix(y*15+j, xpos+b ) = (l >> (6-b)) & 1; - bitmap.pix16(y*15+j, xpos+7 ) = 0; - bitmap.pix16(y*15+j, xpos+8 ) = 0; - bitmap.pix16(y*15+j, xpos+9 ) = 0; + bitmap.pix(y*15+j, xpos+7 ) = 0; + bitmap.pix(y*15+j, xpos+8 ) = 0; + bitmap.pix(y*15+j, xpos+9 ) = 0; } } xpos += 10; diff --git a/src/devices/bus/sbus/bwtwo.cpp b/src/devices/bus/sbus/bwtwo.cpp index 55d9f92b7b6..c034d43e05f 100644 --- a/src/devices/bus/sbus/bwtwo.cpp +++ b/src/devices/bus/sbus/bwtwo.cpp @@ -10,6 +10,9 @@ #include "bwtwo.h" #include "screen.h" +#include <algorithm> + + DEFINE_DEVICE_TYPE(SBUS_BWTWO, sbus_bwtwo_device, "bwtwo", "Sun bwtwo SBus Video") void sbus_bwtwo_device::mem_map(address_map &map) @@ -72,14 +75,14 @@ void sbus_bwtwo_device::install_device() uint32_t sbus_bwtwo_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - uint8_t *line = &m_vram[0]; + uint8_t const *line = &m_vram[0]; for (int y = 0; y < 900; y++) { - uint32_t *scanline = &bitmap.pix32(y); + uint32_t *scanline = &bitmap.pix(y); for (int x = 0; x < 1152/8; x++) { - memcpy(scanline, m_mono_lut[*line], sizeof(uint32_t) * 8); + std::copy_n(m_mono_lut[*line], 8, scanline); line++; scanline += 8; } diff --git a/src/devices/bus/sbus/cgsix.cpp b/src/devices/bus/sbus/cgsix.cpp index 5d7bd715efd..65a24e1b505 100644 --- a/src/devices/bus/sbus/cgsix.cpp +++ b/src/devices/bus/sbus/cgsix.cpp @@ -171,12 +171,12 @@ void sbus_cgsix_device::device_reset() uint32_t sbus_cgsix_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - const pen_t *pens = m_ramdac->pens(); - uint8_t *vram = (uint8_t *)&m_vram[0]; + pen_t const *const pens = m_ramdac->pens(); + uint8_t const *const vram = (uint8_t *)&m_vram[0]; for (int16_t y = 0; y < 900; y++) { - uint32_t *scanline = &bitmap.pix32(y); + uint32_t *scanline = &bitmap.pix(y); const bool cursor_row_hit = (y >= m_cursor_y && y < (m_cursor_y + 32)); for (int16_t x = 0; x < 1152; x++) { diff --git a/src/devices/bus/sbus/cgthree.cpp b/src/devices/bus/sbus/cgthree.cpp index 5ffe6a885c5..ad0ba5c1467 100644 --- a/src/devices/bus/sbus/cgthree.cpp +++ b/src/devices/bus/sbus/cgthree.cpp @@ -67,12 +67,12 @@ void sbus_cgthree_device::install_device() uint32_t sbus_cgthree_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - const pen_t *pens = m_ramdac->pens(); - uint8_t *vram = (uint8_t *)&m_vram[0]; + pen_t const *const pens = m_ramdac->pens(); + uint8_t const *const vram = (uint8_t *)&m_vram[0]; for (int y = 0; y < 900; y++) { - uint32_t *scanline = &bitmap.pix32(y); + uint32_t *scanline = &bitmap.pix(y); for (int x = 0; x < 1152; x++) { const uint8_t pixel = vram[y * 1152 + BYTE4_XOR_BE(x)]; diff --git a/src/devices/bus/scsi/omti5100.cpp b/src/devices/bus/scsi/omti5100.cpp index 519aa723a0b..f095dd2b191 100644 --- a/src/devices/bus/scsi/omti5100.cpp +++ b/src/devices/bus/scsi/omti5100.cpp @@ -15,7 +15,7 @@ DEFINE_DEVICE_TYPE(OMTI5100, omti5100_device, "omti5100", "OMTI 5100") #if 0 ROM_START( omti5100 ) ROM_REGION(0x1000, "mcu", 0) // Hitachi Z8 - ROM_LOAD("100240-N.7a", 0x0000, 0x1000, CRC(d227d6cb) SHA1(3d6140764d3d043428c941826370ebf1597c63bd)) + ROM_LOAD("100240-n.7a", 0x0000, 0x1000, CRC(d227d6cb) SHA1(3d6140764d3d043428c941826370ebf1597c63bd)) ROM_END const tiny_rom_entry *omti5100_device::device_rom_region() const diff --git a/src/devices/bus/svi3x8/slot/sv806.cpp b/src/devices/bus/svi3x8/slot/sv806.cpp index bc4dafbd415..5a7d858d38b 100644 --- a/src/devices/bus/svi3x8/slot/sv806.cpp +++ b/src/devices/bus/svi3x8/slot/sv806.cpp @@ -94,7 +94,7 @@ void sv806_device::device_start() MC6845_UPDATE_ROW( sv806_device::crtc_update_row ) { - const pen_t *pen = m_palette->pens(); + pen_t const *const pen = m_palette->pens(); for (int i = 0; i < x_count; i++) { @@ -103,14 +103,14 @@ MC6845_UPDATE_ROW( sv806_device::crtc_update_row ) if (i == cursor_x) data = 0xff; - bitmap.pix32(y, i * 8 + 0) = pen[BIT(data, 7)]; - bitmap.pix32(y, i * 8 + 1) = pen[BIT(data, 6)]; - bitmap.pix32(y, i * 8 + 2) = pen[BIT(data, 5)]; - bitmap.pix32(y, i * 8 + 3) = pen[BIT(data, 4)]; - bitmap.pix32(y, i * 8 + 4) = pen[BIT(data, 3)]; - bitmap.pix32(y, i * 8 + 5) = pen[BIT(data, 2)]; - bitmap.pix32(y, i * 8 + 6) = pen[BIT(data, 1)]; - bitmap.pix32(y, i * 8 + 7) = pen[BIT(data, 0)]; + bitmap.pix(y, i * 8 + 0) = pen[BIT(data, 7)]; + bitmap.pix(y, i * 8 + 1) = pen[BIT(data, 6)]; + bitmap.pix(y, i * 8 + 2) = pen[BIT(data, 5)]; + bitmap.pix(y, i * 8 + 3) = pen[BIT(data, 4)]; + bitmap.pix(y, i * 8 + 4) = pen[BIT(data, 3)]; + bitmap.pix(y, i * 8 + 5) = pen[BIT(data, 2)]; + bitmap.pix(y, i * 8 + 6) = pen[BIT(data, 1)]; + bitmap.pix(y, i * 8 + 7) = pen[BIT(data, 0)]; } } diff --git a/src/devices/bus/tanbus/mpvdu.cpp b/src/devices/bus/tanbus/mpvdu.cpp index e9f4fe766eb..28cd0b988f9 100644 --- a/src/devices/bus/tanbus/mpvdu.cpp +++ b/src/devices/bus/tanbus/mpvdu.cpp @@ -149,7 +149,7 @@ uint8_t tanbus_mpvdu_device::videoram_r(offs_t offset) MC6845_UPDATE_ROW(tanbus_mpvdu_device::crtc_update_row) { - uint32_t *p = &bitmap.pix32(y); + uint32_t *p = &bitmap.pix(y); m_trom->lose_w(1); m_trom->lose_w(0); @@ -165,11 +165,11 @@ MC6845_UPDATE_ROW(tanbus_mpvdu_device::crtc_update_row) m_trom->tr6_w(1); m_trom->tr6_w(0); - int col = m_trom->get_rgb() ^ ((column == cursor_x) ? 7 : 0); + int const col = m_trom->get_rgb() ^ ((column == cursor_x) ? 7 : 0); - int r = BIT(col, 0) * 0xff; - int g = BIT(col, 1) * 0xff; - int b = BIT(col, 2) * 0xff; + int const r = BIT(col, 0) * 0xff; + int const g = BIT(col, 1) * 0xff; + int const b = BIT(col, 2) * 0xff; *p++ = rgb_t(r, g, b); } diff --git a/src/devices/bus/tanbus/ravdu.cpp b/src/devices/bus/tanbus/ravdu.cpp index 80664797081..b93b1a41c35 100644 --- a/src/devices/bus/tanbus/ravdu.cpp +++ b/src/devices/bus/tanbus/ravdu.cpp @@ -161,7 +161,7 @@ uint8_t tanbus_ravdu_device::videoram_r(offs_t offset) MC6845_UPDATE_ROW(tanbus_ravdu_device::crtc_update_row) { - uint32_t *p = &bitmap.pix32(y); + uint32_t *p = &bitmap.pix(y); m_trom->lose_w(1); m_trom->lose_w(0); @@ -178,11 +178,11 @@ MC6845_UPDATE_ROW(tanbus_ravdu_device::crtc_update_row) m_trom->tr6_w(1); m_trom->tr6_w(0); - int col = m_trom->get_rgb() ^ ((column == cursor_x) ? 7 : 0); + int const col = m_trom->get_rgb() ^ ((column == cursor_x) ? 7 : 0); - int r = BIT(col, 0) * 0xff; - int g = BIT(col, 1) * 0xff; - int b = BIT(col, 2) * 0xff; + int const r = BIT(col, 0) * 0xff; + int const g = BIT(col, 1) * 0xff; + int const b = BIT(col, 2) * 0xff; *p++ = rgb_t(r, g, b); } diff --git a/src/devices/bus/tanbus/tanhrg.cpp b/src/devices/bus/tanbus/tanhrg.cpp index 1c8ffc87ab5..b857e84ac69 100644 --- a/src/devices/bus/tanbus/tanhrg.cpp +++ b/src/devices/bus/tanbus/tanhrg.cpp @@ -323,16 +323,13 @@ void tanbus_tanhrgc_device::set_inhibit_lines(offs_t offset, int &inhram, int &i uint32_t tanbus_tanhrg_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - uint16_t offset; - uint32_t *p; - for (int y = 0; y < 256; y++) { - p = &bitmap.pix32(y); + uint32_t *p = &bitmap.pix(y); for (int x = 0; x < 256; x++) { - offset = (y * 32) + (x / 8); + uint16_t const offset = (y * 32) + (x / 8); *p++ = m_palette->pen_color(BIT(m_videoram[offset], x & 7)); } @@ -344,21 +341,17 @@ uint32_t tanbus_tanhrg_device::screen_update(screen_device &screen, bitmap_rgb32 uint32_t tanbus_tanhrgc_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - uint8_t r, g, b; - uint16_t offset; - uint32_t *p; - for (int y = 0; y < 256; y++) { - p = &bitmap.pix32(y); + uint32_t *p = &bitmap.pix(y); for (int x = 0; x < 256; x++) { - offset = (y * 32) + (x / 8); + uint16_t const offset = (y * 32) + (x / 8); - r = m_videoram[0x0000 | offset]; - b = m_videoram[0x2000 | offset]; - g = m_videoram[0x4000 | offset]; + uint8_t const r = m_videoram[0x0000 | offset]; + uint8_t const b = m_videoram[0x2000 | offset]; + uint8_t const g = m_videoram[0x4000 | offset]; *p++ = m_palette->pen_color(BIT(b, x & 7) << 2 | BIT(g, x & 7) << 1 | BIT(r, x & 7)); } diff --git a/src/devices/bus/tanbus/tug8082.cpp b/src/devices/bus/tanbus/tug8082.cpp index 1e4ad1a4504..582ab726c8e 100644 --- a/src/devices/bus/tanbus/tug8082.cpp +++ b/src/devices/bus/tanbus/tug8082.cpp @@ -241,18 +241,14 @@ WRITE_LINE_MEMBER(tanbus_tug8082_device::vdu_irq_w) uint32_t tanbus_tug8082_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - uint32_t *scanline; - int x, y; - uint8_t pixels; + pen_t const *const pen = m_palette->pens(); - const pen_t *pen = m_palette->pens(); - - for (y = 0; y < 256; y++) + for (int y = 0; y < 256; y++) { - scanline = &bitmap.pix32(y); - for (x = 0; x < 64; x++) + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < 64; x++) { - pixels = m_videoram[(y * 64) + x]; + uint8_t const pixels = m_videoram[(y * 64) + x]; for (int i = 0; i < 8; ++i) *scanline++ = pen[BIT(pixels, 7 - i)]; diff --git a/src/devices/bus/ti99/gromport/cartridges.cpp b/src/devices/bus/ti99/gromport/cartridges.cpp index 6b2da977a2a..c703d331bf9 100644 --- a/src/devices/bus/ti99/gromport/cartridges.cpp +++ b/src/devices/bus/ti99/gromport/cartridges.cpp @@ -1558,13 +1558,13 @@ void ti99_cartridge_device::rpk::close() not a network socket) ***************************************************************/ -ti99_cartridge_device::rpk_socket::rpk_socket(const char* id, int length, uint8_t* contents, std::string &&pathname) - : m_id(id), m_length(length), m_contents(contents), m_pathname(std::move(pathname)) +ti99_cartridge_device::rpk_socket::rpk_socket(const char* id, int length, std::unique_ptr<uint8_t []> &&contents, std::string &&pathname) + : m_id(id), m_length(length), m_contents(std::move(contents)), m_pathname(std::move(pathname)) { } -ti99_cartridge_device::rpk_socket::rpk_socket(const char* id, int length, uint8_t* contents) - : rpk_socket(id, length, contents, "") +ti99_cartridge_device::rpk_socket::rpk_socket(const char* id, int length, std::unique_ptr<uint8_t []> &&contents) + : rpk_socket(id, length, std::move(contents), "") { } @@ -1609,7 +1609,7 @@ std::unique_ptr<ti99_cartridge_device::rpk_socket> ti99_cartridge_device::rpk_re util::archive_file::error ziperr; uint32_t crc; int length; - uint8_t* contents; + std::unique_ptr<uint8_t []> contents; int header; // find the file attribute (required) @@ -1635,11 +1635,11 @@ std::unique_ptr<ti99_cartridge_device::rpk_socket> ti99_cartridge_device::rpk_re length = zip.current_uncompressed_length(); // Allocate storage - contents = global_alloc_array_clear<uint8_t>(length); - if (contents==nullptr) throw rpk_exception(RPK_OUT_OF_MEMORY); + try { contents = make_unique_clear<uint8_t []>(length); } + catch (std::bad_alloc const &) { throw rpk_exception(RPK_OUT_OF_MEMORY); } // and unzip file from the zip file - ziperr = zip.decompress(contents, length); + ziperr = zip.decompress(contents.get(), length); if (ziperr != util::archive_file::error::NONE) { if (ziperr == util::archive_file::error::UNSUPPORTED) throw rpk_exception(RPK_ZIP_UNSUPPORTED); @@ -1651,7 +1651,7 @@ std::unique_ptr<ti99_cartridge_device::rpk_socket> ti99_cartridge_device::rpk_re if (sha1 != nullptr) { util::hash_collection actual_hashes; - actual_hashes.compute((const uint8_t *)contents, length, util::hash_collection::HASH_TYPES_CRC_SHA1); + actual_hashes.compute(contents.get(), length, util::hash_collection::HASH_TYPES_CRC_SHA1); util::hash_collection expected_hashes; expected_hashes.add_from_string(util::hash_collection::HASH_SHA1, sha1, strlen(sha1)); @@ -1660,7 +1660,7 @@ std::unique_ptr<ti99_cartridge_device::rpk_socket> ti99_cartridge_device::rpk_re } // Create a socket instance - return std::make_unique<rpk_socket>(socketname, length, contents); + return std::make_unique<rpk_socket>(socketname, length, std::move(contents)); } /* @@ -1673,7 +1673,7 @@ std::unique_ptr<ti99_cartridge_device::rpk_socket> ti99_cartridge_device::rpk_re const char* ram_filename; std::string ram_pname; unsigned int length; - uint8_t* contents; + std::unique_ptr<uint8_t []> contents; // find the length attribute length_string = ram_resource_node->get_attribute_string("length", nullptr); @@ -1701,8 +1701,8 @@ std::unique_ptr<ti99_cartridge_device::rpk_socket> ti99_cartridge_device::rpk_re } // Allocate memory for this resource - contents = global_alloc_array_clear<uint8_t>(length); - if (contents==nullptr) throw rpk_exception(RPK_OUT_OF_MEMORY); + try { contents = make_unique_clear<uint8_t []>(length); } + catch (std::bad_alloc const &) { throw rpk_exception(RPK_OUT_OF_MEMORY); } LOGMASKED(LOG_RPK, "[RPK handler] Allocating RAM buffer (%d bytes) for socket '%s'\n", length, socketname); @@ -1717,10 +1717,8 @@ std::unique_ptr<ti99_cartridge_device::rpk_socket> ti99_cartridge_device::rpk_re // Get the file name (required if persistent) ram_filename = ram_resource_node->get_attribute_string("file", nullptr); if (ram_filename==nullptr) - { - global_free_array(contents); throw rpk_exception(RPK_INVALID_RAM_SPEC, "<ram type='persistent'> must have a 'file' attribute"); - } + ram_pname = std::string(system_name).append(PATH_SEPARATOR).append(ram_filename); // load, and fill rest with 00 LOGMASKED(LOG_RPK, "[RPK handler] Loading NVRAM contents from '%s'\n", ram_pname.c_str()); @@ -1734,15 +1732,15 @@ std::unique_ptr<ti99_cartridge_device::rpk_socket> ti99_cartridge_device::rpk_re osd_file::error filerr = file.open(ram_pname); int bytes_read = 0; if (filerr == osd_file::error::NONE) - bytes_read = file.read(contents, length); + bytes_read = file.read(contents.get(), length); // fill remaining bytes (if necessary) - memset(((char *) contents) + bytes_read, 0x00, length - bytes_read); + std::fill_n(&contents[bytes_read], length - bytes_read, 0x00); } } // Create a socket instance - return std::make_unique<rpk_socket>(socketname, length, contents, std::move(ram_pname)); + return std::make_unique<rpk_socket>(socketname, length, std::move(contents), std::move(ram_pname)); } /*------------------------------------------------- diff --git a/src/devices/bus/ti99/gromport/cartridges.h b/src/devices/bus/ti99/gromport/cartridges.h index b494ad7e28d..f6e2e991d56 100644 --- a/src/devices/bus/ti99/gromport/cartridges.h +++ b/src/devices/bus/ti99/gromport/cartridges.h @@ -170,21 +170,21 @@ private: class rpk_socket { public: - rpk_socket(const char *id, int length, uint8_t *contents); - rpk_socket(const char *id, int length, uint8_t *contents, std::string &&pathname); + rpk_socket(const char *id, int length, std::unique_ptr<uint8_t []> &&contents); + rpk_socket(const char *id, int length, std::unique_ptr<uint8_t []> &&contents, std::string &&pathname); ~rpk_socket() {} const char* id() { return m_id; } int get_content_length() { return m_length; } - uint8_t* get_contents() { return m_contents; } + uint8_t* get_contents() { return m_contents.get(); } bool persistent_ram() { return !m_pathname.empty(); } const char* get_pathname() { return m_pathname.c_str(); } - void cleanup() { if (m_contents != nullptr) global_free_array(m_contents); } + void cleanup() { m_contents.reset(); } private: const char* m_id; uint32_t m_length; - uint8_t* m_contents; + std::unique_ptr<uint8_t []> m_contents; const std::string m_pathname; }; diff --git a/src/devices/bus/ti99/internal/992board.cpp b/src/devices/bus/ti99/internal/992board.cpp index 031f82d7fe5..2f01c025cb6 100644 --- a/src/devices/bus/ti99/internal/992board.cpp +++ b/src/devices/bus/ti99/internal/992board.cpp @@ -202,7 +202,7 @@ void video992_device::device_timer(emu_timer &timer, device_timer_id id, int par } int vpos = raw_vpos * m_vertical_size / screen().height(); - uint32_t *p = &m_tmpbmp.pix32(vpos); + uint32_t *p = &m_tmpbmp.pix(vpos); bool endofline = false; int linelength = 0; diff --git a/src/devices/bus/ti99/peb/horizon.cpp b/src/devices/bus/ti99/peb/horizon.cpp index 6da8483a046..8d9aa8dd20a 100644 --- a/src/devices/bus/ti99/peb/horizon.cpp +++ b/src/devices/bus/ti99/peb/horizon.cpp @@ -121,24 +121,22 @@ void horizon_ramdisk_device::nvram_read(emu_file &file) int size = 2097152*(1 << ioport("HORIZONSIZE")->read()); // NVRAM plus ROS - uint8_t* buffer = global_alloc_array_clear<uint8_t>(MAXSIZE + ROSSIZE); + auto buffer = make_unique_clear<uint8_t []>(MAXSIZE + ROSSIZE); memset(m_nvram->pointer(), 0, size); memset(m_ros->pointer(), 0, ROSSIZE); // We assume the last 8K is ROS - int filesize = file.read(buffer, MAXSIZE+ROSSIZE); + int filesize = file.read(&buffer[0], MAXSIZE+ROSSIZE); int nvramsize = filesize - ROSSIZE; // If there is a reasonable size if (nvramsize >= 0) { // Copy from buffer to NVRAM and ROS - memcpy(m_nvram->pointer(), buffer, nvramsize); - memcpy(m_ros->pointer(), buffer + nvramsize, ROSSIZE); + memcpy(m_nvram->pointer(), &buffer[0], nvramsize); + memcpy(m_ros->pointer(), &buffer[nvramsize], ROSSIZE); } - - global_free_array(buffer); } //------------------------------------------------- @@ -150,11 +148,11 @@ void horizon_ramdisk_device::nvram_write(emu_file &file) { int nvramsize = 2097152*(1 << ioport("HORIZONSIZE")->read()); - uint8_t* buffer = global_alloc_array_clear<uint8_t>(nvramsize + ROSSIZE); - memcpy(buffer, m_nvram->pointer(), nvramsize); - memcpy(buffer + nvramsize, m_ros->pointer(), ROSSIZE); + auto buffer = make_unique_clear<uint8_t []>(nvramsize + ROSSIZE); + memcpy(&buffer[0], m_nvram->pointer(), nvramsize); + memcpy(&buffer[nvramsize], m_ros->pointer(), ROSSIZE); - file.write(buffer, nvramsize + ROSSIZE); + file.write(buffer.get(), nvramsize + ROSSIZE); } void horizon_ramdisk_device::readz(offs_t offset, uint8_t *value) diff --git a/src/devices/bus/vic20/videopak.cpp b/src/devices/bus/vic20/videopak.cpp index 187224721be..1f2b3c35431 100644 --- a/src/devices/bus/vic20/videopak.cpp +++ b/src/devices/bus/vic20/videopak.cpp @@ -77,7 +77,7 @@ MC6845_UPDATE_ROW( vic20_video_pak_device::crtc_update_row ) int x = (column * 8) + bit; int color = BIT(data, 7) && de; - bitmap.pix32(vbp + y, hbp + x) = pen[color]; + bitmap.pix(vbp + y, hbp + x) = pen[color]; data <<= 1; } diff --git a/src/devices/bus/vsmile/mat.cpp b/src/devices/bus/vsmile/mat.cpp new file mode 100644 index 00000000000..6dfeac5be98 --- /dev/null +++ b/src/devices/bus/vsmile/mat.cpp @@ -0,0 +1,198 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz, Vas Crabb + +#include "emu.h" +#include "mat.h" + +#include <algorithm> + +//#define VERBOSE 1 +#include "logmacro.h" + + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +DEFINE_DEVICE_TYPE(VSMILE_MAT, vsmile_mat_device, "vsmile_mat", "V.Smile Gym Mat") + + +//************************************************************************** +// V.Smile gym mat +//************************************************************************** + +vsmile_mat_device::vsmile_mat_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock) + : vsmile_pad_device(mconfig, VSMILE_MAT, tag, owner, clock) + , m_io_joy(*this, "JOY") + , m_io_colors(*this, "COLORS") + , m_io_buttons(*this, "BUTTONS") +{ +} + +vsmile_mat_device::~vsmile_mat_device() +{ +} + +void vsmile_mat_device::tx_complete() +{ + // update "joystick"-mapped mat pads + if ((m_stale & STALE_JOY) != STALE_NONE) + { + m_sent_joy = m_io_joy->read(); + if ((m_stale & STALE_YELLOW_RIGHT) != STALE_NONE) + { + if (BIT(m_sent_joy, 0)) + uart_tx_fifo_push(0xcb); // yellow + else if (BIT(m_sent_joy, 1)) + uart_tx_fifo_push(0xcd); // right + else + uart_tx_fifo_push(0xc0); + } + if ((m_stale & STALE_RED_LEFT) != STALE_NONE) + { + if (BIT(m_sent_joy, 2)) + uart_tx_fifo_push(0x8b); // red + else if (BIT(m_sent_joy, 3)) + uart_tx_fifo_push(0x8d); // left + else + uart_tx_fifo_push(0x80); + } + } + + // update "color"-mapped mat pads + if ((m_stale & STALE_COLORS) != STALE_NONE) + { + m_sent_colors = m_io_colors->read(); + uart_tx_fifo_push(0x90 | m_sent_colors); + } + + // update "button"-mapped mat pads + if ((m_stale & STALE_BUTTONS) != STALE_NONE) + { + m_sent_buttons = m_io_buttons->read(); + if (((m_stale & STALE_OK) != STALE_NONE) && BIT(m_sent_buttons, 0)) + uart_tx_fifo_push(0xa1); + if (((m_stale & STALE_QUIT) != STALE_NONE) && BIT(m_sent_buttons, 1)) + uart_tx_fifo_push(0xa2); + if (((m_stale & STALE_HELP) != STALE_NONE) && BIT(m_sent_buttons, 2)) + uart_tx_fifo_push(0xa3); + if (((m_stale & STALE_BLUE) != STALE_NONE) && BIT(m_sent_buttons, 3)) + uart_tx_fifo_push(0xa4); + if (!m_sent_buttons) + uart_tx_fifo_push(0xa0); + } + + // if nothing happens in the next second we'll queue a keep-alive + if (!m_active) + LOG("entered active state\n"); + m_idle_timer->adjust(attotime::from_seconds(1)); + m_active = true; + m_stale = STALE_NONE; +} + +INPUT_CHANGED_MEMBER(vsmile_mat_device::mat_joy_changed) +{ + if (m_active) + { + if (!is_tx_empty()) + { + LOG("joy changed while transmission in progress, marking stale\n"); + m_stale |= stale_mat_inputs(param); + } + else + { + uint8_t const joy = m_io_joy->read(); + if ((joy ^ m_sent_joy) & 0x03) + { + if (BIT(joy, 0)) + uart_tx_fifo_push(0xcb); // yellow + else if (BIT(joy, 1)) + uart_tx_fifo_push(0xcd); // right + else + uart_tx_fifo_push(0xc0); + } + if ((joy ^ m_sent_joy) & 0x0c) + { + if (BIT(joy, 2)) + uart_tx_fifo_push(0x8b); // red + else if (BIT(joy, 3)) + uart_tx_fifo_push(0x8d); // left + else + uart_tx_fifo_push(0x80); + } + m_sent_joy = joy; + } + } +} + +INPUT_CHANGED_MEMBER(vsmile_mat_device::mat_color_changed) +{ + if (m_active) + { + if (!is_tx_empty()) + { + LOG("colors changed while transmission in progress, marking stale\n"); + m_stale |= STALE_COLORS; + } + else + { + m_sent_colors = m_io_colors->read(); + uart_tx_fifo_push(0x90 | m_sent_colors); + } + } +} + +INPUT_CHANGED_MEMBER(vsmile_mat_device::mat_button_changed) +{ + if (m_active) + { + if (!is_tx_empty()) + { + LOG("buttons changed while transmission in progress, marking stale\n"); + m_stale |= stale_mat_inputs(param); + } + else + { + uint8_t const buttons = m_io_buttons->read(); + if (BIT((m_sent_buttons ^ buttons) & buttons, 0)) + uart_tx_fifo_push(0xa1); + if (BIT((m_sent_buttons ^ buttons) & buttons, 1)) + uart_tx_fifo_push(0xa2); + if (BIT((m_sent_buttons ^ buttons) & buttons, 2)) + uart_tx_fifo_push(0xa3); + if (BIT((m_sent_buttons ^ buttons) & buttons, 3)) + uart_tx_fifo_push(0xa4); + if (!buttons) + uart_tx_fifo_push(0xa0); + m_sent_buttons = buttons; + } + } +} + +static INPUT_PORTS_START( vsmile_mat ) + PORT_START("JOY") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_CODE(KEYCODE_9_PAD) PORT_CODE(JOYCODE_BUTTON1) PORT_CHANGED_MEMBER(DEVICE_SELF, vsmile_mat_device, mat_joy_changed, vsmile_mat_device::STALE_YELLOW_RIGHT) PORT_NAME("Yellow") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_CODE(KEYCODE_6_PAD) PORT_CODE(JOYCODE_BUTTON2) PORT_CHANGED_MEMBER(DEVICE_SELF, vsmile_mat_device, mat_joy_changed, vsmile_mat_device::STALE_YELLOW_RIGHT) PORT_NAME("Right") + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_CODE(KEYCODE_7_PAD) PORT_CODE(JOYCODE_BUTTON3) PORT_CHANGED_MEMBER(DEVICE_SELF, vsmile_mat_device, mat_joy_changed, vsmile_mat_device::STALE_RED_LEFT) PORT_NAME("Red") + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_CODE(KEYCODE_4_PAD) PORT_CODE(JOYCODE_BUTTON4) PORT_CHANGED_MEMBER(DEVICE_SELF, vsmile_mat_device, mat_joy_changed, vsmile_mat_device::STALE_RED_LEFT) PORT_NAME("Left") + PORT_BIT( 0xf0, IP_ACTIVE_HIGH, IPT_UNUSED ) + + PORT_START("COLORS") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_CODE(KEYCODE_5_PAD) PORT_CODE(JOYCODE_BUTTON5) PORT_CHANGED_MEMBER(DEVICE_SELF, vsmile_mat_device, mat_color_changed, vsmile_mat_device::STALE_COLORS) PORT_NAME("Center") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON6 ) PORT_CODE(KEYCODE_8_PAD) PORT_CODE(JOYCODE_BUTTON6) PORT_CHANGED_MEMBER(DEVICE_SELF, vsmile_mat_device, mat_color_changed, vsmile_mat_device::STALE_COLORS) PORT_NAME("Up") + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON7 ) PORT_CODE(KEYCODE_2_PAD) PORT_CODE(JOYCODE_BUTTON7) PORT_CHANGED_MEMBER(DEVICE_SELF, vsmile_mat_device, mat_color_changed, vsmile_mat_device::STALE_COLORS) PORT_NAME("Down") + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON8 ) PORT_CODE(KEYCODE_3_PAD) PORT_CODE(JOYCODE_BUTTON8) PORT_CHANGED_MEMBER(DEVICE_SELF, vsmile_mat_device, mat_color_changed, vsmile_mat_device::STALE_COLORS) PORT_NAME("Green") + PORT_BIT( 0xf0, IP_ACTIVE_HIGH, IPT_UNUSED ) + + PORT_START("BUTTONS") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON9 ) PORT_CODE(KEYCODE_ENTER_PAD) PORT_CODE(JOYCODE_BUTTON9) PORT_CHANGED_MEMBER(DEVICE_SELF, vsmile_mat_device, mat_button_changed, vsmile_mat_device::STALE_OK) PORT_NAME("OK") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON10 ) PORT_CODE(KEYCODE_0_PAD) PORT_CODE(JOYCODE_BUTTON10) PORT_CHANGED_MEMBER(DEVICE_SELF, vsmile_mat_device, mat_button_changed, vsmile_mat_device::STALE_QUIT) PORT_NAME("Quit") + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON11 ) PORT_CODE(KEYCODE_MINUS_PAD) PORT_CODE(JOYCODE_BUTTON11) PORT_CHANGED_MEMBER(DEVICE_SELF, vsmile_mat_device, mat_button_changed, vsmile_mat_device::STALE_HELP) PORT_NAME("Help") + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON12 ) PORT_CODE(KEYCODE_1_PAD) PORT_CODE(JOYCODE_BUTTON12) PORT_CHANGED_MEMBER(DEVICE_SELF, vsmile_mat_device, mat_button_changed, vsmile_mat_device::STALE_BLUE) PORT_NAME("Blue") + PORT_BIT( 0xf0, IP_ACTIVE_HIGH, IPT_UNUSED ) +INPUT_PORTS_END + +ioport_constructor vsmile_mat_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( vsmile_mat ); +} diff --git a/src/devices/bus/vsmile/mat.h b/src/devices/bus/vsmile/mat.h new file mode 100644 index 00000000000..e184b6b3d25 --- /dev/null +++ b/src/devices/bus/vsmile/mat.h @@ -0,0 +1,69 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz, Vas Crabb +#ifndef MAME_BUS_VSMILE_MAT_H +#define MAME_BUS_VSMILE_MAT_H + +#pragma once + +#include "pad.h" + +/*************************************************************************** + TYPE DEFINITIONS + ***************************************************************************/ + +// ======================> vsmile_mat_device + +class vsmile_mat_device : public vsmile_pad_device +{ +public: + // construction/destruction + vsmile_mat_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock = 0U); + virtual ~vsmile_mat_device(); + + // input handlers + DECLARE_INPUT_CHANGED_MEMBER(mat_joy_changed); + DECLARE_INPUT_CHANGED_MEMBER(mat_color_changed); + DECLARE_INPUT_CHANGED_MEMBER(mat_button_changed); + + enum stale_mat_inputs : uint16_t + { + STALE_NONE = 0U, + STALE_YELLOW_RIGHT = 1U << 0, + STALE_RED_LEFT = 1U << 1, + STALE_CENTER = 1U << 2, + STALE_UP = 1U << 3, + STALE_DOWN = 1U << 4, + STALE_GREEN = 1U << 5, + STALE_OK = 1U << 6, + STALE_QUIT = 1U << 7, + STALE_HELP = 1U << 8, + STALE_BLUE = 1U << 9, + + STALE_JOY = STALE_YELLOW_RIGHT | STALE_RED_LEFT, + STALE_COLORS = STALE_CENTER | STALE_UP | STALE_DOWN | STALE_GREEN, + STALE_BUTTONS = STALE_OK | STALE_QUIT | STALE_HELP | STALE_BLUE, + STALE_ALL = STALE_JOY | STALE_COLORS | STALE_BUTTONS + }; + +protected: + // device_t implementation + virtual ioport_constructor device_input_ports() const override; + + // vsmile_pad_device implementation + virtual void tx_complete() override; + virtual uint16_t stale_all() override { return STALE_ALL; } + +private: + required_ioport m_io_joy; + required_ioport m_io_colors; + required_ioport m_io_buttons; +}; + + +/*************************************************************************** + DEVICE TYPES + ***************************************************************************/ + +DECLARE_DEVICE_TYPE(VSMILE_MAT, vsmile_mat_device) + +#endif // MAME_BUS_VSMILE_MAT_H diff --git a/src/devices/bus/vsmile/pad.cpp b/src/devices/bus/vsmile/pad.cpp index 94c7decdaa9..5cf7940ab39 100644 --- a/src/devices/bus/vsmile/pad.cpp +++ b/src/devices/bus/vsmile/pad.cpp @@ -21,22 +21,24 @@ DEFINE_DEVICE_TYPE(VSMILE_PAD, vsmile_pad_device, "vsmile_pad", "V.Smile Joystic // V.Smile control pad //************************************************************************** -DECLARE_ENUM_BITWISE_OPERATORS(vsmile_pad_device::stale_inputs) -ALLOW_SAVE_TYPE(vsmile_pad_device::stale_inputs); - vsmile_pad_device::vsmile_pad_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock) - : vsmile_ctrl_device_base(mconfig, VSMILE_PAD, tag, owner, clock) + : vsmile_pad_device(mconfig, VSMILE_PAD, tag, owner, clock) +{ +} + +vsmile_pad_device::vsmile_pad_device(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, uint32_t clock) + : vsmile_ctrl_device_base(mconfig, type, tag, owner, clock) , m_io_joy(*this, "JOY") , m_io_colors(*this, "COLORS") , m_io_buttons(*this, "BUTTONS") - , m_idle_timer(nullptr) - , m_sent_joy(0x00U) - , m_sent_colors(0x00U) - , m_sent_buttons(0x00U) - , m_stale(STALE_ALL) + , m_sent_joy(0x0000U) + , m_sent_colors(0x0000U) + , m_sent_buttons(0x0000U) , m_active(false) + , m_idle_timer(nullptr) { std::fill(std::begin(m_ctrl_probe_history), std::end(m_ctrl_probe_history), 0U); + m_stale = stale_all(); } vsmile_pad_device::~vsmile_pad_device() @@ -51,10 +53,10 @@ void vsmile_pad_device::device_start() timer_expired_delegate(FUNC(vsmile_pad_device::handle_idle), this)); m_idle_timer->adjust(attotime::from_seconds(1)); - m_sent_joy = 0x00U; - m_sent_colors = 0x00U; - m_sent_buttons = 0x00U; - m_stale = STALE_ALL; + m_sent_joy = 0x0000U; + m_sent_colors = 0x0000U; + m_sent_buttons = 0x0000U; + m_stale = stale_all(); m_active = false; save_item(NAME(m_sent_joy)); @@ -128,7 +130,7 @@ void vsmile_pad_device::tx_timeout() { m_idle_timer->reset(); m_active = false; - m_stale = STALE_ALL; + m_stale = stale_all(); std::fill(std::begin(m_ctrl_probe_history), std::end(m_ctrl_probe_history), 0U); LOG("left active state\n"); } @@ -174,7 +176,7 @@ INPUT_CHANGED_MEMBER(vsmile_pad_device::pad_joy_changed) if (!is_tx_empty()) { LOG("joy changed while transmission in progress, marking stale\n"); - m_stale |= stale_inputs(param); + m_stale |= stale_pad_inputs(param); } else { @@ -226,7 +228,7 @@ INPUT_CHANGED_MEMBER(vsmile_pad_device::pad_button_changed) if (!is_tx_empty()) { LOG("buttons changed while transmission in progress, marking stale\n"); - m_stale |= stale_inputs(param); + m_stale |= stale_pad_inputs(param); } else { diff --git a/src/devices/bus/vsmile/pad.h b/src/devices/bus/vsmile/pad.h index 5e2515c2b58..bdf896b7646 100644 --- a/src/devices/bus/vsmile/pad.h +++ b/src/devices/bus/vsmile/pad.h @@ -16,7 +16,16 @@ class vsmile_pad_device : public vsmile_ctrl_device_base { public: - enum stale_inputs : uint8_t + // construction/destruction + vsmile_pad_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock = 0U); + virtual ~vsmile_pad_device(); + + // input handlers + DECLARE_INPUT_CHANGED_MEMBER(pad_joy_changed); + DECLARE_INPUT_CHANGED_MEMBER(pad_color_changed); + DECLARE_INPUT_CHANGED_MEMBER(pad_button_changed); + + enum stale_pad_inputs : uint16_t { STALE_NONE = 0U, STALE_LEFT_RIGHT = 1U << 0, @@ -32,16 +41,9 @@ public: STALE_ALL = STALE_JOY | STALE_COLORS | STALE_BUTTONS }; - // construction/destruction - vsmile_pad_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock = 0U); - virtual ~vsmile_pad_device(); - - // input handlers - DECLARE_INPUT_CHANGED_MEMBER(pad_joy_changed); - DECLARE_INPUT_CHANGED_MEMBER(pad_color_changed); - DECLARE_INPUT_CHANGED_MEMBER(pad_button_changed); - protected: + vsmile_pad_device(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, uint32_t clock = 0U); + // device_t implementation virtual ioport_constructor device_input_ports() const override; virtual void device_start() override; @@ -50,21 +52,23 @@ protected: virtual void tx_complete() override; virtual void tx_timeout() override; virtual void rx_complete(uint8_t data, bool cts) override; + virtual uint16_t stale_all() { return STALE_ALL; } -private: void uart_tx_fifo_push(uint8_t data); - TIMER_CALLBACK_MEMBER(handle_idle); - required_ioport m_io_joy; required_ioport m_io_colors; required_ioport m_io_buttons; - emu_timer *m_idle_timer; + uint16_t m_sent_joy, m_sent_colors, m_sent_buttons; - uint8_t m_sent_joy, m_sent_colors, m_sent_buttons; - stale_inputs m_stale; + uint16_t m_stale; bool m_active; + emu_timer *m_idle_timer; + +private: + TIMER_CALLBACK_MEMBER(handle_idle); + uint8_t m_ctrl_probe_history[2]; }; diff --git a/src/devices/bus/vsmile/rom.cpp b/src/devices/bus/vsmile/rom.cpp index ca2780a2725..bc69099d698 100644 --- a/src/devices/bus/vsmile/rom.cpp +++ b/src/devices/bus/vsmile/rom.cpp @@ -52,7 +52,7 @@ void vsmile_rom_device::device_start() save_item(NAME(m_bank_offset)); } -void vsmile_rom_device::device_reset() +void vsmile_rom_device::device_resolve_objects() { m_bank_offset = 0; } diff --git a/src/devices/bus/vsmile/rom.h b/src/devices/bus/vsmile/rom.h index 617d1ad6ecd..b9ac8ef0b07 100644 --- a/src/devices/bus/vsmile/rom.h +++ b/src/devices/bus/vsmile/rom.h @@ -29,7 +29,7 @@ protected: // device-level overrides virtual void device_start() override; - virtual void device_reset() override; + virtual void device_resolve_objects() override; uint32_t m_bank_offset; }; diff --git a/src/devices/bus/vsmile/vsmile_ctrl.cpp b/src/devices/bus/vsmile/vsmile_ctrl.cpp index e3ae106bd3a..4b9d629aaaf 100644 --- a/src/devices/bus/vsmile/vsmile_ctrl.cpp +++ b/src/devices/bus/vsmile/vsmile_ctrl.cpp @@ -277,8 +277,10 @@ TIMER_CALLBACK_MEMBER(vsmile_ctrl_device_base::rts_timer_expired) #include "pad.h" +#include "mat.h" void vsmile_controllers(device_slot_interface &device) { device.option_add("joy", VSMILE_PAD); + device.option_add("mat", VSMILE_MAT); } diff --git a/src/devices/bus/wangpc/lvc.cpp b/src/devices/bus/wangpc/lvc.cpp index 4d31a7b9367..1fd3c0610d4 100644 --- a/src/devices/bus/wangpc/lvc.cpp +++ b/src/devices/bus/wangpc/lvc.cpp @@ -62,17 +62,17 @@ MC6845_UPDATE_ROW( wangpc_lvc_device::crtc_update_row ) { for (int column = 0; column < x_count; column++) { - offs_t addr = scroll_y + (m_scroll & 0x3f) + ((ma / 80) * 0x480) + (((ra & 0x0f) << 7) | (column & 0x7f)); + offs_t const addr = scroll_y + (m_scroll & 0x3f) + ((ma / 80) * 0x480) + (((ra & 0x0f) << 7) | (column & 0x7f)); uint16_t data = m_video_ram[addr & 0x7fff]; for (int bit = 0; bit < 8; bit++) { - int x = (column * 8) + bit; + int const x = (column * 8) + bit; int color = (BIT(data, 15) << 1) | BIT(data, 7); if (column == cursor_x) color = 0x03; - bitmap.pix32(vbp + y, hbp + x) = de ? m_palette[color] : rgb_t::black(); + bitmap.pix(vbp + y, hbp + x) = de ? m_palette[color] : rgb_t::black(); data <<= 1; } @@ -89,12 +89,12 @@ MC6845_UPDATE_ROW( wangpc_lvc_device::crtc_update_row ) for (int bit = 0; bit < 8; bit++) { - int x = (column * 8) + bit; + int const x = (column * 8) + bit; int color = (BIT(data, 31) << 3) | (BIT(data, 23) << 2) | (BIT(data, 15) << 1) | BIT(data, 7); if (column == cursor_x) color = 0x03; - bitmap.pix32(vbp + y, hbp + x) = de ? m_palette[color] : rgb_t::black(); + bitmap.pix(vbp + y, hbp + x) = de ? m_palette[color] : rgb_t::black(); data <<= 1; } diff --git a/src/devices/bus/wangpc/mvc.cpp b/src/devices/bus/wangpc/mvc.cpp index 562e277f982..cff515a05c1 100644 --- a/src/devices/bus/wangpc/mvc.cpp +++ b/src/devices/bus/wangpc/mvc.cpp @@ -73,15 +73,15 @@ MC6845_UPDATE_ROW( wangpc_mvc_device::crtc_update_row ) { for (int sx = 0; sx < 50; sx++) { - offs_t addr = (y * 50) + sx; + offs_t const addr = (y * 50) + sx; uint16_t data = m_bitmap_ram[addr]; for (int bit = 0; bit < 16; bit++) { - int x = (sx * 16) + bit; - int color = BIT(data, 15) && de; + int const x = (sx * 16) + bit; + int const color = BIT(data, 15) && de; - bitmap.pix32(vbp + y, hbp + x) = PALETTE_MVC[color]; + bitmap.pix(vbp + y, hbp + x) = PALETTE_MVC[color]; data <<= 1; } @@ -89,8 +89,8 @@ MC6845_UPDATE_ROW( wangpc_mvc_device::crtc_update_row ) for (int column = 0; column < x_count; column++) { - uint16_t code = m_video_ram[((ma + column) & 0x7ff)]; - uint8_t attr = code & 0xff; + uint16_t const code = m_video_ram[((ma + column) & 0x7ff)]; + uint8_t const attr = code & 0xff; uint8_t new_ra = ra + 1; @@ -103,7 +103,7 @@ MC6845_UPDATE_ROW( wangpc_mvc_device::crtc_update_row ) new_ra = ra; } - offs_t addr = ((code >> 8) << 4) | (new_ra & 0x0f); + offs_t const addr = ((code >> 8) << 4) | (new_ra & 0x0f); uint16_t data = m_char_ram[addr & 0xfff]; if ((column == cursor_x) || (!ra && ATTR_OVERSCORE) || ((ra == 9) && ATTR_UNDERSCORE)) @@ -113,11 +113,13 @@ MC6845_UPDATE_ROW( wangpc_mvc_device::crtc_update_row ) for (int bit = 0; bit < 10; bit++) { - int x = (column * 10) + bit; + int const x = (column * 10) + bit; int color = ((BIT(data, 9) & ~ATTR_BLANK) ^ ATTR_REVERSE); - if ((color | bitmap.pix32(vbp + y, hbp + x)) & ATTR_BOLD) color = 2; - if (color) bitmap.pix32(vbp + y, hbp + x) = de ? PALETTE_MVC[color] : rgb_t::black(); + if ((color | bitmap.pix(vbp + y, hbp + x)) & ATTR_BOLD) + color = 2; + if (color) + bitmap.pix(vbp + y, hbp + x) = de ? PALETTE_MVC[color] : rgb_t::black(); data <<= 1; } diff --git a/src/devices/cpu/bcp/dp8344.cpp b/src/devices/cpu/bcp/dp8344.cpp index fcc872855eb..b58599e3183 100644 --- a/src/devices/cpu/bcp/dp8344.cpp +++ b/src/devices/cpu/bcp/dp8344.cpp @@ -48,8 +48,8 @@ //************************************************************************** // device type definitions -DEFINE_DEVICE_TYPE(DP8344A, dp8344a_device, "dp8344a", "DP8344A BCP") -DEFINE_DEVICE_TYPE(DP8344B, dp8344b_device, "dp8344b", "DP8344B BCP") +DEFINE_DEVICE_TYPE(DP8344A, dp8344a_device, "dp8344a", "National Semiconductor DP8344A BCP") +DEFINE_DEVICE_TYPE(DP8344B, dp8344b_device, "dp8344b", "National Semiconductor DP8344B BCP") //************************************************************************** @@ -109,6 +109,7 @@ dp8344_device::dp8344_device(const machine_config &mconfig, device_type type, co , m_tfifo{0, 0, 0} , m_rfifo_head(0) , m_tfifo_head(0) + , m_receiver_interrupt(false) { } @@ -178,7 +179,7 @@ void dp8344_device::device_start() set_icountptr(m_icount); // debug state registration - state_add<u16>(BCP_PC, "PC", [this]() { return m_pc; }, [this](u16 data) { m_pc = m_ppc = data; prefetch_instruction(); }); + state_add(BCP_PC, "PC", m_pc, [this](u16 data) { m_pc = m_ppc = data; prefetch_instruction(); }); state_add(STATE_GENPC, "GENPC", m_pc).noshow(); state_add(STATE_GENPCBASE, "GENPCBASE", m_pc).noshow(); state_add(STATE_GENFLAGS, "GENFLAGS", m_ccr).formatstr("%09s").noshow(); @@ -257,6 +258,7 @@ void dp8344_device::device_start() save_item(NAME(m_tfifo)); // 3-frame Transmit FIFO save_item(NAME(m_rfifo_head)); save_item(NAME(m_tfifo_head)); + save_item(NAME(m_receiver_interrupt)); } @@ -338,7 +340,7 @@ std::unique_ptr<util::disasm_interface> dp8344_device::create_disassembler() void dp8344_device::set_receiver_interrupt(bool state) { - // TODO + m_receiver_interrupt = state; } @@ -545,8 +547,8 @@ void dp8344_device::set_device_control(u8 data) bool dp8344_device::interrupt_active() const { - // TODO: non-timer interrupts - return !BIT(m_icr, 4) && BIT(m_ccr, 7); + // TODO: non-receiver, non-timer interrupts + return (!BIT(m_icr, 0) && m_receiver_interrupt) || (!BIT(m_icr, 4) && BIT(m_ccr, 7)); } @@ -557,8 +559,11 @@ bool dp8344_device::interrupt_active() const u8 dp8344_device::get_interrupt_vector() const { - // TODO: non-timer interrupts - return 0x14; + // TODO: non-receiver, non-timer interrupts + if (!BIT(m_icr, 0) && m_receiver_interrupt) + return 0x04; + else + return 0x14; } @@ -592,8 +597,8 @@ bool dp8344_device::get_flag(unsigned f) const case 5: // Receiver Error return BIT(m_tsr, 5); - case 6: // Data Available - return BIT(m_tsr, 3); // FIXME: differs from numeric value! + case 6: // Data Available (differs from DAV bit in TSR) + return m_rfifo_head < 3; case 7: // Transmitter FIFO Full (or else Not Full) return BIT(m_tsr, 7); @@ -808,6 +813,19 @@ u8 dp8344_device::data_stack_pop() // TRANSCEIVER OPERATION //************************************************************************** +const char *const dp8344_device::s_protocol_names[8] = +{ + "IBM 3270", + "IBM 3299 Multiplexer", + "IBM 3299 Controller", + "IBM 3299 Repeater", + "IBM 5250", + "IBM 5250 Promiscuous", + "8-bit", + "8-bit Promiscuous" +}; + + //------------------------------------------------- // transceiver_reset - reset the receiver and // transmitter @@ -846,6 +864,30 @@ void dp8344_device::transceiver_reset() void dp8344_device::transmit_fifo_push(u8 data) { + // HACK: loopback data + if (BIT(m_tmr, 6)) + { + u16 frame = data | u16(m_tcr & 0x07) << 8; + if ((m_tmr & 0x07) == 0x00) + { + // Calculate odd parity on 3270 data frames + if (!BIT(m_tcr, 2)) + { + if ((population_count_32(data) & 1) == 0) + frame |= 0x100; + else + frame &= 0x2ff; + } + + // Calculate word parity + frame &= 0x3ff; + if ((population_count_32(frame) & 1) != BIT(m_tcr, 3)) + frame |= 0x400; + } + receive_fifo_push(frame); + return; + } + // Push OWP, TF10-8 and RTF7-0 onto transmit FIFO m_tfifo[0] = data | u16(m_tcr & 0x0f) << 8; @@ -926,14 +968,43 @@ void dp8344_device::receiver_active() //------------------------------------------------- -// receive_fifo_push - +// receive_fifo_push - push a data frame onto +// the receive FIFO //------------------------------------------------- -void dp8344_device::receive_fifo_push(u8 data) +void dp8344_device::receive_fifo_push(u16 data) { - // Overflow error if the receive FIFO is already full - if (BIT(m_ncf, 6)) + // Push word onto receive FIFO + m_rfifo[0] = data; + + if (m_rfifo_head != 0) + { + // Asynchronously propagate data through FIFO (actually takes 40 ns) + m_rfifo_head--; + for (int i = 0; i < m_rfifo_head; i++) + m_rfifo[i + 1] = m_rfifo[i]; + + // Set data available flag + m_tsr |= 0x08; + if ((m_icr & 0xc0) == 0x40) + set_receiver_interrupt(true); + + // Copy upper bits to TSR + m_tsr = (m_tsr & 0xf8) | (data & 0x700) >> 8; + + // Set flag when FIFO is full + if (m_rfifo_head == 0) + { + m_tsr |= 0x40; + if ((m_icr & 0xc0) == 0x00) + set_receiver_interrupt(true); + } + } + else + { + // Overflow error if the receive FIFO is already full set_receiver_error(0x10); + } } @@ -943,19 +1014,32 @@ void dp8344_device::receive_fifo_push(u8 data) u8 dp8344_device::receive_fifo_pop(bool test) { + u8 data = m_rfifo[m_rfifo_head < 3 ? m_rfifo_head : 2] & 0x0ff; + if (!test) { - // Clear Receive FIFO Full, DEME, Auto-Response and Poll/Acknowledge bits in NCF - m_ncf &= 0xb0; + if (m_rfifo_head < 3) + { + // Advance the FIFO + m_rfifo_head++; + + // Copy upper bits to TSR + if (m_rfifo_head < 3) + m_tsr = (m_tsr & 0xf8) | (m_rfifo[m_rfifo_head] & 0x700) >> 8; + } // Clear Data Available flag in TSR m_tsr &= 0xf7; - if ((m_icr & 0xc0) == 0xc0) + + // Clear Receive FIFO Full, DEME, Auto-Response and Poll/Acknowledge bits in NCF + m_ncf &= 0xb0; + + // Clear receiver interrupt unless error interrupt exists + if (BIT(m_icr, 7) || !BIT(m_tsr, 5)) set_receiver_interrupt(false); } - // TODO - return 0; + return data; } @@ -990,12 +1074,19 @@ u8 dp8344_device::get_error_code(bool test) { u8 code = m_ecr; + // Upper bits come from receive FIFO + code |= m_rfifo[m_rfifo_head < 3 ? m_rfifo_head : 2] & 0x0e0; + if (!test) { // Clear Error Code Register and Receiver Error flag in NCF m_ecr = 0x00; m_ncf &= 0xdf; + // Reassert DAV if FIFO is not empty + if (m_rfifo_head < 3) + m_tsr |= 0x08; + // Update interrupt status if RE interrupt selected switch (m_icr & 0xc0) { @@ -1049,40 +1140,8 @@ void dp8344_device::set_transceiver_mode(u8 data) if (!BIT(m_tmr, 6) && BIT(data, 6)) m_tx_act_cb(0); - switch (data & 0x07) - { - case 0: - logerror("%04X: Protocol Select: IBM 3270\n", m_ppc); - break; - - case 1: - logerror("%04X: Protocol Select: IBM 3299 Multiplexer\n", m_ppc); - break; - - case 2: - logerror("%04X: Protocol Select: IBM 3299 Controller\n", m_ppc); - break; - - case 3: - logerror("%04X: Protocol Select: IBM 3299 Repeater\n", m_ppc); - break; - - case 4: - logerror("%04X: Protocol Select: IBM 5250\n", m_ppc); - break; - - case 5: - logerror("%04X: Protocol Select: IBM 5250 Promiscuous\n", m_ppc); - break; - - case 6: - logerror("%04X: Protocol Select: 8-bit\n", m_ppc); - break; - - case 7: - logerror("%04X: Protocol Select: 8-bit Promiscuous\n", m_ppc); - break; - } + if ((m_tmr & 0x07) != (data & 0x07)) + logerror("%04X: Protocol Select: %s\n", m_ppc, s_protocol_names[data & 0x07]); m_tmr = data; } @@ -2064,6 +2123,10 @@ void dp8344_device::cmd_w(u8 data) BIT(data, 3) ? "latched" : BIT(data, 5) ? "fast buffered" : "slow buffered", BIT(data, 6) ? "single step" : BIT(data, 2) ? "start" : "stop"); + // Make sure not to restart in the middle of an instruction + if (!BIT(m_ric, 2) && BIT(data, 2)) + m_inst_state = T1_START; + m_ric = data; set_input_line(INPUT_LINE_HALT, BIT(data, 2) ? CLEAR_LINE : ASSERT_LINE); } @@ -2125,7 +2188,6 @@ u8 dp8344_device::remote_read(offs_t offset) void dp8344_device::remote_write(offs_t offset, u8 data) { // TODO: stop CPU if not accessing DMEM or RIC - switch (m_ric & 0x03) { case 0x00: diff --git a/src/devices/cpu/bcp/dp8344.h b/src/devices/cpu/bcp/dp8344.h index 95e0a671a0b..f4e1e674da9 100644 --- a/src/devices/cpu/bcp/dp8344.h +++ b/src/devices/cpu/bcp/dp8344.h @@ -86,6 +86,8 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; private: + static const char *const s_protocol_names[8]; + enum inst_state : u8 { T1_DECODE, T1_START, T1_SKIP, T1_LJMP, T1_LCALL, TX_READ, TX_WRITE, @@ -123,7 +125,7 @@ private: u16 transmit_fifo_pop(); void transmitter_idle(); void receiver_active(); - void receive_fifo_push(u8 data); + void receive_fifo_push(u16 data); u8 receive_fifo_pop(bool test); void set_receiver_error(u8 code); u8 get_error_code(bool test); @@ -214,6 +216,9 @@ private: u16 m_tfifo[3]; u8 m_rfifo_head; u8 m_tfifo_head; + + // misc. state + bool m_receiver_interrupt; }; // ======================> dp8344a_device diff --git a/src/devices/cpu/e0c6200/e0c6s46.cpp b/src/devices/cpu/e0c6200/e0c6s46.cpp index 9f80774a6e5..5094c36a5f7 100644 --- a/src/devices/cpu/e0c6200/e0c6s46.cpp +++ b/src/devices/cpu/e0c6200/e0c6s46.cpp @@ -589,7 +589,7 @@ u32 e0c6s46_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, c if (!m_pixel_update_cb.isnull()) m_pixel_update_cb(bitmap, cliprect, m_lcd_contrast, seg, com, pixel); else if (cliprect.contains(seg, com)) - bitmap.pix16(com, seg) = pixel; + bitmap.pix(com, seg) = pixel; } } } diff --git a/src/devices/cpu/f8/f8dasm.cpp b/src/devices/cpu/f8/f8dasm.cpp index 24ec47b5154..e35a7d42f70 100644 --- a/src/devices/cpu/f8/f8dasm.cpp +++ b/src/devices/cpu/f8/f8dasm.cpp @@ -17,33 +17,22 @@ offs_t f8_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_ { offs_t base_pc = pc; uint8_t op = opcodes.r8(pc++); + offs_t flags = SUPPORTED; switch( op ) { /* opcode bitmask */ case 0x00: /* 0000 0000 */ - util::stream_format(stream, "LR A,KU"); - break; case 0x01: /* 0000 0001 */ - util::stream_format(stream, "LR A,KL"); - break; case 0x02: /* 0000 0010 */ - util::stream_format(stream, "LR A,QU"); - break; case 0x03: /* 0000 0011 */ - util::stream_format(stream, "LR A,QL"); + util::stream_format(stream, "LR A,%s", rname[op + 12]); break; case 0x04: /* 0000 0100 */ - util::stream_format(stream, "LR KU,A"); - break; case 0x05: /* 0000 0101 */ - util::stream_format(stream, "LR KL,A"); - break; case 0x06: /* 0000 0110 */ - util::stream_format(stream, "LR QU,A"); - break; case 0x07: /* 0000 0111 */ - util::stream_format(stream, "LR QL,A"); + util::stream_format(stream, "LR %s,A", rname[(op - 0x04) + 12]); break; case 0x08: /* 0000 1000 */ @@ -60,7 +49,8 @@ offs_t f8_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_ break; case 0x0c: /* 0000 1100 */ - util::stream_format(stream, "PK") ; + util::stream_format(stream, "PK"); + flags |= STEP_OUT; break; case 0x0d: /* 0000 1101 */ util::stream_format(stream, "LR P0,Q"); @@ -109,6 +99,7 @@ offs_t f8_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_ break; case 0x1c: /* 0001 1100 */ util::stream_format(stream, "POP"); + flags |= STEP_OUT; break; case 0x1d: /* 0001 1101 */ util::stream_format(stream, "LR W,J"); @@ -120,39 +111,40 @@ offs_t f8_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_ util::stream_format(stream, "INC"); break; case 0x20: /* 0010 0000 */ - util::stream_format(stream, "LI $%02X", opcodes.r8(pc++)); + util::stream_format(stream, "LI H'%02X'", opcodes.r8(pc++)); break; case 0x21: /* 0010 0001 */ - util::stream_format(stream, "NI $%02X", opcodes.r8(pc++)); + util::stream_format(stream, "NI H'%02X'", opcodes.r8(pc++)); break; case 0x22: /* 0010 0010 */ - util::stream_format(stream, "OI $%02X", opcodes.r8(pc++)); + util::stream_format(stream, "OI H'%02X'", opcodes.r8(pc++)); break; case 0x23: /* 0010 0011 */ - util::stream_format(stream, "XI $%02X", opcodes.r8(pc++)); + util::stream_format(stream, "XI H'%02X'", opcodes.r8(pc++)); break; case 0x24: /* 0010 0100 */ - util::stream_format(stream, "AI $%02X", opcodes.r8(pc++)); + util::stream_format(stream, "AI H'%02X'", opcodes.r8(pc++)); break; case 0x25: /* 0010 0101 */ - util::stream_format(stream, "CI $%02X", opcodes.r8(pc++)); + util::stream_format(stream, "CI H'%02X'", opcodes.r8(pc++)); break; case 0x26: /* 0010 0110 */ - util::stream_format(stream, "IN $%02X", opcodes.r8(pc++)); + util::stream_format(stream, "IN H'%02X'", opcodes.r8(pc++)); break; case 0x27: /* 0010 0111 */ - util::stream_format(stream, "OUT $%02X", opcodes.r8(pc++)); + util::stream_format(stream, "OUT H'%02X'", opcodes.r8(pc++)); break; case 0x28: /* 0010 1000 */ - util::stream_format(stream, "PI $%04X", opcodes.r16(pc)); + util::stream_format(stream, "PI H'%04X'", opcodes.r16(pc)); pc += 2; + flags |= STEP_OVER; break; case 0x29: /* 0010 1001 */ - util::stream_format(stream, "JMP $%04X", opcodes.r16(pc)); + util::stream_format(stream, "JMP H'%04X'", opcodes.r16(pc)); pc += 2; break; case 0x2a: /* 0010 1010 */ - util::stream_format(stream, "DCI $%04X", opcodes.r16(pc)); + util::stream_format(stream, "DCI H'%04X'", opcodes.r16(pc)); pc += 2; break; case 0x2b: /* 0010 1011 */ @@ -161,11 +153,9 @@ offs_t f8_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_ case 0x2c: /* 0010 1100 */ util::stream_format(stream, "XDC"); break; - case 0x2d: /* 0010 1101 */ - case 0x2e: /* 0010 1110 */ - case 0x2f: /* 0010 1111 */ - util::stream_format(stream, "??? $%02X",op); - break; + /* case 0x2d: 0010 1101 */ + /* case 0x2e: 0010 1110 */ + /* case 0x2f: 0010 1111 */ case 0x30: /* 0011 0000 */ case 0x31: /* 0011 0001 */ @@ -179,20 +169,18 @@ offs_t f8_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_ case 0x39: /* 0011 1001 */ case 0x3a: /* 0011 1010 */ case 0x3b: /* 0011 1011 */ - util::stream_format(stream, "DS %s",rname[op & 15]); + util::stream_format(stream, "DS %s", rname[op & 15]); break; case 0x3c: /* 0011 1100 */ - util::stream_format(stream, "DS (IS)"); + util::stream_format(stream, "DS S"); break; case 0x3d: /* 0011 1101 */ - util::stream_format(stream, "DS (IS++)"); + util::stream_format(stream, "DS I"); break; case 0x3e: /* 0011 1110 */ - util::stream_format(stream, "DS (IS--)"); - break; - case 0x3f: /* 0011 1111 */ - util::stream_format(stream, "??? $%02X",op); + util::stream_format(stream, "DS D"); break; + /* case 0x3f: 0011 1111 */ case 0x40: /* 0100 0000 */ case 0x41: /* 0100 0001 */ @@ -206,20 +194,18 @@ offs_t f8_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_ case 0x49: /* 0100 1001 */ case 0x4a: /* 0100 1010 */ case 0x4b: /* 0100 1011 */ - util::stream_format(stream, "LR A,%s",rname[op & 15]); + util::stream_format(stream, "LR A,%s", rname[op & 15]); break; case 0x4c: /* 0100 1100 */ - util::stream_format(stream, "LR A,(IS)"); + util::stream_format(stream, "LR A,S"); break; case 0x4d: /* 0100 1101 */ - util::stream_format(stream, "LR A,(IS++)"); + util::stream_format(stream, "LR A,I"); break; case 0x4e: /* 0100 1110 */ - util::stream_format(stream, "LR A,(IS--)"); - break; - case 0x4f: /* 0100 1111 */ - util::stream_format(stream, "??? $%02X",op); + util::stream_format(stream, "LR A,D"); break; + /* case 0x4f: 0100 1111 */ case 0x50: /* 0101 0000 */ case 0x51: /* 0101 0001 */ @@ -233,20 +219,18 @@ offs_t f8_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_ case 0x59: /* 0101 1001 */ case 0x5a: /* 0101 1010 */ case 0x5b: /* 0101 1011 */ - util::stream_format(stream, "LR %s,A",rname[op & 15]); + util::stream_format(stream, "LR %s,A", rname[op & 15]); break; case 0x5c: /* 0101 1100 */ - util::stream_format(stream, "LR (IS),A"); + util::stream_format(stream, "LR S,A"); break; case 0x5d: /* 0101 1101 */ - util::stream_format(stream, "LR (IS++),A"); + util::stream_format(stream, "LR I,A"); break; case 0x5e: /* 0101 1110 */ - util::stream_format(stream, "LR (IS--),A"); - break; - case 0x5f: /* 0101 1111 */ - util::stream_format(stream, "??? $%02X",op); + util::stream_format(stream, "LR D,A"); break; + /* case 0x5f: 0101 1111 */ case 0x60: /* 0110 0000 */ case 0x61: /* 0110 0001 */ @@ -256,7 +240,7 @@ offs_t f8_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_ case 0x65: /* 0110 0101 */ case 0x66: /* 0110 0110 */ case 0x67: /* 0110 0111 */ - util::stream_format(stream, "LISU $%02X", op & 0x07); + util::stream_format(stream, "LISU %d", op & 0x07); break; case 0x68: /* 0110 1000 */ case 0x69: /* 0110 1001 */ @@ -266,7 +250,7 @@ offs_t f8_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_ case 0x6d: /* 0110 1101 */ case 0x6e: /* 0110 1110 */ case 0x6f: /* 0110 1111 */ - util::stream_format(stream, "LISL $%02X", op & 0x07); + util::stream_format(stream, "LISL %d", op & 0x07); break; case 0x70: /* 0111 0000 */ @@ -285,27 +269,27 @@ offs_t f8_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_ case 0x7d: /* 0111 1101 */ case 0x7e: /* 0111 1110 */ case 0x7f: /* 0111 1111 */ - util::stream_format(stream, "LIS $%02X", op & 0x0f); + util::stream_format(stream, "LIS H'%02X'", op & 0x0f); break; case 0x81: /* 1000 0001 */ case 0x85: /* 1000 0101 */ - util::stream_format(stream, "BP $%04X", base_pc + (int8_t)opcodes.r8(pc++) + 1); + util::stream_format(stream, "BP H'%04X'", base_pc + (int8_t)opcodes.r8(pc++) + 1); break; case 0x82: /* 1000 0010 */ - util::stream_format(stream, "BC $%04X", base_pc + (int8_t)opcodes.r8(pc++) + 1); + util::stream_format(stream, "BC H'%04X'", base_pc + (int8_t)opcodes.r8(pc++) + 1); break; case 0x84: /* 1000 0100 */ - util::stream_format(stream, "BZ $%04X", base_pc + (int8_t)opcodes.r8(pc++) + 1); + util::stream_format(stream, "BZ H'%04X'", base_pc + (int8_t)opcodes.r8(pc++) + 1); break; case 0x80: /* 1000 0000 */ case 0x83: /* 1000 0011 */ case 0x86: /* 1000 0110 */ case 0x87: /* 1000 0111 */ - util::stream_format(stream, "BT $%02X,$%04X", op & 0x07, base_pc + (int8_t)opcodes.r8(pc++) + 1); + util::stream_format(stream, "BT H'%02X',H'%04X'", op & 0x07, base_pc + (int8_t)opcodes.r8(pc++) + 1); break; case 0x88: /* 1000 1000 */ @@ -337,28 +321,28 @@ offs_t f8_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_ break; case 0x8f: /* 1000 1111 */ - util::stream_format(stream, "BR7 $%04X", base_pc + (int8_t)opcodes.r8(pc++) + 1); + util::stream_format(stream, "BR7 H'%04X'", base_pc + (int8_t)opcodes.r8(pc++) + 1); break; case 0x90: /* 1001 0000 */ - util::stream_format(stream, "BR $%04X", base_pc + (int8_t)opcodes.r8(pc++) + 1); + util::stream_format(stream, "BR H'%04X'", base_pc + (int8_t)opcodes.r8(pc++) + 1); break; case 0x91: /* 1001 0001 */ case 0x95: /* 1001 0101 */ - util::stream_format(stream, "BM $%04X", base_pc + (int8_t)opcodes.r8(pc++) + 1); + util::stream_format(stream, "BM H'%04X'", base_pc + (int8_t)opcodes.r8(pc++) + 1); break; case 0x92: /* 1001 0010 */ - util::stream_format(stream, "BNC $%04X", base_pc + (int8_t)opcodes.r8(pc++) + 1); + util::stream_format(stream, "BNC H'%04X'", base_pc + (int8_t)opcodes.r8(pc++) + 1); break; case 0x94: /* 1001 0100 */ - util::stream_format(stream, "BNZ $%04X", base_pc + (int8_t)opcodes.r8(pc++) + 1); + util::stream_format(stream, "BNZ H'%04X'", base_pc + (int8_t)opcodes.r8(pc++) + 1); break; case 0x98: /* 1001 1000 */ - util::stream_format(stream, "BNO $%04X", base_pc + (int8_t)opcodes.r8(pc++) + 1); + util::stream_format(stream, "BNO H'%04X'", base_pc + (int8_t)opcodes.r8(pc++) + 1); break; case 0x93: /* 1001 0011 */ @@ -371,18 +355,16 @@ offs_t f8_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_ case 0x9d: /* 1001 1101 */ case 0x9e: /* 1001 1110 */ case 0x9f: /* 1001 1111 */ - util::stream_format(stream, "BF $%02X,$%04X", op & 0x0f, base_pc + (int8_t)opcodes.r8(pc++) + 1); + util::stream_format(stream, "BF H'%02X',H'%04X'", op & 0x0f, base_pc + (int8_t)opcodes.r8(pc++) + 1); break; case 0xa0: /* 1010 0000 */ case 0xa1: /* 1010 0001 */ - util::stream_format(stream, "INS $%02X", (unsigned) (int8_t) (op & 0x0F)); + util::stream_format(stream, "INS %d", op & 0x0f); break; - case 0xa2: /* 1010 0010 */ - case 0xa3: /* 1010 0011 */ - util::stream_format(stream, "??? $%02X", op); - break; + /* case 0xa2: 1010 0010 */ + /* case 0xa3: 1010 0011 */ case 0xa4: /* 1010 0100 */ case 0xa5: /* 1010 0101 */ @@ -396,18 +378,16 @@ offs_t f8_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_ case 0xad: /* 1010 1101 */ case 0xae: /* 1010 1110 */ case 0xaf: /* 1010 1111 */ - util::stream_format(stream, "INS $%02X", (int8_t) op & 0x0f); + util::stream_format(stream, "INS H'%02X'", op & 0x0f); break; case 0xb0: /* 1011 0000 */ case 0xb1: /* 1011 0001 */ - util::stream_format(stream, "OUTS $%02X", (int8_t) op & 0x0f); + util::stream_format(stream, "OUTS %d", op & 0x0f); break; - case 0xb2: /* 1011 0010 */ - case 0xb3: /* 1011 0011 */ - util::stream_format(stream, "??? $%02X", op); - break; + /* case 0xb2: 1011 0010 */ + /* case 0xb3: 1011 0011 */ case 0xb4: /* 1011 0100 */ case 0xb5: /* 1011 0101 */ @@ -421,7 +401,7 @@ offs_t f8_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_ case 0xbd: /* 1011 1101 */ case 0xbe: /* 1011 1110 */ case 0xbf: /* 1011 1111 */ - util::stream_format(stream, "OUTS $%02X", (unsigned) (int8_t) op & 0x0f); + util::stream_format(stream, "OUTS H'%02X'", op & 0x0f); break; case 0xc0: /* 1100 0000 */ @@ -439,17 +419,15 @@ offs_t f8_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_ util::stream_format(stream, "AS %s", rname[op & 15]); break; case 0xcc: /* 1100 1100 */ - util::stream_format(stream, "AS (IS)"); + util::stream_format(stream, "AS S"); break; case 0xcd: /* 1100 1101 */ - util::stream_format(stream, "AS (IS++)"); + util::stream_format(stream, "AS I"); break; case 0xce: /* 1100 1110 */ - util::stream_format(stream, "AS (IS--)"); - break; - case 0xcf: /* 1100 1111 */ - util::stream_format(stream, "??? $%02X", op); + util::stream_format(stream, "AS D"); break; + /* case 0xcf: 1100 1111 */ case 0xd0: /* 1101 0000 */ case 0xd1: /* 1101 0001 */ @@ -466,17 +444,15 @@ offs_t f8_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_ util::stream_format(stream, "ASD %s", rname[op & 15]); break; case 0xdc: /* 1101 1100 */ - util::stream_format(stream, "ASD (IS)"); + util::stream_format(stream, "ASD S"); break; case 0xdd: /* 1101 1101 */ - util::stream_format(stream, "ASD (IS++)"); + util::stream_format(stream, "ASD I"); break; case 0xde: /* 1101 1110 */ - util::stream_format(stream, "ASD (IS--)"); - break; - case 0xdf: /* 1101 1111 */ - util::stream_format(stream, "??? $%02X", op); + util::stream_format(stream, "ASD D"); break; + /* case 0xdf: 1101 1111 */ case 0xe0: /* 1110 0000 */ case 0xe1: /* 1110 0001 */ @@ -493,17 +469,15 @@ offs_t f8_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_ util::stream_format(stream, "XS %s", rname[op & 15]); break; case 0xec: /* 1110 1100 */ - util::stream_format(stream, "XS (IS)"); + util::stream_format(stream, "XS S"); break; case 0xed: /* 1110 1101 */ - util::stream_format(stream, "XS (IS++)"); + util::stream_format(stream, "XS I"); break; case 0xee: /* 1110 1110 */ - util::stream_format(stream, "XS (IS--)"); - break; - case 0xef: /* 1110 1111 */ - util::stream_format(stream, "??? $%02X", op); + util::stream_format(stream, "XS D"); break; + /* case 0xef: 1110 1111 */ case 0xf0: /* 1111 0000 */ @@ -521,18 +495,21 @@ offs_t f8_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_ util::stream_format(stream, "NS %s", rname[op & 15]); break; case 0xfc: /* 1111 1100 */ - util::stream_format(stream, "NS (IS)"); + util::stream_format(stream, "NS S"); break; case 0xfd: /* 1111 1101 */ - util::stream_format(stream, "NS (IS++)"); + util::stream_format(stream, "NS I"); break; case 0xfe: /* 1111 1110 */ - util::stream_format(stream, "NS (IS--)"); + util::stream_format(stream, "NS D"); break; - case 0xff: /* 1111 1111 */ - util::stream_format(stream, "??? $%02X", op); + /* case 0xff: 1111 1111 */ + + + default: + util::stream_format(stream, "DC H'%02X' (?)", op); break; } - return pc - base_pc; + return (pc - base_pc) | flags; } diff --git a/src/devices/cpu/lc58/lc58d.cpp b/src/devices/cpu/lc58/lc58d.cpp new file mode 100644 index 00000000000..477ee00ffb0 --- /dev/null +++ b/src/devices/cpu/lc58/lc58d.cpp @@ -0,0 +1,160 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert + +// LC58 generic disassembler + +#include "emu.h" +#include "lc58d.h" + +u32 lc58_disassembler::opcode_alignment() const +{ + return 1; +} + +#define P std::ostream &stream, const lc58_disassembler *d, u16 opcode +const lc58_disassembler::instruction lc58_disassembler::instructions[] { + { 0x5a00, 0xffff, [](P) -> u32 { util::stream_format(stream, "cla"); return 1; } }, + { 0xec01, 0xffff, [](P) -> u32 { util::stream_format(stream, "rcf"); return 1; } }, + { 0xe801, 0xffff, [](P) -> u32 { util::stream_format(stream, "scf"); return 1; } }, + { 0x6000, 0xfc00, [](P) -> u32 { util::stream_format(stream, "mrw wr%x, %02x", (opcode >> 7) & 7, opcode & 0x7f); return 1; } }, + { 0x6400, 0xfc00, [](P) -> u32 { util::stream_format(stream, "mwr %02x, wr%x", opcode & 0x7f, (opcode >> 7) & 7); return 1; } }, + { 0x6800, 0xff80, [](P) -> u32 { util::stream_format(stream, "sr0 %02x", opcode & 0x7f); return 1; } }, + { 0x6900, 0xff80, [](P) -> u32 { util::stream_format(stream, "sr1 %02x", opcode & 0x7f); return 1; } }, + { 0x6a00, 0xff80, [](P) -> u32 { util::stream_format(stream, "sl0 %02x", opcode & 0x7f); return 1; } }, + { 0x6b00, 0xff80, [](P) -> u32 { util::stream_format(stream, "sl1 %02x", opcode & 0x7f); return 1; } }, + { 0x6c00, 0xff80, [](P) -> u32 { util::stream_format(stream, "rar %02x", opcode & 0x7f); return 1; } }, + { 0x6e00, 0xff80, [](P) -> u32 { util::stream_format(stream, "ral %02x", opcode & 0x7f); return 1; } }, + { 0x7400, 0xff80, [](P) -> u32 { util::stream_format(stream, "maf %02x", opcode & 0x7f); return 1; } }, + { 0x0f80, 0xff80, [](P) -> u32 { util::stream_format(stream, "mra %02x", opcode & 0x7f); return 1; } }, + + { 0x4000, 0xff80, [](P) -> u32 { util::stream_format(stream, "adc %02x", opcode & 0x7f); return 1; } }, + { 0x4100, 0xff80, [](P) -> u32 { util::stream_format(stream, "adc* %02x", opcode & 0x7f); return 1; } }, + { 0x4200, 0xff80, [](P) -> u32 { util::stream_format(stream, "sbc %02x", opcode & 0x7f); return 1; } }, + { 0x4300, 0xff80, [](P) -> u32 { util::stream_format(stream, "sbc* %02x", opcode & 0x7f); return 1; } }, + { 0x4400, 0xff80, [](P) -> u32 { util::stream_format(stream, "add %02x", opcode & 0x7f); return 1; } }, + { 0x4500, 0xff80, [](P) -> u32 { util::stream_format(stream, "add* %02x", opcode & 0x7f); return 1; } }, + { 0x4600, 0xff80, [](P) -> u32 { util::stream_format(stream, "sub %02x", opcode & 0x7f); return 1; } }, + { 0x4700, 0xff80, [](P) -> u32 { util::stream_format(stream, "sub* %02x", opcode & 0x7f); return 1; } }, + { 0x4800, 0xff80, [](P) -> u32 { util::stream_format(stream, "adn %02x", opcode & 0x7f); return 1; } }, + { 0x4900, 0xff80, [](P) -> u32 { util::stream_format(stream, "adn* %02x", opcode & 0x7f); return 1; } }, + { 0x4a00, 0xff80, [](P) -> u32 { util::stream_format(stream, "and %02x", opcode & 0x7f); return 1; } }, + { 0x4b00, 0xff80, [](P) -> u32 { util::stream_format(stream, "and* %02x", opcode & 0x7f); return 1; } }, + { 0x4c00, 0xff80, [](P) -> u32 { util::stream_format(stream, "eor %02x", opcode & 0x7f); return 1; } }, + { 0x4d00, 0xff80, [](P) -> u32 { util::stream_format(stream, "eor* %02x", opcode & 0x7f); return 1; } }, + { 0x4e00, 0xff80, [](P) -> u32 { util::stream_format(stream, "or %02x", opcode & 0x7f); return 1; } }, + { 0x4f00, 0xff80, [](P) -> u32 { util::stream_format(stream, "or* %02x", opcode & 0x7f); return 1; } }, + { 0x5000, 0xff00, [](P) -> u32 { util::stream_format(stream, "adci #%x, %02x", (opcode >> 4) & 0xf, 0x70 + (opcode & 0xf)); return 1; } }, + { 0x5100, 0xff00, [](P) -> u32 { util::stream_format(stream, "adci* #%x, %02x", (opcode >> 4) & 0xf, 0x70 + (opcode & 0xf)); return 1; } }, + { 0x5200, 0xff00, [](P) -> u32 { util::stream_format(stream, "sbci #%x, %02x", (opcode >> 4) & 0xf, 0x70 + (opcode & 0xf)); return 1; } }, + { 0x5300, 0xff00, [](P) -> u32 { util::stream_format(stream, "sbci* #%x, %02x", (opcode >> 4) & 0xf, 0x70 + (opcode & 0xf)); return 1; } }, + { 0x5400, 0xff00, [](P) -> u32 { util::stream_format(stream, "addi #%x, %02x", (opcode >> 4) & 0xf, 0x70 + (opcode & 0xf)); return 1; } }, + { 0x5500, 0xff00, [](P) -> u32 { util::stream_format(stream, "addi* #%x, %02x", (opcode >> 4) & 0xf, 0x70 + (opcode & 0xf)); return 1; } }, + { 0x5600, 0xff00, [](P) -> u32 { util::stream_format(stream, "subi #%x, %02x", (opcode >> 4) & 0xf, 0x70 + (opcode & 0xf)); return 1; } }, + { 0x5700, 0xff00, [](P) -> u32 { util::stream_format(stream, "subi* #%x, %02x", (opcode >> 4) & 0xf, 0x70 + (opcode & 0xf)); return 1; } }, + { 0x5800, 0xff00, [](P) -> u32 { util::stream_format(stream, "adni #%x, %02x", (opcode >> 4) & 0xf, 0x70 + (opcode & 0xf)); return 1; } }, + { 0x5900, 0xff00, [](P) -> u32 { util::stream_format(stream, "adni* #%x, %02x", (opcode >> 4) & 0xf, 0x70 + (opcode & 0xf)); return 1; } }, + { 0x5a00, 0xff00, [](P) -> u32 { util::stream_format(stream, "andi #%x, %02x", (opcode >> 4) & 0xf, 0x70 + (opcode & 0xf)); return 1; } }, + { 0x5b00, 0xff00, [](P) -> u32 { util::stream_format(stream, "andi* #%x, %02x", (opcode >> 4) & 0xf, 0x70 + (opcode & 0xf)); return 1; } }, + { 0x5c00, 0xff00, [](P) -> u32 { util::stream_format(stream, "eori #%x, %02x", (opcode >> 4) & 0xf, 0x70 + (opcode & 0xf)); return 1; } }, + { 0x5d00, 0xff00, [](P) -> u32 { util::stream_format(stream, "eori* #%x, %02x", (opcode >> 4) & 0xf, 0x70 + (opcode & 0xf)); return 1; } }, + { 0x5e00, 0xff00, [](P) -> u32 { util::stream_format(stream, "ori #%x, %02x", (opcode >> 4) & 0xf, 0x70 + (opcode & 0xf)); return 1; } }, + { 0x5f00, 0xff00, [](P) -> u32 { util::stream_format(stream, "ori* #%x, %02x", (opcode >> 4) & 0xf, 0x70 + (opcode & 0xf)); return 1; } }, + + { 0x7700, 0xff80, [](P) -> u32 { util::stream_format(stream, "mdpl %02x", opcode & 0x7f); return 1; } }, + { 0x7680, 0xff80, [](P) -> u32 { util::stream_format(stream, "mdph %02x", opcode & 0x7f); return 1; } }, + { 0x6b80, 0xff80, [](P) -> u32 { util::stream_format(stream, "mrdl %02x", opcode & 0x7f); return 1; } }, + { 0x6980, 0xff80, [](P) -> u32 { util::stream_format(stream, "mrdh %02x", opcode & 0x7f); return 1; } }, + { 0x6a80, 0xff80, [](P) -> u32 { util::stream_format(stream, "mrsp %02x", opcode & 0x7f); return 1; } }, + { 0xe800, 0xfc00, [](P) -> u32 { util::stream_format(stream, "sf1 %03x", opcode & 0x3ff); return 1; } }, + { 0xec00, 0xfc00, [](P) -> u32 { util::stream_format(stream, "rf1 %03x", opcode & 0x3ff); return 1; } }, + { 0xf000, 0xfc00, [](P) -> u32 { util::stream_format(stream, "sf2 %03x", opcode & 0x3ff); return 1; } }, + { 0xf400, 0xfc00, [](P) -> u32 { util::stream_format(stream, "rf2 %03x", opcode & 0x3ff); return 1; } }, + { 0xe880, 0xffff, [](P) -> u32 { util::stream_format(stream, "sdpf"); return 1; } }, + { 0xec80, 0xffff, [](P) -> u32 { util::stream_format(stream, "rdpf"); return 1; } }, + + { 0x7780, 0xff80, [](P) -> u32 { util::stream_format(stream, "sta %02x", opcode & 0x7f); return 1; } }, + { 0x7800, 0xf800, [](P) -> u32 { util::stream_format(stream, "lds %02x, #%x", opcode & 0x7f, (opcode >> 7) & 0xf); return 1; } }, + { 0x6880, 0xff80, [](P) -> u32 { util::stream_format(stream, "lda %02x", opcode & 0x7f); return 1; } }, + + { 0xff00, 0xffff, [](P) -> u32 { util::stream_format(stream, "halt"); return 1; } }, + { 0xe000, 0xffc0, [](P) -> u32 { util::stream_format(stream, "ssw %02x", opcode & 0x3f); return 1; } }, + { 0xfa00, 0xfe00, [](P) -> u32 { util::stream_format(stream, "sie %03x", opcode & 0x1ff); return 1 | STEP_OVER; } }, + { 0xfe00, 0xfff0, [](P) -> u32 { util::stream_format(stream, "sie* %x", opcode & 0xf); return 1 | STEP_OVER; } }, + { 0x7580, 0xff80, [](P) -> u32 { util::stream_format(stream, "msb %02x", opcode & 0x7f); return 1; } }, + { 0x7600, 0xff80, [](P) -> u32 { util::stream_format(stream, "msc %02x", opcode & 0x7f); return 1; } }, + { 0x0000, 0xffff, [](P) -> u32 { util::stream_format(stream, "nop"); return 1; } }, + { 0xf018, 0xffff, [](P) -> u32 { util::stream_format(stream, "lon"); return 1; } }, + { 0xf418, 0xffff, [](P) -> u32 { util::stream_format(stream, "loff"); return 1; } }, + { 0xf004, 0xffff, [](P) -> u32 { util::stream_format(stream, "sbak"); return 1; } }, + { 0xf404, 0xffff, [](P) -> u32 { util::stream_format(stream, "rbak"); return 1; } }, + + { 0x7480, 0xff80, [](P) -> u32 { util::stream_format(stream, "mcd %02x", opcode & 0x7f); return 1; } }, + { 0x7500, 0xff80, [](P) -> u32 { util::stream_format(stream, "mcf %02x", opcode & 0x7f); return 1; } }, + { 0xfc22, 0xffff, [](P) -> u32 { util::stream_format(stream, "ccc"); return 1; } }, + { 0xfc40, 0xffff, [](P) -> u32 { util::stream_format(stream, "rlp"); return 1; } }, + { 0xfc80, 0xffff, [](P) -> u32 { util::stream_format(stream, "csp"); return 1; } }, + { 0xfb00, 0xffff, [](P) -> u32 { util::stream_format(stream, "cst"); return 1; } }, + { 0xe802, 0xffff, [](P) -> u32 { util::stream_format(stream, "scex"); return 1; } }, + { 0xec02, 0xffff, [](P) -> u32 { util::stream_format(stream, "rcex"); return 1; } }, + { 0xf000, 0xfffc, [](P) -> u32 { util::stream_format(stream, "schf %x", opcode & 3); return 1; } }, + { 0xf400, 0xfffc, [](P) -> u32 { util::stream_format(stream, "rchf %x", opcode & 3); return 1; } }, + + { 0x7180, 0xff80, [](P) -> u32 { util::stream_format(stream, "ipp %02x", opcode & 0x7f); return 1; } }, + { 0x7000, 0xff80, [](P) -> u32 { util::stream_format(stream, "ips %02x", opcode & 0x7f); return 1; } }, + { 0x7080, 0xff80, [](P) -> u32 { util::stream_format(stream, "ipm %02x", opcode & 0x7f); return 1; } }, + { 0x7100, 0xff80, [](P) -> u32 { util::stream_format(stream, "ipk %02x", opcode & 0x7f); return 1; } }, + { 0x0080, 0xff80, [](P) -> u32 { util::stream_format(stream, "opp %02x", opcode & 0x7f); return 1; } }, + { 0x0f00, 0xff80, [](P) -> u32 { util::stream_format(stream, "opm %02x", opcode & 0x7f); return 1; } }, + { 0xe804, 0xffff, [](P) -> u32 { util::stream_format(stream, "sct1"); return 1; } }, + { 0xec04, 0xffff, [](P) -> u32 { util::stream_format(stream, "rct1"); return 1; } }, + { 0xf200, 0xffff, [](P) -> u32 { util::stream_format(stream, "sct2"); return 1; } }, + { 0xf600, 0xffff, [](P) -> u32 { util::stream_format(stream, "rct2"); return 1; } }, + { 0xf010, 0xffff, [](P) -> u32 { util::stream_format(stream, "slgt"); return 1; } }, + { 0xf410, 0xffff, [](P) -> u32 { util::stream_format(stream, "rlgt"); return 1; } }, + { 0xf800, 0xffff, [](P) -> u32 { util::stream_format(stream, "ras"); return 1; } }, + { 0xf800, 0xfe00, [](P) -> u32 { util::stream_format(stream, "sas %03x", opcode & 0x1ff); return 1; } }, + { 0xe800, 0xff9f, [](P) -> u32 { util::stream_format(stream, "comd %x", (opcode >> 5) & 3); return 1; } }, + { 0xec00, 0xff9f, [](P) -> u32 { util::stream_format(stream, "cimd %x", (opcode >> 5) & 3); return 1; } }, + { 0xf000, 0xfe1f, [](P) -> u32 { util::stream_format(stream, "spdf %x", (opcode >> 5) & 3); return 1; } }, + { 0xf400, 0xfe1f, [](P) -> u32 { util::stream_format(stream, "rpdf %x", (opcode >> 5) & 3); return 1; } }, + { 0xe808, 0xffff, [](P) -> u32 { util::stream_format(stream, "sfsp"); return 1; } }, + { 0xec08, 0xffff, [](P) -> u32 { util::stream_format(stream, "rfsp"); return 1; } }, + { 0x0000, 0xf000, [](P) -> u32 { util::stream_format(stream, "wrt %02x, %02x", (opcode >> 7) & 0x1f, opcode & 0x7f); return 1; } }, + { 0x1000, 0xf000, [](P) -> u32 { util::stream_format(stream, "wrb %02x, %02x", (opcode >> 7) & 0x1f, opcode & 0x7f); return 1; } }, + { 0x2000, 0xf000, [](P) -> u32 { util::stream_format(stream, "wrc %02x, %02x", (opcode >> 7) & 0x1f, opcode & 0x7f); return 1; } }, + { 0x3000, 0xf000, [](P) -> u32 { util::stream_format(stream, "wrp %02x, %02x", (opcode >> 7) & 0x1f, opcode & 0x7f); return 1; } }, + + { 0xc000, 0xf800, [](P) -> u32 { util::stream_format(stream, "jmp %03x", opcode & 0x7ff); return 1; } }, + { 0x8000, 0xf800, [](P) -> u32 { util::stream_format(stream, "bab0 %03x", opcode & 0x7ff); return 1; } }, + { 0x8800, 0xf800, [](P) -> u32 { util::stream_format(stream, "bab1 %03x", opcode & 0x7ff); return 1; } }, + { 0x9000, 0xf800, [](P) -> u32 { util::stream_format(stream, "bab2 %03x", opcode & 0x7ff); return 1; } }, + { 0x9800, 0xf800, [](P) -> u32 { util::stream_format(stream, "bab3 %03x", opcode & 0x7ff); return 1; } }, + { 0xa000, 0xf800, [](P) -> u32 { util::stream_format(stream, "banz %03x", opcode & 0x7ff); return 1; } }, + { 0xb000, 0xf800, [](P) -> u32 { util::stream_format(stream, "baz %03x", opcode & 0x7ff); return 1; } }, + { 0xa800, 0xf800, [](P) -> u32 { util::stream_format(stream, "bcnh %03x", opcode & 0x7ff); return 1; } }, + { 0xb800, 0xf800, [](P) -> u32 { util::stream_format(stream, "bch %03x", opcode & 0x7ff); return 1; } }, + + { 0xc800, 0xf800, [](P) -> u32 { util::stream_format(stream, "call %03x", opcode & 0x7ff); return 1 | STEP_OVER; } }, + { 0xd000, 0xffff, [](P) -> u32 { util::stream_format(stream, "rts"); return 1 | STEP_OUT; } }, + { 0xd800, 0xffff, [](P) -> u32 { util::stream_format(stream, "pop"); return 1; } }, + + { 0xe400, 0xfc00, [](P) -> u32 { util::stream_format(stream, "stm %03x", opcode & 0x7ff); return 1; } }, + { 0xfc04, 0xffff, [](P) -> u32 { util::stream_format(stream, "rtm"); return 1 | STEP_OUT; } }, + { 0xf810, 0xffff, [](P) -> u32 { util::stream_format(stream, "sfpd"); return 1 | STEP_OUT; } }, + { 0xfc10, 0xffff, [](P) -> u32 { util::stream_format(stream, "rfpd"); return 1 | STEP_OUT; } }, + { 0xfc00, 0xfe00, [](P) -> u32 { util::stream_format(stream, "plc %03x", opcode & 0x1ff); return 1 | STEP_OVER; } }, + + { 0x0000, 0x0000, [](P) -> u32 { util::stream_format(stream, "?%04x", opcode); return 1; } }, +}; + +#undef P + +offs_t lc58_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + u16 opcode = opcodes.r16(pc); + + for(u32 i=0;; i++) + if((opcode & instructions[i].mask) == instructions[i].value) + return instructions[i].cb(stream, this, opcode) | SUPPORTED; + return 0; +} diff --git a/src/devices/cpu/lc58/lc58d.h b/src/devices/cpu/lc58/lc58d.h new file mode 100644 index 00000000000..6a570c10f02 --- /dev/null +++ b/src/devices/cpu/lc58/lc58d.h @@ -0,0 +1,30 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert + +// Sanyo LC58 generic disassembler + +#ifndef MAME_CPU_LC58_LC58D_H +#define MAME_CPU_LC58_LC58D_H + +#pragma once + +class lc58_disassembler : public util::disasm_interface +{ +public: + lc58_disassembler() = default; + virtual ~lc58_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + struct instruction { + u16 value; + u16 mask; + u32 (*cb)(std::ostream &, const lc58_disassembler *, u16); + }; + + static const instruction instructions[]; +}; + +#endif // MAME_CPU_LC58_LC58D_H diff --git a/src/devices/cpu/m6502/n2a03.cpp b/src/devices/cpu/m6502/n2a03.cpp index f303f1bf1b6..e1731b62e75 100644 --- a/src/devices/cpu/m6502/n2a03.cpp +++ b/src/devices/cpu/m6502/n2a03.cpp @@ -12,6 +12,7 @@ #include "n2a03.h" #include "n2a03d.h" +DEFINE_DEVICE_TYPE(N2A03_CORE, n2a03_core_device, "n2a03_core", "Ricoh N2A03 core") // needed for some VT systems with XOP instead of standard APU DEFINE_DEVICE_TYPE(N2A03, n2a03_device, "n2a03", "Ricoh N2A03") uint8_t n2a03_device::psg1_4014_r() @@ -51,15 +52,29 @@ void n2a03_device::n2a03_map(address_map &map) +n2a03_core_device::n2a03_core_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) + : m6502_device(mconfig, type, tag, owner, clock) +{ +} + +n2a03_core_device::n2a03_core_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : n2a03_core_device(mconfig, N2A03_CORE, tag, owner, clock) +{ +} + + + n2a03_device::n2a03_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : m6502_device(mconfig, N2A03, tag, owner, clock) + : n2a03_core_device(mconfig, N2A03, tag, owner, clock) , device_mixer_interface(mconfig, *this, 1) , m_apu(*this, "nesapu") { program_config.m_internal_map = address_map_constructor(FUNC(n2a03_device::n2a03_map), this); } -std::unique_ptr<util::disasm_interface> n2a03_device::create_disassembler() + + +std::unique_ptr<util::disasm_interface> n2a03_core_device::create_disassembler() { return std::make_unique<n2a03_disassembler>(); } diff --git a/src/devices/cpu/m6502/n2a03.h b/src/devices/cpu/m6502/n2a03.h index 5a57bcbed2b..4232093c7a5 100644 --- a/src/devices/cpu/m6502/n2a03.h +++ b/src/devices/cpu/m6502/n2a03.h @@ -15,22 +15,18 @@ #include "m6502.h" #include "sound/nes_apu.h" -class n2a03_device : public m6502_device, public device_mixer_interface { +class n2a03_core_device : public m6502_device { public: - n2a03_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + n2a03_core_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); virtual std::unique_ptr<util::disasm_interface> create_disassembler() override; virtual void do_exec_full() override; virtual void do_exec_partial() override; - uint8_t psg1_4014_r(); - uint8_t psg1_4015_r(); - void psg1_4015_w(uint8_t data); - void psg1_4017_w(uint8_t data); - - void n2a03_map(address_map &map); protected: + n2a03_core_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + #define O(o) void o ## _full(); void o ## _partial() // n2a03 opcodes - same as 6502 with D disabled @@ -42,6 +38,21 @@ protected: #undef O +private: +}; + +class n2a03_device : public n2a03_core_device, public device_mixer_interface { +public: + n2a03_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + uint8_t psg1_4014_r(); + uint8_t psg1_4015_r(); + void psg1_4015_w(uint8_t data); + void psg1_4017_w(uint8_t data); + + void n2a03_map(address_map &map); +protected: + required_device<nesapu_device> m_apu; virtual void device_add_mconfig(machine_config &config) override; @@ -52,6 +63,7 @@ private: }; + /* These are the official XTAL values and clock rates used by Nintendo for manufacturing throughout the production of the 2A03. PALC_APU_CLOCK is the clock rate devised by UMC(?) for PAL Famicom clone hardware. */ @@ -69,6 +81,7 @@ enum { N2A03_SET_OVERFLOW = m6502_device::V_LINE }; +DECLARE_DEVICE_TYPE(N2A03_CORE, n2a03_core_device) DECLARE_DEVICE_TYPE(N2A03, n2a03_device) #endif // MAME_CPU_M6502_N2A03_H diff --git a/src/devices/cpu/mcs48/mcs48.cpp b/src/devices/cpu/mcs48/mcs48.cpp index 58f3d31b150..7aabcc4348a 100644 --- a/src/devices/cpu/mcs48/mcs48.cpp +++ b/src/devices/cpu/mcs48/mcs48.cpp @@ -15,6 +15,7 @@ - add special 8022 opcodes (RAD, SEL AN0, SEL AN1, RETI) - according to the user manual, some opcodes(dis/enable timer/interrupt) don't increment the timer, does it affect the prescaler too? + - IRQ timing is hacked due to WY-100 needing to take JNI branch before servicing interrupt **************************************************************************** @@ -517,7 +518,7 @@ void mcs48_cpu_device::execute_call(uint16_t address) conditional jump instruction -------------------------------------------------*/ -void mcs48_cpu_device::execute_jcc(uint8_t result) +void mcs48_cpu_device::execute_jcc(bool result) { uint16_t pch = m_pc & 0xf00; uint8_t offset = argument_fetch(); @@ -747,8 +748,8 @@ OPHANDLER( jc ) { burn_cycles(2); execute_jcc((m_psw & C_FLAG) != 0) OPHANDLER( jf0 ) { burn_cycles(2); execute_jcc((m_psw & F_FLAG) != 0); } OPHANDLER( jf1 ) { burn_cycles(2); execute_jcc((m_sts & STS_F1) != 0); } OPHANDLER( jnc ) { burn_cycles(2); execute_jcc((m_psw & C_FLAG) == 0); } -OPHANDLER( jni ) { burn_cycles(2); execute_jcc(m_irq_state != 0); } -OPHANDLER( jnibf ) { burn_cycles(2); execute_jcc((m_sts & STS_IBF) == 0); } +OPHANDLER( jni ) { burn_cycles(2); m_irq_polled = (m_irq_state == 0); execute_jcc(m_irq_state != 0); } +OPHANDLER( jnibf ) { burn_cycles(2); m_irq_polled = (m_sts & STS_IBF) != 0; execute_jcc((m_sts & STS_IBF) == 0); } OPHANDLER( jnt_0 ) { burn_cycles(2); execute_jcc(test_r(0) == 0); } OPHANDLER( jnt_1 ) { burn_cycles(2); execute_jcc(test_r(1) == 0); } OPHANDLER( jnz ) { burn_cycles(2); execute_jcc(m_a != 0); } @@ -1175,6 +1176,7 @@ void mcs48_cpu_device::device_start() save_item(NAME(m_dbbo)); save_item(NAME(m_irq_state)); + save_item(NAME(m_irq_polled)); save_item(NAME(m_irq_in_progress)); save_item(NAME(m_timer_overflow)); save_item(NAME(m_timer_flag)); @@ -1216,6 +1218,8 @@ void mcs48_cpu_device::device_reset() /* confirmed from interrupt logic description */ m_irq_in_progress = false; m_timer_overflow = false; + + m_irq_polled = false; } @@ -1239,6 +1243,13 @@ void mcs48_cpu_device::check_irqs() burn_cycles(2); m_irq_in_progress = true; + // force JNI to be taken (hack) + if (m_irq_polled) + { + m_pc = ((m_prevpc + 1) & 0x7ff) | (m_prevpc & 0x800); + execute_jcc(true); + } + /* transfer to location 0x03 */ push_pc_psw(); m_pc = 0x03; @@ -1324,6 +1335,10 @@ void mcs48_cpu_device::execute_run() // iterate over remaining cycles, guaranteeing at least one instruction do { + // check interrupts + check_irqs(); + m_irq_polled = false; + m_prevpc = m_pc; debugger_instruction_hook(m_pc); @@ -1331,9 +1346,6 @@ void mcs48_cpu_device::execute_run() unsigned opcode = opcode_fetch(); (this->*m_opcode_table[opcode])(); - // check interrupts - check_irqs(); - } while (m_icount > 0); } diff --git a/src/devices/cpu/mcs48/mcs48.h b/src/devices/cpu/mcs48/mcs48.h index fb78f63cc14..024c084c7f4 100644 --- a/src/devices/cpu/mcs48/mcs48.h +++ b/src/devices/cpu/mcs48/mcs48.h @@ -199,6 +199,7 @@ protected: uint8_t m_dbbo; /* 8-bit output data buffer (UPI-41 only) */ bool m_irq_state; /* true if the IRQ line is active */ + bool m_irq_polled; /* true if last instruction was JNI (and not taken) */ bool m_irq_in_progress; /* true if an IRQ is in progress */ bool m_timer_overflow; /* true on a timer overflow; cleared by taking interrupt */ bool m_timer_flag; /* true on a timer overflow; cleared on JTF */ @@ -257,7 +258,7 @@ protected: void execute_addc(uint8_t dat); void execute_jmp(uint16_t address); void execute_call(uint16_t address); - void execute_jcc(uint8_t result); + void execute_jcc(bool result); uint8_t p2_mask(); void expander_operation(expander_op operation, uint8_t port); void check_irqs(); diff --git a/src/devices/cpu/ns32000/ns32000.cpp b/src/devices/cpu/ns32000/ns32000.cpp index 4b796f8f345..acfddfcdd29 100644 --- a/src/devices/cpu/ns32000/ns32000.cpp +++ b/src/devices/cpu/ns32000/ns32000.cpp @@ -14,14 +14,14 @@ DEFINE_DEVICE_TYPE(NS32032, ns32032_device, "ns32032", "National Semiconductor N /* * TODO: * - prefetch queue - * - fetch/ea/data/rmw cycles + * - fetch/ea/data/rmw bus cycles * - address translation/abort - * - floating point and other unimplemented instructions + * - unimplemented instructions * - format 6: subp,addp - * - format 7: cmpm * - format 8: movus/movsu + * - format 14: rdval,wrval,lmr,smr * - cascaded interrupts - * - instruction cycles + * - opcode/operand/memory clock cycles * - 32332, 32532 */ @@ -71,22 +71,15 @@ enum trap_type : unsigned UND = 10, // undefined opcode }; -enum size_code : unsigned -{ - SIZE_B = 0, - SIZE_W = 1, - SIZE_D = 3, - SIZE_Q = 7, -}; - static const u32 size_mask[] = { 0x000000ffU, 0x0000ffffU, 0x00000000U, 0xffffffffU }; #define SP ((m_psr & PSR_S) ? m_sp1 : m_sp0) -ns32000_device::ns32000_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int databits, int addrbits) +template <int Width>ns32000_device<Width>::ns32000_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int databits, int addrbits) : cpu_device(mconfig, type, tag, owner, clock) , m_program_config("program", ENDIANNESS_LITTLE, databits, addrbits, 0) , m_interrupt_config("interrupt", ENDIANNESS_LITTLE, databits, addrbits, 0) + , m_fpu(*this, finder_base::DUMMY_TAG) , m_icount(0) { } @@ -106,7 +99,7 @@ ns32032_device::ns32032_device(const machine_config &mconfig, const char *tag, d { } -void ns32000_device::device_start() +template <int Width> void ns32000_device<Width>::device_start() { set_icountptr(m_icount); @@ -132,27 +125,27 @@ void ns32000_device::device_start() state_add(STATE_GENFLAGS, "GENFLAGS", m_psr).mask(0xfe7).formatstr("%10s").noshow(); // dedicated registers - int const reg_base = 16; - state_add(reg_base + 0, "PC", m_pc); - state_add(reg_base + 1, "SB", m_sb); - state_add(reg_base + 2, "FP", m_fp); - state_add(reg_base + 3, "SP1", m_sp1); - state_add(reg_base + 4, "SP0", m_sp0); - state_add(reg_base + 5, "INTBASE", m_intbase); - state_add(reg_base + 6, "PSR", m_psr); - state_add(reg_base + 7, "MOD", m_mod); - state_add(reg_base + 8, "CFG", m_cfg); + int index = 0; + state_add(index++, "PC", m_pc); + state_add(index++, "SB", m_sb); + state_add(index++, "FP", m_fp); + state_add(index++, "SP1", m_sp1); + state_add(index++, "SP0", m_sp0); + state_add(index++, "INTBASE", m_intbase); + state_add(index++, "PSR", m_psr); + state_add(index++, "MOD", m_mod); + state_add(index++, "CFG", m_cfg); // general registers for (unsigned i = 0; i < 8; i++) - state_add(i, util::string_format("R%d", i).c_str(), m_r[i]); + state_add(index++, util::string_format("R%d", i).c_str(), m_r[i]); // floating point registers - //for (unsigned i = 0; i < 8; i++) - // state_add(8 + i, util::string_format("F%d", i).c_str(), m_f[i]); + if (m_fpu) + m_fpu->state_add(*this, index); } -void ns32000_device::device_reset() +template <int Width> void ns32000_device<Width>::device_reset() { for (std::pair<int, address_space_config const *> s : memory_space_config()) space(has_configured_map(s.first) ? s.first : 0).cache(m_bus[s.first]); @@ -166,7 +159,7 @@ void ns32000_device::device_reset() m_wait = false; } -void ns32000_device::state_string_export(device_state_entry const &entry, std::string &str) const +template <int Width> void ns32000_device<Width>::state_string_export(device_state_entry const &entry, std::string &str) const { switch (entry.index()) { @@ -186,7 +179,7 @@ void ns32000_device::state_string_export(device_state_entry const &entry, std::s } } -s32 ns32000_device::displacement(unsigned &bytes) +template <int Width> s32 ns32000_device<Width>::displacement(unsigned &bytes) { s32 disp = space(0).read_byte(m_pc + bytes); if (BIT(disp, 7)) @@ -214,7 +207,7 @@ s32 ns32000_device::displacement(unsigned &bytes) return disp; } -void ns32000_device::decode(addr_mode *mode, unsigned imm_size, unsigned &bytes) +template <int Width> void ns32000_device<Width>::decode(addr_mode *mode, unsigned &bytes) { bool scaled[] = { false, false }; @@ -277,12 +270,14 @@ void ns32000_device::decode(addr_mode *mode, unsigned imm_size, unsigned &bytes) break; case 0x14: // immediate - switch (imm_size) + switch (mode[i].size) { - case SIZE_B: mode[i].base = space(0).read_byte(m_pc + bytes); bytes += 1; break; - case SIZE_W: mode[i].base = swapendian_int16(space(0).read_word_unaligned(m_pc + bytes)); bytes += 2; break; - case SIZE_D: mode[i].base = swapendian_int32(space(0).read_dword_unaligned(m_pc + bytes)); bytes += 4; break; + case SIZE_B: mode[i].imm = space(0).read_byte(m_pc + bytes); break; + case SIZE_W: mode[i].imm = swapendian_int16(space(0).read_word_unaligned(m_pc + bytes)); break; + case SIZE_D: mode[i].imm = swapendian_int32(space(0).read_dword_unaligned(m_pc + bytes)); break; + case SIZE_Q: mode[i].imm = swapendian_int64(space(0).read_qword_unaligned(m_pc + bytes)); break; } + bytes += mode[i].size + 1; mode[i].type = IMM; break; case 0x15: @@ -325,7 +320,7 @@ void ns32000_device::decode(addr_mode *mode, unsigned imm_size, unsigned &bytes) } } -u32 ns32000_device::ea(addr_mode const mode) +template <int Width> u32 ns32000_device<Width>::ea(addr_mode const mode) { u32 base; @@ -352,38 +347,36 @@ u32 ns32000_device::ea(addr_mode const mode) return base + mode.disp; } -u64 ns32000_device::gen_read(addr_mode mode, unsigned size) +template <int Width> u64 ns32000_device<Width>::gen_read(addr_mode mode) { u64 data = 0; switch (mode.type) { case IMM: - data = mode.base; + data = mode.imm; break; case REG: - if (size == SIZE_Q) - data = (u64(m_r[mode.gen ^ 1]) << 32) | m_r[mode.gen ^ 0]; - else - data = m_r[mode.gen] & size_mask[size]; + data = m_r[mode.gen] & size_mask[mode.size]; break; case TOS: - if (size) - if (size == 3) - data = space(0).read_dword_unaligned(SP); - else - data = space(0).read_word_unaligned(SP); - else - data = space(0).read_byte(SP); + switch (mode.size) + { + case SIZE_B: data = space(0).read_byte(SP); break; + case SIZE_W: data = space(0).read_word_unaligned(SP); break; + case SIZE_D: data = space(0).read_dword_unaligned(SP); break; + case SIZE_Q: data = space(0).read_qword_unaligned(SP); break; + } // post-increment stack pointer - SP += size + 1; + if (mode.access == READ) + SP += mode.size + 1; break; default: - switch (size) + switch (mode.size) { case SIZE_B: data = space(0).read_byte(ea(mode)); break; case SIZE_W: data = space(0).read_word_unaligned(ea(mode)); break; @@ -396,11 +389,11 @@ u64 ns32000_device::gen_read(addr_mode mode, unsigned size) return data; } -s64 ns32000_device::gen_read_sx(addr_mode mode, unsigned size) +template <int Width> s64 ns32000_device<Width>::gen_read_sx(addr_mode mode) { - u64 data = gen_read(mode, size); + u64 data = gen_read(mode); - switch (size) + switch (mode.size) { case SIZE_B: data = s8(data); break; case SIZE_W: data = s16(data); break; @@ -411,35 +404,30 @@ s64 ns32000_device::gen_read_sx(addr_mode mode, unsigned size) return data; } -void ns32000_device::gen_write(addr_mode mode, unsigned size, u64 data) +template <int Width> void ns32000_device<Width>::gen_write(addr_mode mode, u64 data) { switch (mode.type) { case REG: - if (size == SIZE_Q) - { - m_r[mode.gen ^ 0] = u32(data); - m_r[mode.gen ^ 1] = data >> 32; - } - else - m_r[mode.gen] = (m_r[mode.gen] & ~size_mask[size]) | (data & size_mask[size]); + m_r[mode.gen] = (m_r[mode.gen] & ~size_mask[mode.size]) | (data & size_mask[mode.size]); break; case TOS: // pre-decrement stack pointer - SP -= size + 1; + if (mode.access == WRITE) + SP -= mode.size + 1; - if (size) - if (size == 3) - space(0).write_dword_unaligned(SP, data); - else - space(0).write_word_unaligned(SP, data); - else - space(0).write_byte(SP, data); + switch (mode.size) + { + case SIZE_B: space(0).write_byte(SP, data); break; + case SIZE_W: space(0).write_word_unaligned(SP, data); break; + case SIZE_D: space(0).write_dword_unaligned(SP, data); break; + case SIZE_Q: space(0).write_qword_unaligned(SP, data); break; + } break; default: - switch (size) + switch (mode.size) { case SIZE_B: space(0).write_byte(ea(mode), data); break; case SIZE_W: space(0).write_word_unaligned(ea(mode), data); break; @@ -450,7 +438,7 @@ void ns32000_device::gen_write(addr_mode mode, unsigned size, u64 data) } } -bool ns32000_device::condition(unsigned const cc) +template <int Width> bool ns32000_device<Width>::condition(unsigned const cc) { switch (cc & 15) { @@ -492,7 +480,7 @@ bool ns32000_device::condition(unsigned const cc) return false; } -void ns32000_device::flags(u32 const src1, u32 const src2, u32 const dest, unsigned const size, bool const subtraction) +template <int Width> void ns32000_device<Width>::flags(u32 const src1, u32 const src2, u32 const dest, unsigned const size, bool const subtraction) { unsigned const sign_bit = (size + 1) * 8 - 1; @@ -508,7 +496,7 @@ void ns32000_device::flags(u32 const src1, u32 const src2, u32 const dest, unsig m_psr |= PSR_F; } -void ns32000_device::interrupt(unsigned const vector, u32 const return_address, bool const trap) +template <int Width> void ns32000_device<Width>::interrupt(unsigned const vector, u32 const return_address, bool const trap) { // clear trace pending flag if (vector == TRC) @@ -541,9 +529,13 @@ void ns32000_device::interrupt(unsigned const vector, u32 const return_address, m_pc = space(0).read_dword_unaligned(m_mod + 8) + u16(descriptor >> 16); // TODO: flush queue + m_sequential = false; + + if (trap && (machine().debug_flags & DEBUG_FLAG_ENABLED)) + debug()->exception_hook(vector); } -void ns32000_device::execute_run() +template <int Width> void ns32000_device<Width>::execute_run() { while (m_icount > 0) { @@ -597,18 +589,24 @@ void ns32000_device::execute_run() u8 const opbyte = space(0).read_byte(m_pc); unsigned bytes = 1; + unsigned tcy = 1; + m_sequential = true; if ((opbyte & 15) == 10) { // format 0: cccc 1010 - // Bcond dest + // Bcond dst // disp - s32 const dest = displacement(bytes); + s32 const dst = displacement(bytes); if (condition(opbyte >> 4)) - m_pc += dest; + { + m_pc += dst; + m_sequential = false; + tcy = 6; + } else - m_pc += bytes; + tcy = 7; } else if ((opbyte & 15) == 2) { @@ -616,15 +614,17 @@ void ns32000_device::execute_run() switch (opbyte >> 4) { case 0x0: - // BSR dest + // BSR dst // disp { - s32 const dest = displacement(bytes); + s32 const dst = displacement(bytes); SP -= 4; space(0).write_dword_unaligned(SP, m_pc + bytes); - m_pc += dest; + m_pc += dst; + m_sequential = false; + tcy = 6; } break; case 0x1: @@ -637,6 +637,8 @@ void ns32000_device::execute_run() SP += 4 + constant; m_pc = addr; + m_sequential = false; + tcy = 2; } break; case 0x2: @@ -656,6 +658,8 @@ void ns32000_device::execute_run() m_mod = u16(descriptor); m_sb = space(0).read_dword_unaligned(m_mod + 0); m_pc = space(0).read_dword_unaligned(m_mod + 8) + u16(descriptor >> 16); + m_sequential = false; + tcy = 16; } break; case 0x3: @@ -671,6 +675,8 @@ void ns32000_device::execute_run() m_sb = space(0).read_dword_unaligned(m_mod + 0); SP += constant; + m_sequential = false; + tcy = 2; } break; case 0x4: @@ -691,6 +697,8 @@ void ns32000_device::execute_run() m_sb = space(0).read_dword_unaligned(m_mod); SP += constant; + m_sequential = false; + tcy = 35; } else interrupt(ILL, m_pc); @@ -711,6 +719,8 @@ void ns32000_device::execute_run() sp += 2; m_sb = space(0).read_dword_unaligned(m_mod); + m_sequential = false; + tcy = 39; } else interrupt(ILL, m_pc); @@ -721,16 +731,17 @@ void ns32000_device::execute_run() { u8 const reglist = space(0).read_byte(m_pc + bytes++); + tcy = 13; for (unsigned i = 0; i < 8; i++) { if (BIT(reglist, i)) { SP -= 4; space(0).write_dword_unaligned(SP, m_r[i]); + tcy += 4; } } } - m_pc += bytes; break; case 0x7: // RESTORE reglist @@ -738,16 +749,17 @@ void ns32000_device::execute_run() { u8 const reglist = space(0).read_byte(m_pc + bytes++); + tcy = 12; for (unsigned i = 0; i < 8; i++) { if (BIT(reglist, i)) { m_r[7 - i] = space(0).read_dword_unaligned(SP); SP += 4; + tcy += 5; } } } - m_pc += bytes; break; case 0x8: // ENTER reglist,constant @@ -761,16 +773,17 @@ void ns32000_device::execute_run() m_fp = SP; SP -= constant; + tcy = 18; for (unsigned i = 0; i < 8; i++) { if (BIT(reglist, i)) { SP -= 4; space(0).write_dword_unaligned(SP, m_r[i]); + tcy += 4; } } } - m_pc += bytes; break; case 0x9: // EXIT reglist @@ -778,47 +791,54 @@ void ns32000_device::execute_run() { u8 const reglist = space(0).read_byte(m_pc + bytes++); + tcy = 17; for (unsigned i = 0; i < 8; i++) { if (BIT(reglist, i)) { m_r[7 - i] = space(0).read_dword_unaligned(SP); SP += 4; + tcy += 5; } } SP = m_fp; m_fp = space(0).read_dword_unaligned(SP); SP += 4; } - m_pc += bytes; break; case 0xa: // NOP - m_pc += bytes; + tcy = 3; break; case 0xb: // WAIT m_wait = true; - m_pc += bytes; + tcy = 6; break; case 0xc: // DIA m_wait = true; + tcy = 3; break; case 0xd: // FLAG if (m_psr & PSR_F) + { interrupt(FLG, m_pc); + tcy = 44; + } else - m_pc += bytes; + tcy = 6; break; case 0xe: // SVC interrupt(SVC, m_pc); + tcy = 40; break; case 0xf: // BPT interrupt(BPT, m_pc); + tcy = 40; break; } } @@ -832,187 +852,201 @@ void ns32000_device::execute_run() addr_mode mode[] = { addr_mode((opword >> 11) & 31), addr_mode(0x13) }; unsigned const quick = (opword >> 7) & 15; - unsigned const size = opbyte & 3; - - decode(mode, size, bytes); + size_code const size = size_code(opbyte & 3); switch ((opbyte >> 4) & 7) { case 0: - // ADDQi src,dest + // ADDQi src,dst // quick,gen // rmw.i { - mode[0].rmw(); + mode[0].rmw_i(size); + decode(mode, bytes); u32 const src1 = s32(quick << 28) >> 28; - u32 const src2 = gen_read(mode[0], size); + u32 const src2 = gen_read(mode[0]); - u32 const dest = src1 + src2; - flags(src1, src2, dest, size, false); + u32 const dst = src1 + src2; + flags(src1, src2, dst, size, false); - gen_write(mode[0], size, dest); + gen_write(mode[0], dst); + + tcy = (mode[0].type == REG) ? 4 : 6; } - m_pc += bytes; break; case 1: // CMPQi src1,src2 // quick,gen // read.i { - u32 const src1 = s32(quick << 28) >> 28; - u32 const src2 = gen_read(mode[0], size); + mode[0].read_i(size); + decode(mode, bytes); + + u32 const src1 = (s32(quick << 28) >> 28) & size_mask[size]; + u32 const src2 = gen_read(mode[0]); m_psr &= ~(PSR_N | PSR_Z | PSR_L); if ((size == SIZE_D && s32(src1) > s32(src2)) - || ((size == SIZE_W && s16(src1) > s16(src2)) - || ((size == SIZE_B && s8(src1) > s8(src2))))) + || ((size == SIZE_W && s16(src1) > s16(src2)) + || ((size == SIZE_B && s8(src1) > s8(src2))))) m_psr |= PSR_N; if (src1 == src2) m_psr |= PSR_Z; if ((size == SIZE_D && u32(src1) > u32(src2)) - || ((size == SIZE_W && u16(src1) > u16(src2)) - || ((size == SIZE_B && u8(src1) > u8(src2))))) + || ((size == SIZE_W && u16(src1) > u16(src2)) + || ((size == SIZE_B && u8(src1) > u8(src2))))) m_psr |= PSR_L; + + tcy = 3; } - m_pc += bytes; break; case 2: - // SPRi procreg,dest + // SPRi procreg,dst // short,gen // write.i + mode[0].write_i(size); + decode(mode, bytes); + switch (quick) { case 0x0: // US // TODO: user stack pointer? - gen_write(mode[0], size, m_sp1); - m_pc += bytes; + gen_write(mode[0], m_sp1); break; case 0x8: // FP - gen_write(mode[0], size, m_fp); - m_pc += bytes; + gen_write(mode[0], m_fp); break; case 0x9: // SP - gen_write(mode[0], size, SP); - m_pc += bytes; + gen_write(mode[0], SP); break; case 0xa: // SB - gen_write(mode[0], size, m_sb); - m_pc += bytes; + gen_write(mode[0], m_sb); break; case 0xd: // PSR if (!(m_psr & PSR_U)) - { - gen_write(mode[0], size, m_psr); - m_pc += bytes; - } + gen_write(mode[0], m_psr); else interrupt(ILL, m_pc); break; case 0xe: // INTBASE if (!(m_psr & PSR_U)) - { - gen_write(mode[0], size, m_intbase); - m_pc += bytes; - } + gen_write(mode[0], m_intbase); else interrupt(ILL, m_pc); break; case 0xf: // MOD - gen_write(mode[0], size, m_mod); - m_pc += bytes; + gen_write(mode[0], m_mod); break; } + + // TODO: tcy 21-27 + tcy = 21; break; case 3: - // Scondi dest + // Scondi dst // gen // write.i - gen_write(mode[0], size, condition(quick)); - m_pc += bytes; + { + mode[0].write_i(size); + decode(mode, bytes); + + bool const dst = condition(quick); + gen_write(mode[0], dst); + + tcy = dst ? 10 : 9; + } break; case 4: - // ACBi inc,index,dest + // ACBi inc,index,dst // quick,gen,disp // rmw.i { - mode[0].rmw(); + mode[0].rmw_i(size); + decode(mode, bytes); s32 const inc = s32(quick << 28) >> 28; - u32 index = gen_read(mode[0], size); - s32 const dest = displacement(bytes); + u32 index = gen_read(mode[0]); + s32 const dst = displacement(bytes); index += inc; - gen_write(mode[0], size, index); + gen_write(mode[0], index); if (index & size_mask[size]) - m_pc += dest; + { + m_pc += dst; + m_sequential = false; + + tcy = (mode[0].type == REG) ? 17 : 15; + } else - m_pc += bytes; + tcy = (mode[0].type == REG) ? 18 : 16; } break; case 5: - // MOVQi src,dest + // MOVQi src,dst // quick,gen // write.i - gen_write(mode[0], size, s32(quick << 28) >> 28); - m_pc += bytes; + mode[0].write_i(size); + decode(mode, bytes); + + gen_write(mode[0], s32(quick << 28) >> 28); + + tcy = (mode[0].type == REG) ? 3 : 2; break; case 6: // LPRi procreg,src // short,gen // read.i + mode[0].read_i(size); + decode(mode, bytes); + switch (quick) { - case 0x0: // US - // TODO: user stack pointer? - m_sp1 = gen_read(mode[0], size); - m_pc += bytes; + case 0x0: // UPSR + m_psr = (m_psr & 0xff00) | u8(gen_read(mode[0])); break; case 0x8: // FP - m_fp = gen_read(mode[0], size); - m_pc += bytes; + m_fp = gen_read(mode[0]); break; case 0x9: // SP - SP = gen_read(mode[0], size); - m_pc += bytes; + SP = gen_read(mode[0]); break; case 0xa: // SB - m_sb = gen_read(mode[0], size); - m_pc += bytes; + m_sb = gen_read(mode[0]); break; case 0xd: // PSR if (!(m_psr & PSR_U)) { - u32 const src = gen_read(mode[0], size); + u32 const src = gen_read(mode[0]); - if (size == 0) + if (size == SIZE_B) m_psr = (m_psr & 0xff00) | u8(src); else m_psr = src; - - m_pc += bytes; } else interrupt(ILL, m_pc); break; case 0xe: // INTBASE if (!(m_psr & PSR_U)) - { - m_intbase = gen_read(mode[0], size); - m_pc += bytes; - } + m_intbase = gen_read(mode[0]); else interrupt(ILL, m_pc); break; case 0xf: // MOD - m_mod = gen_read(mode[0], size); - m_pc += bytes; + m_mod = gen_read(mode[0]); + break; + default: + interrupt(UND, m_pc); break; } + + // TODO: tcy 19-33 + tcy = 19; break; case 7: // format 3: gggg gooo o111 11ii @@ -1022,96 +1056,142 @@ void ns32000_device::execute_run() // CXPD desc // gen // addr + if (size == SIZE_D) { mode[0].addr(); + decode(mode, bytes); - u32 const desc = gen_read(mode[0], SIZE_D); + u32 const descriptor = gen_read(mode[0]); SP -= 4; space(0).write_dword_unaligned(SP, m_mod); SP -= 4; space(0).write_dword_unaligned(SP, m_pc + bytes); - m_mod = u16(desc); + m_mod = u16(descriptor); m_sb = space(0).read_dword_unaligned(m_mod + 0); - m_pc = u16(desc >> 16) + space(0).read_dword_unaligned(m_mod + 8); + m_pc = space(0).read_dword_unaligned(m_mod + 8) + u16(descriptor >> 16); + m_sequential = false; + + tcy = 13; } + else + interrupt(UND, m_pc); break; case 0x2: // BICPSRi src // gen // read.[BW] - if (size == 0 || !(m_psr & PSR_U)) + if (size == SIZE_B || size == SIZE_W) { - // FIXME: read.D? - u16 const src = gen_read(mode[0], size); + mode[0].read_i(size); + decode(mode, bytes); + + if (size == SIZE_B || !(m_psr & PSR_U)) + { + u16 const src = gen_read(mode[0]); + + m_psr &= ~src; - m_psr &= ~src; - m_pc += bytes; + tcy = (size == SIZE_B) ? 18 : 30; + } + else + interrupt(ILL, m_pc); } else - interrupt(ILL, m_pc); + interrupt(UND, m_pc); break; case 0x4: - // JUMP dest + // JUMP dst // gen // addr - mode[0].addr(); + if (size == SIZE_D) + { + mode[0].addr(); + decode(mode, bytes); - // FIXME: size != 3? - m_pc = ea(mode[0]); + m_pc = ea(mode[0]); + m_sequential = false; + + tcy = 2; + } + else + interrupt(UND, m_pc); break; case 0x6: // BISPSRi src // gen // read.[BW] - if (size == 0 || !(m_psr & PSR_U)) + if (size == SIZE_B || size == SIZE_W) { - // FIXME: read.D? + mode[0].read_i(size); + decode(mode, bytes); + + if (size == SIZE_B || !(m_psr & PSR_U)) + { + u16 const src = gen_read(mode[0]); - u16 const src = gen_read(mode[0], size); + m_psr |= src; - m_psr |= src; - m_pc += bytes; + tcy = (size == SIZE_B) ? 18 : 30; + } + else + interrupt(ILL, m_pc); } else - interrupt(ILL, m_pc); + interrupt(UND, m_pc); break; case 0xa: // ADJSPi src // gen // read.i { - s32 const src = gen_read_sx(mode[0], size); + mode[0].read_i(size); + decode(mode, bytes); + + s32 const src = gen_read_sx(mode[0]); SP -= src; + + tcy = 6; } - m_pc += bytes; break; case 0xc: - // JSR dest + // JSR dst // gen // addr + if (size == SIZE_D) { mode[0].addr(); + decode(mode, bytes); SP -= 4; space(0).write_dword_unaligned(SP, m_pc + bytes); m_pc = ea(mode[0]); + m_sequential = false; + + tcy = 5; } + else + interrupt(UND, m_pc); break; case 0xe: // CASEi src // gen // read.i { - s32 const src = gen_read_sx(mode[0], size); + mode[0].read_i(size); + decode(mode, bytes); + + s32 const src = gen_read_sx(mode[0]); m_pc += src; + m_sequential = false; + + tcy = 4; } break; - default: interrupt(UND, m_pc); break; @@ -1126,175 +1206,214 @@ void ns32000_device::execute_run() bytes = 2; addr_mode mode[2] = { addr_mode((opword >> 11) & 31), addr_mode((opword >> 6) & 31) }; - unsigned const size = opbyte & 3; - - decode(mode, size, bytes); + size_code const size = size_code(opbyte & 3); switch ((opbyte >> 2) & 15) { case 0x0: - // ADDi src,dest + // ADDi src,dst // gen,gen // read.i,rmw.i { - mode[1].rmw(); + mode[0].read_i(size); + mode[1].rmw_i(size); + decode(mode, bytes); + + u32 const src1 = gen_read(mode[0]); + u32 const src2 = gen_read(mode[1]); - u32 const src1 = gen_read(mode[0], size); - u32 const src2 = gen_read(mode[1], size); + u32 const dst = src1 + src2; + flags(src1, src2, dst, size, false); - u32 const dest = src1 + src2; - flags(src1, src2, dest, size, false); + gen_write(mode[1], dst); - gen_write(mode[1], size, dest); + tcy = (mode[1].type == REG) ? 4 : 3; } - m_pc += bytes; break; case 0x1: // CMPi src1,src2 // gen,gen // read.i,read.i { - u32 const src1 = gen_read(mode[0], size); - u32 const src2 = gen_read(mode[1], size); + mode[0].read_i(size); + mode[1].read_i(size); + decode(mode, bytes); + + u32 const src1 = gen_read(mode[0]); + u32 const src2 = gen_read(mode[1]); m_psr &= ~(PSR_N | PSR_Z | PSR_L); if ((size == SIZE_D && s32(src1) > s32(src2)) - || ((size == SIZE_W && s16(src1) > s16(src2)) - || ((size == SIZE_B && s8(src1) > s8(src2))))) + || ((size == SIZE_W && s16(src1) > s16(src2)) + || ((size == SIZE_B && s8(src1) > s8(src2))))) m_psr |= PSR_N; if (src1 == src2) m_psr |= PSR_Z; if ((size == SIZE_D && u32(src1) > u32(src2)) - || ((size == SIZE_W && u16(src1) > u16(src2)) - || ((size == SIZE_B && u8(src1) > u8(src2))))) + || ((size == SIZE_W && u16(src1) > u16(src2)) + || ((size == SIZE_B && u8(src1) > u8(src2))))) m_psr |= PSR_L; + + tcy = 3; } - m_pc += bytes; break; case 0x2: - // BICi src,dest + // BICi src,dst // gen,gen // read.i,rmw.i { - mode[1].rmw(); + mode[0].read_i(size); + mode[1].rmw_i(size); + decode(mode, bytes); + + u32 const src = gen_read(mode[0]); + u32 const dst = gen_read(mode[1]); - u32 const src = gen_read(mode[0], size); - u32 const dest = gen_read(mode[1], size); + gen_write(mode[1], dst & ~src); - gen_write(mode[1], size, dest & ~src); + tcy = (mode[1].type == REG) ? 4 : 3; } - m_pc += bytes; break; case 0x4: - // ADDCi src,dest + // ADDCi src,dst // gen,gen // read.i,rmw.i { - mode[1].rmw(); + mode[0].read_i(size); + mode[1].rmw_i(size); + decode(mode, bytes); + + u32 const src1 = gen_read(mode[0]); + u32 const src2 = gen_read(mode[1]); - u32 const src1 = gen_read(mode[0], size); - u32 const src2 = gen_read(mode[1], size); + u32 const dst = src1 + src2 + (m_psr & PSR_C); + flags(src1, src2, dst, size, false); - u32 const dest = src1 + src2 + (m_psr & PSR_C); - flags(src1, src2, dest, size, false); + gen_write(mode[1], dst); - gen_write(mode[1], size, dest); + tcy = (mode[1].type == REG) ? 4 : 3; } - m_pc += bytes; break; case 0x5: - // MOVi src,dest + // MOVi src,dst // gen,gen // read.i,write.i { - u32 const src = gen_read(mode[0], size); + mode[0].read_i(size); + mode[1].write_i(size); + decode(mode, bytes); - gen_write(mode[1], size, src); + u32 const src = gen_read(mode[0]); + + gen_write(mode[1], src); + + tcy = (mode[1].type == REG) ? 3 : 1; } - m_pc += bytes; break; case 0x6: - // ORi src,dest + // ORi src,dst // gen,gen // read.i,rmw.i { - mode[1].rmw(); + mode[0].read_i(size); + mode[1].rmw_i(size); + decode(mode, bytes); + + u32 const src = gen_read(mode[0]); + u32 const dst = gen_read(mode[1]); - u32 const src = gen_read(mode[0], size); - u32 const dest = gen_read(mode[1], size); + gen_write(mode[1], src | dst); - gen_write(mode[1], size, src | dest); + tcy = (mode[1].type == REG) ? 4 : 3; } - m_pc += bytes; break; case 0x8: - // SUBi src,dest + // SUBi src,dst // gen,gen // read.i,rmw.i { - mode[1].rmw(); + mode[0].read_i(size); + mode[1].rmw_i(size); + decode(mode, bytes); - u32 const src1 = gen_read(mode[0], size); - u32 const src2 = gen_read(mode[1], size); + u32 const src1 = gen_read(mode[0]); + u32 const src2 = gen_read(mode[1]); - u32 const dest = src2 - src1; - flags(src1, src2, dest, size, true); + u32 const dst = src2 - src1; + flags(src1, src2, dst, size, true); - gen_write(mode[1], size, dest); + gen_write(mode[1], dst); + + tcy = (mode[1].type == REG) ? 4 : 3; } - m_pc += bytes; break; case 0x9: - // ADDR src,dest + // ADDR src,dst // gen,gen // addr,write.D - mode[0].addr(); + if (size == SIZE_D) + { + mode[0].addr(); + mode[1].write_i(size); + decode(mode, bytes); + + gen_write(mode[1], ea(mode[0])); - gen_write(mode[1], SIZE_D, ea(mode[0])); - m_pc += bytes; + tcy = (mode[1].type == REG) ? 3 : 2; + } + else + interrupt(UND, m_pc); break; case 0xa: - // ANDi src,dest + // ANDi src,dst // gen,gen // read.i,rmw.i { - mode[1].rmw(); + mode[0].read_i(size); + mode[1].rmw_i(size); + decode(mode, bytes); + + u32 const src = gen_read(mode[0]); + u32 const dst = gen_read(mode[1]); - u32 const src = gen_read(mode[0], size); - u32 const dest = gen_read(mode[1], size); + gen_write(mode[1], src & dst); - gen_write(mode[1], size, src & dest); + tcy = (mode[1].type == REG) ? 4 : 3; } - m_pc += bytes; break; case 0xc: - // SUBCi src,dest + // SUBCi src,dst // gen,gen // read.i,rmw.i { - mode[1].rmw(); + mode[0].read_i(size); + mode[1].rmw_i(size); + decode(mode, bytes); - u32 const src1 = gen_read(mode[0], size); - u32 const src2 = gen_read(mode[1], size); + u32 const src1 = gen_read(mode[0]); + u32 const src2 = gen_read(mode[1]); - u32 const dest = src2 - src1 - (m_psr & PSR_C); - flags(src1, src2, dest, size, true); + u32 const dst = src2 - src1 - (m_psr & PSR_C); + flags(src1, src2, dst, size, true); - gen_write(mode[1], size, dest); + gen_write(mode[1], dst); + + tcy = (mode[1].type == REG) ? 4 : 3; } - m_pc += bytes; break; case 0xd: // TBITi offset,base // gen,gen // read.i,regaddr { + mode[0].read_i(size); mode[1].regaddr(); + decode(mode, bytes); - s32 const offset = gen_read_sx(mode[0], size); + s32 const offset = gen_read_sx(mode[0]); if (mode[1].type == REG) { @@ -1302,6 +1421,8 @@ void ns32000_device::execute_run() m_psr |= PSR_F; else m_psr &= ~PSR_F; + + tcy = 4; } else { @@ -1311,23 +1432,27 @@ void ns32000_device::execute_run() m_psr |= PSR_F; else m_psr &= ~PSR_F; + + tcy = 14; } } - m_pc += bytes; break; case 0xe: - // XORi src,dest + // XORi src,dst // gen,gen // read.i,rmw.i { - mode[1].rmw(); + mode[0].read_i(size); + mode[1].rmw_i(size); + decode(mode, bytes); - u32 const src = gen_read(mode[0], size); - u32 const dest = gen_read(mode[1], size); + u32 const src = gen_read(mode[0]); + u32 const dst = gen_read(mode[1]); - gen_write(mode[1], size, src ^ dest); + gen_write(mode[1], src ^ dst); + + tcy = (mode[1].type == REG) ? 4 : 3; } - m_pc += bytes; break; } } @@ -1339,7 +1464,7 @@ void ns32000_device::execute_run() u16 const opword = space(0).read_word_unaligned(m_pc + bytes); bytes += 2; - unsigned const size = opword & 3; + size_code const size = size_code(opword & 3); // string instruction options bool const translate = BIT(opword, 7); @@ -1350,6 +1475,8 @@ void ns32000_device::execute_run() { case 0: // MOVSi options + tcy = (translate || backward || uw) ? 54 : 18; + m_psr &= ~PSR_F; while (m_r[0]) { @@ -1361,6 +1488,8 @@ void ns32000_device::execute_run() if (translate) data = space(0).read_byte(m_r[3] + u8(data)); + tcy += translate ? 27 : (backward || uw) ? 24 : 13; + bool const match = !((m_r[4] ^ data) & size_mask[size]); if ((uw == 1 && !match) || (uw == 3 && match)) { @@ -1388,10 +1517,11 @@ void ns32000_device::execute_run() m_r[0]--; } - m_pc += bytes; break; case 1: // CMPSi options + tcy = 53; + m_psr |= PSR_Z; m_psr &= ~(PSR_N | PSR_F | PSR_L); while (m_r[0]) @@ -1408,6 +1538,8 @@ void ns32000_device::execute_run() if (translate) src1 = space(0).read_byte(m_r[3] + u8(src1)); + tcy += translate ? 38 : 35; + bool const match = !((m_r[4] ^ src1) & size_mask[size]); if ((uw == 1 && !match) || (uw == 3 && match)) { @@ -1420,13 +1552,13 @@ void ns32000_device::execute_run() m_psr &= ~PSR_Z; if ((size == SIZE_D && s32(src1) > s32(src2)) - || ((size == SIZE_W && s16(src1) > s16(src2)) - || ((size == SIZE_B && s8(src1) > s8(src2))))) + || ((size == SIZE_W && s16(src1) > s16(src2)) + || ((size == SIZE_B && s8(src1) > s8(src2))))) m_psr |= PSR_N; if ((size == SIZE_D && u32(src1) > u32(src2)) - || ((size == SIZE_W && u16(src1) > u16(src2)) - || ((size == SIZE_B && u8(src1) > u8(src2))))) + || ((size == SIZE_W && u16(src1) > u16(src2)) + || ((size == SIZE_B && u8(src1) > u8(src2))))) m_psr |= PSR_L; break; @@ -1445,7 +1577,6 @@ void ns32000_device::execute_run() m_r[0]--; } - m_pc += bytes; break; case 2: // SETCFG cfglist @@ -1453,13 +1584,16 @@ void ns32000_device::execute_run() if (!(m_psr & PSR_U)) { m_cfg = (opword >> 7) & 15; - m_pc += bytes; + + tcy = 15; } else interrupt(ILL, m_pc); break; case 3: // SKPSi options + tcy = 51; + m_psr &= ~PSR_F; while (m_r[0]) { @@ -1471,6 +1605,8 @@ void ns32000_device::execute_run() if (translate) data = space(0).read_byte(m_r[3] + u8(data)); + tcy += translate ? 30 : 27; + bool const match = !((m_r[4] ^ data) & size_mask[size]); if ((uw == 1 && !match) || (uw == 3 && match)) { @@ -1485,7 +1621,6 @@ void ns32000_device::execute_run() m_r[0]--; } - m_pc += bytes; break; default: interrupt(UND, m_pc); @@ -1500,45 +1635,48 @@ void ns32000_device::execute_run() bytes += 2; addr_mode mode[] = { addr_mode((opword >> 11) & 31), addr_mode((opword >> 6) & 31) }; - unsigned const size = opword & 3; - - // byte-size immediates for ROT, ASH and LSH - decode(mode, ((opword >> 2) & 10) ? size : SIZE_B, bytes); + size_code const size = size_code(opword & 3); switch ((opword >> 2) & 15) { case 0x0: - // ROTi count,dest + // ROTi count,dst // gen,gen // read.B,rmw.i { - mode[1].rmw(); + mode[0].read_i(SIZE_B); + mode[1].rmw_i(size); + decode(mode, bytes); - s32 const count = gen_read_sx(mode[0], SIZE_B); - u32 const src = gen_read(mode[1], size); + s32 const count = gen_read_sx(mode[0]); + u32 const src = gen_read(mode[1]); unsigned const limit = (size + 1) * 8 - 1; - u32 const dest = ((src << (count & limit)) & size_mask[size]) | ((src & size_mask[size]) >> (limit - (count & limit))); + u32 const dst = ((src << (count & limit)) & size_mask[size]) | ((src & size_mask[size]) >> (limit - (count & limit) + 1)); + + gen_write(mode[1], dst); - gen_write(mode[1], size, dest); + tcy = 14 + (count & limit); } - m_pc += bytes; break; case 0x1: - // ASHi count,dest + // ASHi count,dst // gen,gen // read.B,rmw.i { - mode[1].rmw(); + mode[0].read_i(SIZE_B); + mode[1].rmw_i(size); + decode(mode, bytes); - s32 const count = gen_read_sx(mode[0], SIZE_B); - s32 const src = gen_read_sx(mode[1], size); + s32 const count = gen_read_sx(mode[0]); + s32 const src = gen_read_sx(mode[1]); - u32 const dest = (count < 0) ? (src >> -count) : (src << count); + u32 const dst = (count < 0) ? (src >> -count) : (src << count); - gen_write(mode[1], size, dest); + gen_write(mode[1], dst); + + tcy = 14 + std::abs(count); } - m_pc += bytes; break; case 0x2: // CBITi offset,base @@ -1549,9 +1687,11 @@ void ns32000_device::execute_run() // gen,gen // read.i,regaddr { + mode[0].read_i(size); mode[1].regaddr(); + decode(mode, bytes); - s32 const offset = gen_read_sx(mode[0], size); + s32 const offset = gen_read_sx(mode[0]); if (mode[1].type == REG) { @@ -1561,6 +1701,8 @@ void ns32000_device::execute_run() m_psr &= ~PSR_F; m_r[mode[1].gen] &= ~(1U << (offset & 31)); + + tcy = 7; } else { @@ -1573,28 +1715,32 @@ void ns32000_device::execute_run() m_psr &= ~PSR_F; space(0).write_byte(byte_ea, byte & ~(1U << (offset & 7))); + + tcy = 15; } } - m_pc += bytes; break; case 0x4: interrupt(UND, m_pc); break; case 0x5: - // LSHi count,dest + // LSHi count,dst // gen,gen // read.B,rmw.i { - mode[1].rmw(); + mode[0].read_i(SIZE_B); + mode[1].rmw_i(size); + decode(mode, bytes); + + s32 const count = gen_read_sx(mode[0]); + u32 const src = gen_read(mode[1]); - s32 const count = gen_read_sx(mode[0], SIZE_B); - u32 const src = gen_read(mode[1], size); + u32 const dst = (count < 0) ? (src >> -count) : (src << count); - u32 const dest = (count < 0) ? (src >> -count) : (src << count); + gen_write(mode[1], dst); - gen_write(mode[1], size, dest); + tcy = 14 + std::abs(count); } - m_pc += bytes; break; case 0x6: // SBITi offset,base @@ -1605,9 +1751,11 @@ void ns32000_device::execute_run() // gen,gen // read.i,regaddr { + mode[0].read_i(size); mode[1].regaddr(); + decode(mode, bytes); - s32 const offset = gen_read_sx(mode[0], size); + s32 const offset = gen_read_sx(mode[0]); if (mode[1].type == REG) { @@ -1616,7 +1764,9 @@ void ns32000_device::execute_run() else m_psr &= ~PSR_F; - m_r[mode[1].gen] |= ~(1U << (offset & 31)); + m_r[mode[1].gen] |= (1U << (offset & 31)); + + tcy = 7; } else { @@ -1628,17 +1778,22 @@ void ns32000_device::execute_run() else m_psr &= ~PSR_F; - space(0).write_byte(byte_ea, byte | ~(1U << (offset & 7))); + space(0).write_byte(byte_ea, byte | (1U << (offset & 7))); + + tcy = 15; } } - m_pc += bytes; break; case 0x8: - // NEGi src,dest + // NEGi src,dst // gen,gen // read.i,write.i { - u32 const src = gen_read(mode[0], size); + mode[0].read_i(size); + mode[1].write_i(size); + decode(mode, bytes); + + u32 const src = gen_read(mode[0]); if (src) m_psr |= PSR_C; @@ -1648,75 +1803,93 @@ void ns32000_device::execute_run() if ((src ^ ~(size_mask[size] >> 1)) & size_mask[size]) { m_psr &= ~PSR_F; - gen_write(mode[1], size, -src); + gen_write(mode[1], -src); } else { m_psr |= PSR_F; - gen_write(mode[1], size, src); + gen_write(mode[1], src); } + + tcy = 5; } - m_pc += bytes; break; case 0x9: - // NOTi src,dest + // NOTi src,dst // gen,gen // read.i,write.i { - u32 const src = gen_read(mode[0], size); + mode[0].read_i(size); + mode[1].write_i(size); + decode(mode, bytes); - gen_write(mode[1], size, src ^ 1U); + u32 const src = gen_read(mode[0]); + + gen_write(mode[1], src ^ 1U); + + tcy = 5; } - m_pc += bytes; break; case 0xa: interrupt(UND, m_pc); break; case 0xb: - // SUBPi src,dest + // SUBPi src,dst // gen,gen // read.i,rmw.i fatalerror("unimplemented: subp (%s)\n", machine().describe_context()); + + // TODO: tcy 16/18 break; case 0xc: - // ABSi src,dest + // ABSi src,dst // gen,gen // read.i,write.i { - s32 const src = gen_read_sx(mode[0], size); + mode[0].read_i(size); + mode[1].write_i(size); + decode(mode, bytes); - s32 const dest = std::abs(src); + s32 const src = gen_read_sx(mode[0]); m_psr &= ~PSR_F; - if (BIT(dest, ((size + 1) * 8 - 1))) + if (src == s32(0x80000000) >> (32 - (size + 1) * 8)) { m_psr |= PSR_F; - gen_write(mode[1], size, src); + gen_write(mode[1], src); } else - gen_write(mode[1], size, dest); + gen_write(mode[1], std::abs(src)); + + tcy = (src < 0) ? 9 : 8; } - m_pc += bytes; break; case 0xd: - // COMi src,dest + // COMi src,dst // gen,gen // read.i,write.i { - u32 const src = gen_read(mode[0], size); + mode[0].read_i(size); + mode[1].write_i(size); + decode(mode, bytes); + + u32 const src = gen_read(mode[0]); + + gen_write(mode[1], ~src); - gen_write(mode[1], size, ~src); + tcy = 7; } - m_pc += bytes; break; case 0xe: // IBITi offset,base // gen,gen // read.i,regaddr { + mode[0].read_i(size); mode[1].regaddr(); + decode(mode, bytes); - s32 const offset = gen_read_sx(mode[0], size); + s32 const offset = gen_read_sx(mode[0]); if (mode[1].type == REG) { @@ -1726,6 +1899,8 @@ void ns32000_device::execute_run() m_psr &= ~PSR_F; m_r[mode[1].gen] ^= (1U << (offset & 31)); + + tcy = 9; } else { @@ -1738,15 +1913,18 @@ void ns32000_device::execute_run() m_psr &= ~PSR_F; space(0).write_byte(byte_ea, byte ^ (1U << (offset & 7))); + + tcy = 17; } } - m_pc += bytes; break; case 0xf: - // ADDPi src,dest + // ADDPi src,dst // gen,gen // read.i,rmw.i fatalerror("unimplemented: addp (%s)\n", machine().describe_context()); + + // TODO: tcy 16/18 break; } } @@ -1758,9 +1936,7 @@ void ns32000_device::execute_run() bytes += 2; addr_mode mode[2] = { addr_mode((opword >> 11) & 31), addr_mode((opword >> 6) & 31) }; - unsigned const size = opword & 3; - - decode(mode, size, bytes); + size_code const size = size_code(opword & 3); switch ((opword >> 2) & 15) { @@ -1771,164 +1947,280 @@ void ns32000_device::execute_run() { mode[0].addr(); mode[1].addr(); + decode(mode, bytes); u32 block1 = ea(mode[0]); u32 block2 = ea(mode[1]); - s32 length = displacement(bytes); + unsigned const num = displacement(bytes) / (size + 1) + 1; // TODO: aligned/unaligned transfers? - for (unsigned num = 0; num * (size + 1) < length; num++) + for (unsigned i = 0; i < num; i++) { switch (size) { case SIZE_B: space(0).write_byte(block2, space(0).read_byte(block1)); break; case SIZE_W: space(0).write_word_unaligned(block2, space(0).read_word_unaligned(block1)); break; case SIZE_D: space(0).write_dword_unaligned(block2, space(0).read_dword_unaligned(block1)); break; + default: + // can't happen + break; } block1 += (size + 1); block2 += (size + 1); } + + tcy = 20 + 3 * num; } - m_pc += bytes; break; case 0x1: // CMPMi block1,block2,length // gen,gen,disp // addr,addr - fatalerror("unimplemented: cmpm (%s)\n", machine().describe_context()); + { + mode[0].addr(); + mode[1].addr(); + decode(mode, bytes); + + u32 block1 = ea(mode[0]); + u32 block2 = ea(mode[1]); + unsigned const num = displacement(bytes) / (size + 1) + 1; + + tcy = 24; + + m_psr |= PSR_Z; + m_psr &= ~(PSR_N | PSR_L); + + // TODO: aligned/unaligned transfers? + for (unsigned i = 0; i < num; i++) + { + s32 int1 = 0; + s32 int2 = 0; + + switch (size) + { + case SIZE_B: + int1 = s8(space(0).read_byte(block1)); + int2 = s8(space(0).read_byte(block2)); + break; + case SIZE_W: + int1 = s16(space(0).read_word_unaligned(block1)); + int2 = s16(space(0).read_word_unaligned(block2)); + break; + case SIZE_D: + int1 = s32(space(0).read_dword_unaligned(block1)); + int2 = s32(space(0).read_dword_unaligned(block2)); + break; + default: + // can't happen + break; + } + + tcy += 9; + + if (int1 != int2) + { + m_psr &= ~PSR_Z; + if (int1 > int2) + m_psr |= PSR_N; + if (u32(int1) > u32(int2)) + m_psr |= PSR_L; + + break; + } + + block1 += (size + 1); + block2 += (size + 1); + } + } break; case 0x2: // INSSi src,base,offset,length // gen,gen,imm // read.i,regaddr { + mode[0].read_i(size); mode[1].regaddr(); + decode(mode, bytes); u8 const imm = space(0).read_byte(m_pc + bytes++); unsigned const offset = imm >> 5; u32 const mask = ((2ULL << (imm & 31)) - 1) << offset; - u32 const src = gen_read(mode[0], size); - u32 const base = gen_read(mode[1], SIZE_D); + u32 const src = gen_read(mode[0]); + u32 const base = gen_read(mode[1]); - gen_write(mode[1], SIZE_D, (base & ~mask) | ((src << offset) & mask)); + gen_write(mode[1], (base & ~mask) | ((src << offset) & mask)); + + // TODO: tcy 39-49 + tcy = 39; } - m_pc += bytes; break; case 0x3: - // EXTSi base,dest,offset,length + // EXTSi base,dst,offset,length // gen,gen,imm // regaddr,write.i { mode[0].regaddr(); + mode[1].write_i(size); + decode(mode, bytes); u8 const imm = space(0).read_byte(m_pc + bytes++); unsigned const offset = imm >> 5; u32 const mask = (2ULL << (imm & 31)) - 1; - u32 const base = gen_read(mode[0], SIZE_D); - u32 const dest = (base >> offset) & mask; + u32 const base = gen_read(mode[0]); + u32 const dst = (base >> offset) & mask; + + gen_write(mode[1], dst); - gen_write(mode[1], size, dest); + // TODO: tcy 26-36 + tcy = 26; } - m_pc += bytes; break; case 0x4: - // MOVXBW src,dest + // MOVXBW src,dst // gen,gen // read.B,write.W + if (size == SIZE_B) { - u8 const src = gen_read(mode[0], size); - s16 const dest = s8(src); + mode[0].read_i(size); + mode[1].write_i(SIZE_W); + decode(mode, bytes); + + u8 const src = gen_read(mode[0]); + s16 const dst = s8(src); - gen_write(mode[1], SIZE_W, dest); + gen_write(mode[1], dst); + + tcy = 6; } - m_pc += bytes; + else + interrupt(UND, m_pc); break; case 0x5: - // MOVZBW src,dest + // MOVZBW src,dst // gen,gen // read.B,write.W + if (size == SIZE_B) { - u8 const src = gen_read(mode[0], size); - u16 const dest = src; + mode[0].read_i(size); + mode[1].write_i(SIZE_W); + decode(mode, bytes); + + u8 const src = gen_read(mode[0]); + u16 const dst = src; - gen_write(mode[1], SIZE_W, dest); + gen_write(mode[1], dst); + + tcy = 5; } - m_pc += bytes; + else + interrupt(UND, m_pc); break; case 0x6: - // MOVZiD src,dest + // MOVZiD src,dst // gen,gen // read.[BW],write.D + if (size == SIZE_B || size == SIZE_W) { - u32 const src = gen_read(mode[0], size); + mode[0].read_i(size); + mode[1].write_i(SIZE_D); + decode(mode, bytes); - gen_write(mode[1], SIZE_D, src); + u32 const src = gen_read(mode[0]); + + gen_write(mode[1], src); + + tcy = 5; } - m_pc += bytes; + else + interrupt(UND, m_pc); break; case 0x7: - // MOVXiD src,dest + // MOVXiD src,dst // gen,gen // read.[BW],write.D + if (size == SIZE_B || size == SIZE_W) { - u32 const src = gen_read(mode[0], size); - s32 const dest = (size == SIZE_W) ? s16(src) : s8(src); + mode[0].read_i(size); + mode[1].write_i(SIZE_D); + decode(mode, bytes); - gen_write(mode[1], SIZE_D, dest); + u32 const src = gen_read(mode[0]); + s32 const dst = (size == SIZE_W) ? s16(src) : s8(src); + + gen_write(mode[1], dst); + + tcy = 6; } - m_pc += bytes; + else + interrupt(UND, m_pc); break; case 0x8: - // MULi src,dest + // MULi src,dst // gen,gen // read.i,rmw.i { - mode[1].rmw(); + mode[0].read_i(size); + mode[1].rmw_i(size); + decode(mode, bytes); - u32 const src1 = gen_read(mode[0], size); - u32 const src2 = gen_read(mode[1], size); + u32 const src1 = gen_read(mode[0]); + u32 const src2 = gen_read(mode[1]); - u32 const dest = src1 * src2; + u32 const dst = src1 * src2; - gen_write(mode[1], size, dest); + gen_write(mode[1], dst); + + tcy = 15; } - m_pc += bytes; break; case 0x9: - // MEIi src,dest + // MEIi src,dst // gen,gen // read.i,rmw.2i { - mode[1].rmw(); - unsigned const size2 = size * 2 + 1; + mode[0].read_i(size); + mode[1].rmw_i(size_code(size * 2 + 1)); + decode(mode, bytes); - u32 const src1 = gen_read(mode[0], size); - u32 const src2 = gen_read(mode[1], size); + u32 const src1 = gen_read(mode[0]); + u32 const src2 = ((mode[1].type == REG) + ? m_r[mode[1].gen ^ 0] + : gen_read(mode[1])) & size_mask[size]; - u64 const dest = mulu_32x32(src1, src2); + u64 const dst = mulu_32x32(src1, src2); - gen_write(mode[1], size2, dest); + if (mode[1].type == REG) + { + m_r[mode[1].gen ^ 0] = (m_r[mode[1].gen ^ 0] & ~size_mask[size]) | ((dst >> 0) & size_mask[size]); + m_r[mode[1].gen ^ 1] = (m_r[mode[1].gen ^ 1] & ~size_mask[size]) | ((dst >> ((size + 1) * 8)) & size_mask[size]); + } + else + gen_write(mode[1], dst); + + tcy = 23; } - m_pc += bytes; break; case 0xa: interrupt(UND, m_pc); break; case 0xb: - // DEIi src,dest + // DEIi src,dst // gen,gen // read.i,rmw.2i { - mode[1].rmw(); - unsigned const size2 = size * 2 + 1; + mode[0].read_i(size); + mode[1].rmw_i(size_code(size * 2 + 1)); + decode(mode, bytes); - u32 const src1 = gen_read(mode[0], size); + u32 const src1 = gen_read(mode[0]); if (src1) { - u64 const src2 = gen_read(mode[1], size2); + u64 const src2 = (mode[1].type == REG) + ? (u64(m_r[mode[1].gen ^ 1] & size_mask[size]) << ((size + 1) * 8)) | (m_r[mode[1].gen ^ 0] & size_mask[size]) + : gen_read(mode[1]); u32 const quotient = src2 / src1; u32 const remainder = src2 % src1; @@ -1937,11 +2229,15 @@ void ns32000_device::execute_run() { m_r[mode[1].gen ^ 0] = (m_r[mode[1].gen ^ 0] & ~size_mask[size]) | (remainder & size_mask[size]); m_r[mode[1].gen ^ 1] = (m_r[mode[1].gen ^ 1] & ~size_mask[size]) | (quotient & size_mask[size]); + + tcy = 31; } else - gen_write(mode[1], size2, (u64(quotient) << ((size + 1) * 8)) | remainder); + { + gen_write(mode[1], (u64(quotient) << ((size + 1) * 8)) | remainder); - m_pc += bytes; + tcy = 38; + } } else { @@ -1954,21 +2250,25 @@ void ns32000_device::execute_run() } break; case 0xc: - // QUOi src,dest + // QUOi src,dst // gen,gen // read.i,rmw.i { - mode[1].rmw(); + mode[0].read_i(size); + mode[1].rmw_i(size); + decode(mode, bytes); - s32 const src1 = gen_read_sx(mode[0], size); + s32 const src1 = gen_read_sx(mode[0]); if (src1) { - s32 const src2 = gen_read_sx(mode[1], size); + s32 const src2 = gen_read_sx(mode[1]); + + s32 const dst = src2 / src1; - s32 const dest = src2 / src1; + gen_write(mode[1], dst); - gen_write(mode[1], size, dest); - m_pc += bytes; + // TODO: tcy 49-55 + tcy = 49; } else { @@ -1981,21 +2281,25 @@ void ns32000_device::execute_run() } break; case 0xd: - // REMi src,dest + // REMi src,dst // gen,gen // read.i,rmw.i { - mode[1].rmw(); + mode[0].read_i(size); + mode[1].rmw_i(size); + decode(mode, bytes); - s32 const src1 = gen_read_sx(mode[0], size); + s32 const src1 = gen_read_sx(mode[0]); if (src1) { - s32 const src2 = gen_read_sx(mode[1], size); + s32 const src2 = gen_read_sx(mode[1]); + + s32 const dst = src2 % src1; - s32 const dest = src2 % src1; + gen_write(mode[1], dst); - gen_write(mode[1], size, dest); - m_pc += bytes; + // TODO: tcy 57-62 + tcy = 57; } else { @@ -2008,21 +2312,25 @@ void ns32000_device::execute_run() } break; case 0xe: - // MODi src,dest + // MODi src,dst // gen,gen // read.i,rmw.i { - mode[1].rmw(); + mode[0].read_i(size); + mode[1].rmw_i(size); + decode(mode, bytes); - u32 const src1 = gen_read_sx(mode[0], size); + s32 const src1 = gen_read_sx(mode[0]); if (src1) { - u32 const src2 = gen_read_sx(mode[1], size); + s32 const src2 = gen_read_sx(mode[1]); - s32 const dest = (src1 + (src2 % src1)) % src1; + s32 const dst = (src1 + (src2 % src1)) % src1; - gen_write(mode[1], size, dest); - m_pc += bytes; + gen_write(mode[1], dst); + + // TODO: tcy 54-73 + tcy = 54; } else { @@ -2035,26 +2343,29 @@ void ns32000_device::execute_run() } break; case 0xf: - // DIVi src,dest + // DIVi src,dst // gen,gen // read.i,rmw.i { - mode[1].rmw(); + mode[0].read_i(size); + mode[1].rmw_i(size); + decode(mode, bytes); - s32 const src1 = gen_read_sx(mode[0], size); + s32 const src1 = gen_read_sx(mode[0]); if (src1) { - s32 const src2 = gen_read_sx(mode[1], size); + s32 const src2 = gen_read_sx(mode[1]); s32 const quotient = src2 / src1; s32 const remainder = src2 % src1; if ((quotient < 0) && remainder) - gen_write(mode[1], size, quotient - 1); + gen_write(mode[1], quotient - 1); else - gen_write(mode[1], size, quotient); + gen_write(mode[1], quotient); - m_pc += bytes; + // TODO: tcy 58-68 + tcy = 58; } else { @@ -2080,108 +2391,150 @@ void ns32000_device::execute_run() addr_mode mode[2] = { addr_mode((opword >> 11) & 31), addr_mode((opword >> 6) & 31) }; unsigned const reg = (opword >> 3) & 7; - unsigned const size = opword & 3; - - decode(mode, size, bytes); + size_code const size = size_code(opword & 3); switch ((opword & 4) | (opbyte >> 6)) { case 0: - // EXTi offset,base,dest,length + // EXTi offset,base,dst,length // reg,gen,gen,disp // regaddr,write.i { mode[0].regaddr(); + mode[1].write_i(size); + decode(mode, bytes); s32 const offset = m_r[reg]; s32 const length = displacement(bytes); u32 const mask = (1U << length) - 1; - u32 dest; + u32 dst; if (mode[0].type != REG) { u32 const base_ea = ea(mode[0]) + (offset >> 3); u32 const base = space(0).read_dword_unaligned(base_ea); - dest = (base >> (offset & 7)); + dst = (base >> (offset & 7)); + + // TODO: tcy 17-51 + tcy = 17; } else - dest = (m_r[mode[0].gen] >> (offset & 31)); + { + dst = (m_r[mode[0].gen] >> (offset & 31)); + + // TODO: tcy 19-29 + tcy = 19; + } - gen_write(mode[1], size, dest & mask); + gen_write(mode[1], dst & mask); } break; case 1: - // CVTP offset,base,dest + // CVTP offset,base,dst // reg,gen,gen // addr,write.D + if (size == SIZE_D) { - // TODO: size != SIZE_D? mode[0].addr(); + mode[1].write_i(size); + decode(mode, bytes); s32 const offset = s32(m_r[reg]); u32 const base = ea(mode[0]); - gen_write(mode[1], size, base * 8 + offset); + gen_write(mode[1], base * 8 + offset); + + tcy = 7; } + else + interrupt(UND, m_pc); break; case 2: // INSi offset,src,base,length // reg,gen,gen,disp // read.i,regaddr { + mode[0].read_i(size); mode[1].regaddr(); + decode(mode, bytes); s32 const offset = m_r[reg]; s32 const length = displacement(bytes); - u32 const src = gen_read(mode[0], size); + u32 const src = gen_read(mode[0]); - u32 dest; + u32 dst; if (mode[1].type == REG) { u32 const base = m_r[mode[1].gen]; u32 const mask = ((1U << length) - 1) << (offset & 31); - dest = (base & ~mask) | ((src << (offset & 31)) & mask); + dst = (base & ~mask) | ((src << (offset & 31)) & mask); + + // TODO: tcy 29-39 + tcy = 29; } else { - u32 const base_ea = ea(mode[0]) + (offset >> 3); + u32 const base_ea = ea(mode[1]) + (offset >> 3); u32 const base = space(0).read_dword_unaligned(base_ea); u32 const mask = ((1U << length) - 1) << (offset & 7); - dest = (base & ~mask) | ((src << (offset & 7)) & mask); + dst = (base & ~mask) | ((src << (offset & 7)) & mask); + + // TODO: tcy 28-96 + tcy = 28; } - gen_write(mode[1], SIZE_D, dest); + gen_write(mode[1], dst); } break; case 3: - // CHECKi dest,bounds,src + // CHECKi dst,bounds,src // reg,gen,gen // addr,read.i { mode[0].addr(); + mode[1].read_i(size); + decode(mode, bytes); u32 const bounds = ea(mode[0]); - s32 const src = gen_read_sx(mode[1], size); + s32 const src = gen_read_sx(mode[1]); s32 lower = 0; s32 upper = 0; switch (size) { - case SIZE_B: lower = s8(space(0).read_byte(bounds + 0)); upper = s8(space(0).read_byte(bounds + 1)); break; - case SIZE_W: lower = s16(space(0).read_word_unaligned(bounds + 0)); upper = s16(space(0).read_word_unaligned(bounds + 2)); break; - case SIZE_D: lower = s32(space(0).read_dword_unaligned(bounds + 0)); upper = s32(space(0).read_dword_unaligned(bounds + 4)); break; + case SIZE_B: + upper = s8(space(0).read_byte(bounds + 0)); + lower = s8(space(0).read_byte(bounds + 1)); + break; + case SIZE_W: + upper = s16(space(0).read_word_unaligned(bounds + 0)); + lower = s16(space(0).read_word_unaligned(bounds + 2)); + break; + case SIZE_D: + upper = s32(space(0).read_dword_unaligned(bounds + 0)); + lower = s32(space(0).read_dword_unaligned(bounds + 4)); + break; + default: + // can't happen + break; } if (src >= lower && src <= upper) { m_psr &= ~PSR_F; m_r[reg] = src - lower; + + tcy = 11; } else + { m_psr |= PSR_F; + + tcy = (src >= lower) ? 7 : 10; + } } break; case 4: @@ -2189,10 +2542,16 @@ void ns32000_device::execute_run() // reg,gen,gen // read.i,read.i { - u32 const length = gen_read(mode[0], size); - u32 const index = gen_read(mode[1], size); + mode[0].read_i(size); + mode[1].read_i(size); + decode(mode, bytes); + + u32 const length = gen_read(mode[0]); + u32 const index = gen_read(mode[1]); m_r[reg] = m_r[reg] * (length + 1) + index; + + tcy = 25; } break; case 5: @@ -2200,10 +2559,12 @@ void ns32000_device::execute_run() // gen,gen // read.i,rmw.B { - mode[1].rmw(); + mode[0].read_i(size); + mode[1].rmw_i(SIZE_B); + decode(mode, bytes); - u32 const base = gen_read(mode[0], size); - u32 offset = gen_read(mode[1], SIZE_B); + u32 const base = gen_read(mode[0]); + u32 offset = gen_read(mode[1]); unsigned const limit = (size + 1) * 8; m_psr |= PSR_F; @@ -2216,39 +2577,348 @@ void ns32000_device::execute_run() else offset++; - gen_write(mode[1], SIZE_B, offset & limit); + gen_write(mode[1], offset & (limit - 1)); + + // TODO: tcy 24-28 + tcy = 24; } break; case 6: - // MOVSU/MOVUS src,dest + // MOVSU/MOVUS src,dst // gen,gen // addr,addr { mode[0].addr(); mode[1].addr(); + decode(mode, bytes); fatalerror("unimplemented: movsu/movus (%s)\n", machine().describe_context()); + + tcy = 33; } break; } } - m_pc += bytes; break; - case 0x3e: // format 9 - // TODO: floating point + case 0x3e: + // format 9: xxxx xyyy yyoo ofii 0011 1110 + if (m_cfg & CFG_F) + { + if (!m_fpu) + fatalerror("floating point unit not configured (%s)\n", machine().describe_context()); + + u16 const opword = space(0).read_word_unaligned(m_pc + bytes); + bytes += 2; + + addr_mode mode[2] = { addr_mode((opword >> 11) & 31), addr_mode((opword >> 6) & 31) }; + size_code const size_f = BIT(opword, 0) ? SIZE_D : SIZE_Q; + size_code const size = size_code(opword & 3); + + m_fpu->write_id(opbyte); + m_fpu->write_op(swapendian_int16(opword)); + + switch ((opword >> 3) & 7) + { + case 0: + // MOVif src,dst + // gen,gen + // read.i,write.f + mode[0].read_i(size); + mode[1].write_f(size_f); + decode(mode, bytes); + + if (slave(mode[0], mode[1])) + interrupt(FPU, m_pc); + break; + case 1: + // LFSR src + // gen + // read.D + mode[0].read_i(size); + decode(mode, bytes); + + if (slave(mode[0], mode[1])) + interrupt(FPU, m_pc); + break; + case 2: + // MOVLF src,dst + // gen,gen + // read.L,write.F + mode[0].read_f(SIZE_Q); + mode[1].write_f(size_f); + decode(mode, bytes); + + if (slave(mode[0], mode[1])) + interrupt(FPU, m_pc); + break; + case 3: + // MOVFL src,dst + // gen,gen + // read.F,write.L + mode[0].read_f(SIZE_D); + mode[1].write_f(size_f); + decode(mode, bytes); + + if (slave(mode[0], mode[1])) + interrupt(FPU, m_pc); + break; + case 4: + // ROUNDfi src,dst + // gen,gen + // read.f,write.i + mode[0].read_f(size_f); + mode[1].write_i(size); + decode(mode, bytes); + + if (slave(mode[0], mode[1])) + interrupt(FPU, m_pc); + break; + case 5: + // TRUNCfi src,dst + // gen,gen + // read.f,write.i + mode[0].read_f(size_f); + mode[1].write_i(size); + decode(mode, bytes); + + if (slave(mode[0], mode[1])) + interrupt(FPU, m_pc); + break; + case 6: + // SFSR dst + // gen + // write.D + mode[0].write_i(size); + decode(mode, bytes); + + if (slave(mode[1], mode[0])) + interrupt(FPU, m_pc); + break; + case 7: + // FLOORfi src,dst + // gen,gen + // read.f,write.i + mode[0].read_f(size_f); + mode[1].write_i(size); + decode(mode, bytes); + + if (slave(mode[0], mode[1])) + interrupt(FPU, m_pc); + break; + } + } + else + interrupt(UND, m_pc); break; case 0x7e: // format 10 interrupt(UND, m_pc); break; - case 0xbe: // format 11 - // TODO: floating point + case 0xbe: + // format 11: xxxx xyyy yyoo oo0f 1011 1110 + if (m_cfg & CFG_F) + { + if (!m_fpu) + fatalerror("floating point unit not configured (%s)\n", machine().describe_context()); + + u16 const opword = space(0).read_word_unaligned(m_pc + bytes); + bytes += 2; + + addr_mode mode[2] = { addr_mode((opword >> 11) & 31), addr_mode((opword >> 6) & 31) }; + size_code const size_f = BIT(opword, 0) ? SIZE_D : SIZE_Q; + + m_fpu->write_id(opbyte); + m_fpu->write_op(swapendian_int16(opword)); + + switch ((opword >> 2) & 15) + { + case 0x0: + // ADDf src,dst + // gen,gen + // read.f,rmw.f + mode[0].read_f(size_f); + mode[1].rmw_f(size_f); + decode(mode, bytes); + + if (slave(mode[0], mode[1])) + interrupt(FPU, m_pc); + break; + case 0x1: + // MOVf src,dst + // gen,gen + // read.f,write.f + mode[0].read_f(size_f); + mode[1].write_f(size_f); + decode(mode, bytes); + + if (slave(mode[0], mode[1])) + interrupt(FPU, m_pc); + break; + case 0x2: + // CMPf src1,src2 + // gen,gen + // read.f,read.f + { + mode[0].read_f(size_f); + mode[1].read_f(size_f); + decode(mode, bytes); + + u16 const status = slave(mode[0], mode[1]); + if (!(status & ns32000_slave_interface::SLAVE_Q)) + { + m_psr &= ~(PSR_N | PSR_Z | PSR_L); + m_psr |= status & (ns32000_slave_interface::SLAVE_N | ns32000_slave_interface::SLAVE_Z | ns32000_slave_interface::SLAVE_L); + } + else + interrupt(FPU, m_pc); + } + break; + case 0x3: + // Trap(SLAVE) + // operands from ns32532 datasheet + mode[0].read_f(size_f); + mode[1].read_f(size_f); + decode(mode, bytes); + + if (slave(mode[0], mode[1])) + interrupt(FPU, m_pc); + break; + case 0x4: + // SUBf src,dst + // gen,gen + // read.f,rmw.f + mode[0].read_f(size_f); + mode[1].rmw_f(size_f); + decode(mode, bytes); + + if (slave(mode[0], mode[1])) + interrupt(FPU, m_pc); + break; + case 0x5: + // NEGf src,dst + // gen,gen + // read.f,write.f + mode[0].read_f(size_f); + mode[1].write_f(size_f); + decode(mode, bytes); + + if (slave(mode[0], mode[1])) + interrupt(FPU, m_pc); + break; + case 0x8: + // DIVf src,dst + // gen,gen + // read.f,rmw.f + mode[0].read_f(size_f); + mode[1].rmw_f(size_f); + decode(mode, bytes); + + if (slave(mode[0], mode[1])) + interrupt(FPU, m_pc); + break; + case 0x9: + // Trap(SLAVE) + // operands from ns32532 datasheet + mode[0].read_f(size_f); + mode[1].write_f(size_f); + decode(mode, bytes); + + if (slave(mode[0], mode[1])) + interrupt(FPU, m_pc); + break; + case 0xc: + // MULf src,dst + // gen,gen + // read.f,rmw.f + mode[0].read_f(size_f); + mode[1].rmw_f(size_f); + decode(mode, bytes); + + if (slave(mode[0], mode[1])) + interrupt(FPU, m_pc); + break; + case 0xd: + // ABSf src,dst + // gen,gen + // read.f,write.f + mode[0].read_f(size_f); + mode[1].write_f(size_f); + decode(mode, bytes); + + if (slave(mode[0], mode[1])) + interrupt(FPU, m_pc); + break; + } + } + else + interrupt(UND, m_pc); break; case 0xfe: // format 12 case 0x9e: // format 13 interrupt(UND, m_pc); break; - case 0x1e: // format 14 - // TODO: mmu + case 0x1e: + // format 14: xxxx xsss s0oo ooii 0001 1110 + if (!(m_psr & PSR_U)) + { + if (m_cfg & CFG_M) + { + u16 const opword = space(0).read_word_unaligned(m_pc + bytes); + bytes += 2; + + addr_mode mode[] = { addr_mode((opword >> 11) & 31), addr_mode(0x13) }; + + //unsigned const quick = (opword >> 7) & 15; + size_code const size = size_code(opword & 3); + + // TODO: mmu instructions + switch ((opword >> 2) & 15) + { + case 0: + // RDVAL loc + // gen + // addr + mode[0].addr(); + decode(mode, bytes); + + tcy = 21; + break; + case 1: + // WRVAL loc + // gen + // addr + mode[0].addr(); + decode(mode, bytes); + + tcy = 21; + break; + case 2: + // LMR mmureg,src + // short,gen + // read.D + mode[0].read_i(size); + decode(mode, bytes); + + tcy = 30; + break; + case 3: + // SMR mmureg,dst + // short,gen + // write.D + mode[0].write_i(size); + decode(mode, bytes); + + tcy = 25; + break; + default: + interrupt(UND, m_pc); + break; + } + } + else + interrupt(UND, m_pc); + } + else + interrupt(ILL, m_pc); break; case 0x16: // format 15.0 case 0x36: // format 15.1 @@ -2271,15 +2941,18 @@ void ns32000_device::execute_run() break; } + if (m_sequential) + m_pc += bytes; + // trace trap if (m_psr & PSR_P) interrupt(TRC, m_pc); - m_icount--; + m_icount -= tcy; } } -void ns32000_device::execute_set_input(int inputnum, int state) +template <int Width> void ns32000_device<Width>::execute_set_input(int inputnum, int state) { if (state) m_wait = false; @@ -2298,7 +2971,7 @@ void ns32000_device::execute_set_input(int inputnum, int state) } } -device_memory_interface::space_config_vector ns32000_device::memory_space_config() const +template <int Width> device_memory_interface::space_config_vector ns32000_device<Width>::memory_space_config() const { return space_config_vector{ std::make_pair(AS_PROGRAM, &m_program_config), @@ -2312,12 +2985,102 @@ device_memory_interface::space_config_vector ns32000_device::memory_space_config }; } -bool ns32000_device::memory_translate(int spacenum, int intention, offs_t &address) +template <int Width> bool ns32000_device<Width>::memory_translate(int spacenum, int intention, offs_t &address) { return true; } -std::unique_ptr<util::disasm_interface> ns32000_device::create_disassembler() +template <int Width> std::unique_ptr<util::disasm_interface> ns32000_device<Width>::create_disassembler() { return std::make_unique<ns32000_disassembler>(); } + +template <int Width> u16 ns32000_device<Width>::slave(addr_mode op1, addr_mode op2) +{ + if ((op1.access == READ || op1.access == RMW) && !(op1.type == REG && op1.slave)) + { + u64 const data = gen_read(op1); + + switch (op1.size) + { + case SIZE_B: + m_fpu->write_op(u8(data)); + break; + case SIZE_W: + m_fpu->write_op(u16(data)); + break; + case SIZE_D: + m_fpu->write_op(u16(data >> 0)); + m_fpu->write_op(u16(data >> 16)); + break; + case SIZE_Q: + m_fpu->write_op(u16(data >> 0)); + m_fpu->write_op(u16(data >> 16)); + m_fpu->write_op(u16(data >> 32)); + m_fpu->write_op(u16(data >> 48)); + break; + } + } + + if ((op2.access == READ || op2.access == RMW) && !(op2.type == REG && op2.slave)) + { + u64 const data = gen_read(op2); + + switch (op2.size) + { + case SIZE_B: + m_fpu->write_op(u8(data)); + break; + case SIZE_W: + m_fpu->write_op(u16(data)); + break; + case SIZE_D: + m_fpu->write_op(u16(data >> 0)); + m_fpu->write_op(u16(data >> 16)); + break; + case SIZE_Q: + m_fpu->write_op(u16(data >> 0)); + m_fpu->write_op(u16(data >> 16)); + m_fpu->write_op(u16(data >> 32)); + m_fpu->write_op(u16(data >> 48)); + break; + } + } + + u16 const status = m_fpu->read_st(&m_icount); + + if (!(status & ns32000_slave_interface::SLAVE_Q)) + { + if ((op2.access == WRITE || op2.access == RMW) && !(op2.type == REG && op2.slave)) + { + u64 data = m_fpu->read_op(); + + switch (op2.size) + { + case SIZE_D: + data |= u64(m_fpu->read_op()) << 16; + break; + case SIZE_Q: + data |= u64(m_fpu->read_op()) << 16; + data |= u64(m_fpu->read_op()) << 32; + data |= u64(m_fpu->read_op()) << 48; + break; + default: + break; + } + + gen_write(op2, data); + } + } + else + { + // restore stack pointer + if (op1.type == TOS && op1.access == READ) + SP -= op1.size + 1; + + if (op2.type == TOS && op2.access == READ) + SP -= op2.size + 1; + } + + return status; +} diff --git a/src/devices/cpu/ns32000/ns32000.h b/src/devices/cpu/ns32000/ns32000.h index af5977fe52e..f5254fa068d 100644 --- a/src/devices/cpu/ns32000/ns32000.h +++ b/src/devices/cpu/ns32000/ns32000.h @@ -6,9 +6,14 @@ #pragma once +#include "slave.h" + +template <int Width> class ns32000_device : public cpu_device { public: + template <typename T> void set_fpu(T &&tag) { m_fpu.set_tag(std::forward<T>(tag)); } + // construction/destruction ns32000_device(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock); @@ -47,47 +52,79 @@ private: EXT, TOS, }; + enum access_class : unsigned + { + NONE, + READ, + WRITE, + RMW, + ADDR, + REGADDR, + }; + enum size_code : unsigned + { + SIZE_B = 0, + SIZE_W = 1, + SIZE_D = 3, + SIZE_Q = 7, + }; + struct addr_mode { addr_mode(unsigned gen) : gen(gen) + , access(NONE) + , slave(false) , base(0) , disp(0) + , imm(0) {}; - void rmw() { if (type == TOS) type = MEM; } - void addr() { if (type == TOS) type = MEM; } - void regaddr() { if (type == TOS) type = MEM; } + void read_i(size_code code) { access = READ; size = code; } + void read_f(size_code code) { access = READ; size = code; slave = true; } + void write_i(size_code code) { access = WRITE; size = code; } + void write_f(size_code code) { access = WRITE; size = code; slave = true; } + void rmw_i(size_code code) { access = RMW; size = code; } + void rmw_f(size_code code) { access = RMW; size = code; slave = true; } + void addr() { access = ADDR; size = SIZE_D; } + void regaddr() { access = REGADDR; size = SIZE_D; } unsigned gen; addr_mode_type type; + access_class access; + size_code size; + bool slave; u32 base; u32 disp; + u64 imm; }; // instruction decoding helpers s32 displacement(unsigned &bytes); - void decode(addr_mode *mode, unsigned imm_size, unsigned &bytes); + void decode(addr_mode *mode, unsigned &bytes); // operand read/write helpers u32 ea(addr_mode const mode); - u64 gen_read(addr_mode mode, unsigned size); - s64 gen_read_sx(addr_mode mode, unsigned size); - void gen_write(addr_mode mode, unsigned size, u64 data); + u64 gen_read(addr_mode mode); + s64 gen_read_sx(addr_mode mode); + void gen_write(addr_mode mode, u64 data); // other execution helpers bool condition(unsigned const cc); void flags(u32 const src1, u32 const src2, u32 const dest, unsigned const size, bool const subtraction); void interrupt(unsigned const vector, u32 const return_address, bool const trap = true); + u16 slave(addr_mode op1, addr_mode op2); // configuration address_space_config m_program_config; address_space_config m_interrupt_config; + optional_device<ns32000_slave_interface> m_fpu; + // emulation state int m_icount; - memory_access<24, 1, 0, ENDIANNESS_LITTLE>::cache m_bus[16]; + typename memory_access<24, Width, 0, ENDIANNESS_LITTLE>::cache m_bus[16]; u32 m_pc; // program counter u32 m_sb; // static base @@ -105,21 +142,22 @@ private: bool m_nmi_line; bool m_int_line; bool m_wait; + bool m_sequential; }; -class ns32008_device : public ns32000_device +class ns32008_device : public ns32000_device<0> { public: ns32008_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock); }; -class ns32016_device : public ns32000_device +class ns32016_device : public ns32000_device<1> { public: ns32016_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock); }; -class ns32032_device : public ns32000_device +class ns32032_device : public ns32000_device<2> { public: ns32032_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock); diff --git a/src/devices/cpu/ns32000/ns32000dasm.cpp b/src/devices/cpu/ns32000/ns32000dasm.cpp index 600e5f2dfb2..3f8315ec394 100644 --- a/src/devices/cpu/ns32000/ns32000dasm.cpp +++ b/src/devices/cpu/ns32000/ns32000dasm.cpp @@ -354,6 +354,10 @@ const char *const ns32000_disassembler::PR[] = { "UPSR", "DCR", "BPC", "DSR", "CAR", "", "", "", "FP", "SP", "SB", "USP", "CFG", "PSR", "INTBASE", "MOD" }; +const char *const ns32000_disassembler::FP[] = +{ + "F0", "F1", "F2", "F3", "F4", "F5", "F6", "F7" +}; int8_t ns32000_disassembler::short2int(uint8_t val) { @@ -508,7 +512,7 @@ inline std::string ns32000_disassembler::get_reg_list(offs_t &pc, const data_buf return reg_list; } -void ns32000_disassembler::stream_gen(std::ostream &stream, u8 gen_addr, u8 op_len, operand_class op_class, offs_t &pc, const data_buffer &opcodes) +void ns32000_disassembler::stream_gen(std::ostream &stream, u8 gen_addr, u8 op_len, operand_class op_class, offs_t &pc, const data_buffer &opcodes, bool fpreg) { uint8_t index_byte; int32_t disp1, disp2; @@ -518,7 +522,7 @@ void ns32000_disassembler::stream_gen(std::ostream &stream, u8 gen_addr, u8 op_l case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07: /* Register */ if (op_class != operand_class::ADDRESS) - util::stream_format(stream, "%s", R[gen_addr & 0x07]); + util::stream_format(stream, "%s", fpreg ? FP[gen_addr & 0x07] : R[gen_addr & 0x07]); else util::stream_format(stream, "(invalid)"); break; @@ -541,20 +545,25 @@ void ns32000_disassembler::stream_gen(std::ostream &stream, u8 gen_addr, u8 op_l /* Immediate */ if (op_class == operand_class::SOURCE || op_class == operand_class::BITPOS) { + int64_t imm; if (op_len == 0) - disp1 = int8_t(opcodes.r8(pc)); + imm = int8_t(opcodes.r8(pc)); else if (op_len == 1) - disp1 = int16_t(swapendian_int16(opcodes.r16(pc))); + imm = int16_t(swapendian_int16(opcodes.r16(pc))); + else if (op_len == 3) + imm = int32_t(swapendian_int32(opcodes.r32(pc))); else - disp1 = swapendian_int32(opcodes.r32(pc)); + imm = int64_t(swapendian_int64(opcodes.r64(pc))); if (op_class == operand_class::BITPOS) - util::stream_format(stream, "$%d", disp1); + util::stream_format(stream, "$%d", imm); else if (op_len == 0) - util::stream_format(stream, "$0x%02X", uint8_t(disp1)); + util::stream_format(stream, "$0x%02X", uint8_t(imm)); else if (op_len == 1) - util::stream_format(stream, "$0x%04X", uint16_t(disp1)); - else - util::stream_format(stream, "$0x%08X", disp1); + util::stream_format(stream, "$0x%04X", uint16_t(imm)); + else if (op_len == 3) + util::stream_format(stream, "$0x%08X", uint32_t(imm)); + else if (op_len == 7) + util::stream_format(stream, "$0x%016X", imm); pc += op_len + 1; } else @@ -850,10 +859,22 @@ offs_t ns32000_disassembler::disassemble(std::ostream &stream, offs_t pc, const mnemonic = mnemonic_index(Format9[Format9op(opcode)], iType[Format9i(opcode)], fType[Format9f(opcode)]); switch (Format9op(opcode)) { - case 0x00: case 0x02: case 0x03: case 0x04: case 0x05: case 0x07: + case 0x00: util::stream_format(stream, "%-8s ", mnemonic); stream_gen(stream, Format9gen1(opcode), Format9i(opcode), operand_class::SOURCE, pc, opcodes); util::stream_format(stream, ", "); + stream_gen(stream, Format9gen2(opcode), Format9i(opcode), operand_class::DESTINATION, pc, opcodes, true); + break; + case 0x02: case 0x03: + util::stream_format(stream, "%-8s ", mnemonic); + stream_gen(stream, Format9gen1(opcode), Format9f(opcode) ? 7 : 3, operand_class::SOURCE, pc, opcodes, true); + util::stream_format(stream, ", "); + stream_gen(stream, Format9gen2(opcode), Format9f(opcode) ? 3 : 7, operand_class::DESTINATION, pc, opcodes, true); + break; + case 0x04: case 0x05: case 0x07: + util::stream_format(stream, "%-8s ", mnemonic); + stream_gen(stream, Format9gen1(opcode), Format9f(opcode) ? 3 : 7, operand_class::SOURCE, pc, opcodes, true); + util::stream_format(stream, ", "); stream_gen(stream, Format9gen2(opcode), Format9i(opcode), operand_class::DESTINATION, pc, opcodes); break; case 0x01: case 0x06: @@ -873,9 +894,9 @@ offs_t ns32000_disassembler::disassemble(std::ostream &stream, offs_t pc, const { case 0x00: case 0x01: case 0x02: case 0x04: case 0x05 : case 0x08: case 0x0c : case 0x0d: util::stream_format(stream, "%-8s ", mnemonic); - stream_gen(stream, Format11gen1(opcode), Format11f(opcode), operand_class::SOURCE, pc, opcodes); + stream_gen(stream, Format11gen1(opcode), Format11f(opcode) ? 3 : 7, operand_class::SOURCE, pc, opcodes, true); util::stream_format(stream, ","); - stream_gen(stream, Format11gen2(opcode), Format11f(opcode), operand_class::DESTINATION, pc, opcodes); + stream_gen(stream, Format11gen2(opcode), Format11f(opcode) ? 3 : 7, operand_class::DESTINATION, pc, opcodes, true); break; default: /* Trap */ util::stream_format(stream, "%-8s ", mnemonic); diff --git a/src/devices/cpu/ns32000/ns32000dasm.h b/src/devices/cpu/ns32000/ns32000dasm.h index 93c38c62c98..c9f470e05d3 100644 --- a/src/devices/cpu/ns32000/ns32000dasm.h +++ b/src/devices/cpu/ns32000/ns32000dasm.h @@ -109,6 +109,7 @@ private: static char const *const R[]; static char const *const M[]; static char const *const PR[]; + static char const *const FP[]; std::string mnemonic_index(std::string form, const std::string &itype, const std::string &ftype); uint8_t opcode_format(uint8_t byte); @@ -119,7 +120,7 @@ private: static inline std::string get_options(uint8_t opts); static inline std::string get_reg_list(offs_t &pc, const data_buffer &opcodes, bool reverse); - void stream_gen(std::ostream &stream, u8 gen_addr, u8 op_len, operand_class op_class, offs_t &pc, const data_buffer &opcodes); + void stream_gen(std::ostream &stream, u8 gen_addr, u8 op_len, operand_class op_class, offs_t &pc, const data_buffer &opcodes, bool fpreg = false); u32 m_base_pc; }; diff --git a/src/devices/cpu/ns32000/slave.h b/src/devices/cpu/ns32000/slave.h new file mode 100644 index 00000000000..43ed52ecf80 --- /dev/null +++ b/src/devices/cpu/ns32000/slave.h @@ -0,0 +1,45 @@ +// license:BSD-3-Clause +// copyright-holders:Patrick Mackinlay + +#ifndef MAME_CPU_NS32000_SLAVE_H +#define MAME_CPU_NS32000_SLAVE_H + +#pragma once + +class ns32000_slave_interface : public device_interface +{ +public: + auto out_scb() { return m_out_scb.bind(); } + + ns32000_slave_interface(machine_config const &mconfig, device_t &device) + : device_interface(device, "ns32000_slave") + , m_out_scb(*this) + { + } + + enum slave_status : u16 + { + SLAVE_Q = 0x0001, + SLAVE_L = 0x0004, + SLAVE_F = 0x0020, + SLAVE_Z = 0x0040, + SLAVE_N = 0x0080, + }; + + virtual void state_add(device_state_interface &parent, int &index) = 0; + virtual void write_id(u16 data) = 0; + virtual void write_op(u16 data) = 0; + virtual u16 read_st(int *icount = nullptr) = 0; + virtual u16 read_op() = 0; + +protected: + // device_interface overrides + virtual void interface_post_start() override + { + m_out_scb.resolve_safe(); + } + + devcb_write_line m_out_scb; +}; + +#endif // MAME_CPU_NS32000_SLAVE_H diff --git a/src/devices/cpu/pdp1/pdp1.cpp b/src/devices/cpu/pdp1/pdp1.cpp index 2d04709a4a9..f16985610f0 100644 --- a/src/devices/cpu/pdp1/pdp1.cpp +++ b/src/devices/cpu/pdp1/pdp1.cpp @@ -386,6 +386,8 @@ pdp1_device::pdp1_device(const machine_config &mconfig, const char *tag, device_ , m_program_config("program", ENDIANNESS_BIG, 32, 18, -2) // data is actually 18 bits wide , m_extern_iot(*this) , m_io_sc_callback(*this) + , m_program(nullptr) + , m_reset_param(nullptr) { m_program_config.m_is_octal = true; } @@ -783,7 +785,7 @@ void pdp1_device::execute_run() /* read first word as instruction */ MB = 0; /* data will be transferred to IO register in response to RPB */ - m_extern_iot[2](2, 0, 1, IO, AC); + m_extern_iot[2](2, 1, MB, IO, AC); m_rim_step = 1; m_ios = 0; break; @@ -827,9 +829,8 @@ void pdp1_device::execute_run() case 2: /* read second word as data */ - MB = 0; /* data will be transferred to IO register in response to RPB */ - m_extern_iot[2](2, 0, 1, IO, AC); + m_extern_iot[2](2, 1, MB, IO, AC); m_rim_step = 3; m_ios = 0; break; diff --git a/src/devices/cpu/pdp1/pdp1.h b/src/devices/cpu/pdp1/pdp1.h index 0a81c8177d4..f1a4e934236 100644 --- a/src/devices/cpu/pdp1/pdp1.h +++ b/src/devices/cpu/pdp1/pdp1.h @@ -33,8 +33,7 @@ struct pdp1_reset_param_t #define IOT_NO_COMPLETION_PULSE -1 -class pdp1_device : public cpu_device - , public pdp1_reset_param_t +class pdp1_device : public cpu_device, public pdp1_reset_param_t { public: typedef device_delegate<void (int op2, int nac, int mb, int &io, int ac)> iot_delegate; diff --git a/src/devices/cpu/pic16c5x/pic16c5x.cpp b/src/devices/cpu/pic16c5x/pic16c5x.cpp index 715cf574ee1..1871bc260bd 100644 --- a/src/devices/cpu/pic16c5x/pic16c5x.cpp +++ b/src/devices/cpu/pic16c5x/pic16c5x.cpp @@ -130,9 +130,11 @@ pic16c5x_device::pic16c5x_device(const machine_config &mconfig, device_type type , ( ( program_width == 9 ) ? address_map_constructor(FUNC(pic16c5x_device::rom_9), this): ( ( program_width == 10 ) ? address_map_constructor(FUNC(pic16c5x_device::rom_10), this) : address_map_constructor(FUNC(pic16c5x_device::rom_11), this) ))) , m_data_config("data", ENDIANNESS_LITTLE, 8, data_width, 0 , ( ( data_width == 5 ) ? address_map_constructor(FUNC(pic16c5x_device::ram_5), this) : address_map_constructor(FUNC(pic16c5x_device::ram_7), this) ) ) + , m_internalram(nullptr) , m_reset_vector((program_width == 9) ? 0x1ff : ((program_width == 10) ? 0x3ff : 0x7ff)) , m_picmodel(picmodel) , m_temp_config(0) + , m_rtcc(0) , m_picRAMmask((data_width == 5) ? 0x1f : 0x7f) , m_read_a(*this) , m_read_b(*this) diff --git a/src/devices/cpu/t11/t11dasm.cpp b/src/devices/cpu/t11/t11dasm.cpp index 536d811eff0..13705f53477 100644 --- a/src/devices/cpu/t11/t11dasm.cpp +++ b/src/devices/cpu/t11/t11dasm.cpp @@ -119,10 +119,11 @@ offs_t t11_disassembler::disassemble(std::ostream &stream, offs_t pc, const data case 000: util::stream_format(stream, "HALT"); break; case 001: util::stream_format(stream, "WAIT"); break; case 002: util::stream_format(stream, "RTI"); flags = STEP_OUT; break; - case 003: util::stream_format(stream, "BPT"); break; - case 004: util::stream_format(stream, "IOT"); break; + case 003: util::stream_format(stream, "BPT"); flags = STEP_OVER; break; + case 004: util::stream_format(stream, "IOT"); flags = STEP_OVER; break; case 005: util::stream_format(stream, "RESET"); break; - case 006: util::stream_format(stream, "RTT"); break; + case 006: util::stream_format(stream, "RTT"); flags = STEP_OUT; break; + case 007: util::stream_format(stream, "MFPT"); break; default: util::stream_format(stream, ".WORD %06o", op); break; } break; @@ -135,21 +136,22 @@ offs_t t11_disassembler::disassemble(std::ostream &stream, offs_t pc, const data { case 000: if( (lo & 7) == 7 ) - util::stream_format(stream, "RTS"); + util::stream_format(stream, "RETURN"); else util::stream_format(stream, "RTS %s", regs[lo & 7]); flags = STEP_OUT; break; + // 00023x: SPL (not implemented on T-11) case 040: case 050: switch( lo & 15 ) { case 000: util::stream_format(stream, "NOP"); break; case 017: util::stream_format(stream, "CCC"); break; - case 001: util::stream_format(stream, "CEC"); break; - case 002: util::stream_format(stream, "CEV"); break; - case 004: util::stream_format(stream, "CEZ"); break; - case 010: util::stream_format(stream, "CEN"); break; + case 001: util::stream_format(stream, "CLC"); break; + case 002: util::stream_format(stream, "CLV"); break; + case 004: util::stream_format(stream, "CLZ"); break; + case 010: util::stream_format(stream, "CLN"); break; default: util::stream_format(stream, "Ccc #%02o", lo & 15); break; } break; @@ -207,7 +209,7 @@ offs_t t11_disassembler::disassemble(std::ostream &stream, offs_t pc, const data case 0004400: case 0004500: case 0004600: case 0004700: ea1 = MakeEA<false> (lo, pc, opcodes); if ( (hi & 7) == 7 ) - util::stream_format(stream, "JSR %s", ea1); + util::stream_format(stream, "CALL %s", ea1); else util::stream_format(stream, "JSR %s,%s", regs[hi & 7], ea1); flags = STEP_OVER; @@ -260,13 +262,17 @@ offs_t t11_disassembler::disassemble(std::ostream &stream, offs_t pc, const data ea1 = MakeEA<false> (lo, pc, opcodes); util::stream_format(stream, "ASL %s", ea1); break; -/* case 0006400: - util::stream_format(stream, "MARK #%o", lo); - break;*/ + // 0064xx: MARK (not implemented on T-11) + // 0065xx: MFPI (not implemented on T-11) + // 0066xx: MTPI (not implemented on T-11) case 0006700: ea1 = MakeEA<false> (lo, pc, opcodes); util::stream_format(stream, "SXT %s", ea1); break; + // 0070xx: CSM (not implemented on T-11) + // 0072xx: TSTSET (not implemented on T-11) + // 0073xx: WRTLCK (not implemented on T-11) + case 0010000: case 0010100: case 0010200: case 0010300: case 0010400: case 0010500: case 0010600: case 0010700: case 0011000: case 0011100: case 0011200: case 0011300: case 0011400: case 0011500: case 0011600: case 0011700: case 0012000: case 0012100: case 0012200: case 0012300: case 0012400: case 0012500: case 0012600: case 0012700: @@ -277,13 +283,7 @@ offs_t t11_disassembler::disassemble(std::ostream &stream, offs_t pc, const data case 0017000: case 0017100: case 0017200: case 0017300: case 0017400: case 0017500: case 0017600: case 0017700: ea1 = MakeEA<false> (hi, pc, opcodes); ea2 = MakeEA<false> (lo, pc, opcodes); - if (lo == 046) /* MOV src,-(SP) */ - util::stream_format(stream, "PUSH %s", ea1); - else - if (hi == 026) /* MOV (SP)+,buffer */ - util::stream_format(stream, "POP %s", ea2); - else /* all other */ - util::stream_format(stream, "MOV %s,%s", ea1, ea2); + util::stream_format(stream, "MOV %s,%s", ea1, ea2); break; case 0020000: case 0020100: case 0020200: case 0020300: case 0020400: case 0020500: case 0020600: case 0020700: case 0021000: case 0021100: case 0021200: case 0021300: case 0021400: case 0021500: case 0021600: case 0021700: @@ -346,11 +346,16 @@ offs_t t11_disassembler::disassemble(std::ostream &stream, offs_t pc, const data util::stream_format(stream, "ADD %s,%s", ea1, ea2); break; + // 070xxx: MUL (not implemented on T-11) + // 071xxx: DIV (not implemented on T-11) + // 072xxx: ASH (not implemented on T-11) + // 073xxx: ASHC (not implemented on T-11) case 0074000: case 0074100: case 0074200: case 0074300: case 0074400: case 0074500: case 0074600: case 0074700: ea1 = MakeEA<false> (lo, pc, opcodes); util::stream_format(stream, "XOR %s,%s", regs[hi & 7], ea1); break; - + // 075xxx: Floating Instruction Set (not implemented on T-11) + // 076xxx: Commercial Instruction Set (not implemented on T-11) case 0077000: case 0077100: case 0077200: case 0077300: case 0077400: case 0077500: case 0077600: case 0077700: addr = (pc - 2 * lo) & 0177777; util::stream_format(stream, "SOB %s,%06o", regs[hi & 7], addr); @@ -390,9 +395,11 @@ offs_t t11_disassembler::disassemble(std::ostream &stream, offs_t pc, const data break; case 0104000: case 0104100: case 0104200: case 0104300: util::stream_format(stream, "EMT %03o", op & 0377); + flags = STEP_OVER; break; case 0104400: case 0104500: case 0104600: case 0104700: util::stream_format(stream, "TRAP %03o", op & 0377); + flags = STEP_OVER; break; case 0105000: @@ -447,6 +454,8 @@ offs_t t11_disassembler::disassemble(std::ostream &stream, offs_t pc, const data ea1 = MakeEA<true> (lo, pc, opcodes); util::stream_format(stream, "MTPS %s", ea1); break; + // 1065xx: MFPD (not implemented on T-11) + // 1066xx: MTPD (not implemented on T-11) case 0106700: ea1 = MakeEA<true> (lo, pc, opcodes); util::stream_format(stream, "MFPS %s", ea1); diff --git a/src/devices/cpu/tms34010/tms34010.cpp b/src/devices/cpu/tms34010/tms34010.cpp index d5fd882a484..ab820fc1599 100644 --- a/src/devices/cpu/tms34010/tms34010.cpp +++ b/src/devices/cpu/tms34010/tms34010.cpp @@ -1178,7 +1178,7 @@ uint32_t tms340x0_device::tms340x0_ind16(screen_device &screen, bitmap_ind16 &bi params.heblnk = params.hsblnk = cliprect.max_x + 1; /* blank out the blank regions */ - uint16_t *dest = &bitmap.pix16(cliprect.min_y); + uint16_t *dest = &bitmap.pix(cliprect.min_y); for (x = cliprect.min_x; x < params.heblnk; x++) dest[x] = blackpen; for (x = params.hsblnk; x <= cliprect.max_x; x++) @@ -1209,7 +1209,7 @@ uint32_t tms340x0_device::tms340x0_rgb32(screen_device &screen, bitmap_rgb32 &bi params.heblnk = params.hsblnk = cliprect.max_x + 1; /* blank out the blank regions */ - uint32_t *dest = &bitmap.pix32(cliprect.min_y); + uint32_t *dest = &bitmap.pix(cliprect.min_y); for (x = cliprect.min_x; x < params.heblnk; x++) dest[x] = blackpen; for (x = params.hsblnk; x <= cliprect.max_x; x++) diff --git a/src/devices/cpu/tms57002/tms57002.cpp b/src/devices/cpu/tms57002/tms57002.cpp index c2cf28f3f92..da29f23fbcd 100644 --- a/src/devices/cpu/tms57002/tms57002.cpp +++ b/src/devices/cpu/tms57002/tms57002.cpp @@ -929,11 +929,10 @@ void tms57002_device::sound_stream_update(sound_stream &stream, std::vector<read si[2] = s32(inputs[2].get(0) * in_scale) & 0xffffff; si[3] = s32(inputs[3].get(0) * in_scale) & 0xffffff; - stream_buffer::sample_t out_scale = 1.0 / (32768.0 * 65536.0); - outputs[0].put(0, stream_buffer::sample_t(s32(so[0] << 8)) * out_scale); - outputs[1].put(0, stream_buffer::sample_t(s32(so[1] << 8)) * out_scale); - outputs[2].put(0, stream_buffer::sample_t(s32(so[2] << 8)) * out_scale); - outputs[3].put(0, stream_buffer::sample_t(s32(so[3] << 8)) * out_scale); + outputs[0].put_int(0, s32(so[0] << 8) >> 1, 32768 * 32768); + outputs[1].put_int(0, s32(so[1] << 8) >> 1, 32768 * 32768); + outputs[2].put_int(0, s32(so[2] << 8) >> 1, 32768 * 32768); + outputs[3].put_int(0, s32(so[3] << 8) >> 1, 32768 * 32768); sync_w(1); } diff --git a/src/devices/cpu/tms9900/tms9995.cpp b/src/devices/cpu/tms9900/tms9995.cpp index 981356ebcd2..89fdcc8d817 100644 --- a/src/devices/cpu/tms9900/tms9995.cpp +++ b/src/devices/cpu/tms9900/tms9995.cpp @@ -220,6 +220,8 @@ void tms9995_device::device_start() m_source_value = 0; + m_index = 0; + // add the states for the debugger for (int i=0; i < 20; i++) { @@ -242,7 +244,7 @@ void tms9995_device::device_start() save_item(NAME(PC)); save_item(NAME(ST)); // save_item(NAME(PC_debug)); // only for debugger output - save_pointer(NAME(m_onchip_memory),256); + save_item(NAME(m_onchip_memory)); save_item(NAME(m_idle_state)); save_item(NAME(m_nmi_state)); save_item(NAME(m_hold_state)); @@ -285,7 +287,7 @@ void tms9995_device::device_start() save_item(NAME(m_cru_address)); save_item(NAME(m_cru_value)); save_item(NAME(m_cru_first_read)); - save_pointer(NAME(m_flag),16); + save_item(NAME(m_flag)); save_item(NAME(IR)); save_item(NAME(m_pre_IR)); save_item(NAME(m_command)); diff --git a/src/devices/cpu/unsp/unsp.cpp b/src/devices/cpu/unsp/unsp.cpp index ea416cbe05c..b285fbc3048 100644 --- a/src/devices/cpu/unsp/unsp.cpp +++ b/src/devices/cpu/unsp/unsp.cpp @@ -256,11 +256,11 @@ void unsp_device::device_start() state_add(UNSP_FIQ_EN, "FIQE", m_core->m_enable_fiq).formatstr("%1u"); state_add(UNSP_FIR_MOV_EN, "FIR_MOV", m_core->m_fir_move).formatstr("%1u"); state_add(UNSP_SB, "SB", m_core->m_sb).formatstr("%1X"); - state_add(UNSP_AQ, "AQ", m_core->m_sb).formatstr("%1u"); - state_add(UNSP_FRA, "FRA", m_core->m_sb).formatstr("%1u"); - state_add(UNSP_BNK, "BNK", m_core->m_sb).formatstr("%1u"); - state_add(UNSP_INE, "INE", m_core->m_sb).formatstr("%1u"); - state_add(UNSP_PRI, "PRI", m_core->m_sb).formatstr("%1u"); + state_add(UNSP_AQ, "AQ", m_core->m_aq).formatstr("%1u"); + state_add(UNSP_FRA, "FRA", m_core->m_fra).formatstr("%1u"); + state_add(UNSP_BNK, "BNK", m_core->m_bnk).formatstr("%1u"); + state_add(UNSP_INE, "INE", m_core->m_ine).formatstr("%1u"); + state_add(UNSP_PRI, "PRI", m_core->m_pri).formatstr("%1u"); #if UNSP_LOG_OPCODES || UNSP_LOG_REGS state_add(UNSP_LOG_OPS,"LOG", m_log_ops).formatstr("%1u"); #endif diff --git a/src/devices/cpu/unsp/unspdasm_extended.cpp b/src/devices/cpu/unsp/unspdasm_extended.cpp index 3caa182b237..1655936647b 100644 --- a/src/devices/cpu/unsp/unspdasm_extended.cpp +++ b/src/devices/cpu/unsp/unspdasm_extended.cpp @@ -147,7 +147,7 @@ offs_t unsp_20_disassembler::disassemble_extended_group(std::ostream& stream, of uint8_t rb = (ximm & 0x000f) >> 0; uint8_t size = (ximm & 0x7000) >> 12; uint8_t rx = (ximm & 0x0e00) >> 9; - + if (size == 0) size = 8; int start = (rx + 1)&7; diff --git a/src/devices/cpu/vt50/vt50.cpp b/src/devices/cpu/vt50/vt50.cpp index 961dca5aa2c..7a964c4be5b 100644 --- a/src/devices/cpu/vt50/vt50.cpp +++ b/src/devices/cpu/vt50/vt50.cpp @@ -284,7 +284,7 @@ void vt5x_cpu_device::draw_char_line() if (xc > screen().visible_area().right() - 8) return; - u32 *pix = &m_bitmap.pix32(m_current_line, xc); + u32 *pix = &m_bitmap.pix(m_current_line, xc); if (m_video_process && m_cursor_ff && m_cursor_active) std::fill_n(pix, 9, rgb_t::white()); else if (!m_video_process || m_cursor_ff) diff --git a/src/devices/cpu/x86log.cpp b/src/devices/cpu/x86log.cpp index b97f2553f11..7c7b13d1966 100644 --- a/src/devices/cpu/x86log.cpp +++ b/src/devices/cpu/x86log.cpp @@ -37,7 +37,7 @@ x86log_context *x86log_create_context(const char *filename) x86log_context *log; /* allocate the log */ - log = global_alloc_clear<x86log_context>(); + log = new x86log_context; /* allocate the filename */ log->filename.assign(filename); @@ -59,7 +59,7 @@ void x86log_free_context(x86log_context *log) noexcept fclose(log->file); /* free the structure */ - global_free(log); + delete log; } diff --git a/src/devices/cpu/x86log.h b/src/devices/cpu/x86log.h index ba2a349a55f..1383295e720 100644 --- a/src/devices/cpu/x86log.h +++ b/src/devices/cpu/x86log.h @@ -8,10 +8,10 @@ ***************************************************************************/ -#pragma once +#ifndef MAME_CPU_X86LOG_H +#define MAME_CPU_X86LOG_H -#ifndef __X86LOG_H__ -#define __X86LOG_H__ +#pragma once #include <cstdint> #include <cassert> @@ -38,34 +38,34 @@ typedef uint8_t x86code; /* code logging info */ struct log_comment { - x86code* base; - const char* string; + x86code* base = nullptr; + const char* string = nullptr; }; /* data ranges */ struct data_range_t { - x86code* base; - x86code* end; - int size; + x86code* base = nullptr; + x86code* end = nullptr; + int size = 0; }; /* the code logging context */ struct x86log_context { - std::string filename; /* name of the file */ - FILE* file; /* file we are logging to */ + std::string filename; // name of the file + FILE* file = nullptr; // file we are logging to - data_range_t data_range[MAX_DATA_RANGES]; /* list of data ranges */ - int data_range_count; /* number of data ranges */ + data_range_t data_range[MAX_DATA_RANGES]; // list of data ranges + int data_range_count = 0; // number of data ranges - log_comment comment_list[MAX_COMMENTS]; /* list of comments */ - int comment_count; /* number of live comments */ + log_comment comment_list[MAX_COMMENTS]; // list of comments + int comment_count = 0; // number of live comments - char comment_pool[COMMENT_POOL_SIZE]; /* string pool to hold comments */ - char* comment_pool_next; /* pointer to next string pool location */ + char comment_pool[COMMENT_POOL_SIZE]; // string pool to hold comments + char* comment_pool_next = nullptr; // pointer to next string pool location }; @@ -160,4 +160,4 @@ inline void x86log_printf(x86log_context* log, const char* format, Ts&&... xs) fflush(log->file); } -#endif /* __X86LOG_H__ */ +#endif // MAME_CPU_X86LOG_H diff --git a/src/devices/imagedev/cassette.cpp b/src/devices/imagedev/cassette.cpp index c6e20ba66dd..5d17f822e60 100644 --- a/src/devices/imagedev/cassette.cpp +++ b/src/devices/imagedev/cassette.cpp @@ -26,8 +26,8 @@ DEFINE_DEVICE_TYPE(CASSETTE, cassette_image_device, "cassette_image", "Cassette" // cassette_image_device - constructor //------------------------------------------------- -cassette_image_device::cassette_image_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : device_t(mconfig, CASSETTE, tag, owner, clock), +cassette_image_device::cassette_image_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, CASSETTE, tag, owner, clock), device_image_interface(mconfig, *this), device_sound_interface(mconfig, *this), m_cassette(nullptr), @@ -83,13 +83,13 @@ void cassette_image_device::update() switch (int(m_state & CASSETTE_MASK_UISTATE)) // cast to int to suppress unhandled enum value warning { case CASSETTE_RECORD: - cassette_put_sample(m_cassette, m_channel, m_position, new_position - m_position, m_value); + m_cassette->put_sample(m_channel, m_position, new_position - m_position, m_value); break; case CASSETTE_PLAY: if (m_cassette) { - cassette_get_sample(m_cassette, m_channel, new_position, 0.0, &m_value); + m_cassette->get_sample(m_channel, new_position, 0.0, &m_value); // See if reached end of tape double length = get_length(); if (new_position > length) @@ -167,9 +167,7 @@ double cassette_image_device::get_position() double cassette_image_device::get_length() { - struct CassetteInfo info; - - cassette_get_info(m_cassette, &info); + cassette_image::Info info = m_cassette->get_info(); return ((double) info.sample_count) / info.sample_frequency; } @@ -236,7 +234,7 @@ void cassette_image_device::device_start() m_state = m_default_state; m_value = 0; - stream_alloc_legacy(0, (m_stereo? 2:1), machine().sample_rate()); + stream_alloc(0, m_stereo? 2:1, machine().sample_rate()); } image_init_result cassette_image_device::call_create(int format_type, util::option_resolution *format_options) @@ -258,7 +256,7 @@ image_init_result cassette_image_device::internal_load(bool is_create) if (is_create || (length()==0)) // empty existing images are fine to write over. { // creating an image - err = cassette_create((void *)image, &image_ioprocs, &wavfile_format, m_create_opts, CASSETTE_FLAG_READWRITE|CASSETTE_FLAG_SAVEONEXIT, &m_cassette); + err = cassette_image::create((void *)image, &image_ioprocs, &cassette_image::wavfile_format, m_create_opts, cassette_image::FLAG_READWRITE|cassette_image::FLAG_SAVEONEXIT, m_cassette); if (err != cassette_image::error::SUCCESS) goto error; } @@ -273,9 +271,9 @@ image_init_result cassette_image_device::internal_load(bool is_create) // try opening the cassette int cassette_flags = is_readonly() - ? CASSETTE_FLAG_READONLY - : (CASSETTE_FLAG_READWRITE | CASSETTE_FLAG_SAVEONEXIT); - err = cassette_open_choices((void *)image, &image_ioprocs, filetype(), m_formats, cassette_flags, &m_cassette); + ? cassette_image::FLAG_READONLY + : (cassette_image::FLAG_READWRITE | cassette_image::FLAG_SAVEONEXIT); + err = cassette_image::open_choices((void *)image, &image_ioprocs, filetype(), m_formats, cassette_flags, m_cassette); // special case - if we failed due to readwrite not being supported, make the image be read only and retry if (err == cassette_image::error::READ_WRITE_UNSUPPORTED) @@ -337,8 +335,7 @@ void cassette_image_device::call_unload() update(); /* close out the cassette */ - cassette_close(m_cassette); - m_cassette = nullptr; + m_cassette.reset(); /* set to default state, but only change the UI state */ change_state(CASSETTE_STOPPED, CASSETTE_MASK_UISTATE); @@ -404,37 +401,29 @@ std::string cassette_image_device::call_display() // Cassette sound //------------------------------------------------- -void cassette_image_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void cassette_image_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - stream_sample_t *left_buffer = outputs[0]; - stream_sample_t *right_buffer = nullptr; - - if (m_stereo) - right_buffer = outputs[1]; - cassette_state state = get_state() & (CASSETTE_MASK_UISTATE | CASSETTE_MASK_MOTOR | CASSETTE_MASK_SPEAKER); if (exists() && (state == (CASSETTE_PLAY | CASSETTE_MOTOR_ENABLED | CASSETTE_SPEAKER_ENABLED))) { cassette_image *cassette = get_image(); double time_index = get_position(); - double duration = ((double) samples) / machine().sample_rate(); + double duration = ((double) outputs[0].samples()) / outputs[0].sample_rate(); - cassette_get_samples(cassette, 0, time_index, duration, samples, 2, left_buffer, CASSETTE_WAVEFORM_16BIT); - if (m_stereo) - cassette_get_samples(cassette, 1, time_index, duration, samples, 2, right_buffer, CASSETTE_WAVEFORM_16BIT); + if (m_samples.size() < outputs[0].samples()) + m_samples.resize(outputs[0].samples()); - for (int i = samples - 1; i >= 0; i--) + for (int ch = 0; ch < outputs.size(); ch++) { - left_buffer[i] = ((int16_t *) left_buffer)[i]; - if (m_stereo) - right_buffer[i] = ((int16_t *) right_buffer)[i]; + cassette->get_samples(0, time_index, duration, outputs[0].samples(), 2, &m_samples[0], cassette_image::WAVEFORM_16BIT); + for (int sampindex = 0; sampindex < outputs[ch].samples(); sampindex++) + outputs[ch].put_int(sampindex, m_samples[sampindex], 32768); } } else { - memset(left_buffer, 0, sizeof(*left_buffer) * samples); - if (m_stereo) - memset(right_buffer, 0, sizeof(*right_buffer) * samples); + for (int ch = 0; ch < outputs.size(); ch++) + outputs[ch].fill(0); } } diff --git a/src/devices/imagedev/cassette.h b/src/devices/imagedev/cassette.h index a661e8312a8..e36b61d688d 100644 --- a/src/devices/imagedev/cassette.h +++ b/src/devices/imagedev/cassette.h @@ -53,8 +53,8 @@ public: cassette_image_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); virtual ~cassette_image_device(); - void set_formats(const struct CassetteFormat* const *formats) { m_formats = formats; } - void set_create_opts(const struct CassetteOptions *create_opts) { m_create_opts = create_opts; } + void set_formats(const cassette_image::Format* const *formats) { m_formats = formats; } + void set_create_opts(const cassette_image::Options *create_opts) { m_create_opts = create_opts; } void set_default_state(cassette_state default_state) { m_default_state = default_state; } void set_interface(const char *interface) { m_interface = interface; } @@ -92,7 +92,7 @@ public: void set_speaker(int state) { change_state(state ? CASSETTE_SPEAKER_ENABLED : CASSETTE_SPEAKER_MUTED, CASSETTE_MASK_SPEAKER); } int speaker_on() { return ((m_state & CASSETTE_MASK_SPEAKER) == CASSETTE_SPEAKER_ENABLED) ? 1 : 0; } - cassette_image *get_image() { return m_cassette; } + cassette_image *get_image() { return m_cassette.get(); } double get_position(); double get_length(); void set_speed(double speed); @@ -102,7 +102,7 @@ public: void seek(double time, int origin); // sound stream update overrides - void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; device_sound_interface& set_stereo() { m_stereo = true; return *this; } protected: @@ -117,7 +117,7 @@ protected: void update(); private: - cassette_image *m_cassette; + cassette_image::ptr m_cassette; cassette_state m_state; double m_position; double m_position_time; @@ -126,13 +126,14 @@ private: double m_speed; // speed multiplier for tape speeds other than standard 1.875ips (used in adam driver) int m_direction; // direction select char m_extension_list[256]; - const struct CassetteFormat* const *m_formats; - const struct CassetteOptions *m_create_opts; + const cassette_image::Format* const *m_formats; + const cassette_image::Options *m_create_opts; cassette_state m_default_state; const char * m_interface; image_init_result internal_load(bool is_create); bool m_stereo; + std::vector<s16> m_samples; }; // device type definition diff --git a/src/devices/imagedev/floppy.cpp b/src/devices/imagedev/floppy.cpp index 3dd96644f1a..cf3ffefd524 100644 --- a/src/devices/imagedev/floppy.cpp +++ b/src/devices/imagedev/floppy.cpp @@ -178,7 +178,7 @@ floppy_image_device::floppy_image_device(const machine_config &mconfig, device_t device_image_interface(mconfig, *this), input_format(nullptr), output_format(nullptr), - image(nullptr), + image(), fif_list(nullptr), index_timer(nullptr), tracks(0), @@ -307,7 +307,7 @@ void floppy_image_device::commit_image() if (err != osd_file::error::NONE) popmessage("Error, unable to truncate image: %d", int(err)); - output_format->save(&io, image); + output_format->save(&io, image.get()); } //------------------------------------------------- @@ -459,7 +459,7 @@ image_init_result floppy_image_device::call_load() io.filler = 0xff; int best = 0; floppy_image_format_t *best_format = nullptr; - for(floppy_image_format_t *format = fif_list; format; format = format->next) { + for (floppy_image_format_t *format = fif_list; format; format = format->next) { int score = format->identify(&io, form_factor); if(score > best) { best = score; @@ -467,18 +467,15 @@ image_init_result floppy_image_device::call_load() } } - if(!best_format) - { + if (!best_format) { seterror(IMAGE_ERROR_INVALIDIMAGE, "Unable to identify the image format"); return image_init_result::FAIL; } - image = global_alloc(floppy_image(tracks, sides, form_factor)); - if (!best_format->load(&io, form_factor, image)) - { + image = std::make_unique<floppy_image>(tracks, sides, form_factor); + if (!best_format->load(&io, form_factor, image.get())) { seterror(IMAGE_ERROR_UNSUPPORTED, "Incompatible image format or corrupted data"); - global_free(image); - image = nullptr; + image.reset(); return image_init_result::FAIL; } output_format = is_readonly() ? nullptr : best_format; @@ -501,8 +498,7 @@ void floppy_image_device::call_unload() if (image) { if(image_dirty) commit_image(); - global_free(image); - image = nullptr; + image.reset(); } wpt = 1; // disk sleeve is covering the sensor @@ -526,7 +522,7 @@ void floppy_image_device::call_unload() image_init_result floppy_image_device::call_create(int format_type, util::option_resolution *format_options) { - image = global_alloc(floppy_image(tracks, sides, form_factor)); + image = std::make_unique<floppy_image>(tracks, sides, form_factor); output_format = nullptr; // search for a suitable format based on the extension @@ -1248,7 +1244,7 @@ void floppy_sound_device::device_start() // If we don't have all samples, don't allocate a stream or access sample data. if (m_loaded) { - m_sound = stream_alloc_legacy(0, 1, clock()); // per-floppy stream + m_sound = stream_alloc(0, 1, clock()); // per-floppy stream } register_for_save_states(); } @@ -1369,21 +1365,21 @@ void floppy_sound_device::step(int zone) } //------------------------------------------------- -// sound_stream_update_legacy - update the sound stream +// sound_stream_update - update the sound stream //------------------------------------------------- -void floppy_sound_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void floppy_sound_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { // We are using only one stream, unlike the parent class // Also, there is no need for interpolation, as we only expect // one sample rate of 44100 for all samples int16_t out; - stream_sample_t *samplebuffer = outputs[0]; + auto &samplebuffer = outputs[0]; int idx = 0; int sampleend = 0; - while (samples-- > 0) + for (int sampindex = 0; sampindex < samplebuffer.samples(); sampindex++) { out = 0; @@ -1477,7 +1473,7 @@ void floppy_sound_device::sound_stream_update_legacy(sound_stream &stream, strea } // Write to the stream buffer - *(samplebuffer++) = out; + samplebuffer.put_int(sampindex, out, 32768); } } diff --git a/src/devices/imagedev/floppy.h b/src/devices/imagedev/floppy.h index d07a12c146c..b163b0b6a42 100644 --- a/src/devices/imagedev/floppy.h +++ b/src/devices/imagedev/floppy.h @@ -154,7 +154,7 @@ protected: floppy_image_format_t *input_format; floppy_image_format_t *output_format; - floppy_image *image; + std::unique_ptr<floppy_image> image; char extension_list[256]; floppy_image_format_t *fif_list; emu_timer *index_timer; @@ -294,7 +294,7 @@ protected: private: // device_sound_interface overrides - void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; sound_stream* m_sound; int m_step_base; diff --git a/src/devices/imagedev/mfmhd.cpp b/src/devices/imagedev/mfmhd.cpp index a90cf75ea54..61eabb12217 100644 --- a/src/devices/imagedev/mfmhd.cpp +++ b/src/devices/imagedev/mfmhd.cpp @@ -366,7 +366,7 @@ void mfm_harddisk_device::device_start() m_current_cylinder = m_landing_zone; // Park position m_spinup_timer->adjust(attotime::from_msec(m_spinupms)); - m_cache = global_alloc(mfmhd_trackimage_cache(machine())); + m_cache = std::make_unique<mfmhd_trackimage_cache>(machine()); // In 5 second periods, check whether the cache has dirty lines m_cache_timer->adjust(attotime::from_msec(5000), 0, attotime::from_msec(5000)); @@ -411,7 +411,7 @@ void mfm_harddisk_device::device_reset() void mfm_harddisk_device::device_stop() { - if (m_cache!=nullptr) global_free(m_cache); + m_cache.reset(); } /* @@ -1010,9 +1010,8 @@ mfmhd_trackimage_cache::~mfmhd_trackimage_cache() while (current != nullptr) { - global_free_array(current->encdata); mfmhd_trackimage* currenttmp = current->next; - global_free(current); + delete current; current = currenttmp; } } @@ -1025,7 +1024,7 @@ void mfmhd_trackimage_cache::write_back_one() { if (current->dirty) { - m_mfmhd->write_track(current->encdata, current->cylinder, current->head); + m_mfmhd->write_track(current->encdata.get(), current->cylinder, current->head); current->dirty = false; break; } @@ -1045,7 +1044,7 @@ void mfmhd_trackimage_cache::cleanup() if (TRACE_CACHE) m_machine.logerror("[%s:cache] MFM HD cache: evict line cylinder=%d head=%d\n", m_mfmhd->tag(), current->cylinder, current->head); if (current->dirty) { - m_mfmhd->write_track(current->encdata, current->cylinder, current->head); + m_mfmhd->write_track(current->encdata.get(), current->cylinder, current->head); current->dirty = false; } mfmhd_trackimage* currenttmp = current->next; @@ -1087,11 +1086,11 @@ void mfmhd_trackimage_cache::init(mfm_harddisk_device* mfmhd, int tracksize, int { if (TRACE_DETAIL) m_machine.logerror("[%s:cache] MFM HD allocate cache slot\n", mfmhd->tag()); previous = current; - current = global_alloc(mfmhd_trackimage); - current->encdata = global_alloc_array(uint16_t, tracksize); + current = new mfmhd_trackimage; + current->encdata = std::make_unique<uint16_t []>(tracksize); // Load the first tracks into the slots - state = m_mfmhd->load_track(current->encdata, cylinder, head); + state = m_mfmhd->load_track(current->encdata.get(), cylinder, head); if (state != CHDERR_NONE) throw emu_fatalerror("Cannot load (c=%d,h=%d) from hard disk", cylinder, head); current->dirty = false; @@ -1148,7 +1147,7 @@ uint16_t* mfmhd_trackimage_cache::get_trackimage(int cylinder, int head) current->next = m_tracks; // put the previous head into the next field m_tracks = current; // set this line as new head } - return current->encdata; + return current->encdata.get(); } else { @@ -1168,11 +1167,11 @@ uint16_t* mfmhd_trackimage_cache::get_trackimage(int cylinder, int head) if (current->dirty) { - m_mfmhd->write_track(current->encdata, current->cylinder, current->head); + m_mfmhd->write_track(current->encdata.get(), current->cylinder, current->head); current->dirty = false; } - state = m_mfmhd->load_track(current->encdata, cylinder, head); + state = m_mfmhd->load_track(current->encdata.get(), cylinder, head); current->dirty = false; current->cylinder = cylinder; diff --git a/src/devices/imagedev/mfmhd.h b/src/devices/imagedev/mfmhd.h index 2d689a168cb..007be4be420 100644 --- a/src/devices/imagedev/mfmhd.h +++ b/src/devices/imagedev/mfmhd.h @@ -27,7 +27,7 @@ public: bool dirty; int cylinder; int head; - uint16_t* encdata; // MFM encoding per byte + std::unique_ptr<uint16_t []> encdata; // MFM encoding per byte mfmhd_trackimage* next; }; @@ -152,7 +152,7 @@ private: attotime m_settle_time; attotime m_step_time; - mfmhd_trackimage_cache* m_cache; + std::unique_ptr<mfmhd_trackimage_cache> m_cache; mfmhd_image_format_t* m_format; void head_move(); diff --git a/src/devices/imagedev/midiin.cpp b/src/devices/imagedev/midiin.cpp index 6086cb48a3e..62c7cba52a1 100644 --- a/src/devices/imagedev/midiin.cpp +++ b/src/devices/imagedev/midiin.cpp @@ -26,7 +26,7 @@ midiin_device::midiin_device(const machine_config &mconfig, const char *tag, dev : device_t(mconfig, MIDIIN, tag, owner, clock), device_image_interface(mconfig, *this), device_serial_interface(mconfig, *this), - m_midi(nullptr), + m_midi(), m_timer(nullptr), m_input_cb(*this), m_xmit_read(0), @@ -43,7 +43,7 @@ void midiin_device::device_start() { m_input_cb.resolve_safe(); m_timer = timer_alloc(0); - m_midi = nullptr; + m_midi.reset(); m_timer->enable(false); } @@ -68,7 +68,7 @@ void midiin_device::device_timer(emu_timer &timer, device_timer_id id, int param uint8_t buf[8192*4]; int bytesRead; - if (m_midi == nullptr) { + if (!m_midi) { return; } @@ -91,14 +91,13 @@ void midiin_device::device_timer(emu_timer &timer, device_timer_id id, int param call_load -------------------------------------------------*/ -image_init_result midiin_device::call_load(void) +image_init_result midiin_device::call_load() { m_midi = machine().osd().create_midi_device(); if (!m_midi->open_input(filename())) { - global_free(m_midi); - m_midi = nullptr; + m_midi.reset(); return image_init_result::FAIL; } @@ -111,15 +110,14 @@ image_init_result midiin_device::call_load(void) call_unload -------------------------------------------------*/ -void midiin_device::call_unload(void) +void midiin_device::call_unload() { if (m_midi) { m_midi->close(); - global_free(m_midi); } - m_timer->enable(false); - m_midi = nullptr; + m_midi.reset(); + m_timer->enable(false); } void midiin_device::tra_complete() diff --git a/src/devices/imagedev/midiin.h b/src/devices/imagedev/midiin.h index ad9eeabf236..dbebdfd71fc 100644 --- a/src/devices/imagedev/midiin.h +++ b/src/devices/imagedev/midiin.h @@ -60,7 +60,7 @@ private: void xmit_char(uint8_t data); - osd_midi_device *m_midi; + std::unique_ptr<osd_midi_device> m_midi; emu_timer *m_timer; devcb_write_line m_input_cb; uint8_t m_xmitring[XMIT_RING_SIZE]; diff --git a/src/devices/imagedev/midiout.cpp b/src/devices/imagedev/midiout.cpp index 3c0613e2015..e9551a50d17 100644 --- a/src/devices/imagedev/midiout.cpp +++ b/src/devices/imagedev/midiout.cpp @@ -26,7 +26,7 @@ midiout_device::midiout_device(const machine_config &mconfig, const char *tag, d : device_t(mconfig, MIDIOUT, tag, owner, clock), device_image_interface(mconfig, *this), device_serial_interface(mconfig, *this), - m_midi(nullptr) + m_midi() { } @@ -36,7 +36,7 @@ midiout_device::midiout_device(const machine_config &mconfig, const char *tag, d void midiout_device::device_start() { - m_midi = nullptr; + m_midi.reset(); } void midiout_device::device_reset() @@ -51,14 +51,13 @@ void midiout_device::device_reset() call_load -------------------------------------------------*/ -image_init_result midiout_device::call_load(void) +image_init_result midiout_device::call_load() { m_midi = machine().osd().create_midi_device(); if (!m_midi->open_output(filename())) { - global_free(m_midi); - m_midi = nullptr; + m_midi.reset(); return image_init_result::FAIL; } @@ -69,13 +68,12 @@ image_init_result midiout_device::call_load(void) call_unload -------------------------------------------------*/ -void midiout_device::call_unload(void) +void midiout_device::call_unload() { if (m_midi) { m_midi->close(); - global_free(m_midi); - m_midi = nullptr; + m_midi.reset(); } } diff --git a/src/devices/imagedev/midiout.h b/src/devices/imagedev/midiout.h index 2b182e0273d..20bc87131c5 100644 --- a/src/devices/imagedev/midiout.h +++ b/src/devices/imagedev/midiout.h @@ -53,7 +53,7 @@ protected: virtual void rcv_complete() override; // Rx completed receiving byte private: - osd_midi_device *m_midi; + std::unique_ptr<osd_midi_device> m_midi; }; // device type definition diff --git a/src/devices/imagedev/picture.cpp b/src/devices/imagedev/picture.cpp index f80bfb2885e..e6736fb10c9 100644 --- a/src/devices/imagedev/picture.cpp +++ b/src/devices/imagedev/picture.cpp @@ -10,7 +10,7 @@ #include "emu.h" #include "picture.h" -#include "png.h" +#include "rendutil.h" /*************************************************************************** TYPE DEFINITIONS @@ -25,8 +25,7 @@ DEFINE_DEVICE_TYPE(IMAGE_PICTURE, picture_image_device, "picture_image", "Still picture_image_device::picture_image_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, IMAGE_PICTURE, tag, owner, clock), - device_image_interface(mconfig, *this), - m_picture(nullptr) + device_image_interface(mconfig, *this) { } @@ -36,11 +35,6 @@ picture_image_device::picture_image_device(const machine_config &mconfig, const picture_image_device::~picture_image_device() { - if (m_picture) - { - delete m_picture; - m_picture = nullptr; - } } @@ -50,24 +44,31 @@ void picture_image_device::device_start() image_init_result picture_image_device::call_load() { - m_picture = new bitmap_argb32; - if (png_read_bitmap(image_core_file(), *m_picture) != PNGERR_NONE) - { - delete m_picture; - m_picture = nullptr; - - // todo: try JPEG here. - return image_init_result::FAIL; + switch (render_detect_image(image_core_file())) + { + case RENDUTIL_IMGFORMAT_PNG: + render_load_png(m_picture, image_core_file()); + break; + + case RENDUTIL_IMGFORMAT_JPEG: + render_load_jpeg(m_picture, image_core_file()); + break; + + case RENDUTIL_IMGFORMAT_MSDIB: + render_load_msdib(m_picture, image_core_file()); + break; + + default: + m_picture.reset(); } - return image_init_result::PASS; + return m_picture.valid() ? image_init_result::PASS : image_init_result::FAIL; } void picture_image_device::call_unload() { - if (m_picture) + if (m_picture.valid()) { - delete m_picture; - m_picture = nullptr; + m_picture.reset(); } } diff --git a/src/devices/imagedev/picture.h b/src/devices/imagedev/picture.h index f8601345a89..1780a563318 100644 --- a/src/devices/imagedev/picture.h +++ b/src/devices/imagedev/picture.h @@ -41,14 +41,14 @@ public: virtual bool is_reset_on_load() const noexcept override { return false; } virtual const char *file_extensions() const noexcept override { return "png"; } - bitmap_argb32 &get_bitmap() { return *m_picture; } + const bitmap_argb32 &get_bitmap() { return m_picture; } protected: // device-level overrides virtual void device_start() override; private: - bitmap_argb32 *m_picture; + bitmap_argb32 m_picture; }; diff --git a/src/devices/machine/6840ptm.cpp b/src/devices/machine/6840ptm.cpp index 849e59c05a7..21d8c0d80e9 100644 --- a/src/devices/machine/6840ptm.cpp +++ b/src/devices/machine/6840ptm.cpp @@ -156,6 +156,11 @@ void ptm6840_device::device_reset() } } +void ptm6840_device::device_resolve_objects() +{ + for (int i = 0; i < 3; i++) + m_gate[i] = 0; +} //------------------------------------------------- // device_timer - handle timer callbacks diff --git a/src/devices/machine/6840ptm.h b/src/devices/machine/6840ptm.h index 537fd4e7c19..6836aa5d317 100644 --- a/src/devices/machine/6840ptm.h +++ b/src/devices/machine/6840ptm.h @@ -58,6 +58,7 @@ protected: // device-level overrides virtual void device_start() override; virtual void device_reset() override; + virtual void device_resolve_objects() override; virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; private: diff --git a/src/devices/machine/8364_paula.cpp b/src/devices/machine/8364_paula.cpp index 1e10ca55b3e..6869ffb3395 100644 --- a/src/devices/machine/8364_paula.cpp +++ b/src/devices/machine/8364_paula.cpp @@ -58,7 +58,7 @@ void paula_8364_device::device_start() } // create the stream - m_stream = stream_alloc_legacy(0, 4, clock() / CLOCK_DIVIDER); + m_stream = stream_alloc(0, 4, clock() / CLOCK_DIVIDER); } //------------------------------------------------- @@ -159,10 +159,10 @@ void paula_8364_device::dma_reload(audio_channel *chan) } //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void paula_8364_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void paula_8364_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { int channum, sampoffs = 0; @@ -176,11 +176,11 @@ void paula_8364_device::sound_stream_update_legacy(sound_stream &stream, stream_ // clear the sample data to 0 for (channum = 0; channum < 4; channum++) - memset(outputs[channum], 0, sizeof(stream_sample_t) * samples); + outputs[channum].fill(0); return; } - samples *= CLOCK_DIVIDER; + int samples = outputs[0].samples() * CLOCK_DIVIDER; // update the DMA states on each channel and reload if fresh for (channum = 0; channum < 4; channum++) @@ -215,7 +215,7 @@ void paula_8364_device::sound_stream_update_legacy(sound_stream &stream, stream_ audio_channel *chan = &m_channel[channum]; int volume = (nextvol == -1) ? chan->vol : nextvol; int period = (nextper == -1) ? chan->per : nextper; - stream_sample_t sample; + s32 sample; int i; // normalize the volume value @@ -247,7 +247,7 @@ void paula_8364_device::sound_stream_update_legacy(sound_stream &stream, stream_ // fill the buffer with the sample for (i = 0; i < ticks; i += CLOCK_DIVIDER) - outputs[channum][(sampoffs + i) / CLOCK_DIVIDER] = sample; + outputs[channum].put_int((sampoffs + i) / CLOCK_DIVIDER, sample, 32768); // account for the ticks; if we hit 0, advance chan->curticks -= ticks; diff --git a/src/devices/machine/8364_paula.h b/src/devices/machine/8364_paula.h index a2ac2feab26..9fa7a6ebf38 100644 --- a/src/devices/machine/8364_paula.h +++ b/src/devices/machine/8364_paula.h @@ -68,7 +68,7 @@ protected: virtual void device_start() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: enum diff --git a/src/devices/machine/acorn_vidc.cpp b/src/devices/machine/acorn_vidc.cpp index 36733555e7d..f0ebf10f612 100644 --- a/src/devices/machine/acorn_vidc.cpp +++ b/src/devices/machine/acorn_vidc.cpp @@ -492,9 +492,9 @@ void acorn_vidc10_device::draw(bitmap_rgb32 &bitmap, const rectangle &cliprect, if (is_cursor == true && dot == 0) continue; dot += pen_base; - bitmap.pix32(dsty, dstx+xi) = this->pen(dot); + bitmap.pix(dsty, dstx+xi) = this->pen(dot); if (m_crtc_interlace) - bitmap.pix32(dsty+1, dstx+xi) = this->pen(dot); + bitmap.pix(dsty+1, dstx+xi) = this->pen(dot); } } } diff --git a/src/devices/machine/alpha_8921.h b/src/devices/machine/alpha_8921.h index 88ecd850eb9..a6e8ccdb0ad 100644 --- a/src/devices/machine/alpha_8921.h +++ b/src/devices/machine/alpha_8921.h @@ -2,7 +2,7 @@ // copyright-holders:cam900 /*************************************************************************** - Alpha denshi ALPHA-8921 emulation + Alpha denshi ALPHA-8921 emulation ***************************************************************************/ diff --git a/src/devices/machine/am9519.h b/src/devices/machine/am9519.h index 315e0bd890d..ec84cd50e52 100644 --- a/src/devices/machine/am9519.h +++ b/src/devices/machine/am9519.h @@ -32,7 +32,7 @@ class am9519_device : public device_t { public: - am9519_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + am9519_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); auto out_int_callback() { return m_out_int_func.bind(); } diff --git a/src/devices/machine/bl_handhelds_menucontrol.cpp b/src/devices/machine/bl_handhelds_menucontrol.cpp new file mode 100644 index 00000000000..18982731069 --- /dev/null +++ b/src/devices/machine/bl_handhelds_menucontrol.cpp @@ -0,0 +1,214 @@ +// license:BSD-3-Clause +// copyright-holders:David Haywood + +// Menu controller, stores / increments menu position etc. used on handhelds that typically have BL on the boot screen (BaoBaoLong?) + +#include "emu.h" +#include "machine/bl_handhelds_menucontrol.h" + +DEFINE_DEVICE_TYPE(BL_HANDHELDS_MENUCONTROL, bl_handhelds_menucontrol_device, "blhandheldmenu", "BaoBaoLong Handhelds Menu Controller") + +bl_handhelds_menucontrol_device::bl_handhelds_menucontrol_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, BL_HANDHELDS_MENUCONTROL, tag, owner, clock), + m_is_unsp_type_hack(false) +{ +} + +READ_LINE_MEMBER(bl_handhelds_menucontrol_device::status_r) +{ + return m_clockstate; +} + +READ_LINE_MEMBER(bl_handhelds_menucontrol_device::data_r) +{ + return m_responsebit; +} + +// is there some 'carry' related behavior on the add / remove, because sometimes calculations are off by 1 eg command 0x05 (subtract) subcommand 0xf0 +// edge cases to test - moving up and left off entry 0, moving next / previous page when on any entry on the first/last pages, moving down/right off last entry, crossing 255/256 game boundary +void bl_handhelds_menucontrol_device::handle_command() +{ + uint8_t command = m_command; + + // additions and subtractions here are likely also meant to be done as high byte and low byte + if (m_menustate == MENU_READY_FOR_COMMAND) + { + if (command == 0x00) + { + m_menustate = MENU_COMMAND_00_IN; + m_response = m_menupos & 0xff; + } + else if (command == 0x01) + { + m_menustate = MENU_COMMAND_01_IN; + m_response = (m_menupos >> 8) & 0xff; + } + else if (command == 0x02) + { + m_menustate = MENU_COMMAND_02_IN; + } + else if (command == 0x03) + { + m_menustate = MENU_COMMAND_03_IN; + } + else if (command == 0x04) + { + m_menustate = MENU_COMMAND_04_IN; + } + else if (command == 0x05) + { + m_menustate = MENU_COMMAND_05_IN; + } + else if (command == 0x09) + { + // ... + } + else if ((command) == 0x10) + { + // this is followed by 0x1b, written if you try to move right off last entry + m_menupos = 0x00; + } + else if (command == 0x30) + { + m_menupos++; + } + else if (command == 0x37) + { + m_menupos--; + } + else if (command == 0x39) + { + m_menupos -= 4; + } + else if (command == 0x2c) + { + m_menupos = 0x01; + } + else + { + logerror("handle_command %02x (unknown)\n", command); + } + } + else if (m_menustate == MENU_COMMAND_00_IN) + { + m_menustate = MENU_READY_FOR_COMMAND; + } + else if (m_menustate == MENU_COMMAND_01_IN) + { + m_menustate = MENU_READY_FOR_COMMAND; + } + else if (m_menustate == MENU_COMMAND_02_IN) + { + m_menupos = (m_menupos & 0xff00) | ((command - 0x8) & 0xff); + m_menustate = MENU_READY_FOR_COMMAND; + } + else if (m_menustate == MENU_COMMAND_03_IN) + { + m_menupos = (m_menupos & 0x00ff) | (((command - 0x9) & 0xff) << 8); + m_menustate = MENU_READY_FOR_COMMAND; + } + else if (m_menustate == MENU_COMMAND_04_IN) + { + // used if you try to scroll up or left past 0 and the value becomes too large (a negative number) + if (m_is_unsp_type_hack) + { + if (command == 0x0d) + m_menupos += 4; + else if (command == 0x0a) + m_menupos += 0; + // used if you try to scroll up or left past 0 and the value becomes too large (a negative number) + // actually writes 0x314 split into 2 commands, so the 2nd write to 0x04 with param then instead 0b/16 sequence of writes instead of 26/0c adds to the high byte? + else if (command == 0x1e) + m_menupos += 0x310; + } + else + { + m_menupos += (command - 0x09); + m_menustate = MENU_READY_FOR_COMMAND; + } + + m_menustate = MENU_READY_FOR_COMMAND; + } + else if (m_menustate == MENU_COMMAND_05_IN) + { + // used if you try to scroll down past the and the value becomes too large + if (m_is_unsp_type_hack) + { + // actually writes 0x313 split into 2 commands, so the 2nd write to 0x05 with param then instead 0b/16 sequence of writes instead of 26/0c subtracts from the high byte? + if (command == 0x0b) + { + m_menupos -= 0xdc; + } + else if (command == 0x0e) + { + m_menupos -= 0x314; + } + } + else + { + if (command != 0xf0) + m_menupos -= (command - 0x0b); + else + m_menupos -= (command - 0x0a); // dphh8630 when pressing 'right' on final menu page + } + + m_menustate = MENU_READY_FOR_COMMAND; + } +} + +WRITE_LINE_MEMBER(bl_handhelds_menucontrol_device::clock_w) +{ + if (state) + { + m_clockstate = 1; + } + else + { + m_clockstate = 0; + m_command <<= 1; + m_command |= ((m_commandbit)); + m_responsebit = (m_response >> (7 - m_datashifterpos)) & 1; + m_datashifterpos++; + + if (m_datashifterpos == 8) + { + m_datashifterpos = 0; + handle_command(); + } + } +} + +WRITE_LINE_MEMBER(bl_handhelds_menucontrol_device::data_w) +{ + m_commandbit = state; +} + +WRITE_LINE_MEMBER(bl_handhelds_menucontrol_device::reset_w) +{ + m_datashifterpos = 0; +} + +void bl_handhelds_menucontrol_device::device_start() +{ + m_responsebit = 0; + m_clockstate = 0; + m_command = 0; + m_datashifterpos = 0; + m_menupos = 0; + m_response = 0; + m_commandbit = 0; + m_menustate = MENU_READY_FOR_COMMAND; + + save_item(NAME(m_menupos)); + save_item(NAME(m_clockstate)); + save_item(NAME(m_datashifterpos)); + save_item(NAME(m_responsebit)); + save_item(NAME(m_response)); + save_item(NAME(m_commandbit)); + save_item(NAME(m_command)); + save_item(NAME(m_menustate)); +} + +void bl_handhelds_menucontrol_device::device_reset() +{ +} diff --git a/src/devices/machine/bl_handhelds_menucontrol.h b/src/devices/machine/bl_handhelds_menucontrol.h new file mode 100644 index 00000000000..747a60db76b --- /dev/null +++ b/src/devices/machine/bl_handhelds_menucontrol.h @@ -0,0 +1,64 @@ +// license:BSD-3-Clause +// copyright-holders:David Haywood + +#ifndef MAME_MACHINE_BL_HANDHELDS_MENUCONTROL_H +#define MAME_MACHINE_BL_HANDHELDS_MENUCONTROL_H + +#pragma once + +DECLARE_DEVICE_TYPE(BL_HANDHELDS_MENUCONTROL, bl_handhelds_menucontrol_device) + +class bl_handhelds_menucontrol_device : public device_t +{ +public: + // construction/destruction + bl_handhelds_menucontrol_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + // the chip is the same between systems, but there's some logic not fully understood that is causing off-by-1 errors on some calcs + void set_is_unsp_type_hack() { m_is_unsp_type_hack = true; } + + DECLARE_READ_LINE_MEMBER(status_r); + DECLARE_READ_LINE_MEMBER(data_r); + DECLARE_WRITE_LINE_MEMBER(clock_w); + DECLARE_WRITE_LINE_MEMBER(data_w); + DECLARE_WRITE_LINE_MEMBER(reset_w); + +protected: + virtual void device_start() override; + virtual void device_reset() override; + +private: + // config + bool m_is_unsp_type_hack; + + // internal state + uint16_t m_menupos; + + // command handling + uint8_t m_clockstate; + uint8_t m_datashifterpos; + + uint8_t m_responsebit; + uint8_t m_response; + + uint8_t m_commandbit; + uint8_t m_command; + + void handle_command(); + + enum menustate : uint8_t + { + MENU_READY_FOR_COMMAND = 0, + + MENU_COMMAND_00_IN, + MENU_COMMAND_01_IN, + MENU_COMMAND_02_IN, + MENU_COMMAND_03_IN, + MENU_COMMAND_04_IN, + MENU_COMMAND_05_IN, + }; + + uint8_t m_menustate; +}; + +#endif // MAME_MACHINE_BL_HANDHELDS_MENUCONTROL_H diff --git a/src/devices/machine/bq4847.cpp b/src/devices/machine/bq4847.cpp index 09afd9b9424..7dd9031c814 100644 --- a/src/devices/machine/bq4847.cpp +++ b/src/devices/machine/bq4847.cpp @@ -305,6 +305,8 @@ uint8_t bq4847_device::read(offs_t address) set_register(reg_flags, 0xff, false); m_interrupt_cb(intrq_r()); } + else + if (regnum == reg_unused) value = 0; // Reg 15 is locked to 0 in BQ4847 LOGMASKED(LOG_REG, "Reg %d -> %02x\n", regnum, value); diff --git a/src/devices/machine/cs8900a.cpp b/src/devices/machine/cs8900a.cpp index 8a33504a2d8..6f6535150f7 100644 --- a/src/devices/machine/cs8900a.cpp +++ b/src/devices/machine/cs8900a.cpp @@ -4,11 +4,11 @@ /************************************************************************* - CS8900A ethernet controller implementation + CS8900A ethernet controller implementation - by Rhett Aultman <roadriverrail@gmail.com> - ported to MAME from VICE Project (https://sourceforge.net/p/vice-emu/) - VICE CS8900 code by Spiro Trikaliotis <Spiro.Trikaliotis@gmx.de> + by Rhett Aultman <roadriverrail@gmail.com> + ported to MAME from VICE Project (https://sourceforge.net/p/vice-emu/) + VICE CS8900 code by Spiro Trikaliotis <Spiro.Trikaliotis@gmx.de> **************************************************************************/ @@ -20,17 +20,17 @@ DEFINE_DEVICE_TYPE(CS8900A, cs8900a_device, "cs8900a", "CS8900A Crystal LAN 10Base-T Ethernet MAC") /* warn illegal behaviour */ -#define CS8900_DEBUG_WARN_REG (1 << 1U) /* warn about invalid register accesses */ -#define CS8900_DEBUG_WARN_RXTX (1 << 2U) /* warn about invalid rx or tx conditions */ +#define CS8900_DEBUG_WARN_REG (1 << 1U) /* warn about invalid register accesses */ +#define CS8900_DEBUG_WARN_RXTX (1 << 2U) /* warn about invalid rx or tx conditions */ -#define CS8900_DEBUG (1 << 3U) /* enable to see port reads */ +#define CS8900_DEBUG (1 << 3U) /* enable to see port reads */ #define CS8900_DEBUG_INIT (1 << 4U) -#define CS8900_DEBUG_LOAD (1 << 5U) /* enable to see port reads */ -#define CS8900_DEBUG_STORE (1 << 6U) /* enable to see port writes */ -#define CS8900_DEBUG_REGISTERS (1 << 7U) /* enable to see CS8900a register I/O */ -#define CS8900_DEBUG_RXTX_STATE (1 << 8U) /* enable to see tranceiver state changes */ -#define CS8900_DEBUG_RXTX_DATA (1 << 9U) /* enable to see data in/out flow */ -#define CS8900_DEBUG_FRAMES (1 << 10U) /* enable to see arch frame send/recv */ +#define CS8900_DEBUG_LOAD (1 << 5U) /* enable to see port reads */ +#define CS8900_DEBUG_STORE (1 << 6U) /* enable to see port writes */ +#define CS8900_DEBUG_REGISTERS (1 << 7U) /* enable to see CS8900a register I/O */ +#define CS8900_DEBUG_RXTX_STATE (1 << 8U) /* enable to see tranceiver state changes */ +#define CS8900_DEBUG_RXTX_DATA (1 << 9U) /* enable to see data in/out flow */ +#define CS8900_DEBUG_FRAMES (1 << 10U) /* enable to see arch frame send/recv */ /** #define CS8900_DEBUG_IGNORE_RXEVENT 1 **/ /* enable to ignore RXEVENT in DEBUG_REGISTERS */ #define VERBOSE 0 @@ -41,57 +41,57 @@ DEFINE_DEVICE_TYPE(CS8900A, cs8900a_device, "cs8900a", "CS8900A Crystal LAN 10Ba /* CS8900 registers */ -/* these are the 8 16-bit-ports for "I/O space configuration" - (see 4.10 on page 75 of cs8900a-4.pdf, the cs8900a data sheet) +/* these are the 8 16-bit-ports for "I/O space configuration" + (see 4.10 on page 75 of cs8900a-4.pdf, the cs8900a data sheet) - REMARK: The code operatoes the cs8900a in IO space configuration, as - it generates I/OW and I/OR signals. + REMARK: The code operatoes the cs8900a in IO space configuration, as + it generates I/OW and I/OR signals. */ /* - RW: RXTXDATA = DE00/DE01 - RW: RXTXDATA2 = DE02/DE03 (for 32-bit-operation) - -W: TXCMD = DE04/DE05 (TxCMD, Transmit Command) mapped to PP + 0144 (Reg. 9, Sec. 4.4, page 46) - -W: TXLENGTH = DE06/DE07 (TxLenght, Transmit Length) mapped to PP + 0146 - R-: INTSTQUEUE = DE08/DE09 (Interrupt Status Queue) mapped to PP + 0120 (ISQ, Sec. 5.1, page 78) - RW: PP_PTR = DE0A/DE0B (PacketPage Pointer) (see. page 75p: Read -011.---- ----.----) - RW: PP_DATA0 = DE0C/DE0D (PacketPage Data (Port 0)) - RW: PP_DATA1 = DE0E/DE0F (PacketPage Data (Port 1)) (for 32 bit only) + RW: RXTXDATA = DE00/DE01 + RW: RXTXDATA2 = DE02/DE03 (for 32-bit-operation) + -W: TXCMD = DE04/DE05 (TxCMD, Transmit Command) mapped to PP + 0144 (Reg. 9, Sec. 4.4, page 46) + -W: TXLENGTH = DE06/DE07 (TxLenght, Transmit Length) mapped to PP + 0146 + R-: INTSTQUEUE = DE08/DE09 (Interrupt Status Queue) mapped to PP + 0120 (ISQ, Sec. 5.1, page 78) + RW: PP_PTR = DE0A/DE0B (PacketPage Pointer) (see. page 75p: Read -011.---- ----.----) + RW: PP_DATA0 = DE0C/DE0D (PacketPage Data (Port 0)) + RW: PP_DATA1 = DE0E/DE0F (PacketPage Data (Port 1)) (for 32 bit only) */ enum io_space_conf_regs_e : u8 { - CS8900_ADDR_RXTXDATA = 0x00, /* RW */ - CS8900_ADDR_RXTXDATA2 = 0x02, /* RW 32 bit only! */ - CS8900_ADDR_TXCMD = 0x04, /* -W Maps to PP+0144 */ - CS8900_ADDR_TXLENGTH = 0x06, /* -W Maps to PP+0146 */ - CS8900_ADDR_INTSTQUEUE = 0x08, /* R- Interrupt status queue, maps to PP + 0120 */ - CS8900_ADDR_PP_PTR = 0x0a, /* RW PacketPage Pointer */ - CS8900_ADDR_PP_DATA = 0x0c, /* RW PacketPage Data, Port 0 */ - CS8900_ADDR_PP_DATA2 = 0x0e /* RW PacketPage Data, Port 1 - 32 bit only */ + CS8900_ADDR_RXTXDATA = 0x00, /* RW */ + CS8900_ADDR_RXTXDATA2 = 0x02, /* RW 32 bit only! */ + CS8900_ADDR_TXCMD = 0x04, /* -W Maps to PP+0144 */ + CS8900_ADDR_TXLENGTH = 0x06, /* -W Maps to PP+0146 */ + CS8900_ADDR_INTSTQUEUE = 0x08, /* R- Interrupt status queue, maps to PP + 0120 */ + CS8900_ADDR_PP_PTR = 0x0a, /* RW PacketPage Pointer */ + CS8900_ADDR_PP_DATA = 0x0c, /* RW PacketPage Data, Port 0 */ + CS8900_ADDR_PP_DATA2 = 0x0e /* RW PacketPage Data, Port 1 - 32 bit only */ }; /* Makros for reading and writing the visible register: */ -#define GET_CS8900_8(_xxx_) \ - (assert(_xxx_ < CS8900_COUNT_IO_REGISTER), \ - cs8900_ioregs[_xxx_] \ +#define GET_CS8900_8(_xxx_) \ + (assert(_xxx_ < CS8900_COUNT_IO_REGISTER), \ + cs8900_ioregs[_xxx_] \ ) -#define SET_CS8900_8(_xxx_, _val_) \ - do { \ - assert(_xxx_ < CS8900_COUNT_IO_REGISTER); \ - cs8900_ioregs[_xxx_] = (_val_) & 0xff; \ +#define SET_CS8900_8(_xxx_, _val_) \ + do { \ + assert(_xxx_ < CS8900_COUNT_IO_REGISTER); \ + cs8900_ioregs[_xxx_] = (_val_) & 0xff; \ } while (0) -#define GET_CS8900_16(_xxx_) \ - (assert(_xxx_ < CS8900_COUNT_IO_REGISTER), \ - cs8900_ioregs[_xxx_] | (cs8900_ioregs[_xxx_ + 1] << 8) \ +#define GET_CS8900_16(_xxx_) \ + (assert(_xxx_ < CS8900_COUNT_IO_REGISTER), \ + cs8900_ioregs[_xxx_] | (cs8900_ioregs[_xxx_ + 1] << 8) \ ) -#define SET_CS8900_16(_xxx_, _val_) \ - do { \ - assert(_xxx_ < CS8900_COUNT_IO_REGISTER); \ - cs8900_ioregs[_xxx_] = (_val_) & 0xff; \ - cs8900_ioregs[_xxx_ + 1] = (_val_ >> 8) & 0xff; \ +#define SET_CS8900_16(_xxx_, _val_) \ + do { \ + assert(_xxx_ < CS8900_COUNT_IO_REGISTER); \ + cs8900_ioregs[_xxx_] = (_val_) & 0xff; \ + cs8900_ioregs[_xxx_ + 1] = (_val_ >> 8) & 0xff; \ } while (0) /* The PacketPage register */ @@ -99,106 +99,106 @@ enum io_space_conf_regs_e : u8 { /* Macros for reading and writing the PacketPage register: */ -#define GET_PP_8(_xxx_) \ - (assert(_xxx_ < MAX_PACKETPAGE_ARRAY), \ - cs8900_packetpage[_xxx_] \ +#define GET_PP_8(_xxx_) \ + (assert(_xxx_ < MAX_PACKETPAGE_ARRAY), \ + cs8900_packetpage[_xxx_] \ ) -#define GET_PP_16(_xxx_) \ - (assert(_xxx_ < MAX_PACKETPAGE_ARRAY), \ - assert((_xxx_ & 1) == 0), \ - ((u16)cs8900_packetpage[_xxx_]) \ - |((u16)cs8900_packetpage[_xxx_ + 1] << 8) \ +#define GET_PP_16(_xxx_) \ + (assert(_xxx_ < MAX_PACKETPAGE_ARRAY), \ + assert((_xxx_ & 1) == 0), \ + ((u16)cs8900_packetpage[_xxx_]) \ + |((u16)cs8900_packetpage[_xxx_ + 1] << 8) \ ) -#define GET_PP_32(_xxx_) \ - (assert(_xxx_ < MAX_PACKETPAGE_ARRAY), \ - assert((_xxx_ & 3) == 0), \ - (((u32)cs8900_packetpage[_xxx_])) \ - |(((u32)cs8900_packetpage[_xxx_ + 1]) << 8) \ - |(((u32)cs8900_packetpage[_xxx_ + 2]) << 16) \ - |(((u32)cs8900_packetpage[_xxx_ + 3]) << 24) \ +#define GET_PP_32(_xxx_) \ + (assert(_xxx_ < MAX_PACKETPAGE_ARRAY), \ + assert((_xxx_ & 3) == 0), \ + (((u32)cs8900_packetpage[_xxx_])) \ + |(((u32)cs8900_packetpage[_xxx_ + 1]) << 8) \ + |(((u32)cs8900_packetpage[_xxx_ + 2]) << 16) \ + |(((u32)cs8900_packetpage[_xxx_ + 3]) << 24) \ ) -#define SET_PP_8(_xxx_, _val_) \ - do { \ - assert(_xxx_ < MAX_PACKETPAGE_ARRAY); \ - cs8900_packetpage[_xxx_] = (_val_) & 0xFF; \ +#define SET_PP_8(_xxx_, _val_) \ + do { \ + assert(_xxx_ < MAX_PACKETPAGE_ARRAY); \ + cs8900_packetpage[_xxx_] = (_val_) & 0xFF; \ } while (0) -#define SET_PP_16(_xxx_, _val_) \ - do { \ - assert(_xxx_ < MAX_PACKETPAGE_ARRAY); \ - assert((_xxx_ & 1) == 0), \ - cs8900_packetpage[_xxx_] = (_val_) & 0xFF; \ - cs8900_packetpage[_xxx_ + 1] = (_val_ >> 8) & 0xFF; \ +#define SET_PP_16(_xxx_, _val_) \ + do { \ + assert(_xxx_ < MAX_PACKETPAGE_ARRAY); \ + assert((_xxx_ & 1) == 0), \ + cs8900_packetpage[_xxx_] = (_val_) & 0xFF; \ + cs8900_packetpage[_xxx_ + 1] = (_val_ >> 8) & 0xFF; \ } while (0) -#define SET_PP_32(_xxx_, _val_) \ - do { \ - assert(_xxx_ < MAX_PACKETPAGE_ARRAY); \ - assert((_xxx_ & 3) == 0), \ - cs8900_packetpage[_xxx_] = (_val_) & 0xFF; \ - cs8900_packetpage[_xxx_ + 1] = (_val_ >> 8) & 0xFF; \ - cs8900_packetpage[_xxx_ + 2] = (_val_ >> 16) & 0xFF; \ - cs8900_packetpage[_xxx_ + 3] = (_val_ >> 24) & 0xFF; \ +#define SET_PP_32(_xxx_, _val_) \ + do { \ + assert(_xxx_ < MAX_PACKETPAGE_ARRAY); \ + assert((_xxx_ & 3) == 0), \ + cs8900_packetpage[_xxx_] = (_val_) & 0xFF; \ + cs8900_packetpage[_xxx_ + 1] = (_val_ >> 8) & 0xFF; \ + cs8900_packetpage[_xxx_ + 2] = (_val_ >> 16) & 0xFF; \ + cs8900_packetpage[_xxx_ + 3] = (_val_ >> 24) & 0xFF; \ } while (0) enum packetpage_regs_e : u16 { /* The packetpage register: see p. 39f */ - CS8900_PP_ADDR_PRODUCTID = 0x0000, /* R- - 4.3., p. 41 */ - CS8900_PP_ADDR_IOBASE = 0x0020, /* i RW - 4.3., p. 41 - 4.7., p. 72 */ - CS8900_PP_ADDR_INTNO = 0x0022, /* i RW - 3.2., p. 17 - 4.3., p. 41 */ - CS8900_PP_ADDR_DMA_CHAN = 0x0024, /* i RW - 3.2., p. 17 - 4.3., p. 41 */ - CS8900_PP_ADDR_DMA_SOF = 0x0026, /* ? R- - 4.3., p. 41 - 5.4., p. 89 */ - CS8900_PP_ADDR_DMA_FC = 0x0028, /* ? R- - 4.3., p. 41, "Receive DMA" */ - CS8900_PP_ADDR_RXDMA_BC = 0x002a, /* ? R- - 4.3., p. 41 - 5.4., p. 89 */ - CS8900_PP_ADDR_MEMBASE = 0x002c, /* i RW - 4.3., p. 41 - 4.9., p. 73 */ - CS8900_PP_ADDR_BPROM_BASE = 0x0030, /* i RW - 3.6., p. 24 - 4.3., p. 41 */ - CS8900_PP_ADDR_BPROM_MASK = 0x0034, /* i RW - 3.6., p. 24 - 4.3., p. 41 */ + CS8900_PP_ADDR_PRODUCTID = 0x0000, /* R- - 4.3., p. 41 */ + CS8900_PP_ADDR_IOBASE = 0x0020, /* i RW - 4.3., p. 41 - 4.7., p. 72 */ + CS8900_PP_ADDR_INTNO = 0x0022, /* i RW - 3.2., p. 17 - 4.3., p. 41 */ + CS8900_PP_ADDR_DMA_CHAN = 0x0024, /* i RW - 3.2., p. 17 - 4.3., p. 41 */ + CS8900_PP_ADDR_DMA_SOF = 0x0026, /* ? R- - 4.3., p. 41 - 5.4., p. 89 */ + CS8900_PP_ADDR_DMA_FC = 0x0028, /* ? R- - 4.3., p. 41, "Receive DMA" */ + CS8900_PP_ADDR_RXDMA_BC = 0x002a, /* ? R- - 4.3., p. 41 - 5.4., p. 89 */ + CS8900_PP_ADDR_MEMBASE = 0x002c, /* i RW - 4.3., p. 41 - 4.9., p. 73 */ + CS8900_PP_ADDR_BPROM_BASE = 0x0030, /* i RW - 3.6., p. 24 - 4.3., p. 41 */ + CS8900_PP_ADDR_BPROM_MASK = 0x0034, /* i RW - 3.6., p. 24 - 4.3., p. 41 */ /* 0x0038 - 0x003F: reserved */ - CS8900_PP_ADDR_EEPROM_CMD = 0x0040, /* i RW - 3.5., p. 23 - 4.3., p. 41 */ - CS8900_PP_ADDR_EEPROM_DATA = 0x0042, /* i RW - 3.5., p. 23 - 4.3., p. 41 */ + CS8900_PP_ADDR_EEPROM_CMD = 0x0040, /* i RW - 3.5., p. 23 - 4.3., p. 41 */ + CS8900_PP_ADDR_EEPROM_DATA = 0x0042, /* i RW - 3.5., p. 23 - 4.3., p. 41 */ /* 0x0044 - 0x004F: reserved */ - CS8900_PP_ADDR_REC_FRAME_BC = 0x0050, /* RW - 4.3., p. 41 - 5.2.9., p. 86 */ + CS8900_PP_ADDR_REC_FRAME_BC = 0x0050, /* RW - 4.3., p. 41 - 5.2.9., p. 86 */ /* 0x0052 - 0x00FF: reserved */ - CS8900_PP_ADDR_CONF_CTRL = 0x0100, /* - RW - 4.4., p. 46; see below */ - CS8900_PP_ADDR_STATUS_EVENT = 0x0120, /* - R- - 4.4., p. 46; see below */ + CS8900_PP_ADDR_CONF_CTRL = 0x0100, /* - RW - 4.4., p. 46; see below */ + CS8900_PP_ADDR_STATUS_EVENT = 0x0120, /* - R- - 4.4., p. 46; see below */ /* 0x0140 - 0x0143: reserved */ - CS8900_PP_ADDR_TXCMD = 0x0144, /* # -W - 4.5., p. 70 - 5.7., p. 98 */ - CS8900_PP_ADDR_TXLENGTH = 0x0146, /* # -W - 4.5., p. 70 - 5.7., p. 98 */ + CS8900_PP_ADDR_TXCMD = 0x0144, /* # -W - 4.5., p. 70 - 5.7., p. 98 */ + CS8900_PP_ADDR_TXLENGTH = 0x0146, /* # -W - 4.5., p. 70 - 5.7., p. 98 */ /* 0x0148 - 0x014F: reserved */ - CS8900_PP_ADDR_LOG_ADDR_FILTER = 0x0150, /* RW - 4.6., p. 71 - 5.3., p. 86 */ - CS8900_PP_ADDR_MAC_ADDR = 0x0158, /* # RW - 4.6., p. 71 - 5.3., p. 86 */ + CS8900_PP_ADDR_LOG_ADDR_FILTER = 0x0150, /* RW - 4.6., p. 71 - 5.3., p. 86 */ + CS8900_PP_ADDR_MAC_ADDR = 0x0158, /* # RW - 4.6., p. 71 - 5.3., p. 86 */ /* 0x015E - 0x03FF: reserved */ - CS8900_PP_ADDR_RXSTATUS = 0x0400, /* R- - 4.7., p. 72 - 5.2., p. 78 */ - CS8900_PP_ADDR_RXLENGTH = 0x0402, /* R- - 4.7., p. 72 - 5.2., p. 78 */ - CS8900_PP_ADDR_RX_FRAMELOC = 0x0404, /* R- - 4.7., p. 72 - 5.2., p. 78 */ + CS8900_PP_ADDR_RXSTATUS = 0x0400, /* R- - 4.7., p. 72 - 5.2., p. 78 */ + CS8900_PP_ADDR_RXLENGTH = 0x0402, /* R- - 4.7., p. 72 - 5.2., p. 78 */ + CS8900_PP_ADDR_RX_FRAMELOC = 0x0404, /* R- - 4.7., p. 72 - 5.2., p. 78 */ /* here, the received frame is stored */ - CS8900_PP_ADDR_TX_FRAMELOC = 0x0A00, /* -W - 4.7., p. 72 - 5.7., p. 98 */ + CS8900_PP_ADDR_TX_FRAMELOC = 0x0A00, /* -W - 4.7., p. 72 - 5.7., p. 98 */ /* here, the frame to transmit is stored */ - CS8900_PP_ADDR_END = 0x1000, /* memory to CS8900_PP_ADDR_END-1 is used */ + CS8900_PP_ADDR_END = 0x1000, /* memory to CS8900_PP_ADDR_END-1 is used */ /* CS8900_PP_ADDR_CONF_CTRL is subdivided: */ - CS8900_PP_ADDR_CC_RXCFG = 0x0102, /* # RW - 4.4.6., p. 52 - 0003 */ - CS8900_PP_ADDR_CC_RXCTL = 0x0104, /* # RW - 4.4.8., p. 54 - 0005 */ - CS8900_PP_ADDR_CC_TXCFG = 0x0106, /* RW - 4.4.9., p. 55 - 0007 */ - CS8900_PP_ADDR_CC_TXCMD = 0x0108, /* R- - 4.4.11., p. 57 - 0009 */ - CS8900_PP_ADDR_CC_BUFCFG = 0x010A, /* RW - 4.4.12., p. 58 - 000B */ - CS8900_PP_ADDR_CC_LINECTL = 0x0112, /* # RW - 4.4.16., p. 62 - 0013 */ - CS8900_PP_ADDR_CC_SELFCTL = 0x0114, /* RW - 4.4.18., p. 64 - 0015 */ - CS8900_PP_ADDR_CC_BUSCTL = 0x0116, /* RW - 4.4.20., p. 66 - 0017 */ - CS8900_PP_ADDR_CC_TESTCTL = 0x0118, /* RW - 4.4.22., p. 68 - 0019 */ + CS8900_PP_ADDR_CC_RXCFG = 0x0102, /* # RW - 4.4.6., p. 52 - 0003 */ + CS8900_PP_ADDR_CC_RXCTL = 0x0104, /* # RW - 4.4.8., p. 54 - 0005 */ + CS8900_PP_ADDR_CC_TXCFG = 0x0106, /* RW - 4.4.9., p. 55 - 0007 */ + CS8900_PP_ADDR_CC_TXCMD = 0x0108, /* R- - 4.4.11., p. 57 - 0009 */ + CS8900_PP_ADDR_CC_BUFCFG = 0x010A, /* RW - 4.4.12., p. 58 - 000B */ + CS8900_PP_ADDR_CC_LINECTL = 0x0112, /* # RW - 4.4.16., p. 62 - 0013 */ + CS8900_PP_ADDR_CC_SELFCTL = 0x0114, /* RW - 4.4.18., p. 64 - 0015 */ + CS8900_PP_ADDR_CC_BUSCTL = 0x0116, /* RW - 4.4.20., p. 66 - 0017 */ + CS8900_PP_ADDR_CC_TESTCTL = 0x0118, /* RW - 4.4.22., p. 68 - 0019 */ /* CS8900_PP_ADDR_STATUS_EVENT is subdivided: */ - CS8900_PP_ADDR_SE_ISQ = 0x0120, /* R- - 4.4.5., p. 51 - 0000 */ - CS8900_PP_ADDR_SE_RXEVENT = 0x0124, /* # R- - 4.4.7., p. 53 - 0004 */ - CS8900_PP_ADDR_SE_TXEVENT = 0x0128, /* R- - 4.4.10., p. 56 - 0008 */ - CS8900_PP_ADDR_SE_BUFEVENT = 0x012C, /* R- - 4.4.13., p. 59 - 000C */ - CS8900_PP_ADDR_SE_RXMISS = 0x0130, /* R- - 4.4.14., p. 60 - 0010 */ - CS8900_PP_ADDR_SE_TXCOL = 0x0132, /* R- - 4.4.15., p. 61 - 0012 */ - CS8900_PP_ADDR_SE_LINEST = 0x0134, /* R- - 4.4.17., p. 63 - 0014 */ - CS8900_PP_ADDR_SE_SELFST = 0x0136, /* R- - 4.4.19., p. 65 - 0016 */ - CS8900_PP_ADDR_SE_BUSST = 0x0138, /* # R- - 4.4.21., p. 67 - 0018 */ - CS8900_PP_ADDR_SE_TDR = 0x013C /* R- - 4.4.23., p. 69 - 001C */ + CS8900_PP_ADDR_SE_ISQ = 0x0120, /* R- - 4.4.5., p. 51 - 0000 */ + CS8900_PP_ADDR_SE_RXEVENT = 0x0124, /* # R- - 4.4.7., p. 53 - 0004 */ + CS8900_PP_ADDR_SE_TXEVENT = 0x0128, /* R- - 4.4.10., p. 56 - 0008 */ + CS8900_PP_ADDR_SE_BUFEVENT = 0x012C, /* R- - 4.4.13., p. 59 - 000C */ + CS8900_PP_ADDR_SE_RXMISS = 0x0130, /* R- - 4.4.14., p. 60 - 0010 */ + CS8900_PP_ADDR_SE_TXCOL = 0x0132, /* R- - 4.4.15., p. 61 - 0012 */ + CS8900_PP_ADDR_SE_LINEST = 0x0134, /* R- - 4.4.17., p. 63 - 0014 */ + CS8900_PP_ADDR_SE_SELFST = 0x0136, /* R- - 4.4.19., p. 65 - 0016 */ + CS8900_PP_ADDR_SE_BUSST = 0x0138, /* # R- - 4.4.21., p. 67 - 0018 */ + CS8900_PP_ADDR_SE_TDR = 0x013C /* R- - 4.4.23., p. 69 - 001C */ }; enum tx_rx_min_max_e : u16 { @@ -209,21 +209,21 @@ enum tx_rx_min_max_e : u16 { }; enum cs8900_tx_state_e : u8 { - CS8900_TX_IDLE = 0, - CS8900_TX_GOT_CMD = 1, - CS8900_TX_GOT_LEN = 2, - CS8900_TX_READ_BUSST = 3 + CS8900_TX_IDLE = 0, + CS8900_TX_GOT_CMD = 1, + CS8900_TX_GOT_LEN = 2, + CS8900_TX_READ_BUSST = 3 }; enum cs8900_rx_state_e : u8 { - CS8900_RX_IDLE = 0, - CS8900_RX_GOT_FRAME = 1 + CS8900_RX_IDLE = 0, + CS8900_RX_GOT_FRAME = 1 }; enum pp_ptr_masks_e : u16 { - PP_PTR_AUTO_INCR_FLAG = 0x8000, /* auto increment flag in package pointer */ - PP_PTR_FLAG_MASK = 0xf000, /* is always : x y 1 1 (with x=auto incr) */ - PP_PTR_ADDR_MASK = 0x0fff /* address portion of packet page pointer */ + PP_PTR_AUTO_INCR_FLAG = 0x8000, /* auto increment flag in package pointer */ + PP_PTR_FLAG_MASK = 0xf000, /* is always : x y 1 1 (with x=auto incr) */ + PP_PTR_ADDR_MASK = 0x0fff /* address portion of packet page pointer */ }; #define LO_BYTE(x) (u8)((x)& 0xff) @@ -255,10 +255,10 @@ void cs8900a_device::cs8900_set_tx_status(int ready, int error) u16 new_status = old_status & ~0x180; if (ready) - new_status |= 0x100; /* set Rdy4TxNOW */ + new_status |= 0x100; /* set Rdy4TxNOW */ if (error) - new_status |= 0x080; /* set TxBidErr */ + new_status |= 0x080; /* set TxBidErr */ if (new_status != old_status) { @@ -301,39 +301,39 @@ void cs8900a_device::device_reset() SET_PP_16(CS8900_PP_ADDR_DMA_CHAN, 0x0003); /* xxxx xxxx xxxx xx11b */ /* according to descriptions of the registers, see definitions of - CS8900_PP_ADDR_CC_... and CS8900_PP_ADDR_SE_... above! */ - - SET_PP_16(CS8900_PP_ADDR_CC_RXCFG, 0x0003); - SET_PP_16(CS8900_PP_ADDR_CC_RXCTL, 0x0005); - SET_PP_16(CS8900_PP_ADDR_CC_TXCFG, 0x0007); - SET_PP_16(CS8900_PP_ADDR_CC_TXCMD, 0x0009); - SET_PP_16(CS8900_PP_ADDR_CC_BUFCFG, 0x000B); - SET_PP_16(CS8900_PP_ADDR_CC_LINECTL, 0x0013); - SET_PP_16(CS8900_PP_ADDR_CC_SELFCTL, 0x0015); - SET_PP_16(CS8900_PP_ADDR_CC_BUSCTL, 0x0017); - SET_PP_16(CS8900_PP_ADDR_CC_TESTCTL, 0x0019); - - SET_PP_16(CS8900_PP_ADDR_SE_ISQ, 0x0000); - SET_PP_16(CS8900_PP_ADDR_SE_RXEVENT, 0x0004); - SET_PP_16(CS8900_PP_ADDR_SE_TXEVENT, 0x0008); - SET_PP_16(CS8900_PP_ADDR_SE_BUFEVENT, 0x000C); - SET_PP_16(CS8900_PP_ADDR_SE_RXMISS, 0x0010); - SET_PP_16(CS8900_PP_ADDR_SE_TXCOL, 0x0012); - SET_PP_16(CS8900_PP_ADDR_SE_LINEST, 0x0014); - SET_PP_16(CS8900_PP_ADDR_SE_SELFST, 0x0016); - SET_PP_16(CS8900_PP_ADDR_SE_BUSST, 0x0018); - SET_PP_16(CS8900_PP_ADDR_SE_TDR, 0x001C); - - SET_PP_16(CS8900_PP_ADDR_TXCMD, 0x0009); + CS8900_PP_ADDR_CC_... and CS8900_PP_ADDR_SE_... above! */ + + SET_PP_16(CS8900_PP_ADDR_CC_RXCFG, 0x0003); + SET_PP_16(CS8900_PP_ADDR_CC_RXCTL, 0x0005); + SET_PP_16(CS8900_PP_ADDR_CC_TXCFG, 0x0007); + SET_PP_16(CS8900_PP_ADDR_CC_TXCMD, 0x0009); + SET_PP_16(CS8900_PP_ADDR_CC_BUFCFG, 0x000B); + SET_PP_16(CS8900_PP_ADDR_CC_LINECTL, 0x0013); + SET_PP_16(CS8900_PP_ADDR_CC_SELFCTL, 0x0015); + SET_PP_16(CS8900_PP_ADDR_CC_BUSCTL, 0x0017); + SET_PP_16(CS8900_PP_ADDR_CC_TESTCTL, 0x0019); + + SET_PP_16(CS8900_PP_ADDR_SE_ISQ, 0x0000); + SET_PP_16(CS8900_PP_ADDR_SE_RXEVENT, 0x0004); + SET_PP_16(CS8900_PP_ADDR_SE_TXEVENT, 0x0008); + SET_PP_16(CS8900_PP_ADDR_SE_BUFEVENT, 0x000C); + SET_PP_16(CS8900_PP_ADDR_SE_RXMISS, 0x0010); + SET_PP_16(CS8900_PP_ADDR_SE_TXCOL, 0x0012); + SET_PP_16(CS8900_PP_ADDR_SE_LINEST, 0x0014); + SET_PP_16(CS8900_PP_ADDR_SE_SELFST, 0x0016); + SET_PP_16(CS8900_PP_ADDR_SE_BUSST, 0x0018); + SET_PP_16(CS8900_PP_ADDR_SE_TDR, 0x001C); + + SET_PP_16(CS8900_PP_ADDR_TXCMD, 0x0009); /* 4.4.19 Self Status Register, p. 65 - Important: set INITD (Bit 7) to signal device is ready */ - SET_PP_16(CS8900_PP_ADDR_SE_SELFST, 0x0896); + Important: set INITD (Bit 7) to signal device is ready */ + SET_PP_16(CS8900_PP_ADDR_SE_SELFST, 0x0896); cs8900_recv_control = GET_PP_16(CS8900_PP_ADDR_CC_RXCTL); /* spec: mac address is undefined after reset. - real HW: keeps the last set address. */ + real HW: keeps the last set address. */ for (int i = 0; i < 6; i++) SET_PP_8(CS8900_PP_ADDR_MAC_ADDR + i, cs8900_ia_mac[i]); @@ -380,13 +380,13 @@ cs8900a_device::cs8900a_device(const machine_config& mconfig, device_type type, , device_network_interface(mconfig, *this, 10.0f) , cs8900_ia_mac{0, 0, 0, 0, 0, 0} , cs8900_packetpage_ptr(0) - , cs8900_recv_control(0) /* copy of CC_RXCTL (contains all bits below) */ - , cs8900_recv_broadcast(false) /* broadcast */ - , cs8900_recv_mac(false) /* individual address (IA) */ - , cs8900_recv_multicast(false) /* multicast if address passes the hash filter */ - , cs8900_recv_correct(false) /* accept correct frames */ - , cs8900_recv_promiscuous(false) /* promiscuous mode */ - , cs8900_recv_hashfilter(false) /* accept if IA passes the hash filter */ + , cs8900_recv_control(0) /* copy of CC_RXCTL (contains all bits below) */ + , cs8900_recv_broadcast(false) /* broadcast */ + , cs8900_recv_mac(false) /* individual address (IA) */ + , cs8900_recv_multicast(false) /* multicast if address passes the hash filter */ + , cs8900_recv_correct(false) /* accept correct frames */ + , cs8900_recv_promiscuous(false) /* promiscuous mode */ + , cs8900_recv_hashfilter(false) /* accept if IA passes the hash filter */ , tx_buffer(CS8900_PP_ADDR_TX_FRAMELOC) , rx_buffer(CS8900_PP_ADDR_RXSTATUS) , tx_count(0) @@ -405,8 +405,8 @@ cs8900a_device::cs8900a_device(machine_config const& mconfig, char const *tag, d {} /* - This is a helper for cs8900_receive() to determine if the received frame should be accepted - according to the settings. + This is a helper for cs8900_receive() to determine if the received frame should be accepted + according to the settings. */ bool cs8900a_device::cs8900_should_accept(unsigned char *buffer, int length, bool *phashed, int *phash_index, bool *pcorrect_mac, bool *pbroadcast, bool *pmulticast) @@ -419,8 +419,8 @@ bool cs8900a_device::cs8900_should_accept(unsigned char *buffer, int length, boo *phashed = false; *phash_index = 0; *pcorrect_mac = false; - *pbroadcast = false; - *pmulticast = false; + *pbroadcast = false; + *pmulticast = false; LOGMASKED(CS8900_DEBUG_FRAMES, "cs8900_should_accept called with %02X:%02X:%02X:%02X:%02X:%02X, length=%4u", cs8900_ia_mac[0], cs8900_ia_mac[1], cs8900_ia_mac[2], @@ -496,8 +496,8 @@ u16 cs8900a_device::cs8900_receive() u8 buffer[MAX_RXLENGTH]; int len; - bool hashed = false; - int hash_index = 0; + bool hashed = false; + int hash_index = 0; bool rx_ok = false; bool correct_mac = false; bool broadcast = false; @@ -536,7 +536,7 @@ u16 cs8900a_device::cs8900_receive() { /* we already know the type of frame: Trust it! */ LOGMASKED(CS8900_DEBUG_FRAMES, "+++ cs8900_receive(): *** hashed=%u, correct_mac=%u, " - "broadcast=%u", hashed, correct_mac, broadcast); + "broadcast=%u", hashed, correct_mac, broadcast); } else { @@ -619,21 +619,21 @@ u16 cs8900a_device::cs8900_receive() } /* ------------------------------------------------------------------------- */ -/* reading and writing IO register functions */ +/* reading and writing IO register functions */ /* - These registers are currently fully or partially supported: - - CS8900_PP_ADDR_CC_RXCFG 0x0102 * # RW - 4.4.6., p. 52 - 0003 * - CS8900_PP_ADDR_CC_RXCTL 0x0104 * # RW - 4.4.8., p. 54 - 0005 * - CS8900_PP_ADDR_CC_LINECTL 0x0112 * # RW - 4.4.16., p. 62 - 0013 * - CS8900_PP_ADDR_SE_RXEVENT 0x0124 * # R- - 4.4.7., p. 53 - 0004 * - CS8900_PP_ADDR_SE_BUSST 0x0138 * # R- - 4.4.21., p. 67 - 0018 * - CS8900_PP_ADDR_TXCMD 0x0144 * # -W - 4.5., p. 70 - 5.7., p. 98 * - CS8900_PP_ADDR_TXLENGTH 0x0146 * # -W - 4.5., p. 70 - 5.7., p. 98 * - CS8900_PP_ADDR_MAC_ADDR 0x0158 * # RW - 4.6., p. 71 - 5.3., p. 86 * - 0x015a - 0x015c + These registers are currently fully or partially supported: + + CS8900_PP_ADDR_CC_RXCFG 0x0102 * # RW - 4.4.6., p. 52 - 0003 * + CS8900_PP_ADDR_CC_RXCTL 0x0104 * # RW - 4.4.8., p. 54 - 0005 * + CS8900_PP_ADDR_CC_LINECTL 0x0112 * # RW - 4.4.16., p. 62 - 0013 * + CS8900_PP_ADDR_SE_RXEVENT 0x0124 * # R- - 4.4.7., p. 53 - 0004 * + CS8900_PP_ADDR_SE_BUSST 0x0138 * # R- - 4.4.21., p. 67 - 0018 * + CS8900_PP_ADDR_TXCMD 0x0144 * # -W - 4.5., p. 70 - 5.7., p. 98 * + CS8900_PP_ADDR_TXLENGTH 0x0146 * # -W - 4.5., p. 70 - 5.7., p. 98 * + CS8900_PP_ADDR_MAC_ADDR 0x0158 * # RW - 4.6., p. 71 - 5.3., p. 86 * + 0x015a + 0x015c */ /* ------------------------------------------------------------------------- */ @@ -674,7 +674,7 @@ void cs8900a_device::cs8900_write_tx_buffer(u8 value, int odd_address) /* full frame transmitted? */ if (tx_count == tx_length) { - LOGMASKED(CS8900_DEBUG_FRAMES, "cs8900_arch_transmit() called with: " + LOGMASKED(CS8900_DEBUG_FRAMES, "cs8900_arch_transmit() called with:\t\t\t\t\t\t\t\t\t" "length=%4u and buffer %s", tx_length, debug_outbuffer(tx_length, &cs8900_packetpage[CS8900_PP_ADDR_TX_FRAMELOC]) ); @@ -714,19 +714,19 @@ u8 cs8900a_device::cs8900_read_rx_buffer(int odd_address) else { /* - According to the CS8900 spec, the handling is the following: - first read H, then L (RX_STATUS), then H, then L (RX_LENGTH). - Inside the RX frame data, we always get L then H, until the end is reached. - - even odd - CS8900_PP_ADDR_RXSTATUS: - proceed - CS8900_PP_ADDR_RXLENGTH: - proceed - CS8900_PP_ADDR_RX_FRAMELOC: - - - CS8900_PP_ADDR_RX_FRAMELOC+2: proceed - - CS8900_PP_ADDR_RX_FRAMELOC+4: proceed - + According to the CS8900 spec, the handling is the following: + first read H, then L (RX_STATUS), then H, then L (RX_LENGTH). + Inside the RX frame data, we always get L then H, until the end is reached. + + even odd + CS8900_PP_ADDR_RXSTATUS: - proceed + CS8900_PP_ADDR_RXLENGTH: - proceed + CS8900_PP_ADDR_RX_FRAMELOC: - - + CS8900_PP_ADDR_RX_FRAMELOC+2: proceed - + CS8900_PP_ADDR_RX_FRAMELOC+4: proceed - */ u16 addr = odd_address ? 1 : 0; - u8 value; + u8 value; /* read RXSTATUS or RX_LENGTH */ if (rx_count < 4) @@ -769,7 +769,7 @@ u8 cs8900a_device::cs8900_read_rx_buffer(int odd_address) /* handle side-effects of read and write operations */ /* - This is called *after* the relevant octets are written + This is called *after* the relevant octets are written */ void cs8900a_device::cs8900_sideeffects_write_pp(u16 ppaddress, int odd_address) { @@ -934,7 +934,7 @@ void cs8900a_device::cs8900_sideeffects_write_pp(u16 ppaddress, int odd_address) } /* - This is called *before* the relevant octets are read + This is called *before* the relevant octets are read */ void cs8900a_device::cs8900_sideeffects_read_pp(u16 ppaddress, int odd_address) { @@ -946,10 +946,10 @@ void cs8900a_device::cs8900_sideeffects_read_pp(u16 ppaddress, int odd_address) { int access_mask = (odd_address) ? 1 : 2; - /* update the status register only if the full word of the last - status was read! unfortunately different access patterns are - possible: either the status is read LH, LH, LH... - or HL, HL, HL, or even L, L, L or H, H, H */ + /* update the status register only if the full word of the last + status was read! unfortunately different access patterns are + possible: either the status is read LH, LH, LH... + or HL, HL, HL, or even L, L, L or H, H, H */ if ((access_mask & rxevent_read_mask) != 0) { /* receiver is not enabled */ @@ -962,8 +962,8 @@ void cs8900a_device::cs8900_sideeffects_read_pp(u16 ppaddress, int odd_address) /* perform frame reception */ u16 ret_val = cs8900_receive(); - /* RXSTATUS and RXEVENT are the same, except that RXSTATUS buffers - the old value while RXEVENT sets a new value whenever it is called + /* RXSTATUS and RXEVENT are the same, except that RXSTATUS buffers + the old value while RXEVENT sets a new value whenever it is called */ SET_PP_16(CS8900_PP_ADDR_RXSTATUS, ret_val); SET_PP_16(CS8900_PP_ADDR_SE_RXEVENT, ret_val); @@ -1399,11 +1399,11 @@ void cs8900a_device::cs8900_store(u16 io_address, u8 var) if (reg_base == CS8900_ADDR_PP_PTR) { - /* cv: we store the full package pointer in cs8900_packetpage_ptr variable. - this includes the mask area (0xf000) and the addr range (0x0fff). - we ensure that the bits 0x3000 are always set (as in real HW). - odd values of the pointer are valid and supported. - only register read and write have to be mapped to word boundary. */ + /* cv: we store the full package pointer in cs8900_packetpage_ptr variable. + this includes the mask area (0xf000) and the addr range (0x0fff). + we ensure that the bits 0x3000 are always set (as in real HW). + odd values of the pointer are valid and supported. + only register read and write have to be mapped to word boundary. */ word_value |= 0x3000; cs8900_packetpage_ptr = word_value; LOGMASKED(CS8900_DEBUG_STORE, "set PP Ptr to $%04X.\n", cs8900_packetpage_ptr); diff --git a/src/devices/machine/cs8900a.h b/src/devices/machine/cs8900a.h index 69931c583e5..74e4c8b20b3 100644 --- a/src/devices/machine/cs8900a.h +++ b/src/devices/machine/cs8900a.h @@ -3,11 +3,11 @@ /************************************************************************* - CS8900A ethernet controller implementation + CS8900A ethernet controller implementation - by Rhett Aultman <roadriverrail@gmail.com> - ported to MAME from VICE Project (https://sourceforge.net/p/vice-emu/) - VICE CS8900 code by Spiro Trikaliotis <Spiro.Trikaliotis@gmx.de> + by Rhett Aultman <roadriverrail@gmail.com> + ported to MAME from VICE Project (https://sourceforge.net/p/vice-emu/) + VICE CS8900 code by Spiro Trikaliotis <Spiro.Trikaliotis@gmx.de> **************************************************************************/ @@ -19,7 +19,7 @@ #include <queue> /*************************************************************************** - TYPE DEFINITIONS + TYPE DEFINITIONS ***************************************************************************/ class cs8900a_device : public device_t, public device_network_interface { @@ -57,13 +57,13 @@ private: u16 cs8900_packetpage_ptr; /* reveiver setup */ - u16 cs8900_recv_control; /* copy of CC_RXCTL (contains all bits below) */ - bool cs8900_recv_broadcast; /* broadcast */ - bool cs8900_recv_mac; /* individual address (IA) */ - bool cs8900_recv_multicast; /* multicast if address passes the hash filter */ - bool cs8900_recv_correct; /* accept correct frames */ - bool cs8900_recv_promiscuous; /* promiscuous mode */ - bool cs8900_recv_hashfilter; /* accept if IA passes the hash filter */ + u16 cs8900_recv_control; /* copy of CC_RXCTL (contains all bits below) */ + bool cs8900_recv_broadcast; /* broadcast */ + bool cs8900_recv_mac; /* individual address (IA) */ + bool cs8900_recv_multicast; /* multicast if address passes the hash filter */ + bool cs8900_recv_correct; /* accept correct frames */ + bool cs8900_recv_promiscuous; /* promiscuous mode */ + bool cs8900_recv_hashfilter; /* accept if IA passes the hash filter */ u16 tx_buffer; u16 rx_buffer; @@ -90,7 +90,7 @@ private: void cs8900_set_transmitter(int enabled); bool cs8900_should_accept(unsigned char *buffer, int length, bool *phashed, int *phash_index, bool *pcorrect_mac, bool *pbroadcast, bool *pmulticast); u16 cs8900_receive(void); - void cs8900_write_tx_buffer(u8 value, int odd_address); + void cs8900_write_tx_buffer(u8 value, int odd_address); u8 cs8900_read_rx_buffer(int odd_address); void cs8900_sideeffects_write_pp(u16 ppaddress, int odd_address); void cs8900_sideeffects_read_pp(u16 ppaddress, int odd_address); diff --git a/src/devices/machine/exorterm.cpp b/src/devices/machine/exorterm.cpp index 0b62597e3f1..9db3f0658e4 100644 --- a/src/devices/machine/exorterm.cpp +++ b/src/devices/machine/exorterm.cpp @@ -348,7 +348,7 @@ u32 exorterm155_device::screen_update(screen_device &screen, bitmap_rgb32 &bitma u16 sy = 0, ma = 0; u8 disable_fac = m_disable_fac->read() == 0; u8 display_fac = m_display_fac->read() == 0; - const rgb_t *palette = m_palette->palette()->entry_list_raw(); + rgb_t const *const palette = m_palette->palette()->entry_list_raw(); m_framecnt++; @@ -356,7 +356,7 @@ u32 exorterm155_device::screen_update(screen_device &screen, bitmap_rgb32 &bitma { for (u8 ra = 0; ra < 12; ra++) { - u32 *p = &bitmap.pix32(sy++); + u32 *p = &bitmap.pix(sy++); // FAC codes are cleared on horizontal sync. u8 underline1 = 0; u8 underline2 = 0; diff --git a/src/devices/machine/generalplus_gpl16250soc.cpp b/src/devices/machine/generalplus_gpl16250soc.cpp index 2548929027c..1892bbe0880 100644 --- a/src/devices/machine/generalplus_gpl16250soc.cpp +++ b/src/devices/machine/generalplus_gpl16250soc.cpp @@ -219,12 +219,12 @@ void sunplus_gcm394_base_device::trigger_systemm_dma(int channel) // mem.write_word(0x4d8d4, 0x4841); // golden tee IRQ? wait hack //if (mem.read_word(0x3510f) == 0x4845) - // mem.write_word(0x3510f, 0x4840); // camp rock force service mode + // mem.write_word(0x3510f, 0x4840); // camp rock force service mode if (mem.read_word(0x4abe7) == 0x4840) mem.write_word(0x4abe7, 0x4841); // camp rock IRQ? wait hack - + // clear params after operation m_dma_params[0][channel] = m_dma_params[0][channel] & 0x00f7; @@ -667,6 +667,12 @@ void sunplus_gcm394_base_device::unkarea_78b2_w(uint16_t data) { LOGMASKED(LOG_G void sunplus_gcm394_base_device::unkarea_78b8_w(uint16_t data) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_78b8_w %04x\n", machine().describe_context(), data); m_78b8 = data; } void sunplus_gcm394_base_device::unkarea_78f0_w(uint16_t data) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_78f0_w %04x\n", machine().describe_context(), data); m_78f0 = data; } +uint16_t sunplus_gcm394_base_device::unkarea_78c0_r() +{ + LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_78c0_r\n", machine().describe_context()); + return machine().rand(); +} + uint16_t sunplus_gcm394_base_device::unkarea_78d0_r() { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_78d0_r\n", machine().describe_context()); @@ -964,6 +970,8 @@ void sunplus_gcm394_base_device::base_internal_map(address_map &map) map(0x0078b2, 0x0078b2).rw(FUNC(sunplus_gcm394_base_device::unkarea_78b2_r), FUNC(sunplus_gcm394_base_device::unkarea_78b2_w)); // 78b2 TimeBase C Control Register (P_TimeBaseC_Ctrl) map(0x0078b8, 0x0078b8).w(FUNC(sunplus_gcm394_base_device::unkarea_78b8_w)); // 78b8 TimeBase Counter Reset Register (P_TimeBase_Reset) + + map(0x0078c0, 0x0078c0).r(FUNC(sunplus_gcm394_base_device::unkarea_78c0_r)); // beijuehh map(0x0078d0, 0x0078d0).r(FUNC(sunplus_gcm394_base_device::unkarea_78d0_r)); // jak_s500 map(0x0078d8, 0x0078d8).r(FUNC(sunplus_gcm394_base_device::unkarea_78d8_r)); // jak_tsh diff --git a/src/devices/machine/generalplus_gpl16250soc.h b/src/devices/machine/generalplus_gpl16250soc.h index 8df8e780f78..fa2b176e421 100644 --- a/src/devices/machine/generalplus_gpl16250soc.h +++ b/src/devices/machine/generalplus_gpl16250soc.h @@ -319,6 +319,8 @@ private: void unkarea_78b8_w(uint16_t data); + uint16_t unkarea_78c0_r(); + uint16_t unkarea_78d0_r(); uint16_t unkarea_78d8_r(); diff --git a/src/devices/machine/generalplus_gpl16250soc_video.cpp b/src/devices/machine/generalplus_gpl16250soc_video.cpp index 37821e3a10c..ba6ca102ebf 100644 --- a/src/devices/machine/generalplus_gpl16250soc_video.cpp +++ b/src/devices/machine/generalplus_gpl16250soc_video.cpp @@ -1048,32 +1048,30 @@ void gcm394_base_video_device::palette_w(offs_t offset, uint16_t data) if (m_703a_palettebank & 0xfff0) { - fatalerror("palette writes with m_703a_palettebank %04x\n", m_703a_palettebank); - } - else - { - offset |= (m_703a_palettebank & 0x000c) << 6; - m_paletteram[offset] = data; - - // for debug - m_palette->set_pen_color(offset, rgb_t( - (((data >> 10) & 0x1f)<<3), - (((data >> 5) & 0x1f)<<3), - (((data >> 0) & 0x1f)<<3))); + LOGMASKED(LOG_GCM394_VIDEO_PALETTE,"palette writes with m_703a_palettebank %04x\n", m_703a_palettebank); } + + + offset |= (m_703a_palettebank & 0x000c) << 6; + m_paletteram[offset] = data; + + // for debug + m_palette->set_pen_color(offset, rgb_t( + (((data >> 10) & 0x1f)<<3), + (((data >> 5) & 0x1f)<<3), + (((data >> 0) & 0x1f)<<3))); + } uint16_t gcm394_base_video_device::palette_r(offs_t offset) { if (m_703a_palettebank & 0xfff0) { - fatalerror("palette read with m_703a_palettebank %04x\n", m_703a_palettebank); - } - else - { - offset |= (m_703a_palettebank & 0x000c) << 6; - return m_paletteram[offset]; + LOGMASKED(LOG_GCM394_VIDEO_PALETTE,"palette read with m_703a_palettebank %04x\n", m_703a_palettebank); } + + offset |= (m_703a_palettebank & 0x000c) << 6; + return m_paletteram[offset]; } void gcm394_base_video_device::video_701c_w(uint16_t data) diff --git a/src/devices/machine/ie15.cpp b/src/devices/machine/ie15.cpp index 3cdb35af145..eba7ace6fa7 100644 --- a/src/devices/machine/ie15.cpp +++ b/src/devices/machine/ie15.cpp @@ -637,7 +637,8 @@ void ie15_device::scanline_callback() uint32_t ie15_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { update_leds(); - memcpy(&bitmap.pix32(0), &m_tmpbmp[0], sizeof(uint32_t) * IE15_TOTAL_HORZ * IE15_TOTAL_VERT); + for (int y = 0; y < IE15_TOTAL_VERT; y++) + std::copy_n(&m_tmpbmp[y * IE15_TOTAL_HORZ], IE15_TOTAL_HORZ, &bitmap.pix(y)); return 0; } diff --git a/src/devices/machine/laserdsc.cpp b/src/devices/machine/laserdsc.cpp index ef3df359859..d04d3c1201a 100644 --- a/src/devices/machine/laserdsc.cpp +++ b/src/devices/machine/laserdsc.cpp @@ -308,11 +308,11 @@ void laserdisc_device::device_timer(emu_timer &timer, device_timer_id id, int pa //------------------------------------------------- -// sound_stream_update_legacy - audio streamer for +// sound_stream_update - audio streamer for // laserdiscs //------------------------------------------------- -void laserdisc_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void laserdisc_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { // compute AND values based on the squelch int16_t leftand = (m_audiosquelch & 1) ? 0x0000 : 0xffff; @@ -324,12 +324,12 @@ void laserdisc_device::sound_stream_update_legacy(sound_stream &stream, stream_s samples_avail += m_audiobufsize; // if no attached ld, just clear the buffers - stream_sample_t *dst0 = outputs[0]; - stream_sample_t *dst1 = outputs[1]; - if (samples_avail < samples) + auto &dst0 = outputs[0]; + auto &dst1 = outputs[1]; + if (samples_avail < outputs[0].samples()) { - memset(dst0, 0, samples * sizeof(dst0[0])); - memset(dst1, 0, samples * sizeof(dst1[0])); + dst0.fill(0); + dst1.fill(0); } // otherwise, stream from our buffer @@ -340,10 +340,11 @@ void laserdisc_device::sound_stream_update_legacy(sound_stream &stream, stream_s int sampout = m_audiobufout; // copy samples, clearing behind us as we go - while (sampout != m_audiobufin && samples-- > 0) + int sampindex; + for (sampindex = 0; sampout != m_audiobufin && sampindex < outputs[0].samples(); sampindex++) { - *dst0++ = buffer0[sampout] & leftand; - *dst1++ = buffer1[sampout] & rightand; + dst0.put_int(sampindex, buffer0[sampout] & leftand, 32768); + dst1.put_int(sampindex, buffer1[sampout] & rightand, 32768); buffer0[sampout] = 0; buffer1[sampout] = 0; sampout++; @@ -353,16 +354,16 @@ void laserdisc_device::sound_stream_update_legacy(sound_stream &stream, stream_s m_audiobufout = sampout; // clear out the rest of the buffer - if (samples > 0) + if (sampindex < outputs[0].samples()) { sampout = (m_audiobufout == 0) ? m_audiobufsize - 1 : m_audiobufout - 1; - stream_sample_t fill0 = buffer0[sampout] & leftand; - stream_sample_t fill1 = buffer1[sampout] & rightand; + s32 fill0 = buffer0[sampout] & leftand; + s32 fill1 = buffer1[sampout] & rightand; - while (samples-- > 0) + for ( ; sampindex < outputs[0].samples(); sampindex++) { - *dst0++ = fill0; - *dst1++ = fill1; + dst0.put_int(sampindex, fill0, 32768); + dst1.put_int(sampindex, fill1, 32768); } } } @@ -712,10 +713,10 @@ void laserdisc_device::init_video() fillbitmap_yuy16(frame.m_bitmap, 40, 109, 240); // make a copy of the bitmap that clips out the VBI and horizontal blanking areas - frame.m_visbitmap.wrap(&frame.m_bitmap.pix16(44, frame.m_bitmap.width() * 8 / 720), - frame.m_bitmap.width() - 2 * frame.m_bitmap.width() * 8 / 720, - frame.m_bitmap.height() - 44, - frame.m_bitmap.rowpixels()); + frame.m_visbitmap.wrap(&frame.m_bitmap.pix( + 44, frame.m_bitmap.width() * 8 / 720), + frame.m_bitmap.width() - 2 * frame.m_bitmap.width() * 8 / 720, frame.m_bitmap.height() - 44, + frame.m_bitmap.rowpixels()); frame.m_visbitmap.set_palette(m_videopalette); } @@ -762,7 +763,7 @@ void laserdisc_device::init_audio() m_audio_callback.resolve(); // allocate a stream - m_stream = stream_alloc_legacy(0, 2, 48000); + m_stream = stream_alloc(0, 2, 48000); // allocate audio buffers m_audiomaxsamples = ((uint64_t)m_samplerate * 1000000 + m_fps_times_1million - 1) / m_fps_times_1million; @@ -789,7 +790,7 @@ void laserdisc_device::fillbitmap_yuy16(bitmap_yuy16 &bitmap, uint8_t yval, uint // write 32 bits of color (2 pixels at a time) for (int y = 0; y < bitmap.height(); y++) { - uint16_t *dest = &bitmap.pix16(y); + uint16_t *dest = &bitmap.pix(y); for (int x = 0; x < bitmap.width() / 2; x++) { *dest++ = color0; @@ -918,7 +919,8 @@ void laserdisc_device::read_track_data() frame->m_lastfield = m_curtrack * 2 + m_fieldnum; // set the video target information - m_avhuff_config.video.wrap(&frame->m_bitmap.pix16(m_fieldnum), frame->m_bitmap.width(), frame->m_bitmap.height() / 2, frame->m_bitmap.rowpixels() * 2); + m_avhuff_video.wrap(&frame->m_bitmap.pix(m_fieldnum), frame->m_bitmap.width(), frame->m_bitmap.height() / 2, frame->m_bitmap.rowpixels() * 2); + m_avhuff_config.video = &m_avhuff_video; // set the audio target information if (m_audiobufin + m_audiomaxsamples <= m_audiobufsize) @@ -995,13 +997,13 @@ void laserdisc_device::process_track_data() // remove the video if we had an error if (m_readresult != CHDERR_NONE) - m_avhuff_config.video.reset(); + m_avhuff_video.reset(); // count the field as read if we are successful - if (m_avhuff_config.video.valid()) + if (m_avhuff_video.valid()) { m_frame[m_videoindex].m_numfields++; - player_overlay(m_avhuff_config.video); + player_overlay(m_avhuff_video); } // pass the audio to the callback diff --git a/src/devices/machine/laserdsc.h b/src/devices/machine/laserdsc.h index 8ca3abad222..14594bcf7cd 100644 --- a/src/devices/machine/laserdsc.h +++ b/src/devices/machine/laserdsc.h @@ -220,7 +220,7 @@ protected: virtual void device_validity_check(validity_checker &valid) const override; // device_sound_interface overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; // subclass helpers void set_audio_squelch(bool squelchleft, bool squelchright) { m_stream->update(); m_audiosquelch = (squelchleft ? 1 : 0) | (squelchright ? 2 : 0); } @@ -277,28 +277,29 @@ private: std::vector<uint8_t> m_vbidata; // pointer to precomputed VBI data int m_width; // width of video int m_height; // height of video - uint32_t m_fps_times_1million; // frame rate of video + uint32_t m_fps_times_1million; // frame rate of video int m_samplerate; // audio samplerate int m_readresult; // result of the most recent read - uint32_t m_chdtracks; // number of tracks in the CHD - avhuff_decompress_config m_avhuff_config; // decompression configuration + uint32_t m_chdtracks; // number of tracks in the CHD + bitmap_yuy16 m_avhuff_video; // decompresed frame buffer + avhuff_decoder::config m_avhuff_config; // decompression configuration // async operations osd_work_queue * m_work_queue; // work queue - uint32_t m_queued_hunknum; // queued hunk + uint32_t m_queued_hunknum; // queued hunk // core states - uint8_t m_audiosquelch; // audio squelch state: bit 0 = audio 1, bit 1 = audio 2 - uint8_t m_videosquelch; // video squelch state: bit 0 = on/off - uint8_t m_fieldnum; // field number (0 or 1) - int32_t m_curtrack; // current track at this end of this vsync - uint32_t m_maxtrack; // maximum track number + uint8_t m_audiosquelch; // audio squelch state: bit 0 = audio 1, bit 1 = audio 2 + uint8_t m_videosquelch; // video squelch state: bit 0 = on/off + uint8_t m_fieldnum; // field number (0 or 1) + int32_t m_curtrack; // current track at this end of this vsync + uint32_t m_maxtrack; // maximum track number attoseconds_t m_attospertrack; // attoseconds per track, or 0 if not moving attotime m_sliderupdate; // time of last slider update // video data frame_data m_frame[3]; // circular list of frames - uint8_t m_videoindex; // index of the current video buffer + uint8_t m_videoindex; // index of the current video buffer bitmap_yuy16 m_emptyframe; // blank frame // audio data diff --git a/src/devices/machine/ldpr8210.cpp b/src/devices/machine/ldpr8210.cpp index fc94159ff6a..64392ed0c90 100644 --- a/src/devices/machine/ldpr8210.cpp +++ b/src/devices/machine/ldpr8210.cpp @@ -784,12 +784,12 @@ void pioneer_pr8210_device::overlay_draw_group(bitmap_yuy16 &bitmap, const uint8 void pioneer_pr8210_device::overlay_erase(bitmap_yuy16 &bitmap, float xstart, float xend) { - uint32_t xmin = (uint32_t)(xstart * 256.0f * float(bitmap.width())); - uint32_t xmax = (uint32_t)(xend * 256.0f * float(bitmap.width())); + uint32_t xmin = uint32_t(xstart * 256.0f * float(bitmap.width())); + uint32_t xmax = uint32_t(xend * 256.0f * float(bitmap.width())); for (uint32_t y = OVERLAY_Y; y < (OVERLAY_Y + (OVERLAY_Y_PIXELS + 2) * OVERLAY_PIXEL_HEIGHT); y++) { - uint16_t *dest = &bitmap.pix16(y, xmin >> 8); + uint16_t *dest = &bitmap.pix(y, xmin >> 8); uint16_t ymax = *dest >> 8; uint16_t ymin = ymax * 3 / 8; uint16_t yres = ymin + ((ymax - ymin) * (xmin & 0xff)) / 256; @@ -819,8 +819,8 @@ void pioneer_pr8210_device::overlay_erase(bitmap_yuy16 &bitmap, float xstart, fl void pioneer_pr8210_device::overlay_draw_char(bitmap_yuy16 &bitmap, uint8_t ch, float xstart) { - uint32_t xminbase = (uint32_t)(xstart * 256.0f * float(bitmap.width())); - uint32_t xsize = (uint32_t)(OVERLAY_PIXEL_WIDTH * 256.0f * float(bitmap.width())); + uint32_t xminbase = uint32_t(xstart * 256.0f * float(bitmap.width())); + uint32_t xsize = uint32_t(OVERLAY_PIXEL_WIDTH * 256.0f * float(bitmap.width())); // iterate over pixels const uint8_t *chdataptr = &text_bitmap[ch & 0x3f][0]; @@ -835,7 +835,7 @@ void pioneer_pr8210_device::overlay_draw_char(bitmap_yuy16 &bitmap, uint8_t ch, uint32_t xmax = xmin + xsize; for (uint32_t yy = 0; yy < OVERLAY_PIXEL_HEIGHT; yy++) { - uint16_t *dest = &bitmap.pix16(OVERLAY_Y + (y + 1) * OVERLAY_PIXEL_HEIGHT + yy, xmin >> 8); + uint16_t *dest = &bitmap.pix(OVERLAY_Y + (y + 1) * OVERLAY_PIXEL_HEIGHT + yy, xmin >> 8); uint16_t ymax = 0xff; uint16_t ymin = *dest >> 8; uint16_t yres = ymin + ((ymax - ymin) * (~xmin & 0xff)) / 256; diff --git a/src/devices/machine/m3002.cpp b/src/devices/machine/m3002.cpp index 8bb9edda2b9..fd93666a55f 100644 --- a/src/devices/machine/m3002.cpp +++ b/src/devices/machine/m3002.cpp @@ -351,13 +351,13 @@ void m3002_device::irq_update() { LOG("IRQ occurred\n"); m_irq_active = true; - m_irq_callback(ASSERT_LINE); + m_irq_callback(0); } else if (m_irq_active && (m_ram[0xf] & 0x0c) == 0) { LOG("IRQ cleared\n"); m_irq_active = false; - m_irq_callback(CLEAR_LINE); + m_irq_callback(1); } } diff --git a/src/devices/machine/m3002.h b/src/devices/machine/m3002.h index d39f904fe60..ef13c360e47 100644 --- a/src/devices/machine/m3002.h +++ b/src/devices/machine/m3002.h @@ -37,6 +37,8 @@ public: // device type constructor m3002_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + auto irq_out() { return m_irq_callback.bind(); } + // 4-bit read/write handlers u8 read(); void write(u8 data); diff --git a/src/devices/machine/mc68328.cpp b/src/devices/machine/mc68328.cpp index 3df500d2f0c..e3690287710 100644 --- a/src/devices/machine/mc68328.cpp +++ b/src/devices/machine/mc68328.cpp @@ -3044,20 +3044,17 @@ uint16_t mc68328_device::internal_read(offs_t offset, uint16_t mem_mask) uint32_t mc68328_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { uint32_t vram_addr = m_regs.lssa & 0x00fffffe; - uint16_t word; - uint16_t *line; - int y, x, b; if (m_regs.lckcon & LCKCON_LCDC_EN) { - for (y = 0; y < 160; y++) + for (int y = 0; y < 160; y++) { - line = &bitmap.pix16(y); + uint16_t *const line = &bitmap.pix(y); - for (x = 0; x < 160; x += 16, vram_addr += 2) + for (int x = 0; x < 160; x += 16, vram_addr += 2) { - word = space(AS_PROGRAM).read_word(vram_addr); - for (b = 0; b < 16; b++) + uint16_t const word = space(AS_PROGRAM).read_word(vram_addr); + for (int b = 0; b < 16; b++) { line[x + b] = (word >> (15 - b)) & 0x0001; } @@ -3066,11 +3063,11 @@ uint32_t mc68328_device::screen_update(screen_device &screen, bitmap_ind16 &bitm } else { - for (y = 0; y < 160; y++) + for (int y = 0; y < 160; y++) { - line = &bitmap.pix16(y); + uint16_t *const line = &bitmap.pix(y); - for (x = 0; x < 160; x++) + for (int x = 0; x < 160; x++) { line[x] = 0; } diff --git a/src/devices/machine/mm58167.cpp b/src/devices/machine/mm58167.cpp index f226590e9d2..05aa4377ccb 100644 --- a/src/devices/machine/mm58167.cpp +++ b/src/devices/machine/mm58167.cpp @@ -247,10 +247,7 @@ void mm58167_device::write(offs_t offset, uint8_t data) break; case R_CTL_IRQCONTROL: - if (data != 0) - { - logerror("MM58167: IRQs not implemented\n"); - } + m_regs[R_CTL_IRQCONTROL]=data; break; } } diff --git a/src/devices/machine/netlist.cpp b/src/devices/machine/netlist.cpp index 988c21c33e1..a13349e318f 100644 --- a/src/devices/machine/netlist.cpp +++ b/src/devices/machine/netlist.cpp @@ -987,7 +987,6 @@ std::unique_ptr<netlist::netlist_state_t> netlist_mame_device::base_validity_che auto lnetlist = std::make_unique<netlist::netlist_state_t>("netlist", plib::plog_delegate(&validity_logger::log, &logger)); // enable validation mode - lnetlist->set_extended_validation(true); lnetlist->set_static_solver_lib(std::make_unique<plib::dynlib_static>(nullptr)); diff --git a/src/devices/machine/ns32081.cpp b/src/devices/machine/ns32081.cpp new file mode 100644 index 00000000000..73941a85f2c --- /dev/null +++ b/src/devices/machine/ns32081.cpp @@ -0,0 +1,637 @@ +// license:BSD-3-Clause +// copyright-holders:Patrick Mackinlay + +/* + * National Semiconductor 32081 Floating-Point Unit. + * + * Sources: + * - http://bitsavers.org/components/national/_dataBooks/1989_National_Microprocessor_Databook_32000_NSC800.pdf + * + * TODO: + * - testing + */ + +#include "emu.h" +#include "ns32081.h" + +#include "softfloat3/source/include/softfloat.h" + +#define LOG_GENERAL (1U << 0) +//#define VERBOSE (LOG_GENERAL) + +#include "logmacro.h" + +DEFINE_DEVICE_TYPE(NS32081, ns32081_device, "ns32081", "National Semiconductor 32081 Floating-Point Unit") + +enum fsr_mask : u32 +{ + FSR_TT = 0x00000007, // trap type + FSR_UEN = 0x00000008, // underflow trap enable + FSR_UF = 0x00000010, // underflow flag + FSR_IEN = 0x00000020, // inexact result trap enable + FSR_IF = 0x00000040, // inexact result flag + FSR_RM = 0x00000180, // rounding mode + FSR_SWF = 0x0000fe00, // software field +}; + +enum rm_mask : u32 +{ + RM_N = 0x00000000, // round to nearest value + RM_Z = 0x00000080, // round toward zero + RM_U = 0x00000100, // round toward positive infinity + RM_D = 0x00000180, // round toward negative infinity +}; + +enum tt_mask : u32 +{ + TT_UND = 0x00000001, // underflow + TT_OVF = 0x00000002, // overflow + TT_DVZ = 0x00000003, // divide by zero + TT_ILL = 0x00000004, // illegal instruction + TT_INV = 0x00000005, // invalid operation + TT_INX = 0x00000006, // inexact result + TT_RSV = 0x00000007, // reserved +}; + +enum state : unsigned +{ + IDLE = 0, + OPERATION = 1, // awaiting operation word + OPERAND = 2, // awaiting operands + STATUS = 4, // status word available + RESULT = 5, // result word available +}; + +enum idbyte : u8 +{ + FORMAT_9 = 0x3e, + FORMAT_11 = 0xbe, +}; + +enum operand_length : unsigned +{ + LENGTH_F = 4, // single precision + LENGTH_L = 8, // double precision +}; + +enum size_code : unsigned +{ + SIZE_B = 0, + SIZE_W = 1, + SIZE_D = 3, +}; + +ns32081_device::ns32081_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) + : device_t(mconfig, NS32081, tag, owner, clock) + , ns32000_slave_interface(mconfig, *this) +{ +} + +void ns32081_device::device_start() +{ + save_item(NAME(m_fsr)); + save_item(NAME(m_f)); + + save_item(NAME(m_idbyte)); + save_item(NAME(m_opword)); + save_item(STRUCT_MEMBER(m_op, expected)); + save_item(STRUCT_MEMBER(m_op, issued)); + save_item(STRUCT_MEMBER(m_op, value)); + save_item(NAME(m_status)); + + save_item(NAME(m_state)); + save_item(NAME(m_tcy)); + + m_complete = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(ns32081_device::complete), this)); +} + +void ns32081_device::device_reset() +{ + m_fsr = 0; + std::fill_n(&m_f[0], ARRAY_LENGTH(m_f), 0); + + m_state = IDLE; +} + +void ns32081_device::state_add(device_state_interface &parent, int &index) +{ + parent.state_add(index++, "FSR", m_fsr).formatstr("%04X"); + + for (unsigned i = 0; i < 8; i++) + parent.state_add(index++, util::string_format("F%d", i).c_str(), m_f[i]).formatstr("%08X"); +} + +u16 ns32081_device::read_st(int *icount) +{ + if (m_state == STATUS) + { + m_state = (m_op[2].issued == m_op[2].expected) ? IDLE : RESULT; + + if (icount) + *icount -= m_tcy; + + LOG("read_st status 0x%04x tcy %d %s (%s)\n", m_status, m_tcy, + (m_state == RESULT ? "results pending" : "complete"), machine().describe_context()); + + return m_status; + } + + logerror("protocol error reading status word (%s)\n", machine().describe_context()); + return 0; +} + +u16 ns32081_device::read_op() +{ + if (m_state == RESULT && m_op[2].issued < m_op[2].expected) + { + u16 const data = u16(m_op[2].value >> (m_op[2].issued * 8)); + LOG("read_op word %d data 0x%04x (%s)\n", m_op[2].issued >> 1, data, machine().describe_context()); + + m_op[2].issued += 2; + + if (m_op[2].issued == m_op[2].expected) + { + LOG("read_op last result word issued\n"); + m_state = IDLE; + } + + return data; + } + + logerror("protocol error reading result word (%s)\n", machine().describe_context()); + return 0; +} + +void ns32081_device::write_id(u16 data) +{ + bool const match = (data == FORMAT_9) || (data == FORMAT_11); + + if (match) + { + LOG("write_id match 0x%04x (%s)\n", data, machine().describe_context()); + m_state = OPERATION; + } + else + { + LOG("write_id ignore 0x%04x (%s)\n", data, machine().describe_context()); + m_state = IDLE; + } + + m_idbyte = u8(data); +} + +void ns32081_device::write_op(u16 data) +{ + switch (m_state) + { + case OPERATION: + m_opword = swapendian_int16(data); + LOG("write_op opword 0x%04x (%s)\n", m_opword, machine().describe_context()); + + // initialize operands + for (operand &op : m_op) + { + op.expected = 0; + op.issued = 0; + op.value = 0; + } + + // decode operands + if (m_idbyte == FORMAT_9) + { + // format 9: 1111 1222 22oo ofii + unsigned const f_length = BIT(m_opword, 2) ? LENGTH_F : LENGTH_L; + unsigned const size = m_opword & 3; + + switch ((m_opword >> 3) & 7) + { + case 0: // movif + m_op[0].expected = size + 1; + m_op[2].expected = f_length; + break; + case 1: // lfsr + m_op[0].expected = 4; + break; + case 2: // movlf + m_op[0].expected = LENGTH_L; + m_op[2].expected = f_length; + break; + case 3: // movfl + m_op[0].expected = LENGTH_F; + m_op[2].expected = f_length; + break; + case 4: // roundfi + case 5: // truncfi + case 7: // floorfi + m_op[0].expected = f_length; + m_op[2].expected = size + 1; + break; + case 6: // sfsr + m_op[2].expected = 4; + break; + } + } + else if (m_idbyte == FORMAT_11) + { + // format 11: 1111 1222 22oo oo0f + unsigned const opcode = (m_opword >> 2) & 15; + unsigned const f_length = BIT(m_opword, 0) ? LENGTH_F : LENGTH_L; + + m_op[0].expected = f_length; + + // even opcodes have two input operands + if (!BIT(opcode, 0)) + m_op[1].expected = f_length; + + // all operations except CMPf issue a result + if (opcode != 2) + m_op[2].expected = f_length; + } + + // operand 1 in register + if (m_op[0].expected && !(m_opword & 0xc000)) + { + // exclude integer operands + if (m_idbyte == FORMAT_11 || ((m_opword >> 3) & 7) > 1) + { + unsigned const reg = (m_opword >> 11) & 7; + LOG("write_op read f%d\n", reg); + + m_op[0].value = m_f[reg ^ 0]; + if (m_op[0].expected == 8) + m_op[0].value |= u64(m_f[reg ^ 1]) << 32; + + m_op[0].issued = m_op[0].expected; + } + } + + // operand 2 in register + if (m_op[1].expected && !(m_opword & 0x0600)) + { + unsigned const reg = (m_opword >> 6) & 7; + LOG("write_op read f%d\n", reg); + + m_op[1].value = m_f[reg ^ 0]; + if (m_op[1].expected == 8) + m_op[1].value |= u64(m_f[reg ^ 1]) << 32; + + m_op[1].issued = m_op[1].expected; + } + + m_state = OPERAND; + break; + + case OPERAND: + // check awaiting operand word + if (m_op[0].issued < m_op[0].expected || m_op[1].issued < m_op[1].expected) + { + unsigned const n = (m_op[0].issued < m_op[0].expected) ? 0 : 1; + operand &op = m_op[n]; + + LOG("write_op op%d data 0x%04x (%s)\n", n, data, machine().describe_context()); + + // insert word into operand value + op.value |= u64(data) << (op.issued * 8); + op.issued += 2; + } + else + logerror("protocol error unexpected operand word 0x%04x (%s)\n", data, machine().describe_context()); + break; + } + + // start execution when all operands are available + if (m_state == OPERAND && m_op[0].issued >= m_op[0].expected && m_op[1].issued >= m_op[1].expected) + execute(); +} + +void ns32081_device::execute() +{ + softfloat_exceptionFlags = 0; + m_fsr &= ~FSR_TT; + + m_status = 0; + m_tcy = 0; + + switch (m_idbyte) + { + case FORMAT_9: + // format 9: 1111 1222 22oo ofii + { + bool const single = BIT(m_opword, 2); + unsigned const f_length = single ? LENGTH_F : LENGTH_L; + unsigned const size = m_opword & 3; + + switch ((m_opword >> 3) & 7) + { + case 0: + // MOVif src,dest + // gen,gen + // read.i,write.f + { + s32 const src = + (size == SIZE_D) ? s32(m_op[0].value) : + (size == SIZE_W) ? s16(m_op[0].value) : + s8(m_op[0].value); + + if (single) + m_op[2].value = i32_to_f32(src).v; + else + m_op[2].value = i32_to_f64(src).v; + m_op[2].expected = f_length; + m_tcy = 53; + } + break; + case 1: + // LFSR src + // gen + // read.D + m_fsr = u16(m_op[0].value); + + switch (m_fsr & FSR_RM) + { + case RM_N: softfloat_roundingMode = softfloat_round_near_even; break; + case RM_Z: softfloat_roundingMode = softfloat_round_minMag; break; + case RM_U: softfloat_roundingMode = softfloat_round_max; break; + case RM_D: softfloat_roundingMode = softfloat_round_min; break; + } + m_tcy = 18; + break; + case 2: + // MOVLF src,dest + // gen,gen + // read.L,write.F + m_op[2].value = f64_to_f32(float64_t{ m_op[0].value }).v; + m_op[2].expected = f_length; + m_tcy = (m_opword & 0xc000) ? 23 : 27; + break; + case 3: + // MOVFL src,dest + // gen,gen + // read.F,write.L + m_op[2].value = f32_to_f64(float32_t{ u32(m_op[0].value) }).v; + m_op[2].expected = f_length; + m_tcy = (m_opword & 0xc000) ? 22 : 26; + break; + case 4: + // ROUNDfi src,dest + // gen,gen + // read.f,write.i + if (single) + m_op[2].value = f32_to_i64(float32_t{ u32(m_op[0].value) }, softfloat_round_near_even, true); + else + m_op[2].value = f64_to_i64(float64_t{ m_op[0].value }, softfloat_round_near_even, true); + + if ((size == SIZE_D && s64(m_op[2].value) != s32(m_op[2].value)) + || (size == SIZE_W && s64(m_op[2].value) != s16(m_op[2].value)) + || (size == SIZE_B && s64(m_op[2].value) != s8(m_op[2].value))) + softfloat_exceptionFlags |= softfloat_flag_overflow; + + m_op[2].expected = size + 1; + m_tcy = (m_opword & 0xc000) ? 53 : 66; + break; + case 5: + // TRUNCfi src,dest + // gen,gen + // read.f,write.i + if (single) + m_op[2].value = f32_to_i64(float32_t{ u32(m_op[0].value) }, softfloat_round_minMag, true); + else + m_op[2].value = f64_to_i64(float64_t{ m_op[0].value }, softfloat_round_minMag, true); + + if ((size == SIZE_D && s64(m_op[2].value) != s32(m_op[2].value)) + || (size == SIZE_W && s64(m_op[2].value) != s16(m_op[2].value)) + || (size == SIZE_B && s64(m_op[2].value) != s8(m_op[2].value))) + softfloat_exceptionFlags |= softfloat_flag_overflow; + + m_op[2].expected = size + 1; + m_tcy = (m_opword & 0xc000) ? 53 : 66; + break; + case 6: + // SFSR dest + // gen + // write.D + m_op[2].value = m_fsr; + m_op[2].expected = 4; + m_tcy = 13; + break; + case 7: + // FLOORfi src,dest + // gen,gen + // read.f,write.i + if (single) + m_op[2].value = f32_to_i64(float32_t{ u32(m_op[0].value) }, softfloat_round_min, true); + else + m_op[2].value = f64_to_i64(float64_t{ m_op[0].value }, softfloat_round_min, true); + + if ((size == SIZE_D && s64(m_op[2].value) != s32(m_op[2].value)) + || (size == SIZE_W && s64(m_op[2].value) != s16(m_op[2].value)) + || (size == SIZE_B && s64(m_op[2].value) != s8(m_op[2].value))) + softfloat_exceptionFlags |= softfloat_flag_overflow; + + m_op[2].expected = size + 1; + m_tcy = (m_opword & 0xc000) ? 53 : 66; + break; + } + } + break; + + case FORMAT_11: + // format 11: 1111122222oooo0f + { + bool const single = BIT(m_opword, 0); + unsigned const f_length = single ? LENGTH_F : LENGTH_L; + + switch ((m_opword >> 2) & 15) + { + case 0x0: + // ADDf src,dest + // gen,gen + // read.f,rmw.f + if (single) + m_op[2].value = f32_add(float32_t{ u32(m_op[1].value) }, float32_t{ u32(m_op[0].value) }).v; + else + m_op[2].value = f64_add(float64_t{ m_op[1].value }, float64_t{ m_op[0].value }).v; + m_op[2].expected = f_length; + m_tcy = (m_opword & 0xc600) ? 70 : 74; + break; + case 0x1: + // MOVf src,dest + // gen,gen + // read.f,write.f + m_op[2].value = m_op[0].value; + m_op[2].expected = f_length; + m_tcy = (m_opword & 0xc000) ? 23 : 27; + break; + case 0x2: + // CMPf src1,src2 + // gen,gen + // read.f,read.f + if (m_op[0].value == m_op[1].value) + m_status |= SLAVE_Z; + if ((single && f32_le(float32_t{ u32(m_op[1].value) }, float32_t{ u32(m_op[0].value) })) + || (!single && f64_le(float64_t{ m_op[1].value }, float64_t{ m_op[0].value }))) + m_status |= SLAVE_N; + m_tcy = (m_opword & 0xc600) ? 45 : 49; + break; + case 0x3: + // Trap(SLAVE) + m_fsr |= TT_ILL; + m_status = SLAVE_Q; + break; + case 0x4: + // SUBf src,dest + // gen,gen + // read.f,rmw.f + if (single) + m_op[2].value = f32_sub(float32_t{ u32(m_op[1].value) }, float32_t{ u32(m_op[0].value) }).v; + else + m_op[2].value = f64_sub(float64_t{ m_op[1].value }, float64_t{ m_op[0].value }).v; + m_op[2].expected = f_length; + m_tcy = (m_opword & 0xc600) ? 70 : 74; + break; + case 0x5: + // NEGf src,dest + // gen,gen + // read.f,write.f + if (single) + m_op[2].value = f32_mul(float32_t{ u32(m_op[0].value) }, i32_to_f32(-1)).v; + else + m_op[2].value = f64_mul(float64_t{ m_op[0].value }, i32_to_f64(-1)).v; + m_op[2].expected = f_length; + m_tcy = (m_opword & 0xc000) ? 20 : 24; + break; + case 0x8: + // DIVf src,dest + // gen,gen + // read.f,rmw.f + if (single) + m_op[2].value = f32_div(float32_t{ u32(m_op[1].value) }, float32_t{ u32(m_op[0].value) }).v; + else + m_op[2].value = f64_div(float64_t{ m_op[1].value }, float64_t{ m_op[0].value }).v; + m_op[2].expected = f_length; + m_tcy = ((m_opword & 0xc600) ? 55 : 59) + (single ? 30 : 60); + break; + case 0x9: + // Trap(SLAVE) + m_fsr |= TT_ILL; + m_status = SLAVE_Q; + break; + case 0xc: + // MULf src,dest + // gen,gen + // read.f,rmw.f + if (single) + m_op[2].value = f32_mul(float32_t{ u32(m_op[1].value) }, float32_t{ u32(m_op[0].value) }).v; + else + m_op[2].value = f64_mul(float64_t{ m_op[1].value }, float64_t{ m_op[0].value }).v; + m_op[2].expected = f_length; + m_tcy = ((m_opword & 0xc600) ? 30 : 34) + (single ? 14 : 28); + break; + case 0xd: + // ABSf src,dest + // gen,gen + // read.f,write.f + if (single) + if (f32_lt(float32_t{ u32(m_op[0].value) }, float32_t{ 0 })) + m_op[2].value = f32_mul(float32_t{ u32(m_op[0].value) }, i32_to_f32(-1)).v; + else + m_op[2].value = float32_t{ u32(m_op[0].value) }.v; + else + if (f64_lt(float64_t{ m_op[0].value }, float64_t{ 0 })) + m_op[2].value = f64_mul(float64_t{ m_op[0].value }, i32_to_f64(-1)).v; + else + m_op[2].value = float64_t{ m_op[0].value }.v; + m_op[2].expected = f_length; + m_tcy = (m_opword & 0xc000) ? 20 : 24; + break; + } + } + break; + } + + // check for exceptions + if (softfloat_exceptionFlags & softfloat_flag_underflow) + { + m_fsr |= FSR_UF | TT_UND; + + if (m_fsr & FSR_UEN) + m_status |= SLAVE_Q; + else + m_op[2].value = 0; + } + else if (softfloat_exceptionFlags & softfloat_flag_overflow) + { + m_fsr |= TT_OVF; + m_status |= SLAVE_Q; + } + else if (softfloat_exceptionFlags & softfloat_flag_infinite) + { + m_fsr |= TT_DVZ; + m_status |= SLAVE_Q; + } + else if (softfloat_exceptionFlags & softfloat_flag_invalid) + m_fsr |= TT_INV; + else if (softfloat_exceptionFlags & softfloat_flag_inexact) + { + m_fsr |= FSR_IF | TT_INX; + + if (m_fsr & FSR_IEN) + m_status |= SLAVE_Q; + } + + // exceptions suppress result issue + if (m_status & SLAVE_Q) + m_op[2].expected = 0; + + if (VERBOSE & LOG_GENERAL) + { + static char const *format9[] = { "movif", "lfsr", "movlf", "movfl", "roundfi", "truncfi", "sfsr", "floorfi" }; + static char const *format11[] = + { + "addf", "movf", "cmpf", nullptr, "subf", "negf", nullptr, nullptr, + "divf", nullptr, nullptr, nullptr, "mulf", "absf", nullptr, nullptr + }; + + if (m_status & SLAVE_Q) + LOG("execute %s 0x%x,0x%x exception\n", + (m_idbyte == FORMAT_9) + ? format9[(m_opword >> 3) & 7] + : format11[(m_opword >> 2) & 15], + m_op[0].value, m_op[1].value); + else + LOG("execute %s 0x%x,0x%x result 0x%x\n", + (m_idbyte == FORMAT_9) + ? format9[(m_opword >> 3) & 7] + : format11[(m_opword >> 2) & 15], + m_op[0].value, m_op[1].value, m_op[2].value); + } + + // write-back floating point register results + if (m_op[2].expected && !(m_opword & 0x0600)) + { + // exclude integer results (roundfi, truncfi, sfsr, floorfi) + if (m_idbyte == FORMAT_11 || ((m_opword >> 3) & 7) < 4) + { + unsigned const reg = (m_opword >> 6) & 7; + + LOG("execute write-back f%d\n", reg); + + m_f[reg ^ 0] = u32(m_op[2].value >> 0); + if (m_op[2].expected == 8) + m_f[reg ^ 1] = u32(m_op[2].value >> 32); + + m_op[2].issued = m_op[2].expected; + } + } + + m_state = STATUS; + + if (m_out_scb) + m_complete->adjust(attotime::from_ticks(m_tcy, clock())); +} + +void ns32081_device::complete(void *buf, s32 param) +{ + m_out_scb(0); + m_out_scb(1); +} diff --git a/src/devices/machine/ns32081.h b/src/devices/machine/ns32081.h new file mode 100644 index 00000000000..4097494c830 --- /dev/null +++ b/src/devices/machine/ns32081.h @@ -0,0 +1,60 @@ +// license:BSD-3-Clause +// copyright-holders:Patrick Mackinlay + +#ifndef MAME_MACHINE_NS32081_H +#define MAME_MACHINE_NS32081_H + +#pragma once + +#include "cpu/ns32000/slave.h" + +class ns32081_device + : public device_t + , public ns32000_slave_interface +{ +public: + ns32081_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock); + + virtual void state_add(device_state_interface &parent, int &index) override; + + virtual u16 read_st(int *icount = nullptr) override; + virtual u16 read_op() override; + + virtual void write_id(u16 data) override; + virtual void write_op(u16 data) override; + +protected: + // device_t overrides + virtual void device_start() override; + virtual void device_reset() override; + + void execute(); + void complete(void *buf, s32 param); + +private: + emu_timer *m_complete; + + // registers + u32 m_fsr; + u32 m_f[8]; + + // operating state + u8 m_idbyte; + u16 m_opword; + struct operand + { + unsigned expected; + unsigned issued; + u64 value; + } + m_op[3]; + u16 m_status; + + // implementation state + unsigned m_state; + unsigned m_tcy; +}; + +DECLARE_DEVICE_TYPE(NS32081, ns32081_device) + +#endif // MAME_MACHINE_NS32081_H diff --git a/src/devices/machine/ns32202.cpp b/src/devices/machine/ns32202.cpp new file mode 100644 index 00000000000..947bb6e38cd --- /dev/null +++ b/src/devices/machine/ns32202.cpp @@ -0,0 +1,698 @@ +// license:BSD-3-Clause +// copyright-holders:Patrick Mackinlay + +/* + * National Semiconductor NS32202 Interrupt Control Unit (ICU). + * + * Sources: + * + * http://bitsavers.org/components/national/_dataBooks/1989_National_Microprocessor_Databook_32000_NSC800.pdf + * + * TODO + * - timer/counter + */ + +#include "emu.h" +#include "ns32202.h" + +#define LOG_GENERAL (1U << 0) +#define LOG_STATE (1U << 1) +#define LOG_REGW (1U << 2) +#define LOG_REGR (1U << 3) + +//#define VERBOSE (LOG_GENERAL|LOG_STATE|LOG_REGW|LOG_REGR) +#include "logmacro.h" + +DEFINE_DEVICE_TYPE(NS32202, ns32202_device, "ns32202", "NS32202 Interrupt Control Unit") + +enum mctl_mask : u8 +{ + MCTL_T16N8 = 0x01, // data bus mode + MCTL_NTAR = 0x02, // not auto-rotate mode + MCTL_FRZ = 0x08, // freeze interrupt pending + MCTL_CLKM = 0x10, // clock mode (square wave/pulsed) + MCTL_COUTM = 0x20, // cout mode (square wave/pulsed) + MCTL_COUTD = 0x40, // cout/scin input/output + MCTL_CFRZ = 0x80, // freeze counter readings +}; + +enum cctl_mask : u8 +{ + CCTL_CDCRL = 0x01, // decrement l-counter + CCTL_CDCRH = 0x02, // decrement h-counter + CCTL_CRUNL = 0x04, // l-counter running + CCTL_CRUNH = 0x08, // h-counter running + CCTL_COUT0 = 0x10, // zero detect l-counter + CCTL_COUT1 = 0x20, // zero detect h-counter + CCTL_CFNPS = 0x40, // clock not prescaled + CCTL_CCON = 0x80, // counters concatenated +}; + +enum cictl_mask : u8 +{ + CICTL_WENL = 0x01, // l-counter write enable + CICTL_CIEL = 0x02, // l-counter interrupt enable + CICTL_CIRL = 0x04, // l-counter interrupt request + CICTL_CERL = 0x08, // l-counter error flag + CICTL_WENH = 0x10, // h-counter write enable + CICTL_CIEH = 0x20, // h-counter interrupt enable + CICTL_CIRH = 0x40, // h-counter interrupt request + CICTL_CERH = 0x80, // h-counter error flag +}; + +ns32202_device::ns32202_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) + : device_t(mconfig, NS32202, tag, owner, clock) + , m_out_int(*this) + , m_out_cout(*this) + , m_out_port(*this) + , m_line_state(0xffff) + , m_out_int_state(false) + , m_out_cout_state(false) +{ +} + +void ns32202_device::device_start() +{ + m_out_int.resolve_safe(); + m_out_cout.resolve_safe(); + m_out_port.resolve_safe(); + + save_item(NAME(m_hvct)); + save_item(NAME(m_eltg)); + save_item(NAME(m_tpl)); + save_item(NAME(m_ipnd)); + save_item(NAME(m_isrv)); + save_item(NAME(m_imsk)); + save_item(NAME(m_csrc)); + save_item(NAME(m_fprt)); + save_item(NAME(m_mctl)); + save_item(NAME(m_ocasn)); + save_item(NAME(m_ciptr)); + save_item(NAME(m_pdat)); + save_item(NAME(m_ips)); + save_item(NAME(m_pdir)); + save_item(NAME(m_cctl)); + save_item(NAME(m_cictl)); + save_item(NAME(m_csv)); + save_item(NAME(m_ccv)); + + save_item(NAME(m_isrv_count)); + + save_item(NAME(m_line_state)); + save_item(NAME(m_out_int_state)); + save_item(NAME(m_out_cout_state)); + + m_interrupt = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(ns32202_device::interrupt), this)); + m_counter[0] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(ns32202_device::counter<0>), this)); + m_counter[1] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(ns32202_device::counter<1>), this)); +} + +void ns32202_device::device_reset() +{ + m_eltg = 0xffff; + m_tpl = 0; + m_ipnd = 0; + m_isrv = 0; + m_imsk = 0xffff; + m_csrc = 0; + m_fprt = 0x0001; + + m_mctl = MCTL_COUTD; + m_ocasn = 0; + m_ciptr = 0xff; + m_ips = 0xff; + m_pdir = 0xff; + m_cictl = 0; +} + +void ns32202_device::set_int(bool int_state) +{ + if (int_state != m_out_int_state) + { + LOGMASKED(LOG_STATE, "int %s\n", int_state ? "asserted" : "cleared"); + + m_out_int_state = int_state; + m_out_int(!m_out_int_state); + } +} + +void ns32202_device::set_cout(bool cout_state) +{ + if (cout_state != m_out_cout_state) + { + LOGMASKED(LOG_STATE, "cout %s\n", cout_state ? "asserted" : "cleared"); + + m_out_cout_state = cout_state; + m_out_cout(!m_out_cout_state); + } +} + +template <unsigned ST1> void ns32202_device::map(address_map &map) +{ + map(0x00, 0x00).r(&ns32202_device::hvct_r<ST1, true>, "ns32202_device::hvct_r"); + map(0x01, 0x01).rw(&ns32202_device::hvct_r<ST1, false>, "ns32202_device::svct_r", FUNC(ns32202_device::svct_w)); + map(0x02, 0x02).rw(FUNC(ns32202_device::eltgl_r), FUNC(ns32202_device::eltgl_w)); + map(0x03, 0x03).rw(FUNC(ns32202_device::eltgh_r), FUNC(ns32202_device::eltgh_w)); + map(0x04, 0x04).rw(FUNC(ns32202_device::tpll_r), FUNC(ns32202_device::tpll_w)); + map(0x05, 0x05).rw(FUNC(ns32202_device::tplh_r), FUNC(ns32202_device::tplh_w)); + map(0x06, 0x06).rw(FUNC(ns32202_device::ipndl_r), FUNC(ns32202_device::ipndl_w)); + map(0x07, 0x07).rw(FUNC(ns32202_device::ipndh_r), FUNC(ns32202_device::ipndh_w)); + map(0x08, 0x08).rw(FUNC(ns32202_device::isrvl_r), FUNC(ns32202_device::isrvl_w)); + map(0x09, 0x09).rw(FUNC(ns32202_device::isrvh_r), FUNC(ns32202_device::isrvh_w)); + map(0x0a, 0x0a).rw(FUNC(ns32202_device::imskl_r), FUNC(ns32202_device::imskl_w)); + map(0x0b, 0x0b).rw(FUNC(ns32202_device::imskh_r), FUNC(ns32202_device::imskh_w)); + map(0x0c, 0x0c).rw(FUNC(ns32202_device::csrcl_r), FUNC(ns32202_device::csrcl_w)); + map(0x0d, 0x0d).rw(FUNC(ns32202_device::csrch_r), FUNC(ns32202_device::csrch_w)); + map(0x0e, 0x0e).rw(FUNC(ns32202_device::fprtl_r), FUNC(ns32202_device::fprtl_w)); + map(0x0f, 0x0f).rw(FUNC(ns32202_device::fprth_r), FUNC(ns32202_device::fprth_w)); + map(0x10, 0x10).rw(FUNC(ns32202_device::mctl_r), FUNC(ns32202_device::mctl_w)); + map(0x11, 0x11).rw(FUNC(ns32202_device::ocasn_r), FUNC(ns32202_device::ocasn_w)); + map(0x12, 0x12).rw(FUNC(ns32202_device::ciptr_r), FUNC(ns32202_device::ciptr_w)); + map(0x13, 0x13).rw(FUNC(ns32202_device::pdat_r), FUNC(ns32202_device::pdat_w)); + map(0x14, 0x14).rw(FUNC(ns32202_device::ips_r), FUNC(ns32202_device::ips_w)); + map(0x15, 0x15).rw(FUNC(ns32202_device::pdir_r), FUNC(ns32202_device::pdir_w)); + map(0x16, 0x16).rw(FUNC(ns32202_device::cctl_r), FUNC(ns32202_device::cctl_w)); + map(0x17, 0x17).rw(FUNC(ns32202_device::cictl_r), FUNC(ns32202_device::cictl_w)); + map(0x18, 0x18).rw(FUNC(ns32202_device::csvl_r<0>), FUNC(ns32202_device::csvl_w<0>)); + map(0x19, 0x19).rw(FUNC(ns32202_device::csvh_r<0>), FUNC(ns32202_device::csvh_w<0>)); + map(0x1a, 0x1a).rw(FUNC(ns32202_device::csvl_r<1>), FUNC(ns32202_device::csvl_w<1>)); + map(0x1b, 0x1b).rw(FUNC(ns32202_device::csvh_r<1>), FUNC(ns32202_device::csvh_w<1>)); + map(0x1c, 0x1c).rw(FUNC(ns32202_device::lccvl_r), FUNC(ns32202_device::lccvl_w)); + map(0x1d, 0x1d).rw(FUNC(ns32202_device::lccvh_r), FUNC(ns32202_device::lccvh_w)); + map(0x1e, 0x1e).rw(FUNC(ns32202_device::hccvl_r), FUNC(ns32202_device::hccvl_w)); + map(0x1f, 0x1f).rw(FUNC(ns32202_device::hccvh_r), FUNC(ns32202_device::hccvh_w)); +} + +template void ns32202_device::map<0>(address_map &map); +template void ns32202_device::map<1>(address_map &map); + +/* + * Set (and clear, for level-triggered interrupts) interrupt pending state + * based on edge/level/polarity configuration and previous/current line state, + * regardless of mask. + */ +template <unsigned Number> void ns32202_device::ir_w(int state) +{ + // ignore external interrupts assigned to counters + if (((m_cictl & CICTL_CIEL) && (m_ciptr & 15) == Number) || + ((m_cictl & CICTL_CIEH) && (m_ciptr >> 4) == Number)) + return; + + u16 const mask = 1 << Number; + + if (m_eltg & mask) + { + // level triggered + if (state == BIT(m_tpl, Number)) + m_ipnd |= mask; + else + m_ipnd &= ~mask; + } + else + { + // edge triggered + if (bool(state) == BIT(m_tpl, Number) && bool(state) ^ BIT(m_line_state, Number)) + m_ipnd |= mask; + } + + // record input line state + if (state) + m_line_state |= mask; + else + m_line_state &= ~mask; + + // datasheet states maximum 800ns + m_interrupt->adjust(attotime::from_nsec(600)); +} + +// instantiate all valid interrupt request templates +template void ns32202_device::ir_w<0>(int state); +template void ns32202_device::ir_w<1>(int state); +template void ns32202_device::ir_w<2>(int state); +template void ns32202_device::ir_w<3>(int state); +template void ns32202_device::ir_w<4>(int state); +template void ns32202_device::ir_w<5>(int state); +template void ns32202_device::ir_w<6>(int state); +template void ns32202_device::ir_w<7>(int state); +template void ns32202_device::ir_w<8>(int state); +template void ns32202_device::ir_w<9>(int state); +template void ns32202_device::ir_w<10>(int state); +template void ns32202_device::ir_w<11>(int state); +template void ns32202_device::ir_w<12>(int state); +template void ns32202_device::ir_w<13>(int state); +template void ns32202_device::ir_w<14>(int state); +template void ns32202_device::ir_w<15>(int state); + +/* + * Assert interrupt output if there are any unmasked pending interrupts; and + * - in auto-rotate mode and no interrupts are in-service; or + * - in fixed priority mode; and + * - no interrupts are in-service; or + * - unmasked pending interrupt has priority > in-service interrupt; or + * - unmasked pending cascade interrupt has priorty >= in-service interrupt + */ +void ns32202_device::interrupt(void *ptr, s32 param) +{ + // check for unmasked pending interrupts + if (!(m_ipnd & m_imsk)) + return; + + if (m_mctl & MCTL_NTAR) + { + // fixed priority mode + bool accept = false; + + // check any interrupts in-service + if (m_isrv) + { + // check interrupts in descending priority order + u16 mask = m_fprt; + for (unsigned i = 0; i < 16; i++) + { + // check interrupt in-service + if (m_isrv & mask) + { + // check equal priority unmasked pending cascade interrupt + if ((m_csrc & mask) && (m_ipnd & mask) && !(m_imsk & mask)) + { + LOGMASKED(LOG_STATE, "unmasked pending cascade in-service interrupt %d\n", 31 - count_leading_zeros(mask)); + accept = true; + } + + break; + } + + // check unmasked pending interrupt + if ((m_ipnd & mask) && !(m_imsk & mask)) + { + LOGMASKED(LOG_STATE, "unmasked pending interrupt %d\n", 31 - count_leading_zeros(mask)); + accept = true; + break; + } + + // rotate priority mask + mask = (mask << 1) | (mask >> 15); + } + } + else + accept = true; + + if (!accept) + return; + } + else if (m_isrv) + return; + + set_int(true); +} + +u8 ns32202_device::interrupt_acknowledge(bool side_effects) +{ + side_effects &= !machine().side_effects_disabled(); + u8 vector = m_hvct | 0x0f; + + if ((m_ipnd & m_imsk) && m_fprt) + { + // find highest priority unmasked pending interrupt + u16 mask = m_fprt; + for (unsigned i = 0; i < 16; i++) + { + if ((m_ipnd & mask) && !(m_imsk & mask)) + break; + + // rotate priority mask + mask = (mask << 1) | (mask >> 15); + } + + unsigned const number = 31 - count_leading_zeros(mask); + if (side_effects) + { + LOGMASKED(LOG_STATE, "acknowledge highest priority unmasked interrupt %d\n", number); + + if (m_mctl & MCTL_NTAR) + { + if (m_csrc & mask) + m_isrv_count[number]++; + } + else + m_fprt = mask; + + // mark interrupt in-service + m_isrv |= mask; + + // clear interrupt pending + m_ipnd &= ~(mask); + + // clear l-counter interrupt pending + if ((m_cictl & CICTL_CIEL) && (m_cictl & CICTL_CIRL) && BIT(mask, m_ciptr & 15)) + m_cictl &= ~CICTL_CIRL; + + // clear h-counter interrupt pending + if ((m_cictl & CICTL_CIEH) && (m_cictl & CICTL_CIRH) && BIT(mask, m_ciptr >> 4)) + m_cictl &= ~CICTL_CIRH; + + // clear interrupt output + set_int(false); + } + + // compute acknowledge vector + if (m_csrc & mask) + vector = 0xf0 | number; + else + vector = m_hvct | number; + } + else if (side_effects) + { + if (m_fprt) + LOGMASKED(LOG_STATE, "acknowledge without unmasked interrupt pending\n"); + else + LOGMASKED(LOG_STATE, "acknowledge with FPRT clear\n"); + + // clear pending edge for interrupt 15 + if (!BIT(m_eltg, 15)) + m_ipnd &= ~(1 << 15); + + // clear first priority + if (!(m_mctl & MCTL_NTAR)) + m_fprt = 0; + } + + if (side_effects) + LOGMASKED(LOG_STATE, "acknowledge vector 0x%02x\n", vector); + + return vector; +} + +u8 ns32202_device::interrupt_return(bool side_effects) +{ + side_effects &= !machine().side_effects_disabled(); + u8 vector = m_hvct | 0x0f; + + // find highest priority in-service interrupt + if (m_isrv && m_fprt) + { + u16 mask = m_fprt; + for (unsigned i = 0; i < 16; i++) + { + if (m_isrv & mask) + break; + + // rotate priority mask + mask = (mask << 1) | (mask >> 15); + } + unsigned const number = 31 - count_leading_zeros(mask); + + if (side_effects) + { + LOGMASKED(LOG_STATE, "return highest priority in-service interrupt %d\n", number); + + if (m_mctl & MCTL_NTAR) + { + if (m_csrc & mask) + { + m_isrv_count[number]--; + + if (!m_isrv_count[number]) + m_isrv &= ~mask; + } + else + // clear interrupt in-service + m_isrv &= ~mask; + } + else + { + // clear interrupt in-service + m_isrv &= ~mask; + + // rotate priority mask + m_fprt = (m_fprt << 1) | (m_fprt >> 15); + } + } + + // compute return vector + if (m_csrc & mask) + vector = 0xf0 | number; + else + vector = m_hvct | number; + } + else if (side_effects) + { + if (m_fprt) + LOGMASKED(LOG_STATE, "return without in-service interrupt\n"); + else + LOGMASKED(LOG_STATE, "return with FPRT clear\n"); + + if (!(m_mctl & MCTL_NTAR)) + // rotate priority mask + m_fprt = (m_fprt << 1) | (m_fprt >> 15); + } + + if (side_effects) + LOGMASKED(LOG_STATE, "return vector 0x%02x\n", vector); + + return vector; +} + +/* + * Check for level-triggered interrupts which become pending due to change of + * edge/level or polarity registers. + */ +void ns32202_device::interrupt_update() +{ + // compute new pending state + u16 const ipnd = m_ipnd | (m_eltg & ~(m_line_state ^ m_tpl)); + + // update and assert if state changed + if (ipnd ^ m_ipnd) + { + m_ipnd = ipnd; + m_interrupt->adjust(attotime::zero); + } +} + +// N=0 -> l-counter +template <unsigned N> void ns32202_device::counter(void *buf, s32 param) +{ + u32 const scaled_clock = clock() / ((m_cctl & CCTL_CFNPS) ? 1 : 4); + + // for now, assume this is the periodic timer triggered when we hit zero + // reload on cycle after zero + if (param) + { + u32 const ticks = (m_cctl & CCTL_CCON) + ? ((u32(m_csv[1]) << 16) | m_csv[0]) - ((u32(m_ccv[1]) << 16) | m_ccv[0]) + : m_csv[N] - m_ccv[N]; + + // reload current value + if (m_cctl & CCTL_CCON) + { + m_ccv[0] = m_csv[0]; + m_ccv[1] = m_csv[1]; + } + else + m_ccv[N] = m_csv[N]; + + // reschedule counter + m_counter[N]->adjust(attotime::from_ticks(ticks, scaled_clock), 0); + } + else + { + // clear current value + if (m_cctl & CCTL_CCON) + { + m_ccv[0] = 0; + m_ccv[1] = 0; + } + else + m_ccv[N] = 0; + + // schedule reload cycle + m_counter[N]->adjust(attotime::from_ticks(1, scaled_clock), 1); + + // update cout + if (!(m_mctl & MCTL_COUTD) && (m_cctl & (CCTL_COUT0 << N))) + { + if (m_mctl & MCTL_COUTM) + { + set_cout(true); + set_cout(false); + } + else + set_cout(!m_out_cout_state); + } + + // update port + if ((N == 1) && !(m_mctl & MCTL_T16N8) && (m_ocasn & 15)) + { + // TODO: trigger interrupts if IPS != 0 + + u8 const mask = (m_ocasn & ~m_pdir) & 15; + if (m_mctl & MCTL_CLKM) + { + m_pdat &= ~mask; + + m_out_port(0, m_ocasn & 15, mask); + m_out_port(0, 0, mask); + } + else + { + m_pdat ^= mask; + + m_out_port(0, m_pdat, mask); + } + } + + // interrupts + unsigned const shift = N ? 4 : 0; + if (m_cictl & (CICTL_CIEL << shift)) + { + // check counter interrupt error + if (m_cictl & (CICTL_CIRL << shift)) + m_cictl |= (CICTL_CERL << shift); + + // set counter interrupt request + m_cictl |= (CICTL_CIRL << shift); + + // raise interrupt + m_ipnd |= 1 << ((m_ciptr >> shift) & 15); + m_interrupt->adjust(attotime::zero); + } + } +} + +template <unsigned ST1, bool SideEffects> u8 ns32202_device::hvct_r() +{ + if (!ST1) + return interrupt_acknowledge(SideEffects); + else + return interrupt_return(SideEffects); +} + +void ns32202_device::eltgl_w(u8 data) +{ + m_eltg = (m_eltg & 0xff00) | data; + + interrupt_update(); +} + +void ns32202_device::eltgh_w(u8 data) +{ + m_eltg = (u16(data) << 8) | u8(m_eltg); + + interrupt_update(); +} + +void ns32202_device::tpll_w(u8 data) +{ + m_tpl = (m_tpl & 0xff00) | data; + + interrupt_update(); +} + +void ns32202_device::tplh_w(u8 data) +{ + m_tpl = (u16(data) << 8) | u8(m_tpl); + + interrupt_update(); +} + +void ns32202_device::csrcl_w(u8 data) +{ + m_csrc = (m_csrc & 0xff00) | data; + + // clear in-service counters + for (unsigned i = 0; i < 8; i++) + if (!BIT(m_csrc, i)) + m_isrv_count[i] = 0; +} + +void ns32202_device::csrch_w(u8 data) +{ + m_csrc = (u16(data) << 8) | u8(m_csrc); + + // clear in-service counters + for (unsigned i = 8; i < 16; i++) + if (!BIT(m_csrc, i)) + m_isrv_count[i] = 0; +} + +void ns32202_device::ipndl_w(u8 data) +{ + if (BIT(data, 6)) + // clear all pending interrupts in register + m_ipnd &= 0xff00; + else if (BIT(data, 7)) + { + // set interrupt + m_ipnd |= 1 << (data & 7); + + m_interrupt->adjust(attotime::zero); + } + else + // clear interrupt + m_ipnd &= ~(1 << (data & 7)); +} + +void ns32202_device::ipndh_w(u8 data) +{ + if (BIT(data, 6)) + // clear all pending interrupts in register + m_ipnd &= 0x00ff; + else if (BIT(data, 7)) + { + // set interrupt + m_ipnd |= 256 << (data & 7); + + m_interrupt->adjust(attotime::zero); + } + else + // clear interrupt + m_ipnd &= ~(256 << (data & 7)); +} + +void ns32202_device::fprtl_w(u8 data) +{ + m_fprt = 1 << (data & 15); +} + +void ns32202_device::cctl_w(u8 data) +{ + // disable l-counter in concatenated mode + if ((data & CCTL_CCON) && m_counter[0]->enabled()) + m_counter[0]->enable(false); + + // compute scaled clock + u32 const scaled_clock = clock() / ((data & CCTL_CFNPS) ? 1 : 4); + + // start/stop h-counter + if (!(m_cctl & CCTL_CRUNH) && (data & CCTL_CRUNH)) + m_counter[1]->adjust(attotime::from_ticks(1, scaled_clock), 1); + else if ((m_cctl & CCTL_CRUNH) && !(data & CCTL_CRUNH)) + m_counter[1]->enable(false); + + if (!(data & CCTL_CRUNH) && (data & CCTL_CDCRH)) + ; // TODO: decrement h-counter + + // start/stop l-counter + if (!(data & CCTL_CCON)) + { + if (!(m_cctl & CCTL_CRUNH) && (data & CCTL_CRUNH)) + m_counter[0]->adjust(attotime::from_ticks(1, scaled_clock), 1); + else if ((m_cctl & CCTL_CRUNH) && !(data & CCTL_CRUNH)) + m_counter[0]->enable(false); + + if (!(data & CCTL_CRUNL) && (data & CCTL_CDCRL)) + ; // TODO: decrement l-counter + } + + m_cctl = data & ~(CCTL_CRUNH | CCTL_CRUNL); +} + +void ns32202_device::cictl_w(u8 data) +{ + u8 const mask = + ((data & CICTL_WENL) ? (CICTL_CERL | CICTL_CIRL | CICTL_CIEL) : 0) | + ((data & CICTL_WENH) ? (CICTL_CERH | CICTL_CIRH | CICTL_CIEH) : 0); + + m_cictl = (m_cictl & ~mask) | (data & mask); +} diff --git a/src/devices/machine/ns32202.h b/src/devices/machine/ns32202.h new file mode 100644 index 00000000000..c6328e5fa38 --- /dev/null +++ b/src/devices/machine/ns32202.h @@ -0,0 +1,137 @@ +// license:BSD-3-Clause +// copyright-holders:Patrick Mackinlay + +#ifndef MAME_MACHINE_NS32202_H +#define MAME_MACHINE_NS32202_H + +#pragma once + +class ns32202_device : public device_t +{ +public: + auto out_int() { return m_out_int.bind(); } + auto out_cout() { return m_out_cout.bind(); } + auto out_port() { return m_out_port.bind(); } + + template <unsigned Number> void ir_w(int state); + template <unsigned ST1> void map(address_map &map); + + ns32202_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock); + +protected: + // device_t overrides + virtual void device_start() override; + virtual void device_reset() override; + + void set_int(bool int_state); + void set_cout(bool cout_state); + + void interrupt(void *buf, s32 param); + u8 interrupt_acknowledge(bool side_effects); + u8 interrupt_return(bool side_effects); + + void interrupt_update(); + + template <unsigned N> void counter(void *buf, s32 param); + + template <unsigned ST1, bool SideEffects> u8 hvct_r(); + + u8 eltgl_r() { return u8(m_eltg); } + u8 eltgh_r() { return m_eltg >> 8; } + u8 tpll_r() { return u8(m_tpl); } + u8 tplh_r() { return m_tpl >> 8; } + u8 ipndl_r() { return u8(m_ipnd); } + u8 ipndh_r() { return m_ipnd >> 8; } + u8 isrvl_r() { return u8(m_isrv); } + u8 isrvh_r() { return m_isrv >> 8; } + u8 imskl_r() { return u8(m_imsk); } + u8 imskh_r() { return m_imsk >> 8; } + u8 csrcl_r() { return u8(m_csrc); } + u8 csrch_r() { return m_csrc >> 8; } + u8 fprtl_r() { return u8(m_fprt); } + u8 fprth_r() { return m_fprt >> 8; } + u8 mctl_r() { return m_mctl; } + u8 ocasn_r() { return m_ocasn; } + u8 ciptr_r() { return m_ciptr; } + u8 pdat_r() { return 0; } + u8 ips_r() { return m_ips; } + u8 pdir_r() { return m_pdir; } + u8 cctl_r() { return m_cctl; } + u8 cictl_r() { return m_cictl; } + template <unsigned N> u8 csvl_r() { return u8(m_csv[N]); } + template <unsigned N> u8 csvh_r() { return m_csv[N] >> 8; } + u8 lccvl_r() { return 0; } + u8 lccvh_r() { return 0; } + u8 hccvl_r() { return 0; } + u8 hccvh_r() { return 0; } + + void svct_w(u8 data) { m_hvct = data & 0xf0; } + + void eltgl_w(u8 data); + void eltgh_w(u8 data); + void tpll_w(u8 data); + void tplh_w(u8 data); + void ipndl_w(u8 data); + void ipndh_w(u8 data); + void isrvl_w(u8 data) { m_isrv = (m_isrv & 0xff00) | data; } + void isrvh_w(u8 data) { m_isrv = (u16(data) << 8) | u8(m_isrv); } + void imskl_w(u8 data) { m_imsk = (m_imsk & 0xff00) | data; m_interrupt->adjust(attotime::zero); } + void imskh_w(u8 data) { m_imsk = (u16(data) << 8) | u8(m_imsk); m_interrupt->adjust(attotime::zero); } + void csrcl_w(u8 data); + void csrch_w(u8 data); + void fprtl_w(u8 data); + void fprth_w(u8 data) {} + + void mctl_w(u8 data) { m_mctl = data; } + void ocasn_w(u8 data) { m_ocasn = data; } + void ciptr_w(u8 data) { m_ciptr = data; } + void pdat_w(u8 data) {} + void ips_w(u8 data) { m_ips = data; } + void pdir_w(u8 data) { m_pdir = data; } + void cctl_w(u8 data); + void cictl_w(u8 data); + + template <unsigned N> void csvl_w(u8 data) { m_csv[N] = (m_csv[N] & 0xff00) | data; } + template <unsigned N> void csvh_w(u8 data) { m_csv[N] = (u16(data) << 8) | u8(m_csv[N]); } + void lccvl_w(u8 data) {} + void lccvh_w(u8 data) {} + void hccvl_w(u8 data) {} + void hccvh_w(u8 data) {} + +private: + devcb_write_line m_out_int; + devcb_write_line m_out_cout; + devcb_write8 m_out_port; + + emu_timer *m_interrupt; + emu_timer *m_counter[2]; + + u8 m_hvct; // hardware vector + u16 m_eltg; // edge/level triggering + u16 m_tpl; // triggering polarity + u16 m_ipnd; // interrupts pending + u16 m_isrv; // interrupts in-service + u16 m_imsk; // interrupt mask + u16 m_csrc; // cascaded source + u16 m_fprt; // first priority + u8 m_mctl; // mode control + u8 m_ocasn; // output clock assignment + u8 m_ciptr; // counter interrupt pointer + u8 m_pdat; // port data + u8 m_ips; // interrupt/port select + u8 m_pdir; // port direction + u8 m_cctl; // counter control + u8 m_cictl; // counter interrupt control + u16 m_csv[2]; // counter starting value + u16 m_ccv[2]; // counter current value + + unsigned m_isrv_count[16]; + + u16 m_line_state; + bool m_out_int_state; + bool m_out_cout_state; +}; + +DECLARE_DEVICE_TYPE(NS32202, ns32202_device) + +#endif // MAME_MACHINE_NS32202_H diff --git a/src/devices/machine/pxa255.cpp b/src/devices/machine/pxa255.cpp index 07e7d997b8c..6bd82ec987c 100644 --- a/src/devices/machine/pxa255.cpp +++ b/src/devices/machine/pxa255.cpp @@ -1583,7 +1583,7 @@ uint32_t pxa255_periphs_device::screen_update(screen_device &screen, bitmap_rgb3 { for (int y = 0; y <= (m_lcd_regs.lccr2 & PXA255_LCCR2_LPP); y++) { - uint32_t *dst = &bitmap.pix32(y); + uint32_t *dst = &bitmap.pix(y); for (int x = 0; x <= (m_lcd_regs.lccr1 & PXA255_LCCR1_PPL); x++) { *dst++ = m_lcd_palette[m_lcd_framebuffer[y * ((m_lcd_regs.lccr1 & PXA255_LCCR1_PPL) + 1) + x]]; diff --git a/src/devices/machine/s2636.cpp b/src/devices/machine/s2636.cpp index bdf95dc69d0..8ad26690bcf 100644 --- a/src/devices/machine/s2636.cpp +++ b/src/devices/machine/s2636.cpp @@ -203,7 +203,7 @@ void s2636_device::device_start() save_item(NAME(m_intreq)); save_item(NAME(m_intack)); - m_stream = stream_alloc_legacy(0, 1, machine().sample_rate()); + m_stream = stream_alloc(0, 1, machine().sample_rate()); save_item(NAME(m_sample_cnt)); save_item(NAME(m_sound_lvl)); @@ -247,7 +247,7 @@ void s2636_device::render_next_line() // pre-clear the line for convenience rectangle const &vis_area = screen().visible_area(); - uint16_t *const row = &m_bitmap.pix16(m_screen_line); + uint16_t *const row = &m_bitmap.pix(m_screen_line); m_bitmap.plot_box(0, m_screen_line, m_bitmap.width(), 1, 0); if ((vis_area.min_y > m_screen_line) || (vis_area.max_y < m_screen_line)) @@ -447,13 +447,14 @@ void s2636_device::write_intack(int state) //------------------------------------------------- -// sound_stream_update_legacy - generate audio output +// sound_stream_update - generate audio output //------------------------------------------------- -void s2636_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) + +void s2636_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - stream_sample_t *buffer = outputs[0]; - while (samples--) + auto &buffer = outputs[0]; + for (int sampindex = 0; sampindex < buffer.samples(); sampindex++) { if (!m_sample_cnt) { @@ -469,7 +470,7 @@ void s2636_device::sound_stream_update_legacy(sound_stream &stream, stream_sampl } } - *buffer++ = m_sound_lvl ? 0x7fff : 0x0000; + buffer.put(sampindex, m_sound_lvl ? 1.0 : 0.0); m_sample_cnt--; } } diff --git a/src/devices/machine/s2636.h b/src/devices/machine/s2636.h index b5e41b83499..8803c629015 100644 --- a/src/devices/machine/s2636.h +++ b/src/devices/machine/s2636.h @@ -58,7 +58,7 @@ protected: virtual void device_start() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: enum diff --git a/src/devices/machine/s3c24xx.hxx b/src/devices/machine/s3c24xx.hxx index dcff99a7b70..8fae9ee616e 100644 --- a/src/devices/machine/s3c24xx.hxx +++ b/src/devices/machine/s3c24xx.hxx @@ -434,7 +434,7 @@ void S3C24_CLASS_NAME::s3c24xx_lcd_render_tpal() uint32_t color = s3c24xx_get_color_tpal(); for (int y = m_lcd.vpos_min; y <= m_lcd.vpos_max; y++) { - uint32_t *scanline = &bitmap.pix32(y, m_lcd.hpos_min); + uint32_t *scanline = &bitmap.pix(y, m_lcd.hpos_min); for (int x = m_lcd.hpos_min; x <= m_lcd.hpos_max; x++) { *scanline++ = color; @@ -445,7 +445,7 @@ void S3C24_CLASS_NAME::s3c24xx_lcd_render_tpal() void S3C24_CLASS_NAME::s3c24xx_lcd_render_stn_01() { bitmap_rgb32 &bitmap = *m_lcd.bitmap[0]; - uint32_t *scanline = &bitmap.pix32(m_lcd.vpos, m_lcd.hpos); + uint32_t *scanline = &bitmap.pix(m_lcd.vpos, m_lcd.hpos); for (int i = 0; i < 4; i++) { uint32_t data = s3c24xx_lcd_dma_read(); @@ -467,7 +467,7 @@ void S3C24_CLASS_NAME::s3c24xx_lcd_render_stn_01() m_lcd.vpos++; if (m_lcd.vpos > m_lcd.vpos_max) m_lcd.vpos = m_lcd.vpos_min; m_lcd.hpos = m_lcd.hpos_min; - scanline = &bitmap.pix32(m_lcd.vpos, m_lcd.hpos); + scanline = &bitmap.pix(m_lcd.vpos, m_lcd.hpos); } } } @@ -476,7 +476,7 @@ void S3C24_CLASS_NAME::s3c24xx_lcd_render_stn_01() void S3C24_CLASS_NAME::s3c24xx_lcd_render_stn_02() { bitmap_rgb32 &bitmap = *m_lcd.bitmap[0]; - uint32_t *scanline = &bitmap.pix32(m_lcd.vpos, m_lcd.hpos); + uint32_t *scanline = &bitmap.pix(m_lcd.vpos, m_lcd.hpos); for (int i = 0; i < 4; i++) { uint32_t data = s3c24xx_lcd_dma_read(); @@ -490,7 +490,7 @@ void S3C24_CLASS_NAME::s3c24xx_lcd_render_stn_02() m_lcd.vpos++; if (m_lcd.vpos > m_lcd.vpos_max) m_lcd.vpos = m_lcd.vpos_min; m_lcd.hpos = m_lcd.hpos_min; - scanline = &bitmap.pix32(m_lcd.vpos, m_lcd.hpos); + scanline = &bitmap.pix(m_lcd.vpos, m_lcd.hpos); } } } @@ -499,7 +499,7 @@ void S3C24_CLASS_NAME::s3c24xx_lcd_render_stn_02() void S3C24_CLASS_NAME::s3c24xx_lcd_render_stn_04() { bitmap_rgb32 &bitmap = *m_lcd.bitmap[0]; - uint32_t *scanline = &bitmap.pix32(m_lcd.vpos, m_lcd.hpos); + uint32_t *scanline = &bitmap.pix(m_lcd.vpos, m_lcd.hpos); for (int i = 0; i < 4; i++) { uint32_t data = s3c24xx_lcd_dma_read(); @@ -513,7 +513,7 @@ void S3C24_CLASS_NAME::s3c24xx_lcd_render_stn_04() m_lcd.vpos++; if (m_lcd.vpos > m_lcd.vpos_max) m_lcd.vpos = m_lcd.vpos_min; m_lcd.hpos = m_lcd.hpos_min; - scanline = &bitmap.pix32(m_lcd.vpos, m_lcd.hpos); + scanline = &bitmap.pix(m_lcd.vpos, m_lcd.hpos); } } } @@ -522,7 +522,7 @@ void S3C24_CLASS_NAME::s3c24xx_lcd_render_stn_04() void S3C24_CLASS_NAME::s3c24xx_lcd_render_stn_08() { bitmap_rgb32 &bitmap = *m_lcd.bitmap[0]; - uint32_t *scanline = &bitmap.pix32(m_lcd.vpos, m_lcd.hpos); + uint32_t *scanline = &bitmap.pix(m_lcd.vpos, m_lcd.hpos); for (int i = 0; i < 4; i++) { uint32_t data = s3c24xx_lcd_dma_read(); @@ -536,7 +536,7 @@ void S3C24_CLASS_NAME::s3c24xx_lcd_render_stn_08() m_lcd.vpos++; if (m_lcd.vpos > m_lcd.vpos_max) m_lcd.vpos = m_lcd.vpos_min; m_lcd.hpos = m_lcd.hpos_min; - scanline = &bitmap.pix32(m_lcd.vpos, m_lcd.hpos); + scanline = &bitmap.pix(m_lcd.vpos, m_lcd.hpos); } } } @@ -545,7 +545,7 @@ void S3C24_CLASS_NAME::s3c24xx_lcd_render_stn_08() void S3C24_CLASS_NAME::s3c24xx_lcd_render_stn_12_p() { bitmap_rgb32 &bitmap = *m_lcd.bitmap[0]; - uint32_t *scanline = &bitmap.pix32(m_lcd.vpos, m_lcd.hpos); + uint32_t *scanline = &bitmap.pix(m_lcd.vpos, m_lcd.hpos); for (int i = 0; i < 16; i++) { *scanline++ = s3c24xx_get_color_stn_12(s3c24xx_lcd_dma_read_bits(12)); @@ -555,7 +555,7 @@ void S3C24_CLASS_NAME::s3c24xx_lcd_render_stn_12_p() m_lcd.vpos++; if (m_lcd.vpos > m_lcd.vpos_max) m_lcd.vpos = m_lcd.vpos_min; m_lcd.hpos = m_lcd.hpos_min; - scanline = &bitmap.pix32(m_lcd.vpos, m_lcd.hpos); + scanline = &bitmap.pix(m_lcd.vpos, m_lcd.hpos); } } } @@ -563,7 +563,7 @@ void S3C24_CLASS_NAME::s3c24xx_lcd_render_stn_12_p() void S3C24_CLASS_NAME::s3c24xx_lcd_render_stn_12_u() // not tested { bitmap_rgb32 &bitmap = *m_lcd.bitmap[0]; - uint32_t *scanline = &bitmap.pix32(m_lcd.vpos, m_lcd.hpos); + uint32_t *scanline = &bitmap.pix(m_lcd.vpos, m_lcd.hpos); for (int i = 0; i < 4; i++) { uint32_t data = s3c24xx_lcd_dma_read(); @@ -577,7 +577,7 @@ void S3C24_CLASS_NAME::s3c24xx_lcd_render_stn_12_u() // not tested m_lcd.vpos++; if (m_lcd.vpos > m_lcd.vpos_max) m_lcd.vpos = m_lcd.vpos_min; m_lcd.hpos = m_lcd.hpos_min; - scanline = &bitmap.pix32(m_lcd.vpos, m_lcd.hpos); + scanline = &bitmap.pix(m_lcd.vpos, m_lcd.hpos); } } } @@ -586,7 +586,7 @@ void S3C24_CLASS_NAME::s3c24xx_lcd_render_stn_12_u() // not tested void S3C24_CLASS_NAME::s3c24xx_lcd_render_tft_01() { bitmap_rgb32 &bitmap = *m_lcd.bitmap[0]; - uint32_t *scanline = &bitmap.pix32(m_lcd.vpos, m_lcd.hpos); + uint32_t *scanline = &bitmap.pix(m_lcd.vpos, m_lcd.hpos); for (int i = 0; i < 4; i++) { uint32_t data = s3c24xx_lcd_dma_read(); @@ -600,7 +600,7 @@ void S3C24_CLASS_NAME::s3c24xx_lcd_render_tft_01() m_lcd.vpos++; if (m_lcd.vpos > m_lcd.vpos_max) m_lcd.vpos = m_lcd.vpos_min; m_lcd.hpos = m_lcd.hpos_min; - scanline = &bitmap.pix32(m_lcd.vpos, m_lcd.hpos); + scanline = &bitmap.pix(m_lcd.vpos, m_lcd.hpos); } } } @@ -609,7 +609,7 @@ void S3C24_CLASS_NAME::s3c24xx_lcd_render_tft_01() void S3C24_CLASS_NAME::s3c24xx_lcd_render_tft_02() { bitmap_rgb32 &bitmap = *m_lcd.bitmap[0]; - uint32_t *scanline = &bitmap.pix32(m_lcd.vpos, m_lcd.hpos); + uint32_t *scanline = &bitmap.pix(m_lcd.vpos, m_lcd.hpos); for (int i = 0; i < 4; i++) { uint32_t data = s3c24xx_lcd_dma_read(); @@ -623,7 +623,7 @@ void S3C24_CLASS_NAME::s3c24xx_lcd_render_tft_02() m_lcd.vpos++; if (m_lcd.vpos > m_lcd.vpos_max) m_lcd.vpos = m_lcd.vpos_min; m_lcd.hpos = m_lcd.hpos_min; - scanline = &bitmap.pix32(m_lcd.vpos, m_lcd.hpos); + scanline = &bitmap.pix(m_lcd.vpos, m_lcd.hpos); } } } @@ -632,7 +632,7 @@ void S3C24_CLASS_NAME::s3c24xx_lcd_render_tft_02() void S3C24_CLASS_NAME::s3c24xx_lcd_render_tft_04() { bitmap_rgb32 &bitmap = *m_lcd.bitmap[0]; - uint32_t *scanline = &bitmap.pix32(m_lcd.vpos, m_lcd.hpos); + uint32_t *scanline = &bitmap.pix(m_lcd.vpos, m_lcd.hpos); for (int i = 0; i < 4; i++) { uint32_t data = s3c24xx_lcd_dma_read(); @@ -646,7 +646,7 @@ void S3C24_CLASS_NAME::s3c24xx_lcd_render_tft_04() m_lcd.vpos++; if (m_lcd.vpos > m_lcd.vpos_max) m_lcd.vpos = m_lcd.vpos_min; m_lcd.hpos = m_lcd.hpos_min; - scanline = &bitmap.pix32(m_lcd.vpos, m_lcd.hpos); + scanline = &bitmap.pix(m_lcd.vpos, m_lcd.hpos); } } } @@ -655,7 +655,7 @@ void S3C24_CLASS_NAME::s3c24xx_lcd_render_tft_04() void S3C24_CLASS_NAME::s3c24xx_lcd_render_tft_08() { bitmap_rgb32 &bitmap = *m_lcd.bitmap[0]; - uint32_t *scanline = &bitmap.pix32(m_lcd.vpos, m_lcd.hpos); + uint32_t *scanline = &bitmap.pix(m_lcd.vpos, m_lcd.hpos); for (int i = 0; i < 4; i++) { uint32_t data = s3c24xx_lcd_dma_read(); @@ -669,7 +669,7 @@ void S3C24_CLASS_NAME::s3c24xx_lcd_render_tft_08() m_lcd.vpos++; if (m_lcd.vpos > m_lcd.vpos_max) m_lcd.vpos = m_lcd.vpos_min; m_lcd.hpos = m_lcd.hpos_min; - scanline = &bitmap.pix32(m_lcd.vpos, m_lcd.hpos); + scanline = &bitmap.pix(m_lcd.vpos, m_lcd.hpos); } } } @@ -678,7 +678,7 @@ void S3C24_CLASS_NAME::s3c24xx_lcd_render_tft_08() void S3C24_CLASS_NAME::s3c24xx_lcd_render_tft_16() { bitmap_rgb32 &bitmap = *m_lcd.bitmap[0]; - uint32_t *scanline = &bitmap.pix32(m_lcd.vpos, m_lcd.hpos); + uint32_t *scanline = &bitmap.pix(m_lcd.vpos, m_lcd.hpos); for (int i = 0; i < 4; i++) { uint32_t data = s3c24xx_lcd_dma_read(); @@ -692,7 +692,7 @@ void S3C24_CLASS_NAME::s3c24xx_lcd_render_tft_16() m_lcd.vpos++; if (m_lcd.vpos > m_lcd.vpos_max) m_lcd.vpos = m_lcd.vpos_min; m_lcd.hpos = m_lcd.hpos_min; - scanline = &bitmap.pix32(m_lcd.vpos, m_lcd.hpos); + scanline = &bitmap.pix(m_lcd.vpos, m_lcd.hpos); } } } @@ -751,9 +751,9 @@ void S3C24_CLASS_NAME::bitmap_blend( bitmap_rgb32 &bitmap_dst, bitmap_rgb32 &bit { for (int y = 0; y < bitmap_dst.height(); y++) { - uint32_t *line0 = &bitmap_src_1.pix32(y); - uint32_t *line1 = &bitmap_src_2.pix32(y); - uint32_t *line2 = &bitmap_dst.pix32(y); + uint32_t const *const line0 = &bitmap_src_1.pix(y); + uint32_t const *const line1 = &bitmap_src_2.pix(y); + uint32_t *const line2 = &bitmap_dst.pix(y); for (int x = 0; x < bitmap_dst.width(); x++) { uint32_t color0 = line0[x]; @@ -764,9 +764,9 @@ void S3C24_CLASS_NAME::bitmap_blend( bitmap_rgb32 &bitmap_dst, bitmap_rgb32 &bit uint16_t r1 = (color1 >> 16) & 0x000000ff; uint16_t g1 = (color1 >> 8) & 0x000000ff; uint16_t b1 = (color1 >> 0) & 0x000000ff; - uint8_t r = (uint8_t)((r0 + r1) >> 1); - uint8_t g = (uint8_t)((g0 + g1) >> 1); - uint8_t b = (uint8_t)((b0 + b1) >> 1); + uint8_t r = uint8_t((r0 + r1) >> 1); + uint8_t g = uint8_t((g0 + g1) >> 1); + uint8_t b = uint8_t((b0 + b1) >> 1); line2[x] = (r << 16) | (g << 8) | b; } } diff --git a/src/devices/machine/s3c44b0.cpp b/src/devices/machine/s3c44b0.cpp index 6672127e20f..bf3a1ed811c 100644 --- a/src/devices/machine/s3c44b0.cpp +++ b/src/devices/machine/s3c44b0.cpp @@ -17,6 +17,8 @@ #include "coreutil.h" +#include <algorithm> + #define S3C44B0_INTCON (0x00 / 4) // Interrupt Control #define S3C44B0_INTPND (0x04 / 4) // Interrupt Request Status @@ -696,8 +698,8 @@ uint32_t s3c44b0_device::video_update(screen_device &screen, bitmap_rgb32 &bitma { for (int y = 0; y < screen.height(); y++) { - uint32_t *scanline = &bitmap.pix32(y); - uint8_t *vram = m_lcd.bitmap.get() + y * (m_lcd.hpos_max - m_lcd.hpos_min + 1); + uint32_t *scanline = &bitmap.pix(y); + uint8_t const *vram = m_lcd.bitmap.get() + y * (m_lcd.hpos_max - m_lcd.hpos_min + 1); for (int x = 0; x < screen.width(); x++) { *scanline++ = rgb_t(vram[0], vram[1], vram[2]); @@ -710,8 +712,7 @@ uint32_t s3c44b0_device::video_update(screen_device &screen, bitmap_rgb32 &bitma { for (int y = 0; y < screen.height(); y++) { - uint32_t *scanline = &bitmap.pix32(y); - memset(scanline, 0, screen.width() * 4); + std::fill_n(&bitmap.pix(y), screen.width(), 0); } } return 0; diff --git a/src/devices/machine/spg110_video.cpp b/src/devices/machine/spg110_video.cpp index a76fef3bb60..daf7fa5e158 100644 --- a/src/devices/machine/spg110_video.cpp +++ b/src/devices/machine/spg110_video.cpp @@ -4,6 +4,9 @@ #include "emu.h" #include "spg110_video.h" +#include <algorithm> + + DEFINE_DEVICE_TYPE(SPG110_VIDEO, spg110_video_device, "spg110_video", "SPG110 System-on-a-Chip (Video)") spg110_video_device::spg110_video_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : @@ -649,9 +652,9 @@ uint32_t spg110_video_device::screen_update(screen_device &screen, bitmap_rgb32 for (int y = cliprect.min_y; y <= cliprect.max_y; y++) { - uint32_t *dest = &bitmap.pix32(y, cliprect.min_x); - uint32_t *src = &m_screenbuf[cliprect.min_x + 320 * y]; - memcpy(dest, src, sizeof(uint32_t) * ((cliprect.max_x - cliprect.min_x) + 1)); + uint32_t *dest = &bitmap.pix(y, cliprect.min_x); + const uint32_t *src = &m_screenbuf[cliprect.min_x + 320 * y]; + std::copy_n(src, cliprect.width(), dest); } return 0; diff --git a/src/devices/machine/spg290_ppu.cpp b/src/devices/machine/spg290_ppu.cpp index 8f47d61bf18..19ff7ccb1d2 100644 --- a/src/devices/machine/spg290_ppu.cpp +++ b/src/devices/machine/spg290_ppu.cpp @@ -354,9 +354,9 @@ inline void spg290_ppu_device::argb1555(bitmap_rgb32 &bitmap, const rectangle &c { rgb_t color = rgb_t(pal5bit(argb >> 10), pal5bit(argb >> 5), pal5bit(argb >> 0)); if (blend) - color = blend_colors(bitmap.pix32(posy, posx), color, blend); + color = blend_colors(bitmap.pix(posy, posx), color, blend); - bitmap.pix32(posy, posx) = color; + bitmap.pix(posy, posx) = color; } } @@ -366,9 +366,9 @@ inline void spg290_ppu_device::rgb565(bitmap_rgb32 &bitmap, const rectangle &cli { rgb_t color = rgb_t(pal5bit(rgb >> 11), pal6bit(rgb >> 5), pal5bit(rgb >> 0)); if (blend) - color = blend_colors(bitmap.pix32(posy, posx), color, blend); + color = blend_colors(bitmap.pix(posy, posx), color, blend); - bitmap.pix32(posy, posx) = color; + bitmap.pix(posy, posx) = color; } } diff --git a/src/devices/machine/spg2xx.h b/src/devices/machine/spg2xx.h index 0eb2a29f82a..68d42675360 100644 --- a/src/devices/machine/spg2xx.h +++ b/src/devices/machine/spg2xx.h @@ -123,8 +123,6 @@ protected: devcb_write8 m_chip_sel; - emu_timer *m_screenpos_timer; - uint8_t m_fiq_vector; required_device<screen_device> m_screen; diff --git a/src/devices/machine/spg2xx_audio.cpp b/src/devices/machine/spg2xx_audio.cpp index 07d01e88be5..2441ebf17ce 100644 --- a/src/devices/machine/spg2xx_audio.cpp +++ b/src/devices/machine/spg2xx_audio.cpp @@ -76,7 +76,7 @@ void spg2xx_audio_device::device_start() m_audio_beat = timer_alloc(TIMER_BEAT); m_audio_beat->adjust(attotime::never); - m_stream = stream_alloc_legacy(0, 2, 281250/4); + m_stream = stream_alloc(0, 2, 281250/4); m_channel_debug = -1; @@ -887,12 +887,12 @@ void spg2xx_audio_device::audio_w(offs_t offset, uint16_t data) } } -void spg2xx_audio_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void spg2xx_audio_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - stream_sample_t *out_l = outputs[0]; - stream_sample_t *out_r = outputs[1]; + auto &out_l = outputs[0]; + auto &out_r = outputs[1]; - for (int i = 0; i < samples; i++) + for (int i = 0; i < out_l.samples(); i++) { int32_t left_total = 0; int32_t right_total = 0; @@ -992,8 +992,8 @@ void spg2xx_audio_device::sound_stream_update_legacy(sound_stream &stream, strea int32_t left_final = (int16_t)((left_total * (int16_t)m_audio_ctrl_regs[AUDIO_MAIN_VOLUME]) >> 7); int32_t right_final = (int16_t)((right_total * (int16_t)m_audio_ctrl_regs[AUDIO_MAIN_VOLUME]) >> 7); - *out_l++ = (int16_t)left_final; - *out_r++ = (int16_t)right_final; + out_l.put_int(i, int16_t(left_final), 32768); + out_r.put_int(i, int16_t(right_final), 32768); } } diff --git a/src/devices/machine/spg2xx_audio.h b/src/devices/machine/spg2xx_audio.h index 59d7635198d..588d49e7895 100644 --- a/src/devices/machine/spg2xx_audio.h +++ b/src/devices/machine/spg2xx_audio.h @@ -33,7 +33,7 @@ public: protected: // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; void audio_beat_tick(); void audio_rampdown_tick(const uint32_t channel); diff --git a/src/devices/machine/spg_renderer.cpp b/src/devices/machine/spg_renderer.cpp index 0b6efe58c3f..78bc26438ae 100644 --- a/src/devices/machine/spg_renderer.cpp +++ b/src/devices/machine/spg_renderer.cpp @@ -831,7 +831,7 @@ void spg_renderer_device::update_palette_lookup() void spg_renderer_device::apply_saturation_and_fade(bitmap_rgb32& bitmap, const rectangle& cliprect, int scanline) { - uint32_t* src = &bitmap.pix32(scanline, cliprect.min_x); + uint32_t* src = &bitmap.pix(scanline, cliprect.min_x); for (int x = cliprect.min_x; x <= cliprect.max_x; x++) { diff --git a/src/devices/machine/swtpc8212.cpp b/src/devices/machine/swtpc8212.cpp index 68af9d42e07..fffd6eefe7f 100644 --- a/src/devices/machine/swtpc8212.cpp +++ b/src/devices/machine/swtpc8212.cpp @@ -319,7 +319,7 @@ MC6845_UPDATE_ROW(swtpc8212_device::update_row) else font_color = rgb_t(0x00, 0xd0, 0x00); } - bitmap.pix32(y, x++) = font_color; + bitmap.pix(y, x++) = font_color; data <<= 1; } diff --git a/src/devices/machine/tc009xlvc.cpp b/src/devices/machine/tc009xlvc.cpp index e6fcb74a181..b2d302d3922 100644 --- a/src/devices/machine/tc009xlvc.cpp +++ b/src/devices/machine/tc009xlvc.cpp @@ -347,7 +347,7 @@ u32 tc0090lvc_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, { const int res_x = (global_flip()) ? 320 - x : x; - bitmap.pix16(y, x) = palette().pen(m_bitmap_ram[count + (res_x & 0x1ff)]); + bitmap.pix(y, x) = palette().pen(m_bitmap_ram[count + (res_x & 0x1ff)]); } } } @@ -398,7 +398,7 @@ u32 tc0091lvc_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, { const int res_x = (global_flip()) ? 320 - x : x; - bitmap.pix16(y, x) = palette().pen(m_bitmap_ram[count + (res_x & 0x1ff)]); + bitmap.pix(y, x) = palette().pen(m_bitmap_ram[count + (res_x & 0x1ff)]); } } } diff --git a/src/devices/machine/terminal.cpp b/src/devices/machine/terminal.cpp index fd07c5bff35..ccb101d8036 100644 --- a/src/devices/machine/terminal.cpp +++ b/src/devices/machine/terminal.cpp @@ -276,7 +276,7 @@ uint32_t generic_terminal_device::update(screen_device &device, bitmap_rgb32 &bi { for (uint8_t ra = 0; ra < 10; ra++) { - uint32_t *p = &bitmap.pix32(sy++); + uint32_t *p = &bitmap.pix(sy++); for (uint16_t x = ma; x < ma + m_width; x++) { diff --git a/src/devices/machine/upd765.cpp b/src/devices/machine/upd765.cpp index 6328ec74dab..85aabb49335 100644 --- a/src/devices/machine/upd765.cpp +++ b/src/devices/machine/upd765.cpp @@ -174,6 +174,7 @@ upd765_family_device::upd765_family_device(const machine_config &mconfig, device ready_polled(true), select_connected(true), select_multiplexed(true), + has_dor(true), external_ready(false), recalibrate_steps(77), mode(mode_t::AT), @@ -181,8 +182,7 @@ upd765_family_device::upd765_family_device(const machine_config &mconfig, device drq_cb(*this), hdl_cb(*this), idx_cb(*this), - us_cb(*this), - dor_reset(0x00) + us_cb(*this) { } @@ -245,6 +245,7 @@ void upd765_family_device::device_start() cur_rate = 250000; tc = false; selected_drive = -1; + dor = 0x0c; // reset at upper levels may cause a write to tc ending up with // live_sync, which will crash if the live structure isn't @@ -267,7 +268,8 @@ void upd765_family_device::device_start() void upd765_family_device::device_reset() { - dor = dor_reset; + if(has_dor) + dor = 0x00; locked = false; soft_reset(); } @@ -304,6 +306,14 @@ void upd765_family_device::soft_reset() set_ds(select_multiplexed ? 0 : -1); check_irq(); + if(BIT(dor, 2)) + end_reset(); + else if(ready_polled) + poll_timer->adjust(attotime::never); +} + +void upd765_family_device::end_reset() +{ if(ready_polled) poll_timer->adjust(attotime::from_usec(100), 0, attotime::from_usec(1024)); } @@ -333,6 +343,25 @@ bool upd765_family_device::get_ready(int fid) return !external_ready; } +WRITE_LINE_MEMBER(upd765_family_device::reset_w) +{ + // This implementation is not valid for devices with DOR and possibly other extra registers. + // The working assumption is that no need to manipulate the RESET line directly when software can use DOR instead. + assert(!has_dor); + if(bool(state) == !BIT(dor, 2)) + return; + + LOGREGS("reset = %d\n", state); + if(state) { + dor &= 0xfb; + soft_reset(); + } + else { + dor |= 0x04; + end_reset(); + } +} + void upd765_family_device::set_ds(int fid) { if(selected_drive == fid) @@ -399,11 +428,16 @@ uint8_t upd765_family_device::dor_r() void upd765_family_device::dor_w(uint8_t data) { + assert(has_dor); LOGREGS("dor = %02x\n", data); uint8_t diff = dor ^ data; dor = data; - if(diff & 4) - soft_reset(); + if(BIT(diff, 2)) { + if(BIT(data, 2)) + end_reset(); + else + soft_reset(); + } for(int i=0; i<4; i++) { floppy_info &fi = flopi[i]; @@ -513,6 +547,9 @@ uint8_t upd765_family_device::fifo_r() void upd765_family_device::fifo_w(uint8_t data) { + if(!BIT(dor, 2)) + LOGWARN("%s: fifo_w(%02x) in reset\n", machine().describe_context(), data); + switch(main_phase) { case PHASE_CMD: { command[command_pos++] = data; @@ -780,7 +817,7 @@ void upd765_family_device::live_run(attotime limit) if(read_one_bit(limit)) return; - LOGSHIFT("%s: shift = %04x data=%02x c=%d\n", tts(cur_live.tm), cur_live.shift_reg, + LOGSHIFT("%s: shift = %04x data=%02x c=%d\n", cur_live.tm.to_string(), cur_live.shift_reg, (cur_live.shift_reg & 0x4000 ? 0x80 : 0x00) | (cur_live.shift_reg & 0x1000 ? 0x40 : 0x00) | (cur_live.shift_reg & 0x0400 ? 0x20 : 0x00) | @@ -796,7 +833,7 @@ void upd765_family_device::live_run(attotime limit) cur_live.data_separator_phase = false; cur_live.bit_counter = 0; cur_live.state = READ_HEADER_BLOCK_HEADER; - LOGLIVE("%s: Found A1\n", tts(cur_live.tm)); + LOGLIVE("%s: Found A1\n", cur_live.tm.to_string()); } if(!mfm && cur_live.shift_reg == 0xf57e) { @@ -804,7 +841,7 @@ void upd765_family_device::live_run(attotime limit) cur_live.data_separator_phase = false; cur_live.bit_counter = 0; cur_live.state = READ_ID_BLOCK; - LOGLIVE("%s: Found IDAM\n", tts(cur_live.tm)); + LOGLIVE("%s: Found IDAM\n", cur_live.tm.to_string()); } break; @@ -812,7 +849,7 @@ void upd765_family_device::live_run(attotime limit) if(read_one_bit(limit)) return; - LOGSHIFT("%s: shift = %04x data=%02x counter=%d\n", tts(cur_live.tm), cur_live.shift_reg, + LOGSHIFT("%s: shift = %04x data=%02x counter=%d\n", cur_live.tm.to_string(), cur_live.shift_reg, (cur_live.shift_reg & 0x4000 ? 0x80 : 0x00) | (cur_live.shift_reg & 0x1000 ? 0x40 : 0x00) | (cur_live.shift_reg & 0x0400 ? 0x20 : 0x00) | @@ -832,11 +869,11 @@ void upd765_family_device::live_run(attotime limit) if(cur_live.shift_reg != 0x4489) cur_live.state = SEARCH_ADDRESS_MARK_HEADER; else - LOGLIVE("%s: Found A1\n", tts(cur_live.tm)); + LOGLIVE("%s: Found A1\n", cur_live.tm.to_string()); break; } if(cur_live.data_reg != 0xfe) { - LOGLIVE("%s: No ident byte found after triple-A1, continue search\n", tts(cur_live.tm)); + LOGLIVE("%s: No ident byte found after triple-A1, continue search\n", cur_live.tm.to_string()); cur_live.state = SEARCH_ADDRESS_MARK_HEADER; break; } @@ -854,7 +891,7 @@ void upd765_family_device::live_run(attotime limit) break; int slot = (cur_live.bit_counter >> 4)-1; - LOGLIVE("%s: slot=%d data=%02x crc=%04x\n", tts(cur_live.tm), slot, cur_live.data_reg, cur_live.crc); + LOGLIVE("%s: slot=%d data=%02x crc=%04x\n", cur_live.tm.to_string(), slot, cur_live.data_reg, cur_live.crc); cur_live.idbuf[slot] = cur_live.data_reg; if(slot == 5) { live_delay(IDLE); @@ -867,7 +904,7 @@ void upd765_family_device::live_run(attotime limit) if(read_one_bit(limit)) return; - LOGSHIFT("%s: shift = %04x data=%02x c=%d.%x\n", tts(cur_live.tm), cur_live.shift_reg, + LOGSHIFT("%s: shift = %04x data=%02x c=%d.%x\n", cur_live.tm.to_string(), cur_live.shift_reg, (cur_live.shift_reg & 0x4000 ? 0x80 : 0x00) | (cur_live.shift_reg & 0x1000 ? 0x40 : 0x00) | (cur_live.shift_reg & 0x0400 ? 0x20 : 0x00) | @@ -912,7 +949,7 @@ void upd765_family_device::live_run(attotime limit) if(read_one_bit(limit)) return; - LOGSHIFT("%s: shift = %04x data=%02x counter=%d\n", tts(cur_live.tm), cur_live.shift_reg, + LOGSHIFT("%s: shift = %04x data=%02x counter=%d\n", cur_live.tm.to_string(), cur_live.shift_reg, (cur_live.shift_reg & 0x4000 ? 0x80 : 0x00) | (cur_live.shift_reg & 0x1000 ? 0x40 : 0x00) | (cur_live.shift_reg & 0x0400 ? 0x20 : 0x00) | @@ -1218,7 +1255,7 @@ void upd765_family_device::live_run(attotime limit) break; default: - LOGWARN("%s: Unknown live state %d\n", tts(cur_live.tm), cur_live.state); + LOGWARN("%s: Unknown live state %d\n", cur_live.tm.to_string(), cur_live.state); return; } } @@ -2412,17 +2449,6 @@ bool upd765_family_device::get_irq() const return cur_irq; } -std::string upd765_family_device::tts(attotime t) -{ - const char *sign = ""; - if(t.seconds() < 0) { - t = attotime::zero - t; - sign = "-"; - } - int const nsec = t.attoseconds() / ATTOSECONDS_PER_NANOSECOND; - return util::string_format("%s%04d.%03d,%03d,%03d", sign, int(t.seconds()), nsec/1000000, (nsec/1000)%1000, nsec % 1000); -} - std::string upd765_family_device::results() const { std::ostringstream stream; @@ -2440,7 +2466,7 @@ std::string upd765_family_device::results() const std::string upd765_family_device::ttsn() const { - return tts(machine().time()); + return machine().time().to_string(); } void upd765_family_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) @@ -2623,7 +2649,7 @@ bool upd765_family_device::write_one_bit(const attotime &limit) void upd765_family_device::live_write_raw(uint16_t raw) { - LOGLIVE("%s: write %04x %04x\n", tts(cur_live.tm), raw, cur_live.crc); + LOGLIVE("%s: write %04x %04x\n", cur_live.tm.to_string(), raw, cur_live.crc); cur_live.shift_reg = raw; cur_live.data_bit_context = raw & 1; } @@ -2643,7 +2669,7 @@ void upd765_family_device::live_write_mfm(uint8_t mfm) cur_live.data_reg = mfm; cur_live.shift_reg = raw; cur_live.data_bit_context = context; - LOGLIVE("%s: write %02x %04x %04x\n", tts(cur_live.tm), mfm, cur_live.crc, raw); + LOGLIVE("%s: write %02x %04x %04x\n", cur_live.tm.to_string(), mfm, cur_live.crc, raw); } void upd765_family_device::live_write_fm(uint8_t fm) @@ -2655,7 +2681,7 @@ void upd765_family_device::live_write_fm(uint8_t fm) cur_live.data_reg = fm; cur_live.shift_reg = raw; cur_live.data_bit_context = fm & 1; - LOGLIVE("%s: write %02x %04x %04x\n", tts(cur_live.tm), fm, cur_live.crc, raw); + LOGLIVE("%s: write %02x %04x %04x\n", cur_live.tm.to_string(), fm, cur_live.crc, raw); } bool upd765_family_device::sector_matches() const @@ -2672,17 +2698,17 @@ bool upd765_family_device::sector_matches() const upd765a_device::upd765a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : upd765_family_device(mconfig, UPD765A, tag, owner, clock) { - dor_reset = 0x0c; + has_dor = false; } upd765b_device::upd765b_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : upd765_family_device(mconfig, UPD765B, tag, owner, clock) { - dor_reset = 0x0c; + has_dor = false; } i8272a_device::i8272a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : upd765_family_device(mconfig, I8272A, tag, owner, clock) { - dor_reset = 0x0c; + has_dor = false; } upd72065_device::upd72065_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : upd72065_device(mconfig, UPD72065, tag, owner, clock) @@ -2691,7 +2717,7 @@ upd72065_device::upd72065_device(const machine_config &mconfig, const char *tag, upd72065_device::upd72065_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : upd765_family_device(mconfig, type, tag, owner, clock) { - dor_reset = 0x0c; + has_dor = false; recalibrate_steps = 255; } @@ -2713,7 +2739,7 @@ upd72069_device::upd72069_device(const machine_config &mconfig, const char *tag, i82072_device::i82072_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : upd765_family_device(mconfig, I82072, tag, owner, clock) { - dor_reset = 0x0c; + has_dor = false; recalibrate_steps = 255; } @@ -3089,7 +3115,7 @@ mcs3201_device::mcs3201_device(const machine_config &mconfig, const char *tag, d upd765_family_device(mconfig, MCS3201, tag, owner, clock), m_input_handler(*this) { - dor_reset = 0x0c; + has_dor = true; ready_polled = false; ready_connected = false; select_connected = true; diff --git a/src/devices/machine/upd765.h b/src/devices/machine/upd765.h index 0c81f5aaa77..0ba8aa6d1c7 100644 --- a/src/devices/machine/upd765.h +++ b/src/devices/machine/upd765.h @@ -49,6 +49,7 @@ public: void ready_w(bool val); DECLARE_WRITE_LINE_MEMBER(tc_line_w) { tc_w(state == ASSERT_LINE); } + DECLARE_WRITE_LINE_MEMBER(reset_w); void set_rate(int rate); // rate in bps, to be used when the fdc is externally frequency-controlled @@ -231,7 +232,7 @@ protected: static constexpr int rates[4] = { 500000, 300000, 250000, 1000000 }; - bool ready_connected, ready_polled, select_connected, select_multiplexed; + bool ready_connected, ready_polled, select_connected, select_multiplexed, has_dor; bool external_ready; @@ -250,7 +251,7 @@ protected: bool fifo_write; uint8_t dor, dsr, msr, fifo[16], command[16], result[16]; uint8_t st1, st2, st3; - uint8_t fifocfg, dor_reset; + uint8_t fifocfg; uint8_t precomp; uint16_t spec; int sector_size; @@ -259,7 +260,6 @@ protected: emu_timer *poll_timer; - static std::string tts(attotime t); std::string results() const; std::string ttsn() const; @@ -288,6 +288,8 @@ protected: C_INCOMPLETE }; + void end_reset(); + void delay_cycles(emu_timer *tm, int cycles); void check_irq(); void fifo_expect(int size, bool write); diff --git a/src/devices/machine/wd1010.cpp b/src/devices/machine/wd1010.cpp index 96fb4b5fdd0..a330d6c7671 100644 --- a/src/devices/machine/wd1010.cpp +++ b/src/devices/machine/wd1010.cpp @@ -16,7 +16,7 @@ #define LOG_REGS (1U << 4) #define LOG_DATA (1U << 5) -//#define VERBOSE (LOG_CMD | LOG_INT | LOG_SEEK | LOG_REGS | LOG_DATA) +#define VERBOSE (LOG_CMD | LOG_INT | LOG_SEEK | LOG_REGS | LOG_DATA) //#define LOG_OUTPUT_STREAM std::cout #include "logmacro.h" @@ -46,7 +46,11 @@ DEFINE_DEVICE_TYPE(WD1010, wd1010_device, "wd1010", "Western Digital WD1010-05") wd1010_device::wd1010_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, WD1010, tag, owner, clock), m_out_intrq_cb(*this), + m_out_bdrq_cb(*this), + m_out_bcs_cb(*this), m_out_bcr_cb(*this), + m_out_dirin_cb(*this), + m_out_wg_cb(*this), m_in_data_cb(*this), m_out_data_cb(*this), m_intrq(0), @@ -83,13 +87,18 @@ void wd1010_device::device_start() // resolve callbacks m_out_intrq_cb.resolve_safe(); + m_out_bdrq_cb.resolve_safe(); + m_out_bcs_cb.resolve_safe(); m_out_bcr_cb.resolve_safe(); + m_out_dirin_cb.resolve_safe(); + m_out_wg_cb.resolve_safe(); m_in_data_cb.resolve_safe(0); m_out_data_cb.resolve_safe(); // allocate timer m_seek_timer = timer_alloc(TIMER_SEEK); - m_data_timer = timer_alloc(TIMER_DATA); + m_read_timer = timer_alloc(TIMER_READ); + m_write_timer = timer_alloc(TIMER_WRITE); // register for save states save_item(NAME(m_intrq)); @@ -156,14 +165,12 @@ void wd1010_device::device_timer(emu_timer &timer, device_timer_id tid, int para break; - case TIMER_DATA: - - // check if data is ready or continue waiting - if (m_brdy) - cmd_write_sector(); - else - m_data_timer->adjust(attotime::from_usec(35)); + case TIMER_READ: + cmd_read_sector(); + break; + case TIMER_WRITE: + cmd_write_sector(); break; } } @@ -207,6 +214,26 @@ void wd1010_device::set_intrq(int state) } //------------------------------------------------- +// set_bdrq - set drq status +//------------------------------------------------- + +void wd1010_device::set_bdrq(int state) +{ + if ((!(m_status & STATUS_DRQ)) && state == 1) + { + LOGINT("DRQ 1\n"); + m_status |= STATUS_DRQ; + m_out_bdrq_cb(1); + } + else if ((m_status & STATUS_DRQ) && state == 0) + { + LOGINT("DRQ 0\n"); + m_status &= ~STATUS_DRQ; + m_out_bdrq_cb(0); + } +} + +//------------------------------------------------- // get_stepping_rate - calculate stepping rate //------------------------------------------------- @@ -305,6 +332,16 @@ void wd1010_device::brdy_w(int state) m_brdy = state; } +int wd1010_device::sc_r() +{ + return m_status & STATUS_SC ? 1 : 0; +} + +int wd1010_device::tk000_r() +{ + return m_drives[drive()].cylinder == 0 ? 1 : 0; +} + uint8_t wd1010_device::read(offs_t offset) { // if the controller is busy all reads return the status register @@ -423,13 +460,13 @@ void wd1010_device::write(offs_t offset, uint8_t data) if ((m_command >> 4) != CMD_SCAN_ID) m_status &= ~STATUS_SC; - int amount = 0; + int seek = 0; int target = 0; switch (m_command >> 4) { case CMD_RESTORE: - amount = m_drives[drive()].cylinder; + seek = m_drives[drive()].cylinder; target = 0; break; @@ -437,15 +474,17 @@ void wd1010_device::write(offs_t offset, uint8_t data) case CMD_READ_SECTOR: case CMD_WRITE_SECTOR: case CMD_WRITE_FORMAT: - amount = abs(m_drives[drive()].cylinder - m_cylinder); + seek = m_drives[drive()].cylinder - m_cylinder; target = m_cylinder; break; } + m_out_dirin_cb(seek > 0 ? 1 : 0); + if ((m_command >> 4) != CMD_SCAN_ID) - LOGSEEK("Seeking %d cylinders to %d\n", amount, target); + LOGSEEK("Seeking %d cylinders to %d\n", seek, target); - m_seek_timer->adjust(get_stepping_rate() * amount, target); + m_seek_timer->adjust(get_stepping_rate() * abs(seek), target); } break; @@ -465,12 +504,30 @@ void wd1010_device::cmd_restore() void wd1010_device::cmd_read_sector() { + if (m_status & STATUS_DRQ) + { + if (m_brdy) + { + set_bdrq(0); + + // if there's nothing left we're done + if (m_sector_count == 0) + { + end_command(); + return; + } + } + else + { + // continue waiting for the buffer to be ready + m_read_timer->adjust(attotime::from_usec(35)); + return; + } + } + hard_disk_file *file = m_drives[drive()].drive->get_hard_disk_file(); hard_disk_info *info = hard_disk_get_info(file); - m_out_bcr_cb(1); - m_out_bcr_cb(0); - // verify that we can read if (head() > info->heads) { @@ -479,91 +536,112 @@ void wd1010_device::cmd_read_sector() set_error(ERR_AC); end_command(); + return; } - else - { - uint8_t buffer[512]; - while (m_sector_count > 0) - { - LOGDATA("--> Transferring sector to buffer (lba = %08x)\n", get_lbasector()); + uint8_t buffer[512]; - hard_disk_read(file, get_lbasector(), buffer); + m_out_bcr_cb(1); + m_out_bcr_cb(0); - for (int i = 0; i < 512; i++) - m_out_data_cb(buffer[i]); + m_out_bcs_cb(1); - m_out_bcr_cb(1); - m_out_bcr_cb(0); + LOGDATA("--> Transferring sector to buffer (lba = %08x)\n", get_lbasector()); - // save last read head and sector number - m_drives[drive()].head = head(); - m_drives[drive()].sector = m_sector_number; + hard_disk_read(file, get_lbasector(), buffer); - if (BIT(m_command, 2)) - { - m_sector_number++; - m_sector_count--; - } - else - break; - } + for (int i = 0; i < 512; i++) + m_out_data_cb(buffer[i]); - end_command(); + // multi-sector read + if (BIT(m_command, 2)) + { + m_sector_number++; + m_sector_count--; + } + else + { + m_sector_count = 0; } + + if (m_sector_count == 0) + { + m_out_bcr_cb(1); + m_out_bcr_cb(0); + } + + m_out_bcs_cb(0); + + set_bdrq(1); + + // interrupt at bdrq time? + if (BIT(m_command, 3) == 0) + set_intrq(1); + + // now wait for brdy + m_read_timer->adjust(attotime::from_usec(35)); } void wd1010_device::cmd_write_sector() { - if (!(m_status & STATUS_DRQ)) - { - LOGDATA("Setting DATA REQUEST\n"); - m_status |= STATUS_DRQ; - m_data_timer->adjust(attotime::from_usec(35)); - return; - } + set_bdrq(1); + // wait if the buffer isn't ready if (m_brdy == 0) { - m_data_timer->adjust(attotime::from_usec(35)); + m_write_timer->adjust(attotime::from_usec(35)); return; } - LOGDATA("Clearing DATA REQUEST\n"); - m_status &= ~STATUS_DRQ; - hard_disk_file *file = m_drives[drive()].drive->get_hard_disk_file(); uint8_t buffer[512]; - while (m_sector_count > 0) + set_bdrq(0); + + m_out_bcr_cb(1); + m_out_bcr_cb(0); + + m_out_bcs_cb(1); + + m_out_wg_cb(1); + + if ((m_command >> 4) == CMD_WRITE_FORMAT) { - if ((m_command >> 4) == CMD_WRITE_FORMAT) - { - // we ignore the format specification and fill everything with 0xe5 - std::fill(std::begin(buffer), std::end(buffer), 0xe5); - } - else - { - // get data for sector from buffer chip - for (int i = 0; i < 512; i++) - buffer[i] = m_in_data_cb(); - } + // we ignore the format specification and fill everything with 0xe5 + std::fill(std::begin(buffer), std::end(buffer), 0xe5); + } + else + { + // get data for sector from buffer chip + for (int i = 0; i < 512; i++) + buffer[i] = m_in_data_cb(); + } - hard_disk_write(file, get_lbasector(), buffer); + hard_disk_write(file, get_lbasector(), buffer); - // save last read head and sector number - m_drives[drive()].head = head(); - m_drives[drive()].sector = m_sector_number; + // save last read head and sector number + m_drives[drive()].head = head(); + m_drives[drive()].sector = m_sector_number; - if (BIT(m_command, 2)) + // multi-sector write + if (BIT(m_command, 2) && m_sector_count > 0) + { + m_sector_number++; + m_sector_count--; + + // schedule another run if we aren't finished yet + if (m_sector_count > 0) { - m_sector_number++; - m_sector_count--; + m_out_bcs_cb(0); + m_out_wg_cb(0); + m_write_timer->adjust(attotime::from_usec(35)); + return; } - else - break; } + m_out_bcs_cb(0); + m_out_wg_cb(0); + end_command(); } diff --git a/src/devices/machine/wd1010.h b/src/devices/machine/wd1010.h index b6a637c99e9..268ab3a63ca 100644 --- a/src/devices/machine/wd1010.h +++ b/src/devices/machine/wd1010.h @@ -27,7 +27,11 @@ public: wd1010_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); auto out_intrq_callback() { return m_out_intrq_cb.bind(); } + auto out_bdrq_callback() { return m_out_bdrq_cb.bind(); } + auto out_bcs_callback() { return m_out_bcs_cb.bind(); } auto out_bcr_callback() { return m_out_bcr_cb.bind(); } + auto out_dirin_callback() { return m_out_dirin_cb.bind(); } + auto out_wg_callback() { return m_out_wg_cb.bind(); } auto in_data_callback() { return m_in_data_cb.bind(); } auto out_data_callback() { return m_out_data_cb.bind(); } @@ -37,6 +41,10 @@ public: void drdy_w(int state); void brdy_w(int state); + // actually inputs to the controller from the drive + int sc_r(); + int tk000_r(); + protected: // device-level overrides virtual void device_start() override; @@ -81,11 +89,13 @@ private: enum { TIMER_SEEK, - TIMER_DATA + TIMER_READ, + TIMER_WRITE }; void set_error(int error); void set_intrq(int state); + void set_bdrq(int state); attotime get_stepping_rate(); void start_command(); void end_command(); @@ -107,7 +117,11 @@ private: void cmd_seek(); devcb_write_line m_out_intrq_cb; + devcb_write_line m_out_bdrq_cb; + devcb_write_line m_out_bcs_cb; devcb_write_line m_out_bcr_cb; + devcb_write_line m_out_dirin_cb; + devcb_write_line m_out_wg_cb; devcb_read8 m_in_data_cb; devcb_write8 m_out_data_cb; @@ -120,9 +134,11 @@ private: } m_drives[4]; emu_timer *m_seek_timer; - emu_timer *m_data_timer; + emu_timer *m_read_timer; + emu_timer *m_write_timer; int m_intrq; + //int m_bdrq; int m_brdy; uint8_t m_stepping_rate; uint8_t m_command; diff --git a/src/devices/machine/z80scc.cpp b/src/devices/machine/z80scc.cpp index 0259fb5d0b0..e3a7c8a1d00 100644 --- a/src/devices/machine/z80scc.cpp +++ b/src/devices/machine/z80scc.cpp @@ -724,6 +724,7 @@ uint8_t z80scc_device::modify_vector(uint8_t vec, int i, uint8_t src) // Modify vector according to Hi/lo bit of WR9 if (m_wr9 & WR9_BIT_SHSL) // Affect V4-V6 { + src = bitswap<4>(src, 3, 0, 1, 2); // order switched (see table above) vec &= 0x8f; vec |= src << 4; } diff --git a/src/devices/sound/2203intf.cpp b/src/devices/sound/2203intf.cpp index 6b579f486a3..3a1a31d26a2 100644 --- a/src/devices/sound/2203intf.cpp +++ b/src/devices/sound/2203intf.cpp @@ -54,13 +54,12 @@ void ym2203_device::timer_handler(int c, int count, int clock) } //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// stream_generate - handle a stream update //------------------------------------------------- - -void ym2203_device::stream_generate(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void ym2203_device::stream_generate(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - ym2203_update_one(m_chip, outputs[0], samples); + ym2203_update_one(m_chip, outputs[0]); } @@ -108,7 +107,7 @@ void ym2203_device::calculate_rates() if (m_stream != nullptr) m_stream->set_sample_rate(rate); else - m_stream = machine().sound().stream_alloc_legacy(*this,0,1,rate, stream_update_legacy_delegate(&ym2203_device::stream_generate,this)); + m_stream = machine().sound().stream_alloc(*this,0,1,rate, stream_update_delegate(&ym2203_device::stream_generate,this), STREAM_DEFAULT_FLAGS); } //------------------------------------------------- diff --git a/src/devices/sound/2203intf.h b/src/devices/sound/2203intf.h index ccb5841cd82..df10125693a 100644 --- a/src/devices/sound/2203intf.h +++ b/src/devices/sound/2203intf.h @@ -39,7 +39,7 @@ protected: virtual void device_clock_changed() override; virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; - void stream_generate(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples); + void stream_generate(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs); private: enum diff --git a/src/devices/sound/2608intf.cpp b/src/devices/sound/2608intf.cpp index 4ca366fa117..b746ae15e66 100644 --- a/src/devices/sound/2608intf.cpp +++ b/src/devices/sound/2608intf.cpp @@ -63,12 +63,12 @@ void ym2608_device::timer_handler(int c,int count,int clock) } //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// stream_generate - handle a stream update //------------------------------------------------- -void ym2608_device::stream_generate(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void ym2608_device::stream_generate(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - ym2608_update_one(m_chip, outputs, samples); + ym2608_update_one(m_chip, outputs); } void ym2608_device::device_post_load() @@ -93,7 +93,7 @@ void ym2608_device::device_start() m_timer[1] = timer_alloc(1); /* stream system initialize */ - m_stream = machine().sound().stream_alloc_legacy(*this,0,2,rate, stream_update_legacy_delegate(&ym2608_device::stream_generate,this)); + m_stream = machine().sound().stream_alloc(*this,0,2,rate, stream_update_delegate(&ym2608_device::stream_generate,this), STREAM_DEFAULT_FLAGS); /* initialize YM2608 */ m_chip = ym2608_init(this,clock(),rate, diff --git a/src/devices/sound/2608intf.h b/src/devices/sound/2608intf.h index c6a3fec6fc9..ca1361ba867 100644 --- a/src/devices/sound/2608intf.h +++ b/src/devices/sound/2608intf.h @@ -39,7 +39,7 @@ protected: virtual void rom_bank_updated() override; virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; - void stream_generate(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples); + void stream_generate(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs); private: void irq_handler(int irq); diff --git a/src/devices/sound/2610intf.cpp b/src/devices/sound/2610intf.cpp index 2f6e3e08620..b0ee9c99d32 100644 --- a/src/devices/sound/2610intf.cpp +++ b/src/devices/sound/2610intf.cpp @@ -62,20 +62,20 @@ void ym2610_device::timer_handler(int c,int count,int clock) } //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// stream_generate - handle a stream update //------------------------------------------------- -void ym2610_device::stream_generate(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void ym2610_device::stream_generate(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - ym2610_update_one(m_chip, outputs, samples); + ym2610_update_one(m_chip, outputs); } //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// stream_generate - handle a stream update //------------------------------------------------- -void ym2610b_device::stream_generate(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void ym2610b_device::stream_generate(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - ym2610b_update_one(m_chip, outputs, samples); + ym2610b_update_one(m_chip, outputs); } @@ -102,7 +102,7 @@ void ym2610_device::device_start() m_timer[1] = timer_alloc(1); /* stream system initialize */ - m_stream = machine().sound().stream_alloc_legacy(*this,0,2,rate, stream_update_legacy_delegate(&ym2610_device::stream_generate,this)); + m_stream = machine().sound().stream_alloc(*this,0,2,rate, stream_update_delegate(&ym2610_device::stream_generate,this), STREAM_DEFAULT_FLAGS); if (!has_configured_map(0) && !has_configured_map(1)) { diff --git a/src/devices/sound/2610intf.h b/src/devices/sound/2610intf.h index a305f9d352d..9125feee4d6 100644 --- a/src/devices/sound/2610intf.h +++ b/src/devices/sound/2610intf.h @@ -40,7 +40,7 @@ protected: virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; - virtual void stream_generate(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples); + virtual void stream_generate(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs); void * m_chip; @@ -75,7 +75,7 @@ public: ym2610b_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); protected: - virtual void stream_generate(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void stream_generate(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; }; diff --git a/src/devices/sound/2612intf.cpp b/src/devices/sound/2612intf.cpp index 679333cdcf3..b856ef33e65 100644 --- a/src/devices/sound/2612intf.cpp +++ b/src/devices/sound/2612intf.cpp @@ -56,12 +56,12 @@ void ym2612_device::timer_handler(int c,int count,int clock) } //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void ym2612_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void ym2612_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - ym2612_update_one(m_chip, outputs, samples, m_output_bits); + ym2612_update_one(m_chip, outputs, m_output_bits); } @@ -87,7 +87,7 @@ void ym2612_device::device_start() m_timer[1] = timer_alloc(1); /* stream system initialize */ - m_stream = stream_alloc_legacy(0,2,rate); + m_stream = stream_alloc(0,2,rate); /**** initialize YM2612 ****/ m_chip = ym2612_init(this,clock(),rate,&ym2612_device::static_timer_handler,&ym2612_device::static_irq_handler); @@ -108,7 +108,7 @@ void ym2612_device::calculate_rates() if (m_stream != nullptr) m_stream->set_sample_rate(rate); else - m_stream = stream_alloc_legacy(0,2,rate); + m_stream = stream_alloc(0,2,rate); } //------------------------------------------------- diff --git a/src/devices/sound/2612intf.h b/src/devices/sound/2612intf.h index f9447081d9b..c88b83ffef5 100644 --- a/src/devices/sound/2612intf.h +++ b/src/devices/sound/2612intf.h @@ -33,7 +33,7 @@ protected: virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; u8 m_output_bits; private: diff --git a/src/devices/sound/262intf.cpp b/src/devices/sound/262intf.cpp index 0a76cdf6d2b..616cefc6377 100644 --- a/src/devices/sound/262intf.cpp +++ b/src/devices/sound/262intf.cpp @@ -50,12 +50,12 @@ void ymf262_device::timer_handler(int c, const attotime &period) //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void ymf262_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void ymf262_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - ymf262_update_one(m_chip, outputs, samples); + ymf262_update_one(m_chip, outputs); } //------------------------------------------------- @@ -81,7 +81,7 @@ void ymf262_device::device_start() if (!m_chip) throw emu_fatalerror("ymf262_device(%s): Error creating YMF262 chip", tag()); - m_stream = stream_alloc_legacy(0,4,rate); + m_stream = stream_alloc(0,4,rate); /* YMF262 setup */ ymf262_set_timer_handler (m_chip, &ymf262_device::static_timer_handler, this); diff --git a/src/devices/sound/262intf.h b/src/devices/sound/262intf.h index 09ae497748d..6c2376fc960 100644 --- a/src/devices/sound/262intf.h +++ b/src/devices/sound/262intf.h @@ -27,7 +27,7 @@ protected: virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: void irq_handler(int irq); diff --git a/src/devices/sound/3526intf.cpp b/src/devices/sound/3526intf.cpp index dce29c78440..906c3c3fd38 100644 --- a/src/devices/sound/3526intf.cpp +++ b/src/devices/sound/3526intf.cpp @@ -60,12 +60,12 @@ void ym3526_device::timer_handler(int c,const attotime &period) //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void ym3526_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void ym3526_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - ym3526_update_one(m_chip, outputs[0], samples); + ym3526_update_one(m_chip, outputs[0]); } @@ -109,7 +109,7 @@ void ym3526_device::calculate_rates() if (m_stream != nullptr) m_stream->set_sample_rate(rate); else - m_stream = stream_alloc_legacy(0,1,rate); + m_stream = stream_alloc(0,1,rate); } //------------------------------------------------- diff --git a/src/devices/sound/3526intf.h b/src/devices/sound/3526intf.h index 5b425f41241..a45825b57b5 100644 --- a/src/devices/sound/3526intf.h +++ b/src/devices/sound/3526intf.h @@ -32,7 +32,7 @@ protected: virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: void irq_handler(int irq); diff --git a/src/devices/sound/3812intf.cpp b/src/devices/sound/3812intf.cpp index b9287f21d9e..c74c75e27b0 100644 --- a/src/devices/sound/3812intf.cpp +++ b/src/devices/sound/3812intf.cpp @@ -62,12 +62,12 @@ void ym3812_device::timer_handler(int c, const attotime &period) //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void ym3812_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void ym3812_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - ym3812_update_one(m_chip, outputs[0], samples); + ym3812_update_one(m_chip, outputs[0]); } //------------------------------------------------- @@ -110,7 +110,7 @@ void ym3812_device::calculate_rates() if (m_stream != nullptr) m_stream->set_sample_rate(rate); else - m_stream = stream_alloc_legacy(0, 1, rate); + m_stream = stream_alloc(0, 1, rate); } //------------------------------------------------- diff --git a/src/devices/sound/3812intf.h b/src/devices/sound/3812intf.h index 46266bbbca2..5b2b4f9991a 100644 --- a/src/devices/sound/3812intf.h +++ b/src/devices/sound/3812intf.h @@ -30,7 +30,7 @@ protected: virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: enum diff --git a/src/devices/sound/8950intf.cpp b/src/devices/sound/8950intf.cpp index 63056582a0e..5eed79dd138 100644 --- a/src/devices/sound/8950intf.cpp +++ b/src/devices/sound/8950intf.cpp @@ -56,12 +56,12 @@ void y8950_device::timer_handler(int c, const attotime &period) //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void y8950_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void y8950_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - y8950_update_one(m_chip, outputs[0], samples); + y8950_update_one(m_chip, outputs[0]); } @@ -87,7 +87,7 @@ void y8950_device::device_start() /* ADPCM ROM data */ y8950_set_delta_t_memory(m_chip, &y8950_device::static_read_byte, &y8950_device::static_write_byte); - m_stream = stream_alloc_legacy(0,1,rate); + m_stream = stream_alloc(0,1,rate); /* port and keyboard handler */ y8950_set_port_handler(m_chip, &y8950_device::static_port_handler_w, &y8950_device::static_port_handler_r, this); y8950_set_keyboard_handler(m_chip, &y8950_device::static_keyboard_handler_w, &y8950_device::static_keyboard_handler_r, this); diff --git a/src/devices/sound/8950intf.h b/src/devices/sound/8950intf.h index d1ba497c08d..9ed70e7cd92 100644 --- a/src/devices/sound/8950intf.h +++ b/src/devices/sound/8950intf.h @@ -41,7 +41,7 @@ protected: virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: void irq_handler(int irq); diff --git a/src/devices/sound/aica.cpp b/src/devices/sound/aica.cpp index 7bedf5d660a..21d5fa081d0 100644 --- a/src/devices/sound/aica.cpp +++ b/src/devices/sound/aica.cpp @@ -1233,7 +1233,6 @@ void aica_device::DoMasterSamples(std::vector<read_stream_view> const &inputs, w { int i; - constexpr stream_buffer::sample_t sample_scale = 1.0 / stream_buffer::sample_t(32768 << SHIFT); for (int s = 0; s < bufl.samples(); ++s) { s32 smpl = 0, smpr = 0; @@ -1293,8 +1292,8 @@ void aica_device::DoMasterSamples(std::vector<read_stream_view> const &inputs, w smpr = clip16(smpr >> 3); } - bufl.put(s, stream_buffer::sample_t(smpl * m_LPANTABLE[MVOL() << 0xd]) * sample_scale); - bufr.put(s, stream_buffer::sample_t(smpr * m_LPANTABLE[MVOL() << 0xd]) * sample_scale); + bufl.put_int(s, smpl * m_LPANTABLE[MVOL() << 0xd], 32768 << SHIFT); + bufr.put_int(s, smpr * m_LPANTABLE[MVOL() << 0xd], 32768 << SHIFT); } } diff --git a/src/devices/sound/asc.cpp b/src/devices/sound/asc.cpp index e03494040ab..23ec35a2766 100644 --- a/src/devices/sound/asc.cpp +++ b/src/devices/sound/asc.cpp @@ -148,7 +148,6 @@ void asc_device::sound_stream_update(sound_stream &stream, std::vector<read_stre case 1: // FIFO mode { - constexpr stream_buffer::sample_t sample_scale = 64.0 / 32768.0; for (i = 0; i < outL.samples(); i++) { int8_t smpll, smplr; @@ -234,15 +233,14 @@ void asc_device::sound_stream_update(sound_stream &stream, std::vector<read_stre break; } - outL.put(i, stream_buffer::sample_t(smpll) * sample_scale); - outR.put(i, stream_buffer::sample_t(smplr) * sample_scale); + outL.put_int(i, smpll, 32768 / 64); + outR.put_int(i, smplr, 32768 / 64); } break; } case 2: // wavetable mode { - constexpr stream_buffer::sample_t sample_scale = 1.0 / (32768.0 * 4.0); for (i = 0; i < outL.samples(); i++) { int32_t mixL, mixR; @@ -269,8 +267,8 @@ void asc_device::sound_stream_update(sound_stream &stream, std::vector<read_stre mixR += smpl*256; } - outL.put(i, stream_buffer::sample_t(mixL) * sample_scale); - outR.put(i, stream_buffer::sample_t(mixR) * sample_scale); + outL.put_int(i, mixL, 32768 * 4); + outR.put_int(i, mixR, 32768 * 4); } break; } diff --git a/src/devices/sound/astrocde.cpp b/src/devices/sound/astrocde.cpp index 17df6999989..91d0fdc46b9 100644 --- a/src/devices/sound/astrocde.cpp +++ b/src/devices/sound/astrocde.cpp @@ -126,7 +126,7 @@ void astrocade_io_device::device_start() //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- void astrocade_io_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) @@ -146,7 +146,7 @@ void astrocade_io_device::sound_stream_update(sound_stream &stream, std::vector< constexpr stream_buffer::sample_t sample_scale = 1.0f / 60.0f; for (int sampindex = 0; sampindex < dest.samples(); sampindex += samples_this_time) { - stream_sample_t cursample = 0; + s32 cursample = 0; /* compute the number of cycles until the next master oscillator reset */ /* or until the next noise boundary */ diff --git a/src/devices/sound/awacs.cpp b/src/devices/sound/awacs.cpp index 19f734cd468..72cf31d7589 100644 --- a/src/devices/sound/awacs.cpp +++ b/src/devices/sound/awacs.cpp @@ -93,13 +93,12 @@ void awacs_device::sound_stream_update(sound_stream &stream, std::vector<read_st auto &outL = outputs[0]; auto &outR = outputs[1]; - constexpr stream_buffer::sample_t sample_scale = 1.0 / 32768.0; if (m_playback_enable) { for (int i = 0; i < outL.samples(); i++) { - outL.put(i, stream_buffer::sample_t(s16(m_dma_space->read_word(offset + m_play_ptr))) * sample_scale); - outR.put(i, stream_buffer::sample_t(s16(m_dma_space->read_word(offset + m_play_ptr + 2))) * sample_scale); + outL.put_int(i, s16(m_dma_space->read_word(offset + m_play_ptr)), 32768); + outR.put_int(i, s16(m_dma_space->read_word(offset + m_play_ptr + 2)), 32768); m_play_ptr += 4; } diff --git a/src/devices/sound/ay8910.cpp b/src/devices/sound/ay8910.cpp index 26e99cf1bc7..8ba53fb8b3f 100644 --- a/src/devices/sound/ay8910.cpp +++ b/src/devices/sound/ay8910.cpp @@ -1108,12 +1108,13 @@ void ay8910_device::sound_stream_update(sound_stream &stream, std::vector<read_s for (int chan = 0; chan < NUM_CHANNELS; chan++) { tone = &m_tone[chan]; - tone->count++; - if (tone->count >= tone->period) + const int period = std::max<int>(1,tone->period); + tone->count += is_expanded_mode() ? 16 : 1; + while (tone->count >= period) { tone->duty_cycle = (tone->duty_cycle - 1) & 0x1f; - tone->output = (m_feature & PSG_HAS_EXPANDED_MODE) ? BIT(duty_cycle[tone_duty(tone)], tone->duty_cycle) : BIT(tone->duty_cycle, 0); - tone->count = 0; + tone->output = is_expanded_mode() ? BIT(duty_cycle[tone_duty(tone)], tone->duty_cycle) : BIT(tone->duty_cycle, 0); + tone->count -= period; } } @@ -1124,8 +1125,9 @@ void ay8910_device::sound_stream_update(sound_stream &stream, std::vector<read_s * channels. */ m_count_noise = 0; + m_prescale_noise ^= 1; - if (!m_prescale_noise) + if (!m_prescale_noise || is_expanded_mode()) // AY8930 noise generator rate is twice compares as compatibility mode { /* The Random Number Generator of the 8910 is a 17-bit shift */ /* register. The input to the shift register is bit0 XOR bit3 */ @@ -1134,9 +1136,7 @@ void ay8910_device::sound_stream_update(sound_stream &stream, std::vector<read_s // TODO : get actually algorithm for AY8930 m_rng ^= (((m_rng & 1) ^ ((m_rng >> 3) & 1)) << 17); m_rng >>= 1; - m_prescale_noise = (m_feature & PSG_HAS_EXPANDED_MODE) ? 16 : 1; } - m_prescale_noise--; } for (int chan = 0; chan < NUM_CHANNELS; chan++) @@ -1336,7 +1336,7 @@ void ay8910_device::device_start() /* The envelope is pacing twice as fast for the YM2149 as for the AY-3-8910, */ /* This handled by the step parameter. Consequently we use a multipler of 2 here. */ - m_channel = stream_alloc(0, m_streams, (m_feature & PSG_HAS_EXPANDED_MODE) ? master_clock * 2 : master_clock / 8); + m_channel = stream_alloc(0, m_streams, master_clock / 8); ay_set_clock(master_clock); ay8910_statesave(); @@ -1389,9 +1389,9 @@ void ay8910_device::ay_set_clock(int clock) { // FIXME: this doesn't belong here, it should be an input pin exposed via devcb if (((m_feature & PSG_PIN26_IS_CLKSEL) && (m_flags & YM2149_PIN26_LOW)) || (m_feature & PSG_HAS_INTERNAL_DIVIDER)) - m_channel->set_sample_rate((m_feature & PSG_HAS_EXPANDED_MODE) ? clock : clock / 16); + m_channel->set_sample_rate(clock / 16); else - m_channel->set_sample_rate((m_feature & PSG_HAS_EXPANDED_MODE) ? clock * 2 : clock / 8); + m_channel->set_sample_rate(clock / 8); } void ay8910_device::device_clock_changed() @@ -1659,8 +1659,6 @@ void ay8910_device::set_type(psg_type_t psg_type) m_par = &ym2149_param; m_par_env = &ym2149_param_env; } - if (m_feature & PSG_HAS_EXPANDED_MODE) - m_step *= 16; } DEFINE_DEVICE_TYPE(AY8912, ay8912_device, "ay8912", "AY-3-8912A PSG") diff --git a/src/devices/sound/ay8910.h b/src/devices/sound/ay8910.h index 373a850b662..407de93f8a3 100644 --- a/src/devices/sound/ay8910.h +++ b/src/devices/sound/ay8910.h @@ -268,7 +268,7 @@ private: inline u8 get_envelope_chan(int chan) { return is_expanded_mode() ? chan : 0; } inline bool noise_enable(int chan) { return BIT(m_regs[AY_ENABLE], 3 + chan); } - inline u8 noise_period() { return is_expanded_mode() ? m_regs[AY_NOISEPER] & 0xff : (m_regs[AY_NOISEPER] & 0x1f) << 1; } + inline u8 noise_period() { return is_expanded_mode() ? m_regs[AY_NOISEPER] & 0xff : m_regs[AY_NOISEPER] & 0x1f; } inline u8 noise_output() { return m_rng & 1; } inline bool is_expanded_mode() { return ((m_feature & PSG_HAS_EXPANDED_MODE) && ((m_mode & 0xe) == 0xa)); } diff --git a/src/devices/sound/c140.cpp b/src/devices/sound/c140.cpp index 0edb1920a8c..5d0b0811854 100644 --- a/src/devices/sound/c140.cpp +++ b/src/devices/sound/c140.cpp @@ -77,12 +77,6 @@ DEFINE_DEVICE_TYPE(C219, c219_device, "c219", "Namco C219") // LIVE DEVICE //************************************************************************** -static inline stream_buffer::sample_t limit(stream_buffer::sample_t in) -{ - return std::max(-1.0f, std::min(1.0f, in)); -} - - //------------------------------------------------- // c140_device - constructor //------------------------------------------------- @@ -326,15 +320,10 @@ void c140_device::sound_stream_update(sound_stream &stream, std::vector<read_str { auto &dest1 = outputs[0]; auto &dest2 = outputs[1]; - constexpr stream_buffer::sample_t sample_scale = 8.0 / 32768.0; for (int i = 0; i < samples; i++) { - stream_buffer::sample_t val; - - val = stream_buffer::sample_t(*lmix++) * sample_scale; - dest1.put(i, limit(val)); - val = stream_buffer::sample_t(*rmix++) * sample_scale; - dest2.put(i, limit(val)); + dest1.put_int_clamp(i, *lmix++, 32768 / 8); + dest2.put_int_clamp(i, *rmix++, 32768 / 8); } } } @@ -465,15 +454,10 @@ void c219_device::sound_stream_update(sound_stream &stream, std::vector<read_str { auto &dest1 = outputs[0]; auto &dest2 = outputs[1]; - constexpr stream_buffer::sample_t sample_scale = 8.0 / 32768.0; for (int i = 0; i < samples; i++) { - stream_buffer::sample_t val; - - val = stream_buffer::sample_t(*lmix++) * sample_scale; - dest1.put(i, limit(val)); - val = stream_buffer::sample_t(*rmix++) * sample_scale; - dest2.put(i, limit(val)); + dest1.put_int_clamp(i, *lmix++, 32768 / 8); + dest2.put_int_clamp(i, *rmix++, 32768 / 8); } } } diff --git a/src/devices/sound/c352.cpp b/src/devices/sound/c352.cpp index 826f194437a..bea5a561b59 100644 --- a/src/devices/sound/c352.cpp +++ b/src/devices/sound/c352.cpp @@ -129,7 +129,6 @@ void c352_device::sound_stream_update(sound_stream &stream, std::vector<read_str auto &buffer_rl = outputs[2]; auto &buffer_rr = outputs[3]; - constexpr stream_buffer::sample_t sample_scale = 1.0 / 32768.0; for (int i = 0; i < buffer_fl.samples(); i++) { int out[4] = { 0, 0, 0, 0 }; @@ -174,10 +173,10 @@ void c352_device::sound_stream_update(sound_stream &stream, std::vector<read_str out[3] += (((v.flags & C352_FLG_PHASEFR) ? -s : s) * v.curr_vol[3]) >> 8; } - buffer_fl.put(i, stream_buffer::sample_t(s16(out[0] >> 3)) * sample_scale); - buffer_fr.put(i, stream_buffer::sample_t(s16(out[1] >> 3)) * sample_scale); - buffer_rl.put(i, stream_buffer::sample_t(s16(out[2] >> 3)) * sample_scale); - buffer_rr.put(i, stream_buffer::sample_t(s16(out[3] >> 3)) * sample_scale); + buffer_fl.put_int(i, s16(out[0] >> 3), 32768); + buffer_fr.put_int(i, s16(out[1] >> 3), 32768); + buffer_rl.put_int(i, s16(out[2] >> 3), 32768); + buffer_rr.put_int(i, s16(out[3] >> 3), 32768); } } diff --git a/src/devices/sound/c6280.cpp b/src/devices/sound/c6280.cpp index d01dd74125a..1b6666455c9 100644 --- a/src/devices/sound/c6280.cpp +++ b/src/devices/sound/c6280.cpp @@ -51,7 +51,6 @@ void c6280_device::sound_stream_update(sound_stream &stream, std::vector<read_st outputs[0].fill(0); outputs[1].fill(0); - constexpr stream_buffer::sample_t sample_scale = 1.0 / 32768.0; for (int ch = 0; ch < 6; ch++) { channel *chan = &m_channel[ch]; @@ -88,8 +87,8 @@ void c6280_device::sound_stream_update(sound_stream &stream, std::vector<read_st // based on Charles MacDonald's research chan->noise_seed = (seed >> 1) | ((BIT(seed, 0) ^ BIT(seed, 1) ^ BIT(seed, 11) ^ BIT(seed, 12) ^ BIT(seed, 17)) << 17); } - outputs[0].add(i, stream_buffer::sample_t(s16(vll * (data - 16))) * sample_scale); - outputs[1].add(i, stream_buffer::sample_t(s16(vlr * (data - 16))) * sample_scale); + outputs[0].add_int(i, s16(vll * (data - 16)), 32768); + outputs[1].add_int(i, s16(vlr * (data - 16)), 32768); } } else @@ -98,8 +97,8 @@ void c6280_device::sound_stream_update(sound_stream &stream, std::vector<read_st /* DDA mode */ for (int i = 0; i < outputs[0].samples(); i++) { - outputs[0].add(i, stream_buffer::sample_t(s16(vll * (chan->dda - 16))) * sample_scale); - outputs[1].add(i, stream_buffer::sample_t(s16(vlr * (chan->dda - 16))) * sample_scale); + outputs[0].add_int(i, s16(vll * (chan->dda - 16)), 32768); + outputs[1].add_int(i, s16(vlr * (chan->dda - 16)), 32768); } } else @@ -138,8 +137,8 @@ void c6280_device::sound_stream_update(sound_stream &stream, std::vector<read_st lfo_dstchan->tick = step; lfo_dstchan->index = (lfo_dstchan->index + 1) & 0x1f; } - outputs[0].add(i, stream_buffer::sample_t(s16(vll * (data - 16))) * sample_scale); - outputs[1].add(i, stream_buffer::sample_t(s16(vlr * (data - 16))) * sample_scale); + outputs[0].add_int(i, s16(vll * (data - 16)), 32768); + outputs[1].add_int(i, s16(vlr * (data - 16)), 32768); } } } @@ -156,8 +155,8 @@ void c6280_device::sound_stream_update(sound_stream &stream, std::vector<read_st chan->tick = step; chan->index = (chan->index + 1) & 0x1f; } - outputs[0].add(i, stream_buffer::sample_t(s16(vll * (data - 16))) * sample_scale); - outputs[1].add(i, stream_buffer::sample_t(s16(vlr * (data - 16))) * sample_scale); + outputs[0].add_int(i, s16(vll * (data - 16)), 32768); + outputs[1].add_int(i, s16(vlr * (data - 16)), 32768); } } } diff --git a/src/devices/sound/cdda.cpp b/src/devices/sound/cdda.cpp index ca2bd280de8..e208847510e 100644 --- a/src/devices/sound/cdda.cpp +++ b/src/devices/sound/cdda.cpp @@ -164,7 +164,6 @@ void cdda_device::get_audio_data(write_stream_view &bufL, write_stream_view &buf int i; int16_t *audio_cache = (int16_t *) m_audio_cache.get(); - constexpr stream_buffer::sample_t sample_scale = 1.0 / 32768.0; for (int sampindex = 0; sampindex < bufL.samples(); ) { /* if no file, audio not playing, audio paused, or out of disc data, @@ -191,8 +190,8 @@ void cdda_device::get_audio_data(write_stream_view &bufL, write_stream_view &buf for (i = 0; i < samples; i++) { /* CD-DA data on the disc is big-endian */ - bufL.put(sampindex + i, stream_buffer::sample_t(s16(big_endianize_int16( audio_cache[ m_audio_bptr ] ))) * sample_scale); m_audio_bptr++; - bufR.put(sampindex + i, stream_buffer::sample_t(s16(big_endianize_int16( audio_cache[ m_audio_bptr ] ))) * sample_scale); m_audio_bptr++; + bufL.put_int(sampindex + i, s16(big_endianize_int16( audio_cache[ m_audio_bptr ] )), 32768); m_audio_bptr++; + bufR.put_int(sampindex + i, s16(big_endianize_int16( audio_cache[ m_audio_bptr ] )), 32768); m_audio_bptr++; } sampindex += samples; diff --git a/src/devices/sound/cdp1864.cpp b/src/devices/sound/cdp1864.cpp index e8168004811..f4a46748593 100644 --- a/src/devices/sound/cdp1864.cpp +++ b/src/devices/sound/cdp1864.cpp @@ -375,7 +375,7 @@ void cdp1864_device::dma_w(uint8_t data) color = (gdata << 2) | (bdata << 1) | rdata; } - m_bitmap.pix32(y, sx + x) = m_palette[color]; + m_bitmap.pix(y, sx + x) = m_palette[color]; data <<= 1; } diff --git a/src/devices/sound/cdp1869.cpp b/src/devices/sound/cdp1869.cpp index 98580d7ae54..9e28aa4c048 100644 --- a/src/devices/sound/cdp1869.cpp +++ b/src/devices/sound/cdp1869.cpp @@ -574,29 +574,28 @@ void cdp1869_device::sound_stream_update(sound_stream &stream, std::vector<read_ void cdp1869_device::draw_line(bitmap_rgb32 &bitmap, const rectangle &rect, int x, int y, uint8_t data, int color) { - int i; - pen_t fg = m_palette->pen(color); + pen_t const fg = m_palette->pen(color); data <<= 2; - for (i = 0; i < CH_WIDTH; i++) + for (int i = 0; i < CH_WIDTH; i++) { if (data & 0x80) { - bitmap.pix32(y, x) = fg; + bitmap.pix(y, x) = fg; if (!m_fresvert) { - bitmap.pix32(y + 1, x) = fg; + bitmap.pix(y + 1, x) = fg; } if (!m_freshorz) { - bitmap.pix32(y, x + 1) = fg; + bitmap.pix(y, x + 1) = fg; if (!m_fresvert) { - bitmap.pix32(y + 1, x + 1) = fg; + bitmap.pix(y + 1, x + 1) = fg; } } } diff --git a/src/devices/sound/cem3394.cpp b/src/devices/sound/cem3394.cpp index 5b288d2d700..e0c74635648 100644 --- a/src/devices/sound/cem3394.cpp +++ b/src/devices/sound/cem3394.cpp @@ -4,12 +4,7 @@ Curtis Electromusic Specialties CEM3394 µP-Controllable Synthesizer Voice - This driver handles CEM-3394 analog synth chip. Very crudely. - - Still to do: - - adjust the overall volume when multiple waves are being generated - - filter internal sound - - support resonance (don't understand how it works) + This driver handles CEM-3394 analog synth chip. ***************************************************************************/ @@ -19,6 +14,18 @@ #include <algorithm> +// various filter implementations to play with; currently SVTRAP works best +#define FILTER_TYPE_NONE (0) +#define FILTER_TYPE_SVTRAP (1) +#define FILTER_TYPE_ESQ1 (2) + +#define FILTER_TYPE FILTER_TYPE_SVTRAP + + +// logging +#define LOG_CONTROL_CHANGES (0) + + // use 0.25 as the base volume for pulses static constexpr double PULSE_VOLUME = 0.25; @@ -143,37 +150,96 @@ cem3394_device::cem3394_device(const machine_config &mconfig, const char *tag, d m_pulse_width(0), m_inv_sample_rate(1.0/48000.0) { + (void)m_filter_in; } //------------------------------------------------- -// sound_stream_update - generate sound to the mix -// buffer in mono +// filter - apply the lowpass filter at the given +// cutoff frequency //------------------------------------------------- +#if (FILTER_TYPE == FILTER_TYPE_NONE) + +double cem3394_device::filter(double input, double cutoff) +{ + return input; +} + +#elif (FILTER_TYPE == FILTER_TYPE_SVTRAP) + +double cem3394_device::filter(double input, double cutoff) +{ + // clamp cutoff to useful range, 50Hz-20kHz + cutoff = std::min(std::max(cutoff, 50.0), 20000.0); + + // clamp resonance to below 1.0 to prevent runaway behavior; when clamping, + // also apply an (arbitrary) scale factor to the output since we're close + // to resonance and the datasheet indicates there is an amplitude correction + // in this case + double outscale = 1.0; + double res = m_filter_resonance; + if (res > 0.99) + res = 0.99, outscale = 0.5; + + // core filter implementation + double g = tan(M_PI * cutoff * m_inv_sample_rate); + double k = 2.0 - 2.0 * res; + double a1 = 1.0 / (1.0 + g * (g + k)); + double a2 = g * a1; + double a3 = g * a2; + double v3 = input - m_filter_out[1]; + double v1 = a1 * m_filter_out[0] + a2 * v3; + double v2 = m_filter_out[1] + a2 * m_filter_out[0] + a3 * v3; + m_filter_out[0] = 2 * v1 - m_filter_out[0]; + m_filter_out[1] = 2 * v2 - m_filter_out[1]; + + // lowpass output is equal to v2 + double output = v2 * outscale; + + // catch any NaNs + if (std::isnan(output)) + { + logerror("NAN - vco: %6.0f cutoff: %6.0f res: %.5f output: %.5f\n", m_vco_step / m_inv_sample_rate, cutoff, m_filter_resonance, output); + output = 0; + m_filter_out[0] = m_filter_out[1] = 0; + } + + // if we go out of range, scale down to 1.0 and also scale our + // feedback terms to help us stay in control + else if (fabs(output) > 1.0) + { + double scale = 1.0 / fabs(output); + output *= scale; + m_filter_out[0] *= scale; + m_filter_out[1] *= scale; + } + return output; +} + +#elif (FILTER_TYPE == FILTER_TYPE_ESQ1) + double cem3394_device::filter(double input, double cutoff) { - // clamp cutoff to useful range, 20Hz-20kHz - cutoff = std::max(std::min(cutoff, 20000.0), 20.0); + // clamp cutoff to useful range, 50Hz-20kHz + cutoff = std::min(std::max(cutoff, 50.0), 20000.0); // clamp resonance to 0.95 to prevent infinite gain - double r = 4.0 * std::min(m_filter_resonance, 0.95); + double r = 4.0 * std::min(res, 0.95); + // core filter implementation double g = 2 * M_PI * cutoff; double zc = g / tan(g/2 * m_inv_sample_rate); - double gzc = zc / g; double gzc2 = gzc * gzc; double gzc3 = gzc2 * gzc; double gzc4 = gzc3 * gzc; double r1 = 1 + r; - double a0 = r1; double a1 = 4 * r1; double a2 = 6 * r1; double a3 = 4 * r1; double a4 = r1; - double b0 = r1 + 4 * gzc + 6 * gzc2 + 4 * gzc3 + gzc4; double b1 = 4 * (r1 + 2 * gzc - 2 * gzc3 - gzc4); double b2 = 6 * (r1 - 2 * gzc2 + gzc4); @@ -184,15 +250,18 @@ double cem3394_device::filter(double input, double cutoff) + m_filter_in[0] * a1 + m_filter_in[1] * a2 + m_filter_in[2] * a3 + m_filter_in[3] * a4 - m_filter_out[0] * b1 - m_filter_out[1] * b2 - m_filter_out[2] * b3 - m_filter_out[3] * b4) / b0; -// sound_assert(!std::isnan(output)); -// sound_assert(output >= -1.5 && output <= 1.5); - if (output < -1.5 || output > 1.5 || std::isnan(output)) + // catch NaNs + if (std::isnan(output)) { - if (m_filter_out[0] > -1.5 && m_filter_out[0] < 1.5) - printf("cutoff: %6.0f res: %.5f output: %.5f\n", cutoff, m_filter_resonance, output); + logerror("NAN - vco: %6.0f cutoff: %6.0f res: %.5f output: %.5f\n", m_vco_step / m_inv_sample_rate, cutoff, m_filter_resonance, output); + output = 0; } - if (std::isnan(output)) output = 0; + // if output goes significantly out of range, scale it down + else if (fabs(output) > 10.0) + output = 10.0; + + // update memories m_filter_in[3] = m_filter_in[2]; m_filter_in[2] = m_filter_in[1]; m_filter_in[1] = m_filter_in[0]; @@ -203,6 +272,7 @@ double cem3394_device::filter(double input, double cutoff) m_filter_out[1] = m_filter_out[0]; m_filter_out[0] = output; + // clamp to range and return if (output < -1.0) output = -1.0; else if (output > 1.0) @@ -210,6 +280,18 @@ double cem3394_device::filter(double input, double cutoff) return output; } +#else + +#error Unknown FILTER_TYPE + +#endif + + +//------------------------------------------------- +// sound_stream_update - generate sound to the mix +// buffer in mono +//------------------------------------------------- + void cem3394_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { auto &external = inputs[0]; @@ -370,6 +452,7 @@ void cem3394_device::set_voltage(int input, double voltage) case VCO_FREQUENCY: temp = m_vco_zero_freq * pow(2.0, -voltage * (1.0 / 0.75)); m_vco_step = temp * m_inv_sample_rate; + if (LOG_CONTROL_CHANGES) logerror("VCO_FREQ=%6.3fV -> freq=%f\n", voltage, temp); break; // wave select determines triangle/sawtooth enable @@ -381,6 +464,7 @@ void cem3394_device::set_voltage(int input, double voltage) m_wave_select |= WAVE_TRIANGLE | WAVE_SAWTOOTH; else if (voltage >= 2.3 && voltage <= 3.9) m_wave_select |= WAVE_SAWTOOTH; + if (LOG_CONTROL_CHANGES) logerror("WAVE_SEL=%6.3fV -> tri=%d saw=%d\n", voltage, (m_wave_select & WAVE_TRIANGLE) ? 1 : 0, (m_wave_select & WAVE_SAWTOOTH) ? 1 : 0); break; // pulse width determines duty cycle; 0.0 means 0%, 2.0 means 100% @@ -397,11 +481,13 @@ void cem3394_device::set_voltage(int input, double voltage) m_pulse_width = MINIMUM_WIDTH + (MAXIMUM_WIDTH - MINIMUM_WIDTH) * m_pulse_width; m_wave_select |= WAVE_PULSE; } + if (LOG_CONTROL_CHANGES) logerror("PULSE_WI=%6.3fV -> raw=%f adj=%f\n", voltage, voltage * 0.5, m_pulse_width); break; // final gain is pretty self-explanatory; 0.0 means ~90dB, 4.0 means 0dB case FINAL_GAIN: m_volume = compute_db_volume(voltage); + if (LOG_CONTROL_CHANGES) logerror("TOT_GAIN=%6.3fV -> vol=%f\n", voltage, m_volume); break; // mixer balance is a pan between the external input and the internal input @@ -417,11 +503,13 @@ void cem3394_device::set_voltage(int input, double voltage) m_mixer_internal = compute_db_volume(3.55 - 0.45 * (voltage * 0.25)); m_mixer_external = compute_db_volume(3.55 + voltage); } + if (LOG_CONTROL_CHANGES) logerror(" BALANCE=%6.3fV -> int=%f ext=%f\n", voltage, m_mixer_internal, m_mixer_external); break; // filter frequency varies from -3.0 to +4.0, at 0.375V/octave case FILTER_FREQENCY: m_filter_frequency = m_filter_zero_freq * pow(2.0, -voltage * (1.0 / 0.375)); + if (LOG_CONTROL_CHANGES) logerror("FLT_FREQ=%6.3fV -> freq=%f\n", voltage, m_filter_frequency); break; // modulation depth is 0.01*freq at 0V and 2.0*freq at 3.5V @@ -432,6 +520,7 @@ void cem3394_device::set_voltage(int input, double voltage) m_filter_modulation = 1.99; else m_filter_modulation = (voltage * (1.0 / 3.5)) * 1.98 + 0.01; + if (LOG_CONTROL_CHANGES) logerror("FLT_MODU=%6.3fV -> mod=%f\n", voltage, m_filter_modulation); break; // this is not yet implemented @@ -442,6 +531,7 @@ void cem3394_device::set_voltage(int input, double voltage) m_filter_resonance = 1.0; else m_filter_resonance = voltage * (1.0 / 2.5); + if (LOG_CONTROL_CHANGES) logerror("FLT_RESO=%6.3fV -> mod=%f\n", voltage, m_filter_resonance); break; } } diff --git a/src/devices/sound/dac76.cpp b/src/devices/sound/dac76.cpp index bbeb5728577..1c73d7b02c1 100644 --- a/src/devices/sound/dac76.cpp +++ b/src/devices/sound/dac76.cpp @@ -79,7 +79,7 @@ void dac76_device::sound_stream_update(sound_stream &stream, std::vector<read_st { // get current output level int step_size = (2 << m_chord); - stream_sample_t vout = m_level[m_chord] + m_step * step_size; + s32 vout = m_level[m_chord] + m_step * step_size; // apply sign bit vout *= (m_sb ? +1 : -1); diff --git a/src/devices/sound/dave.cpp b/src/devices/sound/dave.cpp index f26ea891879..b7f1487c025 100644 --- a/src/devices/sound/dave.cpp +++ b/src/devices/sound/dave.cpp @@ -205,7 +205,6 @@ void dave_device::sound_stream_update(sound_stream &stream, std::vector<read_str auto &buffer1 = outputs[0]; auto &buffer2 = outputs[1]; - constexpr stream_buffer::sample_t sample_scale = 1.0 / (4.0 * 32768.0); for (int sampindex = 0; sampindex < buffer1.samples(); sampindex++) { int vol[4]; @@ -264,8 +263,8 @@ void dave_device::sound_stream_update(sound_stream &stream, std::vector<read_str left_volume = output_volumes[0] + output_volumes[2] + output_volumes[4] + output_volumes[6]; right_volume = output_volumes[1] + output_volumes[3] + output_volumes[5] + output_volumes[7]; - buffer1.put(sampindex, stream_buffer::sample_t(left_volume) * sample_scale); - buffer2.put(sampindex, stream_buffer::sample_t(right_volume) * sample_scale); + buffer1.put_int(sampindex, left_volume, 32768 * 4); + buffer2.put_int(sampindex, right_volume, 32768 * 4); } } diff --git a/src/devices/sound/digitalk.cpp b/src/devices/sound/digitalk.cpp index 9ca0e6fa5f0..2bff98478e5 100644 --- a/src/devices/sound/digitalk.cpp +++ b/src/devices/sound/digitalk.cpp @@ -548,7 +548,6 @@ void digitalker_device::sound_stream_update(sound_stream &stream, std::vector<re { auto &sout = outputs[0]; int cpos = 0; - constexpr stream_buffer::sample_t sample_scale = 1.0 / 32768.0; while(cpos != sout.samples()) { if(m_zero_count == 0 && m_dac_index == 128) digitalker_step(); @@ -563,10 +562,10 @@ void digitalker_device::sound_stream_update(sound_stream &stream, std::vector<re } else if(m_dac_index != 128) { while(cpos != sout.samples() && m_dac_index != 128) { - stream_buffer::sample_t v = stream_buffer::sample_t(m_dac[m_dac_index]) * sample_scale; + s32 v = m_dac[m_dac_index]; int pp = m_pitch_pos; while(cpos != sout.samples() && pp != m_pitch) { - sout.put(cpos++, v); + sout.put_int(cpos++, v, 32768); pp++; } if(pp == m_pitch) { diff --git a/src/devices/sound/discrete.cpp b/src/devices/sound/discrete.cpp index 7d6a84a4fc7..47e517af633 100644 --- a/src/devices/sound/discrete.cpp +++ b/src/devices/sound/discrete.cpp @@ -44,9 +44,6 @@ #include <iostream> -/* for_each collides with c++ standard libraries - include it here */ -#define for_each(_T, _e, _l) for (_T _e = (_l)->begin_ptr() ; _e <= (_l)->end_ptr(); _e++) - // device type definition DEFINE_DEVICE_TYPE(DISCRETE, discrete_sound_device, "discrete", "Discrete Sound") @@ -93,7 +90,7 @@ DEFINE_DEVICE_TYPE(DISCRETE, discrete_sound_device, "discrete", "Discrete Sound" struct output_buffer { - double *node_buf; + std::unique_ptr<double []> node_buf; const double *source; volatile double *ptr; int node_num; @@ -110,47 +107,44 @@ class discrete_task { friend class discrete_device; public: - virtual ~discrete_task(void) { } + virtual ~discrete_task() { } - inline void step_nodes(void); + inline void step_nodes(); inline bool lock_threadid(int32_t threadid) { int expected = -1; return m_threadid.compare_exchange_weak(expected, threadid, std::memory_order_release,std::memory_order_relaxed); } - inline void unlock(void) { m_threadid = -1; } + inline void unlock() { m_threadid = -1; } //const linked_list_entry *list; - node_step_list_t step_list; + discrete_device::node_step_list_t step_list; /* list of source nodes */ - vector_t<input_buffer> source_list; /* discrete_source_node */ + std::vector<input_buffer> source_list; /* discrete_source_node */ - int task_group; + int task_group = 0; - discrete_task(discrete_device &pdev) - : task_group(0), m_device(pdev), m_threadid(-1), m_samples(0) -{ - source_list.clear(); - step_list.clear(); - m_buffers.clear(); + discrete_task(discrete_device &pdev) : m_device(pdev), m_threadid(-1) + { + // FIXME: the code expects to be able to take pointers to members of elements of this vector before it's filled + source_list.reserve(16); } protected: static void *task_callback(void *param, int threadid); - inline bool process(void); + inline bool process(); - void check(discrete_task *dest_task); + void check(discrete_task &dest_task); void prepare_for_queue(int samples); - vector_t<output_buffer> m_buffers; + std::vector<output_buffer> m_buffers; discrete_device & m_device; private: std::atomic<int32_t> m_threadid; - volatile int m_samples; - + volatile int m_samples = 0; }; @@ -181,29 +175,27 @@ private: * *************************************/ -inline void discrete_task::step_nodes(void) +inline void discrete_task::step_nodes() { - for_each(input_buffer *, sn, &source_list) + for (input_buffer &sn : source_list) { - sn->buffer = *sn->ptr++; + sn.buffer = *sn.ptr++; } if (EXPECTED(!m_device.profiling())) { - for_each(discrete_step_interface **, entry, &step_list) + for (discrete_step_interface *entry : step_list) { /* Now step the node */ - (*entry)->step(); + entry->step(); } } else { osd_ticks_t last = get_profile_ticks(); - for_each(discrete_step_interface **, entry, &step_list) + for (discrete_step_interface *node : step_list) { - discrete_step_interface *node = *entry; - node->run_time -= last; node->step(); last = get_profile_ticks(); @@ -212,23 +204,23 @@ inline void discrete_task::step_nodes(void) } /* buffer the outputs */ - for_each(output_buffer *, outbuf, &m_buffers) - *(outbuf->ptr++) = *outbuf->source; + for (output_buffer &outbuf : m_buffers) + *outbuf.ptr++ = *outbuf.source; } void *discrete_task::task_callback(void *param, int threadid) { - task_list_t *list = (task_list_t *) param; + const auto &list = *reinterpret_cast<const discrete_sound_device::task_list_t *>(param); do { - for_each(discrete_task **, task, list) + for (const auto &task : list) { /* try to lock */ - if ((*task)->lock_threadid(threadid)) + if (task->lock_threadid(threadid)) { - if (!(*task)->process()) + if (!task->process()) return nullptr; - (*task)->unlock(); + task->unlock(); } } } while (1); @@ -236,16 +228,14 @@ void *discrete_task::task_callback(void *param, int threadid) return nullptr; } -bool discrete_task::process(void) +bool discrete_task::process() { int samples = std::min(int(m_samples), MAX_SAMPLES_PER_TASK_SLICE); /* check dependencies */ - for_each(input_buffer *, sn, &source_list) + for (input_buffer &sn : source_list) { - int avail; - - avail = sn->linked_outbuf->ptr - sn->ptr; + int avail = sn.linked_outbuf->ptr - sn.ptr; if (avail < 0) throw emu_fatalerror("discrete_task::process: available samples are negative"); if (avail < samples) @@ -273,33 +263,35 @@ void discrete_task::prepare_for_queue(int samples) { m_samples = samples; /* set up task buffers */ - for_each(output_buffer *, ob, &m_buffers) - ob->ptr = ob->node_buf; + for (output_buffer &ob : m_buffers) + ob.ptr = ob.node_buf.get(); /* initialize sources */ - for_each(input_buffer *, sn, &source_list) + for (input_buffer &sn : source_list) { - sn->ptr = sn->linked_outbuf->node_buf; + sn.ptr = sn.linked_outbuf->node_buf.get(); } } -void discrete_task::check(discrete_task *dest_task) +void discrete_task::check(discrete_task &dest_task) { - int inputnum; + // FIXME: this function takes addresses of elements of a vector that has items added later + // 16 is enough for the systems in MAME, but the code should be fixed properly + m_buffers.reserve(16); /* Determine, which nodes in the task are referenced by nodes in dest_task * and add them to the list of nodes to be buffered for further processing */ - for_each(discrete_step_interface **, node_entry, &step_list) + for (discrete_step_interface *node_entry : step_list) { - discrete_base_node *task_node = (*node_entry)->self; + discrete_base_node *task_node = node_entry->self; - for_each(discrete_step_interface **, step_entry, &dest_task->step_list) + for (discrete_step_interface *step_entry : dest_task.step_list) { - discrete_base_node *dest_node = (*step_entry)->self; + discrete_base_node *dest_node = step_entry->self; /* loop over all active inputs */ - for (inputnum = 0; inputnum < dest_node->active_inputs(); inputnum++) + for (int inputnum = 0; inputnum < dest_node->active_inputs(); inputnum++) { int inputnode_num = dest_node->input_node(inputnum); if IS_VALUE_A_NODE(inputnode_num) @@ -307,11 +299,10 @@ void discrete_task::check(discrete_task *dest_task) /* Fixme: sub nodes ! */ if (NODE_DEFAULT_NODE(task_node->block_node()) == NODE_DEFAULT_NODE(inputnode_num)) { - input_buffer source; - int i, found = -1; + int found = -1; output_buffer *pbuf = nullptr; - for (i = 0; i < m_buffers.count(); i++) + for (int i = 0; i < m_buffers.size(); i++) // if (m_buffers[i].node->block_node() == inputnode_num) if (m_buffers[i].node_num == inputnode_num) { @@ -324,28 +315,20 @@ void discrete_task::check(discrete_task *dest_task) { output_buffer buf; - buf.node_buf = auto_alloc_array(m_device.machine(), double, - ((task_node->sample_rate() + sound_manager::STREAMS_UPDATE_FREQUENCY) / sound_manager::STREAMS_UPDATE_FREQUENCY)); - buf.ptr = buf.node_buf; + buf.node_buf = std::make_unique<double []>((task_node->sample_rate() + sound_manager::STREAMS_UPDATE_FREQUENCY) / sound_manager::STREAMS_UPDATE_FREQUENCY); + buf.ptr = buf.node_buf.get(); buf.source = dest_node->m_input[inputnum]; buf.node_num = inputnode_num; //buf.node = device->discrete_find_node(inputnode); - m_buffers.count(); - pbuf = m_buffers.add(buf); + m_buffers.push_back(std::move(buf)); + pbuf = &m_buffers.back(); } - m_device.discrete_log("dso_task_start - buffering %d(%d) in task %p group %d referenced by %d group %d", NODE_INDEX(inputnode_num), NODE_CHILD_NODE_NUM(inputnode_num), this, task_group, dest_node->index(), dest_task->task_group); + m_device.discrete_log("dso_task_start - buffering %d(%d) in task %p group %d referenced by %d group %d", NODE_INDEX(inputnode_num), NODE_CHILD_NODE_NUM(inputnode_num), this, task_group, dest_node->index(), dest_task.task_group); /* register into source list */ - //source = auto_alloc(device->machine(), discrete_source_node); - //source.task = this; - //source.output_node = i; - source.linked_outbuf = pbuf; - source.buffer = 0.0; /* please compiler */ - source.ptr = nullptr; - dest_task->source_list.add(source); - - /* point the input to a buffered location */ - dest_node->m_input[inputnum] = &dest_task->source_list[dest_task->source_list.count()-1].buffer; // was copied! &source.buffer; + dest_task.source_list.push_back(input_buffer{ nullptr, pbuf, 0.0 }); + // FIXME: taking address of element of vector before it's filled + dest_node->m_input[inputnum] = &dest_task.source_list.back().buffer; } } @@ -374,7 +357,7 @@ discrete_base_node::discrete_base_node() : } -discrete_base_node::~discrete_base_node(void) +discrete_base_node::~discrete_base_node() { /* currently noting */ } @@ -398,7 +381,7 @@ void discrete_base_node::init(discrete_device *pdev, const discrete_block *xbloc } } -void discrete_base_node::save_state(void) +void discrete_base_node::save_state() { if (m_block->node != NODE_SPECIAL) m_device->save_item(NAME(m_output), m_block->node); @@ -410,7 +393,7 @@ discrete_base_node *discrete_device::discrete_find_node(int node) return m_indexed_node[NODE_INDEX(node)]; } -void discrete_base_node::resolve_input_nodes(void) +void discrete_base_node::resolve_input_nodes() { int inputnum; @@ -520,7 +503,7 @@ void discrete_device::discrete_build_list(const discrete_block *intf, sound_bloc if (intf[node_count].type == DSS_NULL) fatalerror("discrete_build_list: DISCRETE_REPLACE at end of node_list\n"); - for (int i=0; i < block_list.count(); i++) + for (int i=0; i < block_list.size(); i++) { const discrete_block *block = block_list[i]; @@ -540,9 +523,9 @@ void discrete_device::discrete_build_list(const discrete_block *intf, sound_bloc } else if (intf[node_count].type == DSO_DELETE) { - vector_t<int> deletethem; + std::vector<int> deletethem; - for (int i=0; i<block_list.count(); i++) + for (int i=0; i<block_list.size(); i++) { const discrete_block *block = block_list[i]; @@ -550,16 +533,16 @@ void discrete_device::discrete_build_list(const discrete_block *intf, sound_bloc (block->node <= intf[node_count].input_node[1])) { discrete_log("discrete_build_list() - DISCRETE_DELETE deleted NODE_%02d", NODE_INDEX(block->node) ); - deletethem.add(i); + deletethem.push_back(i); } } - for_each (int *, i, &deletethem) - block_list.remove(*i); + for (int i : deletethem) + block_list.erase(block_list.begin() + i); // FIXME: how is this supposed to work if there's more than one item to remove? indices are shifted back on each removal } else { discrete_log("discrete_build_list() - adding node %d\n", node_count); - block_list.add(&intf[node_count]); + block_list.push_back(&intf[node_count]); } node_count++; @@ -575,7 +558,7 @@ void discrete_device::discrete_sanity_check(const sound_block_list_t &block_list int node_count = 0; discrete_log("discrete_start() - Doing node list sanity check"); - for (int i=0; i < block_list.count(); i++) + for (int i=0; i < block_list.size(); i++) { const discrete_block *block = block_list[i]; @@ -618,61 +601,60 @@ void discrete_device::discrete_sanity_check(const sound_block_list_t &block_list * *************************************/ -static uint64_t list_run_time(const node_list_t &list) +static uint64_t list_run_time(const discrete_device::node_list_t &list) { uint64_t total = 0; - for_each(discrete_base_node **, node, &list) + for (const auto &node : list) { discrete_step_interface *step; - if ((*node)->interface(step)) + if (node->interface(step)) total += step->run_time; } return total; } -static uint64_t step_list_run_time(const node_step_list_t &list) +static uint64_t step_list_run_time(const discrete_device::node_step_list_t &list) { uint64_t total = 0; - for_each(discrete_step_interface **, node, &list) + for (discrete_step_interface *node : list) { - total += (*node)->run_time; + total += node->run_time; } return total; } -void discrete_device::display_profiling(void) +void discrete_device::display_profiling() { int count; uint64_t total; uint64_t tresh; - double tt; /* calculate total time */ total = list_run_time(m_node_list); - count = m_node_list.count(); + count = m_node_list.size(); /* print statistics */ - util::stream_format(std::cout, "Total Samples : %16d\n", m_total_samples); + osd_printf_info("Total Samples : %16d\n", m_total_samples); tresh = total / count; - util::stream_format(std::cout, "Threshold (mean): %16d\n", tresh / m_total_samples ); - for_each(discrete_base_node **, node, &m_node_list) + osd_printf_info("Threshold (mean): %16d\n", tresh / m_total_samples); + for (const auto &node : m_node_list) { discrete_step_interface *step; - if ((*node)->interface(step)) + if (node->interface(step)) if (step->run_time > tresh) - util::stream_format(std::cout, "%3d: %20s %8.2f %10.2f\n", (*node)->index(), (*node)->module_name(), double(step->run_time) / double(total) * 100.0, double(step->run_time) / double(m_total_samples)); + osd_printf_info("%3d: %20s %8.2f %10.2f\n", node->index(), node->module_name(), double(step->run_time) / double(total) * 100.0, double(step->run_time) / double(m_total_samples)); } /* Task information */ - for_each(discrete_task **, task, &task_list) + for (const auto &task : task_list) { - tt = step_list_run_time((*task)->step_list); + double tt = step_list_run_time(task->step_list); - util::stream_format(std::cout, "Task(%d): %8.2f %15.2f\n", (*task)->task_group, tt / double(total) * 100.0, tt / double(m_total_samples)); + osd_printf_info("Task(%d): %8.2f %15.2f\n", task->task_group, tt / double(total) * 100.0, tt / double(m_total_samples)); } - util::stream_format(std::cout, "Average samples/double->update: %8.2f\n", double(m_total_samples) / double(m_total_stream_updates)); + osd_printf_info("Average samples/double->update: %8.2f\n", double(m_total_samples) / double(m_total_stream_updates)); } @@ -687,15 +669,15 @@ void discrete_device::init_nodes(const sound_block_list_t &block_list) { discrete_task *task = nullptr; /* list tail pointers */ - int has_tasks = 0; + bool has_tasks = false; /* check whether we have tasks ... */ if (USE_DISCRETE_TASKS) { - for (int i = 0; i < block_list.count(); i++) + for (int i = 0; !has_tasks && (i < block_list.size()); i++) { if (block_list[i]->type == DSO_TASK_START) - has_tasks = 1; + has_tasks = true; } } @@ -704,21 +686,23 @@ void discrete_device::init_nodes(const sound_block_list_t &block_list) /* make sure we have one simple task * No need to create a node since there are no dependencies. */ - task = auto_alloc_clear(machine(), <discrete_task>(*this)); - task_list.add(task); + task_list.push_back(std::make_unique<discrete_task>(*this)); + task = task_list.back().get(); } /* loop over all nodes */ - for (int i = 0; i < block_list.count(); i++) + for (int i = 0; i < block_list.size(); i++) { - const discrete_block *block = block_list[i]; + const discrete_block &block = *block_list[i]; + + // add to node list + m_node_list.push_back(block.factory(*this, block)); + discrete_base_node &node = *m_node_list.back(); - //discrete_base_node *node = block->factory->Create(this, block); - discrete_base_node *node = block->factory(this, block); - /* keep track of special nodes */ - if (block->node == NODE_SPECIAL) + if (block.node == NODE_SPECIAL) { - switch(block->type) + // keep track of special nodes + switch (block.type) { /* Output Node */ case DSO_OUTPUT: @@ -739,12 +723,12 @@ void discrete_device::init_nodes(const sound_block_list_t &block_list) { if (task != nullptr) fatalerror("init_nodes() - Nested DISCRETE_START_TASK.\n"); - task = auto_alloc_clear(machine(), <discrete_task>(*this)); - task->task_group = block->initial[0]; + task_list.push_back(std::make_unique<discrete_task>(*this)); + task = task_list.back().get(); + task->task_group = block.initial[0]; if (task->task_group < 0 || task->task_group >= DISCRETE_MAX_TASK_GROUPS) fatalerror("discrete_dso_task: illegal task_group %d\n", task->task_group); - //util::stream_format(std::cout, "task group %d\n", task->task_group); - task_list.add(task); + //logerror("task group %d\n", task->task_group); } break; @@ -760,37 +744,33 @@ void discrete_device::init_nodes(const sound_block_list_t &block_list) fatalerror("init_nodes() - Failed, trying to create unknown special discrete node.\n"); } } - - /* otherwise, make sure we are not a duplicate, and put ourselves into the indexed list */ else { - if (m_indexed_node[NODE_INDEX(block->node)]) - fatalerror("init_nodes() - Duplicate entries for NODE_%02d\n", NODE_INDEX(block->node)); - m_indexed_node[NODE_INDEX(block->node)] = node; + // otherwise, make sure we are not a duplicate, and put ourselves into the indexed list + if (m_indexed_node[NODE_INDEX(block.node)]) + fatalerror("init_nodes() - Duplicate entries for NODE_%02d\n", NODE_INDEX(block.node)); + m_indexed_node[NODE_INDEX(block.node)] = &node; } - /* add to node list */ - m_node_list.add(node); - - /* our running order just follows the order specified */ - /* does the node step ? */ + // our running order just follows the order specified + // does the node step? discrete_step_interface *step; - if (node->interface(step)) + if (node.interface(step)) { /* do we belong to a task? */ if (task == nullptr) - fatalerror("init_nodes() - found node outside of task: %s\n", node->module_name() ); + fatalerror("init_nodes() - found node outside of task: %s\n", node.module_name()); else - task->step_list.add(step); + task->step_list.push_back(step); } - if (USE_DISCRETE_TASKS && block->type == DSO_TASK_END) + if (USE_DISCRETE_TASKS && block.type == DSO_TASK_END) { task = nullptr; } /* and register save state */ - node->save_state(); + node.save_state(); } if (!has_tasks) @@ -810,11 +790,11 @@ int discrete_device::same_module_index(const discrete_base_node &node) { int index = 0; - for_each(discrete_base_node **, n, &m_node_list) + for (const auto &n : m_node_list) { - if (*n == &node) + if (n.get() == &node) return index; - if ((*n)->module_type() == node.module_type()) + if (n->module_type() == node.module_type()) index++; } return -1; @@ -851,7 +831,7 @@ discrete_sound_device::discrete_sound_device(const machine_config &mconfig, cons { } -discrete_device::~discrete_device(void) +discrete_device::~discrete_device() { } @@ -862,7 +842,7 @@ discrete_device::~discrete_device(void) void discrete_device::device_start() { // create the stream - //m_stream = stream_alloc_legacy(0, 2, 22257); + //m_stream = stream_alloc(0, 2, 22257); const discrete_block *intf_start = m_intf; @@ -897,33 +877,33 @@ void discrete_device::device_start() m_node_list.clear(); /* allocate memory to hold pointers to nodes by index */ - m_indexed_node = auto_alloc_array_clear(this->machine(), discrete_base_node *, DISCRETE_MAX_NODES); + m_indexed_node = make_unique_clear<discrete_base_node * []>(DISCRETE_MAX_NODES); /* initialize the node data */ init_nodes(block_list); /* now go back and find pointers to all input nodes */ - for_each(discrete_base_node **, node, &m_node_list) + for (const auto &node : m_node_list) { - (*node)->resolve_input_nodes(); + node->resolve_input_nodes(); } /* allocate a queue */ m_queue = osd_work_queue_alloc(WORK_QUEUE_FLAG_MULTI | WORK_QUEUE_FLAG_HIGH_FREQ); /* Process nodes which have a start func */ - for_each(discrete_base_node **, node, &m_node_list) + for (const auto &node : m_node_list) { - (*node)->start(); + node->start(); } /* Now set up tasks */ - for_each(discrete_task **, task, &task_list) + for (const auto &task : task_list) { - for_each(discrete_task **, dest_task, &task_list) + for (const auto &dest_task : task_list) { - if ((*task)->task_group > (*dest_task)->task_group) - (*dest_task)->check((*task)); + if (task->task_group > dest_task->task_group) + dest_task->check(*task); } } } @@ -942,9 +922,9 @@ void discrete_device::device_stop() /* Process nodes which have a stop func */ - for_each(discrete_base_node **, node, &m_node_list) + for (const auto &node : m_node_list) { - (*node)->stop(); + node->stop(); } if (DISCRETE_DEBUGLOG) @@ -969,31 +949,31 @@ void discrete_sound_device::device_start() discrete_device::device_start(); /* look for input stream nodes */ - for_each(discrete_base_node **, node, &m_node_list) + for (const auto &node : m_node_list) { /* if we are an stream input node, track that */ - discrete_dss_input_stream_node *input_stream = dynamic_cast<discrete_dss_input_stream_node *>(*node); + discrete_dss_input_stream_node *input_stream = dynamic_cast<discrete_dss_input_stream_node *>(node.get()); if (input_stream != nullptr) { - m_input_stream_list.add(input_stream); + m_input_stream_list.push_back(input_stream); } /* if this is an output interface, add it the output list */ discrete_sound_output_interface *out; - if ((*node)->interface(out)) - m_output_list.add(out); + if (node->interface(out)) + m_output_list.push_back(out); } /* if no outputs, give an error */ - if (m_output_list.count() == 0) + if (m_output_list.empty()) fatalerror("init_nodes() - Couldn't find an output node\n"); /* initialize the stream(s) */ - m_stream = stream_alloc(m_input_stream_list.count(), m_output_list.count(), m_sample_rate); + m_stream = stream_alloc(m_input_stream_list.size(), m_output_list.size(), m_sample_rate); /* Finalize stream_input_nodes */ - for_each(discrete_dss_input_stream_node **, node, &m_input_stream_list) + for (discrete_dss_input_stream_node *node : m_input_stream_list) { - (*node)->stream_start(); + node->stream_start(); } @@ -1008,12 +988,12 @@ void discrete_device::device_reset() update_to_current_time(); /* loop over all nodes */ - for_each (discrete_base_node **, node, &m_node_list) + for (const auto &node : m_node_list) { /* Fimxe : node_level */ - (*node)->m_output[0] = 0; + node->m_output[0] = 0; - (*node)->reset(); + node->reset(); } } @@ -1026,7 +1006,7 @@ void discrete_sound_device::device_reset() // discrete_device_process - process a number of // samples. // -// input / output buffers are stream_sample_t +// input / output buffers are s32 // to not to have to convert the buffers. // a "discrete cpu" device will pass nullptr here //------------------------------------------------- @@ -1037,18 +1017,19 @@ void discrete_device::process(int samples) return; /* Setup tasks */ - for_each(discrete_task **, task, &task_list) + for (const auto &task : task_list) { /* unlock the thread */ - (*task)->unlock(); + task->unlock(); - (*task)->prepare_for_queue(samples); + task->prepare_for_queue(samples); } - for_each(discrete_task **, task, &task_list) + for (const auto &task : task_list) { /* Fire a work item for each task */ - osd_work_item_queue(m_queue, discrete_task::task_callback, (void *) &task_list, WORK_ITEM_FLAG_AUTO_RELEASE); + (void)task; + osd_work_item_queue(m_queue, discrete_task::task_callback, (void *)&task_list, WORK_ITEM_FLAG_AUTO_RELEASE); } osd_work_queue_wait(m_queue, osd_ticks_per_second()*10); @@ -1060,7 +1041,7 @@ void discrete_device::process(int samples) } //------------------------------------------------- -// sound_stream_update_legacy - handle update requests for +// sound_stream_update - handle update requests for // our sound stream //------------------------------------------------- @@ -1069,17 +1050,17 @@ void discrete_sound_device::sound_stream_update(sound_stream &stream, std::vecto int outputnum = 0; /* Setup any output streams */ - for_each(discrete_sound_output_interface **, node, &m_output_list) + for (discrete_sound_output_interface *node : m_output_list) { - (*node)->set_output_ptr(outputs[outputnum]); + node->set_output_ptr(outputs[outputnum]); outputnum++; } /* Setup any input streams */ - for_each(discrete_dss_input_stream_node **, node, &m_input_stream_list) + for (discrete_dss_input_stream_node *node : m_input_stream_list) { - (*node)->m_inview = &inputs[(*node)->m_stream_in_number]; - (*node)->m_inview_sample = 0; + node->m_inview = &inputs[node->m_stream_in_number]; + node->m_inview_sample = 0; } /* just process it */ diff --git a/src/devices/sound/discrete.h b/src/devices/sound/discrete.h index 65879da211f..20d445959fa 100644 --- a/src/devices/sound/discrete.h +++ b/src/devices/sound/discrete.h @@ -7,6 +7,9 @@ #include "machine/rescap.h" +#include <vector> + + /*********************************************************************** * * MAME - Discrete sound system emulation library @@ -3745,88 +3748,6 @@ enum * *************************************/ -/* - * add and delete may be slow - the focus is on access! - */ - - // TODO: replace with vector from utils -template<class _ElementType> struct vector_t -{ -public: - vector_t(int initial) { - m_count = 0; - m_allocated = initial; - m_arr = make_unique_clear<_ElementType[]>(m_allocated); - } - vector_t() { - m_count = 0; - m_allocated = 16; - m_arr = make_unique_clear<_ElementType[]>(m_allocated); - } - ~vector_t() { - m_arr = nullptr; - } - _ElementType& operator [] (unsigned int index) const // get array item - { - return m_arr[index]; - } - - vector_t(const vector_t &a) // copy constructor - { - m_allocated = a.count(); - if (m_allocated < 16) - m_allocated = 16; - m_count = a.count(); - m_arr = make_unique_clear<_ElementType[]>(m_allocated); - for (int i=0; i < m_count; i++) - m_arr[i] = a[i]; - } - vector_t& operator = (const vector_t &a) // assignment operator - { - if (this == &a) return *this; - m_allocated = a.count(); - if (m_allocated < 16) - m_allocated = 16; - m_count = a.count(); - m_arr = make_unique_clear<_ElementType[]>(m_allocated); - for (int i=0; i < m_count; i++) - m_arr[i] = a[i]; - return *this; - } - - inline _ElementType* add(_ElementType object) - { - if (m_count >= m_allocated) - { - auto oldarr = make_unique_clear<_ElementType[]>(m_allocated); - for (int i = 0; i < m_count; i++) - oldarr[i] = m_arr[i]; - - m_allocated *= 2; - m_arr = make_unique_clear<_ElementType[]>(m_allocated); - for (int i = 0; i < m_count; i++) - m_arr[i] = oldarr[i]; - } - m_arr[m_count] = object; - m_count++; - return &m_arr[m_count-1]; - } - inline void remove(int index) - { - for (int i=index+1; i < m_count; i++) - m_arr[i-1] = m_arr[i]; - m_count--; - } - inline void clear(void) { m_count = 0; } - inline int count(void) const { return m_count; } - inline _ElementType *begin_ptr(void) const { return m_arr.get(); } - inline _ElementType *end_ptr(void) const { return m_arr.get() + (m_count - 1); } -private: - std::unique_ptr<_ElementType[]> m_arr; - int m_count; - int m_allocated; -}; - /************************************* * * Node-specific struct types @@ -4180,14 +4101,10 @@ enum discrete_node_type *************************************/ struct discrete_block; -class discrete_node_base_factory; class discrete_task; class discrete_base_node; class discrete_dss_input_stream_node; class discrete_device; -typedef vector_t<discrete_base_node *> node_list_t; -typedef vector_t<discrete_dss_input_stream_node *> istream_node_list_t; -typedef vector_t<discrete_task *> task_list_t; /************************************* @@ -4207,7 +4124,7 @@ typedef vector_t<discrete_task *> task_list_t; struct discrete_block { int node; /* Output node number */ - discrete_base_node *(*factory)(discrete_device * pdev, const discrete_block *block); + std::unique_ptr<discrete_base_node> (*factory)(discrete_device &pdev, const discrete_block &block); int type; /* see defines below */ int active_inputs; /* Number of active inputs on this node type */ int input_node[DISCRETE_MAX_INPUTS];/* input/control nodes */ @@ -4216,7 +4133,6 @@ struct discrete_block const char * name; /* Node Name */ const char * mod_name; /* Module / class name */ }; -typedef vector_t<const discrete_block *> sound_block_list_t; /************************************* * @@ -4229,11 +4145,10 @@ class discrete_step_interface public: virtual ~discrete_step_interface() { } - virtual void step(void) = 0; + virtual void step() = 0; osd_ticks_t run_time; discrete_base_node * self; }; -typedef vector_t<discrete_step_interface *> node_step_list_t; class discrete_input_interface { @@ -4256,7 +4171,6 @@ public: //************************************************************************** class discrete_sound_output_interface; -typedef vector_t<discrete_sound_output_interface *> node_output_list_t; // ======================> discrete_device @@ -4270,12 +4184,16 @@ protected: discrete_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); public: + typedef std::vector<std::unique_ptr<discrete_task> > task_list_t; + typedef std::vector<std::unique_ptr<discrete_base_node> > node_list_t; + typedef std::vector<discrete_step_interface *> node_step_list_t; + // inline configuration helpers void set_intf(const discrete_block *intf) { m_intf = intf; } uint8_t read(offs_t offset); void write(offs_t offset, uint8_t data); - virtual ~discrete_device(void); + virtual ~discrete_device(); template<int DiscreteInput> DECLARE_WRITE_LINE_MEMBER(write_line) @@ -4285,7 +4203,7 @@ public: /* --------------------------------- */ - virtual void update_to_current_time(void) const { } + virtual void update_to_current_time() const { } /* process a number of samples */ void process(int samples); @@ -4303,14 +4221,13 @@ public: discrete_base_node *discrete_find_node(int node); /* are we profiling */ - inline int profiling(void) { return m_profiling; } + inline int profiling() { return m_profiling; } - inline int sample_rate(void) { return m_sample_rate; } - inline double sample_time(void) { return m_sample_time; } + inline int sample_rate() { return m_sample_rate; } + inline double sample_time() { return m_sample_time; } protected: - // device-level overrides virtual void device_start() override; virtual void device_reset() override; @@ -4332,13 +4249,15 @@ protected: node_list_t m_node_list; /* node_description * */ private: + typedef std::vector<const discrete_block *> sound_block_list_t; + void discrete_build_list(const discrete_block *intf, sound_block_list_t &block_list); void discrete_sanity_check(const sound_block_list_t &block_list); - void display_profiling(void); + void display_profiling(); void init_nodes(const sound_block_list_t &block_list); /* internal node tracking */ - discrete_base_node ** m_indexed_node; + std::unique_ptr<discrete_base_node * []> m_indexed_node; /* tasks */ task_list_t task_list; /* discrete_task_context * */ @@ -4373,13 +4292,13 @@ public: set_intf(intf); } discrete_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); - virtual ~discrete_sound_device(void) { }; + virtual ~discrete_sound_device() { }; /* --------------------------------- */ - virtual void update_to_current_time(void) const override { m_stream->update(); } + virtual void update_to_current_time() const override { m_stream->update(); } - sound_stream *get_stream(void) { return m_stream; } + sound_stream *get_stream() { return m_stream; } protected: // device-level overrides @@ -4390,6 +4309,9 @@ protected: virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: + typedef std::vector<discrete_dss_input_stream_node *> istream_node_list_t; + typedef std::vector<discrete_sound_output_interface *> node_output_list_t; + /* the output stream */ sound_stream *m_stream; @@ -4415,13 +4337,14 @@ class discrete_base_node friend class discrete_task; public: + virtual ~discrete_base_node(); - virtual void reset(void) { } - virtual void start(void) { } - virtual void stop(void) { } - virtual void save_state(void); + virtual void reset() { } + virtual void start() { } + virtual void stop() { } + virtual void save_state(); - virtual int max_output(void) { return 1; }; + virtual int max_output() { return 1; }; inline bool interface(discrete_step_interface *&intf) const { intf = m_step_intf; return (intf != nullptr); } inline bool interface(discrete_input_interface *&intf) const { intf = m_input_intf; return (intf != nullptr); } @@ -4434,36 +4357,35 @@ public: inline void set_output(int n, double val) { m_output[n] = val; } /* Return the node index, i.e. X from NODE(X) */ - inline int index(void) { return NODE_INDEX(m_block->node); } + inline int index() { return NODE_INDEX(m_block->node); } /* Return the node number, i.e. NODE(X) */ - inline int block_node(void) const { return m_block->node; } + inline int block_node() const { return m_block->node; } /* Custom function specific initialisation data */ - inline const void *custom_data(void) { return m_custom; } + inline const void *custom_data() { return m_custom; } inline int input_node(int inputnum) { return m_block->input_node[inputnum]; } /* Number of active inputs on this node type */ - inline int active_inputs(void) { return m_active_inputs; } + inline int active_inputs() { return m_active_inputs; } /* Bit Flags. 1 in bit location means input_is_node */ - inline int input_is_node(void) { return m_input_is_node; } + inline int input_is_node() { return m_input_is_node; } - inline double sample_time(void) { return m_device->sample_time(); } - inline int sample_rate(void) { return m_device->sample_rate(); } + inline double sample_time() { return m_device->sample_time(); } + inline int sample_rate() { return m_device->sample_rate(); } - const char * module_name(void) { return m_block->mod_name; } - inline int module_type(void) const { return m_block->type; } + const char * module_name() { return m_block->mod_name; } + inline int module_type() const { return m_block->type; } protected: discrete_base_node(); - virtual ~discrete_base_node(); /* finish node setup after allocation is complete */ void init(discrete_device * pdev, const discrete_block *block); - void resolve_input_nodes(void); + void resolve_input_nodes(); double m_output[DISCRETE_MAX_OUTPUTS]; /* The node's last output value */ const double * m_input[DISCRETE_MAX_INPUTS]; /* Addresses of Input values */ @@ -4482,28 +4404,18 @@ private: discrete_sound_output_interface * m_output_intf; }; -class discrete_node_base_factory -{ -public: - virtual discrete_base_node *Create(discrete_device * pdev, const discrete_block *block) = 0; - virtual ~discrete_node_base_factory() {} -}; - template <class C> -class discrete_node_factory : public discrete_node_base_factory +class discrete_node_factory { public: - discrete_base_node *Create(discrete_device * pdev, const discrete_block *block) override; -}; - -template <class C> -discrete_base_node * discrete_node_factory<C>::Create(discrete_device * pdev, const discrete_block *block) -{ - discrete_base_node *r = auto_alloc_clear(pdev->machine(), <C>()); + static std::unique_ptr<discrete_base_node> create(discrete_device &pdev, const discrete_block &block) + { + std::unique_ptr<discrete_base_node> r = make_unique_clear<C>(); - r->init(pdev, block); - return r; -} + r->init(&pdev, &block); + return r; + } +}; /************************************* * @@ -4520,16 +4432,10 @@ discrete_base_node * discrete_node_factory<C>::Create(discrete_device * pdev, co * *************************************/ -template <class C> -discrete_base_node *discrete_create_node(discrete_device * pdev, const discrete_block *block) -{ - return discrete_node_factory< C >().Create(pdev, block); -} - #define DISCRETE_SOUND_EXTERN(name) extern const discrete_block name[] #define DISCRETE_SOUND_START(name) const discrete_block name[] = { //#define DSC_SND_ENTRY(_nod, _class, _dss, _num, _iact, _iinit, _custom, _name) { _nod, new discrete_node_factory< DISCRETE_CLASS_NAME(_class) >, _dss, _num, _iact, _iinit, _custom, _name, # _class } -#define DSC_SND_ENTRY(_nod, _class, _dss, _num, _iact, _iinit, _custom, _name) { _nod, &discrete_create_node< DISCRETE_CLASS_NAME(_class) >, _dss, _num, _iact, _iinit, _custom, _name, # _class } +#define DSC_SND_ENTRY(_nod, _class, _dss, _num, _iact, _iinit, _custom, _name) { _nod, &discrete_node_factory< DISCRETE_CLASS_NAME(_class) >::create, _dss, _num, _iact, _iinit, _custom, _name, # _class } #define DISCRETE_SOUND_END DSC_SND_ENTRY( NODE_00, special, DSS_NULL , 0, DSE( NODE_NC ), DSE( 0 ) ,nullptr ,"DISCRETE_SOUND_END" ) }; diff --git a/src/devices/sound/dmadac.cpp b/src/devices/sound/dmadac.cpp index b3a7d84bbf5..384449fca9b 100644 --- a/src/devices/sound/dmadac.cpp +++ b/src/devices/sound/dmadac.cpp @@ -232,7 +232,7 @@ dmadac_sound_device::dmadac_sound_device(const machine_config &mconfig, const ch } //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- void dmadac_sound_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) diff --git a/src/devices/sound/dspv.cpp b/src/devices/sound/dspv.cpp index 7305c1c5298..cf14ead15d3 100644 --- a/src/devices/sound/dspv.cpp +++ b/src/devices/sound/dspv.cpp @@ -95,6 +95,7 @@ void dspv_device::snd_w(offs_t offset, u16 data) void dspv_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { + outputs[0].fill(0); } void dspv_device::device_start() diff --git a/src/devices/sound/es1373.cpp b/src/devices/sound/es1373.cpp index 9475b410f0b..1c707599188 100644 --- a/src/devices/sound/es1373.cpp +++ b/src/devices/sound/es1373.cpp @@ -120,7 +120,7 @@ void es1373_device::device_start() add_map(0x40, M_IO, FUNC(es1373_device::map)); // create the stream - m_stream = stream_alloc_legacy(0, 2, 44100/2); + m_stream = stream_alloc(0, 2, 44100/2); m_timer = timer_alloc(0, nullptr); m_timer->adjust(attotime::zero, 0, attotime::from_hz(44100/2/16)); @@ -230,24 +230,27 @@ void es1373_device::device_timer(emu_timer &timer, device_timer_id tid, int para } //------------------------------------------------- -// sound_stream_update_legacy - handle update requests for +// sound_stream_update - handle update requests for // our sound stream //------------------------------------------------- -void es1373_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void es1373_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { if (m_dac1.enable) { - logerror("%s: sound_stream_update_legacy DAC1 not implemented yet\n", tag()); + logerror("%s: sound_stream_update DAC1 not implemented yet\n", tag()); } if (m_dac2.enable) { - send_audio_out(m_dac2, ICSTATUS_DAC2_INT_MASK, outputs[0], outputs[1], samples); + send_audio_out(m_dac2, ICSTATUS_DAC2_INT_MASK, outputs[0], outputs[1]); + } else { + outputs[0].fill(0); + outputs[1].fill(0); } if (m_adc.enable) { if (m_adc.format!=SCTRL_16BIT_MONO) { - logerror("%s: sound_stream_update_legacy Only SCTRL_16BIT_MONO recorded supported\n", tag()); + logerror("%s: sound_stream_update Only SCTRL_16BIT_MONO recorded supported\n", tag()); } else { - for (int i=0; i<samples; i++) { + for (int i=0; i<outputs[0].samples(); i++) { if (m_adc.buf_count<=m_adc.buf_size) { if (LOG_ES) logerror("%s: ADC buf_count: %i buf_size: %i buf_rptr: %i buf_wptr: %i\n", machine().describe_context(), @@ -292,7 +295,7 @@ void es1373_device::sound_stream_update_legacy(sound_stream &stream, stream_samp //------------------------------------------------- // send_audio_out - Sends channel audio output data //------------------------------------------------- -void es1373_device::send_audio_out(chan_info& chan, uint32_t intr_mask, stream_sample_t *outL, stream_sample_t *outR, int samples) +void es1373_device::send_audio_out(chan_info& chan, uint32_t intr_mask, write_stream_view &outL, write_stream_view &outR) { // Only transfer PCI data if bus mastering is enabled // Fill initial half buffer @@ -303,8 +306,9 @@ void es1373_device::send_audio_out(chan_info& chan, uint32_t intr_mask, stream_s //uint32_t sample_size = calc_size(chan.format); // Send data to sound stream bool buf_row_done; - for (int i=0; i<samples; i++) { + for (int i=0; i<outL.samples(); i++) { buf_row_done = false; + int16_t lsamp = 0, rsamp = 0; if (chan.buf_count<=chan.buf_size) { // Only transfer PCI data if bus mastering is enabled // Fill half-buffer when read pointer is at start of next half @@ -314,7 +318,7 @@ void es1373_device::send_audio_out(chan_info& chan, uint32_t intr_mask, stream_s } if (LOG_ES && i==0) logerror("%s: chan: %X samples: %i buf_count: %X buf_size: %X buf_rptr: %X buf_wptr: %X\n", - machine().describe_context(), chan.number, samples, chan.buf_count, chan.buf_size, chan.buf_rptr, chan.buf_wptr); + machine().describe_context(), chan.number, outL.samples(), chan.buf_count, chan.buf_size, chan.buf_rptr, chan.buf_wptr); // Buffer is 4 bytes per location, need to switch on sample mode switch (chan.format) { case SCTRL_8BIT_MONO: @@ -324,28 +328,28 @@ void es1373_device::send_audio_out(chan_info& chan, uint32_t intr_mask, stream_s logerror("es1373_device::send_audio_out SCTRL_8BIT_STEREO not implemented yet\n"); break; case SCTRL_16BIT_MONO: - // The sound cache is 32 bit wide fifo, so each entry is two mono 16 bit samples - if ((chan.buf_count&0x1)) { - // Read high 16 bits - outL[i] = outR[i] = (int16_t)(m_sound_cache[chan.buf_rptr]>>16); - chan.buf_rptr++; - buf_row_done = true; - } else { - // Read low 16 bits - outL[i] = outR[i] = (int16_t)(m_sound_cache[chan.buf_rptr]&0xffff); - } - break; - case SCTRL_16BIT_STEREO: - // The sound cache is 32 bit wide fifo, so each entry is one stereo 16 bit sample - outL[i] = (int16_t) m_sound_cache[chan.buf_rptr]&0xffff; - outR[i] = (int16_t) m_sound_cache[chan.buf_rptr]>>16; + // The sound cache is 32 bit wide fifo, so each entry is two mono 16 bit samples + if ((chan.buf_count&0x1)) { + // Read high 16 bits + lsamp = rsamp = m_sound_cache[chan.buf_rptr]>>16; chan.buf_rptr++; buf_row_done = true; + } else { + // Read low 16 bits + lsamp = rsamp = m_sound_cache[chan.buf_rptr]&0xffff; + } + break; + case SCTRL_16BIT_STEREO: + // The sound cache is 32 bit wide fifo, so each entry is one stereo 16 bit sample + lsamp = m_sound_cache[chan.buf_rptr]&0xffff; + rsamp = m_sound_cache[chan.buf_rptr]>>16; + chan.buf_rptr++; + buf_row_done = true; break; } if (LOG_ES_FILE && m_tempCount<1000000) { m_tempCount++; - //logerror("es1373_device::sound_stream_update_legacy count: %i samp16: %X\n", i, samp16); + //logerror("es1373_device::sound_stream_update count: %i samp16: %X\n", i, samp16); //if (LOG_ES_FILE && m_eslog) //fprintf(m_eslog, "%i\n", samp16); } @@ -368,10 +372,9 @@ void es1373_device::send_audio_out(chan_info& chan, uint32_t intr_mask, stream_s if (buf_row_done && !(chan.buf_rptr&0xf)) { chan.buf_rptr -= 0x10; } - } else { - // Send zeros? - outL[i] = outR[i] = 0; } + outL.put_int(i, lsamp, 32768); + outR.put_int(i, rsamp, 32768); } } diff --git a/src/devices/sound/es1373.h b/src/devices/sound/es1373.h index 856d90d7af8..6e3cddb8a42 100644 --- a/src/devices/sound/es1373.h +++ b/src/devices/sound/es1373.h @@ -29,7 +29,7 @@ protected: virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; virtual void device_add_mconfig(machine_config &config) override; virtual void device_post_load() override; - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; // Sound stream sound_stream *m_stream; @@ -55,7 +55,7 @@ private: void transfer_pci_audio(chan_info& chan, int type); uint32_t calc_size(const uint8_t &format); - void send_audio_out(chan_info& chan, uint32_t intr_mask, stream_sample_t *outL, stream_sample_t *outR, int samples); + void send_audio_out(chan_info& chan, uint32_t intr_mask, write_stream_view &outL, write_stream_view &outR); uint32_t m_tempCount; emu_timer *m_timer; diff --git a/src/devices/sound/es5503.cpp b/src/devices/sound/es5503.cpp index 36fcaaf8af1..f22d11473fc 100644 --- a/src/devices/sound/es5503.cpp +++ b/src/devices/sound/es5503.cpp @@ -2,7 +2,7 @@ // copyright-holders:R. Belmont /* - ES5503 - Ensoniq ES5503 "DOC" emulator v2.1.1 + ES5503 - Ensoniq ES5503 "DOC" emulator v2.1.2 By R. Belmont. Copyright R. Belmont. @@ -30,6 +30,9 @@ 2.0 (RB) - C++ conversion, more accurate oscillator IRQ timing 2.1 (RB) - Corrected phase when looping; synthLAB, Arkanoid, and Arkanoid II no longer go out of tune 2.1.1 (RB) - Fixed issue introduced in 2.0 where IRQs were delayed + 2.1.2 (RB) - Fixed SoundSmith POLY.SYNTH inst where one-shot on the even oscillator and swap on the odd should loop. + Conversely, the intro voice in FTA Delta Demo has swap on the even and one-shot on the odd and doesn't + want to loop. */ #include "emu.h" @@ -88,7 +91,8 @@ void es5503_device::halt_osc(int onum, int type, uint32_t *accumulator, int ress { ES5503Osc *pOsc = &oscillators[onum]; ES5503Osc *pPartner = &oscillators[onum^1]; - int mode = (pOsc->control>>1) & 3; + const int mode = (pOsc->control>>1) & 3; + const int partnerMode = (pPartner->control>>1) & 3; // if 0 found in sample data or mode is not free-run, halt this oscillator if ((mode != MODE_FREE) || (type != 0)) @@ -112,8 +116,9 @@ void es5503_device::halt_osc(int onum, int type, uint32_t *accumulator, int ress *accumulator = altram << resshift; } - // if swap mode, start the partner - if (mode == MODE_SWAP) + // if we're in swap mode or we're the even oscillator and the partner is in swap mode, + // start the partner. + if ((mode == MODE_SWAP) || ((partnerMode == MODE_SWAP) && ((onum & 1)==0))) { pPartner->control &= ~1; // clear the halt bit pPartner->accumulator = 0; // and make sure it starts from the top (does this also need phase preservation?) @@ -127,16 +132,15 @@ void es5503_device::halt_osc(int onum, int type, uint32_t *accumulator, int ress m_irq_func(1); } } - -void es5503_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void es5503_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - static int32_t mix[(44100/60)*2*8]; int32_t *mixp; int osc, snum, i; uint32_t ramptr; + int samples = outputs[0].samples(); - assert(samples < (44100/60)*2); - memset(mix, 0, sizeof(mix)); + assert(samples < (44100/50)); + std::fill_n(&m_mix_buffer[0], samples*output_channels, 0); for (int chan = 0; chan < output_channels; chan++) { @@ -155,7 +159,7 @@ void es5503_device::sound_stream_update_legacy(sound_stream &stream, stream_samp int8_t data = -128; int resshift = resshifts[pOsc->resolution] - pOsc->wavetblsize; uint32_t sizemask = accmasks[pOsc->wavetblsize]; - mixp = &mix[0] + chan; + mixp = &m_mix_buffer[0] + chan; for (snum = 0; snum < samples; snum++) { @@ -197,11 +201,14 @@ void es5503_device::sound_stream_update_legacy(sound_stream &stream, stream_samp } } } - - mixp = &mix[0]; - for (i = 0; i < samples; i++) - for (int chan = 0; chan < output_channels; chan++) - outputs[chan][i] = (*mixp++)>>3; + mixp = &m_mix_buffer[0]; + for (int chan = 0; chan < output_channels; chan++) + { + for (i = 0; i < outputs[chan].samples(); i++) + { + outputs[chan].put_int(i, *mixp++, 32768*8); + } + } } @@ -224,7 +231,7 @@ void es5503_device::device_start() save_pointer(STRUCT_MEMBER(oscillators, irqpend), 32); output_rate = (clock() / 8) / (2 + oscsenabled); - m_stream = stream_alloc_legacy(0, output_channels, output_rate); + m_stream = stream_alloc(0, output_channels, output_rate); m_timer = timer_alloc(0, nullptr); attotime update_rate = output_rate ? attotime::from_hz(output_rate) : attotime::never; @@ -236,6 +243,8 @@ void es5503_device::device_clock_changed() output_rate = (clock() / 8) / (2 + oscsenabled); m_stream->set_sample_rate(output_rate); + m_mix_buffer.resize((output_rate/50)*8); + attotime update_rate = output_rate ? attotime::from_hz(output_rate) : attotime::never; m_timer->adjust(update_rate, 0, update_rate); } @@ -388,12 +397,11 @@ void es5503_device::write(offs_t offset, u8 data) break; case 0xa0: // oscillator control - // if a fresh key-on, reset the ccumulator + // if a fresh key-on, reset the accumulator if ((oscillators[osc].control & 1) && (!(data&1))) { oscillators[osc].accumulator = 0; } - oscillators[osc].control = data; break; @@ -427,6 +435,8 @@ void es5503_device::write(offs_t offset, u8 data) output_rate = (clock()/8)/(2+oscsenabled); m_stream->set_sample_rate(output_rate); + m_mix_buffer.resize((output_rate/50)*8); + attotime update_rate = output_rate ? attotime::from_hz(output_rate) : attotime::never; m_timer->adjust(update_rate, 0, update_rate); break; diff --git a/src/devices/sound/es5503.h b/src/devices/sound/es5503.h index 1483e91c8ac..2fd316aad8e 100644 --- a/src/devices/sound/es5503.h +++ b/src/devices/sound/es5503.h @@ -36,7 +36,7 @@ protected: virtual void device_timer(emu_timer &timer, device_timer_id tid, int param, void *ptr) override; // device_sound_interface overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; // device_rom_interface overrides virtual void rom_bank_updated() override; @@ -84,6 +84,8 @@ private: emu_timer *m_timer; + std::vector<int32_t> m_mix_buffer; + void halt_osc(int onum, int type, uint32_t *accumulator, int resshift); }; diff --git a/src/devices/sound/es5506.cpp b/src/devices/sound/es5506.cpp index b238409a1fa..3ea90a97261 100644 --- a/src/devices/sound/es5506.cpp +++ b/src/devices/sound/es5506.cpp @@ -106,7 +106,6 @@ static constexpr u32 FINE_FILTER_BIT = 16; static constexpr u32 FILTER_BIT = 12; static constexpr u32 FILTER_SHIFT = FINE_FILTER_BIT - FILTER_BIT; -static constexpr u32 MAX_SAMPLE_CHUNK = 10000; static constexpr u32 ULAW_MAXBITS = 8; namespace { @@ -163,9 +162,6 @@ es550x_device::es550x_device(const machine_config &mconfig, device_type type, co , m_mode(0) , m_irqv(0x80) , m_voice_index(0) - , m_scratch(nullptr) - , m_ulaw_lookup(nullptr) - , m_volume_lookup(nullptr) #if ES5506_MAKE_WAVS , m_wavraw(nullptr) #endif @@ -208,9 +204,6 @@ void es550x_device::device_start() m_sample_rate_changed_cb.resolve(); m_irqv = 0x80; - // allocate memory - m_scratch = make_unique_clear<s32[]>(2 * MAX_SAMPLE_CHUNK); - // register save save_item(NAME(m_sample_rate)); @@ -220,8 +213,6 @@ void es550x_device::device_start() save_item(NAME(m_irqv)); save_item(NAME(m_voice_index)); - save_pointer(NAME(m_scratch), 2 * MAX_SAMPLE_CHUNK); - save_item(STRUCT_MEMBER(m_voice, control)); save_item(STRUCT_MEMBER(m_voice, freqcount)); save_item(STRUCT_MEMBER(m_voice, start)); @@ -249,7 +240,7 @@ void es5506_device::device_start() channels = m_channels; // create the stream - m_stream = stream_alloc_legacy(0, 2 * channels, clock() / (16*32)); + m_stream = stream_alloc(0, 2 * channels, clock() / (16*32)); // initialize the regions if (m_region0 && !has_configured_map(0)) @@ -378,7 +369,7 @@ void es5505_device::device_start() channels = m_channels; // create the stream - m_stream = stream_alloc_legacy(0, 2 * channels, clock() / (16*32)); + m_stream = stream_alloc(0, 2 * channels, clock() / (16*32)); // initialize the regions if (m_region0 && !has_configured_map(0)) @@ -455,7 +446,7 @@ void es550x_device::update_internal_irq_state() void es550x_device::compute_tables(u32 total_volume_bit, u32 exponent_bit, u32 mantissa_bit) { // allocate ulaw lookup table - m_ulaw_lookup = make_unique_clear<s16[]>(1 << ULAW_MAXBITS); + m_ulaw_lookup.resize(1 << ULAW_MAXBITS); // generate ulaw lookup table for (int i = 0; i < (1 << ULAW_MAXBITS); i++) @@ -465,11 +456,11 @@ void es550x_device::compute_tables(u32 total_volume_bit, u32 exponent_bit, u32 m u32 mantissa = (rawval << 3) & 0xffff; if (exponent == 0) - m_ulaw_lookup[i] = (s16)mantissa >> 7; + m_ulaw_lookup[i] = s16(mantissa) >> 7; else { mantissa = (mantissa >> 1) | (~mantissa & 0x8000); - m_ulaw_lookup[i] = (s16)mantissa >> (7 - exponent); + m_ulaw_lookup[i] = s16(mantissa) >> (7 - exponent); } } @@ -477,7 +468,7 @@ void es550x_device::compute_tables(u32 total_volume_bit, u32 exponent_bit, u32 m m_volume_shift = total_volume_bit - volume_bit; const u32 volume_len = 1 << volume_bit; // allocate volume lookup table - m_volume_lookup = make_unique_clear<u32[]>(volume_len); + m_volume_lookup.resize(volume_len); // generate volume lookup table const u32 exponent_shift = 1 << exponent_bit; @@ -831,7 +822,7 @@ inline void es5505_device::check_for_end_reverse(es550x_voice *voice, u64 &accum ***********************************************************************************************/ -void es550x_device::generate_ulaw(es550x_voice *voice, s32 *lbuffer, s32 *rbuffer, int samples) +void es550x_device::generate_ulaw(es550x_voice *voice, s32 *dest) { const u32 freqcount = voice->freqcount; u64 accum = voice->accum & m_address_acc_mask; @@ -862,8 +853,8 @@ void es550x_device::generate_ulaw(es550x_voice *voice, s32 *lbuffer, s32 *rbuffe update_envelopes(voice); // apply volumes and add - *lbuffer += get_sample(val1, voice->lvol); - *rbuffer += get_sample(val1, voice->rvol); + dest[0] += get_sample(val1, voice->lvol); + dest[1] += get_sample(val1, voice->rvol); // check for loop end check_for_end_forward(voice, accum); @@ -892,8 +883,8 @@ void es550x_device::generate_ulaw(es550x_voice *voice, s32 *lbuffer, s32 *rbuffe update_envelopes(voice); // apply volumes and add - *lbuffer += get_sample(val1, voice->lvol); - *rbuffer += get_sample(val1, voice->rvol); + dest[0] += get_sample(val1, voice->lvol); + dest[1] += get_sample(val1, voice->rvol); // check for loop end check_for_end_reverse(voice, accum); @@ -917,7 +908,7 @@ void es550x_device::generate_ulaw(es550x_voice *voice, s32 *lbuffer, s32 *rbuffe ***********************************************************************************************/ -void es550x_device::generate_pcm(es550x_voice *voice, s32 *lbuffer, s32 *rbuffer, int samples) +void es550x_device::generate_pcm(es550x_voice *voice, s32 *dest) { const u32 freqcount = voice->freqcount; u64 accum = voice->accum & m_address_acc_mask; @@ -944,8 +935,8 @@ void es550x_device::generate_pcm(es550x_voice *voice, s32 *lbuffer, s32 *rbuffer update_envelopes(voice); // apply volumes and add - *lbuffer += get_sample(val1, voice->lvol); - *rbuffer += get_sample(val1, voice->rvol); + dest[0] += get_sample(val1, voice->lvol); + dest[1] += get_sample(val1, voice->rvol); // check for loop end check_for_end_forward(voice, accum); @@ -970,8 +961,8 @@ void es550x_device::generate_pcm(es550x_voice *voice, s32 *lbuffer, s32 *rbuffer update_envelopes(voice); // apply volumes and add - *lbuffer += get_sample(val1, voice->lvol); - *rbuffer += get_sample(val1, voice->rvol); + dest[0] += get_sample(val1, voice->lvol); + dest[1] += get_sample(val1, voice->rvol); // check for loop end check_for_end_reverse(voice, accum); @@ -1022,22 +1013,13 @@ inline void es550x_device::generate_irq(es550x_voice *voice, int v) ***********************************************************************************************/ -void es5506_device::generate_samples(s32 * const *outputs, int offset, int samples) +void es5506_device::generate_samples(std::vector<write_stream_view> &outputs) { - // skip if nothing to do - if (!samples) - return; - - // clear out the accumulators - for (int i = 0; i < m_channels << 1; i++) - { - memset(outputs[i] + offset, 0, sizeof(s32) * samples); - } - // loop while we still have samples to generate - while (samples) + for (int sampindex = 0; sampindex < outputs[0].samples(); sampindex++) { // loop over voices + s32 cursample[12] = { 0 }; for (int v = 0; v <= m_active_voices; v++) { es550x_voice *voice = &m_voice[v]; @@ -1049,40 +1031,29 @@ void es5506_device::generate_samples(s32 * const *outputs, int offset, int sampl const int voice_channel = get_ca(voice->control); const int channel = voice_channel % m_channels; const int l = channel << 1; - const int r = l + 1; - s32 *left = outputs[l] + offset; - s32 *right = outputs[r] + offset; // generate from the appropriate source if (voice->control & CONTROL_CMPD) - generate_ulaw(voice, left, right, samples); + generate_ulaw(voice, &cursample[l]); else - generate_pcm(voice, left, right, samples); + generate_pcm(voice, &cursample[l]); // does this voice have it's IRQ bit raised? generate_irq(voice, v); } - offset++; - samples--; + + for (int c = 0; c < outputs.size(); c++) + outputs[c].put_int(sampindex, cursample[c], 32768); } } -void es5505_device::generate_samples(s32 * const *outputs, int offset, int samples) +void es5505_device::generate_samples(std::vector<write_stream_view> &outputs) { - // skip if nothing to do - if (!samples) - return; - - // clear out the accumulators - for (int i = 0; i < m_channels << 1; i++) - { - memset(outputs[i] + offset, 0, sizeof(s32) * samples); - } - // loop while we still have samples to generate - while (samples) + for (int sampindex = 0; sampindex < outputs[0].samples(); sampindex++) { // loop over voices + s32 cursample[12] = { 0 }; for (int v = 0; v <= m_active_voices; v++) { es550x_voice *voice = &m_voice[v]; @@ -1100,19 +1071,17 @@ void es5505_device::generate_samples(s32 * const *outputs, int offset, int sampl const int voice_channel = get_ca(voice->control); const int channel = voice_channel % m_channels; const int l = channel << 1; - const int r = l + 1; - s32 *left = outputs[l] + offset; - s32 *right = outputs[r] + offset; // generate from the appropriate source // no compressed sample support - generate_pcm(voice, left, right, samples); + generate_pcm(voice, &cursample[l]); // does this voice have it's IRQ bit raised? generate_irq(voice, v); } - offset++; - samples--; + + for (int c = 0; c < outputs.size(); c++) + outputs[c].put_int(sampindex, cursample[c], 32768); } } @@ -2123,10 +2092,10 @@ u16 es5505_device::read(offs_t offset) //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void es550x_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void es550x_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { #if ES5506_MAKE_WAVS // start the logging once we have a sample rate @@ -2138,39 +2107,30 @@ void es550x_device::sound_stream_update_legacy(sound_stream &stream, stream_samp #endif // loop until all samples are output - int offset = 0; - while (samples) - { - int length = (samples > MAX_SAMPLE_CHUNK) ? MAX_SAMPLE_CHUNK : samples; - - generate_samples(outputs, offset, length); + generate_samples(outputs); #if ES5506_MAKE_WAVS - // log the raw data - if (m_wavraw) + // log the raw data + if (m_wavraw) + { + // determine left/right source data + + s32 *lsrc = m_scratch, *rsrc = m_scratch + length; + int channel; + memset(lsrc, 0, sizeof(s32) * length * 2); + // loop over the output channels + for (channel = 0; channel < m_channels; channel++) { - // determine left/right source data - s32 *lsrc = m_scratch, *rsrc = m_scratch + length; - int channel; - memset(lsrc, 0, sizeof(s32) * length * 2); - // loop over the output channels - for (channel = 0; channel < m_channels; channel++) + s32 *l = outputs[(channel << 1)] + sampindex; + s32 *r = outputs[(channel << 1) + 1] + sampindex; + // add the current channel's samples to the WAV data + for (samp = 0; samp < length; samp++) { - s32 *l = outputs[(channel << 1)] + offset; - s32 *r = outputs[(channel << 1) + 1] + offset; - // add the current channel's samples to the WAV data - for (samp = 0; samp < length; samp++) - { - lsrc[samp] += l[samp]; - rsrc[samp] += r[samp]; - } + lsrc[samp] += l[samp]; + rsrc[samp] += r[samp]; } - wav_add_data_32lr(m_wavraw, lsrc, rsrc, length, 4); } -#endif - - // account for these samples - offset += length; - samples -= length; + wav_add_data_32lr(m_wavraw, lsrc, rsrc, length, 4); } +#endif } diff --git a/src/devices/sound/es5506.h b/src/devices/sound/es5506.h index da438066ceb..4e45617c8b7 100644 --- a/src/devices/sound/es5506.h +++ b/src/devices/sound/es5506.h @@ -84,7 +84,7 @@ protected: virtual void device_reset() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; void update_irq_state(); void update_internal_irq_state(); @@ -111,10 +111,10 @@ protected: virtual void update_envelopes(es550x_voice *voice) = 0; virtual void check_for_end_forward(es550x_voice *voice, u64 &accum) = 0; virtual void check_for_end_reverse(es550x_voice *voice, u64 &accum) = 0; - void generate_ulaw(es550x_voice *voice, s32 *lbuffer, s32 *rbuffer, int samples); - void generate_pcm(es550x_voice *voice, s32 *lbuffer, s32 *rbuffer, int samples); + void generate_ulaw(es550x_voice *voice, s32 *dest); + void generate_pcm(es550x_voice *voice, s32 *dest); inline void generate_irq(es550x_voice *voice, int v); - virtual void generate_samples(s32 * const *outputs, int offset, int samples) {}; + virtual void generate_samples(std::vector<write_stream_view> &outputs) {}; inline void update_index(es550x_voice *voice) { m_voice_index = voice->index; } virtual inline u16 read_sample(es550x_voice *voice, offs_t addr) { return 0; } @@ -137,12 +137,11 @@ protected: es550x_voice m_voice[32]; // the 32 voices - std::unique_ptr<s32[]> m_scratch; - - std::unique_ptr<s16[]> m_ulaw_lookup; - std::unique_ptr<u32[]> m_volume_lookup; + std::vector<s16> m_ulaw_lookup; + std::vector<u32> m_volume_lookup; #if ES5506_MAKE_WAVS + std::vector<s32> m_scratch; void * m_wavraw; // raw waveform #endif @@ -190,7 +189,7 @@ protected: virtual void update_envelopes(es550x_voice *voice) override; virtual void check_for_end_forward(es550x_voice *voice, u64 &accum) override; virtual void check_for_end_reverse(es550x_voice *voice, u64 &accum) override; - virtual void generate_samples(s32 * const *outputs, int offset, int samples) override; + virtual void generate_samples(std::vector<write_stream_view> &outputs) override; virtual inline u16 read_sample(es550x_voice *voice, offs_t addr) override { update_index(voice); return m_cache[get_bank(voice->control)].read_word(addr); } @@ -244,7 +243,7 @@ protected: virtual void update_envelopes(es550x_voice *voice) override; virtual void check_for_end_forward(es550x_voice *voice, u64 &accum) override; virtual void check_for_end_reverse(es550x_voice *voice, u64 &accum) override; - virtual void generate_samples(s32 * const *outputs, int offset, int samples) override; + virtual void generate_samples(std::vector<write_stream_view> &outputs) override; virtual inline u16 read_sample(es550x_voice *voice, offs_t addr) override { update_index(voice); return m_cache[get_bank(voice->control)].read_word(addr); } diff --git a/src/devices/sound/esqpump.cpp b/src/devices/sound/esqpump.cpp index 7b37a2c9abd..bf34520869f 100644 --- a/src/devices/sound/esqpump.cpp +++ b/src/devices/sound/esqpump.cpp @@ -17,24 +17,18 @@ esq_5505_5510_pump_device::esq_5505_5510_pump_device(const machine_config &mconf : device_t(mconfig, ESQ_5505_5510_PUMP, tag, owner, clock) , device_sound_interface(mconfig, *this) , m_stream(nullptr) - , m_timer(nullptr) , m_esp(*this, finder_base::DUMMY_TAG) , m_esp_halted(true) , ticks_spent_processing(0) , samples_processed(0) { -#if !PUMP_FAKE_ESP_PROCESSING && PUMP_REPLACE_ESP_PROGRAM - e = nullptr; -#endif } void esq_5505_5510_pump_device::device_start() { logerror("Clock = %d\n", clock()); - m_stream = stream_alloc_legacy(8, 2, clock()); - m_timer = timer_alloc(0); - m_timer->enable(false); + m_stream = stream_alloc(8, 2, clock(), STREAM_SYNCHRONOUS); #if PUMP_DETECT_SILENCE silent_for = 500; @@ -51,95 +45,79 @@ void esq_5505_5510_pump_device::device_start() #endif #if !PUMP_FAKE_ESP_PROCESSING && PUMP_REPLACE_ESP_PROGRAM - e = make_unique_clear<int16_t[]>(0x4000); + e.resize(0x4000); ei = 0; #endif } -void esq_5505_5510_pump_device::device_stop() -{ - m_timer->enable(false); -} - -void esq_5505_5510_pump_device::device_reset() -{ - m_timer->adjust(attotime::zero, 0, attotime::from_hz(clock())); - m_timer->enable(true); -} - void esq_5505_5510_pump_device::device_clock_changed() { m_stream->set_sample_rate(clock()); - m_timer->adjust(attotime::zero, 0, attotime::from_hz(clock())); } -void esq_5505_5510_pump_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void esq_5505_5510_pump_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - if (samples != 1) { - logerror("Pump: request for %d samples\n", samples); - } + sound_assert(outputs[0].samples() == 1); - stream_sample_t *left = outputs[0], *right = outputs[1]; - for (int i = 0; i < samples; i++) - { + auto &left = outputs[0]; + auto &right = outputs[1]; #define SAMPLE_SHIFT 4 - // anything for the 'aux' output? - int16_t l = inputs[0][i] >> SAMPLE_SHIFT; - int16_t r = inputs[1][i] >> SAMPLE_SHIFT; - - // push the samples into the ESP - m_esp->ser_w(0, inputs[2][i] >> SAMPLE_SHIFT); - m_esp->ser_w(1, inputs[3][i] >> SAMPLE_SHIFT); - m_esp->ser_w(2, inputs[4][i] >> SAMPLE_SHIFT); - m_esp->ser_w(3, inputs[5][i] >> SAMPLE_SHIFT); - m_esp->ser_w(4, inputs[6][i] >> SAMPLE_SHIFT); - m_esp->ser_w(5, inputs[7][i] >> SAMPLE_SHIFT); + constexpr stream_buffer::sample_t input_scale = 32768.0 / (1 << SAMPLE_SHIFT); + + // anything for the 'aux' output? + stream_buffer::sample_t l = inputs[0].get(0) * (1.0 / (1 << SAMPLE_SHIFT)); + stream_buffer::sample_t r = inputs[1].get(0) * (1.0 / (1 << SAMPLE_SHIFT)); + + // push the samples into the ESP + m_esp->ser_w(0, s32(inputs[2].get(0) * input_scale)); + m_esp->ser_w(1, s32(inputs[3].get(0) * input_scale)); + m_esp->ser_w(2, s32(inputs[4].get(0) * input_scale)); + m_esp->ser_w(3, s32(inputs[5].get(0) * input_scale)); + m_esp->ser_w(4, s32(inputs[6].get(0) * input_scale)); + m_esp->ser_w(5, s32(inputs[7].get(0) * input_scale)); #if PUMP_FAKE_ESP_PROCESSING - m_esp->ser_w(6, m_esp->ser_r(0) + m_esp->ser_r(2) + m_esp->ser_r(4)); - m_esp->ser_w(7, m_esp->ser_r(1) + m_esp->ser_r(3) + m_esp->ser_r(5)); + m_esp->ser_w(6, m_esp->ser_r(0) + m_esp->ser_r(2) + m_esp->ser_r(4)); + m_esp->ser_w(7, m_esp->ser_r(1) + m_esp->ser_r(3) + m_esp->ser_r(5)); #else - if (!m_esp_halted) { - logerror("passing one sample through ESP\n"); - osd_ticks_t a = osd_ticks(); - m_esp->run_once(); - osd_ticks_t b = osd_ticks(); - ticks_spent_processing += (b - a); - samples_processed++; - } + if (!m_esp_halted) { + logerror("passing one sample through ESP\n"); + osd_ticks_t a = osd_ticks(); + m_esp->run_once(); + osd_ticks_t b = osd_ticks(); + ticks_spent_processing += (b - a); + samples_processed++; + } #endif - // read the processed result from the ESP and add to the saved AUX data - int16_t ll = m_esp->ser_r(6); - int16_t rr = m_esp->ser_r(7); - l += ll; - r += rr; + // read the processed result from the ESP and add to the saved AUX data + stream_buffer::sample_t ll = stream_buffer::sample_t(m_esp->ser_r(6)) * (1.0 / 32768.0); + stream_buffer::sample_t rr = stream_buffer::sample_t(m_esp->ser_r(7)) * (1.0 / 32768.0); + l += ll; + r += rr; #if !PUMP_FAKE_ESP_PROCESSING && PUMP_REPLACE_ESP_PROGRAM - // if we're processing the fake program through the ESP, the result should just be that of adding the inputs - int32_t el = (inputs[2][i]) + (inputs[4][i]) + (inputs[6][i]); - int32_t er = (inputs[3][i]) + (inputs[5][i]) + (inputs[7][i]); - int32_t e_next = el + er; - e[(ei + 0x1d0f) % 0x4000] = e_next; - - if (l != e[ei]) { - util::stream_format(std::cerr, "expected (%d) but have (%d)\n", e[ei], l); - } - ei = (ei + 1) % 0x4000; + // if we're processing the fake program through the ESP, the result should just be that of adding the inputs + stream_buffer::sample_t el = (inputs[2].get(0)) + (inputs[4].get(0)) + (inputs[6].get(0)); + stream_buffer::sample_t er = (inputs[3].get(0)) + (inputs[5].get(0)) + (inputs[7].get(0)); + stream_buffer::sample_t e_next = el + er; + e[(ei + 0x1d0f) % 0x4000] = e_next; + + if (fabs(l - e[ei]) > 1e-5) { + util::stream_format(std::cerr, "expected (%d) but have (%d)\n", e[ei], l); + } + ei = (ei + 1) % 0x4000; #endif - // write the combined data to the output - *left++ = l; - *right++ = r; - } + // write the combined data to the output + left.put(0, l); + right.put(0, r); #if PUMP_DETECT_SILENCE - for (int i = 0; i < samples; i++) { - if (outputs[0][i] == 0 && outputs[1][i] == 0) { - silent_for++; - } else { - silent_for = 0; - } + if (left.get(0) == 0 && right.get(0) == 0) { + silent_for++; + } else { + silent_for = 0; } bool silence = silent_for >= 500; if (was_silence != silence) { @@ -174,8 +152,3 @@ void esq_5505_5510_pump_device::sound_stream_update_legacy(sound_stream &stream, } #endif } - -void esq_5505_5510_pump_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) { - // ecery time there's a new sample period, update the stream! - m_stream->update(); -} diff --git a/src/devices/sound/esqpump.h b/src/devices/sound/esqpump.h index a4fb62b60ff..897475cd8b4 100644 --- a/src/devices/sound/esqpump.h +++ b/src/devices/sound/esqpump.h @@ -70,24 +70,16 @@ public: protected: // device-level overrides virtual void device_start() override; - virtual void device_stop() override; - virtual void device_reset() override; virtual void device_clock_changed() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; - - // timer callback overrides - virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: // internal state: // sound stream sound_stream *m_stream; - // per-sample timer - emu_timer *m_timer; - // ESP signal processor required_device<es5510_device> m_esp; @@ -111,7 +103,7 @@ private: #endif #if !PUMP_FAKE_ESP_PROCESSING && PUMP_REPLACE_ESP_PROGRAM - std::unique_ptr<int16_t[]> e; + std::vector<stream_buffer::sample_t> e; int ei; #endif }; diff --git a/src/devices/sound/flt_biquad.cpp b/src/devices/sound/flt_biquad.cpp new file mode 100644 index 00000000000..a0416bfafb1 --- /dev/null +++ b/src/devices/sound/flt_biquad.cpp @@ -0,0 +1,487 @@ +// license:BSD-3-Clause +// copyright-holders:K.Wilkins,Couriersud,Derrick Renaud,Frank Palazzolo,Jonathan Gevaryahu +/* + This is an implementation of a Direct-form II digital biquad filter, + intended for use in audio paths for filtering audio to or from other + stream devices. + + It has a number of constructor-helpers for automatically generating + a biquad filter equivalent to the filter response of a few standard + analog second order filter topographies. + + This biquad filter implementation is based on one written by Frank + Palazzolo, K. Wilkins, Couriersud, and Derrick Renaud, with some changes: + * It uses the Q factor directly in the filter definitions, rather than the damping factor (1/Q) + * It implements every common type of digital biquad filter which I could find documentation for. + * The filter is Direct-form II instead of Direct-form I, which results in shorter compiled code. + + Possibly useful features which aren't implemented because nothing uses them yet: + * More Sallen-Key filter variations (band-pass, high-pass) + * Direct control of the 5 normalized biquad parameters for a custom/raw parameter filter. +*/ +#include "emu.h" +#include "flt_biquad.h" + +// we need the M_SQRT2 constant +#ifndef M_SQRT2 +#define M_SQRT2 1.41421356237309504880 +#endif + +// define this to display debug info about the filters being set up +#undef FLT_BIQUAD_DEBUG_SETUP + +// device type definition +DEFINE_DEVICE_TYPE(FILTER_BIQUAD, filter_biquad_device, "filter_biquad", "Biquad Filter") + +// allow the enum class for the biquad filter type to be saved by the savestate system +ALLOW_SAVE_TYPE(filter_biquad_device::biquad_type); + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// filter_biquad_device - constructor +//------------------------------------------------- + +// initialize with some sane defaults for a highpass filter with a cutoff at 16hz, same as flt_rc's 'ac' mode. +filter_biquad_device::filter_biquad_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, FILTER_BIQUAD, tag, owner, clock), + device_sound_interface(mconfig, *this), + m_stream(nullptr), + m_type(biquad_type::HIGHPASS), + m_last_sample_rate(0), + m_fc(16.0), + m_q(M_SQRT2/2.0), + m_gain(1.0), + m_input(0.0), + m_w0(0.0), + m_w1(0.0), + m_w2(0.0), + m_output(0.0), + m_a1(0.0), + m_a2(0.0), + m_b0(1.0), + m_b1(0.0), + m_b2(0.0) +{ +} + +// set up the filter with the specified parameters and return a pointer to the new device +filter_biquad_device& filter_biquad_device::setup(biquad_type type, double fc, double q, double gain) +{ + m_type = type; + m_fc = fc; + m_q = q; + m_gain = gain; + return *this; +} + +// update an existing instance with new filter parameters +void filter_biquad_device::update_params(biquad_type type, double fc, double q, double gain) +{ + m_stream->update(); + m_type = type; + m_fc = fc; + m_q = q; + m_gain = gain; + recalc(); +} + + +//------------------------------------------------- +// Filter setup helpers for various filter models +//------------------------------------------------- + +// Sallen-Key filters + +/* Setup a biquad filter structure based on a single op-amp Sallen-Key low-pass filter circuit. + * + * .----------------------------. + * | | + * --- c2 | + * --- | + * | | + * r1 | r2 |\ | + * In >----ZZZZ----+--ZZZZ---+--------+ | \ | + * | '--|+ \ | + * --- c1 | >--+------> out + * --- .--|- / | + * | | | / | + * gnd | |/ | + * | | + * | r4 | + * +--ZZZZ---' + * | + * Z + * Z r3 + * Z + * | + * gnd + */ +filter_biquad_device& filter_biquad_device::opamp_sk_lowpass_setup(double r1, double r2, double r3, double r4, double c1, double c2) +{ + if ((r1 == 0) || (r2 == 0) || (r3 == 0) || (r4 == 0) || (c1 == 0) || (c2 == 0)) + { + fatalerror("filter_biquad_device::opamp_sk_lowpass_setup() - no parameters can be 0; parameters were: r1: %f, r2: %f, r3: %f, r4: %f, c1: %f, c2: %f", r1, r2, r3, r4, c1, c2); /* Filter can not be setup. Undefined results. */ + } + + // note: if R3 doesn't exist (no link to ground), pass a value of RES_M(999.99) or the like, i.e. an 'infinite resistor' + double const gain = (r3 + r4) / r3; + double const fc = 1.0 / (2 * M_PI * sqrt(r1 * r2 * c1 * c2)); + double const q = sqrt(r1 * r2 * c1 * c2) / ((r1 * c1) + (r2 * c1) + ((r2 * c2) * (1.0 - gain))); +#ifdef FLT_BIQUAD_DEBUG_SETUP + logerror("filter_biquad_device::opamp_sk_lowpass_setup() yields: fc = %f, Q = %f, gain = %f\n", fc, q, gain); +#endif + return setup(biquad_type::LOWPASS, fc, q, gain); +} + +// Multiple-Feedback filters +// (This is sometimes called a 'Rauch' filter circuit.) + +/* Setup a biquad filter structure based on a single op-amp Multiple-Feedback low-pass filter circuit. + * NOTE: vRef is not definable when setting up the filter. + * If the analog effects caused by vRef are important to the operation of the specific filter + * in question, a netlist implementation may work better under those circumstances. + * + * .--------+---------. + * | | | + * Z --- c2 | + * Z r3 --- | + * Z | | + * r1 | r2 | |\ | + * In >----ZZZZ----+---------+--ZZZZ--+ | \ | + * | '--|- \ | + * --- c1 | >--+------> out + * --- .--|+ / + * | | | / + * gnd vRef >---' |/ + * + */ +filter_biquad_device& filter_biquad_device::opamp_mfb_lowpass_setup(double r1, double r2, double r3, double c1, double c2) +{ + if ((r1 == 0) || (r2 == 0) || (r3 == 0) || (c2 == 0)) + { + fatalerror("filter_biquad_device::opamp_mfb_lowpass_setup() - only c1 can be 0; parameters were: r1: %f, r2: %f, r3: %f, c1: %f, c2: %f", r1, r2, r3, c1, c2); /* Filter can not be setup. Undefined results. */ + } + + double const gain = -r3 / r1; + double fc, q = (M_SQRT2 / 2.0); + if (c1 == 0) // set C1 to 0 to run this filter in a degraded single pole mode where C1 was left off the filter entirely. Certain Williams boards seem to have omitted C1, presumably by accident. + { + fc = (r1 * r3) / (2 * M_PI * ((r1 * r2) + (r1 * r3) + (r2 * r3)) * r3 * c2); +#ifdef FLT_BIQUAD_DEBUG_SETUP + logerror("filter_biquad_device::opamp_mfb_lowpass_setup() in degraded mode yields: fc = %f, Q = %f(ignored), gain = %f\n", fc, q, gain); +#endif + return setup(biquad_type::LOWPASS1P, fc, q, gain); + } + else + { + fc = 1.0 / (2 * M_PI * sqrt(r2 * r3 * c1 * c2)); + q = sqrt(r2 * r3 * c1 * c2) / ((r3 * c2) + (r2 * c2) + ((r2 * c2) * -gain)); +#ifdef FLT_BIQUAD_DEBUG_SETUP + logerror("filter_biquad_device::opamp_mfb_lowpass_setup() yields: fc = %f, Q = %f, gain = %f\n", fc, q, gain); +#endif + return setup(biquad_type::LOWPASS, fc, q, gain); + } +} + +/* Setup a biquad filter structure based on a single op-amp Multiple-Feedback band-pass filter circuit. + * NOTE: vRef is not definable when setting up the filter. + * If the analog effects caused by vRef are important to the operation of the specific filter + * in question, a netlist implementation may work better under those circumstances. + * NOTE2: If r2 is not used, then set it to 0 ohms, the code will ignore it and assume a fixed gain of 1. + * + * .--------+---------. + * | | | + * --- c1 Z | + * --- Z r3 | + * | Z | + * r1 | c2 | |\ | + * In >----ZZZZ----+---------+--||----+ | \ | + * Z '--|- \ | + * Z r2 | >--+------> out + * Z .--|+ / + * | | | / + * gnd vRef >---' |/ + * + */ +filter_biquad_device& filter_biquad_device::opamp_mfb_bandpass_setup(double r1, double r2, double r3, double c1, double c2) +{ + if ((r1 == 0) || (r3 == 0) || (c1 == 0) || (c2 == 0)) + { + fatalerror("filter_biquad_device::opamp_mfb_bandpass_setup() - only r2 can be 0; parameters were: r1: %f, r2: %f, r3: %f, c1: %f, c2: %f", r1, r2, r3, c1, c2); /* Filter can not be setup. Undefined results. */ + } + + double r_in, gain; + + if (r2 == 0) + { + gain = 1; + r_in = r1; + } + else + { + gain = r2 / (r1 + r2); + r_in = 1.0 / (1.0/r1 + 1.0/r2); + } + + double const fc = 1.0 / (2 * M_PI * sqrt(r_in * r3 * c1 * c2)); + double const q = sqrt(r3 / r_in * c1 * c2) / (c1 + c2); + gain *= -r3 / r_in * c2 / (c1 + c2); +#ifdef FLT_BIQUAD_DEBUG_SETUP + logerror("filter_biquad_device::opamp_mfb_bandpass_setup() yields: fc = %f, Q = %f, gain = %f\n", fc, q, gain); +#endif + return setup(biquad_type::BANDPASS, fc, q, gain); +} + +/* Setup a biquad filter structure based on a single op-amp Multiple-Feedback high-pass filter circuit. + * NOTE: vRef is not definable when setting up the filter. + * If the analog effects caused by vRef are important to the operation of the specific filter + * in question, a netlist implementation may work better under those circumstances. + * + * .--------+---------. + * | | | + * --- c3 Z | + * --- Z r2 | + * | Z | + * c1 | c2 | |\ | + * In >-----||-----+---------+---||---+ | \ | + * Z '--|- \ | + * Z r1 | >--+------> out + * Z .--|+ / + * | | | / + * gnd vRef >---' |/ + * + */ +filter_biquad_device& filter_biquad_device::opamp_mfb_highpass_setup(double r1, double r2, double c1, double c2, double c3) +{ + if ((r1 == 0) || (r2 == 0) || (c1 == 0) || (c2 == 0) || (c3 == 0)) + { + fatalerror("filter_biquad_device::opamp_mfb_highpass_setup() - no parameters can be 0; parameters were: r1: %f, r2: %f, c1: %f, c2: %f, c3: %f", r1, r2, c1, c2, c3); /* Filter can not be setup. Undefined results. */ + } + // TODO: if c1 is 0/shorted, should the circuit should work with a gain of 1 in a first order mode? + + double const gain = -c1 / c3; + double const fc = 1.0 / (2 * M_PI * sqrt(c2 * c3 * r1 * r2)); + double const q = sqrt(c2 * c3 * r1 * r2) / ((c2 * r1) + (c3 * r1) + ((c3 * r1) * -gain)); +#ifdef FLT_BIQUAD_DEBUG_SETUP + logerror("filter_biquad_device::opamp_mfb_highpass_setup() yields: fc = %f, Q = %f, gain = %f\n", fc, q, gain); +#endif + return setup(biquad_type::HIGHPASS, fc, q, gain); +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void filter_biquad_device::device_start() +{ + m_stream = stream_alloc(1, 1, SAMPLE_RATE_OUTPUT_ADAPTIVE); + m_last_sample_rate = 0; + recalc(); + + save_item(NAME(m_type)); + save_item(NAME(m_last_sample_rate)); + save_item(NAME(m_fc)); + save_item(NAME(m_q)); + save_item(NAME(m_gain)); + save_item(NAME(m_input)); + save_item(NAME(m_w0)); + save_item(NAME(m_w1)); + save_item(NAME(m_w2)); + save_item(NAME(m_output)); + save_item(NAME(m_a1)); + save_item(NAME(m_a2)); + save_item(NAME(m_b0)); + save_item(NAME(m_b1)); + save_item(NAME(m_b2)); +} + + +//------------------------------------------------- +// sound_stream_update - handle a stream update +//------------------------------------------------- + +void filter_biquad_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) +{ + auto &src = inputs[0]; + auto &dst = outputs[0]; + + if (m_last_sample_rate != m_stream->sample_rate()) + { + recalc(); + m_last_sample_rate = m_stream->sample_rate(); + } + + for (int sampindex = 0; sampindex < dst.samples(); sampindex++) + { + m_input = src.get(sampindex); + step(); + dst.put(sampindex, m_output); + } +} + + +/* Calculate the filter context based on the passed filter type info. + * m_type - 1 of the 9 defined filter types + * m_fc - center frequency + * m_q - 'Q' (quality) factor of filter (1/damp) + * m_gain - overall filter gain. Set to 1.0 if not needed. The exact meaning of gain changes depending on the filter type. + */ +void filter_biquad_device::recalc() +{ + double const MGain = fabs(m_gain); // absolute multiplicative gain + double const DBGain = log10(MGain) * 20.0; // gain in dB + double const AMGain = pow(10, fabs(DBGain) / 20.0); // multiplicative gain of absolute DB + double const K = tan(M_PI * m_fc / m_stream->sample_rate()); + double const Ksquared = K * K; + double const KoverQ = K / m_q; + double normal = 1.0 / (1.0 + KoverQ + Ksquared); + + m_a1 = 2.0 * (Ksquared - 1.0) * normal; + m_a2 = (1.0 - KoverQ + Ksquared) * normal; + + switch (m_type) + { + case biquad_type::LOWPASS1P: + m_a1 = exp(-2.0 * M_PI * (m_fc / m_stream->sample_rate())); + m_b0 = 1.0 - m_a1; + m_a1 = -m_a1; + m_b1 = m_b2 = m_a2 = 0.0; + break; + case biquad_type::HIGHPASS1P: + m_a1 = -exp(-2.0 * M_PI * (0.5 - m_fc / m_stream->sample_rate())); + m_b0 = 1.0 + m_a1; + m_a1 = -m_a1; + m_b1 = m_b2 = m_a2 = 0.0; + break; + case biquad_type::LOWPASS: + m_b0 = Ksquared * normal; + m_b1 = 2.0 * m_b0; + m_b2 = 1.0 * m_b0; + m_a1 = 2.0 * (Ksquared - 1.0) * normal; + m_a2 = (1.0 - KoverQ + Ksquared) * normal; + break; + case biquad_type::HIGHPASS: + m_b0 = 1.0 * normal; + m_b1 = -2.0 * m_b0; + m_b2 = 1.0 * m_b0; + m_a1 = 2.0 * (Ksquared - 1.0) * normal; + m_a2 = (1.0 - KoverQ + Ksquared) * normal; + break; + case biquad_type::BANDPASS: + m_b0 = KoverQ * normal; + m_b1 = 0.0; + m_b2 = -1.0 * m_b0; + m_a1 = 2.0 * (Ksquared - 1.0) * normal; + m_a2 = (1.0 - KoverQ + Ksquared) * normal; + break; + case biquad_type::NOTCH: + m_b0 = (1.0 + Ksquared) * normal; + m_b1 = 2.0 * (Ksquared - 1.0) * normal; + m_b2 = 1.0 * m_b0; + m_a1 = 1.0 * m_b1; + m_a2 = (1.0 - KoverQ + Ksquared) * normal; + break; + case biquad_type::PEAK: + if (DBGain >= 0.0) + { + m_b0 = (1.0 + (AMGain * KoverQ) + Ksquared) * normal; + m_b1 = 2.0 * (Ksquared - 1.0) * normal; + m_b2 = (1.0 - (AMGain * KoverQ) + Ksquared) * normal; + m_a1 = 1.0 * m_b1; + m_a2 = (1.0 - KoverQ + Ksquared) * normal; + } + else + { + normal = 1.0 / (1.0 + (AMGain * KoverQ) + Ksquared); + m_b0 = (1.0 + KoverQ + Ksquared) * normal; + m_b1 = 2.0 * (Ksquared - 1.0) * normal; + m_b2 = (1.0 - KoverQ + Ksquared) * normal; + m_a1 = 1.0 * m_b1; + m_a2 = (1.0 - (AMGain * KoverQ) + Ksquared) * normal; + } + break; + case biquad_type::LOWSHELF: + if (DBGain >= 0.0) + { + normal = 1.0 / (1.0 + M_SQRT2 * K + Ksquared); + m_b0 = (1.0 + sqrt(2.0 * AMGain) * K + AMGain * Ksquared) * normal; + m_b1 = 2.0 * (AMGain * Ksquared - 1.0) * normal; + m_b2 = (1.0 - sqrt(2.0 * AMGain) * K + AMGain * Ksquared) * normal; + m_a1 = 2.0 * (Ksquared - 1.0) * normal; + m_a2 = (1.0 - M_SQRT2 * K + Ksquared) * normal; + } + else + { + normal = 1.0 / (1.0 + sqrt(2.0 * AMGain) * K + AMGain * Ksquared); + m_b0 = (1.0 + M_SQRT2 * K + Ksquared) * normal; + m_b1 = 2.0 * (Ksquared - 1.0) * normal; + m_b2 = (1.0 - M_SQRT2 * K + Ksquared) * normal; + m_a1 = 2.0 * (AMGain * Ksquared - 1.0) * normal; + m_a2 = (1.0 - sqrt(2.0 * AMGain) * K + AMGain * Ksquared) * normal; + } + break; + case biquad_type::HIGHSHELF: + if (DBGain >= 0.0) + { + normal = 1.0 / (1.0 + M_SQRT2 * K + Ksquared); + m_b0 = (AMGain + sqrt(2.0 * AMGain) * K + Ksquared) * normal; + m_b1 = 2.0 * (Ksquared - AMGain) * normal; + m_b2 = (AMGain - sqrt(2.0 * AMGain) * K + Ksquared) * normal; + m_a1 = 2.0 * (Ksquared - 1.0) * normal; + m_a2 = (1.0 - M_SQRT2 * K + Ksquared) * normal; + } + else + { + normal = 1.0 / (AMGain + sqrt(2.0 * AMGain) * K + Ksquared); + m_b0 = (1.0 + M_SQRT2 * K + Ksquared) * normal; + m_b1 = 2.0 * (Ksquared - 1.0) * normal; + m_b2 = (1.0 - M_SQRT2 * K + Ksquared) * normal; + m_a1 = 2.0 * (Ksquared - AMGain) * normal; + m_a2 = (AMGain - sqrt(2.0 * AMGain) * K + Ksquared) * normal; + } + break; + default: + fatalerror("filter_biquad_device::recalc() - Invalid filter type!"); + break; + } +#ifdef FLT_BIQUAD_DEBUG + logerror("Calculated Parameters:\n"); + logerror( "Gain (dB): %f, (raw): %f\n", DBGain, MGain); + logerror( "k: %f\n", K); + logerror( "normal: %f\n", normal); + logerror("b0: %f\n", m_b0); + logerror("b1: %f\n", m_b1); + logerror("b2: %f\n", m_b2); + logerror("a1: %f\n", m_a1); + logerror("a2: %f\n", m_a2); +#endif + // peak and shelf filters do not use gain for the entire signal, only for the peak/shelf portions + // side note: the first order lowpass and highpass filter analogues technically don't have gain either, + // but this can be 'faked' by adjusting the bx factors, so we support that anyway, even if it isn't realistic. + if ( (m_type != biquad_type::PEAK) + && (m_type != biquad_type::LOWSHELF) + && (m_type != biquad_type::HIGHSHELF) ) + { + m_b0 *= m_gain; + m_b1 *= m_gain; + m_b2 *= m_gain; +#ifdef FLT_BIQUAD_DEBUG + logerror("b0g: %f\n", m_b0); + logerror("b1g: %f\n", m_b1); + logerror("b2g: %f\n", m_b2); +#endif + } +} + +/* Step the filter */ +void filter_biquad_device::step() +{ + m_w2 = m_w1; + m_w1 = m_w0; + m_w0 = (-m_a1 * m_w1) + (-m_a2 * m_w2) + m_input; + m_output = (m_b0 * m_w0) + (m_b1 * m_w1) + (m_b2 * m_w2); +} diff --git a/src/devices/sound/flt_biquad.h b/src/devices/sound/flt_biquad.h new file mode 100644 index 00000000000..17050c75017 --- /dev/null +++ b/src/devices/sound/flt_biquad.h @@ -0,0 +1,80 @@ +// license:BSD-3-Clause +// copyright-holders:K.Wilkins,Couriersud,Derrick Renaud,Frank Palazzolo,Jonathan Gevaryahu +#ifndef MAME_SOUND_FLT_BIQUAD_H +#define MAME_SOUND_FLT_BIQUAD_H + +#pragma once + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> filter_biquad_device + +class filter_biquad_device : public device_t, public device_sound_interface +{ +public: + enum class biquad_type : int + { + LOWPASS1P = 0, + HIGHPASS1P, + LOWPASS, + HIGHPASS, + BANDPASS, + NOTCH, + PEAK, + LOWSHELF, + HIGHSHELF + }; + + filter_biquad_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); + + // set up the filter with the specified filter parameters and return a pointer to the new device + filter_biquad_device& setup(biquad_type type, double fc, double q, double gain); + // update an existing instance with new filter parameters + void update_params(biquad_type type, double fc, double q, double gain); + + // helper setup functions to create common filters representable by biquad filters + // Sallen-Key low-pass + filter_biquad_device& opamp_sk_lowpass_setup(double r1, double r2, double r3, double r4, double c1, double c2); + // TODO when needed: Sallen-Key band-pass + // TODO when needed: Sallen-Key high-pass + + // Multiple-Feedback low-pass + filter_biquad_device& opamp_mfb_lowpass_setup(double r1, double r2, double r3, double c1, double c2); + + // Multiple-Feedback band-pass + filter_biquad_device& opamp_mfb_bandpass_setup(double r1, double r2, double r3, double c1, double c2); + + // Multiple-Feedback high-pass + filter_biquad_device& opamp_mfb_highpass_setup(double r1, double r2, double c1, double c2, double c3); + + +protected: + // device-level overrides + virtual void device_start() override; + + // sound stream update overrides + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; + +private: + void recalc(); + void step(); + + sound_stream* m_stream; + biquad_type m_type; + int m_last_sample_rate; + double m_fc; + double m_q; + double m_gain; + + stream_buffer::sample_t m_input; + double m_w0, m_w1, m_w2; /* w[k], w[k-1], w[k-2], current and previous intermediate values */ + stream_buffer::sample_t m_output; + double m_a1, m_a2; /* digital filter coefficients, denominator */ + double m_b0, m_b1, m_b2; /* digital filter coefficients, numerator */ +}; + +DECLARE_DEVICE_TYPE(FILTER_BIQUAD, filter_biquad_device) + +#endif // MAME_SOUND_FLT_BIQUAD_H diff --git a/src/devices/sound/flt_rc.cpp b/src/devices/sound/flt_rc.cpp index 8de64b37a40..48d542283e0 100644 --- a/src/devices/sound/flt_rc.cpp +++ b/src/devices/sound/flt_rc.cpp @@ -23,6 +23,7 @@ filter_rc_device::filter_rc_device(const machine_config &mconfig, const char *ta m_k(0), m_memory(0), m_type(LOWPASS), + m_last_sample_rate(0), m_R1(1), m_R2(1), m_R3(1), @@ -37,8 +38,8 @@ filter_rc_device::filter_rc_device(const machine_config &mconfig, const char *ta void filter_rc_device::device_start() { - m_stream = stream_alloc_legacy(1, 1, machine().sample_rate()); - recalc(); + m_stream = stream_alloc(1, 1, SAMPLE_RATE_OUTPUT_ADAPTIVE); + m_last_sample_rate = 0; save_item(NAME(m_k)); save_item(NAME(m_memory)); @@ -51,31 +52,37 @@ void filter_rc_device::device_start() //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void filter_rc_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void filter_rc_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - stream_sample_t const *src = inputs[0]; - stream_sample_t *dst = outputs[0]; - int memory = m_memory; + auto &src = inputs[0]; + auto &dst = outputs[0]; + stream_buffer::sample_t memory = m_memory; + + if (m_last_sample_rate != m_stream->sample_rate()) + { + recalc(); + m_last_sample_rate = m_stream->sample_rate(); + } switch (m_type) { case LOWPASS: case LOWPASS_2C: - while (samples--) + for (int sampindex = 0; sampindex < dst.samples(); sampindex++) { - memory += ((*src++ - memory) * m_k) / 0x10000; - *dst++ = memory; + memory += (src.get(sampindex) - memory) * m_k; + dst.put(sampindex, memory); } break; case HIGHPASS: case AC: - while (samples--) + for (int sampindex = 0; sampindex < dst.samples(); sampindex++) { - *dst++ = *src - memory; - memory += ((*src++ - memory) * m_k) / 0x10000; + dst.put(sampindex, src.get(sampindex) - memory); + memory += (src.get(sampindex) - memory) * m_k; } break; } @@ -93,8 +100,8 @@ void filter_rc_device::recalc() if (m_C == 0.0) { /* filter disabled */ - m_k = 0x10000; - m_memory = 0x0; + m_k = 1.0; + m_memory = 0; return; } Req = (m_R1 * (m_R2 + m_R3)) / (m_R1 + m_R2 + m_R3); @@ -103,8 +110,8 @@ void filter_rc_device::recalc() if (m_C == 0.0) { /* filter disabled */ - m_k = 0x10000; - m_memory = 0x0; + m_k = 1.0; + m_memory = 0; return; } Req = m_R1; @@ -114,8 +121,8 @@ void filter_rc_device::recalc() if (m_C == 0.0) { /* filter disabled */ - m_k = 0x0; - m_memory = 0x0; + m_k = 0; + m_memory = 0; return; } Req = m_R1; @@ -126,5 +133,5 @@ void filter_rc_device::recalc() /* Cut Frequency = 1/(2*Pi*Req*C) */ /* k = (1-(EXP(-TIMEDELTA/RC))) */ - m_k = 0x10000 - 0x10000 * (exp(-1 / (Req * m_C) / machine().sample_rate())); + m_k = 1.0 - exp(-1 / (Req * m_C) / m_stream->sample_rate()); } diff --git a/src/devices/sound/flt_rc.h b/src/devices/sound/flt_rc.h index 9c1bc7f3381..d06d0ff75d1 100644 --- a/src/devices/sound/flt_rc.h +++ b/src/devices/sound/flt_rc.h @@ -95,7 +95,7 @@ public: { m_stream->update(); set_rc(type, R1, R2, R3, C); - recalc(); + m_last_sample_rate = 0; return *this; } @@ -109,16 +109,17 @@ protected: virtual void device_start() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: void recalc(); private: sound_stream* m_stream; - int m_k; - int m_memory; + stream_buffer::sample_t m_k; + stream_buffer::sample_t m_memory; int m_type; + int m_last_sample_rate; double m_R1; double m_R2; double m_R3; diff --git a/src/devices/sound/flt_vol.cpp b/src/devices/sound/flt_vol.cpp index 8b8438f9b94..e43da0a1ee6 100644 --- a/src/devices/sound/flt_vol.cpp +++ b/src/devices/sound/flt_vol.cpp @@ -27,21 +27,19 @@ filter_volume_device::filter_volume_device(const machine_config &mconfig, const void filter_volume_device::device_start() { m_gain = 0x100; - m_stream = stream_alloc_legacy(1, 1, machine().sample_rate()); + m_stream = stream_alloc(1, 1, SAMPLE_RATE_OUTPUT_ADAPTIVE); } //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void filter_volume_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void filter_volume_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - stream_sample_t const *src = inputs[0]; - stream_sample_t *dst = outputs[0]; - - while (samples--) - *dst++ = (*src++ * m_gain) >> 8; + // no need to work here; just copy input stream to output and apply gain + outputs[0] = inputs[0]; + outputs[0].apply_gain(m_gain); } @@ -49,5 +47,5 @@ void filter_volume_device::sound_stream_update_legacy(sound_stream &stream, stre void filter_volume_device::flt_volume_set_volume(float volume) { m_stream->update(); - m_gain = int(volume * 256); + m_gain = volume; } diff --git a/src/devices/sound/flt_vol.h b/src/devices/sound/flt_vol.h index 034c3a3cf79..6a3bdab17d5 100644 --- a/src/devices/sound/flt_vol.h +++ b/src/devices/sound/flt_vol.h @@ -24,11 +24,11 @@ protected: virtual void device_start() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: sound_stream* m_stream; - int m_gain; + stream_buffer::sample_t m_gain; }; DECLARE_DEVICE_TYPE(FILTER_VOLUME, filter_volume_device) diff --git a/src/devices/sound/fm.cpp b/src/devices/sound/fm.cpp index 5679860a2f2..01d8ba11bf1 100644 --- a/src/devices/sound/fm.cpp +++ b/src/devices/sound/fm.cpp @@ -2111,12 +2111,11 @@ struct ym2203_state } // anonymous namespace /* Generate samples for one of the YM2203s */ -void ym2203_update_one(void *chip, FMSAMPLE *buffer, int length) +void ym2203_update_one(void *chip, write_stream_view &buf) { ym2203_state *F2203 = (ym2203_state *)chip; FM_OPN *OPN = &F2203->OPN; int i; - FMSAMPLE *buf = buffer; FM_CH *cch[3]; cch[0] = &F2203->CH[0]; @@ -2147,7 +2146,7 @@ void ym2203_update_one(void *chip, FMSAMPLE *buffer, int length) OPN->LFO_PM = 0; /* buffering */ - for (i=0; i < length ; i++) + for (i=0; i < buf.samples() ; i++) { /* clear outputs */ OPN->out_fm[0] = 0; @@ -2186,7 +2185,7 @@ void ym2203_update_one(void *chip, FMSAMPLE *buffer, int length) #endif /* buffering */ - buf[i] = lt; + buf.put_int(i, lt, 32768); } /* timer A control */ @@ -2727,19 +2726,18 @@ static inline void YM2608IRQMaskWrite(FM_OPN *OPN, ym2608_state *F2608, int v) } /* Generate samples for one of the YM2608s */ -void ym2608_update_one(void *chip, FMSAMPLE * const *buffer, int length) +void ym2608_update_one(void *chip, std::vector<write_stream_view> &buffer) { ym2608_state *F2608 = (ym2608_state *)chip; FM_OPN *OPN = &F2608->OPN; YM_DELTAT *DELTAT = &F2608->deltaT; int i,j; - FMSAMPLE *bufL,*bufR; FM_CH *cch[6]; int32_t *out_fm = OPN->out_fm; /* set bufer */ - bufL = buffer[0]; - bufR = buffer[1]; + auto &bufL = buffer[0]; + auto &bufR = buffer[1]; cch[0] = &F2608->CH[0]; cch[1] = &F2608->CH[1]; @@ -2770,7 +2768,7 @@ void ym2608_update_one(void *chip, FMSAMPLE * const *buffer, int length) /* buffering */ - for(i=0; i < length ; i++) + for(i=0; i < bufL.samples() ; i++) { advance_lfo(OPN); @@ -2840,14 +2838,9 @@ void ym2608_update_one(void *chip, FMSAMPLE * const *buffer, int length) lt += ((out_fm[5]>>1) & OPN->pan[10]); rt += ((out_fm[5]>>1) & OPN->pan[11]); - lt >>= FINAL_SH; - rt >>= FINAL_SH; - - Limit( lt, MAXOUT, MINOUT ); - Limit( rt, MAXOUT, MINOUT ); /* buffering */ - bufL[i] = lt; - bufR[i] = rt; + bufL.put_int_clamp(i, lt, 32768 << FINAL_SH); + bufR.put_int_clamp(i, rt, 32768 << FINAL_SH); #ifdef SAVE_SAMPLE SAVE_ALL_CHANNELS @@ -3275,19 +3268,18 @@ int ym2608_timer_over(void *chip,int c) /* YM2610(OPNB) */ /* Generate samples for one of the YM2610s */ -void ym2610_update_one(void *chip, FMSAMPLE * const *buffer, int length) +void ym2610_update_one(void *chip, std::vector<write_stream_view> &buffer) { ym2610_state *F2610 = (ym2610_state *)chip; FM_OPN *OPN = &F2610->OPN; YM_DELTAT *DELTAT = &F2610->deltaT; int i,j; - FMSAMPLE *bufL,*bufR; FM_CH *cch[4]; int32_t *out_fm = OPN->out_fm; /* buffer setup */ - bufL = buffer[0]; - bufR = buffer[1]; + auto &bufL = buffer[0]; + auto &bufR = buffer[1]; cch[0] = &F2610->CH[1]; cch[1] = &F2610->CH[2]; @@ -3323,7 +3315,7 @@ void ym2610_update_one(void *chip, FMSAMPLE * const *buffer, int length) refresh_fc_eg_chan( OPN, cch[3] ); /* buffering */ - for(i=0; i < length ; i++) + for(i=0; i < bufL.samples() ; i++) { advance_lfo(OPN); @@ -3386,20 +3378,13 @@ void ym2610_update_one(void *chip, FMSAMPLE * const *buffer, int length) lt += ((out_fm[5]>>1) & OPN->pan[10]); rt += ((out_fm[5]>>1) & OPN->pan[11]); - - lt >>= FINAL_SH; - rt >>= FINAL_SH; - - Limit( lt, MAXOUT, MINOUT ); - Limit( rt, MAXOUT, MINOUT ); - #ifdef SAVE_SAMPLE SAVE_ALL_CHANNELS #endif /* buffering */ - bufL[i] = lt; - bufR[i] = rt; + bufL.put_int_clamp(i, lt, 32768 << FINAL_SH); + bufR.put_int_clamp(i, rt, 32768 << FINAL_SH); } /* timer A control */ @@ -3411,19 +3396,18 @@ void ym2610_update_one(void *chip, FMSAMPLE * const *buffer, int length) #if BUILD_YM2610B /* Generate samples for one of the YM2610Bs */ -void ym2610b_update_one(void *chip, FMSAMPLE * const *buffer, int length) +void ym2610b_update_one(void *chip, std::vector<write_stream_view> &buffer) { ym2610_state *F2610 = (ym2610_state *)chip; FM_OPN *OPN = &F2610->OPN; YM_DELTAT *DELTAT = &F2610->deltaT; int i,j; - FMSAMPLE *bufL,*bufR; FM_CH *cch[6]; int32_t *out_fm = OPN->out_fm; /* buffer setup */ - bufL = buffer[0]; - bufR = buffer[1]; + auto &bufL = buffer[0]; + auto &bufR = buffer[1]; cch[0] = &F2610->CH[0]; cch[1] = &F2610->CH[1]; @@ -3453,7 +3437,7 @@ void ym2610b_update_one(void *chip, FMSAMPLE * const *buffer, int length) refresh_fc_eg_chan( OPN, cch[5] ); /* buffering */ - for(i=0; i < length ; i++) + for(i=0; i < bufL.samples() ; i++) { advance_lfo(OPN); @@ -3524,20 +3508,13 @@ void ym2610b_update_one(void *chip, FMSAMPLE * const *buffer, int length) lt += ((out_fm[5]>>1) & OPN->pan[10]); rt += ((out_fm[5]>>1) & OPN->pan[11]); - - lt >>= FINAL_SH; - rt >>= FINAL_SH; - - Limit( lt, MAXOUT, MINOUT ); - Limit( rt, MAXOUT, MINOUT ); - #ifdef SAVE_SAMPLE SAVE_ALL_CHANNELS #endif /* buffering */ - bufL[i] = lt; - bufR[i] = rt; + bufL.put_int_clamp(i, lt, 32768); + bufR.put_int_clamp(i, rt, 32768); } /* timer A control */ diff --git a/src/devices/sound/fm.h b/src/devices/sound/fm.h index d5d8760a449..45381d7dda9 100644 --- a/src/devices/sound/fm.h +++ b/src/devices/sound/fm.h @@ -50,7 +50,7 @@ template <typename X> constexpr TIME_TYPE MULTIPLY_TIME_BY_INT(TIME_TYPE const & #endif -typedef stream_sample_t FMSAMPLE; +typedef s32 FMSAMPLE; /* #if (FM_SAMPLE_BITS==16) typedef int16_t FMSAMPLE; @@ -108,7 +108,7 @@ void ym2203_reset_chip(void *chip); /* ** update one of chip */ -void ym2203_update_one(void *chip, FMSAMPLE *buffer, int length); +void ym2203_update_one(void *chip, write_stream_view &buffer); /* ** Write @@ -142,7 +142,7 @@ void * ym2608_init(device_t *device, int baseclock, int rate, void ym2608_clock_changed(void *chip, int clock, int rate); void ym2608_shutdown(void *chip); void ym2608_reset_chip(void *chip); -void ym2608_update_one(void *chip, FMSAMPLE * const *buffer, int length); +void ym2608_update_one(void *chip, std::vector<write_stream_view> &buffer); int ym2608_write(void *chip, int a,unsigned char v); unsigned char ym2608_read(void *chip,int a); @@ -158,10 +158,10 @@ void * ym2610_init(device_t *device, int baseclock, int rate, void ym2610_clock_changed(void *chip, int clock, int rate); void ym2610_shutdown(void *chip); void ym2610_reset_chip(void *chip); -void ym2610_update_one(void *chip, FMSAMPLE * const *buffer, int length); +void ym2610_update_one(void *chip, std::vector<write_stream_view> &buffer); #if BUILD_YM2610B -void ym2610b_update_one(void *chip, FMSAMPLE * const *buffer, int length); +void ym2610b_update_one(void *chip, std::vector<write_stream_view> &buffer); #endif /* BUILD_YM2610B */ int ym2610_write(void *chip, int a,unsigned char v); @@ -176,7 +176,7 @@ void * ym2612_init(device_t *device, int baseclock, int rate, void ym2612_clock_changed(void *chip, int clock, int rate); void ym2612_shutdown(void *chip); void ym2612_reset_chip(void *chip); -void ym2612_update_one(void *chip, FMSAMPLE * const *buffer, int length, u8 output_bits); +void ym2612_update_one(void *chip, std::vector<write_stream_view> &buffer, u8 output_bits); int ym2612_write(void *chip, int a,unsigned char v); unsigned char ym2612_read(void *chip,int a); diff --git a/src/devices/sound/fm2612.cpp b/src/devices/sound/fm2612.cpp index b3482d0ac72..4f905bf80f1 100644 --- a/src/devices/sound/fm2612.cpp +++ b/src/devices/sound/fm2612.cpp @@ -2174,7 +2174,7 @@ static void init_tables(void) /*******************************************************************************/ /* Generate samples for one of the YM2612s */ -void ym2612_update_one(void *chip, FMSAMPLE * const *buffer, int length, u8 output_bits) +void ym2612_update_one(void *chip, std::vector<write_stream_view> &buffer, u8 output_bits) { // TODO : 'ladder' effects for Mega Drive/Genesis const u8 output_shift = (output_bits > 14) ? 0 : (14 - output_bits); @@ -2183,13 +2183,12 @@ void ym2612_update_one(void *chip, FMSAMPLE * const *buffer, int length, u8 outp fm2612_FM_OPN *OPN = &F2612->OPN; int32_t *out_fm = OPN->out_fm; int i; - FMSAMPLE *bufL,*bufR; fm2612_FM_CH *cch[6]; int lt,rt; /* set bufer */ - bufL = buffer[0]; - bufR = buffer[1]; + auto &bufL = buffer[0]; + auto &bufR = buffer[1]; cch[0] = &F2612->CH[0]; cch[1] = &F2612->CH[1]; @@ -2220,7 +2219,7 @@ void ym2612_update_one(void *chip, FMSAMPLE * const *buffer, int length, u8 outp refresh_fc_eg_chan( OPN, cch[5] ); /* buffering */ - for(i=0; i < length ; i++) + for(i=0; i < bufL.samples() ; i++) { /* clear outputs */ out_fm[0] = 0; @@ -2302,8 +2301,8 @@ void ym2612_update_one(void *chip, FMSAMPLE * const *buffer, int length, u8 outp #endif /* buffering */ - bufL[i] = lt; - bufR[i] = rt; + bufL.put_int(i, lt, 32768); + bufR.put_int(i, rt, 32768); /* CSM mode: if CSM Key ON has occurred, CSM Key OFF need to be sent */ /* only if Timer A does not overflow again (i.e CSM Key ON not set again) */ diff --git a/src/devices/sound/fmopl.cpp b/src/devices/sound/fmopl.cpp index 99139310d69..cb4d5ae686e 100644 --- a/src/devices/sound/fmopl.cpp +++ b/src/devices/sound/fmopl.cpp @@ -1498,7 +1498,7 @@ const int8_t FM_OPL::lfo_pm_table[8*8*2] = { int FM_OPL::num_lock = 0; - +#if 0 static inline int limit( int val, int max, int min ) { if ( val > max ) val = max; @@ -1507,7 +1507,7 @@ static inline int limit( int val, int max, int min ) { return val; } - +#endif /* generic table initialize */ int FM_OPL::init_tables() @@ -2206,14 +2206,13 @@ void ym3812_set_update_handler(void *chip,OPL_UPDATEHANDLER UpdateHandler,device ** '*buffer' is the output buffer pointer ** 'length' is the number of samples that should be generated */ -void ym3812_update_one(void *chip, OPLSAMPLE *buffer, int length) +void ym3812_update_one(void *chip, write_stream_view &buf) { FM_OPL *OPL = (FM_OPL *)chip; uint8_t rhythm = OPL->rhythm&0x20; - OPLSAMPLE *buf = buffer; int i; - for( i=0; i < length ; i++ ) + for( i=0; i < buf.samples(); i++ ) { int lt; @@ -2242,11 +2241,6 @@ void ym3812_update_one(void *chip, OPLSAMPLE *buffer, int length) lt = OPL->output[0]; - lt >>= FINAL_SH; - - /* limit check */ - lt = limit( lt , MAXOUT, MINOUT ); - #ifdef SAVE_SAMPLE if (which==0) { @@ -2255,7 +2249,7 @@ void ym3812_update_one(void *chip, OPLSAMPLE *buffer, int length) #endif /* store to sound buffer */ - buf[i] = lt; + buf.put_int_clamp(i, lt, 32768 << FINAL_SH); OPL->advance(); } @@ -2335,14 +2329,13 @@ void ym3526_set_update_handler(void *chip,OPL_UPDATEHANDLER UpdateHandler,device ** '*buffer' is the output buffer pointer ** 'length' is the number of samples that should be generated */ -void ym3526_update_one(void *chip, OPLSAMPLE *buffer, int length) +void ym3526_update_one(void *chip, write_stream_view &buf) { FM_OPL *OPL = (FM_OPL *)chip; uint8_t rhythm = OPL->rhythm&0x20; - OPLSAMPLE *buf = buffer; int i; - for( i=0; i < length ; i++ ) + for( i=0; i < buf.samples() ; i++ ) { int lt; @@ -2371,11 +2364,6 @@ void ym3526_update_one(void *chip, OPLSAMPLE *buffer, int length) lt = OPL->output[0]; - lt >>= FINAL_SH; - - /* limit check */ - lt = limit( lt , MAXOUT, MINOUT ); - #ifdef SAVE_SAMPLE if (which==0) { @@ -2384,7 +2372,7 @@ void ym3526_update_one(void *chip, OPLSAMPLE *buffer, int length) #endif /* store to sound buffer */ - buf[i] = lt; + buf.put_int_clamp(i, lt, 32768 << FINAL_SH); OPL->advance(); } @@ -2491,15 +2479,14 @@ void y8950_set_delta_t_memory(void *chip, FM_READBYTE read_byte, FM_WRITEBYTE wr ** '*buffer' is the output buffer pointer ** 'length' is the number of samples that should be generated */ -void y8950_update_one(void *chip, OPLSAMPLE *buffer, int length) +void y8950_update_one(void *chip, write_stream_view &buf) { int i; FM_OPL *OPL = (FM_OPL *)chip; uint8_t rhythm = OPL->rhythm&0x20; YM_DELTAT &DELTAT = *OPL->deltat; - OPLSAMPLE *buf = buffer; - for( i=0; i < length ; i++ ) + for( i=0; i < buf.samples() ; i++ ) { int lt; @@ -2533,11 +2520,6 @@ void y8950_update_one(void *chip, OPLSAMPLE *buffer, int length) lt = OPL->output[0] + (OPL->output_deltat[0]>>11); - lt >>= FINAL_SH; - - /* limit check */ - lt = limit( lt , MAXOUT, MINOUT ); - #ifdef SAVE_SAMPLE if (which==0) { @@ -2546,7 +2528,7 @@ void y8950_update_one(void *chip, OPLSAMPLE *buffer, int length) #endif /* store to sound buffer */ - buf[i] = lt; + buf.put_int_clamp(i, lt, 32768 << FINAL_SH); OPL->advance(); } diff --git a/src/devices/sound/fmopl.h b/src/devices/sound/fmopl.h index add973a2369..bb484b0e41b 100644 --- a/src/devices/sound/fmopl.h +++ b/src/devices/sound/fmopl.h @@ -16,7 +16,7 @@ /* select output bits size of output : 8 or 16 */ #define OPL_SAMPLE_BITS 16 -typedef stream_sample_t OPLSAMPLE; +typedef s32 OPLSAMPLE; /* #if (OPL_SAMPLE_BITS==16) typedef int16_t OPLSAMPLE; @@ -44,7 +44,7 @@ void ym3812_reset_chip(void *chip); int ym3812_write(void *chip, int a, int v); unsigned char ym3812_read(void *chip, int a); int ym3812_timer_over(void *chip, int c); -void ym3812_update_one(void *chip, OPLSAMPLE *buffer, int length); +void ym3812_update_one(void *chip, write_stream_view &buffer); void ym3812_set_timer_handler(void *chip, OPL_TIMERHANDLER TimerHandler, device_t *device); void ym3812_set_irq_handler(void *chip, OPL_IRQHANDLER IRQHandler, device_t *device); @@ -77,7 +77,7 @@ int ym3526_timer_over(void *chip, int c); ** '*buffer' is the output buffer pointer ** 'length' is the number of samples that should be generated */ -void ym3526_update_one(void *chip, OPLSAMPLE *buffer, int length); +void ym3526_update_one(void *chip, write_stream_view &buffer); void ym3526_set_timer_handler(void *chip, OPL_TIMERHANDLER TimerHandler, device_t *device); void ym3526_set_irq_handler(void *chip, OPL_IRQHANDLER IRQHandler, device_t *device); @@ -100,7 +100,7 @@ void y8950_reset_chip(void *chip); int y8950_write(void *chip, int a, int v); unsigned char y8950_read (void *chip, int a); int y8950_timer_over(void *chip, int c); -void y8950_update_one(void *chip, OPLSAMPLE *buffer, int length); +void y8950_update_one(void *chip, write_stream_view &buffer); void y8950_set_timer_handler(void *chip, OPL_TIMERHANDLER TimerHandler, device_t *device); void y8950_set_irq_handler(void *chip, OPL_IRQHANDLER IRQHandler, device_t *device); diff --git a/src/devices/sound/gaelco.cpp b/src/devices/sound/gaelco.cpp index 41fbfc0a4c4..2a213408095 100644 --- a/src/devices/sound/gaelco.cpp +++ b/src/devices/sound/gaelco.cpp @@ -76,10 +76,10 @@ gaelco_gae1_device::gaelco_gae1_device(const machine_config &mconfig, device_typ Writes length bytes to the sound buffer ============================================================================*/ -void gaelco_gae1_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void gaelco_gae1_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { /* fill all data needed */ - for (int j = 0; j < samples; j++) + for (int j = 0; j < outputs[0].samples(); j++) { int output_l = 0, output_r = 0; @@ -177,12 +177,12 @@ void gaelco_gae1_device::sound_stream_update_legacy(sound_stream &stream, stream #endif /* now that we have computed all channels, save current data to the output buffer */ - outputs[0][j] = output_l; - outputs[1][j] = output_r; + outputs[0].put_int(j, output_l, 32768); + outputs[1].put_int(j, output_r, 32768); } - if (wavraw) - wav_add_data_32lr(wavraw, outputs[0], outputs[1], samples, 0); +// if (wavraw) +// wav_add_data_buffer(wavraw, outputs[0], outputs[1]); } /*============================================================================ @@ -253,7 +253,7 @@ void gaelco_gae1_device::gaelcosnd_w(offs_t offset, uint16_t data, uint16_t mem_ void gaelco_gae1_device::device_start() { u32 rate = clock() / 128; - m_stream = stream_alloc_legacy(0, 2, rate); + m_stream = stream_alloc(0, 2, rate); /* init volume table */ for (int vol = 0; vol < VOLUME_LEVELS; vol++) diff --git a/src/devices/sound/gaelco.h b/src/devices/sound/gaelco.h index 4f7eeaeb7a7..a598c64345d 100644 --- a/src/devices/sound/gaelco.h +++ b/src/devices/sound/gaelco.h @@ -43,7 +43,7 @@ protected: virtual void device_clock_changed() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; // device_rom_interface overrides virtual void rom_bank_updated() override; diff --git a/src/devices/sound/gb.cpp b/src/devices/sound/gb.cpp index 42944daf152..2fc1c81e5b0 100644 --- a/src/devices/sound/gb.cpp +++ b/src/devices/sound/gb.cpp @@ -142,7 +142,7 @@ cgb04_apu_device::cgb04_apu_device(const machine_config &mconfig, const char *ta void gameboy_sound_device::device_start() { - m_channel = stream_alloc_legacy(0, 2, machine().sample_rate()); + m_channel = stream_alloc(0, 2, SAMPLE_RATE_OUTPUT_ADAPTIVE); m_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gameboy_sound_device::timer_callback),this)); m_timer->adjust(clocks_to_attotime(FRAME_CYCLES/128), 0, clocks_to_attotime(FRAME_CYCLES/128)); @@ -1211,18 +1211,18 @@ void cgb04_apu_device::apu_power_off() //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void gameboy_sound_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void gameboy_sound_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - stream_sample_t *outputl = outputs[0]; - stream_sample_t *outputr = outputs[1]; - while (samples-- > 0) + auto &outputl = outputs[0]; + auto &outputr = outputs[1]; + for (int sampindex = 0; sampindex < outputl.samples(); sampindex++) { - stream_sample_t sample; - stream_sample_t left = 0; - stream_sample_t right = 0; + s32 sample; + s32 left = 0; + s32 right = 0; /* Mode 1 - Wave with Envelope and Sweep */ if (m_snd_1.on) @@ -1269,12 +1269,8 @@ void gameboy_sound_device::sound_stream_update_legacy(sound_stream &stream, stre left *= m_snd_control.vol_left; right *= m_snd_control.vol_right; - /* pump up the volume */ - left <<= 6; - right <<= 6; - /* Update the buffers */ - *outputl++ = left; - *outputr++ = right; + outputl.put_int(sampindex, left, 32768 / 64); + outputr.put_int(sampindex, right, 32768 / 64); } } diff --git a/src/devices/sound/gb.h b/src/devices/sound/gb.h index a0ea67ed0a8..fee26bd8a74 100644 --- a/src/devices/sound/gb.h +++ b/src/devices/sound/gb.h @@ -25,7 +25,7 @@ protected: virtual void device_reset() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; protected: enum diff --git a/src/devices/sound/hc55516.cpp b/src/devices/sound/hc55516.cpp index 6397d2c927c..2d96ad2cb3b 100644 --- a/src/devices/sound/hc55516.cpp +++ b/src/devices/sound/hc55516.cpp @@ -1,8 +1,18 @@ // license:BSD-3-Clause -// copyright-holders:Aaron Giles +// copyright-holders:Aaron Giles, Jonathan Gevaryahu +// thanks-to:Zonn Moore /***************************************************************************** - Harris HC-55516 (and related) emulator + Continuously Variable Slope Demodulator standalone chip emulator: + Harris HC-55516 (sometimes labeled HCI-55516 or HC1-55516) + Harris HC-55532 (sometimes labeled HCI-55532 or HC1-55532) [preliminary] + Motorola MC-3417/MC-34115 + Motorola MC-3418 + TODO: research HC-55536 and HC-55564 differences vs HC-55516 (better auto-zeroing, and removal of the encoder offset compensation DAC?) + + Driver TODOs: + /src/mame/audio/exidy440.cpp has its own internal implementation of the MC3417 and MC3418, it should be using this file instead + *****************************************************************************/ @@ -10,7 +20,7 @@ #include "hc55516.h" -/* 4x oversampling */ +/* fixed samplerate of 192khz */ #define SAMPLE_RATE (48000 * 4) #define INTEGRATOR_LEAK_TC 0.001 @@ -18,36 +28,26 @@ #define FILTER_CHARGE_TC 0.004 #define FILTER_MIN 0.0416 #define FILTER_MAX 1.0954 -#define SAMPLE_GAIN 10000.0 - - - - -DEFINE_DEVICE_TYPE(HC55516, hc55516_device, "hc55516", "HC-55516") - -hc55516_device::hc55516_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : hc55516_device(mconfig, HC55516, tag, owner, clock) -{ -} - -hc55516_device::hc55516_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) - : device_t(mconfig, type, tag, owner, clock), - device_sound_interface(mconfig, *this), - m_channel(nullptr), - m_active_clock_hi(0), - m_shiftreg_mask(0), - m_last_clock_state(0), - m_digit(0), - m_new_digit(0), - m_shiftreg(0), - m_curr_sample(0), - m_next_sample(0), - m_update_count(0), - m_filter(0), - m_integrator(0), - m_charge(0), - m_decay(0), - m_leak(0) +#define SAMPLE_GAIN (10000.0 / 32768.0) + + +//##################################### +// COMMON +//##################################### +cvsd_device_base::cvsd_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, bool active_clock_edge, uint8_t shiftreg_mask) + : device_t(mconfig, type, tag, owner, clock) + , device_sound_interface(mconfig, *this) + , m_clock_state_push_cb(*this) + , m_digin_pull_cb(*this) + , m_digout_push_cb(*this) + , m_active_clock_edge(active_clock_edge) + , m_shiftreg_mask(shiftreg_mask) + , m_last_clock_state(false) + , m_buffered_bit(false) + , m_shiftreg(0) + , m_curr_sample(0) + , m_next_sample(0) + , m_samples_generated(0) { } @@ -55,240 +55,490 @@ hc55516_device::hc55516_device(const machine_config &mconfig, device_type type, // device_start - device-specific startup //------------------------------------------------- -void hc55516_device::device_start() +void cvsd_device_base::device_start() { - start_common(0x07, true); + /* create the stream */ + m_stream = stream_alloc(0, 1, SAMPLE_RATE); + + save_item(NAME(m_last_clock_state)); + save_item(NAME(m_buffered_bit)); + save_item(NAME(m_shiftreg)); + save_item(NAME(m_curr_sample)); + save_item(NAME(m_next_sample)); + save_item(NAME(m_samples_generated)); } //------------------------------------------------- // device_reset - device-specific reset //------------------------------------------------- -void hc55516_device::device_reset() +void cvsd_device_base::device_reset() { m_last_clock_state = 0; } -DEFINE_DEVICE_TYPE(MC3417, mc3417_device, "mc3417", "MC3417") +//------------------------------------------------- +// device_clock_changed - device-specific samplerate change +//------------------------------------------------- +/*void cvsd_device_base::device_clock_changed() +{ + // do nothing. + //m_stream->set_sample_rate(clock()); +}*/ -mc3417_device::mc3417_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : hc55516_device(mconfig, MC3417, tag, owner, clock) +READ_LINE_MEMBER( cvsd_device_base::clock_r ) { + // prevent debugger from changing the internal state + if (!machine().side_effects_disabled()) + m_stream->update(); /* bring up to date first */ + return clock_state_r(); } -//------------------------------------------------- -// device_start - device-specific startup -//------------------------------------------------- +WRITE_LINE_MEMBER( cvsd_device_base::mclock_w ) +{ + clock_w(state); +} -void mc3417_device::device_start() +WRITE_LINE_MEMBER( cvsd_device_base::digin_w ) { - start_common(0x07, false); + digit_w(state); } +// the following encode related functions don't do anything yet, don't call them. +/*void cvsd_device_base::audio_in_w(int16_t data) +{ + assert(0); +}*/ -DEFINE_DEVICE_TYPE(MC3418, mc3418_device, "mc3418", "MC3418") +WRITE_LINE_MEMBER( cvsd_device_base::dec_encq_w ) +{ + assert(0); +} -mc3418_device::mc3418_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : hc55516_device(mconfig, MC3418, tag, owner, clock) +READ_LINE_MEMBER( cvsd_device_base::digout_r ) { + return 0; } -//------------------------------------------------- -// device_start - device-specific startup -//------------------------------------------------- +// default and stub implementations -void mc3418_device::device_start() +inline bool cvsd_device_base::is_external_oscillator() { - start_common(0x0f, false); + return clock() != 0; } +inline bool cvsd_device_base::is_clock_changed(bool clock_state) +{ + return ((!m_last_clock_state && clock_state) || + (m_last_clock_state && !clock_state)); +} -void hc55516_device::start_common(uint8_t _shiftreg_mask, int _active_clock_hi) +inline bool cvsd_device_base::is_active_clock_transition(bool clock_state) { - /* compute the fixed charge, decay, and leak time constants */ - m_charge = pow(exp(-1.0), 1.0 / (FILTER_CHARGE_TC * 16000.0)); - m_decay = pow(exp(-1.0), 1.0 / (FILTER_DECAY_TC * 16000.0)); - m_leak = pow(exp(-1.0), 1.0 / (INTEGRATOR_LEAK_TC * 16000.0)); + return ((clock_state != m_last_clock_state) && + (clock_state == m_active_clock_edge)); +} - m_shiftreg_mask = _shiftreg_mask; - m_active_clock_hi = _active_clock_hi; - m_last_clock_state = 0; +inline bool cvsd_device_base::current_clock_state() +{ + // keep track of the clock state given its previous state and the number of samples produced + // i.e. if we generated m_samples_generated samples, at a sample rate of SAMPLE_RATE, then are we on a positive or negative level of a squarewave at clock() hz? SAMPLE_RATE may not be an integer multiple of clock() + //uint64_t fractions_of_second = (((uint64_t)m_samples_generated)<<32) / SAMPLE_RATE; // 32.32 bits of seconds passed so far + //uint32_t clock_edges_passed = (fractions_of_second * clock() * 2)>>32 + //return (((((uint64_t)m_samples_generated<<32) * clock() * 2 / SAMPLE_RATE)>>32) & 0x1)?true:false; + return (((uint64_t)m_samples_generated * clock() * 2 / SAMPLE_RATE) & 0x01)?true:false; +} - /* create the stream */ - m_channel = stream_alloc_legacy(0, 1, SAMPLE_RATE); +void cvsd_device_base::digit_w(int digit) +{ + m_stream->update(); + m_buffered_bit = digit ? true : false; +} - save_item(NAME(m_last_clock_state)); - save_item(NAME(m_digit)); - save_item(NAME(m_new_digit)); - save_item(NAME(m_shiftreg)); - save_item(NAME(m_curr_sample)); - save_item(NAME(m_next_sample)); - save_item(NAME(m_update_count)); - save_item(NAME(m_filter)); - save_item(NAME(m_integrator)); +void cvsd_device_base::clock_w(int state) +{ + /* update the output buffer first */ + m_stream->update(); + bool clock_state = state ? true : false; + + /* only makes sense for setups with a software driven clock */ + assert(!is_external_oscillator()); + + /* speech clock changing? */ + if (is_clock_changed(clock_state)) + { + /* clear the update count */ + m_samples_generated = 0; + process_bit(m_buffered_bit, clock_state); + } + + /* update the clock */ + m_last_clock_state = clock_state; } -inline int hc55516_device::is_external_oscillator() +int cvsd_device_base::clock_state_r() { - return clock() != 0; + /* only makes sense for setups with an external oscillator */ + assert(is_external_oscillator()); + + m_stream->update(); + + return current_clock_state(); } +void cvsd_device_base::process_bit(bool bit, bool clock_state) +{ + // stub +} -inline int hc55516_device::is_active_clock_transition(int clock_state) +//------------------------------------------------- +// sound_stream_update - handle a stream update +//------------------------------------------------- + +void cvsd_device_base::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) +{ + // Stub, just return silence + auto &buffer = outputs[0]; + + m_samples_generated += buffer.samples(); + if (m_samples_generated >= SAMPLE_RATE) + m_samples_generated -= SAMPLE_RATE; + buffer.fill(0); +} + + +//######################################### +// HC55516 +//######################################### +DEFINE_DEVICE_TYPE(HC55516, hc55516_device, "hc55516", "HC-55516") + +hc55516_device::hc55516_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : hc55516_device(mconfig, HC55516, tag, owner, clock, 0xfc0, 6, 0xfc1, 4) +{ +} + +// overridable type for hc55532 etc +hc55516_device::hc55516_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint32_t sylmask, int32_t sylshift, int32_t syladd, int32_t intshift) + : cvsd_device_base(mconfig, type, tag, owner, clock, RISING, 0x7) + , m_agc_push_cb(*this) + , m_fzq_pull_cb(*this) + , m_sylmask(sylmask) + , m_sylshift(sylshift) + , m_syladd(syladd) + , m_intshift(intshift) + , m_sylfilter(0) + , m_intfilter(0) + , m_agc(true) + , m_buffered_fzq(true) { - return (( m_active_clock_hi && !m_last_clock_state && clock_state) || - (!m_active_clock_hi && m_last_clock_state && !clock_state)); } +//------------------------------------------------- +// device_start - device-specific start +//------------------------------------------------- -inline int hc55516_device::current_clock_state() +void hc55516_device::device_start() { - return ((uint64_t)m_update_count * clock() * 2 / SAMPLE_RATE) & 0x01; + cvsd_device_base::device_start(); + save_item(NAME(m_sylfilter)); + save_item(NAME(m_intfilter)); + save_item(NAME(m_agc)); + save_item(NAME(m_buffered_fzq)); + + /* resolve lines */ + m_agc_push_cb.resolve(); + m_fzq_pull_cb.resolve(); } +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- -void hc55516_device::process_digit() +void hc55516_device::device_reset() { - double integrator = m_integrator, temp; + cvsd_device_base::device_reset(); + // simulate /FZ having been held for a while + m_sylfilter = 0x3f; + m_intfilter = 0; + m_agc = true; + m_buffered_fzq = true; // assuming /FZ was just released and is now high/inactive +} - /* shift the bit into the shift register */ - m_shiftreg = (m_shiftreg << 1) | m_digit; +// device specific functions - /* move the estimator up or down a step based on the bit */ - if (m_digit) - integrator += m_filter; - else - integrator -= m_filter; +WRITE_LINE_MEMBER( hc55516_device::fzq_w ) +{ + m_buffered_fzq = state; +} - /* simulate leakage */ - integrator *= m_leak; +READ_LINE_MEMBER( hc55516_device::agc_r ) +{ + // prevent debugger from changing the internal state + if (!machine().side_effects_disabled()) + m_stream->update(); /* bring up to date first */ + return m_agc; +} + +void hc55516_device::process_bit(bool bit, bool clock_state) +{ + bool frozen = ( ( (m_intfilter >= 0x180) && (!bit) ) || + ( (m_intfilter <= -0x180) && (bit) ) ); - /* if we got all 0's or all 1's in the last n bits, bump the step up */ - if (((m_shiftreg & m_shiftreg_mask) == 0) || - ((m_shiftreg & m_shiftreg_mask) == m_shiftreg_mask)) + int32_t sum; + if (is_active_clock_transition(clock_state)) { - m_filter = FILTER_MAX - ((FILTER_MAX - m_filter) * m_charge); + // grab the /FZ state; if the callback is present, use that, otherwise use the buffered state + bool fzq_state = false; + if (!m_fzq_pull_cb.isnull()) + fzq_state = m_fzq_pull_cb(); + else + fzq_state = m_buffered_fzq; + + if (!fzq_state) // /FZ is active low, if it is active, the input bit is ignored and the inverse of the previous bit in the shifter is used instead + bit = !(m_shiftreg&1); + + /* shift the new bit into the shift register */ + m_shiftreg = (m_shiftreg << 1) | (bit?1:0); + + /* if we got all 0's or all 1's in the last n bits... */ + if (((m_shiftreg & m_shiftreg_mask) == 0) || + ((m_shiftreg & m_shiftreg_mask) == m_shiftreg_mask)) + { + // coincidence is true + if (!frozen) m_sylfilter += (((~m_sylfilter) & m_sylmask) >> m_sylshift); + } + else + { + // coincidence is false + if (!frozen) m_sylfilter += (((~m_sylfilter) & m_sylmask) >> m_sylshift) + m_syladd; + } + m_sylfilter &= 0xfff; - if (m_filter > FILTER_MAX) - m_filter = FILTER_MAX; + sum = ( ((~m_intfilter) >> m_intshift) + 1 ) & 0x3ff; } - - /* simulate decay */ - else + else // inactive clock transition { - m_filter *= m_decay; + if (m_shiftreg&1) + { + sum = ( ( ~std::max(2, m_sylfilter >> 6) ) + 1 ) & 0x3ff; + } + else + { + sum = std::max(2, m_sylfilter >> 6) & 0x3ff; + } + } - if (m_filter < FILTER_MIN) - m_filter = FILTER_MIN; + if (sum & 0x200) + sum |= ~0x3ff; // sign extend + + if (!frozen) + { + m_intfilter += sum; + m_intfilter &= 0x3ff; + if (m_intfilter & 0x200) m_intfilter |= ~0x3ff; // sign extend } - /* compute the sample as a 32-bit word */ - temp = integrator * SAMPLE_GAIN; - m_integrator = integrator; + /* scale the result (-512 to 511) to -32768 thru 32767 */ + /* + F E D C B A 9 8 7 6 5 4 3 2 1 0 + 9 8 7 6 5 4 3 2 1 0/9 8 7 6 5 4 + */ + m_next_sample = ( (m_intfilter << 6) | ( ((m_intfilter & 0x3ff) ^ 0x200 ) >> 4 ) ); - /* compress the sample range to fit better in a 16-bit word */ - if (temp < 0) - m_next_sample = (int)(temp / (-temp * (1.0 / 32768.0) + 1.0)); + // update agc state + if ( (m_intfilter >= 0x100) || (m_intfilter <= -0x100) ) + m_agc = false; else - m_next_sample = (int)(temp / (temp * (1.0 / 32768.0) + 1.0)); + m_agc = true; + + // push agc state if a callback is present + if (!m_agc_push_cb.isnull()) + m_agc_push_cb(m_agc); } -void hc55516_device::clock_w(int state) +//------------------------------------------------- +// sound_stream_update_legacy - handle a stream update +//------------------------------------------------- + +void hc55516_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - uint8_t clock_state = state ? true : false; + auto &buffer = outputs[0]; - /* only makes sense for setups with a software driven clock */ - assert(!is_external_oscillator()); +/* + if (!is_external_oscillator()) + { + // track how many samples we've updated without a clock; if it's been more than 1/32 of a second, output silence + m_samples_generated += buffer.samples(); + if (m_samples_generated > SAMPLE_RATE / 32) + { + m_samples_generated = SAMPLE_RATE; + m_next_sample = 0; + } + } +*/ - /* speech clock changing? */ - if (is_active_clock_transition(clock_state)) + if (is_external_oscillator()) { - /* update the output buffer before changing the registers */ - m_channel->update(); + /* external oscillator */ + for (int i = 0; i < buffer.samples(); i++) + { + buffer.put_int(i, m_next_sample, 32768); - /* clear the update count */ - m_update_count = 0; + m_samples_generated++; - process_digit(); + uint8_t clock_state = current_clock_state(); + + /* pull in next digit on the appropriate edge of the clock */ + if (is_clock_changed(clock_state)) + { + process_bit(m_buffered_bit, clock_state); + } + + m_last_clock_state = clock_state; + } } - /* update the clock */ - m_last_clock_state = clock_state; + /* software driven clock */ + else + for (int i = 0; i < buffer.samples(); i++) + buffer.put_int(i, m_next_sample, 32768); } -void hc55516_device::digit_w(int digit) + +//######################################### +// HC55532 +//######################################### +DEFINE_DEVICE_TYPE(HC55532, hc55532_device, "hc55532", "HC-55532") + +hc55532_device::hc55532_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : hc55516_device(mconfig, HC55532, tag, owner, clock, 0xf80, 7, 0xfe1, 5) { - if (is_external_oscillator()) - { - m_channel->update(); - m_new_digit = digit & 1; - } - else - m_digit = digit & 1; } +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- -int hc55516_device::clock_state_r() +void hc55532_device::device_reset() { - /* only makes sense for setups with an external oscillator */ - assert(is_external_oscillator()); + cvsd_device_base::device_reset(); + // simulate /FZ having been held for a while + m_sylfilter = 0x7f; + m_intfilter = 0; + m_agc = true; + m_buffered_fzq = true; // assuming /FZ was just released and is now high/inactive +} - m_channel->update(); - return current_clock_state(); + +//########################################## +// MC3417 +//########################################## +DEFINE_DEVICE_TYPE(MC3417, mc3417_device, "mc3417", "MC3417") + +mc3417_device::mc3417_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : mc3417_device(mconfig, MC3417, tag, owner, clock, 0x7) +{ } +// overridable type for mc3418 etc +mc3417_device::mc3417_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint8_t shiftreg_mask) + : cvsd_device_base(mconfig, type, tag, owner, clock, FALLING, shiftreg_mask) + , m_charge(pow(exp(-1.0), 1.0 / (FILTER_CHARGE_TC * 16000.0))) + , m_decay(pow(exp(-1.0), 1.0 / (FILTER_DECAY_TC * 16000.0))) + , m_leak(pow(exp(-1.0), 1.0 / (INTEGRATOR_LEAK_TC * 16000.0))) + , m_sylfilter_d(0.0) + , m_intfilter_d(0.0) +{ +} //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// device_start - device-specific startup //------------------------------------------------- -void hc55516_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void mc3417_device::device_start() { - stream_sample_t *buffer = outputs[0]; - int i; - int32_t sample, slope; + cvsd_device_base::device_start(); + save_item(NAME(m_sylfilter_d)); + save_item(NAME(m_intfilter_d)); +} - /* zero-length? bail */ - if (samples == 0) - return; +void mc3417_device::process_bit(bool bit, bool clock_state) +{ + if (is_active_clock_transition(clock_state)) + { + + /* shift the new bit into the shift register */ + m_shiftreg = (m_shiftreg << 1) | (bit?1:0); + + /* move the estimator up or down a step based on the bit */ + if (!bit) + m_intfilter_d += m_sylfilter_d; + else + m_intfilter_d -= m_sylfilter_d; + + /* simulate leakage */ + m_intfilter_d *= m_leak; + + /* if we got all 0's or all 1's in the last n bits, bump the step up */ + if (((m_shiftreg & m_shiftreg_mask) == 0) || + ((m_shiftreg & m_shiftreg_mask) == m_shiftreg_mask)) + { + // coincidence is true + m_sylfilter_d = FILTER_MAX - ((FILTER_MAX - m_sylfilter_d) * m_charge); + + if (m_sylfilter_d > FILTER_MAX) + m_sylfilter_d = FILTER_MAX; + } + else + { + m_sylfilter_d *= m_decay; + + if (m_sylfilter_d < FILTER_MIN) + m_sylfilter_d = FILTER_MIN; + } + + /* compute the sample as a 32-bit word */ + m_next_sample = m_intfilter_d * SAMPLE_GAIN; + } +} + +void mc3417_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) +{ + auto &buffer = outputs[0]; if (!is_external_oscillator()) { - /* track how many samples we've updated without a clock */ - m_update_count += samples; - if (m_update_count > SAMPLE_RATE / 32) + /* track how many samples we've updated without a clock; if it's been more than 1/32 of a second, output silence */ + m_samples_generated += buffer.samples(); + if (m_samples_generated > SAMPLE_RATE / 32) { - m_update_count = SAMPLE_RATE; + m_samples_generated = SAMPLE_RATE; m_next_sample = 0; } } /* compute the interpolation slope */ - sample = m_curr_sample; - slope = ((int32_t)m_next_sample - sample) / samples; + stream_buffer::sample_t sample = m_curr_sample; + stream_buffer::sample_t slope = (m_next_sample - sample) / buffer.samples(); m_curr_sample = m_next_sample; if (is_external_oscillator()) { /* external oscillator */ - for (i = 0; i < samples; i++, sample += slope) + for (int i = 0; i < buffer.samples(); i++, sample += slope) { - uint8_t clock_state; - - *buffer++ = sample; + buffer.put(i, sample); - m_update_count++; + m_samples_generated++; - clock_state = current_clock_state(); + uint8_t clock_state = current_clock_state(); /* pull in next digit on the appropriate edge of the clock */ - if (is_active_clock_transition(clock_state)) + if (is_clock_changed(clock_state)) { - m_digit = m_new_digit; - - process_digit(); + process_bit(m_buffered_bit, clock_state); } m_last_clock_state = clock_state; @@ -297,16 +547,18 @@ void hc55516_device::sound_stream_update_legacy(sound_stream &stream, stream_sam /* software driven clock */ else - for (i = 0; i < samples; i++, sample += slope) - *buffer++ = sample; + for (int i = 0; i < buffer.samples(); i++, sample += slope) + buffer.put(i, sample); } -void mc3417_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) -{ - hc55516_device::sound_stream_update_legacy(stream, inputs, outputs, samples); -} -void mc3418_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) + +//########################################## +// MC3418 +//########################################## +DEFINE_DEVICE_TYPE(MC3418, mc3418_device, "mc3418", "MC3418") + +mc3418_device::mc3418_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : mc3417_device(mconfig, MC3418, tag, owner, clock, 0xf) { - hc55516_device::sound_stream_update_legacy(stream, inputs, outputs, samples); } diff --git a/src/devices/sound/hc55516.h b/src/devices/sound/hc55516.h index 96284167c52..48c1b768a4f 100644 --- a/src/devices/sound/hc55516.h +++ b/src/devices/sound/hc55516.h @@ -1,95 +1,176 @@ // license:BSD-3-Clause -// copyright-holders:Aaron Giles +// copyright-holders:Aaron Giles, Jonathan Gevaryahu +// thanks-to:Zonn Moore #ifndef MAME_SOUND_HC55516_H #define MAME_SOUND_HC55516_H #pragma once -class hc55516_device : public device_t, public device_sound_interface +class cvsd_device_base : public device_t, public device_sound_interface { public: - hc55516_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - - /* sets the digit (0 or 1) */ - void digit_w(int digit); - - /* sets the clock state (0 or 1, clocked on the rising edge) */ - void clock_w(int state); - - /* returns whether the clock is currently LO or HI */ - int clock_state_r(); + enum + { + RISING=true, + FALLING=false + }; + + auto clock_state_cb() { return m_clock_state_push_cb.bind(); } // A clock state change callback. Using this is a bad idea due to lack of synchronization to other devices. TODO: remove this. + auto digin_cb() { return m_digin_pull_cb.bind(); } // Digital in pull callback function, for use if a clock is specified and we need to pull in the digital in pin state, otherwise unused. TODO: this is not hooked up yet, and should be. + auto digout_cb() { return m_digout_push_cb.bind(); } // Digital out push callback function. TODO: this is not hooked up or implemented yet, although it is only really relevant for devices which use the CVSD chips in encode mode. + + READ_LINE_MEMBER( clock_r ); // Clock pull, really only relevant of something manually polls the clock (and clock is specified), which is a very bad design pattern and will cause synchronization/missed clock transition issues. This function WILL ASSERT if it is called and the clock hz is NOT specified! TODO: remove all use of this, and remove it. + WRITE_LINE_MEMBER( mclock_w ); // Clock push; this function WILL ASSERT if it is called and the clock hz IS specified! + WRITE_LINE_MEMBER( digin_w ); // Digital in push to the pin, as a pseudo 'buffer' implemented within the cvsd device itself. This is not technically accurate to hardware, and in the future should be deprecated in favor of digin_cb once the latter is implemented. + WRITE_LINE_MEMBER( dec_encq_w ); //DEC/ENC decode/encode select push. This is not implemented yet, and relies on an input audio stream. TODO: implement this beyond a do-nothing stub + READ_LINE_MEMBER( digout_r ); // Digital out pull. TODO: this is not hooked up or implemented yet, although it is only really relevant for devices which use the CVSD chips in encode mode. + //void audio_in_w(stream_buffer::sample_t data); // Audio In pin, an analog value of the audio waveform being pushed to the chip. TODO: this is not hooked up or implemented yet, and this should really be handled as an input stream from a separate DAC device, not a value push function at all. + void digit_w(int digit); /* sets the buffered digit (0 or 1), common to all chips. TODO: replace all use of this with digin_cb once implemented */ + void clock_w(int state); /* sets the clock state (0 or 1, clocked on the rising edge), common to all chips */ + virtual int clock_state_r(); /* returns whether the clock is currently LO or HI, common to all chips. TODO: get rid of all use of this, then get rid of it. */ protected: - hc55516_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + cvsd_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, bool active_clock_edge, uint8_t shiftreg_mask); // device-level overrides virtual void device_start() override; virtual void device_reset() override; + //virtual void device_clock_changed() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; - void start_common(uint8_t _shiftreg_mask, int _active_clock_hi); + // callbacks + devcb_write_line m_clock_state_push_cb; ///TODO: get rid of this, if you use it you should feel bad + devcb_read_line m_digin_pull_cb; + devcb_write_line m_digout_push_cb; - // internal state - sound_stream *m_channel; - int m_active_clock_hi; - uint8_t m_shiftreg_mask; + // const state defined by constructor + const bool m_active_clock_edge; + const uint8_t m_shiftreg_mask; // it may be desirable to allow this to be changed by the user under some circumstances - uint8_t m_last_clock_state; - uint8_t m_digit; - uint8_t m_new_digit; + // internal state + sound_stream *m_stream; + bool m_last_clock_state; + bool m_buffered_bit; uint8_t m_shiftreg; + stream_buffer::sample_t m_curr_sample; + stream_buffer::sample_t m_next_sample; + uint32_t m_samples_generated; - int16_t m_curr_sample; - int16_t m_next_sample; + // specific internal handler overrides, overridden by each chip + virtual void process_bit(bool bit, bool clock_state); - uint32_t m_update_count; + ///TODO: get rid of these + inline bool is_external_oscillator(); + inline bool is_clock_changed(bool clock_state); + inline bool is_active_clock_transition(bool clock_state); + inline bool current_clock_state(); - double m_filter; - double m_integrator; - - double m_charge; - double m_decay; - double m_leak; - - inline int is_external_oscillator(); - inline int is_active_clock_transition(int clock_state); - inline int current_clock_state(); - void process_digit(); }; -class mc3417_device : public hc55516_device +class hc55516_device : public cvsd_device_base { public: - mc3417_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + hc55516_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + auto fzq_cb() { return m_fzq_pull_cb.bind(); } // /FZ (partial reset) pull callback, ok to leave unconnected (we assume it is pulled high) + auto agc_cb() { return m_agc_push_cb.bind(); } // AGC callback function, called to push the state if the AGC pin changes, ok to leave unconnected + + WRITE_LINE_MEMBER( fzq_w ); // /FZ (partial reset) push + READ_LINE_MEMBER( agc_r ); // AGC pull + /* TODO: These are only relevant for encode mode, which isn't done yet! */ + //WRITE_LINE_MEMBER( aptq_w ); // /APT (silence encoder output) push + //WRITE_LINE_MEMBER( dec_encq_w ); // DEC/ENC decode/encode select push protected: + // overridable type for subclass + hc55516_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint32_t sylmask, int32_t sylshift, int32_t syladd, int32_t intshift); + // device-level overrides virtual void device_start() override; + virtual void device_reset() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; + + // callbacks + devcb_write_line m_agc_push_cb; + devcb_read_line m_fzq_pull_cb; + + // const coefficients defined by constructor + const uint32_t m_sylmask; + const int32_t m_sylshift; + const int32_t m_syladd; + const int32_t m_intshift; + + // internal state + int32_t m_sylfilter; + int32_t m_intfilter; + bool m_agc; + bool m_buffered_fzq; + + // internal handlers + virtual void process_bit(bool bit, bool clock_state) override; }; -class mc3418_device : public hc55516_device +class hc55532_device : public hc55516_device { public: - mc3418_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + hc55532_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); +protected: + // device-level overrides + virtual void device_reset() override; +}; + + +class mc3417_device : public cvsd_device_base +{ +public: + mc3417_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + // override for clock_w + //virtual void clock_w(int state) override; protected: + // overridable type for subclass + mc3417_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint8_t shiftreg_mask); + // device-level overrides virtual void device_start() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; + + // const coefficients defined by constructor; should these be adjustable by the user or externally defined, as they are implemented using a set of two small lowpass filters outside the chip? + const double m_charge; + const double m_decay; + const double m_leak; + + // internal state + double m_sylfilter_d; + double m_intfilter_d; + + // internal handlers + virtual void process_bit(bool bit, bool clock_state) override; +}; + + +class mc3418_device : public mc3417_device +{ +public: + mc3418_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); }; DECLARE_DEVICE_TYPE(HC55516, hc55516_device) +DECLARE_DEVICE_TYPE(HC55532, hc55532_device) +//DECLARE_DEVICE_TYPE(HC55536, hc55536_device) +//DECLARE_DEVICE_TYPE(HC55564, hc55564_device) DECLARE_DEVICE_TYPE(MC3417, mc3417_device) +//DECLARE_DEVICE_TYPE(MC34115, mc34115_device) DECLARE_DEVICE_TYPE(MC3418, mc3418_device) #endif // MAME_SOUND_HC55516_H diff --git a/src/devices/sound/huc6230.cpp b/src/devices/sound/huc6230.cpp index fd2ef5b9689..31e143fea8c 100644 --- a/src/devices/sound/huc6230.cpp +++ b/src/devices/sound/huc6230.cpp @@ -21,12 +21,12 @@ constexpr int clamp(int val, int min, int max) { return std::min(max, std::max(min, val)); } -void huc6230_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void huc6230_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - for (int i = 0; i < samples; i++) + for (int i = 0; i < outputs[0].samples(); i++) { - outputs[0][i] = inputs[0][i]; - outputs[1][i] = inputs[1][i]; + s32 samp0 = inputs[0].get(i) * 32768.0; + s32 samp1 = inputs[1].get(i) * 32768.0; for (int adpcm = 0; adpcm < 2; adpcm++) { @@ -35,9 +35,12 @@ void huc6230_device::sound_stream_update_legacy(sound_stream &stream, stream_sam if (!channel->m_playing) continue; - outputs[0][i] = clamp(outputs[0][i] + ((channel->m_output * channel->m_lvol) >> 3), -32768, 32767); - outputs[1][i] = clamp(outputs[1][i] + ((channel->m_output * channel->m_rvol) >> 3), -32768, 32767); + samp0 = clamp(samp0 + ((channel->m_output * channel->m_lvol) >> 3), -32768, 32767); + samp1 = clamp(samp1 + ((channel->m_output * channel->m_rvol) >> 3), -32768, 32767); } + + outputs[0].put_int(i, samp0, 32768); + outputs[1].put_int(i, samp1, 32768); } } @@ -172,7 +175,7 @@ void huc6230_device::device_start() m_vca_cb.resolve_safe(); - m_stream = stream_alloc_legacy(2, 2, clock() / 6); + m_stream = stream_alloc(2, 2, clock() / 6); m_adpcm_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(huc6230_device::adpcm_timer),this)); for (int i = 0; i < 2; i++) diff --git a/src/devices/sound/huc6230.h b/src/devices/sound/huc6230.h index 27e67ce41a3..a2ca7824617 100644 --- a/src/devices/sound/huc6230.h +++ b/src/devices/sound/huc6230.h @@ -28,7 +28,7 @@ protected: virtual void device_clock_changed() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: struct adpcm_channel { diff --git a/src/devices/sound/i5000.cpp b/src/devices/sound/i5000.cpp index 747d5e96e19..6978b9336f3 100644 --- a/src/devices/sound/i5000.cpp +++ b/src/devices/sound/i5000.cpp @@ -44,7 +44,7 @@ void i5000snd_device::device_start() m_lut_volume[0xff] = 0; // create the stream - m_stream = stream_alloc_legacy(0, 2, clock() / 0x400); + m_stream = stream_alloc(0, 2, clock() / 0x400); m_rom_base = (uint16_t *)device().machine().root_device().memregion(":i5000snd")->base(); m_rom_mask = device().machine().root_device().memregion(":i5000snd")->bytes() / 2 - 1; @@ -114,9 +114,9 @@ bool i5000snd_device::read_sample(int ch) } -void i5000snd_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void i5000snd_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - for (int i = 0; i < samples; i++) + for (int i = 0; i < outputs[0].samples(); i++) { int32_t mix_l = 0; int32_t mix_r = 0; @@ -157,8 +157,8 @@ void i5000snd_device::sound_stream_update_legacy(sound_stream &stream, stream_sa mix_l += m_channels[ch].output_l; } - outputs[0][i] = mix_r / 16; - outputs[1][i] = mix_l / 16; + outputs[0].put_int(i, mix_r, 32768 * 16); + outputs[1].put_int(i, mix_l, 32768 * 16); } } diff --git a/src/devices/sound/i5000.h b/src/devices/sound/i5000.h index 0bb994ebdb6..abd84f5ac43 100644 --- a/src/devices/sound/i5000.h +++ b/src/devices/sound/i5000.h @@ -33,7 +33,7 @@ protected: virtual void device_start() override; virtual void device_reset() override; - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; sound_stream *m_stream; diff --git a/src/devices/sound/ics2115.cpp b/src/devices/sound/ics2115.cpp index fa570814019..868bcb70bc4 100644 --- a/src/devices/sound/ics2115.cpp +++ b/src/devices/sound/ics2115.cpp @@ -63,7 +63,7 @@ void ics2115_device::device_start() m_timer[0].timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(ics2115_device::timer_cb_0),this), this); m_timer[1].timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(ics2115_device::timer_cb_1),this), this); - m_stream = stream_alloc_legacy(0, 2, clock() / (32 * 32)); + m_stream = stream_alloc(0, 2, clock() / (32 * 32)); m_irq_cb.resolve_safe(); @@ -316,7 +316,7 @@ int ics2115_device::ics2115_voice::update_oscillator() } //TODO: proper interpolation for 8-bit samples (looping) -stream_sample_t ics2115_device::get_sample(ics2115_voice& voice) +s32 ics2115_device::get_sample(ics2115_voice& voice) { const u32 curaddr = voice.osc.acc >> 12; u32 nextaddr; @@ -385,13 +385,13 @@ void ics2115_device::ics2115_voice::update_ramp() } } -int ics2115_device::fill_output(ics2115_voice& voice, stream_sample_t * const outputs[2], int samples) +int ics2115_device::fill_output(ics2115_voice& voice, std::vector<write_stream_view> &outputs) { bool irq_invalid = false; const u16 fine = 1 << (3*(voice.vol.incr >> 6)); voice.vol.add = (voice.vol.incr & 0x3f)<< (10 - fine); - for (int i = 0; i < samples; i++) + for (int i = 0; i < outputs[0].samples(); i++) { const u32 volacc = (voice.vol.acc >> 10) & 0xffff; const u32 volume = (m_volume[volacc >> 4] * voice.state.ramp) >> 6; @@ -403,15 +403,15 @@ int ics2115_device::fill_output(ics2115_voice& voice, stream_sample_t * const ou //final output, even if they are not running. This means that whatever data value //that the voice is pointing at is contributing to the summation. //(austere note: this will of course fix some of the glitches due to multiple transition) - stream_sample_t sample = get_sample(voice); + s32 sample = get_sample(voice); //15-bit volume + (5-bit worth of 32 channel sum) + 16-bit samples = 4-bit extra if (!m_vmode || voice.playing()) { /*if (voice.playing()) {*/ - outputs[0][i] += (sample * vleft) >> (5 + volume_bits - 16); - outputs[1][i] += (sample * vright) >> (5 + volume_bits - 16); + outputs[0].add_int(i, (sample * vleft) >> (5 + volume_bits), 32768); + outputs[1].add_int(i, (sample * vright) >> (5 + volume_bits), 32768); } voice.update_ramp(); @@ -426,10 +426,10 @@ int ics2115_device::fill_output(ics2115_voice& voice, stream_sample_t * const ou return irq_invalid; } -void ics2115_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void ics2115_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - memset(outputs[0], 0, samples * sizeof(stream_sample_t)); - memset(outputs[1], 0, samples * sizeof(stream_sample_t)); + outputs[0].fill(0); + outputs[1].fill(0); bool irq_invalid = false; for (int osc = 0; osc <= m_active_osc; osc++) @@ -443,11 +443,11 @@ void ics2115_device::sound_stream_update_legacy(sound_stream &stream, stream_sam /* #ifdef ICS2115_DEBUG u32 curaddr = ((voice.osc.saddr << 20) & 0xffffff) | (voice.osc.acc >> 12); - stream_sample_t sample = get_sample(voice); + s32 sample = get_sample(voice); logerror("[%06x=%04x]", curaddr, (s16)sample); #endif */ - if (fill_output(voice, outputs, samples)) + if (fill_output(voice, outputs)) irq_invalid = true; #ifdef ICS2115_DEBUG @@ -479,13 +479,6 @@ void ics2115_device::sound_stream_update_legacy(sound_stream &stream, stream_sam logerror("|"); #endif - //rescale - for (int i = 0; i < samples; i++) - { - outputs[0][i] >>= 16; - outputs[1][i] >>= 16; - } - if (irq_invalid) recalc_irq(); diff --git a/src/devices/sound/ics2115.h b/src/devices/sound/ics2115.h index 777ee8eabf4..5dd18fcf4ed 100644 --- a/src/devices/sound/ics2115.h +++ b/src/devices/sound/ics2115.h @@ -39,7 +39,7 @@ protected: virtual void device_clock_changed() override; // device_sound_interface overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; // device_memory_interface configuration virtual space_config_vector memory_space_config() const override; @@ -119,8 +119,8 @@ private: void recalc_irq(); // stream helper functions - int fill_output(ics2115_voice& voice, stream_sample_t * const outputs[2], int samples); - stream_sample_t get_sample(ics2115_voice& voice); + int fill_output(ics2115_voice& voice, std::vector<write_stream_view> &outputs); + s32 get_sample(ics2115_voice& voice); u8 read_sample(ics2115_voice& voice, u32 addr) { return m_cache.read_byte((voice.osc.saddr << 20) | (addr & 0xfffff)); } sound_stream *m_stream; diff --git a/src/devices/sound/iopspu.cpp b/src/devices/sound/iopspu.cpp index 73399b1ef2c..0267c31eadb 100644 --- a/src/devices/sound/iopspu.cpp +++ b/src/devices/sound/iopspu.cpp @@ -89,9 +89,10 @@ void iop_spu_device::dma_done(int bank) core.m_status &= ~STATUS_DMA_ACTIVE; } -void iop_spu_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void iop_spu_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { // TODO + outputs[0].fill(0); } TIMER_CALLBACK_MEMBER(iop_spu_device::autodma_done_timer_hack) diff --git a/src/devices/sound/iopspu.h b/src/devices/sound/iopspu.h index 4348e471051..bea55615c04 100644 --- a/src/devices/sound/iopspu.h +++ b/src/devices/sound/iopspu.h @@ -48,7 +48,7 @@ protected: virtual void device_reset() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; // HACK: This timer is currently used to trigger an interrupt after the auto-DMA-transferred buffer would have been // mixed and played back, as the PS2 BIOS pulls a null return address and crashes if we trigger the auto-DMA-complete diff --git a/src/devices/sound/iremga20.cpp b/src/devices/sound/iremga20.cpp index ba49eaa75c4..3ec07d3de35 100644 --- a/src/devices/sound/iremga20.cpp +++ b/src/devices/sound/iremga20.cpp @@ -73,7 +73,7 @@ iremga20_device::iremga20_device(const machine_config &mconfig, const char *tag, void iremga20_device::device_start() { - m_stream = stream_alloc_legacy(0, 2, clock()/4); + m_stream = stream_alloc(0, 2, clock()/4); save_item(NAME(m_regs)); for (int i = 0; i < 4; i++) @@ -126,19 +126,17 @@ void iremga20_device::rom_bank_updated() } //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void iremga20_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void iremga20_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - stream_sample_t *outL, *outR; + auto &outL = outputs[0]; + auto &outR = outputs[1]; - outL = outputs[0]; - outR = outputs[1]; - - for (int i = 0; i < samples; i++) + for (int i = 0; i < outL.samples(); i++) { - stream_sample_t sampleout = 0; + s32 sampleout = 0; for (auto &ch : m_channel) { @@ -160,9 +158,8 @@ void iremga20_device::sound_stream_update_legacy(sound_stream &stream, stream_sa } } - sampleout >>= 2; - outL[i] = sampleout; - outR[i] = sampleout; + outL.put_int(i, sampleout, 32768 * 4); + outR.put_int(i, sampleout, 32768 * 4); } } diff --git a/src/devices/sound/iremga20.h b/src/devices/sound/iremga20.h index df9942c9ccb..ae60c563d78 100644 --- a/src/devices/sound/iremga20.h +++ b/src/devices/sound/iremga20.h @@ -36,7 +36,7 @@ protected: virtual void device_clock_changed() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; // device_rom_interface overrides virtual void rom_bank_updated() override; diff --git a/src/devices/sound/k005289.cpp b/src/devices/sound/k005289.cpp index bf07743f7d3..00fe18e2c2f 100644 --- a/src/devices/sound/k005289.cpp +++ b/src/devices/sound/k005289.cpp @@ -59,9 +59,7 @@ k005289_device::k005289_device(const machine_config &mconfig, const char *tag, d , m_sound_prom(*this, DEVICE_SELF) , m_stream(nullptr) , m_rate(0) - , m_mixer_table(nullptr) , m_mixer_lookup(nullptr) - , m_mixer_buffer(nullptr) { } @@ -74,10 +72,7 @@ void k005289_device::device_start() { /* get stream channels */ m_rate = clock() / CLOCK_DIVIDER; - m_stream = stream_alloc_legacy(0, 1, m_rate); - - /* allocate a pair of buffers to mix into - 1 second's worth should be more than enough */ - m_mixer_buffer = std::make_unique<short[]>(2 * m_rate); + m_stream = stream_alloc(0, 1, m_rate); /* build the mixer table */ make_mixer_table(2); @@ -101,17 +96,19 @@ void k005289_device::device_start() //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void k005289_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void k005289_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - stream_sample_t *buffer = outputs[0]; + auto &buffer = outputs[0]; short *mix; int i,v,f; /* zap the contents of the mixer buffer */ - memset(m_mixer_buffer.get(), 0, samples * sizeof(int16_t)); + if (m_mixer_buffer.size() < buffer.samples()) + m_mixer_buffer.resize(buffer.samples()); + std::fill_n(&m_mixer_buffer[0], buffer.samples(), 0); v=m_volume[0]; f=m_frequency[0]; @@ -120,10 +117,10 @@ void k005289_device::sound_stream_update_legacy(sound_stream &stream, stream_sam const unsigned char *w = &m_sound_prom[m_waveform[0]]; int c = m_counter[0]; - mix = m_mixer_buffer.get(); + mix = &m_mixer_buffer[0]; /* add our contribution */ - for (i = 0; i < samples; i++) + for (i = 0; i < buffer.samples(); i++) { int offs; @@ -143,10 +140,10 @@ void k005289_device::sound_stream_update_legacy(sound_stream &stream, stream_sam const unsigned char *w = &m_sound_prom[m_waveform[1]]; int c = m_counter[1]; - mix = m_mixer_buffer.get(); + mix = &m_mixer_buffer[0]; /* add our contribution */ - for (i = 0; i < samples; i++) + for (i = 0; i < buffer.samples(); i++) { int offs; @@ -160,9 +157,9 @@ void k005289_device::sound_stream_update_legacy(sound_stream &stream, stream_sam } /* mix it down */ - mix = m_mixer_buffer.get(); - for (i = 0; i < samples; i++) - *buffer++ = m_mixer_lookup[*mix++]; + mix = &m_mixer_buffer[0]; + for (i = 0; i < buffer.samples(); i++) + buffer.put(i, m_mixer_lookup[*mix++]); } @@ -174,22 +171,22 @@ void k005289_device::sound_stream_update_legacy(sound_stream &stream, stream_sam void k005289_device::make_mixer_table(int voices) { int count = voices * 128; - int i; int gain = 16; /* allocate memory */ - m_mixer_table = std::make_unique<int16_t[]>(256 * voices); + m_mixer_table = std::make_unique<stream_buffer::sample_t []>(256 * voices); /* find the middle of the table */ - m_mixer_lookup = m_mixer_table.get() + (128 * voices); + m_mixer_lookup = &m_mixer_table[128 * voices]; /* fill in the table - 16 bit case */ - for (i = 0; i < count; i++) + for (int i = 0; i < count; i++) { int val = i * gain * 16 / voices; if (val > 32767) val = 32767; - m_mixer_lookup[ i] = val; - m_mixer_lookup[-i] = -val; + stream_buffer::sample_t fval = stream_buffer::sample_t(val) / 32768.0; + m_mixer_lookup[ i] = fval; + m_mixer_lookup[-i] = -fval; } } diff --git a/src/devices/sound/k005289.h b/src/devices/sound/k005289.h index a8dc7b1d0b0..989ab15ae6d 100644 --- a/src/devices/sound/k005289.h +++ b/src/devices/sound/k005289.h @@ -26,7 +26,7 @@ protected: virtual void device_start() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: void make_mixer_table(int voices); @@ -36,9 +36,9 @@ private: int m_rate; /* mixer tables and internal buffers */ - std::unique_ptr<int16_t[]> m_mixer_table; - int16_t *m_mixer_lookup; - std::unique_ptr<short[]> m_mixer_buffer; + std::unique_ptr<stream_buffer::sample_t []> m_mixer_table; + stream_buffer::sample_t *m_mixer_lookup; + std::vector<short> m_mixer_buffer; uint32_t m_counter[2]; uint16_t m_frequency[2]; diff --git a/src/devices/sound/k007232.cpp b/src/devices/sound/k007232.cpp index 3b35eeb9d5c..a8b6c135a51 100644 --- a/src/devices/sound/k007232.cpp +++ b/src/devices/sound/k007232.cpp @@ -86,7 +86,7 @@ void k007232_device::device_start() for (auto & elem : m_wreg) elem = 0; - m_stream = stream_alloc_legacy(0, 2, clock()/128); + m_stream = stream_alloc(0, 2, clock()/128); save_item(STRUCT_MEMBER(m_channel, vol)); save_item(STRUCT_MEMBER(m_channel, addr)); @@ -206,14 +206,11 @@ void k007232_device::set_bank(int chan_a_bank, int chan_b_bank) //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void k007232_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void k007232_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - memset(outputs[0], 0, samples * sizeof(stream_sample_t)); - memset(outputs[1], 0, samples * sizeof(stream_sample_t)); - if (K007232_LOG_PCM) { for (int i = 0; i < KDAC_A_PCM_MAX; i++) @@ -239,8 +236,9 @@ void k007232_device::sound_stream_update_legacy(sound_stream &stream, stream_sam } } - for (int j = 0; j < samples; j++) + for (int j = 0; j < outputs[0].samples(); j++) { + s32 lsum = 0, rsum = 0; for (int i = 0; i < KDAC_A_PCM_MAX; i++) { channel_t *channel = &m_channel[i]; @@ -279,9 +277,11 @@ void k007232_device::sound_stream_update_legacy(sound_stream &stream, stream_sam int out = (read_sample(i, addr) & 0x7f) - 0x40; - outputs[0][j] += out * vol_a; - outputs[1][j] += out * vol_b; + lsum += out * vol_a; + rsum += out * vol_b; } } + outputs[0].put_int(j, lsum, 32768); + outputs[1].put_int(j, rsum, 32768); } } diff --git a/src/devices/sound/k007232.h b/src/devices/sound/k007232.h index e9a4ba255da..57cb72fcf7b 100644 --- a/src/devices/sound/k007232.h +++ b/src/devices/sound/k007232.h @@ -37,7 +37,7 @@ protected: virtual void device_clock_changed() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; // device_memory_interface configuration virtual space_config_vector memory_space_config() const override; diff --git a/src/devices/sound/k051649.cpp b/src/devices/sound/k051649.cpp index 0e39a94230a..9a1f748580e 100644 --- a/src/devices/sound/k051649.cpp +++ b/src/devices/sound/k051649.cpp @@ -56,7 +56,6 @@ k051649_device::k051649_device(const machine_config &mconfig, const char *tag, d , device_sound_interface(mconfig, *this) , m_stream(nullptr) , m_rate(0) - , m_mixer_table(nullptr) , m_mixer_lookup(nullptr) , m_test(0) { @@ -71,7 +70,7 @@ void k051649_device::device_start() { // get stream channels m_rate = clock()/16; - m_stream = stream_alloc_legacy(0, 1, m_rate); + m_stream = stream_alloc(0, 1, m_rate); // allocate a buffer to mix into - 1 second's worth should be more than enough m_mixer_buffer.resize(2 * m_rate); @@ -140,10 +139,10 @@ void k051649_device::device_clock_changed() //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void k051649_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void k051649_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { // zap the contents of the mixer buffer std::fill(m_mixer_buffer.begin(), m_mixer_buffer.end(), 0); @@ -159,7 +158,7 @@ void k051649_device::sound_stream_update_legacy(sound_stream &stream, stream_sam const int step = voice.frequency; // add our contribution - for (int i = 0; i < samples; i++) + for (int i = 0; i < outputs[0].samples(); i++) { c += 32; while (c > step) @@ -177,9 +176,9 @@ void k051649_device::sound_stream_update_legacy(sound_stream &stream, stream_sam } // mix it down - stream_sample_t *buffer = outputs[0]; - for (int i = 0; i < samples; i++) - *buffer++ = m_mixer_lookup[m_mixer_buffer[i]]; + auto &buffer = outputs[0]; + for (int i = 0; i < buffer.samples(); i++) + buffer.put(i, m_mixer_lookup[m_mixer_buffer[i]]); } @@ -309,16 +308,17 @@ u8 k051649_device::k051649_test_r() void k051649_device::make_mixer_table(int voices) { // allocate memory - m_mixer_table = std::make_unique<s16[]>(512 * voices); + m_mixer_table.resize(512 * voices); // find the middle of the table - m_mixer_lookup = m_mixer_table.get() + (256 * voices); + m_mixer_lookup = &m_mixer_table[256 * voices]; // fill in the table - 16 bit case for (int i = 0; i < (voices * 256); i++) { const int val = std::min(32767, i * DEF_GAIN * 16 / voices); - m_mixer_lookup[ i] = val; - m_mixer_lookup[-i] = -val; + stream_buffer::sample_t fval = stream_buffer::sample_t(val) / 32768.0; + m_mixer_lookup[ i] = fval; + m_mixer_lookup[-i] = -fval; } } diff --git a/src/devices/sound/k051649.h b/src/devices/sound/k051649.h index 2fda5936685..368ef6c58a9 100644 --- a/src/devices/sound/k051649.h +++ b/src/devices/sound/k051649.h @@ -38,7 +38,7 @@ protected: virtual void device_clock_changed() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: // Parameters for a channel @@ -71,8 +71,8 @@ private: int m_rate; /* mixer tables and internal buffers */ - std::unique_ptr<s16[]> m_mixer_table; - s16 *m_mixer_lookup; + std::vector<stream_buffer::sample_t> m_mixer_table; + stream_buffer::sample_t *m_mixer_lookup; std::vector<s16> m_mixer_buffer; /* chip registers */ diff --git a/src/devices/sound/k053260.cpp b/src/devices/sound/k053260.cpp index ff2356ac600..7337b0c8b91 100644 --- a/src/devices/sound/k053260.cpp +++ b/src/devices/sound/k053260.cpp @@ -115,7 +115,7 @@ void k053260_device::device_start() m_sh1_cb.resolve_safe(); m_sh2_cb.resolve_safe(); - m_stream = stream_alloc_legacy( 0, 2, clock() / CLOCKS_PER_SAMPLE ); + m_stream = stream_alloc( 0, 2, clock() / CLOCKS_PER_SAMPLE ); /* register with the save state system */ save_item(NAME(m_portdata)); @@ -301,25 +301,17 @@ void k053260_device::write(offs_t offset, u8 data) } } -static inline int limit(int val, int max, int min) -{ - return std::max(min, std::min(max, val)); -} - -static constexpr s32 MAXOUT = 0x7fff; -static constexpr s32 MINOUT = -0x8000; - //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void k053260_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void k053260_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { if (m_mode & 2) { - for ( int j = 0; j < samples; j++ ) + for ( int j = 0; j < outputs[0].samples(); j++ ) { - stream_sample_t buffer[2] = {0, 0}; + s32 buffer[2] = {0, 0}; for (auto & voice : m_voice) { @@ -327,14 +319,14 @@ void k053260_device::sound_stream_update_legacy(sound_stream &stream, stream_sam voice.play(buffer); } - outputs[0][j] = limit( buffer[0], MAXOUT, MINOUT ); - outputs[1][j] = limit( buffer[1], MAXOUT, MINOUT ); + outputs[0].put_int_clamp(j, buffer[0], 32768); + outputs[1].put_int_clamp(j, buffer[1], 32768); } } else { - std::fill_n(&outputs[0][0], samples, 0); - std::fill_n(&outputs[1][0], samples, 0); + outputs[0].fill(0); + outputs[1].fill(0); } } @@ -429,7 +421,7 @@ void k053260_device::KDSC_Voice::update_pan_volume() void k053260_device::KDSC_Voice::key_on() { m_position = m_kadpcm ? 1 : 0; // for kadpcm low bit is nybble offset, so must start at 1 due to preincrement - m_counter = 0x1000 - CLOCKS_PER_SAMPLE; // force update on next sound_stream_update_legacy + m_counter = 0x1000 - CLOCKS_PER_SAMPLE; // force update on next sound_stream_update m_output = 0; m_playing = true; if (LOG) m_device.logerror("K053260: start = %06x, length = %06x, pitch = %04x, vol = %02x:%x, loop = %s, %s\n", @@ -443,7 +435,7 @@ void k053260_device::KDSC_Voice::key_off() m_playing = false; } -void k053260_device::KDSC_Voice::play(stream_sample_t *outputs) +void k053260_device::KDSC_Voice::play(s32 *outputs) { m_counter += CLOCKS_PER_SAMPLE; diff --git a/src/devices/sound/k053260.h b/src/devices/sound/k053260.h index 4288b603d5a..ad14244ceb9 100644 --- a/src/devices/sound/k053260.h +++ b/src/devices/sound/k053260.h @@ -42,7 +42,7 @@ protected: virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; // device_rom_interface overrides virtual void rom_bank_updated() override; @@ -79,7 +79,7 @@ private: inline void update_pan_volume(); inline void key_on(); inline void key_off(); - inline void play(stream_sample_t *outputs); + inline void play(s32 *outputs); inline bool playing() { return m_playing; } inline u8 read_rom(bool side_effects); diff --git a/src/devices/sound/k054539.cpp b/src/devices/sound/k054539.cpp index 2ed7dc134a2..cba942e002f 100644 --- a/src/devices/sound/k054539.cpp +++ b/src/devices/sound/k054539.cpp @@ -23,7 +23,6 @@ k054539_device::k054539_device(const machine_config &mconfig, const char *tag, d , device_sound_interface(mconfig, *this) , device_rom_interface(mconfig, *this) , flags(0) - , ram(nullptr) , reverb_pos(0) , cur_ptr(0) , cur_limit(0) @@ -115,7 +114,7 @@ void k054539_device::sound_stream_update(sound_stream &stream, std::vector<read_ }; - int16_t *rbase = (int16_t *)ram.get(); + int16_t *rbase = (int16_t *)&ram[0]; if(!(regs[0x22f] & 1)) { @@ -124,7 +123,6 @@ void k054539_device::sound_stream_update(sound_stream &stream, std::vector<read_ return; } - constexpr stream_buffer::sample_t sample_scale = 1.0 / 32768.0; for(int sample = 0; sample != outputs[0].samples(); sample++) { double lval, rval; if(!(flags & DISABLE_REVERB)) @@ -303,8 +301,8 @@ void k054539_device::sound_stream_update(sound_stream &stream, std::vector<read_ } } reverb_pos = (reverb_pos + 1) & 0x1fff; - outputs[0].put(sample, stream_buffer::sample_t(lval) * sample_scale); - outputs[1].put(sample, stream_buffer::sample_t(rval) * sample_scale); + outputs[0].put_int(sample, lval, 32768); + outputs[1].put_int(sample, rval, 32768); } } @@ -321,10 +319,11 @@ void k054539_device::init_chip() memset(posreg_latch, 0, sizeof(posreg_latch)); //* flags |= UPDATE_AT_KEYON; //* make it default until proven otherwise - ram = std::make_unique<uint8_t[]>(0x4000); + ram = std::make_unique<uint8_t []>(0x4000); + reverb_pos = 0; cur_ptr = 0; - memset(ram.get(), 0, 0x4000); + memset(&ram[0], 0, 0x4000); stream = stream_alloc(0, 2, clock() / 384); @@ -553,7 +552,7 @@ void k054539_device::device_reset() { regs[0x22c] = 0; regs[0x22f] = 0; - memset(ram.get(), 0, 0x4000); + memset(&ram[0], 0, 0x4000); m_timer->enable(false); } diff --git a/src/devices/sound/k054539.h b/src/devices/sound/k054539.h index 6e4b6c10c8c..6c79ac6d0be 100644 --- a/src/devices/sound/k054539.h +++ b/src/devices/sound/k054539.h @@ -88,7 +88,7 @@ private: int flags; unsigned char regs[0x230]; - std::unique_ptr<uint8_t[]> ram; + std::unique_ptr<uint8_t []> ram; int reverb_pos; int32_t cur_ptr; diff --git a/src/devices/sound/ks0164.cpp b/src/devices/sound/ks0164.cpp index 5280af611f6..2086b014478 100644 --- a/src/devices/sound/ks0164.cpp +++ b/src/devices/sound/ks0164.cpp @@ -50,7 +50,7 @@ void ks0164_device::device_start() space().install_rom(0, rend, ((1 << 23) - 1) ^ rmask, m_mem_region->base()); } - m_stream = stream_alloc_legacy(0, 2, clock()/3/2/2/32); + m_stream = stream_alloc(0, 2, clock()/3/2/2/32); space().cache(m_mem_cache); m_timer = timer_alloc(0); @@ -368,9 +368,9 @@ u16 ks0164_device::uncomp_8_16(u8 value) return o; } -void ks0164_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void ks0164_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - for(int sample = 0; sample != samples; sample++) { + for(int sample = 0; sample != outputs[0].samples(); sample++) { s32 suml = 0, sumr = 0; for(int voice = 0; voice < 0x20; voice++) { u16 *regs = m_sregs[voice]; @@ -415,7 +415,7 @@ void ks0164_device::sound_stream_update_legacy(sound_stream &stream, stream_samp sumr += samp; } } - outputs[0][sample] = suml >> 5; - outputs[1][sample] = sumr >> 5; + outputs[0].put_int(sample, suml, 32768 * 32); + outputs[1].put_int(sample, sumr, 32768 * 32); } } diff --git a/src/devices/sound/ks0164.h b/src/devices/sound/ks0164.h index a668753f250..cc707699f2e 100644 --- a/src/devices/sound/ks0164.h +++ b/src/devices/sound/ks0164.h @@ -23,7 +23,7 @@ public: protected: virtual void device_start() override; virtual void device_reset() override; - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; virtual void device_add_mconfig(machine_config &config) override; virtual space_config_vector memory_space_config() const override; virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; diff --git a/src/devices/sound/l7a1045_l6028_dsp_a.cpp b/src/devices/sound/l7a1045_l6028_dsp_a.cpp index 280d12a20d9..7f567f86cbb 100644 --- a/src/devices/sound/l7a1045_l6028_dsp_a.cpp +++ b/src/devices/sound/l7a1045_l6028_dsp_a.cpp @@ -117,7 +117,7 @@ l7a1045_sound_device::l7a1045_sound_device(const machine_config &mconfig, const void l7a1045_sound_device::device_start() { /* Allocate the stream */ - m_stream = stream_alloc_legacy(0, 2, 66150); //clock() / 384); + m_stream = stream_alloc(0, 2, 66150); //clock() / 384); for (int voice = 0; voice < 32; voice++) { @@ -143,14 +143,14 @@ void l7a1045_sound_device::device_start() //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void l7a1045_sound_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void l7a1045_sound_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { /* Clear the buffers */ - memset(outputs[0], 0, samples*sizeof(*outputs[0])); - memset(outputs[1], 0, samples*sizeof(*outputs[1])); + outputs[0].fill(0); + outputs[1].fill(0); for (int i = 0; i < 32; i++) { @@ -165,7 +165,7 @@ void l7a1045_sound_device::sound_stream_update_legacy(sound_stream &stream, stre uint32_t pos = vptr->pos; uint32_t frac = vptr->frac; - for (int j = 0; j < samples; j++) + for (int j = 0; j < outputs[0].samples(); j++) { int32_t sample; uint8_t data; @@ -192,8 +192,8 @@ void l7a1045_sound_device::sound_stream_update_legacy(sound_stream &stream, stre sample = ((int8_t)(data & 0xfc)) << (3 - (data & 3)); frac += step; - outputs[0][j] += ((sample * vptr->l_volume) >> 9); - outputs[1][j] += ((sample * vptr->r_volume) >> 9); + outputs[0].add_int(j, sample * vptr->l_volume, 32768 * 512); + outputs[1].add_int(j, sample * vptr->r_volume, 32768 * 512); } vptr->pos = pos; diff --git a/src/devices/sound/l7a1045_l6028_dsp_a.h b/src/devices/sound/l7a1045_l6028_dsp_a.h index bc9c3b5d500..542b6aad386 100644 --- a/src/devices/sound/l7a1045_l6028_dsp_a.h +++ b/src/devices/sound/l7a1045_l6028_dsp_a.h @@ -33,7 +33,7 @@ protected: virtual void device_start() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: struct l7a1045_voice diff --git a/src/devices/sound/lmc1992.cpp b/src/devices/sound/lmc1992.cpp index ad412395d9d..cf0d8f35d33 100644 --- a/src/devices/sound/lmc1992.cpp +++ b/src/devices/sound/lmc1992.cpp @@ -171,12 +171,13 @@ void lmc1992_device::device_start() //------------------------------------------------- -// sound_stream_update_legacy - handle update requests for +// sound_stream_update - handle update requests for // our sound stream //------------------------------------------------- -void lmc1992_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void lmc1992_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { + outputs[0].fill(0); } diff --git a/src/devices/sound/lmc1992.h b/src/devices/sound/lmc1992.h index cfaffc1f13f..beb893d9983 100644 --- a/src/devices/sound/lmc1992.h +++ b/src/devices/sound/lmc1992.h @@ -71,7 +71,7 @@ protected: virtual void device_start() override; // internal callbacks - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: inline void execute_command(int addr, int data); diff --git a/src/devices/sound/mas3507d.cpp b/src/devices/sound/mas3507d.cpp index 641ec52a06e..a5b7a7917d2 100644 --- a/src/devices/sound/mas3507d.cpp +++ b/src/devices/sound/mas3507d.cpp @@ -29,7 +29,7 @@ mas3507d_device::mas3507d_device(const machine_config &mconfig, const char *tag, void mas3507d_device::device_start() { current_rate = 44100; - stream = stream_alloc_legacy(0, 2, current_rate); + stream = stream_alloc(0, 2, current_rate); cb_sample.resolve(); } @@ -359,11 +359,8 @@ void mas3507d_device::fill_buffer() } } -void mas3507d_device::append_buffer(stream_sample_t * const *outputs, int &pos, int scount) +void mas3507d_device::append_buffer(std::vector<write_stream_view> &outputs, int &pos, int scount) { - if(!sample_count) - return; - buffered_frame_count = scount; int s1 = scount - pos; @@ -372,14 +369,13 @@ void mas3507d_device::append_buffer(stream_sample_t * const *outputs, int &pos, if(mp3_info.channels == 1) { for(int i=0; i<s1; i++) { - stream_sample_t v = samples[i]; - outputs[0][i+pos] = v; - outputs[1][i+pos] = v; + outputs[0].put_int(i+pos, samples[i], 32768); + outputs[1].put_int(i+pos, samples[i], 32768); } } else { for(int i=0; i<s1; i++) { - outputs[0][i+pos] = samples[i*2]; - outputs[1][i+pos] = samples[i*2+1]; + outputs[0].put_int(i+pos, samples[i*2], 32768); + outputs[1].put_int(i+pos, samples[i*2+1], 32768); } } @@ -400,8 +396,9 @@ void mas3507d_device::append_buffer(stream_sample_t * const *outputs, int &pos, total_frame_count += s1; } -void mas3507d_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int csamples) +void mas3507d_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { + int csamples = outputs[0].samples(); int pos = 0; append_buffer(outputs, pos, csamples); @@ -419,10 +416,8 @@ void mas3507d_device::sound_stream_update_legacy(sound_stream &stream, stream_sa total_frame_count = 0; buffered_frame_count = 0; - for(int i=pos; i != csamples; i++) { - outputs[0][i] = 0; - outputs[1][i] = 0; - } + outputs[0].fill(0, pos); + outputs[1].fill(0, pos); return; } append_buffer(outputs, pos, csamples); diff --git a/src/devices/sound/mas3507d.h b/src/devices/sound/mas3507d.h index 31410fa576e..b04e157e2f2 100644 --- a/src/devices/sound/mas3507d.h +++ b/src/devices/sound/mas3507d.h @@ -27,7 +27,7 @@ public: protected: virtual void device_start() override; virtual void device_reset() override; - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: devcb_read16 cb_sample; @@ -63,7 +63,7 @@ private: void reg_write(uint32_t adr, uint32_t val); void fill_buffer(); - void append_buffer(stream_sample_t * const *outputs, int &pos, int samples); + void append_buffer(std::vector<write_stream_view> &outputs, int &pos, int samples); }; diff --git a/src/devices/sound/mea8000.cpp b/src/devices/sound/mea8000.cpp index 4f7fbc453ac..3cf2ad51a6e 100644 --- a/src/devices/sound/mea8000.cpp +++ b/src/devices/sound/mea8000.cpp @@ -134,7 +134,7 @@ void mea8000_device::device_start() init_tables(); - m_stream = stream_alloc_legacy(0, 1, clock() / 60); + m_stream = stream_alloc(0, 1, clock() / 60); save_item(NAME(m_output)); m_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mea8000_device::timer_expire),this)); @@ -422,12 +422,9 @@ void mea8000_device::stop_frame() -void mea8000_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void mea8000_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - for (int samp = 0; samp < samples; samp++) - { - outputs[0][samp] = m_output; - } + outputs[0].fill(stream_buffer::sample_t(m_output) * (1.0 / 32768.0)); } /* next sample in frame, sampling at 64 kHz */ diff --git a/src/devices/sound/mea8000.h b/src/devices/sound/mea8000.h index 14cb0384d09..7538bffa62c 100644 --- a/src/devices/sound/mea8000.h +++ b/src/devices/sound/mea8000.h @@ -29,7 +29,7 @@ public: protected: // device-level overrides virtual void device_start() override; - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: /* filter coefficients from frequencies */ @@ -111,7 +111,7 @@ private: emu_timer *m_timer = nullptr; sound_stream * m_stream = nullptr; - stream_sample_t m_output = 0; + int32_t m_output = 0; int m_cos_table[TABLE_LEN]; /* fm => cos coefficient */ int m_exp_table[TABLE_LEN]; /* bw => exp coefficient */ diff --git a/src/devices/sound/mm5837.cpp b/src/devices/sound/mm5837.cpp index 7b59758fdcd..6049b64d0fe 100644 --- a/src/devices/sound/mm5837.cpp +++ b/src/devices/sound/mm5837.cpp @@ -13,21 +13,15 @@ //************************************************************************** -// CONSTEXPR DEFINITIONS -//************************************************************************** - -constexpr int mm5837_device::m_frequency[]; - - -//************************************************************************** // DEVICE DEFINITIONS //************************************************************************** DEFINE_DEVICE_TYPE(MM5837, mm5837_device, "mm5837", "MM5837 Digital Noise Source") +DEFINE_DEVICE_TYPE(MM5837_STREAM, mm5837_stream_device, "mm5837_stream", "MM5837 Digital Noise Stream") //************************************************************************** -// LIVE DEVICE +// MM5837 DEVICE //************************************************************************** //------------------------------------------------- @@ -37,12 +31,12 @@ DEFINE_DEVICE_TYPE(MM5837, mm5837_device, "mm5837", "MM5837 Digital Noise Source mm5837_device::mm5837_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, MM5837, tag, owner, clock), m_output_cb(*this), - m_vdd(0), m_timer(nullptr), - m_shift(0) + m_vdd(-12) { } + //------------------------------------------------- // device_start - device-specific startup //------------------------------------------------- @@ -56,36 +50,70 @@ void mm5837_device::device_start() m_timer = timer_alloc(0); // register for save states - save_item(NAME(m_shift)); + save_item(NAME(m_source.m_shift)); } + //------------------------------------------------- // device_reset - device-specific reset //------------------------------------------------- void mm5837_device::device_reset() { - // initialize with something - m_shift = 123456; + m_source.reset(); if (m_vdd < 16) - m_timer->adjust(attotime::zero, 0, attotime::from_hz(m_frequency[m_vdd])); + m_timer->adjust(attotime::zero, 0, attotime::from_hz(mm5837_source::frequency(m_vdd))); else throw emu_fatalerror("%s: Invalid voltage: %d\n", tag(), m_vdd); } + //------------------------------------------------- // device_timer - handle timer callbacks //------------------------------------------------- void mm5837_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) { - int tap_14 = BIT(m_shift, 13); - int tap_17 = BIT(m_shift, 16); - int zero = (m_shift == 0) ? 1 : 0; + m_output_cb(m_source.clock()); +} + + + +//************************************************************************** +// MM5837 STREAM DEVICE +//************************************************************************** + +//------------------------------------------------- +// mm5837_stream_device - constructor +//------------------------------------------------- + +mm5837_stream_device::mm5837_stream_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, MM5837_STREAM, tag, owner, clock), + device_sound_interface(mconfig, *this), + m_stream(nullptr), + m_vdd(-12) +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void mm5837_stream_device::device_start() +{ + m_stream = stream_alloc(0, 1, mm5837_source::frequency(m_vdd)); + save_item(NAME(m_source.m_shift)); +} - m_shift <<= 1; - m_shift |= tap_14 ^ tap_17 ^ zero; - m_output_cb(BIT(m_shift, 16)); +//------------------------------------------------- +// sound_stream_update - fill the sound buffer +//------------------------------------------------- + +void mm5837_stream_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) +{ + for (int sampindex = 0; sampindex < outputs[0].samples(); sampindex++) + outputs[0].put(sampindex, m_source.clock() ? 1.0 : 0.0); } diff --git a/src/devices/sound/mm5837.h b/src/devices/sound/mm5837.h index 8c7f8287db6..49374537b9c 100644 --- a/src/devices/sound/mm5837.h +++ b/src/devices/sound/mm5837.h @@ -94,6 +94,66 @@ // TYPE DEFINITIONS //************************************************************************** +// ======================> mm5837_source + +class mm5837_source +{ +public: + // construction/destruction + mm5837_source() : + m_shift(0x1ffff) + { + } + + // reset to base state + void reset() + { + m_shift = 0x1ffff; + } + + // clock one time and return the shift value + u8 clock() + { + int tap_14 = BIT(m_shift, 13); + int tap_17 = BIT(m_shift, 16); + int zero = (m_shift == 0) ? 1 : 0; + + m_shift <<= 1; + m_shift |= tap_14 ^ tap_17 ^ zero; + + return BIT(m_shift, 16); + } + + // taken from the book 'mims circuit scrapbook, vol. 1' + static u32 frequency(double vdd) + { + // Vdd should be negative -6.2..-15V + if (vdd > -6.2 || vdd < -15) + throw emu_fatalerror("mm5837 frequency should be -6.2V .. -15V"); + + // curve fitting done in excel from this table: + // { 0, 0, 0, 0, 0, 0, 1, 2267, 8731, 16382, 23531, 32564, 38347, 40010, 37800, 33173 } + double result = 191.98*vdd*vdd*vdd + 5448.4*vdd*vdd + 43388*vdd + 105347; + + // datasheet claims frequency range 24-56kHz at Vdd=-14V, but also lists + // maximum cycle times as ranging from 1.1-2.4s; since the 17-bit shift + // register cycles after 131072 clocks, we would expect the actual cycle + // times to be 2.34-5.46s at the 24-56kHz frequency range, so I'm presuming + // that it ticks 2x per "clock", effectively running at 2x the frequency + result *= 2; + + // make sure the result isn't TOO crazy + result = std::max(result, 100.0); + return u32(result); + } + + // leave this public for easy saving + u32 m_shift; +}; + + +// ======================> mm5837_device + class mm5837_device : public device_t { public: @@ -101,7 +161,7 @@ public: mm5837_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); // configuration - void set_vdd_voltage(int voltage) { m_vdd = voltage; } + void set_vdd(double voltage) { m_vdd = voltage; } auto output_callback() { return m_output_cb.bind(); } protected: @@ -111,24 +171,42 @@ protected: virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; private: - // taken from the book 'mims circuit scrapbook, vol. 1' - // this is the frequency the chip runs at when given a vdd voltage of -0 to -15 - static constexpr int m_frequency[16] = { 0, 0, 0, 0, 0, 0, 1, 2267, 8731, 16382, 23531, 32564, 38347, 40010, 37800, 33173 }; + // internal state + devcb_write_line m_output_cb; // output callback + emu_timer *m_timer; // output timer + double m_vdd; // configured voltage + mm5837_source m_source; // noise source +}; - // callbacks - devcb_write_line m_output_cb; - // voltage (as positive number) - int m_vdd; +// ======================> mm5837_stream_device - // output timer - emu_timer *m_timer; +class mm5837_stream_device : public device_t, public device_sound_interface +{ +public: + // construction/destruction + mm5837_stream_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + // configuration + void set_vdd(double voltage) { m_vdd = voltage; } + +protected: + // device-level overrides + virtual void device_start() override; + + // sound stream update overrides + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; - // state - uint32_t m_shift; +private: + sound_stream *m_stream; // sound stream + double m_vdd; // configured voltage + mm5837_source m_source; // noise source }; -// device type definition + +// device type definitions DECLARE_DEVICE_TYPE(MM5837, mm5837_device) +DECLARE_DEVICE_TYPE(MM5837_STREAM, mm5837_stream_device) + #endif // MAME_SOUND_MM5837_H diff --git a/src/devices/sound/mos6560.cpp b/src/devices/sound/mos6560.cpp index 05ab0bcd08e..fadef01dd20 100644 --- a/src/devices/sound/mos6560.cpp +++ b/src/devices/sound/mos6560.cpp @@ -173,20 +173,18 @@ inline uint8_t mos6560_device::read_colorram(offs_t offset) void mos6560_device::draw_character( int ybegin, int yend, int ch, int yoff, int xoff, uint16_t *color ) { - int y, code; - - for (y = ybegin; y <= yend; y++) + for (int y = ybegin; y <= yend; y++) { - code = read_videoram((m_chargenaddr + ch * m_charheight + y) & 0x3fff); - - m_bitmap.pix32(y + yoff, xoff + 0) = PALETTE_MOS[color[code >> 7]]; - m_bitmap.pix32(y + yoff, xoff + 1) = PALETTE_MOS[color[(code >> 6) & 1]]; - m_bitmap.pix32(y + yoff, xoff + 2) = PALETTE_MOS[color[(code >> 5) & 1]]; - m_bitmap.pix32(y + yoff, xoff + 3) = PALETTE_MOS[color[(code >> 4) & 1]]; - m_bitmap.pix32(y + yoff, xoff + 4) = PALETTE_MOS[color[(code >> 3) & 1]]; - m_bitmap.pix32(y + yoff, xoff + 5) = PALETTE_MOS[color[(code >> 2) & 1]]; - m_bitmap.pix32(y + yoff, xoff + 6) = PALETTE_MOS[color[(code >> 1) & 1]]; - m_bitmap.pix32(y + yoff, xoff + 7) = PALETTE_MOS[color[code & 1]]; + int code = read_videoram((m_chargenaddr + ch * m_charheight + y) & 0x3fff); + + m_bitmap.pix(y + yoff, xoff + 0) = PALETTE_MOS[color[BIT(code, 7)]]; + m_bitmap.pix(y + yoff, xoff + 1) = PALETTE_MOS[color[BIT(code, 6)]]; + m_bitmap.pix(y + yoff, xoff + 2) = PALETTE_MOS[color[BIT(code, 5)]]; + m_bitmap.pix(y + yoff, xoff + 3) = PALETTE_MOS[color[BIT(code, 4)]]; + m_bitmap.pix(y + yoff, xoff + 4) = PALETTE_MOS[color[BIT(code, 3)]]; + m_bitmap.pix(y + yoff, xoff + 5) = PALETTE_MOS[color[BIT(code, 2)]]; + m_bitmap.pix(y + yoff, xoff + 6) = PALETTE_MOS[color[BIT(code, 1)]]; + m_bitmap.pix(y + yoff, xoff + 7) = PALETTE_MOS[color[BIT(code, 0)]]; } } @@ -197,20 +195,18 @@ void mos6560_device::draw_character( int ybegin, int yend, int ch, int yoff, int void mos6560_device::draw_character_multi( int ybegin, int yend, int ch, int yoff, int xoff, uint16_t *color ) { - int y, code; - - for (y = ybegin; y <= yend; y++) + for (int y = ybegin; y <= yend; y++) { - code = read_videoram((m_chargenaddr + ch * m_charheight + y) & 0x3fff); - - m_bitmap.pix32(y + yoff, xoff + 0) = - m_bitmap.pix32(y + yoff, xoff + 1) = PALETTE_MOS[color[code >> 6]]; - m_bitmap.pix32(y + yoff, xoff + 2) = - m_bitmap.pix32(y + yoff, xoff + 3) = PALETTE_MOS[color[(code >> 4) & 3]]; - m_bitmap.pix32(y + yoff, xoff + 4) = - m_bitmap.pix32(y + yoff, xoff + 5) = PALETTE_MOS[color[(code >> 2) & 3]]; - m_bitmap.pix32(y + yoff, xoff + 6) = - m_bitmap.pix32(y + yoff, xoff + 7) = PALETTE_MOS[color[code & 3]]; + int code = read_videoram((m_chargenaddr + ch * m_charheight + y) & 0x3fff); + + m_bitmap.pix(y + yoff, xoff + 0) = m_bitmap.pix(y + yoff, xoff + 1) = + PALETTE_MOS[color[code >> 6]]; + m_bitmap.pix(y + yoff, xoff + 2) = m_bitmap.pix(y + yoff, xoff + 3) = + PALETTE_MOS[color[(code >> 4) & 3]]; + m_bitmap.pix(y + yoff, xoff + 4) = m_bitmap.pix(y + yoff, xoff + 5) = + PALETTE_MOS[color[(code >> 2) & 3]]; + m_bitmap.pix(y + yoff, xoff + 6) = m_bitmap.pix(y + yoff, xoff + 7) = + PALETTE_MOS[color[code & 3]]; } } @@ -221,9 +217,7 @@ void mos6560_device::draw_character_multi( int ybegin, int yend, int ch, int yof void mos6560_device::drawlines( int first, int last ) { - int line, vline; - int offs, yoff, xoff, ybegin, yend, i, j; - int attr, ch; + int line; m_lastline = last; if (first >= last) @@ -231,12 +225,13 @@ void mos6560_device::drawlines( int first, int last ) for (line = first; (line < m_ypos) && (line < last); line++) { - for (j = 0; j < m_total_xsize; j++) - m_bitmap.pix32(line, j) = PALETTE_MOS[m_framecolor]; + for (int j = 0; j < m_total_xsize; j++) + m_bitmap.pix(line, j) = PALETTE_MOS[m_framecolor]; } - for (vline = line - m_ypos; (line < last) && (line < m_ypos + m_ysize);) + for (int vline = line - m_ypos; (line < last) && (line < m_ypos + m_ysize);) { + int offs, yoff, xoff, ybegin, yend; if (m_matrix8x16) { offs = (vline >> 4) * m_chars_x; @@ -254,16 +249,16 @@ void mos6560_device::drawlines( int first, int last ) if (m_xpos > 0) { - for (i = ybegin; i <= yend; i++) - for (j = 0; j < m_xpos; j++) - m_bitmap.pix32(yoff + i, j) = PALETTE_MOS[m_framecolor]; + for (int i = ybegin; i <= yend; i++) + for (int j = 0; j < m_xpos; j++) + m_bitmap.pix(yoff + i, j) = PALETTE_MOS[m_framecolor]; } for (xoff = m_xpos; (xoff < m_xpos + m_xsize) && (xoff < m_total_xsize); xoff += 8, offs++) { - ch = read_videoram((m_videoaddr + offs) & 0x3fff); + int ch = read_videoram((m_videoaddr + offs) & 0x3fff); - attr = (read_colorram((m_videoaddr + offs) & 0x3fff)) & 0xf; + int attr = (read_colorram((m_videoaddr + offs) & 0x3fff)) & 0xf; if (m_variant == TYPE_ATTACK_UFO) { @@ -301,9 +296,9 @@ void mos6560_device::drawlines( int first, int last ) if (xoff < m_total_xsize) { - for (i = ybegin; i <= yend; i++) - for (j = xoff; j < m_total_xsize; j++) - m_bitmap.pix32(yoff + i, j) = PALETTE_MOS[m_framecolor]; + for (int i = ybegin; i <= yend; i++) + for (int j = xoff; j < m_total_xsize; j++) + m_bitmap.pix(yoff + i, j) = PALETTE_MOS[m_framecolor]; } if (m_matrix8x16) @@ -319,8 +314,8 @@ void mos6560_device::drawlines( int first, int last ) } for (; line < last; line++) - for (j = 0; j < m_total_xsize; j++) - m_bitmap.pix32(line, j) = PALETTE_MOS[m_framecolor]; + for (int j = 0; j < m_total_xsize; j++) + m_bitmap.pix(line, j) = PALETTE_MOS[m_framecolor]; } @@ -620,20 +615,17 @@ void mos6560_device::soundport_w( int offset, int data ) void mos6560_device::sound_start() { - int i; - - m_channel = stream_alloc_legacy(0, 1, machine().sample_rate()); + m_channel = stream_alloc(0, 1, machine().sample_rate()); /* buffer for fastest played sample for 5 second so we have enough data for min 5 second */ m_noisesize = NOISE_FREQUENCY_MAX * NOISE_BUFFER_SIZE_SEC; - m_noise = std::make_unique<int8_t[]>(m_noisesize); + m_noise = std::make_unique<int8_t []>(m_noisesize); { int noiseshift = 0x7ffff8; - char data; - for (i = 0; i < m_noisesize; i++) + for (int i = 0; i < m_noisesize; i++) { - data = 0; + char data = 0; if (noiseshift & 0x400000) data |= 0x80; if (noiseshift & 0x100000) @@ -661,17 +653,13 @@ void mos6560_device::sound_start() if (m_tonesize > 0) { - m_tone = std::make_unique<int16_t[]>(m_tonesize); + m_tone = std::make_unique<int16_t []>(m_tonesize); - for (i = 0; i < m_tonesize; i++) + for (int i = 0; i < m_tonesize; i++) { - m_tone[i] = (int16_t)(sin (2 * M_PI * i / m_tonesize) * 127 + 0.5); + m_tone[i] = int16_t(sin (2 * M_PI * i / m_tonesize) * 127 + 0.5); } } - else - { - m_tone = nullptr; - } } @@ -888,15 +876,15 @@ void mos6560_device::device_timer(emu_timer &timer, device_timer_id id, int para } //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void mos6560_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void mos6560_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { int i, v; - stream_sample_t *buffer = outputs[0]; + auto &buffer = outputs[0]; - for (i = 0; i < samples; i++) + for (i = 0; i < buffer.samples(); i++) { v = 0; if (TONE1_ON /*||(m_tone1pos != 0) */ ) @@ -909,7 +897,7 @@ void mos6560_device::sound_stream_update_legacy(sound_stream &stream, stream_sam if (m_tone1pos >= m_tone1samples) { m_tone1pos = 0; - m_tone1samples = machine().sample_rate() / TONE1_FREQUENCY; + m_tone1samples = buffer.sample_rate() / TONE1_FREQUENCY; if (m_tone1samples == 0) m_tone1samples = 1; } @@ -925,7 +913,7 @@ void mos6560_device::sound_stream_update_legacy(sound_stream &stream, stream_sam if (m_tone2pos >= m_tone2samples) { m_tone2pos = 0; - m_tone2samples = machine().sample_rate() / TONE2_FREQUENCY; + m_tone2samples = buffer.sample_rate() / TONE2_FREQUENCY; if (m_tone2samples == 0) m_tone2samples = 1; } @@ -941,7 +929,7 @@ void mos6560_device::sound_stream_update_legacy(sound_stream &stream, stream_sam if (m_tone3pos >= m_tone3samples) { m_tone3pos = 0; - m_tone3samples = machine().sample_rate() / TONE3_FREQUENCY; + m_tone3samples = buffer.sample_rate() / TONE3_FREQUENCY; if (m_tone3samples == 0) m_tone3samples = 1; } @@ -956,12 +944,11 @@ void mos6560_device::sound_stream_update_legacy(sound_stream &stream, stream_sam m_noisepos = 0; } } - v = (v * VOLUME) << 2; - if (v > 32767) - buffer[i] = 32767; - else if (v < -32767) - buffer[i] = -32767; - else - buffer[i] = v; + v *= VOLUME; + if (v > 8191) + v = 8191; + else if (v < -8191) + v = -8191; + buffer.put_int(i, v, 8192); } } diff --git a/src/devices/sound/mos6560.h b/src/devices/sound/mos6560.h index cf657255198..182cba47dba 100644 --- a/src/devices/sound/mos6560.h +++ b/src/devices/sound/mos6560.h @@ -124,7 +124,7 @@ protected: virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; inline uint8_t read_videoram(offs_t offset); inline uint8_t read_colorram(offs_t offset); @@ -176,8 +176,8 @@ protected: m_noisesamples; /* count of samples to give out per tone */ sound_stream *m_channel; - std::unique_ptr<int16_t[]> m_tone; - std::unique_ptr<int8_t[]> m_noise; + std::unique_ptr<int16_t []> m_tone; + std::unique_ptr<int8_t []> m_noise; emu_timer *m_line_timer; }; diff --git a/src/devices/sound/mos6581.cpp b/src/devices/sound/mos6581.cpp index 2fe073a1347..4ee3ddd7ebd 100644 --- a/src/devices/sound/mos6581.cpp +++ b/src/devices/sound/mos6581.cpp @@ -199,7 +199,7 @@ void mos6581_device::device_start() m_read_poty.resolve_safe(0xff); // create sound stream - m_stream = stream_alloc_legacy(0, 1, machine().sample_rate()); + m_stream = stream_alloc(0, 1, machine().sample_rate()); // initialize SID engine m_token->device = this; @@ -235,13 +235,13 @@ void mos6581_device::device_post_load() //------------------------------------------------- -// sound_stream_update_legacy - handle update requests for +// sound_stream_update - handle update requests for // our sound stream //------------------------------------------------- -void mos6581_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void mos6581_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - m_token->fill_buffer(outputs[0], samples); + m_token->fill_buffer(outputs[0]); } diff --git a/src/devices/sound/mos6581.h b/src/devices/sound/mos6581.h index 47e5959ef41..de05db489d3 100644 --- a/src/devices/sound/mos6581.h +++ b/src/devices/sound/mos6581.h @@ -65,7 +65,7 @@ protected: virtual void device_post_load() override; // device_sound_interface overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; void save_state(SID6581_t *token); private: diff --git a/src/devices/sound/mos7360.cpp b/src/devices/sound/mos7360.cpp index 9105fd656e3..aa9604b3a78 100644 --- a/src/devices/sound/mos7360.cpp +++ b/src/devices/sound/mos7360.cpp @@ -297,7 +297,7 @@ void mos7360_device::device_start() screen().register_screen_bitmap(m_bitmap); // create sound stream - m_stream = stream_alloc_legacy(0, 1, machine().sample_rate()); + m_stream = stream_alloc(0, 1, machine().sample_rate()); // buffer for fastest played sample for 5 second so we have enough data for min 5 second m_noisesize = NOISE_FREQUENCY_MAX * NOISE_BUFFER_SIZE_SEC; @@ -454,16 +454,16 @@ void mos7360_device::device_timer(emu_timer &timer, device_timer_id id, int para //------------------------------------------------- -// sound_stream_update_legacy - handle update requests for +// sound_stream_update - handle update requests for // our sound stream //------------------------------------------------- -void mos7360_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void mos7360_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { int i, v, a; - stream_sample_t *buffer = outputs[0]; + auto &buffer = outputs[0]; - for (i = 0; i < samples; i++) + for (i = 0; i < buffer.samples(); i++) { v = 0; @@ -506,113 +506,100 @@ void mos7360_device::sound_stream_update_legacy(sound_stream &stream, stream_sam v = v * a; - buffer[i] = v; + buffer.put_int(i, v, 32768); } } void mos7360_device::draw_character(int ybegin, int yend, int ch, int yoff, int xoff, uint16_t *color) { - int y, code; - - for (y = ybegin; y <= yend; y++) + for (int y = ybegin; y <= yend; y++) { + int code; if (INROM) code = read_rom(m_chargenaddr + ch * 8 + y); else code = read_ram(m_chargenaddr + ch * 8 + y); - m_bitmap.pix32(y + yoff, 0 + xoff) = PALETTE_MOS[color[code >> 7]]; - m_bitmap.pix32(y + yoff, 1 + xoff) = PALETTE_MOS[color[(code >> 6) & 1]]; - m_bitmap.pix32(y + yoff, 2 + xoff) = PALETTE_MOS[color[(code >> 5) & 1]]; - m_bitmap.pix32(y + yoff, 3 + xoff) = PALETTE_MOS[color[(code >> 4) & 1]]; - m_bitmap.pix32(y + yoff, 4 + xoff) = PALETTE_MOS[color[(code >> 3) & 1]]; - m_bitmap.pix32(y + yoff, 5 + xoff) = PALETTE_MOS[color[(code >> 2) & 1]]; - m_bitmap.pix32(y + yoff, 6 + xoff) = PALETTE_MOS[color[(code >> 1) & 1]]; - m_bitmap.pix32(y + yoff, 7 + xoff) = PALETTE_MOS[color[code & 1]]; + m_bitmap.pix(y + yoff, 0 + xoff) = PALETTE_MOS[color[BIT(code, 7)]]; + m_bitmap.pix(y + yoff, 1 + xoff) = PALETTE_MOS[color[BIT(code, 6)]]; + m_bitmap.pix(y + yoff, 2 + xoff) = PALETTE_MOS[color[BIT(code, 5)]]; + m_bitmap.pix(y + yoff, 3 + xoff) = PALETTE_MOS[color[BIT(code, 4)]]; + m_bitmap.pix(y + yoff, 4 + xoff) = PALETTE_MOS[color[BIT(code, 3)]]; + m_bitmap.pix(y + yoff, 5 + xoff) = PALETTE_MOS[color[BIT(code, 2)]]; + m_bitmap.pix(y + yoff, 6 + xoff) = PALETTE_MOS[color[BIT(code, 1)]]; + m_bitmap.pix(y + yoff, 7 + xoff) = PALETTE_MOS[color[BIT(code, 0)]]; } } void mos7360_device::draw_character_multi(int ybegin, int yend, int ch, int yoff, int xoff) { - int y, code; - - for (y = ybegin; y <= yend; y++) + for (int y = ybegin; y <= yend; y++) { + int code; if (INROM) code = read_rom(m_chargenaddr + ch * 8 + y); else code = read_ram(m_chargenaddr + ch * 8 + y); - m_bitmap.pix32(y + yoff, 0 + xoff) = - m_bitmap.pix32(y + yoff, 1 + xoff) = PALETTE_MOS[m_multi[code >> 6]]; - m_bitmap.pix32(y + yoff, 2 + xoff) = - m_bitmap.pix32(y + yoff, 3 + xoff) = PALETTE_MOS[m_multi[(code >> 4) & 3]]; - m_bitmap.pix32(y + yoff, 4 + xoff) = - m_bitmap.pix32(y + yoff, 5 + xoff) = PALETTE_MOS[m_multi[(code >> 2) & 3]]; - m_bitmap.pix32(y + yoff, 6 + xoff) = - m_bitmap.pix32(y + yoff, 7 + xoff) = PALETTE_MOS[m_multi[code & 3]]; + m_bitmap.pix(y + yoff, 0 + xoff) = m_bitmap.pix(y + yoff, 1 + xoff) = + PALETTE_MOS[m_multi[code >> 6]]; + m_bitmap.pix(y + yoff, 2 + xoff) = m_bitmap.pix(y + yoff, 3 + xoff) = + PALETTE_MOS[m_multi[(code >> 4) & 3]]; + m_bitmap.pix(y + yoff, 4 + xoff) = m_bitmap.pix(y + yoff, 5 + xoff) = + PALETTE_MOS[m_multi[(code >> 2) & 3]]; + m_bitmap.pix(y + yoff, 6 + xoff) = m_bitmap.pix(y + yoff, 7 + xoff) = + PALETTE_MOS[m_multi[code & 3]]; } } void mos7360_device::draw_bitmap(int ybegin, int yend, int ch, int yoff, int xoff) { - int y, code; - - for (y = ybegin; y <= yend; y++) + for (int y = ybegin; y <= yend; y++) { - code = read_ram(m_bitmapaddr + ch * 8 + y); - - m_bitmap.pix32(y + yoff, 0 + xoff) = PALETTE_MOS[m_c16_bitmap[code >> 7]]; - m_bitmap.pix32(y + yoff, 1 + xoff) = PALETTE_MOS[m_c16_bitmap[(code >> 6) & 1]]; - m_bitmap.pix32(y + yoff, 2 + xoff) = PALETTE_MOS[m_c16_bitmap[(code >> 5) & 1]]; - m_bitmap.pix32(y + yoff, 3 + xoff) = PALETTE_MOS[m_c16_bitmap[(code >> 4) & 1]]; - m_bitmap.pix32(y + yoff, 4 + xoff) = PALETTE_MOS[m_c16_bitmap[(code >> 3) & 1]]; - m_bitmap.pix32(y + yoff, 5 + xoff) = PALETTE_MOS[m_c16_bitmap[(code >> 2) & 1]]; - m_bitmap.pix32(y + yoff, 6 + xoff) = PALETTE_MOS[m_c16_bitmap[(code >> 1) & 1]]; - m_bitmap.pix32(y + yoff, 7 + xoff) = PALETTE_MOS[m_c16_bitmap[code & 1]]; + int code = read_ram(m_bitmapaddr + ch * 8 + y); + + m_bitmap.pix(y + yoff, 0 + xoff) = PALETTE_MOS[m_c16_bitmap[BIT(code, 7)]]; + m_bitmap.pix(y + yoff, 1 + xoff) = PALETTE_MOS[m_c16_bitmap[BIT(code, 6)]]; + m_bitmap.pix(y + yoff, 2 + xoff) = PALETTE_MOS[m_c16_bitmap[BIT(code, 5)]]; + m_bitmap.pix(y + yoff, 3 + xoff) = PALETTE_MOS[m_c16_bitmap[BIT(code, 4)]]; + m_bitmap.pix(y + yoff, 4 + xoff) = PALETTE_MOS[m_c16_bitmap[BIT(code, 3)]]; + m_bitmap.pix(y + yoff, 5 + xoff) = PALETTE_MOS[m_c16_bitmap[BIT(code, 2)]]; + m_bitmap.pix(y + yoff, 6 + xoff) = PALETTE_MOS[m_c16_bitmap[BIT(code, 1)]]; + m_bitmap.pix(y + yoff, 7 + xoff) = PALETTE_MOS[m_c16_bitmap[BIT(code, 0)]]; } } void mos7360_device::draw_bitmap_multi(int ybegin, int yend, int ch, int yoff, int xoff) { - int y, code; - - for (y = ybegin; y <= yend; y++) + for (int y = ybegin; y <= yend; y++) { - code = read_ram(m_bitmapaddr + ch * 8 + y); - - m_bitmap.pix32(y + yoff, 0 + xoff) = - m_bitmap.pix32(y + yoff, 1 + xoff) = PALETTE_MOS[m_bitmapmulti[code >> 6]]; - m_bitmap.pix32(y + yoff, 2 + xoff) = - m_bitmap.pix32(y + yoff, 3 + xoff) = PALETTE_MOS[m_bitmapmulti[(code >> 4) & 3]]; - m_bitmap.pix32(y + yoff, 4 + xoff) = - m_bitmap.pix32(y + yoff, 5 + xoff) = PALETTE_MOS[m_bitmapmulti[(code >> 2) & 3]]; - m_bitmap.pix32(y + yoff, 6 + xoff) = - m_bitmap.pix32(y + yoff, 7 + xoff) = PALETTE_MOS[m_bitmapmulti[code & 3]]; + int code = read_ram(m_bitmapaddr + ch * 8 + y); + + m_bitmap.pix(y + yoff, 0 + xoff) = m_bitmap.pix(y + yoff, 1 + xoff) = + PALETTE_MOS[m_bitmapmulti[code >> 6]]; + m_bitmap.pix(y + yoff, 2 + xoff) = m_bitmap.pix(y + yoff, 3 + xoff) = + PALETTE_MOS[m_bitmapmulti[(code >> 4) & 3]]; + m_bitmap.pix(y + yoff, 4 + xoff) = m_bitmap.pix(y + yoff, 5 + xoff) = + PALETTE_MOS[m_bitmapmulti[(code >> 2) & 3]]; + m_bitmap.pix(y + yoff, 6 + xoff) = m_bitmap.pix(y + yoff, 7 + xoff) = + PALETTE_MOS[m_bitmapmulti[code & 3]]; } } void mos7360_device::draw_cursor(int ybegin, int yend, int yoff, int xoff, int color) { - int y; - - for (y = ybegin; y <= yend; y++) + for (int y = ybegin; y <= yend; y++) { for (int x = 0; x < 8; x++) { - m_bitmap.pix32(y + yoff, x + xoff) = PALETTE_MOS[color]; + m_bitmap.pix(y + yoff, x + xoff) = PALETTE_MOS[color]; } } } void mos7360_device::drawlines(int first, int last) { - int line, vline, end; - int attr, ch, c1, c2, ecm; - int offs, yoff, xoff, ybegin, yend, xbegin, xend; - int i; - m_lastline = last; /* top part of display not rastered */ @@ -625,34 +612,44 @@ void mos7360_device::drawlines(int first, int last) if (!SCREENON) { - for (line = first; (line < last) && (line < m_bitmap.height()); line++) + for (int line = first; (line < last) && (line < m_bitmap.height()); line++) { for (int x = 0; x < m_bitmap.width(); x++) { - m_bitmap.pix32(line, x) = PALETTE_MOS[FRAMECOLOR]; + m_bitmap.pix(line, x) = PALETTE_MOS[FRAMECOLOR]; } } return; } + int xbegin, xend; if (COLUMNS40) - xbegin = XPOS, xend = xbegin + 320; + { + xbegin = XPOS; + xend = xbegin + 320; + } else - xbegin = XPOS + 7, xend = xbegin + 304; + { + xbegin = XPOS + 7; + xend = xbegin + 304; + } + int end; if (last < m_y_begin) end = last; else end = m_y_begin + YPOS; + + int line; + for (line = first; line < end; line++) { - for (line = first; line < end; line++) + for (int x = 0; x < m_bitmap.width(); x++) { - for (int x = 0; x < m_bitmap.width(); x++) - { - m_bitmap.pix32(line, x) = PALETTE_MOS[FRAMECOLOR]; - } + m_bitmap.pix(line, x) = PALETTE_MOS[FRAMECOLOR]; } } + + int vline; if (LINES25) vline = line - m_y_begin - YPOS; else @@ -663,23 +660,23 @@ void mos7360_device::drawlines(int first, int last) else end = m_y_end + YPOS; - for (; line < end; vline = (vline + 8) & ~7, line = line + 1 + yend - ybegin) + for (int ybegin, yend; line < end; vline = (vline + 8) & ~7, line = line + 1 + yend - ybegin) { - offs = (vline >> 3) * 40; + int offs = (vline >> 3) * 40; ybegin = vline & 7; - yoff = line - ybegin; + int yoff = line - ybegin; yend = (yoff + 7 < end) ? 7 : (end - yoff - 1); /* rendering 39 characters */ /* left and right borders are overwritten later */ - for (xoff = m_x_begin + XPOS; xoff < m_x_end + XPOS; xoff += 8, offs++) + for (int xoff = m_x_begin + XPOS; xoff < m_x_end + XPOS; xoff += 8, offs++) { if (HIRESON) { - ch = read_ram((m_videoaddr | 0x400) + offs); - attr = read_ram(m_videoaddr + offs); - c1 = ((ch >> 4) & 0xf) | (attr << 4); - c2 = (ch & 0xf) | (attr & 0x70); + int ch = read_ram((m_videoaddr | 0x400) + offs); + int attr = read_ram(m_videoaddr + offs); + int c1 = ((ch >> 4) & 0xf) | (attr << 4); + int c2 = (ch & 0xf) | (attr & 0x70); m_bitmapmulti[1] = m_c16_bitmap[1] = c1 & 0x7f; m_bitmapmulti[2] = m_c16_bitmap[0] = c2 & 0x7f; if (MULTICOLORON) @@ -693,13 +690,13 @@ void mos7360_device::drawlines(int first, int last) } else { - ch = read_ram((m_videoaddr | 0x400) + offs); - attr = read_ram(m_videoaddr + offs); + int ch = read_ram((m_videoaddr | 0x400) + offs); + int attr = read_ram(m_videoaddr + offs); // levente harsfalvi's docu says cursor off in ecm and multicolor if (ECMON) { // hardware reverse off - ecm = ch >> 6; + int ecm = ch >> 6; m_ecmcolor[0] = m_colors[ecm]; m_ecmcolor[1] = attr & 0x7f; draw_character(ybegin, yend, ch & ~0xc0, yoff, xoff, m_ecmcolor); @@ -741,16 +738,16 @@ void mos7360_device::drawlines(int first, int last) } } - for (i = ybegin; i <= yend; i++) + for (int i = ybegin; i <= yend; i++) { for (int x = 0; x < xbegin; x++) { - m_bitmap.pix32(yoff + i, x) = PALETTE_MOS[FRAMECOLOR]; + m_bitmap.pix(yoff + i, x) = PALETTE_MOS[FRAMECOLOR]; } for (int x = xend; x < m_bitmap.width(); x++) { - m_bitmap.pix32(yoff + i, x) = PALETTE_MOS[FRAMECOLOR]; + m_bitmap.pix(yoff + i, x) = PALETTE_MOS[FRAMECOLOR]; } } } @@ -764,7 +761,7 @@ void mos7360_device::drawlines(int first, int last) { for (int x = 0; x < m_bitmap.width(); x++) { - m_bitmap.pix32(line, x) = PALETTE_MOS[FRAMECOLOR]; + m_bitmap.pix(line, x) = PALETTE_MOS[FRAMECOLOR]; } } } diff --git a/src/devices/sound/mos7360.h b/src/devices/sound/mos7360.h index 7e41bddb7c6..c8733dc3e46 100644 --- a/src/devices/sound/mos7360.h +++ b/src/devices/sound/mos7360.h @@ -110,7 +110,7 @@ protected: virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; // device_sound_interface callbacks - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; inline void set_interrupt(int mask); inline void clear_interrupt(int mask); diff --git a/src/devices/sound/msm5232.cpp b/src/devices/sound/msm5232.cpp index da8fc499dc7..972b83a8c53 100644 --- a/src/devices/sound/msm5232.cpp +++ b/src/devices/sound/msm5232.cpp @@ -34,7 +34,7 @@ void msm5232_device::device_start() init(clock(), rate); - m_stream = stream_alloc_legacy(0, 11, rate); + m_stream = stream_alloc(0, 11, rate); /* register with the save state system */ save_item(NAME(m_EN_out16)); @@ -725,34 +725,34 @@ void msm5232_device::set_clock(int clock) //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void msm5232_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void msm5232_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - stream_sample_t *buf1 = outputs[0]; - stream_sample_t *buf2 = outputs[1]; - stream_sample_t *buf3 = outputs[2]; - stream_sample_t *buf4 = outputs[3]; - stream_sample_t *buf5 = outputs[4]; - stream_sample_t *buf6 = outputs[5]; - stream_sample_t *buf7 = outputs[6]; - stream_sample_t *buf8 = outputs[7]; - stream_sample_t *bufsolo1 = outputs[8]; - stream_sample_t *bufsolo2 = outputs[9]; - stream_sample_t *bufnoise = outputs[10]; + auto &buf1 = outputs[0]; + auto &buf2 = outputs[1]; + auto &buf3 = outputs[2]; + auto &buf4 = outputs[3]; + auto &buf5 = outputs[4]; + auto &buf6 = outputs[5]; + auto &buf7 = outputs[6]; + auto &buf8 = outputs[7]; + auto &bufsolo1 = outputs[8]; + auto &bufsolo2 = outputs[9]; + auto &bufnoise = outputs[10]; int i; - for (i=0; i<samples; i++) + for (i=0; i<buf1.samples(); i++) { /* calculate all voices' envelopes */ EG_voices_advance(); TG_group_advance(0); /* calculate tones group 1 */ - buf1[i] = o2; - buf2[i] = o4; - buf3[i] = o8; - buf4[i] = o16; + buf1.put_int(i, o2, 32768); + buf2.put_int(i, o4, 32768); + buf3.put_int(i, o8, 32768); + buf4.put_int(i, o16, 32768); SAVE_SINGLE_CHANNEL(0,o2) SAVE_SINGLE_CHANNEL(1,o4) @@ -760,13 +760,13 @@ void msm5232_device::sound_stream_update_legacy(sound_stream &stream, stream_sam SAVE_SINGLE_CHANNEL(3,o16) TG_group_advance(1); /* calculate tones group 2 */ - buf5[i] = o2; - buf6[i] = o4; - buf7[i] = o8; - buf8[i] = o16; + buf5.put_int(i, o2, 32768); + buf6.put_int(i, o4, 32768); + buf7.put_int(i, o8, 32768); + buf8.put_int(i, o16, 32768); - bufsolo1[i] = solo8; - bufsolo2[i] = solo16; + bufsolo1.put_int(i, solo8, 32768); + bufsolo2.put_int(i, solo16, 32768); SAVE_SINGLE_CHANNEL(4,o2) SAVE_SINGLE_CHANNEL(5,o4) @@ -794,6 +794,6 @@ void msm5232_device::sound_stream_update_legacy(sound_stream &stream, stream_sam } } - bufnoise[i] = (m_noise_rng & (1<<16)) ? 32767 : 0; + bufnoise.put(i, (m_noise_rng & (1<<16)) ? 1.0 : 0.0); } } diff --git a/src/devices/sound/msm5232.h b/src/devices/sound/msm5232.h index 364f944353b..552cd7669e3 100644 --- a/src/devices/sound/msm5232.h +++ b/src/devices/sound/msm5232.h @@ -26,7 +26,7 @@ protected: virtual void device_post_load() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: struct VOICE { diff --git a/src/devices/sound/multipcm.cpp b/src/devices/sound/multipcm.cpp index c4a5892990f..4ea099b947a 100644 --- a/src/devices/sound/multipcm.cpp +++ b/src/devices/sound/multipcm.cpp @@ -479,7 +479,7 @@ void multipcm_device::device_start() const float clock_divider = 180.0f; m_rate = (float)clock() / clock_divider; - m_stream = stream_alloc_legacy(0, 2, m_rate); + m_stream = stream_alloc(0, 2, m_rate); // Volume + pan table m_left_pan_table = make_unique_clear<int32_t[]>(0x800); @@ -575,7 +575,7 @@ void multipcm_device::device_start() save_item(NAME(m_address)); // Slots - m_slots = make_unique_clear<slot_t []>(28); + m_slots = std::make_unique<slot_t []>(28); save_pointer(STRUCT_MEMBER(m_slots, m_regs), 28); save_pointer(STRUCT_MEMBER(m_slots, m_playing), 28); @@ -628,22 +628,10 @@ void multipcm_device::device_clock_changed() } //----------------------------------------------------- -// clamp_to_int16 - clamp a 32-bit value to 16 bits +// convert_to_stream_sample - clamp a 32-bit value to +// 16 bits and convert to a stream_buffer::sample_t //----------------------------------------------------- -int16_t multipcm_device::clamp_to_int16(int32_t value) -{ - if (value < -32768) - { - return -32768; - } - else if (value > 32767) - { - return 32767; - } - return (int16_t)value; -} - #if MULTIPCM_LOG_SAMPLES void multipcm_device::dump_sample(slot_t &slot) { @@ -677,20 +665,12 @@ void multipcm_device::dump_sample(slot_t &slot) #endif //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void multipcm_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int32_t samples) +void multipcm_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - stream_sample_t *datap[2]; - - datap[0] = outputs[0]; - datap[1] = outputs[1]; - - memset(datap[0], 0, sizeof(*datap[0]) * samples); - memset(datap[1], 0, sizeof(*datap[1]) * samples); - - for (int32_t i = 0; i < samples; ++i) + for (int32_t i = 0; i < outputs[0].samples(); ++i) { int32_t smpl = 0; int32_t smpr = 0; @@ -741,8 +721,8 @@ void multipcm_device::sound_stream_update_legacy(sound_stream &stream, stream_sa } } - datap[0][i] = clamp_to_int16(smpl); - datap[1][i] = clamp_to_int16(smpr); + outputs[0].put_int_clamp(i, smpl, 32768); + outputs[1].put_int_clamp(i, smpr, 32768); } } diff --git a/src/devices/sound/multipcm.h b/src/devices/sound/multipcm.h index 4308703b9dc..e8de5a06851 100644 --- a/src/devices/sound/multipcm.h +++ b/src/devices/sound/multipcm.h @@ -29,7 +29,7 @@ protected: virtual void device_clock_changed() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; // device_rom_interface overrides virtual void rom_bank_updated() override; @@ -37,17 +37,17 @@ protected: private: struct sample_t { - uint32_t m_start; - uint32_t m_loop; - uint32_t m_end; - uint8_t m_attack_reg; - uint8_t m_decay1_reg; - uint8_t m_decay2_reg; - uint8_t m_decay_level; - uint8_t m_release_reg; - uint8_t m_key_rate_scale; - uint8_t m_lfo_vibrato_reg; - uint8_t m_lfo_amplitude_reg; + uint32_t m_start = 0; + uint32_t m_loop = 0; + uint32_t m_end = 0; + uint8_t m_attack_reg = 0; + uint8_t m_decay1_reg = 0; + uint8_t m_decay2_reg = 0; + uint8_t m_decay_level = 0; + uint8_t m_release_reg = 0; + uint8_t m_key_rate_scale = 0; + uint8_t m_lfo_vibrato_reg = 0; + uint8_t m_lfo_amplitude_reg = 0; }; enum class state_t : u8 @@ -60,38 +60,38 @@ private: struct envelope_gen_t { - int32_t m_volume; - state_t m_state; - int32_t step; + int32_t m_volume = 0; + state_t m_state = state_t::ATTACK; + int32_t step = 0; //step vals - int32_t m_attack_rate; // Attack - int32_t m_decay1_rate; // Decay1 - int32_t m_decay2_rate; // Decay2 - int32_t m_release_rate; // Release - int32_t m_decay_level; // Decay level + int32_t m_attack_rate = 0; // Attack + int32_t m_decay1_rate = 0; // Decay1 + int32_t m_decay2_rate = 0; // Decay2 + int32_t m_release_rate = 0; // Release + int32_t m_decay_level = 0; // Decay level }; struct lfo_t { - uint16_t m_phase; - uint32_t m_phase_step; - int32_t *m_table; - int32_t *m_scale; + uint16_t m_phase = 0; + uint32_t m_phase_step = 0; + int32_t *m_table = nullptr; + int32_t *m_scale = nullptr; }; struct slot_t { - uint8_t m_regs[8]; - bool m_playing; + uint8_t m_regs[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + bool m_playing = false; sample_t m_sample; - uint32_t m_base; - uint32_t m_offset; - uint32_t m_step; - uint32_t m_pan; - uint32_t m_total_level; - uint32_t m_dest_total_level; - int32_t m_total_level_step; - int32_t m_prev_sample; + uint32_t m_base = 0; + uint32_t m_offset = 0; + uint32_t m_step = 0; + uint32_t m_pan = 0; + uint32_t m_total_level = 0; + uint32_t m_dest_total_level = 0; + int32_t m_total_level_step = 0; + int32_t m_prev_sample = 0; envelope_gen_t m_envelope_gen; lfo_t m_pitch_lfo; // Pitch lfo lfo_t m_amplitude_lfo; // AM lfo @@ -135,7 +135,7 @@ private: void write_slot(slot_t &slot, int32_t reg, uint8_t data); - int16_t clamp_to_int16(int32_t value); + stream_buffer::sample_t convert_to_stream_sample(int32_t value); #if MULTIPCM_LOG_SAMPLES void dump_sample(slot_t &slot); diff --git a/src/devices/sound/n63701x.cpp b/src/devices/sound/n63701x.cpp index f9dea8e4509..6f16c988d8e 100644 --- a/src/devices/sound/n63701x.cpp +++ b/src/devices/sound/n63701x.cpp @@ -46,7 +46,7 @@ namco_63701x_device::namco_63701x_device(const machine_config &mconfig, const ch void namco_63701x_device::device_start() { - m_stream = stream_alloc_legacy(0, 2, clock()/1000); + m_stream = stream_alloc(0, 2, clock()/1000); for (int i = 0; i < 2; i++) { @@ -61,16 +61,16 @@ void namco_63701x_device::device_start() //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void namco_63701x_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void namco_63701x_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { int ch; for (ch = 0;ch < 2;ch++) { - stream_sample_t *buf = outputs[ch]; + auto &buf = outputs[ch]; voice_63701x *v = &m_voices[ch]; if (v->playing) @@ -80,12 +80,12 @@ void namco_63701x_device::sound_stream_update_legacy(sound_stream &stream, strea int vol = vol_table[v->volume]; int p; - for (p = 0;p < samples;p++) + for (p = 0;p < buf.samples();p++) { if (v->silence_counter) { v->silence_counter--; - *(buf++) = 0; + buf.put(p, 0); } else { @@ -94,17 +94,18 @@ void namco_63701x_device::sound_stream_update_legacy(sound_stream &stream, strea if (data == 0xff) /* end of sample */ { v->playing = 0; + buf.fill(0, p); break; } else if (data == 0x00) /* silence compression */ { data = base[(pos++) & 0xffff]; v->silence_counter = data; - *(buf++) = 0; + buf.put(p, 0); } else { - *(buf++) = vol * (data - 0x80); + buf.put_int(p, vol * (data - 0x80), 32768); } } } @@ -112,7 +113,7 @@ void namco_63701x_device::sound_stream_update_legacy(sound_stream &stream, strea v->position = pos; } else - memset(buf, 0, samples * sizeof(*buf)); + buf.fill(0); } } diff --git a/src/devices/sound/n63701x.h b/src/devices/sound/n63701x.h index 4992065d7bf..3ca5411df6d 100644 --- a/src/devices/sound/n63701x.h +++ b/src/devices/sound/n63701x.h @@ -25,7 +25,7 @@ protected: virtual void device_start() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: struct voice_63701x diff --git a/src/devices/sound/namco.cpp b/src/devices/sound/namco.cpp index 830f3713b45..694dad0cd29 100644 --- a/src/devices/sound/namco.cpp +++ b/src/devices/sound/namco.cpp @@ -43,8 +43,6 @@ /* a position of waveform sample */ #define WAVEFORM_POSITION(n) (((n) >> m_f_fracbits) & 0x1f) -static constexpr stream_buffer::sample_t sample_scale = 1.0 / 32768.0; - DEFINE_DEVICE_TYPE(NAMCO, namco_device, "namco", "Namco") DEFINE_DEVICE_TYPE(NAMCO_15XX, namco_15xx_device, "namco_15xx", "Namco 15xx") DEFINE_DEVICE_TYPE(NAMCO_CUS30, namco_cus30_device, "namco_cus30", "Namco CUS30") @@ -54,7 +52,6 @@ namco_audio_device::namco_audio_device(const machine_config &mconfig, device_typ , device_sound_interface(mconfig, *this) , m_wave_ptr(*this, DEVICE_SELF) , m_last_channel(nullptr) - , m_soundregs(nullptr) , m_wavedata(nullptr) , m_wave_size(0) , m_sound_enable(false) @@ -69,11 +66,13 @@ namco_audio_device::namco_audio_device(const machine_config &mconfig, device_typ namco_device::namco_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : namco_audio_device(mconfig, NAMCO, tag, owner, clock) + , m_soundregs(nullptr) { } namco_15xx_device::namco_15xx_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :namco_audio_device(mconfig, NAMCO_15XX, tag, owner, clock) + , m_soundregs(nullptr) { } @@ -89,13 +88,9 @@ namco_cus30_device::namco_cus30_device(const machine_config &mconfig, const char void namco_audio_device::device_start() { - sound_channel *voice; - /* extract globals from the interface */ m_last_channel = m_channel_list + m_voices; - m_soundregs = auto_alloc_array_clear(machine(), uint8_t, 0x400); - /* build the waveform table */ build_decoded_waveform(m_wave_ptr); @@ -109,20 +104,17 @@ void namco_audio_device::device_start() m_sound_enable = true; /* register with the save state system */ - save_pointer(NAME(m_soundregs), 0x400); - if (m_wave_ptr == nullptr) save_pointer(NAME(m_wavedata), 0x400); save_item(NAME(m_voices)); save_item(NAME(m_sound_enable)); - save_pointer(NAME(m_waveform[0]), MAX_VOLUME * 32 * 8 * (1+m_wave_size)); + for (int v = 0; v < MAX_VOLUME; v++) + save_pointer(NAME(m_waveform[v]), 32 * 8 * (1+m_wave_size), v); /* reset all the voices */ - for (voice = m_channel_list; voice < m_last_channel; voice++) + for (sound_channel *voice = m_channel_list; voice < m_last_channel; voice++) { - int voicenum = voice - m_channel_list; - voice->frequency = 0; voice->volume[0] = voice->volume[1] = 0; voice->waveform_select = 0; @@ -132,18 +124,36 @@ void namco_audio_device::device_start() voice->noise_seed = 1; voice->noise_counter = 0; voice->noise_hold = 0; - - /* register with the save state system */ - save_item(NAME(voice->frequency), voicenum); - save_item(NAME(voice->counter), voicenum); - save_item(NAME(voice->volume), voicenum); - save_item(NAME(voice->noise_sw), voicenum); - save_item(NAME(voice->noise_state), voicenum); - save_item(NAME(voice->noise_seed), voicenum); - save_item(NAME(voice->noise_hold), voicenum); - save_item(NAME(voice->noise_counter), voicenum); - save_item(NAME(voice->waveform_select), voicenum); } + + /* register with the save state system */ + save_pointer(STRUCT_MEMBER(m_channel_list, frequency), m_voices); + save_pointer(STRUCT_MEMBER(m_channel_list, counter), m_voices); + save_pointer(STRUCT_MEMBER(m_channel_list, volume), m_voices); + save_pointer(STRUCT_MEMBER(m_channel_list, noise_sw), m_voices); + save_pointer(STRUCT_MEMBER(m_channel_list, noise_state), m_voices); + save_pointer(STRUCT_MEMBER(m_channel_list, noise_seed), m_voices); + save_pointer(STRUCT_MEMBER(m_channel_list, noise_hold), m_voices); + save_pointer(STRUCT_MEMBER(m_channel_list, noise_counter), m_voices); + save_pointer(STRUCT_MEMBER(m_channel_list, waveform_select), m_voices); +} + + +void namco_device::device_start() +{ + namco_audio_device::device_start(); + + m_soundregs = make_unique_clear<uint8_t[]>(0x400); + save_pointer(NAME(m_soundregs), 0x400); +} + + +void namco_15xx_device::device_start() +{ + namco_audio_device::device_start(); + + m_soundregs = make_unique_clear<uint8_t[]>(0x400); + save_pointer(NAME(m_soundregs), 0x400); } @@ -198,14 +208,16 @@ void namco_audio_device::update_namco_waveform(int offset, uint8_t data) /* build the decoded waveform table */ void namco_audio_device::build_decoded_waveform(uint8_t *rgnbase) { - int16_t *p; - int size; - int offset; - int v; - - m_wavedata = (rgnbase != nullptr) ? rgnbase : auto_alloc_array_clear(machine(), uint8_t, 0x400); + if (rgnbase != nullptr) + m_wavedata = rgnbase; + else + { + m_waveram_alloc = make_unique_clear<uint8_t[]>(0x400); + m_wavedata = m_waveram_alloc.get(); + } /* 20pacgal has waves in RAM but old sound system */ + int size; if (rgnbase == nullptr && m_voices != 3) { m_wave_size = 1; @@ -217,20 +229,11 @@ void namco_audio_device::build_decoded_waveform(uint8_t *rgnbase) size = 32 * 8; /* 32 samples, 8 waveforms */ } - p = auto_alloc_array(machine(), int16_t, size * MAX_VOLUME); - - for (v = 0; v < MAX_VOLUME; v++) - { - m_waveform[v] = p; - p += size; - } + for (int v = 0; v < MAX_VOLUME; v++) + m_waveform[v] = std::make_unique<int16_t[]>(size); - /* We need waveform data. It fails if region is not specified. */ - if (m_wavedata) - { - for (offset = 0; offset < 256; offset++) - update_namco_waveform(offset, m_wavedata[offset]); - } + for (int offset = 0; offset < 256; offset++) + update_namco_waveform(offset, m_wavedata[offset]); } @@ -239,7 +242,7 @@ uint32_t namco_audio_device::namco_update_one(write_stream_view &buffer, const i { for (int sampindex = 0; sampindex < buffer.samples(); sampindex++) { - buffer.add(sampindex, stream_buffer::sample_t(wave[WAVEFORM_POSITION(counter)]) * sample_scale); + buffer.add_int(sampindex, wave[WAVEFORM_POSITION(counter)], 32768); counter += freq; } @@ -329,15 +332,17 @@ void namco_cus30_device::pacman_sound_w(offs_t offset, uint8_t data) sound_channel *voice; int ch; + uint8_t *soundregs = &m_wavedata[0x100]; + data &= 0x0f; - if (m_soundregs[offset] == data) + if (soundregs[offset] == data) return; /* update the streams */ m_stream->update(); /* set the register */ - m_soundregs[offset] = data; + soundregs[offset] = data; if (offset < 0x10) ch = (offset - 5) / 5; @@ -364,11 +369,11 @@ void namco_cus30_device::pacman_sound_w(offs_t offset, uint8_t data) case 0x14: /* the frequency has 20 bits */ /* the first voice has extra frequency bits */ - voice->frequency = (ch == 0) ? m_soundregs[0x10] : 0; - voice->frequency += (m_soundregs[ch * 5 + 0x11] << 4); - voice->frequency += (m_soundregs[ch * 5 + 0x12] << 8); - voice->frequency += (m_soundregs[ch * 5 + 0x13] << 12); - voice->frequency += (m_soundregs[ch * 5 + 0x14] << 16); /* always 0 */ + voice->frequency = (ch == 0) ? soundregs[0x10] : 0; + voice->frequency += (soundregs[ch * 5 + 0x11] << 4); + voice->frequency += (soundregs[ch * 5 + 0x12] << 8); + voice->frequency += (soundregs[ch * 5 + 0x13] << 12); + voice->frequency += (soundregs[ch * 5 + 0x14] << 16); /* always 0 */ break; case 0x15: @@ -568,16 +573,16 @@ void namco_cus30_device::namcos1_sound_w(offs_t offset, uint8_t data) return; } - m_soundregs = m_wavedata + 0x100; + uint8_t *soundregs = &m_wavedata[0x100]; - if (m_soundregs[offset] == data) + if (soundregs[offset] == data) return; /* update the streams */ m_stream->update(); /* set the register */ - m_soundregs[offset] = data; + soundregs[offset] = data; ch = offset / 8; if (ch >= m_voices) @@ -596,9 +601,9 @@ void namco_cus30_device::namcos1_sound_w(offs_t offset, uint8_t data) case 0x02: case 0x03: /* the frequency has 20 bits */ - voice->frequency = (m_soundregs[ch * 8 + 0x01] & 15) << 16; /* high bits are from here */ - voice->frequency += m_soundregs[ch * 8 + 0x02] << 8; - voice->frequency += m_soundregs[ch * 8 + 0x03]; + voice->frequency = (soundregs[ch * 8 + 0x01] & 15) << 16; /* high bits are from here */ + voice->frequency += soundregs[ch * 8 + 0x02] << 8; + voice->frequency += soundregs[ch * 8 + 0x03]; break; case 0x04: @@ -699,13 +704,13 @@ void namco_audio_device::sound_stream_update(sound_stream &stream, std::vector<r if (voice->noise_state) { - lmix.add(i, stream_buffer::sample_t(l_noise_data) * sample_scale); - rmix.add(i, stream_buffer::sample_t(r_noise_data) * sample_scale); + lmix.add_int(i, l_noise_data, 32768); + rmix.add_int(i, r_noise_data, 32768); } else { - lmix.add(i, stream_buffer::sample_t(-l_noise_data) * sample_scale); - rmix.add(i, stream_buffer::sample_t(-r_noise_data) * sample_scale); + lmix.add_int(i, -l_noise_data, 32768); + rmix.add_int(i, -r_noise_data, 32768); } if (hold) @@ -799,9 +804,9 @@ void namco_audio_device::sound_stream_update(sound_stream &stream, std::vector<r int cnt; if (voice->noise_state) - buffer.add(i, stream_buffer::sample_t(noise_data) * sample_scale); + buffer.add_int(i, noise_data, 32768); else - buffer.add(i, stream_buffer::sample_t(-noise_data) * sample_scale); + buffer.add_int(i, -noise_data, 32768); if (hold) { diff --git a/src/devices/sound/namco.h b/src/devices/sound/namco.h index 6b3cee6a1f5..f032a71a536 100644 --- a/src/devices/sound/namco.h +++ b/src/devices/sound/namco.h @@ -52,7 +52,6 @@ protected: /* data about the sound system */ sound_channel m_channel_list[MAX_VOICES]; sound_channel *m_last_channel; - uint8_t *m_soundregs; uint8_t *m_wavedata; /* global sound parameters */ @@ -66,8 +65,10 @@ protected: int m_voices; /* number of voices */ bool m_stereo; /* set to indicate stereo (e.g., System 1) */ + std::unique_ptr<uint8_t[]> m_waveram_alloc; + /* decoded waveform table */ - int16_t *m_waveform[MAX_VOLUME]; + std::unique_ptr<int16_t[]> m_waveform[MAX_VOLUME]; virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; }; @@ -79,13 +80,17 @@ public: void pacman_sound_w(offs_t offset, uint8_t data); - void polepos_sound_enable(int enable); - uint8_t polepos_sound_r(offs_t offset); void polepos_sound_w(offs_t offset, uint8_t data); protected: + // device-level overrides + virtual void device_start() override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; + +private: + std::unique_ptr<uint8_t[]> m_soundregs; }; @@ -99,7 +104,13 @@ public: void sharedram_w(offs_t offset, uint8_t data); protected: + // device-level overrides + virtual void device_start() override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; + +private: + std::unique_ptr<uint8_t[]> m_soundregs; }; diff --git a/src/devices/sound/namco_163.cpp b/src/devices/sound/namco_163.cpp index 153b0bfe042..08daf720d17 100644 --- a/src/devices/sound/namco_163.cpp +++ b/src/devices/sound/namco_163.cpp @@ -11,13 +11,14 @@ #include "emu.h" #include "namco_163.h" +#include <algorithm> + DEFINE_DEVICE_TYPE(NAMCO_163, namco_163_sound_device, "namco_163_sound", "Namco 163 (Sound)") namco_163_sound_device::namco_163_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, NAMCO_163, tag, owner, clock) , device_sound_interface(mconfig, *this) - , m_ram(nullptr) , m_reg_addr(0x78) , m_addr(0) , m_inc(false) @@ -33,10 +34,11 @@ namco_163_sound_device::namco_163_sound_device(const machine_config &mconfig, co void namco_163_sound_device::device_start() { - m_ram = make_unique_clear<u8[]>(0x80); - m_stream = stream_alloc_legacy(0, 1, clock() / 15); + std::fill(std::begin(m_ram), std::end(m_ram), 0); + + m_stream = stream_alloc(0, 1, clock() / 15); - save_pointer(NAME(m_ram), 0x80); + save_item(NAME(m_ram)); save_item(NAME(m_reg_addr)); save_item(NAME(m_addr)); save_item(NAME(m_inc)); @@ -143,15 +145,16 @@ u8 namco_163_sound_device::data_r() } -void namco_163_sound_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void namco_163_sound_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - std::fill_n(&outputs[0][0], samples, 0); - if (m_disable) + { + outputs[0].fill(0); return; + } // Slightly noisy but closer to real hardware behavior - for (int s = 0; s < samples; s++) + for (int s = 0; s < outputs[0].samples(); s++) { u32 phase = (m_ram[m_reg_addr + 5] << 16) | (m_ram[m_reg_addr + 3] << 8) | m_ram[m_reg_addr + 1]; const u32 freq = ((m_ram[m_reg_addr + 4] & 0x3) << 16) | (m_ram[m_reg_addr + 2] << 8) | m_ram[m_reg_addr + 0]; @@ -171,6 +174,6 @@ void namco_163_sound_device::sound_stream_update_legacy(sound_stream &stream, st { m_reg_addr = 0x78 - ((m_ram[0x7f] & 0x70) >> 1); } - outputs[0][s] = (output << 8); + outputs[0].put_int(s, output, 128); } } diff --git a/src/devices/sound/namco_163.h b/src/devices/sound/namco_163.h index 74d2ceacb68..f3a7428300d 100644 --- a/src/devices/sound/namco_163.h +++ b/src/devices/sound/namco_163.h @@ -24,7 +24,7 @@ protected: virtual void device_clock_changed() override; // global sound parameters - std::unique_ptr<u8[]> m_ram; + u8 m_ram[0x80]; u8 m_reg_addr; u8 m_addr; bool m_inc; @@ -34,7 +34,7 @@ protected: // internals inline s8 get_sample(u16 addr); - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; }; DECLARE_DEVICE_TYPE(NAMCO_163, namco_163_sound_device) diff --git a/src/devices/sound/nes_apu.cpp b/src/devices/sound/nes_apu.cpp index 1e79304fb3a..483b337475f 100644 --- a/src/devices/sound/nes_apu.cpp +++ b/src/devices/sound/nes_apu.cpp @@ -83,8 +83,8 @@ void nesapu_device::create_syncs(unsigned long sps) DEFINE_DEVICE_TYPE(NES_APU, nesapu_device, "nesapu", "N2A03 APU") -nesapu_device::nesapu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : device_t(mconfig, NES_APU, tag, owner, clock) +nesapu_device::nesapu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, type, tag, owner, clock) , device_sound_interface(mconfig, *this) , m_samps_per_sync(0) , m_buffer_size(0) @@ -108,6 +108,11 @@ nesapu_device::nesapu_device(const machine_config &mconfig, const char *tag, dev } } +nesapu_device::nesapu_device(const machine_config& mconfig, const char* tag, device_t* owner, u32 clock) + : nesapu_device(mconfig, NES_APU, tag, owner, clock) +{ +} + void nesapu_device::device_reset() { write(0x15, 0x00); @@ -134,7 +139,7 @@ void nesapu_device::calculate_rates() if (m_stream != nullptr) m_stream->set_sample_rate(rate); else - m_stream = stream_alloc_legacy(0, 1, rate); + m_stream = stream_alloc(0, 1, rate); } //------------------------------------------------- @@ -725,16 +730,15 @@ void nesapu_device::write(offs_t address, u8 value) //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void nesapu_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void nesapu_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { int accum; - stream_sample_t *output = outputs[0]; - memset( output, 0, samples*sizeof(*output) ); + auto &output = outputs[0]; - while (samples--) + for (int sampindex = 0; sampindex < output.samples(); sampindex++) { accum = apu_square(&m_APU.squ[0]); accum += apu_square(&m_APU.squ[1]); @@ -742,12 +746,6 @@ void nesapu_device::sound_stream_update_legacy(sound_stream &stream, stream_samp accum += apu_noise(&m_APU.noi); accum += apu_dpcm(&m_APU.dpcm); - /* 8-bit clamps */ - if (accum > 127) - accum = 127; - else if (accum < -128) - accum = -128; - - *output++=accum<<8; + output.put_int_clamp(sampindex, accum, 128); } } diff --git a/src/devices/sound/nes_apu.h b/src/devices/sound/nes_apu.h index c0e2e02244b..673c967fec7 100644 --- a/src/devices/sound/nes_apu.h +++ b/src/devices/sound/nes_apu.h @@ -56,11 +56,13 @@ public: void write(offs_t offset, u8 data); protected: + nesapu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + // device-level overrides virtual void device_start() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: /* GLOBAL CONSTANTS */ diff --git a/src/devices/sound/nes_apu_vt.cpp b/src/devices/sound/nes_apu_vt.cpp new file mode 100644 index 00000000000..f93c3203bac --- /dev/null +++ b/src/devices/sound/nes_apu_vt.cpp @@ -0,0 +1,28 @@ +// license:BSD-3-Clause +// copyright-holders:David Haywood + +// The XOP is the NES APU type found in VT platforms, it roughly doubles the functionality of the APU +// but in ways that means simply installing 2 APU devices isn't entirely correct (registers on one +// APU module having an effect on the other) + +// TODO: everything + +#include "emu.h" +#include "sound/nes_apu_vt.h" + +DEFINE_DEVICE_TYPE(NES_APU_VT, nes_apu_vt_device, "nes_apu_vt", "XOP APU") + +nes_apu_vt_device::nes_apu_vt_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : nesapu_device(mconfig, NES_APU_VT, tag, owner, clock) +{ +} + +void nes_apu_vt_device::device_start() +{ + nesapu_device::device_start(); +} + +void nes_apu_vt_device::device_reset() +{ + nesapu_device::device_reset(); +} diff --git a/src/devices/sound/nes_apu_vt.h b/src/devices/sound/nes_apu_vt.h new file mode 100644 index 00000000000..f93616673fa --- /dev/null +++ b/src/devices/sound/nes_apu_vt.h @@ -0,0 +1,26 @@ +// license:BSD-3-Clause +// copyright-holders:David Haywood + +#ifndef MAME_AUDIO_NES_VT_APU_H +#define MAME_AUDIO_NES_VT_APU_H + +#pragma once + +#include "sound/nes_apu.h" + +DECLARE_DEVICE_TYPE(NES_APU_VT, nes_apu_vt_device) + +class nes_apu_vt_device : public nesapu_device +{ +public: + // construction/destruction + nes_apu_vt_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + virtual void device_start() override; + virtual void device_reset() override; + +private: +}; + +#endif // MAME_AUDIO_NES_VT_APU_H diff --git a/src/devices/sound/nile.cpp b/src/devices/sound/nile.cpp index aeaeeaca59c..345c88f2bf0 100644 --- a/src/devices/sound/nile.cpp +++ b/src/devices/sound/nile.cpp @@ -68,7 +68,7 @@ nile_device::nile_device(const machine_config &mconfig, const char *tag, device_ void nile_device::device_start() { - m_stream = stream_alloc_legacy(0, 2, 44100); + m_stream = stream_alloc(0, 2, 44100); save_item(NAME(m_sound_regs)); save_item(NAME(m_vpos)); save_item(NAME(m_frac)); @@ -78,23 +78,24 @@ void nile_device::device_start() //------------------------------------------------- -// sound_stream_update_legacy - handle update requests +// sound_stream_update - handle update requests // for our sound stream //------------------------------------------------- -void nile_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void nile_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { uint8_t *sound_ram = &m_sound_ram[0]; int v, i, snum; uint16_t *slot; - int32_t mix[48000*2]; + int32_t mix[4800*2]; int32_t *mixp; int16_t sample; int sptr, eptr, freq, lsptr, leptr; lsptr=leptr=0; - memset(mix, 0, sizeof(mix[0])*samples*2); + sound_assert(outputs[0].samples() * 2 < ARRAY_LENGTH(mix)); + std::fill_n(&mix[0], outputs[0].samples()*2, 0); for (v = 0; v < NILE_VOICES; v++) { @@ -111,7 +112,7 @@ void nile_device::sound_stream_update_legacy(sound_stream &stream, stream_sample lsptr = slot[NILE_REG_LSPTR_HI]<<16 | slot[NILE_REG_LSPTR_LO]; leptr = slot[NILE_REG_LEPTR_HI]<<16 | slot[NILE_REG_LEPTR_LO]; - for (snum = 0; snum < samples; snum++) + for (snum = 0; snum < outputs[0].samples(); snum++) { sample = sound_ram[sptr + m_vpos[v]]<<8; @@ -159,10 +160,10 @@ void nile_device::sound_stream_update_legacy(sound_stream &stream, stream_sample } } mixp = &mix[0]; - for (i = 0; i < samples; i++) + for (i = 0; i < outputs[0].samples(); i++) { - outputs[0][i] = (*mixp++)>>4; - outputs[1][i] = (*mixp++)>>4; + outputs[0].put_int(i, *mixp++, 32768 * 16); + outputs[1].put_int(i, *mixp++, 32768 * 16); } } diff --git a/src/devices/sound/nile.h b/src/devices/sound/nile.h index a87fb875c11..61add38d44e 100644 --- a/src/devices/sound/nile.h +++ b/src/devices/sound/nile.h @@ -23,7 +23,7 @@ protected: virtual void device_start() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; public: void nile_snd_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); diff --git a/src/devices/sound/okim6258.cpp b/src/devices/sound/okim6258.cpp index 5f063f4cd87..349fe9ca13c 100644 --- a/src/devices/sound/okim6258.cpp +++ b/src/devices/sound/okim6258.cpp @@ -114,7 +114,7 @@ void okim6258_device::device_start() m_divider = dividers[m_start_divider]; - m_stream = stream_alloc_legacy(0, 1, clock()/m_divider); + m_stream = stream_alloc(0, 1, clock()/m_divider); m_signal = -2; m_step = 0; @@ -138,20 +138,18 @@ void okim6258_device::device_reset() //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void okim6258_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void okim6258_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - stream_sample_t *buffer = outputs[0]; - - memset(outputs[0], 0, samples * sizeof(*outputs[0])); + auto &buffer = outputs[0]; if (m_status & STATUS_PLAYING) { int nibble_shift = m_nibble_shift; - while (samples) + for (int sampindex = 0; sampindex < buffer.samples(); sampindex++) { /* Compute the new amplitude and update the current step */ int nibble = (m_data_in >> nibble_shift) & 0xf; @@ -161,8 +159,7 @@ void okim6258_device::sound_stream_update_legacy(sound_stream &stream, stream_sa nibble_shift ^= 4; - *buffer++ = sample; - samples--; + buffer.put_int(sampindex, sample, 32768); } /* Update the parameters */ @@ -170,9 +167,7 @@ void okim6258_device::sound_stream_update_legacy(sound_stream &stream, stream_sa } else { - /* Fill with 0 */ - while (samples--) - *buffer++ = 0; + buffer.fill(0); } } diff --git a/src/devices/sound/okim6258.h b/src/devices/sound/okim6258.h index c8397b998bf..95189f0ef3c 100644 --- a/src/devices/sound/okim6258.h +++ b/src/devices/sound/okim6258.h @@ -47,7 +47,7 @@ protected: virtual void device_clock_changed() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: void state_save_register(); diff --git a/src/devices/sound/okim6295.cpp b/src/devices/sound/okim6295.cpp index c3aee26e52e..a6acbe12e9b 100644 --- a/src/devices/sound/okim6295.cpp +++ b/src/devices/sound/okim6295.cpp @@ -344,7 +344,6 @@ void okim6295_device::okim_voice::generate_adpcm(device_rom_interface &rom, writ return; // loop while we still have samples to generate - constexpr stream_buffer::sample_t sample_scale = 1.0 / 2048.0; for (int sampindex = 0; sampindex < buffer.samples(); sampindex++) { // fetch the next sample byte @@ -352,7 +351,7 @@ void okim6295_device::okim_voice::generate_adpcm(device_rom_interface &rom, writ // output to the buffer, scaling by the volume // signal in range -2048..2047 - buffer.add(sampindex, m_adpcm.clock(nibble) * sample_scale * m_volume); + buffer.add_int(sampindex, m_adpcm.clock(nibble) * m_volume, 2048); // next! if (++m_sample >= m_count) diff --git a/src/devices/sound/okim6376.cpp b/src/devices/sound/okim6376.cpp index 3cb3e6fc17b..d7cd143e003 100644 --- a/src/devices/sound/okim6376.cpp +++ b/src/devices/sound/okim6376.cpp @@ -169,7 +169,7 @@ void okim6376_device::device_start() m_ch2_update = 0; m_st_pulses = 0; /* generate the name and create the stream */ - m_stream = stream_alloc_legacy(0, 1, get_sample_rate()); + m_stream = stream_alloc(0, 1, get_sample_rate()); /* initialize the voices */ for (voice = 0; voice < OKIM6376_VOICES; voice++) @@ -578,21 +578,18 @@ void okim6376_device::write(uint8_t data) } //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void okim6376_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void okim6376_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - int i; - - memset(outputs[0], 0, samples * sizeof(*outputs[0])); + outputs[0].fill(0); - for (i = 0; i < OKIM6376_VOICES; i++) + for (int i = 0; i < OKIM6376_VOICES; i++) { struct ADPCMVoice *voice = &m_voice[i]; - stream_sample_t *buffer = outputs[0]; + auto &buffer = outputs[0]; int16_t sample_data[MAX_SAMPLE_CHUNK]; - int remaining = samples; if (i == 0) //channel 1 is the only channel to affect NAR { if (m_nartimer > 0) @@ -606,16 +603,16 @@ void okim6376_device::sound_stream_update_legacy(sound_stream &stream, stream_sa } /* loop while we have samples remaining */ - while (remaining) + for (int sampindex = 0; sampindex < buffer.samples(); ) { + int remaining = buffer.samples() - sampindex; int samples = (remaining > MAX_SAMPLE_CHUNK) ? MAX_SAMPLE_CHUNK : remaining; - int samp; generate_adpcm(voice, sample_data, samples,i); - for (samp = 0; samp < samples; samp++) - *buffer++ += sample_data[samp]; + for (int samp = 0; samp < samples; samp++) + buffer.add_int(sampindex + samp, sample_data[samp], 32768); - remaining -= samples; + sampindex += samples; } } } diff --git a/src/devices/sound/okim6376.h b/src/devices/sound/okim6376.h index 83be973fadf..34a23764e3a 100644 --- a/src/devices/sound/okim6376.h +++ b/src/devices/sound/okim6376.h @@ -32,7 +32,7 @@ protected: virtual void device_post_load() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; // device_rom_interface overrides virtual void rom_bank_updated() override; diff --git a/src/devices/sound/okim9810.cpp b/src/devices/sound/okim9810.cpp index a28cfb1af79..21e2624cd80 100644 --- a/src/devices/sound/okim9810.cpp +++ b/src/devices/sound/okim9810.cpp @@ -112,7 +112,7 @@ okim9810_device::okim9810_device(const machine_config &mconfig, const char *tag, void okim9810_device::device_start() { // create the stream - m_stream = stream_alloc_legacy(0, 2, clock()); + m_stream = stream_alloc(0, 2, clock()); // save state stuff save_item(NAME(m_TMP_register)); @@ -214,15 +214,15 @@ void okim9810_device::rom_bank_updated() // our sound stream //------------------------------------------------- -void okim9810_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void okim9810_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { // reset the output streams - memset(outputs[0], 0, samples * sizeof(*outputs[0])); - memset(outputs[1], 0, samples * sizeof(*outputs[1])); + outputs[0].fill(0); + outputs[1].fill(0); // iterate over voices and accumulate sample data for (auto & elem : m_voice) - elem.generate_audio(*this, outputs, samples, m_global_volume, m_filter_type); + elem.generate_audio(*this, outputs, m_global_volume, m_filter_type); } @@ -613,8 +613,7 @@ okim9810_device::okim_voice::okim_voice() //------------------------------------------------- void okim9810_device::okim_voice::generate_audio(device_rom_interface &rom, - stream_sample_t * const *buffers, - int samples, + std::vector<write_stream_view> &outputs, const uint8_t global_volume, const uint8_t filter_type) { @@ -623,8 +622,8 @@ void okim9810_device::okim_voice::generate_audio(device_rom_interface &rom, return; // separate out left and right channels - stream_sample_t *outL = buffers[0]; - stream_sample_t *outR = buffers[1]; + auto &outL = outputs[0]; + auto &outR = outputs[1]; // get left and right volumes uint8_t volume_scale_left = volume_scale(global_volume, m_channel_volume, m_pan_volume_left); @@ -636,7 +635,7 @@ void okim9810_device::okim_voice::generate_audio(device_rom_interface &rom, return; // loop while we still have samples to generate - while (samples-- != 0) + for (int sampindex = 0; sampindex < outL.samples(); sampindex++) { // If interpSampleNum == 0, we are at the beginning of a new interp chunk, gather data if (m_interpSampleNum == 0) @@ -747,11 +746,11 @@ void okim9810_device::okim_voice::generate_audio(device_rom_interface &rom, // output to the stereo buffers, scaling by the volume // signal in range -2048..2047, volume in range 2..128 => signal * volume / 8 in range -32768..32767 - int32_t interpValueL = (interpValue * (int32_t)volume_scale_left) / 8; - *outL++ += interpValueL; + int32_t interpValueL = (interpValue * (int32_t)volume_scale_left); + outL.add_int(sampindex, interpValueL, 32768 * 8); - int32_t interpValueR = (interpValue * (int32_t)volume_scale_right) / 8; - *outR++ += interpValueR; + int32_t interpValueR = (interpValue * (int32_t)volume_scale_right); + outR.add_int(sampindex, interpValueR, 32768 * 8); // if the interpsample has reached its end, move on to the next sample m_interpSampleNum++; diff --git a/src/devices/sound/okim9810.h b/src/devices/sound/okim9810.h index dfb4cd047aa..01977b23e2b 100644 --- a/src/devices/sound/okim9810.h +++ b/src/devices/sound/okim9810.h @@ -30,7 +30,7 @@ class okim9810_device : public device_t, public device_sound_interface, - public device_rom_interface<24> + public device_rom_interface<24, 0, 0, ENDIANNESS_BIG> { public: // construction/destruction @@ -87,7 +87,7 @@ protected: virtual void device_clock_changed() override; // device_sound_interface overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; // device_rom_interface overrides virtual void rom_bank_updated() override; @@ -98,8 +98,7 @@ protected: public: okim_voice(); void generate_audio(device_rom_interface &rom, - stream_sample_t * const *buffers, - int samples, + std::vector<write_stream_view> &buffers, const uint8_t global_volume, const uint8_t filter_type); diff --git a/src/devices/sound/pcd3311.cpp b/src/devices/sound/pcd3311.cpp index deae4f61062..4b5a4fb87f5 100644 --- a/src/devices/sound/pcd3311.cpp +++ b/src/devices/sound/pcd3311.cpp @@ -48,10 +48,11 @@ void pcd3311_device::device_start() //------------------------------------------------- -// sound_stream_update_legacy - handle update requests for +// sound_stream_update - handle update requests for // our sound stream //------------------------------------------------- -void pcd3311_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void pcd3311_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { + outputs[0].fill(0); } diff --git a/src/devices/sound/pcd3311.h b/src/devices/sound/pcd3311.h index f56d63633ba..5d5b8870008 100644 --- a/src/devices/sound/pcd3311.h +++ b/src/devices/sound/pcd3311.h @@ -48,7 +48,7 @@ protected: virtual void device_start() override; // internal callbacks - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: int m_a0; diff --git a/src/devices/sound/qs1000.cpp b/src/devices/sound/qs1000.cpp index 5674ab6db18..23b0ee76a44 100644 --- a/src/devices/sound/qs1000.cpp +++ b/src/devices/sound/qs1000.cpp @@ -229,7 +229,7 @@ void qs1000_device::device_start() // The QS1000 operates at 24MHz. Creating a stream at that rate // would be overkill so we opt for a fraction of that rate which // gives reasonable results - m_stream = stream_alloc_legacy(0, 2, clock() / 32); + m_stream = stream_alloc(0, 2, clock() / 32); // Resolve CPU port callbacks m_in_p1_cb.resolve_safe(0); @@ -466,13 +466,13 @@ void qs1000_device::wave_w(offs_t offset, uint8_t data) //------------------------------------------------- -// sound_stream_update_legacy - +// sound_stream_update - //------------------------------------------------- -void qs1000_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void qs1000_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { // Rset the output stream - memset(outputs[0], 0x0, samples * sizeof(*outputs[0])); - memset(outputs[1], 0x0, samples * sizeof(*outputs[1])); + outputs[0].fill(0); + outputs[1].fill(0); // Iterate over voices and accumulate sample data for (auto & chan : m_channels) @@ -485,7 +485,7 @@ void qs1000_device::sound_stream_update_legacy(sound_stream &stream, stream_samp { if (chan.m_flags & QS1000_ADPCM) { - for (int samp = 0; samp < samples; samp++) + for (int samp = 0; samp < outputs[0].samples(); samp++) { if (chan.m_addr >= chan.m_loop_end) { @@ -529,13 +529,13 @@ void qs1000_device::sound_stream_update_legacy(sound_stream &stream, stream_samp chan.m_addr = (chan.m_addr + (chan.m_acc >> 18)) & QS1000_ADDRESS_MASK; chan.m_acc &= ((1 << 18) - 1); - outputs[0][samp] += (result * 4 * lvol * vol) >> 12; - outputs[1][samp] += (result * 4 * rvol * vol) >> 12; + outputs[0].add_int(samp, result * 4 * lvol * vol, 32768 << 12); + outputs[1].add_int(samp, result * 4 * rvol * vol, 32768 << 12); } } else { - for (int samp = 0; samp < samples; samp++) + for (int samp = 0; samp < outputs[0].samples(); samp++) { if (chan.m_addr >= chan.m_loop_end) { @@ -558,8 +558,8 @@ void qs1000_device::sound_stream_update_legacy(sound_stream &stream, stream_samp chan.m_addr = (chan.m_addr + (chan.m_acc >> 18)) & QS1000_ADDRESS_MASK; chan.m_acc &= ((1 << 18) - 1); - outputs[0][samp] += (result * lvol * vol) >> 12; - outputs[1][samp] += (result * rvol * vol) >> 12; + outputs[0].add_int(samp, result * lvol * vol, 32768 << 12); + outputs[1].add_int(samp, result * rvol * vol, 32768 << 12); } } } diff --git a/src/devices/sound/qs1000.h b/src/devices/sound/qs1000.h index 0c16e69b193..aad353962a5 100644 --- a/src/devices/sound/qs1000.h +++ b/src/devices/sound/qs1000.h @@ -73,7 +73,7 @@ protected: virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; // device_sound_interface overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; // device_rom_interface overrides virtual void rom_bank_updated() override; diff --git a/src/devices/sound/qsound.cpp b/src/devices/sound/qsound.cpp index 232e367f1d2..29b2661add5 100644 --- a/src/devices/sound/qsound.cpp +++ b/src/devices/sound/qsound.cpp @@ -207,7 +207,7 @@ void qsound_device::device_add_mconfig(machine_config &config) void qsound_device::device_start() { // hope we get good synchronisation between the DSP and the sound system - m_stream = stream_alloc_legacy(0, 2, clock() / 2 / 1248); + m_stream = stream_alloc(0, 2, clock() / 2 / 1248); // save DSP communication state save_item(NAME(m_rom_bank)); @@ -251,13 +251,13 @@ void qsound_device::device_reset() //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void qsound_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void qsound_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - std::fill_n(outputs[0], samples, m_samples[0]); - std::fill_n(outputs[1], samples, m_samples[1]); + outputs[0].fill(stream_buffer::sample_t(m_samples[0]) * (1.0 / 32768.0)); + outputs[1].fill(stream_buffer::sample_t(m_samples[1]) * (1.0 / 32768.0)); } diff --git a/src/devices/sound/qsound.h b/src/devices/sound/qsound.h index ac0a1053ffe..6a9be5dfbc2 100644 --- a/src/devices/sound/qsound.h +++ b/src/devices/sound/qsound.h @@ -32,7 +32,7 @@ protected: virtual void device_reset() override; // device_sound_interface implementation - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; // device_rom_interface implementation virtual void rom_bank_updated() override; diff --git a/src/devices/sound/qsoundhle.cpp b/src/devices/sound/qsoundhle.cpp index 9ff99ee8cab..913d22baed1 100644 --- a/src/devices/sound/qsoundhle.cpp +++ b/src/devices/sound/qsoundhle.cpp @@ -64,7 +64,7 @@ void qsound_hle_device::rom_bank_updated() void qsound_hle_device::device_start() { - m_stream = stream_alloc_legacy(0, 2, clock() / 2 / 1248); // DSP program uses 1248 machine cycles per iteration + m_stream = stream_alloc(0, 2, clock() / 2 / 1248); // DSP program uses 1248 machine cycles per iteration init_register_map(); @@ -158,20 +158,16 @@ void qsound_hle_device::device_reset() } //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void qsound_hle_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void qsound_hle_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - // Clear the buffers - std::fill_n(outputs[0], samples, 0); - std::fill_n(outputs[1], samples, 0); - - for (int i = 0; i < samples; i ++) + for (int i = 0; i < outputs[0].samples(); i ++) { update_sample(); - outputs[0][i] = m_out[0]; - outputs[1][i] = m_out[1]; + outputs[0].put_int(i, m_out[0], 32768); + outputs[1].put_int(i, m_out[1], 32768); } } diff --git a/src/devices/sound/qsoundhle.h b/src/devices/sound/qsoundhle.h index 23b92738b9b..4d6f61e0c7d 100644 --- a/src/devices/sound/qsoundhle.h +++ b/src/devices/sound/qsoundhle.h @@ -30,7 +30,7 @@ protected: virtual void device_reset() override; // device_sound_interface implementation - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; // device_rom_interface implementation virtual void rom_bank_updated() override; diff --git a/src/devices/sound/rf5c400.cpp b/src/devices/sound/rf5c400.cpp index b8de150f7f6..7495e484540 100644 --- a/src/devices/sound/rf5c400.cpp +++ b/src/devices/sound/rf5c400.cpp @@ -180,7 +180,7 @@ void rf5c400_device::device_start() save_item(STRUCT_MEMBER(m_channels, env_step)); save_item(STRUCT_MEMBER(m_channels, env_scale)); - m_stream = stream_alloc_legacy(0, 2, clock() / 384); + m_stream = stream_alloc(0, 2, clock() / 384); } //------------------------------------------------- @@ -195,10 +195,10 @@ void rf5c400_device::device_clock_changed() } //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void rf5c400_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void rf5c400_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { int i, ch; uint64_t end, loop; @@ -207,14 +207,14 @@ void rf5c400_device::sound_stream_update_legacy(sound_stream &stream, stream_sam uint8_t env_phase; double env_level, env_step, env_rstep; - memset(outputs[0], 0, samples * sizeof(*outputs[0])); - memset(outputs[1], 0, samples * sizeof(*outputs[1])); + outputs[0].fill(0); + outputs[1].fill(0); for (ch=0; ch < 32; ch++) { rf5c400_channel *channel = &m_channels[ch]; - stream_sample_t *buf0 = outputs[0]; - stream_sample_t *buf1 = outputs[1]; + auto &buf0 = outputs[0]; + auto &buf1 = outputs[1]; // start = ((channel->startH & 0xFF00) << 8) | channel->startL; end = ((channel->endHloopH & 0xFF) << 16) | channel->endL; @@ -230,7 +230,7 @@ void rf5c400_device::sound_stream_update_legacy(sound_stream &stream, stream_sam env_step = channel->env_step; env_rstep = env_step * channel->env_scale; - for (i=0; i < samples; i++) + for (i=0; i < buf0.samples(); i++) { int16_t tmp; int32_t sample; @@ -300,8 +300,8 @@ void rf5c400_device::sound_stream_update_legacy(sound_stream &stream, stream_sam sample *= volume_table[vol]; sample = (sample >> 9) * env_level; - *buf0++ += sample * pan_table[lvol]; - *buf1++ += sample * pan_table[rvol]; + buf0.add_int(i, sample * pan_table[lvol], 32768); + buf1.add_int(i, sample * pan_table[rvol], 32768); pos += channel->step; if ((pos>>16) > end) diff --git a/src/devices/sound/rf5c400.h b/src/devices/sound/rf5c400.h index fdd82910b76..6e729daad0a 100644 --- a/src/devices/sound/rf5c400.h +++ b/src/devices/sound/rf5c400.h @@ -34,7 +34,7 @@ protected: virtual void device_clock_changed() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; // device_rom_interface overrides virtual void rom_bank_updated() override; diff --git a/src/devices/sound/rf5c68.cpp b/src/devices/sound/rf5c68.cpp index 1c00941000b..f91e370b95f 100644 --- a/src/devices/sound/rf5c68.cpp +++ b/src/devices/sound/rf5c68.cpp @@ -81,7 +81,7 @@ void rf5c68_device::device_start() m_sample_end_cb.resolve(); /* allocate the stream */ - m_stream = stream_alloc_legacy(0, 2, clock() / 384); + m_stream = stream_alloc(0, 2, clock() / 384); save_item(STRUCT_MEMBER(m_chan, enable)); save_item(STRUCT_MEMBER(m_chan, env)); @@ -116,21 +116,29 @@ device_memory_interface::space_config_vector rf5c68_device::memory_space_config( } //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void rf5c68_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void rf5c68_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - stream_sample_t *left = outputs[0]; - stream_sample_t *right = outputs[1]; - - /* start with clean buffers */ - memset(left, 0, samples * sizeof(*left)); - memset(right, 0, samples * sizeof(*right)); + auto &left = outputs[0]; + auto &right = outputs[1]; /* bail if not enabled */ if (!m_enable) + { + left.fill(0); + right.fill(0); return; + } + + if (m_mixleft.size() < left.samples()) + m_mixleft.resize(left.samples()); + if (m_mixright.size() < right.samples()) + m_mixright.resize(right.samples()); + + std::fill_n(&m_mixleft[0], left.samples(), 0); + std::fill_n(&m_mixright[0], right.samples(), 0); /* loop over channels */ for (pcm_channel &chan : m_chan) @@ -142,7 +150,7 @@ void rf5c68_device::sound_stream_update_legacy(sound_stream &stream, stream_samp int rv = ((chan.pan >> 4) & 0x0f) * chan.env; /* loop over the sample buffer */ - for (int j = 0; j < samples; j++) + for (int j = 0; j < left.samples(); j++) { int sample; @@ -170,13 +178,13 @@ void rf5c68_device::sound_stream_update_legacy(sound_stream &stream, stream_samp if (sample & 0x80) { sample &= 0x7f; - left[j] += (sample * lv) >> 5; - right[j] += (sample * rv) >> 5; + m_mixleft[j] += (sample * lv) >> 5; + m_mixright[j] += (sample * rv) >> 5; } else { - left[j] -= (sample * lv) >> 5; - right[j] -= (sample * rv) >> 5; + m_mixleft[j] -= (sample * lv) >> 5; + m_mixright[j] -= (sample * rv) >> 5; } } } @@ -188,19 +196,10 @@ void rf5c68_device::sound_stream_update_legacy(sound_stream &stream, stream_samp */ const u8 output_shift = (m_output_bits > 16) ? 0 : (16 - m_output_bits); const s32 output_nandmask = (1 << output_shift) - 1; - for (int j = 0; j < samples; j++) + for (int j = 0; j < left.samples(); j++) { - stream_sample_t temp; - - temp = left[j]; - if (temp > 32767) temp = 32767; - else if (temp < -32768) temp = -32768; - left[j] = temp & ~output_nandmask; - - temp = right[j]; - if (temp > 32767) temp = 32767; - else if (temp < -32768) temp = -32768; - right[j] = temp & ~output_nandmask; + left.put_int_clamp(j, m_mixleft[j] & ~output_nandmask, 32768); + right.put_int_clamp(j, m_mixright[j] & ~output_nandmask, 32768); } } diff --git a/src/devices/sound/rf5c68.h b/src/devices/sound/rf5c68.h index 4a1d465e291..d78f378faaf 100644 --- a/src/devices/sound/rf5c68.h +++ b/src/devices/sound/rf5c68.h @@ -45,7 +45,7 @@ protected: virtual void device_clock_changed() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; // device_memory_interface configuration virtual space_config_vector memory_space_config() const override; @@ -75,6 +75,8 @@ private: u16 m_wbank; u8 m_enable; int m_output_bits; + std::vector<s32> m_mixleft; + std::vector<s32> m_mixright; sample_end_cb_delegate m_sample_end_cb; }; diff --git a/src/devices/sound/rolandpcm.cpp b/src/devices/sound/rolandpcm.cpp index 4916605dd7e..d3393785f88 100644 --- a/src/devices/sound/rolandpcm.cpp +++ b/src/devices/sound/rolandpcm.cpp @@ -61,7 +61,7 @@ void mb87419_mb87420_device::device_start() m_clock = clock() / 2; m_rate = m_clock / 512; // usually 32 KHz - m_stream = stream_alloc_legacy(0, 2, m_rate); + m_stream = stream_alloc(0, 2, m_rate); logerror("Roland PCM: Clock %u, Rate %u\n", m_clock, m_rate); } @@ -266,29 +266,29 @@ void mb87419_mb87420_device::write(offs_t offset, u8 data) } //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void mb87419_mb87420_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void mb87419_mb87420_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - memset(outputs[0], 0, samples * sizeof(stream_sample_t)); - memset(outputs[1], 0, samples * sizeof(stream_sample_t)); + outputs[0].fill(0); + outputs[1].fill(0); for (auto& chn : m_chns) { if (! chn.enable || chn.play_dir == 0) continue; - for (int smpl = 0; smpl < samples; smpl ++) + for (int smpl = 0; smpl < outputs[0].samples(); smpl ++) { - stream_sample_t smp_data; + s32 smp_data; if (chn.play_dir > 0) smp_data = sample_interpolate(chn.smpl_cur, chn.smpl_nxt, chn.addr & 0x3FFF); else smp_data = sample_interpolate(chn.smpl_nxt, chn.smpl_cur, chn.addr & 0x3FFF); - smp_data = (smp_data * chn.volume) >> 14; // >>14 results in a good overall volume - outputs[0][smpl] += smp_data; - outputs[1][smpl] += smp_data; + smp_data = smp_data * chn.volume; + outputs[0].add_int(smpl, smp_data, 32768 << 14); // >>14 results in a good overall volume + outputs[1].add_int(smpl, smp_data, 32768 << 14); uint32_t old_addr = chn.addr; if (chn.play_dir > 0) diff --git a/src/devices/sound/rolandpcm.h b/src/devices/sound/rolandpcm.h index 5d1e814d517..1c77be39b98 100644 --- a/src/devices/sound/rolandpcm.h +++ b/src/devices/sound/rolandpcm.h @@ -24,7 +24,7 @@ protected: virtual void device_reset() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; // device_rom_interface overrides virtual void rom_bank_updated() override; diff --git a/src/devices/sound/rp2c33_snd.cpp b/src/devices/sound/rp2c33_snd.cpp index 57e60cf9fb5..d0701041a6b 100644 --- a/src/devices/sound/rp2c33_snd.cpp +++ b/src/devices/sound/rp2c33_snd.cpp @@ -56,7 +56,7 @@ void rp2c33_sound_device::device_start() for (int i = 0; i < 4; i++) m_mvol_table[i] = int((65536.0 / (32.0 * 64.0)) * 2.0 / double(i + 2)); - m_stream = stream_alloc_legacy(0, 1, clock()); + m_stream = stream_alloc(0, 1, clock()); // save states save_item(NAME(m_regs)); @@ -218,12 +218,12 @@ void rp2c33_sound_device::write(offs_t offset, u8 data) } //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void rp2c33_sound_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void rp2c33_sound_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - for (int i = 0; i < samples; i++) + for (int i = 0; i < outputs[0].samples(); i++) { m_output = 0; if (!m_env_halt && !m_wave_halt) @@ -234,7 +234,7 @@ void rp2c33_sound_device::sound_stream_update_legacy(sound_stream &stream, strea exec_mod(); exec_wave(); /* Update the buffers */ - outputs[0][i] = m_output * m_mvol_table[m_mvol]; + outputs[0].put_int(i, m_output * m_mvol_table[m_mvol], 32768); } } diff --git a/src/devices/sound/rp2c33_snd.h b/src/devices/sound/rp2c33_snd.h index 73b737409c2..bdb32e58f60 100644 --- a/src/devices/sound/rp2c33_snd.h +++ b/src/devices/sound/rp2c33_snd.h @@ -43,7 +43,7 @@ protected: virtual void device_clock_changed() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: sound_stream *m_stream = nullptr; diff --git a/src/devices/sound/s14001a.cpp b/src/devices/sound/s14001a.cpp index 5230a66b534..aa4506ba1c8 100644 --- a/src/devices/sound/s14001a.cpp +++ b/src/devices/sound/s14001a.cpp @@ -226,7 +226,7 @@ ALLOW_SAVE_TYPE(s14001a_device::states); // allow save_item on a non-fundamental void s14001a_device::device_start() { - m_stream = stream_alloc_legacy(0, 1, clock() ? clock() : machine().sample_rate()); + m_stream = stream_alloc(0, 1, clock() ? clock() : machine().sample_rate()); // resolve callbacks m_ext_read_handler.resolve(); @@ -311,16 +311,16 @@ void s14001a_device::device_start() //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void s14001a_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void s14001a_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - for (int i = 0; i < samples; i++) + for (int i = 0; i < outputs[0].samples(); i++) { Clock(); int16_t sample = m_uOutputP2 - 7; // range -7..8 - outputs[0][i] = sample * 0xf00; + outputs[0].put_int(i, sample, 8); } } diff --git a/src/devices/sound/s14001a.h b/src/devices/sound/s14001a.h index 09f985a51dc..511503d9daa 100644 --- a/src/devices/sound/s14001a.h +++ b/src/devices/sound/s14001a.h @@ -31,7 +31,7 @@ protected: virtual void device_start() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: uint8_t readmem(uint16_t offset, bool phase); diff --git a/src/devices/sound/s_dsp.cpp b/src/devices/sound/s_dsp.cpp index 9385273ba66..98cd204b503 100644 --- a/src/devices/sound/s_dsp.cpp +++ b/src/devices/sound/s_dsp.cpp @@ -160,7 +160,7 @@ void s_dsp_device::device_start() space().cache(m_cache); space().specific(m_data); - m_channel = stream_alloc_legacy(0, 2, clock() / 64); + m_channel = stream_alloc(0, 2, clock() / 64); state_register(); } @@ -1061,20 +1061,20 @@ void s_dsp_device::state_register() } //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void s_dsp_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void s_dsp_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { s16 mix[2]; - for (int i = 0; i < samples; i++) + for (int i = 0; i < outputs[0].samples(); i++) { mix[0] = mix[1] = 0; dsp_update(mix); /* Update the buffers */ - outputs[0][i] = (stream_sample_t)mix[0]; - outputs[1][i] = (stream_sample_t)mix[1]; + outputs[0].put_int(i, (s32)mix[0], 32768); + outputs[1].put_int(i, (s32)mix[1], 32768); } } diff --git a/src/devices/sound/s_dsp.h b/src/devices/sound/s_dsp.h index 4ab841d0ebd..00097b17303 100644 --- a/src/devices/sound/s_dsp.h +++ b/src/devices/sound/s_dsp.h @@ -30,7 +30,7 @@ protected: virtual void device_clock_changed() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; // device_memory_interface configuration virtual space_config_vector memory_space_config() const override; diff --git a/src/devices/sound/saa1099.cpp b/src/devices/sound/saa1099.cpp index cad84d184bb..080ebabe89c 100644 --- a/src/devices/sound/saa1099.cpp +++ b/src/devices/sound/saa1099.cpp @@ -161,7 +161,7 @@ saa1099_device::saa1099_device(const machine_config &mconfig, const char *tag, d void saa1099_device::device_start() { /* for each chip allocate one stream */ - m_stream = stream_alloc_legacy(0, 2, clock()/clock_divider); + m_stream = stream_alloc(0, 2, clock()/clock_divider); save_item(NAME(m_noise_params)); save_item(NAME(m_env_enable)); @@ -200,18 +200,18 @@ void saa1099_device::device_clock_changed() //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void saa1099_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void saa1099_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { int j, ch; /* if the channels are disabled we're done */ if (!m_all_ch_enable) { /* init output data */ - memset(outputs[LEFT],0,samples*sizeof(*outputs[LEFT])); - memset(outputs[RIGHT],0,samples*sizeof(*outputs[RIGHT])); + outputs[LEFT].fill(0); + outputs[RIGHT].fill(0); return; } @@ -227,7 +227,7 @@ void saa1099_device::sound_stream_update_legacy(sound_stream &stream, stream_sam } /* fill all data needed */ - for( j = 0; j < samples; j++ ) + for( j = 0; j < outputs[0].samples(); j++ ) { int output_l = 0, output_r = 0; @@ -285,8 +285,8 @@ void saa1099_device::sound_stream_update_legacy(sound_stream &stream, stream_sam m_noise[ch].counter -= clock_divider; } /* write sound data to the buffer */ - outputs[LEFT][j] = output_l / 6; - outputs[RIGHT][j] = output_r / 6; + outputs[LEFT].put_int(j, output_l, 32768 * 6); + outputs[RIGHT].put_int(j, output_r, 32768 * 6); } } diff --git a/src/devices/sound/saa1099.h b/src/devices/sound/saa1099.h index 2f9361d5ce8..87f5b58f48a 100644 --- a/src/devices/sound/saa1099.h +++ b/src/devices/sound/saa1099.h @@ -32,7 +32,7 @@ protected: virtual void device_clock_changed() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: struct saa1099_channel diff --git a/src/devices/sound/scsp.cpp b/src/devices/sound/scsp.cpp index 143be37ca40..b340da3d237 100644 --- a/src/devices/sound/scsp.cpp +++ b/src/devices/sound/scsp.cpp @@ -36,9 +36,6 @@ #include <algorithm> -static constexpr s32 clip16(int x) { return std::min(32767, std::max(-32768, x)); } -static constexpr s32 clip18(int x) { return std::min(131071, std::max(-131072, x)); } - #define SHIFT 12 #define LFO_SHIFT 8 #define FIX(v) ((u32) ((float) (1 << SHIFT) * (v))) @@ -165,11 +162,6 @@ scsp_device::scsp_device(const machine_config &mconfig, const char *tag, device_ m_timerC(nullptr), m_mcieb(0), m_mcipd(0), - m_bufferl(nullptr), - m_bufferr(nullptr), - m_exts0(nullptr), - m_exts1(nullptr), - m_length(0), m_RBUFDST(nullptr) { std::fill(std::begin(m_RINGBUF), std::end(m_RINGBUF), 0); @@ -212,7 +204,7 @@ void scsp_device::device_start() m_main_irq_cb.resolve_safe(); // Stereo output with EXTS0,1 Input (External digital audio output) - m_stream = stream_alloc_legacy(2, 2, clock() / 512); + m_stream = stream_alloc(2, 2, clock() / 512); for (int slot = 0; slot < 32; slot++) { @@ -317,17 +309,12 @@ void scsp_device::rom_bank_updated() } //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void scsp_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void scsp_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - m_exts0 = inputs[0]; - m_exts1 = inputs[1]; - m_bufferl = outputs[0]; - m_bufferr = outputs[1]; - m_length = samples; - DoMasterSamples(samples); + DoMasterSamples(inputs, outputs); } u8 scsp_device::DecodeSCI(u8 irq) @@ -1276,17 +1263,12 @@ inline s32 scsp_device::UpdateSlot(SCSP_SLOT *slot) return sample; } -void scsp_device::DoMasterSamples(int nsamples) +void scsp_device::DoMasterSamples(std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - stream_sample_t *bufr,*bufl; - stream_sample_t const *exts[2]; - - bufr = m_bufferr; - bufl = m_bufferl; - exts[0] = m_exts0; - exts[1] = m_exts1; + auto &bufr = outputs[1]; + auto &bufl = outputs[0]; - for (int s = 0; s < nsamples; ++s) + for (int s = 0; s < bufl.samples(); ++s) { s32 smpl = 0, smpr = 0; @@ -1342,7 +1324,7 @@ void scsp_device::DoMasterSamples(int nsamples) SCSP_SLOT *slot = m_Slots + i + 16; // 100217, 100237 EFSDL, EFPAN for EXTS0/1 if (EFSDL(slot)) { - m_DSP.EXTS[i] = exts[i][s]; + m_DSP.EXTS[i] = s32(inputs[i].get(s) * 32768.0); u16 Enc = ((EFPAN(slot)) << 0x8) | ((EFSDL(slot)) << 0xd); smpl += (m_DSP.EXTS[i] * m_LPANTABLE[Enc]) >> SHIFT; smpr += (m_DSP.EXTS[i] * m_RPANTABLE[Enc]) >> SHIFT; @@ -1351,17 +1333,14 @@ void scsp_device::DoMasterSamples(int nsamples) if (DAC18B()) { - smpl = clip18(smpl); - smpr = clip18(smpr); + bufl.put_int_clamp(s, smpl, 131072); + bufr.put_int_clamp(s, smpr, 131072); } else { - smpl = clip16(smpl >> 2); - smpr = clip16(smpr >> 2); + bufl.put_int_clamp(s, smpl >> 2, 32768); + bufr.put_int_clamp(s, smpr >> 2, 32768); } - - *bufl++ = smpl; - *bufr++ = smpr; } } diff --git a/src/devices/sound/scsp.h b/src/devices/sound/scsp.h index 4fe8c5e2a91..7ff91fdb576 100644 --- a/src/devices/sound/scsp.h +++ b/src/devices/sound/scsp.h @@ -45,7 +45,7 @@ protected: virtual void rom_bank_updated() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: enum SCSP_STATE { SCSP_ATTACK, SCSP_DECAY1, SCSP_DECAY2, SCSP_RELEASE }; @@ -148,13 +148,6 @@ private: SCSPDSP m_DSP; - stream_sample_t *m_bufferl; - stream_sample_t *m_bufferr; - stream_sample_t const *m_exts0; - stream_sample_t const *m_exts1; - - int m_length; - s16 *m_RBUFDST; //this points to where the sample will be stored in the RingBuf //LFO @@ -187,7 +180,7 @@ private: void w16(u32 addr, u16 val); u16 r16(u32 addr); inline s32 UpdateSlot(SCSP_SLOT *slot); - void DoMasterSamples(int nsamples); + void DoMasterSamples(std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs); //LFO void LFO_Init(); diff --git a/src/devices/sound/segapcm.cpp b/src/devices/sound/segapcm.cpp index e93bbaec7ee..9b4d7a9c803 100644 --- a/src/devices/sound/segapcm.cpp +++ b/src/devices/sound/segapcm.cpp @@ -39,7 +39,7 @@ void segapcm_device::device_start() std::fill(&m_ram[0], &m_ram[0x800], 0xff); - m_stream = stream_alloc_legacy(0, 2, clock() / 128); + m_stream = stream_alloc(0, 2, clock() / 128); save_item(NAME(m_low)); save_pointer(NAME(m_ram), 0x800); @@ -68,14 +68,14 @@ void segapcm_device::rom_bank_updated() //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void segapcm_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void segapcm_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { /* clear the buffers */ - memset(outputs[0], 0, samples*sizeof(*outputs[0])); - memset(outputs[1], 0, samples*sizeof(*outputs[1])); + outputs[0].fill(0); + outputs[1].fill(0); // reg function // ------------------------------------------------ @@ -113,7 +113,7 @@ void segapcm_device::sound_stream_update_legacy(sound_stream &stream, stream_sam int i; /* loop over samples on this channel */ - for (i = 0; i < samples; i++) + for (i = 0; i < outputs[0].samples(); i++) { int8_t v; @@ -132,8 +132,8 @@ void segapcm_device::sound_stream_update_legacy(sound_stream &stream, stream_sam v = read_byte(offset + (addr >> 8)) - 0x80; /* apply panning and advance */ - outputs[0][i] += v * (regs[2] & 0x7f); - outputs[1][i] += v * (regs[3] & 0x7f); + outputs[0].add_int(i, v * (regs[2] & 0x7f), 32768); + outputs[1].add_int(i, v * (regs[3] & 0x7f), 32768); addr = (addr + regs[7]) & 0xffffff; } diff --git a/src/devices/sound/segapcm.h b/src/devices/sound/segapcm.h index 8b9942a5727..f9869f2211f 100644 --- a/src/devices/sound/segapcm.h +++ b/src/devices/sound/segapcm.h @@ -41,7 +41,7 @@ protected: virtual void device_clock_changed() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; // device_rom_interface overrides virtual void rom_bank_updated() override; diff --git a/src/devices/sound/sid.cpp b/src/devices/sound/sid.cpp index 26ba13a1f4b..86264810fda 100644 --- a/src/devices/sound/sid.cpp +++ b/src/devices/sound/sid.cpp @@ -29,34 +29,10 @@ float filterResTable[16]; #define maxLogicalVoices 4 -const int mix16monoMiddleIndex = 256*maxLogicalVoices/2; -uint16_t mix16mono[256*maxLogicalVoices]; - -uint16_t zero16bit = 0; /* either signed or unsigned */ -//uint32_t splitBufferLen; - -void MixerInit(int threeVoiceAmplify) +inline stream_buffer::sample_t mix_mono(uint16_t usum) { - long si; - uint16_t ui; - long ampDiv = maxLogicalVoices; - - if (threeVoiceAmplify) - { - ampDiv = (maxLogicalVoices-1); - } - - /* Mixing formulas are optimized by sample input value. */ - - si = (-128*maxLogicalVoices) * 256; - for (ui = 0; ui < sizeof(mix16mono)/sizeof(uint16_t); ui++) - { - mix16mono[ui] = (uint16_t)(si/ampDiv) + zero16bit; - si+=256; - } - + return stream_buffer::sample_t(int16_t(usum - maxLogicalVoices*128)) * (1.0 / (256 * maxLogicalVoices)); } - } // anonymous namespace @@ -85,22 +61,22 @@ inline void SID6581_t::syncEm() } -void SID6581_t::fill_buffer(stream_sample_t *buffer, uint32_t bufferLen) +void SID6581_t::fill_buffer(write_stream_view &buffer) { //void* SID6581_t::fill16bitMono(void* buffer, uint32_t numberOfSamples) - for (; bufferLen > 0; bufferLen--) + for (int sampindex = 0; sampindex < buffer.samples(); sampindex++) { - *buffer++ = (int16_t) mix16mono[unsigned(mix16monoMiddleIndex - +(*optr[0].outProc)(&optr[0]) + buffer.put(sampindex, mix_mono( + (*optr[0].outProc)(&optr[0]) +(*optr[1].outProc)(&optr[1]) - +(optr[2].outProc(&optr[2])&optr3_outputmask) + +((*optr[2].outProc)(&optr[2])&optr3_outputmask) /* hack for digi sounds does n't seam to come from a tone operator ghostbusters and goldrunner everything except volume zeroed */ +(masterVolume<<2) // +(*sampleEmuRout)() - )]; + )); syncEm(); } } @@ -227,8 +203,6 @@ void SID6581_t::init() enveEmuInit(PCMfreq, true); - MixerInit(0); - reset(); } diff --git a/src/devices/sound/sid.h b/src/devices/sound/sid.h index 6e5ad1dfa3f..ecf27c2b300 100644 --- a/src/devices/sound/sid.h +++ b/src/devices/sound/sid.h @@ -63,7 +63,7 @@ struct SID6581_t int port_r(running_machine &machine, int offset); void port_w(int offset, int data); - void fill_buffer(stream_sample_t *buffer, uint32_t bufferLen); + void fill_buffer(write_stream_view &buffer); private: void syncEm(); diff --git a/src/devices/sound/sn76477.cpp b/src/devices/sound/sn76477.cpp index 2903af1904b..b8db037e26b 100644 --- a/src/devices/sound/sn76477.cpp +++ b/src/devices/sound/sn76477.cpp @@ -203,7 +203,7 @@ sn76477_device::sn76477_device(const machine_config &mconfig, const char *tag, d void sn76477_device::device_start() { - m_channel = stream_alloc_legacy(0, 1, machine().sample_rate()); + m_channel = stream_alloc(0, 1, machine().sample_rate()); if (clock() > 0) { @@ -1698,10 +1698,10 @@ void sn76477_device::state_save_register() } //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void sn76477_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void sn76477_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { double one_shot_cap_charging_step; double one_shot_cap_discharging_step; @@ -1720,7 +1720,7 @@ void sn76477_device::sound_stream_update_legacy(sound_stream &stream, stream_sam double voltage_out; double center_to_peak_voltage_out; - stream_sample_t *buffer = outputs[0]; + auto &buffer = outputs[0]; /* compute charging values, doing it here ensures that we always use the latest values */ one_shot_cap_charging_step = compute_one_shot_cap_charging_rate() / m_our_sample_rate; @@ -1744,7 +1744,7 @@ void sn76477_device::sound_stream_update_legacy(sound_stream &stream, stream_sam /* process 'samples' number of samples */ - while (samples--) + for (int sampindex = 0; sampindex < buffer.samples(); sampindex++) { /* update the one-shot cap voltage */ if (!m_one_shot_cap_voltage_ext) @@ -1993,10 +1993,10 @@ void sn76477_device::sound_stream_update_legacy(sound_stream &stream, stream_sam 32767 = 2 * OUT_CENTER_LEVEL_VOLTAGE + OUT_LOW_CLIP_THRESHOLD / Vout - Vmin \ - sample = | ----------- - 1 | * 32767 + sample = | ----------- - 1 | \ Vcen - Vmin / */ - *buffer++ = (((voltage_out - OUT_LOW_CLIP_THRESHOLD) / (OUT_CENTER_LEVEL_VOLTAGE - OUT_LOW_CLIP_THRESHOLD)) - 1) * 32767; + buffer.put(sampindex, ((voltage_out - OUT_LOW_CLIP_THRESHOLD) / (OUT_CENTER_LEVEL_VOLTAGE - OUT_LOW_CLIP_THRESHOLD)) - 1); if (LOG_WAV && (!m_enable || !LOG_WAV_ENABLED_ONLY)) { diff --git a/src/devices/sound/sn76477.h b/src/devices/sound/sn76477.h index 42fa82e5efc..094f8e78e1b 100644 --- a/src/devices/sound/sn76477.h +++ b/src/devices/sound/sn76477.h @@ -147,7 +147,7 @@ protected: virtual void device_stop() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: /* chip's external interface */ diff --git a/src/devices/sound/sn76496.cpp b/src/devices/sound/sn76496.cpp index 9bc686dedb2..eac04a2d99f 100644 --- a/src/devices/sound/sn76496.cpp +++ b/src/devices/sound/sn76496.cpp @@ -378,7 +378,6 @@ void sn76496_base_device::sound_stream_update(sound_stream &stream, std::vector< int16_t out; int16_t out2 = 0; - constexpr stream_buffer::sample_t sample_scale = 1.0 / 32768.0; for (int sampindex = 0; sampindex < lbuffer->samples(); sampindex++) { // clock chip once @@ -445,9 +444,9 @@ void sn76496_base_device::sound_stream_update(sound_stream &stream, std::vector< if (m_negate) { out = -out; out2 = -out2; } - lbuffer->put(sampindex, stream_buffer::sample_t(out) * sample_scale); + lbuffer->put_int(sampindex, out, 32768); if (m_stereo) - rbuffer->put(sampindex, stream_buffer::sample_t(out2) * sample_scale); + rbuffer->put_int(sampindex, out2, 32768); } } diff --git a/src/devices/sound/snkwave.cpp b/src/devices/sound/snkwave.cpp index 718dde017fb..44e6ba51466 100644 --- a/src/devices/sound/snkwave.cpp +++ b/src/devices/sound/snkwave.cpp @@ -44,7 +44,7 @@ void snkwave_device::device_start() m_sample_rate = m_external_clock >> CLOCK_SHIFT; /* get stream channels */ - m_stream = stream_alloc_legacy(0, 1, m_sample_rate); + m_stream = stream_alloc(0, 1, m_sample_rate); /* reset all the voices */ m_frequency = 0; @@ -60,26 +60,26 @@ void snkwave_device::device_start() //------------------------------------------------- -// sound_stream_update_legacy - handle update requests +// sound_stream_update - handle update requests // for our sound stream //------------------------------------------------- -void snkwave_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void snkwave_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - stream_sample_t *buffer = outputs[0]; - - /* zap the contents of the buffer */ - memset(buffer, 0, samples * sizeof(*buffer)); + auto &buffer = outputs[0]; assert(m_counter < 0x1000); assert(m_frequency < 0x1000); /* if no sound, we're done */ if (m_frequency == 0xfff) + { + buffer.fill(0); return; + } /* generate sound into buffer while updating the counter */ - while (samples-- > 0) + for (int sampindex = 0; sampindex < buffer.samples(); sampindex++) { int loops; int16_t out = 0; @@ -104,7 +104,7 @@ void snkwave_device::sound_stream_update_legacy(sound_stream &stream, stream_sam } } - *buffer++ = out; + buffer.put_int(sampindex, out, 32768); } } diff --git a/src/devices/sound/snkwave.h b/src/devices/sound/snkwave.h index 2ecb5f7715d..bf40a33e500 100644 --- a/src/devices/sound/snkwave.h +++ b/src/devices/sound/snkwave.h @@ -26,7 +26,7 @@ protected: virtual void device_start() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: static constexpr unsigned WAVEFORM_LENGTH = 16; diff --git a/src/devices/sound/sp0250.cpp b/src/devices/sound/sp0250.cpp index e18143a29b0..862b3781a7c 100644 --- a/src/devices/sound/sp0250.cpp +++ b/src/devices/sound/sp0250.cpp @@ -258,9 +258,8 @@ void sp0250_device::sound_stream_update(sound_stream &stream, std::vector<read_s if (!m_pwm_mode) { - constexpr stream_buffer::sample_t sample_scale = 1.0 / 128.0; for (int sampindex = 0; sampindex < output.samples(); sampindex++) - output.put(sampindex, stream_buffer::sample_t(next()) * sample_scale); + output.put_int(sampindex, next(), 128); } else { diff --git a/src/devices/sound/sp0256.cpp b/src/devices/sound/sp0256.cpp index b4d18e6d6d3..5188d3bc31f 100644 --- a/src/devices/sound/sp0256.cpp +++ b/src/devices/sound/sp0256.cpp @@ -74,7 +74,7 @@ void sp0256_device::device_start() m_drq_cb(1); m_sby_cb(1); - m_stream = stream_alloc_legacy(0, 1, clock() / CLOCK_DIVIDER); + m_stream = stream_alloc(0, 1, clock() / CLOCK_DIVIDER); /* -------------------------------------------------------------------- */ /* Configure our internal variables. */ @@ -1260,16 +1260,16 @@ TIMER_CALLBACK_MEMBER(sp0256_device::set_lrq_timer_proc) } //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void sp0256_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void sp0256_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - stream_sample_t *output = outputs[0]; + auto &output = outputs[0]; int output_index = 0; int length, did_samp/*, old_idx*/; - while (output_index < samples) + while (output_index < output.samples()) { /* ---------------------------------------------------------------- */ /* First, drain as much of our scratch buffer as we can into the */ @@ -1278,20 +1278,20 @@ void sp0256_device::sound_stream_update_legacy(sound_stream &stream, stream_samp while (m_sc_tail != m_sc_head) { - output[output_index++] = m_scratch[m_sc_tail++ & SCBUF_MASK]; + output.put_int(output_index++, m_scratch[m_sc_tail++ & SCBUF_MASK], 32768); m_sc_tail &= SCBUF_MASK; - if (output_index > samples) + if (output_index >= output.samples()) break; } /* ---------------------------------------------------------------- */ /* If output outputs is full, then we're done. */ /* ---------------------------------------------------------------- */ - if (output_index > samples) + if (output_index > output.samples()) break; - length = samples - output_index; + length = output.samples() - output_index; /* ---------------------------------------------------------------- */ /* Process the current set of filter coefficients as long as the */ diff --git a/src/devices/sound/sp0256.h b/src/devices/sound/sp0256.h index 3720b3429ed..d1e1d5612cf 100644 --- a/src/devices/sound/sp0256.h +++ b/src/devices/sound/sp0256.h @@ -61,7 +61,7 @@ protected: virtual void device_reset() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: struct lpc12_t diff --git a/src/devices/sound/spkrdev.cpp b/src/devices/sound/spkrdev.cpp index 3fc3467771e..184a628fe73 100644 --- a/src/devices/sound/spkrdev.cpp +++ b/src/devices/sound/spkrdev.cpp @@ -76,7 +76,7 @@ #include "sound/spkrdev.h" -static constexpr int16_t default_levels[2] = {0, 32767}; +static constexpr double default_levels[2] = {0.0, 1.0}; // Internal oversampling factor (interm. samples vs stream samples) static constexpr int RATE_MULTIPLIER = 4; @@ -102,7 +102,7 @@ void speaker_sound_device::device_start() int i; double x; - m_channel = stream_alloc_legacy(0, 1, machine().sample_rate()); + m_channel = stream_alloc(0, 1, machine().sample_rate()); m_level = 0; for (i = 0; i < FILTER_LENGTH; i++) @@ -198,23 +198,23 @@ void speaker_sound_device::device_post_load() } //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- // This can be triggered by the core (based on emulated time) or via level_w(). -void speaker_sound_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void speaker_sound_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - stream_sample_t *buffer = outputs[0]; - int volume = m_levels[m_level]; + auto &buffer = outputs[0]; + double volume = m_levels[m_level]; double filtered_volume; attotime sampled_time = attotime::zero; - if (samples > 0) + if (buffer.samples() > 0) { /* Prepare to update time state */ sampled_time = attotime(0, m_channel_sample_period); - if (samples > 1) - sampled_time *= samples; + if (buffer.samples() > 1) + sampled_time *= buffer.samples(); /* Note: since the stream is in the process of being updated, * stream->sample_time() will return the time before the update! (MAME 0.130) @@ -222,19 +222,19 @@ void speaker_sound_device::sound_stream_update_legacy(sound_stream &stream, stre */ } - if (samples-- > 0) + for (int sampindex = 0; sampindex < buffer.samples(); ) { /* Note that first interm. sample may be composed... */ filtered_volume = update_interm_samples_get_filtered_volume(volume); /* Composite volume is now quantized to the stream resolution */ - *buffer++ = (stream_sample_t)filtered_volume; + buffer.put(sampindex++, filtered_volume); /* Any additional samples will be homogeneous, however may need filtering across samples: */ - while (samples-- > 0) + while (sampindex < buffer.samples()) { filtered_volume = update_interm_samples_get_filtered_volume(volume); - *buffer++ = (stream_sample_t)filtered_volume; + buffer.put(sampindex++, filtered_volume); } /* Update the time state */ @@ -322,7 +322,7 @@ void speaker_sound_device::update_interm_samples(const attotime &time, int volum } -double speaker_sound_device::update_interm_samples_get_filtered_volume(int volume) +double speaker_sound_device::update_interm_samples_get_filtered_volume(double volume) { double filtered_volume, tempx; @@ -355,7 +355,7 @@ double speaker_sound_device::update_interm_samples_get_filtered_volume(int volum } -void speaker_sound_device::finalize_interm_sample(int volume) +void speaker_sound_device::finalize_interm_sample(double volume) { double fraction; @@ -401,7 +401,7 @@ double speaker_sound_device::get_filtered_volume() { if (i >= FILTER_LENGTH) i = 0; filtered_volume += m_composed_volume[i] * m_ampl[c]; - ampsum += m_ampl[c]; + ampsum += std::abs(m_ampl[c]); } filtered_volume /= ampsum; diff --git a/src/devices/sound/spkrdev.h b/src/devices/sound/spkrdev.h index 7411e47170d..596a4f94854 100644 --- a/src/devices/sound/spkrdev.h +++ b/src/devices/sound/spkrdev.h @@ -21,7 +21,7 @@ public: ~speaker_sound_device() {} // configuration - void set_levels(int num_levels, const int16_t *levels) { m_num_levels = num_levels; m_levels = levels; } + void set_levels(int num_levels, const double *levels) { m_num_levels = num_levels; m_levels = levels; } void level_w(int new_level); // can use as writeline @@ -32,7 +32,7 @@ protected: virtual void device_post_load() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: // Length of anti-aliasing filter kernel, measured in number of intermediate samples @@ -47,9 +47,9 @@ private: void update_interm_samples(const attotime &time, int volume); // Updates the composed volume array and returns final filtered volume of next stream sample - double update_interm_samples_get_filtered_volume(int volume); + double update_interm_samples_get_filtered_volume(double volume); - void finalize_interm_sample(int volume); + void finalize_interm_sample(double volume); void init_next_interm_sample(); inline double make_fraction(const attotime &a, const attotime &b, double timediv); double get_filtered_volume(); @@ -80,7 +80,7 @@ private: double m_prevx, m_prevy; int m_num_levels; /* optional: number of levels (if not two) */ - const int16_t *m_levels; /* optional: pointer to level lookup table */ + const double *m_levels; /* optional: pointer to level lookup table */ }; DECLARE_DEVICE_TYPE(SPEAKER_SOUND, speaker_sound_device) diff --git a/src/devices/sound/spu.cpp b/src/devices/sound/spu.cpp index 82f5d3973ac..9a8f503cf04 100644 --- a/src/devices/sound/spu.cpp +++ b/src/devices/sound/spu.cpp @@ -272,7 +272,8 @@ public: invalid_end, loopaddr, last_update_end; - signed short *data,*loop,*dend; + std::unique_ptr<signed short []> data; + signed short *loop,*dend; adpcm_decoder decoder, update_decoder; mutable int ref_count; bool valid, @@ -301,8 +302,8 @@ public: ref_count--; if (ref_count==0) { - cache_size-=(dend-data)<<1; - global_free(this); + cache_size-=(dend-data.get())<<1; + delete this; } } @@ -521,7 +522,7 @@ public: head=xam->offset; marker_tail=xam->prev; if (marker_tail) marker_tail->next=nullptr; - global_free(xam); + delete xam; } // Set marker head to nullptr if the list is now empty @@ -544,7 +545,7 @@ public: { stream_marker *m=marker_head; marker_head=marker_head->next; - global_free(m); + delete m; } marker_head=marker_tail=nullptr; @@ -566,7 +567,7 @@ public: stream_marker *xam=marker_head; marker_head=xam->next; - global_free(xam); + delete xam; if (marker_head) marker_head->prev=nullptr; } @@ -606,12 +607,12 @@ static inline int clamp(const int v) spu_device::sample_cache::~sample_cache() { - global_free_array(data); + data.reset(); while (loop_cache) { sample_loop_cache *lc=loop_cache; loop_cache=lc->next; - global_free(lc); + delete lc; } } @@ -623,7 +624,7 @@ signed short *spu_device::sample_cache::get_sample_pointer(const unsigned int ad { if ((addr>=start) && (addr<end)) { - return data+(((addr-start)>>4)*28); + return &data[((addr-start)>>4)*28]; } else { return nullptr; @@ -668,9 +669,9 @@ bool spu_device::sample_cache::get_loop_pointer(cache_pointer *cp) unsigned int spu_device::sample_cache::get_sample_address(const signed short *ptr) const { - if ((ptr>=data) && (ptr<=dend)) + if ((ptr>=data.get()) && (ptr<=dend)) { - return start+(((ptr-data)/28)<<4); + return start+(((ptr-data.get())/28)<<4); } else { return -1; @@ -705,7 +706,7 @@ void spu_device::sample_cache::add_loop_cache(sample_loop_cache *lc) bool spu_device::sample_cache::is_valid_pointer(signed short *ptr) const { - if ((ptr>=data) && (data<=dend)) return true; + if ((ptr>=data.get()) && (data.get()<=dend)) return true; for (sample_loop_cache *slc=loop_cache; slc; slc=slc->next) if ((ptr>=slc->data) && (ptr<(slc->data+num_loop_cache_samples))) return true; @@ -720,7 +721,7 @@ bool spu_device::sample_cache::try_update(spu_device *spu) { if ((invalid_start>=start) && (invalid_end<=end)) { - adpcm_packet *ap=(adpcm_packet *)(spu->spu_ram+start); + adpcm_packet *ap=(adpcm_packet *)&spu->spu_ram[start]; unsigned int a; unsigned int loop=0; @@ -756,8 +757,8 @@ bool spu_device::sample_cache::try_update(spu_device *spu) printf("\n"); #endif - signed short *dp=data+(((invalid_start-start)>>4)*28); - ap=(adpcm_packet *)(spu->spu_ram+invalid_start); + signed short *dp=&data[((invalid_start-start)>>4)*28]; + ap=(adpcm_packet *)&spu->spu_ram[invalid_start]; for (a=invalid_start; a<invalid_end; a+=16, ap++) dp=update_decoder.decode_packet(ap,dp); @@ -779,7 +780,7 @@ bool spu_device::sample_cache::try_update(spu_device *spu) signed short *dpend=dp+lc->len; unsigned int adr=lc->loopstart; for (unsigned int i=0; ((i<num_loop_cache_packets) && (dp<dpend)); i++, adr+=16) - dp=tmp.decode_packet((adpcm_packet *)(spu->spu_ram+adr),dp); + dp=tmp.decode_packet((adpcm_packet *)&spu->spu_ram[adr],dp); } } @@ -847,7 +848,7 @@ bool spu_device::cache_pointer::update(spu_device *spu) // Cache is invalid, calculate play address offset from start of // old cache block - unsigned int off=ptr-cache->data, + unsigned int off=ptr-cache->data.get(), addr=cache->start; // Release cache block and get updated one @@ -856,7 +857,7 @@ bool spu_device::cache_pointer::update(spu_device *spu) // Calculate play address in new cache block - ptr=cache->data+off; + ptr=&cache->data[off]; if (ptr>=cache->dend) { @@ -870,7 +871,7 @@ bool spu_device::cache_pointer::update(spu_device *spu) // Return false if we do not have a cache block or the play address is invalid - if ((cache) && ((ptr>=cache->data) && (ptr<cache->dend))) + if ((cache) && ((ptr>=cache->data.get()) && (ptr<cache->dend))) { return true; } else @@ -967,15 +968,15 @@ void spu_device::device_start() m_irq_handler.resolve_safe(); voice=new voiceinfo [24]; - spu_ram=new unsigned char [spu_ram_size]; + spu_ram=std::make_unique<unsigned char []>(spu_ram_size); xa_buffer=new spu_stream_buffer(xa_sector_size,xa_buffer_sectors); cdda_buffer=new spu_stream_buffer(cdda_sector_size,cdda_buffer_sectors); init_stream(); - cache=new sample_cache *[spu_ram_size>>4]; - memset(cache,0,(spu_ram_size>>4)*sizeof(sample_cache *)); + cache=std::make_unique<sample_cache * []>(spu_ram_size>>4); + std::fill_n(cache.get(), spu_ram_size>>4, nullptr); // register save state stuff save_item(NAME(reg)); // this covers all spureg.* plus the reverb parameter block @@ -1031,16 +1032,16 @@ void spu_device::device_reset() cdda_playing=false; m_cd_out_ptr = 0; - memset(spu_ram,0,spu_ram_size); + memset(spu_ram.get(),0,spu_ram_size); memset(reg,0,0x200); memset(voice,0,sizeof(voiceinfo)*24); spureg.status|=(1<<7)|(1<<10); - memset(cache,0,(spu_ram_size>>4)*sizeof(sample_cache *)); + std::fill_n(cache.get(), spu_ram_size>>4, nullptr); for (auto & elem : output_buf) - elem=new unsigned char [output_buffer_size]; + elem=std::make_unique<unsigned char []>(output_buffer_size); output_head=output_tail=output_size=0; noise_t=0; @@ -1058,7 +1059,7 @@ void spu_device::device_post_load() dirty_flags = -1; // kill and reallocate reverb to avoid artifacts - global_free(rev); + delete rev; rev = new reverb(44100); // and do some update processing @@ -1074,16 +1075,16 @@ void spu_device::device_post_load() void spu_device::device_stop() { for (auto & elem : output_buf) - global_free_array(elem); + elem.reset(); kill_stream(); - global_free_array(spu_ram); + spu_ram.reset(); invalidate_cache(0,spu_ram_size); - global_free_array(cache); - global_free(xa_buffer); - global_free(cdda_buffer); - global_free_array(voice); + cache.reset(); + delete xa_buffer; + delete cdda_buffer; + delete [] voice; } // // @@ -1093,7 +1094,7 @@ void spu_device::init_stream() { const unsigned int hz=44100; - m_stream = stream_alloc_legacy(0, 2, hz); + m_stream = stream_alloc(0, 2, hz); rev=new reverb(hz); @@ -1107,7 +1108,7 @@ void spu_device::init_stream() void spu_device::kill_stream() { - global_free(rev); + delete rev; rev=nullptr; } @@ -1262,7 +1263,7 @@ void spu_device::write_data(const unsigned short data) assert(taddr<spu_ram_size); if (cache[taddr>>4]) flush_cache(cache[taddr>>4],taddr,taddr+2); - *((unsigned short *)(spu_ram+taddr))=data; + *((unsigned short *)&spu_ram[taddr])=data; taddr+=2; } @@ -1342,7 +1343,7 @@ spu_device::sample_cache *spu_device::get_sample_cache(const unsigned int addr) sc->start=addr; sc->loop=nullptr; - adpcm_packet *ap=(adpcm_packet *)(spu_ram+sc->start); + adpcm_packet *ap=(adpcm_packet *)&spu_ram[sc->start]; unsigned int a; for (a=addr; a<(512*1024); a+=16, ap++) { @@ -1358,13 +1359,13 @@ spu_device::sample_cache *spu_device::get_sample_cache(const unsigned int addr) sc->end=(std::min)(spu_ram_size,a+16); unsigned int sz=((sc->end-sc->start)>>4)*28; - sc->data=new signed short [sz]; + sc->data=std::make_unique<signed short []>(sz); sample_cache::cache_size+=sz<<1; sc->loopaddr=loop; - if (loop) sc->loop=sc->data+(((loop-sc->start)>>4)*28); + if (loop) sc->loop=&sc->data[((loop-sc->start)>>4)*28]; - signed short *dp=sc->data; - ap=(adpcm_packet *)(spu_ram+sc->start); + signed short *dp=sc->data.get(); + ap=(adpcm_packet *)&spu_ram[sc->start]; for (a=sc->start; a<sc->end; a+=16, ap++) dp=sc->decoder.decode_packet(ap,dp); @@ -1389,7 +1390,7 @@ bool spu_device::translate_sample_addr(const unsigned int addr, cache_pointer *c cp->reset(); if ((cp->cache=get_sample_cache(addr))) { - cp->ptr=cp->cache->data+(((addr-cp->cache->start)>>4)*28); + cp->ptr=&cp->cache->data[((addr-cp->cache->start)>>4)*28]; cp->cache->add_ref(); return true; } @@ -1530,7 +1531,7 @@ spu_device::sample_loop_cache *spu_device::get_loop_cache(sample_cache *cache, c signed short *dp=lc->data; for (unsigned int i=0; ((i<num_loop_cache_packets) && (adr<lpcache->end)); i++, adr+=16) - dp=tmp.decode_packet((adpcm_packet *)(spu_ram+adr),dp); + dp=tmp.decode_packet((adpcm_packet *)&spu_ram[adr],dp); #ifdef log_loop_cache log(log_spu,"spu: add loop cache %08x %08x->%08x (end at %08x)\n",lc,lpen,lpst,adr); @@ -1572,7 +1573,7 @@ void spu_device::update_voice_loop(const unsigned int v) { ra=spureg.voice[v].repaddr<<3; ra=(ra+0xf)&~0xf; - const adpcm_packet *ap=ra?(adpcm_packet *)(spu_ram+ra):nullptr; + const adpcm_packet *ap=ra?(adpcm_packet *)&spu_ram[ra]:nullptr; if (ap) { @@ -2393,8 +2394,8 @@ void spu_device::generate_xa(void *ptr, const unsigned int sz) // Write to SPU XA buffer (for emulation purposes - some games read this // back to do analysers, etc...) - *(signed short *)(spu_ram+xa_out_ptr)=vl; - *(signed short *)(spu_ram+xa_out_ptr+0x800)=vr; + *(signed short *)&spu_ram[xa_out_ptr]=vl; + *(signed short *)&spu_ram[xa_out_ptr+0x800]=vr; xa_out_ptr=(xa_out_ptr+2)&0x7ff; // Mix samples into output buffer @@ -2430,7 +2431,7 @@ void spu_device::generate_xa(void *ptr, const unsigned int sz) { xa_playing=false; - memset(spu_ram,0,0x1000); + memset(spu_ram.get(),0,0x1000); xa_out_ptr=0; } } @@ -2465,8 +2466,8 @@ void spu_device::generate_cdda(void *ptr, const unsigned int sz) int16_t vr = ((sp[1]*volr)>>15); // if the volume adjusted samples are stored here, vibribbon does nothing - *(signed short *)(spu_ram+m_cd_out_ptr)=sp[0]; - *(signed short *)(spu_ram+m_cd_out_ptr+0x400)=sp[1]; + *(signed short *)&spu_ram[m_cd_out_ptr]=sp[0]; + *(signed short *)&spu_ram[m_cd_out_ptr+0x400]=sp[1]; m_cd_out_ptr=(m_cd_out_ptr+2)&0x3ff; //if((m_cd_out_ptr == ((spureg.irq_addr << 3) & ~0x400)) && (spureg.ctrl & spuctrl_irq_enable)) @@ -2575,10 +2576,10 @@ void spu_device::generate(void *ptr, const unsigned int sz) while ((left) && (output_size)) { unsigned int n=(std::min)((std::min)(left,output_buffer_size-output_head),output_size); - memcpy(dp,output_buf[0]+output_head,n); + memcpy(dp,&output_buf[0][output_head],n); rev->process((signed short *)dp, - (signed short *)(output_buf[1]+output_head), + (signed short *)&output_buf[1][output_head], spu_reverb_cfg, (signed short)spureg.rvol_l, (signed short)spureg.rvol_r, @@ -2683,10 +2684,10 @@ void spu_device::process_until(const unsigned int tsample) process_samples=(std::min)(process_samples, (output_buffer_size-output_tail)>>2); - unsigned char *outptr=output_buf[0]+output_tail, - *reverbptr=output_buf[1]+output_tail, - *fmptr=output_buf[2]+output_tail, - *noiseptr=output_buf[3]+output_tail; + unsigned char *outptr=&output_buf[0][output_tail], + *reverbptr=&output_buf[1][output_tail], + *fmptr=&output_buf[2][output_tail], + *noiseptr=&output_buf[3][output_tail]; output_tail+=process_samples<<2; output_tail&=(output_buffer_size-1); @@ -2761,21 +2762,20 @@ void spu_device::update_timing() // // -void spu_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void spu_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - stream_sample_t *outL, *outR; int16_t temp[44100], *src; - outL = outputs[0]; - outR = outputs[1]; + auto &outL = outputs[0]; + auto &outR = outputs[1]; - generate(temp, samples*4); // second parameter is bytes, * 2 (size of int16_t) * 2 (stereo) + generate(temp, outputs[0].samples()*4); // second parameter is bytes, * 2 (size of int16_t) * 2 (stereo) src = &temp[0]; - for (int i = 0; i < samples; i++) + for (int i = 0; i < outputs[0].samples(); i++) { - *outL++ = *src++; - *outR++ = *src++; + outL.put_int(i, *src++, 32768); + outR.put_int(i, *src++, 32768); } } @@ -2797,13 +2797,13 @@ void spu_device::start_dma(uint8_t *mainram, bool to_spu, uint32_t size) { invalidate_cache(st,en); - memcpy(spu_ram+(spureg.trans_addr<<3), mainram, size); + memcpy(&spu_ram[spureg.trans_addr<<3], mainram, size); dirty_flags|=dirtyflag_ram; } else { - memcpy(mainram, spu_ram+(spureg.trans_addr<<3), size); + memcpy(mainram, &spu_ram[spureg.trans_addr<<3], size); } } @@ -3034,7 +3034,7 @@ bool spu_device::play_cdda(const unsigned int sector, const unsigned char *cdda) flip[i] = flip[i+1]; flip[i+1] = temp; } - // this should be done in generate but sound_stream_update_legacy may not be called frequently enough + // this should be done in generate but sound_stream_update may not be called frequently enough if(((spureg.irq_addr << 3) < 0x800) && (spureg.ctrl & spuctrl_irq_enable)) m_irq_handler(1); diff --git a/src/devices/sound/spu.h b/src/devices/sound/spu.h index 7913670c667..7aee602e38c 100644 --- a/src/devices/sound/spu.h +++ b/src/devices/sound/spu.h @@ -35,7 +35,7 @@ protected: virtual void device_post_load() override; virtual void device_stop() override; - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; static constexpr float ms_to_rate(float ms) { return 1.0f / (ms * (float(spu_base_frequency_hz) / 1000.0f)); } static constexpr float s_to_rate(float s) { return ms_to_rate(s * 1000.0f); } @@ -49,7 +49,7 @@ protected: // internal state devcb_write_line m_irq_handler; - unsigned char *spu_ram; + std::unique_ptr<unsigned char []> spu_ram; reverb *rev; unsigned int taddr; unsigned int sample_t; @@ -73,13 +73,13 @@ protected: bool status_enabled, xa_playing, cdda_playing; int xa_voll, xa_volr, changed_xa_vol; voiceinfo *voice; - sample_cache **cache; + std::unique_ptr<sample_cache * []> cache; float samples_per_frame; float samples_per_cycle; static float freq_multiplier; - unsigned char *output_buf[4]; + std::unique_ptr<unsigned char []> output_buf[4]; unsigned int output_head; unsigned int output_tail; unsigned int output_size; diff --git a/src/devices/sound/spureverb.cpp b/src/devices/sound/spureverb.cpp index cf747af1acb..e57c33d448d 100644 --- a/src/devices/sound/spureverb.cpp +++ b/src/devices/sound/spureverb.cpp @@ -34,15 +34,11 @@ spu_device::reverb::reverb(const int hz, const int maxdelay) for (int c=0; c<2; c++) { for (int f=0; f<4; f++) { - y[c][f]=new signed short [maxdelay]; - memset(y[c][f], 0, sizeof(signed short) * maxdelay); + y[c][f]=make_unique_clear<signed short []>(maxdelay); } - x[c]=new signed short [maxdelay]; - memset(x[c], 0, sizeof(signed short) * maxdelay); - ax[c]=new signed short [maxdelay]; - memset(ax[c], 0, sizeof(signed short) * maxdelay); - ay[c]=new signed short [maxdelay]; - memset(ay[c], 0, sizeof(signed short) * maxdelay); + x[c]=make_unique_clear<signed short []>(maxdelay); + ax[c]=make_unique_clear<signed short []>(maxdelay); + ay[c]=make_unique_clear<signed short []>(maxdelay); } memset(bx1,0,sizeof(bx1)); memset(by1,0,sizeof(by1)); @@ -54,14 +50,6 @@ spu_device::reverb::reverb(const int hz, const int maxdelay) spu_device::reverb::~reverb() { - for (int c=0; c<2; c++) - { - for (int f=0; f<4; f++) - global_free_array(y[c][f]); - global_free_array(x[c]); - global_free_array(ax[c]); - global_free_array(ay[c]); - } } // diff --git a/src/devices/sound/spureverb.h b/src/devices/sound/spureverb.h index 64b174bcfb6..d87c3a6b4b8 100644 --- a/src/devices/sound/spureverb.h +++ b/src/devices/sound/spureverb.h @@ -29,12 +29,12 @@ struct spu_device::reverb_preset class spu_device::reverb { - signed short - *y[2][4], - *x[2], - *ax[2], - *ay[2], - bx1[2][2],by1[2]; + std::unique_ptr<signed short []> + y[2][4], + x[2], + ax[2], + ay[2]; + signed short bx1[2][2],by1[2]; int yp, max_delay, sound_hz; typedef int comb_param[2][4]; diff --git a/src/devices/sound/st0016.cpp b/src/devices/sound/st0016.cpp index e0318eca466..d13dfd7cacc 100644 --- a/src/devices/sound/st0016.cpp +++ b/src/devices/sound/st0016.cpp @@ -43,7 +43,7 @@ st0016_device::st0016_device(const machine_config &mconfig, const char *tag, dev void st0016_device::device_start() { - m_stream = stream_alloc_legacy(0, 2, 44100); + m_stream = stream_alloc(0, 2, 44100); m_ram_read_cb.resolve_safe(0); save_item(NAME(m_vpos)); @@ -54,10 +54,10 @@ void st0016_device::device_start() //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void st0016_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void st0016_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { int v, i, snum; unsigned char *slot; @@ -66,7 +66,7 @@ void st0016_device::sound_stream_update_legacy(sound_stream &stream, stream_samp int16_t sample; int sptr, eptr, freq, lsptr, leptr; - memset(mix, 0, sizeof(mix[0])*samples*2); + memset(mix, 0, sizeof(mix[0])*outputs[0].samples()*2); for (v = 0; v < 8; v++) { @@ -82,7 +82,7 @@ void st0016_device::sound_stream_update_legacy(sound_stream &stream, stream_samp lsptr = slot[0x06]<<16 | slot[0x05]<<8 | slot[0x04]; leptr = slot[0x0a]<<16 | slot[0x09]<<8 | slot[0x08]; - for (snum = 0; snum < samples; snum++) + for (snum = 0; snum < outputs[0].samples(); snum++) { sample = m_ram_read_cb((sptr + m_vpos[v]) & 0x1fffff) << 8; @@ -124,10 +124,10 @@ void st0016_device::sound_stream_update_legacy(sound_stream &stream, stream_samp } mixp = &mix[0]; - for (i = 0; i < samples; i++) + for (i = 0; i < outputs[0].samples(); i++) { - outputs[0][i] = (*mixp++)>>4; - outputs[1][i] = (*mixp++)>>4; + outputs[0].put_int(i, *mixp++, 32768<<4); + outputs[1].put_int(i, *mixp++, 32768<<4); } } diff --git a/src/devices/sound/st0016.h b/src/devices/sound/st0016.h index 21dd14e07c7..b18317da348 100644 --- a/src/devices/sound/st0016.h +++ b/src/devices/sound/st0016.h @@ -27,7 +27,7 @@ protected: virtual void device_start() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: sound_stream *m_stream; diff --git a/src/devices/sound/swp00.cpp b/src/devices/sound/swp00.cpp index d4d323af0a5..f94006a1868 100644 --- a/src/devices/sound/swp00.cpp +++ b/src/devices/sound/swp00.cpp @@ -21,7 +21,7 @@ void swp00_device::device_add_mconfig(machine_config &config) void swp00_device::device_start() { - m_stream = stream_alloc_legacy(0, 2, 44100); + m_stream = stream_alloc(0, 2, 44100); } void swp00_device::device_reset() @@ -97,6 +97,8 @@ void swp00_device::snd_w(offs_t offset, u8 data) // Synthesis -void swp00_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void swp00_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { + outputs[0].fill(0); + outputs[1].fill(0); } diff --git a/src/devices/sound/swp00.h b/src/devices/sound/swp00.h index 0bf2d8b43d3..ae732979606 100644 --- a/src/devices/sound/swp00.h +++ b/src/devices/sound/swp00.h @@ -21,7 +21,7 @@ public: protected: virtual void device_start() override; virtual void device_reset() override; - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; virtual void rom_bank_updated() override; virtual void device_add_mconfig(machine_config &config) override; diff --git a/src/devices/sound/swp20.cpp b/src/devices/sound/swp20.cpp index c1c92c8cb27..a9de3851fef 100644 --- a/src/devices/sound/swp20.cpp +++ b/src/devices/sound/swp20.cpp @@ -69,7 +69,8 @@ void swp20_device::snd_w(offs_t offset, u8 data) logerror("w %02x, %02x %s\n", offset, data, machine().describe_context()); } -void swp20_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void swp20_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { + outputs[0].fill(0); } diff --git a/src/devices/sound/swp20.h b/src/devices/sound/swp20.h index a65bae793a3..7323dd64f17 100644 --- a/src/devices/sound/swp20.h +++ b/src/devices/sound/swp20.h @@ -20,7 +20,7 @@ public: protected: virtual void device_start() override; virtual void device_reset() override; - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; virtual void rom_bank_updated() override; private: diff --git a/src/devices/sound/swp30.cpp b/src/devices/sound/swp30.cpp index 849af9f9946..aec573aa07a 100644 --- a/src/devices/sound/swp30.cpp +++ b/src/devices/sound/swp30.cpp @@ -163,7 +163,7 @@ void swp30_device::device_add_mconfig(machine_config &config) void swp30_device::device_start() { - m_stream = stream_alloc_legacy(0, 2, 44100); + m_stream = stream_alloc(0, 2, 44100); // Attenuantion for panning is 4.4 floating point. That means 0 // to -96.3dB. Since it's a nice range, we assume it's the same @@ -761,12 +761,12 @@ void swp30_device::snd_w(offs_t offset, u16 data) // Synthesis -void swp30_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void swp30_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { // Loop first on the samples and not on the channels otherwise // effects will be annoying to implement. - for(int sample = 0; sample < samples; sample++) { + for(int sample = 0; sample < outputs[0].samples(); sample++) { // Accumulate on 64 bits, shift/clamp at the end s64 acc_left = 0, acc_right = 0; @@ -871,17 +871,9 @@ void swp30_device::sound_stream_update_legacy(sound_stream &stream, stream_sampl // Global EQ is missing (it's done in the MEG) acc_left >>= (16+6); - if(acc_left < -0x8000) - acc_left = -0x8000; - else if(acc_left > 0x7fff) - acc_left = 0x7fff; - outputs[0][sample] = acc_left; + outputs[0].put_int_clamp(sample, acc_left, 32768); acc_right >>= (16+6); - if(acc_right < -0x8000) - acc_right = -0x8000; - else if(acc_right > 0x7fff) - acc_right = 0x7fff; - outputs[1][sample] = acc_right; + outputs[1].put_int_clamp(sample, acc_right, 32768); } } diff --git a/src/devices/sound/swp30.h b/src/devices/sound/swp30.h index fc8424b66d2..1eb68270626 100644 --- a/src/devices/sound/swp30.h +++ b/src/devices/sound/swp30.h @@ -21,7 +21,7 @@ public: protected: virtual void device_start() override; virtual void device_reset() override; - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; virtual void rom_bank_updated() override; virtual void device_add_mconfig(machine_config &config) override; diff --git a/src/devices/sound/t6721a.cpp b/src/devices/sound/t6721a.cpp index 7c0c07544e0..2c29e31dc62 100644 --- a/src/devices/sound/t6721a.cpp +++ b/src/devices/sound/t6721a.cpp @@ -56,17 +56,18 @@ void t6721a_device::device_start() m_write_apd.resolve_safe(); // create sound stream - m_stream = stream_alloc_legacy(0, 1, machine().sample_rate()); + m_stream = stream_alloc(0, 1, machine().sample_rate()); } //------------------------------------------------- -// sound_stream_update_legacy - handle update requests for +// sound_stream_update - handle update requests for // our sound stream //------------------------------------------------- -void t6721a_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void t6721a_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { + outputs[0].fill(0); } diff --git a/src/devices/sound/t6721a.h b/src/devices/sound/t6721a.h index 208cd7e8896..52a76393894 100644 --- a/src/devices/sound/t6721a.h +++ b/src/devices/sound/t6721a.h @@ -65,7 +65,7 @@ protected: virtual void device_start() override; // device_sound_interface overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: enum diff --git a/src/devices/sound/t6w28.cpp b/src/devices/sound/t6w28.cpp index 6c024c37757..9525794e489 100644 --- a/src/devices/sound/t6w28.cpp +++ b/src/devices/sound/t6w28.cpp @@ -101,14 +101,14 @@ void t6w28_device::write(offs_t offset, uint8_t data) //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void t6w28_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void t6w28_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { int i; - stream_sample_t *buffer0 = outputs[0]; - stream_sample_t *buffer1 = outputs[1]; + auto &buffer0 = outputs[0]; + auto &buffer1 = outputs[1]; /* If the volume is 0, increase the counter */ @@ -119,11 +119,11 @@ void t6w28_device::sound_stream_update_legacy(sound_stream &stream, stream_sampl /* note that I do count += samples, NOT count = samples + 1. You might think */ /* it's the same since the volume is 0, but doing the latter could cause */ /* interferencies when the program is rapidly modulating the volume. */ - if (m_count[i] <= samples*STEP) m_count[i] += samples*STEP; + if (m_count[i] <= buffer0.samples()*STEP) m_count[i] += buffer0.samples()*STEP; } } - while (samples > 0) + for (int sampindex = 0; sampindex < buffer0.samples(); sampindex++) { int vol[8]; unsigned int out0, out1; @@ -252,10 +252,8 @@ void t6w28_device::sound_stream_update_legacy(sound_stream &stream, stream_sampl if (out0 > MAX_OUTPUT * STEP) out0 = MAX_OUTPUT * STEP; if (out1 > MAX_OUTPUT * STEP) out1 = MAX_OUTPUT * STEP; - *(buffer0++) = out0 / STEP; - *(buffer1++) = out1 / STEP; - - samples--; + buffer0.put_int(sampindex, out0 / STEP, 32768); + buffer1.put_int(sampindex, out1 / STEP, 32768); } } @@ -296,7 +294,7 @@ void t6w28_device::device_start() int i; m_sample_rate = clock() / 16; - m_channel = stream_alloc_legacy(0, 2, m_sample_rate); + m_channel = stream_alloc(0, 2, m_sample_rate); for (i = 0;i < 8;i++) m_volume[i] = 0; diff --git a/src/devices/sound/t6w28.h b/src/devices/sound/t6w28.h index f1112f58839..6b953449f87 100644 --- a/src/devices/sound/t6w28.h +++ b/src/devices/sound/t6w28.h @@ -18,7 +18,7 @@ protected: virtual void device_start() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; void set_gain(int gain); diff --git a/src/devices/sound/tc8830f.cpp b/src/devices/sound/tc8830f.cpp index e387cc746f7..85635f2f466 100644 --- a/src/devices/sound/tc8830f.cpp +++ b/src/devices/sound/tc8830f.cpp @@ -46,7 +46,7 @@ tc8830f_device::tc8830f_device(const machine_config &mconfig, const char *tag, d void tc8830f_device::device_start() { // create the stream - m_stream = stream_alloc_legacy(0, 1, clock() / 0x10); + m_stream = stream_alloc(0, 1, clock() / 0x10); // register for savestates save_item(NAME(m_playing)); @@ -79,11 +79,11 @@ void tc8830f_device::device_clock_changed() -void tc8830f_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void tc8830f_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { int32_t mix = 0; - for (int i = 0; i < samples; i++) + for (int i = 0; i < outputs[0].samples(); i++) { if (m_playing) { @@ -125,7 +125,7 @@ void tc8830f_device::sound_stream_update_legacy(sound_stream &stream, stream_sam mix = m_output; } - outputs[0][i] = mix; + outputs[0].put_int(i, mix, 32768); } } diff --git a/src/devices/sound/tc8830f.h b/src/devices/sound/tc8830f.h index e0e715ccbef..0a447b02dba 100644 --- a/src/devices/sound/tc8830f.h +++ b/src/devices/sound/tc8830f.h @@ -32,7 +32,7 @@ protected: virtual void device_post_load() override; virtual void device_clock_changed() override; - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: sound_stream *m_stream; diff --git a/src/devices/sound/tiaintf.cpp b/src/devices/sound/tiaintf.cpp index 5c85db19b91..5a64db7bb4c 100644 --- a/src/devices/sound/tiaintf.cpp +++ b/src/devices/sound/tiaintf.cpp @@ -31,7 +31,7 @@ tia_device::tia_device(const machine_config &mconfig, const char *tag, device_t void tia_device::device_start() { - m_channel = stream_alloc_legacy(0, 1, clock()); + m_channel = stream_alloc(0, 1, clock()); m_chip = tia_sound_init(this, clock(), clock(), 16); if (!m_chip) throw emu_fatalerror("tia_device(%s): Error creating TIA chip", tag()); @@ -49,12 +49,12 @@ void tia_device::device_stop() //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void tia_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void tia_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - tia_process(m_chip, outputs[0], samples); + tia_process(m_chip, outputs[0]); } diff --git a/src/devices/sound/tiaintf.h b/src/devices/sound/tiaintf.h index c86be7173a9..8ef5d0341f7 100644 --- a/src/devices/sound/tiaintf.h +++ b/src/devices/sound/tiaintf.h @@ -24,7 +24,7 @@ protected: virtual void device_stop() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: sound_stream *m_channel; diff --git a/src/devices/sound/tiasound.cpp b/src/devices/sound/tiasound.cpp index 0e8275fb33f..87fa657bfab 100644 --- a/src/devices/sound/tiasound.cpp +++ b/src/devices/sound/tiasound.cpp @@ -90,16 +90,127 @@ namespace { -struct tia +class tia { - /* structures to hold the 6 tia sound control bytes */ - uint8_t AUDC[2]; /* AUDCx (15, 16) */ - uint8_t AUDF[2]; /* AUDFx (17, 18) */ - int16_t AUDV[2]; /* AUDVx (19, 1A) */ +public: + tia(device_t &device, int clock, int sample_rate, int gain) : + tia_gain(gain) // set the gain factor (normally use TIA_DEFAULT_GAIN) + { + // fill the polynomials + poly_init(Bit4, 4, 4, 3); + poly_init(Bit5, 5, 5, 3); + poly_init(Bit9, 9, 9, 5); + + // calculate the sample 'divide by N' value based on the playback freq. + Samp_n_max = ((uint16_t)(uint32_t)clock << 8) / sample_rate; + Samp_n_cnt = Samp_n_max; /* initialize all bits of the sample counter */ + + if (Samp_n_max < 256) // we need to use oversampling for sample_rate > clock_rate + { + Samp_n_max = ((uint16_t)(uint32_t)sample_rate << 8) / clock; + Samp_n_cnt = Samp_n_max; + oversampling = true; + } + + device.save_item(NAME(AUDC)); + device.save_item(NAME(AUDF)); + device.save_item(NAME(AUDV)); + device.save_item(NAME(Outvol)); + device.save_item(NAME(P4)); + device.save_item(NAME(P5)); + device.save_item(NAME(P9)); + device.save_item(NAME(Div_n_cnt)); + device.save_item(NAME(Div_n_max)); + device.save_item(NAME(Div_3_cnt)); + device.save_item(NAME(Samp_n_cnt)); + device.save_item(NAME(oversampling)); + } + + void write(offs_t offset, uint8_t data) + { + // determine which address was changed + uint8_t chan; + switch (offset) + { + case AUDC0: + AUDC[0] = data & 0x0f; + chan = 0; + break; + + case AUDC1: + AUDC[1] = data & 0x0f; + chan = 1; + break; + + case AUDF0: + AUDF[0] = data & 0x1f; + chan = 0; + break; + + case AUDF1: + AUDF[1] = data & 0x1f; + chan = 1; + break; + + case AUDV0: + AUDV[0] = ((data & 0x0f) << AUDV_SHIFT); + chan = 0; + break; + + case AUDV1: + AUDV[1] = ((data & 0x0f) << AUDV_SHIFT); + chan = 1; + break; + + default: + return; + } + + // an AUDC value of 0 is a special case + uint16_t new_val; + if (AUDC[chan] == SET_TO_1 || AUDC[chan] == POLY5_POLY5) + { + // indicate the clock is zero so no processing will occur + new_val = 0; + + // and set the output to the selected volume + Outvol[chan] = AUDV[chan]; + } + else + { + // otherwise calculate the 'divide by N' value + new_val = AUDF[chan] + 1; + + // if bits 2 & 3 are set, then multiply the 'div by n' count by 3 + if ((AUDC[chan] & DIV3_MASK) == DIV3_MASK && AUDC[chan] != POLY5_DIV3) + { + new_val *= 3; + } + } - int16_t Outvol[2]; /* last output volume for each channel */ + // only reset those channels that have changed + if (new_val != Div_n_max[chan]) + { + // reset the divide by n counters + Div_n_max[chan] = new_val; - int tia_gain; /* initialized in tia_sound_init() */ + // if the channel is now volume only or was volume only + if ((Div_n_cnt[chan] == 0) || (new_val == 0)) + { + // reset the counter (otherwise let it complete the previous) + Div_n_cnt[chan] = new_val; + } + } + } + + // structures to hold the 6 tia sound control bytes + uint8_t AUDC[2] = { 0, 0 }; // AUDCx (15, 16) + uint8_t AUDF[2] = { 0, 0 }; // AUDFx (17, 18) + int16_t AUDV[2] = { 0, 0 }; // AUDVx (19, 1A) + + int16_t Outvol[2] = { 0, 0 }; // last output volume for each channel + + int tia_gain; // initialized in tia_sound_init() /* Initialze the bit patterns for the polynomials. */ @@ -115,23 +226,41 @@ struct tia uint8_t Bit9[POLY9_SIZE]; - uint8_t P4[2]; /* Position pointer for the 4-bit POLY array */ - uint8_t P5[2]; /* Position pointer for the 5-bit POLY array */ - uint16_t P9[2]; /* Position pointer for the 9-bit POLY array */ + uint8_t P4[2] = { 0, 0 }; // Position pointer for the 4-bit POLY array + uint8_t P5[2] = { 0, 0 }; // Position pointer for the 5-bit POLY array + uint16_t P9[2] = { 0, 0 }; // Position pointer for the 9-bit POLY array - uint8_t Div_n_cnt[2]; /* Divide by n counter. one for each channel */ - uint8_t Div_n_max[2]; /* Divide by n maximum, one for each channel */ - uint8_t Div_3_cnt[2]; /* Div 3 counter, used for POLY5_DIV3 mode */ + uint8_t Div_n_cnt[2] = { 0, 0 }; // Divide by n counter. one for each channel + uint8_t Div_n_max[2] = { 0, 0 }; // Divide by n maximum, one for each channel + uint8_t Div_3_cnt[2] = { 3, 3 }; // Div 3 counter, used for POLY5_DIV3 mode /* In my routines, I treat the sample output as another divide by N counter. */ /* For better accuracy, the Samp_n_cnt has a fixed binary decimal point */ /* which has 8 binary digits to the right of the decimal point. */ - uint16_t Samp_n_max; /* Sample max, multiplied by 256 */ - uint16_t Samp_n_cnt; /* Sample cnt. */ + uint16_t Samp_n_max; // Sample max, multiplied by 256 + uint16_t Samp_n_cnt; // Sample cnt. + + bool oversampling = false; // Added oversampling for sample_rate > clock_rate + +private: + template <unsigned N> + static void poly_init(uint8_t (&poly)[N], int size, int f0, int f1) + { + const int mask = (1 << size) - 1; + int x = mask; + + for (int i = 0; i < mask; i++) + { + const int bit0 = ((size - f0) ? (x >> (size - f0)) : x) & 0x01; + const int bit1 = ((size - f1) ? (x >> (size - f1)) : x) & 0x01; + poly[i] = x & 1; + /* calculate next bit */ + x = (x >> 1) | ((bit0 ^ bit1) << ( size - 1) ); + } + } - int oversampling; /* Added oversampling for sample_rate > clock_rate */ }; @@ -163,88 +292,9 @@ constexpr uint8_t Div31[POLY5_SIZE] = /* */ /*****************************************************************************/ -void tia_write(void *_chip, offs_t offset, uint8_t data) +void tia_write(void *chip, offs_t offset, uint8_t data) { - struct tia *chip = (struct tia *)_chip; - uint16_t new_val; - uint8_t chan; - - /* determine which address was changed */ - switch (offset) - { - case AUDC0: - chip->AUDC[0] = data & 0x0f; - chan = 0; - break; - - case AUDC1: - chip->AUDC[1] = data & 0x0f; - chan = 1; - break; - - case AUDF0: - chip->AUDF[0] = data & 0x1f; - chan = 0; - break; - - case AUDF1: - chip->AUDF[1] = data & 0x1f; - chan = 1; - break; - - case AUDV0: - chip->AUDV[0] = ((data & 0x0f) << AUDV_SHIFT); - chan = 0; - break; - - case AUDV1: - chip->AUDV[1] = ((data & 0x0f) << AUDV_SHIFT); - chan = 1; - break; - - default: - chan = 255; - break; - } - - /* if the output value changed */ - if (chan != 255) - { - /* an AUDC value of 0 is a special case */ - if (chip->AUDC[chan] == SET_TO_1 || chip->AUDC[chan] == POLY5_POLY5) - { - /* indicate the clock is zero so no processing will occur */ - new_val = 0; - - /* and set the output to the selected volume */ - chip->Outvol[chan] = chip->AUDV[chan]; - } - else - { - /* otherwise calculate the 'divide by N' value */ - new_val = chip->AUDF[chan] + 1; - - /* if bits 2 & 3 are set, then multiply the 'div by n' count by 3 */ - if ((chip->AUDC[chan] & DIV3_MASK) == DIV3_MASK && chip->AUDC[chan] != POLY5_DIV3) - { - new_val *= 3; - } - } - - /* only reset those channels that have changed */ - if (new_val != chip->Div_n_max[chan]) - { - /* reset the divide by n counters */ - chip->Div_n_max[chan] = new_val; - - /* if the channel is now volume only or was volume only */ - if ((chip->Div_n_cnt[chan] == 0) || (new_val == 0)) - { - /* reset the counter (otherwise let it complete the previous) */ - chip->Div_n_cnt[chan] = new_val; - } - } - } + reinterpret_cast<tia *>(chip)->write(offset, data); } @@ -264,9 +314,9 @@ void tia_write(void *_chip, offs_t offset, uint8_t data) /* */ /*****************************************************************************/ -void tia_process(void *_chip, stream_sample_t *buffer, int length) +void tia_process(void *_chip, write_stream_view &buffer) { - struct tia *chip = (struct tia *)_chip; + tia *chip = (tia *)_chip; uint8_t audc0, audc1; uint8_t div_n_cnt0, div_n_cnt1; uint8_t p5_0, p5_1; @@ -286,7 +336,7 @@ void tia_process(void *_chip, stream_sample_t *buffer, int length) div_n_cnt1 = chip->Div_n_cnt[1]; /* loop until the buffer is filled */ - while (length > 0) + for (int sampindex = 0; sampindex < buffer.samples(); ) { /* Process channel 0 */ if (div_n_cnt0 > 1) @@ -482,10 +532,7 @@ void tia_process(void *_chip, stream_sample_t *buffer, int length) chip->Samp_n_cnt += chip->Samp_n_max; /* calculate the latest output value and place in buffer */ - *buffer++ = outvol_0 + outvol_1; - - /* and indicate one less byte to process */ - length--; + buffer.put_int(sampindex++, outvol_0 + outvol_1, 32768); } } else @@ -496,10 +543,9 @@ void tia_process(void *_chip, stream_sample_t *buffer, int length) * byte contains the fractional part */ chip->Samp_n_cnt -= 256; /* calculate the latest output value and place in buffer */ - *buffer++ = outvol_0 + outvol_1; - length--; + buffer.put_int(sampindex++, outvol_0 + outvol_1, 32768); } - while ((chip->Samp_n_cnt >= 256) && (length > 0)); + while ((chip->Samp_n_cnt >= 256) && (sampindex < buffer.samples())); /* adjust the sample counter if necessary */ if (chip->Samp_n_cnt < 256) @@ -517,37 +563,6 @@ void tia_process(void *_chip, stream_sample_t *buffer, int length) } -static void poly_init(uint8_t *poly, int size, int f0, int f1) -{ - int mask = (1 << size) - 1; - int i, x = mask; - - for (i = 0; i < mask; i++) - { - int bit0 = ( ( size - f0 ) ? ( x >> ( size - f0 ) ) : x ) & 0x01; - int bit1 = ( ( size - f1 ) ? ( x >> ( size - f1 ) ) : x ) & 0x01; - poly[i] = x & 1; - /* calculate next bit */ - x = ( x >> 1 ) | ( ( bit0 ^ bit1 ) << ( size - 1) ); - } -} - -static void tia_save_state(device_t *device, tia *tia) -{ - device->save_item(NAME(tia->AUDC)); - device->save_item(NAME(tia->AUDF)); - device->save_item(NAME(tia->AUDV)); - device->save_item(NAME(tia->Outvol)); - device->save_item(NAME(tia->P4)); - device->save_item(NAME(tia->P5)); - device->save_item(NAME(tia->P9)); - device->save_item(NAME(tia->Div_n_cnt)); - device->save_item(NAME(tia->Div_n_max)); - device->save_item(NAME(tia->Div_3_cnt)); - device->save_item(NAME(tia->Samp_n_cnt)); - device->save_item(NAME(tia->oversampling)); -} - /*****************************************************************************/ /* Module: tia_sh_start() */ /* Purpose: to handle the power-up initialization functions */ @@ -565,52 +580,11 @@ static void tia_save_state(device_t *device, tia *tia) void *tia_sound_init(device_t *device, int clock, int sample_rate, int gain) { - struct tia *chip; - int chan; - - chip = global_alloc_clear<struct tia>(); - - /* set the gain factor (normally use TIA_DEFAULT_GAIN) */ - chip->tia_gain = gain; - - /* fill the polynomials */ - poly_init(chip->Bit4, 4, 4, 3); - poly_init(chip->Bit5, 5, 5, 3); - poly_init(chip->Bit9, 9, 9, 5); - - /* calculate the sample 'divide by N' value based on the playback freq. */ - chip->Samp_n_max = ((uint16_t)(uint32_t)clock << 8) / sample_rate; - chip->Samp_n_cnt = chip->Samp_n_max; /* initialize all bits of the sample counter */ - - if (chip->Samp_n_max < 256) /* we need to use oversampling for sample_rate > clock_rate */ - { - chip->Samp_n_max = ((uint16_t)(uint32_t)sample_rate << 8) / clock; - chip->Samp_n_cnt = chip->Samp_n_max; - chip->oversampling = 1; - } - - /* initialize the local globals */ - for (chan = CHAN1; chan <= CHAN2; chan++) - { - chip->Outvol[chan] = 0; - chip->Div_n_cnt[chan] = 0; - chip->Div_n_max[chan] = 0; - chip->Div_3_cnt[chan] = 3; - chip->AUDC[chan] = 0; - chip->AUDF[chan] = 0; - chip->AUDV[chan] = 0; - chip->P4[chan] = 0; - chip->P5[chan] = 0; - chip->P9[chan] = 0; - } - - tia_save_state(device, chip); - - return chip; + return new tia(*device, clock, sample_rate, gain); } void tia_sound_free(void *chip) { - global_free((struct tia *)chip); + delete(reinterpret_cast<tia *>(chip)); } diff --git a/src/devices/sound/tiasound.h b/src/devices/sound/tiasound.h index b406bf14598..2edafdda912 100644 --- a/src/devices/sound/tiasound.h +++ b/src/devices/sound/tiasound.h @@ -41,7 +41,7 @@ void *tia_sound_init(device_t *device, int clock, int sample_rate, int gain); void tia_sound_free(void *chip); -void tia_process(void *chip, stream_sample_t *buffer, int length); +void tia_process(void *chip, write_stream_view &buffer); void tia_write(void *chip, offs_t offset, uint8_t data); #endif // MAME_SOUND_TIASOUND_H diff --git a/src/devices/sound/tms3615.cpp b/src/devices/sound/tms3615.cpp index e59c64eab04..3f595c8a97b 100644 --- a/src/devices/sound/tms3615.cpp +++ b/src/devices/sound/tms3615.cpp @@ -46,7 +46,7 @@ void tms3615_device::device_start() //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- void tms3615_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) diff --git a/src/devices/sound/tms36xx.cpp b/src/devices/sound/tms36xx.cpp index 73ec59b4121..08df1d03f51 100644 --- a/src/devices/sound/tms36xx.cpp +++ b/src/devices/sound/tms36xx.cpp @@ -355,7 +355,7 @@ void tms36xx_device::device_start() { int enable = 0; - m_channel = stream_alloc_legacy(0, 1, clock() * 64); + m_channel = stream_alloc(0, 1, clock() * 64); m_samplerate = clock() * 64; m_basefreq = clock(); @@ -394,23 +394,22 @@ void tms36xx_device::device_start() //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void tms36xx_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void tms36xx_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { int samplerate = m_samplerate; - stream_sample_t *buffer = outputs[0]; + auto &buffer = outputs[0]; /* no tune played? */ if( !tunes[m_tune_num] || m_voices == 0 ) { - while (--samples >= 0) - buffer[samples] = 0; + buffer.fill(0); return; } - while( samples-- > 0 ) + for (int sampindex = 0; sampindex < buffer.samples(); sampindex++) { int sum = 0; @@ -444,7 +443,7 @@ void tms36xx_device::sound_stream_update_legacy(sound_stream &stream, stream_sam TONE( 0) TONE( 1) TONE( 2) TONE( 3) TONE( 4) TONE( 5) TONE( 6) TONE( 7) TONE( 8) TONE( 9) TONE(10) TONE(11) - *buffer++ = sum / m_voices; + buffer.put_int(sampindex, sum, 32768 * m_voices); } } diff --git a/src/devices/sound/tms36xx.h b/src/devices/sound/tms36xx.h index 03dd5dc2412..5693e3b8e7c 100644 --- a/src/devices/sound/tms36xx.h +++ b/src/devices/sound/tms36xx.h @@ -63,7 +63,7 @@ protected: virtual void device_start() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; public: // MM6221AA interface functions diff --git a/src/devices/sound/tms5110.cpp b/src/devices/sound/tms5110.cpp index 73f5244738e..5782aa905af 100644 --- a/src/devices/sound/tms5110.cpp +++ b/src/devices/sound/tms5110.cpp @@ -1048,7 +1048,7 @@ void tms5110_device::device_start() m_data_cb.resolve(); /* initialize a stream */ - m_stream = stream_alloc_legacy(0, 1, clock() / 80); + m_stream = stream_alloc(0, 1, clock() / 80); m_state = CTL_STATE_INPUT; /* most probably not defined */ m_romclk_hack_timer = timer_alloc(0); @@ -1220,27 +1220,25 @@ int tms5110_device::romclk_hack_r() ******************************************************************************/ //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void tms5110_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void tms5110_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { int16_t sample_data[MAX_SAMPLE_CHUNK]; - stream_sample_t *buffer = outputs[0]; + auto &buffer = outputs[0]; /* loop while we still have samples to generate */ - while (samples) + for (int sampindex = 0; sampindex < buffer.samples(); ) { - int length = (samples > MAX_SAMPLE_CHUNK) ? MAX_SAMPLE_CHUNK : samples; - int index; + int length = buffer.samples() - sampindex; + if (length > MAX_SAMPLE_CHUNK) + length = MAX_SAMPLE_CHUNK; /* generate the samples and copy to the target buffer */ process(sample_data, length); - for (index = 0; index < length; index++) - *buffer++ = sample_data[index]; - - /* account for the samples */ - samples -= length; + for (int index = 0; index < length; index++) + buffer.put_int(sampindex++, sample_data[index], 32768); } } diff --git a/src/devices/sound/tms5110.h b/src/devices/sound/tms5110.h index 84c7f68fc73..e3bb2078075 100644 --- a/src/devices/sound/tms5110.h +++ b/src/devices/sound/tms5110.h @@ -60,7 +60,7 @@ protected: virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; uint8_t TALK_STATUS() const { return m_SPEN | m_TALKD; } diff --git a/src/devices/sound/tms5220.cpp b/src/devices/sound/tms5220.cpp index 9c4974c34e2..d0afb710f46 100644 --- a/src/devices/sound/tms5220.cpp +++ b/src/devices/sound/tms5220.cpp @@ -2061,7 +2061,6 @@ void tms5220_device::sound_stream_update(sound_stream &stream, std::vector<read_ auto &output = outputs[0]; /* loop while we still have samples to generate */ - constexpr stream_buffer::sample_t sample_scale = 1.0 / 32768.0; for (int sampindex = 0; sampindex < output.samples(); ) { int length = (output.samples() > MAX_SAMPLE_CHUNK) ? MAX_SAMPLE_CHUNK : output.samples(); @@ -2069,7 +2068,7 @@ void tms5220_device::sound_stream_update(sound_stream &stream, std::vector<read_ /* generate the samples and copy to the target buffer */ process(sample_data, length); for (int index = 0; index < length; index++) - output.put(sampindex++, sample_data[index] * sample_scale); + output.put_int(sampindex++, sample_data[index], 32768); } } diff --git a/src/devices/sound/upd1771.cpp b/src/devices/sound/upd1771.cpp index bb8e61f2d00..2ec1d767ba0 100644 --- a/src/devices/sound/upd1771.cpp +++ b/src/devices/sound/upd1771.cpp @@ -255,7 +255,7 @@ void upd1771c_device::device_start() m_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(upd1771c_device::ack_callback),this)); - m_channel = stream_alloc_legacy(0, 1, clock() / 4); + m_channel = stream_alloc(0, 1, clock() / 4); save_item(NAME(m_packet)); save_item(NAME(m_index)); @@ -476,12 +476,12 @@ TIMER_CALLBACK_MEMBER( upd1771c_device::ack_callback ) //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void upd1771c_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void upd1771c_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - stream_sample_t *buffer = outputs[0]; + auto &buffer = outputs[0]; switch (m_state) { @@ -489,9 +489,9 @@ void upd1771c_device::sound_stream_update_legacy(sound_stream &stream, stream_sa //logerror( "upd1771_STATE_TONE samps:%d %d %d %d %d %d\n",(int)samples, // (int)m_t_timbre,(int)m_t_offset,(int)m_t_volume,(int)m_t_period,(int)m_t_tpos); - while (--samples >= 0) + for (int sampindex = 0; sampindex < buffer.samples(); sampindex++) { - *buffer++ = (WAVEFORMS[m_t_timbre][m_t_tpos]) * m_t_volume * 2; + buffer.put_int(sampindex, (WAVEFORMS[m_t_timbre][m_t_tpos]) * m_t_volume, 32768 / 2); m_t_ppos++; if (m_t_ppos >= m_t_period) @@ -506,10 +506,8 @@ void upd1771c_device::sound_stream_update_legacy(sound_stream &stream, stream_sa break; case STATE_NOISE: - while (--samples >= 0) + for (int sampindex = 0; sampindex < buffer.samples(); sampindex++) { - *buffer = 0; - //"wavetable-LFSR" component int wlfsr_val = ((int)noise_tbl[m_nw_tpos]) - 127;//data too wide @@ -535,23 +533,18 @@ void upd1771c_device::sound_stream_update_legacy(sound_stream &stream, stream_sa } } //not quite, but close. - *buffer+= ( + buffer.put_int(sampindex, (wlfsr_val * m_nw_volume) | (res[0] * m_n_volume[0]) | (res[1] * m_n_volume[1]) | - (res[2] * m_n_volume[2]) - ) ; - - buffer++; + (res[2] * m_n_volume[2]), + 32768) ; } break; default: //fill buffer with silence - while (--samples >= 0) - { - *buffer++ = 0; - } + buffer.fill(0); break; } } diff --git a/src/devices/sound/upd1771.h b/src/devices/sound/upd1771.h index 9fe86b58c1d..7c5cc5f7f95 100644 --- a/src/devices/sound/upd1771.h +++ b/src/devices/sound/upd1771.h @@ -32,7 +32,7 @@ protected: virtual void device_reset() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: static constexpr unsigned MAX_PACKET_SIZE = 0x8000; diff --git a/src/devices/sound/upd7752.cpp b/src/devices/sound/upd7752.cpp index 19977dcafdc..7c063fbee95 100644 --- a/src/devices/sound/upd7752.cpp +++ b/src/devices/sound/upd7752.cpp @@ -72,7 +72,7 @@ device_memory_interface::space_config_vector upd7752_device::memory_space_config void upd7752_device::device_start() { /* TODO: clock */ - m_stream = stream_alloc_legacy(0, 1, clock() / 64); + m_stream = stream_alloc(0, 1, clock() / 64); m_status = 0; } @@ -96,11 +96,12 @@ void upd7752_device::device_stop() } //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void upd7752_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void upd7752_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { + outputs[0].fill(0); } //************************************************************************** diff --git a/src/devices/sound/upd7752.h b/src/devices/sound/upd7752.h index b65048624f1..9693ee99f4d 100644 --- a/src/devices/sound/upd7752.h +++ b/src/devices/sound/upd7752.h @@ -30,7 +30,7 @@ protected: virtual void device_stop() override; virtual void device_reset() override; - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; virtual space_config_vector memory_space_config() const override; private: diff --git a/src/devices/sound/upd934g.cpp b/src/devices/sound/upd934g.cpp index fecb6fc8a18..fc25628abbd 100644 --- a/src/devices/sound/upd934g.cpp +++ b/src/devices/sound/upd934g.cpp @@ -49,7 +49,7 @@ upd934g_device::upd934g_device(const machine_config &mconfig, const char *tag, d void upd934g_device::device_start() { // create sound stream - m_stream = stream_alloc_legacy(0, 4, 20000); + m_stream = stream_alloc(0, 4, 20000); // resolve callbacks m_data_cb.resolve_safe(0); @@ -81,32 +81,33 @@ void upd934g_device::device_reset() } //------------------------------------------------- -// sound_stream_update_legacy - handle update requests for +// sound_stream_update - handle update requests for // our sound stream //------------------------------------------------- -void upd934g_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void upd934g_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { for (unsigned ch = 0; ch < 4; ch++) { - std::fill(&outputs[ch][0], &outputs[ch][samples], 0); - if (m_ready && m_channel[ch].playing != -1) { uint16_t end = m_addr[m_channel[ch].playing + 1] - 1; - for (unsigned i = 0; i < samples; i++) + for (unsigned i = 0; i < outputs[ch].samples(); i++) { int8_t raw = static_cast<int8_t>(m_data_cb(m_channel[ch].pos)); - outputs[ch][i] = raw * (m_channel[ch].volume + 1) * 64; + outputs[ch].put_int(i, raw * (m_channel[ch].volume + 1), 32768 / 64); if (++m_channel[ch].pos >= end) { m_channel[ch].playing = -1; + outputs[ch].fill(0, i + 1); break; } } } + else + outputs[ch].fill(0); } } diff --git a/src/devices/sound/upd934g.h b/src/devices/sound/upd934g.h index ed145671c38..c61ac5a4910 100644 --- a/src/devices/sound/upd934g.h +++ b/src/devices/sound/upd934g.h @@ -36,7 +36,7 @@ protected: virtual void device_start() override; virtual void device_reset() override; - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: devcb_read8 m_data_cb; diff --git a/src/devices/sound/vgm_visualizer.cpp b/src/devices/sound/vgm_visualizer.cpp index c1f438f2b2c..bab3c909ddf 100644 --- a/src/devices/sound/vgm_visualizer.cpp +++ b/src/devices/sound/vgm_visualizer.cpp @@ -158,7 +158,7 @@ void vgmviz_device::apply_fft() void vgmviz_device::apply_waterfall() { - int total_bars = FFT_LENGTH / 2; + const int total_bars = FFT_LENGTH / 2; WDL_FFT_COMPLEX* bins[2] = { (WDL_FFT_COMPLEX*)m_fft_buf[0], (WDL_FFT_COMPLEX*)m_fft_buf[1] }; for (int bar = 0; bar < std::min<int>(total_bars, SCREEN_HEIGHT); bar++) { @@ -555,7 +555,7 @@ template <int BarSize, int SpecMode> void vgmviz_device::draw_spectrogram(bitmap m_clear_pending = false; } - const pen_t *pal = m_palette->pens(); + pen_t const *const pal = m_palette->pens(); int width = SCREEN_WIDTH; switch (SpecMode) @@ -563,31 +563,26 @@ template <int BarSize, int SpecMode> void vgmviz_device::draw_spectrogram(bitmap case SPEC_VIZ_PILLAR: for (int y = 2; y < SCREEN_HEIGHT; y++) { - uint32_t *src = &m_bitmap.pix32(y); - uint32_t *dst = &bitmap.pix32(y - 2); + uint32_t const *const src = &m_bitmap.pix(y); + uint32_t *const dst = &bitmap.pix(y - 2); for (int x = SCREEN_WIDTH - 1; x >= 1; x--) { dst[x] = src[x - 1]; } } - width = (int)(SCREEN_WIDTH * 0.75f); + width = int(SCREEN_WIDTH * 0.75f); break; case SPEC_VIZ_TOP: for (int y = 1; y < SCREEN_HEIGHT; y++) { - uint32_t *src = &m_bitmap.pix32(y); - uint32_t *dst = &bitmap.pix32(y - 1); - for (int x = 0; x < SCREEN_WIDTH; x++) - { - dst[x] = src[x]; - } + std::copy_n(&m_bitmap.pix(y), SCREEN_WIDTH, &bitmap.pix(y - 1)); } break; default: break; } - int total_bars = FFT_LENGTH / 2; + const int total_bars = FFT_LENGTH / 2; WDL_FFT_COMPLEX *bins[2] = { (WDL_FFT_COMPLEX *)m_fft_buf[0], (WDL_FFT_COMPLEX *)m_fft_buf[1] }; for (int bar = 2; bar < total_bars && bar < width; bar += BarSize) @@ -614,8 +609,8 @@ template <int BarSize, int SpecMode> void vgmviz_device::draw_spectrogram(bitmap } for (int y = 0; y < SCREEN_HEIGHT; y++) { - int bar_y = SCREEN_HEIGHT - y; - uint32_t *line = &bitmap.pix32(y); + const int bar_y = SCREEN_HEIGHT - y; + uint32_t *const line = &bitmap.pix(y); for (int x = 0; x < BarSize; x++) { line[(bar - 2) + x] = bar_y <= level ? pal[256 + pal_index] : pal[black_index]; @@ -631,8 +626,8 @@ template <int BarSize, int SpecMode> void vgmviz_device::draw_spectrogram(bitmap for (int y = 0; y < SCREEN_HEIGHT; y++) { - int bar_y = SCREEN_HEIGHT - y; - uint32_t *line = &bitmap.pix32(y); + const int bar_y = SCREEN_HEIGHT - y; + uint32_t *const line = &bitmap.pix(y); line[0] = 0; if (bar_y > level) { @@ -643,9 +638,9 @@ template <int BarSize, int SpecMode> void vgmviz_device::draw_spectrogram(bitmap { if (bar_y < (level - 1)) { - const uint8_t r = (uint8_t)(((entry >> 16) & 0xff) * 0.75f); - const uint8_t g = (uint8_t)(((entry >> 8) & 0xff) * 0.75f); - const uint8_t b = (uint8_t)(((entry >> 0) & 0xff) * 0.75f); + const uint8_t r = uint8_t(((entry >> 16) & 0xff) * 0.75f); + const uint8_t g = uint8_t(((entry >> 8) & 0xff) * 0.75f); + const uint8_t b = uint8_t(((entry >> 0) & 0xff) * 0.75f); line[(bar - 2) + x] = 0xff000000 | (r << 16) | (g << 8) | b; } else @@ -653,9 +648,9 @@ template <int BarSize, int SpecMode> void vgmviz_device::draw_spectrogram(bitmap line[(bar - 2) + x] = pal[256 + pal_index]; } } - const uint8_t r = (uint8_t)(((entry >> 16) & 0xff) * 0.5f); - const uint8_t g = (uint8_t)(((entry >> 8) & 0xff) * 0.5f); - const uint8_t b = (uint8_t)(((entry >> 0) & 0xff) * 0.5f); + const uint8_t r = uint8_t(((entry >> 16) & 0xff) * 0.5f); + const uint8_t g = uint8_t(((entry >> 8) & 0xff) * 0.5f); + const uint8_t b = uint8_t(((entry >> 0) & 0xff) * 0.5f); line[(bar - 2) + (BarSize - 1)] = 0xff000000 | (r << 16) | (g << 8) | b; if (bar_y < level) { @@ -664,10 +659,11 @@ template <int BarSize, int SpecMode> void vgmviz_device::draw_spectrogram(bitmap } for (int x = 0; x < SCREEN_WIDTH; x++) { - bitmap.pix32(SCREEN_HEIGHT - 1, x) = 0; - bitmap.pix32(SCREEN_HEIGHT - 2, x) = 0; + bitmap.pix(SCREEN_HEIGHT - 1, x) = 0; + bitmap.pix(SCREEN_HEIGHT - 2, x) = 0; } - memcpy(&m_bitmap.pix32(0), &bitmap.pix32(0), sizeof(uint32_t) * SCREEN_WIDTH * SCREEN_HEIGHT); + for (int y = 0; y < SCREEN_HEIGHT; y++) + std::copy_n(&bitmap.pix(y), SCREEN_WIDTH, &m_bitmap.pix(y)); break; case SPEC_VIZ_TOP: level = int(raw_level * 63.0f); @@ -678,10 +674,11 @@ template <int BarSize, int SpecMode> void vgmviz_device::draw_spectrogram(bitmap for (int x = 0; x < BarSize; x++) { - bitmap.pix32(SCREEN_HEIGHT - 1, (bar - 2) + x) = level > 0 ? pal[256 + pal_index] : pal[black_index]; + bitmap.pix(SCREEN_HEIGHT - 1, (bar - 2) + x) = level > 0 ? pal[256 + pal_index] : pal[black_index]; } - memcpy(&m_bitmap.pix32(0), &bitmap.pix32(0), sizeof(uint32_t) * SCREEN_WIDTH * SCREEN_HEIGHT); + for (int y = 0; y < SCREEN_HEIGHT; y++) + std::copy_n(&bitmap.pix(y), SCREEN_WIDTH, &m_bitmap.pix(y)); break; } } @@ -700,7 +697,7 @@ void vgmviz_device::draw_waterfall(bitmap_rgb32 &bitmap) const int v0_index = (int)v0h; const int v1_index = (int)v1h; const float interp = v0h - (float)v0_index; - uint32_t* line = &bitmap.pix32(y); + uint32_t* line = &bitmap.pix(y); for (int x = 0; x < SCREEN_WIDTH; x++) { if (m_waterfall_length < SCREEN_WIDTH) @@ -736,8 +733,8 @@ void vgmviz_device::draw_waveform(bitmap_rgb32 &bitmap) for (int x = 0; x < SCREEN_WIDTH; x++) { - bitmap.pix32(CHANNEL_CENTER, x) = MED_GRAY; - bitmap.pix32(CHANNEL_HEIGHT + 1 + CHANNEL_CENTER, x) = MED_GRAY; + bitmap.pix(CHANNEL_CENTER, x) = MED_GRAY; + bitmap.pix(CHANNEL_HEIGHT + 1 + CHANNEL_CENTER, x) = MED_GRAY; const float raw_l = m_audio_buf[1 - m_audio_fill_index][0][((int)m_history_length + 1 + x) % FFT_LENGTH]; const int sample_l = (int)((raw_l - 0.5f) * (CHANNEL_HEIGHT - 1)); @@ -746,7 +743,7 @@ void vgmviz_device::draw_waveform(bitmap_rgb32 &bitmap) int y = endy_l - sample_l; do { - bitmap.pix32(y, x) = LEFT_COLOR; + bitmap.pix(y, x) = LEFT_COLOR; y += dy_l; } while(y != endy_l); @@ -757,11 +754,11 @@ void vgmviz_device::draw_waveform(bitmap_rgb32 &bitmap) y = endy_r - sample_r; do { - bitmap.pix32(y, x) = RIGHT_COLOR; + bitmap.pix(y, x) = RIGHT_COLOR; y += dy_r; } while(y != endy_r); - bitmap.pix32(CHANNEL_HEIGHT, x) = WHITE; - bitmap.pix32(CHANNEL_HEIGHT + 1, x) = WHITE; + bitmap.pix(CHANNEL_HEIGHT, x) = WHITE; + bitmap.pix(CHANNEL_HEIGHT + 1, x) = WHITE; } } diff --git a/src/devices/sound/vlm5030.cpp b/src/devices/sound/vlm5030.cpp index 3d3cc7863fd..71dd026000c 100644 --- a/src/devices/sound/vlm5030.cpp +++ b/src/devices/sound/vlm5030.cpp @@ -214,7 +214,7 @@ void vlm5030_device::device_start() device_reset(); m_phase = PH_IDLE; - m_channel = stream_alloc_legacy(0, 1, clock() / 440); + m_channel = stream_alloc(0, 1, clock() / 440); save_item(NAME(m_address)); save_item(NAME(m_pin_BSY)); @@ -491,22 +491,22 @@ if( m_interp_step != 1) //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void vlm5030_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void vlm5030_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - int buf_count=0; int interp_effect; int i; int u[11]; - stream_sample_t *buffer = outputs[0]; + auto &buffer = outputs[0]; /* running */ + int sampindex = 0; if( m_phase == PH_RUN || m_phase == PH_STOP ) { /* playing speech */ - while (samples > 0) + for ( ; sampindex < buffer.samples(); sampindex++) { int current_val; @@ -592,13 +592,7 @@ void vlm5030_device::sound_stream_update_legacy(sound_stream &stream, stream_sam m_x[0] = u[0]; /* clipping, buffering */ - if (u[0] > 511) - buffer[buf_count] = 511<<6; - else if (u[0] < -511) - buffer[buf_count] = uint32_t(-511)<<6; - else - buffer[buf_count] = (u[0] << 6); - buf_count++; + buffer.put_int_clamp(sampindex, u[0], 512); /* sample count */ m_sample_count--; @@ -607,7 +601,6 @@ void vlm5030_device::sound_stream_update_legacy(sound_stream &stream, stream_sam if (m_pitch_count >= m_current_pitch ) m_pitch_count = 0; /* size */ - samples--; } /* return;*/ } @@ -616,7 +609,7 @@ phase_stop: switch( m_phase ) { case PH_SETUP: - if( m_sample_count <= samples) + if( m_sample_count <= buffer.samples()) { m_sample_count = 0; /* logerror("VLM5030 BSY=H\n" ); */ @@ -625,11 +618,11 @@ phase_stop: } else { - m_sample_count -= samples; + m_sample_count -= buffer.samples(); } break; case PH_END: - if( m_sample_count <= samples) + if( m_sample_count <= buffer.samples()) { m_sample_count = 0; /* logerror("VLM5030 BSY=L\n" ); */ @@ -638,13 +631,9 @@ phase_stop: } else { - m_sample_count -= samples; + m_sample_count -= buffer.samples(); } } /* silent buffering */ - while (samples > 0) - { - buffer[buf_count++] = 0x00; - samples--; - } + buffer.fill(0, sampindex); } diff --git a/src/devices/sound/vlm5030.h b/src/devices/sound/vlm5030.h index 7520bf76007..4675d99fce4 100644 --- a/src/devices/sound/vlm5030.h +++ b/src/devices/sound/vlm5030.h @@ -34,7 +34,7 @@ protected: virtual void device_post_load() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; // device_rom_interface overrides virtual void rom_bank_updated() override; diff --git a/src/devices/sound/votrax.cpp b/src/devices/sound/votrax.cpp index 000a568d2a3..067e639ed78 100644 --- a/src/devices/sound/votrax.cpp +++ b/src/devices/sound/votrax.cpp @@ -489,7 +489,7 @@ void votrax_sc01_device::chip_update() m_noise = ((m_noise << 1) & 0x7ffe) | inp; m_cur_noise = !(((m_noise >> 14) ^ (m_noise >> 13)) & 1); - // logerror("%s tick %02x.%03x 625=%d 208=%d pitch=%02x.%x ns=%04x ni=%d noise=%d cl=%x.%x clf=%d/%d\n", machine().time().to_string(), m_ticks, m_phonetick, tick_625, tick_208, m_pitch >> 3, m_pitch & 7, m_noise, inp, m_cur_noise, m_closure >> 2, m_closure & 3, m_rom_closure, m_cur_closure); + // logerror("%s tick %02x.%03x 625=%d 208=%d pitch=%02x.%x ns=%04x ni=%d noise=%d cl=%x.%x clf=%d/%d\n", machine().time().to_string(), m_ticks, m_phonetick, tick_625, tick_208, m_pitch >> 3, m_pitch & 7, m_noise, inp, m_cur_noise, m_closure >> 2, m_closure & 3, m_rom_closure, m_cur_closure); } void votrax_sc01_device::filters_commit(bool force) @@ -877,8 +877,11 @@ void votrax_sc01_device::build_lowpass_filter(double *a, double *b, double c1t, // Unswitched cap, over amp-op, top double c1b) // Switched cap, over amp-op, bottom { + // The caps values puts the cutoff at around 150Hz, put that's no good. + // Recordings shows we want it around 4K, so fuzz it. + // Compute the only coefficient we care about - double k = c1b / (m_cclock * c1t); + double k = c1b / (m_cclock * c1t) * (150.0/4000.0); // Compute the filter cutoff frequency double fpeak = 1/(2*M_PI*k); @@ -1001,7 +1004,7 @@ void votrax_sc01_device::build_injection_filter(double *a, double *b, b[1] = k1 + m; // That ends up in a numerically unstable filter. Neutralize it for now. - a[0] = 1; + a[0] = 0; a[1] = 0; b[0] = 1; b[1] = 0; diff --git a/src/devices/sound/vrc6.cpp b/src/devices/sound/vrc6.cpp index 58022411766..d9b36f5b8a6 100644 --- a/src/devices/sound/vrc6.cpp +++ b/src/devices/sound/vrc6.cpp @@ -45,7 +45,7 @@ vrc6snd_device::vrc6snd_device(const machine_config &mconfig, const char *tag, d void vrc6snd_device::device_start() { - m_stream = stream_alloc_legacy(0, 1, clock()); + m_stream = stream_alloc(0, 1, clock()); m_freqctrl = m_pulsectrl[0] = m_pulsectrl[1] = 0; m_pulsefrql[0] = m_pulsefrql[1] = m_pulsefrqh[0] = m_pulsefrqh[1] = 0; @@ -89,19 +89,20 @@ void vrc6snd_device::device_reset() } //------------------------------------------------- -// sound_stream_update_legacy - handle update requests for +// sound_stream_update - handle update requests for // our sound stream //------------------------------------------------- -void vrc6snd_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void vrc6snd_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - std::fill_n(&outputs[0][0], samples, 0); - // check global halt bit if (m_freqctrl & 1) + { + outputs[0].fill(0); return; + } - for (int i = 0; i < samples; i++) + for (int i = 0; i < outputs[0].samples(); i++) { // update pulse1 if (m_pulsefrqh[0] & 0x80) @@ -198,9 +199,8 @@ void vrc6snd_device::sound_stream_update_legacy(sound_stream &stream, stream_sam // sum 2 4-bit pulses, 1 5-bit saw = unsigned 6 bit output s16 tmp = (s16)(u8)(m_output[0] + m_output[1] + m_output[2]); - tmp <<= 8; - outputs[0][i] = tmp; + outputs[0].put_int(i, tmp, 128); } } diff --git a/src/devices/sound/vrc6.h b/src/devices/sound/vrc6.h index 0c1dd422d14..eb17dabff82 100644 --- a/src/devices/sound/vrc6.h +++ b/src/devices/sound/vrc6.h @@ -31,7 +31,7 @@ protected: virtual void device_start() override; virtual void device_reset() override; - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: u8 m_freqctrl, m_pulsectrl[2], m_sawrate, m_master_freq; diff --git a/src/devices/sound/vrender0.cpp b/src/devices/sound/vrender0.cpp index 09fb0f14940..fd86b56adea 100644 --- a/src/devices/sound/vrender0.cpp +++ b/src/devices/sound/vrender0.cpp @@ -148,7 +148,7 @@ void vr0sound_device::device_start() for (auto &elem : m_channel) elem.Cache = &m_fbcache; - m_stream = stream_alloc_legacy(0, 2, clock() / 972); // TODO : Correct source / divider? + m_stream = stream_alloc(0, 2, clock() / 972); // TODO : Correct source / divider? save_item(STRUCT_MEMBER(m_channel, CurSAddr)); save_item(STRUCT_MEMBER(m_channel, EnvVol)); @@ -208,13 +208,13 @@ device_memory_interface::space_config_vector vr0sound_device::memory_space_confi } //------------------------------------------------- -// sound_stream_update_legacy - handle update requests +// sound_stream_update - handle update requests // for our sound stream //------------------------------------------------- -void vr0sound_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void vr0sound_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - VR0_RenderAudio(samples, outputs[0], outputs[1]); + VR0_RenderAudio(outputs[0], outputs[1]); } u16 vr0sound_device::channel_r(offs_t offset) @@ -500,7 +500,7 @@ void vr0sound_device::channel_t::write(offs_t offset, u16 data, u16 mem_mask) } } -void vr0sound_device::VR0_RenderAudio(int nsamples, stream_sample_t *l, stream_sample_t *r) +void vr0sound_device::VR0_RenderAudio(write_stream_view &l, write_stream_view &r) { int div; if (m_ChnClkNum) @@ -508,7 +508,7 @@ void vr0sound_device::VR0_RenderAudio(int nsamples, stream_sample_t *l, stream_s else div = 1 << 16; - for (int s = 0; s < nsamples; s++) + for (int s = 0; s < l.samples(); s++) { s32 lsample = 0, rsample = 0; for (int i = 0; i <= m_MaxChn; i++) @@ -590,7 +590,7 @@ void vr0sound_device::VR0_RenderAudio(int nsamples, stream_sample_t *l, stream_s lsample += (sample * channel->LChnVol) >> 8; rsample += (sample * channel->RChnVol) >> 8; } - l[s] = std::max(-32768, std::min(32767, lsample)); - r[s] = std::max(-32768, std::min(32767, rsample)); + l.put_int_clamp(s, lsample, 32768); + r.put_int_clamp(s, rsample, 32768); } } diff --git a/src/devices/sound/vrender0.h b/src/devices/sound/vrender0.h index 99e2235a1be..1e234232c69 100644 --- a/src/devices/sound/vrender0.h +++ b/src/devices/sound/vrender0.h @@ -78,7 +78,7 @@ protected: virtual void device_clock_changed() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; // device_memory_interface configuration virtual space_config_vector memory_space_config() const override; @@ -151,7 +151,7 @@ private: u8 m_MaxChn = 0x1f; // Max Channels - 1 u8 m_ChnClkNum = 0; // Clock Number per Channel u16 m_Ctrl = 0; // 0x602 Control Functions - void VR0_RenderAudio(int nsamples, stream_sample_t *l, stream_sample_t *r); + void VR0_RenderAudio(write_stream_view &l, write_stream_view &r); }; DECLARE_DEVICE_TYPE(SOUND_VRENDER0, vr0sound_device) diff --git a/src/devices/sound/wave.cpp b/src/devices/sound/wave.cpp index 27407a2dbd2..99c56615171 100644 --- a/src/devices/sound/wave.cpp +++ b/src/devices/sound/wave.cpp @@ -40,51 +40,36 @@ wave_device::wave_device(const machine_config &mconfig, const char *tag, device_ void wave_device::device_start() { - speaker_device_iterator spkiter(*owner()); - int speakers = spkiter.count(); - if (speakers > 1) - stream_alloc_legacy(0, 2, machine().sample_rate()); - else - stream_alloc_legacy(0, 1, machine().sample_rate()); + stream_alloc(0, 2, machine().sample_rate()); } //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void wave_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void wave_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - stream_sample_t *left_buffer = outputs[0]; - stream_sample_t *right_buffer = nullptr; - - speaker_device_iterator spkiter(*owner()); - int speakers = spkiter.count(); - if (speakers > 1) - right_buffer = outputs[1]; - cassette_state state = m_cass->get_state() & (CASSETTE_MASK_UISTATE | CASSETTE_MASK_MOTOR | CASSETTE_MASK_SPEAKER); if (m_cass->exists() && (ALWAYS_PLAY_SOUND || (state == (CASSETTE_PLAY | CASSETTE_MOTOR_ENABLED | CASSETTE_SPEAKER_ENABLED)))) { cassette_image *cassette = m_cass->get_image(); double time_index = m_cass->get_position(); - double duration = double(samples) / m_cass->machine().sample_rate(); + double duration = double(outputs[0].samples()) / outputs[0].sample_rate(); - cassette_get_samples(cassette, 0, time_index, duration, samples, 2, left_buffer, CASSETTE_WAVEFORM_16BIT); - if (speakers > 1) - cassette_get_samples(cassette, 1, time_index, duration, samples, 2, right_buffer, CASSETTE_WAVEFORM_16BIT); + if (m_sample_buf.size() < outputs[0].samples()) + m_sample_buf.resize(outputs[0].samples()); - for (int i = samples - 1; i >= 0; i--) + for (int ch = 0; ch < 2; ch++) { - left_buffer[i] = ((int16_t *) left_buffer)[i]; - if (speakers > 1) - right_buffer[i] = ((int16_t *) right_buffer)[i]; + cassette->get_samples(ch, time_index, duration, outputs[ch].samples(), 2, &m_sample_buf[0], cassette_image::WAVEFORM_16BIT); + for (int sampindex = 0; sampindex < outputs[0].samples(); sampindex++) + outputs[ch].put_int(sampindex, m_sample_buf[sampindex], 32768); } } else { - memset(left_buffer, 0, sizeof(*left_buffer) * samples); - if (speakers > 1) - memset(right_buffer, 0, sizeof(*right_buffer) * samples); + outputs[0].fill(0); + outputs[1].fill(0); } } diff --git a/src/devices/sound/wave.h b/src/devices/sound/wave.h index 9f2a834d6c1..e81379ee93a 100644 --- a/src/devices/sound/wave.h +++ b/src/devices/sound/wave.h @@ -30,10 +30,11 @@ protected: virtual void device_start() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: required_device<cassette_image_device> m_cass; + std::vector<s16> m_sample_buf; }; DECLARE_DEVICE_TYPE(WAVE, wave_device) diff --git a/src/devices/sound/x1_010.cpp b/src/devices/sound/x1_010.cpp index 8334db4a299..b54fa6bd6cf 100644 --- a/src/devices/sound/x1_010.cpp +++ b/src/devices/sound/x1_010.cpp @@ -119,7 +119,7 @@ void x1_010_device::device_start() LOG_SOUND("masterclock = %d rate = %d\n", clock(), m_rate); /* get stream channels */ - m_stream = stream_alloc_legacy(0, 2, m_rate); + m_stream = stream_alloc(0, 2, m_rate); m_reg = make_unique_clear<u8[]>(0x2000); m_HI_WORD_BUF = make_unique_clear<u8[]>(0x2000); @@ -204,14 +204,14 @@ void x1_010_device::word_w(offs_t offset, u16 data) //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void x1_010_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void x1_010_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { // mixer buffer zero clear - memset(outputs[0], 0, samples*sizeof(*outputs[0])); - memset(outputs[1], 0, samples*sizeof(*outputs[1])); + outputs[0].fill(0); + outputs[1].fill(0); // if (m_sound_enable == 0) return; @@ -220,8 +220,8 @@ void x1_010_device::sound_stream_update_legacy(sound_stream &stream, stream_samp X1_010_CHANNEL *reg = (X1_010_CHANNEL *)&(m_reg[ch*sizeof(X1_010_CHANNEL)]); if ((reg->status & 1) != 0) // Key On { - stream_sample_t *bufL = outputs[0]; - stream_sample_t *bufR = outputs[1]; + auto &bufL = outputs[0]; + auto &bufR = outputs[1]; const int div = (reg->status & 0x80) ? 1 : 0; if ((reg->status & 2) == 0) // PCM sampling { @@ -240,7 +240,7 @@ void x1_010_device::sound_stream_update_legacy(sound_stream &stream, stream_samp LOG_SOUND("Play sample %p - %p, channel %X volume %d:%d freq %X step %X offset %X\n", start, end, ch, volL, volR, freq, smp_step, smp_offs); } - for (int i = 0; i < samples; i++) + for (int i = 0; i < bufL.samples(); i++) { const u32 delta = smp_offs >> 4; // sample ended? @@ -250,8 +250,8 @@ void x1_010_device::sound_stream_update_legacy(sound_stream &stream, stream_samp break; } const s8 data = (s8)(read_byte(start+delta)); - *bufL++ += (data * volL / 256); - *bufR++ += (data * volR / 256); + bufL.add_int(i, data * volL, 32768 * 256); + bufR.add_int(i, data * volR, 32768 * 256); smp_offs += smp_step; } m_smp_offset[ch] = smp_offs; @@ -272,7 +272,7 @@ void x1_010_device::sound_stream_update_legacy(sound_stream &stream, stream_samp LOG_SOUND("Play waveform %X, channel %X volume %X freq %4X step %X offset %X\n", reg->volume, ch, reg->end, freq, smp_step, smp_offs); } - for (int i = 0; i < samples; i++) + for (int i = 0; i < bufL.samples(); i++) { const u32 delta = env_offs >> 10; // Envelope one shot mode @@ -285,8 +285,8 @@ void x1_010_device::sound_stream_update_legacy(sound_stream &stream, stream_samp const int volL = ((vol >> 4) & 0xf) * VOL_BASE; const int volR = ((vol >> 0) & 0xf) * VOL_BASE; const s8 data = (s8)(m_reg[start + ((smp_offs >> 10) & 0x7f)]); - *bufL++ += (data * volL / 256); - *bufR++ += (data * volR / 256); + bufL.add_int(i, data * volL, 32768 * 256); + bufR.add_int(i, data * volR, 32768 * 256); smp_offs += smp_step; env_offs += env_step; } diff --git a/src/devices/sound/x1_010.h b/src/devices/sound/x1_010.h index 3c8f1e60dc6..b6b266b0ba0 100644 --- a/src/devices/sound/x1_010.h +++ b/src/devices/sound/x1_010.h @@ -26,7 +26,7 @@ protected: virtual void device_clock_changed() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; // device_rom_interface overrides virtual void rom_bank_updated() override; diff --git a/src/devices/sound/ym2151.cpp b/src/devices/sound/ym2151.cpp index b519d9a1224..74cfa9643ae 100644 --- a/src/devices/sound/ym2151.cpp +++ b/src/devices/sound/ym2151.cpp @@ -1845,7 +1845,6 @@ void ym2151_device::sound_stream_update(sound_stream &stream, std::vector<read_s return; } - constexpr stream_buffer::sample_t sample_scale = 1.0 / 32768.0; for (int sampindex=0; sampindex<outputs[0].samples(); sampindex++) { advance_eg(); @@ -1864,16 +1863,8 @@ void ym2151_device::sound_stream_update(sound_stream &stream, std::vector<read_s outr += chanout[ch] & pan[2*ch+1]; } - if (outl > 32767) - outl = 32767; - else if (outl < -32768) - outl = -32768; - if (outr > 32767) - outr = 32767; - else if (outr < -32768) - outr = -32768; - outputs[0].put(sampindex, stream_buffer::sample_t(outl) * sample_scale); - outputs[1].put(sampindex, stream_buffer::sample_t(outr) * sample_scale); + outputs[0].put_int_clamp(sampindex, outl, 32768); + outputs[1].put_int_clamp(sampindex, outr, 32768); advance(); } diff --git a/src/devices/sound/ym2413.cpp b/src/devices/sound/ym2413.cpp index ca4a9acb874..28cf77c097b 100644 --- a/src/devices/sound/ym2413.cpp +++ b/src/devices/sound/ym2413.cpp @@ -1470,12 +1470,12 @@ void ym2413_device::write_reg(int r, int v) } //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void ym2413_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void ym2413_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - for(int i=0; i < samples ; i++ ) + for(int i=0; i < outputs[0].samples() ; i++ ) { output[0] = 0; output[1] = 0; @@ -1496,8 +1496,8 @@ void ym2413_device::sound_stream_update_legacy(sound_stream &stream, stream_samp rhythm_calc(&P_CH[0], noise_rng & 1 ); } - outputs[0][i] = limit( output[0] , 32767, -32768 ); - outputs[1][i] = limit( output[1] , 32767, -32768 ); + outputs[0].put_int_clamp(i, output[0], 32768); + outputs[1].put_int_clamp(i, output[1], 32768); advance(); } @@ -1511,7 +1511,7 @@ void ym2413_device::device_start() { int rate = clock()/72; - m_stream = stream_alloc_legacy(0,2,rate); + m_stream = stream_alloc(0,2,rate); for (int x=0; x<TL_RES_LEN; x++) { diff --git a/src/devices/sound/ym2413.h b/src/devices/sound/ym2413.h index 2e1db357150..27174977332 100644 --- a/src/devices/sound/ym2413.h +++ b/src/devices/sound/ym2413.h @@ -25,7 +25,7 @@ protected: virtual void device_reset() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; uint8_t m_inst_table[19][8]; diff --git a/src/devices/sound/ymf262.cpp b/src/devices/sound/ymf262.cpp index 6ec8e081021..708970a7c0b 100644 --- a/src/devices/sound/ymf262.cpp +++ b/src/devices/sound/ymf262.cpp @@ -639,6 +639,7 @@ static inline void OPL3_SLOT_CONNECT(OPL3 *chip, OPL3_SLOT *slot) { } } +#if 0 static inline int limit( int val, int max, int min ) { if ( val > max ) val = max; @@ -647,7 +648,7 @@ static inline int limit( int val, int max, int min ) { return val; } - +#endif /* status set and IRQ handling */ static inline void OPL3_STATUS_SET(OPL3 *chip,int flag) @@ -2618,19 +2619,19 @@ void ymf262_set_update_handler(void *chip, OPL3_UPDATEHANDLER UpdateHandler, dev ** '**buffers' is table of 4 pointers to the buffers: CH.A, CH.B, CH.C and CH.D ** 'length' is the number of samples that should be generated */ -void ymf262_update_one(void *_chip, OPL3SAMPLE * const *buffers, int length) +void ymf262_update_one(void *_chip, std::vector<write_stream_view> &buffers) { int i; OPL3 *chip = (OPL3 *)_chip; signed int *chanout = chip->chanout; uint8_t rhythm = chip->rhythm&0x20; - OPL3SAMPLE *ch_a = buffers[0]; // DO2 (mixed) left output for OPL4 - OPL3SAMPLE *ch_b = buffers[1]; // DO2 (mixed) right output for OPL4 - OPL3SAMPLE *ch_c = buffers[2]; // DO0 (FM only) left output for OPL4 - OPL3SAMPLE *ch_d = buffers[3]; // DO0 (FM only) right output for OPL4 + auto &ch_a = buffers[0]; // DO2 (mixed) left output for OPL4 + auto &ch_b = buffers[1]; // DO2 (mixed) right output for OPL4 + auto &ch_c = buffers[2]; // DO0 (FM only) left output for OPL4 + auto &ch_d = buffers[3]; // DO0 (FM only) right output for OPL4 - for( i=0; i < length ; i++ ) + for( i=0; i < ch_a.samples() ; i++ ) { int a,b,c,d; @@ -2782,16 +2783,6 @@ void ymf262_update_one(void *_chip, OPL3SAMPLE * const *buffers, int length) c += chanout[17] & chip->pan[70]; d += chanout[17] & chip->pan[71]; #endif - a >>= FINAL_SH; - b >>= FINAL_SH; - c >>= FINAL_SH; - d >>= FINAL_SH; - - /* limit check */ - a = limit( a , MAXOUT, MINOUT ); - b = limit( b , MAXOUT, MINOUT ); - c = limit( c , MAXOUT, MINOUT ); - d = limit( d , MAXOUT, MINOUT ); #ifdef SAVE_SAMPLE if (which==0) @@ -2801,10 +2792,10 @@ void ymf262_update_one(void *_chip, OPL3SAMPLE * const *buffers, int length) #endif /* store to sound buffer */ - ch_a[i] = a; - ch_b[i] = b; - ch_c[i] = c; - ch_d[i] = d; + ch_a.put_int_clamp(i, a, 32768 << FINAL_SH); + ch_b.put_int_clamp(i, a, 32768 << FINAL_SH); + ch_c.put_int_clamp(i, a, 32768 << FINAL_SH); + ch_d.put_int_clamp(i, a, 32768 << FINAL_SH); advance(chip); } diff --git a/src/devices/sound/ymf262.h b/src/devices/sound/ymf262.h index d459a9a68ee..fe131169fcf 100644 --- a/src/devices/sound/ymf262.h +++ b/src/devices/sound/ymf262.h @@ -8,7 +8,7 @@ /* select number of output bits: 8 or 16 */ #define OPL3_SAMPLE_BITS 16 -typedef stream_sample_t OPL3SAMPLE; +typedef s32 OPL3SAMPLE; /* #if (OPL3_SAMPLE_BITS==16) typedef int16_t OPL3SAMPLE; @@ -33,7 +33,7 @@ void ymf262_reset_chip(void *chip); int ymf262_write(void *chip, int a, int v); unsigned char ymf262_read(void *chip, int a); int ymf262_timer_over(void *chip, int c); -void ymf262_update_one(void *chip, OPL3SAMPLE * const *buffers, int length); +void ymf262_update_one(void *chip, std::vector<write_stream_view> &buffers); void ymf262_set_timer_handler(void *chip, OPL3_TIMERHANDLER TimerHandler, device_t *device); void ymf262_set_irq_handler(void *chip, OPL3_IRQHANDLER IRQHandler, device_t *device); diff --git a/src/devices/sound/ymf271.cpp b/src/devices/sound/ymf271.cpp index 03ca33a2382..a473705b065 100644 --- a/src/devices/sound/ymf271.cpp +++ b/src/devices/sound/ymf271.cpp @@ -563,10 +563,10 @@ void ymf271_device::set_feedback(int slotnum, int64_t inp) } //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void ymf271_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void ymf271_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { int i, j; int op; @@ -599,7 +599,7 @@ void ymf271_device::sound_stream_update_legacy(sound_stream &stream, stream_samp if (m_slots[slot1].active) { - for (i = 0; i < samples; i++) + for (i = 0; i < outputs[0].samples(); i++) { int64_t output1 = 0, output2 = 0, output3 = 0, output4 = 0; int64_t phase_mod1, phase_mod2, phase_mod3; @@ -833,7 +833,7 @@ void ymf271_device::sound_stream_update_legacy(sound_stream &stream, stream_samp mixp = &m_mix_buffer[0]; if (m_slots[slot1].active) { - for (i = 0; i < samples; i++) + for (i = 0; i < outputs[0].samples(); i++) { int64_t output1 = 0, output3 = 0; int64_t phase_mod1, phase_mod3; @@ -900,7 +900,7 @@ void ymf271_device::sound_stream_update_legacy(sound_stream &stream, stream_samp if (m_slots[slot1].active) { - for (i = 0; i < samples; i++) + for (i = 0; i < outputs[0].samples(); i++) { int64_t output1 = 0, output2 = 0, output3 = 0; int64_t phase_mod1, phase_mod3; @@ -1006,29 +1006,29 @@ void ymf271_device::sound_stream_update_legacy(sound_stream &stream, stream_samp } mixp = &m_mix_buffer[0]; - update_pcm(j + (3*12), mixp, samples); + update_pcm(j + (3*12), mixp, outputs[0].samples()); break; } // PCM case 3: { - update_pcm(j + (0*12), mixp, samples); - update_pcm(j + (1*12), mixp, samples); - update_pcm(j + (2*12), mixp, samples); - update_pcm(j + (3*12), mixp, samples); + update_pcm(j + (0*12), mixp, outputs[0].samples()); + update_pcm(j + (1*12), mixp, outputs[0].samples()); + update_pcm(j + (2*12), mixp, outputs[0].samples()); + update_pcm(j + (3*12), mixp, outputs[0].samples()); break; } } } mixp = &m_mix_buffer[0]; - for (i = 0; i < samples; i++) + for (i = 0; i < outputs[0].samples(); i++) { - outputs[0][i] = (*mixp++)>>2; - outputs[1][i] = (*mixp++)>>2; - outputs[2][i] = (*mixp++)>>2; - outputs[3][i] = (*mixp++)>>2; + outputs[0].put_int(i, *mixp++, 32768 << 2); + outputs[1].put_int(i, *mixp++, 32768 << 2); + outputs[2].put_int(i, *mixp++, 32768 << 2); + outputs[3].put_int(i, *mixp++, 32768 << 2); } } @@ -1520,8 +1520,11 @@ u8 ymf271_device::read(offs_t offset) return 0xff; uint8_t ret = m_ext_readlatch; - m_ext_address = (m_ext_address + 1) & 0x7fffff; - m_ext_readlatch = read_byte(m_ext_address); + if (!machine().side_effects_disabled()) + { + m_ext_address = (m_ext_address + 1) & 0x7fffff; + m_ext_readlatch = read_byte(m_ext_address); + } return ret; } @@ -1660,64 +1663,56 @@ void ymf271_device::calculate_clock_correction() void ymf271_device::init_state() { - int i; - - for (i = 0; i < ARRAY_LENGTH(m_slots); i++) - { - save_item(NAME(m_slots[i].ext_en), i); - save_item(NAME(m_slots[i].ext_out), i); - save_item(NAME(m_slots[i].lfoFreq), i); - save_item(NAME(m_slots[i].pms), i); - save_item(NAME(m_slots[i].ams), i); - save_item(NAME(m_slots[i].detune), i); - save_item(NAME(m_slots[i].multiple), i); - save_item(NAME(m_slots[i].tl), i); - save_item(NAME(m_slots[i].keyscale), i); - save_item(NAME(m_slots[i].ar), i); - save_item(NAME(m_slots[i].decay1rate), i); - save_item(NAME(m_slots[i].decay2rate), i); - save_item(NAME(m_slots[i].decay1lvl), i); - save_item(NAME(m_slots[i].relrate), i); - save_item(NAME(m_slots[i].block), i); - save_item(NAME(m_slots[i].fns_hi), i); - save_item(NAME(m_slots[i].fns), i); - save_item(NAME(m_slots[i].feedback), i); - save_item(NAME(m_slots[i].waveform), i); - save_item(NAME(m_slots[i].accon), i); - save_item(NAME(m_slots[i].algorithm), i); - save_item(NAME(m_slots[i].ch0_level), i); - save_item(NAME(m_slots[i].ch1_level), i); - save_item(NAME(m_slots[i].ch2_level), i); - save_item(NAME(m_slots[i].ch3_level), i); - save_item(NAME(m_slots[i].startaddr), i); - save_item(NAME(m_slots[i].loopaddr), i); - save_item(NAME(m_slots[i].endaddr), i); - save_item(NAME(m_slots[i].altloop), i); - save_item(NAME(m_slots[i].fs), i); - save_item(NAME(m_slots[i].srcnote), i); - save_item(NAME(m_slots[i].srcb), i); - save_item(NAME(m_slots[i].step), i); - save_item(NAME(m_slots[i].stepptr), i); - save_item(NAME(m_slots[i].active), i); - save_item(NAME(m_slots[i].bits), i); - save_item(NAME(m_slots[i].volume), i); - save_item(NAME(m_slots[i].env_state), i); - save_item(NAME(m_slots[i].env_attack_step), i); - save_item(NAME(m_slots[i].env_decay1_step), i); - save_item(NAME(m_slots[i].env_decay2_step), i); - save_item(NAME(m_slots[i].env_release_step), i); - save_item(NAME(m_slots[i].feedback_modulation0), i); - save_item(NAME(m_slots[i].feedback_modulation1), i); - save_item(NAME(m_slots[i].lfo_phase), i); - save_item(NAME(m_slots[i].lfo_step), i); - save_item(NAME(m_slots[i].lfo_amplitude), i); - } - - for (i = 0; i < ARRAY_LENGTH(m_groups); i++) - { - save_item(NAME(m_groups[i].sync), i); - save_item(NAME(m_groups[i].pfm), i); - } + save_item(STRUCT_MEMBER(m_slots, ext_en)); + save_item(STRUCT_MEMBER(m_slots, ext_out)); + save_item(STRUCT_MEMBER(m_slots, lfoFreq)); + save_item(STRUCT_MEMBER(m_slots, pms)); + save_item(STRUCT_MEMBER(m_slots, ams)); + save_item(STRUCT_MEMBER(m_slots, detune)); + save_item(STRUCT_MEMBER(m_slots, multiple)); + save_item(STRUCT_MEMBER(m_slots, tl)); + save_item(STRUCT_MEMBER(m_slots, keyscale)); + save_item(STRUCT_MEMBER(m_slots, ar)); + save_item(STRUCT_MEMBER(m_slots, decay1rate)); + save_item(STRUCT_MEMBER(m_slots, decay2rate)); + save_item(STRUCT_MEMBER(m_slots, decay1lvl)); + save_item(STRUCT_MEMBER(m_slots, relrate)); + save_item(STRUCT_MEMBER(m_slots, block)); + save_item(STRUCT_MEMBER(m_slots, fns_hi)); + save_item(STRUCT_MEMBER(m_slots, fns)); + save_item(STRUCT_MEMBER(m_slots, feedback)); + save_item(STRUCT_MEMBER(m_slots, waveform)); + save_item(STRUCT_MEMBER(m_slots, accon)); + save_item(STRUCT_MEMBER(m_slots, algorithm)); + save_item(STRUCT_MEMBER(m_slots, ch0_level)); + save_item(STRUCT_MEMBER(m_slots, ch1_level)); + save_item(STRUCT_MEMBER(m_slots, ch2_level)); + save_item(STRUCT_MEMBER(m_slots, ch3_level)); + save_item(STRUCT_MEMBER(m_slots, startaddr)); + save_item(STRUCT_MEMBER(m_slots, loopaddr)); + save_item(STRUCT_MEMBER(m_slots, endaddr)); + save_item(STRUCT_MEMBER(m_slots, altloop)); + save_item(STRUCT_MEMBER(m_slots, fs)); + save_item(STRUCT_MEMBER(m_slots, srcnote)); + save_item(STRUCT_MEMBER(m_slots, srcb)); + save_item(STRUCT_MEMBER(m_slots, step)); + save_item(STRUCT_MEMBER(m_slots, stepptr)); + save_item(STRUCT_MEMBER(m_slots, active)); + save_item(STRUCT_MEMBER(m_slots, bits)); + save_item(STRUCT_MEMBER(m_slots, volume)); + save_item(STRUCT_MEMBER(m_slots, env_state)); + save_item(STRUCT_MEMBER(m_slots, env_attack_step)); + save_item(STRUCT_MEMBER(m_slots, env_decay1_step)); + save_item(STRUCT_MEMBER(m_slots, env_decay2_step)); + save_item(STRUCT_MEMBER(m_slots, env_release_step)); + save_item(STRUCT_MEMBER(m_slots, feedback_modulation0)); + save_item(STRUCT_MEMBER(m_slots, feedback_modulation1)); + save_item(STRUCT_MEMBER(m_slots, lfo_phase)); + save_item(STRUCT_MEMBER(m_slots, lfo_step)); + save_item(STRUCT_MEMBER(m_slots, lfo_amplitude)); + + save_item(STRUCT_MEMBER(m_groups, sync)); + save_item(STRUCT_MEMBER(m_groups, pfm)); save_item(NAME(m_regs_main)); save_item(NAME(m_timerA)); @@ -1748,7 +1743,7 @@ void ymf271_device::device_start() init_state(); m_mix_buffer.resize(m_master_clock/(384/4)); - m_stream = stream_alloc_legacy(0, 4, m_master_clock/384); + m_stream = stream_alloc(0, 4, m_master_clock/384); } //------------------------------------------------- diff --git a/src/devices/sound/ymf271.h b/src/devices/sound/ymf271.h index 87f06eb8e73..1c628f34cf1 100644 --- a/src/devices/sound/ymf271.h +++ b/src/devices/sound/ymf271.h @@ -28,7 +28,7 @@ protected: virtual void device_clock_changed() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; // device_rom_interface overrides virtual void rom_bank_updated() override; diff --git a/src/devices/sound/ymf278b.cpp b/src/devices/sound/ymf278b.cpp index 7bda7b6b8ef..f9f308a4892 100644 --- a/src/devices/sound/ymf278b.cpp +++ b/src/devices/sound/ymf278b.cpp @@ -212,10 +212,10 @@ void ymf278b_device::compute_envelope(YMF278BSlot *slot) } //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void ymf278b_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void ymf278b_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { int i, j; YMF278BSlot *slot; @@ -223,14 +223,14 @@ void ymf278b_device::sound_stream_update_legacy(sound_stream &stream, stream_sam int32_t *mixp; int32_t vl, vr; - ymf262_update_one(m_ymf262, outputs, samples); - vl = m_mix_level[m_fm_l]; - vr = m_mix_level[m_fm_r]; - for (i = 0; i < samples; i++) + ymf262_update_one(m_ymf262, outputs); + stream_buffer::sample_t fvl = stream_buffer::sample_t(m_mix_level[m_fm_l]) * (1.0 / 65536.0); + stream_buffer::sample_t fvr = stream_buffer::sample_t(m_mix_level[m_fm_r]) * (1.0 / 65536.0); + for (i = 0; i < outputs[0].samples(); i++) { // DO2 mixing - outputs[0][i] = (outputs[0][i] * vl) >> 16; - outputs[1][i] = (outputs[1][i] * vr) >> 16; + outputs[0].put(i, outputs[0].get(i) * fvl); + outputs[1].put(i, outputs[1].get(i) * fvr); } std::fill(m_mix_buffer.begin(), m_mix_buffer.end(), 0); @@ -243,7 +243,7 @@ void ymf278b_device::sound_stream_update_legacy(sound_stream &stream, stream_sam { mixp = &m_mix_buffer[0]; - for (j = 0; j < samples; j++) + for (j = 0; j < outputs[0].samples(); j++) { if (slot->stepptr >= slot->endaddr) { @@ -316,12 +316,12 @@ void ymf278b_device::sound_stream_update_legacy(sound_stream &stream, stream_sam mixp = &m_mix_buffer[0]; vl = m_mix_level[m_pcm_l]; vr = m_mix_level[m_pcm_r]; - for (i = 0; i < samples; i++) + for (i = 0; i < outputs[0].samples(); i++) { - outputs[0][i] += (*mixp++ * vl) >> 16; - outputs[1][i] += (*mixp++ * vr) >> 16; - outputs[4][i] = *mixp++; - outputs[5][i] = *mixp++; + outputs[0].add_int(i, (*mixp++ * vl) >> 16, 32768); + outputs[1].add_int(i, (*mixp++ * vr) >> 16, 32768); + outputs[4].put_int(i, *mixp++, 32768); + outputs[5].put_int(i, *mixp++, 32768); } } @@ -1009,7 +1009,7 @@ void ymf278b_device::device_start() m_slots[i].num = i; } - m_stream = stream_alloc_legacy(0, 6, m_rate); + m_stream = stream_alloc(0, 6, m_rate); m_mix_buffer.resize(m_rate*4,0); // rate tables diff --git a/src/devices/sound/ymf278b.h b/src/devices/sound/ymf278b.h index 03fa9880442..d872ce13e38 100644 --- a/src/devices/sound/ymf278b.h +++ b/src/devices/sound/ymf278b.h @@ -29,7 +29,7 @@ protected: virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; // device_rom_interface overrides virtual void rom_bank_updated() override; diff --git a/src/devices/sound/ymz280b.cpp b/src/devices/sound/ymz280b.cpp index 94ef134bd4c..b2836c74967 100644 --- a/src/devices/sound/ymz280b.cpp +++ b/src/devices/sound/ymz280b.cpp @@ -412,18 +412,18 @@ int ymz280b_device::generate_pcm16(struct YMZ280BVoice *voice, s16 *buffer, int //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void ymz280b_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void ymz280b_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - stream_sample_t *lacc = outputs[0]; - stream_sample_t *racc = outputs[1]; + auto &lacc = outputs[0]; + auto &racc = outputs[1]; int v; /* clear out the accumulator */ - memset(lacc, 0, samples * sizeof(lacc[0])); - memset(racc, 0, samples * sizeof(racc[0])); + lacc.fill(0); + racc.fill(0); /* loop over voices */ for (v = 0; v < 8; v++) @@ -432,11 +432,10 @@ void ymz280b_device::sound_stream_update_legacy(sound_stream &stream, stream_sam s16 prev = voice->last_sample; s16 curr = voice->curr_sample; s16 *curr_data = m_scratch.get(); - s32 *ldest = lacc; - s32 *rdest = racc; + s32 sampindex = 0; u32 new_samples, samples_left; u32 final_pos; - int remaining = samples; + int remaining = lacc.samples(); int lvol = voice->output_left; int rvol = voice->output_right; @@ -453,8 +452,9 @@ void ymz280b_device::sound_stream_update_legacy(sound_stream &stream, stream_sam while (remaining > 0 && voice->output_pos < FRAC_ONE) { int interp_sample = ((s32(prev) * (FRAC_ONE - voice->output_pos)) + (s32(curr) * voice->output_pos)) >> FRAC_BITS; - *ldest++ += interp_sample * lvol; - *rdest++ += interp_sample * rvol; + lacc.add_int(sampindex, interp_sample * lvol, 32768 * 256); + racc.add_int(sampindex, interp_sample * rvol, 32768 * 256); + sampindex++; voice->output_pos += voice->output_step; remaining--; } @@ -517,8 +517,9 @@ void ymz280b_device::sound_stream_update_legacy(sound_stream &stream, stream_sam while (remaining > 0 && voice->output_pos < FRAC_ONE) { int interp_sample = ((s32(prev) * (FRAC_ONE - voice->output_pos)) + (s32(curr) * voice->output_pos)) >> FRAC_BITS; - *ldest++ += interp_sample * lvol; - *rdest++ += interp_sample * rvol; + lacc.add_int(sampindex, interp_sample * lvol, 32768 * 256); + racc.add_int(sampindex, interp_sample * rvol, 32768 * 256); + sampindex++; voice->output_pos += voice->output_step; remaining--; } @@ -536,12 +537,6 @@ void ymz280b_device::sound_stream_update_legacy(sound_stream &stream, stream_sam voice->last_sample = prev; voice->curr_sample = curr; } - - for (v = 0; v < samples; v++) - { - outputs[0][v] /= 256; - outputs[1][v] /= 256; - } } @@ -565,7 +560,7 @@ void ymz280b_device::device_start() } /* create the stream */ - m_stream = stream_alloc_legacy(0, 2, INTERNAL_SAMPLE_RATE); + m_stream = stream_alloc(0, 2, INTERNAL_SAMPLE_RATE); /* allocate memory */ assert(MAX_SAMPLE_CHUNK < 0x10000); diff --git a/src/devices/sound/ymz280b.h b/src/devices/sound/ymz280b.h index ccbcb393bd8..5da3ea46cc3 100644 --- a/src/devices/sound/ymz280b.h +++ b/src/devices/sound/ymz280b.h @@ -36,7 +36,7 @@ protected: virtual void device_clock_changed() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; // device_rom_interface overrides virtual void rom_bank_updated() override; diff --git a/src/devices/sound/ymz770.cpp b/src/devices/sound/ymz770.cpp index 3934c6ac6dd..9d489d8a89d 100644 --- a/src/devices/sound/ymz770.cpp +++ b/src/devices/sound/ymz770.cpp @@ -77,7 +77,7 @@ ymz770_device::ymz770_device(const machine_config &mconfig, device_type type, co void ymz770_device::device_start() { // create the stream - m_stream = stream_alloc_legacy(0, 2, m_sclock); + m_stream = stream_alloc(0, 2, m_sclock); for (auto & channel : m_channels) { @@ -178,18 +178,16 @@ void ymz770_device::device_reset() //------------------------------------------------- -// sound_stream_update_legacy - handle update requests for +// sound_stream_update - handle update requests for // our sound stream //------------------------------------------------- -void ymz770_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void ymz770_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - stream_sample_t *outL, *outR; + auto &outL = outputs[0]; + auto &outR = outputs[1]; - outL = outputs[0]; - outR = outputs[1]; - - for (int i = 0; i < samples; i++) + for (int i = 0; i < outL.samples(); i++) { sequencer(); @@ -282,8 +280,8 @@ retry: } if (m_mute) mixr = mixl = 0; - outL[i] = mixl; - outR[i] = mixr; + outL.put_int(i, mixl, 32768); + outR.put_int(i, mixr, 32768); } } diff --git a/src/devices/sound/ymz770.h b/src/devices/sound/ymz770.h index ade24f61501..6c87cef8de4 100644 --- a/src/devices/sound/ymz770.h +++ b/src/devices/sound/ymz770.h @@ -33,7 +33,7 @@ protected: virtual void device_start() override; virtual void device_reset() override; - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; virtual void internal_reg_write(uint8_t reg, uint8_t data); virtual uint32_t get_phrase_offs(int phrase) { return m_rom[(4 * phrase) + 1] << 16 | m_rom[(4 * phrase) + 2] << 8 | m_rom[(4 * phrase) + 3]; }; diff --git a/src/devices/sound/zsg2.cpp b/src/devices/sound/zsg2.cpp index b964bce5f14..2fa01cfb3a5 100644 --- a/src/devices/sound/zsg2.cpp +++ b/src/devices/sound/zsg2.cpp @@ -134,7 +134,7 @@ void zsg2_device::device_start() memset(&m_chan, 0, sizeof(m_chan)); - m_stream = stream_alloc_legacy(0, 4, clock() / 768); + m_stream = stream_alloc(0, 4, clock() / 768); m_mem_blocks = m_mem_base.length(); m_mem_copy = make_unique_clear<uint32_t[]>(m_mem_blocks); @@ -280,12 +280,12 @@ void zsg2_device::filter_samples(zchan *ch) } //------------------------------------------------- -// sound_stream_update_legacy - handle a stream update +// sound_stream_update - handle a stream update //------------------------------------------------- -void zsg2_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) +void zsg2_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - for (int i = 0; i < samples; i++) + for (int i = 0; i < outputs[0].samples(); i++) { int32_t mix[4] = {}; @@ -355,8 +355,7 @@ void zsg2_device::sound_stream_update_legacy(sound_stream &stream, stream_sample } for(int output=0; output<4; output++) - outputs[output][i] = std::min<int32_t>(std::max<int32_t>(mix[output], -32768), 32767); - + outputs[output].put_int_clamp(i, mix[output], 32768); } m_sample_count++; } diff --git a/src/devices/sound/zsg2.h b/src/devices/sound/zsg2.h index 592cbf83787..0239f6ff03d 100644 --- a/src/devices/sound/zsg2.h +++ b/src/devices/sound/zsg2.h @@ -29,7 +29,7 @@ protected: virtual void device_reset() override; // sound stream update overrides - virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: const uint16_t STATUS_ACTIVE = 0x8000; diff --git a/src/devices/video/315_5124.cpp b/src/devices/video/315_5124.cpp index 4e7d04bcab6..9a3a0f8c339 100644 --- a/src/devices/video/315_5124.cpp +++ b/src/devices/video/315_5124.cpp @@ -1723,8 +1723,8 @@ void sega315_5124_device::draw_scanline(int pixel_offset_x, int pixel_plot_y, in void sega315_5124_device::blit_scanline(int *line_buffer, int *priority_selected, int pixel_offset_x, int pixel_plot_y, int line) { - u32 *p_bitmap = &m_tmpbitmap.pix32(pixel_plot_y + line, pixel_offset_x); - u8 *p_y1 = &m_y1_bitmap.pix8(pixel_plot_y + line, pixel_offset_x); + u32 *const p_bitmap = &m_tmpbitmap.pix(pixel_plot_y + line, pixel_offset_x); + u8 *const p_y1 = &m_y1_bitmap.pix(pixel_plot_y + line, pixel_offset_x); int x = 0; if (m_vdp_mode == 4 && BIT(m_reg[0x00], 5)) @@ -1755,8 +1755,8 @@ void sega315_5377_device::blit_scanline(int *line_buffer, int *priority_selected } else { - u32 *p_bitmap = &m_tmpbitmap.pix32(pixel_plot_y + line, pixel_offset_x); - u8 *p_y1 = &m_y1_bitmap.pix8(pixel_plot_y + line, pixel_offset_x); + u32 *const p_bitmap = &m_tmpbitmap.pix(pixel_plot_y + line, pixel_offset_x); + u8 *const p_y1 = &m_y1_bitmap.pix(pixel_plot_y + line, pixel_offset_x); int x = 0; /* border on left side of the GG active screen */ diff --git a/src/devices/video/315_5313.cpp b/src/devices/video/315_5313.cpp index 77bd8a9094a..4360a4e78a1 100644 --- a/src/devices/video/315_5313.cpp +++ b/src/devices/video/315_5313.cpp @@ -2108,7 +2108,7 @@ void sega315_5313_device::render_videobuffer_to_screenbuffer(int scanline) if (scanline >= m_render_bitmap->height()) // safety, shouldn't happen now we allocate a fixed amount tho return; - lineptr = &m_render_bitmap->pix32(scanline); + lineptr = &m_render_bitmap->pix(scanline); } else lineptr = m_render_line.get(); diff --git a/src/devices/video/cdp1861.cpp b/src/devices/video/cdp1861.cpp index 6a79087990d..03bcd3e0e90 100644 --- a/src/devices/video/cdp1861.cpp +++ b/src/devices/video/cdp1861.cpp @@ -248,12 +248,11 @@ void cdp1861_device::dma_w(uint8_t data) { int sx = screen().hpos() + 4; int y = screen().vpos(); - int x; - for (x = 0; x < 8; x++) + for (int x = 0; x < 8; x++) { pen_t color = BIT(data, 7) ? rgb_t::white() : rgb_t::black(); - m_bitmap.pix32(y, sx + x) = color; + m_bitmap.pix(y, sx + x) = color; data <<= 1; } } diff --git a/src/devices/video/cdp1862.cpp b/src/devices/video/cdp1862.cpp index 977615955fe..66fa8d9e684 100644 --- a/src/devices/video/cdp1862.cpp +++ b/src/devices/video/cdp1862.cpp @@ -131,7 +131,6 @@ void cdp1862_device::dma_w(uint8_t data) int rd = 1, bd = 1, gd = 1; int sx = screen().hpos() + 4; int y = screen().vpos(); - int x; if (!m_con) { @@ -140,7 +139,7 @@ void cdp1862_device::dma_w(uint8_t data) gd = m_read_gd(); } - for (x = 0; x < 8; x++) + for (int x = 0; x < 8; x++) { int color = CDP1862_BACKGROUND_COLOR_SEQUENCE[m_bgcolor] + 8; @@ -149,7 +148,7 @@ void cdp1862_device::dma_w(uint8_t data) color = (gd << 2) | (bd << 1) | rd; } - m_bitmap.pix32(y, sx + x) = m_palette[color]; + m_bitmap.pix(y, sx + x) = m_palette[color]; data <<= 1; } diff --git a/src/devices/video/cesblit.cpp b/src/devices/video/cesblit.cpp index 4cea7aef4f5..7e0e6a2085b 100644 --- a/src/devices/video/cesblit.cpp +++ b/src/devices/video/cesblit.cpp @@ -213,8 +213,6 @@ void cesblit_device::do_blit() // Draw bitmap_ind16 &bitmap = m_bitmap[layer][buffer]; - int x,y; - uint16_t pen; switch (mode & 0x20) { @@ -227,17 +225,17 @@ void cesblit_device::do_blit() uint8_t dst_pen = (m_color >> 8) & 0xff; uint8_t src_pen = (m_color >> 0) & 0xff; - for (y = y0; y != y1; y += dy) + for (int y = y0; y != y1; y += dy) { - for (x = x0; x != x1; x += dx) + for (int x = x0; x != x1; x += dx) { - pen = m_space->read_byte(addr); + uint16_t pen = m_space->read_byte(addr); if (pen == src_pen) pen = dst_pen; if (pen != 0xff) - bitmap.pix16((sy + y) & 0x1ff, (sx + x) & 0x1ff) = pen + color; + bitmap.pix((sy + y) & 0x1ff, (sx + x) & 0x1ff) = pen + color; ++addr; } @@ -247,14 +245,14 @@ void cesblit_device::do_blit() { // copy from ROM as is - for (y = y0; y != y1; y += dy) + for (int y = y0; y != y1; y += dy) { - for (x = x0; x != x1; x += dx) + for (int x = x0; x != x1; x += dx) { - pen = m_space->read_byte(addr); + uint16_t pen = m_space->read_byte(addr); if (pen != 0xff) - bitmap.pix16((sy + y) & 0x1ff, (sx + x) & 0x1ff) = pen + color; + bitmap.pix((sy + y) & 0x1ff, (sx + x) & 0x1ff) = pen + color; ++addr; } @@ -263,16 +261,18 @@ void cesblit_device::do_blit() break; case 0x20: // solid fill - pen = ((m_addr_hi >> 8) & 0xff) + color; + { + uint16_t pen = ((m_addr_hi >> 8) & 0xff) + color; - if ((pen & 0xff) == 0xff) - pen = 0xff; + if ((pen & 0xff) == 0xff) + pen = 0xff; - for (y = y0; y != y1; y += dy) - { - for (x = x0; x != x1; x += dx) + for (int y = y0; y != y1; y += dy) { - bitmap.pix16((sy + y) & 0x1ff, (sx + x) & 0x1ff) = pen; + for (int x = x0; x != x1; x += dx) + { + bitmap.pix((sy + y) & 0x1ff, (sx + x) & 0x1ff) = pen; + } } } break; diff --git a/src/devices/video/clgd542x.cpp b/src/devices/video/clgd542x.cpp index ace2e7a4820..eff9f5473c8 100644 --- a/src/devices/video/clgd542x.cpp +++ b/src/devices/video/clgd542x.cpp @@ -134,7 +134,6 @@ void cirrus_gd5428_device::device_reset() uint32_t cirrus_gd5428_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - int x,y,bit; uint32_t ptr = (vga.svga_intf.vram_size - 0x4000); // cursor patterns are stored in the last 16kB of VRAM svga_device::screen_update(screen, bitmap, cliprect); @@ -145,11 +144,11 @@ uint32_t cirrus_gd5428_device::screen_update(screen_device &screen, bitmap_rgb32 if(m_cursor_attr & 0x04) // 64x64 { ptr += ((m_cursor_addr & 0x3c) * 256); - for(y=0;y<64;y++) + for(int y=0;y<64;y++) { - for(x=0;x<64;x+=8) + for(int x=0;x<64;x+=8) { - for(bit=0;bit<8;bit++) + for(int bit=0;bit<8;bit++) { uint8_t pixel1 = vga.memory[ptr % vga.svga_intf.vram_size] >> (7-bit); uint8_t pixel2 = vga.memory[(ptr+512) % vga.svga_intf.vram_size] >> (7-bit); @@ -159,13 +158,13 @@ uint32_t cirrus_gd5428_device::screen_update(screen_device &screen, bitmap_rgb32 case 0: // transparent - do nothing break; case 1: // background - bitmap.pix32(m_cursor_y+y,m_cursor_x+x+bit) = (m_ext_palette[0].red << 16) | (m_ext_palette[0].green << 8) | (m_ext_palette[0].blue); + bitmap.pix(m_cursor_y+y,m_cursor_x+x+bit) = (m_ext_palette[0].red << 16) | (m_ext_palette[0].green << 8) | (m_ext_palette[0].blue); break; case 2: // XOR - bitmap.pix32(m_cursor_y+y,m_cursor_x+x+bit) = ~bitmap.pix32(m_cursor_y+y,m_cursor_x+x+bit); + bitmap.pix(m_cursor_y+y,m_cursor_x+x+bit) = ~bitmap.pix(m_cursor_y+y,m_cursor_x+x+bit); break; case 3: // foreground - bitmap.pix32(m_cursor_y+y,m_cursor_x+x+bit) = (m_ext_palette[15].red << 16) | (m_ext_palette[15].green << 8) | (m_ext_palette[15].blue); + bitmap.pix(m_cursor_y+y,m_cursor_x+x+bit) = (m_ext_palette[15].red << 16) | (m_ext_palette[15].green << 8) | (m_ext_palette[15].blue); break; } } @@ -175,11 +174,11 @@ uint32_t cirrus_gd5428_device::screen_update(screen_device &screen, bitmap_rgb32 else { ptr += ((m_cursor_addr & 0x3f) * 256); - for(y=0;y<32;y++) + for(int y=0;y<32;y++) { - for(x=0;x<32;x+=8) + for(int x=0;x<32;x+=8) { - for(bit=0;bit<8;bit++) + for(int bit=0;bit<8;bit++) { uint8_t pixel1 = vga.memory[ptr % vga.svga_intf.vram_size] >> (7-bit); uint8_t pixel2 = vga.memory[(ptr+128) % vga.svga_intf.vram_size] >> (7-bit); @@ -189,13 +188,13 @@ uint32_t cirrus_gd5428_device::screen_update(screen_device &screen, bitmap_rgb32 case 0: // transparent - do nothing break; case 1: // background - bitmap.pix32(m_cursor_y+y,m_cursor_x+x+bit) = (m_ext_palette[0].red << 18) | (m_ext_palette[0].green << 10) | (m_ext_palette[0].blue << 2); + bitmap.pix(m_cursor_y+y,m_cursor_x+x+bit) = (m_ext_palette[0].red << 18) | (m_ext_palette[0].green << 10) | (m_ext_palette[0].blue << 2); break; case 2: // XOR - bitmap.pix32(m_cursor_y+y,m_cursor_x+x+bit) = ~bitmap.pix32(m_cursor_y+y,m_cursor_x+x+bit); + bitmap.pix(m_cursor_y+y,m_cursor_x+x+bit) = ~bitmap.pix(m_cursor_y+y,m_cursor_x+x+bit); break; case 3: // foreground - bitmap.pix32(m_cursor_y+y,m_cursor_x+x+bit) = (m_ext_palette[15].red << 18) | (m_ext_palette[15].green << 10) | (m_ext_palette[15].blue << 2); + bitmap.pix(m_cursor_y+y,m_cursor_x+x+bit) = (m_ext_palette[15].red << 18) | (m_ext_palette[15].green << 10) | (m_ext_palette[15].blue << 2); break; } } diff --git a/src/devices/video/ef9340_1.cpp b/src/devices/video/ef9340_1.cpp index 9cc05ab747b..f58106fb5c4 100644 --- a/src/devices/video/ef9340_1.cpp +++ b/src/devices/video/ef9340_1.cpp @@ -16,7 +16,6 @@ This is implemented with a callback. The datasheet explains how to hook up TODO: - busy state (right now it is immediate) - internal display timing (on g7400, most of it is done externally) -- read slice from internal ROM - window boxing - Y zoom @@ -35,7 +34,7 @@ TODO: DEFINE_DEVICE_TYPE(EF9340_1, ef9340_1_device, "ef9340_1", "Thomson EF9340+EF9341") -ef9340_1_device::ef9340_1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +ef9340_1_device::ef9340_1_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, EF9340_1, tag, owner, clock) , device_video_interface(mconfig, *this) , m_charset(*this, "ef9340_1") @@ -46,7 +45,7 @@ ef9340_1_device::ef9340_1_device(const machine_config &mconfig, const char *tag, ROM_START( ef9340_1 ) - ROM_REGION( 0xA00, "ef9340_1", 0 ) + ROM_REGION( 0xa00, "ef9340_1", 0 ) ROM_LOAD( "charset_ef9340_1.rom", 0x0000, 0x0a00, BAD_DUMP CRC(8de85988) SHA1(f8e3892234da6626eb4302e171179ada5a51fca8) ) // taken from datasheet ROM_END @@ -66,10 +65,10 @@ void ef9340_1_device::device_start() screen().register_screen_bitmap(m_tmp_bitmap); m_line_timer = timer_alloc(TIMER_LINE); - m_line_timer->adjust( screen().time_until_pos(0, 0), 0, screen().scan_period() ); + m_line_timer->adjust(screen().time_until_pos(0, 0), 0, screen().scan_period()); m_blink_timer = timer_alloc(TIMER_BLINK); - m_blink_timer->adjust( screen().time_until_pos(0, 0), 0, screen().frame_period() ); + m_blink_timer->adjust(screen().time_until_pos(0, 0), 0, screen().frame_period()); // zerofill m_ef9341.TA = 0; @@ -109,7 +108,7 @@ void ef9340_1_device::device_start() void ef9340_1_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) { - switch ( id ) + switch (id) { case TIMER_LINE: ef9340_scanline(screen().vpos()); @@ -129,27 +128,27 @@ void ef9340_1_device::device_timer(emu_timer &timer, device_timer_id id, int par } -uint16_t ef9340_1_device::ef9340_get_c_addr(uint8_t x, uint8_t y) +u16 ef9340_1_device::ef9340_get_c_addr(u8 x, u8 y) { - if ( ( y & 0x18 ) == 0x18 ) + if ((y & 0x18) == 0x18) { - return 0x318 | ( ( x & 0x38 ) << 2 ) | ( x & 0x07 ); + return 0x318 | ((x & 0x38) << 2) | (x & 0x07); } - if ( x & 0x20 ) + if (x & 0x20) { - return 0x300 | ( ( y & 0x07 ) << 5 ) | ( y & 0x18 ) | ( x & 0x07 ); + return 0x300 | ((y & 0x07) << 5) | (y & 0x18) | (x & 0x07); } - return ( y & 0x1f ) << 5 | ( x & 0x1f ); + return (y & 0x1f) << 5 | (x & 0x1f); } void ef9340_1_device::ef9340_inc_c() { m_ef9340.X++; - if ( m_ef9340.X == 40 || m_ef9340.X == 48 || m_ef9340.X == 56 || m_ef9340.X == 64 ) + if (m_ef9340.X == 40 || m_ef9340.X == 48 || m_ef9340.X == 56 || m_ef9340.X == 64) { - m_ef9340.Y = ( m_ef9340.Y + 1 ) & 0x1f; - if ( m_ef9340.Y == 24 ) + m_ef9340.Y = (m_ef9340.Y + 1) & 0x1f; + if (m_ef9340.Y == 24) { m_ef9340.Y = 0; } @@ -158,27 +157,27 @@ void ef9340_1_device::ef9340_inc_c() } -void ef9340_1_device::ef9341_write( uint8_t command, uint8_t b, uint8_t data ) +void ef9340_1_device::ef9341_write(u8 command, u8 b, u8 data) { - LOG("ef9341 %s write, t%s, data %02X\n", command ? "command" : "data", b ? "B" : "A", data ); + LOG("ef9341 %s write, t%s, data %02X\n", command ? "command" : "data", b ? "B" : "A", data); - if ( command ) + if (command) { - if ( b ) + if (b) { m_ef9341.TB = data; m_ef9341.busy = true; - switch( m_ef9341.TB & 0xE0 ) + switch (m_ef9341.TB & 0xe0) { case 0x00: /* Begin row */ m_ef9340.X = 0; - m_ef9340.Y = m_ef9341.TA & 0x1F; + m_ef9340.Y = m_ef9341.TA & 0x1f; break; case 0x20: /* Load Y */ - m_ef9340.Y = m_ef9341.TA & 0x1F; + m_ef9340.Y = m_ef9341.TA & 0x1f; break; case 0x40: /* Load X */ - m_ef9340.X = m_ef9341.TA & 0x3F; + m_ef9340.X = m_ef9341.TA & 0x3f; break; case 0x60: /* INC C */ ef9340_inc_c(); @@ -186,13 +185,13 @@ void ef9340_1_device::ef9341_write( uint8_t command, uint8_t b, uint8_t data ) case 0x80: /* Load M */ m_ef9340.M = m_ef9341.TA; break; - case 0xA0: /* Load R */ + case 0xa0: /* Load R */ m_ef9340.R = m_ef9341.TA; break; - case 0xC0: /* Load Y0 */ - m_ef9340.Y0 = m_ef9341.TA & 0x3F; + case 0xc0: /* Load Y0 */ + m_ef9340.Y0 = m_ef9341.TA & 0x3f; break; - case 0xE0: /* Not interpreted */ + case 0xe0: /* Not interpreted */ break; } m_ef9341.busy = false; @@ -204,13 +203,13 @@ void ef9340_1_device::ef9341_write( uint8_t command, uint8_t b, uint8_t data ) } else { - if ( b ) + if (b) { - uint16_t addr = ef9340_get_c_addr( m_ef9340.X, m_ef9340.Y ) & 0x3ff; + u16 addr = ef9340_get_c_addr(m_ef9340.X, m_ef9340.Y) & 0x3ff; m_ef9341.TB = data; m_ef9341.busy = true; - switch ( m_ef9340.M & 0xE0 ) + switch (m_ef9340.M & 0xe0) { case 0x00: /* Write */ m_ram_a[addr] = m_ef9341.TA; @@ -225,15 +224,15 @@ void ef9340_1_device::ef9341_write( uint8_t command, uint8_t b, uint8_t data ) case 0x80: /* Write slice */ { - uint8_t a = m_ram_a[addr]; - uint8_t b = m_ram_b[addr]; - uint8_t slice = m_ef9340.M & 0x0f; + u8 a = m_ram_a[addr]; + u8 b = m_ram_b[addr]; + u8 slice = m_ef9340.M & 0x0f; if (b >= 0xa0) m_write_exram(a << 12 | b << 4 | slice, m_ef9341.TA); // Increment slice number - m_ef9340.M = ( m_ef9340.M & 0xf0) | ( ( slice + 1 ) % 10 ); + m_ef9340.M = (m_ef9340.M & 0xf0) | ((slice + 1) % 10); } break; @@ -250,15 +249,15 @@ void ef9340_1_device::ef9341_write( uint8_t command, uint8_t b, uint8_t data ) } -uint8_t ef9340_1_device::ef9341_read( uint8_t command, uint8_t b ) +u8 ef9340_1_device::ef9341_read(u8 command, u8 b) { - uint8_t data; + u8 data; - LOG("ef9341 %s read, t%s\n", command ? "command" : "data", b ? "B" : "A" ); + LOG("ef9341 %s read, t%s\n", command ? "command" : "data", b ? "B" : "A"); - if ( command ) + if (command) { - if ( b ) + if (b) { data = 0; } @@ -269,13 +268,13 @@ uint8_t ef9340_1_device::ef9341_read( uint8_t command, uint8_t b ) } else { - if ( b ) + if (b) { - uint16_t addr = ef9340_get_c_addr( m_ef9340.X, m_ef9340.Y ) & 0x3ff; + u16 addr = ef9340_get_c_addr(m_ef9340.X, m_ef9340.Y) & 0x3ff; data = m_ef9341.TB; m_ef9341.busy = true; - switch ( m_ef9340.M & 0xE0 ) + switch (m_ef9340.M & 0xe0) { case 0x20: /* Read */ m_ef9341.TA = m_ram_a[addr]; @@ -288,22 +287,22 @@ uint8_t ef9340_1_device::ef9341_read( uint8_t command, uint8_t b ) m_ef9341.TB = m_ram_b[addr]; break; - case 0xA0: /* Read slice */ + case 0xa0: /* Read slice */ { - uint8_t a = m_ram_a[addr]; - uint8_t b = m_ram_b[addr]; - uint8_t slice = m_ef9340.M & 0x0f; + u8 a = m_ram_a[addr]; + u8 b = m_ram_b[addr]; + u8 slice = m_ef9340.M & 0x0f; m_ef9341.TA = 0xff; m_ef9341.TB = 0xff; if (b >= 0xa0) m_ef9341.TA = m_read_exram(a << 12 | b << 4 | slice); - else - logerror("ef9341 read slice from internal\n"); + else if (b < 0x80 && slice < 10) + m_ef9341.TA = m_charset[(((a & 0x80) | (b & 0x7f)) * 10) + slice]; // Increment slice number - m_ef9340.M = ( m_ef9340.M & 0xf0) | ( ( slice + 1 ) % 10 ); + m_ef9340.M = (m_ef9340.M & 0xf0) | ((slice + 1) % 10); } break; @@ -338,14 +337,14 @@ void ef9340_1_device::ef9340_scanline(int vpos) if (m_ef9340.R & 0x01 && vpos < max_vpos) { int y_row = 0; - uint16_t char_data = 0x00; - uint8_t fg = 0; - uint8_t bg = 0; + u16 char_data = 0x00; + u8 fg = 0; + u8 bg = 0; bool underline = false; bool blank = false; bool w_parity = false; - if ( vpos < 10 ) + if (vpos < 10) { // Service row if (m_ef9340.R & 0x08) @@ -357,7 +356,7 @@ void ef9340_1_device::ef9340_scanline(int vpos) { // Service row is disabled for (int i = 0; i < 40 * 8; i++) - m_tmp_bitmap.pix16(m_offset_y + vpos, m_offset_x + i) = 8; + m_tmp_bitmap.pix(m_offset_y + vpos, m_offset_x + i) = 8; return; } } @@ -370,9 +369,9 @@ void ef9340_1_device::ef9340_scanline(int vpos) for (int x = 0; x < 40; x++) { int s = slice; - uint16_t addr = ef9340_get_c_addr(x, y_row); - uint8_t a = m_ram_a[addr]; - uint8_t b = m_ram_b[addr]; + u16 addr = ef9340_get_c_addr(x, y_row); + u8 a = m_ram_a[addr]; + u8 b = m_ram_b[addr]; bool blink = m_ef9340.R & 0x80 && m_ef9340.blink; bool cursor = m_ef9340.R & 0x10 && x == m_ef9340.X && y_row == m_ef9340.Y; bool invert = cursor && !blink; @@ -465,8 +464,8 @@ void ef9340_1_device::ef9340_scanline(int vpos) for (int i = 0; i < 8; i++) { - uint16_t d = blank ? 0 : (char_data & 1) ? fg : bg; - m_tmp_bitmap.pix16(m_offset_y + vpos, m_offset_x + x*8 + i) = d | 8; + u16 d = blank ? 0 : (char_data & 1) ? fg : bg; + m_tmp_bitmap.pix(m_offset_y + vpos, m_offset_x + x*8 + i) = d | 8; char_data >>= 1; } @@ -480,7 +479,7 @@ void ef9340_1_device::ef9340_scanline(int vpos) else { for (int i = 0; i < 40 * 8; i++) - m_tmp_bitmap.pix16(m_offset_y + vpos, m_offset_x + i) = 0; + m_tmp_bitmap.pix(m_offset_y + vpos, m_offset_x + i) = 0; } // determine next h parity @@ -494,12 +493,12 @@ void ef9340_1_device::ef9340_scanline(int vpos) } -uint32_t ef9340_1_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +u32 ef9340_1_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { // note: palette d3 is transparency (datasheet calls it "I"), this handler masks it off for (int y = cliprect.min_y; y <= cliprect.max_y; y++) for (int x = cliprect.min_x; x <= cliprect.max_x; x++) - bitmap.pix16(y, x) = m_tmp_bitmap.pix16(y, x) & 7; + bitmap.pix(y, x) = m_tmp_bitmap.pix(y, x) & 7; return 0; } diff --git a/src/devices/video/ef9340_1.h b/src/devices/video/ef9340_1.h index 61d1eb6d584..2d9a6671d27 100644 --- a/src/devices/video/ef9340_1.h +++ b/src/devices/video/ef9340_1.h @@ -18,7 +18,7 @@ class ef9340_1_device : public device_t, public: // construction/destruction template <typename T> - ef9340_1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&screen_tag) + ef9340_1_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock, T &&screen_tag) : ef9340_1_device(mconfig, tag, owner, clock) { set_screen(std::forward<T>(screen_tag)); @@ -29,13 +29,13 @@ public: auto write_exram() { return m_write_exram.bind(); } // ADR0-ADR3 in a0-a3, B in a4-a11, A in a12-a19 auto read_exram() { return m_read_exram.bind(); } // " - ef9340_1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + ef9340_1_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); inline bitmap_ind16 *get_bitmap() { return &m_tmp_bitmap; } - uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - void ef9341_write( uint8_t command, uint8_t b, uint8_t data ); - uint8_t ef9341_read( uint8_t command, uint8_t b ); + void ef9341_write(u8 command, u8 b, u8 data); + u8 ef9341_read(u8 command, u8 b); protected: // device-level overrides @@ -43,7 +43,7 @@ protected: virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; virtual const tiny_rom_entry *device_rom_region() const override; - inline uint16_t ef9340_get_c_addr(uint8_t x, uint8_t y); + inline u16 ef9340_get_c_addr(u8 x, u8 y); inline void ef9340_inc_c(); void ef9340_scanline(int vpos); @@ -55,7 +55,7 @@ protected: emu_timer *m_line_timer; emu_timer *m_blink_timer; - required_region_ptr<uint8_t> m_charset; + required_region_ptr<u8> m_charset; bitmap_ind16 m_tmp_bitmap; @@ -64,25 +64,25 @@ protected: struct { - uint8_t TA; - uint8_t TB; + u8 TA; + u8 TB; bool busy; } m_ef9341; struct { - uint8_t X; - uint8_t Y; - uint8_t Y0; - uint8_t R; - uint8_t M; + u8 X; + u8 Y; + u8 Y0; + u8 R; + u8 M; bool blink; int blink_prescaler; bool h_parity; } m_ef9340; - uint8_t m_ram_a[0x400]; - uint8_t m_ram_b[0x400]; + u8 m_ram_a[0x400]; + u8 m_ram_b[0x400]; devcb_write8 m_write_exram; devcb_read8 m_read_exram; diff --git a/src/devices/video/ef9345.cpp b/src/devices/video/ef9345.cpp index 74aa3334c1c..4b8907d0da7 100644 --- a/src/devices/video/ef9345.cpp +++ b/src/devices/video/ef9345.cpp @@ -225,7 +225,7 @@ void ef9345_device::draw_char_40(uint8_t *c, uint16_t x, uint16_t y) for(int i = 0; i < scan_ysize; i++) for(int j = 0; j < scan_xsize; j++) - m_screen_out.pix32(y * 10 + i, x * 8 + j) = palette[c[8 * i + j] & 0x07]; + m_screen_out.pix(y * 10 + i, x * 8 + j) = palette[c[8 * i + j] & 0x07]; } // draw a char in 80 char line mode @@ -237,7 +237,7 @@ void ef9345_device::draw_char_80(uint8_t *c, uint16_t x, uint16_t y) for(int i = 0; i < scan_ysize; i++) for(int j = 0; j < scan_xsize; j++) - m_screen_out.pix32(y * 10 + i, x * 6 + j) = palette[c[6 * i + j] & 0x07]; + m_screen_out.pix(y * 10 + i, x * 6 + j) = palette[c[6 * i + j] & 0x07]; } diff --git a/src/devices/video/ef9364.cpp b/src/devices/video/ef9364.cpp index 858b7309ca6..cef0a33664e 100644 --- a/src/devices/video/ef9364.cpp +++ b/src/devices/video/ef9364.cpp @@ -178,30 +178,27 @@ void ef9364_device::draw_border(uint16_t line) uint32_t ef9364_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - int x,y,r; - unsigned char c; - - for( r = 0 ; r < NB_OF_ROWS ; r++ ) + for( int r = 0 ; r < NB_OF_ROWS ; r++ ) { - for( y = 0 ; y < 8 ; y++ ) + for( int y = 0 ; y < 8 ; y++ ) { - for( x = 0 ; x < NB_OF_COLUMNS * 8 ; x++ ) + for( int x = 0 ; x < NB_OF_COLUMNS * 8 ; x++ ) { if( ( ( x >> 3 ) != x_curs_pos ) || ( r != y_curs_pos ) || !cursor_state) { - c = m_textram->read_byte( ( r * NB_OF_COLUMNS ) + ( x>>3 ) ); + unsigned char c = m_textram->read_byte( ( r * NB_OF_COLUMNS ) + ( x>>3 ) ); if( m_charset[((c&0x7F)<<3) + y] & (0x80>>(x&7)) ) - m_screen_out.pix32((r*12)+y, x) = palette[1]; + m_screen_out.pix((r*12)+y, x) = palette[1]; else - m_screen_out.pix32((r*12)+y, x) = palette[0]; + m_screen_out.pix((r*12)+y, x) = palette[0]; } else { if(y != 7) - m_screen_out.pix32((r*12)+y, x) = palette[0]; + m_screen_out.pix((r*12)+y, x) = palette[0]; else - m_screen_out.pix32((r*12)+y, x) = palette[1]; + m_screen_out.pix((r*12)+y, x) = palette[1]; } } } diff --git a/src/devices/video/ef9365.cpp b/src/devices/video/ef9365.cpp index a24783298d1..7697e6885e6 100644 --- a/src/devices/video/ef9365.cpp +++ b/src/devices/video/ef9365.cpp @@ -1156,18 +1156,15 @@ void ef9365_device::ef9365_exec(uint8_t cmd) uint32_t ef9365_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - int i,j,ptr,p; - unsigned char color_index; - - for(j=0;j<bitplane_yres;j++) + for(int j=0;j<bitplane_yres;j++) { - for(i=0;i<bitplane_xres;i++) + for(int i=0;i<bitplane_xres;i++) { - color_index = 0x00; + unsigned char color_index = 0x00; - ptr = ( bitplane_xres * j ) + i; + int ptr = ( bitplane_xres * j ) + i; - for( p = 0; p < nb_of_bitplanes; p++) + for(int p = 0; p < nb_of_bitplanes; p++) { if( m_videoram->read_byte( (BITPLANE_MAX_SIZE*p) + (ptr>>3)) & (0x80>>(ptr&7))) { @@ -1175,7 +1172,7 @@ uint32_t ef9365_device::screen_update(screen_device &screen, bitmap_rgb32 &bitma } } - m_screen_out.pix32(j, i) = m_palette->pen( color_index ); + m_screen_out.pix(j, i) = m_palette->pen( color_index ); } } diff --git a/src/devices/video/fixfreq.cpp b/src/devices/video/fixfreq.cpp index 3810dc76a76..5de27dc0b08 100644 --- a/src/devices/video/fixfreq.cpp +++ b/src/devices/video/fixfreq.cpp @@ -14,10 +14,11 @@ ***************************************************************************/ #include "emu.h" -#include "ui/uimain.h" -#include "rendutil.h" #include "fixfreq.h" +#include "render.h" +#include "ui/uimain.h" + // for quick and dirty debugging #define VERBOSE 0 #define LOG_OUTPUT_STREAM std::cerr diff --git a/src/devices/video/gb_lcd.cpp b/src/devices/video/gb_lcd.cpp index 4f02d39bfab..06cceeca7b0 100644 --- a/src/devices/video/gb_lcd.cpp +++ b/src/devices/video/gb_lcd.cpp @@ -671,7 +671,7 @@ void cgb_ppu_device::device_reset() inline void dmg_ppu_device::plot_pixel(int x, int y, uint16_t color) { - m_bitmap.pix16(y, x) = color; + m_bitmap.pix(y, x) = color; } diff --git a/src/devices/video/gba_lcd.cpp b/src/devices/video/gba_lcd.cpp index ab71569a9fe..e3e46b5ceae 100644 --- a/src/devices/video/gba_lcd.cpp +++ b/src/devices/video/gba_lcd.cpp @@ -267,7 +267,7 @@ inline void gba_lcd_device::update_mask(uint8_t* mask, int y) void gba_lcd_device::draw_scanline(int y) { - uint16_t *scanline = &m_bitmap.pix16(y); + uint16_t *const scanline = &m_bitmap.pix(y); if (is_set(dispcnt::forced_blank)) { diff --git a/src/devices/video/gf4500.cpp b/src/devices/video/gf4500.cpp index e8c35e7ff25..b703e7cb8c3 100644 --- a/src/devices/video/gf4500.cpp +++ b/src/devices/video/gf4500.cpp @@ -89,12 +89,11 @@ static rgb_t gf4500_get_color_16( uint16_t data ) uint32_t gf4500_device::screen_update(screen_device &device, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - uint16_t *vram = (uint16_t *)(m_data.get() + GF4500_FRAMEBUF_OFFSET / 4); - int x, y; - for (y = 0; y < 240; y++) + uint16_t const *vram = (uint16_t *)(m_data.get() + GF4500_FRAMEBUF_OFFSET / 4); + for (int y = 0; y < 240; y++) { - uint32_t *scanline = &bitmap.pix32(y); - for (x = 0; x < 320; x++) + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < 320; x++) { *scanline++ = gf4500_get_color_16(*vram++); } diff --git a/src/devices/video/hd44102.cpp b/src/devices/video/hd44102.cpp index 3b05f1e5e69..1bb8cbf5a4d 100644 --- a/src/devices/video/hd44102.cpp +++ b/src/devices/video/hd44102.cpp @@ -268,7 +268,7 @@ uint32_t hd44102_device::screen_update(screen_device &screen, bitmap_ind16 &bitm { int color = (m_status & STATUS_DISPLAY_OFF) ? 0 : BIT(data, z % 8); - bitmap.pix16(sy, sx) = color; + bitmap.pix(sy, sx) = color; } z++; diff --git a/src/devices/video/hd44352.cpp b/src/devices/video/hd44352.cpp index 7fa4b53f1d0..1ca378723f3 100644 --- a/src/devices/video/hd44352.cpp +++ b/src/devices/video/hd44352.cpp @@ -152,7 +152,7 @@ uint32_t hd44352_device::screen_update(screen_device &screen, bitmap_ind16 &bitm uint8_t d = compute_newval((m_cursor_status>>5) & 0x07, m_video_ram[a][py*16*cw + px*cw + c + m_scroll * 48], m_cursor[c]); for (int b=0; b<8; b++) { - bitmap.pix16(py*8 + b, a*cw*16 + px*cw + c) = BIT(d, 7-b); + bitmap.pix(py*8 + b, a*cw*16 + px*cw + c) = BIT(d, 7-b); } } } @@ -163,7 +163,7 @@ uint32_t hd44352_device::screen_update(screen_device &screen, bitmap_ind16 &bitm uint8_t d = m_video_ram[a][py*16*cw + px*cw + c + m_scroll * 48]; for (int b=0; b<8; b++) { - bitmap.pix16(py*8 + b, a*cw*16 + px*cw + c) = BIT(d, 7-b); + bitmap.pix(py*8 + b, a*cw*16 + px*cw + c) = BIT(d, 7-b); } } } diff --git a/src/devices/video/hd44780.cpp b/src/devices/video/hd44780.cpp index 7abf8e0a979..8d6db247ba7 100644 --- a/src/devices/video/hd44780.cpp +++ b/src/devices/video/hd44780.cpp @@ -274,7 +274,7 @@ inline void hd44780_device::pixel_update(bitmap_ind16 &bitmap, u8 line, u8 pos, if (m_lines <= 2) { if (pos < m_chars) - bitmap.pix16(line * (line_height + 1) + y, pos * 6 + x) = state; + bitmap.pix(line * (line_height + 1) + y, pos * 6 + x) = state; } else if (m_lines <= 4) { @@ -287,7 +287,7 @@ inline void hd44780_device::pixel_update(bitmap_ind16 &bitmap, u8 line, u8 pos, } if (line < m_lines) - bitmap.pix16(line * (line_height + 1) + y, pos * 6 + x) = state; + bitmap.pix(line * (line_height + 1) + y, pos * 6 + x) = state; } } else diff --git a/src/devices/video/hd61830.cpp b/src/devices/video/hd61830.cpp index 26ee97cb22f..55bf2bbd588 100644 --- a/src/devices/video/hd61830.cpp +++ b/src/devices/video/hd61830.cpp @@ -360,9 +360,9 @@ uint16_t hd61830_device::draw_scanline(bitmap_ind16 &bitmap, const rectangle &cl if(y >= 0 && y < bitmap.height()) { if(((sx * m_hp) + x) >= 0 && ((sx * m_hp) + x) < bitmap.width()) - bitmap.pix16(y, (sx * m_hp) + x) = BIT(data1, x); + bitmap.pix(y, (sx * m_hp) + x) = BIT(data1, x); if(((sx * m_hp) + x + m_hp) >= 0 && ((sx * m_hp) + x + m_hp) < bitmap.width()) - bitmap.pix16(y, (sx * m_hp) + x + m_hp) = BIT(data2, x); + bitmap.pix(y, (sx * m_hp) + x + m_hp) = BIT(data2, x); } } } @@ -454,7 +454,7 @@ void hd61830_device::draw_char(bitmap_ind16 &bitmap, const rectangle &cliprect, } if (sy < screen().height() && sx < screen().width()) - bitmap.pix16(sy, sx) = pixel; + bitmap.pix(sy, sx) = pixel; } } } diff --git a/src/devices/video/hd63484.cpp b/src/devices/video/hd63484.cpp index e0b08389492..a740aaa93f9 100644 --- a/src/devices/video/hd63484.cpp +++ b/src/devices/video/hd63484.cpp @@ -2107,7 +2107,7 @@ void hd63484_device::draw_graphics_line(bitmap_ind16 &bitmap, const rectangle &c if (!m_display_cb.isnull()) m_display_cb(bitmap, cliprect, y, px, data & mask); else if (cliprect.contains(px, y)) - bitmap.pix16(y, px) = data & mask; + bitmap.pix(y, px) = data & mask; data >>= bpp; } diff --git a/src/devices/video/hd66421.cpp b/src/devices/video/hd66421.cpp index 22efe3689e8..6be96c81e1f 100644 --- a/src/devices/video/hd66421.cpp +++ b/src/devices/video/hd66421.cpp @@ -208,7 +208,7 @@ void hd66421_device::reg_dat_w(uint8_t data) void hd66421_device::plot_pixel(bitmap_ind16 &bitmap, int x, int y, uint32_t color) { - bitmap.pix16(y, x) = (uint16_t)color; + bitmap.pix(y, x) = (uint16_t)color; } uint32_t hd66421_device::update_screen(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) diff --git a/src/devices/video/hp1ll3.cpp b/src/devices/video/hp1ll3.cpp index 9a1952d8c25..006b8823122 100644 --- a/src/devices/video/hp1ll3.cpp +++ b/src/devices/video/hp1ll3.cpp @@ -810,14 +810,14 @@ uint32_t hp1ll3_device::screen_update(screen_device &screen, bitmap_ind16 &bitma { if (!m_enable_video) { - bitmap.fill(rgb_t::black()); + bitmap.fill(0); return 0; } for (int y = 0; y < m_vert_pix_total; y++) { int const offset = m_sad + y*m_conf[CONF_WPL]; - uint16_t *p = &m_bitmap.pix16(y); + uint16_t *p = &m_bitmap.pix(y); for (int x = offset; x < offset + m_horiz_pix_total / 16; x++) { diff --git a/src/devices/video/huc6260.cpp b/src/devices/video/huc6260.cpp index 1160f7edf13..08ca9abc5d9 100644 --- a/src/devices/video/huc6260.cpp +++ b/src/devices/video/huc6260.cpp @@ -69,7 +69,7 @@ void huc6260_device::device_timer(emu_timer &timer, device_timer_id id, int para int hpos = screen().hpos(); int h = m_last_h; int v = m_last_v; - uint16_t *bitmap_line = &m_bmp->pix16(v); + uint16_t *bitmap_line = &m_bmp->pix(v); while ( h != hpos || v != vpos ) { @@ -112,7 +112,7 @@ void huc6260_device::device_timer(emu_timer &timer, device_timer_id id, int para m_hsync_changed_cb( 1 ); m_pixel_clock = 0; v = ( v + 1 ) % m_height; - bitmap_line = &m_bmp->pix16(v); + bitmap_line = &m_bmp->pix(v); break; case HUC6260_HSYNC_START + 30: /* End/Start of VSync */ diff --git a/src/devices/video/huc6261.cpp b/src/devices/video/huc6261.cpp index 42568090447..4ff0080777a 100644 --- a/src/devices/video/huc6261.cpp +++ b/src/devices/video/huc6261.cpp @@ -100,7 +100,7 @@ void huc6261_device::device_timer(emu_timer &timer, device_timer_id id, int para int hpos = screen().hpos(); int h = m_last_h; int v = m_last_v; - uint32_t *bitmap_line = &m_bmp->pix32(v); + uint32_t *bitmap_line = &m_bmp->pix(v); while ( h != hpos || v != vpos ) { @@ -153,7 +153,7 @@ void huc6261_device::device_timer(emu_timer &timer, device_timer_id id, int para m_huc6270_b->hsync_changed( 1 ); m_pixel_clock = 0; v = ( v + 1 ) % m_height; - bitmap_line = &m_bmp->pix32(v); + bitmap_line = &m_bmp->pix(v); break; case HUC6261_HSYNC_START + 30: /* End/Start of VSync */ diff --git a/src/devices/video/i8244.cpp b/src/devices/video/i8244.cpp index 8288dd9e552..4272f3dfeac 100644 --- a/src/devices/video/i8244.cpp +++ b/src/devices/video/i8244.cpp @@ -24,13 +24,13 @@ DEFINE_DEVICE_TYPE(I8245, i8245_device, "i8245", "Intel 8245") // i8244_device - constructor //------------------------------------------------- -i8244_device::i8244_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +i8244_device::i8244_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : i8244_device(mconfig, I8244, tag, owner, clock) { } -i8244_device::i8244_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) +i8244_device::i8244_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, type, tag, owner, clock) , device_sound_interface(mconfig, *this) , device_video_interface(mconfig, *this) @@ -40,7 +40,7 @@ i8244_device::i8244_device(const machine_config &mconfig, device_type type, cons } -i8245_device::i8245_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +i8245_device::i8245_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : i8244_device(mconfig, I8245, tag, owner, clock) { } @@ -135,7 +135,7 @@ void i8244_device::device_start() memset(m_vdc.reg, 0, 0x100); save_pointer(NAME(m_vdc.reg), 0x100); - memset( m_collision_map, 0, sizeof( m_collision_map ) ); + memset(m_collision_map, 0, sizeof(m_collision_map)); save_item(NAME(m_collision_map)); save_item(NAME(m_x_beam_pos)); @@ -174,13 +174,13 @@ void i8244_device::i8244_palette(palette_device &palette) const { 0xff, 0xff, 0xff } // I R G B }; - palette.set_pen_colors( 0, i8244_colors ); + palette.set_pen_colors(0, i8244_colors); } void i8244_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) { - switch ( id ) + switch (id) { case TIMER_HBLANK_START: // hblank starts (updates sound shift register) @@ -199,25 +199,25 @@ void i8244_device::device_timer(emu_timer &timer, device_timer_id id, int param, } -offs_t i8244_device::fix_register_mirrors( offs_t offset ) +offs_t i8244_device::fix_register_mirrors(offs_t offset) { // quad x/y registers are mirrored for each quad - if ( ( offset & 0xC2 ) == 0x40 ) + if ((offset & 0xc2) == 0x40) { - offset &= ~0x0C; + offset &= ~0x0c; } // registers $A0-$AF are mirrored at $B0-$BF - if ( ( offset & 0xE0 ) == 0xA0 ) + if ((offset & 0xe0) == 0xa0) { offset &= ~0x10; } - return offset & 0xFF; + return offset & 0xff; } -bool i8244_device::invalid_register( offs_t offset, bool rw ) +bool i8244_device::invalid_register(offs_t offset, bool rw) { // object x/y/attr registers are not accessible when display is enabled // (sprite shape registers still are) @@ -280,9 +280,9 @@ bool i8244_device::invalid_register( offs_t offset, bool rw ) } -uint8_t i8244_device::read(offs_t offset) +u8 i8244_device::read(offs_t offset) { - uint8_t data; + u8 data; offset = fix_register_mirrors(offset); @@ -337,7 +337,7 @@ uint8_t i8244_device::read(offs_t offset) } -void i8244_device::write(offs_t offset, uint8_t data) +void i8244_device::write(offs_t offset, u8 data) { offset = fix_register_mirrors(offset); @@ -470,7 +470,7 @@ void i8244_device::write_cx(int x, bool cx) } -uint32_t i8244_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +u32 i8244_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { /* Draw background color */ bitmap.fill(bitswap<3>(m_vdc.s.color,3,4,5), cliprect); @@ -478,28 +478,28 @@ uint32_t i8244_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap for (int scanline = cliprect.min_y; scanline <= cliprect.max_y; scanline++) { /* Clear collision map */ - memset( m_collision_map, 0, sizeof( m_collision_map ) ); + memset(m_collision_map, 0, sizeof(m_collision_map)); /* Display grid if enabled */ - if ( m_vdc.s.control & 0x08 ) + if (m_vdc.s.control & 0x08) { - uint16_t color = bitswap<4>(m_vdc.s.color,6,0,1,2); + u16 color = bitswap<4>(m_vdc.s.color,6,0,1,2); int x_grid_offset = 13; int y_grid_offset = 24; int width = 16; int height = 24; - int w = ( m_vdc.s.control & 0x80 ) ? width : 2; + int w = (m_vdc.s.control & 0x80) ? width : 2; /* Draw horizontal part of the grid */ - for ( int y = 0; y < 9; y++ ) + for (int y = 0; y < 9; y++) { - if ( y_grid_offset + y * height <= scanline && scanline < y_grid_offset + y * height + 3 ) + if (y_grid_offset + y * height <= scanline && scanline < y_grid_offset + y * height + 3) { - for ( int i = 0; i < 9; i++ ) + for (int i = 0; i < 9; i++) { - if ( BIT(m_vdc.s.hgrid[1][i] << 8 | m_vdc.s.hgrid[0][i], y) ) + if (BIT(m_vdc.s.hgrid[1][i] << 8 | m_vdc.s.hgrid[0][i], y)) { - for ( int k = 0; k < width + 2; k++ ) + for (int k = 0; k < width + 2; k++) { int x = (x_grid_offset + i * width + k) * 2; @@ -507,8 +507,8 @@ uint32_t i8244_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap { if (cliprect.contains(px, scanline)) { - m_collision_map[ px ] |= 0x20; - bitmap.pix16( scanline, px ) = color; + m_collision_map[px] |= 0x20; + bitmap.pix(scanline, px) = color; } } } @@ -518,15 +518,15 @@ uint32_t i8244_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap } /* Draw dots part of the grid */ - if ( m_vdc.s.control & 0x40 ) + if (m_vdc.s.control & 0x40) { - for ( int y = 0; y < 9; y++ ) + for (int y = 0; y < 9; y++) { - if ( y_grid_offset + y * height <= scanline && scanline < y_grid_offset + y * height + 3 ) + if (y_grid_offset + y * height <= scanline && scanline < y_grid_offset + y * height + 3) { - for ( int i = 0; i < 10; i++ ) + for (int i = 0; i < 10; i++) { - for ( int k = 0; k < 2; k++ ) + for (int k = 0; k < 2; k++) { int x = (x_grid_offset + i * width + k) * 2; @@ -534,8 +534,8 @@ uint32_t i8244_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap { if (cliprect.contains(px, scanline)) { - m_collision_map[ px ] |= 0x20; - bitmap.pix16( scanline, px ) = color; + m_collision_map[px] |= 0x20; + bitmap.pix(scanline, px) = color; } } } @@ -545,15 +545,15 @@ uint32_t i8244_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap } /* Draw vertical part of the grid */ - for( int j = 1, y = 0; y < 8; y++, j <<= 1 ) + for (int j = 1, y = 0; y < 8; y++, j <<= 1) { - if ( y_grid_offset + y * height <= scanline && scanline < y_grid_offset + ( y + 1 ) * height ) + if (y_grid_offset + y * height <= scanline && scanline < y_grid_offset + (y + 1) * height) { - for ( int i = 0; i < 10; i++ ) + for (int i = 0; i < 10; i++) { - if ( m_vdc.s.vgrid[i] & j ) + if (m_vdc.s.vgrid[i] & j) { - for ( int k = 0; k < w; k++ ) + for (int k = 0; k < w; k++) { int x = (x_grid_offset + i * width + k) * 2; @@ -561,8 +561,8 @@ uint32_t i8244_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap { if (cliprect.contains(px, scanline)) { - m_collision_map[ px ] |= 0x10; - bitmap.pix16( scanline, px ) = color; + m_collision_map[px] |= 0x10; + bitmap.pix(scanline, px) = color; } } } @@ -573,37 +573,37 @@ uint32_t i8244_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap } /* Display objects if enabled */ - if ( m_vdc.s.control & 0x20 && scanline <= 242 ) + if (m_vdc.s.control & 0x20 && scanline <= 242) { /* Quad objects */ - for ( int i = ARRAY_LENGTH( m_vdc.s.quad ) - 1; i >= 0; i-- ) + for (int i = ARRAY_LENGTH(m_vdc.s.quad) - 1; i >= 0; i--) { int y = m_vdc.s.quad[i].single[0].y; // Character height is always determined by the height of the 4th character - int height = 8 - ( ( ( y >> 1 ) + m_vdc.s.quad[i].single[3].ptr ) & 7 ); + int height = 8 - (((y >> 1) + m_vdc.s.quad[i].single[3].ptr) & 7); if (height == 1) height = 8; - if ( y <= scanline && scanline < y + height * 2 ) + if (y <= scanline && scanline < y + height * 2) { int x = (m_vdc.s.quad[i].single[0].x + 5) * 2; - for ( int j = 0; j < ARRAY_LENGTH( m_vdc.s.quad[0].single ); j++, x += 16 ) + for (int j = 0; j < ARRAY_LENGTH(m_vdc.s.quad[0].single); j++, x += 16) { - uint16_t color = 8 + ( ( m_vdc.s.quad[i].single[j].color >> 1 ) & 0x07 ); - int offset = ( m_vdc.s.quad[i].single[j].ptr | ( ( m_vdc.s.quad[i].single[j].color & 0x01 ) << 8 ) ) + ( y >> 1 ) + ( ( scanline - y ) >> 1 ); - uint8_t chr = m_charset[ offset & 0x1FF ]; + u16 color = 8 + ((m_vdc.s.quad[i].single[j].color >> 1) & 0x07); + int offset = (m_vdc.s.quad[i].single[j].ptr | ((m_vdc.s.quad[i].single[j].color & 0x01) << 8)) + (y >> 1) + ((scanline - y) >> 1); + u8 chr = m_charset[offset & 0x1ff]; - for ( uint8_t m = 0x80; m > 0; m >>= 1, x += 2 ) + for (u8 m = 0x80; m > 0; m >>= 1, x += 2) { - if ( chr & m ) + if (chr & m) { for (int px = x; px < x + 2; px++) { if (cliprect.contains(px, scanline)) { // Check collision with self - u8 colx = m_collision_map[ px ]; + u8 colx = m_collision_map[px]; if (colx & 0x80) { colx &= ~0x80; @@ -618,8 +618,8 @@ uint32_t i8244_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap if (m_vdc.s.collision & 0x80) m_collision_status |= colx; - m_collision_map[ px ] |= 0x80; - bitmap.pix16( scanline, px ) = color; + m_collision_map[px] |= 0x80; + bitmap.pix(scanline, px) = color; } } } @@ -629,29 +629,29 @@ uint32_t i8244_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap } /* Regular foreground objects */ - for ( int i = ARRAY_LENGTH( m_vdc.s.foreground ) - 1; i >= 0; i-- ) + for (int i = ARRAY_LENGTH(m_vdc.s.foreground) - 1; i >= 0; i--) { int y = m_vdc.s.foreground[i].y; - int height = 8 - ( ( ( y >> 1 ) + m_vdc.s.foreground[i].ptr ) & 7 ); + int height = 8 - (((y >> 1) + m_vdc.s.foreground[i].ptr) & 7); if (height == 1) height = 8; - if ( y <= scanline && scanline < y + height * 2 ) + if (y <= scanline && scanline < y + height * 2) { - uint16_t color = 8 + ( ( m_vdc.s.foreground[i].color >> 1 ) & 0x07 ); - int offset = ( m_vdc.s.foreground[i].ptr | ( ( m_vdc.s.foreground[i].color & 0x01 ) << 8 ) ) + ( y >> 1 ) + ( ( scanline - y ) >> 1 ); - uint8_t chr = m_charset[ offset & 0x1FF ]; + u16 color = 8 + ((m_vdc.s.foreground[i].color >> 1) & 0x07); + int offset = (m_vdc.s.foreground[i].ptr | ((m_vdc.s.foreground[i].color & 0x01) << 8)) + (y >> 1) + ((scanline - y) >> 1); + u8 chr = m_charset[offset & 0x1ff]; int x = (m_vdc.s.foreground[i].x + 5) * 2; - for ( uint8_t m = 0x80; m > 0; m >>= 1, x += 2 ) + for (u8 m = 0x80; m > 0; m >>= 1, x += 2) { - if ( chr & m ) + if (chr & m) { for (int px = x; px < x + 2; px++) { if (cliprect.contains(px, scanline)) { // Check collision with self - u8 colx = m_collision_map[ px ]; + u8 colx = m_collision_map[px]; if (colx & 0x80) { colx &= ~0x80; @@ -666,8 +666,8 @@ uint32_t i8244_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap if (m_vdc.s.collision & 0x80) m_collision_status |= colx; - m_collision_map[ px ] |= 0x80; - bitmap.pix16( scanline, px ) = color; + m_collision_map[px] |= 0x80; + bitmap.pix(scanline, px) = color; } } } @@ -676,30 +676,30 @@ uint32_t i8244_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap } /* Sprites */ - for ( int i = ARRAY_LENGTH( m_vdc.s.sprites ) - 1; i >= 0; i-- ) + for (int i = ARRAY_LENGTH(m_vdc.s.sprites) - 1; i >= 0; i--) { int y = m_vdc.s.sprites[i].y; int height = 8; bool zoom_enable = bool(m_vdc.s.sprites[i].color & 4); int zoom_px = zoom_enable ? 4 : 2; - if ( y <= scanline && scanline < y + height * zoom_px ) + if (y <= scanline && scanline < y + height * zoom_px) { - uint16_t color = 8 + ( ( m_vdc.s.sprites[i].color >> 3 ) & 0x07 ); - uint8_t chr = m_vdc.s.shape[i][ ( ( scanline - y ) / zoom_px ) ]; + u16 color = 8 + ((m_vdc.s.sprites[i].color >> 3) & 0x07); + u8 chr = m_vdc.s.shape[i][((scanline - y) / zoom_px)]; int x = (m_vdc.s.sprites[i].x + 5) * 2; int x_shift = 0; - switch ( m_vdc.s.sprites[i].color & 0x03 ) + switch (m_vdc.s.sprites[i].color & 0x03) { case 1: // Xg attribute set x_shift = 1; break; case 2: // S attribute set - x_shift = ( ( ( scanline - y ) / zoom_px ) & 0x01 ) ^ 0x01; + x_shift = (((scanline - y) / zoom_px) & 0x01) ^ 0x01; break; case 3: // Xg and S attributes set - x_shift = ( ( scanline - y ) / zoom_px ) & 0x01; + x_shift = ((scanline - y) / zoom_px) & 0x01; break; default: break; @@ -707,9 +707,9 @@ uint32_t i8244_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap x += x_shift * (zoom_px / 2); - for ( uint8_t m = 0x01; m > 0; m <<= 1, x += zoom_px ) + for (u8 m = 0x01; m > 0; m <<= 1, x += zoom_px) { - if ( chr & m ) + if (chr & m) { for (int px = x; px < x + zoom_px; px++) { @@ -718,15 +718,15 @@ uint32_t i8244_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap u8 mask = 1 << i; // Check if we collide with an already drawn source object - if (m_vdc.s.collision & m_collision_map[ px ]) + if (m_vdc.s.collision & m_collision_map[px]) m_collision_status |= mask; // Check if an already drawn object would collide with us if (m_vdc.s.collision & mask) - m_collision_status |= m_collision_map[ px ]; + m_collision_status |= m_collision_map[px]; - m_collision_map[ px ] |= mask; - bitmap.pix16( scanline, px ) = color; + m_collision_map[px] |= mask; + bitmap.pix(scanline, px) = color; } } } @@ -783,9 +783,9 @@ void i8244_device::sound_update() // loop sound signal |= feedback << 23; - m_vdc.s.shift3 = signal & 0xFF; - m_vdc.s.shift2 = ( signal >> 8 ) & 0xFF; - m_vdc.s.shift1 = ( signal >> 16 ) & 0xFF; + m_vdc.s.shift3 = signal & 0xff; + m_vdc.s.shift2 = (signal >> 8) & 0xff; + m_vdc.s.shift1 = (signal >> 16) & 0xff; // sound interrupt if (++m_sh_count == 24) diff --git a/src/devices/video/i8244.h b/src/devices/video/i8244.h index 3568f5a613d..565ed13826f 100644 --- a/src/devices/video/i8244.h +++ b/src/devices/video/i8244.h @@ -27,68 +27,68 @@ class i8244_device : public device_t { public: // construction/destruction - i8244_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + i8244_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); // configuration helpers auto irq_cb() { return m_irq_func.bind(); } i8244_device &set_screen_size(int width, int height, int cropx = 0, int cropy = 0); - uint8_t read(offs_t offset); - void write(offs_t offset, uint8_t data); + u8 read(offs_t offset); + void write(offs_t offset, u8 data); void write_cx(int x, bool cx); // CX pin on current scanline int vblank(); int hblank(); void i8244_palette(palette_device &palette) const; - uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); protected: union vdc_t { - uint8_t reg[0x100]; + u8 reg[0x100]; struct { // 0x00 struct { - uint8_t y,x,color,unused; + u8 y,x,color,unused; } sprites[4]; // 0x10 struct { - uint8_t y,x,ptr,color; + u8 y,x,ptr,color; } foreground[12]; // 0x40 struct { struct { - uint8_t y,x,ptr,color; + u8 y,x,ptr,color; } single[4]; } quad[4]; // 0x80 - uint8_t shape[4][8]; + u8 shape[4][8]; // 0xa0 - uint8_t control; - uint8_t status; - uint8_t collision; - uint8_t color; - uint8_t y; - uint8_t x; - uint8_t unused; - uint8_t shift1; - uint8_t shift2; - uint8_t shift3; - uint8_t sound; - uint8_t unused2[5+0x10]; + u8 control; + u8 status; + u8 collision; + u8 color; + u8 y; + u8 x; + u8 unused; + u8 shift1; + u8 shift2; + u8 shift3; + u8 sound; + u8 unused2[5+0x10]; // 0xc0 - uint8_t hgrid[2][0x10]; - uint8_t vgrid[0x10]; - uint8_t unused3[0x10]; + u8 hgrid[2][0x10]; + u8 vgrid[0x10]; + u8 unused3[0x10]; } s; }; - i8244_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + i8244_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); // device-level overrides virtual void device_config_complete() override; @@ -103,8 +103,8 @@ protected: int get_y_beam(); int get_x_beam(); - offs_t fix_register_mirrors( offs_t offset ); - bool invalid_register( offs_t offset, bool rw ); + offs_t fix_register_mirrors(offs_t offset); + bool invalid_register(offs_t offset, bool rw); /* timers */ static constexpr device_timer_id TIMER_VBLANK_START = 0; @@ -113,7 +113,7 @@ protected: // callbacks devcb_write_line m_irq_func; - required_region_ptr<uint8_t> m_charset; + required_region_ptr<u8> m_charset; emu_timer *m_hblank_timer; emu_timer *m_vblank_timer; @@ -135,12 +135,12 @@ protected: int m_bgate_start; vdc_t m_vdc; - uint8_t m_collision_map[0x200]; + u8 m_collision_map[0x200]; - uint8_t m_x_beam_pos = 0; - uint8_t m_y_beam_pos = 0; - uint8_t m_control_status = 0; - uint8_t m_collision_status = 0; + u8 m_x_beam_pos = 0; + u8 m_y_beam_pos = 0; + u8 m_control_status = 0; + u8 m_collision_status = 0; bool m_sh_written = false; bool m_sh_pending = false; @@ -155,7 +155,7 @@ class i8245_device : public i8244_device { public: // construction/destruction - i8245_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + i8245_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); protected: virtual void set_default_params() override; diff --git a/src/devices/video/imagetek_i4100.cpp b/src/devices/video/imagetek_i4100.cpp index 030314636c1..8c0eaff1011 100644 --- a/src/devices/video/imagetek_i4100.cpp +++ b/src/devices/video/imagetek_i4100.cpp @@ -59,7 +59,7 @@ 8 to 64 (independently for width and height) with an 8 pixel granularity. The "tile" address is a multiple of 8x8 pixels. - Each sprite can be shrinked to ~1/4 or enlarged to ~32x following + Each sprite can be shrunk to ~1/4 or enlarged to ~32x following an exponential curve of sizes (with one zoom value for both width and height) @@ -295,7 +295,7 @@ imagetek_i4300_device::imagetek_i4300_device(const machine_config &mconfig, cons //------------------------------------------------- // device_add_mconfig - device-specific machine -// configuration addiitons +// configuration additions //------------------------------------------------- void imagetek_i4100_device::device_add_mconfig(machine_config &config) @@ -331,6 +331,10 @@ void imagetek_i4100_device::expand_gfx1() void imagetek_i4100_device::device_start() { m_inited_hack = false; + + m_screen_blank = false; + m_screen_flip = false; + save_item(NAME(m_rombank)); save_item(NAME(m_crtc_unlock)); save_item(NAME(m_sprite_count)); @@ -395,7 +399,7 @@ void imagetek_i4100_device::vram_2_w(offs_t offset, uint16_t data, uint16_t mem_ /* Some game uses almost only the blitter to write to the tilemaps. The CPU can only access a "window" of 512x256 pixels in the upper left corner of the big tilemap */ -// TODO: Puzzlet, Sankokushi & Lady Killer contradicts with aformentioned description (more like RMW?) +// TODO: Puzzlet, Sankokushi & Lady Killer contradicts with aforementioned description (more like RMW?) static inline offs_t RMW_OFFS(offs_t offset) { @@ -923,8 +927,8 @@ void imagetek_i4100_device::draw_spritegfx(screen_device &screen, bitmap_rgb32 & for (int y = sy; y < ey; y++) { const u8 *source = source_base + (y_index >> 16) * width; - u32 *dest = &bitmap.pix32(y); - u8 *pri = &priority_bitmap.pix8(y); + u32 *dest = &bitmap.pix(y); + u8 *pri = &priority_bitmap.pix(y); int x_index = x_index_base; for (int x = sx; x < ex; x++) { @@ -1200,8 +1204,8 @@ void imagetek_i4100_device::draw_tilemap(screen_device &screen, bitmap_rgb32 &bi int const srctilerow = srcline >> tileshift; srcline &= tilemask; - u32 *dst = &bitmap.pix32(y); - u8 *priority_baseaddr = &priority_bitmap.pix8(y); + u32 *dst = &bitmap.pix(y); + u8 *priority_baseaddr = &priority_bitmap.pix(y); for (int x = cliprect.min_x; x <= cliprect.max_x; x++) { diff --git a/src/devices/video/m50458.cpp b/src/devices/video/m50458.cpp index 97e67af8a75..e2404684700 100644 --- a/src/devices/video/m50458.cpp +++ b/src/devices/video/m50458.cpp @@ -204,21 +204,19 @@ void m50458_device::device_validity_check(validity_checker &valid) const void m50458_device::device_start() { - uint16_t tmp; - uint8_t *pcg = memregion("m50458")->base(); - int tile; - int yi; - uint16_t src,dst; + uint8_t const *const pcg = memregion("m50458")->base(); /* Create an array for shadow gfx */ /* this will spread the source ROM into four directions (up-left, up-right, down-left, down-right) thus creating a working shadow copy */ m_shadow_gfx = make_unique_clear<uint8_t[]>(0x1200); - for(tile=0;tile<0x80;tile++) + for(int tile=0;tile<0x80;tile++) { - for(yi=1;yi<17;yi++) + for(int yi=1;yi<17;yi++) { - src = (tile & 0x7f)*36+yi*2; /* source offset */ + uint16_t tmp, dst; + + uint16_t const src = (tile & 0x7f)*36+yi*2; /* source offset */ dst = (tile & 0x7f)*36+(yi-1)*2; /* destination offset */ @@ -331,40 +329,34 @@ WRITE_LINE_MEMBER( m50458_device::set_clock_line ) uint32_t m50458_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - int x,y; - uint8_t *pcg = memregion("m50458")->base(); - uint8_t bg_r,bg_g,bg_b; + uint8_t const *const pcg = memregion("m50458")->base(); /* TODO: there's probably a way to control the brightness in this */ - bg_r = m_phase & 1 ? 0xdf : 0; - bg_g = m_phase & 2 ? 0xdf : 0; - bg_b = m_phase & 4 ? 0xdf : 0; + uint8_t const bg_r = m_phase & 1 ? 0xdf : 0; + uint8_t const bg_g = m_phase & 2 ? 0xdf : 0; + uint8_t const bg_b = m_phase & 4 ? 0xdf : 0; bitmap.fill(rgb_t(0xff,bg_r,bg_g,bg_b),cliprect); - for(y=0;y<12;y++) + for(int y=0;y<12;y++) { - for(x=0;x<24;x++) + for(int x=0;x<24;x++) { - int xi,yi; - uint16_t tile; int y_base = y; if(y != 0 && m_scrr > 1) { y_base+=(m_scrr - 1); } if(y_base > 11) { y_base -= 11; } if(m_scrr && y == 11) { y_base = 0; } /* Guess: repeat line 0 if scrolling is active */ - tile = read_word(x+y_base*24); + uint16_t const tile = read_word(x+y_base*24); - for(yi=0;yi<18;yi++) + for(int yi=0;yi<18;yi++) { - for(xi=4;xi<16;xi++) /* TODO: remove 4 / 16 / -4 offset once that the ROM is fixed */ + for(int xi=4;xi<16;xi++) /* TODO: remove 4 / 16 / -4 offset once that the ROM is fixed */ { - uint8_t pix; - uint8_t color = (tile & 0x700) >> 8; - uint16_t offset = ((tile & 0x7f)*36+yi*2); - int res_y,res_x; - uint8_t xh,yh; + uint8_t const color = (tile & 0x700) >> 8; + uint16_t const offset = ((tile & 0x7f)*36+yi*2); + uint8_t pix; if(xi>=8) pix = ((pcg[offset+1] >> (7-(xi & 0x7))) & 1) << 1; else @@ -382,8 +374,8 @@ uint32_t m50458_device::screen_update(screen_device &screen, bitmap_rgb32 &bitma if(yi == 17 && tile & 0x1000) /* underline? */ pix |= 1; - res_y = y*18+yi; - res_x = x*12+(xi-4); + int res_y = y*18+yi; + int res_x = x*12+(xi-4); if(y != 0 && y != 11) { @@ -419,9 +411,9 @@ uint32_t m50458_device::screen_update(screen_device &screen, bitmap_rgb32 &bitma if(res_y > 215 || res_x > 288) continue; - for(yh=0;yh<m_vsz1+1;yh++) - for(xh=0;xh<m_hsz1+1;xh++) - bitmap.pix32(res_y+yh,res_x+xh) = r << 16 | g << 8 | b; + for(uint8_t yh=0;yh<m_vsz1+1;yh++) + for(uint8_t xh=0;xh<m_hsz1+1;xh++) + bitmap.pix(res_y+yh,res_x+xh) = r << 16 | g << 8 | b; } else if(y_base == 11) { @@ -432,9 +424,9 @@ uint32_t m50458_device::screen_update(screen_device &screen, bitmap_rgb32 &bitma if(res_y > 215 || res_x > 288) continue; - for(yh=0;yh<m_vsz3+1;yh++) - for(xh=0;xh<m_hsz3+1;xh++) - bitmap.pix32(res_y+yh,res_x+xh) = r << 16 | g << 8 | b; + for(uint8_t yh=0;yh<m_vsz3+1;yh++) + for(uint8_t xh=0;xh<m_hsz3+1;xh++) + bitmap.pix(res_y+yh,res_x+xh) = r << 16 | g << 8 | b; } else { @@ -444,9 +436,9 @@ uint32_t m50458_device::screen_update(screen_device &screen, bitmap_rgb32 &bitma if(res_y > 215 || res_x > 288) continue; - for(yh=0;yh<m_vsz2+1;yh++) - for(xh=0;xh<m_hsz2+1;xh++) - bitmap.pix32(res_y+yh,res_x+xh) = r << 16 | g << 8 | b; + for(uint8_t yh=0;yh<m_vsz2+1;yh++) + for(uint8_t xh=0;xh<m_hsz2+1;xh++) + bitmap.pix(res_y+yh,res_x+xh) = r << 16 | g << 8 | b; } } } diff --git a/src/devices/video/mb88303.cpp b/src/devices/video/mb88303.cpp index 1112012db1d..16a24122306 100644 --- a/src/devices/video/mb88303.cpp +++ b/src/devices/video/mb88303.cpp @@ -339,7 +339,7 @@ void mb88303_device::update_bitmap(bitmap_rgb32 &bitmap, const rectangle &clipre const uint32_t color = BIT(gfx[row], bit) ? 0xffffffff : 0; if (!show_background() && !color) continue; - bitmap.pix32(bitmap_y + row + m_vert_display_pos, bitmap_x + (6 - bit) + m_horiz_display_pos) = color; + bitmap.pix(bitmap_y + row + m_vert_display_pos, bitmap_x + (6 - bit) + m_horiz_display_pos) = color; } } } diff --git a/src/devices/video/mb90082.cpp b/src/devices/video/mb90082.cpp index b56e4e61409..27ef9238ec6 100644 --- a/src/devices/video/mb90082.cpp +++ b/src/devices/video/mb90082.cpp @@ -207,44 +207,37 @@ void mb90082_device::write(uint8_t data) uint32_t mb90082_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - int x,y; - uint8_t *pcg = memregion("mb90082")->base(); - uint16_t tile,attr; - uint8_t bg_r,bg_g,bg_b; + uint8_t const *const pcg = memregion("mb90082")->base(); /* TODO: there's probably a way to control the brightness in this */ - bg_b = m_uc & 1 ? 0xdf : 0; - bg_g = m_uc & 2 ? 0xdf : 0; - bg_r = m_uc & 4 ? 0xdf : 0; + uint8_t const bg_b = m_uc & 1 ? 0xdf : 0; + uint8_t const bg_g = m_uc & 2 ? 0xdf : 0; + uint8_t const bg_r = m_uc & 4 ? 0xdf : 0; bitmap.fill(rgb_t(0xff,bg_r,bg_g,bg_b),cliprect); - for(y=0;y<12;y++) + for(int y=0;y<12;y++) { - for(x=0;x<24;x++) + for(int x=0;x<24;x++) { - int xi,yi; - - tile = read_word(x+y*24); - attr = read_word((x+y*24)|0x200); + uint16_t tile = read_word(x+y*24); + uint16_t attr = read_word((x+y*24)|0x200); /* TODO: charset hook-up is obviously WRONG so following mustn't be trusted at all */ - for(yi=0;yi<16;yi++) + for(int yi=0;yi<16;yi++) { - for(xi=0;xi<16;xi++) + for(int xi=0;xi<16;xi++) { - uint8_t pix; - uint8_t color = (attr & 0x70) >> 4; - uint8_t r,g,b; + uint8_t const color = (attr & 0x70) >> 4; - pix = (pcg[(tile*8)+(yi >> 1)] >> (7-(xi >> 1))) & 1; + uint8_t const pix = (pcg[(tile*8)+(yi >> 1)] >> (7-(xi >> 1))) & 1; /* TODO: check this */ - b = (color & 1) ? 0xff : 0; - g = (color & 2) ? 0xff : 0; - r = (color & 4) ? 0xff : 0; + uint8_t const b = (color & 1) ? 0xff : 0; + uint8_t const g = (color & 2) ? 0xff : 0; + uint8_t const r = (color & 4) ? 0xff : 0; if(tile != 0xff && pix != 0) - bitmap.pix32(y*16+yi,x*16+xi) = r << 16 | g << 8 | b; + bitmap.pix(y*16+yi,x*16+xi) = r << 16 | g << 8 | b; } } } diff --git a/src/devices/video/mb_vcu.cpp b/src/devices/video/mb_vcu.cpp index 745675243e6..09ac807f13a 100644 --- a/src/devices/video/mb_vcu.cpp +++ b/src/devices/video/mb_vcu.cpp @@ -526,36 +526,33 @@ void mb_vcu_device::vbank_clear_w(uint8_t data) uint32_t mb_vcu_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - int x,y; - uint8_t dot; - bitmap.fill(m_palette->pen(0x100),cliprect); - for(y=0;y<256;y++) + for(int y=0;y<256;y++) { - for(x=0;x<256;x++) + for(int x=0;x<256;x++) { - dot = read_byte((x >> 0)|(y<<8)|1<<16|(m_vbank ^ 1)<<18); + uint8_t dot = read_byte((x >> 0)|(y<<8)|1<<16|(m_vbank ^ 1)<<18); //if(dot != 0xf) { dot|= m_vregs[1] << 4; - bitmap.pix32(y,x) = m_palette->pen(dot); + bitmap.pix(y,x) = m_palette->pen(dot); } } } - for(y=0;y<256;y++) + for(int y=0;y<256;y++) { - for(x=0;x<256;x++) + for(int x=0;x<256;x++) { - dot = read_byte((x >> 0)|(y<<8)|0<<16|(m_vbank ^ 1)<<18); + uint8_t dot = read_byte((x >> 0)|(y<<8)|0<<16|(m_vbank ^ 1)<<18); if(dot != 0xf) { dot|= m_vregs[1] << 4; - bitmap.pix32(y,x) = m_palette->pen(dot); + bitmap.pix(y,x) = m_palette->pen(dot); } } } diff --git a/src/devices/video/mc6845.cpp b/src/devices/video/mc6845.cpp index b8cc7148243..abf5692b7c7 100644 --- a/src/devices/video/mc6845.cpp +++ b/src/devices/video/mc6845.cpp @@ -108,6 +108,7 @@ mc6845_device::mc6845_device(const machine_config &mconfig, device_type type, co : device_t(mconfig, type, tag, owner, clock) , device_video_interface(mconfig, *this, false) , m_show_border_area(true) + , m_noninterlace_adjust(0) , m_interlace_adjust(0) , m_clk_scale(1) , m_visarea_adjust_min_x(0) @@ -188,7 +189,7 @@ void mc6845_device::transparent_update() { m_update_addr++; m_update_addr &= 0x3fff; - call_on_update_address(0); + call_on_update_address(MODE_UPDATE_STROBE); } else { @@ -267,7 +268,7 @@ void mc6845_device::register_w(uint8_t data) { m_update_addr = ((data & 0x3f) << 8) | (m_update_addr & 0x00ff); if(MODE_TRANSPARENT_PHI2) - call_on_update_address(0); + call_on_update_address(MODE_UPDATE_STROBE); } break; case 0x13: @@ -275,7 +276,7 @@ void mc6845_device::register_w(uint8_t data) { m_update_addr = ((data & 0xff) << 0) | (m_update_addr & 0xff00); if(MODE_TRANSPARENT_PHI2) - call_on_update_address(0); + call_on_update_address(MODE_UPDATE_STROBE); } break; case 0x1f: transparent_update(); break; @@ -993,7 +994,7 @@ void mc6845_device::device_timer(emu_timer &timer, device_timer_id id, int param case TIMER_UPD_ADR: /* fire a update address strobe */ - call_on_update_address(0); + call_on_update_address(MODE_UPDATE_STROBE); break; case TIMER_UPD_TRANS: @@ -1122,7 +1123,7 @@ uint8_t mc6845_device::draw_scanline(int y, bitmap_rgb32 &bitmap, const rectangl // is in units of characters and is relative to the start of the // displayable area, not relative to the screen bitmap origin. int8_t cursor_x = cursor_visible ? (m_cursor_addr - m_current_disp_addr) : -1; - int de = (y < m_max_visible_y) ? 1 : 0; + int de = (y <= m_max_visible_y) ? 1 : 0; int vbp = m_vert_pix_total - m_vsync_off_pos; if (vbp < 0) vbp = 0; int hbp = m_horiz_pix_total - m_hsync_off_pos; @@ -1250,6 +1251,7 @@ void mc6845_device::device_start() m_horiz_char_total = 0xff; m_max_ras_addr = 0x1f; m_vert_char_total = 0x7f; + m_mode_control = 0x00; m_supports_disp_start_addr_r = false; // MC6845 can not read Display Start (double checked on datasheet) m_supports_vert_sync_width = false; @@ -1779,7 +1781,7 @@ MC6845_UPDATE_ROW( mos8563_device::vdc_update_row ) if (x < 0) x = 0; int color = BIT(code, 7) ? fg : bg; - bitmap.pix32(vbp + y, hbp + x) = pen(de ? color : 0); + bitmap.pix(vbp + y, hbp + x) = pen(de ? color : 0); } } else @@ -1815,7 +1817,7 @@ MC6845_UPDATE_ROW( mos8563_device::vdc_update_row ) if (x < 0) x = 0; int color = BIT(data, 7) ? fg : bg; - bitmap.pix32(vbp + y, hbp + x) = pen(de ? color : 0); + bitmap.pix(vbp + y, hbp + x) = pen(de ? color : 0); if ((bit < 8) || !HSS_SEMI) data <<= 1; } diff --git a/src/devices/video/mc6847.h b/src/devices/video/mc6847.h index 78a8ad57345..78fe0eac5f3 100644 --- a/src/devices/video/mc6847.h +++ b/src/devices/video/mc6847.h @@ -81,7 +81,7 @@ protected: pixel_t *bitmap_addr(bitmap_rgb32 &bitmap, int y, int x) { - return &bitmap.pix32(y, x); + return &bitmap.pix(y, x); } static uint8_t simplify_mode(uint8_t data, uint8_t mode) @@ -183,8 +183,8 @@ protected: if( (mode & MODE_AS) || ((mode & (MODE_AG|MODE_GM0) ) == MODE_AG) ) { - pixel_t *line1 = &bitmap.pix32(y + base_y, base_x); - pixel_t *line2 = &bitmap.pix32(y + base_y + 1, base_x); + pixel_t *line1 = &bitmap.pix(y + base_y, base_x); + pixel_t *line2 = &bitmap.pix(y + base_y + 1, base_x); std::map<std::pair<pixel_t,pixel_t>,pixel_t>::const_iterator newColor; for( int pixel = 0; pixel < bitmap.width() - (base_x * 2); ++pixel ) diff --git a/src/devices/video/mos6566.cpp b/src/devices/video/mos6566.cpp index b88cad06c64..a6e3c246a76 100644 --- a/src/devices/video/mos6566.cpp +++ b/src/devices/video/mos6566.cpp @@ -515,55 +515,37 @@ inline void mos6566_device::draw_background() inline void mos6566_device::draw_mono( uint16_t p, uint8_t c0, uint8_t c1 ) { - uint8_t c[2]; + uint8_t const c[2] = { c0, c1 }; uint8_t data = m_gfx_data; - c[0] = c0; - c[1] = c1; - - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + 7) = PALETTE_MOS[c[data & 1]]; - m_fore_coll_buf[p + 7] = data & 1; data >>= 1; - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + 6) = PALETTE_MOS[c[data & 1]]; - m_fore_coll_buf[p + 6] = data & 1; data >>= 1; - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + 5) = PALETTE_MOS[c[data & 1]]; - m_fore_coll_buf[p + 5] = data & 1; data >>= 1; - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + 4) = PALETTE_MOS[c[data & 1]]; - m_fore_coll_buf[p + 4] = data & 1; data >>= 1; - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + 3) = PALETTE_MOS[c[data & 1]]; - m_fore_coll_buf[p + 3] = data & 1; data >>= 1; - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + 2) = PALETTE_MOS[c[data & 1]]; - m_fore_coll_buf[p + 2] = data & 1; data >>= 1; - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + 1) = PALETTE_MOS[c[data & 1]]; - m_fore_coll_buf[p + 1] = data & 1; data >>= 1; - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + 0) = PALETTE_MOS[c[data]]; - m_fore_coll_buf[p + 0] = data & 1; + for (unsigned i = 0; i < 8; i++) + { + m_bitmap.pix(VIC2_RASTER_2_EMU(m_rasterline), p + 7 - i) = PALETTE_MOS[c[data & 1]]; + m_fore_coll_buf[p + 7 - i] = data & 1; + data >>= 1; + } } inline void mos6566_device::draw_multi( uint16_t p, uint8_t c0, uint8_t c1, uint8_t c2, uint8_t c3 ) { - uint8_t c[4]; + uint8_t const c[4] = { c0, c1, c2, c3 }; uint8_t data = m_gfx_data; - c[0] = c0; - c[1] = c1; - c[2] = c2; - c[3] = c3; - - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + 7) = PALETTE_MOS[c[data & 3]]; + m_bitmap.pix(VIC2_RASTER_2_EMU(m_rasterline), p + 7) = PALETTE_MOS[c[data & 3]]; m_fore_coll_buf[p + 7] = data & 2; - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + 6) = PALETTE_MOS[c[data & 3]]; + m_bitmap.pix(VIC2_RASTER_2_EMU(m_rasterline), p + 6) = PALETTE_MOS[c[data & 3]]; m_fore_coll_buf[p + 6] = data & 2; data >>= 2; - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + 5) = PALETTE_MOS[c[data & 3]]; + m_bitmap.pix(VIC2_RASTER_2_EMU(m_rasterline), p + 5) = PALETTE_MOS[c[data & 3]]; m_fore_coll_buf[p + 5] = data & 2; - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + 4) = PALETTE_MOS[c[data & 3]]; + m_bitmap.pix(VIC2_RASTER_2_EMU(m_rasterline), p + 4) = PALETTE_MOS[c[data & 3]]; m_fore_coll_buf[p + 4] = data & 2; data >>= 2; - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + 3) = PALETTE_MOS[c[data & 3]]; + m_bitmap.pix(VIC2_RASTER_2_EMU(m_rasterline), p + 3) = PALETTE_MOS[c[data & 3]]; m_fore_coll_buf[p + 3] = data & 2; - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + 2) = PALETTE_MOS[c[data & 3]]; + m_bitmap.pix(VIC2_RASTER_2_EMU(m_rasterline), p + 2) = PALETTE_MOS[c[data & 3]]; m_fore_coll_buf[p + 2] = data & 2; data >>= 2; - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + 1) = PALETTE_MOS[c[data]]; + m_bitmap.pix(VIC2_RASTER_2_EMU(m_rasterline), p + 1) = PALETTE_MOS[c[data]]; m_fore_coll_buf[p + 1] = data & 2; - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + 0) = PALETTE_MOS[c[data]]; + m_bitmap.pix(VIC2_RASTER_2_EMU(m_rasterline), p + 0) = PALETTE_MOS[c[data]]; m_fore_coll_buf[p + 0] = data & 2; } @@ -2078,57 +2060,23 @@ void mos6566_device::draw_graphics() draw_mono(p, tmp_col, m_color_data & 0x0f); break; case 5: - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + 7) = PALETTE_MOS[0]; - m_fore_coll_buf[p + 7] = 0; - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + 6) = PALETTE_MOS[0]; - m_fore_coll_buf[p + 6] = 0; - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + 5) = PALETTE_MOS[0]; - m_fore_coll_buf[p + 5] = 0; - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + 4) = PALETTE_MOS[0]; - m_fore_coll_buf[p + 4] = 0; - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + 3) = PALETTE_MOS[0]; - m_fore_coll_buf[p + 3] = 0; - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + 2) = PALETTE_MOS[0]; - m_fore_coll_buf[p + 2] = 0; - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + 1) = PALETTE_MOS[0]; - m_fore_coll_buf[p + 1] = 0; - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + 0) = PALETTE_MOS[0]; - m_fore_coll_buf[p + 0] = 0; - break; case 6: - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + 7) = PALETTE_MOS[0]; - m_fore_coll_buf[p + 7] = 0; - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + 6) = PALETTE_MOS[0]; - m_fore_coll_buf[p + 6] = 0; - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + 5) = PALETTE_MOS[0]; - m_fore_coll_buf[p + 5] = 0; - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + 4) = PALETTE_MOS[0]; - m_fore_coll_buf[p + 4] = 0; - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + 3) = PALETTE_MOS[0]; - m_fore_coll_buf[p + 3] = 0; - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + 2) = PALETTE_MOS[0]; - m_fore_coll_buf[p + 2] = 0; - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + 1) = PALETTE_MOS[0]; - m_fore_coll_buf[p + 1] = 0; - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + 0) = PALETTE_MOS[0]; - m_fore_coll_buf[p + 0] = 0; - break; case 7: - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + 7) = PALETTE_MOS[0]; + m_bitmap.pix(VIC2_RASTER_2_EMU(m_rasterline), p + 7) = PALETTE_MOS[0]; m_fore_coll_buf[p + 7] = 0; - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + 6) = PALETTE_MOS[0]; + m_bitmap.pix(VIC2_RASTER_2_EMU(m_rasterline), p + 6) = PALETTE_MOS[0]; m_fore_coll_buf[p + 6] = 0; - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + 5) = PALETTE_MOS[0]; + m_bitmap.pix(VIC2_RASTER_2_EMU(m_rasterline), p + 5) = PALETTE_MOS[0]; m_fore_coll_buf[p + 5] = 0; - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + 4) = PALETTE_MOS[0]; + m_bitmap.pix(VIC2_RASTER_2_EMU(m_rasterline), p + 4) = PALETTE_MOS[0]; m_fore_coll_buf[p + 4] = 0; - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + 3) = PALETTE_MOS[0]; + m_bitmap.pix(VIC2_RASTER_2_EMU(m_rasterline), p + 3) = PALETTE_MOS[0]; m_fore_coll_buf[p + 3] = 0; - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + 2) = PALETTE_MOS[0]; + m_bitmap.pix(VIC2_RASTER_2_EMU(m_rasterline), p + 2) = PALETTE_MOS[0]; m_fore_coll_buf[p + 2] = 0; - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + 1) = PALETTE_MOS[0]; + m_bitmap.pix(VIC2_RASTER_2_EMU(m_rasterline), p + 1) = PALETTE_MOS[0]; m_fore_coll_buf[p + 1] = 0; - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + 0) = PALETTE_MOS[0]; + m_bitmap.pix(VIC2_RASTER_2_EMU(m_rasterline), p + 0) = PALETTE_MOS[0]; m_fore_coll_buf[p + 0] = 0; break; } @@ -2203,12 +2151,12 @@ void mos6566_device::draw_sprites() if (SPRITE_PRIORITY(snum)) { if (m_fore_coll_buf[p + i] == 0) - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + i) = PALETTE_MOS[col]; + m_bitmap.pix(VIC2_RASTER_2_EMU(m_rasterline), p + i) = PALETTE_MOS[col]; m_spr_coll_buf[p + i] = sbit; } else { - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + i) = PALETTE_MOS[col]; + m_bitmap.pix(VIC2_RASTER_2_EMU(m_rasterline), p + i) = PALETTE_MOS[col]; m_spr_coll_buf[p + i] = sbit; } } @@ -2251,12 +2199,12 @@ void mos6566_device::draw_sprites() if (SPRITE_PRIORITY(snum)) { if (m_fore_coll_buf[p + i] == 0) - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + i) = PALETTE_MOS[col]; + m_bitmap.pix(VIC2_RASTER_2_EMU(m_rasterline), p + i) = PALETTE_MOS[col]; m_spr_coll_buf[p + i] = sbit; } else { - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + i) = PALETTE_MOS[col]; + m_bitmap.pix(VIC2_RASTER_2_EMU(m_rasterline), p + i) = PALETTE_MOS[col]; m_spr_coll_buf[p + i] = sbit; } } @@ -2282,12 +2230,12 @@ void mos6566_device::draw_sprites() if (SPRITE_PRIORITY(snum)) { if (m_fore_coll_buf[p + i] == 0) - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + i) = PALETTE_MOS[color]; + m_bitmap.pix(VIC2_RASTER_2_EMU(m_rasterline), p + i) = PALETTE_MOS[color]; m_spr_coll_buf[p + i] = sbit; } else { - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + i) = PALETTE_MOS[color]; + m_bitmap.pix(VIC2_RASTER_2_EMU(m_rasterline), p + i) = PALETTE_MOS[color]; m_spr_coll_buf[p + i] = sbit; } } @@ -2308,12 +2256,12 @@ void mos6566_device::draw_sprites() if (SPRITE_PRIORITY(snum)) { if (m_fore_coll_buf[p + i] == 0) - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + i) = PALETTE_MOS[color]; + m_bitmap.pix(VIC2_RASTER_2_EMU(m_rasterline), p + i) = PALETTE_MOS[color]; m_spr_coll_buf[p + i] = sbit; } else { - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + i) = PALETTE_MOS[color]; + m_bitmap.pix(VIC2_RASTER_2_EMU(m_rasterline), p + i) = PALETTE_MOS[color]; m_spr_coll_buf[p + i] = sbit; } } @@ -2363,12 +2311,12 @@ void mos6566_device::draw_sprites() if (SPRITE_PRIORITY(snum)) { if (m_fore_coll_buf[p + i] == 0) - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + i) = PALETTE_MOS[col]; + m_bitmap.pix(VIC2_RASTER_2_EMU(m_rasterline), p + i) = PALETTE_MOS[col]; m_spr_coll_buf[p + i] = sbit; } else { - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + i) = PALETTE_MOS[col]; + m_bitmap.pix(VIC2_RASTER_2_EMU(m_rasterline), p + i) = PALETTE_MOS[col]; m_spr_coll_buf[p + i] = sbit; } } @@ -2393,12 +2341,12 @@ void mos6566_device::draw_sprites() if (SPRITE_PRIORITY(snum)) { if (m_fore_coll_buf[p + i] == 0) - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + i) = PALETTE_MOS[color]; + m_bitmap.pix(VIC2_RASTER_2_EMU(m_rasterline), p + i) = PALETTE_MOS[color]; m_spr_coll_buf[p + i] = sbit; } else { - m_bitmap.pix32(VIC2_RASTER_2_EMU(m_rasterline), p + i) = PALETTE_MOS[color]; + m_bitmap.pix(VIC2_RASTER_2_EMU(m_rasterline), p + i) = PALETTE_MOS[color]; m_spr_coll_buf[p + i] = sbit; } } diff --git a/src/devices/video/msm6255.cpp b/src/devices/video/msm6255.cpp index f7f0ee2928a..de34d079cde 100644 --- a/src/devices/video/msm6255.cpp +++ b/src/devices/video/msm6255.cpp @@ -328,9 +328,7 @@ void msm6255_device::draw_scanline(bitmap_ind16 &bitmap, const rectangle &clipre uint8_t cpd = m_cpr & CPR_CPD_MASK; uint16_t car = (m_cur << 8) | m_clr; - int sx, x; - - for (sx = 0; sx < hn; sx++) + for (int sx = 0; sx < hn; sx++) { uint8_t data = read_byte(ma, ra); @@ -345,9 +343,9 @@ void msm6255_device::draw_scanline(bitmap_ind16 &bitmap, const rectangle &clipre } } - for (x = 0; x < hp; x++) + for (int x = 0; x < hp; x++) { - bitmap.pix16(y, (sx * hp) + x) = BIT(data, 7); + bitmap.pix(y, (sx * hp) + x) = BIT(data, 7); data <<= 1; } diff --git a/src/devices/video/nt7534.cpp b/src/devices/video/nt7534.cpp index e777aac55dc..15fd1fb41e5 100644 --- a/src/devices/video/nt7534.cpp +++ b/src/devices/video/nt7534.cpp @@ -148,7 +148,7 @@ uint32_t nt7534_device::screen_update(screen_device &screen, bitmap_ind16 &bitma { uint8_t py = (y + m_display_start_line - 32) % 65; uint8_t page = py/8; - bitmap.pix16(y, x) = BIT(m_ddram[page*132 + px], py%8); + bitmap.pix(y, x) = BIT(m_ddram[page*132 + px], py%8); } } diff --git a/src/devices/video/pc_vga.cpp b/src/devices/video/pc_vga.cpp index 33f2f48d999..9f0bf5c48a7 100644 --- a/src/devices/video/pc_vga.cpp +++ b/src/devices/video/pc_vga.cpp @@ -449,42 +449,37 @@ uint32_t vga_device::start_addr() void vga_device::vga_vh_text(bitmap_rgb32 &bitmap, const rectangle &cliprect) { - uint8_t ch, attr; - uint8_t bits; - uint32_t font_base; - uint32_t *bitmapline; int width=VGA_CH_WIDTH, height = (vga.crtc.maximum_scan_line) * (vga.crtc.scan_doubling + 1); - int pos, line, column, mask, w, h, addr; - uint8_t blink_en,fore_col,back_col; - pen_t pen; if(vga.crtc.cursor_enable) vga.cursor.visible = screen().frame_number() & 0x10; else vga.cursor.visible = 0; - for (addr = vga.crtc.start_addr, line = -vga.crtc.preset_row_scan; line < TEXT_LINES; + for (int addr = vga.crtc.start_addr, line = -vga.crtc.preset_row_scan; line < TEXT_LINES; line += height, addr += (offset()>>1)) { - for (pos = addr, column=0; column<TEXT_COLUMNS; column++, pos++) + for (int pos = addr, column=0; column<TEXT_COLUMNS; column++, pos++) { - ch = vga.memory[(pos<<1) + 0]; - attr = vga.memory[(pos<<1) + 1]; - font_base = 0x20000+(ch<<5); + uint8_t ch = vga.memory[(pos<<1) + 0]; + uint8_t attr = vga.memory[(pos<<1) + 1]; + uint32_t font_base = 0x20000+(ch<<5); font_base += ((attr & 8) ? vga.sequencer.char_sel.A : vga.sequencer.char_sel.B)*0x2000; - blink_en = (vga.attribute.data[0x10]&8&&screen().frame_number() & 0x20) ? attr & 0x80 : 0; + uint8_t blink_en = (vga.attribute.data[0x10]&8&&screen().frame_number() & 0x20) ? attr & 0x80 : 0; - fore_col = attr & 0xf; - back_col = (attr & 0x70) >> 4; + uint8_t fore_col = attr & 0xf; + uint8_t back_col = (attr & 0x70) >> 4; back_col |= (vga.attribute.data[0x10]&8) ? 0 : ((attr & 0x80) >> 4); - for (h = std::max(-line, 0); (h < height) && (line+h < std::min(TEXT_LINES, bitmap.height())); h++) + for (int h = std::max(-line, 0); (h < height) && (line+h < std::min(TEXT_LINES, bitmap.height())); h++) { - bitmapline = &bitmap.pix32(line+h); - bits = vga.memory[font_base+(h>>(vga.crtc.scan_doubling))]; + uint32_t *const bitmapline = &bitmap.pix(line+h); + uint8_t bits = vga.memory[font_base+(h>>(vga.crtc.scan_doubling))]; + int mask, w; for (mask=0x80, w=0; (w<width)&&(w<8); w++, mask>>=1) { + pen_t pen; if (bits&mask) pen = vga.pens[blink_en ? back_col : fore_col]; else @@ -498,6 +493,7 @@ void vga_device::vga_vh_text(bitmap_rgb32 &bitmap, const rectangle &cliprect) if (w<width) { /* 9 column */ + pen_t pen; if (TEXT_COPY_9COLUMN(ch)&&(bits&1)) pen = vga.pens[blink_en ? back_col : fore_col]; else @@ -510,7 +506,7 @@ void vga_device::vga_vh_text(bitmap_rgb32 &bitmap, const rectangle &cliprect) } if (vga.cursor.visible&&(pos==vga.crtc.cursor_addr)) { - for (h=vga.crtc.cursor_scan_start; + for (int h=vga.crtc.cursor_scan_start; (h<=vga.crtc.cursor_scan_end)&&(h<height)&&(line+h<TEXT_LINES); h++) { @@ -525,34 +521,29 @@ void vga_device::vga_vh_text(bitmap_rgb32 &bitmap, const rectangle &cliprect) void vga_device::vga_vh_ega(bitmap_rgb32 &bitmap, const rectangle &cliprect) { - int pos, line, column, c, addr, i, yi; int height = vga.crtc.maximum_scan_line * (vga.crtc.scan_doubling + 1); - uint32_t *bitmapline; - pen_t pen; int pel_shift = (vga.attribute.pel_shift & 7); // popmessage("%08x %02x",EGA_START_ADDRESS,pel_shift); /**/ - for (addr=EGA_START_ADDRESS, pos=0, line=0; line<LINES; - line += height, addr += offset()) + for (int addr=EGA_START_ADDRESS, line=0; line<LINES; line += height, addr += offset()) { - for(yi=0;yi<height;yi++) + for (int yi=0;yi<height;yi++) { - bitmapline = &bitmap.pix32(line + yi); + uint32_t *const bitmapline = &bitmap.pix(line + yi); - for (pos=addr, c=0, column=0; column<EGA_COLUMNS+1; column++, c+=8, pos=(pos+1)&0xffff) + for (int pos=addr, c=0, column=0; column<EGA_COLUMNS+1; column++, c+=8, pos=(pos+1)&0xffff) { - int data[4]; + int data[4] = { + vga.memory[(pos & 0xffff)], + vga.memory[(pos & 0xffff)+0x10000]<<1, + vga.memory[(pos & 0xffff)+0x20000]<<2, + vga.memory[(pos & 0xffff)+0x30000]<<3 }; - data[0]=vga.memory[(pos & 0xffff)]; - data[1]=vga.memory[(pos & 0xffff)+0x10000]<<1; - data[2]=vga.memory[(pos & 0xffff)+0x20000]<<2; - data[3]=vga.memory[(pos & 0xffff)+0x30000]<<3; - - for (i = 7; i >= 0; i--) + for (int i = 7; i >= 0; i--) { - pen = vga.pens[(data[0]&1) | (data[1]&2) | (data[2]&4) | (data[3]&8)]; + pen_t pen = vga.pens[(data[0]&1) | (data[1]&2) | (data[2]&4) | (data[3]&8)]; data[0]>>=1; data[1]>>=1; @@ -571,26 +562,21 @@ void vga_device::vga_vh_ega(bitmap_rgb32 &bitmap, const rectangle &cliprect) /* TODO: I'm guessing that in 256 colors mode every pixel actually outputs two pixels. Is it right? */ void vga_device::vga_vh_vga(bitmap_rgb32 &bitmap, const rectangle &cliprect) { - int pos, line, column, c, addr, curr_addr; - uint32_t *bitmapline; - uint16_t mask_comp; int height = vga.crtc.maximum_scan_line * (vga.crtc.scan_doubling + 1); - int yi; - int xi; int pel_shift = (vga.attribute.pel_shift & 6); int addrmask = vga.crtc.no_wrap ? -1 : 0xffff; /* line compare is screen sensitive */ - mask_comp = 0x3ff; //| (LINES & 0x300); + uint16_t mask_comp = 0x3ff; //| (LINES & 0x300); // popmessage("%02x %02x",vga.attribute.pel_shift,vga.sequencer.data[4] & 0x08); - curr_addr = 0; + int curr_addr = 0; if(!(vga.sequencer.data[4] & 0x08)) { - for (addr = start_addr(), line=0; line<LINES; line+=height, addr+=offset(), curr_addr+=offset()) + for (int addr = start_addr(), line=0; line<LINES; line+=height, addr+=offset(), curr_addr+=offset()) { - for(yi = 0;yi < height; yi++) + for(int yi = 0;yi < height; yi++) { if((line + yi) < (vga.crtc.line_compare & mask_comp)) curr_addr = addr; @@ -599,15 +585,15 @@ void vga_device::vga_vh_vga(bitmap_rgb32 &bitmap, const rectangle &cliprect) curr_addr = 0; pel_shift = 0; } - bitmapline = &bitmap.pix32(line + yi); - for (pos=curr_addr, c=0, column=0; column<VGA_COLUMNS+1; column++, c+=8, pos++) + uint32_t *const bitmapline = &bitmap.pix(line + yi); + for (int pos=curr_addr, c=0, column=0; column<VGA_COLUMNS+1; column++, c+=8, pos++) { if(pos > 0x80000/4) return; - for(xi=0;xi<8;xi++) + for(int xi=0;xi<8;xi++) { - if(!screen().visible_area().contains(c+xi-(pel_shift), line + yi)) + if (!screen().visible_area().contains(c+xi-(pel_shift), line + yi)) continue; bitmapline[c+xi-(pel_shift)] = pen(vga.memory[(pos & addrmask)+((xi >> 1)*0x10000)]); } @@ -617,22 +603,22 @@ void vga_device::vga_vh_vga(bitmap_rgb32 &bitmap, const rectangle &cliprect) } else { - for (addr = start_addr(), line=0; line<LINES; line+=height, addr+=offset(), curr_addr+=offset()) + for (int addr = start_addr(), line=0; line<LINES; line+=height, addr+=offset(), curr_addr+=offset()) { - for(yi = 0;yi < height; yi++) + for(int yi = 0;yi < height; yi++) { if((line + yi) < (vga.crtc.line_compare & mask_comp)) curr_addr = addr; if((line + yi) == (vga.crtc.line_compare & mask_comp)) curr_addr = 0; - bitmapline = &bitmap.pix32(line + yi); + uint32_t *const bitmapline = &bitmap.pix(line + yi); //addr %= 0x80000; - for (pos=curr_addr, c=0, column=0; column<VGA_COLUMNS+1; column++, c+=0x10, pos+=0x8) + for (int pos=curr_addr, c=0, column=0; column<VGA_COLUMNS+1; column++, c+=0x10, pos+=0x8) { if(pos + 0x08 > 0x80000) return; - for(xi=0;xi<0x10;xi++) + for (int xi=0;xi<0x10;xi++) { if(!screen().visible_area().contains(c+xi-(pel_shift), line + yi)) continue; @@ -646,28 +632,23 @@ void vga_device::vga_vh_vga(bitmap_rgb32 &bitmap, const rectangle &cliprect) void vga_device::vga_vh_cga(bitmap_rgb32 &bitmap, const rectangle &cliprect) { - uint32_t *bitmapline; int height = (vga.crtc.scan_doubling + 1); - int x,xi,y,yi; - uint32_t addr; - pen_t pen; - int width; - width = (vga.crtc.horz_disp_end + 1) * 8; + int width = (vga.crtc.horz_disp_end + 1) * 8; - for(y=0;y<LINES;y++) + for(int y=0;y<LINES;y++) { - addr = ((y & 1) * 0x2000) + (((y & ~1) >> 1) * width/4); + uint32_t addr = ((y & 1) * 0x2000) + (((y & ~1) >> 1) * width/4); - for(x=0;x<width;x+=4) + for(int x=0;x<width;x+=4) { - for(yi=0;yi<height;yi++) + for(int yi=0;yi<height;yi++) { - bitmapline = &bitmap.pix32(y * height + yi); + uint32_t *const bitmapline = &bitmap.pix(y * height + yi); - for(xi=0;xi<4;xi++) + for(int xi=0;xi<4;xi++) { - pen = vga.pens[(vga.memory[addr] >> (6-xi*2)) & 3]; + pen_t pen = vga.pens[(vga.memory[addr] >> (6-xi*2)) & 3]; if(!screen().visible_area().contains(x+xi, y * height + yi)) continue; bitmapline[x+xi] = pen; @@ -681,28 +662,23 @@ void vga_device::vga_vh_cga(bitmap_rgb32 &bitmap, const rectangle &cliprect) void vga_device::vga_vh_mono(bitmap_rgb32 &bitmap, const rectangle &cliprect) { - uint32_t *bitmapline; int height = (vga.crtc.scan_doubling + 1); - int x,xi,y,yi; - uint32_t addr; - pen_t pen; - int width; - width = (vga.crtc.horz_disp_end + 1) * 8; + int width = (vga.crtc.horz_disp_end + 1) * 8; - for(y=0;y<LINES;y++) + for(int y=0;y<LINES;y++) { - addr = ((y & 1) * 0x2000) + (((y & ~1) >> 1) * width/8); + uint32_t addr = ((y & 1) * 0x2000) + (((y & ~1) >> 1) * width/8); - for(x=0;x<width;x+=8) + for(int x=0;x<width;x+=8) { - for(yi=0;yi<height;yi++) + for(int yi=0;yi<height;yi++) { - bitmapline = &bitmap.pix32(y * height + yi); + uint32_t *const bitmapline = &bitmap.pix(y * height + yi); - for(xi=0;xi<8;xi++) + for(int xi=0;xi<8;xi++) { - pen = vga.pens[(vga.memory[addr] >> (7-xi)) & 1]; + pen_t pen = vga.pens[(vga.memory[addr] >> (7-xi)) & 1]; if(!screen().visible_area().contains(x+xi, y * height + yi)) continue; bitmapline[x+xi] = pen; @@ -716,18 +692,12 @@ void vga_device::vga_vh_mono(bitmap_rgb32 &bitmap, const rectangle &cliprect) void svga_device::svga_vh_rgb8(bitmap_rgb32 &bitmap, const rectangle &cliprect) { - int pos, line, column, c, addr, curr_addr; - uint32_t *bitmapline; - uint16_t mask_comp; int height = vga.crtc.maximum_scan_line * (vga.crtc.scan_doubling + 1); - int yi; - int xi; - uint8_t start_shift; -// uint16_t line_length; /* line compare is screen sensitive */ - mask_comp = 0x3ff; - curr_addr = 0; + uint16_t mask_comp = 0x3ff; + int curr_addr = 0; +// uint16_t line_length; // if(vga.crtc.dw) // line_length = vga.crtc.offset << 3; // doubleword mode // else @@ -735,29 +705,27 @@ void svga_device::svga_vh_rgb8(bitmap_rgb32 &bitmap, const rectangle &cliprect) // line_length = vga.crtc.offset << 4; // } - start_shift = (!(vga.sequencer.data[4] & 0x08)) ? 2 : 0; + uint8_t start_shift = (!(vga.sequencer.data[4] & 0x08)) ? 2 : 0; + for (int addr = VGA_START_ADDRESS << start_shift, line=0; line<LINES; line+=height, addr+=offset(), curr_addr+=offset()) { - for (addr = VGA_START_ADDRESS << start_shift, line=0; line<LINES; line+=height, addr+=offset(), curr_addr+=offset()) + for (int yi = 0;yi < height; yi++) { - for(yi = 0;yi < height; yi++) + if((line + yi) < (vga.crtc.line_compare & mask_comp)) + curr_addr = addr; + if((line + yi) == (vga.crtc.line_compare & mask_comp)) + curr_addr = 0; + uint32_t *const bitmapline = &bitmap.pix(line + yi); + addr %= vga.svga_intf.vram_size; + for (int pos=curr_addr, c=0, column=0; column<VGA_COLUMNS; column++, c+=8, pos+=0x8) { - if((line + yi) < (vga.crtc.line_compare & mask_comp)) - curr_addr = addr; - if((line + yi) == (vga.crtc.line_compare & mask_comp)) - curr_addr = 0; - bitmapline = &bitmap.pix32(line + yi); - addr %= vga.svga_intf.vram_size; - for (pos=curr_addr, c=0, column=0; column<VGA_COLUMNS; column++, c+=8, pos+=0x8) - { - if(pos + 0x08 >= vga.svga_intf.vram_size) - return; + if(pos + 0x08 >= vga.svga_intf.vram_size) + return; - for(xi=0;xi<8;xi++) - { - if(!screen().visible_area().contains(c+xi, line + yi)) - continue; - bitmapline[c+xi] = pen(vga.memory[(pos+(xi))]); - } + for (int xi=0;xi<8;xi++) + { + if(!screen().visible_area().contains(c+xi, line + yi)) + continue; + bitmapline[c+xi] = pen(vga.memory[(pos+(xi))]); } } } @@ -767,38 +735,29 @@ void svga_device::svga_vh_rgb8(bitmap_rgb32 &bitmap, const rectangle &cliprect) void svga_device::svga_vh_rgb15(bitmap_rgb32 &bitmap, const rectangle &cliprect) { #define MV(x) (vga.memory[x]+(vga.memory[x+1]<<8)) - #define IV 0xff000000 + constexpr uint32_t IV = 0xff000000; int height = vga.crtc.maximum_scan_line * (vga.crtc.scan_doubling + 1); - int xi; - int yi; - int xm; - int pos, line, column, c, addr, curr_addr; - - uint32_t *bitmapline; -// uint16_t mask_comp; /* line compare is screen sensitive */ -// mask_comp = 0xff | (TLINES & 0x300); - curr_addr = 0; - yi=0; - for (addr = TGA_START_ADDRESS, line=0; line<TLINES; line+=height, addr+=offset(), curr_addr+=offset()) +// uint16_t mask_comp = 0xff | (TLINES & 0x300); + int curr_addr = 0; + int yi=0; + for (int addr = TGA_START_ADDRESS, line=0; line<TLINES; line+=height, addr+=offset(), curr_addr+=offset()) { - bitmapline = &bitmap.pix32(line); + uint32_t *const bitmapline = &bitmap.pix(line); addr %= vga.svga_intf.vram_size; - for (pos=addr, c=0, column=0; column<TGA_COLUMNS; column++, c+=8, pos+=0x10) + for (int pos=addr, c=0, column=0; column<TGA_COLUMNS; column++, c+=8, pos+=0x10) { if(pos + 0x10 >= vga.svga_intf.vram_size) return; - for(xi=0,xm=0;xi<8;xi++,xm+=2) + for(int xi=0,xm=0;xi<8;xi++,xm+=2) { - int r,g,b; - if(!screen().visible_area().contains(c+xi, line + yi)) continue; - r = (MV(pos+xm)&0x7c00)>>10; - g = (MV(pos+xm)&0x03e0)>>5; - b = (MV(pos+xm)&0x001f)>>0; + int r = (MV(pos+xm)&0x7c00)>>10; + int g = (MV(pos+xm)&0x03e0)>>5; + int b = (MV(pos+xm)&0x001f)>>0; r = (r << 3) | (r & 0x7); g = (g << 3) | (g & 0x7); b = (b << 3) | (b & 0x7); @@ -811,38 +770,29 @@ void svga_device::svga_vh_rgb15(bitmap_rgb32 &bitmap, const rectangle &cliprect) void svga_device::svga_vh_rgb16(bitmap_rgb32 &bitmap, const rectangle &cliprect) { #define MV(x) (vga.memory[x]+(vga.memory[x+1]<<8)) - #define IV 0xff000000 + constexpr uint32_t IV = 0xff000000; int height = vga.crtc.maximum_scan_line * (vga.crtc.scan_doubling + 1); - int xi; - int yi; - int xm; - int pos, line, column, c, addr, curr_addr; - - uint32_t *bitmapline; -// uint16_t mask_comp; /* line compare is screen sensitive */ -// mask_comp = 0xff | (TLINES & 0x300); - curr_addr = 0; - yi=0; - for (addr = TGA_START_ADDRESS, line=0; line<TLINES; line+=height, addr+=offset(), curr_addr+=offset()) +// uint16_t mask_comp = 0xff | (TLINES & 0x300); + int curr_addr = 0; + int yi=0; + for (int addr = TGA_START_ADDRESS, line=0; line<TLINES; line+=height, addr+=offset(), curr_addr+=offset()) { - bitmapline = &bitmap.pix32(line); + uint32_t *const bitmapline = &bitmap.pix(line); addr %= vga.svga_intf.vram_size; - for (pos=addr, c=0, column=0; column<TGA_COLUMNS; column++, c+=8, pos+=0x10) + for (int pos=addr, c=0, column=0; column<TGA_COLUMNS; column++, c+=8, pos+=0x10) { if(pos + 0x10 >= vga.svga_intf.vram_size) return; - for(xi=0,xm=0;xi<8;xi++,xm+=2) + for (int xi=0,xm=0;xi<8;xi++,xm+=2) { - int r,g,b; - if(!screen().visible_area().contains(c+xi, line + yi)) continue; - r = (MV(pos+xm)&0xf800)>>11; - g = (MV(pos+xm)&0x07e0)>>5; - b = (MV(pos+xm)&0x001f)>>0; + int r = (MV(pos+xm)&0xf800)>>11; + int g = (MV(pos+xm)&0x07e0)>>5; + int b = (MV(pos+xm)&0x001f)>>0; r = (r << 3) | (r & 0x7); g = (g << 2) | (g & 0x3); b = (b << 3) | (b & 0x7); @@ -855,39 +805,30 @@ void svga_device::svga_vh_rgb16(bitmap_rgb32 &bitmap, const rectangle &cliprect) void svga_device::svga_vh_rgb24(bitmap_rgb32 &bitmap, const rectangle &cliprect) { #define MD(x) (vga.memory[x]+(vga.memory[x+1]<<8)+(vga.memory[x+2]<<16)) - #define ID 0xff000000 + constexpr uint32_t ID = 0xff000000; int height = vga.crtc.maximum_scan_line * (vga.crtc.scan_doubling + 1); - int xi; - int yi; - int xm; - int pos, line, column, c, addr, curr_addr; - uint32_t *bitmapline; - -// uint16_t mask_comp; /* line compare is screen sensitive */ -// mask_comp = 0xff | (TLINES & 0x300); - curr_addr = 0; - yi=0; - for (addr = TGA_START_ADDRESS<<1, line=0; line<TLINES; line+=height, addr+=offset(), curr_addr+=offset()) +// uint16_t mask_comp = 0xff | (TLINES & 0x300); + int curr_addr = 0; + int yi=0; + for (int addr = TGA_START_ADDRESS<<1, line=0; line<TLINES; line+=height, addr+=offset(), curr_addr+=offset()) { - bitmapline = &bitmap.pix32(line); + uint32_t *const bitmapline = &bitmap.pix(line); addr %= vga.svga_intf.vram_size; - for (pos=addr, c=0, column=0; column<TGA_COLUMNS; column++, c+=8, pos+=24) + for (int pos=addr, c=0, column=0; column<TGA_COLUMNS; column++, c+=8, pos+=24) { if(pos + 24 >= vga.svga_intf.vram_size) return; - for(xi=0,xm=0;xi<8;xi++,xm+=3) + for (int xi=0,xm=0;xi<8;xi++,xm+=3) { - int r,g,b; - if(!screen().visible_area().contains(c+xi, line + yi)) continue; - r = (MD(pos+xm)&0xff0000)>>16; - g = (MD(pos+xm)&0x00ff00)>>8; - b = (MD(pos+xm)&0x0000ff)>>0; - bitmapline[c+xi] = IV|(r<<16)|(g<<8)|(b<<0); + int r = (MD(pos+xm)&0xff0000)>>16; + int g = (MD(pos+xm)&0x00ff00)>>8; + int b = (MD(pos+xm)&0x0000ff)>>0; + bitmapline[c+xi] = ID|(r<<16)|(g<<8)|(b<<0); } } } @@ -896,39 +837,32 @@ void svga_device::svga_vh_rgb24(bitmap_rgb32 &bitmap, const rectangle &cliprect) void svga_device::svga_vh_rgb32(bitmap_rgb32 &bitmap, const rectangle &cliprect) { #define MD(x) (vga.memory[x]+(vga.memory[x+1]<<8)+(vga.memory[x+2]<<16)) - #define ID 0xff000000 + constexpr uint32_t ID = 0xff000000; int height = vga.crtc.maximum_scan_line * (vga.crtc.scan_doubling + 1); - int xi; - int yi; - int xm; - int pos, line, column, c, addr, curr_addr; - uint32_t *bitmapline; // uint16_t mask_comp; /* line compare is screen sensitive */ // mask_comp = 0xff | (TLINES & 0x300); - curr_addr = 0; - yi=0; - for (addr = TGA_START_ADDRESS, line=0; line<TLINES; line+=height, addr+=(offset()), curr_addr+=(offset())) + int curr_addr = 0; + int yi=0; + for (int addr = TGA_START_ADDRESS, line=0; line<TLINES; line+=height, addr+=(offset()), curr_addr+=(offset())) { - bitmapline = &bitmap.pix32(line); + uint32_t *const bitmapline = &bitmap.pix(line); addr %= vga.svga_intf.vram_size; - for (pos=addr, c=0, column=0; column<TGA_COLUMNS; column++, c+=8, pos+=0x20) + for (int pos=addr, c=0, column=0; column<TGA_COLUMNS; column++, c+=8, pos+=0x20) { if(pos + 0x20 >= vga.svga_intf.vram_size) return; - for(xi=0,xm=0;xi<8;xi++,xm+=4) + for (int xi=0,xm=0;xi<8;xi++,xm+=4) { - int r,g,b; - if(!screen().visible_area().contains(c+xi, line + yi)) continue; - r = (MD(pos+xm)&0xff0000)>>16; - g = (MD(pos+xm)&0x00ff00)>>8; - b = (MD(pos+xm)&0x0000ff)>>0; - bitmapline[c+xi] = IV|(r<<16)|(g<<8)|(b<<0); + int r = (MD(pos+xm)&0xff0000)>>16; + int g = (MD(pos+xm)&0x00ff00)>>8; + int b = (MD(pos+xm)&0x0000ff)>>0; + bitmapline[c+xi] = ID|(r<<16)|(g<<8)|(b<<0); } } } @@ -936,13 +870,11 @@ void svga_device::svga_vh_rgb32(bitmap_rgb32 &bitmap, const rectangle &cliprect) uint8_t vga_device::pc_vga_choosevideomode() { - int i; - if (vga.crtc.sync_en) { if (vga.dac.dirty) { - for (i=0; i<256;i++) + for (int i=0; i<256;i++) { /* TODO: color shifters? */ set_pen_color(i, (vga.dac.color[3*(i & vga.dac.mask)] & 0x3f) << 2, @@ -954,7 +886,7 @@ uint8_t vga_device::pc_vga_choosevideomode() if (vga.attribute.data[0x10] & 0x80) { - for (i=0; i<16;i++) + for (int i=0; i<16;i++) { vga.pens[i] = pen((vga.attribute.data[i]&0x0f) |((vga.attribute.data[0x14]&0xf)<<4)); @@ -962,7 +894,7 @@ uint8_t vga_device::pc_vga_choosevideomode() } else { - for (i=0; i<16;i++) + for (int i=0; i<16;i++) { vga.pens[i] = pen((vga.attribute.data[i]&0x3f) |((vga.attribute.data[0x14]&0xc)<<4)); @@ -997,13 +929,11 @@ uint8_t vga_device::pc_vga_choosevideomode() uint8_t svga_device::pc_vga_choosevideomode() { - int i; - if (vga.crtc.sync_en) { if (vga.dac.dirty) { - for (i=0; i<256;i++) + for (int i=0; i<256;i++) { /* TODO: color shifters? */ set_pen_color(i, (vga.dac.color[3*(i & vga.dac.mask)] & 0x3f) << 2, @@ -1015,7 +945,7 @@ uint8_t svga_device::pc_vga_choosevideomode() if (vga.attribute.data[0x10] & 0x80) { - for (i=0; i<16;i++) + for (int i=0; i<16;i++) { vga.pens[i] = pen((vga.attribute.data[i]&0x0f) |((vga.attribute.data[0x14]&0xf)<<4)); @@ -1023,7 +953,7 @@ uint8_t svga_device::pc_vga_choosevideomode() } else { - for (i=0; i<16;i++) + for (int i=0; i<16;i++) { vga.pens[i] = pen((vga.attribute.data[i]&0x3f) |((vga.attribute.data[0x14]&0xc)<<4)); @@ -1132,32 +1062,26 @@ uint32_t svga_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, uint32_t s3_vga_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - uint8_t cur_mode; - svga_device::screen_update(screen, bitmap, cliprect); - cur_mode = pc_vga_choosevideomode(); + uint8_t cur_mode = pc_vga_choosevideomode(); // draw hardware graphics cursor // TODO: support 16 bit and greater video modes if(s3.cursor_mode & 0x01) // if cursor is enabled { - uint32_t src; - uint32_t* dst; - uint8_t val; - int x,y; uint16_t cx = s3.cursor_x & 0x07ff; uint16_t cy = s3.cursor_y & 0x07ff; - uint32_t bg_col; - uint32_t fg_col; - int r,g,b; - uint32_t datax; if(cur_mode == SCREEN_OFF || cur_mode == TEXT_MODE || cur_mode == MONO_MODE || cur_mode == CGA_MODE || cur_mode == EGA_MODE) return 0; // cursor only works in VGA or SVGA modes - src = s3.cursor_start_addr * 1024; // start address is in units of 1024 bytes + uint32_t src = s3.cursor_start_addr * 1024; // start address is in units of 1024 bytes + uint32_t bg_col; + uint32_t fg_col; + int r,g,b; + uint32_t datax; switch(cur_mode) { case RGB15_MODE: @@ -1204,16 +1128,16 @@ uint32_t s3_vga_device::screen_update(screen_device &screen, bitmap_rgb32 &bitma // ,(s3.cursor_fg[0])|(s3.cursor_fg[1]<<8)|(s3.cursor_fg[2]<<16)|(s3.cursor_fg[3]<<24)); // for(x=0;x<64;x++) // printf("%08x: %02x %02x %02x %02x\n",src+x*4,vga.memory[src+x*4],vga.memory[src+x*4+1],vga.memory[src+x*4+2],vga.memory[src+x*4+3]); - for(y=0;y<64;y++) + for(int y=0;y<64;y++) { if(cy + y < cliprect.max_y && cx < cliprect.max_x) { - dst = &bitmap.pix32(cy + y, cx); - for(x=0;x<64;x++) + uint32_t *const dst = &bitmap.pix(cy + y, cx); + for(int x=0;x<64;x++) { uint16_t bita = (vga.memory[(src+1) % vga.svga_intf.vram_size] | ((vga.memory[(src+0) % vga.svga_intf.vram_size]) << 8)) >> (15-(x % 16)); uint16_t bitb = (vga.memory[(src+3) % vga.svga_intf.vram_size] | ((vga.memory[(src+2) % vga.svga_intf.vram_size]) << 8)) >> (15-(x % 16)); - val = ((bita & 0x01) << 1) | (bitb & 0x01); + uint8_t val = ((bita & 0x01) << 1) | (bitb & 0x01); if(s3.extended_dac_ctrl & 0x10) { // X11 mode switch(val) diff --git a/src/devices/video/ppu2c0x.cpp b/src/devices/video/ppu2c0x.cpp index bad650cf0a6..d769ff54162 100644 --- a/src/devices/video/ppu2c0x.cpp +++ b/src/devices/video/ppu2c0x.cpp @@ -30,37 +30,6 @@ #include "screen.h" - -/*************************************************************************** - CONSTANTS -***************************************************************************/ - -/* default monochromatic colortable */ -static const pen_t default_colortable_mono[] = -{ - 0,1,2,3, - 0,1,2,3, - 0,1,2,3, - 0,1,2,3, - 0,1,2,3, - 0,1,2,3, - 0,1,2,3, - 0,1,2,3, -}; - -/* default colortable */ -static const pen_t default_colortable[] = -{ - 0,1,2,3, - 0,5,6,7, - 0,9,10,11, - 0,13,14,15, - 0,17,18,19, - 0,21,22,23, - 0,25,26,27, - 0,29,30,31, -}; - //************************************************************************** // GLOBAL VARIABLES //************************************************************************** @@ -119,7 +88,6 @@ ppu2c0x_device::ppu2c0x_device(const machine_config& mconfig, device_type type, device_t(mconfig, type, tag, owner, clock), device_memory_interface(mconfig, *this), device_video_interface(mconfig, *this), - device_palette_interface(mconfig, *this), m_space_config("videoram", ENDIANNESS_LITTLE, 8, 17, 0, internal_map), m_cpu(*this, finder_base::DUMMY_TAG), m_scanline(0), // reset the scanline count @@ -234,7 +202,7 @@ ppu2c05_04_device::ppu2c05_04_device(const machine_config& mconfig, const char* // device_start - device-specific startup //------------------------------------------------- -void ppu2c0x_device::device_start() +void ppu2c0x_device::start_nopalram() { // bind our handler m_int_callback.resolve_safe(); @@ -252,25 +220,8 @@ void ppu2c0x_device::device_start() /* allocate a screen bitmap, videomem and spriteram, a dirtychar array and the monochromatic colortable */ m_bitmap = std::make_unique<bitmap_rgb32>(VISIBLE_SCREEN_WIDTH, VISIBLE_SCREEN_HEIGHT); m_spriteram = make_unique_clear<uint8_t[]>(SPRITERAM_SIZE); - m_colortable = std::make_unique<pen_t[]>(ARRAY_LENGTH(default_colortable)); - m_colortable_mono = std::make_unique<pen_t[]>(ARRAY_LENGTH(default_colortable_mono)); - - m_palette_ram.resize(0x20); - - for (int i = 0; i < 0x20; i++) - m_palette_ram[i] = 0x00; - - /* initialize the color tables */ - for (int i = 0; i < ARRAY_LENGTH(default_colortable_mono); i++) - { - /* monochromatic table */ - m_colortable_mono[i] = default_colortable_mono[i]; - - /* color table */ - m_colortable[i] = default_colortable[i]; - } - init_palette(); + init_palette_tables(); // register for state saving save_item(NAME(m_scanline)); @@ -289,15 +240,25 @@ void ppu2c0x_device::device_start() save_item(NAME(m_scanlines_per_frame)); save_item(NAME(m_vblank_first_scanline)); save_item(NAME(m_regs)); - save_item(NAME(m_palette_ram)); save_item(NAME(m_draw_phase)); save_item(NAME(m_tilecount)); save_pointer(NAME(m_spriteram), SPRITERAM_SIZE); - save_pointer(NAME(m_colortable), ARRAY_LENGTH(default_colortable)); - save_pointer(NAME(m_colortable_mono), ARRAY_LENGTH(default_colortable_mono)); + save_item(NAME(*m_bitmap)); } +void ppu2c0x_device::device_start() +{ + start_nopalram(); + + m_palette_ram.resize(0x20); + + for (int i = 0; i < 0x20; i++) + m_palette_ram[i] = 0x00; + + save_item(NAME(m_palette_ram)); +} + //************************************************************************** // INLINE HELPERS //************************************************************************** @@ -332,12 +293,49 @@ inline void ppu2c0x_device::writebyte(offs_t address, uint8_t data) * *************************************/ -void ppu2c0x_device::init_palette() +void ppu2c0x_device::apply_color_emphasis_and_clamp(bool is_pal_or_dendy, int color_emphasis, double& R, double& G, double& B) { - init_palette(false); + if (is_pal_or_dendy) // PAL machines swap the colour emphasis bits, this means the red/blue highlighting on rampart tally bar doesn't look as good + { + color_emphasis = bitswap<3>(color_emphasis, 2, 0, 1); + } + + double r_mod = 0.0; + double g_mod = 0.0; + double b_mod = 0.0; + + switch (color_emphasis) + { + case 0: r_mod = 1.0; g_mod = 1.0; b_mod = 1.0; break; + case 1: r_mod = 1.24; g_mod = .915; b_mod = .743; break; + case 2: r_mod = .794; g_mod = 1.09; b_mod = .882; break; + case 3: r_mod = .905; g_mod = 1.03; b_mod = 1.28; break; + case 4: r_mod = .741; g_mod = .987; b_mod = 1.0; break; + case 5: r_mod = 1.02; g_mod = .908; b_mod = .979; break; + case 6: r_mod = 1.02; g_mod = .98; b_mod = .653; break; + case 7: r_mod = .75; g_mod = .75; b_mod = .75; break; + } + + R = R * r_mod; + G = G * g_mod; + B = B * b_mod; + + /* Clipping, in case of saturation */ + if (R < 0) + R = 0; + if (R > 255) + R = 255; + if (G < 0) + G = 0; + if (G > 255) + G = 255; + if (B < 0) + B = 0; + if (B > 255) + B = 255; } -rgb_t ppu2c0x_device::nespal_to_RGB(int color_intensity, int color_num) +rgb_t ppu2c0x_device::nespal_to_RGB(int color_intensity, int color_num, int color_emphasis, bool is_pal_or_dendy) { const double tint = 0.22; /* adjust to taste */ const double hue = 287.0; @@ -390,25 +388,15 @@ rgb_t ppu2c0x_device::nespal_to_RGB(int color_intensity, int color_num) double G = (y - (Kb * Ku * u + Kr * Kv * v) / (1 - Kb - Kr)) * 255.0; double B = (y + Ku * u) * 255.0; - /* Clipping, in case of saturation */ - if (R < 0) - R = 0; - if (R > 255) - R = 255; - if (G < 0) - G = 0; - if (G > 255) - G = 255; - if (B < 0) - B = 0; - if (B > 255) - B = 255; + apply_color_emphasis_and_clamp(is_pal_or_dendy, color_emphasis, R, G, B); return rgb_t(floor(R + .5), floor(G + .5), floor(B + .5)); } -void ppu2c0x_device::init_palette(bool indirect) +void ppu2c0x_device::init_palette_tables() { + bool is_pal = m_scanlines_per_frame != NTSC_SCANLINES_PER_FRAME; + /* This routine builds a palette using a transformation from */ /* the YUV (Y, B-Y, R-Y) to the RGB color space */ @@ -421,45 +409,23 @@ void ppu2c0x_device::init_palette(bool indirect) /* Loop through the emphasis modes (8 total) */ for (int color_emphasis = 0; color_emphasis < 8; color_emphasis++) { - /* - double r_mod = 0.0; - double g_mod = 0.0; - double b_mod = 0.0; - - switch (color_emphasis) - { - case 0: r_mod = 1.0; g_mod = 1.0; b_mod = 1.0; break; - case 1: r_mod = 1.24; g_mod = .915; b_mod = .743; break; - case 2: r_mod = .794; g_mod = 1.09; b_mod = .882; break; - case 3: r_mod = .905; g_mod = 1.03; b_mod = 1.28; break; - case 4: r_mod = .741; g_mod = .987; b_mod = 1.0; break; - case 5: r_mod = 1.02; g_mod = .908; b_mod = .979; break; - case 6: r_mod = 1.02; g_mod = .98; b_mod = .653; break; - case 7: r_mod = .75; g_mod = .75; b_mod = .75; break; - } - */ - /* loop through the 4 intensities */ for (int color_intensity = 0; color_intensity < 4; color_intensity++) { /* loop through the 16 colors */ for (int color_num = 0; color_num < 16; color_num++) { - rgb_t col = nespal_to_RGB(color_intensity, color_num); + rgb_t col = nespal_to_RGB(color_intensity, color_num, color_emphasis, is_pal); + + m_nespens[entry] = (uint32_t)col; + entry++; - /* Round, and set the value */ - if (indirect) - set_indirect_color(entry++, col); - else - set_pen_color(entry++, col); } } } - - /* color tables are modified at run-time, and are initialized on 'ppu2c0x_reset' */ } -void ppu2c0x_rgb_device::init_palette() +void ppu2c0x_rgb_device::init_palette_tables() { /* Loop through the emphasis modes (8 total) */ int entry = 0; @@ -471,27 +437,14 @@ void ppu2c0x_rgb_device::init_palette() int G = ((color_emphasis & 2) ? 7 : m_palette_data[color_num * 3 + 1]); int B = ((color_emphasis & 4) ? 7 : m_palette_data[color_num * 3 + 2]); - set_pen_color(entry++, pal3bit(R), pal3bit(G), pal3bit(B)); + m_nespens[entry] = (pal3bit(R)<<16) | (pal3bit(G)<<8) | pal3bit(B); + + //set_pen_color(entry++, pal3bit(R), pal3bit(G), pal3bit(B)); + entry++; } } - - /* color tables are modified at run-time, and are initialized on 'ppu2c0x_reset' */ } -#if 0 -/* the charlayout we use for the chargen */ -static const gfx_layout ppu_charlayout = -{ - 8, 8, /* 8*8 characters */ - 0, - 2, /* 2 bits per pixel */ - { 8*8, 0 }, /* the two bitplanes are separated */ - { 0, 1, 2, 3, 4, 5, 6, 7 }, - { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 }, - 16*8 /* every char takes 16 consecutive bytes */ -}; -#endif - /************************************* * * PPU Initialization and Disposal @@ -609,24 +562,34 @@ void ppu2c0x_device::shift_tile_plane_data(uint8_t& pix) m_planebuf[1] = m_planebuf[1] << 1; } -void ppu2c0x_device::draw_tile_pixel(uint8_t pix, int color, pen_t back_pen, uint32_t*& dest, const pen_t* color_table) +void ppu2c0x_device::draw_tile_pixel(uint8_t pix, int color, uint32_t back_pen, uint32_t*& dest) { - pen_t pen; + uint32_t usepen; if (pix) { - const pen_t* paldata = &color_table[4 * color]; - pen = this->pen(paldata[pix]); + uint8_t pen = ((4 * color) + pix) & 0x1f; + uint16_t palval = m_palette_ram[pen]; + + if (m_regs[PPU_CONTROL1] & PPU_CONTROL1_DISPLAY_MONO) + palval &= 0x30; + + // apply colour emphasis + palval |= ((m_regs[PPU_CONTROL1] & PPU_CONTROL1_COLOR_EMPHASIS) << 1); + + usepen = m_nespens[palval]; } else { - pen = back_pen; + usepen = m_nespens[back_pen]; } - *dest = pen; + + + *dest = usepen; } -void ppu2c0x_device::draw_tile(uint8_t* line_priority, int color_byte, int color_bits, int address, int start_x, pen_t back_pen, uint32_t*& dest, const pen_t* color_table) +void ppu2c0x_device::draw_tile(uint8_t* line_priority, int color_byte, int color_bits, int address, int start_x, uint32_t back_pen, uint32_t*& dest) { int color = (((color_byte >> color_bits) & 0x03)); @@ -640,7 +603,7 @@ void ppu2c0x_device::draw_tile(uint8_t* line_priority, int color_byte, int color if ((start_x + i) >= 0 && (start_x + i) < VISIBLE_SCREEN_WIDTH) { - draw_tile_pixel(pix, color, back_pen, dest, color_table); + draw_tile_pixel(pix, color, back_pen, dest); // priority marking if (pix) @@ -659,24 +622,6 @@ void ppu2c0x_device::draw_background(uint8_t* line_priority) { bitmap_rgb32& bitmap = *m_bitmap; - uint8_t color_mask; - const pen_t* color_table; - - /* setup the color mask and colortable to use */ - if (m_regs[PPU_CONTROL1] & PPU_CONTROL1_DISPLAY_MONO) - { - color_mask = 0xf0; - color_table = m_colortable_mono.get(); - } - else - { - color_mask = 0xff; - color_table = m_colortable.get(); - } - - /* cache the background pen */ - pen_t back_pen = pen(m_back_color & color_mask); - /* determine where in the nametable to start drawing from */ /* based on the current scanline and scroll regs */ uint8_t scroll_x_coarse = m_refresh_data & 0x001f; @@ -691,7 +636,7 @@ void ppu2c0x_device::draw_background(uint8_t* line_priority) /* set up dest */ int start_x = (m_x_fine ^ 0x07) - 7; - uint32_t* dest = &bitmap.pix32(m_scanline, start_x); + uint32_t* dest = &bitmap.pix(m_scanline, start_x); m_tilecount = 0; @@ -730,7 +675,7 @@ void ppu2c0x_device::draw_background(uint8_t* line_priority) // plus something that accounts for y address += scroll_y_fine; - draw_tile(line_priority, color_byte, color_bits, address, start_x, back_pen, dest, color_table); + draw_tile(line_priority, color_byte, color_bits, address, start_x, m_back_color, dest); start_x += 8; @@ -748,28 +693,32 @@ void ppu2c0x_device::draw_background(uint8_t* line_priority) /* if the left 8 pixels for the background are off, blank 'em */ if (!(m_regs[PPU_CONTROL1] & PPU_CONTROL1_BACKGROUND_L8)) { - dest = &bitmap.pix32(m_scanline); + dest = &bitmap.pix(m_scanline); for (int i = 0; i < 8; i++) { - *(dest++) = back_pen; + draw_back_pen(dest, m_back_color); + dest++; + line_priority[i] ^= 0x02; } } } +void ppu2c0x_device::draw_back_pen(uint32_t* dst, int back_pen) +{ + *dst = m_nespens[back_pen]; +} + void ppu2c0x_device::draw_background_pen() { bitmap_rgb32& bitmap = *m_bitmap; /* setup the color mask and colortable to use */ - uint8_t color_mask = (m_regs[PPU_CONTROL1] & PPU_CONTROL1_DISPLAY_MONO) ? 0xf0 : 0xff; - - /* cache the background pen */ - pen_t back_pen = pen(m_back_color & color_mask); + uint8_t color_mask = (m_regs[PPU_CONTROL1] & PPU_CONTROL1_DISPLAY_MONO) ? 0x30 : 0x3f; // Fill this scanline with the background pen. for (int i = 0; i < bitmap.width(); i++) - bitmap.pix32(m_scanline, i) = back_pen; + draw_back_pen(&bitmap.pix(m_scanline, i), m_back_color & color_mask); } void ppu2c0x_device::read_sprite_plane_data(int address) @@ -796,8 +745,16 @@ void ppu2c0x_device::make_sprite_pixel_data(uint8_t& pixel_data, int flipx) void ppu2c0x_device::draw_sprite_pixel(int sprite_xpos, int color, int pixel, uint8_t pixel_data, bitmap_rgb32& bitmap) { - const pen_t* paldata = &m_colortable[4 * color]; - bitmap.pix32(m_scanline, sprite_xpos + pixel) = pen(paldata[pixel_data]); + uint16_t palval = m_palette_ram[((4 * color) | pixel_data) & 0x1f]; + + if (m_regs[PPU_CONTROL1] & PPU_CONTROL1_DISPLAY_MONO) + palval &= 0x30; + + // apply colour emphasis + palval |= ((m_regs[PPU_CONTROL1] & PPU_CONTROL1_COLOR_EMPHASIS) << 1); + + uint32_t pix = m_nespens[palval]; + bitmap.pix(m_scanline, sprite_xpos + pixel) = pix; } void ppu2c0x_device::read_extra_sprite_bits(int sprite_index) @@ -1074,12 +1031,14 @@ void ppu2c0x_device::update_visible_enabled_scanline() void ppu2c0x_device::update_visible_disabled_scanline() { bitmap_rgb32& bitmap = *m_bitmap; - pen_t back_pen; + uint32_t back_pen; /* setup the color mask and colortable to use */ - uint8_t color_mask = (m_regs[PPU_CONTROL1] & PPU_CONTROL1_DISPLAY_MONO) ? 0xf0 : 0xff; + uint8_t color_mask = (m_regs[PPU_CONTROL1] & PPU_CONTROL1_DISPLAY_MONO) ? 0x30 : 0x3f; + + uint16_t palval = m_back_color & color_mask; - back_pen = pen(m_back_color & color_mask); + back_pen = palval; if (m_paletteram_in_ppuspace) { @@ -1092,13 +1051,13 @@ void ppu2c0x_device::update_visible_disabled_scanline() // pen. Micro Machines makes use of this feature. int pen_num = m_palette_ram[(m_videomem_addr & 0x03) ? (m_videomem_addr & 0x1f) : 0]; - back_pen = pen(pen_num); + back_pen = pen_num; } } // Fill this scanline with the background pen. for (int i = 0; i < bitmap.width(); i++) - bitmap.pix32(m_scanline, i) = back_pen; + draw_back_pen(&bitmap.pix(m_scanline, i), back_pen); } void ppu2c0x_device::update_visible_scanline() @@ -1135,29 +1094,20 @@ void ppu2c0x_device::update_scanline() void ppu2c0x_device::palette_write(offs_t offset, uint8_t data) { - int color_emphasis = (m_regs[PPU_CONTROL1] & PPU_CONTROL1_COLOR_EMPHASIS) * 2; - // palette RAM is only 6 bits wide data &= 0x3f; - // transparent pens are mirrored! if (offset & 0x3) { + // regular pens, no mirroring m_palette_ram[offset & 0x1f] = data; - m_colortable[offset & 0x1f] = data + color_emphasis; - m_colortable_mono[offset & 0x1f] = (data & 0xf0) + color_emphasis; } else { - int i; + // transparent pens are mirrored! if (0 == (offset & 0xf)) { m_back_color = data; - for (i = 0; i < 32; i += 4) - { - m_colortable[i] = data + color_emphasis; - m_colortable_mono[i] = (data & 0xf0) + color_emphasis; - } } m_palette_ram[offset & 0xf] = m_palette_ram[(offset & 0xf) + 0x10] = data; } @@ -1279,18 +1229,6 @@ void ppu2c0x_device::write(offs_t offset, uint8_t data) break; case PPU_CONTROL1: /* 1 */ - /* if color intensity has changed, change all the color tables to reflect them */ - if ((data & PPU_CONTROL1_COLOR_EMPHASIS) != (m_regs[PPU_CONTROL1] & PPU_CONTROL1_COLOR_EMPHASIS)) - { - int i; - for (i = 0; i <= 0x1f; i++) - { - uint8_t oldColor = m_palette_ram[i]; - - m_colortable[i] = oldColor + (data & PPU_CONTROL1_COLOR_EMPHASIS) * 2; - } - } - //logerror("control1 write: %02x (scanline: %d)\n", data, m_scanline); m_regs[PPU_CONTROL1] = data; break; diff --git a/src/devices/video/ppu2c0x.h b/src/devices/video/ppu2c0x.h index fcd53435809..9d8fa0f5351 100644 --- a/src/devices/video/ppu2c0x.h +++ b/src/devices/video/ppu2c0x.h @@ -42,8 +42,7 @@ class ppu2c0x_device : public device_t, public device_memory_interface, - public device_video_interface, - public device_palette_interface + public device_video_interface { public: typedef device_delegate<void (int scanline, int vblank, int blanked)> scanline_delegate; @@ -76,16 +75,16 @@ public: auto int_callback() { return m_int_callback.bind(); } /* routines */ - rgb_t nespal_to_RGB(int color_intensity, int color_num); - virtual void init_palette(); - void init_palette(bool indirect); - virtual uint32_t palette_entries() const override { return 4*16*8; } + void apply_color_emphasis_and_clamp(bool is_pal_or_dendy, int color_emphasis, double& R, double& G, double& B); + rgb_t nespal_to_RGB(int color_intensity, int color_num, int color_emphasis, bool is_pal_or_dendy); + virtual void init_palette_tables(); virtual void read_tile_plane_data(int address, int color); virtual void shift_tile_plane_data(uint8_t &pix); - virtual void draw_tile_pixel(uint8_t pix, int color, pen_t back_pen, uint32_t *&dest, const pen_t *color_table); - virtual void draw_tile(uint8_t *line_priority, int color_byte, int color_bits, int address, int start_x, pen_t back_pen, uint32_t *&dest, const pen_t *color_table); + virtual void draw_tile_pixel(uint8_t pix, int color, uint32_t back_pen, uint32_t *&dest); + virtual void draw_tile(uint8_t *line_priority, int color_byte, int color_bits, int address, int start_x, uint32_t back_pen, uint32_t *&dest); virtual void draw_background( uint8_t *line_priority ); + virtual void draw_back_pen(uint32_t* dst, int back_pen); void draw_background_pen(); virtual void read_sprite_plane_data(int address); @@ -131,6 +130,8 @@ public: void set_vram_dest(uint16_t dest); void ppu2c0x(address_map &map); + + bool in_vblanking() { return (m_scanline >= m_vblank_first_scanline - 1); } protected: ppu2c0x_device(const machine_config& mconfig, device_type type, const char* tag, device_t* owner, uint32_t clock, address_map_constructor internal_map); @@ -184,6 +185,8 @@ protected: required_device<cpu_device> m_cpu; + void start_nopalram(); + int m_scanlines_per_frame; /* number of scanlines per frame */ int m_security_value; /* 2C05 protection */ int m_vblank_first_scanline; /* the very first scanline where VBLANK occurs */ @@ -205,12 +208,12 @@ protected: int m_refresh_data; /* refresh-related */ int m_x_fine; /* refresh-related */ int m_tilecount; /* MMC5 can change attributes to subsets of the 34 visible tiles */ - std::unique_ptr<pen_t[]> m_colortable; /* color table modified at run time */ - std::unique_ptr<pen_t[]> m_colortable_mono; /* monochromatic color table modified at run time */ latch_delegate m_latch; uint8_t readbyte(offs_t address); + + uint32_t m_nespens[0x40*8]; private: static constexpr device_timer_id TIMER_HBLANK = 0; static constexpr device_timer_id TIMER_NMI = 1; @@ -246,7 +249,7 @@ class ppu2c0x_rgb_device : public ppu2c0x_device { protected: ppu2c0x_rgb_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock = 0); - virtual void init_palette() override; + virtual void init_palette_tables() override; private: required_region_ptr<uint8_t> m_palette_data; diff --git a/src/devices/video/ppu2c0x_sh6578.cpp b/src/devices/video/ppu2c0x_sh6578.cpp index c74fa5e54fb..a63fa2a5162 100644 --- a/src/devices/video/ppu2c0x_sh6578.cpp +++ b/src/devices/video/ppu2c0x_sh6578.cpp @@ -51,12 +51,14 @@ void ppu_sh6578_device::ppu_internal_map(address_map& map) void ppu_sh6578_device::device_start() { - ppu2c0x_device::device_start(); + start_nopalram(); m_palette_ram.resize(0x40); for (int i = 0; i < 0x40; i++) m_palette_ram[i] = 0x00; + + save_item(NAME(m_palette_ram)); } void ppu_sh6578_device::device_reset() @@ -89,7 +91,7 @@ void ppu_sh6578_device::scanline_increment_fine_ycounter() void ppu_sh6578_device::draw_sprite_pixel(int sprite_xpos, int color, int pixel, uint8_t pixel_data, bitmap_rgb32& bitmap) { uint8_t palval = m_palette_ram[(pixel_data | color << 2)] & 0x3f; - bitmap.pix32(m_scanline, sprite_xpos + pixel) = this->pen(palval); + bitmap.pix(m_scanline, sprite_xpos + pixel) = m_nespens[palval]; } void ppu_sh6578_device::read_tile_plane_data(int address, int color) @@ -97,15 +99,25 @@ void ppu_sh6578_device::read_tile_plane_data(int address, int color) m_planebuf[0] = readbyte(address); m_planebuf[1] = readbyte(address + 8); - m_extplanebuf[0] = readbyte(address + 16); - m_extplanebuf[1] = readbyte(address + 24); + if (m_colsel_pntstart & 0x80) + { + m_extplanebuf[0] = readbyte(address + 16); + m_extplanebuf[1] = readbyte(address + 24); + } } -void ppu_sh6578_device::draw_tile(uint8_t* line_priority, int color_byte, int color_bits, int address, int start_x, pen_t back_pen, uint32_t*& dest, const pen_t* color_table) +void ppu_sh6578_device::draw_tile(uint8_t* line_priority, int color_byte, int color_bits, int address, int start_x, uint32_t back_pen, uint32_t*& dest) { int color = color_byte; - color &= 0xc; + if (m_colsel_pntstart & 0x80) + { + color &= 0xc; + } + else + { + color &= 0xf; + } read_tile_plane_data(address, color); @@ -116,19 +128,29 @@ void ppu_sh6578_device::draw_tile(uint8_t* line_priority, int color_byte, int co pix = ((m_planebuf[0] & 0x80) >> 7); pix |= ((m_planebuf[1] & 0x80) >> 6); - pix |= ((m_extplanebuf[0] & 0x80) >> 5); - pix |= ((m_extplanebuf[1] & 0x80) >> 4); + + if (m_colsel_pntstart & 0x80) + { + pix |= ((m_extplanebuf[0] & 0x80) >> 5); + pix |= ((m_extplanebuf[1] & 0x80) >> 4); + } m_planebuf[0] <<= 1; m_planebuf[1] <<= 1; - m_extplanebuf[0] <<= 1; - m_extplanebuf[1] <<= 1; + + if (m_colsel_pntstart & 0x80) + { + m_extplanebuf[0] <<= 1; + m_extplanebuf[1] <<= 1; + } if ((start_x + i) >= 0 && (start_x + i) < VISIBLE_SCREEN_WIDTH) { pen_t pen; - uint8_t palval = m_palette_ram[(pix | color << 2)] & 0x3f; + uint8_t palval; + + palval = m_palette_ram[(pix | color << 2)] & 0x3f; bool trans = false; if ((palval & 0x1f) == 0x1f) @@ -136,12 +158,12 @@ void ppu_sh6578_device::draw_tile(uint8_t* line_priority, int color_byte, int co if (!trans) { - pen = this->pen(palval); + pen = m_nespens[palval]; } else { uint8_t palval = m_palette_ram[0x0] & 0x3f; - pen = this->pen(palval); + pen = m_nespens[palval]; } *dest = pen; @@ -158,23 +180,24 @@ void ppu_sh6578_device::draw_background(uint8_t* line_priority) { bitmap_rgb32& bitmap = *m_bitmap; - uint8_t color_mask; - const pen_t* color_table; + uint8_t color_mask = 0xff; + //const pen_t* color_table; /* setup the color mask and colortable to use */ + + //TODO FIX if (m_regs[PPU_CONTROL1] & PPU_CONTROL1_DISPLAY_MONO) { color_mask = 0xf0; - color_table = m_colortable_mono.get(); } else { color_mask = 0xff; - color_table = m_colortable.get(); } + /* cache the background pen */ - pen_t back_pen = pen(m_back_color & color_mask); + pen_t back_pen = m_nespens[m_back_color & color_mask]; /* determine where in the nametable to start drawing from */ /* based on the current scanline and scroll regs */ @@ -190,7 +213,7 @@ void ppu_sh6578_device::draw_background(uint8_t* line_priority) /* set up dest */ int start_x = (m_x_fine ^ 0x07) - 7; - uint32_t* dest = &bitmap.pix32(m_scanline, start_x); + uint32_t* dest = &bitmap.pix(m_scanline, start_x); m_tilecount = 0; @@ -225,7 +248,7 @@ void ppu_sh6578_device::draw_background(uint8_t* line_priority) // plus something that accounts for y address += scroll_y_fine; - draw_tile(line_priority, (color_byte >> 4) & 0xf, 0, address, start_x, back_pen, dest, color_table); + draw_tile(line_priority, (color_byte >> 4) & 0xf, 0, address, start_x, back_pen, dest); start_x += 8; @@ -243,7 +266,7 @@ void ppu_sh6578_device::draw_background(uint8_t* line_priority) /* if the left 8 pixels for the background are off, blank 'em */ if (!(m_regs[PPU_CONTROL1] & PPU_CONTROL1_BACKGROUND_L8)) { - dest = &bitmap.pix32(m_scanline); + dest = &bitmap.pix(m_scanline); for (int i = 0; i < 8; i++) { *(dest++) = back_pen; diff --git a/src/devices/video/ppu2c0x_sh6578.h b/src/devices/video/ppu2c0x_sh6578.h index 9671bf00dfb..34448ac9dfa 100644 --- a/src/devices/video/ppu2c0x_sh6578.h +++ b/src/devices/video/ppu2c0x_sh6578.h @@ -33,7 +33,7 @@ private: void scanline_increment_fine_ycounter() override; void read_tile_plane_data(int address, int color) override; - void draw_tile(uint8_t* line_priority, int color_byte, int color_bits, int address, int start_x, pen_t back_pen, uint32_t*& dest, const pen_t* color_table) override; + void draw_tile(uint8_t* line_priority, int color_byte, int color_bits, int address, int start_x, uint32_t back_pen, uint32_t*& dest) override; virtual void draw_sprite_pixel(int sprite_xpos, int color, int pixel, uint8_t pixel_data, bitmap_rgb32& bitmap) override; //virtual void draw_sprites(uint8_t* line_priority) override; diff --git a/src/devices/video/ppu2c0x_vt.cpp b/src/devices/video/ppu2c0x_vt.cpp index 04da1b8740b..2b8b9b6e3dd 100644 --- a/src/devices/video/ppu2c0x_vt.cpp +++ b/src/devices/video/ppu2c0x_vt.cpp @@ -47,14 +47,10 @@ ppu_vt03pal_device::ppu_vt03pal_device(const machine_config& mconfig, const char uint8_t ppu_vt03_device::palette_read(offs_t offset) { - if (m_201x_regs[0] & 0x80) - { - return m_newpal[offset]; - } - else - { + if (offset < 0x20) return ppu2c0x_device::palette_read(offset); - } + else + return m_palette_ram[offset]; } void ppu_vt03_device::set_201x_descramble(uint8_t reg0, uint8_t reg1, uint8_t reg2, uint8_t reg3, uint8_t reg4, uint8_t reg5) @@ -67,110 +63,17 @@ void ppu_vt03_device::set_201x_descramble(uint8_t reg0, uint8_t reg1, uint8_t re m_2012_2017_descramble[5] = reg5; } -void ppu_vt03_device::set_new_pen(int i) -{ - if ((i < 0x20) && ((i & 0x3) == 0)) - { - set_pen_color(i & 0x7f, rgb_t(0, 0, 0)); - } - else - { - if (m_pal_mode == PAL_MODE_NEW_RGB) - { - uint16_t rgbval = (m_newpal[i & 0x7f] & 0xff) | ((m_newpal[(i & 0x7f) + 0x80] & 0xff) << 8); - uint8_t blue = (rgbval & 0x001f) << 3; - uint8_t green = (rgbval & 0x3e0) >> 2; - uint8_t red = (rgbval & 0x7C00) >> 7; - set_pen_color(i & 0x7f, rgb_t(red, green, blue)); - } - else if (m_pal_mode == PAL_MODE_NEW_RGB12) - { - uint16_t rgbval = (m_newpal[i & 0x7f] & 0x3f) | ((m_newpal[(i & 0x7f) + 0x80] & 0x3f) << 6); - uint8_t red = (rgbval & 0x000f) << 4; - uint8_t green = (rgbval & 0x0f0); - uint8_t blue = (rgbval & 0xf00) >> 4; - set_pen_color(i & 0x7f, rgb_t(red, green, blue)); - } - else - { - // Credit to NewRisingSun - uint16_t palval = (m_newpal[i & 0x7f] & 0x3f) | ((m_newpal[(i & 0x7f) + 0x80] & 0x3f) << 6); - int nPhase = (palval >> 0) & 0xF; - int nLuma = (palval >> 4) & 0xF; - int nChroma = (palval >> 8) & 0xF; - float phaseOffset = -11.0; - //bool inverted = false; - if ((nLuma < (nChroma + 1) >> 1 || nLuma > 15 - (nChroma >> 1)) && (m_pal_mode != PAL_MODE_NEW_VG)) - { - //inverted = true; - // Strange color number wrap-around. Is this for protection reasons, or a bug of the original hardware? - // The VT03 data sheet advises programmers that 4 <= nLuma*2 +nChroma <= 0x1F, which does not correspond exactly to this condition. - static const unsigned char altPhases[16] = { 13, 7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 6, 0, 14, 15 }; - static const float altPhaseOffset[16] = { -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, 0, -5, -5, -5 }; // Slight tweak in phase 6 for Z-Dog - phaseOffset += altPhaseOffset[nPhase]; // These "alternative" colors seem to be slightly shifted in addition to being wrapped-around, at least in EmuVT. - nPhase = altPhases[nPhase]; - nChroma = 16 - nChroma; - nLuma = (nLuma - 8) & 0xF; - } - - float fLuma = (nLuma - 4) / 9.625; // Value determined from matching saturation =0 phases 1-12 - float fChroma = nChroma / 18.975; // Value determined from matching phases 0 and 13 across all luminance and saturation levels - float fPhase = ((nPhase - 2) * 30.0 + phaseOffset) * M_PI / 180.0; - - if (m_pal_mode == PAL_MODE_NEW_VG) - { - if (fPhase > 0 && fPhase < 13) - { - fLuma /= 1.5; - fChroma /= 2; - } - } - - float Y = fLuma; - float C = fChroma; - if (nPhase == 0 || nPhase > 12) C = 0.0;// Phases 0 and 13-15 are grays - if (nPhase == 0) Y += fChroma; // Phase 0 is the upper bound of the waveform - if (nPhase == 13) Y -= fChroma; // Phase 13 is the lower bound of the waveform - if (nPhase >= 14) Y = 0.0; // Phases 14 and 15 always black - - float V = sin(fPhase) * C * 1.05; // 1.05 needed to get closer to EmuVT palette's color levels in phases 1-12 - float U = cos(fPhase) * C * 1.05; - float R = Y + 1.1400 * V + 0.0000 * U; - float G = Y - 0.5807 * V - 0.3940 * U; - float B = Y - 0.0000 * V + 2.0290 * U; - if (R < 0.0) R = 0.0; - if (R > 1.0) R = 1.0; - if (G < 0.0) G = 0.0; - if (G > 1.0) G = 1.0; - if (B < 0.0) B = 0.0; - if (B > 1.0) B = 1.0; - int RV = R * 255.0; - int GV = G * 255.0; - int BV = B * 255.0; - - set_pen_color(i & 0x7f, rgb_t(RV, GV, BV)); - } - } -} - void ppu_vt03_device::palette_write(offs_t offset, uint8_t data) { - //logerror("pal write %d %02x\n", offset, data); - // why is the check pal_mask = (m_pal_mode == PAL_MODE_NEW_VG) ? 0x08 : 0x80 in set_2010_reg and 0x04 : 0x80 here? - uint8_t pal_mask = (m_pal_mode == PAL_MODE_NEW_VG) ? 0x04 : 0x80; - - if (m_201x_regs[0] & pal_mask) + if (offset < 0x20) { - m_newpal[offset & 0xff] = data; - set_new_pen(offset); + ppu2c0x_device::palette_write(offset, data); } else { - //if(m_pal_mode == PAL_MODE_NEW_VG) // ddrdismx writes the palette before setting the register but doesn't use 'PAL_MODE_NEW_VG', Konami logo is missing if you don't allow writes to be stored for when we switch - m_newpal[offset & 0xff] = data; - ppu2c0x_device::palette_write(offset, data); + m_palette_ram[offset] = data; } } @@ -235,20 +138,131 @@ uint8_t ppu_vt03_device::read_extended(offs_t offset) } -void ppu_vt03_device::init_palette() + +void ppu_vt03_device::init_vtxx_rgb555_palette_tables() { - // todo, work out the format of the 12 palette bits instead of just calling the main init - ppu2c0x_device::init_palette(true); + int entry = 0; + for (int emp = 0; emp < 8; emp++) + { + for (int palval = 0; palval < 0x8000; palval++) + { + // uint16_t rgbval = (m_palette_ram[i & 0x7f] & 0xff) | ((m_palette_ram[(i & 0x7f) + 0x80] & 0xff) << 8); + uint8_t blue = (palval & 0x001f) << 3; + uint8_t green = (palval & 0x3e0) >> 2; + uint8_t red = (palval & 0x7C00) >> 7; + + // TODO: apply emphasis values if they work in this mode + m_vtpens_rgb555[entry] = rgb_t(red, green, blue); + entry++; + } + } +} + +void ppu_vt03_device::init_vtxx_rgb444_palette_tables() +{ + int entry = 0; + for (int emp = 0; emp < 8; emp++) + { + for (int palval = 0; palval < 0x1000; palval++) + { + //uint16_t rgbval = (m_palette_ram[i & 0x7f] & 0x3f) | ((m_palette_ram[(i & 0x7f) + 0x80] & 0x3f) << 6); + uint8_t red = (palval & 0x000f) << 4; + uint8_t green = (palval & 0x0f0); + uint8_t blue = (palval & 0xf00) >> 4; + + // TODO: apply emphasis values if they work in this mode + m_vtpens_rgb444[entry] = rgb_t(red, green, blue); + entry++; + } + } +} +// what cases are palmode 1 anyway? +void ppu_vt03_device::init_vt03_palette_tables(int palmode) +{ + // the 12-bit VT HSV format, Credit to NewRisingSun + int entry = 0; + for (int color_emphasis = 0; color_emphasis < 8; color_emphasis++) + { + for (int palval = 0; palval < 0x1000; palval++) + { + int nPhase = (palval >> 0) & 0xF; + int nLuma = (palval >> 4) & 0xF; + int nChroma = (palval >> 8) & 0xF; + float phaseOffset = -11.0; + //bool inverted = false; + if ((nLuma < (nChroma + 1) >> 1 || nLuma > 15 - (nChroma >> 1)) && (palmode != 1)) + { + //inverted = true; + // Strange color number wrap-around. Is this for protection reasons, or a bug of the original hardware? + // The VT03 data sheet advises programmers that 4 <= nLuma*2 +nChroma <= 0x1F, which does not correspond exactly to this condition. + static const unsigned char altPhases[16] = { 13, 7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 6, 0, 14, 15 }; + static const float altPhaseOffset[16] = { -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, 0, -5, -5, -5 }; // Slight tweak in phase 6 for Z-Dog + phaseOffset += altPhaseOffset[nPhase]; // These "alternative" colors seem to be slightly shifted in addition to being wrapped-around, at least in EmuVT. + nPhase = altPhases[nPhase]; + nChroma = 16 - nChroma; + nLuma = (nLuma - 8) & 0xF; + } + + float fLuma = (nLuma - 4) / 9.625; // Value determined from matching saturation =0 phases 1-12 + float fChroma = nChroma / 18.975; // Value determined from matching phases 0 and 13 across all luminance and saturation levels + float fPhase = ((nPhase - 2) * 30.0 + phaseOffset) * M_PI / 180.0; + + if (palmode == 1) + { + if (fPhase > 0 && fPhase < 13) + { + fLuma /= 1.5; + fChroma /= 2; + } + } + + float Y = fLuma; + float C = fChroma; + if (nPhase == 0 || nPhase > 12) C = 0.0;// Phases 0 and 13-15 are grays + if (nPhase == 0) Y += fChroma; // Phase 0 is the upper bound of the waveform + if (nPhase == 13) Y -= fChroma; // Phase 13 is the lower bound of the waveform + if (nPhase >= 14) Y = 0.0; // Phases 14 and 15 always black + + float V = sin(fPhase) * C * 1.05; // 1.05 needed to get closer to EmuVT palette's color levels in phases 1-12 + float U = cos(fPhase) * C * 1.05; + float R = Y + 1.1400 * V + 0.0000 * U; + float G = Y - 0.5807 * V - 0.3940 * U; + float B = Y - 0.0000 * V + 2.0290 * U; + if (R < 0.0) R = 0.0; + if (R > 1.0) R = 1.0; + if (G < 0.0) G = 0.0; + if (G > 1.0) G = 1.0; + if (B < 0.0) B = 0.0; + if (B > 1.0) B = 1.0; + int RV = R * 255.0; + int GV = G * 255.0; + int BV = B * 255.0; + + // does this really apply to the VT palette? + //bool is_pal = m_scanlines_per_frame != NTSC_SCANLINES_PER_FRAME; + //apply_color_emphasis_and_clamp(is_pal, color_emphasis, R, G, B); + + m_vtpens[entry] = rgb_t(RV, GV, BV); + entry++; + } + } } void ppu_vt03_device::device_start() { - ppu2c0x_device::device_start(); + start_nopalram(); + + m_palette_ram.resize(0x100); - m_newpal = std::make_unique<uint8_t[]>(0x100); - save_pointer(NAME(m_newpal), 0x100); + for (int i = 0; i < 0x100; i++) + m_palette_ram[i] = 0x00; + save_item(NAME(m_palette_ram)); save_item(NAME(m_201x_regs)); + + init_vt03_palette_tables(0); + init_vtxx_rgb555_palette_tables(); + init_vtxx_rgb444_palette_tables(); } uint8_t ppu_vt03_device::get_201x_reg(int reg) @@ -270,16 +284,12 @@ void ppu_vt03_device::device_reset() m_read_bg.resolve_safe(0); m_read_sp.resolve_safe(0); for (int i = 0; i < 0xff; i++) - m_newpal[i] = 0x0; + m_palette_ram[i] = 0x0; // todo: what are the actual defaults for these? for (int i = 0; i < 0x20; i++) set_201x_reg(i, 0x00); - //m_201x_regs[0] = 0x86; // alt fix for ddrdismx would be to set the default palette mode here - - init_palette(); - m_read_bg4_bg3 = 0; m_va34 = 0; } @@ -353,7 +363,8 @@ void ppu_vt03_device::draw_sprite_pixel(int sprite_xpos, int color, int pixel, u { if (!is16pix) { - bitmap.pix32(m_scanline, sprite_xpos + pixel) = pen(pixel_data + (4 * color)); + uint8_t pen = pixel_data + (4 * color); + draw_tile_pixel_inner(pen, &bitmap.pix(m_scanline, sprite_xpos + pixel)); } else { @@ -361,9 +372,16 @@ void ppu_vt03_device::draw_sprite_pixel(int sprite_xpos, int color, int pixel, u we probably need to split them out again and draw them at xpos+8 with a cliprect - not seen used yet */ if ((pixel_data & 0x03) != 0) - bitmap.pix32(m_scanline, sprite_xpos + pixel) = pen((pixel_data & 0x03) + (4 * color)); + { + uint8_t pen = (pixel_data & 0x03) + (4 * color); + draw_tile_pixel_inner(pen, &bitmap.pix(m_scanline, sprite_xpos + pixel)); + } + if (((pixel_data >> 5) & 0x03) != 0) - bitmap.pix32(m_scanline, sprite_xpos + pixel + 8) = pen(((pixel_data >> 5) & 0x03) + (4 * color)); + { + uint8_t pen = ((pixel_data >> 5) & 0x03) + (4 * color); + draw_tile_pixel_inner(pen, &bitmap.pix(m_scanline, sprite_xpos + pixel + 8)); + } //ppu2c0x_device::draw_sprite_pixel(sprite_xpos, color, pixel, pixel_data & 0x03, bitmap); //ppu2c0x_device::draw_sprite_pixel(sprite_xpos, color, pixel + 8, (pixel_data >> 5) & 0x03, bitmap); } @@ -414,13 +432,100 @@ void ppu_vt03_device::shift_tile_plane_data(uint8_t& pix) } } -void ppu_vt03_device::draw_tile_pixel(uint8_t pix, int color, pen_t back_pen, uint32_t*& dest, const pen_t* color_table) + +void ppu_vt03_device::draw_back_pen(uint32_t* dst, int back_pen) +{ + if (m_201x_regs[0] & 0x80) + { + // is the back_pen always just pen 0 in VT modes? (using last data written to a transparent pen as per NES logic doesn't work as writes are split across 2 bytes) + draw_tile_pixel_inner(0, dst); + } + else + { + // in normal modes we still have the data from the palette writes as the 'backpen' so treat it as before + uint32_t pix; + pix = m_nespens[back_pen & 0x1ff]; + *dst = pix; + } +} + + +void ppu_vt03_device::draw_tile_pixel_inner(uint8_t pen, uint32_t *dest) +{ + if (m_201x_regs[0] & 0x80) + { + if (m_pal_mode == PAL_MODE_NEW_RGB) // unknown newer VT mode + { + uint32_t palval; + palval = (m_palette_ram[pen & 0x7f] & 0xff) | ((m_palette_ram[(pen & 0x7f) + 0x80] & 0x7f) << 8); + + // does grayscale mode exist here? (we haven't calculated any colours for it) + //if (m_regs[PPU_CONTROL1] & PPU_CONTROL1_DISPLAY_MONO) + // palval &= 0x30; + + // apply colour emphasis (does it really exist here?) (we haven't calculated any colours for it, so ths has no effect) + palval |= ((m_regs[PPU_CONTROL1] & PPU_CONTROL1_COLOR_EMPHASIS) << 10); + + uint32_t pix; + pix = m_vtpens_rgb555[palval & 0x3ffff]; + *dest = pix; + } + else if (m_pal_mode == PAL_MODE_NEW_RGB12) // unknown newer VT mode + { + uint32_t palval; + palval = (m_palette_ram[pen & 0x7f] & 0x3f) | ((m_palette_ram[(pen & 0x7f) + 0x80] & 0x3f) << 6); + + // does grayscale mode exist here? (we haven't calculated any colours for it) + //if (m_regs[PPU_CONTROL1] & PPU_CONTROL1_DISPLAY_MONO) + // palval &= 0x30; + + // apply colour emphasis (does it really exist here?) (we haven't calculated any colours for it, so ths has no effect) + palval |= ((m_regs[PPU_CONTROL1] & PPU_CONTROL1_COLOR_EMPHASIS) << 7); + + uint32_t pix; + pix = m_vtpens_rgb444[palval & 0x7fff]; + *dest = pix; + } + else // VT03 mode + { + uint32_t palval; + palval = (m_palette_ram[pen & 0x7f] & 0x3f) | ((m_palette_ram[(pen & 0x7f) + 0x80] & 0x3f) << 6); + + // does grayscale mode exist here? (we haven't calculated any colours for it) + //if (m_regs[PPU_CONTROL1] & PPU_CONTROL1_DISPLAY_MONO) + // palval &= 0x30; + + // apply colour emphasis (does it really exist here?) (we calculate values for it when building the palette lookup) + palval |= ((m_regs[PPU_CONTROL1] & PPU_CONTROL1_COLOR_EMPHASIS) << 7); + + uint32_t pix; + pix = m_vtpens[palval & 0x7fff]; + *dest = pix; + } + } + else // old colour compatible mode + { + uint16_t palval; + palval = (m_palette_ram[pen & 0x7f] & 0x3f); + + if (m_regs[PPU_CONTROL1] & PPU_CONTROL1_DISPLAY_MONO) + palval &= 0x30; + + // apply colour emphasis + palval |= ((m_regs[PPU_CONTROL1] & PPU_CONTROL1_COLOR_EMPHASIS) << 1); + + uint32_t pix; + pix = m_nespens[palval & 0x1ff]; + *dest = pix; + } +} +void ppu_vt03_device::draw_tile_pixel(uint8_t pix, int color, uint32_t back_pen, uint32_t*& dest) { int is4bpp = get_201x_reg(0x0) & 0x02; if (!is4bpp) { - ppu2c0x_device::draw_tile_pixel(pix, color, back_pen, dest, color_table); + ppu2c0x_device::draw_tile_pixel(pix, color, back_pen, dest); } else { @@ -442,9 +547,10 @@ void ppu_vt03_device::draw_tile_pixel(uint8_t pix, int color, pen_t back_pen, ui } else { - pen = 0; // fixme backpen logic probably differs on vt03 due to extra colours + pen = 0; // back_pen; // fixme backpen logic probably differs on vt03 due to extra colours } - *dest = this->pen(pen); + + draw_tile_pixel_inner(pen, dest); } } @@ -468,24 +574,6 @@ void ppu_vt03_device::set_2010_reg(uint8_t data) 2 : SP16EN 1 : BK16EN 0 : PIX16EN */ - uint8_t pal_mask = (m_pal_mode == PAL_MODE_NEW_VG) ? 0x08 : 0x80; - if ((m_201x_regs[0x0] & pal_mask) != (data & pal_mask)) - { - if (data & pal_mask) - { - for (int i = 0; i < 256; i++) - { - set_new_pen(i); - } - } - else - { - for (int i = 0; i < 256; i++) - { - set_pen_indirect(i, i); - } - } - } m_201x_regs[0x0] = data; } diff --git a/src/devices/video/ppu2c0x_vt.h b/src/devices/video/ppu2c0x_vt.h index c238f91b031..f63da1ebdf1 100644 --- a/src/devices/video/ppu2c0x_vt.h +++ b/src/devices/video/ppu2c0x_vt.h @@ -19,7 +19,6 @@ enum vtxx_pal_mode { PAL_MODE_VT0x, PAL_MODE_NEW_RGB, - PAL_MODE_NEW_VG, PAL_MODE_NEW_RGB12, }; @@ -40,13 +39,15 @@ public: virtual uint8_t palette_read(offs_t offset) override; virtual void palette_write(offs_t offset, uint8_t data) override; - virtual uint32_t palette_entries() const override { return 256; } - virtual uint32_t palette_indirect_entries() const override { return 4*16*8; } - virtual void init_palette() override; + void init_vt03_palette_tables(int palmode); + void init_vtxx_rgb555_palette_tables(); + void init_vtxx_rgb444_palette_tables(); virtual void read_tile_plane_data(int address, int color) override; virtual void shift_tile_plane_data(uint8_t &pix) override; - virtual void draw_tile_pixel(uint8_t pix, int color, pen_t back_pen, uint32_t *&dest, const pen_t *color_table) override; + virtual void draw_tile_pixel(uint8_t pix, int color, uint32_t back_pen, uint32_t *&dest) override; + inline void draw_tile_pixel_inner(uint8_t pen, uint32_t *dest); + virtual void draw_back_pen(uint32_t* dst, int back_pen) override; virtual void read_sprite_plane_data(int address) override; virtual void make_sprite_pixel_data(uint8_t &pixel_data, int flipx) override; @@ -70,12 +71,14 @@ protected: bool m_is_pal; bool m_is_50hz; + uint32_t m_vtpens[0x1000*8]; + uint32_t m_vtpens_rgb555[0x8000*8]; + uint32_t m_vtpens_rgb444[0x1000*8]; + private: devcb_read8 m_read_bg; devcb_read8 m_read_sp; - std::unique_ptr<uint8_t[]> m_newpal; - int m_read_bg4_bg3; int m_va34; @@ -89,8 +92,6 @@ private: vtxx_pal_mode m_pal_mode = PAL_MODE_VT0x; void set_2010_reg(uint8_t data); - - void set_new_pen(int i); }; class ppu_vt03pal_device : public ppu_vt03_device { diff --git a/src/devices/video/psx.cpp b/src/devices/video/psx.cpp index 83cd0e5c02d..b73adb2a319 100644 --- a/src/devices/video/psx.cpp +++ b/src/devices/video/psx.cpp @@ -265,8 +265,8 @@ void psxgpu_device::DebugMesh( int n_coordx, int n_coordy ) (int16_t)n_x.w.h <= width - 1 && (int16_t)n_y.w.h <= height - 1 ) { - if( m_debug.mesh->pix16( n_y.w.h, n_x.w.h ) != 0xffff ) - m_debug.mesh->pix16( n_y.w.h, n_x.w.h ) = n_colour; + if( m_debug.mesh->pix( n_y.w.h, n_x.w.h ) != 0xffff ) + m_debug.mesh->pix( n_y.w.h, n_x.w.h ) = n_colour; } n_x.d += n_dx; @@ -364,7 +364,7 @@ int psxgpu_device::DebugMeshDisplay( bitmap_rgb32 &bitmap, const rectangle &clip if( m_debug.b_mesh ) { for( int y = cliprect.min_y; y <= cliprect.max_y; y++ ) - draw_scanline16( bitmap, cliprect.min_x, y, cliprect.max_x + 1 - cliprect.min_x, &m_debug.mesh->pix16( y ), pens() ); + draw_scanline16( bitmap, cliprect.min_x, y, cliprect.max_x + 1 - cliprect.min_x, &m_debug.mesh->pix( y ), pens() ); } m_debug.b_clear = 1; @@ -772,7 +772,7 @@ uint32_t psxgpu_device::update_screen(screen_device &screen, bitmap_rgb32 &bitma while( n_line > 0 ) { uint16_t *p_n_src = p_p_vram[ n_y + n_displaystarty ] + 3 * n_x + n_displaystartx; - uint32_t *p_n_dest = &bitmap.pix32(n_y + n_top, n_x + n_left); + uint32_t *p_n_dest = &bitmap.pix(n_y + n_top, n_x + n_left); n_column = n_columns; while( n_column > 0 ) diff --git a/src/devices/video/saa5050.cpp b/src/devices/video/saa5050.cpp index 77af6be01ea..b873edfbbb9 100644 --- a/src/devices/video/saa5050.cpp +++ b/src/devices/video/saa5050.cpp @@ -661,9 +661,7 @@ uint32_t saa5050_device::screen_update(screen_device &screen, bitmap_rgb32 &bitm int g = BIT(color, 1) * 0xff; int b = BIT(color, 2) * 0xff; - rgb_t rgb = rgb_t(r, g, b); - - bitmap.pix32(y, x++) = rgb; + bitmap.pix(y, x++) = rgb_t(r, g, b); } } } diff --git a/src/devices/video/scn2674.cpp b/src/devices/video/scn2674.cpp index 17fc68c6b9a..96e1e7d3ca5 100644 --- a/src/devices/video/scn2674.cpp +++ b/src/devices/video/scn2674.cpp @@ -1178,7 +1178,7 @@ TIMER_CALLBACK_MEMBER(scn2674_device::scanline_timer) } if (!m_display_enabled) - std::fill_n(&m_bitmap.pix32(m_linecounter), m_character_per_row * m_hpixels_per_column, rgb_t::black()); + std::fill_n(&m_bitmap.pix(m_linecounter), m_character_per_row * m_hpixels_per_column, rgb_t::black()); if (m_gfx_enabled || (charrow == (m_scanline_per_char_row - 1))) m_address = address; diff --git a/src/devices/video/sed1330.cpp b/src/devices/video/sed1330.cpp index 101ebe72944..37d95caac7b 100644 --- a/src/devices/video/sed1330.cpp +++ b/src/devices/video/sed1330.cpp @@ -605,7 +605,7 @@ void sed1330_device::data_w(uint8_t data) void sed1330_device::draw_text_scanline(bitmap_ind16 &bitmap, const rectangle &cliprect, int y, int r, uint16_t va, bool cursor) { - uint16_t *p = &bitmap.pix16(y, 0); + uint16_t *p = &bitmap.pix(y); for (int sx = 0; sx < m_cr; sx++, p += m_fx) { @@ -653,7 +653,7 @@ void sed1330_device::draw_graphics_scanline(bitmap_ind16 &bitmap, const rectangl for (int x = 0; x < m_fx; x++) { - bitmap.pix16(y, (sx * m_fx) + x) = BIT(data, 7); + bitmap.pix(y, (sx * m_fx) + x) = BIT(data, 7); data <<= 1; } } diff --git a/src/devices/video/snes_ppu.cpp b/src/devices/video/snes_ppu.cpp index a74f7af905d..e0b4eb544b1 100644 --- a/src/devices/video/snes_ppu.cpp +++ b/src/devices/video/snes_ppu.cpp @@ -1251,7 +1251,7 @@ void snes_ppu_device::refresh_scanline( bitmap_rgb32 &bitmap, uint16_t curline ) if (m_screen_disabled) /* screen is forced blank */ for (int x = 0; x < SNES_SCR_WIDTH * 2; x++) - bitmap.pix32(0, x) = rgb_t::black(); + bitmap.pix(0, x) = rgb_t::black(); else { uint8_t window_above[256]; @@ -1323,8 +1323,8 @@ void snes_ppu_device::refresh_scanline( bitmap_rgb32 &bitmap, uint16_t curline ) const int g = (c & 0x3e0) >> 5; const int b = (c & 0x7c00) >> 10; - bitmap.pix32(0, x * 2 + 0) = rgb_t(pal5bit(r), pal5bit(g), pal5bit(b)); - bitmap.pix32(0, x * 2 + 1) = rgb_t(pal5bit(r), pal5bit(g), pal5bit(b)); + bitmap.pix(0, x * 2 + 0) = rgb_t(pal5bit(r), pal5bit(g), pal5bit(b)); + bitmap.pix(0, x * 2 + 1) = rgb_t(pal5bit(r), pal5bit(g), pal5bit(b)); } else if (!blurring) { @@ -1337,8 +1337,8 @@ void snes_ppu_device::refresh_scanline( bitmap_rgb32 &bitmap, uint16_t curline ) const int b0 = (c0 & 0x7c00) >> 10; const int b1 = (c1 & 0x7c00) >> 10; - bitmap.pix32(0, x * 2 + 0) = rgb_t(pal5bit(r0), pal5bit(g0), pal5bit(b0)); - bitmap.pix32(0, x * 2 + 1) = rgb_t(pal5bit(r1), pal5bit(g1), pal5bit(b1)); + bitmap.pix(0, x * 2 + 0) = rgb_t(pal5bit(r0), pal5bit(g0), pal5bit(b0)); + bitmap.pix(0, x * 2 + 1) = rgb_t(pal5bit(r1), pal5bit(g1), pal5bit(b1)); } else { @@ -1348,7 +1348,7 @@ void snes_ppu_device::refresh_scanline( bitmap_rgb32 &bitmap, uint16_t curline ) const int r0 = (c0 & 0x1f); const int g0 = (c0 & 0x3e0) >> 5; const int b0 = (c0 & 0x7c00) >> 10; - bitmap.pix32(0, x * 2 + 0) = rgb_t(pal5bit(r0), pal5bit(g0), pal5bit(b0)); + bitmap.pix(0, x * 2 + 0) = rgb_t(pal5bit(r0), pal5bit(g0), pal5bit(b0)); prev = curr; curr = luma[pixel(x, above, below, window_above, window_below)]; @@ -1357,7 +1357,7 @@ void snes_ppu_device::refresh_scanline( bitmap_rgb32 &bitmap, uint16_t curline ) const int r1 = (c1 & 0x1f); const int g1 = (c1 & 0x3e0) >> 5; const int b1 = (c1 & 0x7c00) >> 10; - bitmap.pix32(0, x * 2 + 1) = rgb_t(pal5bit(r1), pal5bit(g1), pal5bit(b1)); + bitmap.pix(0, x * 2 + 1) = rgb_t(pal5bit(r1), pal5bit(g1), pal5bit(b1)); prev = curr; } diff --git a/src/devices/video/stvvdp2.cpp b/src/devices/video/stvvdp2.cpp index 473fa710f7d..f79f0aec207 100644 --- a/src/devices/video/stvvdp2.cpp +++ b/src/devices/video/stvvdp2.cpp @@ -2530,11 +2530,11 @@ void saturn_state::stv_vdp2_drawgfxzoom( { for( y=sy; y<ey; y++ ) { - const uint8_t *source = source_base + (y_index>>16) * gfx->rowbytes(); - uint32_t *dest = &dest_bmp.pix32(y); + uint8_t const *const source = source_base + (y_index>>16) * gfx->rowbytes(); + uint32_t *const dest = &dest_bmp.pix(y); - int x, x_index = x_index_base; - for( x=sx; x<ex; x++ ) + int x_index = x_index_base; + for( int x=sx; x<ex; x++ ) { if(stv_vdp2_window_process(x,y)) { @@ -2552,11 +2552,11 @@ void saturn_state::stv_vdp2_drawgfxzoom( { for( y=sy; y<ey; y++ ) { - const uint8_t *source = source_base + (y_index>>16) * gfx->rowbytes(); - uint32_t *dest = &dest_bmp.pix32(y); + uint8_t const *const source = source_base + (y_index>>16) * gfx->rowbytes(); + uint32_t *const dest = &dest_bmp.pix(y); - int x, x_index = x_index_base; - for( x=sx; x<ex; x++ ) + int x_index = x_index_base; + for( int x=sx; x<ex; x++ ) { if(stv_vdp2_window_process(x,y)) { @@ -2574,11 +2574,11 @@ void saturn_state::stv_vdp2_drawgfxzoom( { for( y=sy; y<ey; y++ ) { - const uint8_t *source = source_base + (y_index>>16) * gfx->rowbytes(); - uint32_t *dest = &dest_bmp.pix32(y); + uint8_t const *const source = source_base + (y_index>>16) * gfx->rowbytes(); + uint32_t *const dest = &dest_bmp.pix(y); - int x, x_index = x_index_base; - for( x=sx; x<ex; x++ ) + int x_index = x_index_base; + for( int x=sx; x<ex; x++ ) { if(stv_vdp2_window_process(x,y)) { @@ -2716,17 +2716,16 @@ void saturn_state::stv_vdp2_drawgfxzoom_rgb555( { for( y=sy; y<ey; y++ ) { - const uint8_t *source = gfxdata + (y_index>>16)*16; - uint32_t *dest = &dest_bmp.pix32(y); - int r,g,b,data; + uint8_t const *const source = gfxdata + (y_index>>16)*16; + uint32_t *const dest = &dest_bmp.pix(y); - int x, x_index = x_index_base; - for( x=sx; x<ex; x++ ) + int x_index = x_index_base; + for( int x=sx; x<ex; x++ ) { - data = (source[(x_index>>16)*2] << 8) | source[(x_index>>16)*2+1]; - b = pal5bit((data & 0x7c00) >> 10); - g = pal5bit((data & 0x03e0) >> 5); - r = pal5bit( data & 0x001f); + int data = (source[(x_index>>16)*2] << 8) | source[(x_index>>16)*2+1]; + int b = pal5bit((data & 0x7c00) >> 10); + int g = pal5bit((data & 0x03e0) >> 5); + int r = pal5bit( data & 0x001f); if(stv2_current_tilemap.fade_control & 1) stv_vdp2_compute_color_offset(&r,&g,&b,stv2_current_tilemap.fade_control & 2); @@ -2743,17 +2742,16 @@ void saturn_state::stv_vdp2_drawgfxzoom_rgb555( { for( y=sy; y<ey; y++ ) { - const uint8_t *source = gfxdata + (y_index>>16)*16; - uint32_t *dest = &dest_bmp.pix32(y); - int r,g,b,data; + uint8_t const *const source = gfxdata + (y_index>>16)*16; + uint32_t *const dest = &dest_bmp.pix(y); - int x, x_index = x_index_base; - for( x=sx; x<ex; x++ ) + int x_index = x_index_base; + for( int x=sx; x<ex; x++ ) { - data = (source[(x_index*2+0)>>16]<<0)|(source[(x_index*2+1)>>16]<<8); - b = pal5bit((data & 0x7c00) >> 10); - g = pal5bit((data & 0x03e0) >> 5); - r = pal5bit( data & 0x001f); + int data = (source[(x_index*2+0)>>16]<<0)|(source[(x_index*2+1)>>16]<<8); + int b = pal5bit((data & 0x7c00) >> 10); + int g = pal5bit((data & 0x03e0) >> 5); + int r = pal5bit( data & 0x001f); if(stv2_current_tilemap.fade_control & 1) stv_vdp2_compute_color_offset(&r,&g,&b,stv2_current_tilemap.fade_control & 2); @@ -2770,17 +2768,16 @@ void saturn_state::stv_vdp2_drawgfxzoom_rgb555( { for( y=sy; y<ey; y++ ) { - const uint8_t *source = gfxdata + (y_index>>16)*16; - uint32_t *dest = &dest_bmp.pix32(y); - int r,g,b,data; + uint8_t const *const source = gfxdata + (y_index>>16)*16; + uint32_t *const dest = &dest_bmp.pix(y); - int x, x_index = x_index_base; - for( x=sx; x<ex; x++ ) + int x_index = x_index_base; + for( int x=sx; x<ex; x++ ) { - data = (source[(x_index>>16)*2] << 8) | source[(x_index>>16)*2+1]; - b = pal5bit((data & 0x7c00) >> 10); - g = pal5bit((data & 0x03e0) >> 5); - r = pal5bit( data & 0x001f); + int data = (source[(x_index>>16)*2] << 8) | source[(x_index>>16)*2+1]; + int b = pal5bit((data & 0x7c00) >> 10); + int g = pal5bit((data & 0x03e0) >> 5); + int r = pal5bit( data & 0x001f); if(stv2_current_tilemap.fade_control & 1) stv_vdp2_compute_color_offset(&r,&g,&b,stv2_current_tilemap.fade_control & 2); @@ -2877,21 +2874,18 @@ void saturn_state::stv_vdp2_drawgfx_rgb555( bitmap_rgb32 &dest_bmp, const rectan for( y=sy; y<ey; y++ ) { - const uint8_t *source = gfxdata + (y_index>>16)*16; - uint32_t *dest = &dest_bmp.pix32(y); - uint16_t data; + uint8_t const *const source = gfxdata + (y_index>>16)*16; + uint32_t *const dest = &dest_bmp.pix(y); - int x, x_index = x_index_base; - for( x=sx; x<ex; x++ ) + int x_index = x_index_base; + for( int x=sx; x<ex; x++ ) { - int r,g,b; - - data = (source[(x_index>>16)*2] << 8) | source[(x_index>>16)*2+1]; + uint16_t data = (source[(x_index>>16)*2] << 8) | source[(x_index>>16)*2+1]; if ((data & 0x8000) || (transparency & STV_TRANSPARENCY_NONE)) { - b = pal5bit((data & 0x7c00) >> 10); - g = pal5bit((data & 0x03e0) >> 5); - r = pal5bit( data & 0x001f); + int b = pal5bit((data & 0x7c00) >> 10); + int g = pal5bit((data & 0x03e0) >> 5); + int r = pal5bit( data & 0x001f); if(stv2_current_tilemap.fade_control & 1) stv_vdp2_compute_color_offset(&r,&g,&b,stv2_current_tilemap.fade_control & 2); @@ -2986,26 +2980,21 @@ void saturn_state::stv_vdp2_drawgfx_rgb888( bitmap_rgb32 &dest_bmp, const rectan if( ex>sx ) { /* skip if inner loop doesn't draw anything */ - int y; - - for( y=sy; y<ey; y++ ) + for( int y=sy; y<ey; y++ ) { - const uint8_t *source = gfxdata + (y_index>>16)*32; - uint32_t *dest = &dest_bmp.pix32(y); - uint32_t data; + uint8_t const *const source = gfxdata + (y_index>>16)*32; + uint32_t *const dest = &dest_bmp.pix(y); - int x, x_index = x_index_base; + int x_index = x_index_base; - for( x=sx; x<ex; x++ ) + for( int x=sx; x<ex; x++ ) { - int r,g,b; - - data = (source[(x_index>>16)*4+0] << 24) | (source[(x_index>>16)*4+1] << 16) | (source[(x_index>>16)*4+2] << 8) | (source[(x_index>>16)*4+3] << 0); + uint32_t data = (source[(x_index>>16)*4+0] << 24) | (source[(x_index>>16)*4+1] << 16) | (source[(x_index>>16)*4+2] << 8) | (source[(x_index>>16)*4+3] << 0); if ((data & 0x80000000) || (transparency & STV_TRANSPARENCY_NONE)) { - b = (data & 0xff0000) >> 16; - g = (data & 0x00ff00) >> 8; - r = (data & 0x0000ff); + int b = (data & 0xff0000) >> 16; + int g = (data & 0x00ff00) >> 8; + int r = (data & 0x0000ff); if(stv2_current_tilemap.fade_control & 1) stv_vdp2_compute_color_offset(&r,&g,&b,stv2_current_tilemap.fade_control & 2); @@ -3078,27 +3067,23 @@ void saturn_state::stv_vdp2_drawgfx_alpha(bitmap_rgb32 &dest_bmp,const rectangle /* skip if inner loop doesn't draw anything */ if (ex > sx) { - int x, y; - + for (int y = sy; y < ey; y++) { - for (y = sy; y < ey; y++) + uint8_t const *const source = source_base + y_index*gfx->rowbytes(); + uint32_t *const dest = &dest_bmp.pix(y); + int x_index = x_index_base; + for (int x = sx; x < ex; x++) { - const uint8_t *source = source_base + y_index*gfx->rowbytes(); - uint32_t *dest = &dest_bmp.pix32(y); - int x_index = x_index_base; - for (x = sx; x < ex; x++) + if(stv_vdp2_window_process(x,y)) { - if(stv_vdp2_window_process(x,y)) - { - int c = (source[x_index]); - if ((transparency & STV_TRANSPARENCY_NONE) || (c != 0)) - dest[x] = alpha_blend_r32( dest[x], pal[c], alpha ); - } - - x_index += xinc; + int c = (source[x_index]); + if ((transparency & STV_TRANSPARENCY_NONE) || (c != 0)) + dest[x] = alpha_blend_r32( dest[x], pal[c], alpha ); } - y_index += yinc; + + x_index += xinc; } + y_index += yinc; } } } @@ -3155,27 +3140,23 @@ void saturn_state::stv_vdp2_drawgfx_transpen(bitmap_rgb32 &dest_bmp,const rectan /* skip if inner loop doesn't draw anything */ if (ex > sx) { - int x, y; - + for (int y = sy; y < ey; y++) { - for (y = sy; y < ey; y++) + uint8_t const *const source = source_base + y_index*gfx->rowbytes(); + uint32_t *const dest = &dest_bmp.pix(y); + int x_index = x_index_base; + for (int x = sx; x < ex; x++) { - const uint8_t *source = source_base + y_index*gfx->rowbytes(); - uint32_t *dest = &dest_bmp.pix32(y); - int x_index = x_index_base; - for (x = sx; x < ex; x++) + if(stv_vdp2_window_process(x,y)) { - if(stv_vdp2_window_process(x,y)) - { - int c = (source[x_index]); - if ((transparency & STV_TRANSPARENCY_NONE) || (c != 0)) - dest[x] = pal[c]; - } - - x_index += xinc; + int c = (source[x_index]); + if ((transparency & STV_TRANSPARENCY_NONE) || (c != 0)) + dest[x] = pal[c]; } - y_index += yinc; + + x_index += xinc; } + y_index += yinc; } } } @@ -3227,9 +3208,9 @@ void saturn_state::draw_4bpp_bitmap(bitmap_rgb32 &bitmap, const rectangle &clipr dot_data += pal_bank; if ( stv2_current_tilemap.colour_calculation_enabled == 0 ) - bitmap.pix32(ydst, xdst) = m_palette->pen(dot_data); + bitmap.pix(ydst, xdst) = m_palette->pen(dot_data); else - bitmap.pix32(ydst, xdst) = alpha_blend_r32(bitmap.pix32(ydst, xdst), m_palette->pen(dot_data), stv2_current_tilemap.alpha); + bitmap.pix(ydst, xdst) = alpha_blend_r32(bitmap.pix(ydst, xdst), m_palette->pen(dot_data), stv2_current_tilemap.alpha); } } } @@ -3287,9 +3268,9 @@ void saturn_state::draw_8bpp_bitmap(bitmap_rgb32 &bitmap, const rectangle &clipr dot_data += pal_bank; if ( stv2_current_tilemap.colour_calculation_enabled == 0 ) - bitmap.pix32(ydst, xdst) = m_palette->pen(dot_data); + bitmap.pix(ydst, xdst) = m_palette->pen(dot_data); else - bitmap.pix32(ydst, xdst) = alpha_blend_r32(bitmap.pix32(ydst, xdst), m_palette->pen(dot_data), stv2_current_tilemap.alpha); + bitmap.pix(ydst, xdst) = alpha_blend_r32(bitmap.pix(ydst, xdst), m_palette->pen(dot_data), stv2_current_tilemap.alpha); } } } @@ -3344,9 +3325,9 @@ void saturn_state::draw_11bpp_bitmap(bitmap_rgb32 &bitmap, const rectangle &clip dot_data += pal_bank; if ( stv2_current_tilemap.colour_calculation_enabled == 0 ) - bitmap.pix32(ydst, xdst) = m_palette->pen(dot_data); + bitmap.pix(ydst, xdst) = m_palette->pen(dot_data); else - bitmap.pix32(ydst, xdst) = alpha_blend_r32(bitmap.pix32(ydst, xdst), m_palette->pen(dot_data), stv2_current_tilemap.alpha); + bitmap.pix(ydst, xdst) = alpha_blend_r32(bitmap.pix(ydst, xdst), m_palette->pen(dot_data), stv2_current_tilemap.alpha); } } } @@ -3403,9 +3384,9 @@ void saturn_state::draw_rgb15_bitmap(bitmap_rgb32 &bitmap, const rectangle &clip stv_vdp2_compute_color_offset(&r,&g,&b,stv2_current_tilemap.fade_control & 2); if ( stv2_current_tilemap.colour_calculation_enabled == 0 ) - bitmap.pix32(ydst, xdst) = rgb_t(r, g, b); + bitmap.pix(ydst, xdst) = rgb_t(r, g, b); else - bitmap.pix32(ydst, xdst) = alpha_blend_r32( bitmap.pix32(ydst, xdst), rgb_t(r, g, b), stv2_current_tilemap.alpha ); + bitmap.pix(ydst, xdst) = alpha_blend_r32( bitmap.pix(ydst, xdst), rgb_t(r, g, b), stv2_current_tilemap.alpha ); } } } @@ -3461,9 +3442,9 @@ void saturn_state::draw_rgb32_bitmap(bitmap_rgb32 &bitmap, const rectangle &clip stv_vdp2_compute_color_offset(&r,&g,&b,stv2_current_tilemap.fade_control & 2); if ( stv2_current_tilemap.colour_calculation_enabled == 0 ) - bitmap.pix32(ydst, xdst) = rgb_t(r, g, b); + bitmap.pix(ydst, xdst) = rgb_t(r, g, b); else - bitmap.pix32(ydst, xdst) = alpha_blend_r32( bitmap.pix32(ydst, xdst), rgb_t(r, g, b), stv2_current_tilemap.alpha ); + bitmap.pix(ydst, xdst) = alpha_blend_r32( bitmap.pix(ydst, xdst), rgb_t(r, g, b), stv2_current_tilemap.alpha ); } } } @@ -4354,9 +4335,9 @@ void saturn_state::stv_vdp2_draw_line(bitmap_rgb32 &bitmap, const rectangle &cli uint16_t pen; pen = (gfxdata[base_offs+0]<<8)|gfxdata[base_offs+1]; - pix = bitmap.pix32(y, x); + pix = bitmap.pix(y, x); - bitmap.pix32(y, x) = add_blend_r32(m_palette->pen(pen & 0x7ff),pix); + bitmap.pix(y, x) = add_blend_r32(m_palette->pen(pen & 0x7ff),pix); } } } @@ -4364,12 +4345,8 @@ void saturn_state::stv_vdp2_draw_line(bitmap_rgb32 &bitmap, const rectangle &cli void saturn_state::stv_vdp2_draw_mosaic(bitmap_rgb32 &bitmap, const rectangle &cliprect, uint8_t is_roz) { - int x,y,xi,yi; - uint8_t h_size,v_size; - uint32_t pix; - - h_size = STV_VDP2_MZSZH+1; - v_size = STV_VDP2_MZSZV+1; + uint8_t h_size = STV_VDP2_MZSZH+1; + uint8_t v_size = STV_VDP2_MZSZV+1; if(is_roz) v_size = 1; @@ -4380,15 +4357,15 @@ void saturn_state::stv_vdp2_draw_mosaic(bitmap_rgb32 &bitmap, const rectangle &c if(STV_VDP2_LSMD == 3) v_size <<= 1; - for(y=cliprect.top();y<=cliprect.bottom();y+=v_size) + for(int y=cliprect.top();y<=cliprect.bottom();y+=v_size) { - for(x=cliprect.left();x<=cliprect.right();x+=h_size) + for(int x=cliprect.left();x<=cliprect.right();x+=h_size) { - pix = bitmap.pix32(y, x); + uint32_t pix = bitmap.pix(y, x); - for(yi=0;yi<v_size;yi++) - for(xi=0;xi<h_size;xi++) - bitmap.pix32(y+yi, x+xi) = pix; + for(int yi=0;yi<v_size;yi++) + for(int xi=0;xi<h_size;xi++) + bitmap.pix(y+yi, x+xi) = pix; } } } @@ -4726,7 +4703,7 @@ void saturn_state::stv_vdp2_copy_roz_bitmap(bitmap_rgb32 &bitmap, //dx = (RP.A * RP.dx) + (RP.B * RP.dy); //dy = (RP.D * RP.dx) + (RP.E * RP.dy); - line = &bitmap.pix32(vcnt); + line = &bitmap.pix(vcnt); // TODO: nuke this spaghetti code if ( !use_coeff_table || RP.dkax == 0 ) @@ -4814,7 +4791,7 @@ void saturn_state::stv_vdp2_copy_roz_bitmap(bitmap_rgb32 &bitmap, continue; } - pix = roz_bitmap.pix32(y & planerenderedsizey, x & planerenderedsizex); + pix = roz_bitmap.pix(y & planerenderedsizey, x & planerenderedsizex); if (stv2_current_tilemap.transparency & STV_TRANSPARENCY_ALPHA) { if ((stv2_current_tilemap.transparency & STV_TRANSPARENCY_NONE) || (pix & 0xffffff)) @@ -4918,7 +4895,7 @@ void saturn_state::stv_vdp2_copy_roz_bitmap(bitmap_rgb32 &bitmap, if ( x & clipxmask || y & clipymask ) continue; - pix = roz_bitmap.pix32(y & planerenderedsizey, x & planerenderedsizex); + pix = roz_bitmap.pix(y & planerenderedsizey, x & planerenderedsizex); if (stv2_current_tilemap.transparency & STV_TRANSPARENCY_ALPHA) { if ((stv2_current_tilemap.transparency & STV_TRANSPARENCY_NONE) || (pix & 0xffffff)) @@ -5753,12 +5730,9 @@ void saturn_state::stv_vdp2_draw_RBG0(bitmap_rgb32 &bitmap, const rectangle &cli void saturn_state::stv_vdp2_draw_back(bitmap_rgb32 &bitmap, const rectangle &cliprect) { - int x,y; - uint8_t* gfxdata = m_vdp2.gfx_decode.get(); - uint32_t base_offs,base_mask; - uint8_t interlace; + uint8_t const *const gfxdata = m_vdp2.gfx_decode.get(); - interlace = (STV_VDP2_LSMD == 3)+1; + uint8_t interlace = (STV_VDP2_LSMD == 3)+1; // popmessage("Back screen %08x %08x %08x",STV_VDP2_BDCLMD,STV_VDP2_BKCLMD,STV_VDP2_BKTA); @@ -5767,27 +5741,24 @@ void saturn_state::stv_vdp2_draw_back(bitmap_rgb32 &bitmap, const rectangle &cli bitmap.fill(m_palette->black_pen(), cliprect); else { - base_mask = STV_VDP2_VRAMSZ ? 0x7ffff : 0x3ffff; + uint32_t base_mask = STV_VDP2_VRAMSZ ? 0x7ffff : 0x3ffff; - for(y=cliprect.top();y<=cliprect.bottom();y++) + for(int y=cliprect.top();y<=cliprect.bottom();y++) { - base_offs = ((STV_VDP2_BKTA ) & base_mask) << 1; + uint32_t base_offs = ((STV_VDP2_BKTA ) & base_mask) << 1; if(STV_VDP2_BKCLMD) base_offs += ((y / interlace) << 1); - for(x=cliprect.left();x<=cliprect.right();x++) + for(int x=cliprect.left();x<=cliprect.right();x++) { - int r,g,b; - uint16_t dot; - - dot = (gfxdata[base_offs+0]<<8)|gfxdata[base_offs+1]; - b = pal5bit((dot & 0x7c00) >> 10); - g = pal5bit((dot & 0x03e0) >> 5); - r = pal5bit( dot & 0x001f); + uint16_t dot = (gfxdata[base_offs+0]<<8)|gfxdata[base_offs+1]; + int b = pal5bit((dot & 0x7c00) >> 10); + int g = pal5bit((dot & 0x03e0) >> 5); + int r = pal5bit( dot & 0x001f); if(STV_VDP2_BKCOEN) stv_vdp2_compute_color_offset( &r, &g, &b, STV_VDP2_BKCOSL ); - bitmap.pix32(y, x) = rgb_t(r, g, b); + bitmap.pix(y, x) = rgb_t(r, g, b); } } } @@ -6737,7 +6708,7 @@ void saturn_state::draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprect, continue; framebuffer_line = m_vdp1.framebuffer_display_lines[y]; - bitmap_line = &bitmap.pix32(y); + bitmap_line = &bitmap.pix(y); for ( x = cliprect.left(); x <= cliprect.right(); x++ ) { @@ -6830,7 +6801,7 @@ void saturn_state::draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprect, continue; framebuffer_line = m_vdp1.framebuffer_display_lines[y]; - bitmap_line = &bitmap.pix32(y); + bitmap_line = &bitmap.pix(y); for ( x = cliprect.left(); x <= cliprect.right(); x++ ) { @@ -6941,12 +6912,12 @@ void saturn_state::draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprect, framebuffer_line = m_vdp1.framebuffer_display_lines[y]; if ( interlace_framebuffer == 0 ) { - bitmap_line = &bitmap.pix32(y); + bitmap_line = &bitmap.pix(y); } else { - bitmap_line = &bitmap.pix32(2*y); - bitmap_line2 = &bitmap.pix32(2*y + 1); + bitmap_line = &bitmap.pix(2*y); + bitmap_line2 = &bitmap.pix(2*y + 1); } for ( x = cliprect.left(); x <= cliprect.right() /(double_x+1) ; x++ ) diff --git a/src/devices/video/t6963c.cpp b/src/devices/video/t6963c.cpp index 96995f62c68..215911ed3ff 100644 --- a/src/devices/video/t6963c.cpp +++ b/src/devices/video/t6963c.cpp @@ -346,7 +346,7 @@ uint32_t t6963c_device::screen_update(screen_device &screen, bitmap_ind16 &bitma data = m_display_ram->read_byte(m_cgram_offset + c * 8 + cy); for(int cx=0; cx<m_font_size; cx++) - bitmap.pix16(y * 8 + cy, x * m_font_size + cx) = BIT(data, m_font_size - 1 - cx); + bitmap.pix(y * 8 + cy, x * m_font_size + cx) = BIT(data, m_font_size - 1 - cx); } } @@ -362,13 +362,13 @@ uint32_t t6963c_device::screen_update(screen_device &screen, bitmap_ind16 &bitma switch(m_mode & 7) { case 0: // OR - bitmap.pix16(y, x * m_font_size + i) |= pix; + bitmap.pix(y, x * m_font_size + i) |= pix; break; case 1: // EXOR - bitmap.pix16(y, x * m_font_size + i) ^= pix; + bitmap.pix(y, x * m_font_size + i) ^= pix; break; case 3: // AND - bitmap.pix16(y, x * m_font_size + i) &= pix; + bitmap.pix(y, x * m_font_size + i) &= pix; break; case 4: // Text attribute logerror("%s: Unimplemented Text attribute\n", machine().describe_context()); diff --git a/src/devices/video/t6963c.h b/src/devices/video/t6963c.h index 33b748e38c3..aaaeb7c3e57 100644 --- a/src/devices/video/t6963c.h +++ b/src/devices/video/t6963c.h @@ -45,7 +45,7 @@ public: uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - static constexpr feature_type unemulated_features() { return feature::GRAPHICS; } + static constexpr feature_type imperfect_features() { return feature::GRAPHICS; } protected: // device-specific overrides diff --git a/src/devices/video/t6a04.cpp b/src/devices/video/t6a04.cpp index 8b55f8ce153..a5dc8bfa928 100644 --- a/src/devices/video/t6a04.cpp +++ b/src/devices/video/t6a04.cpp @@ -110,7 +110,7 @@ uint32_t t6a04_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap for (int b=7; b>=0; b--) { - bitmap.pix16(x&0x3f, y*8+b) = data & 1; + bitmap.pix(x&0x3f, y*8+b) = data & 1; data>>=1; } } diff --git a/src/devices/video/tms3556.cpp b/src/devices/video/tms3556.cpp index dbd45105a97..3088e02e685 100644 --- a/src/devices/video/tms3556.cpp +++ b/src/devices/video/tms3556.cpp @@ -573,12 +573,12 @@ void tms3556_device::draw_line(bitmap_ind16 &bmp, int line) // if (m_control_regs[4] & 0x??) // { // interlaced mode -// ln = &bmp->pix16(line, m_field); +// ln = &bmp->pix(line, m_field); // } // else { /* non-interlaced mode */ - ln = &bmp.pix16(line); - ln2 = &bmp.pix16(line, 1); + ln = &bmp.pix(line); + ln2 = &bmp.pix(line, 1); double_lines = 1; } diff --git a/src/devices/video/tms9928a.cpp b/src/devices/video/tms9928a.cpp index 129b364e860..27395fecacb 100644 --- a/src/devices/video/tms9928a.cpp +++ b/src/devices/video/tms9928a.cpp @@ -365,7 +365,7 @@ void tms9928a_device::device_timer(emu_timer &timer, device_timer_id id, int par int raw_vpos = screen().vpos(); int vpos = raw_vpos * m_vertical_size / screen().height(); uint16_t BackColour = m_Regs[7] & 15; - uint32_t *p = &m_tmpbmp.pix32(vpos); + uint32_t *p = &m_tmpbmp.pix(vpos); int y = vpos - m_top_border; diff --git a/src/devices/video/v9938.cpp b/src/devices/video/v9938.cpp index 0876a3b9923..e82858056e7 100644 --- a/src/devices/video/v9938.cpp +++ b/src/devices/video/v9938.cpp @@ -1863,12 +1863,12 @@ void v99x8_device::refresh_32(int line) if (m_cont_reg[9] & 0x08) { - ln = &m_bitmap.pix32(m_scanline*2+((m_stat_reg[2]>>1)&1)); + ln = &m_bitmap.pix(m_scanline*2+((m_stat_reg[2]>>1)&1)); } else { - ln = &m_bitmap.pix32(m_scanline*2); - ln2 = &m_bitmap.pix32(m_scanline*2+1); + ln = &m_bitmap.pix(m_scanline*2); + ln2 = &m_bitmap.pix(m_scanline*2+1); double_lines = true; } diff --git a/src/devices/video/vector.cpp b/src/devices/video/vector.cpp index 28b507323d5..46a21b535be 100644 --- a/src/devices/video/vector.cpp +++ b/src/devices/video/vector.cpp @@ -42,10 +42,11 @@ **************************************************************************** */ #include "emu.h" -#include "emuopts.h" -#include "rendutil.h" #include "vector.h" +#include "emuopts.h" +#include "render.h" + #define VECTOR_WIDTH_DENOM 512 @@ -85,7 +86,7 @@ void vector_device::device_start() m_vector_index = 0; /* allocate memory for tables */ - m_vector_list = make_unique_clear<point[]>(MAX_POINTS); + m_vector_list = std::make_unique<point[]>(MAX_POINTS); } /* diff --git a/src/devices/video/vic4567.cpp b/src/devices/video/vic4567.cpp index c493e3d3a05..6b8cae5f04f 100644 --- a/src/devices/video/vic4567.cpp +++ b/src/devices/video/vic4567.cpp @@ -20,6 +20,8 @@ #include "screen.h" +#include <algorithm> + /***************************************************************************** CONSTANTS @@ -424,105 +426,93 @@ TIMER_CALLBACK_MEMBER( vic3_device::timer_timeout ) void vic3_device::draw_character( int ybegin, int yend, int ch, int yoff, int xoff, uint16_t *color, int start_x, int end_x ) { - int code; - for (int y = ybegin; y <= yend; y++) { - code = m_dma_read_cb(m_chargenaddr + ch * 8 + y); + int code = m_dma_read_cb(m_chargenaddr + ch * 8 + y); m_screenptr[y + yoff][xoff >> 3] = code; - if ((xoff + 0 > start_x) && (xoff + 0 < end_x)) m_bitmap->pix16(y + yoff + FIRSTLINE, xoff + 0) = color[code >> 7]; - if ((xoff + 1 > start_x) && (xoff + 0 < end_x)) m_bitmap->pix16(y + yoff + FIRSTLINE, xoff + 1) = color[(code >> 6) & 1]; - if ((xoff + 2 > start_x) && (xoff + 0 < end_x)) m_bitmap->pix16(y + yoff + FIRSTLINE, xoff + 2) = color[(code >> 5) & 1]; - if ((xoff + 3 > start_x) && (xoff + 0 < end_x)) m_bitmap->pix16(y + yoff + FIRSTLINE, xoff + 3) = color[(code >> 4) & 1]; - if ((xoff + 4 > start_x) && (xoff + 0 < end_x)) m_bitmap->pix16(y + yoff + FIRSTLINE, xoff + 4) = color[(code >> 3) & 1]; - if ((xoff + 5 > start_x) && (xoff + 0 < end_x)) m_bitmap->pix16(y + yoff + FIRSTLINE, xoff + 5) = color[(code >> 2) & 1]; - if ((xoff + 6 > start_x) && (xoff + 0 < end_x)) m_bitmap->pix16(y + yoff + FIRSTLINE, xoff + 6) = color[(code >> 1) & 1]; - if ((xoff + 7 > start_x) && (xoff + 0 < end_x)) m_bitmap->pix16(y + yoff + FIRSTLINE, xoff + 7) = color[code & 1]; + if ((xoff + 0 > start_x) && (xoff + 0 < end_x)) m_bitmap->pix(y + yoff + FIRSTLINE, xoff + 0) = color[code >> 7]; + if ((xoff + 1 > start_x) && (xoff + 0 < end_x)) m_bitmap->pix(y + yoff + FIRSTLINE, xoff + 1) = color[(code >> 6) & 1]; + if ((xoff + 2 > start_x) && (xoff + 0 < end_x)) m_bitmap->pix(y + yoff + FIRSTLINE, xoff + 2) = color[(code >> 5) & 1]; + if ((xoff + 3 > start_x) && (xoff + 0 < end_x)) m_bitmap->pix(y + yoff + FIRSTLINE, xoff + 3) = color[(code >> 4) & 1]; + if ((xoff + 4 > start_x) && (xoff + 0 < end_x)) m_bitmap->pix(y + yoff + FIRSTLINE, xoff + 4) = color[(code >> 3) & 1]; + if ((xoff + 5 > start_x) && (xoff + 0 < end_x)) m_bitmap->pix(y + yoff + FIRSTLINE, xoff + 5) = color[(code >> 2) & 1]; + if ((xoff + 6 > start_x) && (xoff + 0 < end_x)) m_bitmap->pix(y + yoff + FIRSTLINE, xoff + 6) = color[(code >> 1) & 1]; + if ((xoff + 7 > start_x) && (xoff + 0 < end_x)) m_bitmap->pix(y + yoff + FIRSTLINE, xoff + 7) = color[code & 1]; } } void vic3_device::draw_character_multi( int ybegin, int yend, int ch, int yoff, int xoff, int start_x, int end_x ) { - int code; - for (int y = ybegin; y <= yend; y++) { - code = m_dma_read_cb(m_chargenaddr + ch * 8 + y); + int code = m_dma_read_cb(m_chargenaddr + ch * 8 + y); m_screenptr[y + yoff][xoff >> 3] = m_foreground[code]; - if ((xoff + 0 > start_x) && (xoff + 0 < end_x)) m_bitmap->pix16(y + yoff + FIRSTLINE, xoff + 0) = m_multi[code >> 6]; - if ((xoff + 1 > start_x) && (xoff + 1 < end_x)) m_bitmap->pix16(y + yoff + FIRSTLINE, xoff + 1) = m_multi[code >> 6]; - if ((xoff + 2 > start_x) && (xoff + 2 < end_x)) m_bitmap->pix16(y + yoff + FIRSTLINE, xoff + 2) = m_multi[(code >> 4) & 3]; - if ((xoff + 3 > start_x) && (xoff + 3 < end_x)) m_bitmap->pix16(y + yoff + FIRSTLINE, xoff + 3) = m_multi[(code >> 4) & 3]; - if ((xoff + 4 > start_x) && (xoff + 4 < end_x)) m_bitmap->pix16(y + yoff + FIRSTLINE, xoff + 4) = m_multi[(code >> 2) & 3]; - if ((xoff + 5 > start_x) && (xoff + 5 < end_x)) m_bitmap->pix16(y + yoff + FIRSTLINE, xoff + 5) = m_multi[(code >> 2) & 3]; - if ((xoff + 6 > start_x) && (xoff + 6 < end_x)) m_bitmap->pix16(y + yoff + FIRSTLINE, xoff + 6) = m_multi[code & 3]; - if ((xoff + 7 > start_x) && (xoff + 7 < end_x)) m_bitmap->pix16(y + yoff + FIRSTLINE, xoff + 7) = m_multi[code & 3]; + if ((xoff + 0 > start_x) && (xoff + 0 < end_x)) m_bitmap->pix(y + yoff + FIRSTLINE, xoff + 0) = m_multi[code >> 6]; + if ((xoff + 1 > start_x) && (xoff + 1 < end_x)) m_bitmap->pix(y + yoff + FIRSTLINE, xoff + 1) = m_multi[code >> 6]; + if ((xoff + 2 > start_x) && (xoff + 2 < end_x)) m_bitmap->pix(y + yoff + FIRSTLINE, xoff + 2) = m_multi[(code >> 4) & 3]; + if ((xoff + 3 > start_x) && (xoff + 3 < end_x)) m_bitmap->pix(y + yoff + FIRSTLINE, xoff + 3) = m_multi[(code >> 4) & 3]; + if ((xoff + 4 > start_x) && (xoff + 4 < end_x)) m_bitmap->pix(y + yoff + FIRSTLINE, xoff + 4) = m_multi[(code >> 2) & 3]; + if ((xoff + 5 > start_x) && (xoff + 5 < end_x)) m_bitmap->pix(y + yoff + FIRSTLINE, xoff + 5) = m_multi[(code >> 2) & 3]; + if ((xoff + 6 > start_x) && (xoff + 6 < end_x)) m_bitmap->pix(y + yoff + FIRSTLINE, xoff + 6) = m_multi[code & 3]; + if ((xoff + 7 > start_x) && (xoff + 7 < end_x)) m_bitmap->pix(y + yoff + FIRSTLINE, xoff + 7) = m_multi[code & 3]; } } void vic3_device::draw_bitmap( int ybegin, int yend, int ch, int yoff, int xoff, int start_x, int end_x ) { - int code; - for (int y = ybegin; y <= yend; y++) { - code = m_dma_read_cb((m_chargenaddr & 0x2000) + ch * 8 + y); + int code = m_dma_read_cb((m_chargenaddr & 0x2000) + ch * 8 + y); m_screenptr[y + yoff][xoff >> 3] = code; - if ((xoff + 0 > start_x) && (xoff + 0 < end_x)) m_bitmap->pix16(y + yoff + FIRSTLINE, xoff + 0) = m_c64_bitmap[code >> 7]; - if ((xoff + 1 > start_x) && (xoff + 1 < end_x)) m_bitmap->pix16(y + yoff + FIRSTLINE, xoff + 1) = m_c64_bitmap[(code >> 6) & 1]; - if ((xoff + 2 > start_x) && (xoff + 2 < end_x)) m_bitmap->pix16(y + yoff + FIRSTLINE, xoff + 2) = m_c64_bitmap[(code >> 5) & 1]; - if ((xoff + 3 > start_x) && (xoff + 3 < end_x)) m_bitmap->pix16(y + yoff + FIRSTLINE, xoff + 3) = m_c64_bitmap[(code >> 4) & 1]; - if ((xoff + 4 > start_x) && (xoff + 4 < end_x)) m_bitmap->pix16(y + yoff + FIRSTLINE, xoff + 4) = m_c64_bitmap[(code >> 3) & 1]; - if ((xoff + 5 > start_x) && (xoff + 5 < end_x)) m_bitmap->pix16(y + yoff + FIRSTLINE, xoff + 5) = m_c64_bitmap[(code >> 2) & 1]; - if ((xoff + 6 > start_x) && (xoff + 6 < end_x)) m_bitmap->pix16(y + yoff + FIRSTLINE, xoff + 6) = m_c64_bitmap[(code >> 1) & 1]; - if ((xoff + 7 > start_x) && (xoff + 7 < end_x)) m_bitmap->pix16(y + yoff + FIRSTLINE, xoff + 7) = m_c64_bitmap[code & 1]; + if ((xoff + 0 > start_x) && (xoff + 0 < end_x)) m_bitmap->pix(y + yoff + FIRSTLINE, xoff + 0) = m_c64_bitmap[code >> 7]; + if ((xoff + 1 > start_x) && (xoff + 1 < end_x)) m_bitmap->pix(y + yoff + FIRSTLINE, xoff + 1) = m_c64_bitmap[(code >> 6) & 1]; + if ((xoff + 2 > start_x) && (xoff + 2 < end_x)) m_bitmap->pix(y + yoff + FIRSTLINE, xoff + 2) = m_c64_bitmap[(code >> 5) & 1]; + if ((xoff + 3 > start_x) && (xoff + 3 < end_x)) m_bitmap->pix(y + yoff + FIRSTLINE, xoff + 3) = m_c64_bitmap[(code >> 4) & 1]; + if ((xoff + 4 > start_x) && (xoff + 4 < end_x)) m_bitmap->pix(y + yoff + FIRSTLINE, xoff + 4) = m_c64_bitmap[(code >> 3) & 1]; + if ((xoff + 5 > start_x) && (xoff + 5 < end_x)) m_bitmap->pix(y + yoff + FIRSTLINE, xoff + 5) = m_c64_bitmap[(code >> 2) & 1]; + if ((xoff + 6 > start_x) && (xoff + 6 < end_x)) m_bitmap->pix(y + yoff + FIRSTLINE, xoff + 6) = m_c64_bitmap[(code >> 1) & 1]; + if ((xoff + 7 > start_x) && (xoff + 7 < end_x)) m_bitmap->pix(y + yoff + FIRSTLINE, xoff + 7) = m_c64_bitmap[code & 1]; } } void vic3_device::draw_bitmap_multi( int ybegin, int yend, int ch, int yoff, int xoff, int start_x, int end_x ) { - int code; - for (int y = ybegin; y <= yend; y++) { - code = m_dma_read_cb((m_chargenaddr & 0x2000) + ch * 8 + y); + int code = m_dma_read_cb((m_chargenaddr & 0x2000) + ch * 8 + y); m_screenptr[y + yoff][xoff >> 3] = m_foreground[code]; - if ((xoff + 0 > start_x) && (xoff + 0 < end_x)) m_bitmap->pix16(y + yoff + FIRSTLINE, xoff + 0) = m_bitmapmulti[code >> 6]; - if ((xoff + 1 > start_x) && (xoff + 1 < end_x)) m_bitmap->pix16(y + yoff + FIRSTLINE, xoff + 1) = m_bitmapmulti[code >> 6]; - if ((xoff + 2 > start_x) && (xoff + 2 < end_x)) m_bitmap->pix16(y + yoff + FIRSTLINE, xoff + 2) = m_bitmapmulti[(code >> 4) & 3]; - if ((xoff + 3 > start_x) && (xoff + 3 < end_x)) m_bitmap->pix16(y + yoff + FIRSTLINE, xoff + 3) = m_bitmapmulti[(code >> 4) & 3]; - if ((xoff + 4 > start_x) && (xoff + 4 < end_x)) m_bitmap->pix16(y + yoff + FIRSTLINE, xoff + 4) = m_bitmapmulti[(code >> 2) & 3]; - if ((xoff + 5 > start_x) && (xoff + 5 < end_x)) m_bitmap->pix16(y + yoff + FIRSTLINE, xoff + 5) = m_bitmapmulti[(code >> 2) & 3]; - if ((xoff + 6 > start_x) && (xoff + 6 < end_x)) m_bitmap->pix16(y + yoff + FIRSTLINE, xoff + 6) = m_bitmapmulti[code & 3]; - if ((xoff + 7 > start_x) && (xoff + 7 < end_x)) m_bitmap->pix16(y + yoff + FIRSTLINE, xoff + 7) = m_bitmapmulti[code & 3]; + if ((xoff + 0 > start_x) && (xoff + 0 < end_x)) m_bitmap->pix(y + yoff + FIRSTLINE, xoff + 0) = m_bitmapmulti[code >> 6]; + if ((xoff + 1 > start_x) && (xoff + 1 < end_x)) m_bitmap->pix(y + yoff + FIRSTLINE, xoff + 1) = m_bitmapmulti[code >> 6]; + if ((xoff + 2 > start_x) && (xoff + 2 < end_x)) m_bitmap->pix(y + yoff + FIRSTLINE, xoff + 2) = m_bitmapmulti[(code >> 4) & 3]; + if ((xoff + 3 > start_x) && (xoff + 3 < end_x)) m_bitmap->pix(y + yoff + FIRSTLINE, xoff + 3) = m_bitmapmulti[(code >> 4) & 3]; + if ((xoff + 4 > start_x) && (xoff + 4 < end_x)) m_bitmap->pix(y + yoff + FIRSTLINE, xoff + 4) = m_bitmapmulti[(code >> 2) & 3]; + if ((xoff + 5 > start_x) && (xoff + 5 < end_x)) m_bitmap->pix(y + yoff + FIRSTLINE, xoff + 5) = m_bitmapmulti[(code >> 2) & 3]; + if ((xoff + 6 > start_x) && (xoff + 6 < end_x)) m_bitmap->pix(y + yoff + FIRSTLINE, xoff + 6) = m_bitmapmulti[code & 3]; + if ((xoff + 7 > start_x) && (xoff + 7 < end_x)) m_bitmap->pix(y + yoff + FIRSTLINE, xoff + 7) = m_bitmapmulti[code & 3]; } } void vic3_device::draw_sprite_code( int y, int xbegin, int code, int color, int start_x, int end_x ) { - int mask, x; - if ((y < YPOS) || (y >= (VIC2_STARTVISIBLELINES + VIC2_VISIBLELINES)) || (xbegin <= 1) || (xbegin >= (VIC2_STARTVISIBLECOLUMNS + VIC2_VISIBLECOLUMNS))) return; - for (x = 0, mask = 0x80; x < 8; x++, mask >>= 1) + for (int x = 0, mask = 0x80; x < 8; x++, mask >>= 1) { if (code & mask) { if ((xbegin + x > start_x) && (xbegin + x < end_x)) - m_bitmap->pix16(y + FIRSTLINE, xbegin + x) = color; + m_bitmap->pix(y + FIRSTLINE, xbegin + x) = color; } } } void vic3_device::draw_sprite_code_multi( int y, int xbegin, int code, int prior, int start_x, int end_x ) { - int x, mask, shift; - if ((y < YPOS) || (y >= (VIC2_STARTVISIBLELINES + VIC2_VISIBLELINES)) || (xbegin <= 1) || (xbegin >= (VIC2_STARTVISIBLECOLUMNS + VIC2_VISIBLECOLUMNS))) return; - for (x = 0, mask = 0xc0, shift = 6; x < 8; x += 2, mask >>= 2, shift -= 2) + for (int x = 0, mask = 0xc0, shift = 6; x < 8; x += 2, mask >>= 2, shift -= 2) { if (code & mask) { @@ -530,17 +520,17 @@ void vic3_device::draw_sprite_code_multi( int y, int xbegin, int code, int prior { case 1: if ((xbegin + x + 1 > start_x) && (xbegin + x + 1 < end_x)) - m_bitmap->pix16(y + FIRSTLINE, xbegin + x + 1) = m_spritemulti[(code >> shift) & 3]; + m_bitmap->pix(y + FIRSTLINE, xbegin + x + 1) = m_spritemulti[(code >> shift) & 3]; break; case 2: if ((xbegin + x > start_x) && (xbegin + x < end_x)) - m_bitmap->pix16(y + FIRSTLINE, xbegin + x) = m_spritemulti[(code >> shift) & 3]; + m_bitmap->pix(y + FIRSTLINE, xbegin + x) = m_spritemulti[(code >> shift) & 3]; break; case 3: if ((xbegin + x > start_x) && (xbegin + x < end_x)) - m_bitmap->pix16(y + FIRSTLINE, xbegin + x) = m_spritemulti[(code >> shift) & 3]; + m_bitmap->pix(y + FIRSTLINE, xbegin + x) = m_spritemulti[(code >> shift) & 3]; if ((xbegin + x + 1> start_x) && (xbegin + x + 1< end_x)) - m_bitmap->pix16(y + FIRSTLINE, xbegin + x + 1) = m_spritemulti[(code >> shift) & 3]; + m_bitmap->pix(y + FIRSTLINE, xbegin + x + 1) = m_spritemulti[(code >> shift) & 3]; break; } } @@ -549,8 +539,6 @@ void vic3_device::draw_sprite_code_multi( int y, int xbegin, int code, int prior void vic3_device::sprite_collision( int nr, int y, int x, int mask ) { - int value, xdiff; - for (int i = 7; i > nr; i--) { if (!SPRITEON(i) || !m_sprites[i].paintedline[y] || (SPRITE_COLLISION(i) && SPRITE_COLLISION(nr))) @@ -559,8 +547,9 @@ void vic3_device::sprite_collision( int nr, int y, int x, int mask ) if ((x + 7 < SPRITE_X_POS(i)) || (x >= SPRITE_X_POS(i) + SPRITE_X_SIZE(i))) continue; - xdiff = x - SPRITE_X_POS(i); + int xdiff = x - SPRITE_X_POS(i); + int value; if ((x & 7) == (SPRITE_X_POS(i) & 7)) value = m_sprites[i].bitmap[y][xdiff >> 3]; else if (xdiff < 0) @@ -785,17 +774,6 @@ void vic3_device::draw_sprite_multi( int nr, int yoff, int ybegin, int yend, int } } -#ifndef memset16 -static void *memset16(void *dest, int value, size_t size) -{ - int i; - - for (i = 0; i < size; i++) - ((short *) dest)[i] = value; - return dest; -} -#endif - void vic3_device::drawlines( int first, int last, int start_x, int end_x ) { int line, vline, end; @@ -825,7 +803,7 @@ void vic3_device::drawlines( int first, int last, int start_x, int end_x ) { for (line = first; (line < last) && (line < m_bitmap->height()); line++) { - memset16(&m_bitmap->pix16(line + FIRSTLINE), 0, m_bitmap->width()); + std::fill_n(&m_bitmap->pix(line + FIRSTLINE), m_bitmap->width(), 0); } return; } @@ -841,7 +819,7 @@ void vic3_device::drawlines( int first, int last, int start_x, int end_x ) for (line = first; line < end; line++) { - memset16(&m_bitmap->pix16(line + FIRSTLINE), FRAMECOLOR, m_bitmap->width()); + std::fill_n(&m_bitmap->pix(line + FIRSTLINE), m_bitmap->width(), FRAMECOLOR); } if (LINES25) @@ -1013,20 +991,14 @@ void vic3_device::drawlines( int first, int last, int start_x, int end_x ) for (; line < end; line++) { - memset16(&m_bitmap->pix16(line + FIRSTLINE), FRAMECOLOR, m_bitmap->width()); + std::fill_n(&m_bitmap->pix(line + FIRSTLINE), m_bitmap->width(), FRAMECOLOR); } } void vic3_device::vic2_drawlines( int first, int last, int start_x, int end_x ) { - int line, vline, end; - int attr, ch, ecm; - int syend; - int offs, yoff, xoff, ybegin, yend, xbegin, xend; - int i; - if (VIC3_BITPLANES) - return ; + return; /* temporary allowing vic3 displaying 80 columns */ if (m_reg[0x31] & 0x80) @@ -1040,8 +1012,8 @@ void vic3_device::vic2_drawlines( int first, int last, int start_x, int end_x ) /* top part of display not rastered */ first -= VIC2_YPOS - YPOS; - xbegin = VIC2_STARTVISIBLECOLUMNS; - xend = xbegin + VIC2_VISIBLECOLUMNS; + int xbegin = VIC2_STARTVISIBLECOLUMNS; + int xend = xbegin + VIC2_VISIBLECOLUMNS; if (!SCREENON) { xbegin = VIC2_STARTVISIBLECOLUMNS; @@ -1068,12 +1040,13 @@ void vic3_device::vic2_drawlines( int first, int last, int start_x, int end_x ) xend = xbegin + 304; } + int end; if (first + 1 < m_y_begin) end = first + 1; else end = m_y_begin + YPOS; - line = first; + int line = first; // top border if (line < end) { @@ -1088,7 +1061,7 @@ void vic3_device::vic2_drawlines( int first, int last, int start_x, int end_x ) line = end; } - vline = line - YPOS + 3 - VERTICALPOS; + int vline = line - YPOS + 3 - VERTICALPOS; if (first + 1 < m_y_end + YPOS) end = first + 1; @@ -1097,23 +1070,23 @@ void vic3_device::vic2_drawlines( int first, int last, int start_x, int end_x ) if (line < end) { - offs = (vline >> 3) * 40; - ybegin = vline & 7; - yoff = line - ybegin; - yend = (yoff + 7 < end) ? 7 : (end - yoff - 1); + int offs = (vline >> 3) * 40; + int ybegin = vline & 7; + int yoff = line - ybegin; + int yend = (yoff + 7 < end) ? 7 : (end - yoff - 1); /* rendering 39 characters */ /* left and right borders are overwritten later */ m_shift[line] = HORIZONTALPOS; - for (xoff = m_x_begin + XPOS; xoff < m_x_end + XPOS; xoff += 8, offs++) + for (int xoff = m_x_begin + XPOS; xoff < m_x_end + XPOS; xoff += 8, offs++) { - ch = m_dma_read_cb(m_videoaddr + offs); + int ch = m_dma_read_cb(m_videoaddr + offs); #if 0 - attr = m_dma_read_color_cb(m_videoaddr + offs); + int attr = m_dma_read_color_cb(m_videoaddr + offs); #else /* temporary until vic3 finished */ - attr = m_dma_read_color_cb((m_videoaddr + offs)&0x3ff)&0x0f; + int attr = m_dma_read_color_cb((m_videoaddr + offs)&0x3ff)&0x0f; #endif if (HIRESON) { @@ -1131,7 +1104,7 @@ void vic3_device::vic2_drawlines( int first, int last, int start_x, int end_x ) } else if (ECMON) { - ecm = ch >> 6; + int ecm = ch >> 6; m_ecmcolor[0] = m_colors[ecm]; m_ecmcolor[1] = attr; draw_character(ybegin, yend, ch & ~0xC0, yoff, xoff, m_ecmcolor, start_x, end_x); @@ -1149,7 +1122,7 @@ void vic3_device::vic2_drawlines( int first, int last, int start_x, int end_x ) } /* sprite priority, sprite overwrites lowerprior pixels */ - for (i = 7; i >= 0; i--) + for (int i = 7; i >= 0; i--) { if (SPRITEON (i) && (yoff + ybegin >= SPRITE_Y_POS (i)) && @@ -1158,7 +1131,7 @@ void vic3_device::vic2_drawlines( int first, int last, int start_x, int end_x ) { int wrapped = - SPRITE_Y_POS (i) + 6; - syend = yend; + int syend = yend; if (SPRITE_Y_EXPAND (i)) { @@ -1187,7 +1160,7 @@ void vic3_device::vic2_drawlines( int first, int last, int start_x, int end_x ) { int wrapped = yoff + ybegin - SPRITE_Y_POS (i); - syend = yend; + int syend = yend; if (SPRITE_Y_EXPAND (i)) { @@ -1659,77 +1632,76 @@ uint8_t vic3_device::port_r(offs_t offset) } -#define VIC3_MASK(M) \ - if (M) \ - { \ - if (M & 0x01) \ - colors[0] = m_c64_mem_r_cb(VIC3_ADDR(0) + offset); \ - if (M & 0x02) \ - colors[1] = m_c64_mem_r_cb(VIC3_ADDR(1) + offset) << 1; \ - if (M & 0x04) \ - colors[2] = m_c64_mem_r_cb(VIC3_ADDR(2) + offset) << 2; \ - if (M & 0x08) \ - colors[3] = m_c64_mem_r_cb(VIC3_ADDR(3) + offset) << 3; \ - if (M & 0x10) \ - colors[4] = m_c64_mem_r_cb(VIC3_ADDR(4) + offset) << 4; \ - if (M & 0x20) \ - colors[5] = m_c64_mem_r_cb(VIC3_ADDR(5) + offset) << 5; \ - if (M & 0x40) \ - colors[6] = m_c64_mem_r_cb(VIC3_ADDR(6) + offset) << 6; \ - if (M & 0x80) \ - colors[7] = m_c64_mem_r_cb(VIC3_ADDR(7) + offset) << 7; \ - for (i = 7; i >= 0; i--) \ - { \ - p = 0; \ - if (M & 0x01) \ - { \ - p = colors[0] & 0x01; \ - colors[0] >>= 1; \ - } \ - if (M & 0x02) \ - { \ - p |= colors[1] & 0x02; \ - colors[1] >>= 1; \ - } \ - if (M & 0x04) \ - { \ - p |= colors[2] & 0x04; \ - colors[2] >>= 1; \ - } \ - if (M & 0x08) \ - { \ - p |= colors[3] & 0x08; \ - colors[3] >>= 1; \ - } \ - if (M & 0x10) \ - { \ - p |= colors[4] & 0x10; \ - colors[4] >>= 1; \ - } \ - if (M & 0x20) \ - { \ - p |= colors[5] & 0x20; \ - colors[5] >>= 1; \ - } \ - if (M & 0x40) \ - { \ - p |= colors[6] & 0x40; \ - colors[6] >>= 1; \ - } \ - if (M & 0x80) \ - { \ - p |= colors[7] & 0x80; \ - colors[7] >>= 1; \ - } \ - m_bitmap->pix16(YPOS + y, XPOS + x + i) = p; \ - } \ +#define VIC3_MASK(M) \ + if (M) \ + { \ + if (M & 0x01) \ + colors[0] = m_c64_mem_r_cb(VIC3_ADDR(0) + offset); \ + if (M & 0x02) \ + colors[1] = m_c64_mem_r_cb(VIC3_ADDR(1) + offset) << 1; \ + if (M & 0x04) \ + colors[2] = m_c64_mem_r_cb(VIC3_ADDR(2) + offset) << 2; \ + if (M & 0x08) \ + colors[3] = m_c64_mem_r_cb(VIC3_ADDR(3) + offset) << 3; \ + if (M & 0x10) \ + colors[4] = m_c64_mem_r_cb(VIC3_ADDR(4) + offset) << 4; \ + if (M & 0x20) \ + colors[5] = m_c64_mem_r_cb(VIC3_ADDR(5) + offset) << 5; \ + if (M & 0x40) \ + colors[6] = m_c64_mem_r_cb(VIC3_ADDR(6) + offset) << 6; \ + if (M & 0x80) \ + colors[7] = m_c64_mem_r_cb(VIC3_ADDR(7) + offset) << 7; \ + for (int i = 7; i >= 0; i--) \ + { \ + int p = 0; \ + if (M & 0x01) \ + { \ + p = colors[0] & 0x01; \ + colors[0] >>= 1; \ + } \ + if (M & 0x02) \ + { \ + p |= colors[1] & 0x02; \ + colors[1] >>= 1; \ + } \ + if (M & 0x04) \ + { \ + p |= colors[2] & 0x04; \ + colors[2] >>= 1; \ + } \ + if (M & 0x08) \ + { \ + p |= colors[3] & 0x08; \ + colors[3] >>= 1; \ + } \ + if (M & 0x10) \ + { \ + p |= colors[4] & 0x10; \ + colors[4] >>= 1; \ + } \ + if (M & 0x20) \ + { \ + p |= colors[5] & 0x20; \ + colors[5] >>= 1; \ + } \ + if (M & 0x40) \ + { \ + p |= colors[6] & 0x40; \ + colors[6] >>= 1; \ + } \ + if (M & 0x80) \ + { \ + p |= colors[7] & 0x80; \ + colors[7] >>= 1; \ + } \ + m_bitmap->pix(YPOS + y, XPOS + x + i) = p; \ + } \ } #define VIC3_ADDR(a) VIC3_BITPLANE_IADDR(a) void vic3_device::interlace_draw_block( int x, int y, int offset ) { int colors[8] = {0}; - int i, p; switch (VIC3_BITPLANES_MASK) { @@ -1776,13 +1748,13 @@ void vic3_device::interlace_draw_block( int x, int y, int offset ) if (VIC3_BITPLANES_MASK & 0x80) colors[7] = m_c64_mem_r_cb(VIC3_BITPLANE_IADDR(7) + offset) << 7; - for (i = 7; i >= 0; i--) + for (int i = 7; i >= 0; i--) { - m_bitmap->pix16(YPOS + y, XPOS + x + i) = - (colors[0] & 0x01) | (colors[1] & 0x02) - | (colors[2] & 0x04) | (colors[3] & 0x08) - | (colors[4] & 0x10) | (colors[5] & 0x20) - | (colors[6] & 0x40) | (colors[7] & 0x80); + m_bitmap->pix(YPOS + y, XPOS + x + i) = + (colors[0] & 0x01) | (colors[1] & 0x02) | + (colors[2] & 0x04) | (colors[3] & 0x08) | + (colors[4] & 0x10) | (colors[5] & 0x20) | + (colors[6] & 0x40) | (colors[7] & 0x80); colors[0] >>= 1; colors[1] >>= 1; colors[2] >>= 1; @@ -1800,7 +1772,6 @@ void vic3_device::interlace_draw_block( int x, int y, int offset ) void vic3_device::draw_block( int x, int y, int offset ) { int colors[8] = {0}; - int i, p; switch (VIC3_BITPLANES_MASK) { @@ -1847,13 +1818,13 @@ void vic3_device::draw_block( int x, int y, int offset ) if (VIC3_BITPLANES_MASK & 0x80) colors[7] = m_c64_mem_r_cb(VIC3_BITPLANE_ADDR(7) + offset) << 7; - for (i = 7; i >= 0; i--) + for (int i = 7; i >= 0; i--) { - m_bitmap->pix16(YPOS + y, XPOS + x + i) = - (colors[0] & 0x01) | (colors[1] & 0x02) - | (colors[2] & 0x04) | (colors[3] & 0x08) - | (colors[4] & 0x10) | (colors[5] & 0x20) - | (colors[6] & 0x40) | (colors[7] & 0x80); + m_bitmap->pix(YPOS + y, XPOS + x + i) = + (colors[0] & 0x01) | (colors[1] & 0x02) | + (colors[2] & 0x04) | (colors[3] & 0x08) | + (colors[4] & 0x10) | (colors[5] & 0x20) | + (colors[6] & 0x40) | (colors[7] & 0x80); colors[0] >>= 1; colors[1] >>= 1; colors[2] >>= 1; @@ -1869,17 +1840,15 @@ void vic3_device::draw_block( int x, int y, int offset ) void vic3_device::draw_bitplanes() { - int x, y, y1s, offset; - rectangle vis; const rectangle &visarea = screen().visible_area(); if (VIC3_LINES == 400) { /* interlaced! */ - for (y1s = 0, offset = 0; y1s < 400; y1s += 16) + for (int y1s = 0, offset = 0; y1s < 400; y1s += 16) { - for (x = 0; x < VIC3_BITPLANES_WIDTH; x += 8) + for (int x = 0; x < VIC3_BITPLANES_WIDTH; x += 8) { - for (y = y1s; y < y1s + 16; y += 2, offset++) + for (int y = y1s; y < y1s + 16; y += 2, offset++) { if (m_interlace) draw_block(x, y, offset); @@ -1892,11 +1861,11 @@ void vic3_device::draw_bitplanes() } else { - for (y1s = 0, offset = 0; y1s < 200; y1s += 8) + for (int y1s = 0, offset = 0; y1s < 200; y1s += 8) { - for (x = 0; x < VIC3_BITPLANES_WIDTH; x += 8) + for (int x = 0; x < VIC3_BITPLANES_WIDTH; x += 8) { - for (y = y1s; y < y1s + 8; y++, offset++) + for (int y = y1s; y < y1s + 8; y++, offset++) { draw_block(x, y, offset); } @@ -1906,25 +1875,25 @@ void vic3_device::draw_bitplanes() if (XPOS > 0) { - vis.set(0, XPOS - 1, 0, visarea.bottom()); + rectangle vis(0, XPOS - 1, 0, visarea.bottom()); m_bitmap->fill(FRAMECOLOR, vis); } if (XPOS + VIC3_BITPLANES_WIDTH < visarea.right()) { - vis.set(XPOS + VIC3_BITPLANES_WIDTH, visarea.right(), 0, visarea.bottom()); + rectangle vis(XPOS + VIC3_BITPLANES_WIDTH, visarea.right(), 0, visarea.bottom()); m_bitmap->fill(FRAMECOLOR, vis); } if (YPOS > 0) { - vis.set(0, visarea.right(), 0, YPOS - 1); + rectangle vis(0, visarea.right(), 0, YPOS - 1); m_bitmap->fill(FRAMECOLOR, vis); } if (YPOS + VIC3_LINES < visarea.bottom()) { - vis.set(0, visarea.right(), YPOS + VIC3_LINES, visarea.bottom()); + rectangle vis(0, visarea.right(), YPOS + VIC3_LINES, visarea.bottom()); m_bitmap->fill(FRAMECOLOR, vis); } } diff --git a/src/devices/video/voodoo.cpp b/src/devices/video/voodoo.cpp index 72ef43032ef..ebc9555f25c 100644 --- a/src/devices/video/voodoo.cpp +++ b/src/devices/video/voodoo.cpp @@ -917,8 +917,8 @@ int voodoo_device::voodoo_update(bitmap_rgb32 &bitmap, const rectangle &cliprect for (y = cliprect.min_y; y <= cliprect.max_y; y++) if (y >= fbi.yoffs) { - uint16_t *src = (uint16_t *)(fbi.ram + fbi.rgboffs[drawbuf]) + (y - fbi.yoffs) * fbi.rowpixels - fbi.xoffs; - uint32_t *dst = &bitmap.pix32(y); + uint16_t const *const src = (uint16_t *)(fbi.ram + fbi.rgboffs[drawbuf]) + (y - fbi.yoffs) * fbi.rowpixels - fbi.xoffs; + uint32_t *const dst = &bitmap.pix(y); for (x = cliprect.min_x; x <= cliprect.max_x; x++) dst[x] = fbi.pen[src[x]]; } @@ -944,8 +944,8 @@ int voodoo_device::voodoo_update(bitmap_rgb32 &bitmap, const rectangle &cliprect { for (y = cliprect.min_y; y <= cliprect.max_y; y++) { - uint16_t* src = (uint16_t*)(fbi.ram + fbi.auxoffs) + (y - fbi.yoffs) * fbi.rowpixels - fbi.xoffs; - uint32_t* dst = &bitmap.pix32(y); + uint16_t const *const src = (uint16_t*)(fbi.ram + fbi.auxoffs) + (y - fbi.yoffs) * fbi.rowpixels - fbi.xoffs; + uint32_t *const dst = &bitmap.pix(y); for (x = cliprect.min_x; x <= cliprect.max_x; x++) dst[x] = ((src[x] << 8) & 0xff0000) | ((src[x] >> 0) & 0xff00) | ((src[x] >> 8) & 0xff); } diff --git a/src/devices/video/vrender0.cpp b/src/devices/video/vrender0.cpp index f2bb5c74ac1..8a0e7c9319c 100644 --- a/src/devices/video/vrender0.cpp +++ b/src/devices/video/vrender0.cpp @@ -716,7 +716,7 @@ uint32_t vr0video_device::screen_update(screen_device &screen, bitmap_ind16 &bit uint32_t const dx = cliprect.left(); for (int y = cliprect.top(); y <= cliprect.bottom(); y++) - std::copy_n(&m_DisplayDest[(y * 1024) + dx], width, &bitmap.pix16(y, dx)); + std::copy_n(&m_DisplayDest[(y * 1024) + dx], width, &bitmap.pix(y, dx)); return 0; } diff --git a/src/devices/video/zeus2.cpp b/src/devices/video/zeus2.cpp index 0c6c34e3fcc..c585373c74e 100644 --- a/src/devices/video/zeus2.cpp +++ b/src/devices/video/zeus2.cpp @@ -8,6 +8,9 @@ #include "emu.h" #include "zeus2.h" +#include <algorithm> + + #define LOG_REGS 1 // Setting ALWAYS_LOG_FIFO will always log the fifo versus having to hold 'L' #define ALWAYS_LOG_FIFO 0 @@ -236,10 +239,7 @@ uint32_t zeus2_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap for (y = cliprect.min_y; y <= cliprect.max_y; y++) { uint32_t *colorptr = &m_frameColor[frame_addr_from_xy(0, y, false)]; - uint32_t *dest = &bitmap.pix32(y); - for (x = cliprect.min_x; x <= cliprect.max_x; x++) { - dest[x] = colorptr[x]; - } + std::copy(colorptr + cliprect.min_x, colorptr + cliprect.max_x + 1, &bitmap.pix(y, cliprect.min_x)); } } @@ -265,7 +265,7 @@ uint32_t zeus2_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap int xoffs = screen.visible_area().min_x; for (y = cliprect.min_y; y <= cliprect.max_y; y++) { - uint32_t *dest = &bitmap.pix32(y); + uint32_t *const dest = &bitmap.pix(y); for (x = cliprect.min_x; x <= cliprect.max_x; x++) { if (1) { |