From 9ce843c1d471d166f2844659bcc2ee2b092dee92 Mon Sep 17 00:00:00 2001 From: MooglyGuy Date: Sun, 30 Oct 2022 16:17:12 +0100 Subject: quantel/dpb7000.cpp: Major functional improvements. (#10467) [Ryan Holtz] * Added tablet comms HLE, improved drawing, and store combiner functionality. * Added hard disk support. Fixed Field-In/Field-Out IRQ polarity. * Fixed stencil-store selection - improves brush edges. * Fixed handling of horizontal and vertical scroll registers. * Added support for Framestore Read and Framestore Write commands. * Improved position matching between cursor and crosshair. * Started work on support for typeface brushes. * Fixed disk initialization, in-use flag was erroneously removed from Restore command. * Improved typeface emulation and keyboard emulation. * Improved text stamping. * Added known issues list to the driver's comment block. --- src/mame/quantel/dpb7000.cpp | 2721 +++++++++++++++++++++++++++++++----------- 1 file changed, 2019 insertions(+), 702 deletions(-) diff --git a/src/mame/quantel/dpb7000.cpp b/src/mame/quantel/dpb7000.cpp index d56bf759739..718d6b21dac 100644 --- a/src/mame/quantel/dpb7000.cpp +++ b/src/mame/quantel/dpb7000.cpp @@ -4,11 +4,24 @@ DPB-7001 (c) 1981 Quantel - Skeleton Driver + Known issues/possible improvements: + - Disk Sequencer Card is currently implemented via HLE. + - Tablet is currently implemented via HLE. + - Blanking PAL is currently disabled, which results in on-screen + garbage when scrolling. + - Size Card and Filter Card functionality is not yet implemented. + - Video input functionality is not yet implemented. + - There are numerous Brush Processor Card functions that are not yet + implemented. + + To create a hard disk image compatible with the "330Mb Fujitsu" DIP + setting: + - chdman createhd -o [output name] -chs 1024,16,80 -ss 256 -c none ***************************************************************************/ #include "emu.h" + #include "bus/rs232/rs232.h" #include "cpu/m68000/m68000.h" #include "cpu/m6800/m6800.h" @@ -16,6 +29,7 @@ #include "cpu/mcs48/mcs48.h" #include "cpu/z8/z8.h" #include "imagedev/floppy.h" +#include "imagedev/harddriv.h" #include "machine/6850acia.h" #include "machine/am25s55x.h" #include "machine/am2901b.h" @@ -26,8 +40,13 @@ #include "machine/mc68681.h" #include "machine/tdc1008.h" #include "video/mc6845.h" -#include "emupal.h" + #include "screen.h" +#include "emupal.h" + +#include "utf8.h" + +#include #include #define LOG_UNKNOWN (1 << 0) @@ -49,13 +68,25 @@ #define LOG_KEYBC (1 << 16) #define LOG_TDS (1 << 17) #define LOG_TABLET (1 << 18) -#define LOG_ALL (LOG_UNKNOWN | LOG_CSR | LOG_CTRLBUS | LOG_SYS_CTRL | LOG_FDC_CTRL | LOG_FDC_PORT | LOG_FDC_CMD | LOG_FDC_MECH | LOG_BRUSH_ADDR | \ - LOG_STORE_ADDR | LOG_COMBINER | LOG_SIZE_CARD | LOG_FILTER_CARD | LOG_TABLET) - -#define VERBOSE (LOG_TABLET) +#define LOG_COMMANDS (1 << 19) +#define LOG_HDD (1 << 20) +#define LOG_FDD (1 << 21) +#define LOG_DDB (1 << 22) +#define LOG_IRQ (1 << 23) +#define LOG_BRUSH_LATCH (1 << 24) +#define LOG_BRUSH_DRAWS (1 << 25) +#define LOG_BRUSH_WRITES (1 << 26) +#define LOG_STORE_READS (1 << 27) +#define LOG_ALL (LOG_UNKNOWN | LOG_CSR | LOG_CTRLBUS | LOG_SYS_CTRL | LOG_BRUSH_ADDR | \ + LOG_STORE_ADDR | LOG_COMBINER | LOG_SIZE_CARD | LOG_FILTER_CARD | LOG_COMMANDS | LOG_OUTPUT_TIMING | \ + LOG_BRUSH_LATCH | LOG_FDC_PORT | LOG_FDC_CMD | LOG_FDC_MECH | LOG_BRUSH_WRITES | LOG_STORE_READS) + +//#define VERBOSE (LOG_CSR | LOG_CTRLBUS | LOG_STORE_ADDR | LOG_COMBINER | LOG_SIZE_CARD | LOG_FILTER_CARD | LOG_BRUSH_ADDR | LOG_COMMANDS | LOG_OUTPUT_TIMING) +#define VERBOSE (0) #include "logmacro.h" -static const uint16_t temp_pen_reads[4] = { 573, 840, 1320, 1360 }; +namespace +{ class dpb7000_state : public driver_device { @@ -75,13 +106,24 @@ public: , m_auto_start(*this, "AUTOSTART") , m_config_sw12(*this, "CONFIGSW12") , m_config_sw34(*this, "CONFIGSW34") - , m_diskseq(*this, "diskseq") - , m_diskseq_ucode(*this, "diskseq_ucode") - , m_diskseq_prom(*this, "diskseq_prom") , m_fddcpu(*this, "fddcpu") , m_fdd_serial(*this, "fddserial") , m_floppy0(*this, "0") + , m_hdd(*this, "hdd") , m_floppy(nullptr) + , m_hdd_file(nullptr) + , m_output_cursor(*this, "output_timing_cursor") + , m_output_hlines(*this, "output_timing_hlines") + , m_output_hflags(*this, "output_timing_hflags") + , m_output_vlines(*this, "output_timing_vlines") + , m_output_vflags(*this, "output_timing_vflags") + , m_brushaddr_pal(*this, "brushaddr_pal") + , m_storeaddr_protx(*this, "storeaddr_prom_protx") + , m_storeaddr_proty(*this, "storeaddr_prom_proty") + , m_storeaddr_xlnib(*this, "storeaddr_prom_xlnib") + , m_storeaddr_xmnib(*this, "storeaddr_prom_xmnib") + , m_storeaddr_xhnib(*this, "storeaddr_prom_xhnib") + , m_storeaddr_pal_blank(*this, "storeaddr_pal_blank") , m_keybcpu(*this, "keybcpu") , m_keybc_cols(*this, "KEYB_COL%u", 0U) , m_tds_cpu(*this, "tds") @@ -89,30 +131,27 @@ public: , m_tds_dips(*this, "TDSDIPS") , m_pen_switches(*this, "PENSW") , m_tablet_cpu(*this, "tablet") - , m_tablet_dips(*this, "TABDIP%u", 0U) , m_pen_prox(*this, "PENPROX") , m_pen_x(*this, "PENX") , m_pen_y(*this, "PENY") - , m_filter_signalprom(*this, "filter_signalprom") - , m_filter_multprom(*this, "filter_multprom") - , m_filter_signal(nullptr) - , m_filter_mult(nullptr) - , m_size_yl(*this, "filter_de") - , m_size_yh(*this, "filter_df") - , m_size_xl(*this, "filter_dg") - , m_size_xh(*this, "filter_dh") + , m_pen_press(*this, "PENPRESS") + , m_brushproc_prom(*this, "brushproc_prom") + , m_brushproc_pal(*this, "brushproc_pal") { } void dpb7000(machine_config &config); - DECLARE_INPUT_CHANGED_MEMBER(pen_prox_changed); + //DECLARE_INPUT_CHANGED_MEMBER(pen_prox_changed); private: virtual void machine_start() override; virtual void machine_reset() override; - template uint32_t store_screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + template uint32_t store_debug_screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + uint32_t stencil_debug_screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + uint32_t brush_debug_screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + uint32_t combined_screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); void main_map(address_map &map); void fddcpu_map(address_map &map); @@ -130,10 +169,16 @@ private: uint16_t cpu_ctrlbus_r(); void cpu_ctrlbus_w(uint16_t data); - DECLARE_WRITE_LINE_MEMBER(req_a_w); - DECLARE_WRITE_LINE_MEMBER(req_b_w); + TIMER_CALLBACK_MEMBER(req_a_w); + TIMER_CALLBACK_MEMBER(req_b_w); + TIMER_CALLBACK_MEMBER(cmd_done); + TIMER_CALLBACK_MEMBER(execute_hdd_command); + bool is_disk_group_fdd(int group_index); + bool is_disk_group_hdd(int group_index); + int get_heads_for_disk_group(int group_index); void fdd_index_callback(floppy_image_device *floppy, int state); + void seek_fdd_to_cylinder(); uint8_t fdd_ctrl_r(); uint8_t fdd_cmd_r(); void fddcpu_p1_w(uint8_t data); @@ -141,14 +186,10 @@ private: void fddcpu_p2_w(uint8_t data); DECLARE_WRITE_LINE_MEMBER(fddcpu_debug_rx); - void handle_command(uint16_t data); + bool handle_command(uint16_t data); void store_address_w(uint8_t card, uint16_t data); void combiner_reg_w(uint16_t data); - TIMER_CALLBACK_MEMBER(diskseq_complete); - TIMER_CALLBACK_MEMBER(field_in); - TIMER_CALLBACK_MEMBER(field_out); - enum : uint16_t { SYSCTRL_AUTO_START = 0x0001, @@ -165,13 +206,11 @@ private: MC6845_UPDATE_ROW(crtc_update_row); MC6845_ON_UPDATE_ADDR_CHANGED(crtc_addr_changed); - void diskseq_y_w(uint16_t data); - void diskseq_tick(); - void advance_line_count(); void toggle_line_clock(); void process_sample(); void process_byte_from_disc(uint8_t data_byte); + uint8_t process_byte_to_disc(); required_device m_maincpu; required_device_array m_acia; @@ -181,19 +220,20 @@ private: required_device m_crtc; required_device m_palette; required_shared_ptr m_vdu_ram; - required_memory_region m_vdu_char_rom; + required_region_ptr m_vdu_char_rom; required_ioport m_baud_dip; required_ioport m_auto_start; required_ioport m_config_sw12; required_ioport m_config_sw34; - required_device m_diskseq; - required_memory_region m_diskseq_ucode; - required_memory_region m_diskseq_prom; - required_device m_fddcpu; required_device m_fdd_serial; + required_device m_floppy0; + required_device m_hdd; + + // Floppy Drive + floppy_image_device *m_floppy; std::deque m_fdd_debug_rx_bits; uint32_t m_fdd_debug_rx_bit_count; uint32_t m_fdd_debug_rx_byte_count; @@ -204,12 +244,15 @@ private: uint8_t m_fdd_side; fdc_pll_t m_fdd_pll; - required_device m_floppy0; - floppy_image_device *m_floppy; + // Hard Disk + hard_disk_file *m_hdd_file; + // Timers emu_timer *m_diskseq_complete_clk; emu_timer *m_field_in_clk; emu_timer *m_field_out_clk; + emu_timer *m_cmd_done_timer; + emu_timer *m_hdd_command_timer; enum : size_t { @@ -222,33 +265,20 @@ private: FRAMESTORE_COUNT }; - enum : uint8_t - { - DSEQ_STATUS_READY_BIT = 0, // C5 - DSEQ_STATUS_FAULT_BIT = 1, // C6 - DSEQ_STATUS_ONCYL_BIT = 2, // C7 - DSEQ_STATUS_SKERR_BIT = 3, // C8 - DSEQ_STATUS_INDEX_BIT = 4, // C9 - DSEQ_STATUS_SECTOR_BIT = 5, // C10 - DSEQ_STATUS_AMFND_BIT = 6, // C11 - DSEQ_STATUS_WTPROT_BIT = 7, // C12 - DSEQ_STATUS_SELECTED_BIT = 8, // C13 - DSEQ_STATUS_SEEKEND_BIT = 9, // C14 - DSEQ_STATUS_SYNC_DET_BIT = 10, // C15 - DSEQ_STATUS_RAM_ADDR_OVFLO_BIT = 11, // C16 - - DSEQ_CTRLOUT_CK_SEL_1 = (1 << 0), // S40 - DSEQ_CTRLOUT_CK_SEL_0 = (1 << 1), // S41 - DSEQ_CTRLOUT_ADDR_W_PERMIT = (1 << 2), // S42 - DSEQ_CTRLOUT_ZERO_RAM = (1 << 3), // S43 - DSEQ_CTRLOUT_WRITE_RAM = (1 << 4), // S44 - DSEQ_CTRLOUT_WORD_READ_RAM = (1 << 5), // S45 - DSEQ_CTRLOUT_WRITE_SYNC = (1 << 6), // S46 - DSEQ_CTRLOUT_SYNC_DET_EN = (1 << 7), // S47 - - DSEQ_CTRLOUT_WRITE_ZERO = (1 << 5), // S53 - DSEQ_CTRLOUT_LINE_CK = (1 << 6), // S54 - DSEQ_CTRLOUT_DISC_CLEAR = (1 << 7), // S55 + enum : uint16_t + { + DGROUP_TYPE_INVALID0 = 0, + DGROUP_TYPE_80MB_CDC = 1, + DGROUP_TYPE_INVALID1 = 2, + DGROUP_TYPE_FLOPPY = 3, + DGROUP_TYPE_INVALID2 = 4, + DGROUP_TYPE_330MB_FUJITSU = 5, + DGROUP_TYPE_160MB_FUJITSU = 6, + DGROUP_TYPE_NONE = 7, + + DGROUP_0_SHIFT = 2, + DGROUP_1_SHIFT = 7, + DGROUP_2_SHIFT = 12 }; // Computer Card @@ -256,22 +286,15 @@ private: uint16_t m_sys_ctrl; // Disc Sequencer Card - int m_diskseq_cp; - bool m_diskseq_reset; - bool m_diskseq_halt; - uint8_t m_diskseq_line_cnt; // EF/EE - uint8_t m_diskseq_ed_cnt; // ED - uint8_t m_diskseq_head_cnt; // EC uint16_t m_diskseq_cyl_from_cpu; // AE/BH uint16_t m_diskseq_cmd_word_from_cpu; // DD/CC uint8_t m_diskseq_cmd; - uint8_t m_diskseq_cyl_to_ctrl; uint8_t m_diskseq_cmd_to_ctrl; - uint8_t m_diskseq_status_in; // CG - uint8_t m_diskseq_status_out; // BC - uint8_t m_diskseq_ucode_latch[7]; // GG/GF/GE/GD/GC/GB/GA - uint8_t m_diskseq_cc_inputs[4]; // Inputs to FE/FD/FC/FB + uint8_t m_diskseq_status; // BC bool m_diskseq_cyl_read_pending; + bool m_diskseq_cyl_write_pending; + bool m_diskseq_use_hdd_pending; + uint16_t m_diskseq_command_stride; // Disc Data Buffer Card uint16_t m_diskbuf_ram_addr; @@ -283,12 +306,21 @@ private: uint16_t m_cursor_origin_y; uint16_t m_cursor_size_x; uint16_t m_cursor_size_y; + uint8_t m_output_csflags; + uint8_t m_output_cpflags; + required_region_ptr m_output_cursor; + required_region_ptr m_output_hlines; + required_region_ptr m_output_hflags; + required_region_ptr m_output_vlines; + required_region_ptr m_output_vflags; // Brush Address Card + required_region_ptr m_brushaddr_pal; uint8_t m_line_clock; uint16_t m_line_count; uint16_t m_line_length; uint16_t m_brush_addr_func; + uint8_t m_brush_addr_cmd; uint8_t m_bif; uint8_t m_bixos; uint8_t m_biyos; @@ -296,8 +328,8 @@ private: uint16_t m_bylen; uint16_t m_bxlen_counter; uint16_t m_bylen_counter; - uint8_t m_plum; - uint8_t m_pchr; + uint8_t m_brush_press_lum; + uint8_t m_brush_press_chr; std::unique_ptr m_framestore_chr[2]; std::unique_ptr m_framestore_lum[2]; std::unique_ptr m_framestore_ext[2]; @@ -319,12 +351,18 @@ private: uint16_t m_cxpos[2]; uint16_t m_cypos[2]; uint16_t m_ca0; + required_region_ptr m_storeaddr_protx; + required_region_ptr m_storeaddr_proty; + required_region_ptr m_storeaddr_xlnib; + required_region_ptr m_storeaddr_xmnib; + required_region_ptr m_storeaddr_xhnib; + required_region_ptr m_storeaddr_pal_blank; // Combiner Card uint8_t m_cursor_y; uint8_t m_cursor_u; uint8_t m_cursor_v; - uint8_t m_invert_mask; + uint8_t m_ext_store_flags; bool m_select_matte[2]; uint8_t m_matte_ext[2]; uint8_t m_matte_y[2]; @@ -345,12 +383,22 @@ private: uint8_t m_keybc_tx; // TDS Box + enum tds_press_state : uint32_t + { + STATE_IDLE, + STATE_PRESS_IN, + STATE_PRESSED, + STATE_PRESS_OUT + }; + required_device m_tds_cpu; required_device m_tds_duart; required_ioport m_tds_dips; required_ioport m_pen_switches; uint8_t tds_p1_r(); uint8_t tds_p2_r(); + uint8_t tds_p3_r(); + uint8_t tds_p4_r(); void tds_p1_w(uint8_t data); void tds_p2_w(uint8_t data); void tds_dac_w(uint8_t data); @@ -359,16 +407,26 @@ private: uint8_t tds_pen_switches_r(); DECLARE_WRITE_LINE_MEMBER(duart_b_w); TIMER_CALLBACK_MEMBER(tablet_tx_tick); + TIMER_CALLBACK_MEMBER(tds_adc_tick); + TIMER_CALLBACK_MEMBER(tds_press_tick); uint8_t m_tds_dac_value; + uint8_t m_tds_dac_offset; + float m_tds_dac_percent; + bool m_tds_adc_busy; uint8_t m_tds_adc_value; uint8_t m_tds_p1_data; + uint32_t m_tds_press_state; + uint8_t m_tds_pressure_shift; + emu_timer *m_tds_adc_timer; + emu_timer *m_tds_press_timer; + bool m_tds_in_proximity; // Tablet required_device m_tablet_cpu; - required_ioport_array<2> m_tablet_dips; required_ioport m_pen_prox; required_ioport m_pen_x; required_ioport m_pen_y; + required_ioport m_pen_press; uint8_t tablet_p2_r(offs_t offset, uint8_t mem_mask); void tablet_p2_w(offs_t offset, uint8_t data, uint8_t mem_mask); uint8_t tablet_p3_r(offs_t offset, uint8_t mem_mask); @@ -385,28 +443,40 @@ private: emu_timer *m_tablet_tx_timer; emu_timer *m_tablet_irq_timer; uint8_t m_tablet_tx_bit; - bool m_tablet_pen_in_proximity; + uint16_t m_tablet_pen_x; + uint16_t m_tablet_pen_y; + uint16_t m_tablet_pen_switches; uint8_t m_tablet_state; + // Table HLE + TIMER_CALLBACK_MEMBER(tablet_hle_tick); + std::deque m_tablet_hle_tx_bits; + emu_timer *m_tablet_hle_timer; + // Filter Card - required_memory_region m_filter_signalprom; - required_memory_region m_filter_multprom; - uint8_t *m_filter_signal; - uint8_t *m_filter_mult; - uint8_t m_filter_acbc[16]; - uint8_t m_filter_abbb[16]; + int8_t m_filter_x_coeffs[12]; + int8_t m_filter_y_coeffs[8]; uint8_t m_incoming_lum; uint8_t m_incoming_chr; bool m_buffer_lum; // Size Card - required_device m_size_yl; - required_device m_size_yh; - required_device m_size_xl; - required_device m_size_xh; - - uint8_t m_size_h; - uint8_t m_size_v; + uint32_t m_size_dsx_ddx; + uint32_t m_size_dsy_ddx; + uint32_t m_size_dsx_ddy; + uint32_t m_size_dsy_ddy; + uint8_t m_size_frac_origin_sx_dx; + uint8_t m_size_frac_origin_sy_dx; + uint8_t m_size_frac_origin_sx_dy; + uint8_t m_size_frac_origin_sy_dy; + int16_t m_size_dxdx_counter; + int16_t m_size_dydy_counter; + uint16_t m_size_dest_x; + uint16_t m_size_dest_y; + + // Brush Processor Card + required_region_ptr m_brushproc_prom; + required_region_ptr m_brushproc_pal; // Utility std::unique_ptr m_yuv_lut; @@ -414,9 +484,12 @@ private: void dpb7000_state::main_map(address_map &map) { - map(0x000000, 0x07ffff).rom().region("monitor", 0); + map(0x000000, 0x09ffff).rom().region("monitor", 0); + map(0x0006aa, 0x0006ab).nopw(); map(0xb00000, 0xb7ffff).rw(FUNC(dpb7000_state::bus_error_r), FUNC(dpb7000_state::bus_error_w)); map(0xb80000, 0xbfffff).ram(); + //map(0xb00000, 0xbfffff).rw(FUNC(dpb7000_state::bus_error_r), FUNC(dpb7000_state::bus_error_w)); + //map(0xfc0000, 0xffd3ff).ram(); map(0xffd000, 0xffd3ff).rw(FUNC(dpb7000_state::bus_error_r), FUNC(dpb7000_state::bus_error_w)); map(0xffe000, 0xffefff).ram().share("vduram").umask16(0x00ff); map(0xfff801, 0xfff801).rw(m_crtc, FUNC(sy6545_1_device::status_r), FUNC(sy6545_1_device::address_w)).cswidth(16); @@ -470,9 +543,9 @@ static INPUT_PORTS_START( dpb7000 ) PORT_START("KEYB_COL0") PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M') - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(u8"9 ) \u2013") PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')') PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N') - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(u8"8 ( \u2014") PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(') PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K') PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U') PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J') @@ -480,9 +553,9 @@ static INPUT_PORTS_START( dpb7000 ) PORT_START("KEYB_COL1") PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y') PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B') - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("7 \' @") PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('\'') PORT_CHAR('@') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(u8"7 \u2019 \u2018") PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('\'') PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('&') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(u8"6 & \u00bb") PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('&') PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H') PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T') PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G') @@ -490,83 +563,83 @@ static INPUT_PORTS_START( dpb7000 ) PORT_START("KEYB_COL2") PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R') PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V') - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("5 % >") PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') PORT_CHAR('>') PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C') - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("4 $ <") PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') PORT_CHAR('<') PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F') PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E') PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D') PORT_START("KEYB_COL3") PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P') - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(". : >") PORT_CODE(KEYCODE_STOP) PORT_CHAR ('.') PORT_CHAR(':') PORT_CHAR('>') - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("\" = #") PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\"') PORT_CHAR('=') - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('d') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(u8". : \u00e6") PORT_CODE(KEYCODE_STOP) PORT_CHAR ('.') PORT_CHAR(':') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(u8"\u00b9 = ~") PORT_CODE(KEYCODE_MINUS) PORT_CHAR('=') + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(u8", ;") PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR(';') PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR('-') - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_UNUSED) // 0x16 - arrow key? + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(u8"\ufb02 + \u00c6") PORT_CODE(KEYCODE_COLON) PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O') PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L') PORT_START("KEYB_COL4") PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W') PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X') - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('\\') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(u8"3 \u00a3 \u00ab") PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z') - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("2 \" _") PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('\"') PORT_CHAR('_') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("2 \"") PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('\"') PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S') PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q') PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A') PORT_START("KEYB_COL5") PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_TAB) PORT_CHAR('\t') - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LSHIFT) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Left Shift") PORT_CODE(KEYCODE_LSHIFT) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') PORT_CHAR('#') PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Ctrl") PORT_CODE(KEYCODE_LCONTROL) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_UNUSED) // 0x1b - arrow key? - PORT_BIT(0xe0, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0xf0, IP_ACTIVE_LOW, IPT_UNUSED) PORT_START("KEYB_COL6") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR('}') - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_RSHIFT) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('^') PORT_CHAR('|') - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_TILDE) PORT_CHAR('~') - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_UNUSED) // 0x1a - arrow key? - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('{') - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('\x19') PORT_CHAR('*') + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("` ` " A_RING) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR('}') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Right Shift") PORT_CODE(KEYCODE_RSHIFT) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(u8"\ua788 \u02c6 \u00f8") PORT_CODE(KEYCODE_EQUALS) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(u8"/ ? \u0153") PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(u8"\u0324 \u00a8 \u00d8") PORT_CODE(KEYCODE_TILDE) PORT_CHAR('~') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(u8"\u00df \u00b8 " a_RING) PORT_CODE(KEYCODE_BACKSLASH) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(u8"\u00b4 \u00b4 ~") PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('{') + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(u8"\ufb01 * \u03d2") PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('*') PORT_START("KEYB_COL7") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNUSED) // 0x0b - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_UNUSED) // 0x09 + PORT_BIT(0x03, IP_ACTIVE_LOW, IPT_UNUSED) PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Esc") PORT_CODE(KEYCODE_ESC) // 0x7f PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Delete") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR('\x08') // 0x08 - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_UNUSED) // 0x7f - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_UNUSED) //PORT_NAME("Return") PORT_CODE(KEYCODE_ENTER) PORT_CHAR('\x0d') + PORT_BIT(0x30, IP_ACTIVE_LOW, IPT_UNUSED) PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Enter") PORT_CODE(KEYCODE_ENTER) PORT_CHAR('\x0d') - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) // PORT_NAME("Carriage Return") PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHAR('\x0d') + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) PORT_START("PENSW") - PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON2) PORT_NAME("Pen Button 1") PORT_CODE(MOUSECODE_BUTTON2) + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON2) PORT_NAME("Pen Button 1") PORT_CODE(MOUSECODE_BUTTON1) PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_BUTTON3) PORT_NAME("Pen Button 2") PORT_CODE(MOUSECODE_BUTTON3) PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_BUTTON4) PORT_NAME("Pen Button 3") PORT_CODE(MOUSECODE_BUTTON4) PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_BUTTON5) PORT_NAME("Pen Button 4") PORT_CODE(MOUSECODE_BUTTON5) PORT_BIT(0xf0, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_START("PENPROX") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_NAME("Pen Proximity") PORT_CODE(MOUSECODE_BUTTON1) PORT_CHANGED_MEMBER(DEVICE_SELF, dpb7000_state, pen_prox_changed, 0) + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_NAME("Pen Proximity") PORT_CODE(MOUSECODE_BUTTON2) PORT_BIT(0xfe, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_START("PENX") - PORT_BIT( 0xffff, 5000, IPT_LIGHTGUN_X) PORT_NAME("Pen X") PORT_MINMAX(0, 10000) PORT_SENSITIVITY(50) PORT_CROSSHAIR(X, 1.0, 0.0, 0) + PORT_BIT( 0xffff, 3800, IPT_LIGHTGUN_X) PORT_NAME("Pen X") PORT_MINMAX(500, 4599) PORT_SENSITIVITY(50) PORT_CROSSHAIR(X, 1.385, -0.17, 0) PORT_START("PENY") - PORT_BIT( 0xffff, 5000, IPT_LIGHTGUN_Y) PORT_NAME("Pen Y") PORT_MINMAX(0, 10000) PORT_SENSITIVITY(50) PORT_CROSSHAIR(Y, 1.0, 0.0, 0) + PORT_BIT( 0xffff, 2048, IPT_LIGHTGUN_Y) PORT_NAME("Pen Y") PORT_MINMAX(1000, 4399) PORT_SENSITIVITY(50) PORT_CROSSHAIR(Y, 1.53, -0.26, 0) + + PORT_START("PENPRESS") + PORT_BIT( 0xff, 0x02, IPT_PEDAL ) PORT_MINMAX(0x02,0xaf) PORT_SENSITIVITY(100) PORT_KEYDELTA(10) PORT_START("TDSDIPS") - PORT_DIPNAME(0x08, 0x00, "TDS Box Encoding") + PORT_DIPNAME(0x08, 0x08, "TDS Box Encoding") PORT_DIPSETTING( 0x08, "Binary") PORT_DIPSETTING( 0x00, "ASCII") - PORT_DIPNAME(0x10, 0x00, "TDS Box Mode") + PORT_DIPNAME(0x10, 0x10, "TDS Box Mode") PORT_DIPSETTING( 0x10, "Normal") PORT_DIPSETTING( 0x00, "Monitor") PORT_DIPNAME(0x40, 0x00, "TDS Box Standard") @@ -574,58 +647,6 @@ static INPUT_PORTS_START( dpb7000 ) PORT_DIPSETTING( 0x00, "PAL") PORT_BIT(0xa7, IP_ACTIVE_HIGH, IPT_UNUSED) - PORT_START("TABDIP0") - PORT_DIPNAME(0x01, 0x00, "Tablet SW1:1"); - PORT_DIPSETTING( 0x00, DEF_STR( Off )) - PORT_DIPSETTING( 0x01, DEF_STR( On )) - PORT_DIPNAME(0x02, 0x00, "Tablet SW1:2"); - PORT_DIPSETTING( 0x00, DEF_STR( Off )) - PORT_DIPSETTING( 0x02, DEF_STR( On )) - PORT_DIPNAME(0x04, 0x00, "Tablet SW1:3"); - PORT_DIPSETTING( 0x00, DEF_STR( Off )) - PORT_DIPSETTING( 0x04, DEF_STR( On )) - PORT_DIPNAME(0x08, 0x00, "Tablet SW1:4"); - PORT_DIPSETTING( 0x00, DEF_STR( Off )) - PORT_DIPSETTING( 0x08, DEF_STR( On )) - PORT_DIPNAME(0x10, 0x00, "Tablet SW1:5"); - PORT_DIPSETTING( 0x00, DEF_STR( Off )) - PORT_DIPSETTING( 0x10, DEF_STR( On )) - PORT_DIPNAME(0x20, 0x00, "Tablet SW1:6"); - PORT_DIPSETTING( 0x00, DEF_STR( Off )) - PORT_DIPSETTING( 0x20, DEF_STR( On )) - PORT_DIPNAME(0x40, 0x00, "Tablet SW1:7"); - PORT_DIPSETTING( 0x00, DEF_STR( Off )) - PORT_DIPSETTING( 0x40, DEF_STR( On )) - PORT_DIPNAME(0x80, 0x00, "Tablet SW1:8"); - PORT_DIPSETTING( 0x00, DEF_STR( Off )) - PORT_DIPSETTING( 0x80, DEF_STR( On )) - - PORT_START("TABDIP1") - PORT_DIPNAME(0x01, 0x00, "Tablet SW2:1"); - PORT_DIPSETTING( 0x00, DEF_STR( Off )) - PORT_DIPSETTING( 0x01, DEF_STR( On )) - PORT_DIPNAME(0x02, 0x00, "Tablet SW2:2"); - PORT_DIPSETTING( 0x00, DEF_STR( Off )) - PORT_DIPSETTING( 0x02, DEF_STR( On )) - PORT_DIPNAME(0x04, 0x00, "Tablet SW2:3"); - PORT_DIPSETTING( 0x00, DEF_STR( Off )) - PORT_DIPSETTING( 0x04, DEF_STR( On )) - PORT_DIPNAME(0x08, 0x00, "Tablet SW2:4"); - PORT_DIPSETTING( 0x00, DEF_STR( Off )) - PORT_DIPSETTING( 0x08, DEF_STR( On )) - PORT_DIPNAME(0x10, 0x00, "Tablet SW2:5"); - PORT_DIPSETTING( 0x00, DEF_STR( Off )) - PORT_DIPSETTING( 0x10, DEF_STR( On )) - PORT_DIPNAME(0x20, 0x00, "Tablet SW2:6"); - PORT_DIPSETTING( 0x00, DEF_STR( Off )) - PORT_DIPSETTING( 0x20, DEF_STR( On )) - PORT_DIPNAME(0x40, 0x00, "Tablet SW2:7"); - PORT_DIPSETTING( 0x00, DEF_STR( Off )) - PORT_DIPSETTING( 0x40, DEF_STR( On )) - PORT_DIPNAME(0x80, 0x00, "Tablet SW2:8"); - PORT_DIPSETTING( 0x00, DEF_STR( Off )) - PORT_DIPSETTING( 0x80, DEF_STR( On )) - PORT_START("BAUD") PORT_DIPNAME(0x0f, 0x0e, "Baud Rate for Terminal") PORT_DIPSETTING( 0x00, "50") @@ -645,7 +666,7 @@ static INPUT_PORTS_START( dpb7000 ) PORT_DIPSETTING( 0x0f, "19200") PORT_START("AUTOSTART") - PORT_DIPNAME(0x0001, 0x0000, "Auto-Start") + PORT_DIPNAME(0x0001, 0x0001, "Auto-Start") PORT_DIPSETTING( 0x0000, DEF_STR( Off )) PORT_DIPSETTING( 0x0001, DEF_STR( On )) PORT_BIT(0xfffe, IP_ACTIVE_HIGH, IPT_UNUSED) @@ -654,7 +675,7 @@ static INPUT_PORTS_START( dpb7000 ) PORT_DIPNAME( 0x0001, 0x0001, DEF_STR( Unknown ) ) PORT_DIPSETTING( 0x0001, DEF_STR( Off ) ) PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x0002, 0x0002, "NTSC/PAL" ) + PORT_DIPNAME( 0x0002, 0x0000, "NTSC/PAL" ) PORT_DIPSETTING( 0x0002, "NTSC" ) PORT_DIPSETTING( 0x0000, "PAL" ) PORT_DIPNAME( 0x0004, 0x0004, DEF_STR( Unknown ) ) @@ -666,7 +687,7 @@ static INPUT_PORTS_START( dpb7000 ) PORT_DIPNAME( 0x0010, 0x0010, DEF_STR( Unknown ) ) PORT_DIPSETTING( 0x0010, DEF_STR( Off ) ) PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x0020, 0x0020, DEF_STR( Unknown ) ) + PORT_DIPNAME( 0x0020, 0x0020, "Diagnostic Mode" ) PORT_DIPSETTING( 0x0020, DEF_STR( Off ) ) PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) PORT_DIPNAME( 0x0040, 0x0040, DEF_STR( Unknown ) ) @@ -706,11 +727,10 @@ static INPUT_PORTS_START( dpb7000 ) PORT_DIPSETTING( 0x0002, "Two" ) PORT_DIPSETTING( 0x0001, "Three" ) PORT_DIPSETTING( 0x0000, "Four" ) - PORT_DIPNAME( 0x001c, 0x0018, "Disc Group 0 Type" ) + PORT_DIPNAME( 0x001c, 0x000c, "Disc Group 0 Type" ) PORT_DIPSETTING( 0x001c, "None" ) PORT_DIPSETTING( 0x0018, "160Mb Fujitsu" ) PORT_DIPSETTING( 0x0014, "330Mb Fujitsu" ) - PORT_DIPSETTING( 0x0010, "80Mb Fujitsu" ) PORT_DIPSETTING( 0x000c, "Floppy Disc" ) PORT_DIPSETTING( 0x0008, "NTSC/Floppy/PAL/Conv" ) PORT_DIPSETTING( 0x0004, "80Mb CDC Removable" ) @@ -720,11 +740,10 @@ static INPUT_PORTS_START( dpb7000 ) PORT_DIPSETTING( 0x0040, "Two" ) PORT_DIPSETTING( 0x0020, "Three" ) PORT_DIPSETTING( 0x0000, "Four" ) - PORT_DIPNAME( 0x0380, 0x0180, "Disc Group 1 Type" ) + PORT_DIPNAME( 0x0380, 0x0380, "Disc Group 1 Type" ) PORT_DIPSETTING( 0x0380, "None" ) PORT_DIPSETTING( 0x0300, "160Mb Fujitsu" ) PORT_DIPSETTING( 0x0280, "330Mb Fujitsu" ) - PORT_DIPSETTING( 0x0200, "80Mb Fujitsu" ) PORT_DIPSETTING( 0x0180, "Floppy Disc" ) PORT_DIPSETTING( 0x0100, "NTSC/Floppy/PAL/Conv" ) PORT_DIPSETTING( 0x0080, "80Mb CDC Removable" ) @@ -738,7 +757,6 @@ static INPUT_PORTS_START( dpb7000 ) PORT_DIPSETTING( 0x7000, "None" ) PORT_DIPSETTING( 0x6000, "160Mb Fujitsu" ) PORT_DIPSETTING( 0x5000, "330Mb Fujitsu" ) - PORT_DIPSETTING( 0x4000, "80Mb Fujitsu" ) PORT_DIPSETTING( 0x3000, "Floppy Disc" ) PORT_DIPSETTING( 0x2000, "NTSC/Floppy/PAL/Conv" ) PORT_DIPSETTING( 0x1000, "80Mb CDC Removable" ) @@ -754,30 +772,29 @@ void dpb7000_state::machine_start() save_item(NAME(m_csr)); save_item(NAME(m_sys_ctrl)); - m_field_in_clk = timer_alloc(FUNC(dpb7000_state::field_in), this); + m_field_in_clk = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(dpb7000_state::req_a_w), this)); m_field_in_clk->adjust(attotime::never); - m_field_out_clk = timer_alloc(FUNC(dpb7000_state::field_out), this); + m_field_out_clk = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(dpb7000_state::req_a_w), this)); m_field_out_clk->adjust(attotime::never); + m_cmd_done_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(dpb7000_state::cmd_done), this)); + m_cmd_done_timer->adjust(attotime::never); + + m_hdd_command_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(dpb7000_state::execute_hdd_command), this)); + m_hdd_command_timer->adjust(attotime::never); + // Disc Sequencer Card - save_item(NAME(m_diskseq_cp)); - save_item(NAME(m_diskseq_reset)); - save_item(NAME(m_diskseq_halt)); - save_item(NAME(m_diskseq_line_cnt)); - save_item(NAME(m_diskseq_ed_cnt)); - save_item(NAME(m_diskseq_head_cnt)); save_item(NAME(m_diskseq_cyl_from_cpu)); save_item(NAME(m_diskseq_cmd_word_from_cpu)); save_item(NAME(m_diskseq_cmd)); - save_item(NAME(m_diskseq_cyl_to_ctrl)); save_item(NAME(m_diskseq_cmd_to_ctrl)); - save_item(NAME(m_diskseq_status_in)); - save_item(NAME(m_diskseq_status_out)); - save_item(NAME(m_diskseq_ucode_latch)); - save_item(NAME(m_diskseq_cc_inputs)); + save_item(NAME(m_diskseq_status)); save_item(NAME(m_diskseq_cyl_read_pending)); - m_diskseq_complete_clk = timer_alloc(FUNC(dpb7000_state::diskseq_complete), this); + save_item(NAME(m_diskseq_cyl_write_pending)); + save_item(NAME(m_diskseq_use_hdd_pending)); + save_item(NAME(m_diskseq_command_stride)); + m_diskseq_complete_clk = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(dpb7000_state::req_b_w), this));; m_diskseq_complete_clk->adjust(attotime::never); // Floppy Disc Controller Card @@ -799,12 +816,15 @@ void dpb7000_state::machine_start() save_item(NAME(m_cursor_origin_y)); save_item(NAME(m_cursor_size_x)); save_item(NAME(m_cursor_size_y)); + save_item(NAME(m_output_csflags)); + save_item(NAME(m_output_cpflags)); // Brush Address Card save_item(NAME(m_line_clock)); save_item(NAME(m_line_count)); save_item(NAME(m_line_length)); save_item(NAME(m_brush_addr_func)); + save_item(NAME(m_brush_addr_cmd)); save_item(NAME(m_bif)); save_item(NAME(m_bixos)); save_item(NAME(m_biyos)); @@ -812,8 +832,8 @@ void dpb7000_state::machine_start() save_item(NAME(m_bylen)); save_item(NAME(m_bxlen_counter)); save_item(NAME(m_bylen_counter)); - save_item(NAME(m_plum)); - save_item(NAME(m_pchr)); + save_item(NAME(m_brush_press_lum)); + save_item(NAME(m_brush_press_chr)); // Frame Store Cards, 640x1024 for (int i = 0; i < 2; i++) @@ -854,7 +874,7 @@ void dpb7000_state::machine_start() save_item(NAME(m_cursor_y)); save_item(NAME(m_cursor_u)); save_item(NAME(m_cursor_v)); - save_item(NAME(m_invert_mask)); + save_item(NAME(m_ext_store_flags)); save_item(NAME(m_select_matte)); save_item(NAME(m_matte_ext)); save_item(NAME(m_matte_y)); @@ -862,14 +882,22 @@ void dpb7000_state::machine_start() save_item(NAME(m_matte_v)); // Size Card - save_item(NAME(m_size_h)); - save_item(NAME(m_size_v)); + save_item(NAME(m_size_dsx_ddx)); + save_item(NAME(m_size_dsy_ddx)); + save_item(NAME(m_size_dsx_ddy)); + save_item(NAME(m_size_dsy_ddy)); + save_item(NAME(m_size_frac_origin_sx_dx)); + save_item(NAME(m_size_frac_origin_sy_dx)); + save_item(NAME(m_size_frac_origin_sx_dy)); + save_item(NAME(m_size_frac_origin_sy_dy)); + save_item(NAME(m_size_dxdx_counter)); + save_item(NAME(m_size_dydy_counter)); + save_item(NAME(m_size_dest_x)); + save_item(NAME(m_size_dest_y)); // Filter Card - m_filter_signal = m_filter_signalprom->base(); - m_filter_mult = m_filter_multprom->base(); - save_item(NAME(m_filter_acbc)); - save_item(NAME(m_filter_abbb)); + save_item(NAME(m_filter_x_coeffs)); + save_item(NAME(m_filter_y_coeffs)); save_item(NAME(m_incoming_lum)); save_item(NAME(m_incoming_chr)); save_item(NAME(m_buffer_lum)); @@ -881,7 +909,17 @@ void dpb7000_state::machine_start() // TDS Box save_item(NAME(m_tds_dac_value)); + save_item(NAME(m_tds_dac_offset)); + save_item(NAME(m_tds_dac_percent)); + save_item(NAME(m_tds_adc_busy)); save_item(NAME(m_tds_adc_value)); + save_item(NAME(m_tds_press_state)); + save_item(NAME(m_tds_pressure_shift)); + save_item(NAME(m_tds_in_proximity)); + m_tds_adc_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(dpb7000_state::tds_adc_tick), this)); + m_tds_adc_timer->adjust(attotime::never); + m_tds_press_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(dpb7000_state::tds_press_tick), this)); + m_tds_press_timer->adjust(attotime::never); // Tablet save_item(NAME(m_tablet_p2_data)); @@ -889,13 +927,19 @@ void dpb7000_state::machine_start() save_item(NAME(m_tablet_dip_shifter)); save_item(NAME(m_tablet_counter_latch)); save_item(NAME(m_tablet_tx_bit)); - save_item(NAME(m_tablet_pen_in_proximity)); + save_item(NAME(m_tablet_pen_x)); + save_item(NAME(m_tablet_pen_y)); + save_item(NAME(m_tablet_pen_switches)); save_item(NAME(m_tablet_state)); - m_tablet_tx_timer = timer_alloc(FUNC(dpb7000_state::tablet_tx_tick), this); + m_tablet_tx_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(dpb7000_state::tablet_tx_tick), this)); m_tablet_tx_timer->adjust(attotime::never); - m_tablet_irq_timer = timer_alloc(FUNC(dpb7000_state::tablet_irq_tick), this); + m_tablet_irq_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(dpb7000_state::tablet_irq_tick), this)); m_tablet_irq_timer->adjust(attotime::never); + // Tablet HLE + m_tablet_hle_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(dpb7000_state::tablet_hle_tick), this)); + m_tablet_hle_timer->adjust(attotime::never); + m_yuv_lut = std::make_unique(0x1000000); for (uint16_t u = 0; u < 256; u++) { @@ -917,10 +961,12 @@ void dpb7000_state::machine_start() void dpb7000_state::machine_reset() { + m_cmd_done_timer->adjust(attotime::never); + // Computer Card m_brg->stt_w(m_baud_dip->read()); m_csr = 0; - m_sys_ctrl = SYSCTRL_REQ_B_IN; + m_sys_ctrl = 0; for (int i = 0; i < 3; i++) { m_acia[i]->write_cts(0); @@ -928,26 +974,20 @@ void dpb7000_state::machine_reset() } m_field_in_clk->adjust(attotime::from_hz(59.94), 0, attotime::from_hz(59.94)); - m_field_out_clk->adjust(attotime::from_hz(59.94) + attotime::from_hz(15734.0 / 1.0), 0, attotime::from_hz(59.94)); + m_field_out_clk->adjust(attotime::from_hz(59.94) + attotime::from_hz(15734.0 / 1.0), 1, attotime::from_hz(59.94)); // Disc Sequencer Card - m_diskseq_cp = 0; - m_diskseq_reset = false; - m_diskseq_halt = true; - m_diskseq_line_cnt = 0; - m_diskseq_ed_cnt = 0; - m_diskseq_head_cnt = 0; m_diskseq_cyl_from_cpu = 0; m_diskseq_cmd_word_from_cpu = 0; m_diskseq_cmd = 0; - m_diskseq_cyl_to_ctrl = 0; m_diskseq_cmd_to_ctrl = 0; - m_diskseq_status_in = 0; - m_diskseq_status_out = 0xf9; - memset(m_diskseq_ucode_latch, 0, 7); - memset(m_diskseq_cc_inputs, 0, 4); + m_diskseq_status = 0xf9; m_diskseq_cyl_read_pending = false; + m_diskseq_cyl_write_pending = false; + m_diskseq_use_hdd_pending = false; + m_diskseq_command_stride = 1; m_diskseq_complete_clk->adjust(attotime::never); + m_hdd_command_timer->adjust(attotime::never); // Floppy Disc Controller Card m_fdd_debug_rx_bits.clear(); @@ -962,6 +1002,9 @@ void dpb7000_state::machine_reset() m_fdd_pll.reset(machine().time()); m_floppy = nullptr; + // Hard Disc Handling + m_hdd_file = m_hdd->get_hard_disk_file(); + // Disc Data Buffer Card m_diskbuf_ram_addr = 0; memset(m_diskbuf_ram, 0, 14 * 0x800); @@ -972,12 +1015,15 @@ void dpb7000_state::machine_reset() m_cursor_origin_y = 0; m_cursor_size_x = 0; m_cursor_size_y = 0; + m_output_csflags = 0; + m_output_cpflags = 0; // Brush Address Card m_line_clock = 0; m_line_count = 0; m_line_length = 0; m_brush_addr_func = 0; + m_brush_addr_cmd = 0; m_bif = 0; m_bixos = 0; m_biyos = 0; @@ -985,8 +1031,8 @@ void dpb7000_state::machine_reset() m_bylen = 0; m_bxlen_counter = 0; m_bylen_counter = 0; - m_plum = 0; - m_pchr = 0; + m_brush_press_lum = 0; + m_brush_press_chr = 0; // Frame Store Cards, 640x1024 for (int i = 0; i < 2; i++) @@ -1005,20 +1051,20 @@ void dpb7000_state::machine_reset() memset(&m_brushstore_ext[0], 0, 0x10000); // Store Address Card - memset(m_rhscr, 0, sizeof(uint16_t) * 2); - memset(m_rvscr, 0, sizeof(uint16_t) * 2); - memset(m_rzoom, 0, sizeof(uint16_t) * 2); - memset(m_fld_sel, 0, sizeof(uint16_t) * 2); - memset(m_window_enable, 0, sizeof(uint16_t) * 2); - memset(m_cxpos, 0, sizeof(uint16_t) * 2); - memset(m_cypos, 0, sizeof(uint16_t) * 2); + memset(m_rhscr, 0, sizeof(m_rhscr)); + memset(m_rvscr, 0, sizeof(m_rvscr)); + memset(m_rzoom, 0, sizeof(m_rzoom)); + memset(m_fld_sel, 0, sizeof(m_fld_sel)); + memset(m_window_enable, 0, sizeof(m_window_enable)); + memset(m_cxpos, 0, sizeof(m_cxpos)); + memset(m_cypos, 0, sizeof(m_cypos)); m_ca0 = 0; // Combiner Card m_cursor_y = 0; m_cursor_u = 0; m_cursor_v = 0; - m_invert_mask = 0; + m_ext_store_flags = 0; memset(m_select_matte, 0, 2); memset(m_matte_ext, 0, 2); memset(m_matte_y, 0, 2); @@ -1026,15 +1072,25 @@ void dpb7000_state::machine_reset() memset(m_matte_v, 0, 2); // Filter Card - memset(m_filter_acbc, 0, 16); - memset(m_filter_abbb, 0, 16); + memset(m_filter_x_coeffs, 0, sizeof(m_filter_x_coeffs)); + memset(m_filter_y_coeffs, 0, sizeof(m_filter_y_coeffs)); m_incoming_lum = 0; m_incoming_chr = 0; m_buffer_lum = true; // Size Card - m_size_h = 0; - m_size_v = 0; + m_size_dsx_ddx = 0; + m_size_dsy_ddx = 0; + m_size_dsx_ddy = 0; + m_size_dsy_ddy = 0; + m_size_frac_origin_sx_dx = 0; + m_size_frac_origin_sy_dx = 0; + m_size_frac_origin_sx_dy = 0; + m_size_frac_origin_sy_dy = 0; + m_size_dxdx_counter = 0; + m_size_dydy_counter = 0; + m_size_dest_x = 0; + m_size_dest_y = 0; // Keyboard m_keybc_latched_bit = 1; @@ -1043,7 +1099,15 @@ void dpb7000_state::machine_reset() // TDS Box m_tds_dac_value = 0; - m_tds_adc_value = 0; + m_tds_dac_offset = 0; + m_tds_dac_percent = 0.0f; + m_tds_adc_busy = false; + m_tds_adc_value = 0x00; + m_tds_pressure_shift = 0; + m_tds_in_proximity = false; + m_tds_press_state = STATE_IDLE; + m_tds_adc_timer->adjust(attotime::never); + m_tds_press_timer->adjust(attotime::from_hz(120), 0, attotime::from_hz(120)); // Tablet m_tablet_p2_data = 0; @@ -1055,35 +1119,25 @@ void dpb7000_state::machine_reset() m_tablet_tx_timer->adjust(attotime::from_hz(9600), 0, attotime::from_hz(9600)); m_tablet_irq_timer->adjust(attotime::never); m_tablet_tx_bit = 1; - m_tablet_pen_in_proximity = false; + m_tablet_pen_x = 0; + m_tablet_pen_y = 0; + m_tablet_pen_switches = 0; m_tablet_state = 0; -} - -TIMER_CALLBACK_MEMBER(dpb7000_state::diskseq_complete) -{ - req_b_w(1); -} - -TIMER_CALLBACK_MEMBER(dpb7000_state::field_in) -{ - req_a_w(1); -} -TIMER_CALLBACK_MEMBER(dpb7000_state::field_out) -{ - req_a_w(0); + // Tablet HLE + m_tablet_hle_tx_bits.clear(); + m_tablet_hle_timer->adjust(attotime::from_hz(40), 0, attotime::from_hz(40)); } MC6845_UPDATE_ROW(dpb7000_state::crtc_update_row) { const pen_t *const pen = m_palette->pens(); - const uint8_t *const char_rom = m_vdu_char_rom->base(); for (int column = 0; column < x_count; column++) { uint8_t code = (uint8_t)m_vdu_ram[((ma + column) & 0x7ff)]; uint16_t addr = code << 4 | (ra & 0x0f); - uint8_t data = char_rom[addr & 0xfff]; + uint8_t data = m_vdu_char_rom[addr & 0xfff]; if (column == cursor_x) { @@ -1106,184 +1160,6 @@ MC6845_ON_UPDATE_ADDR_CHANGED(dpb7000_state::crtc_addr_changed) { } -// NOTE: This function is not used, but is retained in the event we wish for low-level disk sequencer emulation. -void dpb7000_state::diskseq_y_w(uint16_t data) -{ - uint8_t old_prom_latch[7]; - memcpy(old_prom_latch, m_diskseq_ucode_latch, 7); - - const uint8_t *ucode_prom = m_diskseq_ucode->base(); - for (int i = 0; i < 7; i++) - { - m_diskseq_ucode_latch[i] = ucode_prom[data | (i << 8)]; - } - - if (m_diskseq_halt) - { - m_diskseq->i_w(0); - } - else - { - m_diskseq->i_w(m_diskseq_ucode_latch[1] & 0x0f); - } - m_diskseq->d_w(m_diskseq_ucode_latch[0]); - - if (!BIT(old_prom_latch[2], 1) && BIT(m_diskseq_ucode_latch[2], 1)) // S17: Line Counter Clock - m_diskseq_line_cnt++; - if (BIT(m_diskseq_ucode_latch[2], 2)) // S18: Line Counter Reset - m_diskseq_line_cnt = 0; - - if (!BIT(old_prom_latch[2], 3) && BIT(m_diskseq_ucode_latch[2], 3)) // S19: ED Counter Clock - m_diskseq_ed_cnt++; - if (BIT(m_diskseq_ucode_latch[2], 4)) // S20: ED Counter Reset - m_diskseq_ed_cnt = 0; - - if (!BIT(old_prom_latch[2], 5) && BIT(m_diskseq_ucode_latch[2], 5)) // S21: Auto-Head Clock - m_diskseq_head_cnt++; - if (BIT(m_diskseq_ucode_latch[2], 6)) // S22: Auto-Head Reset - m_diskseq_head_cnt = 0; - - memset(m_diskseq_cc_inputs, 0, 4); - m_diskseq_cc_inputs[0] |= m_diskseq_prom->base()[m_diskseq_line_cnt & 0x1f] & 3; - m_diskseq_cc_inputs[0] |= BIT(m_diskseq_ed_cnt, 2) << 2; - m_diskseq_cc_inputs[0] |= BIT(m_diskseq_head_cnt, 0) << 3; - m_diskseq_cc_inputs[0] |= BIT(~m_diskseq_status_in, DSEQ_STATUS_READY_BIT) << 5; - m_diskseq_cc_inputs[0] |= BIT(m_diskseq_status_in, DSEQ_STATUS_FAULT_BIT) << 6; - m_diskseq_cc_inputs[0] |= BIT(m_diskseq_status_in, DSEQ_STATUS_ONCYL_BIT) << 7; - - m_diskseq_cc_inputs[1] |= BIT(m_diskseq_status_in, DSEQ_STATUS_SKERR_BIT); - m_diskseq_cc_inputs[1] |= BIT(m_diskseq_status_in, DSEQ_STATUS_INDEX_BIT) << 1; - m_diskseq_cc_inputs[1] |= BIT(m_diskseq_status_in, DSEQ_STATUS_SECTOR_BIT) << 2; - m_diskseq_cc_inputs[1] |= BIT(m_diskseq_status_in, DSEQ_STATUS_AMFND_BIT) << 3; - m_diskseq_cc_inputs[1] |= BIT(m_diskseq_status_in, DSEQ_STATUS_WTPROT_BIT) << 4; - m_diskseq_cc_inputs[1] |= BIT(m_diskseq_status_in, DSEQ_STATUS_SELECTED_BIT) << 5; - m_diskseq_cc_inputs[1] |= BIT(m_diskseq_status_in, DSEQ_STATUS_SEEKEND_BIT) << 6; - m_diskseq_cc_inputs[1] |= BIT(m_diskseq_status_in, DSEQ_STATUS_SYNC_DET_BIT) << 7; - - m_diskseq_cc_inputs[2] |= BIT(m_diskseq_status_in, DSEQ_STATUS_RAM_ADDR_OVFLO_BIT); - // C17..C19 tied low - m_diskseq_cc_inputs[2] |= ~(m_diskseq_cmd_word_from_cpu & 0xf) << 4; - - m_diskseq_cc_inputs[3] = ~(m_diskseq_cmd_word_from_cpu >> 4) & 0xff; - - // S15, S16: Select which bank of 8 lines is treated as /CC input to Am2910 - const uint8_t fx_bank_sel = (BIT(m_diskseq_ucode_latch[2], 0) << 1) | BIT(m_diskseq_ucode_latch[1], 7); - - // S12, S13, S14: Select which bit from the bank is treated as /CC input to Am2910 - const uint8_t fx_bit_sel = (BIT(m_diskseq_ucode_latch[1], 6) << 2) | (BIT(m_diskseq_ucode_latch[1], 5) << 1) | BIT(m_diskseq_ucode_latch[1], 4); - - const int cc = BIT(m_diskseq_cc_inputs[fx_bank_sel], fx_bit_sel) ? 1 : 0; - if (!m_diskseq_halt) - { -#if (VERBOSE & (LOG_UCODE | LOG_MORE_UCODE)) - char debug_buf[1024]; - int buf_idx = 0; - - buf_idx += sprintf(debug_buf + buf_idx, "%02x: %02x%02x%02x%02x%02x%02x%02x ", data, - m_diskseq_ucode_latch[6], m_diskseq_ucode_latch[5], m_diskseq_ucode_latch[4], m_diskseq_ucode_latch[3], - m_diskseq_ucode_latch[2], m_diskseq_ucode_latch[1], m_diskseq_ucode_latch[0]); - - switch (m_diskseq_ucode_latch[1] & 0x0f) - { - case 0: buf_idx += sprintf(debug_buf + buf_idx, "JZ ; "); break; - case 1: buf_idx += sprintf(debug_buf + buf_idx, "CJS %02x ; ", m_diskseq_ucode_latch[0]); break; - case 2: buf_idx += sprintf(debug_buf + buf_idx, "JMAP ; "); break; - case 3: buf_idx += sprintf(debug_buf + buf_idx, "CJP %02x ; ", m_diskseq_ucode_latch[0]); break; - case 4: buf_idx += sprintf(debug_buf + buf_idx, "PUSH %02x ; ", m_diskseq_ucode_latch[0]); break; - case 5: buf_idx += sprintf(debug_buf + buf_idx, "JSRP %02x ; ", m_diskseq_ucode_latch[0]); break; - case 6: buf_idx += sprintf(debug_buf + buf_idx, "CJV %02x ; ", m_diskseq_ucode_latch[0]); break; - case 7: buf_idx += sprintf(debug_buf + buf_idx, "JRP %02x ; ", m_diskseq_ucode_latch[0]); break; - case 8: buf_idx += sprintf(debug_buf + buf_idx, "RFCT ; "); break; - case 9: buf_idx += sprintf(debug_buf + buf_idx, "RPCT ; "); break; - case 10: buf_idx += sprintf(debug_buf + buf_idx, "CRTN ; "); break; - case 11: buf_idx += sprintf(debug_buf + buf_idx, "CJPP %02x ; ", m_diskseq_ucode_latch[0]); break; - case 12: buf_idx += sprintf(debug_buf + buf_idx, "LDCT %02x ; ", m_diskseq_ucode_latch[0]); break; - case 13: buf_idx += sprintf(debug_buf + buf_idx, "LOOP ; "); break; - case 14: buf_idx += sprintf(debug_buf + buf_idx, "CONT ; "); break; - case 15: buf_idx += sprintf(debug_buf + buf_idx, "TWB %02x ; ", m_diskseq_ucode_latch[0]); break; - } - -#if LOG_MORE_UCODE - buf_idx += sprintf(debug_buf + buf_idx, "CCSel:%2d, CCx:%02x%02x%02x%02x, CC:%d, ", fx_bank_sel * 8 + fx_bit_sel, m_diskseq_cc_inputs[3], m_diskseq_cc_inputs[2], m_diskseq_cc_inputs[1], m_diskseq_cc_inputs[0], cc); - buf_idx += sprintf(debug_buf + buf_idx, "FCyl:%d, FHD:%d, FCmd:%d, FSel:%d", BIT(m_diskseq_ucode_latch[2], 7), BIT(m_diskseq_ucode_latch[4], 2), BIT(m_diskseq_ucode_latch[4], 4), BIT(m_diskseq_ucode_latch[4], 5)); -#endif - LOGMASKED(LOG_UCODE, "%s\n", debug_buf); -#endif - } - m_diskseq->cc_w(cc); - - // S25: End of sequencer program - if (BIT(m_diskseq_ucode_latch[3], 1)) - { - m_diskseq_halt = true; - req_b_w(1); - } - - // S23: FCYL TAG - // S26, S28..S34: Command word to push onto bus cable - // S35: FHD TAG - // S36: FCMD TAG - // S37: FSEL TAG - // S38: N/C - // S39: N/C from PROM, contains D INDEX status bit - // S40: CK SEL 0 - // S41: CK SEL 1 - // S42: ADDR W. PERMIT - // S43: ZERO RAM - // S44: WRITE RAM - // S45: WORD READ RAM - // S46: WRITE SYNC - // S47: SYNC DET EN - // S48: CPU Status Byte D0 - // S49: CPU Status Byte D1 - // S50: CPU Status Byte D2 - // C5 (D READY): CPU Status Byte D3 - // C12 (D WTPROT): CPU Status Byte D4 - // ED Bit 0: CPU Status Byte D5 - // ED Bit 1: CPU Status Byte D6 - // C6 (D FAULT): CPU Status Byte D7 - - if (BIT(m_diskseq_ucode_latch[3], 3)) // S27: Push command word from S26, S28..S34 onto bus cable - { - uint8_t disk_cmd = BIT(m_diskseq_ucode_latch[4], 2); - disk_cmd |= BIT(m_diskseq_ucode_latch[4], 1) << 1; - disk_cmd |= BIT(m_diskseq_ucode_latch[4], 0) << 4; - disk_cmd |= BIT(m_diskseq_ucode_latch[3], 7) << 5; - disk_cmd |= BIT(m_diskseq_ucode_latch[3], 6) << 6; - disk_cmd |= BIT(m_diskseq_ucode_latch[3], 5) << 7; - disk_cmd |= BIT(m_diskseq_ucode_latch[3], 4) << 8; - m_diskseq_cmd_to_ctrl = disk_cmd; - m_fdd_ctrl |= 0x10; - } - - if (BIT(m_diskseq_ucode_latch[3], 0)) // S24: Push cylinder number onto the bus cable - { - m_diskseq_cyl_to_ctrl = m_diskseq_cyl_from_cpu; - m_fdd_ctrl |= 0x40; - } - - if (BIT(m_diskseq_ucode_latch[6], 4)) - { - m_diskseq_status_out = m_diskseq_ucode_latch[6] & 7; - m_diskseq_status_out |= BIT(m_diskseq_status_in, DSEQ_STATUS_READY_BIT) << 3; - m_diskseq_status_out |= BIT(m_diskseq_status_in, DSEQ_STATUS_WTPROT_BIT) << 4; - m_diskseq_status_out |= (m_diskseq_ed_cnt & 3) << 5; - m_diskseq_status_out |= 0x80;//BIT(m_diskseq_status_in, DSEQ_STATUS_FAULT_BIT) << 7; - } -} - -// NOTE: This function is not used, but is retained in the event we wish for low-level disk sequencer emulation. -void dpb7000_state::diskseq_tick() -{ - m_diskseq_cp = (m_diskseq_cp ? 0 : 1); - m_diskseq->cp_w(m_diskseq_cp); - - if (m_diskseq_cp && m_diskseq_reset) - { - m_diskseq_reset = false; - } -} - uint16_t dpb7000_state::bus_error_r(offs_t offset) { if(!machine().side_effects_disabled()) @@ -1307,7 +1183,7 @@ void dpb7000_state::bus_error_w(offs_t offset, uint16_t data) void dpb7000_state::csr_w(uint8_t data) { - LOGMASKED(LOG_CSR, "%s: Card Select write: %02x\n", machine().describe_context(), data & 0x0f); + LOGMASKED(LOG_CSR, "%s: Card Select write: %02x (%04x)\n", machine().describe_context(), data & 0x0f, data); m_csr = data & 0x0f; } @@ -1323,29 +1199,89 @@ uint16_t dpb7000_state::cpu_ctrlbus_r() switch (m_csr) { case 0: - LOGMASKED(LOG_CTRLBUS, "%s: CPU read from Control Bus, Brush Address Card status: %04x\n", machine().describe_context(), m_brush_addr_func); + if (!machine().side_effects_disabled()) + LOGMASKED(LOG_CTRLBUS, "%s: CPU read from Control Bus, Brush Address Card status: %04x\n", machine().describe_context(), m_brush_addr_func); ret = m_brush_addr_func; break; case 1: - LOGMASKED(LOG_CTRLBUS, "%s: CPU read from Control Bus, Disk Sequencer Card status: %02x\n", machine().describe_context(), m_diskseq_status_out); - ret = m_diskseq_status_out; - //req_b_w(0); + if (!machine().side_effects_disabled()) + { + LOGMASKED(LOG_CTRLBUS, "%s: CPU read from Control Bus, Disk Sequencer Card status: %02x\n", machine().describe_context(), m_diskseq_status); + } + ret = m_diskseq_status; break; case 7: ret = m_diskbuf_ram[m_diskbuf_ram_addr]; - LOGMASKED(LOG_CTRLBUS, "%s: CPU read from Control Bus, Disc Data Buffer Card RAM read: %04x = %02x\n", machine().describe_context(), m_diskbuf_ram_addr, ret); + LOGMASKED(LOG_DDB, "%s: CPU read from Control Bus, Disc Data Buffer Card RAM read: %04x = %02x\n", machine().describe_context(), m_diskbuf_ram_addr, ret); m_diskbuf_ram_addr++; break; + case 8: + { + if (m_brush_addr_cmd == 3) // Framestore Read + { + const uint16_t x = m_cxpos[1] + (m_bxlen_counter - m_bxlen); + const uint16_t y = m_cypos[1] + (m_bylen_counter - m_bylen); + + uint32_t pix_idx = y * 800 + x; + uint8_t &chr = m_ca0 ? m_bs_v_latch : m_bs_u_latch; + if (!BIT(m_brush_addr_func, 5)) + { + if (BIT(m_brush_addr_func, 7)) + m_bs_y_latch = m_framestore_lum[0][pix_idx]; + if (BIT(m_brush_addr_func, 8)) + chr = m_framestore_chr[0][pix_idx]; + if (BIT(m_brush_addr_func, 9)) + m_bs_y_latch = m_framestore_ext[0][pix_idx]; + } + if (!BIT(m_brush_addr_func, 6)) + { + if (BIT(m_brush_addr_func, 7)) + m_bs_y_latch = m_framestore_lum[1][pix_idx]; + if (BIT(m_brush_addr_func, 8)) + chr = m_framestore_chr[1][pix_idx]; + if (BIT(m_brush_addr_func, 9)) + m_bs_y_latch = m_framestore_ext[1][pix_idx]; + } + + m_bxlen_counter++; + if (m_bxlen_counter == 0x1000) + { + m_bxlen_counter = m_bxlen; + m_bylen_counter++; + if (m_bylen_counter == 0x1000) + { + cmd_done(0); + } + } + } + + uint16_t data = (uint16_t)m_bs_y_latch; + if (m_ca0) + { + data |= (uint16_t)m_bs_v_latch << 8; + LOGMASKED(LOG_CTRLBUS | LOG_BRUSH_ADDR | LOG_BRUSH_LATCH, "%s: Brush Store Card color latches read (VY): %04x\n\n", machine().describe_context(), data); + } + else + { + data |= (uint16_t)m_bs_u_latch << 8; + LOGMASKED(LOG_CTRLBUS | LOG_BRUSH_ADDR | LOG_BRUSH_LATCH, "%s: Brush Store Card color latches read (UY): %04x\n", machine().describe_context(), data); + } + m_ca0 = 1 - m_ca0; + return data; + } case 12: ret = m_config_sw34->read(); - LOGMASKED(LOG_CTRLBUS, "%s: CPU read from Control Bus, Config Switches 1/2: %04x\n", machine().describe_context(), ret); + if (!machine().side_effects_disabled()) + LOGMASKED(LOG_CTRLBUS, "%s: CPU read from Control Bus, Config Switches 3/4: %04x\n", machine().describe_context(), ret); break; case 14: ret = m_config_sw12->read(); - LOGMASKED(LOG_CTRLBUS, "%s: CPU read from Control Bus, Config Switches 3/4: %04x\n", machine().describe_context(), ret); + if (!machine().side_effects_disabled()) + LOGMASKED(LOG_CTRLBUS, "%s: CPU read from Control Bus, Config Switches 1/2: %04x\n", machine().describe_context(), ret); break; default: - LOGMASKED(LOG_CTRLBUS | LOG_UNKNOWN, "%s: CPU read from Control Bus, unknown CSR %d\n", machine().describe_context(), m_csr); + if (!machine().side_effects_disabled()) + LOGMASKED(LOG_CTRLBUS | LOG_UNKNOWN, "%s: CPU read from Control Bus, unknown CSR %d\n", machine().describe_context(), m_csr); break; } return ret; @@ -1358,10 +1294,20 @@ void dpb7000_state::store_address_w(uint8_t card, uint16_t data) case 0: LOGMASKED(LOG_STORE_ADDR, "%s: Store Address Card %d, set RHSCR: %03x\n", machine().describe_context(), card + 1, data & 0xfff); m_rhscr[card] = data & 0xfff; + if (!card) + { + LOGMASKED(LOG_STORE_ADDR, "%s: Setting Store Address Card 2 RHSCR also: %03x\n", machine().describe_context(), data & 0xfff); + m_rhscr[1] = data & 0xfff; + } break; case 1: LOGMASKED(LOG_STORE_ADDR, "%s: Store Address Card %d, set RVSCR: %03x\n", machine().describe_context(), card + 1, data & 0xfff); m_rvscr[card] = data & 0xfff; + if (!card) + { + LOGMASKED(LOG_STORE_ADDR, "%s: Setting Store Address Card 2 RVSCR also: %03x\n", machine().describe_context(), data & 0xfff); + m_rvscr[1] = data & 0xfff; + } break; case 2: LOGMASKED(LOG_STORE_ADDR, "%s: Store Address Card %d, set R ZOOM: %03x\n", machine().describe_context(), card + 1, data & 0xfff); @@ -1374,11 +1320,14 @@ void dpb7000_state::store_address_w(uint8_t card, uint16_t data) break; case 4: LOGMASKED(LOG_STORE_ADDR, "%s: Store Address Card %d, set CXPOS: %03x\n", machine().describe_context(), card + 1, data & 0xfff); - m_cxpos[card] = data & 0xfff; + m_cxpos[0] = data & 0xfff; + m_cxpos[1] = data & 0xfff; + //m_ca0 = data & 1; break; case 5: LOGMASKED(LOG_STORE_ADDR, "%s: Store Address Card %d, set CYPOS: %03x\n", machine().describe_context(), card + 1, data & 0xfff); - m_cypos[card] = data & 0xfff; + m_cypos[0] = data & 0xfff; + m_cypos[1] = data & 0xfff; break; default: LOGMASKED(LOG_STORE_ADDR, "%s: Store Address Card %d, unknown register: %04x\n", machine().describe_context(), card + 1, data); @@ -1388,158 +1337,499 @@ void dpb7000_state::store_address_w(uint8_t card, uint16_t data) void dpb7000_state::combiner_reg_w(uint16_t data) { - static const char* const s_const_names[16] = { "Y0", "CY", "CU", "CV", "ES", "EI", "EII", "Y7", "IS", "IY", "IU", "IV", "IIS", "IIY", "IIU", "IIV" }; - LOGMASKED(LOG_COMBINER, "%s: Combiner Card register write: %s = %02x\n", machine().describe_context(), s_const_names[(data >> 10) & 0xf], (uint8_t)data); - switch ((data >> 10) & 0xf) + const uint8_t reg_idx = (data >> 10) & 0xf; + switch (reg_idx) { + case 0: // Output Timing CS Flags + LOGMASKED(LOG_OUTPUT_TIMING, "%s: Output Timing Card CS Register write: %02x\n", machine().describe_context(), (uint8_t)data); + m_output_csflags = (uint8_t)(data & 0x0003); + break; case 1: // CY + LOGMASKED(LOG_COMBINER, "%s: Combiner Card Constant Y write: %02x\n", machine().describe_context(), (uint8_t)data); m_cursor_y = (uint8_t)data; break; - case 2: // CU - m_cursor_u = (uint8_t)data; - break; - case 3: // CV + case 2: // CV + LOGMASKED(LOG_COMBINER, "%s: Combiner Card Constant V write: %02x\n", machine().describe_context(), (uint8_t)data); m_cursor_v = (uint8_t)data; break; + case 3: // CU + LOGMASKED(LOG_COMBINER, "%s: Combiner Card Constant U write: %02x\n", machine().describe_context(), (uint8_t)data); + m_cursor_u = (uint8_t)data; + break; case 4: // ES - m_invert_mask = (uint8_t)data; + LOGMASKED(LOG_COMBINER, "%s: Combiner Card Ext. Store Flags (ES) write: %02x\n", machine().describe_context(), (uint8_t)data); + m_ext_store_flags = (uint8_t)data; break; case 5: // EI + LOGMASKED(LOG_COMBINER, "%s: Combiner Card Ext I Matte (EI) write: %02x\n", machine().describe_context(), (uint8_t)data); m_matte_ext[0] = (uint8_t)data; break; case 6: // EII + LOGMASKED(LOG_COMBINER, "%s: Combiner Card Ext II Matte (EII) write: %02x\n", machine().describe_context(), (uint8_t)data); m_matte_ext[1] = (uint8_t)data; break; + case 7: // Output Timing CP Flags + LOGMASKED(LOG_OUTPUT_TIMING, "%s: Output Timing Card CP Register write: %02x\n", machine().describe_context(), (uint8_t)data); + m_output_cpflags = (uint8_t)(data & 0x001f); + break; case 8: // IS + LOGMASKED(LOG_COMBINER, "%s: Combiner Card Matte I Select (IS) write: %02x\n", machine().describe_context(), (uint8_t)data); m_select_matte[0] = BIT(data, 0); break; case 9: // IY + LOGMASKED(LOG_COMBINER, "%s: Combiner Card Matte I Y (IY) write: %02x\n", machine().describe_context(), (uint8_t)data); m_matte_y[0] = (uint8_t)data; break; case 10: // IU + LOGMASKED(LOG_COMBINER, "%s: Combiner Card Matte I U (IU) write: %02x\n", machine().describe_context(), (uint8_t)data); m_matte_u[0] = (uint8_t)data; break; case 11: // IV + LOGMASKED(LOG_COMBINER, "%s: Combiner Card Matte I V (IV) write: %02x\n", machine().describe_context(), (uint8_t)data); m_matte_v[0] = (uint8_t)data; break; case 12: // IIS + LOGMASKED(LOG_COMBINER, "%s: Combiner Card Matte II Select (IIS) write: %02x\n", machine().describe_context(), (uint8_t)data); m_select_matte[1] = BIT(data, 0); break; case 13: // IIY + LOGMASKED(LOG_COMBINER, "%s: Combiner Card Matte II Y (IIY) write: %02x\n", machine().describe_context(), (uint8_t)data); m_matte_y[1] = (uint8_t)data; break; case 14: // IIU + LOGMASKED(LOG_COMBINER, "%s: Combiner Card Matte II U (IIU) write: %02x\n", machine().describe_context(), (uint8_t)data); m_matte_u[1] = (uint8_t)data; break; case 15: // IIV + LOGMASKED(LOG_COMBINER, "%s: Combiner Card Matte II V (IIV) write: %02x\n", machine().describe_context(), (uint8_t)data); m_matte_v[1] = (uint8_t)data; break; } } -void dpb7000_state::handle_command(uint16_t data) +bool dpb7000_state::handle_command(uint16_t data) { - //printf("handle_command %d, cxpos %d, cypos %d\n", (data >> 1) & 0xf, m_cxpos[1], m_cypos[1]); - switch ((data >> 1) & 0xf) + //printf("handle_command %d, cxpos %d, cypos %d\n", m_brush_addr_cmd, m_cxpos[1], m_cypos[1]); + switch (m_brush_addr_cmd) { case 0: // Live Video + LOGMASKED(LOG_COMMANDS, "Unsupported command: Live Video\n"); break; case 1: // Brush Store Read + LOGMASKED(LOG_COMMANDS, "Unsupported command: Brush Store Read\n"); break; case 2: // Brush Store Write - m_bxlen_counter = m_bxlen; - m_bylen_counter = m_bylen; - break; case 3: // Framestore Read - break; case 4: // Framestore Write - break; + m_bxlen_counter = m_bxlen; + m_bylen_counter = m_bylen; + return false; case 5: // Fast Wipe Video + LOGMASKED(LOG_COMMANDS, "Unsupported command: Fast Wipe Video\n"); break; case 6: // Fast Wipe Brush Store + LOGMASKED(LOG_COMMANDS, "Unsupported command: Fast Wipe Brush Store\n"); break; - case 7: // Fast Wipe Framestore + /*case 7: // Fast Wipe Framestore for (int i = 0; i < 2; i++) { - if (!BIT(data, 5 + i) && m_cxpos[i] < 800 && m_cypos[i] < 768) + if (!BIT(data, 5 + i)) { m_bylen_counter = m_bylen; - for (uint16_t y = m_cypos[i]; m_bylen_counter != 0x1000 && y < 768; m_bylen_counter++, y++) + for (uint16_t y = m_cypos[1]; m_bylen_counter != 0x1000; m_bylen_counter++, y = (y + 1) & 0xfff) { + if (y >= 768) + continue; + uint8_t *lum = &m_framestore_lum[i][y * 800]; uint8_t *chr = &m_framestore_chr[i][y * 800]; + uint8_t *ext = &m_framestore_ext[i][y * 800]; m_bxlen_counter = m_bxlen; - for (uint16_t x = m_cxpos[i]; m_bxlen_counter != 0x1000 && x < 800; m_bxlen_counter++, x++) + for (uint16_t x = m_cxpos[1]; m_bxlen_counter != 0x1000; m_bxlen_counter++, x = (x + 1) & 0xfff) { + if (x >= 800) + continue; + lum[x] = m_bs_y_latch; chr[x] = (x & 1) ? m_bs_v_latch : m_bs_u_latch; + if (BIT(data, 9)) + ext[x] = m_bs_y_latch; } } } } - break; + break;*/ + case 7: // Fast Wipe Framestore case 8: // Draw - for (int i = 0; i < 2; i++) + { + const bool use_brush = (m_brush_addr_cmd == 8); + const bool lum_en = BIT(data, 7); + const bool chr_en = BIT(data, 8); + const bool ext_en = BIT(data, 9); + bool const write_en[2] = { lum_en, chr_en }; + + const bool s1_disable = BIT(data, 5); + const bool s2_disable = BIT(data, 6); + + const uint16_t sel_1 = (uint16_t)s1_disable << 5; + const uint16_t sel_2 = (uint16_t)s2_disable << 4; + const uint16_t sel_ext = ext_en << 6; + const uint16_t fcs = BIT(data, 13); + + const uint16_t prom_addr = (fcs << 8) | (use_brush ? 0x80 : 0x00) | sel_ext | sel_1 | sel_2 | bitswap<4>(data, 1, 2, 3, 4); + const uint8_t prom_data = m_brushproc_prom[prom_addr]; + + const bool brush_zero = BIT(data, 12); + const bool oe1 = BIT(prom_data, 0); + const bool oe2 = BIT(prom_data, 1); + const bool oe3 = BIT(prom_data, 2); + const bool oe4 = BIT(prom_data, 7); + + const bool use_s1_data = (oe3 == oe4); + const bool use_s2_data = !oe4; + const bool use_ext_data = !oe3; + const bool mask_sel = BIT(prom_data, 3); + const bool word_width = BIT(prom_data, 4); + const bool use_k_data = BIT(~prom_data, 6); + const bool brush_invert = BIT(~data, 11); + const uint16_t pal_addr_extra = (BIT(prom_data, 5) << 8) | (brush_invert << 9); + + const uint16_t brushaddr_pal_addr = (uint16_t)bitswap<4>(data, 1, 2, 3, 4) | (1 << 4) | (1 << 5) | (0 << 7) | (BIT(data, 5) << 8) | (1 << 9) | (1 << 10); + const uint8_t brushaddr_pal_val = m_brushaddr_pal[brushaddr_pal_addr]; + + int ext_idx = BIT(brushaddr_pal_val, 1) ? 1 : 0; + + uint8_t *store_1[2] = { &m_framestore_lum[0][0], &m_framestore_chr[0][0] }; + uint8_t *store_2[2] = { &m_framestore_lum[1][0], &m_framestore_chr[1][0] }; + uint8_t pressure[2] = { m_brush_press_lum, m_brush_press_chr }; + + uint16_t bxlen = m_bxlen;//(((m_bxlen << 3) | (m_bixos & 7)) >> (m_bif & 3)) & 0xfff; + uint16_t bylen = m_bylen;//(((m_bylen << 3) | (m_biyos & 7)) >> ((m_bif >> 2) & 3)) & 0xfff; + //uint16_t width = 0x1000 - bxlen; + //if (m_brush_addr_cmd == 8) + m_ca0 = 0; + //printf("\n%sing %dx%d brush at %d,%d (data %04x) (Store %d)\n", m_brush_addr_cmd == 8 ? "Draw" : "Wip", 0x1000 - m_bxlen, 0x1000 - m_bylen, m_cxpos[1], m_cypos[1], data, !s1_disable ? 1 : (!s2_disable ? 2 : 0)); + LOGMASKED(LOG_BRUSH_DRAWS, "%sing %dx%d brush at %d,%d (Store %d)\n", m_brush_addr_cmd == 8 ? "Draw" : "Wip", 0x1000 - m_bxlen, 0x1000 - m_bylen, m_cxpos[1], m_cypos[1], !s1_disable ? 1 : (!s2_disable ? 2 : 0)); + if ((m_cxpos[1] == 0x16 && m_cypos[1] == 0xda) || (m_cxpos[1] == 0x216 && m_cypos[1] == 0x58) || data == 0x39d1) { - if (!BIT(data, 5 + i) && m_cxpos[i] < 800 && m_cypos[i] < 768) + LOGMASKED(LOG_BRUSH_DRAWS, " BAddrPALAddr:%03x BAddrPALVal:%02x ExtIdx:%d\n", brushaddr_pal_addr, brushaddr_pal_val, ext_idx); + LOGMASKED(LOG_BRUSH_DRAWS, " /S1:%d /S2:%d LUM:%d CHR:%d EXT:%d BZ:%d /BI:%d FCS:%d\n", s1_disable, s2_disable, lum_en, chr_en, BIT(data, 9), brush_zero, brush_invert, fcs); + LOGMASKED(LOG_BRUSH_DRAWS, " PROMAddr:%03x PROMVal:%02x OE1:%d OE2:%d OE3:%d OE4:%d MSEL:%d 16BIT:%d\n", prom_addr, prom_data, oe1, oe2, oe3, oe4, mask_sel, word_width); + } + + for (uint16_t y = m_cypos[1], bly = bylen; bly != 0x1000; bly++, y = (y + 1) & 0xfff) + { + if (y >= 768) + continue; + + uint32_t line_idx = y * 800; + for (uint16_t x = m_cxpos[1], blx = bxlen; blx != 0x1000; blx++, x = (x + 1) & 0xfff) { - uint16_t bxlen = m_bxlen;//(((m_bxlen << 3) | (m_bixos & 7)) >> (m_bif & 3)) & 0xfff; - uint16_t bylen = m_bylen;//(((m_bylen << 3) | (m_biyos & 7)) >> ((m_bif >> 2) & 3)) & 0xfff; - for (uint16_t y = m_cypos[i], bly = bylen; bly != 0x1000 && y < 768; bly++, y++) + if (x >= 800) + continue; + + if (m_output_cpflags & 0x0c) { - uint8_t *lum = &m_framestore_lum[i][y * 800]; - uint8_t *chr = &m_framestore_chr[i][y * 800]; - for (uint16_t x = m_cxpos[i], blx = bxlen; blx != 0x1000 && x < 800; blx++, x++) + const uint16_t x_nib_addr = (x >> 1) & 0x3ff; + uint16_t x_xlnib = m_storeaddr_xlnib[x_nib_addr] & 0xe; + uint16_t x_xmnib = (m_storeaddr_xmnib[x_nib_addr] & 0x0f) << 4; + uint16_t x_xhnib = (m_storeaddr_xhnib[x_nib_addr] & 0x0f) << 8; + uint16_t remapped_x = x_xhnib | x_xmnib | x_xlnib | (x & 1); + + uint16_t prot_addr = (BIT(~m_output_cpflags, 2) << 8) | (BIT(~m_output_cpflags, 3) << 9); + uint16_t prot_x_addr = (remapped_x >> 4) & 0xff; + uint16_t prot_y_addr = ((y - 8) >> 2) & 0xff; + const bool prot_x = m_storeaddr_protx[prot_addr | prot_x_addr] & 1; + const bool prot_y = m_storeaddr_proty[prot_addr | prot_y_addr] & 1; + + if (prot_x || prot_y) + { + LOGMASKED(LOG_CSR, "Prot Reject: %03x, %03x (%d, %d)\n", prot_addr | prot_x_addr, prot_addr | prot_y_addr, prot_x, prot_y); + continue; + } + } + + uint32_t pix_idx = line_idx + x; + + uint8_t uv_bsel = x & 1; + + uint8_t fixed_chr = (uv_bsel ? m_bs_v_latch : m_bs_u_latch); + uint8_t brush_values[2] = { m_bs_y_latch, fixed_chr }; + uint8_t brush_ext = 0xff; + + if ((m_cxpos[1] == 0x16 && m_cypos[1] == 0xda) || (m_cxpos[1] == 0x216 && m_cypos[1] == 0x58) || data == 0x39d1) + { + LOGMASKED(LOG_BRUSH_DRAWS, " Out x,y: %d,%d\n", x, y); + } + if (use_brush) + { + uint16_t bx = ((((blx - bxlen) << 3) | (m_bixos & 7)) >> (3 - (m_bif & 3))) & 0xfff; + uint16_t by = ((((bly - bylen) << 3) | (m_biyos & 7)) >> ((3 - (m_bif >> 2)) & 3)) & 0xfff; + uint16_t uv_bx = ((x & 1) ? (bx | 1) : (bx & ~1)); + uint8_t brush_lum = m_brushstore_lum[by * 256 + bx]; + uint8_t brush_chr = m_brushstore_chr[by * 256 + uv_bx]; + brush_ext = ext_en ? m_brushstore_ext[by * 256 + bx] : brush_lum; + brush_values[0] = (fcs || !lum_en) ? m_bs_y_latch : brush_lum; + brush_values[1] = (fcs || !chr_en) ? fixed_chr : brush_chr; + + if ((m_cxpos[1] == 0x16 && m_cypos[1] == 0xda) || (m_cxpos[1] == 0x216 && m_cypos[1] == 0x58) || data == 0x39d1) + { + LOGMASKED(LOG_BRUSH_DRAWS, " Brush pixel %d,%d (bl %03x,%03x) (blen %03x,%03x) (store %d,%d), Brush LCE %02x %02x %02x:\n", 0x1000 - blx, 0x1000 - bly, blx, bly, bxlen, bylen, bx, by, brush_values[0], brush_values[1], brush_ext); + } + } + else if (s1_disable && !s2_disable && x == 22 && y == 8) + { + LOGMASKED(LOG_BRUSH_DRAWS, " Fixed brush value LCE %02x %02x %02x (YUV %02x %02x %02x)\n\n", brush_values[0], brush_values[1], brush_ext, m_bs_y_latch, m_bs_u_latch, m_bs_v_latch); + } + + for (int ch = 0; ch < 2; ch++) + { + uint8_t s1_data = store_1[ch][pix_idx]; + uint8_t s2_data = store_2[ch][pix_idx]; + //uint8_t sext_data = m_framestore_ext[!s2_disable ? 1 : 0][pix_idx]; + uint8_t sext_data = m_framestore_ext[ext_idx][pix_idx]; + + uint8_t brush_data = brush_values[ch]; + uint8_t brush_ext_data = use_k_data ? brush_ext : 0xff; + uint8_t other_data = 0x00; + uint8_t pressure_data = pressure[ch]; + uint8_t press_product = (uint8_t)((brush_ext_data * pressure_data + 0x0080) >> 8); + if ((m_cxpos[1] == 0x16 && m_cypos[1] == 0xda) || (m_cxpos[1] == 0x216 && m_cypos[1] == 0x58) || data == 0x39d1) + { + LOGMASKED(LOG_BRUSH_DRAWS, " brush ext (%02x) * pressure (%02x) = %02x\n", brush_ext_data, pressure_data, press_product); + } + + uint8_t mask_multiplicand = 0x00; + if (brush_zero) + mask_multiplicand = (mask_sel ? sext_data : 0xff); + + uint8_t press_result = (uint8_t)((press_product * mask_multiplicand + 0x0080) >> 8); + if ((m_cxpos[1] == 0x16 && m_cypos[1] == 0xda) || (m_cxpos[1] == 0x216 && m_cypos[1] == 0x58) || data == 0x39d1) + { + LOGMASKED(LOG_BRUSH_DRAWS, " press product (%02x) * mask multiplicand (%02x) = %02x\n\n", press_product, mask_multiplicand, press_result); + } + uint16_t pal_addr = (uint8_t)bitswap<8>(press_result, 0, 1, 2, 3, 4, 5, 6, 7) | pal_addr_extra; + uint16_t pal_data = m_brushproc_pal[pal_addr]; + uint8_t pal_value = (uint8_t)pal_data; + bool pal_sel = BIT(pal_data, 8); + bool pal_invert = BIT(pal_data, 9); + + if ((m_cxpos[1] == 0x16 && m_cypos[1] == 0xda) || (m_cxpos[1] == 0x216 && m_cypos[1] == 0x58) || data == 0x39d1) + { + LOGMASKED(LOG_BRUSH_DRAWS, " Brush %s data: %02x\n", ch ? "chr" : "lum", brush_data); + LOGMASKED(LOG_BRUSH_DRAWS, " Bext:%02x, PressDat:%02x, PressProd:%02x, MaskMult:%02x, PressRes:%02x, PALAddr:%03x, PALData:%03x, PALVal:%02x\n", brush_ext_data, pressure_data, press_product, mask_multiplicand, press_result, pal_addr, pal_data, pal_value); + LOGMASKED(LOG_BRUSH_DRAWS, " S1:%02x S2:%02x SE:%02x\n", s1_data, s2_data, sext_data); + } + + if (use_s1_data) + { + other_data = s1_data; + if ((m_cxpos[1] == 0x16 && m_cypos[1] == 0xda) || (m_cxpos[1] == 0x216 && m_cypos[1] == 0x58) || data == 0x39d1) LOGMASKED(LOG_BRUSH_DRAWS, " Using Store I for other data, %02x\n", other_data); + } + else if (use_s2_data) + { + other_data = s2_data; + if ((m_cxpos[1] == 0x16 && m_cypos[1] == 0xda) || (m_cxpos[1] == 0x216 && m_cypos[1] == 0x58) || data == 0x39d1) LOGMASKED(LOG_BRUSH_DRAWS, " Using Store II for other data, %02x\n", other_data); + } + else if (use_ext_data) + { + other_data = sext_data; + if ((m_cxpos[1] == 0x16 && m_cypos[1] == 0xda) || (m_cxpos[1] == 0x216 && m_cypos[1] == 0x58) || data == 0x39d1) LOGMASKED(LOG_BRUSH_DRAWS, " Using Stencil for other data, %02x\n", other_data); + } + + if (!oe1) + { + brush_data = s1_data; + if ((m_cxpos[1] == 0x16 && m_cypos[1] == 0xda) || (m_cxpos[1] == 0x216 && m_cypos[1] == 0x58) || data == 0x39d1) LOGMASKED(LOG_BRUSH_DRAWS, " Using Store I for brush data, %02x\n", other_data); + } + else if (!oe2) + { + brush_data = s2_data; + if ((m_cxpos[1] == 0x16 && m_cypos[1] == 0xda) || (m_cxpos[1] == 0x216 && m_cypos[1] == 0x58) || data == 0x39d1) LOGMASKED(LOG_BRUSH_DRAWS, " Using Store II for brush data, %02x\n", other_data); + } + + if ((m_cxpos[1] == 0x16 && m_cypos[1] == 0xda) || (m_cxpos[1] == 0x216 && m_cypos[1] == 0x58) || data == 0x39d1) + { + LOGMASKED(LOG_BRUSH_DRAWS, " Before-comp brush data %02x, other data %02x\n", brush_data, other_data); + } + + uint8_t comp_a = brush_data; + uint8_t comp_b = other_data; + + uint8_t alu_out = 0x00; + bool final_add = false; + if (comp_a < comp_b) + { + if ((m_cxpos[1] == 0x16 && m_cypos[1] == 0xda) || (m_cxpos[1] == 0x216 && m_cypos[1] == 0x58) || data == 0x39d1) + { + LOGMASKED(LOG_BRUSH_DRAWS, " comp_a %02x < comp_b %02x, final ALU pass should subtract\n", comp_a, comp_b); + } + alu_out = other_data - brush_data; + } + else + { + if ((m_cxpos[1] == 0x16 && m_cypos[1] == 0xda) || (m_cxpos[1] == 0x216 && m_cypos[1] == 0x58) || data == 0x39d1) + { + LOGMASKED(LOG_BRUSH_DRAWS, " comp_a %02x > comp_b %02x, final ALU pass should add, calculating %02x - %02x = %02x\n", comp_a, comp_b, comp_a, comp_b, comp_a - comp_b); + } + alu_out = brush_data - other_data; + final_add = true; + } + + if (pal_invert) + brush_data = ~brush_data; + + uint16_t out_product = (uint16_t)alu_out * (uint16_t)pal_value; + if ((m_cxpos[1] == 0x16 && m_cypos[1] == 0xda) || (m_cxpos[1] == 0x216 && m_cypos[1] == 0x58) || data == 0x39d1) + { + LOGMASKED(LOG_BRUSH_DRAWS, " ALU out %02x, out product %04x (%02x * %02x), PALSel:%d, PALInv:%d\n", alu_out, out_product, alu_out, pal_value, pal_sel, pal_invert); + } + uint8_t final_msb = 0; + uint8_t final_lsb = 0; + if (!word_width) + { + uint16_t alu_a = (other_data << 8) | s2_data; + uint16_t alu_b = out_product; + uint16_t final_alu_out = (final_add ? (alu_a + alu_b) : (alu_a - alu_b)); + + final_msb = (pal_sel ? (final_alu_out >> 8) : brush_data); + final_lsb = final_msb; + + if ((m_cxpos[1] == 0x16 && m_cypos[1] == 0xda) || (m_cxpos[1] == 0x216 && m_cypos[1] == 0x58) || data == 0x39d1) + { + if (final_add) + { + LOGMASKED(LOG_BRUSH_DRAWS, " 8bpp, S1D %02x, S2D %02x, ALUA %04x, ALUB %04x, ALU final %04x + %04x = %04x, MSB %02x\n", s1_data, s2_data, alu_a, alu_b, alu_a, alu_b, final_alu_out, final_msb); + } + else + { + LOGMASKED(LOG_BRUSH_DRAWS, " 8bpp, S1D %02x, S2D %02x, ALUA %04x, ALUB %04x, ALU final %04x - %04x = %04x, MSB %02x\n", s1_data, s2_data, alu_a, alu_b, alu_a, alu_b, final_alu_out, final_msb); + } + } + } + else + { + uint16_t alu_a = (other_data << 8) | s2_data; + uint16_t alu_b = out_product; + uint16_t final_alu_out = (final_add ? (alu_a + alu_b) : (alu_a - alu_b)); + final_msb = (pal_sel ? (final_alu_out >> 8) : brush_data); + final_lsb = (uint8_t)final_alu_out; + + if ((m_cxpos[1] == 0x16 && m_cypos[1] == 0xda) || (m_cxpos[1] == 0x216 && m_cypos[1] == 0x58) || data == 0x39d1) + { + if (final_add) + { + LOGMASKED(LOG_BRUSH_DRAWS, " 16bpp, ALUA %04x, ALUB %04x, %04x+%04x=%04x, MSB %02x, LSB %02x\n", alu_a, alu_b, alu_a, alu_b, final_alu_out, final_msb, final_lsb); + } + else + { + LOGMASKED(LOG_BRUSH_DRAWS, " 16bpp, ALUA %04x, ALUB %04x, %04x-%04x=%04x, MSB %02x, LSB %02x\n", alu_a, alu_b, alu_a, alu_b, final_alu_out, final_msb, final_lsb); + } + } + } + + if (write_en[ch]) + { + if (!s1_disable) + { + if ((m_cxpos[1] == 0x16 && m_cypos[1] == 0xda) || (m_cxpos[1] == 0x216 && m_cypos[1] == 0x58) || data == 0x39d1) + { + LOGMASKED(LOG_BRUSH_DRAWS, " Storing %02x in Store 1 %s\n", final_msb, ch ? "chr" : "lum"); + } + store_1[ch][pix_idx] = s2_disable ? final_lsb : final_msb; + } + if (!s2_disable) + { + store_2[ch][pix_idx] = final_lsb; + if ((m_cxpos[1] == 0x16 && m_cypos[1] == 0xda) || (m_cxpos[1] == 0x216 && m_cypos[1] == 0x58) || data == 0x39d1) + { + LOGMASKED(LOG_BRUSH_DRAWS, " Storing %02x in Store 2 %s\n", final_lsb, ch ? "chr" : "lum"); + } + } + } + + if (ch == 0 && ext_en) { - if (BIT(data, 13)) // Fixed Colour Select + if (!s1_disable) { - uint8_t y = m_bs_y_latch; - uint8_t u = m_bs_u_latch; - uint8_t v = m_bs_v_latch; - if (!BIT(data, 12)) // Brush Zero + if ((m_cxpos[1] == 0x16 && m_cypos[1] == 0xda) || (m_cxpos[1] == 0x216 && m_cypos[1] == 0x58) || data == 0x39d1) { - y = 0x00; - u = 0x80; - v = 0x80; + LOGMASKED(LOG_BRUSH_DRAWS, " Storing %02x in EXT 1\n", final_msb); } - else if (!BIT(data, 9)) + m_framestore_ext[0][pix_idx] = final_msb; + } + if (!s2_disable) + { + if ((m_cxpos[1] == 0x16 && m_cypos[1] == 0xda) || (m_cxpos[1] == 0x216 && m_cypos[1] == 0x58) || data == 0x39d1) { - uint16_t bx = ((((blx - bxlen) << 3) | (m_bixos & 7)) >> (3 - (m_bif & 3))) & 0xfff; - uint16_t by = ((((bly - bylen) << 3) | (m_biyos & 7)) >> ((3 - (m_bif >> 2)) & 3)) & 0xfff; - - // TODO: Actual Brush Processor functionality - uint16_t lum_sum = lum[x] + m_brushstore_lum[by * 256 + bx]; - uint16_t chr_sum = chr[x] + m_brushstore_chr[by * 256 + bx]; - y = lum_sum > 0xff ? 0xff : (uint16_t)lum_sum; - uint8_t chr_clamped = chr_sum > 0xff ? 0xff : (uint16_t)chr_sum; - if (m_cxpos[i] & 1) - v = chr_clamped; - else - u = chr_clamped; + LOGMASKED(LOG_BRUSH_DRAWS, " Storing %02x in EXT 2\n", final_lsb); } - lum[x] = y; - chr[x] = (m_cxpos[i] & 1) ? v : u; + m_framestore_ext[1][pix_idx] = final_lsb; } } } } } break; + } case 9: // Draw with Stencil I + LOGMASKED(LOG_COMMANDS, "Unsupported command: Draw with Stencil I\n"); break; case 10: // Draw with Stencil II + LOGMASKED(LOG_COMMANDS, "Unsupported command: Draw with Stencil II\n"); break; case 11: // Copy to Framestore + LOGMASKED(LOG_COMMANDS, "Unsupported command: Copy to Framestore\n"); break; case 12: // Copy to Brush Store + { + uint8_t *store_lum = !BIT(data, 5) ? &m_framestore_lum[0][0] : (!BIT(data, 6) ? &m_framestore_lum[1][0] : nullptr); + uint8_t *store_chr = !BIT(data, 5) ? &m_framestore_chr[0][0] : (!BIT(data, 6) ? &m_framestore_chr[1][0] : nullptr); + uint8_t *store_ext = !BIT(data, 5) ? &m_framestore_ext[0][0] : (!BIT(data, 6) ? &m_framestore_ext[1][0] : nullptr); + if (!BIT(data, 7) || true) + store_lum = nullptr; + if (!BIT(data, 8)) + store_chr = nullptr; + if (!BIT(data, 9)) + store_ext = nullptr; + + m_ca0 = 0; + for (uint32_t y = m_cypos[1], bly = m_bylen; bly != 0x1000; bly++, y = (y + 1) & 0xfff) + { + if (y >= 256) + continue; + + const uint32_t line_idx = y * 800; + for (uint32_t x = m_cxpos[1], blx = m_bxlen; blx != 0x1000; blx++, x = (x + 1) & 0xfff) + { + if (x >= 256) + continue; + + const uint32_t pix_idx = line_idx + x; + const uint16_t bx = x;//((((blx - m_bxlen) << 3) | (m_bixos & 7)) >> (3 - (m_bif & 3))) & 0xfff; + const uint16_t by = y;//((((bly - m_bylen) << 3) | (m_biyos & 7)) >> ((3 - (m_bif >> 2)) & 3)) & 0xfff; + const uint16_t uv_bx = ((x & 1) ? (bx | 1) : (bx & ~1)); + if (store_lum) + m_brushstore_lum[by * 256 + bx] = store_lum[pix_idx]; + if (store_chr) + m_brushstore_chr[by * 256 + uv_bx] = store_chr[pix_idx]; + if (store_ext) + m_brushstore_ext[by * 256 + bx] = store_ext[pix_idx]; + } + } break; + } case 13: // Paste with Stencil I + LOGMASKED(LOG_COMMANDS, "Unsupported command: Paste with Stencil I\n"); break; case 14: // Paste with Stencil II + LOGMASKED(LOG_COMMANDS, "Unsupported command: Paste with Stencil II\n"); break; case 15: // Copy to same Framestore (Invert) + LOGMASKED(LOG_COMMANDS, "Unsupported command: Copy to Framestore (Invert)\n"); break; } + return true; } void dpb7000_state::cpu_ctrlbus_w(uint16_t data) @@ -1548,7 +1838,7 @@ void dpb7000_state::cpu_ctrlbus_w(uint16_t data) { case 0: // Brush Address Card, function select { - static const char* const s_func_names[16] = + static const char* const func_names[16] = { "Live Video", "Brush Store Read", "Brush Store Write", "Framestore Read", "Framestore Write", "Fast Wipe Video", "Fast Wipe Brush Store", "Fast Wipe Framestore", @@ -1556,69 +1846,51 @@ void dpb7000_state::cpu_ctrlbus_w(uint16_t data) "Copy to Brush Store", "Paste with Stencil I", "Paste with Stencil II", "Copy to same Framestore (Invert)" }; LOGMASKED(LOG_BRUSH_ADDR, "%s: Brush Address Card, Function Select: %04x\n", machine().describe_context(), data); - LOGMASKED(LOG_BRUSH_ADDR, " Function: %s\n", s_func_names[(data >> 1) & 0xf]); - LOGMASKED(LOG_BRUSH_ADDR, " Store I: %d\n", BIT(data, 5)); - LOGMASKED(LOG_BRUSH_ADDR, " Store II: %d\n", BIT(data, 6)); - LOGMASKED(LOG_BRUSH_ADDR, " Luma Enable: %d\n", BIT(data, 7)); - LOGMASKED(LOG_BRUSH_ADDR, " Chroma Enable: %d\n", BIT(data, 8)); - LOGMASKED(LOG_BRUSH_ADDR, " Brush Select: %d\n", BIT(data, 9)); - LOGMASKED(LOG_BRUSH_ADDR, " Disc Enable: %d\n", BIT(data, 10)); - LOGMASKED(LOG_BRUSH_ADDR, " Brush Invert: %d\n", BIT(data, 11)); - LOGMASKED(LOG_BRUSH_ADDR, " Brush Zero: %d\n", BIT(data, 12)); - LOGMASKED(LOG_BRUSH_ADDR, " Fixed Color Select: %d\n", BIT(data, 13)); + LOGMASKED(LOG_BRUSH_ADDR, " Function: %s\n", func_names[(data >> 1) & 0xf]); + LOGMASKED(LOG_BRUSH_ADDR, " /S1: %d\n", BIT(data, 5)); + LOGMASKED(LOG_BRUSH_ADDR, " /S2: %d\n", BIT(data, 6)); + LOGMASKED(LOG_BRUSH_ADDR, " LUMEN: %d\n", BIT(data, 7)); + LOGMASKED(LOG_BRUSH_ADDR, " CHREN: %d\n", BIT(data, 8)); + LOGMASKED(LOG_BRUSH_ADDR, " KSEL: %d\n", BIT(data, 9)); + LOGMASKED(LOG_BRUSH_ADDR, " DISCEN: %d\n", BIT(data, 10)); + LOGMASKED(LOG_BRUSH_ADDR, " /KINV: %d\n", BIT(data, 11)); + LOGMASKED(LOG_BRUSH_ADDR, " /KZERO: %d\n", BIT(data, 12)); + LOGMASKED(LOG_BRUSH_ADDR, " FCS: %d\n", BIT(data, 13)); LOGMASKED(LOG_BRUSH_ADDR, " Go: %d\n", BIT(data, 0)); m_brush_addr_func = data & ~1; if (BIT(data, 0)) { - handle_command(data); + m_brush_addr_func |= 0x8000; + m_brush_addr_cmd = (data >> 1) & 0xf; + if (handle_command(data)) { + m_cmd_done_timer->adjust(attotime::from_usec(500)); + } } break; } - case 1: // Disk Sequencer Card, disc access + case 1: // Disk Sequencer Card, disk access { const uint8_t hi_nybble = data >> 12; if (hi_nybble == 0) { - uint16_t old_cyl = m_diskseq_cyl_from_cpu; m_diskseq_cyl_from_cpu = data & 0x3ff; - LOGMASKED(LOG_CTRLBUS, "%s: CPU write to Control Bus, Disk Sequencer Card, Cylinder Number: %04x\n", machine().describe_context(), m_diskseq_cyl_from_cpu); - //printf("Cylinder %d\n", m_diskseq_cyl_from_cpu); - if (old_cyl != m_diskseq_cyl_from_cpu && m_diskseq_cyl_from_cpu < 78 && m_floppy != nullptr) - { - if (m_diskseq_cyl_from_cpu < old_cyl) - { - m_floppy->dir_w(1); - for (uint16_t i = m_diskseq_cyl_from_cpu; i < old_cyl; i++) - { - m_floppy->stp_w(1); - m_floppy->stp_w(0); - m_floppy->stp_w(1); - } - } - else - { - m_floppy->dir_w(0); - for (uint16_t i = old_cyl; i < m_diskseq_cyl_from_cpu; i++) - { - m_floppy->stp_w(1); - m_floppy->stp_w(0); - m_floppy->stp_w(1); - } - } - LOGMASKED(LOG_CTRLBUS, "%s: New floppy cylinder: %04x\n", machine().describe_context(), m_floppy->get_cyl()); - } + LOGMASKED(LOG_CTRLBUS, "%s: CPU write to Control Bus, Disk Sequencer Card, Cylinder Number: %04x (%04x)\n", machine().describe_context(), m_diskseq_cyl_from_cpu, data); + if (m_diskseq_cyl_from_cpu == 0) + m_diskseq_status |= 0x04; + else + m_diskseq_status &= ~0x04; } else if (hi_nybble == 1) { LOGMASKED(LOG_CTRLBUS, "%s: CPU write to Control Bus, Disc Data Buffer Card, Preset RAM Address: %04x\n", machine().describe_context(), data & 0xfff); - m_diskbuf_ram_addr = data & 0xfff; + m_diskbuf_ram_addr = (data & 0xfff) << 3; } else if (hi_nybble == 2) { m_diskseq_cmd_word_from_cpu = data & 0xfff; m_diskseq_cmd = (data >> 8) & 0xf; - req_b_w(0); // Flag ourselves as in-use + int group = (int)(data >> 5) & 3; LOGMASKED(LOG_CTRLBUS, "%s: CPU write to Control Bus, Disk Sequencer Card, Command: %x (%04x)\n", machine().describe_context(), (data >> 8) & 0xf, data); LOGMASKED(LOG_CTRLBUS, "%s Head: %x\n", machine().describe_context(), data & 0xf); LOGMASKED(LOG_CTRLBUS, "%s Drive: %x\n", machine().describe_context(), (data >> 5) & 7); @@ -1629,68 +1901,187 @@ void dpb7000_state::cpu_ctrlbus_w(uint16_t data) case 9: case 13: LOGMASKED(LOG_CTRLBUS, "%s: Disk Sequencer Card Command: No command\n", machine().describe_context()); - req_b_w(1); - //m_diskseq_complete_clk->adjust(attotime::from_msec(1)); break; + case 0: LOGMASKED(LOG_CTRLBUS, "%s: Disk Sequencer Card Command: Read track to buffer RAM\n", machine().describe_context()); - if (!BIT(m_diskseq_status_out, 3)) + if (!BIT(m_diskseq_status, 3)) { + req_b_w(0); // Flag ourselves as in-use m_diskseq_cyl_read_pending = true; - m_fdd_side = 0; - } - break; - case 2: + m_diskseq_command_stride = 1; + if (is_disk_group_fdd(group)) + { + m_fdd_side = 0; + seek_fdd_to_cylinder(); + } + else if (is_disk_group_hdd(group)) + { + m_diskseq_use_hdd_pending = true; + m_hdd_command_timer->adjust(attotime::from_double((double)19200 / 1012000)); + } + } + break; + + case 2: LOGMASKED(LOG_CTRLBUS, "%s: Disk Sequencer Card Command: Read track, stride 2, to buffer RAM\n", machine().describe_context()); - if (!BIT(m_diskseq_status_out, 3)) + if (!BIT(m_diskseq_status, 3)) { + req_b_w(0); // Flag ourselves as in-use m_diskseq_cyl_read_pending = true; - m_fdd_side = 0; + m_diskseq_command_stride = 2; + if (is_disk_group_fdd(group)) + { + m_fdd_side = 0; + seek_fdd_to_cylinder(); + } + else if (is_disk_group_hdd(group)) + { + m_diskseq_use_hdd_pending = true; + m_hdd_command_timer->adjust(attotime::from_double((double)19200 / 1012000)); + } } break; + + case 3: + LOGMASKED(LOG_CTRLBUS, "%s: Disk Sequencer Card Command: Restore\n", machine().describe_context()); + m_diskseq_cyl_from_cpu = 0; + req_b_w(0); // Flag ourselves as in-use + m_diskseq_complete_clk->adjust(attotime::from_msec(1), 1); + break; + case 4: LOGMASKED(LOG_CTRLBUS, "%s: Disk Sequencer Card Command: Read Track\n", machine().describe_context()); - if (!BIT(m_diskseq_status_out, 3)) + if (!BIT(m_diskseq_status, 3)) { - m_diskbuf_data_count = 0x2700; + req_b_w(0); // Flag ourselves as in-use m_line_count = 0; m_line_clock = 0; + m_diskseq_cyl_read_pending = true; - m_fdd_side = 0; + m_diskseq_command_stride = 1; + if (is_disk_group_fdd(group)) + { + m_diskbuf_data_count = 0x2700; + m_fdd_side = 0; + seek_fdd_to_cylinder(); + } + else if (is_disk_group_hdd(group)) + { + m_diskbuf_data_count = 0x4b00; + m_diskseq_use_hdd_pending = true; + m_hdd_command_timer->adjust(attotime::from_double((double)19200 / 1012000)); + } } break; + case 6: LOGMASKED(LOG_CTRLBUS, "%s: Disk Sequencer Card Command: Disc Clear, Read Track\n", machine().describe_context()); - if (!BIT(m_diskseq_status_out, 3)) + if (!BIT(m_diskseq_status, 3)) { - m_diskbuf_data_count = 0x2700; + m_size_dxdx_counter = 0; + m_size_dydy_counter = 0; + m_size_dest_x = (m_brush_addr_cmd != 2) ? m_cxpos[1] : 0; + m_size_dest_y = (m_brush_addr_cmd != 2) ? m_cypos[1] : 0; + + req_b_w(0); // Flag ourselves as in-use m_diskseq_cyl_read_pending = true; - m_fdd_side = 0; + m_diskseq_command_stride = 1; + if (is_disk_group_fdd(group)) + { + m_diskbuf_data_count = 0x2700; + m_fdd_side = 0; + seek_fdd_to_cylinder(); + } + else if (is_disk_group_hdd(group)) + { + m_diskbuf_data_count = 0x4b00; + m_diskseq_use_hdd_pending = true; + m_hdd_command_timer->adjust(attotime::from_double((double)19200 / 1012000)); + } } break; + case 8: - LOGMASKED(LOG_CTRLBUS, "%s: Disk Sequencer Card Command: Write Track from Buffer RAM (not yet implemented)\n", machine().describe_context()); - req_b_w(1); - //m_diskseq_complete_clk->adjust(attotime::from_msec(1)); + LOGMASKED(LOG_CTRLBUS, "%s: Disk Sequencer Card Command: Write Track from Buffer RAM\n", machine().describe_context()); + if (!BIT(m_diskseq_status, 3)) + { + req_b_w(0); // Flag ourselves as in-use + m_diskseq_cyl_write_pending = true; + m_diskseq_command_stride = 1; + if (is_disk_group_fdd(group)) + { + m_diskbuf_data_count = 0x2700; + m_fdd_side = 0; + seek_fdd_to_cylinder(); + } + else if (is_disk_group_hdd(group)) + { + m_diskbuf_data_count = 0x4b00; + m_diskseq_use_hdd_pending = true; + m_hdd_command_timer->adjust(attotime::from_double((double)19200 / 1012000)); + } + } break; + case 10: - LOGMASKED(LOG_CTRLBUS, "%s: Disk Sequencer Card Command: Write Track, stride 2, from Buffer RAM (not yet implemented)\n", machine().describe_context()); - req_b_w(1); - //m_diskseq_complete_clk->adjust(attotime::from_msec(1)); + LOGMASKED(LOG_CTRLBUS, "%s: Disk Sequencer Card Command: Write Track, stride 2, from Buffer RAM\n", machine().describe_context()); + if (!BIT(m_diskseq_status, 3)) + { + req_b_w(0); // Flag ourselves as in-use + m_diskseq_cyl_write_pending = true; + m_diskseq_command_stride = 2; + if (is_disk_group_fdd(group)) + { + m_diskbuf_data_count = 0x2700; + m_fdd_side = 0; + seek_fdd_to_cylinder(); + } + else if (is_disk_group_hdd(group)) + { + m_diskbuf_data_count = 0x4b00; + m_diskseq_use_hdd_pending = true; + m_hdd_command_timer->adjust(attotime::from_double((double)19200 / 1012000)); + } + } break; + case 12: - LOGMASKED(LOG_CTRLBUS, "%s: Disk Sequencer Card Command: Write Track (not yet implemented)\n", machine().describe_context()); - req_b_w(1); - //m_diskseq_complete_clk->adjust(attotime::from_msec(1)); + LOGMASKED(LOG_CTRLBUS, "%s: Disk Sequencer Card Command: Write Track\n", machine().describe_context()); + if (!BIT(m_diskseq_status, 3) && is_disk_group_hdd(group)) + { + req_b_w(0); // Flag ourselves as in-use + + m_diskseq_cyl_write_pending = true; + m_diskseq_command_stride = 1; + + m_diskbuf_data_count = 0x4b00; + m_diskseq_use_hdd_pending = true; + m_hdd_command_timer->adjust(attotime::from_double((double)19200 / 1012000)); + } break; + case 14: - LOGMASKED(LOG_CTRLBUS, "%s: Disk Sequencer Card Command: Disc Clear, Write Track (not yet implemented)\n", machine().describe_context()); - req_b_w(1); - //m_diskseq_complete_clk->adjust(attotime::from_msec(1)); + LOGMASKED(LOG_CTRLBUS, "%s: Disk Sequencer Card Command: Disc Clear, Write Track\n", machine().describe_context()); + if (!BIT(m_diskseq_status, 3) && is_disk_group_hdd(group)) + { + req_b_w(0); // Flag ourselves as in-use + m_line_count = 0; + m_line_clock = 0; + + m_diskseq_cyl_write_pending = true; + m_diskseq_command_stride = 1; + + m_diskbuf_data_count = 0x4b00; + m_diskseq_use_hdd_pending = true; + m_hdd_command_timer->adjust(attotime::from_double((double)19200 / 1012000)); + } break; + default: LOGMASKED(LOG_CTRLBUS, "%s: Unknown Disk Sequencer Card command.\n", machine().describe_context()); - m_diskseq_complete_clk->adjust(attotime::from_msec(1)); + req_b_w(0); // Flag ourselves as in-use + m_diskseq_complete_clk->adjust(attotime::from_msec(1), 1); break; } } @@ -1702,9 +2093,10 @@ void dpb7000_state::cpu_ctrlbus_w(uint16_t data) } case 2: // Store Address Card - store_address_w(1, data); if (BIT(data, 15)) store_address_w(0, data); + else + store_address_w(1, data); break; case 3: // Size Card, Y6/Y7 @@ -1714,34 +2106,195 @@ void dpb7000_state::cpu_ctrlbus_w(uint16_t data) } else { - LOGMASKED(LOG_CTRLBUS | LOG_SIZE_CARD, "%s: Size Card Y6 (Coefficients): %04x\n", machine().describe_context(), data & 0x7fff); + switch (data & 0x3300) + { + case 0x1000: // Change in source X per change in dest X, MSB + LOGMASKED(LOG_CTRLBUS | LOG_SIZE_CARD, "%s: Size Card delta source X per delta dest X, MSB: %02x (%04x)\n", machine().describe_context(), data & 0xff, data); + m_size_dsx_ddx &= 0x00ff; + m_size_dsx_ddx |= (data & 0x00ff) << 8; + break; + case 0x0000: // Change in source X per change in dest X, LSB + LOGMASKED(LOG_CTRLBUS | LOG_SIZE_CARD, "%s: Size Card delta source X per delta dest X, LSB: %02x (%04x)\n", machine().describe_context(), data & 0xff, data); + m_size_dsx_ddx &= 0xff00; + m_size_dsx_ddx |= data & 0x00ff; + break; + case 0x3000: // Change in source Y per change in dest X, MSB + LOGMASKED(LOG_CTRLBUS | LOG_SIZE_CARD, "%s: Size Card delta source Y per delta dest X, MSB: %02x (%04x)\n", machine().describe_context(), data & 0xff, data); + m_size_dsy_ddx &= 0x00ff; + m_size_dsy_ddx |= (data & 0x00ff) << 8; + break; + case 0x2000: // Change in source Y per change in dest X, LSB + LOGMASKED(LOG_CTRLBUS | LOG_SIZE_CARD, "%s: Size Card delta source Y per delta dest X, LSB: %02x (%04x)\n", machine().describe_context(), data & 0xff, data); + m_size_dsy_ddx &= 0xff00; + m_size_dsy_ddx |= data & 0x00ff; + break; + case 0x1100: // Change in source X per change in dest Y, MSB + LOGMASKED(LOG_CTRLBUS | LOG_SIZE_CARD, "%s: Size Card delta source X per delta dest Y, MSB: %02x (%04x)\n", machine().describe_context(), data & 0xff, data); + m_size_dsx_ddy &= 0x00ff; + m_size_dsx_ddy |= (data & 0x00ff) << 8; + break; + case 0x0100: // Change in source X per change in dest Y, LSB + LOGMASKED(LOG_CTRLBUS | LOG_SIZE_CARD, "%s: Size Card delta source X per delta dest Y, LSB: %02x (%04x)\n", machine().describe_context(), data & 0xff, data); + m_size_dsx_ddy &= 0xff00; + m_size_dsx_ddy |= data & 0x00ff; + break; + case 0x3100: // Change in source Y per change in dest Y, MSB + LOGMASKED(LOG_CTRLBUS | LOG_SIZE_CARD, "%s: Size Card delta source Y per delta dest Y, MSB: %02x (%04x)\n", machine().describe_context(), data & 0xff, data); + m_size_dsy_ddy &= 0x00ff; + m_size_dsy_ddy |= (data & 0x00ff) << 8; + break; + case 0x2100: // Change in source Y per change in dest Y, LSB + LOGMASKED(LOG_CTRLBUS | LOG_SIZE_CARD, "%s: Size Card delta source Y per delta dest Y, LSB: %02x (%04x)\n", machine().describe_context(), data & 0xff, data); + m_size_dsy_ddy &= 0xff00; + m_size_dsy_ddy |= data & 0x00ff; + break; + case 0x1300: // Origin, source X / dest X + LOGMASKED(LOG_CTRLBUS | LOG_SIZE_CARD, "%s: Size Card origin, source X / dest X: %02x (%04x)\n", machine().describe_context(), data & 0xff, data); + m_size_frac_origin_sx_dx = data & 0x00ff; + break; + case 0x0300: // Origin, source X / dest Y + LOGMASKED(LOG_CTRLBUS | LOG_SIZE_CARD, "%s: Size Card origin, source X / dest Y: %02x (%04x)\n", machine().describe_context(), data & 0xff, data); + m_size_frac_origin_sx_dy = data & 0x00ff; + break; + case 0x3300: // Origin, source Y / dest X + LOGMASKED(LOG_CTRLBUS | LOG_SIZE_CARD, "%s: Size Card origin, source Y / dest X: %02x (%04x)\n", machine().describe_context(), data & 0xff, data); + m_size_frac_origin_sy_dx = data & 0x00ff; + break; + case 0x2300: // Origin, source Y / dest Y + LOGMASKED(LOG_CTRLBUS | LOG_SIZE_CARD, "%s: Size Card origin, source Y / dest Y: %02x (%04x)\n", machine().describe_context(), data & 0xff, data); + m_size_frac_origin_sy_dy = data & 0x00ff; + break; + } } break; case 5: // Filter Card if (BIT(data, 15)) { - LOGMASKED(LOG_CTRLBUS | LOG_FILTER_CARD, "%s: Coefficient(?) RAM B: Index %x = %02x\n", machine().describe_context(), (data >> 8) & 0xf, data & 0xff); - m_filter_abbb[(data >> 8) & 0xf] = data & 0xff; + static const char *const coeff_names[8] = { "Y-3", "Y-2", "Y-1", "Y (LSB)", "Y (MSB)", "Y+1", "Y+2", "Y+3" }; + const uint16_t coeff_idx = ((data >> 8) & 0xf) - 2; + switch ((data >> 8) & 0xf) + { + case 2: // Y-3 + case 3: // Y-2 + case 4: // Y-1 + case 5: // Y (LSB) + case 6: // Y (MSB) + case 7: // Y+1 + case 8: // Y+2 + case 9: // Y+3 + LOGMASKED(LOG_CTRLBUS | LOG_FILTER_CARD, "%s: Filter Card %s Coefficient Write: %02x\n", machine().describe_context(), coeff_names[coeff_idx], data & 0xff); + m_filter_y_coeffs[coeff_idx] = data & 0xff; + break; + default: // Ignored + LOGMASKED(LOG_CTRLBUS | LOG_FILTER_CARD, "%s: Filter Card Coefficient (ignored Y) Write: %04x\n", machine().describe_context(), data); + break; + } } else { - LOGMASKED(LOG_CTRLBUS | LOG_FILTER_CARD, "%s: Coefficient(?) RAM C: Index %x = %02x\n", machine().describe_context(), (data >> 8) & 0xf, data & 0xff); - m_filter_acbc[(data >> 8) & 0xf] = data & 0xff; + static const char *const coeff_names[12] = { "X-5", "X-4", "X-3", "X-2", "X-1", "X (LSB)", "X (MSB)", "X+1", "X+2", "X+3", "X+4", "X+5" }; + const uint16_t coeff_idx = ((data >> 8) & 0xf) - 1; + switch ((data >> 8) & 0xf) + { + case 1: // X-5 + case 2: // X-4 + case 3: // X-3 + case 4: // X-2 + case 5: // X-1 + case 6: // X (LSB) + case 7: // X (MSB) + case 8: // X+1 + case 9: // X+2 + case 10: // X+3 + case 11: // X+4 + case 12: // X+5 + LOGMASKED(LOG_CTRLBUS | LOG_FILTER_CARD, "%s: Filter Card %s Coefficient Write: %02x\n", machine().describe_context(), coeff_names[coeff_idx], data & 0xff); + m_filter_x_coeffs[coeff_idx] = data & 0xff; + break; + default: // Ignored + LOGMASKED(LOG_CTRLBUS | LOG_FILTER_CARD, "%s: Filter Card Coefficient (ignored X) Write: %04x\n", machine().describe_context(), data); + break; + } } break; + case 7: // Disk Data Buffer RAM + LOGMASKED(LOG_DDB, "%s: Disc Data Buffer Card RAM write: %04x = %04x\n", machine().describe_context(), m_diskbuf_ram_addr, data); + m_diskbuf_ram[m_diskbuf_ram_addr++] = (uint8_t)data; + break; + case 8: // Brush Store Card color latches - LOGMASKED(LOG_CTRLBUS | LOG_BRUSH_ADDR, "%s: Brush Store Card color latches (%s): %04x\n", machine().describe_context(), m_ca0 ? "VY" : "UY", data); + m_bs_y_latch = (uint8_t)data; if (m_ca0) { + LOGMASKED(LOG_CTRLBUS | LOG_BRUSH_ADDR | LOG_BRUSH_LATCH, "%s: Brush Store Card color latches (VY): %04x\n\n", machine().describe_context(), data); m_bs_v_latch = (uint8_t)(data >> 8); - m_bs_y_latch = (uint8_t)data; } else { + LOGMASKED(LOG_CTRLBUS | LOG_BRUSH_ADDR | LOG_BRUSH_LATCH, "%s: Brush Store Card color latches (UY): %04x\n", machine().describe_context(), data); m_bs_u_latch = (uint8_t)(data >> 8); } + if (m_brush_addr_cmd == 4) // Framestore Write + { + const uint8_t chr = m_ca0 ? m_bs_v_latch : m_bs_u_latch; + if (!BIT(m_brush_addr_func, 5)) + { + const uint16_t x = m_cxpos[0] + (m_bxlen_counter - m_bxlen); + const uint16_t y = m_cypos[0] + (m_bylen_counter - m_bylen); + uint32_t pix_idx = y * 800 + x; + + if (BIT(m_brush_addr_func, 7)) + { + LOGMASKED(LOG_CTRLBUS | LOG_BRUSH_ADDR | LOG_BRUSH_LATCH, "%s: Writing %02x to Store 1 luma at %d,%d\n", machine().describe_context(), m_bs_y_latch, x, y); + m_framestore_lum[0][pix_idx] = m_bs_y_latch; + } + if (BIT(m_brush_addr_func, 8)) + { + LOGMASKED(LOG_CTRLBUS | LOG_BRUSH_ADDR | LOG_BRUSH_LATCH, "%s: Writing %02x to Store 1 chroma at %d,%d\n", machine().describe_context(), chr, x, y); + m_framestore_chr[0][pix_idx] = chr; + } + if (BIT(m_brush_addr_func, 9)) + { + LOGMASKED(LOG_CTRLBUS | LOG_BRUSH_ADDR | LOG_BRUSH_LATCH, "%s: Writing %02x to Store 1 stencil at %d,%d\n", machine().describe_context(), m_bs_y_latch, x, y); + m_framestore_ext[0][pix_idx] = m_bs_y_latch; + } + } + if (!BIT(m_brush_addr_func, 6)) + { + const uint16_t x = m_cxpos[1] + (m_bxlen_counter - m_bxlen); + const uint16_t y = m_cypos[1] + (m_bylen_counter - m_bylen); + uint32_t pix_idx = y * 800 + x; + + if (BIT(m_brush_addr_func, 7)) + { + LOGMASKED(LOG_CTRLBUS | LOG_BRUSH_ADDR | LOG_BRUSH_LATCH, "%s: Writing %02x to Store 2 luma at %d,%d\n", machine().describe_context(), m_bs_y_latch, x, y); + m_framestore_lum[1][pix_idx] = m_bs_y_latch; + } + if (BIT(m_brush_addr_func, 8)) + { + LOGMASKED(LOG_CTRLBUS | LOG_BRUSH_ADDR | LOG_BRUSH_LATCH, "%s: Writing %02x to Store 2 chroma at %d,%d\n", machine().describe_context(), chr, x, y); + m_framestore_chr[1][pix_idx] = chr; + } + if (BIT(m_brush_addr_func, 9)) + { + LOGMASKED(LOG_CTRLBUS | LOG_BRUSH_ADDR | LOG_BRUSH_LATCH, "%s: Writing %02x to Store 2 stencil at %d,%d\n", machine().describe_context(), m_bs_y_latch, x, y); + m_framestore_ext[1][pix_idx] = m_bs_y_latch; + } + } + + m_bxlen_counter++; + if (m_bxlen_counter == 0x1000) + { + m_bxlen_counter = m_bxlen; + m_bylen_counter++; + if (m_bylen_counter == 0x1000) + { + cmd_done(0); + } + } + } m_ca0 = 1 - m_ca0; break; @@ -1771,12 +2324,12 @@ void dpb7000_state::cpu_ctrlbus_w(uint16_t data) m_bylen_counter = data & 0xfff; break; case 6: - LOGMASKED(LOG_CTRLBUS | LOG_BRUSH_ADDR, "%s: Brush Address Card, Register Write: PLUM = %03x(?)\n", machine().describe_context(), data & 0xff); - m_plum = data & 0xff; + LOGMASKED(LOG_CTRLBUS | LOG_BRUSH_ADDR | LOG_BRUSH_LATCH, "%s: Brush Address Card, Register Write: PLUM = %03x\n", machine().describe_context(), data & 0xff); + m_brush_press_lum = data & 0xff; break; case 7: - LOGMASKED(LOG_CTRLBUS | LOG_BRUSH_ADDR, "%s: Brush Address Card, Register Write: PCHR = %03x(?)\n", machine().describe_context(), data & 0xff); - m_pchr = data & 0xff; + LOGMASKED(LOG_CTRLBUS | LOG_BRUSH_ADDR | LOG_BRUSH_LATCH, "%s: Brush Address Card, Register Write: PCHR = %03x\n", machine().describe_context(), data & 0xff); + m_brush_press_chr = data & 0xff; break; default: LOGMASKED(LOG_CTRLBUS | LOG_BRUSH_ADDR, "%s: Brush Address Card, Register Write: Unknown (%04x)\n", machine().describe_context(), data); @@ -1789,21 +2342,23 @@ void dpb7000_state::cpu_ctrlbus_w(uint16_t data) const uint8_t hi_bits = (data >> 14) & 3; if (hi_bits == 0) // Cursor Parameters { - static const char* const s_reg_names[4] = { "Cursor X Origin", "Cursor Y Origin", "Cursor X Size", "Cursor Y Size" }; const uint8_t reg = (data >> 12) & 3; - LOGMASKED(LOG_CTRLBUS | LOG_OUTPUT_TIMING, "%s: CPU write to Output Timing Card: %s = %03x\n", machine().describe_context(), s_reg_names[reg], data & 0xfff); switch (reg) { case 0: // Cursor X Origin + LOGMASKED(LOG_CTRLBUS | LOG_OUTPUT_TIMING, "%s: CPU write to Output Timing Card: Cursor Origin X = %03x\n", machine().describe_context(), data & 0xfff); m_cursor_origin_x = data & 0xfff; break; case 1: // Cursor Y Origin + LOGMASKED(LOG_CTRLBUS | LOG_OUTPUT_TIMING, "%s: CPU write to Output Timing Card: Cursor Origin Y = %03x\n", machine().describe_context(), data & 0xfff); m_cursor_origin_y = data & 0xfff; break; case 2: // Cursor X Size + LOGMASKED(LOG_CTRLBUS | LOG_OUTPUT_TIMING, "%s: CPU write to Output Timing Card: Cursor Size X = %03x\n", machine().describe_context(), data & 0xfff); m_cursor_size_x = data & 0xfff; break; case 3: // Cursor Y Size + LOGMASKED(LOG_CTRLBUS | LOG_OUTPUT_TIMING, "%s: CPU write to Output Timing Card: Cursor Size Y = %03x\n", machine().describe_context(), data & 0xfff); m_cursor_size_y = data & 0xfff; break; } @@ -1821,35 +2376,176 @@ void dpb7000_state::cpu_ctrlbus_w(uint16_t data) case 15: // Disk Sequencer Card, panic reset LOGMASKED(LOG_CTRLBUS, "%s: CPU write to Control Bus, Disk Sequencer Card, panic reset\n", machine().describe_context()); - m_diskseq_reset = true; - m_diskseq_halt = true; break; + default: LOGMASKED(LOG_CTRLBUS | LOG_UNKNOWN, "%s: CPU write to Control Bus, unknown CSR %d: %04x\n", machine().describe_context(), m_csr, data); break; } } -WRITE_LINE_MEMBER(dpb7000_state::req_a_w) +TIMER_CALLBACK_MEMBER(dpb7000_state::req_a_w) { - if (state) - m_sys_ctrl |= SYSCTRL_REQ_A_IN; - else - m_sys_ctrl &= ~SYSCTRL_REQ_A_IN; + //if (machine().input().code_pressed(KEYCODE_LALT)) + { + if (param) + { + m_sys_ctrl |= SYSCTRL_REQ_A_IN; + } + else + { + m_sys_ctrl &= ~SYSCTRL_REQ_A_IN; + } - update_req_irqs(); + update_req_irqs(); + } + /*else + { + m_sys_ctrl &= ~SYSCTRL_REQ_A_IN; + update_req_irqs(); + }*/ } -WRITE_LINE_MEMBER(dpb7000_state::req_b_w) +TIMER_CALLBACK_MEMBER(dpb7000_state::req_b_w) { - if (state) + if (param) + { m_sys_ctrl |= SYSCTRL_REQ_B_IN; + } else + { m_sys_ctrl &= ~SYSCTRL_REQ_B_IN; + } update_req_irqs(); } +TIMER_CALLBACK_MEMBER(dpb7000_state::cmd_done) +{ + m_brush_addr_func &= ~0x8000; +} + +TIMER_CALLBACK_MEMBER(dpb7000_state::execute_hdd_command) +{ + constexpr int SECTORS_PER_TRACK = 20480 / 256; + int group = (int)(m_diskseq_cmd_word_from_cpu >> 5) & 3; + int head_count = get_heads_for_disk_group(group); + int head_index = m_diskseq_cmd_word_from_cpu & 0xf; + int image_lba = SECTORS_PER_TRACK * head_count * (int)m_diskseq_cyl_from_cpu + SECTORS_PER_TRACK * head_index; + + if (m_hdd_file != nullptr) + { + if (m_diskseq_cyl_write_pending) + { + unsigned char sector_buffer[256]; + int start_sector = m_diskbuf_ram_addr >> 8; + uint16_t ram_addr = m_diskbuf_ram_addr; + if (m_diskseq_command_stride != 1) + { + for (int sector = start_sector; sector < 19200 / 256; sector++, image_lba++) + { + m_hdd_file->read(image_lba, sector_buffer); + for (int stride_idx = 0; stride_idx < 256; stride_idx += 2) + { + sector_buffer[stride_idx] = m_diskbuf_ram[ram_addr]; + ram_addr += 2; + } + LOGMASKED(LOG_HDD, "Performing write to LBA %d: Cylinder %03x, head %x, command word %03x, Stride 2 (RAM address %04x, offset %04x)\n", image_lba, m_diskseq_cyl_from_cpu, head_index, m_diskseq_cmd_word_from_cpu, m_diskbuf_ram_addr, sector * 256); + m_hdd_file->write(image_lba, sector_buffer); + } + } + else + { + if (m_diskseq_cmd == 12 || m_diskseq_cmd == 14) + { + for (int sector = 0; sector < 19200 / 256; sector++, image_lba++) + { + LOGMASKED(LOG_HDD, "Performing write to LBA %d: Cylinder %03x, head %x, command word %03x\n", image_lba, m_diskseq_cyl_from_cpu, head_index, m_diskseq_cmd_word_from_cpu); + for (int i = 0; i < 256; i += 2) + { + sector_buffer[i + 0] = process_byte_to_disc(); + sector_buffer[i + 1] = process_byte_to_disc(); + } + m_hdd_file->write(image_lba, sector_buffer); + } + } + else + { + for (int sector = start_sector; sector < 19200 / 256; sector++, image_lba++) + { + LOGMASKED(LOG_HDD, "Performing write to LBA %d: Cylinder %03x, head %x, command word %03x (RAM address %04x, offset %04x)\n", image_lba, m_diskseq_cyl_from_cpu, head_index, m_diskseq_cmd_word_from_cpu, m_diskbuf_ram_addr, sector * 256); + m_hdd_file->write(image_lba, m_diskbuf_ram + sector * 256); + } + } + } + m_diskseq_cyl_write_pending = false; + } + else if (m_diskseq_cyl_read_pending) + { + unsigned char sector_buffer[256]; + if (m_diskseq_command_stride != 1) + { + for (int sector = 0; sector < 19200 / 256; sector++, image_lba++) + { + LOGMASKED(LOG_HDD, "Performing read of LBA %d: Cylinder %03x, head %x, command word %03x\n", image_lba, m_diskseq_cyl_from_cpu, head_index, m_diskseq_cmd_word_from_cpu); + m_hdd_file->read(image_lba, sector_buffer); + for (int clear_idx = 0; clear_idx < 256; clear_idx += 2) + { + sector_buffer[clear_idx] = 0; + } + if (m_diskseq_cmd == 4 || m_diskseq_cmd == 6) + { + for (int i = 0; i < 256; i++) + { + process_byte_from_disc(sector_buffer[i]); + } + } + else + { + memcpy(m_diskbuf_ram + sector * 256, sector_buffer, 256); + } + } + } + else + { + int start_sector = BIT(m_diskseq_cmd, 2) ? 0 : (m_diskbuf_ram_addr >> 8); + int partial_bytes = m_diskbuf_ram_addr & 0x00ff; + if (partial_bytes && !BIT(m_diskseq_cmd, 2)) + { + LOGMASKED(LOG_HDD, "Performing partial read of sector into disk buffer address %04x\n", m_diskbuf_ram_addr); + m_hdd_file->read(image_lba, sector_buffer); + memcpy(m_diskbuf_ram + m_diskbuf_ram_addr, sector_buffer + partial_bytes, 0x100 - partial_bytes); + m_diskbuf_ram_addr += 0x100; + m_diskbuf_ram_addr &= 0xff00; + image_lba += start_sector; + } + + for (int sector = start_sector; sector < 19200 / 256; sector++, image_lba++) + { + LOGMASKED(LOG_HDD, "Performing read of LBA %d: Cylinder %03x, head %x, command word %03x\n", image_lba, m_diskseq_cyl_from_cpu, head_index, m_diskseq_cmd_word_from_cpu); + if (BIT(m_diskseq_cmd, 2)) + { + m_hdd_file->read(image_lba, sector_buffer); + for (int i = 0; i < 256; i++) + { + process_byte_from_disc(sector_buffer[i]); + } + } + else + { + m_hdd_file->read(image_lba, m_diskbuf_ram + sector * 256); + } + } + } + m_diskseq_cyl_read_pending = false; + } + m_diskseq_command_stride = 2; + } + + m_diskseq_use_hdd_pending = false; + req_b_w(1); +} + uint16_t dpb7000_state::cpu_sysctrl_r() { const uint16_t ctrl = m_sys_ctrl &~ SYSCTRL_AUTO_START; @@ -1862,7 +2558,7 @@ uint16_t dpb7000_state::cpu_sysctrl_r() void dpb7000_state::cpu_sysctrl_w(uint16_t data) { const uint16_t mask = (SYSCTRL_REQ_A_EN | SYSCTRL_REQ_B_EN); - LOGMASKED(LOG_SYS_CTRL, "%s: CPU to Control Bus write: %04x\n", machine().describe_context(), data); + LOGMASKED(LOG_IRQ, "%s: CPU to Control Bus write: %04x\n", machine().describe_context(), data); m_sys_ctrl &= ~mask; m_sys_ctrl |= (data & mask); @@ -1871,8 +2567,18 @@ void dpb7000_state::cpu_sysctrl_w(uint16_t data) void dpb7000_state::update_req_irqs() { - m_maincpu->set_input_line(5, (m_sys_ctrl & SYSCTRL_REQ_A_IN) && (m_sys_ctrl & SYSCTRL_REQ_A_EN) ? ASSERT_LINE : CLEAR_LINE); - m_maincpu->set_input_line(4, (m_sys_ctrl & SYSCTRL_REQ_B_IN) && (m_sys_ctrl & SYSCTRL_REQ_B_EN) ? ASSERT_LINE : CLEAR_LINE); + const bool take_irq_a = (m_sys_ctrl & SYSCTRL_REQ_A_IN) && (m_sys_ctrl & SYSCTRL_REQ_A_EN); + const bool take_irq_b = (m_sys_ctrl & SYSCTRL_REQ_B_IN) && (m_sys_ctrl & SYSCTRL_REQ_B_EN); + if (take_irq_a) + { + LOGMASKED(LOG_IRQ, "Flagging to take IRQ A\n"); + } + m_maincpu->set_input_line(5, take_irq_a ? ASSERT_LINE : CLEAR_LINE); + if (take_irq_b) + { + LOGMASKED(LOG_IRQ, "Flagging to take IRQ B\n"); + } + m_maincpu->set_input_line(4, take_irq_b ? ASSERT_LINE : CLEAR_LINE); } uint8_t dpb7000_state::fdd_ctrl_r() @@ -1901,28 +2607,184 @@ void dpb7000_state::toggle_line_clock() void dpb7000_state::process_sample() { - const uint16_t x = (m_bxlen_counter - m_bxlen); - const uint16_t y = (m_bylen_counter - m_bylen); - //printf("Processing sample %d,%d (%04x:%04x, %04x:%04x) LC:%d\n", x, y, m_bxlen_counter, m_bxlen, m_bylen_counter, m_bylen, m_line_count); - if (BIT(m_brush_addr_func, 7)) - m_brushstore_lum[y * 256 + x] = m_incoming_lum; - if (BIT(m_brush_addr_func, 8)) - m_brushstore_chr[y * 256 + x] = m_incoming_chr; + const uint16_t x = m_size_dest_x; + const uint16_t y = m_size_dest_y; + + //m_size_dsx_ddx = 0x100; + //m_size_dsy_ddy = 0x100; + + //if (m_size_dsx_ddx != 0x100) printf("Processing sample %d,%d (%04x:%04x, %04x:%04x) LC:%d dxdx:%06x, dydy:%06x\n", x, y, m_bxlen_counter, m_bxlen, m_bylen_counter, m_bylen, m_line_count, m_size_dxdx_counter, m_size_dydy_counter); + bool process_sample = m_size_dxdx_counter <= 0 && m_size_dydy_counter <= 0; + if (process_sample) + { + switch (m_brush_addr_cmd) + { + case 2: // Brush Store Write + LOGMASKED(LOG_BRUSH_WRITES, "Processing %02x,%02x into Brush Store L/C/E at %d, %d\n", m_incoming_lum, m_incoming_chr, x, y); + if (BIT(m_brush_addr_func, 7)) + m_brushstore_lum[y * 256 + x] = m_incoming_lum; + if (BIT(m_brush_addr_func, 8)) + m_brushstore_chr[y * 256 + x] = m_incoming_chr; + if (BIT(m_brush_addr_func, 9)) + m_brushstore_ext[y * 256 + x] = m_incoming_lum; + break; + + case 4: // Framestore Write + { + uint32_t pix_idx = y * 800 + x; + if (!BIT(m_brush_addr_func, 5)) + { + if (BIT(m_brush_addr_func, 7)) + m_framestore_lum[0][pix_idx] = m_incoming_lum; + if (BIT(m_brush_addr_func, 8)) + m_framestore_chr[0][pix_idx] = m_incoming_chr; + if (BIT(m_brush_addr_func, 9)) + m_framestore_ext[0][pix_idx] = m_incoming_lum; + } + if (!BIT(m_brush_addr_func, 6)) + { + if (BIT(m_brush_addr_func, 7)) + m_framestore_lum[1][pix_idx] = m_incoming_lum; + if (BIT(m_brush_addr_func, 8)) + m_framestore_chr[1][pix_idx] = m_incoming_chr; + if (BIT(m_brush_addr_func, 9)) + m_framestore_ext[1][pix_idx] = m_incoming_lum; + } + break; + } + } + } + + if (m_size_dxdx_counter <= 0) + { + m_size_dxdx_counter += 0x100;//(int16_t)(m_size_dsx_ddx & 0x7fff); + m_size_dest_x++; + } + m_size_dxdx_counter -= 0x100; m_bxlen_counter++; if (m_bxlen_counter == 0x1000) { + //if (m_size_dsx_ddx != 0x100) printf("Advancing to next line due to bxlen counter elapsing\n"); m_bxlen_counter = m_bxlen; m_bylen_counter++; + + if (m_size_dydy_counter <= 0) + { + m_size_dydy_counter += 0x100;//(int16_t)(m_size_dsy_ddy & 0x7fff); + m_size_dest_y++; + //if (m_size_dsx_ddx != 0x100) printf("dydy counter is <= 0, resetting dydy counter to %04x, dxdx counter to 0, dest X to %d, dest Y to %d\n", m_size_dydy_counter, m_size_dest_x, m_size_dest_y); + } + m_size_dydy_counter -= 0x100; + + m_size_dxdx_counter = 0; + m_size_dest_x = (m_brush_addr_cmd != 2) ? m_cxpos[1] : 0; + + //if (m_size_dsx_ddx != 0x100) printf("At end of line, dydy counter is now %04x\n", m_size_dydy_counter); + if (m_bylen_counter == 0x1000) { m_diskseq_cyl_read_pending = false; + cmd_done(0); } } } +uint8_t dpb7000_state::process_byte_to_disc() +{ + if (!m_diskseq_cyl_write_pending) + return 0; + + uint8_t lum = 0; + uint8_t chr = 0; + switch (m_brush_addr_cmd) + { + case 3: // Framestore Read + { + if (!BIT(m_brush_addr_func, 5)) + { + const uint16_t x = m_cxpos[0] + (m_bxlen_counter - m_bxlen); + const uint16_t y = m_cypos[0] + (m_bylen_counter - m_bylen); + uint32_t pix_idx = y * 800 + x; + + if (BIT(m_brush_addr_func, 9)) + { + lum = m_framestore_ext[0][pix_idx]; + LOGMASKED(LOG_STORE_READS, "Reading %02x from Store 1 Stencil at %d, %d to disk [%03x %03x]\n", lum, x, y, m_bxlen_counter, m_bylen_counter); + } + if (BIT(m_brush_addr_func, 8)) + { + chr = m_framestore_chr[0][pix_idx]; + LOGMASKED(LOG_STORE_READS, "Reading %02x from Store 1 Chroma at %d, %d to disk [%03x %03x]\n", chr, x, y, m_bxlen_counter, m_bylen_counter); + } + if (BIT(m_brush_addr_func, 7)) + { + lum = m_framestore_lum[0][pix_idx]; + LOGMASKED(LOG_STORE_READS, "Reading %02x from Store 1 Luma at %d, %d to disk [%03x %03x]\n", lum, x, y, m_bxlen_counter, m_bylen_counter); + } + } + + if (!BIT(m_brush_addr_func, 6)) + { + const uint16_t x = m_cxpos[1] + (m_bxlen_counter - m_bxlen); + const uint16_t y = m_cypos[1] + (m_bylen_counter - m_bylen); + uint32_t pix_idx = y * 800 + x; + + if (BIT(m_brush_addr_func, 9)) + { + lum = m_framestore_ext[1][pix_idx]; + LOGMASKED(LOG_STORE_READS, "Reading %02x from Store 2 Stencil at %d, %d to disk [%03x %03x]\n", lum, x, y, m_bxlen_counter, m_bylen_counter); + } + if (BIT(m_brush_addr_func, 8)) + { + chr = m_framestore_chr[1][pix_idx]; + LOGMASKED(LOG_STORE_READS, "Reading %02x from Store 2 Chroma at %d, %d to disk [%03x %03x]\n", chr, x, y, m_bxlen_counter, m_bylen_counter); + } + if (BIT(m_brush_addr_func, 7)) + { + lum = m_framestore_lum[1][pix_idx]; + LOGMASKED(LOG_STORE_READS, "Reading %02x from Store 2 Luma at %d, %d to disk [%03x %03x]\n", lum, x, y, m_bxlen_counter, m_bylen_counter); + } + } + break; + } + } + + const uint8_t ret = m_buffer_lum ? lum : chr; + + m_buffer_lum = !m_buffer_lum; + if (m_buffer_lum) + { + m_line_length++; + if (m_line_length == 0x300) + { + advance_line_count(); + } + + m_bxlen_counter++; + if (m_bxlen_counter == 0x1000) + { + m_bxlen_counter = m_bxlen; + m_bylen_counter++; + if (m_bylen_counter == 0x1000) + { + if (m_brush_addr_cmd == 3) + { + LOGMASKED(LOG_STORE_READS, "Done with Store Read command\n"); + } + m_diskseq_cyl_write_pending = false; + cmd_done(0); + } + } + } + return ret; +} + void dpb7000_state::process_byte_from_disc(uint8_t data_byte) { + if (!m_diskseq_cyl_read_pending) + return; + if (m_buffer_lum) { m_incoming_lum = data_byte; @@ -1941,15 +2803,51 @@ void dpb7000_state::process_byte_from_disc(uint8_t data_byte) } } +bool dpb7000_state::is_disk_group_fdd(int group_index) +{ + constexpr uint16_t GROUP_SHIFTS[3] = { DGROUP_0_SHIFT, DGROUP_1_SHIFT, DGROUP_2_SHIFT }; + uint16_t val = (m_config_sw34->read() >> GROUP_SHIFTS[group_index]) & 7; + return val == DGROUP_TYPE_FLOPPY; +} + +bool dpb7000_state::is_disk_group_hdd(int group_index) +{ + constexpr uint16_t GROUP_SHIFTS[3] = { DGROUP_0_SHIFT, DGROUP_1_SHIFT, DGROUP_2_SHIFT }; + uint16_t val = (m_config_sw34->read() >> GROUP_SHIFTS[group_index]) & 7; + return val == DGROUP_TYPE_80MB_CDC || val == DGROUP_TYPE_160MB_FUJITSU || val == DGROUP_TYPE_330MB_FUJITSU; +} + +int dpb7000_state::get_heads_for_disk_group(int group_index) +{ + constexpr uint16_t GROUP_SHIFTS[3] = { DGROUP_0_SHIFT, DGROUP_1_SHIFT, DGROUP_2_SHIFT }; + uint16_t val = (m_config_sw34->read() >> GROUP_SHIFTS[group_index]) & 7; + switch (val) + { + case DGROUP_TYPE_FLOPPY: + return 1; + case DGROUP_TYPE_80MB_CDC: + return 5; + case DGROUP_TYPE_160MB_FUJITSU: + return 10; + case DGROUP_TYPE_330MB_FUJITSU: + return 16; + default: + return 0; + } +} + void dpb7000_state::fdd_index_callback(floppy_image_device *floppy, int state) { + if (m_diskseq_use_hdd_pending) + return; + if (!state && m_diskseq_cyl_read_pending && m_floppy && m_fdd_side < 2) { - //printf("Cylinder read is pending, index just passed by, we have a floppy. Let's go.\n"); + LOGMASKED(LOG_COMMANDS, "Reading cylinder from floppy\n"); m_fdd_pll.read_reset(machine().time()); - static const uint16_t PREGAP_MARK = 0xaaaa; - static const uint16_t SYNC_MARK = 0x9125; + constexpr uint16_t PREGAP_MARK = 0xaaaa; + constexpr uint16_t SYNC_MARK = 0x9125; m_floppy->ss_w(m_fdd_side); @@ -1959,7 +2857,6 @@ void dpb7000_state::fdd_index_callback(floppy_image_device *floppy, int state) uint16_t curr_window = 0; uint16_t bit_idx = 0; - //printf("Side %d, not seen pregap, not in the track, no current bit, no current window, no bit index.\n", m_fdd_side); attotime tm = machine().time(); attotime limit = machine().time() + attotime::from_ticks(1, 6); // One revolution at 360rpm on a Shugart SA850 do @@ -1978,21 +2875,18 @@ void dpb7000_state::fdd_index_callback(floppy_image_device *floppy, int state) if (!seen_pregap && curr_window == PREGAP_MARK) { seen_pregap = true; - //printf("\nFound pregap area.\n"); bit_idx = 0; curr_window = 0; } else if (seen_pregap && !in_track && curr_window == SYNC_MARK) { in_track = true; - //printf("\nOh hi, mark.\n"); bit_idx = 0; curr_window = 0; } else if (seen_pregap && in_track && bit_idx == 16) { uint8_t data_byte = (uint8_t)bitswap<16>((uint16_t)curr_window, 15, 13, 11, 9, 7, 5, 3, 1, 14, 12, 10, 8, 6, 4, 2, 0); - //printf("%02x ", data_byte); switch (m_diskseq_cmd) { case 4: // Read Track @@ -2003,7 +2897,6 @@ void dpb7000_state::fdd_index_callback(floppy_image_device *floppy, int state) { curr_bit = -1; m_fdd_side = 2; - //printf("\nThe whole world has betrayed me!\n"); } else if (m_fdd_side == 0 && m_diskbuf_data_count == 0) { @@ -2011,13 +2904,11 @@ void dpb7000_state::fdd_index_callback(floppy_image_device *floppy, int state) m_floppy->ss_w(1); m_fdd_side++; m_diskbuf_data_count = 0x2400; - //printf("\nCatch you on the flip side!\n"); } else if (m_fdd_side == 1 && m_diskbuf_data_count == 0) { curr_bit = -1; m_fdd_side++; - //printf("\nYou're my favorite customer.\n"); } break; case 0: // Read Track to Buffer RAM @@ -2042,14 +2933,12 @@ void dpb7000_state::fdd_index_callback(floppy_image_device *floppy, int state) curr_bit = -1; m_floppy->ss_w(1); m_fdd_side++; - //printf("\nCatch you on the flip side!\n"); } else if(m_diskbuf_ram_addr >= 0x4B00 && m_fdd_side == 1) { // If we've read the side 1 portion of the cylinder, yield out, we're done curr_bit = -1; m_fdd_side++; - //printf("\nYou're my favorite customer.\n"); } break; } @@ -2058,7 +2947,6 @@ void dpb7000_state::fdd_index_callback(floppy_image_device *floppy, int state) } } } while (curr_bit != -1); - //printf("\n"); } if (m_fdd_side == 2) @@ -2068,6 +2956,35 @@ void dpb7000_state::fdd_index_callback(floppy_image_device *floppy, int state) } } +void dpb7000_state::seek_fdd_to_cylinder() +{ + uint16_t floppy_cyl = (uint16_t)m_floppy->get_cyl(); + if (floppy_cyl != m_diskseq_cyl_from_cpu && m_diskseq_cyl_from_cpu < 78 && m_floppy != nullptr) + { + if (m_diskseq_cyl_from_cpu < floppy_cyl) + { + m_floppy->dir_w(1); + for (uint16_t i = m_diskseq_cyl_from_cpu; i < floppy_cyl; i++) + { + m_floppy->stp_w(1); + m_floppy->stp_w(0); + m_floppy->stp_w(1); + } + } + else + { + m_floppy->dir_w(0); + for (uint16_t i = floppy_cyl; i < m_diskseq_cyl_from_cpu; i++) + { + m_floppy->stp_w(1); + m_floppy->stp_w(0); + m_floppy->stp_w(1); + } + } + LOGMASKED(LOG_FDD, "%s: New floppy cylinder: %04x\n", machine().describe_context(), floppy_cyl); + } +} + void dpb7000_state::fddcpu_p1_w(uint8_t data) { LOGMASKED(LOG_FDC_PORT, "%s: Floppy CPU Port 1 Write: %02x\n", machine().describe_context(), data); @@ -2115,9 +3032,14 @@ void dpb7000_state::fddcpu_p1_w(uint8_t data) // C5 D READY if (BIT(m_fdd_port1, 7)) - m_diskseq_status_out &= ~(1 << 3); + { + m_diskseq_status &= ~(1 << 3); + m_diskseq_status |= 0x04; + } else - m_diskseq_status_out |= (1 << 3); + { + m_diskseq_status |= (1 << 3); + } } void dpb7000_state::fddcpu_p2_w(uint8_t data) @@ -2218,19 +3140,73 @@ READ_LINE_MEMBER(dpb7000_state::keyboard_t1_r) void dpb7000_state::tds_dac_w(uint8_t data) { - LOGMASKED(LOG_TDS, "%s: TDS DAC Write: %02x\n", machine().describe_context(), data); - m_tds_dac_value = data; + m_tds_dac_value = ~data; + uint16_t offset = 0x67 * m_tds_dac_value; + m_tds_dac_offset = (uint8_t)(offset >> 8); + m_tds_dac_percent = std::clamp(m_tds_dac_value / 255.0f, 0.0f, 1.0f); + LOGMASKED(LOG_TDS, "%s: TDS DAC Write: %02x (%f)\n", machine().describe_context(), data, m_tds_dac_percent); +} + +TIMER_CALLBACK_MEMBER(dpb7000_state::tds_press_tick) +{ + m_tds_in_proximity = !m_pen_prox->read(); + + switch (m_tds_press_state) + { + case STATE_IDLE: + if (m_tds_in_proximity) + { + m_tds_press_state = STATE_PRESS_IN; + m_tds_pressure_shift = 6; + } + break; + case STATE_PRESS_IN: + if (!m_tds_in_proximity) + m_tds_press_state = STATE_PRESS_OUT; + else if (m_tds_pressure_shift > 0) + m_tds_pressure_shift--; + else + m_tds_press_state = STATE_PRESSED; + break; + case STATE_PRESSED: + if (!m_tds_in_proximity) + m_tds_press_state = STATE_PRESS_OUT; + break; + case STATE_PRESS_OUT: + if (m_tds_in_proximity) + m_tds_press_state = STATE_PRESS_IN; + else if (m_tds_pressure_shift < 6) + m_tds_pressure_shift++; + else + m_tds_press_state = STATE_IDLE; + break; + } +} + +TIMER_CALLBACK_MEMBER(dpb7000_state::tds_adc_tick) +{ + m_tds_adc_busy = false; + + uint16_t value = m_tds_dac_offset; + if (m_tds_press_state != STATE_IDLE) + { + value += (m_pen_press->read() >> m_tds_pressure_shift); + } + m_tds_adc_value = (value >= 0xf8 ? 0xf7 : (uint8_t)value); } void dpb7000_state::tds_convert_w(uint8_t data) { - LOGMASKED(LOG_TDS, "%s: TDS ADC Convert Start\n", machine().describe_context()); - m_tds_adc_value = m_tds_dac_value; + LOGMASKED(LOG_TDS, "%s: TDS ADC Convert Start: %02x\n", machine().describe_context(), data); + + m_tds_adc_busy = true; + m_tds_adc_value = 0x80; + m_tds_adc_timer->adjust(attotime::from_ticks(8, 120000)); } uint8_t dpb7000_state::tds_adc_r() { - LOGMASKED(LOG_TDS, "%s: TDS ADC Read: %02x\n", machine().describe_context(), m_tds_adc_value); + LOGMASKED(LOG_TDS, "%s: TDS ADC Read: %02x (DAC value %02x)\n", machine().describe_context(), m_tds_adc_value, m_tds_dac_value); return m_tds_adc_value; } @@ -2243,7 +3219,16 @@ uint8_t dpb7000_state::tds_pen_switches_r() TIMER_CALLBACK_MEMBER(dpb7000_state::tablet_tx_tick) { - m_tds_duart->rx_b_w(m_tablet_tx_bit); + //m_tds_duart->rx_b_w(m_tablet_tx_bit); + if (!m_tablet_hle_tx_bits.empty()) + { + m_tds_duart->rx_b_w(m_tablet_hle_tx_bits[0]); + m_tablet_hle_tx_bits.pop_front(); + } + else + { + m_tds_duart->rx_b_w(1); + } } WRITE_LINE_MEMBER(dpb7000_state::duart_b_w) @@ -2253,8 +3238,8 @@ WRITE_LINE_MEMBER(dpb7000_state::duart_b_w) uint8_t dpb7000_state::tds_p1_r() { - const uint8_t latched = m_tds_p1_data & 0x82; - const uint8_t adc_not_busy = (1 << 5); + const uint8_t latched = m_tds_p1_data & 0x80; + const uint8_t adc_not_busy = m_tds_adc_busy ? 0x00 : 0x20; uint8_t data = m_tds_dips->read() | adc_not_busy | latched; LOGMASKED(LOG_TDS, "%s: TDS Port 1 Read, %02x\n", machine().describe_context(), data); return data; @@ -2267,6 +3252,18 @@ uint8_t dpb7000_state::tds_p2_r() return data; } +uint8_t dpb7000_state::tds_p3_r() +{ + LOGMASKED(LOG_TDS, "%s: TDS Port 3 Read, %02x\n", machine().describe_context(), 0); + return 0; +} + +uint8_t dpb7000_state::tds_p4_r() +{ + LOGMASKED(LOG_TDS, "%s: TDS Port 4 Read, %02x\n", machine().describe_context(), 0); + return 0; +} + void dpb7000_state::tds_p1_w(uint8_t data) { LOGMASKED(LOG_TDS, "%s: TDS Port 1 Write = %02x\n", machine().describe_context(), data); @@ -2284,14 +3281,43 @@ void dpb7000_state::tds_p2_w(uint8_t data) LOGMASKED(LOG_TDS, "%s: TDS Port 2 Write = %02x\n", machine().describe_context(), data); } -INPUT_CHANGED_MEMBER(dpb7000_state::pen_prox_changed) +/*INPUT_CHANGED_MEMBER(dpb7000_state::pen_prox_changed) { - m_tablet_pen_in_proximity = newval ? false : true; - if (m_tablet_pen_in_proximity) + m_tds_in_proximity = newval ? false : true; + if (m_tds_in_proximity) { LOGMASKED(LOG_TABLET, "Triggering IRQ due to proximity\n"); m_tablet_cpu->set_input_line(INPUT_LINE_IRQ1, ASSERT_LINE); } +}*/ + +TIMER_CALLBACK_MEMBER(dpb7000_state::tablet_hle_tick) +{ + if (m_tds_press_state != STATE_IDLE || (m_pen_switches->read() == 1)) + { + m_tablet_pen_x = m_pen_x->read(); + m_tablet_pen_y = 4799 - m_pen_y->read(); + m_tablet_pen_switches = m_pen_switches->read(); + uint8_t data[5] = + { + (uint8_t)(0x40 | (BIT(m_tablet_pen_switches, 1) << 2) | (BIT(m_tablet_pen_y, 12) << 1) | BIT(m_tablet_pen_x, 12)), + (uint8_t)(m_tablet_pen_x & 0x003f), + (uint8_t)((m_tablet_pen_x & 0x0fc0) >> 6), + (uint8_t)(m_tablet_pen_y & 0x003f), + (uint8_t)((m_tablet_pen_y & 0x0fc0) >> 6) + }; + + for (int i = 0; i < 5; i++) + { + data[i] |= (population_count_32(data[i]) & 1) ? 0x80 : 0x00; + m_tablet_hle_tx_bits.push_back(0); + for (int bit = 0; bit < 8; bit++) + { + m_tablet_hle_tx_bits.push_back(BIT(data[i], bit)); + } + m_tablet_hle_tx_bits.push_back(1); + } + } } uint8_t dpb7000_state::tablet_p2_r(offs_t offset, uint8_t mem_mask) @@ -2323,7 +3349,7 @@ void dpb7000_state::tablet_p2_w(offs_t offset, uint8_t data, uint8_t mem_mask) LOGMASKED(LOG_TABLET, "Tablet DRQ: %d\n", m_tablet_drq); LOGMASKED(LOG_TABLET, "Clearing tablet CPU IRQ\n"); m_tablet_cpu->set_input_line(INPUT_LINE_IRQ1, CLEAR_LINE); - if (old_drq && !m_tablet_drq && m_tablet_pen_in_proximity) // DRQ transition to low + if (old_drq && !m_tablet_drq && m_tds_in_proximity) // DRQ transition to low { if (m_tablet_state == 0) // We're idle { @@ -2336,7 +3362,7 @@ void dpb7000_state::tablet_p2_w(offs_t offset, uint8_t data, uint8_t mem_mask) { if (m_tablet_state == 1) { - m_tablet_irq_timer->adjust(attotime::from_ticks(temp_pen_reads[3 - m_tablet_mux], 1200000), 1); + m_tablet_irq_timer->adjust(attotime::from_ticks(1, 1200000), 1); LOGMASKED(LOG_TABLET, "Setting up IRQ timer for read (continuous)\n"); } } @@ -2387,8 +3413,7 @@ void dpb7000_state::tablet_p3_w(offs_t offset, uint8_t data, uint8_t mem_mask) uint8_t dpb7000_state::tablet_rdh_r() { - //m_tablet_counter_latch = temp_pen_reads[3 - m_tablet_mux]; - uint8_t data = /*((~m_pen_switches->read() & 0x0f) << 4) |*/ (m_tablet_counter_latch >> 8); + uint8_t data = (m_tablet_counter_latch >> 8); LOGMASKED(LOG_TABLET, "%s: Tablet RDH Read (Mux %d): %02x\n", machine().describe_context(), m_tablet_mux, data); return data; } @@ -2398,38 +3423,229 @@ uint8_t dpb7000_state::tablet_rdl_r() //if (m_tablet_mux == 3) //m_tablet_state = 0; - m_tablet_counter_latch = rand() & 0xfff;//temp_pen_reads[m_tablet_mux]; + m_tablet_counter_latch = rand() & 0xfff; LOGMASKED(LOG_TABLET, "%s: Random latch: %04x\n", machine().describe_context(), m_tablet_counter_latch); uint8_t data = (uint8_t)m_tablet_counter_latch; LOGMASKED(LOG_TABLET, "%s: Tablet RDL Read (Mux %d): %02x\n", machine().describe_context(), m_tablet_mux, data); return data; } -template -uint32_t dpb7000_state::store_screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +uint32_t dpb7000_state::combined_screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - for (int py = 0; py < 768; py++) + const uint16_t upper_flag_addr = (uint16_t)((m_output_cpflags & 3) << 8); + + // TODO: Implement the Store Address Card in a more accurate manner, and implement framestore scan-out and flag handling accordingly. + int32_t y_addr[2] = { m_rvscr[0], m_rvscr[1] }; + int32_t dest_y = 0; + uint8_t matte_chr[2][2] = { { m_matte_u[0], m_matte_v[0] }, { m_matte_u[1], m_matte_v[1] } }; + bool seen_rvr = false; + bool started_scanout = false; + for (int32_t y = 0; y < 625; y++) { - const uint8_t *src_lum = &m_framestore_lum[StoreNum][py * 800]; - const uint8_t *src_chr = &m_framestore_chr[StoreNum][py * 800]; - uint32_t *dst = &bitmap.pix(py); - for (int px = 0; px < 800; px++) + const uint8_t vlines = m_output_vlines[y + 0x18f] & 0x0f; + + const uint8_t hlines = m_output_hlines[0xa0 + 70] & 0x0f; + const uint16_t flag_addr = (hlines & 0x0f) | ((vlines & 0x0f) << 4); + const uint8_t hflags = m_output_hflags[flag_addr | upper_flag_addr] & 0x0f; + const bool palette = BIT(hflags, 3); + + if (!BIT(hflags, 1)) + { + seen_rvr = true; + if (palette) + { + y_addr[0] = 0; + y_addr[1] = 0; + } + else + { + y_addr[0] = m_rvscr[0]; + y_addr[1] = m_rvscr[1]; + } + } + else if (!started_scanout && seen_rvr) + { + started_scanout = true; + dest_y = 0; + } + + // TODO: Enabling the blanking PAL causes strangeness when bringing up either the menu or the palette. + // Most likely scenario is that assuming a horizontal coordinate of 0 coming into the PAL puts us in a blanking region. + //const bool blank_1_q = BIT(m_storeaddr_pal_blank[((y_addr[0] << 3) & 0x1800) | ((y_addr[0] << 2) & 0x3f0)], 0); + //const bool blank_2_q = BIT(m_storeaddr_pal_blank[((y_addr[1] << 3) & 0x1800) | ((y_addr[1] << 2) & 0x3f0)], 0); + const bool blank_1_q = true; + const bool blank_2_q = true; + const bool use_store1_matte = !palette && (!blank_1_q || m_select_matte[0]); + const bool use_store2_matte = !palette && (!blank_2_q || m_select_matte[1]); + const bool use_ext_store1_matte = !(blank_1_q && !BIT(m_ext_store_flags, 0)); + const bool use_ext_store2_matte = !(blank_2_q && !BIT(m_ext_store_flags, 1)); + const bool invert_a = palette ? BIT(~m_ext_store_flags, 3) : BIT(m_ext_store_flags, 2); + const bool invert_b = !invert_a; + const uint8_t ext_src_invert = BIT(m_ext_store_flags, 4) ? 0xff : 0x00; + const uint8_t ext_a_mask = (invert_a ? 0xff : 0x00); + const uint8_t ext_b_mask = (invert_b ? 0xff : 0x00); + + const int32_t y_line1 = y_addr[0] * 800; + const int32_t y_line2 = y_addr[1] * 800; + + uint32_t *d = &bitmap.pix(dest_y); + int32_t x_addr[2] = { m_rhscr[0] & ~1, m_rhscr[1] & ~1 }; + for (int32_t x = 0; x < 800; x++, x_addr[0] = (x_addr[0] + 1) % 800, x_addr[1] = (x_addr[1] + 1) % 800) + { + const uint8_t uv_sel1 = x_addr[0] & 1; + const uint8_t uv_sel2 = x_addr[1] & 1; + + const uint32_t pix_idx1 = y_line1 + x_addr[0]; + const uint32_t pix_idx2 = y_line2 + x_addr[1]; + + const uint16_t lum1 = use_store1_matte ? m_matte_y[0] : m_framestore_lum[0][pix_idx1]; + const uint16_t chr1 = use_store1_matte ? matte_chr[0][uv_sel1] : m_framestore_chr[0][pix_idx1]; + const uint16_t ext1 = use_ext_store1_matte ? m_matte_ext[0] : (m_framestore_ext[0][pix_idx1] ^ ext_src_invert); + + const uint16_t lum2 = use_store2_matte ? m_matte_y[1] : m_framestore_lum[1][pix_idx2]; + const uint16_t chr2 = use_store2_matte ? matte_chr[0][uv_sel2] : m_framestore_chr[1][pix_idx2]; + const uint16_t ext2 = use_ext_store2_matte ? m_matte_ext[1] : (m_framestore_ext[1][pix_idx2] ^ ext_src_invert); + + const uint8_t ext_product = (uint8_t)(((ext1 * ext2) + 0x0080) >> 8); + const uint8_t ext_a = ext_product ^ ext_a_mask; + const uint8_t ext_b = ext_product ^ ext_b_mask; + + const uint16_t lum1_product = ((lum1 * ext_a) + 0x0080) >> 8; + const uint16_t lum2_product = ((lum2 * ext_b) + 0x0080) >> 8; + const uint16_t chr1_product = ((chr1 * ext_a) + 0x0080) >> 8; + const uint16_t chr2_product = ((chr2 * ext_b) + 0x0080) >> 8; + + const uint8_t lum_sum = (uint8_t)std::min(lum1_product + lum2_product, 255); + const uint8_t chr_sum = (uint8_t)std::min(chr1_product + chr2_product, 255); + + *d++ = 0xff000000 | (lum_sum << 8) | chr_sum; + } + + if (BIT(hflags, 1)) + { + dest_y++; + + y_addr[0]++; + if (y_addr[0] == 4096) + y_addr[0] = 0; + + y_addr[1]++; + if (y_addr[1] == 4096) + y_addr[1] = 0; + } + } + + const uint32_t cursor_rgb = m_yuv_lut[(m_cursor_u << 16) | (m_cursor_v << 8) | m_cursor_y]; + uint16_t cursor_origin_y_counter = m_cursor_origin_y; + uint16_t cursor_y_size = m_cursor_size_y; + uint16_t cursor_y_index = 0; + + for (int32_t dst_y = 0; dst_y < 625; dst_y++) + { + uint16_t cursor_origin_x_counter = m_cursor_origin_x; + uint16_t cursor_x_size = m_cursor_size_x; + uint16_t cursor_x_index = 0; + + uint32_t *d = &bitmap.pix(dst_y); + for (int32_t x = 0; x < 800; x += 2) + { + const uint32_t u = (d[x] << 16) & 0xff0000; + const uint32_t v = (d[x | 1] << 8) & 0x00ff00; + const uint32_t y0 = (d[x] >> 8) & 0x0000ff; + const uint32_t y1 = (d[x | 1] >> 8) & 0x0000ff; + + uint32_t combined[2] = { m_yuv_lut[u | v | y0], m_yuv_lut[u | v | y1] }; + for (int32_t h = 0; h < 2; h++) + { + if (m_output_csflags) + { + const bool cursor_in_window = (cursor_origin_x_counter == 0x1000 && cursor_origin_y_counter == 0x1000); + const bool cursor_enable = cursor_in_window && (cursor_x_index < 0x20 && cursor_y_index < 0x20); + if (cursor_enable) + { + const uint16_t cursor_addr_x = cursor_x_index ^ 0x10; + const uint16_t cursor_addr_y = cursor_y_index ^ 0x10; + const uint16_t cursor_addr = (cursor_addr_y << 5) | cursor_addr_x; + + const uint8_t cursor_data = m_output_cursor[cursor_addr]; + + bool cursor_bit = true; + bool cursor_colored = true; + switch (m_output_csflags) + { + case 1: + cursor_bit = BIT(cursor_data, 0); + cursor_colored = BIT(cursor_data, 1); + break; + case 2: + cursor_bit = BIT(cursor_data, 2); + cursor_colored = BIT(cursor_data, 3); + break; + case 3: + cursor_bit = ((cursor_addr_x & cursor_addr_y) & 0x10) ? 0 : 1; + break; + default: + // Cursor inactive + break; + } + + if (!cursor_bit) + { + combined[h] = cursor_colored ? cursor_rgb : 0xff000000; + } + } + + if (cursor_origin_x_counter < 0x1000) + { + cursor_origin_x_counter++; + } + else if (cursor_x_size < 0x1000) + { + cursor_x_size++; + cursor_x_index++; + } + else if (cursor_x_index < 0x20) + { + cursor_x_index++; + } + } + + d[x + h] = combined[h]; + } + } + + if (m_output_csflags) { - const uint32_t u = *src_chr++ << 16; - const uint32_t v = *src_chr++ << 8; - *dst++ = m_yuv_lut[u | v | *src_lum++]; - *dst++ = m_yuv_lut[u | v | *src_lum++]; + if (cursor_origin_y_counter < 0x1000) + { + cursor_origin_y_counter++; + } + else if (cursor_y_size < 0x1000) + { + cursor_y_size++; + cursor_y_index++; + } + else if (cursor_y_index < 0x20) + { + cursor_y_index++; + } } } - if (StoreNum == 0) + return 0; +} + +template +uint32_t dpb7000_state::store_debug_screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + if (0) { - for (int py = 512; py < 768; py++) + for (int py = 0; py < 768; py++) { - const uint8_t *src_lum = &m_brushstore_lum[(py - 512) * 256]; - const uint8_t *src_chr = &m_brushstore_chr[(py - 512) * 256]; + const uint8_t *src_lum = &m_framestore_lum[StoreNum][py * 800]; + const uint8_t *src_chr = &m_framestore_chr[StoreNum][py * 800]; uint32_t *dst = &bitmap.pix(py); - for (int px = 0; px < 256; px += 2) + for (int px = 0; px < 800; px += 2) { const uint32_t u = *src_chr++ << 16; const uint32_t v = *src_chr++ << 8; @@ -2441,6 +3657,50 @@ uint32_t dpb7000_state::store_screen_update(screen_device &screen, bitmap_rgb32 return 0; } +uint32_t dpb7000_state::stencil_debug_screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + if (0) + { + for (int py = 0; py < 768; py++) + { + const uint8_t *src_ext1 = &m_framestore_ext[0][py * 800]; + const uint8_t *src_ext2 = &m_framestore_ext[1][py * 800]; + uint32_t *dst = &bitmap.pix(py); + for (int px = 0; px < 800; px++, src_ext1++, src_ext2++) + { + const uint16_t h = (uint8_t)px >> 4; + const uint16_t pal_blank_addr = ((h << 12) & 0xe000) | ((py << 3) & 0x1800) | (BIT(h, 0) << 10) | ((py << 2) & 0x3f0) | ((h >> 4) & 0xf); + const uint8_t blank_val = m_storeaddr_pal_blank[pal_blank_addr]; + const uint32_t blank_color = ((blank_val & 3) != 3) ? 0x000000ff : 0; + *dst++ = 0xff000000 | (*src_ext1 << 16) | (*src_ext2 << 8) | blank_color; + } + } + } + return 0; +} + +uint32_t dpb7000_state::brush_debug_screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + if (0) + { + for (int y = 0; y < 256; y++) + { + const uint8_t *src_lum = &m_brushstore_lum[y * 256]; + const uint8_t *src_chr = &m_brushstore_chr[y * 256]; + const uint8_t *src_ext = &m_brushstore_ext[y * 256]; + uint32_t *dst_lc = &bitmap.pix(y); + uint32_t *dst_ext = &bitmap.pix(y + 256); + for (int x = 0; x < 256; x++) + { + dst_lc[x] = (0xff << 24) | (src_lum[x] << 16) | (src_lum[x] << 8) | src_lum[x]; + dst_lc[x + 256] = (0xff << 24) | (src_chr[x] << 16) | (src_chr[x] << 8) | src_chr[x]; + dst_ext[x] = (0xff << 24) | (src_ext[x] << 16) | (src_ext[x] << 8) | src_ext[x]; + } + } + } + return 0; +} + static void dpb7000_floppies(device_slot_interface &device) { device.option_add("8", FLOPPY_8_DSDD); @@ -2486,23 +3746,44 @@ void dpb7000_state::dpb7000(machine_config &config) m_brg->ft_handler().append(m_acia[2], FUNC(acia6850_device::write_txc)); m_brg->ft_handler().append(m_acia[2], FUNC(acia6850_device::write_rxc)); + screen_device &combined_screen(SCREEN(config, "combined_screen", SCREEN_TYPE_RASTER)); + combined_screen.set_refresh_hz(50); + combined_screen.set_size(800, 625); + combined_screen.set_visarea(0, 709, 0, 574); + combined_screen.set_screen_update(FUNC(dpb7000_state::combined_screen_update)); + screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); - screen.set_refresh_hz(60); + screen.set_refresh_hz(50); screen.set_size(696, 276); screen.set_visarea(56, 695, 36, 275); screen.set_screen_update("crtc", FUNC(mc6845_device::screen_update)); - screen_device &store_screen1(SCREEN(config, "store_screen1", SCREEN_TYPE_RASTER)); - store_screen1.set_refresh_hz(60); - store_screen1.set_size(800, 768); - store_screen1.set_visarea(0, 799, 0, 767); - store_screen1.set_screen_update(FUNC(dpb7000_state::store_screen_update<0>)); - - screen_device &store_screen2(SCREEN(config, "store_screen2", SCREEN_TYPE_RASTER)); - store_screen2.set_refresh_hz(60); - store_screen2.set_size(800, 768); - store_screen2.set_visarea(0, 799, 0, 767); - store_screen2.set_screen_update(FUNC(dpb7000_state::store_screen_update<1>)); + if (0) + { + screen_device &store_screen1(SCREEN(config, "store_screen1", SCREEN_TYPE_RASTER)); + store_screen1.set_refresh_hz(50); + store_screen1.set_size(800, 768); + store_screen1.set_visarea(0, 799, 0, 767); + store_screen1.set_screen_update(FUNC(dpb7000_state::store_debug_screen_update<0>)); + + screen_device &store_screen2(SCREEN(config, "store_screen2", SCREEN_TYPE_RASTER)); + store_screen2.set_refresh_hz(50); + store_screen2.set_size(800, 768); + store_screen2.set_visarea(0, 799, 0, 767); + store_screen2.set_screen_update(FUNC(dpb7000_state::store_debug_screen_update<1>)); + + screen_device &ext_screen(SCREEN(config, "ext_screen", SCREEN_TYPE_RASTER)); + ext_screen.set_refresh_hz(50); + ext_screen.set_size(800, 768); + ext_screen.set_visarea(0, 799, 0, 767); + ext_screen.set_screen_update(FUNC(dpb7000_state::stencil_debug_screen_update)); + + screen_device &brush_screen(SCREEN(config, "brush_screen", SCREEN_TYPE_RASTER)); + brush_screen.set_refresh_hz(50); + brush_screen.set_size(512, 512); + brush_screen.set_visarea(0, 511, 0, 511); + brush_screen.set_screen_update(FUNC(dpb7000_state::brush_debug_screen_update)); + } PALETTE(config, m_palette, palette_device::MONOCHROME); @@ -2515,13 +3796,6 @@ void dpb7000_state::dpb7000(machine_config &config) m_crtc->set_update_row_callback(FUNC(dpb7000_state::crtc_update_row)); m_crtc->set_on_update_addr_change_callback(FUNC(dpb7000_state::crtc_addr_changed)); - // Disc Sequencer Card - AM2910(config, m_diskseq, 0); // We drive the clock manually from the driver - m_diskseq->ci_w(1); - m_diskseq->rld_w(1); - m_diskseq->ccen_w(0); - m_diskseq->y().set(FUNC(dpb7000_state::diskseq_y_w)); - // Floppy Disc Unit M6803(config, m_fddcpu, 4.9152_MHz_XTAL); m_fddcpu->set_addrmap(AS_PROGRAM, &dpb7000_state::fddcpu_map); @@ -2536,11 +3810,8 @@ void dpb7000_state::dpb7000(machine_config &config) config.set_perfect_quantum(m_fddcpu); - // Size Card - AM2901B(config, m_size_yl); - AM2901B(config, m_size_yh); - AM2901B(config, m_size_xl); - AM2901B(config, m_size_xh); + // Hard Disk + HARDDISK(config, "hdd", 0); // Keyboard I8039(config, m_keybcpu, 4.608_MHz_XTAL); @@ -2559,6 +3830,8 @@ void dpb7000_state::dpb7000(machine_config &config) m_tds_cpu->out_p1_cb().set(FUNC(dpb7000_state::tds_p1_w)); m_tds_cpu->in_p2_cb().set(FUNC(dpb7000_state::tds_p2_r)); m_tds_cpu->out_p2_cb().set(FUNC(dpb7000_state::tds_p2_w)); + m_tds_cpu->in_p3_cb().set(FUNC(dpb7000_state::tds_p3_r)); + m_tds_cpu->in_p4_cb().set(FUNC(dpb7000_state::tds_p4_r)); SCN2681(config, m_tds_duart, 3.6864_MHz_XTAL); m_tds_duart->irq_cb().set_inputline(m_tds_cpu, M6803_IRQ_LINE); @@ -2575,25 +3848,38 @@ void dpb7000_state::dpb7000(machine_config &config) m_tablet_cpu->p3_out_cb().set(FUNC(dpb7000_state::tablet_p3_w)); } - ROM_START( dpb7000 ) - ROM_REGION16_BE(0x80000, "monitor", 0) - ROM_LOAD16_BYTE("01616a-nad-4af2.bin", 0x00001, 0x8000, CRC(a42eace6) SHA1(78c629a8afb48a95fc0a86ca762cc5b84bd9929b)) - ROM_LOAD16_BYTE("01616a-ncd-58de.bin", 0x00000, 0x8000, CRC(f70fff2a) SHA1(a6f85d086a0c53d156eeeb157184ebcad4adecb3)) - ROM_LOAD16_BYTE("01616a-mad-f512.bin", 0x10001, 0x8000, CRC(4c3e39f6) SHA1(443095c56481fbcadd4dcec1757d889c8f78805d)) - ROM_LOAD16_BYTE("01616a-mcd-91f2.bin", 0x10000, 0x8000, CRC(4b6b6eb3) SHA1(1bef443d78197d33e44c708ead9604020881f67f)) - ROM_LOAD16_BYTE("01616a-lad-0059.bin", 0x20001, 0x8000, CRC(0daf670d) SHA1(2342a43054ed141de298a1c1a6867949297bb52a)) - ROM_LOAD16_BYTE("01616a-lcd-5639.bin", 0x20000, 0x8000, CRC(c8977d3f) SHA1(4ee9f3a883400b4771e6ae33c6e4edcd5c0b49e7)) - ROM_LOAD16_BYTE("01616a-kad-1d9b.bin", 0x30001, 0x8000, CRC(bda7e309) SHA1(377edf2675a6736fe7ec775894858967b0e9247e)) - ROM_LOAD16_BYTE("01616a-kcd-e51c.bin", 0x30000, 0x8000, CRC(aa05a5cc) SHA1(85dce335a72643f7640524b18cfe480a3c299f23)) - ROM_LOAD16_BYTE("01616a-jad-47a8.bin", 0x40001, 0x8000, CRC(60fff4c9) SHA1(ba60281c0dd8627dffe07e7ea66f4eb688e74001)) - ROM_LOAD16_BYTE("01616a-jcd-7825.bin", 0x40000, 0x8000, CRC(bb258ede) SHA1(ab8042391cd361bcd874b2f9d8fcaf20d4b2ebe7)) - ROM_LOAD16_BYTE("01616a-iad-73a8.bin", 0x50001, 0x8000, CRC(98709fd2) SHA1(bd0f4689600e9fc49dbd8f2f326e18f8d602825e)) - ROM_LOAD16_BYTE("01616a-icd-0562.bin", 0x50000, 0x8000, CRC(bab5274e) SHA1(3e51977da3dfe8fda089b9d2c3199acb4fed3212)) - ROM_LOAD16_BYTE("01616a-had-d6fa.bin", 0x60001, 0x8000, CRC(70d791c5) SHA1(c281e4f27404e58ad5a80d6de1c5583cd9f3fe0e)) - ROM_LOAD16_BYTE("01616a-hcd-9c0e.bin", 0x60000, 0x8000, CRC(938cb614) SHA1(ea7ea8a13e0ab1497691bab53090296ba51d271f)) - ROM_LOAD16_BYTE("01616a-gcd-3ab8.bin", 0x70001, 0x8000, CRC(e9c21438) SHA1(1784ab2de1bb6023565b2e27872a0fcda25e1b1f)) - ROM_LOAD16_BYTE("01616a-gad-397d.bin", 0x70000, 0x8000, CRC(0b95f9ed) SHA1(77126ee6c1f3dcdb8aa669ab74ff112e3f01918a)) + ROM_REGION16_BE(0xa0000, "monitor", 0) + ROM_SYSTEM_BIOS( 0, "v406", "V4.06A" ) + ROMX_LOAD("01616a-nad-4af2.bin", 0x00001, 0x8000, CRC(a42eace6) SHA1(78c629a8afb48a95fc0a86ca762cc5b84bd9929b), ROM_BIOS(0) | ROM_SKIP(1)) + ROMX_LOAD("01616a-ncd-58de.bin", 0x00000, 0x8000, CRC(f70fff2a) SHA1(a6f85d086a0c53d156eeeb157184ebcad4adecb3), ROM_BIOS(0) | ROM_SKIP(1)) + ROMX_LOAD("01616a-mad-f512.bin", 0x10001, 0x8000, CRC(4c3e39f6) SHA1(443095c56481fbcadd4dcec1757d889c8f78805d), ROM_BIOS(0) | ROM_SKIP(1)) + ROMX_LOAD("01616a-mcd-91f2.bin", 0x10000, 0x8000, CRC(4b6b6eb3) SHA1(1bef443d78197d33e44c708ead9604020881f67f), ROM_BIOS(0) | ROM_SKIP(1)) + ROMX_LOAD("01616a-lad-0059.bin", 0x20001, 0x8000, CRC(0daf670d) SHA1(2342a43054ed141de298a1c1a6867949297bb52a), ROM_BIOS(0) | ROM_SKIP(1)) + ROMX_LOAD("01616a-lcd-5639.bin", 0x20000, 0x8000, CRC(c8977d3f) SHA1(4ee9f3a883400b4771e6ae33c6e4edcd5c0b49e7), ROM_BIOS(0) | ROM_SKIP(1)) + ROMX_LOAD("01616a-kad-1d9b.bin", 0x30001, 0x8000, CRC(bda7e309) SHA1(377edf2675a6736fe7ec775894858967b0e9247e), ROM_BIOS(0) | ROM_SKIP(1)) + ROMX_LOAD("01616a-kcd-e51c.bin", 0x30000, 0x8000, CRC(aa05a5cc) SHA1(85dce335a72643f7640524b18cfe480a3c299f23), ROM_BIOS(0) | ROM_SKIP(1)) + ROMX_LOAD("01616a-jad-47a8.bin", 0x40001, 0x8000, CRC(60fff4c9) SHA1(ba60281c0dd8627dffe07e7ea66f4eb688e74001), ROM_BIOS(0) | ROM_SKIP(1)) + ROMX_LOAD("01616a-jcd-7825.bin", 0x40000, 0x8000, CRC(bb258ede) SHA1(ab8042391cd361bcd874b2f9d8fcaf20d4b2ebe7), ROM_BIOS(0) | ROM_SKIP(1)) + ROMX_LOAD("01616a-iad-73a8.bin", 0x50001, 0x8000, CRC(98709fd2) SHA1(bd0f4689600e9fc49dbd8f2f326e18f8d602825e), ROM_BIOS(0) | ROM_SKIP(1)) + ROMX_LOAD("01616a-icd-0562.bin", 0x50000, 0x8000, CRC(bab5274e) SHA1(3e51977da3dfe8fda089b9d2c3199acb4fed3212), ROM_BIOS(0) | ROM_SKIP(1)) + ROMX_LOAD("01616a-had-d6fa.bin", 0x60001, 0x8000, CRC(70d791c5) SHA1(c281e4f27404e58ad5a80d6de1c5583cd9f3fe0e), ROM_BIOS(0) | ROM_SKIP(1)) + ROMX_LOAD("01616a-hcd-9c0e.bin", 0x60000, 0x8000, CRC(938cb614) SHA1(ea7ea8a13e0ab1497691bab53090296ba51d271f), ROM_BIOS(0) | ROM_SKIP(1)) + ROMX_LOAD("01616a-gad-397d.bin", 0x70001, 0x8000, CRC(0b95f9ed) SHA1(77126ee6c1f3dcdb8aa669ab74ff112e3f01918a), ROM_BIOS(0) | ROM_SKIP(1)) + ROMX_LOAD("01616a-gcd-3ab8.bin", 0x70000, 0x8000, CRC(e9c21438) SHA1(1784ab2de1bb6023565b2e27872a0fcda25e1b1f), ROM_BIOS(0) | ROM_SKIP(1)) + ROM_SYSTEM_BIOS( 1, "v411", "V4.11A" ) + ROMX_LOAD("01993c-naa-0608.bin", 0x00001, 0x10000, CRC(9e4cfd96) SHA1(faae2ba849d30c894d9f929bae371ae76e05bdac), ROM_BIOS(1) | ROM_SKIP(1)) + ROMX_LOAD("01993c-nca-3964.bin", 0x00000, 0x10000, CRC(04d75a15) SHA1(79f706296ba0c399b4e2d3acf947cae7706f9d63), ROM_BIOS(1) | ROM_SKIP(1)) + ROMX_LOAD("01993c-maa-fa58.bin", 0x20001, 0x10000, CRC(88dc8ee0) SHA1(a2f6b80022ddb5adf687b678c621c8f5db1f3575), ROM_BIOS(1) | ROM_SKIP(1)) + ROMX_LOAD("01993c-mca-b2b0.bin", 0x20000, 0x10000, CRC(16bf9db4) SHA1(a4696ee5a68b8a304c2433f16a6d57d7108f6406), ROM_BIOS(1) | ROM_SKIP(1)) + ROMX_LOAD("01993c-laa-6be3.bin", 0x40001, 0x10000, CRC(56e693cc) SHA1(b4f3e0f8b635fe2b3fa975ed57f966e8ade7fbb1), ROM_BIOS(1) | ROM_SKIP(1)) + ROMX_LOAD("01993c-lca-7c0d.bin", 0x40000, 0x10000, CRC(9540fa68) SHA1(79e46c4b6e86f6e53e3f5fea72e3be8c64de03af), ROM_BIOS(1) | ROM_SKIP(1)) + ROMX_LOAD("01993c-kaa-3b12.bin", 0x60001, 0x10000, CRC(41e2ec71) SHA1(37112f878b3db24b198e878f5dba90fcbb4175d2), ROM_BIOS(1) | ROM_SKIP(1)) + ROMX_LOAD("01993c-kca-f705.bin", 0x60000, 0x10000, CRC(00bfbd62) SHA1(17a5f2cbc91cabf1113c7d6e26124b67e5ece848), ROM_BIOS(1) | ROM_SKIP(1)) + ROMX_LOAD("01993c-jaa-3cc9.bin", 0x80001, 0x10000, CRC(9e477845) SHA1(b89e5d2b69a6043452a56685a1227df86c83a328), ROM_BIOS(1) | ROM_SKIP(1)) + ROMX_LOAD("01993c-jca-0b41.bin", 0x80000, 0x10000, CRC(58e8f302) SHA1(b37953046d81027b069b7a7a1834cd8c94fd9dca), ROM_BIOS(1) | ROM_SKIP(1)) + ROM_SYSTEM_BIOS( 2, "diags", "Diagnostics" ) + ROMX_LOAD("cat7000_diagnostic_rom_merged.bin", 0x00000, 0x20000, CRC(666767d6) SHA1(1dad9747321302bca7e03728c63034070f9ebf13), ROM_BIOS(2) ) ROM_REGION(0x1000, "vduchar", 0) ROM_LOAD("bw14char.ic1", 0x0000, 0x1000, BAD_DUMP CRC(f9dd68b5) SHA1(50132b759a6d84c22c387c39c0f57535cd380411)) @@ -2613,12 +3899,20 @@ ROM_START( dpb7000 ) ROM_REGION(0x800, "fddprom", 0) ROM_LOAD("17446a-gd-m2716.bin", 0x000, 0x800, CRC(a0be00ca) SHA1(48c4f8c07b9f6bc9b68698e1e326782e0b01e1b0)) - ROM_REGION(0x1200, "output_timing_proms", 0) - ROM_LOAD("pb-037-17418-bea.bin", 0x0000, 0x400, CRC(644e82a3) SHA1(d7634e03809abe2db924571c05821c1b2aca051b)) - ROM_LOAD("pb-037-17418-bga.bin", 0x0400, 0x400, CRC(3b2c3635) SHA1(2038d616dd7f65ba55497bd037b0ad69aaa801ed)) - ROM_LOAD("pb-037-17418-cda.bin", 0x0800, 0x400, CRC(a31f3793) SHA1(4e74e528088c155e2c2592fa937e4cabfe6324c8)) - ROM_LOAD("pb-037-17418-dfa.bin", 0x0c00, 0x400, CRC(ca2ec308) SHA1(4232f44ea5bd3fa240eaf7c14e4b925140f90a1e)) - ROM_LOAD("pb-037-17418-bfa.bin", 0x1000, 0x200, CRC(db84a171) SHA1(ed63f384928a017dafd694c7bcf99e315af6bd3c)) + ROM_REGION(0x400, "output_timing_cursor", 0) + ROM_LOAD("pb-037-17418-cda.bin", 0x000, 0x400, CRC(a31f3793) SHA1(4e74e528088c155e2c2592fa937e4cabfe6324c8)) + + ROM_REGION(0x400, "output_timing_hlines", 0) + ROM_LOAD("pb-037-17418-bga.bin", 0x000, 0x400, CRC(3b2c3635) SHA1(2038d616dd7f65ba55497bd037b0ad69aaa801ed)) + + ROM_REGION(0x400, "output_timing_hflags", 0) + ROM_LOAD("pb-037-17418-bea.bin", 0x000, 0x400, CRC(644e82a3) SHA1(d7634e03809abe2db924571c05821c1b2aca051b)) + + ROM_REGION(0x400, "output_timing_vlines", 0) + ROM_LOAD("pb-037-17418-dfa.bin", 0x000, 0x400, CRC(ca2ec308) SHA1(4232f44ea5bd3fa240eaf7c14e4b925140f90a1e)) + + ROM_REGION(0x200, "output_timing_vflags", 0) + ROM_LOAD("pb-037-17418-bfa.bin", 0x000, 0x100, CRC(a4486aac) SHA1(3834d550da3f1865b921807300a94612149f69d4)) ROM_REGION(0x800, "keyboard", 0) ROM_LOAD("etc2716 63b2.bin", 0x000, 0x800, CRC(04614a50) SHA1(e547458f2c9cf29cf52f02b8824b32e5e91807fd)) @@ -2629,8 +3923,11 @@ ROM_START( dpb7000 ) ROM_REGION(0x2000, "tablet", 0) ROM_LOAD("nmc27c64q.bin", 0x0000, 0x2000, CRC(a453928f) SHA1(f4a25298fb446f0046c6f9f3ce70e7169dcebd01)) + ROM_REGION(0x800, "brushaddr_pal", 0) + ROM_LOAD("pb-029-17419a-bea.bin", 0x000, 0x800, CRC(d30015c3) SHA1(fb5856df3ace452dfb1c1882b2adb6562e3a6800)) + ROM_REGION(0x200, "brushproc_prom", 0) - ROM_LOAD("pb-02c-17593-baa.bin", 0x000, 0x200, CRC(a74cc1f5) SHA1(3b789d5a29c70c93dec56f44be8c14b41915bdef)) + ROM_LOAD("pb-02c-17593-baa.bin", 0x000, 0x200, CRC(6e31339f) SHA1(72a92d97412be19c884c3b854f7d9831435391a5)) ROM_REGION16_BE(0x800, "brushproc_pal", 0) ROMX_LOAD("pb-02c-17593-hba.bin", 0x000, 0x800, CRC(76018e4f) SHA1(73d995e2e78410676061d45857756d5305a9984a), ROM_GROUPWORD) @@ -2664,6 +3961,26 @@ ROM_START( dpb7000 ) ROM_REGION(0x200, "size_prom_xl", 0) ROM_LOAD("pb-012-17428a-gca.bin", 0x000, 0x200, CRC(ec7d26f3) SHA1(8bdbec33218f903294c135554d61271fa18d1a8d)) + + ROM_REGION(0x10000, "storeaddr_pal_blank", 0) + ROM_LOAD("pb-032-17425b-igb.bin", 0x00000, 0x10000, CRC(cdd80590) SHA1(fecb64695b61e8ec740af1480240088d5447688d)) + + ROM_REGION(0x400, "storeaddr_prom_xlnib", 0) + ROM_LOAD("pb-032-17425b-bbb.bin", 0x000, 0x400, CRC(2051a6e4) SHA1(3bd8a9015e77b034a94fe072a9753649b76f9f69)) + + ROM_REGION(0x400, "storeaddr_prom_xmnib", 0) + ROM_LOAD("pb-032-17425b-bcb.bin", 0x000, 0x400, CRC(01aaa6f7) SHA1(e31bff0c68f74996368443bfb58a3524a838f270)) + + ROM_REGION(0x400, "storeaddr_prom_xhnib", 0) + ROM_LOAD("pb-032-17425b-bdb.bin", 0x000, 0x400, CRC(20e2fb9e) SHA1(c4c77ec02ab6d3a1a28edf5543e57235a64a9d8d)) + + ROM_REGION(0x400, "storeaddr_prom_protx", 0) + ROM_LOAD("pb-032-17425b-deb.bin", 0x000, 0x400, CRC(faeb44dd) SHA1(3eaf981245824332d216e97095bdc02ff04e4800)) + + ROM_REGION(0x400, "storeaddr_prom_proty", 0) + ROM_LOAD("pb-032-17425b-edb.bin", 0x000, 0x400, CRC(83585876) SHA1(7c244adcd365f7b2ec347255100fa3597857905c)) ROM_END +} // anonymous namespace + COMP( 1981, dpb7000, 0, 0, dpb7000, dpb7000, dpb7000_state, empty_init, "Quantel", "DPB-7000", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW ) -- cgit v1.2.3