// license:BSD-3-Clause // copyright-holders:Barry Rodewald /* * * FM-7 header file * */ #ifndef MAME_INCLUDES_FM7_H #define MAME_INCLUDES_FM7_H #pragma once #include "machine/buffer.h" #include "bus/centronics/ctronics.h" #include "imagedev/cassette.h" #include "imagedev/floppy.h" #include "sound/ay8910.h" #include "sound/beep.h" #include "sound/ymopn.h" #include "machine/wd_fdc.h" #include "machine/bankdev.h" #include "emupal.h" class fm7_state : public driver_device { public: fm7_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag), m_shared_ram(*this, "shared_ram"), m_a15_ram(*this, "a15_ram"), m_vectors(*this, "vectors"), m_maincpu(*this, "maincpu"), m_sub(*this, "sub"), m_cassette(*this, "cassette"), m_beeper(*this, "beeper"), m_psg(*this, "psg"), m_screen(*this, "screen"), m_centronics(*this, "centronics"), m_cent_data_out(*this, "cent_data_out"), m_fdc(*this, "fdc"), m_floppy0(*this, "fdc:0"), m_floppy1(*this, "fdc:1"), m_floppy(nullptr), m_rom_ptr(*this, "init"), m_btrom_ptr(*this, "boot"), m_basic_ptr(*this, "fbasic"), m_kanji(*this, "kanji1"), m_kb_ports(*this, "key%u", 1), m_keymod(*this, "key_modifiers"), m_joy1(*this, "joy1"), m_dsw(*this, "DSW"), m_palette(*this, "palette"), m_av_palette(*this, "av_palette") { } void fm16beta(machine_config &config); void fm8(machine_config &config); void fm7(machine_config &config); void init_fm7(); protected: // Interrupt flags enum : uint8_t { IRQ_FLAG_KEY = 0x01, IRQ_FLAG_PRINTER = 0x02, IRQ_FLAG_TIMER = 0x04, IRQ_FLAG_OTHER = 0x08, // the following are not read in port 0xfd03 IRQ_FLAG_MFD = 0x10, IRQ_FLAG_TXRDY = 0x20, IRQ_FLAG_RXRDY = 0x40, IRQ_FLAG_SYNDET = 0x80 }; // system types enum { SYS_FM7 = 1, SYS_FM77AV = 2, SYS_FM77AV40EX = 3, SYS_FM11 = 4, SYS_FM16 = 5 }; // keyboard scancode formats enum { KEY_MODE_FM7 = 0, // FM-7 ASCII type code KEY_MODE_FM16B = 1, // FM-16B (FM-77AV and later only) KEY_MODE_SCAN = 2 // Scancode Make/Break (PC-like) }; struct fm7_video_t { uint8_t sub_busy = 0U; uint8_t sub_halt = 0U; uint8_t sub_reset = 0U; // high if reset caused by subrom change uint8_t attn_irq = 0U; uint8_t vram_access = 0U; // VRAM access flag uint8_t crt_enable = 0U; uint16_t vram_offset = 0U; uint16_t vram_offset2 = 0U; uint8_t fm7_pal[8]{}; uint16_t fm77av_pal_selected = 0U; uint8_t subrom = 0U; // currently active sub CPU ROM (AV only) uint8_t cgrom = 0U; // currently active CGROM (AV only) uint8_t modestatus = 0U; uint8_t multi_page = 0U; uint8_t fine_offset = 0U; uint8_t nmi_mask = 0U; uint8_t active_video_page = 0U; uint8_t display_video_page = 0U; uint8_t vsync_flag = 0U; }; struct fm7_alu_t { uint8_t command = 0U; uint8_t lcolour = 0U; uint8_t mask = 0U; uint8_t compare_data = 0U; uint8_t compare[8]{}; uint8_t bank_disable = 0U; uint8_t tilepaint_b = 0U; uint8_t tilepaint_r = 0U; uint8_t tilepaint_g = 0U; uint16_t addr_offset = 0U; uint16_t line_style = 0U; uint16_t x0 = 0U; uint16_t x1 = 0U; uint16_t y0 = 0U; uint16_t y1 = 0U; uint8_t busy = 0U; }; virtual void machine_reset() override; virtual void video_start() override; virtual void fm7_alu_function(uint32_t offset) { } virtual void fm7_mmr_refresh(address_space &space) { } DECLARE_MACHINE_START(fm7); DECLARE_MACHINE_START(fm16); DECLARE_WRITE_LINE_MEMBER(fdc_intrq_w); DECLARE_WRITE_LINE_MEMBER(fdc_drq_w); uint8_t subintf_r(); void subintf_w(uint8_t data); uint8_t sub_busyflag_r(); void sub_busyflag_w(uint8_t data); uint8_t cancel_ack(); uint8_t attn_irq_r(); uint8_t vram_access_r(); void vram_access_w(uint8_t data); uint8_t vram_r(offs_t offset); void vram_w(offs_t offset, uint8_t data); uint8_t crt_r(); void crt_w(uint8_t data); void vram_offset_w(offs_t offset, uint8_t data); void multipage_w(uint8_t data); uint8_t palette_r(offs_t offset); void palette_w(offs_t offset, uint8_t data); void irq_mask_w(uint8_t data); uint8_t irq_cause_r(); void beeper_w(uint8_t data); uint8_t sub_beeper_r(); uint8_t fd04_r(); uint8_t rom_en_r(address_space &space); void rom_en_w(address_space &space, uint8_t data); uint8_t fdc_r(offs_t offset); void fdc_w(offs_t offset, uint8_t data); uint8_t keyboard_r(offs_t offset); uint8_t sub_keyboard_r(offs_t offset); uint8_t cassette_printer_r(); void cassette_printer_w(offs_t offset, uint8_t data); uint8_t psg_select_r(); void psg_select_w(uint8_t data); uint8_t psg_data_r(); void psg_data_w(uint8_t data); uint8_t main_shared_r(offs_t offset); void main_shared_w(offs_t offset, uint8_t data); uint8_t unknown_r(); uint8_t kanji_r(offs_t offset); void kanji_w(offs_t offset, uint8_t data); IRQ_CALLBACK_MEMBER(irq_ack); IRQ_CALLBACK_MEMBER(sub_irq_ack); DECLARE_WRITE_LINE_MEMBER(write_centronics_busy); DECLARE_WRITE_LINE_MEMBER(write_centronics_fault); DECLARE_WRITE_LINE_MEMBER(write_centronics_ack); DECLARE_WRITE_LINE_MEMBER(write_centronics_perror); uint32_t screen_update_fm7(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); void fm16_io(address_map &map); void fm16_mem(address_map &map); void fm16_sub_mem(address_map &map); void fm7_mem(address_map &map); void fm7_sub_mem(address_map &map); void fm8_mem(address_map &map); optional_shared_ptr m_shared_ram; optional_shared_ptr m_a15_ram; optional_shared_ptr m_vectors; uint8_t m_irq_flags = 0U; uint8_t m_irq_mask = 0U; emu_timer* m_beeper_off_timer = nullptr; emu_timer* m_timer = nullptr; emu_timer* m_subtimer = nullptr; emu_timer* m_keyboard_timer = nullptr; bool m_basic_rom_en = false; bool m_init_rom_en = false; unsigned int m_key_delay = 0U; unsigned int m_key_repeat = 0U; uint16_t m_current_scancode = 0U; uint32_t m_key_data[4]{}; uint32_t m_mod_data = 0U; uint8_t m_key_scan_mode = 0U; uint8_t m_break_flag = 0U; uint8_t m_psg_regsel = 0U; uint8_t m_psg_data = 0U; uint8_t m_fdc_side = 0U; uint8_t m_fdc_drive = 0U; uint8_t m_fdc_irq_flag = 0U; uint8_t m_fdc_drq_flag = 0U; uint8_t m_speaker_active = 0U; uint16_t m_kanji_address = 0U; uint8_t m_cp_prev = 0U; std::unique_ptr m_video_ram{}; uint8_t m_type = 0U; fm7_video_t m_video{}; fm7_alu_t m_alu{}; int m_sb_prev = 0; TIMER_CALLBACK_MEMBER(beeper_off); TIMER_CALLBACK_MEMBER(timer_irq); TIMER_CALLBACK_MEMBER(subtimer_irq); TIMER_CALLBACK_MEMBER(keyboard_poll); required_device m_maincpu; required_device m_sub; required_device m_cassette; required_device m_beeper; optional_device m_psg; required_device m_screen; required_device m_centronics; required_device m_cent_data_out; required_device m_fdc; required_device m_floppy0; required_device m_floppy1; floppy_image_device *m_floppy = nullptr; optional_region_ptr m_rom_ptr; optional_region_ptr m_btrom_ptr; optional_region_ptr m_basic_ptr; void main_irq_set_flag(uint8_t flag); void main_irq_clear_flag(uint8_t flag); virtual void fm7_update_psg(); void key_press(uint16_t scancode); void keyboard_poll_scan(); int m_centronics_busy = 0; int m_centronics_fault = 0; int m_centronics_ack = 0; int m_centronics_perror = 0; optional_memory_region m_kanji; required_ioport_array<3> m_kb_ports; required_ioport m_keymod; required_ioport m_joy1; required_ioport m_dsw; required_device m_palette; optional_device m_av_palette; }; class fm77_state : public fm7_state { public: fm77_state(const machine_config &mconfig, device_type type, const char *tag) : fm7_state(mconfig, type, tag), m_avbank(*this, "av_bank%u", 1), m_ym(*this, "ym"), m_boot_ram(*this, "boot_ram"), m_extended_ram(*this, "extended_ram"), m_fbasic_bank_ram(*this, "fbasic_bank_w"), m_init_bank_ram(*this, "init_bank_w") { } void fm77av(machine_config &config); protected: struct fm7_encoder_t { uint8_t buffer[12]{}; uint8_t tx_count = 0U; uint8_t rx_count = 0U; uint8_t command_length = 0U; uint8_t answer_length = 0U; uint8_t latch = 0U; // 0=ready to receive uint8_t ack = 0U; uint8_t position = 0U; }; struct fm7_mmr_t { uint8_t bank_addr[8][16]{}; uint8_t segment = 0U; uint8_t window_offset = 0U; uint8_t enabled = 0U; uint8_t mode = 0U; }; virtual void machine_reset() override; DECLARE_MACHINE_START(fm77av); void av_encoder_setup_command(); void av_encoder_handle_command(); TIMER_CALLBACK_MEMBER(av_encoder_ack); TIMER_CALLBACK_MEMBER(av_alu_task_end); TIMER_CALLBACK_MEMBER(av_vsync); DECLARE_WRITE_LINE_MEMBER(av_fmirq); void av_analog_palette_w(offs_t offset, uint8_t data); uint8_t av_video_flags_r(); void av_video_flags_w(uint8_t data); uint8_t av_sub_modestatus_r(); void av_sub_modestatus_w(uint8_t data); void av_sub_bank_w(uint8_t data); uint8_t av_alu_r(offs_t offset); void av_alu_w(offs_t offset, uint8_t data); void av_bootram_w(offs_t offset, uint8_t data); uint8_t av_key_encoder_r(offs_t offset); void av_key_encoder_w(offs_t offset, uint8_t data); uint8_t av_boot_mode_r(); void av_ym_select_w(uint8_t data); uint8_t vector_r(offs_t offset); void init_en_w(address_space &space, uint8_t data); uint8_t fmirq_r(); virtual void fm7_update_psg() override; uint8_t mmr_r(offs_t offset); void mmr_w(address_space &space, offs_t offset, uint8_t data); void fm7_update_bank(int bank, uint8_t physical); virtual void fm7_mmr_refresh(address_space &space) override; void alu_mask_write(uint32_t offset, int bank, uint8_t dat); void alu_function_compare(uint32_t offset); void alu_function_pset(uint32_t offset); void alu_function_or(uint32_t offset); void alu_function_and(uint32_t offset); void alu_function_xor(uint32_t offset); void alu_function_not(uint32_t offset); void alu_function_invalid(uint32_t offset); void alu_function_tilepaint(uint32_t offset); virtual void fm7_alu_function(uint32_t offset) override; uint32_t av_line_set_pixel(int x, int y); void av_line_draw(); void fm77av_mem(address_map &map); void fm77av_sub_mem(address_map &map); void fm7_banked_mem(address_map &map); required_device_array m_avbank; optional_device m_ym; required_shared_ptr m_boot_ram; required_shared_ptr m_extended_ram; required_shared_ptr m_fbasic_bank_ram; required_shared_ptr m_init_bank_ram; fm7_encoder_t m_encoder{}; fm7_mmr_t m_mmr{}; emu_timer *m_encoder_ack_timer = nullptr; emu_timer *m_alu_task_end_timer = nullptr; emu_timer *m_vsync_timer = nullptr; uint8_t m_fm77av_ym_irq = 0U; }; class fm11_state : public fm77_state { public: fm11_state(const machine_config &mconfig, device_type type, const char *tag) : fm77_state(mconfig, type, tag), m_x86(*this, "x86") { } void fm11(machine_config &config); protected: virtual void machine_reset() override; private: DECLARE_MACHINE_START(fm11); void fm11_mem(address_map &map); void fm11_sub_mem(address_map &map); void fm11_x86_io(address_map &map); void fm11_x86_mem(address_map &map); required_device m_x86; }; #endif // MAME_INCLUDES_FM7_H