From f6972910851c7489f70f17f10ac1f58b79863b02 Mon Sep 17 00:00:00 2001 From: Daniel Tremblay Date: Tue, 5 Aug 2025 21:45:41 +0200 Subject: [PATCH 01/11] Commit for Foenix F256K retro-computer. More information available here: https://wiki.f256foenix.com/ For the list of supported features, see: https://wiki.f256foenix.com/index.php?title=Emulation#MAME. Report defects on Discord server: https://discord.com/channels/691915291721990194/1330998392481906768 --- src/devices/machine/bq4847.cpp | 48 +- src/devices/machine/bq4847.h | 16 +- src/mame/f256/f256.cpp | 2002 ++++++++++++++++++++++++++++++++ src/mame/f256/f256.h | 204 ++++ src/mame/f256/f256k.md | 18 + src/mame/f256/tiny_vicky.cpp | 611 ++++++++++ src/mame/f256/tiny_vicky.h | 79 ++ src/mame/mame.lst | 3 + 8 files changed, 2967 insertions(+), 14 deletions(-) create mode 100644 src/mame/f256/f256.cpp create mode 100644 src/mame/f256/f256.h create mode 100644 src/mame/f256/f256k.md create mode 100644 src/mame/f256/tiny_vicky.cpp create mode 100644 src/mame/f256/tiny_vicky.h diff --git a/src/devices/machine/bq4847.cpp b/src/devices/machine/bq4847.cpp index ff2ea20265ad2..9bd7564a3b0d7 100644 --- a/src/devices/machine/bq4847.cpp +++ b/src/devices/machine/bq4847.cpp @@ -31,6 +31,7 @@ #include "logmacro.h" // device type definition +DEFINE_DEVICE_TYPE(BQ4802, bq4802_device, "bq4802", "Benchmarq BQ4802 RTC") DEFINE_DEVICE_TYPE(BQ4845, bq4845_device, "bq4845", "Benchmarq BQ4845 RTC") DEFINE_DEVICE_TYPE(BQ4847, bq4847_device, "bq4847", "Benchmarq BQ4847 RTC") @@ -51,7 +52,7 @@ enum reg_interrupts, // 0 0 0 0 AIE PIE PWRIE ABE 0x00 on powerup reg_flags, // 0 0 0 0 AF PF PWRF BVF 0x00 after reading reg_control, // 0 0 0 0 UTI STOP* 24/12* DSE - reg_unused // 0x00 + reg_century // 0x00-0x99 }; enum @@ -101,7 +102,11 @@ bq4845_device::bq4845_device(const machine_config& mconfig, const char* tag, dev : bq4847_device(mconfig, BQ4845, tag, owner, clock) { } - +bq4802_device::bq4802_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock) + : bq4847_device(mconfig, BQ4845, tag, owner, clock) +{ + set_has_century(true); +} // device_rtc_interface void bq4847_device::rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second) @@ -112,10 +117,15 @@ void bq4847_device::rtc_clock_updated(int year, int month, int day, int day_of_w (((hour % 24) >= 12) ? 0x80 : 0x00) | convert_to_bcd((hour % 12) ? (hour % 12) : 12); m_register[reg_minutes] = convert_to_bcd(minute); m_register[reg_seconds] = convert_to_bcd(second); - m_register[reg_year] = convert_to_bcd(year); + m_register[reg_year] = convert_to_bcd(year%100); m_register[reg_month] = convert_to_bcd(month); m_register[reg_date] = convert_to_bcd(day); m_register[reg_days] = convert_to_bcd(day_of_week); + if (has_century) + { + m_register[reg_century] = convert_to_bcd(year / 100); + } + } // Clear the saved flags (TODO: check that flags set before power down, or during battery backup are lost) @@ -183,16 +193,26 @@ TIMER_CALLBACK_MEMBER(bq4847_device::update_callback) if (carry) advance_days_bcd(); - LOGMASKED(LOG_CLOCK, "%s 20%02x-%02x-%02x %02x:%02x:%02x\n", - dow[m_register[reg_days] - 1], m_register[reg_year], m_register[reg_month], m_register[reg_date], - m_register[reg_hours], m_register[reg_minutes], m_register[reg_seconds]); + if (!has_century) + { + LOGMASKED(LOG_CLOCK, "%s 20%02x-%02x-%02x %02x:%02x:%02x\n", + dow[m_register[reg_days] - 1], m_register[reg_year], m_register[reg_month], m_register[reg_date], + m_register[reg_hours], m_register[reg_minutes], m_register[reg_seconds]); + } + else + { + LOGMASKED(LOG_CLOCK, "%s %02x%02x-%02x-%02x %02x:%02x:%02x\n", + dow[m_register[reg_days] - 1], m_register[reg_century], m_register[reg_year], m_register[reg_month], m_register[reg_date], + m_register[reg_hours], m_register[reg_minutes], m_register[reg_seconds]); + } + if (newsec) { if ((m_register[reg_control] & CONTROL_UTI) == 0) { LOGMASKED(LOG_TRANSFER, "Transfer to external regs\n"); - for (int i = reg_seconds; i < reg_unused; i++) + for (int i = reg_seconds; i < reg_century + 1; i++) { if (is_clock_register(i)) m_userbuffer[i] = m_register[i]; } @@ -289,9 +309,13 @@ void bq4847_device::advance_days_bcd() if (m_register[reg_month] == 0x13) { m_register[reg_month] = 0x01; - increment_bcd(m_register[reg_year], 0xff, 0); + carry = increment_bcd(m_register[reg_year], 0xff, 0); } } + if (has_century && carry) + { + increment_bcd(m_register[reg_century], 0xff, 1); + } } bool bq4847_device::check_alarm(int now, int alarm) @@ -313,8 +337,8 @@ uint8_t bq4847_device::read(offs_t address) } else if (regnum >= reg_interrupts && regnum <= reg_control) value &= 0xf; - else if (regnum == reg_unused) - value = 0; // Reg 15 is locked to 0 in BQ4847 + else if (regnum == reg_century) + value = has_century? m_register[reg_century]: 0; // Reg 15 is locked to 0 in BQ4847 LOGMASKED(LOG_REG, "Reg %d -> %02x\n", regnum, value); @@ -358,7 +382,7 @@ void bq4847_device::write(offs_t address, uint8_t data) if (uti_set && !uti_set_now && m_writing) { LOGMASKED(LOG_TRANSFER, "Transfer to internal regs\n"); - for (int i = reg_seconds; i < reg_unused; i++) + for (int i = reg_seconds; i < reg_century + 1; i++) { if (is_clock_register(i)) m_register[i] = m_userbuffer[i]; } @@ -372,7 +396,7 @@ bool bq4847_device::is_clock_register(int regnum) { return (regnum == reg_seconds || regnum == reg_minutes || regnum == reg_hours || regnum == reg_date || regnum == reg_days || regnum == reg_month - || regnum == reg_year); + || regnum == reg_year || regnum == reg_century); } void bq4847_device::set_periodic_timer() diff --git a/src/devices/machine/bq4847.h b/src/devices/machine/bq4847.h index b53f4ccb43e03..5b2fbef7efbc8 100644 --- a/src/devices/machine/bq4847.h +++ b/src/devices/machine/bq4847.h @@ -31,6 +31,11 @@ class bq4847_device : public device_t, void write_wdi(int state); // watchdog disabled if wdi pin is left floating + void set_has_century(bool value) + { + has_century = value; + } + protected: bq4847_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock = 32768); @@ -45,7 +50,7 @@ class bq4847_device : public device_t, virtual bool nvram_write(util::write_stream& file) override; // device_rtc_interface - virtual bool rtc_feature_y2k() const override { return false; } + virtual bool rtc_feature_y2k() const override { return has_century; } virtual bool rtc_feature_leap_year() const override { return true; } virtual bool rtc_battery_backed() const override { return true; } virtual void rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second) override; @@ -84,6 +89,7 @@ class bq4847_device : public device_t, int m_rst_state; int m_wdi_state; bool m_writing; + bool has_century = false; }; class bq4845_device : public bq4847_device @@ -91,7 +97,13 @@ class bq4845_device : public bq4847_device public: bq4845_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock); }; - +class bq4802_device : public bq4847_device +{ +public: + bq4802_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock); +private: +}; +DECLARE_DEVICE_TYPE(BQ4802, bq4802_device) DECLARE_DEVICE_TYPE(BQ4845, bq4845_device) DECLARE_DEVICE_TYPE(BQ4847, bq4847_device) diff --git a/src/mame/f256/f256.cpp b/src/mame/f256/f256.cpp new file mode 100644 index 0000000000000..2945ad4853548 --- /dev/null +++ b/src/mame/f256/f256.cpp @@ -0,0 +1,2002 @@ +#include "emu.h" +#include "f256.h" + +#include "cpu/m6502/w65c02.h" +#include "tiny_vicky.h" + +/** + * + * F256K - WDC65C02 Processor running at 6.25MHz + * 512KB RAM managed with slots of 8KB in MMU located at address $0000. Slots 0 to $3F + * 512KB Flash Slots $40 to $7F + * All I/O are mapped to slot 6 ($C000-$DFFF) - there are 4 I/O maps, switched using address $0001. + * Sound Chips: OPL3, PSG, SN74689, CODEC + * Keyboard: mechanical switch in a matrix - controlled by VIA6522 chip. + * Joysticks: 2 Atari-type ports and 2 S/NES ports + * Mouse: over PS/2 - which can also be used for PS/2 Keyboard + * IEC: Commodore Floppy Drive Controller + * + */ + +f256_state::f256_state(const machine_config &mconfig, device_type type, const char *tag) : + driver_device(mconfig, type, tag) + , m_maincpu(*this, MAINCPU_TAG) + , m_ram(*this, RAM_TAG) + , m_iopage0(*this, IOPAGE0_TAG) + , m_iopage1(*this, IOPAGE1_TAG) + , m_iopage2(*this, IOPAGE2_TAG) + , m_iopage3(*this, IOPAGE3_TAG) + , m_rom(*this, ROM_TAG) + , m_font(*this, FONT_TAG) + , m_screen(*this, SCREEN_TAG) + , m_rtc(*this, "rtc") + , m_keyboard(*this, "ROW%u", 0) // this, with the 8 array, requires 8 ROW of INPUTs + , m_via6522_0(*this, "via6522_0") + , m_via6522_1(*this, "via6522_1") + + , m_sn0(*this, "sn76489_0") + , m_sn1(*this, "sn76489_1") + , m_opl3(*this, "ymf262") + , m_sid0(*this, "sid_0") + , m_sid1(*this, "sid_1") + + , m_video(*this, "tiny_vicky") + //, m_iec(*this, "iec_bus") + //, m_iec_data_out(1) + //, m_iec_srq(1) + , m_ps2_keyboard(*this, "ps2_kbd") + , m_mouse(*this, "ps_mouse") + , m_uart(*this, "uart") + , m_sdcard(*this, "sdcard") + , m_spi_clock_state(false) + , m_spi_clock_sysclk(false) + , m_spi_clock_cycles(0) +{ +} + +void f256_state::f256k(machine_config &config) +{ + W65C02(config, m_maincpu, MASTER_CLOCK/4); + RAM(config, m_ram).set_default_size("512k").set_default_value(0x0); + RAM(config, m_iopage0).set_default_size("8k").set_default_value(0x0); + RAM(config, m_iopage1).set_default_size("8k").set_default_value(0x0); + RAM(config, m_iopage2).set_default_size("8k").set_default_value(0x0); + RAM(config, m_iopage3).set_default_size("8k").set_default_value(0x0); + SCREEN(config, m_screen, SCREEN_TYPE_RASTER); + BQ4802(config, m_rtc, MASTER_CLOCK / 1000); // RTC clock in kHz + + m_maincpu->set_addrmap(AS_PROGRAM, &f256_state::program_map); + + m_screen->set_refresh_hz(60); // Refresh rate (e.g., 60Hz) + m_screen->set_size(800,525); + //m_screen->set_visarea(160, 799, 45, 524); // this is how it should reall work, but the screen ends up offset + m_screen->set_visarea(0, 639, 0, 479); + m_screen->set_screen_update(m_video, FUNC(tiny_vicky_video_device::screen_update)); + TINY_VICKY(config, m_video, MASTER_CLOCK); + m_video->sof_irq_handler().set(FUNC(f256_state::sof_interrtupt)); + m_video->sol_irq_handler().set(FUNC(f256_state::sol_interrtupt)); + + MOS6522(config, m_via6522_0, MASTER_CLOCK / 4); // Atari Joysticks + m_via6522_0->readpa_handler().set(FUNC(f256_state::via0_system_porta_r)); + m_via6522_0->readpb_handler().set(FUNC(f256_state::via0_system_portb_r)); + m_via6522_0->writepa_handler().set(FUNC(f256_state::via0_system_porta_w)); + m_via6522_0->writepb_handler().set(FUNC(f256_state::via0_system_portb_w)); + m_via6522_0->ca2_handler().set(FUNC(f256_state::via0_ca2_write)); + m_via6522_0->cb2_handler().set(FUNC(f256_state::via0_cb2_write)); + m_via6522_0->irq_handler().set(FUNC(f256_state::via0_interrupt)); + + // initialize the PS2 mouse + PC_KBDC(config, m_ps2_keyboard, XTAL(32'768)); + HLE_PS2_MOUSE(config, m_mouse, XTAL(32'768)); + + MOS6522(config, m_via6522_1, MASTER_CLOCK / 4); // Keyboard XTAL(14'318'181)/14) + m_via6522_1->readpa_handler().set(FUNC(f256_state::via1_system_porta_r)); + m_via6522_1->readpb_handler().set(FUNC(f256_state::via1_system_portb_r)); + m_via6522_1->writepa_handler().set(FUNC(f256_state::via1_system_porta_w)); + m_via6522_1->writepb_handler().set(FUNC(f256_state::via1_system_portb_w)); + m_via6522_1->ca2_handler().set(FUNC(f256_state::via1_ca2_write)); + m_via6522_1->cb2_handler().set(FUNC(f256_state::via1_cb2_write)); + m_via6522_1->irq_handler().set(FUNC(f256_state::via1_interrupt)); + + SN76489(config, m_sn0, MUSIC_CLOCK / 4); + SN76489(config, m_sn1, MUSIC_CLOCK / 4); + YMF262(config, m_opl3, MUSIC_CLOCK); + MOS6581(config, m_sid0, MUSIC_CLOCK/14); + MOS6581(config, m_sid1, MUSIC_CLOCK/14); + + SPEAKER(config, "lspeaker").front_left(); + SPEAKER(config, "rspeaker").front_right(); + // Mix PSG + m_sn0->add_route(ALL_OUTPUTS, "lspeaker", 0.5); + m_sn0->add_route(ALL_OUTPUTS, "rspeaker", 0.5); + m_sn1->add_route(ALL_OUTPUTS, "lspeaker", 0.5); + m_sn1->add_route(ALL_OUTPUTS, "rspeaker", 0.5); + + m_opl3->add_route(0, "lspeaker", 1.0); + m_opl3->add_route(1, "rspeaker", 1.0); + m_opl3->add_route(2, "lspeaker", 1.0); + m_opl3->add_route(3, "rspeaker", 1.0); + // The SIDs are very noisy + m_sid0->add_route(ALL_OUTPUTS, "lspeaker", 0.5); + m_sid0->add_route(ALL_OUTPUTS, "rspeaker", 0.5); + m_sid1->add_route(ALL_OUTPUTS, "lspeaker", 0.5); + m_sid1->add_route(ALL_OUTPUTS, "rspeaker", 0.5); + + //set interrupt handler for the RTC + m_rtc->int_handler().set(FUNC(f256_state::rtc_interrupt_handler)); + + // Add an SD card device + SPI_SDCARD(config, m_sdcard, 0); + m_sdcard->set_prefer_sdhc(); + m_sdcard->spi_miso_callback().set([this](int state) { + //m_in_bit = state; + m_in_latch <<= 1; + m_in_latch |= state; + }); + + m_mouse->set_pc_kbdc(m_ps2_keyboard); + NS16550(config, m_uart, MASTER_CLOCK); + + // cbm_iec_slot_device::add(config, m_iec, "c1581"); + // m_iec->srq_callback().set(FUNC(f256_state::iec_srq_w)); + // m_iec->data_callback().set(FUNC(f256_state::iec_data_w)); + // m_iec->atn_callback().set(FUNC(f256_state::iec_atn_w)); + // m_iec->clk_callback().set(FUNC(f256_state::iec_clk_w)); +} +f256_state::~f256_state() +{ +} +/* + Memory map + $00:0000 - $07:FFFF RAM + $08:0000 - $0F:FFFF Flash + $10:0000 - $13:FFFF Expansion Memory - NOT IMPLEMENTED + $14:0000 - $1F:FFFF Reserved +*/ +void f256_state::program_map(address_map &map) +{ + // the address range 0:F + // 0: LUT Edit $80 allows writing to 8 to F, LUT Select 0 to 3 + map(0x0000, 0x000F).rw(FUNC(f256_state::lut_r), FUNC(f256_state::lut_w)); + map(0x0010, 0xFFFF).rw(FUNC(f256_state::mem_r), FUNC(f256_state::mem_w)); +}; + +void f256_state::data_map(address_map &map) +{ + map(0x0000, 0x1FFF).ram().share(IOPAGE0_TAG); + map(0x0000, 0x1FFF).ram().share(IOPAGE1_TAG); + map(0x0000, 0x1FFF).ram().share(IOPAGE2_TAG); + map(0x0000, 0x1FFF).ram().share(IOPAGE3_TAG); +} + +u8 f256_state::lut_r(offs_t offset) +{ + // addresses 2 to 7 are always read from RAM + if (offset == 0) + { + return m_mmu_reg; + } + else if (offset == 1) + { + return m_ioreg; + } + else if (offset < 8) + { + return m_ram->read(offset); + } + else + { + // if we are not in edit mode, return RAM data + if ((m_mmu_reg & 0x80) != 0) + { + uint8_t mmu = (m_mmu_reg >> 4) & 0x3; // use the top nibble + return mmu_lut[(mmu & 0x3) * 8 + (offset-8)]; + } + else + { + return m_ram->read(offset); + } + } +} +void f256_state::lut_w(offs_t offset, u8 data) +{ + // addresses 2:7 are always RAM + if (offset == 0) + { + m_mmu_reg = data; + } + else if (offset == 1) + { + m_ioreg = data; + } + else if (offset < 8) + { + m_ram->write(offset, data); + } + else + { + // bit 7 of mmu0 determines if the MMU is writable + if ((m_mmu_reg & 0x80) == 0) + { + m_ram->write(offset, data); + } + else + { + uint8_t mmu = (m_mmu_reg >> 4) & 0x3; // use the top nibble + mmu_lut[mmu * 8 + (offset - 8)] = data; + } + } +} + +// offsets are 0x10 based +u8 f256_state::mem_r(offs_t offset) +{ + + // find which slot to read + uint8_t mmu = m_mmu_reg & 3; + uint16_t adj_addr = offset + 0x10; + uint8_t slot = adj_addr >> 13; + uint16_t low_addr = adj_addr & 0x1FFF; + uint8_t bank = mmu_lut[mmu * 8 + slot]; + + // fslot < 0x40 is RAM, greater is FLASH/ROM + if (bank < 0x40) + { + // Slot 6 is where I/O devices are located, when IO_DISABLE is 0 + if (slot == 6 && (m_ioreg & 0x4) == 0) + { + switch (m_ioreg & 0x3) + { + case 0: + // here we have a number of devices to read + if (adj_addr >= 0xD018 && adj_addr < 0xD01C) + { + // return Vicky's scan line and colum + uint16_t line = m_screen->hpos(); + //uint16_t column = m_video->column(); + logerror("Scanline Addr: %04X, Line: %04X\n", adj_addr, line); + switch (adj_addr - 0xD018) + { + case 0: + return 0; //column & 0xFF; + case 1: + return 0; // (column >> 8); + case 2: + return line & 0xFF; + case 3: + return (line >> 8); + } + + } + else if (adj_addr >= 0xD400 && adj_addr < 0xD580) + { + // SID + return 0; + } + else if (adj_addr >= 0xD580 && adj_addr < 0xD583) + { + // OPL3 + return 0; + } + else if (adj_addr >= 0xD600 && adj_addr < 0xD620) + { + // PSG - left channel D600, right channel D610 - both D608 + return 0; + } + else if (adj_addr >= 0xD620 && adj_addr < 0xD630) + { + // logerror("CODEC Read Addr: %04X\n", adj_addr); + uint16_t base = adj_addr - 0xD620; + return m_codec[base]; + } + else if (adj_addr >= 0xD630 && adj_addr < 0xD640) + { + // UART + uint8_t v_uart = m_uart->ins8250_r(adj_addr - 0xD630); + logerror("UART Read %X %02X\n", adj_addr, v_uart); + return v_uart; + } + else if (adj_addr >= 0xD640 && adj_addr < 0xD64F) + { + // PS2 + logerror("PS/2 Read %04X\n", adj_addr); + switch(adj_addr - 0xD640) + { + case 0: + case 1: + return m_ps2[adj_addr - 0xD640]; + case 2: + { + // Read from the keyboard fifo + if (kbPacketCntr > kbQLen) + { + return 0; + } + uint8_t kbval = kbFifo[kbPacketCntr++]; + if (kbPacketCntr == kbQLen) + { + kbPacketCntr = 0; + kbQLen = 0; + memset(kbFifo, 0, 6); + } + return kbval; + } + case 3: + { + // Read from the mouse fifo + if (msPacketCntr> msQLen) + { + return 0; + } + uint8_t msval = msFifo[msPacketCntr++]; + if (msPacketCntr == msQLen) + { + msPacketCntr = 0; + msQLen = 0; + memset(msFifo, 0, 3); + } + return msval; + } + case 4: + K_AK = false; + M_AK = false; + return ((K_AK ? 0x80:0) + (M_AK ? 0x20 : 0) + (msQLen == 0 ? 2 : 0) + (kbQLen == 0? 1 : 0)); + } + + return m_ps2[adj_addr - 0xD640]; + } + else if (adj_addr >= 0xD650 && adj_addr < 0xD660) + { + // Timers + switch (adj_addr) + { + case 0xD650: + return m_timer0_eq; + case 0xD651: + return m_timer0_val & 0xFF; + case 0xD652: + return (m_timer0_val >> 8) & 0xFF; + case 0xD653: + return (m_timer0_val >> 16) & 0xFF; + case 0xD658: + return m_timer1_eq; + case 0xD659: + return m_timer1_val & 0xFF; + case 0xD65A: + return (m_timer1_val >> 8) & 0xFF; + case 0xD65B: + return (m_timer1_val >> 16) & 0xFF; + } + return m_iopage0->read(adj_addr - 0xC000); + } + else if (adj_addr >= 0xD660 && adj_addr < 0xD670) + { + // Interrupt Registers + logerror("Interrupt Registers Read: %04X\n", adj_addr); + switch (adj_addr) + { + case 0xD660: + return m_interrupt_reg[0]; // int_pending_0 + case 0xD661: + return m_interrupt_reg[1]; // int_pending_1 + case 0xD662: + return m_interrupt_reg[2]; // int_pending_2 + case 0xD663: + return 0; + case 0xD664: + return m_interrupt_polarity[0]; // int_polarity_0 + case 0xD665: + return m_interrupt_polarity[1]; // int_polarity_1 + case 0xD666: + return m_interrupt_polarity[2]; // int_polarity_2 + case 0xD667: + return 0; + case 0xD668: + return m_interrupt_edge[0]; // int_edge_0 + case 0xD669: + return m_interrupt_edge[1]; // int_edge_1 + case 0xD66A: + return m_interrupt_edge[2]; // int_edge_2 + case 0xD66B: + return 0; + case 0xD66C: + return m_interrupt_masks[0]; + case 0xD66D: + return m_interrupt_masks[1]; + case 0xD66E: + return m_interrupt_masks[2]; + case 0xD66F: + return 0; + + } + } + else if (adj_addr >= 0xD680 && adj_addr < 0xD682) + { + //IEC + logerror("Reading from IEC Reg: %X", adj_addr - 0xD680); + switch (adj_addr - 0xD680) + { + case 0: + logerror(", data: %02X\n", m_iec_in); + // gather the IEC bus values + // m_iec_in = + // (m_iec->srq_r() << 7) + + // (m_iec->atn_r() << 4) + + // (m_iec->clk_r() << 1) + + // (m_iec->data_r()); + logerror(", data: %02X\n", m_iec_in); + return m_iec_in; + case 1: + logerror(", data: %02X\n", m_iec_out); + return m_iec_out; + } + } + else if (adj_addr >= 0xD690 && adj_addr < 0xD6A0) + { + // RTC + logerror("RTC Read %04X\n", adj_addr); + return m_rtc->read(adj_addr - 0xDC90); + } + else if (adj_addr >= 0xD6A0 && adj_addr < 0xD6C0) + { + // System Control Registers + // D6A0 - buzzer and LED controls - including RESET bit + // D6A1 - sound mixer + // D6A2 - Set to 0xDE to enable software reset + // D6A3 - Set to 0xAD to enable software reset + // D6A4 - D6A6 : Random Number generator + // D6A7 - Macine ID - For the F256, the machine ID will be 0x02. For the F256k, the machine ID will be 0x12. + logerror("System Register Read %04X\n", adj_addr); + switch (adj_addr){ + case 0xD6A0: + return m_sdcard->get_card_present() ? 0x10:0; + case 0xD6A1: + return m_iopage0->read(0xD6A1 - 0xC000); + case 0xD6A4: + if (m_rng_enabled) + { + return get_random() & 0xFF; + } + else + { + return m_seed & 0xFF; + } + case 0xD6A5: + if (m_rng_enabled) + { + return get_random() & 0xFF; + } + else + { + return (m_seed >> 8) & 0xFF; + } + case 0xD6A6: + return m_rng_enabled ? 0x80: 0; + case 0xD6A7: + return 0x12; // F256K ID + case 0XD6A8: + return 'A'; + case 0XD6A9: + return '0'; + case 0XD6AA: + return 1; + case 0XD6AB: + return 1; + case 0XD6AC: + return 0; + case 0XD6AD: + return 0x14; + case 0XD6AE: + return 0; + case 0XD6AF: + return 0; + } + + } + // mouse registers + // else if (adj_addr >= 0xD6E0 && adj_addr < 0xD6E9) + // { + // switch (adj_addr) + // { + // case 0xD6E0: + // return (m_mouse_mode << 1) + m_mouse_enabled ? 1 : 0; + // break; + // case 0xD6E2: + // return m_mouse_x & 0xFF; + // case 0xD6E3: + // return (m_mouse_x >> 8) & 0xFF; + // case 0xD6E4: + // return m_mouse_y & 0xFF; + // case 0xD6E5: + // return (m_mouse_y >> 8) & 0xFF; + + // default: + // break; + // } + // } + else if (adj_addr >= 0xD880 && adj_addr < 0xD8C0) + { + // NES + return 0xFF; + } + else if (adj_addr >= 0xDB00 && adj_addr < 0xDB10) + { + // VIA1 - Keyboard for F256K + return m_via6522_1->read(adj_addr - 0xDB00); + } + else if (adj_addr >= 0xDC00 && adj_addr < 0xDC10) + { + // VIA0 - Atari Joystick + return m_via6522_0->read(adj_addr - 0xDC00); + } + else if (adj_addr >= 0xDD00 && adj_addr < 0xDD20) + { + // SD Card + //m_sdcard->(adj_addr - 0xDD00); + // logerror("Reading SD Card: %04X\n", adj_addr); + switch (adj_addr) + { + case 0xDD00: + { + // bit 7 is the busy state + u8 spi_reg = (m_spi_clock_cycles > 0 ? 0x80 : 0x00) + (spi_sd_enabled ? 1 : 0); // TODO add clock bits + //logerror("Read SD 0: %02X\n", spi_reg); + return spi_reg; + } + case 0xDD01: + //logerror("Read SD 1: %02X\n", m_in_latch); + return m_in_latch; + default: + return 0xFF; + } + } + else if (adj_addr >= 0xDE00 && adj_addr < 0xDE20) + { + // Math Coprocessor + switch (adj_addr - 0xDE10) + { + case 0: + return m_multiplication_result & 0xFF; + case 1: + return (m_multiplication_result >> 8) & 0xFF; + case 2: + return (m_multiplication_result >> 16) & 0xFF; + case 3: + return (m_multiplication_result >> 24) & 0xFF; + case 4: + return m_division_result & 0xFF; + case 5: + return (m_division_result >> 8) & 0xFF; + case 6: + return m_division_remainder & 0xFF; + case 7: + return (m_division_remainder >> 8) & 0xFF; + case 8: + return m_addition_result & 0xFF; + case 9: + return (m_addition_result >> 8) & 0xFF; + case 0xA: + return (m_addition_result >> 16) & 0xFF; + case 0xB: + return (m_addition_result >> 24) & 0xFF; + } + return m_iopage0->read(adj_addr - 0xC000); + } + else if (adj_addr >= 0xDF00 && adj_addr < 0xE000) + { + // DMA + if (adj_addr == 0xDF01) + { + return m_dma_status; + } + else + { + return m_iopage0->read(adj_addr - 0xC000); + } + } + // Stick everything else in Vicky + // (adj_addr >= 0xC000 && adj_addr < 0xD400) || // gamma, mouse graphics, vicky registers, bitmaps, tiles + // (adj_addr >= 0xD800 && adj_addr < 0xD880) || // text colors + // (adj_addr >= 0xD900 && adj_addr < 0xDB00) // sprite registers + return m_iopage0->read(adj_addr - 0xC000); + case 1: + return m_iopage1->read(adj_addr - 0xC000); + case 2: + return m_iopage2->read(adj_addr - 0xC000); + case 3: + return m_iopage3->read(adj_addr - 0xC000); + } + } + offs_t address = (bank << 13) + low_addr; + return m_ram->read(address); + } + else if (bank < 0x80) + { + offs_t address = (bank << 13) + low_addr; + return m_rom->as_u8(address); + } + else if (bank < 0xA0) + { + // this is now trying to read expansion RAM/Flash - NOT IMPLEMENTED + } + // Invalid area of memory + return 0; +} +void f256_state::mem_w(offs_t offset, u8 data) +{ + // find which slot to write + uint8_t mmu = m_mmu_reg & 3; + uint16_t adj_addr = offset + 0x10; + uint8_t slot = adj_addr >> 13; + uint16_t low_addr = adj_addr & 0x1FFF; + uint8_t old, combo; + + uint8_t bank = mmu_lut[mmu * 8 + slot]; + if (bank < 0x40) + { + // Slot 6 is where I/O devices are located, when IO_DISABLE is 0 + if (slot == 6) + { + // if IO_DISABLED is 1, then slot 6 is regular RAM + if ((m_ioreg & 0x4) == 0) + { + switch (m_ioreg & 0x3) + { + case 0: + // here we have a number of devices to write + if (adj_addr == 0xD001) + { + logerror("Change Resolution %04X %02X\n", adj_addr, data); + if ((data & 0x1) != 0 ) + { + m_screen->set_refresh_hz(70); + m_screen->set_visarea(0, 639, 0, 399); + m_screen->set_size(800,450); + } + else + { + m_screen->set_refresh_hz(60); + m_screen->set_visarea(0, 639, 0, 479); + m_screen->set_size(800,525); + } + m_iopage0->write(0xD001 - 0xC000, data); + } + else if (adj_addr >= 0xD400 && adj_addr < 0xD419) + { + // SID 0 + m_sid0->write(adj_addr - 0xD400, data); + + } + else if (adj_addr >= 0xD500 && adj_addr < 0xD519) + { + // SID 1 + m_sid1->write(adj_addr - 0xD500, data); + } + else if (adj_addr >= 0xD580 && adj_addr < 0xD583) + { + // OPL3 + switch(adj_addr) + { + case 0xD580: + m_opl3_reg = data; + m_opl3->address_w(data); + break; + case 0xD581: + //m_opl3->write(m_opl3_reg, data); + if (m_opl3_reg > 0xFF) { m_opl3->data_hi_w(data);} else { m_opl3->data_w(data);} + break; + case 0xD582: + m_opl3_reg = 0x100 + data; + m_opl3->address_hi_w(data); + break; + } + } + else if (adj_addr == 0xD600) + { + // PSG + logerror("PSG Left Write: %02X\n", data); + m_sn0->write(data); + } + else if (adj_addr == 0xD608) + { + // PSG + logerror("PSG Both Write: %02X\n", data); + m_sn0->write(data); + m_sn1->write(data); + } + else if (adj_addr == 0xD610) + { + // PSG + logerror("PSG Right Write: %02X\n", data); + m_sn1->write(data); + } + else if (adj_addr >= 0xD620 && adj_addr < 0xD630) + { + // Codec + logerror("CODEC Write %04X %02X\n", adj_addr, data); + uint16_t base = adj_addr-0xD620; + m_codec[base] = data; + // the program is telling the codec to start + if ((base == 2) && ((data & 1) == 1)) + { + // start a timer that will reset the value to zero + this->machine().scheduler().timer_set(attotime::from_msec(100), timer_expired_delegate(FUNC(f256_state::codec_done), this), 1); // timer_alloc(timer_expired_delegate(FUNC(f256_state::timer), this)); + } + } + else if (adj_addr >= 0xD630 && adj_addr < 0xD640) + { + // UART + logerror("UART Writing %X %02X\n", adj_addr, data); + m_uart->ins8250_w(adj_addr - 0xD630, data); + } + else if (adj_addr >= 0xD640 && adj_addr < 0xD64F) + { + // PS/2 Keyboard + logerror("PS/2 Write %04X %02X\n", adj_addr, data); + uint16_t delta = adj_addr-0xD640; + m_ps2[delta] = data; + // Only addresses 0 and 1 are writable + if (delta == 0) + { + switch (data) + { + case 0: + if (isK_WR) + { + // write out the byte in data[1] to keyboard + isK_WR = false; + K_AK = true; + m_ps2_keyboard->data_write_from_kb(data); + } + if (isM_WR) + { + // write out the byte in data[1] to mouse + isM_WR = false; + M_AK = true; + m_mouse->data_write(data); + } + break; + case 2: + isK_WR = true; + break; + case 8: + isM_WR = true; + break; + case 0x10: // clear keyboard fifo + memset(kbFifo, 0 , 6); + break; + case 0x20: // clear mouse fifo + memset(msFifo, 0, 3); + break; + } + } + else if (delta == 1) + { + + } + } + else if (adj_addr >= 0xD650 && adj_addr < 0xD660) + { + // Timers + logerror("Writing to Timer Register: %X, %02X\n", adj_addr, data); + m_iopage0->write(adj_addr - 0xC000, data); + switch(adj_addr) + { + case 0xD650: + // Timer0 is based on Master Clock and causes some slow down. + // I'm computing the next period and avoiding increments by one. + if ((data & 0x1) == 1) + { + + uint32_t timer0_cmp = m_iopage0->read(0xD655 - 0xC000) + + (m_iopage0->read(0xD656 - 0xC000) << 8) + + (m_iopage0->read(0xD657 - 0xC000) << 16); + logerror("Start Timer0: %06X\n", timer0_cmp); + attotime period = attotime::from_double((double)(timer0_cmp - m_timer0_load)/(double)25'175'000); + m_timer0->adjust(period, 0, period); + } + else + { + logerror("Stop Timer0\n"); + m_timer0->adjust(attotime::never); + } + + if ((data & 0x2) != 0) + { + m_timer0_val = 0; + } + if ((data & 0x4) != 0) + { + m_timer0_val = m_timer0_load; + } + break; + case 0xD651: + case 0xD652: + case 0xD653: + // writing to these registers sets the load value + m_timer0_load = m_iopage0->read(0xD651 - 0xC000) + (m_iopage0->read(0xD652 - 0xC000) << 8) + + (m_iopage0->read(0xD653 - 0xC000) << 16); + break; + case 0xD658: + // Timer1 is based on the Start of Frame - so it's very slow + if ((data & 0x1) == 1) + { + logerror("Start Timer1 %X, %X\n", data, m_timer1_val); + // Get the frame frequency from video + int frame_freq = (m_iopage0->read(0xD001 - 0xC000) & 1) == 1? 70: 60; + m_timer1->adjust(attotime::from_hz(XTAL(frame_freq)), 0, attotime::from_hz(XTAL(frame_freq))); + } + else + { + logerror("Stop Timer1\n"); + m_timer1->adjust(attotime::never); + } + + if ((data & 0x2) != 0) + { + logerror("Timer1 value = 0\n"); + m_timer1_val = 0; + } + if ((data & 0x4) != 0) + { + m_timer1_val = m_timer1_load; + logerror("Timer1 value = %06X\n", m_timer1_val); + } + break; + case 0xD659: + case 0xD65A: + case 0xD65B: + // writing to these registers sets the load value + m_timer1_load = m_iopage0->read(0xD659 - 0xC000) + (m_iopage0->read(0xD65A - 0xC000) << 8) + + (m_iopage0->read(0xD65B - 0xC000) << 16); + break; + } + } + else if (adj_addr >= 0xD660 && adj_addr < 0xD670) + { + // Interrupt Registers + logerror("Interrupt Register Write: %04X with %02X\n", adj_addr, data); + switch (adj_addr) + { + case 0xD660: + // int_pending_0 + old = m_interrupt_reg[0]; + combo = old & data; + if (combo > 0) + { + m_interrupt_reg[0] = old & ~combo; + } + + break; + case 0xD661: + // int_pending_1 + old = m_interrupt_reg[1]; + combo = old & data; + if (combo > 0) + { + m_interrupt_reg[1] = old & ~combo; + } + break; + case 0xD662: + // int_pending_2 + old = m_interrupt_reg[2]; + combo = old & data; + if (combo > 0) + { + m_interrupt_reg[2] = old & ~combo; + } + break; + case 0xD663: + break; + case 0xD664: + // int_polarity_0 + m_interrupt_polarity[0] = data; + break; + case 0xD665: + // int_polarity_1 + m_interrupt_polarity[1] = data; + break; + case 0xD666: + // int_polarity_2 + m_interrupt_polarity[2] = data; + break; + case 0xD667: + break; + case 0xD668: + // int_edge_0 + m_interrupt_edge[0] = data; + break; + case 0xD669: + // int_edge_1 + m_interrupt_edge[1] = data; + break; + case 0xD66A: + // int_edge_2 + m_interrupt_edge[2] = data; + break; + case 0xD66B: + break; + case 0xD66C: + m_interrupt_masks[0] = data; + break; + case 0xD66D: + m_interrupt_masks[1] = data; + break; + case 0xD66E: + m_interrupt_masks[2] = data; + break; + case 0xD66F: + break; + + } + if (m_interrupt_reg[0] == 0 && m_interrupt_reg[1] == 0 && m_interrupt_reg[2] == 0) + { + logerror("Clearing Interrupt Line\n"); + m_maincpu->set_input_line(M6502_IRQ_LINE, CLEAR_LINE); + } + } + //IEC - 0xD680 is not writable + else if (adj_addr >= 0xD680 && adj_addr < 0xD682) + { + logerror("Writing to IEC reg %X %02X\n", adj_addr, data); + if (adj_addr == 0xD681) + { + m_iec_out = data; + // Bit 6 is RESET + // m_iec->host_reset_w((data & 0x40) >> 6); + + // // distribute these to the IEC bus + // m_iec->host_clk_w((data & 2) >> 1); + // m_iec->host_data_w(data & 1); + // m_iec->host_atn_w((data & 0x10) >> 4); + // m_iec->host_srq_w((data & 0x80) >> 7); + + // fake the bus + m_iec_in &= 0xFE; + m_iec_in |= (data & 1); + } + } + else if (adj_addr >= 0xD690 && adj_addr < 0xD6A0) + { + // RTC + logerror("RTC Write %04X %02X\n", adj_addr, data); + m_rtc->write(adj_addr - 0xDC90, data); + } + else if (adj_addr >= 0xD6A0 && adj_addr < 0xD6A7) + { + // RNG + logerror("RNG Write %04X %02X\n", adj_addr, data); + switch (adj_addr) + { + case 0xD6A1: + // mix the PSG or SID based on the value + m_iopage0->write(0xD6A1 - 0xC000, data); + if ((data & 4) == 0) + { + // PSG mix - both outputs to both speakers + m_sn0->reset_routes(); + m_sn1->reset_routes(); + m_sn0->add_route(ALL_OUTPUTS, "lspeaker", 0.5); + m_sn0->add_route(ALL_OUTPUTS, "rspeaker", 0.5); + m_sn1->add_route(ALL_OUTPUTS, "lspeaker", 0.5); + m_sn1->add_route(ALL_OUTPUTS, "rspeaker", 0.5); + } + else + { + // PSG0 to left, PSG1 to right + m_sn0->reset_routes(); + m_sn1->reset_routes(); + m_sn0->add_route(ALL_OUTPUTS, "lspeaker", 1.0); + m_sn1->add_route(ALL_OUTPUTS, "rspeaker", 1.0); + } + if ((data & 8) == 0) + { + // SID mix - + m_sid0->reset_routes(); + m_sid1->reset_routes(); + m_sid0->add_route(ALL_OUTPUTS, "lspeaker", 0.5); + m_sid0->add_route(ALL_OUTPUTS, "rspeaker", 0.5); + m_sid1->add_route(ALL_OUTPUTS, "lspeaker", 0.5); + m_sid1->add_route(ALL_OUTPUTS, "rspeaker", 0.5); + } + else + { + m_sid0->reset_routes(); + m_sid1->reset_routes(); + m_sid0->add_route(ALL_OUTPUTS, "lspeaker", 1.0); + m_sid1->add_route(ALL_OUTPUTS, "rspeaker", 1.0); + } + break; + case 0xD6A4: + m_seed &= 0xFF00; // zero the low byte + m_seed |= data; // set the low byte + break; + case 0xD6A5: + m_seed &= 0xFF; // zero the high byte + m_seed |= (data << 8); // set the high byte + break; + case 0xD6A6: + m_rng_enabled = (data & 1); + if ((data & 2) != 0) + { + srand(m_seed); + } + break; + } + } + // mouse registers + // else if (adj_addr >= 0xD6E0 && adj_addr < 0xD6E9) + // { + // switch (adj_addr) + // { + // case 0xD6E0: + // m_mouse_enabled = (data & 1) != 0; + // m_mouse_mode = (data >> 1) & 1; + // break; + // case 0xD6E2: + // // keep the high byte + // m_mouse_x &= 0xFF00; + // m_mouse_x |= data; + // break; + // case 0xD6E3: + // // keep the low byte + // m_mouse_x &= 0xFF; + // m_mouse_x |= data << 8; + // break; + // case 0xD6E4: + // // keep the high byte + // m_mouse_y &= 0xFF00; + // m_mouse_y |= data; + // break; + // case 0xD6E5: + // // keep the low byte + // m_mouse_y &= 0xFF; + // m_mouse_y |= data << 8; + // break; + + // default: + // break; + // } + // } + else if (adj_addr >= 0xD880 && adj_addr < 0xD8C0) + { + // NES - only address 0xD8800 is writable + } + else if (adj_addr >= 0xDB00 && adj_addr < 0xDC00) + { + // VIA1 - Keyboard for F256K + m_via6522_1->write(adj_addr - 0xDB00, data); + } + else if (adj_addr >= 0xDC00 && adj_addr < 0xDD00) + { + // VIA0 - Atari Joystick + m_via6522_0->write(adj_addr - 0xDC00, data); + } + else if (adj_addr >= 0xDD00 && adj_addr < 0xDD20) + { + // SD Card + switch(adj_addr - 0xDD00) + { + case 0: + // When bit is set, clock is 400kHz - 0= 12.5 MHz + //logerror("Write SD 0: %02X\n", data); + m_spi_clock_sysclk = bool(BIT(data, 1)); + spi_sd_enabled = BIT(data, 0); + break; + case 1: + if (m_spi_clock_cycles == 0) + { + //logerror("Write SD 1: %02X\n", data); + m_out_latch = data; + if (spi_sd_enabled) + { + m_spi_clock_cycles = 8; + m_sdcard->spi_ss_w(spi_sd_enabled); + if (m_spi_clock_sysclk) + m_spi_clock->adjust(attotime::from_hz(XTAL(400'000)), 0, attotime::from_hz(XTAL(400'000))); + else + m_spi_clock->adjust(attotime::from_hz(XTAL(12'500'000)), 0, attotime::from_hz(XTAL(12'500'000))); + } + } + else + { + logerror("SD card is busy - refusing to write\n"); + } + break; + } + + // - F256K2c + // $DD00 - $DD1F - SDCARD0 + // $DD20 - $DD3F - SDCARD1 *** This one has moved *** + // $DD40 - $DD5F - SPLASH LCD (SPI Port) + // $DD60 - $DD7F - Wiznet Copper SPI Interface + // $DD80 - $DD9F - Wiznet WIFI UART interface (115K or 2M) + // $DDA0 - $DDBF - MIDI UART (Fixed @ 31,250Baud) + // $DDC0 - $DDDF - Master SPI Interface to Supervisor (RP2040)* + } + else if (adj_addr >= 0xDE00 && adj_addr < 0xDE20) + { + // Math Coprocessor - 4 blocks + u8 block = (adj_addr - 0xDE00) >> 2; + if (adj_addr < 0xDE10) + { + m_iopage0->write(adj_addr - 0xC000, data); + } + switch (block) + { + case 0: + unsignedMultiplier(0xDE00 - 0xC000); + break; + case 1: + unsignedDivider(0xDE04 - 0xC000); + break; + case 2: + case 3: + unsignedAdder(0xDE08 - 0xC000); + break; + } + } + else if (adj_addr >= 0xDF00 && adj_addr < 0xE000) + { + // DMA + logerror("DMA Write %04X %02X\n", adj_addr, data); + m_iopage0->write(adj_addr - 0xC000, data); + if ((adj_addr - 0xDF00) == 0) + { + // control register - when start and enabled are set start DMA operation + if ((data & 0x81) == 0x81) + { + bool fill = data & 0x4; + bool tfr_2d = data & 0x2; + // set to busy + m_dma_status = 0x80; + if (fill) + { + if (tfr_2d) + perform2DFillDMA(); + else + performLinearFillDMA(); + } + else + { + if (tfr_2d) + perform2DDMA(); + else + performLinearDMA(); + } + // set to not busy + m_dma_status = 0x0; + // check if an interrupt needs to be raised + if ((data & 0x8) != 0) + { + dma_interrupt_handler(1); + } + } + } + } + // stick everything else in Vicky + // (adj_addr >= 0xC000 && adj_addr < 0xD400) || // gamma, mouse graphics, vicky registers, bitmaps, tiles + // (adj_addr >= 0xD800 && adj_addr < 0xD880) || // text colors + // (adj_addr >= 0xD900 && adj_addr < 0xDB00) // sprite registers + else + { + m_iopage0->write(adj_addr - 0xC000, data); + } + + break; + case 1: + m_iopage1->write(adj_addr - 0xC000, data); + break; + case 2: + m_iopage2->write(adj_addr - 0xC000, data); + break; + case 3: + m_iopage3->write(adj_addr - 0xC000, data); + break; + } + } + else + { + offs_t address = (bank << 13) + low_addr; + m_ram->write(address, data); + } + } + else + { + offs_t address = (bank << 13) + low_addr; + m_ram->write(address, data); + } + } +} +void f256_state::codec_done(s32 param) +{ + m_codec[2] = 0; +} +void f256_state::reset_mmu() +{ + logerror("reset_mmu\n"); + for (int i =0; i < 32; i++) + { + if (i % 8 == 7) + { + mmu_lut[i]= 0x7f; + } + else + { + mmu_lut[i] = i % 8; + } + } +} + + +//------------------------------------------------- +// IEC Methods +//------------------------------------------------- +inline void f256_state::update_iec() +{ + // int fsdir = m_mmu->fsdir_r(); + + // fast serial data in + //int data_in = m_iec->data_r(); + + // m_cia1->sp_w(fsdir || data_in); + + // fast serial data out + //int data_out = !m_iec_data_out; + + //if (fsdir) data_out &= m_sp1; + + //m_iec->host_data_w(data_out); + + // fast serial clock in + // m_cia1->cnt_w(fsdir || m_iec_srq); + + // fast serial clock out + //int srq_out = m_iec_srq; + + // if (fsdir) srq_out &= m_cnt1; + + //m_iec->host_srq_w(srq_out); +} + +void f256_state::iec_srq_w(int state) +{ + logerror("Event iec_srq_w: %X\n", state); + + m_iec_srq = state; + + if (state && ((m_interrupt_masks[2] & 0x8) == 0)) + { + m_interrupt_reg[2] |= 0x8; + m_maincpu->set_input_line((m_iec_out & 0x20) !=0 ? M6502_NMI_LINE:M6502_IRQ_LINE, state); + } + + update_iec(); +} +void f256_state::iec_data_w(int state) +{ + logerror("Event iec_data_w: %X\n", state); + + if (state && ((m_interrupt_masks[2] & 0x1) == 0)) + { + m_interrupt_reg[2] |= 0x1; + m_maincpu->set_input_line((m_iec_out & 0x20) !=0 ? M6502_NMI_LINE:M6502_IRQ_LINE, state); + } + update_iec(); +} +void f256_state::iec_atn_w(int state) +{ + logerror("Event iec_atn_w: %X\n", state); + if (state && ((m_interrupt_masks[2] & 0x4) == 0)) + { + m_interrupt_reg[2] |= 0x4; + m_maincpu->set_input_line((m_iec_out & 0x20) !=0 ? M6502_NMI_LINE:M6502_IRQ_LINE, state); + } +} +void f256_state::iec_clk_w(int state) +{ + logerror("Event iec_clk_w: %X\n", state); + if (state && ((m_interrupt_masks[2] & 0x2) == 0)) + { + m_interrupt_reg[2] |= 0x2; + m_maincpu->set_input_line((m_iec_out & 0x20) !=0 ? M6502_NMI_LINE:M6502_IRQ_LINE, state); + } +} +//------------------------------------------------- +// Math Coprocessor Methods +//------------------------------------------------- +void f256_state::unsignedMultiplier(int baseAddr) +{ + uint16_t acc1 = (m_iopage0->read(baseAddr + 1) << 8) + m_iopage0->read(baseAddr); + uint16_t acc2 = (m_iopage0->read(baseAddr + 3) << 8) + m_iopage0->read(baseAddr + 2); + m_multiplication_result = acc1 * acc2; +} + +void f256_state::unsignedDivider(int baseAddr) +{ + uint16_t acc1 = (m_iopage0->read(baseAddr + 1) << 8) + m_iopage0->read(baseAddr); + uint16_t acc2 = (m_iopage0->read(baseAddr + 3) << 8) + m_iopage0->read(baseAddr + 2); + if (acc1 != 0) + { + m_division_result= acc2 / acc1; + m_division_remainder = acc2 % acc1; + } +} + +void f256_state::unsignedAdder(int baseAddr) +{ + int acc1 = (m_iopage0->read(baseAddr + 3) << 24) + (m_iopage0->read(baseAddr + 2) << 16) + + (m_iopage0->read(baseAddr + 1) << 8) + m_iopage0->read(baseAddr); + int acc2 = (m_iopage0->read(baseAddr + 7) << 24) + (m_iopage0->read(baseAddr + 6) << 16) + + (m_iopage0->read(baseAddr + 5) << 8) + m_iopage0->read(baseAddr + 4); + m_addition_result = acc1 + acc2; +} + +//------------------------------------------------- +// DMA Methods +//------------------------------------------------- +uint8_t f256_state::get_random() +{ + uint8_t m_random = rand(); + return m_random & 0xFF; +} +//------------------------------------------------- +// DMA Methods +//------------------------------------------------- +void f256_state::perform2DFillDMA() +{ + + uint8_t fill_byte = m_iopage0->read(0xDF01 - 0xC000); + uint32_t dest_addr = ((m_iopage0->read(0xDF0A) & 0x7) << 16) + (m_iopage0->read(0xDF09) << 8) + m_iopage0->read(0xDF08); + uint16_t width_2D = (m_iopage0->read(0xDF0D - 0xC000) << 8) + m_iopage0->read(0xDF0C - 0xC000); + uint16_t height_2D = (m_iopage0->read(0xDF0F - 0xC000) << 8) + m_iopage0->read(0xDF0E - 0xC000); + uint16_t dest_stride = (m_iopage0->read(0xDF13 - 0xC000) << 8) + m_iopage0->read(0xDF12 - 0xC000); + //logerror("2D Fill DMA: DEST: %X, W: %X, H: %X\n", dest_addr, width_2D, height_2D); + for (int y = 0; y < height_2D; y++) + { + for (int x = 0; x < width_2D; x++) + { + m_ram->write(dest_addr + x + y * dest_stride, fill_byte); + } + } +} +void f256_state::performLinearFillDMA() +{ + uint8_t fill_byte = m_iopage0->read(0xDF01 - 0xC000); + uint32_t dest_addr = ((m_iopage0->read(0xDF0A) & 0x7) << 16) + (m_iopage0->read(0xDF09) << 8) + m_iopage0->read(0xDF08); + uint32_t count = ((m_iopage0->read(0xDF0E) & 0x7) << 16) + (m_iopage0->read(0xDF0D) << 8) + m_iopage0->read(0xDF0C); + //logerror("Linear Fill DMA DEST: %X, LEN: %X\n", dest_addr, count); + memset(m_ram->pointer() + dest_addr, fill_byte, count); +} +void f256_state::perform2DDMA() +{ + uint32_t src_addr = ((m_iopage0->read(0xDF06) & 0x7) << 16) + (m_iopage0->read(0xDF05) << 8) + m_iopage0->read(0xDF04); + uint32_t dest_addr = ((m_iopage0->read(0xDF0A) & 0x7) << 16) + (m_iopage0->read(0xDF09) << 8) + m_iopage0->read(0xDF08); + uint16_t width_2D = (m_iopage0->read(0xDF0D - 0xC000) << 8) + m_iopage0->read(0xDF0C - 0xC000); + uint16_t height_2D = (m_iopage0->read(0xDF0F - 0xC000) << 8) + m_iopage0->read(0xDF0E - 0xC000); + uint16_t src_stride = (m_iopage0->read(0xDF11 - 0xC000) << 8) + m_iopage0->read(0xDF10 - 0xC000); + uint16_t dest_stride = (m_iopage0->read(0xDF13 - 0xC000) << 8) + m_iopage0->read(0xDF12 - 0xC000); + //logerror("2D Copy DMA, SRC: %X, DEST: %X, W: %X H: %X, SRC_STR: %X, DEST_STR: %X\n", src_addr, dest_addr, + // width_2D, height_2D, src_stride, dest_stride); + for (int y = 0; y < height_2D; y++) + { + for (int x = 0; x < width_2D; x++) + { + uint8_t src_byte = m_ram->read(src_addr + x + y * src_stride); + m_ram->write(dest_addr + x + y * dest_stride, src_byte); + } + } +} +void f256_state::performLinearDMA() +{ + uint32_t src_addr = ((m_iopage0->read(0xDF06) & 0x7) << 16) + (m_iopage0->read(0xDF05) << 8) + m_iopage0->read(0xDF04); + uint32_t dest_addr = ((m_iopage0->read(0xDF0A) & 0x7) << 16) + (m_iopage0->read(0xDF09) << 8) + m_iopage0->read(0xDF08); + uint32_t count = ((m_iopage0->read(0xDF0E) & 0x7) << 16) + (m_iopage0->read(0xDF0D) << 8) + m_iopage0->read(0xDF0C); + //logerror("Linear Copy DMA SRC: %X, DEST: %X, LEN: %X\n", src_addr, dest_addr, count); + memcpy(m_ram->pointer() + dest_addr, m_ram->pointer() + src_addr, count); +} + + +//------------------------------------------------- +// device_start +//------------------------------------------------- +void f256_state::device_start() +{ + driver_device::device_start(); + reset_mmu(); + // TODO: Copy the font from file to IO Page 1 + //memcpy(m_iopage1, m_font, 0x800); + for (int i=0;i<0x800;i++) + { + m_iopage1->write(i, m_font->as_u8(i)); + } + // Copy the gamma correction table + uint8_t gamma_1_8[] = { + 0x00, 0x0b, 0x11, 0x15, 0x19, 0x1c, 0x1f, 0x22, 0x25, 0x27, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, + 0x36, 0x38, 0x3a, 0x3c, 0x3d, 0x3f, 0x41, 0x43, 0x44, 0x46, 0x47, 0x49, 0x4a, 0x4c, 0x4d, 0x4f, + 0x50, 0x51, 0x53, 0x54, 0x55, 0x57, 0x58, 0x59, 0x5b, 0x5c, 0x5d, 0x5e, 0x60, 0x61, 0x62, 0x63, + 0x64, 0x65, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, + 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x84, + 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, + 0x94, 0x95, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0x9f, 0xa0, + 0xa1, 0xa2, 0xa3, 0xa3, 0xa4, 0xa5, 0xa6, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xaa, 0xab, 0xac, 0xad, + 0xad, 0xae, 0xaf, 0xb0, 0xb0, 0xb1, 0xb2, 0xb3, 0xb3, 0xb4, 0xb5, 0xb6, 0xb6, 0xb7, 0xb8, 0xb8, + 0xb9, 0xba, 0xbb, 0xbb, 0xbc, 0xbd, 0xbd, 0xbe, 0xbf, 0xbf, 0xc0, 0xc1, 0xc2, 0xc2, 0xc3, 0xc4, + 0xc4, 0xc5, 0xc6, 0xc6, 0xc7, 0xc8, 0xc8, 0xc9, 0xca, 0xca, 0xcb, 0xcc, 0xcc, 0xcd, 0xce, 0xce, + 0xcf, 0xd0, 0xd0, 0xd1, 0xd2, 0xd2, 0xd3, 0xd4, 0xd4, 0xd5, 0xd6, 0xd6, 0xd7, 0xd7, 0xd8, 0xd9, + 0xd9, 0xda, 0xdb, 0xdb, 0xdc, 0xdc, 0xdd, 0xde, 0xde, 0xdf, 0xe0, 0xe0, 0xe1, 0xe1, 0xe2, 0xe3, + 0xe3, 0xe4, 0xe4, 0xe5, 0xe6, 0xe6, 0xe7, 0xe7, 0xe8, 0xe9, 0xe9, 0xea, 0xea, 0xeb, 0xec, 0xec, + 0xed, 0xed, 0xee, 0xef, 0xef, 0xf0, 0xf0, 0xf1, 0xf1, 0xf2, 0xf3, 0xf3, 0xf4, 0xf4, 0xf5, 0xf5, + 0xf6, 0xf7, 0xf7, 0xf8, 0xf8, 0xf9, 0xf9, 0xfa, 0xfb, 0xfb, 0xfc, 0xfc, 0xfd, 0xfd, 0xfe, 0xff + }; + + memcpy(m_iopage0->pointer(), gamma_1_8, 256); + memcpy(m_iopage0->pointer() + 0x400, gamma_1_8, 256); + memcpy(m_iopage0->pointer() + 0x800, gamma_1_8, 256); + m_video->set_videoram(m_ram->pointer(), m_iopage0->pointer(), m_iopage1->pointer(), m_iopage2->pointer(), m_iopage3->pointer()); + m_video->start(); + + // set the current time on the RTC device + time_t now; + time(&now); + system_time stnow = system_time(now); + + m_rtc->set_current_time(stnow); + + // Initialize the VIA0 + m_via6522_0->write(via6522_device::VIA_DDRB, 0xFF); // DDRB + m_via6522_0->write(via6522_device::VIA_DDRA, 0xFF); // DDRA + m_via6522_0->write(via6522_device::VIA_PB, 0xFF); // JOYSTICK 2 + m_via6522_0->write(via6522_device::VIA_PA, 0xFF); // JOYSTICK 1 + m_via6522_0->write(via6522_device::VIA_DDRB, 0); // DDRB + m_via6522_0->write(via6522_device::VIA_DDRA, 0); // DDRA + + // Initialize the VIA1 + m_via6522_1->write(via6522_device::VIA_PB, 0); + m_via6522_1->write(via6522_device::VIA_PA, 0); + m_via6522_1->write(via6522_device::VIA_DDRB, 0); // DDRB + m_via6522_1->write(via6522_device::VIA_DDRA, 0); // DDRA + + // Initialize SD Card / SPI clock + m_spi_clock = timer_alloc(FUNC(f256_state::spi_clock), this); + save_item(NAME(m_spi_clock_state)); + save_item(NAME(m_spi_clock_sysclk)); + save_item(NAME(m_spi_clock_cycles)); + save_item(NAME(m_in_bit)); + save_item(NAME(m_in_latch)); + save_item(NAME(m_out_latch)); + save_item(NAME(m_iec_srq)); + + m_timer0 = timer_alloc(FUNC(f256_state::timer0), this); + m_timer1 = timer_alloc(FUNC(f256_state::timer1), this); +} + +//------------------------------------------------- +// device_reset +//------------------------------------------------- +void f256_state::device_reset() +{ + driver_device::device_reset(); + reset_mmu(); + m_via6522_0->reset(); + m_via6522_1->reset(); + + m_opl3->reset(); + m_sdcard->reset(); + m_spi_clock->adjust(attotime::never); + m_spi_clock_cycles = 0; + m_in_bit = 0; + m_spi_clock_state = false; + spi_sd_enabled = 0; + m_mouse->reset(); + + m_sid0->reset(); + m_sid1->reset(); + m_sn0->reset(); + m_sn1->reset(); + //m_iec->reset(); + m_uart->reset(); + + m_timer0_load = 0; + m_timer0_val = 0; + m_timer1_load = 0; + m_timer1_val = 0; +} + +//------------------------------------------------- +// Interrupts +//------------------------------------------------- +void f256_state::sof_interrtupt(int state) +{ + if (state) // && ((m_interrupt_masks[1] & 0x01) == 0)) + { + //logerror("SOF INTERRUPT: %02X\n", state); + m_interrupt_reg[0] |= 0x01; + m_maincpu->set_input_line(M6502_IRQ_LINE, state); + } +} +void f256_state::sol_interrtupt(int state) +{ + if (state && ((m_interrupt_masks[1] & 0x02) == 0)) + { + logerror("SOL INTERRUPT: %02X\n", state); + m_interrupt_reg[0] |= 0x02; + m_maincpu->set_input_line(M6502_IRQ_LINE, state); + } +} +void f256_state::rtc_interrupt_handler(int state) +{ + // this is really odd: if I set state==1, then the interrupt gets only called once. + if (state == 0 && ((m_interrupt_masks[1] & 0x10) == 0)) + { + logerror("RTC INTERRUPT: %02X:%02X:%02X\n", m_rtc->read(4), m_rtc->read(2), m_rtc->read(0)); + m_interrupt_reg[1] |= 0x10; + m_maincpu->set_input_line(M6502_IRQ_LINE, state); + } +} + +void f256_state::via0_interrupt(int state) +{ + // if a joystick button is pressed, set the VIA0 interrupt if the mask allows if + if (state && ((m_interrupt_masks[1] & 0x20) == 0)) + { + logerror("VIA0 INTERRUPT: %02X\n", state); + m_interrupt_reg[1] |= 0x20; + m_maincpu->set_input_line(M6502_IRQ_LINE, state); + } +} +void f256_state::via1_interrupt(int state) +{ + // if a keyboard button is pressed, set the VIA1 interrupt if the mask allows if + if (state && ((m_interrupt_masks[1] & 0x40) == 0)) + { + logerror("VIA1 INTERRUPT: %02X\n", state); + m_interrupt_reg[1] |= 0x40; + m_maincpu->set_input_line(M6502_IRQ_LINE, state); + } +} +void f256_state::dma_interrupt_handler(int state) +{ + // if (state && ((m_interrupt_masks[1] & 0x10) == 0)) + // { + // logerror("DMA Interrupt Not implemented!"); + // m_interrupt_reg[1] |= 0x10; + // m_maincpu->set_input_line(M6502_IRQ_LINE, state); + // } +} +void f256_state::timer0_interrupt_handler(int state) +{ + if (state && ((m_interrupt_masks[0] & 0x10) == 0)) + { + logerror("TIMER0 INTERRUPT: %02X\n", state); + m_interrupt_reg[0] |= 0x10; + m_maincpu->set_input_line(M6502_IRQ_LINE, state); + } +} +void f256_state::timer1_interrupt_handler(int state) +{ + logerror("Timer1 interrupt handler %d\n", state); + if (state && ((m_interrupt_masks[0] & 0x20) == 0)) + { + logerror("TIMER1 INTERRUPT: %02X\n", state); + m_interrupt_reg[0] |= 0x20; + m_maincpu->set_input_line(M6502_IRQ_LINE, state); + } +} +TIMER_CALLBACK_MEMBER(f256_state::spi_clock) +{ + + if (m_spi_clock_cycles > 0) + { + + if (m_spi_clock_state) + { + m_sdcard->spi_clock_w(1); + m_spi_clock_cycles--; + } + else + { + m_sdcard->spi_mosi_w(BIT(m_out_latch, 7)); + m_sdcard->spi_clock_w(0); + m_out_latch <<= 1; + } + // toggle the clock signal + m_spi_clock_state = !m_spi_clock_state; + } + else + { + m_spi_clock_state = false; + m_spi_clock->adjust(attotime::never); + } +} + +// This is the optimized function for Timer0 +TIMER_CALLBACK_MEMBER(f256_state::timer0) +{ + logerror("Timer0 reached value: %06X\n", m_timer0_load); + uint8_t reg_t0 = m_iopage0->read(0xD650 - 0xC000); + if ((reg_t0 & 0x80) !=0) + { + timer0_interrupt_handler(1); + } +} +// TIMER_CALLBACK_MEMBER(f256_state::timer0) +// { +// uint8_t reg_t0 = m_iopage0->read(0xD650 - 0xC000); +// uint32_t cmp = m_iopage0->read(0xD655 - 0xC000) + (m_iopage0->read(0xD656 - 0xC000) << 8) + +// (m_iopage0->read(0xD657 - 0xC000) << 16); + +// // if timer as reached value, then execute the action +// if (m_timer0_eq == 1) +// { +// int8_t action = m_iopage0->read(0xD654 - 0xC000); +// if (action & 1) +// { +// logerror("TIMER0 Cleared\n"); +// m_timer0_val = 0; +// } +// else +// { +// m_timer0_val = m_timer0_load; +// logerror("TIMER0 Reloaded with: %X\n", m_timer0_val); +// } +// m_timer0_eq = 0; +// } +// else +// { +// if ((reg_t0 & 8) != 0) +// { +// // up +// m_timer0_val++; + +// // it's a 24 bit register +// if (m_timer0_val == 0x100'0000) +// { +// m_timer0_val = 0; +// } + +// if (m_timer0_val == cmp) +// { +// m_timer0_eq = 1; +// logerror("TIMER0 up value reached %X\n", cmp); +// } + +// } +// else +// { +// // down +// m_timer0_val--; +// // roll over to 24 bits +// if (m_timer0_val == 0xFFFF'FFFF) +// { +// m_timer0_val = 0xFF'FFFF; +// } +// if (m_timer0_val == cmp) +// { +// m_timer0_eq = 1; +// logerror("TIMER0 down value reached %X\n", cmp); +// } +// } +// if (m_timer0_eq == 1 && (reg_t0 & 0x80) !=0) +// { +// timer0_interrupt_handler(1); +// } +// } +// } + + +// This timer is much slower than Timer0, so we can use single increments +TIMER_CALLBACK_MEMBER(f256_state::timer1) +{ + uint8_t reg_t1 = m_iopage0->read(0xD658 - 0xC000); + uint32_t cmp = m_iopage0->read(0xD65D - 0xC000) + (m_iopage0->read(0xD65E - 0xC000) << 8) + + (m_iopage0->read(0xD65F - 0xC000) << 16); + logerror("TIMER1 event %06X CMP: %06X\n", m_timer1_val, cmp); + // if timer as reached value, then execute the action + if (m_timer1_eq == 1) + { + int8_t action = m_iopage0->read(0xD65C - 0xC000); + if (action & 1) + { + logerror("TIMER1 Cleared\n"); + m_timer1_val = 0; + } + else + { + m_timer1_val = m_timer1_load; + logerror("TIMER1 Reloaded with %X\n", m_timer1_val); + } + m_timer1_eq = 0; + } + else + { + if ((reg_t1 & 8) != 0) + { + // up + m_timer1_val++; + + // it's a 24 bit register + if (m_timer1_val == 0x100'0000) + { + m_timer1_val = 0; + } + + if (m_timer1_val == cmp) + { + m_timer1_eq = 1; + logerror("TIMER1 up value reached %X\n", cmp); + } + + } + else + { + // down + m_timer1_val--; + // roll over to 24 bits + if (m_timer1_val == 0xFFFF'FFFF) + { + m_timer1_val = 0xFF'FFFF; + } + if (m_timer1_val == cmp) + { + m_timer1_eq = 1; + logerror("TIMER1 up value reached %X\n", cmp); + } + } + if (m_timer1_eq == 1 && (reg_t1 & 0x80) !=0) + { + timer1_interrupt_handler(1); + } + } +} + +//------------------------------------------------- +// VIA0 - JOYSTICK +//------------------------------------------------- +u8 f256_state::via0_system_porta_r() +{ + //logerror("VIA #0 Port A Read ioport JOY2: %02X\n", data); + return ioport("JOY2")->read(); +} +u8 f256_state::via0_system_portb_r() +{ + //logerror("VIA #0 Port B Read ioport JOY1: %02X\n", m_via_joy1); + return m_via_joy1; +} +void f256_state::via0_system_porta_w(u8 data) +{ + //logerror("VIA #0 Port A Write: %02X\n", data); + // writing should only be done if DDR allows it + m_via6522_0->write_pa(data); +} +void f256_state::via0_system_portb_w(u8 data) +{ + //logerror("VIA #0 Port B Write: %02X\n", data); + // writing should only be done if DDR allows it + m_via6522_0->write_pb(data); +} +void f256_state::via0_ca2_write(u8 value) +{ + //logerror("Write to VIA0 - CA2 %02X\n", value); + m_via6522_0->write_ca2(value); +} +void f256_state::via0_cb2_write(u8 value) +{ + //logerror("Write to VIA0 - CB2 %02X\n", value); + m_via6522_0->write_cb2(value); +} + +static INPUT_PORTS_START(f256k_mouse) + PORT_START("MOUSE_X") + PORT_BIT(0xff, 0, IPT_MOUSE_X) PORT_SENSITIVITY(50) PORT_KEYDELTA(10) + + PORT_START("MOUSE_Y") + PORT_BIT(0xff, 0, IPT_MOUSE_Y) PORT_SENSITIVITY(50) PORT_KEYDELTA(10) + + PORT_START("MOUSE_BUTTONS") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_NAME("Left Button") + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_BUTTON2) PORT_NAME("Right Button") +INPUT_PORTS_END + +static INPUT_PORTS_START(f256k_joysticks) + PORT_START("JOY1") /* Atari Joystick 1 */ + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP) PORT_8WAY PORT_PLAYER(1) PORT_NAME("Atari Joystick P1 Up") + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN) PORT_8WAY PORT_PLAYER(1) PORT_NAME("Atari Joystick P1 Down") + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT) PORT_8WAY PORT_PLAYER(1) PORT_NAME("Atari Joystick P1 Left") + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT) PORT_8WAY PORT_PLAYER(1) PORT_NAME("Atari Joystick P1 Right") + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_PLAYER(1) PORT_NAME("Atari Joystick P1 Button 1") + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_BUTTON2) PORT_PLAYER(1) PORT_NAME("Atari Joystick P1 Button 2") + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_BUTTON3) PORT_PLAYER(1) PORT_NAME("Atari Joystick P1 Button 3") + + PORT_START("JOY2") /* Atari Joystick 2 */ + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP) PORT_8WAY PORT_PLAYER(2) PORT_NAME("Atari Joystick P2 Up") + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN) PORT_8WAY PORT_PLAYER(2) PORT_NAME("Atari Joystick P2 Down") + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT) PORT_8WAY PORT_PLAYER(2) PORT_NAME("Atari Joystick P2 Left") + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT) PORT_8WAY PORT_PLAYER(2) PORT_NAME("Atari Joystick P2 Right") + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_PLAYER(2) PORT_NAME("Atari Joystick P2 Button 1") + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_BUTTON2) PORT_PLAYER(2) PORT_NAME("Atari Joystick P2 Button 2") + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_BUTTON3) PORT_PLAYER(2) PORT_NAME("Atari Joystick P2 Button 3") +INPUT_PORTS_END + +//------------------------------------------------- +// VIA1 - F256K Keyboard +//------------------------------------------------- +u8 f256_state::via1_system_porta_r() +{ + //logerror("VIA1 Read Port A - %02X\n", m_via_keyboard_port_a); + return m_via_keyboard_port_a; +} +u8 f256_state::via1_system_portb_r() +{ + //logerror("VIA1 Read Port B - %02X\n", m_via_keyboard_port_b); + return m_via_keyboard_port_b; +} +// Read keyboard as rows +void f256_state::via1_system_porta_w(u8 data) +{ + //logerror("VIA1 Write Port A - %02X\n", data); + + m_via_keyboard_port_a = data; + m_via_keyboard_port_b = 0xFF; + // scan each keyboard row + u8 joy1 = ioport("JOY1")->read(); + m_via_joy1 = joy1 | 0x80; + for (int r = 0; r < 8; r++) + { + //if (BIT(m_via_keyboard_port_a,r) == 0) + if (BIT(data, r) == 0) + { + uint16_t kbval = m_keyboard[r]->read(); + m_via_keyboard_port_b &= (kbval & 0xFF); + if (r == 6 || r == 0) + { + if (BIT(kbval,8) == 0) + { + m_via_joy1 = joy1; + //logerror("row: %d, kbval: %02X, joy1: %02X, porta: %02X, portb: %02X\n", r, kbval, m_via_joy1, m_via_keyboard_port_a, m_via_keyboard_port_b); + } + } + } + } + m_via6522_1->write_pa(m_via_keyboard_port_a); + m_via6522_0->write_pb(m_via_joy1); +} +// Read keyboard as columns +void f256_state::via1_system_portb_w(u8 data) +{ + m_via_keyboard_port_b = data; + m_via6522_1->write_pb(data); +} +void f256_state::via1_ca2_write(u8 value) +{ + m_via6522_1->write_ca2(value); +} +void f256_state::via1_cb2_write(u8 value) +{ + m_via6522_1->write_cb2(value); +} + +static INPUT_PORTS_START(f256k) + PORT_INCLUDE( f256k_joysticks ) + PORT_INCLUDE( f256k_mouse ) + + PORT_START("ROW0") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("DEL") PORT_CODE(KEYCODE_DEL) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("ENTER") PORT_CODE(KEYCODE_ENTER) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_LEFT) PORT_CODE(KEYCODE_LEFT) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F7") PORT_CODE(KEYCODE_F7) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F1") PORT_CODE(KEYCODE_F1) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F3") PORT_CODE(KEYCODE_F3) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F5") PORT_CODE(KEYCODE_F5) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_UP) PORT_CODE(KEYCODE_UP) + PORT_BIT(0x100,IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_DOWN) PORT_CODE(KEYCODE_DOWN) + + PORT_START("ROW1") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("3") PORT_CODE(KEYCODE_3) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("W") PORT_CODE(KEYCODE_W) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A") PORT_CODE(KEYCODE_A) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("4") PORT_CODE(KEYCODE_4) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Z") PORT_CODE(KEYCODE_Z) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("S") PORT_CODE(KEYCODE_S) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E") PORT_CODE(KEYCODE_E) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("L SHIFT") PORT_CODE(KEYCODE_LSHIFT) + + PORT_START("ROW2") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("5") PORT_CODE(KEYCODE_5) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("R") PORT_CODE(KEYCODE_R) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D") PORT_CODE(KEYCODE_D) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("6") PORT_CODE(KEYCODE_6) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C") PORT_CODE(KEYCODE_C) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F") PORT_CODE(KEYCODE_F) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("T") PORT_CODE(KEYCODE_T) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("X") PORT_CODE(KEYCODE_X) + + PORT_START("ROW3") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("7") PORT_CODE(KEYCODE_7) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Y") PORT_CODE(KEYCODE_Y) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G") PORT_CODE(KEYCODE_G) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("8") PORT_CODE(KEYCODE_8) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B") PORT_CODE(KEYCODE_B) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("H") PORT_CODE(KEYCODE_H) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("U") PORT_CODE(KEYCODE_U) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("V") PORT_CODE(KEYCODE_V) + + PORT_START("ROW4") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("9") PORT_CODE(KEYCODE_9) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("I") PORT_CODE(KEYCODE_I) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("J") PORT_CODE(KEYCODE_J) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("0") PORT_CODE(KEYCODE_0) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("M") PORT_CODE(KEYCODE_M) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("K") PORT_CODE(KEYCODE_K) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("O") PORT_CODE(KEYCODE_O) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("N") PORT_CODE(KEYCODE_N) + + PORT_START("ROW5") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("-") PORT_CODE(KEYCODE_MINUS) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("P") PORT_CODE(KEYCODE_P) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("L") PORT_CODE(KEYCODE_L) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("CAPS LOCK") PORT_CODE(KEYCODE_CAPSLOCK) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(".") PORT_CODE(KEYCODE_STOP) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(";") PORT_CODE(KEYCODE_COLON) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("[") PORT_CODE(KEYCODE_OPENBRACE) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(",") PORT_CODE(KEYCODE_COMMA) + + PORT_START("ROW6") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("=") PORT_CODE(KEYCODE_EQUALS) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("]") PORT_CODE(KEYCODE_CLOSEBRACE) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("'") PORT_CODE(KEYCODE_QUOTE) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("HOME") PORT_CODE(KEYCODE_HOME) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("R SHIFT") PORT_CODE(KEYCODE_RSHIFT) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("ALT") PORT_CODE(KEYCODE_LALT) PORT_CODE(KEYCODE_RALT) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("TAB") PORT_CODE(KEYCODE_TAB) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("/") PORT_CODE(KEYCODE_SLASH) + PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("RIGHT") PORT_CODE(KEYCODE_RIGHT) + + PORT_START("ROW7") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("1") PORT_CODE(KEYCODE_1) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("BKSP") PORT_CODE(KEYCODE_BACKSPACE) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("2") PORT_CODE(KEYCODE_2) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("SPACE") PORT_CODE(KEYCODE_SPACE) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("FOENIX") PORT_CODE(KEYCODE_LWIN) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Q") PORT_CODE(KEYCODE_Q) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("RUN/STOP") PORT_CODE(KEYCODE_STOP) +INPUT_PORTS_END + +ROM_START(f256k) + ROM_REGION(0x10'0000,ROM_TAG,0) + // Offsets are based on the REGION base address - offset by 0x10 because of map. + ROM_LOAD("xdev.bin", 0x08'2000, 0x2000, CRC(5cee0cb0) SHA1(a5fb10ad914069f506847150bdd387371e73f1de)) + ROM_LOAD("sb01.bin", 0x08'4000, 0x2000, CRC(21f06e73) SHA1(bbeefb52d4b126b61367169c21599180f3358af7)) + ROM_LOAD("sb02.bin", 0x08'6000, 0x2000, CRC(6ed611b9) SHA1(4a03aa286f6274e6974a3cecdedad651a58f5fb1)) + ROM_LOAD("sb03.bin", 0x08'8000, 0x2000, CRC(653f849d) SHA1(65942d98f26b86499e6359170aa2d0c6e16124ff)) + ROM_LOAD("sb04.bin", 0x08'A000, 0x2000, CRC(f4aa6049) SHA1(11f02fee6ec412f0c96b27b0b149f72cf1770d15)) + ROM_LOAD("dos.bin", 0x08'C000, 0x2000, CRC(f3673c4e) SHA1(9c6b70067d7195d4a6bbd7f379b8e5382bf8cc1b)) + ROM_LOAD("pexec.bin", 0x08'E000, 0x2000, CRC(937c1374) SHA1(40566a51d2ef7321a42fe926b03dee3571c78202)) + ROM_LOAD("3b.bin", 0x0F'6000, 0x2000, CRC(7c5d2f27) SHA1(bd1ece74b02a210cfe5a1ed15a0febefc39a1861)) + ROM_LOAD("3c.bin", 0x0F'8000, 0x2000, CRC(2e2295d1) SHA1(9049b83d4506b49701669c335ded2879c7992751)) + ROM_LOAD("3d.bin", 0x0F'A000, 0x2000, CRC(97743cb7) SHA1(693fa7762528eca6a75c9ea30a603dadc4d55cf9)) + ROM_LOAD("3e.bin", 0x0F'C000, 0x2000, CRC(9012398f) SHA1(4ae1e37aa3ad4c2b498bf1797d591d7fa25a9d43)) + ROM_LOAD("3f.bin", 0x0F'E000, 0x2000, CRC(b9ddda5e) SHA1(2f21ef84a269cc2ed25c6441c9451f61dbb5b285)) + ROM_LOAD("docs_superbasic1.bin", 0x09'6000, 0x2000, CRC(ad6398cd) SHA1(d926ae72f8f3af2a0b15ac165bc680db2e647740)) + ROM_LOAD("docs_superbasic2.bin", 0x09'8000, 0x2000, CRC(3cf07824) SHA1(b92e88a99ccf51461f45d317e3e555c5d62792eb)) + ROM_LOAD("docs_superbasic3.bin", 0x09'A000, 0x2000, CRC(838cb5df) SHA1(103b182ad76c185c4a779f4865c48c5fc71e2a14)) + ROM_LOAD("docs_superbasic4.bin", 0x09'C000, 0x2000, CRC(bf7841b9) SHA1(7dcbf77c46d680a1c47ac11ed871b832a1479e8e)) + ROM_LOAD("help.bin", 0x09'4000, 0x2000, CRC(b7d63466) SHA1(bd1dafb5849dee61fd48ece16a409e56de62f464)) + + // Load the file manager application + ROM_LOAD("fm.00", 0x0A'0000, 0x2000, CRC(f877c712) SHA1(18d7b2a484ef6dc2ee4a83b6a4dd28ffc3ffe26f)) + ROM_LOAD("fm.01", 0x0A'2000, 0x2000, CRC(de843f4b) SHA1(f132ebf997a57fd15fcaa51ab9ff9a4aa40183a0)) + ROM_LOAD("fm.02", 0x0A'4000, 0x2000, CRC(9c90cf7d) SHA1(0ed0a09f7bb1eeb0a99141e9d4625d027448b7ea)) + ROM_LOAD("fm.03", 0x0A'6000, 0x2000, CRC(7dfe0934) SHA1(48d2aa2f4c926f7a81e9eab312883e4e573e7cd9)) + ROM_LOAD("fm.04", 0x0A'8000, 0x2000, CRC(3bc5832d) SHA1(5a8491e4c6e4e56e4017ece97615f7eb5aa928e3)) + ROM_LOAD("fm.05", 0x0A'A000, 0x2000, CRC(48dcadc7) SHA1(52e051d5e8446deddfc469f7aed0f18fb2483715)) + ROM_LOAD("fm.06", 0x0A'C000, 0x2000, CRC(035c3c8a) SHA1(649601087b7b95a4f432f362428e98291648434c)) + ROM_LOAD("fm.07", 0x0A'E000, 0x2000, CRC(76f749d4) SHA1(a3e7e881f4c4fd39c94385de2c8d7546a2239d96)) + + ROM_REGION(0x0800,FONT_TAG,0) + ROM_LOAD("f256jr_font_micah_jan25th.bin", 0x0000, 0x0800, CRC(6d66da85) SHA1(377dc27ff3a4ae2d80d740b2d16373f8e639eef6)) +ROM_END + +// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS +COMP( 2024, f256k, 0, 0, f256k, f256k, f256_state, empty_init, "Stefany Allaire", "F256K 8-bit Retro System", MACHINE_UNOFFICIAL ) diff --git a/src/mame/f256/f256.h b/src/mame/f256/f256.h new file mode 100644 index 0000000000000..0ac34d4b15fa0 --- /dev/null +++ b/src/mame/f256/f256.h @@ -0,0 +1,204 @@ +#ifndef MAME_F256_F256_H +#define MAME_F256_F256_H + +#pragma once + +#include "machine/ram.h" +#include "screen.h" +#include "machine/bq4847.h" +#include "machine/6522via.h" +#include "sound/sn76496.h" +#include "sound/ymopl.h" +#include "sound/mos6581.h" +#include "utf8.h" +#include "tiny_vicky.h" +#include "speaker.h" +#include "machine/spi_sdcard.h" +// PS/2 mouse and keyboard +#include "bus/pc_kbd/pc_kbdc.h" +#include "bus/pc_kbd/hle_mouse.h" +#include "debug/debugcon.h" +#include "debugger.h" +//#include "bus/cbmiec/cbmiec.h" +//#include "bus/cbmiec/c1581.h" +#include "machine/ins8250.h" + +#define MASTER_CLOCK (XTAL(25'175'000)) +#define MUSIC_CLOCK (XTAL(14'318'181)) +#define MAINCPU_TAG "maincpu" +#define RAM_TAG "ram" +#define IOPAGE0_TAG "iopage0" +#define IOPAGE1_TAG "iopage1" +#define IOPAGE2_TAG "iopage2" +#define IOPAGE3_TAG "iopage3" +#define ROM_TAG "rom" +#define FONT_TAG "font" +#define FLASH_TAG "flash" +#define VICKY_VIDEO_TAG "vicky" +#define SCREEN_TAG "screen" + +class f256_state : public driver_device +{ +public: + f256_state(const machine_config &mconfig, device_type type, const char *tag); + ~f256_state(); + void f256k(machine_config &config); + +protected: + // device-level overrides + virtual void device_start() override ATTR_COLD; + virtual void device_reset() override ATTR_COLD; + +private: + required_device m_maincpu; + required_device m_ram; + required_device m_iopage0, m_iopage1, m_iopage2, m_iopage3; + required_memory_region m_rom; + required_memory_region m_font; + required_device m_screen; + required_device m_rtc; + required_ioport_array<8> m_keyboard; // the number 8 will require 8 COL + required_device m_via6522_0, m_via6522_1; + required_device m_sn0, m_sn1; + required_device m_opl3; + required_device m_sid0, m_sid1; + + required_device m_video; + //required_device m_iec; + optional_device m_ps2_keyboard; + optional_device m_mouse; + required_device m_uart; + + // SD Card stuff + TIMER_CALLBACK_MEMBER(spi_clock); + required_device m_sdcard; + emu_timer *m_spi_clock; + bool m_spi_clock_state; + bool m_spi_clock_sysclk; + int m_spi_clock_cycles; + int m_in_bit = 0; + u8 spi_sd_enabled = 0; + uint8_t m_in_latch = 0; + uint8_t m_out_latch = 0; + // End of SD Card stuff + + void program_map(address_map &map); + void data_map(address_map &map); + + uint8_t m_mmu_reg, m_ioreg; + uint8_t mmu_lut[32]; + void reset_mmu(); + u8 lut_r(offs_t offset); + void lut_w(offs_t offset, u8 data); + u8 mem_r(offs_t offset); + void mem_w(offs_t offset, u8 data); + + // screen update + void sof_interrtupt(int state); + void sol_interrtupt(int state); + void rtc_interrupt_handler(int state); + void via0_interrupt(int state); + void via1_interrupt(int state); + uint8_t m_interrupt_reg[3] = { 0, 0 ,0}; + uint8_t m_interrupt_masks[3] = { 0xFF, 0xFF, 0xFF}; + uint8_t m_interrupt_edge[3] = { 0xFF, 0xFF, 0xFF}; + uint8_t m_interrupt_polarity[3] = {0, 0, 0}; + + // VIA0 - Atari joystick functions + u8 via0_system_porta_r(); + u8 via0_system_portb_r(); + void via0_system_porta_w(u8 data); + void via0_system_portb_w(u8 data); + void via0_ca2_write(u8 data); + void via0_cb2_write(u8 data); + + // VIA1 - Internal Keyboard + uint8_t m_via_keyboard_port_a = 0xFF; + uint8_t m_via_keyboard_port_b = 0xFF; + uint8_t m_via_joy1 = 0xFF; + + u8 via1_system_porta_r(); + u8 via1_system_portb_r(); + void via1_system_porta_w(u8 data); + void via1_system_portb_w(u8 data); + void via1_ca2_write(u8 data); + void via1_cb2_write(u8 data); + + // codec + uint8_t m_codec[16] = {}; + TIMER_CALLBACK_MEMBER(codec_done); + + // PS/2 + uint8_t m_ps2[16] = {}; + bool isK_WR = false; + bool isM_WR = false; + bool K_AK = false; + bool M_AK = false; + + uint8_t kbPacketCntr = 0; + uint8_t msPacketCntr = 0; + int kbQLen = 0; + int msQLen = 0; + uint8_t kbFifo[6] = {}; + uint8_t msFifo[3] = {}; + + // mouse + // uint16_t m_mouse_x = 0, m_mouse_y = 0; + // bool m_mouse_enabled = false; + // uint8_t m_mouse_mode = 0; + + // SDCard + void write_sd_control(u8 ctrl); + void write_sd_data(u8 data); + + // Math Copro + uint32_t m_multiplication_result = 0; + uint32_t m_addition_result = 0; + uint16_t m_division_result = 0; + uint16_t m_division_remainder = 0; + void unsignedMultiplier(int baseAddr); + void unsignedDivider(int baseAddr); + void unsignedAdder(int baseAddr); + + // Random Number Generator (RNG) + uint16_t m_seed = 0; + bool m_rng_enabled = false; + uint8_t get_random(); + + // DMA + uint8_t m_dma_status = 0; + void perform2DFillDMA(); + void performLinearFillDMA(); + void perform2DDMA(); + void performLinearDMA(); + void dma_interrupt_handler(int state); + + // Timers + uint8_t m_timer0_eq = 0; + uint32_t m_timer0_load = 0; + uint32_t m_timer0_val = 0; + TIMER_CALLBACK_MEMBER(timer0); + emu_timer *m_timer0; + void timer0_interrupt_handler(int state); + + uint8_t m_timer1_eq = 0; + uint32_t m_timer1_load = 0; + uint32_t m_timer1_val = 0; + TIMER_CALLBACK_MEMBER(timer1); + emu_timer *m_timer1; + void timer1_interrupt_handler(int state); + + uint16_t m_opl3_reg = 0; + + // IEC + inline void update_iec(); + void iec_srq_w(int state); + void iec_data_w(int state); + void iec_atn_w(int state); + void iec_clk_w(int state); + int m_iec_data_out; + int m_iec_srq; + uint8_t m_iec_in, m_iec_out; +}; + +#endif // MAME_F256_F256_H diff --git a/src/mame/f256/f256k.md b/src/mame/f256/f256k.md new file mode 100644 index 0000000000000..d9fd55e57f1ce --- /dev/null +++ b/src/mame/f256/f256k.md @@ -0,0 +1,18 @@ +#F256K on MAME Instructions +Place the executable in a desired folder. +Create a sub-folder named "roms" and place the f256k.zip file in it, without decompressing. + +Open a terminal window, such as "cmd" on Windows or bash in Linux. + +For help, type `./f256 -h`. On Windows, type `.\f256.exe -h`. +For usage info, type `./f256 -showusage`. On Windows, type `.\f256.exe -showusage`. +To run in fullscreen mode, type `./f256 f256k`. On Windows, type `.\f256.exe f256k`. + +To use the provided SD card image, add ` -harddisk sdcard.img` with the appropriate filename, of course. + +To run in "windowed" mode, add ` -window -resolution 800x600` to get a resolution of 800 by 600. + +You will have to study the MAME key codes to see how to get debugging going (backtick `` is the default). + +You can turn off sound by adding ` -sound none` to the command. + diff --git a/src/mame/f256/tiny_vicky.cpp b/src/mame/f256/tiny_vicky.cpp new file mode 100644 index 0000000000000..73848c2d4975e --- /dev/null +++ b/src/mame/f256/tiny_vicky.cpp @@ -0,0 +1,611 @@ +#include "emu.h" +#include "tiny_vicky.h" + +#include "machine/ram.h" +#include "screen.h" + +DEFINE_DEVICE_TYPE(TINY_VICKY, tiny_vicky_video_device, "tiny_vicky", "F256K Tiny Vicky") + +tiny_vicky_video_device::tiny_vicky_video_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock): + device_t(mconfig, type, tag, owner, clock) + , m_sof_irq_handler(*this) + , m_sol_irq_handler(*this) +{ +} + +tiny_vicky_video_device::tiny_vicky_video_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock): + tiny_vicky_video_device(mconfig, TINY_VICKY, tag, owner, clock) +{ +} + +rgb_t tiny_vicky_video_device::get_text_lut(uint8_t color_index, bool fg, bool gamma) +{ + uint8_t red = iopage0_ptr[(fg ? 0x1800 : 0x1840) + color_index * 4 + 2]; + uint8_t green = iopage0_ptr[(fg ? 0x1800 : 0x1840) + color_index * 4 + 1]; + uint8_t blue = iopage0_ptr[(fg ? 0x1800 : 0x1840) + color_index * 4 ]; + if (gamma) + { + blue = iopage0_ptr[blue]; + green = iopage0_ptr[0x400 + green]; + red = iopage0_ptr[0x800 + red]; + } + return rgb_t(red, green, blue); +} + +rgb_t tiny_vicky_video_device::get_lut_value(uint8_t lut_index, uint8_t pix_val, bool gamma) +{ + int lutAddress = 0xD000 - 0xC000 + (lut_index * 256 + pix_val) * 4; + if (!gamma) + { + return rgb_t(iopage1_ptr[lutAddress + 2],iopage1_ptr[lutAddress + 1],iopage1_ptr[lutAddress]); + } + else + { + return rgb_t(iopage0_ptr[0x800 + iopage1_ptr[lutAddress + 2]], + iopage0_ptr[0x400 + iopage1_ptr[lutAddress + 1]], + iopage0_ptr[iopage1_ptr[lutAddress]]); + } +} + +uint32_t tiny_vicky_video_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + if (running && iopage0_ptr) + { + uint8_t mcr = iopage0_ptr[0x1000]; + uint8_t mcr_h = iopage0_ptr[0x1001]; + cursor_counter++; + if (cursor_counter > cursor_flash_rate *2) + { + cursor_counter = 0; + } + // if MCR=0 or MCR bit 7 is set, then video is disabled + if (mcr != 0 && (mcr != 0x80)) + { + // TODO: generate start of frame (SOF) interrupt + m_sof_irq_handler(1); + uint8_t border_reg = iopage0_ptr[0x1004]; + bool display_border = (border_reg & 0x1) > 0; + bool enable_gamma = (mcr & 0x40) > 0; + bool enable_graphics = (mcr & 0x4) > 0; + uint16_t lines = (mcr_h & 1) == 0 ? 480 : 400; + + uint8_t border_x = 0; + uint8_t border_y = 0; + rgb_t border_color = rgb_t(); + if (display_border) { + border_x = iopage0_ptr[0x1008]; + border_y = iopage0_ptr[0x1009]; + } + uint32_t *topleft = (uint32_t *)bitmap.raw_pixptr(0); + for (int y = 0; y < lines; y++) + { + // Check the Sart of Line registers + uint8_t sol_reg = iopage0_ptr[0x1018]; + // 12-bit line + uint16_t sol_line = iopage0_ptr[0x1018] + ((iopage0_ptr[0x101A] & 0xF) << 8); + uint32_t *row = topleft + y * 800; + if ((sol_reg & 1) != 0 && y == sol_line) + { + // raise an interrupt + m_sol_irq_handler(1); + } + // border color can change during painting the screen + if (display_border) + { + if (!enable_gamma) + { + border_color = rgb_t(iopage0_ptr[0x1007], iopage0_ptr[0x1006], iopage0_ptr[0x1005]); + } + else + { + border_color = rgb_t(iopage0_ptr[0x800 + iopage0_ptr[0x1007]], + iopage0_ptr[0x400 + iopage0_ptr[0x1006]], + iopage0_ptr[iopage0_ptr[0x1005]]); + } + } + + if (y < border_y || y >= lines - border_y) + { + for (int x = 0; x < 640; x++) + { + row[x] = border_color; + } + } + else + { + rgb_t background_color = rgb_t(); + // only draw the even lines + if (enable_graphics && y % 2 == 0) + { + if (!enable_gamma) + { + background_color = rgb_t(iopage0_ptr[0x100F], iopage0_ptr[0x100E], iopage0_ptr[0x100D]); + } + else + { + background_color = rgb_t(iopage0_ptr[0x800 + iopage0_ptr[0x100F]], + iopage0_ptr[0x400 + iopage0_ptr[0x100E]], + iopage0_ptr[iopage0_ptr[0x100D]]); + } + } + // draw the border or background + if (y % 2 == 0) + { + for (int x = 0; x < 640; x++) + { + row[x] = x < border_x || x >= 640 - border_x ? border_color : background_color; + } + memcpy(row+800,row, 640*4); + } + + if (enable_graphics) + { + if (y % 2 == 0) + { + // Tiny Vicky Layers for Bitmaps, Tilemaps and sprites + uint8_t LayerMgr0 = iopage0_ptr[0xD002 - 0xC000] & 0x7; + uint8_t LayerMgr1 = iopage0_ptr[0xD002 - 0xC000] >> 4; + uint8_t LayerMgr2 = iopage0_ptr[0xD003 - 0xC000] & 0x7; + + // draw layers starting from the back + if ((mcr & 0x20) != 0) + { + draw_sprites(row, enable_gamma, 3, display_border, border_x, border_y, y, (uint16_t)640, lines / 2); + } + if ((mcr & 0x8) != 0 && LayerMgr2 < 3) + { + draw_bitmap(row, enable_gamma, LayerMgr2, display_border, background_color, border_x, border_y, y, (uint16_t)640); + + } + if ((mcr & 0x10) != 0 && (LayerMgr2 > 3 && LayerMgr2 < 7)) + { + draw_tiles(row, enable_gamma, LayerMgr2 & 3, display_border, border_x, y, (uint16_t)640); + } + if ((mcr & 0x20) != 0) + { + draw_sprites(row, enable_gamma, 2, display_border, border_x, border_y, y, (uint16_t)640, lines/2); + } + if ((mcr & 0x8) != 0 && LayerMgr1 < 3) + { + draw_bitmap(row, enable_gamma, LayerMgr1, display_border, background_color, border_x, border_y, y, (uint16_t)640); + } + if ((mcr & 0x10) != 0 && (LayerMgr1 > 3 && LayerMgr1 < 7)) + { + draw_tiles(row, enable_gamma, LayerMgr1 & 3, display_border, border_x, y, (uint16_t)640); + } + if ((mcr & 0x20) != 0) + { + draw_sprites(row, enable_gamma, 1, display_border, border_x, border_y, y, (uint16_t)640, lines / 2); + } + if ((mcr & 0x8) != 0 && LayerMgr0 < 3) + { + draw_bitmap(row, enable_gamma, LayerMgr0, display_border, background_color, border_x, border_y, y, (uint16_t)640); + } + if ((mcr & 0x10) != 0 && (LayerMgr0 > 3 && LayerMgr0 < 7)) + { + draw_tiles(row, enable_gamma, LayerMgr0 & 3, display_border, border_x, y, (uint16_t)640); + } + if ((mcr & 0x20) != 0) + { + draw_sprites(row, enable_gamma, 0, display_border, border_x, border_y, y, (uint16_t)640, lines/ 2); + } + // copy the odd line now + memcpy(row + 800, row, 640 * 4); + } + } + // Only display text in these cases + if ((mcr & 0x7) == 1 || (mcr & 0x7) == 3 || (mcr & 0x7) == 7) + { + draw_text(row, mcr, enable_gamma, border_x, border_y, y, (uint16_t)640, (uint16_t)lines); + } + } + draw_mouse(row, enable_gamma, y, (uint16_t)640, (uint16_t)lines); + } + } + } + + return 0; +} + + +void tiny_vicky_video_device::draw_text(uint32_t *row, uint8_t mcr, bool enable_gamma, uint8_t brd_x, uint8_t brd_y, uint16_t line, uint16_t x_res, uint16_t y_res) +{ + bool overlay = (mcr & 0x2) != 0; + uint8_t mcrh = iopage0_ptr[0x1001] & 0x3F; + bool double_x = (mcrh & 0x2) != 0; + bool double_y = (mcrh & 0x4) != 0; + bool use_font1 = (mcrh & 0x20) != 0; + bool overlay_font = (mcrh & 0x10) != 0; + int txt_line = ((double_y ? line / 2 : line) - brd_y) / CHAR_HEIGHT; + // Each character is defined by 8 bytes + int font_line = ((double_y ? line / 2 : line) - brd_y) % CHAR_HEIGHT; + int txt_cols = double_x ? 40 : 80; + + // do cursor stuff + int cursor_x = iopage0_ptr[0x1014] + (iopage0_ptr[0x1015] << 8); + int cursor_y = iopage0_ptr[0x1016] + (iopage0_ptr[0x1017] << 8); + + // TODO: enabling/disabling cursor and flashing should be handled somewhere else... maybe in the top screen_update function. + bool enable_cursor = (iopage0_ptr[0x1010] & 0x1) > 0; + enable_cursor_flash = (iopage0_ptr[0x1010] & 0x8) == 0; + // flash rate is the count of screen updates + // 1s = 60 ==> 00 + // 0.5s = 30 ==> 01 + // 0.25s= 15 ==> 10 + // 0.20s= 12 ==> 11 + cursor_flash_rate = 60; + switch ((iopage0_ptr[0x1010] & 6) >> 1) + { + case 1: + cursor_flash_rate = 30; + break; + case 2: + cursor_flash_rate = 15; + break; + case 3: + cursor_flash_rate = 12; + break; + } + int screen_x = brd_x; + // I'm assuming that if enable_cursor_flash is 0, then the cursor is always visible + cursor_visible = enable_cursor && (enable_cursor_flash && (cursor_counter < cursor_flash_rate)); + // the loop should go to txt_cols - going to 80 causes a weird alias, but the machine works this way... so. + for (int col = 0; col < 80; col++) + { + int x = col * CHAR_WIDTH; + if (x + brd_x > x_res - 1 - brd_x) + { + continue; + } + // int offset = 0; + // if (col < (double_x ? 40 : 80)) + // { + // // offset is always based on 80 columns + // offset = 80 * txt_line + col; + // } + int offset = txt_cols * txt_line + col; + // Each character will have foreground and background colors + uint8_t character = iopage2_ptr[offset]; + uint8_t color = iopage3_ptr[offset]; + + // Display the cursor - this replaces the text character + if (cursor_x == col && cursor_y == txt_line && cursor_visible) + { + character = iopage0_ptr[0x1012]; + } + + uint8_t fg_color_index = (color & 0xF0) >> 4; + uint8_t bg_color_index = (color & 0x0F); + + rgb_t fg_color = get_text_lut(fg_color_index, true, enable_gamma); + rgb_t bg_color = get_text_lut(bg_color_index, false, enable_gamma); + + uint8_t value = iopage1_ptr[(use_font1 ? 0x800 : 0) + character * 8 + font_line]; + + // For each bit in the font, set the foreground color - if the bit is 0 and overlay is set, skip it (keep the background) + for (int b = 0x80; b > 0; b >>= 1) + { + if (double_x) + { + if ((value & b) != 0) + { + row[screen_x] = fg_color; + row[screen_x + 1] = fg_color; + } + else if (!overlay || (overlay_font && (bg_color == 0))) + { + row[screen_x] = bg_color; + row[screen_x + 1] = bg_color; + } + screen_x += 2; + } + else + { + if ((value & b) != 0) + { + row[screen_x] = fg_color; + } + else if (!overlay || (overlay_font && (bg_color != 0))) + { + row[screen_x] = bg_color; + } + screen_x++; + } + } + } +} +void tiny_vicky_video_device::device_start() +{ +} +void tiny_vicky_video_device::device_reset() +{ + +} +void tiny_vicky_video_device::draw_bitmap(uint32_t *row, bool enable_gamma, uint8_t layer, bool bkgrnd, rgb_t bgndColor, uint8_t borderXSize, uint8_t borderYSize, uint16_t line, uint16_t width) +{ + uint8_t reg = iopage0_ptr[(0xD100 - 0xC000) + layer * 8]; + // check if the bitmap is enabled + if ((reg & 0x01) == 0) + { + return; + } + uint8_t lut_index = (reg >> 1) & 7; // 8 possible LUTs + constexpr int base_offset = 0xD101 - 0xC000; + int bitmapAddress = (iopage0_ptr[base_offset + layer * 8] + + (iopage0_ptr[base_offset + 1 + layer * 8] << 8) + + (iopage0_ptr[base_offset + 2 + layer * 8] << 16) + ) & 0x3F'FFFF; + + rgb_t color_val = 0; + int offsetAddress = bitmapAddress + (line/2) * width/2; + uint8_t pix_val = 0; + + for (int col = borderXSize; col < width - borderXSize; col += 2) + { + pix_val = videoram_ptr[offsetAddress + col/2 + 1]; + if (pix_val != 0) + { + color_val = get_lut_value(lut_index, pix_val, enable_gamma); + row[col] = color_val; + row[col + 1] = color_val; + } + } +} + + +void tiny_vicky_video_device::draw_sprites(uint32_t *row, bool enable_gamma, uint8_t layer, bool bkgrnd, uint8_t borderXSize, uint8_t borderYSize, uint16_t line, uint16_t width, uint16_t height) +{ + // There are 64 possible sprites to choose from. + for (int s = 63; s > -1; s--) + { + int addr_sprite = 0xD900 - 0xC000 + s * 8; + uint8_t reg = iopage0_ptr[addr_sprite]; + // if the set is not enabled, we're done. + uint8_t sprite_layer = (reg & 0x18) >> 3; + // if the sprite is enabled and the layer matches, then check the line + if ((reg & 1) != 0 && layer == sprite_layer) + { + uint8_t sprite_size = 32; + switch ((reg & 0x60) >> 5) + { + case 1: + sprite_size = 24; + break; + case 2: + sprite_size = 16; + break; + case 3: + sprite_size = 8; + break; + } + int posY = iopage0_ptr[addr_sprite + 6] + (iopage0_ptr[addr_sprite + 7] << 8) - 32; + int actualLine = line / 2; + if ((actualLine >= posY && actualLine < posY + sprite_size)) + { + // TODO Fix this when Vicky II fixes the LUT issue + uint8_t lut_index = ((reg & 6) >> 1); + + //int lut_address = 0xD000 - 0xC000 + lut_index * 0x400; + //bool striding = (reg & 0x80) == 0x80; + + int sprite_address = (iopage0_ptr[addr_sprite + 1] + + (iopage0_ptr[addr_sprite + 2] << 8) + + (iopage0_ptr[addr_sprite + 3] << 16)) & 0x3F'FFFF; + int posX = iopage0_ptr[addr_sprite + 4] + (iopage0_ptr[addr_sprite + 5] << 8) - 32; + posX *= 2; + + if (posX >= width || posY >= height || (posX + sprite_size) < 0 || (posY + sprite_size) < 0) + { + continue; + } + int sprite_width = sprite_size; + int xOffset = 0; + // Check for sprite bleeding on the left-hand-side + if (posX < borderXSize) + { + xOffset = borderXSize - posX; + posX = borderXSize; + sprite_width = sprite_size - xOffset; + if (sprite_width == 0) + { + continue; + } + } + // Check for sprite bleeding on the right-hand side + if (posX + sprite_size > width - borderXSize) + { + sprite_width = width - borderXSize - posX; + if (sprite_width == 0) + { + continue; + } + } + + rgb_t clrVal = 0; + uint8_t pixVal = 0; + + int sline = actualLine - posY; + int cols = sprite_size; + if (posX + sprite_size*2 >= width - borderXSize) + { + cols = width - borderXSize - posX; + cols /= 2; + } + for (int col = xOffset; col < xOffset + cols; col++) + { + // Lookup the pixel in the tileset - if the value is 0, it's transparent + pixVal = videoram_ptr[sprite_address + col + sline * sprite_size]; + if (pixVal != 0) + { + clrVal = get_lut_value(lut_index, pixVal, enable_gamma); + row[(col * 2) - xOffset + posX] = clrVal; + row[(col * 2) + 1 - xOffset + posX] = clrVal; + } + } + } + } + } +} + +void tiny_vicky_video_device::draw_tiles(uint32_t *row, bool enable_gamma, uint8_t layer, bool bkgrnd, uint8_t borderXSize, uint16_t line, uint16_t width) +{ + // There are four possible tilemaps to choose from + int addr_tile_addr = 0xD200 - 0xC000 + layer * 12; + int reg = iopage0_ptr[addr_tile_addr]; + // if the set is not enabled, we're done. + if ((reg & 0x01) == 00) + { + return; + } + bool smallTiles = (reg & 0x10) > 0; + + int tileSize = (smallTiles ? 8 : 16); + int strideLine = tileSize * 16; + uint8_t scrollMask = smallTiles ? 0xF : 0xF; // Tiny Vicky bug: this should be 0xE + + int tilemapWidth = (iopage0_ptr[addr_tile_addr + 4] + (iopage0_ptr[addr_tile_addr + 5] << 8)) & 0x3FF; // 10 bits + //int tilemapHeight = VICKY.ReadWord(addrTileCtrlReg + 6) & 0x3FF; // 10 bits + int tilemapAddress = (iopage0_ptr[addr_tile_addr + 1] + (iopage0_ptr[addr_tile_addr + 2] << 8) + (iopage0_ptr[addr_tile_addr + 3] << 16)) & 0x3F'FFFF; + + // the tilemapWindowX is 10 bits and the scrollX is the lower 4 bits. The IDE combines them. + int tilemapWindowX = iopage0_ptr[addr_tile_addr + 8] + (iopage0_ptr[addr_tile_addr + 9] << 8); + uint8_t scrollX = (tilemapWindowX & scrollMask) & scrollMask; + // the tilemapWindowY is 10 bits and the scrollY is the lower 4 bits. The IDE combines them. + int tilemapWindowY = iopage0_ptr[addr_tile_addr + 10] + (iopage0_ptr[addr_tile_addr + 11] << 8); + uint8_t scrollY = (tilemapWindowY & scrollMask) & scrollMask; + if (smallTiles) + { + tilemapWindowX = ((tilemapWindowX & 0x3FF0) >> 1) + scrollX + 8; + tilemapWindowY = ((tilemapWindowY & 0x3FF0) >> 1) + scrollY; + } + else + { + tilemapWindowX = (tilemapWindowX & 0x3FF0) + scrollX; + tilemapWindowY = (tilemapWindowY & 0x3FF0) + scrollY; + } + int tileXOffset = tilemapWindowX % tileSize; + + int tileRow = (line / 2 + tilemapWindowY) / tileSize; + int tileYOffset = (line / 2 + tilemapWindowY) % tileSize; + int maxX = width - borderXSize; + + // we always read tiles 0 to width/TILE_SIZE + 1 - this is to ensure we can display partial tiles, with X,Y offsets + // TODO - variable length array: int tilemapItemCount = width / 2 / tileSize + 1; + const uint8_t tilemapItemCount = 41; // this is the maximum number of tiles in a line + // The + 2 below is to take an FPGA bug in the F256Jr into account + //int tlmSize = tilemapItemCount * 2 + 2; + const uint8_t tlmSize = 84; + uint8_t tiles[tlmSize]; + int tilesetOffsets[tilemapItemCount]; + + // The + 2 below is to take an FPGA bug in the F256Jr into account + memcpy(tiles, videoram_ptr + tilemapAddress + (tilemapWindowX / tileSize) * 2 + (tileRow + 0) * tilemapWidth * 2, tlmSize); + + // cache of tilesetPointers + int tilesetPointers[8]; + int strides[8]; + for (int i = 0; i < 8; i++) + { + tilesetPointers[i] = (iopage0_ptr[0xD280 - 0xC000 + i * 4] + (iopage0_ptr[0xD280 - 0xC000 + i * 4 + 1] << 8) + + (iopage0_ptr[0xD280 - 0xC000 + i * 4 + 2] << 16)) & 0x3F'FFFF; + uint8_t tilesetConfig = iopage0_ptr[0xD280 - 0xC000 + i * 4 + 3]; + strides[i] = (tilesetConfig & 8) != 0 ? strideLine : tileSize; + } + for (int i = 0; i < tilemapItemCount; i++) + { + uint8_t tile = tiles[i * 2]; + uint8_t tilesetReg = tiles[i * 2 + 1]; + uint8_t tileset = tilesetReg & 7; + + // tileset + int tilesetPointer = tilesetPointers[tileset]; + int strideX = strides[tileset]; + if (strideX == tileSize) + { + tilesetOffsets[i] = tilesetPointer + (tile % 16) * tileSize * tileSize + (tile / 16) * tileSize * tileSize * 16 + tileYOffset * tileSize; + } + else + { + tilesetOffsets[i] = tilesetPointer + ((tile / 16) * strideX * tileSize + (tile % 16) * tileSize) + tileYOffset * strideX; + } + } + + // alternate display style - avoids repeating the loop so often + int startTileX = (borderXSize + tileXOffset) / tileSize; + int endTileX = (width/2 - borderXSize + tileXOffset) / tileSize + 1; + int startOffset = (borderXSize + tilemapWindowX) % tileSize; + int x = borderXSize; + //uint8_t tilepix[tileSize]; + rgb_t clr_val = 0; + for (int t = startTileX; t < endTileX; t++) + { + // The (mode==0 ? 1 : 3) below is to take an FPGA but in the F256Jr into account + uint8_t tilesetReg = tiles[t * 2 + 3]; + uint8_t lut_index = (tilesetReg & 0x38) >> 3; + //int lutAddress = MemoryMap.GRP_LUT_BASE_ADDR - VICKY.StartAddress + lutIndex * 1024; + //int tilesetOffsetAddress = tilesetOffsets[t]; // + startOffset + //memcpy(tilepix, videoram_ptr + tilesetOffsets[t], tileSize); + do + { + uint8_t pixVal = videoram_ptr[tilesetOffsets[t] + startOffset]; // tilepix[startOffset]; + if (pixVal > 0) + { + clr_val = get_lut_value(lut_index, pixVal, enable_gamma); + row[x] = clr_val; + row[x+1] = clr_val; + } + startOffset++; + //tilesetOffsetAddress++; + x+=2; + } while (startOffset != tileSize && x < maxX); + startOffset = 0; + if (x == maxX) + { + break; + } + } +} + +void tiny_vicky_video_device::draw_mouse(uint32_t *row, bool enable_gamma, uint16_t line, uint16_t width, uint16_t height) +{ + uint8_t mouse_reg = iopage0_ptr[0xD6E0 - 0xC000]; + + bool MousePointerEnabled = (mouse_reg & 3) != 0; + + if (MousePointerEnabled) + { + int PosX = iopage0_ptr[0xD6E0 - 0xC000 + 2] + (iopage0_ptr[0xD6E0 - 0xC000 + 3] << 8); + int PosY = iopage0_ptr[0xD6E0 - 0xC000 + 4] + (iopage0_ptr[0xD6E0 - 0xC000 + 5] << 8); + if (line >= PosY && line < PosY + 16) + { + int ptr_addr = 0xCC00 - 0xC000; + + // Mouse pointer is a 16x16 icon + int colsToDraw = PosX < width - 16 ? 16 : width - PosX; + + int mouse_line = line - PosY; + for (int col = 0; col < colsToDraw; col++) + { + // Values are 0: transparent, 1:black, 255: white (gray scales) + uint8_t pixel_index = iopage0_ptr[ptr_addr + mouse_line * 16 + col]; + rgb_t value; + + if (pixel_index != 0) + { + if (!enable_gamma) + { + value = rgb_t(pixel_index, pixel_index, pixel_index); + } + else + { + value = rgb_t(iopage0_ptr[0x800 + pixel_index], + iopage0_ptr[0x400 + pixel_index], + iopage0_ptr[pixel_index]); + } + row[col + PosX] = value; + } + } + } + + } +} diff --git a/src/mame/f256/tiny_vicky.h b/src/mame/f256/tiny_vicky.h new file mode 100644 index 0000000000000..5d23c9f7c22af --- /dev/null +++ b/src/mame/f256/tiny_vicky.h @@ -0,0 +1,79 @@ +#ifndef MAME_F256_TINYVICKYVIDEO_H +#define MAME_F256_TINYVICKYVIDEO_H + +#define CHAR_HEIGHT 8 +#define CHAR_WIDTH 8 + +//#include + +class tiny_vicky_video_device : public device_t +{ +public: + tiny_vicky_video_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + tiny_vicky_video_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock = 0); + //tiny_vicky_video_device() = default; + + // screen update + uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + void stop() + { + running = false; + videoram_ptr = nullptr; + iopage0_ptr = nullptr; + iopage1_ptr = nullptr; + iopage2_ptr = nullptr; + iopage3_ptr = nullptr; + } + void set_videoram(uint8_t *videoram, uint8_t *iopage0, uint8_t *iopage1, uint8_t *iopage2, uint8_t *iopage3) + { + videoram_ptr = videoram; + iopage0_ptr = iopage0; + iopage1_ptr = iopage1; + iopage2_ptr = iopage2; + iopage3_ptr = iopage3; + } + void start() + { + running = true; + }; + auto sof_irq_handler() + { + return m_sof_irq_handler.bind(); + }; + auto sol_irq_handler() + { + return m_sol_irq_handler.bind(); + }; +protected: + // device-level overrides + virtual void device_start() override ATTR_COLD; + virtual void device_reset() override ATTR_COLD; + // virtual void device_add_mconfig(machine_config &config) override; +private: + bool running = false; + devcb_write_line m_sof_irq_handler; + devcb_write_line m_sol_irq_handler; + uint8_t *videoram_ptr = nullptr; // Pointer to video RAM + uint8_t *iopage0_ptr = nullptr; // Pointer to IO Page 0 + uint8_t *iopage1_ptr = nullptr; // Pointer to IO Page 1 + uint8_t *iopage2_ptr = nullptr; // Pointer to IO Page 2 + uint8_t *iopage3_ptr = nullptr; // Pointer to IO Page 3 + + // cursor handling routines + bool cursor_visible = false; + bool enable_cursor_flash = true; + uint8_t cursor_counter = 0; + uint8_t cursor_flash_rate = 60; + + // raster + rgb_t get_text_lut(uint8_t color_index, bool fg, bool gamma); + rgb_t get_lut_value(uint8_t lut_index, uint8_t pix_val, bool gamma); + void draw_text(uint32_t *row, uint8_t mcr, bool enable_gamma, uint8_t brd_x, uint8_t brd_y, uint16_t line, uint16_t x_res, uint16_t y_res); + void draw_bitmap(uint32_t *row, bool enable_gamma, uint8_t layer, bool bkgrnd, rgb_t bgndColor, uint8_t borderXSize, uint8_t borderYSize, uint16_t line, uint16_t width); + void draw_sprites(uint32_t *row, bool enable_gamma, uint8_t layer, bool bkgrnd, uint8_t borderXSize, uint8_t borderYSize, uint16_t line, uint16_t width, uint16_t height); + void draw_tiles(uint32_t *row, bool enable_gamma, uint8_t layer, bool bkgrnd, uint8_t borderXSize, uint16_t line, uint16_t width); + void draw_mouse(uint32_t *row, bool enable_gamma, uint16_t line, uint16_t width, uint16_t height); +}; + +DECLARE_DEVICE_TYPE(TINY_VICKY, tiny_vicky_video_device) +#endif diff --git a/src/mame/mame.lst b/src/mame/mame.lst index ec4fe57785854..69cc238630bec 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -18248,6 +18248,9 @@ topgunnr victorba victory +@source:f256/f256.cpp +f256k + @source:f32/crospang.cpp bestri bestria From 263cfc328c0908b81233404ced3a4c886886b325 Mon Sep 17 00:00:00 2001 From: Daniel Tremblay Date: Tue, 5 Aug 2025 22:13:39 +0200 Subject: [PATCH 02/11] Fixed the header constant to match guard. --- src/mame/f256/tiny_vicky.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mame/f256/tiny_vicky.h b/src/mame/f256/tiny_vicky.h index 5d23c9f7c22af..ffa785ce8eaf1 100644 --- a/src/mame/f256/tiny_vicky.h +++ b/src/mame/f256/tiny_vicky.h @@ -1,5 +1,5 @@ -#ifndef MAME_F256_TINYVICKYVIDEO_H -#define MAME_F256_TINYVICKYVIDEO_H +#ifndef MAME_F256_TINY_VICKY_H +#define MAME_F256_TINY_VICKY_H #define CHAR_HEIGHT 8 #define CHAR_WIDTH 8 From 28e69a134cfad0aeb5601cf79c137209628bb229 Mon Sep 17 00:00:00 2001 From: Daniel Tremblay Date: Tue, 5 Aug 2025 23:24:10 +0200 Subject: [PATCH 03/11] Added SPDX license and my handle. Removed github workflow files. Re-arranged the setters to follow the constructors in the main constructor. --- src/mame/f256/f256.cpp | 36 ++-- src/mame/f256/f256.h | 2 + src/mame/f256/harddriv.old | 408 +++++++++++++++++++++++++++++++++++ src/mame/f256/tiny_vicky.cpp | 2 + src/mame/f256/tiny_vicky.h | 2 + 5 files changed, 435 insertions(+), 15 deletions(-) create mode 100644 src/mame/f256/harddriv.old diff --git a/src/mame/f256/f256.cpp b/src/mame/f256/f256.cpp index 2945ad4853548..9b9f755c4879b 100644 --- a/src/mame/f256/f256.cpp +++ b/src/mame/f256/f256.cpp @@ -1,3 +1,5 @@ +// license:BSD-3-Clause +// copyright-holders:Daniel Tremblay #include "emu.h" #include "f256.h" @@ -57,21 +59,25 @@ f256_state::f256_state(const machine_config &mconfig, device_type type, const ch void f256_state::f256k(machine_config &config) { W65C02(config, m_maincpu, MASTER_CLOCK/4); + m_maincpu->set_addrmap(AS_PROGRAM, &f256_state::program_map); + RAM(config, m_ram).set_default_size("512k").set_default_value(0x0); RAM(config, m_iopage0).set_default_size("8k").set_default_value(0x0); RAM(config, m_iopage1).set_default_size("8k").set_default_value(0x0); RAM(config, m_iopage2).set_default_size("8k").set_default_value(0x0); RAM(config, m_iopage3).set_default_size("8k").set_default_value(0x0); - SCREEN(config, m_screen, SCREEN_TYPE_RASTER); - BQ4802(config, m_rtc, MASTER_CLOCK / 1000); // RTC clock in kHz - - m_maincpu->set_addrmap(AS_PROGRAM, &f256_state::program_map); + SCREEN(config, m_screen, SCREEN_TYPE_RASTER); m_screen->set_refresh_hz(60); // Refresh rate (e.g., 60Hz) m_screen->set_size(800,525); //m_screen->set_visarea(160, 799, 45, 524); // this is how it should reall work, but the screen ends up offset m_screen->set_visarea(0, 639, 0, 479); m_screen->set_screen_update(m_video, FUNC(tiny_vicky_video_device::screen_update)); + + BQ4802(config, m_rtc, MASTER_CLOCK / 1000); // RTC clock in kHz + //set interrupt handler for the RTC + m_rtc->int_handler().set(FUNC(f256_state::rtc_interrupt_handler)); + TINY_VICKY(config, m_video, MASTER_CLOCK); m_video->sof_irq_handler().set(FUNC(f256_state::sof_interrtupt)); m_video->sol_irq_handler().set(FUNC(f256_state::sol_interrtupt)); @@ -88,6 +94,7 @@ void f256_state::f256k(machine_config &config) // initialize the PS2 mouse PC_KBDC(config, m_ps2_keyboard, XTAL(32'768)); HLE_PS2_MOUSE(config, m_mouse, XTAL(32'768)); + m_mouse->set_pc_kbdc(m_ps2_keyboard); MOS6522(config, m_via6522_1, MASTER_CLOCK / 4); // Keyboard XTAL(14'318'181)/14) m_via6522_1->readpa_handler().set(FUNC(f256_state::via1_system_porta_r)); @@ -98,32 +105,30 @@ void f256_state::f256k(machine_config &config) m_via6522_1->cb2_handler().set(FUNC(f256_state::via1_cb2_write)); m_via6522_1->irq_handler().set(FUNC(f256_state::via1_interrupt)); - SN76489(config, m_sn0, MUSIC_CLOCK / 4); - SN76489(config, m_sn1, MUSIC_CLOCK / 4); - YMF262(config, m_opl3, MUSIC_CLOCK); - MOS6581(config, m_sid0, MUSIC_CLOCK/14); - MOS6581(config, m_sid1, MUSIC_CLOCK/14); - - SPEAKER(config, "lspeaker").front_left(); - SPEAKER(config, "rspeaker").front_right(); // Mix PSG + SN76489(config, m_sn0, MUSIC_CLOCK / 4); m_sn0->add_route(ALL_OUTPUTS, "lspeaker", 0.5); m_sn0->add_route(ALL_OUTPUTS, "rspeaker", 0.5); + SN76489(config, m_sn1, MUSIC_CLOCK / 4); m_sn1->add_route(ALL_OUTPUTS, "lspeaker", 0.5); m_sn1->add_route(ALL_OUTPUTS, "rspeaker", 0.5); + YMF262(config, m_opl3, MUSIC_CLOCK); m_opl3->add_route(0, "lspeaker", 1.0); m_opl3->add_route(1, "rspeaker", 1.0); m_opl3->add_route(2, "lspeaker", 1.0); m_opl3->add_route(3, "rspeaker", 1.0); + // The SIDs are very noisy + MOS6581(config, m_sid0, MUSIC_CLOCK/14); m_sid0->add_route(ALL_OUTPUTS, "lspeaker", 0.5); m_sid0->add_route(ALL_OUTPUTS, "rspeaker", 0.5); + MOS6581(config, m_sid1, MUSIC_CLOCK/14); m_sid1->add_route(ALL_OUTPUTS, "lspeaker", 0.5); m_sid1->add_route(ALL_OUTPUTS, "rspeaker", 0.5); - //set interrupt handler for the RTC - m_rtc->int_handler().set(FUNC(f256_state::rtc_interrupt_handler)); + SPEAKER(config, "lspeaker").front_left(); + SPEAKER(config, "rspeaker").front_right(); // Add an SD card device SPI_SDCARD(config, m_sdcard, 0); @@ -134,9 +139,10 @@ void f256_state::f256k(machine_config &config) m_in_latch |= state; }); - m_mouse->set_pc_kbdc(m_ps2_keyboard); + NS16550(config, m_uart, MASTER_CLOCK); + // The IEC interface is not yet implemented // cbm_iec_slot_device::add(config, m_iec, "c1581"); // m_iec->srq_callback().set(FUNC(f256_state::iec_srq_w)); // m_iec->data_callback().set(FUNC(f256_state::iec_data_w)); diff --git a/src/mame/f256/f256.h b/src/mame/f256/f256.h index 0ac34d4b15fa0..2363bf0b2d98e 100644 --- a/src/mame/f256/f256.h +++ b/src/mame/f256/f256.h @@ -1,3 +1,5 @@ +// license:BSD-3-Clause +// copyright-holders:Daniel Tremblay #ifndef MAME_F256_F256_H #define MAME_F256_F256_H diff --git a/src/mame/f256/harddriv.old b/src/mame/f256/harddriv.old new file mode 100644 index 0000000000000..c1396b6d22b5a --- /dev/null +++ b/src/mame/f256/harddriv.old @@ -0,0 +1,408 @@ +// license:BSD-3-Clause +// copyright-holders:Nathan Woods, Raphael Nabet, Miodrag Milanovic +/********************************************************************* + + Code to interface the image code with harddisk core. + + Raphael Nabet 2003 + + Update: 23-Feb-2004 - Unlike floppy disks, for which we support + myriad formats on many systems, it is my intention for MESS to + standardize on the CHD file format for hard drives so I made a few + changes to support this + +*********************************************************************/ + +#include "emu.h" +#include "harddriv.h" + +#include "emuopts.h" +#include "fileio.h" +#include "harddisk.h" +#include "romload.h" + +#include "multibyte.h" +#include "opresolv.h" + + +OPTION_GUIDE_START(hd_option_guide) + OPTION_INT('C', "cylinders", "Cylinders") + OPTION_INT('H', "heads", "Heads") + OPTION_INT('S', "sectors", "Sectors") + OPTION_INT('L', "sectorlength", "Sector Bytes") + OPTION_INT('K', "hunksize", "Hunk Bytes") +OPTION_GUIDE_END + +static char const *const hd_option_spec = + "C1-[512]-1024;H1/2/[4]/8;S1-[16]-64;L128/256/[512]/1024;K512/1024/2048/[4096]"; + + +// device type definition +DEFINE_DEVICE_TYPE(HARDDISK, harddisk_image_device, "harddisk_image", "Hard disk") + +//------------------------------------------------- +// harddisk_image_base_device - constructor +//------------------------------------------------- + +harddisk_image_base_device::harddisk_image_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, type, tag, owner, clock) + , device_image_interface(mconfig, *this) +{ +} + +//------------------------------------------------- +// harddisk_image_device - constructor +//------------------------------------------------- + +harddisk_image_device::harddisk_image_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : harddisk_image_device(mconfig, HARDDISK, tag, owner, clock) +{ +} + +//------------------------------------------------- +// harddisk_image_device - constructor for subclasses +//------------------------------------------------- + +harddisk_image_device::harddisk_image_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) + : harddisk_image_base_device(mconfig, type, tag, owner, clock) + , m_chd(nullptr) + , m_hard_disk_handle() + , m_device_image_load(*this) + , m_device_image_unload(*this) + , m_interface(nullptr) +{ +} + +//------------------------------------------------- +// harddisk_image_device - destructor +//------------------------------------------------- + +harddisk_image_device::~harddisk_image_device() +{ +} + +//------------------------------------------------- +// device_config_complete - perform any +// operations now that the configuration is +// complete +//------------------------------------------------- + +void harddisk_image_device::device_config_complete() +{ + add_format("chd", "CHD Hard drive", "chd,hd,hdv,2mg,hdi", hd_option_spec); +} + +const util::option_guide &harddisk_image_device::create_option_guide() const +{ + return hd_option_guide; +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void harddisk_image_device::device_start() +{ + m_device_image_load.resolve(); + m_device_image_unload.resolve(); + + m_chd = nullptr; + + if (has_preset_images()) + setup_current_preset_image(); + else + m_hard_disk_handle.reset(); +} + +void harddisk_image_device::device_stop() +{ + m_hard_disk_handle.reset(); +} + +std::pair harddisk_image_device::call_load() +{ + std::error_condition our_result = internal_load_hd(); + + // Check if there is an image_load callback defined + if (!our_result && !m_device_image_load.isnull()) + { + // Let the override do some additional work/checks + our_result = m_device_image_load(*this); + } + return std::make_pair(our_result, std::string()); + +} + +std::pair harddisk_image_device::call_create(int create_format, util::option_resolution *create_args) +{ + if (!create_args) + throw emu_fatalerror("harddisk_image_device::call_create: Expected create_args to not be nullptr"); + + const uint32_t cylinders = create_args->lookup_int('C'); + const uint32_t heads = create_args->lookup_int('H'); + const uint32_t sectors = create_args->lookup_int('S'); + const uint32_t sectorsize = create_args->lookup_int('L'); + const uint32_t hunksize = create_args->lookup_int('K'); + + const uint32_t totalsectors = cylinders * heads * sectors; + + // create the CHD file + chd_codec_type compression[4] = { CHD_CODEC_NONE }; + util::core_file::ptr proxy; + std::error_condition err = util::core_file::open_proxy(image_core_file(), proxy); + if (!err) + err = m_origchd.create(std::move(proxy), uint64_t(totalsectors) * uint64_t(sectorsize), hunksize, sectorsize, compression); + if (err) + return std::make_pair(err, std::string()); + + // if we created the image and hence, have metadata to set, set the metadata + err = m_origchd.write_metadata(HARD_DISK_METADATA_TAG, 0, string_format(HARD_DISK_METADATA_FORMAT, cylinders, heads, sectors, sectorsize)); + m_origchd.close(); + + if (err) + return std::make_pair(err, std::string()); + + return std::make_pair(internal_load_hd(), std::string()); +} + +void harddisk_image_device::setup_current_preset_image() +{ + chd_file *chd = current_preset_image_chd(); + m_hard_disk_handle.reset(new hard_disk_file(chd)); +} + +void harddisk_image_device::call_unload() +{ + // Check if there is an image_unload callback defined + if (!m_device_image_unload.isnull()) + m_device_image_unload(*this); + + m_hard_disk_handle.reset(); + + if (m_chd) + { + m_origchd.close(); + m_diffchd.close(); + } + m_chd = nullptr; +} + +/*------------------------------------------------- + open_disk_diff - open a DISK diff file +-------------------------------------------------*/ + +static std::error_condition open_disk_diff(emu_options &options, const char *name, chd_file &source, chd_file &diff_chd) +{ + std::string fname = std::string(name).append(".dif"); + + /* try to open the diff */ + //printf("Opening differencing image file: %s\n", fname.c_str()); + emu_file diff_file(options.diff_directory(), OPEN_FLAG_READ | OPEN_FLAG_WRITE); + std::error_condition filerr = diff_file.open(fname); + if (!filerr) + { + std::string fullpath(diff_file.fullpath()); + diff_file.close(); + + //printf("Opening differencing image file: %s\n", fullpath.c_str()); + return diff_chd.open(fullpath, true, &source); + } + + /* didn't work; try creating it instead */ + //printf("Creating differencing image: %s\n", fname.c_str()); + diff_file.set_openflags(OPEN_FLAG_READ | OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); + filerr = diff_file.open(fname); + if (!filerr) + { + std::string fullpath(diff_file.fullpath()); + diff_file.close(); + + /* create the CHD */ + //printf("Creating differencing image file: %s\n", fupointllpath.c_str()); + chd_codec_type compression[4] = { CHD_CODEC_NONE }; + std::error_condition err = diff_chd.create(fullpath, source.logical_bytes(), source.hunk_bytes(), compression, source); + if (err) + return err; + + return diff_chd.clone_all_metadata(source); + } + + return std::errc::no_such_file_or_directory; +} + +std::error_condition harddisk_image_device::internal_load_hd() +{ + if (has_preset_images()) + { + setup_current_preset_image(); + return std::error_condition(); + } + + std::error_condition err; + m_chd = nullptr; + uint8_t header[0x200]; + + m_hard_disk_handle.reset(); + + // open the CHD file + if (loaded_through_softlist()) + { + m_chd = machine().rom_load().get_disk_handle(device().subtag("harddriv").c_str()); + } + else + { + fseek(0, SEEK_SET); + fread(header, 0x200); // read 512 bytes + fseek(0, SEEK_SET); + + if (!memcmp("MComprHD", header, 8)) + { + util::core_file::ptr proxy; + err = util::core_file::open_proxy(image_core_file(), proxy); + if (!err) + err = m_origchd.open(std::move(proxy), true); + + if (!err) + { + m_chd = &m_origchd; + } + else if (err == chd_file::error::FILE_NOT_WRITEABLE) + { + err = util::core_file::open_proxy(image_core_file(), proxy); + if (!err) + err = m_origchd.open(std::move(proxy), false); + + if (!err) + { + err = open_disk_diff(device().machine().options(), basename_noext(), m_origchd, m_diffchd); + if (!err) + { + m_chd = &m_diffchd; + } + } + } + } + } + + if (m_chd) + { + // open the hard disk file + try + { + m_hard_disk_handle.reset(new hard_disk_file(m_chd)); + if (m_hard_disk_handle) + return std::error_condition(); + } + catch (...) + { + err = image_error::INVALIDIMAGE; + } + } + else if (!is_open()) + { + err = image_error::UNSPECIFIED; + } + else + { + uint32_t skip = 0; + bool is_mbr = false; + uint8_t hd_start = 0; + uint8_t sct_start = 0; + uint16_t cyl_start = 0; + uint8_t hd_end = 0; + uint8_t sct_end = 0; + uint16_t cyl_end = 0; + + if (!memcmp(header, "2IMG", 4)) // check for 2MG format + { + skip = get_u32le(&header[0x18]); + osd_printf_verbose("harddriv: detected 2MG, creator is %c%c%c%c, data at %08x\n", header[4], header[5], header[6], header[7], skip); + } + else if (is_filetype("hdi")) // check for HDI format + { + skip = get_u32le(&header[0x8]); + uint32_t data_size = get_u32le(&header[0xc]); + if (data_size == length() - skip) + { + osd_printf_verbose("harddriv: detected Anex86 HDI, data at %08x\n", skip); + } + else + { + skip = 0; + } + } + else if (header[510] == 0x55 && header[511] == 0xAA) + { + is_mbr = true; + // this is a Master Boot Record disk - therefore, there is a partition table at 0x1BE + hd_start = header[0x1BE + 1]; + sct_start = header[0x1BE + 2] & 0x3F; + cyl_start = ((header[0x1BE + 2] & 0xC0) << 2) + header[0x1BE + 3]; + hd_end = header[0x1BE + 5]; + sct_end = header[0x1BE + 6] & 0x3F; + cyl_end = ((header[0x1BE + 6] & 0xC0) << 2) + header[0x1BE + 7]; + skip = (header[0x1BE + 8] + (header[0x1BE + 9] << 8) + (header[0x1BE + 10] << 16) + (header[0x1BE + 11] << 24)) * 512; + } + + try + { + if (!is_mbr) + m_hard_disk_handle.reset(new hard_disk_file(image_core_file(), skip)); + else + m_hard_disk_handle.reset(new hard_disk_file(image_core_file(), hd_start, sct_start, cyl_start, hd_end, sct_end, cyl_end, 0)); + if (m_hard_disk_handle) + return std::error_condition(); + } + catch (...) + { + err = image_error::INVALIDIMAGE; + } + } + + /* if we had an error, close out the CHD */ + m_diffchd.close(); + m_origchd.close(); + m_chd = nullptr; + + if (err) + return err; + else + return image_error::UNSPECIFIED; +} + +const hard_disk_file::info &harddisk_image_device::get_info() const +{ + return m_hard_disk_handle->get_info(); +} + +bool harddisk_image_device::read(uint32_t lbasector, void *buffer) +{ + logerror("Disk Read: %X\n", lbasector); + return m_hard_disk_handle->read(lbasector, buffer); +} + +bool harddisk_image_device::write(uint32_t lbasector, const void *buffer) +{ + return m_hard_disk_handle->write(lbasector, buffer); +} + + +bool harddisk_image_device::set_block_size(uint32_t blocksize) +{ + return m_hard_disk_handle->set_block_size(blocksize); +} + +std::error_condition harddisk_image_device::get_inquiry_data(std::vector &data) const +{ + return m_hard_disk_handle->get_inquiry_data(data); +} + +std::error_condition harddisk_image_device::get_cis_data(std::vector &data) const +{ + return m_hard_disk_handle->get_cis_data(data); +} + +std::error_condition harddisk_image_device::get_disk_key_data(std::vector &data) const +{ + return m_hard_disk_handle->get_disk_key_data(data); +} diff --git a/src/mame/f256/tiny_vicky.cpp b/src/mame/f256/tiny_vicky.cpp index 73848c2d4975e..1fb2e89080eaf 100644 --- a/src/mame/f256/tiny_vicky.cpp +++ b/src/mame/f256/tiny_vicky.cpp @@ -1,3 +1,5 @@ +// license:BSD-3-Clause +// copyright-holders:Daniel Tremblay #include "emu.h" #include "tiny_vicky.h" diff --git a/src/mame/f256/tiny_vicky.h b/src/mame/f256/tiny_vicky.h index ffa785ce8eaf1..8f1cbe6ae0491 100644 --- a/src/mame/f256/tiny_vicky.h +++ b/src/mame/f256/tiny_vicky.h @@ -1,3 +1,5 @@ +// license:BSD-3-Clause +// copyright-holders:Daniel Tremblay #ifndef MAME_F256_TINY_VICKY_H #define MAME_F256_TINY_VICKY_H From a6ef931ca2aa4f85b3ce54dd955c6b3766c6ddcb Mon Sep 17 00:00:00 2001 From: Daniel Tremblay Date: Tue, 5 Aug 2025 23:29:14 +0200 Subject: [PATCH 04/11] Removed the harddriv.old file. --- src/mame/f256/harddriv.old | 408 ------------------------------------- 1 file changed, 408 deletions(-) delete mode 100644 src/mame/f256/harddriv.old diff --git a/src/mame/f256/harddriv.old b/src/mame/f256/harddriv.old deleted file mode 100644 index c1396b6d22b5a..0000000000000 --- a/src/mame/f256/harddriv.old +++ /dev/null @@ -1,408 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Nathan Woods, Raphael Nabet, Miodrag Milanovic -/********************************************************************* - - Code to interface the image code with harddisk core. - - Raphael Nabet 2003 - - Update: 23-Feb-2004 - Unlike floppy disks, for which we support - myriad formats on many systems, it is my intention for MESS to - standardize on the CHD file format for hard drives so I made a few - changes to support this - -*********************************************************************/ - -#include "emu.h" -#include "harddriv.h" - -#include "emuopts.h" -#include "fileio.h" -#include "harddisk.h" -#include "romload.h" - -#include "multibyte.h" -#include "opresolv.h" - - -OPTION_GUIDE_START(hd_option_guide) - OPTION_INT('C', "cylinders", "Cylinders") - OPTION_INT('H', "heads", "Heads") - OPTION_INT('S', "sectors", "Sectors") - OPTION_INT('L', "sectorlength", "Sector Bytes") - OPTION_INT('K', "hunksize", "Hunk Bytes") -OPTION_GUIDE_END - -static char const *const hd_option_spec = - "C1-[512]-1024;H1/2/[4]/8;S1-[16]-64;L128/256/[512]/1024;K512/1024/2048/[4096]"; - - -// device type definition -DEFINE_DEVICE_TYPE(HARDDISK, harddisk_image_device, "harddisk_image", "Hard disk") - -//------------------------------------------------- -// harddisk_image_base_device - constructor -//------------------------------------------------- - -harddisk_image_base_device::harddisk_image_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) - : device_t(mconfig, type, tag, owner, clock) - , device_image_interface(mconfig, *this) -{ -} - -//------------------------------------------------- -// harddisk_image_device - constructor -//------------------------------------------------- - -harddisk_image_device::harddisk_image_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : harddisk_image_device(mconfig, HARDDISK, tag, owner, clock) -{ -} - -//------------------------------------------------- -// harddisk_image_device - constructor for subclasses -//------------------------------------------------- - -harddisk_image_device::harddisk_image_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) - : harddisk_image_base_device(mconfig, type, tag, owner, clock) - , m_chd(nullptr) - , m_hard_disk_handle() - , m_device_image_load(*this) - , m_device_image_unload(*this) - , m_interface(nullptr) -{ -} - -//------------------------------------------------- -// harddisk_image_device - destructor -//------------------------------------------------- - -harddisk_image_device::~harddisk_image_device() -{ -} - -//------------------------------------------------- -// device_config_complete - perform any -// operations now that the configuration is -// complete -//------------------------------------------------- - -void harddisk_image_device::device_config_complete() -{ - add_format("chd", "CHD Hard drive", "chd,hd,hdv,2mg,hdi", hd_option_spec); -} - -const util::option_guide &harddisk_image_device::create_option_guide() const -{ - return hd_option_guide; -} - -//------------------------------------------------- -// device_start - device-specific startup -//------------------------------------------------- - -void harddisk_image_device::device_start() -{ - m_device_image_load.resolve(); - m_device_image_unload.resolve(); - - m_chd = nullptr; - - if (has_preset_images()) - setup_current_preset_image(); - else - m_hard_disk_handle.reset(); -} - -void harddisk_image_device::device_stop() -{ - m_hard_disk_handle.reset(); -} - -std::pair harddisk_image_device::call_load() -{ - std::error_condition our_result = internal_load_hd(); - - // Check if there is an image_load callback defined - if (!our_result && !m_device_image_load.isnull()) - { - // Let the override do some additional work/checks - our_result = m_device_image_load(*this); - } - return std::make_pair(our_result, std::string()); - -} - -std::pair harddisk_image_device::call_create(int create_format, util::option_resolution *create_args) -{ - if (!create_args) - throw emu_fatalerror("harddisk_image_device::call_create: Expected create_args to not be nullptr"); - - const uint32_t cylinders = create_args->lookup_int('C'); - const uint32_t heads = create_args->lookup_int('H'); - const uint32_t sectors = create_args->lookup_int('S'); - const uint32_t sectorsize = create_args->lookup_int('L'); - const uint32_t hunksize = create_args->lookup_int('K'); - - const uint32_t totalsectors = cylinders * heads * sectors; - - // create the CHD file - chd_codec_type compression[4] = { CHD_CODEC_NONE }; - util::core_file::ptr proxy; - std::error_condition err = util::core_file::open_proxy(image_core_file(), proxy); - if (!err) - err = m_origchd.create(std::move(proxy), uint64_t(totalsectors) * uint64_t(sectorsize), hunksize, sectorsize, compression); - if (err) - return std::make_pair(err, std::string()); - - // if we created the image and hence, have metadata to set, set the metadata - err = m_origchd.write_metadata(HARD_DISK_METADATA_TAG, 0, string_format(HARD_DISK_METADATA_FORMAT, cylinders, heads, sectors, sectorsize)); - m_origchd.close(); - - if (err) - return std::make_pair(err, std::string()); - - return std::make_pair(internal_load_hd(), std::string()); -} - -void harddisk_image_device::setup_current_preset_image() -{ - chd_file *chd = current_preset_image_chd(); - m_hard_disk_handle.reset(new hard_disk_file(chd)); -} - -void harddisk_image_device::call_unload() -{ - // Check if there is an image_unload callback defined - if (!m_device_image_unload.isnull()) - m_device_image_unload(*this); - - m_hard_disk_handle.reset(); - - if (m_chd) - { - m_origchd.close(); - m_diffchd.close(); - } - m_chd = nullptr; -} - -/*------------------------------------------------- - open_disk_diff - open a DISK diff file --------------------------------------------------*/ - -static std::error_condition open_disk_diff(emu_options &options, const char *name, chd_file &source, chd_file &diff_chd) -{ - std::string fname = std::string(name).append(".dif"); - - /* try to open the diff */ - //printf("Opening differencing image file: %s\n", fname.c_str()); - emu_file diff_file(options.diff_directory(), OPEN_FLAG_READ | OPEN_FLAG_WRITE); - std::error_condition filerr = diff_file.open(fname); - if (!filerr) - { - std::string fullpath(diff_file.fullpath()); - diff_file.close(); - - //printf("Opening differencing image file: %s\n", fullpath.c_str()); - return diff_chd.open(fullpath, true, &source); - } - - /* didn't work; try creating it instead */ - //printf("Creating differencing image: %s\n", fname.c_str()); - diff_file.set_openflags(OPEN_FLAG_READ | OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); - filerr = diff_file.open(fname); - if (!filerr) - { - std::string fullpath(diff_file.fullpath()); - diff_file.close(); - - /* create the CHD */ - //printf("Creating differencing image file: %s\n", fupointllpath.c_str()); - chd_codec_type compression[4] = { CHD_CODEC_NONE }; - std::error_condition err = diff_chd.create(fullpath, source.logical_bytes(), source.hunk_bytes(), compression, source); - if (err) - return err; - - return diff_chd.clone_all_metadata(source); - } - - return std::errc::no_such_file_or_directory; -} - -std::error_condition harddisk_image_device::internal_load_hd() -{ - if (has_preset_images()) - { - setup_current_preset_image(); - return std::error_condition(); - } - - std::error_condition err; - m_chd = nullptr; - uint8_t header[0x200]; - - m_hard_disk_handle.reset(); - - // open the CHD file - if (loaded_through_softlist()) - { - m_chd = machine().rom_load().get_disk_handle(device().subtag("harddriv").c_str()); - } - else - { - fseek(0, SEEK_SET); - fread(header, 0x200); // read 512 bytes - fseek(0, SEEK_SET); - - if (!memcmp("MComprHD", header, 8)) - { - util::core_file::ptr proxy; - err = util::core_file::open_proxy(image_core_file(), proxy); - if (!err) - err = m_origchd.open(std::move(proxy), true); - - if (!err) - { - m_chd = &m_origchd; - } - else if (err == chd_file::error::FILE_NOT_WRITEABLE) - { - err = util::core_file::open_proxy(image_core_file(), proxy); - if (!err) - err = m_origchd.open(std::move(proxy), false); - - if (!err) - { - err = open_disk_diff(device().machine().options(), basename_noext(), m_origchd, m_diffchd); - if (!err) - { - m_chd = &m_diffchd; - } - } - } - } - } - - if (m_chd) - { - // open the hard disk file - try - { - m_hard_disk_handle.reset(new hard_disk_file(m_chd)); - if (m_hard_disk_handle) - return std::error_condition(); - } - catch (...) - { - err = image_error::INVALIDIMAGE; - } - } - else if (!is_open()) - { - err = image_error::UNSPECIFIED; - } - else - { - uint32_t skip = 0; - bool is_mbr = false; - uint8_t hd_start = 0; - uint8_t sct_start = 0; - uint16_t cyl_start = 0; - uint8_t hd_end = 0; - uint8_t sct_end = 0; - uint16_t cyl_end = 0; - - if (!memcmp(header, "2IMG", 4)) // check for 2MG format - { - skip = get_u32le(&header[0x18]); - osd_printf_verbose("harddriv: detected 2MG, creator is %c%c%c%c, data at %08x\n", header[4], header[5], header[6], header[7], skip); - } - else if (is_filetype("hdi")) // check for HDI format - { - skip = get_u32le(&header[0x8]); - uint32_t data_size = get_u32le(&header[0xc]); - if (data_size == length() - skip) - { - osd_printf_verbose("harddriv: detected Anex86 HDI, data at %08x\n", skip); - } - else - { - skip = 0; - } - } - else if (header[510] == 0x55 && header[511] == 0xAA) - { - is_mbr = true; - // this is a Master Boot Record disk - therefore, there is a partition table at 0x1BE - hd_start = header[0x1BE + 1]; - sct_start = header[0x1BE + 2] & 0x3F; - cyl_start = ((header[0x1BE + 2] & 0xC0) << 2) + header[0x1BE + 3]; - hd_end = header[0x1BE + 5]; - sct_end = header[0x1BE + 6] & 0x3F; - cyl_end = ((header[0x1BE + 6] & 0xC0) << 2) + header[0x1BE + 7]; - skip = (header[0x1BE + 8] + (header[0x1BE + 9] << 8) + (header[0x1BE + 10] << 16) + (header[0x1BE + 11] << 24)) * 512; - } - - try - { - if (!is_mbr) - m_hard_disk_handle.reset(new hard_disk_file(image_core_file(), skip)); - else - m_hard_disk_handle.reset(new hard_disk_file(image_core_file(), hd_start, sct_start, cyl_start, hd_end, sct_end, cyl_end, 0)); - if (m_hard_disk_handle) - return std::error_condition(); - } - catch (...) - { - err = image_error::INVALIDIMAGE; - } - } - - /* if we had an error, close out the CHD */ - m_diffchd.close(); - m_origchd.close(); - m_chd = nullptr; - - if (err) - return err; - else - return image_error::UNSPECIFIED; -} - -const hard_disk_file::info &harddisk_image_device::get_info() const -{ - return m_hard_disk_handle->get_info(); -} - -bool harddisk_image_device::read(uint32_t lbasector, void *buffer) -{ - logerror("Disk Read: %X\n", lbasector); - return m_hard_disk_handle->read(lbasector, buffer); -} - -bool harddisk_image_device::write(uint32_t lbasector, const void *buffer) -{ - return m_hard_disk_handle->write(lbasector, buffer); -} - - -bool harddisk_image_device::set_block_size(uint32_t blocksize) -{ - return m_hard_disk_handle->set_block_size(blocksize); -} - -std::error_condition harddisk_image_device::get_inquiry_data(std::vector &data) const -{ - return m_hard_disk_handle->get_inquiry_data(data); -} - -std::error_condition harddisk_image_device::get_cis_data(std::vector &data) const -{ - return m_hard_disk_handle->get_cis_data(data); -} - -std::error_condition harddisk_image_device::get_disk_key_data(std::vector &data) const -{ - return m_hard_disk_handle->get_disk_key_data(data); -} From 2bf708d8777a06709a914580353004cc492cb4a1 Mon Sep 17 00:00:00 2001 From: Daniel Tremblay Date: Wed, 6 Aug 2025 21:35:27 +0200 Subject: [PATCH 05/11] Addressed comments by ajrhacker. --- src/mame/f256/f256.cpp | 12 +++++++----- src/mame/f256/f256.h | 1 + 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/mame/f256/f256.cpp b/src/mame/f256/f256.cpp index 9b9f755c4879b..78ab57effa04d 100644 --- a/src/mame/f256/f256.cpp +++ b/src/mame/f256/f256.cpp @@ -3,7 +3,7 @@ #include "emu.h" #include "f256.h" -#include "cpu/m6502/w65c02.h" +#include "cpu/m6502/w65c02s.h" #include "tiny_vicky.h" /** @@ -41,6 +41,8 @@ f256_state::f256_state(const machine_config &mconfig, device_type type, const ch , m_opl3(*this, "ymf262") , m_sid0(*this, "sid_0") , m_sid1(*this, "sid_1") + , m_joy1(*this, "JOY1") + , m_joy2(*this, "JOY2") , m_video(*this, "tiny_vicky") //, m_iec(*this, "iec_bus") @@ -58,7 +60,7 @@ f256_state::f256_state(const machine_config &mconfig, device_type type, const ch void f256_state::f256k(machine_config &config) { - W65C02(config, m_maincpu, MASTER_CLOCK/4); + W65C02S(config, m_maincpu, MASTER_CLOCK/4); m_maincpu->set_addrmap(AS_PROGRAM, &f256_state::program_map); RAM(config, m_ram).set_default_size("512k").set_default_value(0x0); @@ -82,7 +84,7 @@ void f256_state::f256k(machine_config &config) m_video->sof_irq_handler().set(FUNC(f256_state::sof_interrtupt)); m_video->sol_irq_handler().set(FUNC(f256_state::sol_interrtupt)); - MOS6522(config, m_via6522_0, MASTER_CLOCK / 4); // Atari Joysticks + W65C22S(config, m_via6522_0, MASTER_CLOCK / 4); // Atari Joysticks m_via6522_0->readpa_handler().set(FUNC(f256_state::via0_system_porta_r)); m_via6522_0->readpb_handler().set(FUNC(f256_state::via0_system_portb_r)); m_via6522_0->writepa_handler().set(FUNC(f256_state::via0_system_porta_w)); @@ -1762,7 +1764,7 @@ TIMER_CALLBACK_MEMBER(f256_state::timer1) u8 f256_state::via0_system_porta_r() { //logerror("VIA #0 Port A Read ioport JOY2: %02X\n", data); - return ioport("JOY2")->read(); + return m_joy2->read(); } u8 f256_state::via0_system_portb_r() { @@ -1845,7 +1847,7 @@ void f256_state::via1_system_porta_w(u8 data) m_via_keyboard_port_a = data; m_via_keyboard_port_b = 0xFF; // scan each keyboard row - u8 joy1 = ioport("JOY1")->read(); + u8 joy1 = m_joy1->read(); m_via_joy1 = joy1 | 0x80; for (int r = 0; r < 8; r++) { diff --git a/src/mame/f256/f256.h b/src/mame/f256/f256.h index 2363bf0b2d98e..906f675209e07 100644 --- a/src/mame/f256/f256.h +++ b/src/mame/f256/f256.h @@ -64,6 +64,7 @@ class f256_state : public driver_device required_device m_sn0, m_sn1; required_device m_opl3; required_device m_sid0, m_sid1; + required_ioport m_joy1, m_joy2; required_device m_video; //required_device m_iec; From 451cb918c746cabe96e09337c964fa647e68284f Mon Sep 17 00:00:00 2001 From: Daniel Tremblay Date: Fri, 8 Aug 2025 23:41:14 +0200 Subject: [PATCH 06/11] Fixed the issue with "-validate" reporting a duplicate name. --- src/devices/machine/bq4847.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/devices/machine/bq4847.cpp b/src/devices/machine/bq4847.cpp index 9bd7564a3b0d7..0ea77c57ab9d4 100644 --- a/src/devices/machine/bq4847.cpp +++ b/src/devices/machine/bq4847.cpp @@ -103,7 +103,7 @@ bq4845_device::bq4845_device(const machine_config& mconfig, const char* tag, dev { } bq4802_device::bq4802_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock) - : bq4847_device(mconfig, BQ4845, tag, owner, clock) + : bq4847_device(mconfig, BQ4802, tag, owner, clock) { set_has_century(true); } From 22cac54ed05915d78410c6a0e08a7d8ac13716fa Mon Sep 17 00:00:00 2001 From: Daniel Tremblay Date: Mon, 18 Aug 2025 20:17:31 +0200 Subject: [PATCH 07/11] Converted the iopages to an array. --- src/mame/f256/f256.cpp | 151 ++++++++++++++++++++--------------------- src/mame/f256/f256.h | 7 +- 2 files changed, 76 insertions(+), 82 deletions(-) diff --git a/src/mame/f256/f256.cpp b/src/mame/f256/f256.cpp index 78ab57effa04d..1f907cef07a5b 100644 --- a/src/mame/f256/f256.cpp +++ b/src/mame/f256/f256.cpp @@ -24,10 +24,7 @@ f256_state::f256_state(const machine_config &mconfig, device_type type, const ch driver_device(mconfig, type, tag) , m_maincpu(*this, MAINCPU_TAG) , m_ram(*this, RAM_TAG) - , m_iopage0(*this, IOPAGE0_TAG) - , m_iopage1(*this, IOPAGE1_TAG) - , m_iopage2(*this, IOPAGE2_TAG) - , m_iopage3(*this, IOPAGE3_TAG) + , m_iopage(*this, "iopage%u", 0U) , m_rom(*this, ROM_TAG) , m_font(*this, FONT_TAG) , m_screen(*this, SCREEN_TAG) @@ -64,10 +61,10 @@ void f256_state::f256k(machine_config &config) m_maincpu->set_addrmap(AS_PROGRAM, &f256_state::program_map); RAM(config, m_ram).set_default_size("512k").set_default_value(0x0); - RAM(config, m_iopage0).set_default_size("8k").set_default_value(0x0); - RAM(config, m_iopage1).set_default_size("8k").set_default_value(0x0); - RAM(config, m_iopage2).set_default_size("8k").set_default_value(0x0); - RAM(config, m_iopage3).set_default_size("8k").set_default_value(0x0); + for (auto &iopage : m_iopage) + { + RAM(config, iopage).set_default_size("8k").set_default_value(0x0); + } SCREEN(config, m_screen, SCREEN_TYPE_RASTER); m_screen->set_refresh_hz(60); // Refresh rate (e.g., 60Hz) @@ -171,10 +168,10 @@ void f256_state::program_map(address_map &map) void f256_state::data_map(address_map &map) { - map(0x0000, 0x1FFF).ram().share(IOPAGE0_TAG); - map(0x0000, 0x1FFF).ram().share(IOPAGE1_TAG); - map(0x0000, 0x1FFF).ram().share(IOPAGE2_TAG); - map(0x0000, 0x1FFF).ram().share(IOPAGE3_TAG); + map(0x0000, 0x1FFF).ram().share("iopage0"); + map(0x0000, 0x1FFF).ram().share("iopage1"); + map(0x0000, 0x1FFF).ram().share("iopage2"); + map(0x0000, 0x1FFF).ram().share("iopage3"); } u8 f256_state::lut_r(offs_t offset) @@ -375,7 +372,7 @@ u8 f256_state::mem_r(offs_t offset) case 0xD65B: return (m_timer1_val >> 16) & 0xFF; } - return m_iopage0->read(adj_addr - 0xC000); + return m_iopage[0]->read(adj_addr - 0xC000); } else if (adj_addr >= 0xD660 && adj_addr < 0xD670) { @@ -459,7 +456,7 @@ u8 f256_state::mem_r(offs_t offset) case 0xD6A0: return m_sdcard->get_card_present() ? 0x10:0; case 0xD6A1: - return m_iopage0->read(0xD6A1 - 0xC000); + return m_iopage[0]->read(0xD6A1 - 0xC000); case 0xD6A4: if (m_rng_enabled) { @@ -588,7 +585,7 @@ u8 f256_state::mem_r(offs_t offset) case 0xB: return (m_addition_result >> 24) & 0xFF; } - return m_iopage0->read(adj_addr - 0xC000); + return m_iopage[0]->read(adj_addr - 0xC000); } else if (adj_addr >= 0xDF00 && adj_addr < 0xE000) { @@ -599,20 +596,20 @@ u8 f256_state::mem_r(offs_t offset) } else { - return m_iopage0->read(adj_addr - 0xC000); + return m_iopage[0]->read(adj_addr - 0xC000); } } // Stick everything else in Vicky // (adj_addr >= 0xC000 && adj_addr < 0xD400) || // gamma, mouse graphics, vicky registers, bitmaps, tiles // (adj_addr >= 0xD800 && adj_addr < 0xD880) || // text colors // (adj_addr >= 0xD900 && adj_addr < 0xDB00) // sprite registers - return m_iopage0->read(adj_addr - 0xC000); + return m_iopage[0]->read(adj_addr - 0xC000); case 1: - return m_iopage1->read(adj_addr - 0xC000); + return m_iopage[1]->read(adj_addr - 0xC000); case 2: - return m_iopage2->read(adj_addr - 0xC000); + return m_iopage[2]->read(adj_addr - 0xC000); case 3: - return m_iopage3->read(adj_addr - 0xC000); + return m_iopage[3]->read(adj_addr - 0xC000); } } offs_t address = (bank << 13) + low_addr; @@ -667,7 +664,7 @@ void f256_state::mem_w(offs_t offset, u8 data) m_screen->set_visarea(0, 639, 0, 479); m_screen->set_size(800,525); } - m_iopage0->write(0xD001 - 0xC000, data); + m_iopage[0]->write(0xD001 - 0xC000, data); } else if (adj_addr >= 0xD400 && adj_addr < 0xD419) { @@ -787,7 +784,7 @@ void f256_state::mem_w(offs_t offset, u8 data) { // Timers logerror("Writing to Timer Register: %X, %02X\n", adj_addr, data); - m_iopage0->write(adj_addr - 0xC000, data); + m_iopage[0]->write(adj_addr - 0xC000, data); switch(adj_addr) { case 0xD650: @@ -796,9 +793,9 @@ void f256_state::mem_w(offs_t offset, u8 data) if ((data & 0x1) == 1) { - uint32_t timer0_cmp = m_iopage0->read(0xD655 - 0xC000) + - (m_iopage0->read(0xD656 - 0xC000) << 8) + - (m_iopage0->read(0xD657 - 0xC000) << 16); + uint32_t timer0_cmp = m_iopage[0]->read(0xD655 - 0xC000) + + (m_iopage[0]->read(0xD656 - 0xC000) << 8) + + (m_iopage[0]->read(0xD657 - 0xC000) << 16); logerror("Start Timer0: %06X\n", timer0_cmp); attotime period = attotime::from_double((double)(timer0_cmp - m_timer0_load)/(double)25'175'000); m_timer0->adjust(period, 0, period); @@ -822,8 +819,8 @@ void f256_state::mem_w(offs_t offset, u8 data) case 0xD652: case 0xD653: // writing to these registers sets the load value - m_timer0_load = m_iopage0->read(0xD651 - 0xC000) + (m_iopage0->read(0xD652 - 0xC000) << 8) + - (m_iopage0->read(0xD653 - 0xC000) << 16); + m_timer0_load = m_iopage[0]->read(0xD651 - 0xC000) + (m_iopage[0]->read(0xD652 - 0xC000) << 8) + + (m_iopage[0]->read(0xD653 - 0xC000) << 16); break; case 0xD658: // Timer1 is based on the Start of Frame - so it's very slow @@ -831,7 +828,7 @@ void f256_state::mem_w(offs_t offset, u8 data) { logerror("Start Timer1 %X, %X\n", data, m_timer1_val); // Get the frame frequency from video - int frame_freq = (m_iopage0->read(0xD001 - 0xC000) & 1) == 1? 70: 60; + int frame_freq = (m_iopage[0]->read(0xD001 - 0xC000) & 1) == 1? 70: 60; m_timer1->adjust(attotime::from_hz(XTAL(frame_freq)), 0, attotime::from_hz(XTAL(frame_freq))); } else @@ -855,8 +852,8 @@ void f256_state::mem_w(offs_t offset, u8 data) case 0xD65A: case 0xD65B: // writing to these registers sets the load value - m_timer1_load = m_iopage0->read(0xD659 - 0xC000) + (m_iopage0->read(0xD65A - 0xC000) << 8) + - (m_iopage0->read(0xD65B - 0xC000) << 16); + m_timer1_load = m_iopage[0]->read(0xD659 - 0xC000) + (m_iopage[0]->read(0xD65A - 0xC000) << 8) + + (m_iopage[0]->read(0xD65B - 0xC000) << 16); break; } } @@ -978,7 +975,7 @@ void f256_state::mem_w(offs_t offset, u8 data) { case 0xD6A1: // mix the PSG or SID based on the value - m_iopage0->write(0xD6A1 - 0xC000, data); + m_iopage[0]->write(0xD6A1 - 0xC000, data); if ((data & 4) == 0) { // PSG mix - both outputs to both speakers @@ -1128,7 +1125,7 @@ void f256_state::mem_w(offs_t offset, u8 data) u8 block = (adj_addr - 0xDE00) >> 2; if (adj_addr < 0xDE10) { - m_iopage0->write(adj_addr - 0xC000, data); + m_iopage[0]->write(adj_addr - 0xC000, data); } switch (block) { @@ -1148,7 +1145,7 @@ void f256_state::mem_w(offs_t offset, u8 data) { // DMA logerror("DMA Write %04X %02X\n", adj_addr, data); - m_iopage0->write(adj_addr - 0xC000, data); + m_iopage[0]->write(adj_addr - 0xC000, data); if ((adj_addr - 0xDF00) == 0) { // control register - when start and enabled are set start DMA operation @@ -1188,18 +1185,18 @@ void f256_state::mem_w(offs_t offset, u8 data) // (adj_addr >= 0xD900 && adj_addr < 0xDB00) // sprite registers else { - m_iopage0->write(adj_addr - 0xC000, data); + m_iopage[0]->write(adj_addr - 0xC000, data); } break; case 1: - m_iopage1->write(adj_addr - 0xC000, data); + m_iopage[1]->write(adj_addr - 0xC000, data); break; case 2: - m_iopage2->write(adj_addr - 0xC000, data); + m_iopage[2]->write(adj_addr - 0xC000, data); break; case 3: - m_iopage3->write(adj_addr - 0xC000, data); + m_iopage[3]->write(adj_addr - 0xC000, data); break; } } @@ -1315,15 +1312,15 @@ void f256_state::iec_clk_w(int state) //------------------------------------------------- void f256_state::unsignedMultiplier(int baseAddr) { - uint16_t acc1 = (m_iopage0->read(baseAddr + 1) << 8) + m_iopage0->read(baseAddr); - uint16_t acc2 = (m_iopage0->read(baseAddr + 3) << 8) + m_iopage0->read(baseAddr + 2); + uint16_t acc1 = (m_iopage[0]->read(baseAddr + 1) << 8) + m_iopage[0]->read(baseAddr); + uint16_t acc2 = (m_iopage[0]->read(baseAddr + 3) << 8) + m_iopage[0]->read(baseAddr + 2); m_multiplication_result = acc1 * acc2; } void f256_state::unsignedDivider(int baseAddr) { - uint16_t acc1 = (m_iopage0->read(baseAddr + 1) << 8) + m_iopage0->read(baseAddr); - uint16_t acc2 = (m_iopage0->read(baseAddr + 3) << 8) + m_iopage0->read(baseAddr + 2); + uint16_t acc1 = (m_iopage[0]->read(baseAddr + 1) << 8) + m_iopage[0]->read(baseAddr); + uint16_t acc2 = (m_iopage[0]->read(baseAddr + 3) << 8) + m_iopage[0]->read(baseAddr + 2); if (acc1 != 0) { m_division_result= acc2 / acc1; @@ -1333,10 +1330,10 @@ void f256_state::unsignedDivider(int baseAddr) void f256_state::unsignedAdder(int baseAddr) { - int acc1 = (m_iopage0->read(baseAddr + 3) << 24) + (m_iopage0->read(baseAddr + 2) << 16) + - (m_iopage0->read(baseAddr + 1) << 8) + m_iopage0->read(baseAddr); - int acc2 = (m_iopage0->read(baseAddr + 7) << 24) + (m_iopage0->read(baseAddr + 6) << 16) + - (m_iopage0->read(baseAddr + 5) << 8) + m_iopage0->read(baseAddr + 4); + int acc1 = (m_iopage[0]->read(baseAddr + 3) << 24) + (m_iopage[0]->read(baseAddr + 2) << 16) + + (m_iopage[0]->read(baseAddr + 1) << 8) + m_iopage[0]->read(baseAddr); + int acc2 = (m_iopage[0]->read(baseAddr + 7) << 24) + (m_iopage[0]->read(baseAddr + 6) << 16) + + (m_iopage[0]->read(baseAddr + 5) << 8) + m_iopage[0]->read(baseAddr + 4); m_addition_result = acc1 + acc2; } @@ -1354,11 +1351,11 @@ uint8_t f256_state::get_random() void f256_state::perform2DFillDMA() { - uint8_t fill_byte = m_iopage0->read(0xDF01 - 0xC000); - uint32_t dest_addr = ((m_iopage0->read(0xDF0A) & 0x7) << 16) + (m_iopage0->read(0xDF09) << 8) + m_iopage0->read(0xDF08); - uint16_t width_2D = (m_iopage0->read(0xDF0D - 0xC000) << 8) + m_iopage0->read(0xDF0C - 0xC000); - uint16_t height_2D = (m_iopage0->read(0xDF0F - 0xC000) << 8) + m_iopage0->read(0xDF0E - 0xC000); - uint16_t dest_stride = (m_iopage0->read(0xDF13 - 0xC000) << 8) + m_iopage0->read(0xDF12 - 0xC000); + uint8_t fill_byte = m_iopage[0]->read(0xDF01 - 0xC000); + uint32_t dest_addr = ((m_iopage[0]->read(0xDF0A) & 0x7) << 16) + (m_iopage[0]->read(0xDF09) << 8) + m_iopage[0]->read(0xDF08); + uint16_t width_2D = (m_iopage[0]->read(0xDF0D - 0xC000) << 8) + m_iopage[0]->read(0xDF0C - 0xC000); + uint16_t height_2D = (m_iopage[0]->read(0xDF0F - 0xC000) << 8) + m_iopage[0]->read(0xDF0E - 0xC000); + uint16_t dest_stride = (m_iopage[0]->read(0xDF13 - 0xC000) << 8) + m_iopage[0]->read(0xDF12 - 0xC000); //logerror("2D Fill DMA: DEST: %X, W: %X, H: %X\n", dest_addr, width_2D, height_2D); for (int y = 0; y < height_2D; y++) { @@ -1370,20 +1367,20 @@ void f256_state::perform2DFillDMA() } void f256_state::performLinearFillDMA() { - uint8_t fill_byte = m_iopage0->read(0xDF01 - 0xC000); - uint32_t dest_addr = ((m_iopage0->read(0xDF0A) & 0x7) << 16) + (m_iopage0->read(0xDF09) << 8) + m_iopage0->read(0xDF08); - uint32_t count = ((m_iopage0->read(0xDF0E) & 0x7) << 16) + (m_iopage0->read(0xDF0D) << 8) + m_iopage0->read(0xDF0C); + uint8_t fill_byte = m_iopage[0]->read(0xDF01 - 0xC000); + uint32_t dest_addr = ((m_iopage[0]->read(0xDF0A) & 0x7) << 16) + (m_iopage[0]->read(0xDF09) << 8) + m_iopage[0]->read(0xDF08); + uint32_t count = ((m_iopage[0]->read(0xDF0E) & 0x7) << 16) + (m_iopage[0]->read(0xDF0D) << 8) + m_iopage[0]->read(0xDF0C); //logerror("Linear Fill DMA DEST: %X, LEN: %X\n", dest_addr, count); memset(m_ram->pointer() + dest_addr, fill_byte, count); } void f256_state::perform2DDMA() { - uint32_t src_addr = ((m_iopage0->read(0xDF06) & 0x7) << 16) + (m_iopage0->read(0xDF05) << 8) + m_iopage0->read(0xDF04); - uint32_t dest_addr = ((m_iopage0->read(0xDF0A) & 0x7) << 16) + (m_iopage0->read(0xDF09) << 8) + m_iopage0->read(0xDF08); - uint16_t width_2D = (m_iopage0->read(0xDF0D - 0xC000) << 8) + m_iopage0->read(0xDF0C - 0xC000); - uint16_t height_2D = (m_iopage0->read(0xDF0F - 0xC000) << 8) + m_iopage0->read(0xDF0E - 0xC000); - uint16_t src_stride = (m_iopage0->read(0xDF11 - 0xC000) << 8) + m_iopage0->read(0xDF10 - 0xC000); - uint16_t dest_stride = (m_iopage0->read(0xDF13 - 0xC000) << 8) + m_iopage0->read(0xDF12 - 0xC000); + uint32_t src_addr = ((m_iopage[0]->read(0xDF06) & 0x7) << 16) + (m_iopage[0]->read(0xDF05) << 8) + m_iopage[0]->read(0xDF04); + uint32_t dest_addr = ((m_iopage[0]->read(0xDF0A) & 0x7) << 16) + (m_iopage[0]->read(0xDF09) << 8) + m_iopage[0]->read(0xDF08); + uint16_t width_2D = (m_iopage[0]->read(0xDF0D - 0xC000) << 8) + m_iopage[0]->read(0xDF0C - 0xC000); + uint16_t height_2D = (m_iopage[0]->read(0xDF0F - 0xC000) << 8) + m_iopage[0]->read(0xDF0E - 0xC000); + uint16_t src_stride = (m_iopage[0]->read(0xDF11 - 0xC000) << 8) + m_iopage[0]->read(0xDF10 - 0xC000); + uint16_t dest_stride = (m_iopage[0]->read(0xDF13 - 0xC000) << 8) + m_iopage[0]->read(0xDF12 - 0xC000); //logerror("2D Copy DMA, SRC: %X, DEST: %X, W: %X H: %X, SRC_STR: %X, DEST_STR: %X\n", src_addr, dest_addr, // width_2D, height_2D, src_stride, dest_stride); for (int y = 0; y < height_2D; y++) @@ -1397,9 +1394,9 @@ void f256_state::perform2DDMA() } void f256_state::performLinearDMA() { - uint32_t src_addr = ((m_iopage0->read(0xDF06) & 0x7) << 16) + (m_iopage0->read(0xDF05) << 8) + m_iopage0->read(0xDF04); - uint32_t dest_addr = ((m_iopage0->read(0xDF0A) & 0x7) << 16) + (m_iopage0->read(0xDF09) << 8) + m_iopage0->read(0xDF08); - uint32_t count = ((m_iopage0->read(0xDF0E) & 0x7) << 16) + (m_iopage0->read(0xDF0D) << 8) + m_iopage0->read(0xDF0C); + uint32_t src_addr = ((m_iopage[0]->read(0xDF06) & 0x7) << 16) + (m_iopage[0]->read(0xDF05) << 8) + m_iopage[0]->read(0xDF04); + uint32_t dest_addr = ((m_iopage[0]->read(0xDF0A) & 0x7) << 16) + (m_iopage[0]->read(0xDF09) << 8) + m_iopage[0]->read(0xDF08); + uint32_t count = ((m_iopage[0]->read(0xDF0E) & 0x7) << 16) + (m_iopage[0]->read(0xDF0D) << 8) + m_iopage[0]->read(0xDF0C); //logerror("Linear Copy DMA SRC: %X, DEST: %X, LEN: %X\n", src_addr, dest_addr, count); memcpy(m_ram->pointer() + dest_addr, m_ram->pointer() + src_addr, count); } @@ -1413,10 +1410,10 @@ void f256_state::device_start() driver_device::device_start(); reset_mmu(); // TODO: Copy the font from file to IO Page 1 - //memcpy(m_iopage1, m_font, 0x800); + //memcpy(m_iopage[1], m_font, 0x800); for (int i=0;i<0x800;i++) { - m_iopage1->write(i, m_font->as_u8(i)); + m_iopage[1]->write(i, m_font->as_u8(i)); } // Copy the gamma correction table uint8_t gamma_1_8[] = { @@ -1438,10 +1435,10 @@ void f256_state::device_start() 0xf6, 0xf7, 0xf7, 0xf8, 0xf8, 0xf9, 0xf9, 0xfa, 0xfb, 0xfb, 0xfc, 0xfc, 0xfd, 0xfd, 0xfe, 0xff }; - memcpy(m_iopage0->pointer(), gamma_1_8, 256); - memcpy(m_iopage0->pointer() + 0x400, gamma_1_8, 256); - memcpy(m_iopage0->pointer() + 0x800, gamma_1_8, 256); - m_video->set_videoram(m_ram->pointer(), m_iopage0->pointer(), m_iopage1->pointer(), m_iopage2->pointer(), m_iopage3->pointer()); + memcpy(m_iopage[0]->pointer(), gamma_1_8, 256); + memcpy(m_iopage[0]->pointer() + 0x400, gamma_1_8, 256); + memcpy(m_iopage[0]->pointer() + 0x800, gamma_1_8, 256); + m_video->set_videoram(m_ram->pointer(), m_iopage[0]->pointer(), m_iopage[1]->pointer(), m_iopage[2]->pointer(), m_iopage[3]->pointer()); m_video->start(); // set the current time on the RTC device @@ -1622,7 +1619,7 @@ TIMER_CALLBACK_MEMBER(f256_state::spi_clock) TIMER_CALLBACK_MEMBER(f256_state::timer0) { logerror("Timer0 reached value: %06X\n", m_timer0_load); - uint8_t reg_t0 = m_iopage0->read(0xD650 - 0xC000); + uint8_t reg_t0 = m_iopage[0]->read(0xD650 - 0xC000); if ((reg_t0 & 0x80) !=0) { timer0_interrupt_handler(1); @@ -1630,14 +1627,14 @@ TIMER_CALLBACK_MEMBER(f256_state::timer0) } // TIMER_CALLBACK_MEMBER(f256_state::timer0) // { -// uint8_t reg_t0 = m_iopage0->read(0xD650 - 0xC000); -// uint32_t cmp = m_iopage0->read(0xD655 - 0xC000) + (m_iopage0->read(0xD656 - 0xC000) << 8) + -// (m_iopage0->read(0xD657 - 0xC000) << 16); +// uint8_t reg_t0 = m_iopage[0]->read(0xD650 - 0xC000); +// uint32_t cmp = m_iopage[0]->read(0xD655 - 0xC000) + (m_iopage[0]->read(0xD656 - 0xC000) << 8) + +// (m_iopage[0]->read(0xD657 - 0xC000) << 16); // // if timer as reached value, then execute the action // if (m_timer0_eq == 1) // { -// int8_t action = m_iopage0->read(0xD654 - 0xC000); +// int8_t action = m_iopage[0]->read(0xD654 - 0xC000); // if (action & 1) // { // logerror("TIMER0 Cleared\n"); @@ -1696,14 +1693,14 @@ TIMER_CALLBACK_MEMBER(f256_state::timer0) // This timer is much slower than Timer0, so we can use single increments TIMER_CALLBACK_MEMBER(f256_state::timer1) { - uint8_t reg_t1 = m_iopage0->read(0xD658 - 0xC000); - uint32_t cmp = m_iopage0->read(0xD65D - 0xC000) + (m_iopage0->read(0xD65E - 0xC000) << 8) + - (m_iopage0->read(0xD65F - 0xC000) << 16); + uint8_t reg_t1 = m_iopage[0]->read(0xD658 - 0xC000); + uint32_t cmp = m_iopage[0]->read(0xD65D - 0xC000) + (m_iopage[0]->read(0xD65E - 0xC000) << 8) + + (m_iopage[0]->read(0xD65F - 0xC000) << 16); logerror("TIMER1 event %06X CMP: %06X\n", m_timer1_val, cmp); // if timer as reached value, then execute the action if (m_timer1_eq == 1) { - int8_t action = m_iopage0->read(0xD65C - 0xC000); + int8_t action = m_iopage[0]->read(0xD65C - 0xC000); if (action & 1) { logerror("TIMER1 Cleared\n"); diff --git a/src/mame/f256/f256.h b/src/mame/f256/f256.h index 906f675209e07..1b27a2fa9a72d 100644 --- a/src/mame/f256/f256.h +++ b/src/mame/f256/f256.h @@ -29,10 +29,7 @@ #define MUSIC_CLOCK (XTAL(14'318'181)) #define MAINCPU_TAG "maincpu" #define RAM_TAG "ram" -#define IOPAGE0_TAG "iopage0" -#define IOPAGE1_TAG "iopage1" -#define IOPAGE2_TAG "iopage2" -#define IOPAGE3_TAG "iopage3" +#define IOPAGE_TAG "iopage" #define ROM_TAG "rom" #define FONT_TAG "font" #define FLASH_TAG "flash" @@ -54,7 +51,7 @@ class f256_state : public driver_device private: required_device m_maincpu; required_device m_ram; - required_device m_iopage0, m_iopage1, m_iopage2, m_iopage3; + required_device_array m_iopage; required_memory_region m_rom; required_memory_region m_font; required_device m_screen; From ebc5f478786034ad0810b68ef2c6fecbe6147af5 Mon Sep 17 00:00:00 2001 From: Daniel Tremblay Date: Mon, 18 Aug 2025 20:33:12 +0200 Subject: [PATCH 08/11] Used a DEFINED variable instead of magic string. --- src/mame/f256/f256.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/mame/f256/f256.cpp b/src/mame/f256/f256.cpp index 1f907cef07a5b..87a90b46c4566 100644 --- a/src/mame/f256/f256.cpp +++ b/src/mame/f256/f256.cpp @@ -24,7 +24,7 @@ f256_state::f256_state(const machine_config &mconfig, device_type type, const ch driver_device(mconfig, type, tag) , m_maincpu(*this, MAINCPU_TAG) , m_ram(*this, RAM_TAG) - , m_iopage(*this, "iopage%u", 0U) + , m_iopage(*this, IOPAGE_TAG "%u", 0U) , m_rom(*this, ROM_TAG) , m_font(*this, FONT_TAG) , m_screen(*this, SCREEN_TAG) @@ -168,10 +168,10 @@ void f256_state::program_map(address_map &map) void f256_state::data_map(address_map &map) { - map(0x0000, 0x1FFF).ram().share("iopage0"); - map(0x0000, 0x1FFF).ram().share("iopage1"); - map(0x0000, 0x1FFF).ram().share("iopage2"); - map(0x0000, 0x1FFF).ram().share("iopage3"); + map(0x0000, 0x1FFF).ram().share(IOPAGE_TAG "0"); + map(0x0000, 0x1FFF).ram().share(IOPAGE_TAG "1"); + map(0x0000, 0x1FFF).ram().share(IOPAGE_TAG "2"); + map(0x0000, 0x1FFF).ram().share(IOPAGE_TAG "3"); } u8 f256_state::lut_r(offs_t offset) From a4964ede3eb9f9009f4140199e04f2850ad95add Mon Sep 17 00:00:00 2001 From: Daniel Tremblay Date: Mon, 18 Aug 2025 21:44:25 +0200 Subject: [PATCH 09/11] Converted other devices to arrays. Retested with both "-validate" flag and with actual applications. SID is still noisy. --- src/mame/f256/f256.cpp | 198 +++++++++++++++++++++-------------------- src/mame/f256/f256.h | 9 +- 2 files changed, 106 insertions(+), 101 deletions(-) diff --git a/src/mame/f256/f256.cpp b/src/mame/f256/f256.cpp index 87a90b46c4566..bac70f7be0e39 100644 --- a/src/mame/f256/f256.cpp +++ b/src/mame/f256/f256.cpp @@ -30,16 +30,12 @@ f256_state::f256_state(const machine_config &mconfig, device_type type, const ch , m_screen(*this, SCREEN_TAG) , m_rtc(*this, "rtc") , m_keyboard(*this, "ROW%u", 0) // this, with the 8 array, requires 8 ROW of INPUTs - , m_via6522_0(*this, "via6522_0") - , m_via6522_1(*this, "via6522_1") + , m_via6522(*this, VIA_TAG "%u", 0U) - , m_sn0(*this, "sn76489_0") - , m_sn1(*this, "sn76489_1") + , m_sn(*this, "sn76489_%u", 0U) , m_opl3(*this, "ymf262") - , m_sid0(*this, "sid_0") - , m_sid1(*this, "sid_1") - , m_joy1(*this, "JOY1") - , m_joy2(*this, "JOY2") + , m_sid(*this, "sid_%u", 0U) + , m_joy(*this, "JOY%u", 1U) , m_video(*this, "tiny_vicky") //, m_iec(*this, "iec_bus") @@ -81,51 +77,59 @@ void f256_state::f256k(machine_config &config) m_video->sof_irq_handler().set(FUNC(f256_state::sof_interrtupt)); m_video->sol_irq_handler().set(FUNC(f256_state::sol_interrtupt)); - W65C22S(config, m_via6522_0, MASTER_CLOCK / 4); // Atari Joysticks - m_via6522_0->readpa_handler().set(FUNC(f256_state::via0_system_porta_r)); - m_via6522_0->readpb_handler().set(FUNC(f256_state::via0_system_portb_r)); - m_via6522_0->writepa_handler().set(FUNC(f256_state::via0_system_porta_w)); - m_via6522_0->writepb_handler().set(FUNC(f256_state::via0_system_portb_w)); - m_via6522_0->ca2_handler().set(FUNC(f256_state::via0_ca2_write)); - m_via6522_0->cb2_handler().set(FUNC(f256_state::via0_cb2_write)); - m_via6522_0->irq_handler().set(FUNC(f256_state::via0_interrupt)); + // VIA are used to implement the keyboard and Atari-style joysticks polling + for (auto &via655: m_via6522) + { + W65C22S(config, via655, MASTER_CLOCK / 4); // Atari Joysticks + } + // The functions for VIA 0 and VIA 1 are different as they poll different devices + m_via6522[0]->readpa_handler().set(FUNC(f256_state::via0_system_porta_r)); + m_via6522[0]->readpb_handler().set(FUNC(f256_state::via0_system_portb_r)); + m_via6522[0]->writepa_handler().set(FUNC(f256_state::via0_system_porta_w)); + m_via6522[0]->writepb_handler().set(FUNC(f256_state::via0_system_portb_w)); + m_via6522[0]->ca2_handler().set(FUNC(f256_state::via0_ca2_write)); + m_via6522[0]->cb2_handler().set(FUNC(f256_state::via0_cb2_write)); + m_via6522[0]->irq_handler().set(FUNC(f256_state::via0_interrupt)); + + m_via6522[1]->readpa_handler().set(FUNC(f256_state::via1_system_porta_r)); + m_via6522[1]->readpb_handler().set(FUNC(f256_state::via1_system_portb_r)); + m_via6522[1]->writepa_handler().set(FUNC(f256_state::via1_system_porta_w)); + m_via6522[1]->writepb_handler().set(FUNC(f256_state::via1_system_portb_w)); + m_via6522[1]->ca2_handler().set(FUNC(f256_state::via1_ca2_write)); + m_via6522[1]->cb2_handler().set(FUNC(f256_state::via1_cb2_write)); + m_via6522[1]->irq_handler().set(FUNC(f256_state::via1_interrupt)); // initialize the PS2 mouse PC_KBDC(config, m_ps2_keyboard, XTAL(32'768)); HLE_PS2_MOUSE(config, m_mouse, XTAL(32'768)); m_mouse->set_pc_kbdc(m_ps2_keyboard); + - MOS6522(config, m_via6522_1, MASTER_CLOCK / 4); // Keyboard XTAL(14'318'181)/14) - m_via6522_1->readpa_handler().set(FUNC(f256_state::via1_system_porta_r)); - m_via6522_1->readpb_handler().set(FUNC(f256_state::via1_system_portb_r)); - m_via6522_1->writepa_handler().set(FUNC(f256_state::via1_system_porta_w)); - m_via6522_1->writepb_handler().set(FUNC(f256_state::via1_system_portb_w)); - m_via6522_1->ca2_handler().set(FUNC(f256_state::via1_ca2_write)); - m_via6522_1->cb2_handler().set(FUNC(f256_state::via1_cb2_write)); - m_via6522_1->irq_handler().set(FUNC(f256_state::via1_interrupt)); - - // Mix PSG - SN76489(config, m_sn0, MUSIC_CLOCK / 4); - m_sn0->add_route(ALL_OUTPUTS, "lspeaker", 0.5); - m_sn0->add_route(ALL_OUTPUTS, "rspeaker", 0.5); - SN76489(config, m_sn1, MUSIC_CLOCK / 4); - m_sn1->add_route(ALL_OUTPUTS, "lspeaker", 0.5); - m_sn1->add_route(ALL_OUTPUTS, "rspeaker", 0.5); + // There are two PSG sound chips + for (auto &sn: m_sn) + { + SN76489(config, sn, MUSIC_CLOCK / 4); + sn->add_route(ALL_OUTPUTS, "lspeaker", 0.5); + sn->add_route(ALL_OUTPUTS, "rspeaker", 0.5); + } + // Single OPL3 sound chip YMF262(config, m_opl3, MUSIC_CLOCK); m_opl3->add_route(0, "lspeaker", 1.0); m_opl3->add_route(1, "rspeaker", 1.0); m_opl3->add_route(2, "lspeaker", 1.0); m_opl3->add_route(3, "rspeaker", 1.0); - // The SIDs are very noisy - MOS6581(config, m_sid0, MUSIC_CLOCK/14); - m_sid0->add_route(ALL_OUTPUTS, "lspeaker", 0.5); - m_sid0->add_route(ALL_OUTPUTS, "rspeaker", 0.5); - MOS6581(config, m_sid1, MUSIC_CLOCK/14); - m_sid1->add_route(ALL_OUTPUTS, "lspeaker", 0.5); - m_sid1->add_route(ALL_OUTPUTS, "rspeaker", 0.5); - + // There are two SID sound chips + // Try to figure out why the SID are so noisy + for (auto &sid: m_sid) + { + MOS6581(config, sid, MUSIC_CLOCK/14); + sid->add_route(ALL_OUTPUTS, "lspeaker", 0.25); + sid->add_route(ALL_OUTPUTS, "rspeaker", 0.25); + } + + // Mix all sound chips SPEAKER(config, "lspeaker").front_left(); SPEAKER(config, "rspeaker").front_right(); @@ -527,12 +531,12 @@ u8 f256_state::mem_r(offs_t offset) else if (adj_addr >= 0xDB00 && adj_addr < 0xDB10) { // VIA1 - Keyboard for F256K - return m_via6522_1->read(adj_addr - 0xDB00); + return m_via6522[1]->read(adj_addr - 0xDB00); } else if (adj_addr >= 0xDC00 && adj_addr < 0xDC10) { // VIA0 - Atari Joystick - return m_via6522_0->read(adj_addr - 0xDC00); + return m_via6522[0]->read(adj_addr - 0xDC00); } else if (adj_addr >= 0xDD00 && adj_addr < 0xDD20) { @@ -669,13 +673,13 @@ void f256_state::mem_w(offs_t offset, u8 data) else if (adj_addr >= 0xD400 && adj_addr < 0xD419) { // SID 0 - m_sid0->write(adj_addr - 0xD400, data); + m_sid[0]->write(adj_addr - 0xD400, data); } else if (adj_addr >= 0xD500 && adj_addr < 0xD519) { // SID 1 - m_sid1->write(adj_addr - 0xD500, data); + m_sid[1]->write(adj_addr - 0xD500, data); } else if (adj_addr >= 0xD580 && adj_addr < 0xD583) { @@ -700,20 +704,20 @@ void f256_state::mem_w(offs_t offset, u8 data) { // PSG logerror("PSG Left Write: %02X\n", data); - m_sn0->write(data); + m_sn[0]->write(data); } else if (adj_addr == 0xD608) { // PSG logerror("PSG Both Write: %02X\n", data); - m_sn0->write(data); - m_sn1->write(data); + m_sn[0]->write(data); + m_sn[1]->write(data); } else if (adj_addr == 0xD610) { // PSG logerror("PSG Right Write: %02X\n", data); - m_sn1->write(data); + m_sn[1]->write(data); } else if (adj_addr >= 0xD620 && adj_addr < 0xD630) { @@ -979,37 +983,37 @@ void f256_state::mem_w(offs_t offset, u8 data) if ((data & 4) == 0) { // PSG mix - both outputs to both speakers - m_sn0->reset_routes(); - m_sn1->reset_routes(); - m_sn0->add_route(ALL_OUTPUTS, "lspeaker", 0.5); - m_sn0->add_route(ALL_OUTPUTS, "rspeaker", 0.5); - m_sn1->add_route(ALL_OUTPUTS, "lspeaker", 0.5); - m_sn1->add_route(ALL_OUTPUTS, "rspeaker", 0.5); + m_sn[0]->reset_routes(); + m_sn[1]->reset_routes(); + m_sn[0]->add_route(ALL_OUTPUTS, "lspeaker", 0.5); + m_sn[0]->add_route(ALL_OUTPUTS, "rspeaker", 0.5); + m_sn[1]->add_route(ALL_OUTPUTS, "lspeaker", 0.5); + m_sn[1]->add_route(ALL_OUTPUTS, "rspeaker", 0.5); } else { // PSG0 to left, PSG1 to right - m_sn0->reset_routes(); - m_sn1->reset_routes(); - m_sn0->add_route(ALL_OUTPUTS, "lspeaker", 1.0); - m_sn1->add_route(ALL_OUTPUTS, "rspeaker", 1.0); + m_sn[0]->reset_routes(); + m_sn[1]->reset_routes(); + m_sn[0]->add_route(ALL_OUTPUTS, "lspeaker", 1.0); + m_sn[1]->add_route(ALL_OUTPUTS, "rspeaker", 1.0); } if ((data & 8) == 0) { // SID mix - - m_sid0->reset_routes(); - m_sid1->reset_routes(); - m_sid0->add_route(ALL_OUTPUTS, "lspeaker", 0.5); - m_sid0->add_route(ALL_OUTPUTS, "rspeaker", 0.5); - m_sid1->add_route(ALL_OUTPUTS, "lspeaker", 0.5); - m_sid1->add_route(ALL_OUTPUTS, "rspeaker", 0.5); + m_sid[0]->reset_routes(); + m_sid[1]->reset_routes(); + m_sid[0]->add_route(ALL_OUTPUTS, "lspeaker", 0.5); + m_sid[0]->add_route(ALL_OUTPUTS, "rspeaker", 0.5); + m_sid[1]->add_route(ALL_OUTPUTS, "lspeaker", 0.5); + m_sid[1]->add_route(ALL_OUTPUTS, "rspeaker", 0.5); } else { - m_sid0->reset_routes(); - m_sid1->reset_routes(); - m_sid0->add_route(ALL_OUTPUTS, "lspeaker", 1.0); - m_sid1->add_route(ALL_OUTPUTS, "rspeaker", 1.0); + m_sid[0]->reset_routes(); + m_sid[1]->reset_routes(); + m_sid[0]->add_route(ALL_OUTPUTS, "lspeaker", 1.0); + m_sid[1]->add_route(ALL_OUTPUTS, "rspeaker", 1.0); } break; case 0xD6A4: @@ -1070,12 +1074,12 @@ void f256_state::mem_w(offs_t offset, u8 data) else if (adj_addr >= 0xDB00 && adj_addr < 0xDC00) { // VIA1 - Keyboard for F256K - m_via6522_1->write(adj_addr - 0xDB00, data); + m_via6522[1]->write(adj_addr - 0xDB00, data); } else if (adj_addr >= 0xDC00 && adj_addr < 0xDD00) { // VIA0 - Atari Joystick - m_via6522_0->write(adj_addr - 0xDC00, data); + m_via6522[0]->write(adj_addr - 0xDC00, data); } else if (adj_addr >= 0xDD00 && adj_addr < 0xDD20) { @@ -1449,18 +1453,18 @@ void f256_state::device_start() m_rtc->set_current_time(stnow); // Initialize the VIA0 - m_via6522_0->write(via6522_device::VIA_DDRB, 0xFF); // DDRB - m_via6522_0->write(via6522_device::VIA_DDRA, 0xFF); // DDRA - m_via6522_0->write(via6522_device::VIA_PB, 0xFF); // JOYSTICK 2 - m_via6522_0->write(via6522_device::VIA_PA, 0xFF); // JOYSTICK 1 - m_via6522_0->write(via6522_device::VIA_DDRB, 0); // DDRB - m_via6522_0->write(via6522_device::VIA_DDRA, 0); // DDRA + m_via6522[0]->write(via6522_device::VIA_DDRB, 0xFF); // DDRB + m_via6522[0]->write(via6522_device::VIA_DDRA, 0xFF); // DDRA + m_via6522[0]->write(via6522_device::VIA_PB, 0xFF); // JOYSTICK 2 + m_via6522[0]->write(via6522_device::VIA_PA, 0xFF); // JOYSTICK 1 + m_via6522[0]->write(via6522_device::VIA_DDRB, 0); // DDRB + m_via6522[0]->write(via6522_device::VIA_DDRA, 0); // DDRA // Initialize the VIA1 - m_via6522_1->write(via6522_device::VIA_PB, 0); - m_via6522_1->write(via6522_device::VIA_PA, 0); - m_via6522_1->write(via6522_device::VIA_DDRB, 0); // DDRB - m_via6522_1->write(via6522_device::VIA_DDRA, 0); // DDRA + m_via6522[1]->write(via6522_device::VIA_PB, 0); + m_via6522[1]->write(via6522_device::VIA_PA, 0); + m_via6522[1]->write(via6522_device::VIA_DDRB, 0); // DDRB + m_via6522[1]->write(via6522_device::VIA_DDRA, 0); // DDRA // Initialize SD Card / SPI clock m_spi_clock = timer_alloc(FUNC(f256_state::spi_clock), this); @@ -1483,8 +1487,8 @@ void f256_state::device_reset() { driver_device::device_reset(); reset_mmu(); - m_via6522_0->reset(); - m_via6522_1->reset(); + m_via6522[0]->reset(); + m_via6522[1]->reset(); m_opl3->reset(); m_sdcard->reset(); @@ -1495,10 +1499,10 @@ void f256_state::device_reset() spi_sd_enabled = 0; m_mouse->reset(); - m_sid0->reset(); - m_sid1->reset(); - m_sn0->reset(); - m_sn1->reset(); + m_sid[0]->reset(); + m_sid[1]->reset(); + m_sn[0]->reset(); + m_sn[1]->reset(); //m_iec->reset(); m_uart->reset(); @@ -1761,7 +1765,7 @@ TIMER_CALLBACK_MEMBER(f256_state::timer1) u8 f256_state::via0_system_porta_r() { //logerror("VIA #0 Port A Read ioport JOY2: %02X\n", data); - return m_joy2->read(); + return m_joy[1]->read(); } u8 f256_state::via0_system_portb_r() { @@ -1772,23 +1776,23 @@ void f256_state::via0_system_porta_w(u8 data) { //logerror("VIA #0 Port A Write: %02X\n", data); // writing should only be done if DDR allows it - m_via6522_0->write_pa(data); + m_via6522[0]->write_pa(data); } void f256_state::via0_system_portb_w(u8 data) { //logerror("VIA #0 Port B Write: %02X\n", data); // writing should only be done if DDR allows it - m_via6522_0->write_pb(data); + m_via6522[0]->write_pb(data); } void f256_state::via0_ca2_write(u8 value) { //logerror("Write to VIA0 - CA2 %02X\n", value); - m_via6522_0->write_ca2(value); + m_via6522[0]->write_ca2(value); } void f256_state::via0_cb2_write(u8 value) { //logerror("Write to VIA0 - CB2 %02X\n", value); - m_via6522_0->write_cb2(value); + m_via6522[0]->write_cb2(value); } static INPUT_PORTS_START(f256k_mouse) @@ -1844,7 +1848,7 @@ void f256_state::via1_system_porta_w(u8 data) m_via_keyboard_port_a = data; m_via_keyboard_port_b = 0xFF; // scan each keyboard row - u8 joy1 = m_joy1->read(); + u8 joy1 = m_joy[0]->read(); m_via_joy1 = joy1 | 0x80; for (int r = 0; r < 8; r++) { @@ -1863,22 +1867,22 @@ void f256_state::via1_system_porta_w(u8 data) } } } - m_via6522_1->write_pa(m_via_keyboard_port_a); - m_via6522_0->write_pb(m_via_joy1); + m_via6522[1]->write_pa(m_via_keyboard_port_a); + m_via6522[0]->write_pb(m_via_joy1); } // Read keyboard as columns void f256_state::via1_system_portb_w(u8 data) { m_via_keyboard_port_b = data; - m_via6522_1->write_pb(data); + m_via6522[1]->write_pb(data); } void f256_state::via1_ca2_write(u8 value) { - m_via6522_1->write_ca2(value); + m_via6522[1]->write_ca2(value); } void f256_state::via1_cb2_write(u8 value) { - m_via6522_1->write_cb2(value); + m_via6522[1]->write_cb2(value); } static INPUT_PORTS_START(f256k) diff --git a/src/mame/f256/f256.h b/src/mame/f256/f256.h index 1b27a2fa9a72d..15e5921aa1400 100644 --- a/src/mame/f256/f256.h +++ b/src/mame/f256/f256.h @@ -35,6 +35,7 @@ #define FLASH_TAG "flash" #define VICKY_VIDEO_TAG "vicky" #define SCREEN_TAG "screen" +#define VIA_TAG "via6522" class f256_state : public driver_device { @@ -57,11 +58,11 @@ class f256_state : public driver_device required_device m_screen; required_device m_rtc; required_ioport_array<8> m_keyboard; // the number 8 will require 8 COL - required_device m_via6522_0, m_via6522_1; - required_device m_sn0, m_sn1; + required_device_array m_via6522; + required_device_array m_sn; required_device m_opl3; - required_device m_sid0, m_sid1; - required_ioport m_joy1, m_joy2; + required_device_array m_sid; + required_ioport_array<2> m_joy; required_device m_video; //required_device m_iec; From 39ae79cd17e98f6d2fed9f2c1a7b9f09d27b0d33 Mon Sep 17 00:00:00 2001 From: Daniel Tremblay Date: Tue, 19 Aug 2025 22:14:35 +0200 Subject: [PATCH 10/11] Addressing comments from reviewers. --- src/devices/machine/bq4847.cpp | 16 ++-- src/devices/machine/bq4847.h | 8 +- src/mame/f256/f256.cpp | 24 ++--- src/mame/f256/f256.h | 4 +- src/mame/f256/tiny_vicky.cpp | 158 ++++++++++++++++----------------- src/mame/f256/tiny_vicky.h | 56 ++++++------ 6 files changed, 135 insertions(+), 131 deletions(-) diff --git a/src/devices/machine/bq4847.cpp b/src/devices/machine/bq4847.cpp index 0ea77c57ab9d4..740ffbf181d52 100644 --- a/src/devices/machine/bq4847.cpp +++ b/src/devices/machine/bq4847.cpp @@ -52,7 +52,7 @@ enum reg_interrupts, // 0 0 0 0 AIE PIE PWRIE ABE 0x00 on powerup reg_flags, // 0 0 0 0 AF PF PWRF BVF 0x00 after reading reg_control, // 0 0 0 0 UTI STOP* 24/12* DSE - reg_century // 0x00-0x99 + reg_century, // 0x00-0x99 }; enum @@ -89,7 +89,8 @@ bq4847_device::bq4847_device(const machine_config& mconfig, device_type type, co m_int_state(1), m_rst_state(1), m_wdi_state(-1), - m_writing(false) + m_writing(false), + m_century(false) { } @@ -102,10 +103,11 @@ bq4845_device::bq4845_device(const machine_config& mconfig, const char* tag, dev : bq4847_device(mconfig, BQ4845, tag, owner, clock) { } + bq4802_device::bq4802_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock) : bq4847_device(mconfig, BQ4802, tag, owner, clock) { - set_has_century(true); + set_century(true); } // device_rtc_interface @@ -121,7 +123,7 @@ void bq4847_device::rtc_clock_updated(int year, int month, int day, int day_of_w m_register[reg_month] = convert_to_bcd(month); m_register[reg_date] = convert_to_bcd(day); m_register[reg_days] = convert_to_bcd(day_of_week); - if (has_century) + if (m_century) { m_register[reg_century] = convert_to_bcd(year / 100); } @@ -193,7 +195,7 @@ TIMER_CALLBACK_MEMBER(bq4847_device::update_callback) if (carry) advance_days_bcd(); - if (!has_century) + if (!m_century) { LOGMASKED(LOG_CLOCK, "%s 20%02x-%02x-%02x %02x:%02x:%02x\n", dow[m_register[reg_days] - 1], m_register[reg_year], m_register[reg_month], m_register[reg_date], @@ -312,7 +314,7 @@ void bq4847_device::advance_days_bcd() carry = increment_bcd(m_register[reg_year], 0xff, 0); } } - if (has_century && carry) + if (m_century && carry) { increment_bcd(m_register[reg_century], 0xff, 1); } @@ -338,7 +340,7 @@ uint8_t bq4847_device::read(offs_t address) else if (regnum >= reg_interrupts && regnum <= reg_control) value &= 0xf; else if (regnum == reg_century) - value = has_century? m_register[reg_century]: 0; // Reg 15 is locked to 0 in BQ4847 + value = m_century? m_register[reg_century]: 0; // Reg 15 is locked to 0 in BQ4847 LOGMASKED(LOG_REG, "Reg %d -> %02x\n", regnum, value); diff --git a/src/devices/machine/bq4847.h b/src/devices/machine/bq4847.h index 5b2fbef7efbc8..f23e1bb549ac4 100644 --- a/src/devices/machine/bq4847.h +++ b/src/devices/machine/bq4847.h @@ -31,9 +31,9 @@ class bq4847_device : public device_t, void write_wdi(int state); // watchdog disabled if wdi pin is left floating - void set_has_century(bool value) + void set_century(bool value) { - has_century = value; + m_century = value; } protected: @@ -50,7 +50,7 @@ class bq4847_device : public device_t, virtual bool nvram_write(util::write_stream& file) override; // device_rtc_interface - virtual bool rtc_feature_y2k() const override { return has_century; } + virtual bool rtc_feature_y2k() const override { return m_century; } virtual bool rtc_feature_leap_year() const override { return true; } virtual bool rtc_battery_backed() const override { return true; } virtual void rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second) override; @@ -89,7 +89,7 @@ class bq4847_device : public device_t, int m_rst_state; int m_wdi_state; bool m_writing; - bool has_century = false; + bool m_century; }; class bq4845_device : public bq4847_device diff --git a/src/mame/f256/f256.cpp b/src/mame/f256/f256.cpp index bac70f7be0e39..7e578dd7c545f 100644 --- a/src/mame/f256/f256.cpp +++ b/src/mame/f256/f256.cpp @@ -74,8 +74,8 @@ void f256_state::f256k(machine_config &config) m_rtc->int_handler().set(FUNC(f256_state::rtc_interrupt_handler)); TINY_VICKY(config, m_video, MASTER_CLOCK); - m_video->sof_irq_handler().set(FUNC(f256_state::sof_interrtupt)); - m_video->sol_irq_handler().set(FUNC(f256_state::sol_interrtupt)); + m_video->sof_irq_handler().set(FUNC(f256_state::sof_interrupt)); + m_video->sol_irq_handler().set(FUNC(f256_state::sol_interrupt)); // VIA are used to implement the keyboard and Atari-style joysticks polling for (auto &via655: m_via6522) @@ -125,8 +125,8 @@ void f256_state::f256k(machine_config &config) for (auto &sid: m_sid) { MOS6581(config, sid, MUSIC_CLOCK/14); - sid->add_route(ALL_OUTPUTS, "lspeaker", 0.25); - sid->add_route(ALL_OUTPUTS, "rspeaker", 0.25); + sid->add_route(ALL_OUTPUTS, "lspeaker", 0.25, 0); + sid->add_route(ALL_OUTPUTS, "rspeaker", 0.25, 0); } // Mix all sound chips @@ -1003,17 +1003,17 @@ void f256_state::mem_w(offs_t offset, u8 data) // SID mix - m_sid[0]->reset_routes(); m_sid[1]->reset_routes(); - m_sid[0]->add_route(ALL_OUTPUTS, "lspeaker", 0.5); - m_sid[0]->add_route(ALL_OUTPUTS, "rspeaker", 0.5); - m_sid[1]->add_route(ALL_OUTPUTS, "lspeaker", 0.5); - m_sid[1]->add_route(ALL_OUTPUTS, "rspeaker", 0.5); + m_sid[0]->add_route(ALL_OUTPUTS, "lspeaker", 0.25, 0); + m_sid[0]->add_route(ALL_OUTPUTS, "rspeaker", 0.25, 0); + m_sid[1]->add_route(ALL_OUTPUTS, "lspeaker", 0.25, 0); + m_sid[1]->add_route(ALL_OUTPUTS, "rspeaker", 0.25, 0); } else { m_sid[0]->reset_routes(); m_sid[1]->reset_routes(); - m_sid[0]->add_route(ALL_OUTPUTS, "lspeaker", 1.0); - m_sid[1]->add_route(ALL_OUTPUTS, "rspeaker", 1.0); + m_sid[0]->add_route(ALL_OUTPUTS, "lspeaker", 0.5, 0); + m_sid[1]->add_route(ALL_OUTPUTS, "rspeaker", 0.5, 0); } break; case 0xD6A4: @@ -1515,7 +1515,7 @@ void f256_state::device_reset() //------------------------------------------------- // Interrupts //------------------------------------------------- -void f256_state::sof_interrtupt(int state) +void f256_state::sof_interrupt(int state) { if (state) // && ((m_interrupt_masks[1] & 0x01) == 0)) { @@ -1524,7 +1524,7 @@ void f256_state::sof_interrtupt(int state) m_maincpu->set_input_line(M6502_IRQ_LINE, state); } } -void f256_state::sol_interrtupt(int state) +void f256_state::sol_interrupt(int state) { if (state && ((m_interrupt_masks[1] & 0x02) == 0)) { diff --git a/src/mame/f256/f256.h b/src/mame/f256/f256.h index 15e5921aa1400..4a9a53ff7d5e5 100644 --- a/src/mame/f256/f256.h +++ b/src/mame/f256/f256.h @@ -95,8 +95,8 @@ class f256_state : public driver_device void mem_w(offs_t offset, u8 data); // screen update - void sof_interrtupt(int state); - void sol_interrtupt(int state); + void sof_interrupt(int state); + void sol_interrupt(int state); void rtc_interrupt_handler(int state); void via0_interrupt(int state); void via1_interrupt(int state); diff --git a/src/mame/f256/tiny_vicky.cpp b/src/mame/f256/tiny_vicky.cpp index 1fb2e89080eaf..de2590fb994b0 100644 --- a/src/mame/f256/tiny_vicky.cpp +++ b/src/mame/f256/tiny_vicky.cpp @@ -22,14 +22,14 @@ tiny_vicky_video_device::tiny_vicky_video_device(const machine_config &mconfig, rgb_t tiny_vicky_video_device::get_text_lut(uint8_t color_index, bool fg, bool gamma) { - uint8_t red = iopage0_ptr[(fg ? 0x1800 : 0x1840) + color_index * 4 + 2]; - uint8_t green = iopage0_ptr[(fg ? 0x1800 : 0x1840) + color_index * 4 + 1]; - uint8_t blue = iopage0_ptr[(fg ? 0x1800 : 0x1840) + color_index * 4 ]; + uint8_t red = m_iopage0_ptr[(fg ? 0x1800 : 0x1840) + color_index * 4 + 2]; + uint8_t green = m_iopage0_ptr[(fg ? 0x1800 : 0x1840) + color_index * 4 + 1]; + uint8_t blue = m_iopage0_ptr[(fg ? 0x1800 : 0x1840) + color_index * 4 ]; if (gamma) { - blue = iopage0_ptr[blue]; - green = iopage0_ptr[0x400 + green]; - red = iopage0_ptr[0x800 + red]; + blue = m_iopage0_ptr[blue]; + green = m_iopage0_ptr[0x400 + green]; + red = m_iopage0_ptr[0x800 + red]; } return rgb_t(red, green, blue); } @@ -39,33 +39,33 @@ rgb_t tiny_vicky_video_device::get_lut_value(uint8_t lut_index, uint8_t pix_val, int lutAddress = 0xD000 - 0xC000 + (lut_index * 256 + pix_val) * 4; if (!gamma) { - return rgb_t(iopage1_ptr[lutAddress + 2],iopage1_ptr[lutAddress + 1],iopage1_ptr[lutAddress]); + return rgb_t(m_iopage1_ptr[lutAddress + 2], m_iopage1_ptr[lutAddress + 1], m_iopage1_ptr[lutAddress]); } else { - return rgb_t(iopage0_ptr[0x800 + iopage1_ptr[lutAddress + 2]], - iopage0_ptr[0x400 + iopage1_ptr[lutAddress + 1]], - iopage0_ptr[iopage1_ptr[lutAddress]]); + return rgb_t(m_iopage0_ptr[0x800 + m_iopage1_ptr[lutAddress + 2]], + m_iopage0_ptr[0x400 + m_iopage1_ptr[lutAddress + 1]], + m_iopage0_ptr[m_iopage1_ptr[lutAddress]]); } } uint32_t tiny_vicky_video_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - if (running && iopage0_ptr) + if (m_running && m_iopage0_ptr) { - uint8_t mcr = iopage0_ptr[0x1000]; - uint8_t mcr_h = iopage0_ptr[0x1001]; - cursor_counter++; - if (cursor_counter > cursor_flash_rate *2) + uint8_t mcr = m_iopage0_ptr[0x1000]; + uint8_t mcr_h = m_iopage0_ptr[0x1001]; + m_cursor_counter++; + if (m_cursor_counter > m_cursor_flash_rate *2) { - cursor_counter = 0; + m_cursor_counter = 0; } // if MCR=0 or MCR bit 7 is set, then video is disabled if (mcr != 0 && (mcr != 0x80)) { // TODO: generate start of frame (SOF) interrupt m_sof_irq_handler(1); - uint8_t border_reg = iopage0_ptr[0x1004]; + uint8_t border_reg = m_iopage0_ptr[0x1004]; bool display_border = (border_reg & 0x1) > 0; bool enable_gamma = (mcr & 0x40) > 0; bool enable_graphics = (mcr & 0x4) > 0; @@ -75,16 +75,16 @@ uint32_t tiny_vicky_video_device::screen_update(screen_device &screen, bitmap_rg uint8_t border_y = 0; rgb_t border_color = rgb_t(); if (display_border) { - border_x = iopage0_ptr[0x1008]; - border_y = iopage0_ptr[0x1009]; + border_x = m_iopage0_ptr[0x1008]; + border_y = m_iopage0_ptr[0x1009]; } uint32_t *topleft = (uint32_t *)bitmap.raw_pixptr(0); for (int y = 0; y < lines; y++) { // Check the Sart of Line registers - uint8_t sol_reg = iopage0_ptr[0x1018]; + uint8_t sol_reg = m_iopage0_ptr[0x1018]; // 12-bit line - uint16_t sol_line = iopage0_ptr[0x1018] + ((iopage0_ptr[0x101A] & 0xF) << 8); + uint16_t sol_line = m_iopage0_ptr[0x1018] + ((m_iopage0_ptr[0x101A] & 0xF) << 8); uint32_t *row = topleft + y * 800; if ((sol_reg & 1) != 0 && y == sol_line) { @@ -96,13 +96,13 @@ uint32_t tiny_vicky_video_device::screen_update(screen_device &screen, bitmap_rg { if (!enable_gamma) { - border_color = rgb_t(iopage0_ptr[0x1007], iopage0_ptr[0x1006], iopage0_ptr[0x1005]); + border_color = rgb_t(m_iopage0_ptr[0x1007], m_iopage0_ptr[0x1006], m_iopage0_ptr[0x1005]); } else { - border_color = rgb_t(iopage0_ptr[0x800 + iopage0_ptr[0x1007]], - iopage0_ptr[0x400 + iopage0_ptr[0x1006]], - iopage0_ptr[iopage0_ptr[0x1005]]); + border_color = rgb_t(m_iopage0_ptr[0x800 + m_iopage0_ptr[0x1007]], + m_iopage0_ptr[0x400 + m_iopage0_ptr[0x1006]], + m_iopage0_ptr[m_iopage0_ptr[0x1005]]); } } @@ -121,13 +121,13 @@ uint32_t tiny_vicky_video_device::screen_update(screen_device &screen, bitmap_rg { if (!enable_gamma) { - background_color = rgb_t(iopage0_ptr[0x100F], iopage0_ptr[0x100E], iopage0_ptr[0x100D]); + background_color = rgb_t(m_iopage0_ptr[0x100F], m_iopage0_ptr[0x100E], m_iopage0_ptr[0x100D]); } else { - background_color = rgb_t(iopage0_ptr[0x800 + iopage0_ptr[0x100F]], - iopage0_ptr[0x400 + iopage0_ptr[0x100E]], - iopage0_ptr[iopage0_ptr[0x100D]]); + background_color = rgb_t(m_iopage0_ptr[0x800 + m_iopage0_ptr[0x100F]], + m_iopage0_ptr[0x400 + m_iopage0_ptr[0x100E]], + m_iopage0_ptr[m_iopage0_ptr[0x100D]]); } } // draw the border or background @@ -145,9 +145,9 @@ uint32_t tiny_vicky_video_device::screen_update(screen_device &screen, bitmap_rg if (y % 2 == 0) { // Tiny Vicky Layers for Bitmaps, Tilemaps and sprites - uint8_t LayerMgr0 = iopage0_ptr[0xD002 - 0xC000] & 0x7; - uint8_t LayerMgr1 = iopage0_ptr[0xD002 - 0xC000] >> 4; - uint8_t LayerMgr2 = iopage0_ptr[0xD003 - 0xC000] & 0x7; + uint8_t LayerMgr0 = m_iopage0_ptr[0xD002 - 0xC000] & 0x7; + uint8_t LayerMgr1 = m_iopage0_ptr[0xD002 - 0xC000] >> 4; + uint8_t LayerMgr2 = m_iopage0_ptr[0xD003 - 0xC000] & 0x7; // draw layers starting from the back if ((mcr & 0x20) != 0) @@ -213,7 +213,7 @@ uint32_t tiny_vicky_video_device::screen_update(screen_device &screen, bitmap_rg void tiny_vicky_video_device::draw_text(uint32_t *row, uint8_t mcr, bool enable_gamma, uint8_t brd_x, uint8_t brd_y, uint16_t line, uint16_t x_res, uint16_t y_res) { bool overlay = (mcr & 0x2) != 0; - uint8_t mcrh = iopage0_ptr[0x1001] & 0x3F; + uint8_t mcrh = m_iopage0_ptr[0x1001] & 0x3F; bool double_x = (mcrh & 0x2) != 0; bool double_y = (mcrh & 0x4) != 0; bool use_font1 = (mcrh & 0x20) != 0; @@ -224,33 +224,33 @@ void tiny_vicky_video_device::draw_text(uint32_t *row, uint8_t mcr, bool enable_ int txt_cols = double_x ? 40 : 80; // do cursor stuff - int cursor_x = iopage0_ptr[0x1014] + (iopage0_ptr[0x1015] << 8); - int cursor_y = iopage0_ptr[0x1016] + (iopage0_ptr[0x1017] << 8); + int cursor_x = m_iopage0_ptr[0x1014] + (m_iopage0_ptr[0x1015] << 8); + int cursor_y = m_iopage0_ptr[0x1016] + (m_iopage0_ptr[0x1017] << 8); // TODO: enabling/disabling cursor and flashing should be handled somewhere else... maybe in the top screen_update function. - bool enable_cursor = (iopage0_ptr[0x1010] & 0x1) > 0; - enable_cursor_flash = (iopage0_ptr[0x1010] & 0x8) == 0; + bool enable_cursor = (m_iopage0_ptr[0x1010] & 0x1) > 0; + m_enable_cursor_flash = (m_iopage0_ptr[0x1010] & 0x8) == 0; // flash rate is the count of screen updates // 1s = 60 ==> 00 // 0.5s = 30 ==> 01 // 0.25s= 15 ==> 10 // 0.20s= 12 ==> 11 - cursor_flash_rate = 60; - switch ((iopage0_ptr[0x1010] & 6) >> 1) + m_cursor_flash_rate = 60; + switch ((m_iopage0_ptr[0x1010] & 6) >> 1) { case 1: - cursor_flash_rate = 30; + m_cursor_flash_rate = 30; break; case 2: - cursor_flash_rate = 15; + m_cursor_flash_rate = 15; break; case 3: - cursor_flash_rate = 12; + m_cursor_flash_rate = 12; break; } int screen_x = brd_x; - // I'm assuming that if enable_cursor_flash is 0, then the cursor is always visible - cursor_visible = enable_cursor && (enable_cursor_flash && (cursor_counter < cursor_flash_rate)); + // I'm assuming that if m_enable_cursor_flash is 0, then the cursor is always visible + m_cursor_visible = enable_cursor && (m_enable_cursor_flash && (m_cursor_counter < m_cursor_flash_rate)); // the loop should go to txt_cols - going to 80 causes a weird alias, but the machine works this way... so. for (int col = 0; col < 80; col++) { @@ -267,13 +267,13 @@ void tiny_vicky_video_device::draw_text(uint32_t *row, uint8_t mcr, bool enable_ // } int offset = txt_cols * txt_line + col; // Each character will have foreground and background colors - uint8_t character = iopage2_ptr[offset]; - uint8_t color = iopage3_ptr[offset]; + uint8_t character = m_iopage2_ptr[offset]; + uint8_t color = m_iopage3_ptr[offset]; // Display the cursor - this replaces the text character - if (cursor_x == col && cursor_y == txt_line && cursor_visible) + if (cursor_x == col && cursor_y == txt_line && m_cursor_visible) { - character = iopage0_ptr[0x1012]; + character = m_iopage0_ptr[0x1012]; } uint8_t fg_color_index = (color & 0xF0) >> 4; @@ -282,7 +282,7 @@ void tiny_vicky_video_device::draw_text(uint32_t *row, uint8_t mcr, bool enable_ rgb_t fg_color = get_text_lut(fg_color_index, true, enable_gamma); rgb_t bg_color = get_text_lut(bg_color_index, false, enable_gamma); - uint8_t value = iopage1_ptr[(use_font1 ? 0x800 : 0) + character * 8 + font_line]; + uint8_t value = m_iopage1_ptr[(use_font1 ? 0x800 : 0) + character * 8 + font_line]; // For each bit in the font, set the foreground color - if the bit is 0 and overlay is set, skip it (keep the background) for (int b = 0x80; b > 0; b >>= 1) @@ -325,7 +325,7 @@ void tiny_vicky_video_device::device_reset() } void tiny_vicky_video_device::draw_bitmap(uint32_t *row, bool enable_gamma, uint8_t layer, bool bkgrnd, rgb_t bgndColor, uint8_t borderXSize, uint8_t borderYSize, uint16_t line, uint16_t width) { - uint8_t reg = iopage0_ptr[(0xD100 - 0xC000) + layer * 8]; + uint8_t reg = m_iopage0_ptr[(0xD100 - 0xC000) + layer * 8]; // check if the bitmap is enabled if ((reg & 0x01) == 0) { @@ -333,9 +333,9 @@ void tiny_vicky_video_device::draw_bitmap(uint32_t *row, bool enable_gamma, uint } uint8_t lut_index = (reg >> 1) & 7; // 8 possible LUTs constexpr int base_offset = 0xD101 - 0xC000; - int bitmapAddress = (iopage0_ptr[base_offset + layer * 8] + - (iopage0_ptr[base_offset + 1 + layer * 8] << 8) + - (iopage0_ptr[base_offset + 2 + layer * 8] << 16) + int bitmapAddress = (m_iopage0_ptr[base_offset + layer * 8] + + (m_iopage0_ptr[base_offset + 1 + layer * 8] << 8) + + (m_iopage0_ptr[base_offset + 2 + layer * 8] << 16) ) & 0x3F'FFFF; rgb_t color_val = 0; @@ -344,7 +344,7 @@ void tiny_vicky_video_device::draw_bitmap(uint32_t *row, bool enable_gamma, uint for (int col = borderXSize; col < width - borderXSize; col += 2) { - pix_val = videoram_ptr[offsetAddress + col/2 + 1]; + pix_val = m_videoram_ptr[offsetAddress + col/2 + 1]; if (pix_val != 0) { color_val = get_lut_value(lut_index, pix_val, enable_gamma); @@ -361,7 +361,7 @@ void tiny_vicky_video_device::draw_sprites(uint32_t *row, bool enable_gamma, uin for (int s = 63; s > -1; s--) { int addr_sprite = 0xD900 - 0xC000 + s * 8; - uint8_t reg = iopage0_ptr[addr_sprite]; + uint8_t reg = m_iopage0_ptr[addr_sprite]; // if the set is not enabled, we're done. uint8_t sprite_layer = (reg & 0x18) >> 3; // if the sprite is enabled and the layer matches, then check the line @@ -380,7 +380,7 @@ void tiny_vicky_video_device::draw_sprites(uint32_t *row, bool enable_gamma, uin sprite_size = 8; break; } - int posY = iopage0_ptr[addr_sprite + 6] + (iopage0_ptr[addr_sprite + 7] << 8) - 32; + int posY = m_iopage0_ptr[addr_sprite + 6] + (m_iopage0_ptr[addr_sprite + 7] << 8) - 32; int actualLine = line / 2; if ((actualLine >= posY && actualLine < posY + sprite_size)) { @@ -390,10 +390,10 @@ void tiny_vicky_video_device::draw_sprites(uint32_t *row, bool enable_gamma, uin //int lut_address = 0xD000 - 0xC000 + lut_index * 0x400; //bool striding = (reg & 0x80) == 0x80; - int sprite_address = (iopage0_ptr[addr_sprite + 1] + - (iopage0_ptr[addr_sprite + 2] << 8) + - (iopage0_ptr[addr_sprite + 3] << 16)) & 0x3F'FFFF; - int posX = iopage0_ptr[addr_sprite + 4] + (iopage0_ptr[addr_sprite + 5] << 8) - 32; + int sprite_address = (m_iopage0_ptr[addr_sprite + 1] + + (m_iopage0_ptr[addr_sprite + 2] << 8) + + (m_iopage0_ptr[addr_sprite + 3] << 16)) & 0x3F'FFFF; + int posX = m_iopage0_ptr[addr_sprite + 4] + (m_iopage0_ptr[addr_sprite + 5] << 8) - 32; posX *= 2; if (posX >= width || posY >= height || (posX + sprite_size) < 0 || (posY + sprite_size) < 0) @@ -436,7 +436,7 @@ void tiny_vicky_video_device::draw_sprites(uint32_t *row, bool enable_gamma, uin for (int col = xOffset; col < xOffset + cols; col++) { // Lookup the pixel in the tileset - if the value is 0, it's transparent - pixVal = videoram_ptr[sprite_address + col + sline * sprite_size]; + pixVal = m_videoram_ptr[sprite_address + col + sline * sprite_size]; if (pixVal != 0) { clrVal = get_lut_value(lut_index, pixVal, enable_gamma); @@ -453,7 +453,7 @@ void tiny_vicky_video_device::draw_tiles(uint32_t *row, bool enable_gamma, uint8 { // There are four possible tilemaps to choose from int addr_tile_addr = 0xD200 - 0xC000 + layer * 12; - int reg = iopage0_ptr[addr_tile_addr]; + int reg = m_iopage0_ptr[addr_tile_addr]; // if the set is not enabled, we're done. if ((reg & 0x01) == 00) { @@ -465,15 +465,15 @@ void tiny_vicky_video_device::draw_tiles(uint32_t *row, bool enable_gamma, uint8 int strideLine = tileSize * 16; uint8_t scrollMask = smallTiles ? 0xF : 0xF; // Tiny Vicky bug: this should be 0xE - int tilemapWidth = (iopage0_ptr[addr_tile_addr + 4] + (iopage0_ptr[addr_tile_addr + 5] << 8)) & 0x3FF; // 10 bits + int tilemapWidth = (m_iopage0_ptr[addr_tile_addr + 4] + (m_iopage0_ptr[addr_tile_addr + 5] << 8)) & 0x3FF; // 10 bits //int tilemapHeight = VICKY.ReadWord(addrTileCtrlReg + 6) & 0x3FF; // 10 bits - int tilemapAddress = (iopage0_ptr[addr_tile_addr + 1] + (iopage0_ptr[addr_tile_addr + 2] << 8) + (iopage0_ptr[addr_tile_addr + 3] << 16)) & 0x3F'FFFF; + int tilemapAddress = (m_iopage0_ptr[addr_tile_addr + 1] + (m_iopage0_ptr[addr_tile_addr + 2] << 8) + (m_iopage0_ptr[addr_tile_addr + 3] << 16)) & 0x3F'FFFF; // the tilemapWindowX is 10 bits and the scrollX is the lower 4 bits. The IDE combines them. - int tilemapWindowX = iopage0_ptr[addr_tile_addr + 8] + (iopage0_ptr[addr_tile_addr + 9] << 8); + int tilemapWindowX = m_iopage0_ptr[addr_tile_addr + 8] + (m_iopage0_ptr[addr_tile_addr + 9] << 8); uint8_t scrollX = (tilemapWindowX & scrollMask) & scrollMask; // the tilemapWindowY is 10 bits and the scrollY is the lower 4 bits. The IDE combines them. - int tilemapWindowY = iopage0_ptr[addr_tile_addr + 10] + (iopage0_ptr[addr_tile_addr + 11] << 8); + int tilemapWindowY = m_iopage0_ptr[addr_tile_addr + 10] + (m_iopage0_ptr[addr_tile_addr + 11] << 8); uint8_t scrollY = (tilemapWindowY & scrollMask) & scrollMask; if (smallTiles) { @@ -501,16 +501,16 @@ void tiny_vicky_video_device::draw_tiles(uint32_t *row, bool enable_gamma, uint8 int tilesetOffsets[tilemapItemCount]; // The + 2 below is to take an FPGA bug in the F256Jr into account - memcpy(tiles, videoram_ptr + tilemapAddress + (tilemapWindowX / tileSize) * 2 + (tileRow + 0) * tilemapWidth * 2, tlmSize); + memcpy(tiles, m_videoram_ptr + tilemapAddress + (tilemapWindowX / tileSize) * 2 + (tileRow + 0) * tilemapWidth * 2, tlmSize); // cache of tilesetPointers int tilesetPointers[8]; int strides[8]; for (int i = 0; i < 8; i++) { - tilesetPointers[i] = (iopage0_ptr[0xD280 - 0xC000 + i * 4] + (iopage0_ptr[0xD280 - 0xC000 + i * 4 + 1] << 8) + - (iopage0_ptr[0xD280 - 0xC000 + i * 4 + 2] << 16)) & 0x3F'FFFF; - uint8_t tilesetConfig = iopage0_ptr[0xD280 - 0xC000 + i * 4 + 3]; + tilesetPointers[i] = (m_iopage0_ptr[0xD280 - 0xC000 + i * 4] + (m_iopage0_ptr[0xD280 - 0xC000 + i * 4 + 1] << 8) + + (m_iopage0_ptr[0xD280 - 0xC000 + i * 4 + 2] << 16)) & 0x3F'FFFF; + uint8_t tilesetConfig = m_iopage0_ptr[0xD280 - 0xC000 + i * 4 + 3]; strides[i] = (tilesetConfig & 8) != 0 ? strideLine : tileSize; } for (int i = 0; i < tilemapItemCount; i++) @@ -546,10 +546,10 @@ void tiny_vicky_video_device::draw_tiles(uint32_t *row, bool enable_gamma, uint8 uint8_t lut_index = (tilesetReg & 0x38) >> 3; //int lutAddress = MemoryMap.GRP_LUT_BASE_ADDR - VICKY.StartAddress + lutIndex * 1024; //int tilesetOffsetAddress = tilesetOffsets[t]; // + startOffset - //memcpy(tilepix, videoram_ptr + tilesetOffsets[t], tileSize); + //memcpy(tilepix, m_videoram_ptr + tilesetOffsets[t], tileSize); do { - uint8_t pixVal = videoram_ptr[tilesetOffsets[t] + startOffset]; // tilepix[startOffset]; + uint8_t pixVal = m_videoram_ptr[tilesetOffsets[t] + startOffset]; // tilepix[startOffset]; if (pixVal > 0) { clr_val = get_lut_value(lut_index, pixVal, enable_gamma); @@ -570,14 +570,14 @@ void tiny_vicky_video_device::draw_tiles(uint32_t *row, bool enable_gamma, uint8 void tiny_vicky_video_device::draw_mouse(uint32_t *row, bool enable_gamma, uint16_t line, uint16_t width, uint16_t height) { - uint8_t mouse_reg = iopage0_ptr[0xD6E0 - 0xC000]; + uint8_t mouse_reg = m_iopage0_ptr[0xD6E0 - 0xC000]; bool MousePointerEnabled = (mouse_reg & 3) != 0; if (MousePointerEnabled) { - int PosX = iopage0_ptr[0xD6E0 - 0xC000 + 2] + (iopage0_ptr[0xD6E0 - 0xC000 + 3] << 8); - int PosY = iopage0_ptr[0xD6E0 - 0xC000 + 4] + (iopage0_ptr[0xD6E0 - 0xC000 + 5] << 8); + int PosX = m_iopage0_ptr[0xD6E0 - 0xC000 + 2] + (m_iopage0_ptr[0xD6E0 - 0xC000 + 3] << 8); + int PosY = m_iopage0_ptr[0xD6E0 - 0xC000 + 4] + (m_iopage0_ptr[0xD6E0 - 0xC000 + 5] << 8); if (line >= PosY && line < PosY + 16) { int ptr_addr = 0xCC00 - 0xC000; @@ -589,7 +589,7 @@ void tiny_vicky_video_device::draw_mouse(uint32_t *row, bool enable_gamma, uint1 for (int col = 0; col < colsToDraw; col++) { // Values are 0: transparent, 1:black, 255: white (gray scales) - uint8_t pixel_index = iopage0_ptr[ptr_addr + mouse_line * 16 + col]; + uint8_t pixel_index = m_iopage0_ptr[ptr_addr + mouse_line * 16 + col]; rgb_t value; if (pixel_index != 0) @@ -600,9 +600,9 @@ void tiny_vicky_video_device::draw_mouse(uint32_t *row, bool enable_gamma, uint1 } else { - value = rgb_t(iopage0_ptr[0x800 + pixel_index], - iopage0_ptr[0x400 + pixel_index], - iopage0_ptr[pixel_index]); + value = rgb_t(m_iopage0_ptr[0x800 + pixel_index], + m_iopage0_ptr[0x400 + pixel_index], + m_iopage0_ptr[pixel_index]); } row[col + PosX] = value; } diff --git a/src/mame/f256/tiny_vicky.h b/src/mame/f256/tiny_vicky.h index 8f1cbe6ae0491..bc21b82560cfc 100644 --- a/src/mame/f256/tiny_vicky.h +++ b/src/mame/f256/tiny_vicky.h @@ -19,24 +19,24 @@ class tiny_vicky_video_device : public device_t uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); void stop() { - running = false; - videoram_ptr = nullptr; - iopage0_ptr = nullptr; - iopage1_ptr = nullptr; - iopage2_ptr = nullptr; - iopage3_ptr = nullptr; + m_running = false; + m_videoram_ptr = nullptr; + m_iopage0_ptr = nullptr; + m_iopage1_ptr = nullptr; + m_iopage2_ptr = nullptr; + m_iopage3_ptr = nullptr; } void set_videoram(uint8_t *videoram, uint8_t *iopage0, uint8_t *iopage1, uint8_t *iopage2, uint8_t *iopage3) { - videoram_ptr = videoram; - iopage0_ptr = iopage0; - iopage1_ptr = iopage1; - iopage2_ptr = iopage2; - iopage3_ptr = iopage3; + m_videoram_ptr = videoram; + m_iopage0_ptr = iopage0; + m_iopage1_ptr = iopage1; + m_iopage2_ptr = iopage2; + m_iopage3_ptr = iopage3; } void start() { - running = true; + m_running = true; }; auto sof_irq_handler() { @@ -52,21 +52,6 @@ class tiny_vicky_video_device : public device_t virtual void device_reset() override ATTR_COLD; // virtual void device_add_mconfig(machine_config &config) override; private: - bool running = false; - devcb_write_line m_sof_irq_handler; - devcb_write_line m_sol_irq_handler; - uint8_t *videoram_ptr = nullptr; // Pointer to video RAM - uint8_t *iopage0_ptr = nullptr; // Pointer to IO Page 0 - uint8_t *iopage1_ptr = nullptr; // Pointer to IO Page 1 - uint8_t *iopage2_ptr = nullptr; // Pointer to IO Page 2 - uint8_t *iopage3_ptr = nullptr; // Pointer to IO Page 3 - - // cursor handling routines - bool cursor_visible = false; - bool enable_cursor_flash = true; - uint8_t cursor_counter = 0; - uint8_t cursor_flash_rate = 60; - // raster rgb_t get_text_lut(uint8_t color_index, bool fg, bool gamma); rgb_t get_lut_value(uint8_t lut_index, uint8_t pix_val, bool gamma); @@ -75,6 +60,23 @@ class tiny_vicky_video_device : public device_t void draw_sprites(uint32_t *row, bool enable_gamma, uint8_t layer, bool bkgrnd, uint8_t borderXSize, uint8_t borderYSize, uint16_t line, uint16_t width, uint16_t height); void draw_tiles(uint32_t *row, bool enable_gamma, uint8_t layer, bool bkgrnd, uint8_t borderXSize, uint16_t line, uint16_t width); void draw_mouse(uint32_t *row, bool enable_gamma, uint16_t line, uint16_t width, uint16_t height); + + bool m_running = false; + devcb_write_line m_sof_irq_handler; + devcb_write_line m_sol_irq_handler; + uint8_t *m_videoram_ptr = nullptr; // Pointer to video RAM + uint8_t *m_iopage0_ptr = nullptr; // Pointer to IO Page 0 + uint8_t *m_iopage1_ptr = nullptr; // Pointer to IO Page 1 + uint8_t *m_iopage2_ptr = nullptr; // Pointer to IO Page 2 + uint8_t *m_iopage3_ptr = nullptr; // Pointer to IO Page 3 + + // cursor handling routines + bool m_cursor_visible = false; + bool m_enable_cursor_flash = true; + uint8_t m_cursor_counter = 0; + uint8_t m_cursor_flash_rate = 60; + + }; DECLARE_DEVICE_TYPE(TINY_VICKY, tiny_vicky_video_device) From cca1b72a8b3415a89dfe0f8ef9d4f7a6af041152 Mon Sep 17 00:00:00 2001 From: Daniel Tremblay Date: Sat, 23 Aug 2025 14:25:58 +0200 Subject: [PATCH 11/11] Updated code to address comments from reviewers. --- src/devices/machine/bq4847.cpp | 12 +- src/devices/machine/bq4847.h | 15 +- src/mame/f256/f256.cpp | 600 +++++++++++++++++---------------- src/mame/f256/f256.h | 10 +- src/mame/f256/tiny_vicky.cpp | 101 +++--- src/mame/f256/tiny_vicky.h | 7 +- 6 files changed, 374 insertions(+), 371 deletions(-) diff --git a/src/devices/machine/bq4847.cpp b/src/devices/machine/bq4847.cpp index 740ffbf181d52..9fc5ff8e42b3b 100644 --- a/src/devices/machine/bq4847.cpp +++ b/src/devices/machine/bq4847.cpp @@ -75,7 +75,7 @@ enum // Constructors for basetype //------------------------------------------------- -bq4847_device::bq4847_device(const machine_config& mconfig, device_type type, const char* tag, device_t* owner, uint32_t clock) +bq4847_device::bq4847_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, type, tag, owner, clock), device_nvram_interface(mconfig, *this), device_rtc_interface(mconfig, *this), @@ -94,17 +94,17 @@ bq4847_device::bq4847_device(const machine_config& mconfig, device_type type, co { } -bq4847_device::bq4847_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock) +bq4847_device::bq4847_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : bq4847_device(mconfig, BQ4847, tag, owner, clock) { } -bq4845_device::bq4845_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock) +bq4845_device::bq4845_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : bq4847_device(mconfig, BQ4845, tag, owner, clock) { } -bq4802_device::bq4802_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock) +bq4802_device::bq4802_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : bq4847_device(mconfig, BQ4802, tag, owner, clock) { set_century(true); @@ -119,7 +119,7 @@ void bq4847_device::rtc_clock_updated(int year, int month, int day, int day_of_w (((hour % 24) >= 12) ? 0x80 : 0x00) | convert_to_bcd((hour % 12) ? (hour % 12) : 12); m_register[reg_minutes] = convert_to_bcd(minute); m_register[reg_seconds] = convert_to_bcd(second); - m_register[reg_year] = convert_to_bcd(year%100); + m_register[reg_year] = convert_to_bcd(year % 100); m_register[reg_month] = convert_to_bcd(month); m_register[reg_date] = convert_to_bcd(day); m_register[reg_days] = convert_to_bcd(day_of_week); @@ -144,7 +144,7 @@ void bq4847_device::rtc_clock_updated(int year, int month, int day, int day_of_w // What about the DSE flag? } -bool bq4847_device::increment_bcd(uint8_t& bcdnumber, uint8_t limit, uint8_t min) +bool bq4847_device::increment_bcd(uint8_t &bcdnumber, uint8_t limit, uint8_t min) { if (bcdnumber >= limit) { diff --git a/src/devices/machine/bq4847.h b/src/devices/machine/bq4847.h index f23e1bb549ac4..e1f47a6cc4fd2 100644 --- a/src/devices/machine/bq4847.h +++ b/src/devices/machine/bq4847.h @@ -31,11 +31,6 @@ class bq4847_device : public device_t, void write_wdi(int state); // watchdog disabled if wdi pin is left floating - void set_century(bool value) - { - m_century = value; - } - protected: bq4847_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock = 32768); @@ -54,6 +49,10 @@ class bq4847_device : public device_t, virtual bool rtc_feature_leap_year() const override { return true; } virtual bool rtc_battery_backed() const override { return true; } virtual void rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second) override; + void set_century(bool value) + { + m_century = value; + } private: optional_memory_region m_region; @@ -95,14 +94,16 @@ class bq4847_device : public device_t, class bq4845_device : public bq4847_device { public: - bq4845_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock); + bq4845_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); }; + class bq4802_device : public bq4847_device { public: - bq4802_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock); + bq4802_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); private: }; + DECLARE_DEVICE_TYPE(BQ4802, bq4802_device) DECLARE_DEVICE_TYPE(BQ4845, bq4845_device) DECLARE_DEVICE_TYPE(BQ4847, bq4847_device) diff --git a/src/mame/f256/f256.cpp b/src/mame/f256/f256.cpp index 7e578dd7c545f..6a2a86231f39c 100644 --- a/src/mame/f256/f256.cpp +++ b/src/mame/f256/f256.cpp @@ -2,9 +2,10 @@ // copyright-holders:Daniel Tremblay #include "emu.h" #include "f256.h" - -#include "cpu/m6502/w65c02s.h" #include "tiny_vicky.h" +#include "cpu/m6502/w65c02s.h" + + /** * @@ -57,7 +58,7 @@ void f256_state::f256k(machine_config &config) m_maincpu->set_addrmap(AS_PROGRAM, &f256_state::program_map); RAM(config, m_ram).set_default_size("512k").set_default_value(0x0); - for (auto &iopage : m_iopage) + for (auto &iopage : m_iopage) { RAM(config, iopage).set_default_size("8k").set_default_value(0x0); } @@ -68,11 +69,11 @@ void f256_state::f256k(machine_config &config) //m_screen->set_visarea(160, 799, 45, 524); // this is how it should reall work, but the screen ends up offset m_screen->set_visarea(0, 639, 0, 479); m_screen->set_screen_update(m_video, FUNC(tiny_vicky_video_device::screen_update)); - + BQ4802(config, m_rtc, MASTER_CLOCK / 1000); // RTC clock in kHz //set interrupt handler for the RTC m_rtc->int_handler().set(FUNC(f256_state::rtc_interrupt_handler)); - + TINY_VICKY(config, m_video, MASTER_CLOCK); m_video->sof_irq_handler().set(FUNC(f256_state::sof_interrupt)); m_video->sol_irq_handler().set(FUNC(f256_state::sol_interrupt)); @@ -103,7 +104,7 @@ void f256_state::f256k(machine_config &config) PC_KBDC(config, m_ps2_keyboard, XTAL(32'768)); HLE_PS2_MOUSE(config, m_mouse, XTAL(32'768)); m_mouse->set_pc_kbdc(m_ps2_keyboard); - + // There are two PSG sound chips for (auto &sn: m_sn) @@ -128,7 +129,7 @@ void f256_state::f256k(machine_config &config) sid->add_route(ALL_OUTPUTS, "lspeaker", 0.25, 0); sid->add_route(ALL_OUTPUTS, "rspeaker", 0.25, 0); } - + // Mix all sound chips SPEAKER(config, "lspeaker").front_left(); SPEAKER(config, "rspeaker").front_right(); @@ -136,13 +137,14 @@ void f256_state::f256k(machine_config &config) // Add an SD card device SPI_SDCARD(config, m_sdcard, 0); m_sdcard->set_prefer_sdhc(); - m_sdcard->spi_miso_callback().set([this](int state) { + m_sdcard->spi_miso_callback().set([this](int state) + { //m_in_bit = state; m_in_latch <<= 1; m_in_latch |= state; }); - + NS16550(config, m_uart, MASTER_CLOCK); // The IEC interface is not yet implemented @@ -166,16 +168,16 @@ void f256_state::program_map(address_map &map) { // the address range 0:F // 0: LUT Edit $80 allows writing to 8 to F, LUT Select 0 to 3 - map(0x0000, 0x000F).rw(FUNC(f256_state::lut_r), FUNC(f256_state::lut_w)); - map(0x0010, 0xFFFF).rw(FUNC(f256_state::mem_r), FUNC(f256_state::mem_w)); + map(0x0000, 0x000f).rw(FUNC(f256_state::lut_r), FUNC(f256_state::lut_w)); + map(0x0010, 0xffff).rw(FUNC(f256_state::mem_r), FUNC(f256_state::mem_w)); }; void f256_state::data_map(address_map &map) { - map(0x0000, 0x1FFF).ram().share(IOPAGE_TAG "0"); - map(0x0000, 0x1FFF).ram().share(IOPAGE_TAG "1"); - map(0x0000, 0x1FFF).ram().share(IOPAGE_TAG "2"); - map(0x0000, 0x1FFF).ram().share(IOPAGE_TAG "3"); + map(0x0000, 0x1fff).ram().share(IOPAGE_TAG "0"); + map(0x0000, 0x1fff).ram().share(IOPAGE_TAG "1"); + map(0x0000, 0x1fff).ram().share(IOPAGE_TAG "2"); + map(0x0000, 0x1fff).ram().share(IOPAGE_TAG "3"); } u8 f256_state::lut_r(offs_t offset) @@ -245,7 +247,7 @@ u8 f256_state::mem_r(offs_t offset) uint8_t mmu = m_mmu_reg & 3; uint16_t adj_addr = offset + 0x10; uint8_t slot = adj_addr >> 13; - uint16_t low_addr = adj_addr & 0x1FFF; + uint16_t low_addr = adj_addr & 0x1fff; uint8_t bank = mmu_lut[mmu * 8 + slot]; // fslot < 0x40 is RAM, greater is FLASH/ROM @@ -258,62 +260,62 @@ u8 f256_state::mem_r(offs_t offset) { case 0: // here we have a number of devices to read - if (adj_addr >= 0xD018 && adj_addr < 0xD01C) + if (adj_addr >= 0xd018 && adj_addr < 0xd01c) { // return Vicky's scan line and colum uint16_t line = m_screen->hpos(); //uint16_t column = m_video->column(); logerror("Scanline Addr: %04X, Line: %04X\n", adj_addr, line); - switch (adj_addr - 0xD018) + switch (adj_addr - 0xd018) { case 0: - return 0; //column & 0xFF; + return 0; //column & 0xff; case 1: return 0; // (column >> 8); case 2: - return line & 0xFF; + return line & 0xff; case 3: return (line >> 8); } } - else if (adj_addr >= 0xD400 && adj_addr < 0xD580) + else if (adj_addr >= 0xd400 && adj_addr < 0xd580) { // SID return 0; } - else if (adj_addr >= 0xD580 && adj_addr < 0xD583) + else if (adj_addr >= 0xd580 && adj_addr < 0xd583) { // OPL3 return 0; } - else if (adj_addr >= 0xD600 && adj_addr < 0xD620) + else if (adj_addr >= 0xd600 && adj_addr < 0xd620) { // PSG - left channel D600, right channel D610 - both D608 return 0; } - else if (adj_addr >= 0xD620 && adj_addr < 0xD630) + else if (adj_addr >= 0xd620 && adj_addr < 0xd630) { // logerror("CODEC Read Addr: %04X\n", adj_addr); - uint16_t base = adj_addr - 0xD620; + uint16_t base = adj_addr - 0xd620; return m_codec[base]; } - else if (adj_addr >= 0xD630 && adj_addr < 0xD640) + else if (adj_addr >= 0xd630 && adj_addr < 0xd640) { // UART - uint8_t v_uart = m_uart->ins8250_r(adj_addr - 0xD630); + uint8_t v_uart = m_uart->ins8250_r(adj_addr - 0xd630); logerror("UART Read %X %02X\n", adj_addr, v_uart); return v_uart; } - else if (adj_addr >= 0xD640 && adj_addr < 0xD64F) + else if (adj_addr >= 0xd640 && adj_addr < 0xd64f) { // PS2 logerror("PS/2 Read %04X\n", adj_addr); - switch(adj_addr - 0xD640) + switch(adj_addr - 0xd640) { case 0: case 1: - return m_ps2[adj_addr - 0xD640]; + return m_ps2[adj_addr - 0xd640]; case 2: { // Read from the keyboard fifo @@ -352,78 +354,78 @@ u8 f256_state::mem_r(offs_t offset) return ((K_AK ? 0x80:0) + (M_AK ? 0x20 : 0) + (msQLen == 0 ? 2 : 0) + (kbQLen == 0? 1 : 0)); } - return m_ps2[adj_addr - 0xD640]; + return m_ps2[adj_addr - 0xd640]; } - else if (adj_addr >= 0xD650 && adj_addr < 0xD660) + else if (adj_addr >= 0xd650 && adj_addr < 0xd660) { // Timers switch (adj_addr) { - case 0xD650: + case 0xd650: return m_timer0_eq; - case 0xD651: - return m_timer0_val & 0xFF; - case 0xD652: - return (m_timer0_val >> 8) & 0xFF; - case 0xD653: - return (m_timer0_val >> 16) & 0xFF; - case 0xD658: + case 0xd651: + return m_timer0_val & 0xff; + case 0xd652: + return (m_timer0_val >> 8) & 0xff; + case 0xd653: + return (m_timer0_val >> 16) & 0xff; + case 0xd658: return m_timer1_eq; - case 0xD659: - return m_timer1_val & 0xFF; - case 0xD65A: - return (m_timer1_val >> 8) & 0xFF; - case 0xD65B: - return (m_timer1_val >> 16) & 0xFF; + case 0xd659: + return m_timer1_val & 0xff; + case 0xd65a: + return (m_timer1_val >> 8) & 0xff; + case 0xd65b: + return (m_timer1_val >> 16) & 0xff; } - return m_iopage[0]->read(adj_addr - 0xC000); + return m_iopage[0]->read(adj_addr - 0xc000); } - else if (adj_addr >= 0xD660 && adj_addr < 0xD670) + else if (adj_addr >= 0xd660 && adj_addr < 0xd670) { // Interrupt Registers logerror("Interrupt Registers Read: %04X\n", adj_addr); switch (adj_addr) { - case 0xD660: + case 0xd660: return m_interrupt_reg[0]; // int_pending_0 - case 0xD661: + case 0xd661: return m_interrupt_reg[1]; // int_pending_1 - case 0xD662: + case 0xd662: return m_interrupt_reg[2]; // int_pending_2 - case 0xD663: + case 0xd663: return 0; - case 0xD664: + case 0xd664: return m_interrupt_polarity[0]; // int_polarity_0 - case 0xD665: + case 0xd665: return m_interrupt_polarity[1]; // int_polarity_1 - case 0xD666: + case 0xd666: return m_interrupt_polarity[2]; // int_polarity_2 - case 0xD667: + case 0xd667: return 0; - case 0xD668: + case 0xd668: return m_interrupt_edge[0]; // int_edge_0 - case 0xD669: + case 0xd669: return m_interrupt_edge[1]; // int_edge_1 - case 0xD66A: + case 0xd66a: return m_interrupt_edge[2]; // int_edge_2 - case 0xD66B: + case 0xd66b: return 0; - case 0xD66C: + case 0xd66c: return m_interrupt_masks[0]; - case 0xD66D: + case 0xd66d: return m_interrupt_masks[1]; - case 0xD66E: + case 0xd66e: return m_interrupt_masks[2]; - case 0xD66F: + case 0xd66f: return 0; } } - else if (adj_addr >= 0xD680 && adj_addr < 0xD682) + else if (adj_addr >= 0xd680 && adj_addr < 0xd682) { //IEC - logerror("Reading from IEC Reg: %X", adj_addr - 0xD680); - switch (adj_addr - 0xD680) + logerror("Reading from IEC Reg: %X", adj_addr - 0xd680); + switch (adj_addr - 0xd680) { case 0: logerror(", data: %02X\n", m_iec_in); @@ -440,180 +442,180 @@ u8 f256_state::mem_r(offs_t offset) return m_iec_out; } } - else if (adj_addr >= 0xD690 && adj_addr < 0xD6A0) + else if (adj_addr >= 0xd690 && adj_addr < 0xd6a0) { // RTC logerror("RTC Read %04X\n", adj_addr); - return m_rtc->read(adj_addr - 0xDC90); + return m_rtc->read(adj_addr - 0xdc90); } - else if (adj_addr >= 0xD6A0 && adj_addr < 0xD6C0) + else if (adj_addr >= 0xd6a0 && adj_addr < 0xd6c0) { // System Control Registers // D6A0 - buzzer and LED controls - including RESET bit // D6A1 - sound mixer - // D6A2 - Set to 0xDE to enable software reset - // D6A3 - Set to 0xAD to enable software reset + // D6A2 - Set to 0xde to enable software reset + // D6A3 - Set to 0xad to enable software reset // D6A4 - D6A6 : Random Number generator // D6A7 - Macine ID - For the F256, the machine ID will be 0x02. For the F256k, the machine ID will be 0x12. logerror("System Register Read %04X\n", adj_addr); switch (adj_addr){ - case 0xD6A0: + case 0xd6a0: return m_sdcard->get_card_present() ? 0x10:0; - case 0xD6A1: - return m_iopage[0]->read(0xD6A1 - 0xC000); - case 0xD6A4: + case 0xd6a1: + return m_iopage[0]->read(0xd6a1 - 0xc000); + case 0xd6a4: if (m_rng_enabled) { - return get_random() & 0xFF; + return get_random() & 0xff; } else { - return m_seed & 0xFF; + return m_seed & 0xff; } - case 0xD6A5: + case 0xd6a5: if (m_rng_enabled) { - return get_random() & 0xFF; + return get_random() & 0xff; } else { - return (m_seed >> 8) & 0xFF; + return (m_seed >> 8) & 0xff; } - case 0xD6A6: + case 0xd6a6: return m_rng_enabled ? 0x80: 0; - case 0xD6A7: + case 0xd6a7: return 0x12; // F256K ID - case 0XD6A8: + case 0xd6a8: return 'A'; - case 0XD6A9: + case 0xd6a9: return '0'; - case 0XD6AA: + case 0xd6aa: return 1; - case 0XD6AB: + case 0xd6ab: return 1; - case 0XD6AC: + case 0xd6ac: return 0; - case 0XD6AD: + case 0xd6ad: return 0x14; - case 0XD6AE: + case 0xd6ae: return 0; - case 0XD6AF: + case 0xd6af: return 0; } } // mouse registers - // else if (adj_addr >= 0xD6E0 && adj_addr < 0xD6E9) + // else if (adj_addr >= 0xd6e0 && adj_addr < 0xd6e9) // { // switch (adj_addr) // { - // case 0xD6E0: + // case 0xd6e0: // return (m_mouse_mode << 1) + m_mouse_enabled ? 1 : 0; // break; - // case 0xD6E2: - // return m_mouse_x & 0xFF; - // case 0xD6E3: - // return (m_mouse_x >> 8) & 0xFF; - // case 0xD6E4: - // return m_mouse_y & 0xFF; - // case 0xD6E5: - // return (m_mouse_y >> 8) & 0xFF; + // case 0xd6e2: + // return m_mouse_x & 0xff; + // case 0xd6e3: + // return (m_mouse_x >> 8) & 0xff; + // case 0xd6e4: + // return m_mouse_y & 0xff; + // case 0xd6e5: + // return (m_mouse_y >> 8) & 0xff; // default: // break; // } // } - else if (adj_addr >= 0xD880 && adj_addr < 0xD8C0) + else if (adj_addr >= 0xd880 && adj_addr < 0xd8c0) { // NES - return 0xFF; + return 0xff; } - else if (adj_addr >= 0xDB00 && adj_addr < 0xDB10) + else if (adj_addr >= 0xdb00 && adj_addr < 0xdb10) { // VIA1 - Keyboard for F256K - return m_via6522[1]->read(adj_addr - 0xDB00); + return m_via6522[1]->read(adj_addr - 0xdB00); } - else if (adj_addr >= 0xDC00 && adj_addr < 0xDC10) + else if (adj_addr >= 0xdc00 && adj_addr < 0xdc10) { // VIA0 - Atari Joystick - return m_via6522[0]->read(adj_addr - 0xDC00); + return m_via6522[0]->read(adj_addr - 0xdc00); } - else if (adj_addr >= 0xDD00 && adj_addr < 0xDD20) + else if (adj_addr >= 0xdd00 && adj_addr < 0xdd20) { // SD Card - //m_sdcard->(adj_addr - 0xDD00); + //m_sdcard->(adj_addr - 0xdd00); // logerror("Reading SD Card: %04X\n", adj_addr); switch (adj_addr) { - case 0xDD00: + case 0xdd00: { // bit 7 is the busy state u8 spi_reg = (m_spi_clock_cycles > 0 ? 0x80 : 0x00) + (spi_sd_enabled ? 1 : 0); // TODO add clock bits //logerror("Read SD 0: %02X\n", spi_reg); return spi_reg; } - case 0xDD01: + case 0xdd01: //logerror("Read SD 1: %02X\n", m_in_latch); return m_in_latch; default: - return 0xFF; + return 0xff; } } - else if (adj_addr >= 0xDE00 && adj_addr < 0xDE20) + else if (adj_addr >= 0xde00 && adj_addr < 0xde20) { // Math Coprocessor - switch (adj_addr - 0xDE10) + switch (adj_addr - 0xde10) { case 0: - return m_multiplication_result & 0xFF; + return m_multiplication_result & 0xff; case 1: - return (m_multiplication_result >> 8) & 0xFF; + return (m_multiplication_result >> 8) & 0xff; case 2: - return (m_multiplication_result >> 16) & 0xFF; + return (m_multiplication_result >> 16) & 0xff; case 3: - return (m_multiplication_result >> 24) & 0xFF; + return (m_multiplication_result >> 24) & 0xff; case 4: - return m_division_result & 0xFF; + return m_division_result & 0xff; case 5: - return (m_division_result >> 8) & 0xFF; + return (m_division_result >> 8) & 0xff; case 6: - return m_division_remainder & 0xFF; + return m_division_remainder & 0xff; case 7: - return (m_division_remainder >> 8) & 0xFF; + return (m_division_remainder >> 8) & 0xff; case 8: - return m_addition_result & 0xFF; + return m_addition_result & 0xff; case 9: - return (m_addition_result >> 8) & 0xFF; - case 0xA: - return (m_addition_result >> 16) & 0xFF; - case 0xB: - return (m_addition_result >> 24) & 0xFF; + return (m_addition_result >> 8) & 0xff; + case 0xa: + return (m_addition_result >> 16) & 0xff; + case 0xb: + return (m_addition_result >> 24) & 0xff; } - return m_iopage[0]->read(adj_addr - 0xC000); + return m_iopage[0]->read(adj_addr - 0xc000); } - else if (adj_addr >= 0xDF00 && adj_addr < 0xE000) + else if (adj_addr >= 0xdf00 && adj_addr < 0xe000) { // DMA - if (adj_addr == 0xDF01) + if (adj_addr == 0xdf01) { return m_dma_status; } else { - return m_iopage[0]->read(adj_addr - 0xC000); + return m_iopage[0]->read(adj_addr - 0xc000); } } // Stick everything else in Vicky - // (adj_addr >= 0xC000 && adj_addr < 0xD400) || // gamma, mouse graphics, vicky registers, bitmaps, tiles - // (adj_addr >= 0xD800 && adj_addr < 0xD880) || // text colors - // (adj_addr >= 0xD900 && adj_addr < 0xDB00) // sprite registers - return m_iopage[0]->read(adj_addr - 0xC000); + // (adj_addr >= 0xc000 && adj_addr < 0xd400) || // gamma, mouse graphics, vicky registers, bitmaps, tiles + // (adj_addr >= 0xd800 && adj_addr < 0xd880) || // text colors + // (adj_addr >= 0xd900 && adj_addr < 0xdb00) // sprite registers + return m_iopage[0]->read(adj_addr - 0xc000); case 1: - return m_iopage[1]->read(adj_addr - 0xC000); + return m_iopage[1]->read(adj_addr - 0xc000); case 2: - return m_iopage[2]->read(adj_addr - 0xC000); + return m_iopage[2]->read(adj_addr - 0xc000); case 3: - return m_iopage[3]->read(adj_addr - 0xC000); + return m_iopage[3]->read(adj_addr - 0xc000); } } offs_t address = (bank << 13) + low_addr; @@ -624,7 +626,7 @@ u8 f256_state::mem_r(offs_t offset) offs_t address = (bank << 13) + low_addr; return m_rom->as_u8(address); } - else if (bank < 0xA0) + else if (bank < 0xa0) { // this is now trying to read expansion RAM/Flash - NOT IMPLEMENTED } @@ -637,7 +639,7 @@ void f256_state::mem_w(offs_t offset, u8 data) uint8_t mmu = m_mmu_reg & 3; uint16_t adj_addr = offset + 0x10; uint8_t slot = adj_addr >> 13; - uint16_t low_addr = adj_addr & 0x1FFF; + uint16_t low_addr = adj_addr & 0x1fff; uint8_t old, combo; uint8_t bank = mmu_lut[mmu * 8 + slot]; @@ -653,7 +655,7 @@ void f256_state::mem_w(offs_t offset, u8 data) { case 0: // here we have a number of devices to write - if (adj_addr == 0xD001) + if (adj_addr == 0xd001) { logerror("Change Resolution %04X %02X\n", adj_addr, data); if ((data & 0x1) != 0 ) @@ -668,62 +670,65 @@ void f256_state::mem_w(offs_t offset, u8 data) m_screen->set_visarea(0, 639, 0, 479); m_screen->set_size(800,525); } - m_iopage[0]->write(0xD001 - 0xC000, data); + m_iopage[0]->write(0xd001 - 0xc000, data); } - else if (adj_addr >= 0xD400 && adj_addr < 0xD419) + else if (adj_addr >= 0xd400 && adj_addr < 0xd419) { // SID 0 - m_sid[0]->write(adj_addr - 0xD400, data); + m_sid[0]->write(adj_addr - 0xd400, data); } - else if (adj_addr >= 0xD500 && adj_addr < 0xD519) + else if (adj_addr >= 0xd500 && adj_addr < 0xd519) { // SID 1 - m_sid[1]->write(adj_addr - 0xD500, data); + m_sid[1]->write(adj_addr - 0xd500, data); } - else if (adj_addr >= 0xD580 && adj_addr < 0xD583) + else if (adj_addr >= 0xd580 && adj_addr < 0xd583) { // OPL3 switch(adj_addr) { - case 0xD580: + case 0xd580: m_opl3_reg = data; m_opl3->address_w(data); break; - case 0xD581: + case 0xd581: //m_opl3->write(m_opl3_reg, data); - if (m_opl3_reg > 0xFF) { m_opl3->data_hi_w(data);} else { m_opl3->data_w(data);} + if (m_opl3_reg > 0xff) + { + m_opl3->data_hi_w(data);} else { m_opl3->data_w(data); + } break; - case 0xD582: + case 0xd582: m_opl3_reg = 0x100 + data; m_opl3->address_hi_w(data); break; } } - else if (adj_addr == 0xD600) + else if (adj_addr == 0xd600) { // PSG logerror("PSG Left Write: %02X\n", data); m_sn[0]->write(data); } - else if (adj_addr == 0xD608) + else if (adj_addr == 0xd608) { // PSG logerror("PSG Both Write: %02X\n", data); m_sn[0]->write(data); m_sn[1]->write(data); } - else if (adj_addr == 0xD610) + else if (adj_addr == 0xd610) { // PSG logerror("PSG Right Write: %02X\n", data); m_sn[1]->write(data); } - else if (adj_addr >= 0xD620 && adj_addr < 0xD630) + else if (adj_addr >= 0xd620 && adj_addr < 0xd630) { // Codec logerror("CODEC Write %04X %02X\n", adj_addr, data); - uint16_t base = adj_addr-0xD620; + uint16_t base = adj_addr-0xd620; m_codec[base] = data; // the program is telling the codec to start if ((base == 2) && ((data & 1) == 1)) @@ -732,17 +737,17 @@ void f256_state::mem_w(offs_t offset, u8 data) this->machine().scheduler().timer_set(attotime::from_msec(100), timer_expired_delegate(FUNC(f256_state::codec_done), this), 1); // timer_alloc(timer_expired_delegate(FUNC(f256_state::timer), this)); } } - else if (adj_addr >= 0xD630 && adj_addr < 0xD640) + else if (adj_addr >= 0xd630 && adj_addr < 0xd640) { // UART logerror("UART Writing %X %02X\n", adj_addr, data); - m_uart->ins8250_w(adj_addr - 0xD630, data); + m_uart->ins8250_w(adj_addr - 0xd630, data); } - else if (adj_addr >= 0xD640 && adj_addr < 0xD64F) + else if (adj_addr >= 0xd640 && adj_addr < 0xd64f) { // PS/2 Keyboard logerror("PS/2 Write %04X %02X\n", adj_addr, data); - uint16_t delta = adj_addr-0xD640; + uint16_t delta = adj_addr-0xd640; m_ps2[delta] = data; // Only addresses 0 and 1 are writable if (delta == 0) @@ -784,22 +789,22 @@ void f256_state::mem_w(offs_t offset, u8 data) } } - else if (adj_addr >= 0xD650 && adj_addr < 0xD660) + else if (adj_addr >= 0xd650 && adj_addr < 0xd660) { // Timers logerror("Writing to Timer Register: %X, %02X\n", adj_addr, data); - m_iopage[0]->write(adj_addr - 0xC000, data); + m_iopage[0]->write(adj_addr - 0xc000, data); switch(adj_addr) { - case 0xD650: + case 0xd650: // Timer0 is based on Master Clock and causes some slow down. // I'm computing the next period and avoiding increments by one. if ((data & 0x1) == 1) { - uint32_t timer0_cmp = m_iopage[0]->read(0xD655 - 0xC000) + - (m_iopage[0]->read(0xD656 - 0xC000) << 8) + - (m_iopage[0]->read(0xD657 - 0xC000) << 16); + uint32_t timer0_cmp = m_iopage[0]->read(0xd655 - 0xc000) + + (m_iopage[0]->read(0xd656 - 0xc000) << 8) + + (m_iopage[0]->read(0xd657 - 0xc000) << 16); logerror("Start Timer0: %06X\n", timer0_cmp); attotime period = attotime::from_double((double)(timer0_cmp - m_timer0_load)/(double)25'175'000); m_timer0->adjust(period, 0, period); @@ -819,20 +824,20 @@ void f256_state::mem_w(offs_t offset, u8 data) m_timer0_val = m_timer0_load; } break; - case 0xD651: - case 0xD652: - case 0xD653: + case 0xd651: + case 0xd652: + case 0xd653: // writing to these registers sets the load value - m_timer0_load = m_iopage[0]->read(0xD651 - 0xC000) + (m_iopage[0]->read(0xD652 - 0xC000) << 8) + - (m_iopage[0]->read(0xD653 - 0xC000) << 16); + m_timer0_load = m_iopage[0]->read(0xd651 - 0xc000) + (m_iopage[0]->read(0xd652 - 0xc000) << 8) + + (m_iopage[0]->read(0xd653 - 0xc000) << 16); break; - case 0xD658: + case 0xd658: // Timer1 is based on the Start of Frame - so it's very slow if ((data & 0x1) == 1) { logerror("Start Timer1 %X, %X\n", data, m_timer1_val); // Get the frame frequency from video - int frame_freq = (m_iopage[0]->read(0xD001 - 0xC000) & 1) == 1? 70: 60; + int frame_freq = (m_iopage[0]->read(0xd001 - 0xc000) & 1) == 1? 70: 60; m_timer1->adjust(attotime::from_hz(XTAL(frame_freq)), 0, attotime::from_hz(XTAL(frame_freq))); } else @@ -852,22 +857,22 @@ void f256_state::mem_w(offs_t offset, u8 data) logerror("Timer1 value = %06X\n", m_timer1_val); } break; - case 0xD659: - case 0xD65A: - case 0xD65B: + case 0xd659: + case 0xd65a: + case 0xd65b: // writing to these registers sets the load value - m_timer1_load = m_iopage[0]->read(0xD659 - 0xC000) + (m_iopage[0]->read(0xD65A - 0xC000) << 8) + - (m_iopage[0]->read(0xD65B - 0xC000) << 16); + m_timer1_load = m_iopage[0]->read(0xd659 - 0xc000) + (m_iopage[0]->read(0xd65a - 0xc000) << 8) + + (m_iopage[0]->read(0xd65b - 0xc000) << 16); break; } } - else if (adj_addr >= 0xD660 && adj_addr < 0xD670) + else if (adj_addr >= 0xd660 && adj_addr < 0xd670) { // Interrupt Registers logerror("Interrupt Register Write: %04X with %02X\n", adj_addr, data); switch (adj_addr) { - case 0xD660: + case 0xd660: // int_pending_0 old = m_interrupt_reg[0]; combo = old & data; @@ -877,7 +882,7 @@ void f256_state::mem_w(offs_t offset, u8 data) } break; - case 0xD661: + case 0xd661: // int_pending_1 old = m_interrupt_reg[1]; combo = old & data; @@ -886,7 +891,7 @@ void f256_state::mem_w(offs_t offset, u8 data) m_interrupt_reg[1] = old & ~combo; } break; - case 0xD662: + case 0xd662: // int_pending_2 old = m_interrupt_reg[2]; combo = old & data; @@ -895,46 +900,46 @@ void f256_state::mem_w(offs_t offset, u8 data) m_interrupt_reg[2] = old & ~combo; } break; - case 0xD663: + case 0xd663: break; - case 0xD664: + case 0xd664: // int_polarity_0 m_interrupt_polarity[0] = data; break; - case 0xD665: + case 0xd665: // int_polarity_1 m_interrupt_polarity[1] = data; break; - case 0xD666: + case 0xd666: // int_polarity_2 m_interrupt_polarity[2] = data; break; - case 0xD667: + case 0xd667: break; - case 0xD668: + case 0xd668: // int_edge_0 m_interrupt_edge[0] = data; break; - case 0xD669: + case 0xd669: // int_edge_1 m_interrupt_edge[1] = data; break; - case 0xD66A: + case 0xd66a: // int_edge_2 m_interrupt_edge[2] = data; break; - case 0xD66B: + case 0xd66b: break; - case 0xD66C: + case 0xd66c: m_interrupt_masks[0] = data; break; - case 0xD66D: + case 0xd66d: m_interrupt_masks[1] = data; break; - case 0xD66E: + case 0xd66e: m_interrupt_masks[2] = data; break; - case 0xD66F: + case 0xd66f: break; } @@ -944,11 +949,11 @@ void f256_state::mem_w(offs_t offset, u8 data) m_maincpu->set_input_line(M6502_IRQ_LINE, CLEAR_LINE); } } - //IEC - 0xD680 is not writable - else if (adj_addr >= 0xD680 && adj_addr < 0xD682) + //IEC - 0xd680 is not writable + else if (adj_addr >= 0xd680 && adj_addr < 0xd682) { logerror("Writing to IEC reg %X %02X\n", adj_addr, data); - if (adj_addr == 0xD681) + if (adj_addr == 0xd681) { m_iec_out = data; // Bit 6 is RESET @@ -961,25 +966,25 @@ void f256_state::mem_w(offs_t offset, u8 data) // m_iec->host_srq_w((data & 0x80) >> 7); // fake the bus - m_iec_in &= 0xFE; + m_iec_in &= 0xfe; m_iec_in |= (data & 1); } } - else if (adj_addr >= 0xD690 && adj_addr < 0xD6A0) + else if (adj_addr >= 0xd690 && adj_addr < 0xd6a0) { // RTC logerror("RTC Write %04X %02X\n", adj_addr, data); - m_rtc->write(adj_addr - 0xDC90, data); + m_rtc->write(adj_addr - 0xdc90, data); } - else if (adj_addr >= 0xD6A0 && adj_addr < 0xD6A7) + else if (adj_addr >= 0xd6a0 && adj_addr < 0xd6a7) { // RNG logerror("RNG Write %04X %02X\n", adj_addr, data); switch (adj_addr) { - case 0xD6A1: + case 0xd6a1: // mix the PSG or SID based on the value - m_iopage[0]->write(0xD6A1 - 0xC000, data); + m_iopage[0]->write(0xd6a1 - 0xc000, data); if ((data & 4) == 0) { // PSG mix - both outputs to both speakers @@ -1016,15 +1021,15 @@ void f256_state::mem_w(offs_t offset, u8 data) m_sid[1]->add_route(ALL_OUTPUTS, "rspeaker", 0.5, 0); } break; - case 0xD6A4: - m_seed &= 0xFF00; // zero the low byte + case 0xd6a4: + m_seed &= 0xff00; // zero the low byte m_seed |= data; // set the low byte break; - case 0xD6A5: - m_seed &= 0xFF; // zero the high byte + case 0xd6a5: + m_seed &= 0xff; // zero the high byte m_seed |= (data << 8); // set the high byte break; - case 0xD6A6: + case 0xd6a6: m_rng_enabled = (data & 1); if ((data & 2) != 0) { @@ -1034,32 +1039,32 @@ void f256_state::mem_w(offs_t offset, u8 data) } } // mouse registers - // else if (adj_addr >= 0xD6E0 && adj_addr < 0xD6E9) + // else if (adj_addr >= 0xd6e0 && adj_addr < 0xd6e9) // { // switch (adj_addr) // { - // case 0xD6E0: + // case 0xd6e0: // m_mouse_enabled = (data & 1) != 0; // m_mouse_mode = (data >> 1) & 1; // break; - // case 0xD6E2: + // case 0xd6e2: // // keep the high byte - // m_mouse_x &= 0xFF00; + // m_mouse_x &= 0xff00; // m_mouse_x |= data; // break; - // case 0xD6E3: + // case 0xd6e3: // // keep the low byte - // m_mouse_x &= 0xFF; + // m_mouse_x &= 0xff; // m_mouse_x |= data << 8; // break; - // case 0xD6E4: + // case 0xd6e4: // // keep the high byte - // m_mouse_y &= 0xFF00; + // m_mouse_y &= 0xff00; // m_mouse_y |= data; // break; - // case 0xD6E5: + // case 0xd6e5: // // keep the low byte - // m_mouse_y &= 0xFF; + // m_mouse_y &= 0xff; // m_mouse_y |= data << 8; // break; @@ -1067,24 +1072,24 @@ void f256_state::mem_w(offs_t offset, u8 data) // break; // } // } - else if (adj_addr >= 0xD880 && adj_addr < 0xD8C0) + else if (adj_addr >= 0xd880 && adj_addr < 0xd8c0) { - // NES - only address 0xD8800 is writable + // NES - only address 0xd8800 is writable } - else if (adj_addr >= 0xDB00 && adj_addr < 0xDC00) + else if (adj_addr >= 0xdb00 && adj_addr < 0xdc00) { // VIA1 - Keyboard for F256K - m_via6522[1]->write(adj_addr - 0xDB00, data); + m_via6522[1]->write(adj_addr - 0xdb00, data); } - else if (adj_addr >= 0xDC00 && adj_addr < 0xDD00) + else if (adj_addr >= 0xdc00 && adj_addr < 0xdd00) { // VIA0 - Atari Joystick - m_via6522[0]->write(adj_addr - 0xDC00, data); + m_via6522[0]->write(adj_addr - 0xdc00, data); } - else if (adj_addr >= 0xDD00 && adj_addr < 0xDD20) + else if (adj_addr >= 0xdd00 && adj_addr < 0xdd20) { // SD Card - switch(adj_addr - 0xDD00) + switch(adj_addr - 0xdd00) { case 0: // When bit is set, clock is 400kHz - 0= 12.5 MHz @@ -1123,34 +1128,34 @@ void f256_state::mem_w(offs_t offset, u8 data) // $DDA0 - $DDBF - MIDI UART (Fixed @ 31,250Baud) // $DDC0 - $DDDF - Master SPI Interface to Supervisor (RP2040)* } - else if (adj_addr >= 0xDE00 && adj_addr < 0xDE20) + else if (adj_addr >= 0xde00 && adj_addr < 0xde20) { // Math Coprocessor - 4 blocks - u8 block = (adj_addr - 0xDE00) >> 2; - if (adj_addr < 0xDE10) + u8 block = (adj_addr - 0xde00) >> 2; + if (adj_addr < 0xde10) { - m_iopage[0]->write(adj_addr - 0xC000, data); + m_iopage[0]->write(adj_addr - 0xc000, data); } switch (block) { case 0: - unsignedMultiplier(0xDE00 - 0xC000); + unsignedMultiplier(0xde00 - 0xc000); break; case 1: - unsignedDivider(0xDE04 - 0xC000); + unsignedDivider(0xde04 - 0xc000); break; case 2: case 3: - unsignedAdder(0xDE08 - 0xC000); + unsignedAdder(0xde08 - 0xc000); break; } } - else if (adj_addr >= 0xDF00 && adj_addr < 0xE000) + else if (adj_addr >= 0xdf00 && adj_addr < 0xe000) { // DMA logerror("DMA Write %04X %02X\n", adj_addr, data); - m_iopage[0]->write(adj_addr - 0xC000, data); - if ((adj_addr - 0xDF00) == 0) + m_iopage[0]->write(adj_addr - 0xc000, data); + if ((adj_addr - 0xdf00) == 0) { // control register - when start and enabled are set start DMA operation if ((data & 0x81) == 0x81) @@ -1184,23 +1189,23 @@ void f256_state::mem_w(offs_t offset, u8 data) } } // stick everything else in Vicky - // (adj_addr >= 0xC000 && adj_addr < 0xD400) || // gamma, mouse graphics, vicky registers, bitmaps, tiles - // (adj_addr >= 0xD800 && adj_addr < 0xD880) || // text colors - // (adj_addr >= 0xD900 && adj_addr < 0xDB00) // sprite registers + // (adj_addr >= 0xc000 && adj_addr < 0xd400) || // gamma, mouse graphics, vicky registers, bitmaps, tiles + // (adj_addr >= 0xd800 && adj_addr < 0xd880) || // text colors + // (adj_addr >= 0xd900 && adj_addr < 0xdB00) // sprite registers else { - m_iopage[0]->write(adj_addr - 0xC000, data); + m_iopage[0]->write(adj_addr - 0xc000, data); } break; case 1: - m_iopage[1]->write(adj_addr - 0xC000, data); + m_iopage[1]->write(adj_addr - 0xc000, data); break; case 2: - m_iopage[2]->write(adj_addr - 0xC000, data); + m_iopage[2]->write(adj_addr - 0xc000, data); break; case 3: - m_iopage[3]->write(adj_addr - 0xC000, data); + m_iopage[3]->write(adj_addr - 0xc000, data); break; } } @@ -1347,7 +1352,7 @@ void f256_state::unsignedAdder(int baseAddr) uint8_t f256_state::get_random() { uint8_t m_random = rand(); - return m_random & 0xFF; + return m_random & 0xff; } //------------------------------------------------- // DMA Methods @@ -1355,11 +1360,11 @@ uint8_t f256_state::get_random() void f256_state::perform2DFillDMA() { - uint8_t fill_byte = m_iopage[0]->read(0xDF01 - 0xC000); - uint32_t dest_addr = ((m_iopage[0]->read(0xDF0A) & 0x7) << 16) + (m_iopage[0]->read(0xDF09) << 8) + m_iopage[0]->read(0xDF08); - uint16_t width_2D = (m_iopage[0]->read(0xDF0D - 0xC000) << 8) + m_iopage[0]->read(0xDF0C - 0xC000); - uint16_t height_2D = (m_iopage[0]->read(0xDF0F - 0xC000) << 8) + m_iopage[0]->read(0xDF0E - 0xC000); - uint16_t dest_stride = (m_iopage[0]->read(0xDF13 - 0xC000) << 8) + m_iopage[0]->read(0xDF12 - 0xC000); + uint8_t fill_byte = m_iopage[0]->read(0xdf01 - 0xc000); + uint32_t dest_addr = ((m_iopage[0]->read(0xdf0a) & 0x7) << 16) + (m_iopage[0]->read(0xdf09) << 8) + m_iopage[0]->read(0xdf08); + uint16_t width_2D = (m_iopage[0]->read(0xdf0d - 0xc000) << 8) + m_iopage[0]->read(0xdf0c - 0xc000); + uint16_t height_2D = (m_iopage[0]->read(0xdf0f - 0xc000) << 8) + m_iopage[0]->read(0xdf0e - 0xc000); + uint16_t dest_stride = (m_iopage[0]->read(0xdf13 - 0xc000) << 8) + m_iopage[0]->read(0xdf12 - 0xc000); //logerror("2D Fill DMA: DEST: %X, W: %X, H: %X\n", dest_addr, width_2D, height_2D); for (int y = 0; y < height_2D; y++) { @@ -1371,20 +1376,20 @@ void f256_state::perform2DFillDMA() } void f256_state::performLinearFillDMA() { - uint8_t fill_byte = m_iopage[0]->read(0xDF01 - 0xC000); - uint32_t dest_addr = ((m_iopage[0]->read(0xDF0A) & 0x7) << 16) + (m_iopage[0]->read(0xDF09) << 8) + m_iopage[0]->read(0xDF08); - uint32_t count = ((m_iopage[0]->read(0xDF0E) & 0x7) << 16) + (m_iopage[0]->read(0xDF0D) << 8) + m_iopage[0]->read(0xDF0C); + uint8_t fill_byte = m_iopage[0]->read(0xdf01 - 0xc000); + uint32_t dest_addr = ((m_iopage[0]->read(0xdf0a) & 0x7) << 16) + (m_iopage[0]->read(0xdf09) << 8) + m_iopage[0]->read(0xdf08); + uint32_t count = ((m_iopage[0]->read(0xdf0e) & 0x7) << 16) + (m_iopage[0]->read(0xdf0d) << 8) + m_iopage[0]->read(0xdf0c); //logerror("Linear Fill DMA DEST: %X, LEN: %X\n", dest_addr, count); memset(m_ram->pointer() + dest_addr, fill_byte, count); } void f256_state::perform2DDMA() { - uint32_t src_addr = ((m_iopage[0]->read(0xDF06) & 0x7) << 16) + (m_iopage[0]->read(0xDF05) << 8) + m_iopage[0]->read(0xDF04); - uint32_t dest_addr = ((m_iopage[0]->read(0xDF0A) & 0x7) << 16) + (m_iopage[0]->read(0xDF09) << 8) + m_iopage[0]->read(0xDF08); - uint16_t width_2D = (m_iopage[0]->read(0xDF0D - 0xC000) << 8) + m_iopage[0]->read(0xDF0C - 0xC000); - uint16_t height_2D = (m_iopage[0]->read(0xDF0F - 0xC000) << 8) + m_iopage[0]->read(0xDF0E - 0xC000); - uint16_t src_stride = (m_iopage[0]->read(0xDF11 - 0xC000) << 8) + m_iopage[0]->read(0xDF10 - 0xC000); - uint16_t dest_stride = (m_iopage[0]->read(0xDF13 - 0xC000) << 8) + m_iopage[0]->read(0xDF12 - 0xC000); + uint32_t src_addr = ((m_iopage[0]->read(0xdf06) & 0x7) << 16) + (m_iopage[0]->read(0xdf05) << 8) + m_iopage[0]->read(0xdf04); + uint32_t dest_addr = ((m_iopage[0]->read(0xdf0a) & 0x7) << 16) + (m_iopage[0]->read(0xdf09) << 8) + m_iopage[0]->read(0xdf08); + uint16_t width_2D = (m_iopage[0]->read(0xdf0d - 0xc000) << 8) + m_iopage[0]->read(0xdf0c - 0xc000); + uint16_t height_2D = (m_iopage[0]->read(0xdf0f - 0xc000) << 8) + m_iopage[0]->read(0xdf0e - 0xc000); + uint16_t src_stride = (m_iopage[0]->read(0xdf11 - 0xc000) << 8) + m_iopage[0]->read(0xdf10 - 0xc000); + uint16_t dest_stride = (m_iopage[0]->read(0xdf13 - 0xc000) << 8) + m_iopage[0]->read(0xdf12 - 0xc000); //logerror("2D Copy DMA, SRC: %X, DEST: %X, W: %X H: %X, SRC_STR: %X, DEST_STR: %X\n", src_addr, dest_addr, // width_2D, height_2D, src_stride, dest_stride); for (int y = 0; y < height_2D; y++) @@ -1398,9 +1403,9 @@ void f256_state::perform2DDMA() } void f256_state::performLinearDMA() { - uint32_t src_addr = ((m_iopage[0]->read(0xDF06) & 0x7) << 16) + (m_iopage[0]->read(0xDF05) << 8) + m_iopage[0]->read(0xDF04); - uint32_t dest_addr = ((m_iopage[0]->read(0xDF0A) & 0x7) << 16) + (m_iopage[0]->read(0xDF09) << 8) + m_iopage[0]->read(0xDF08); - uint32_t count = ((m_iopage[0]->read(0xDF0E) & 0x7) << 16) + (m_iopage[0]->read(0xDF0D) << 8) + m_iopage[0]->read(0xDF0C); + uint32_t src_addr = ((m_iopage[0]->read(0xdf06) & 0x7) << 16) + (m_iopage[0]->read(0xdf05) << 8) + m_iopage[0]->read(0xdf04); + uint32_t dest_addr = ((m_iopage[0]->read(0xdf0a) & 0x7) << 16) + (m_iopage[0]->read(0xdf09) << 8) + m_iopage[0]->read(0xdf08); + uint32_t count = ((m_iopage[0]->read(0xdf0e) & 0x7) << 16) + (m_iopage[0]->read(0xdf0d) << 8) + m_iopage[0]->read(0xdf0c); //logerror("Linear Copy DMA SRC: %X, DEST: %X, LEN: %X\n", src_addr, dest_addr, count); memcpy(m_ram->pointer() + dest_addr, m_ram->pointer() + src_addr, count); } @@ -1413,12 +1418,9 @@ void f256_state::device_start() { driver_device::device_start(); reset_mmu(); - // TODO: Copy the font from file to IO Page 1 - //memcpy(m_iopage[1], m_font, 0x800); - for (int i=0;i<0x800;i++) - { - m_iopage[1]->write(i, m_font->as_u8(i)); - } + // Copy the font from file to IO Page 1 + memcpy(m_iopage[1]->pointer(), m_font->base(), 0x800); + // Copy the gamma correction table uint8_t gamma_1_8[] = { 0x00, 0x0b, 0x11, 0x15, 0x19, 0x1c, 0x1f, 0x22, 0x25, 0x27, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, @@ -1453,10 +1455,10 @@ void f256_state::device_start() m_rtc->set_current_time(stnow); // Initialize the VIA0 - m_via6522[0]->write(via6522_device::VIA_DDRB, 0xFF); // DDRB - m_via6522[0]->write(via6522_device::VIA_DDRA, 0xFF); // DDRA - m_via6522[0]->write(via6522_device::VIA_PB, 0xFF); // JOYSTICK 2 - m_via6522[0]->write(via6522_device::VIA_PA, 0xFF); // JOYSTICK 1 + m_via6522[0]->write(via6522_device::VIA_DDRB, 0xff); // DDRB + m_via6522[0]->write(via6522_device::VIA_DDRA, 0xff); // DDRA + m_via6522[0]->write(via6522_device::VIA_PB, 0xff); // JOYSTICK 2 + m_via6522[0]->write(via6522_device::VIA_PA, 0xff); // JOYSTICK 1 m_via6522[0]->write(via6522_device::VIA_DDRB, 0); // DDRB m_via6522[0]->write(via6522_device::VIA_DDRA, 0); // DDRA @@ -1623,7 +1625,7 @@ TIMER_CALLBACK_MEMBER(f256_state::spi_clock) TIMER_CALLBACK_MEMBER(f256_state::timer0) { logerror("Timer0 reached value: %06X\n", m_timer0_load); - uint8_t reg_t0 = m_iopage[0]->read(0xD650 - 0xC000); + uint8_t reg_t0 = m_iopage[0]->read(0xd650 - 0xc000); if ((reg_t0 & 0x80) !=0) { timer0_interrupt_handler(1); @@ -1631,14 +1633,14 @@ TIMER_CALLBACK_MEMBER(f256_state::timer0) } // TIMER_CALLBACK_MEMBER(f256_state::timer0) // { -// uint8_t reg_t0 = m_iopage[0]->read(0xD650 - 0xC000); -// uint32_t cmp = m_iopage[0]->read(0xD655 - 0xC000) + (m_iopage[0]->read(0xD656 - 0xC000) << 8) + -// (m_iopage[0]->read(0xD657 - 0xC000) << 16); +// uint8_t reg_t0 = m_iopage[0]->read(0xd650 - 0xc000); +// uint32_t cmp = m_iopage[0]->read(0xd655 - 0xc000) + (m_iopage[0]->read(0xd656 - 0xc000) << 8) + +// (m_iopage[0]->read(0xd657 - 0xc000) << 16); // // if timer as reached value, then execute the action // if (m_timer0_eq == 1) // { -// int8_t action = m_iopage[0]->read(0xD654 - 0xC000); +// int8_t action = m_iopage[0]->read(0xd654 - 0xc000); // if (action & 1) // { // logerror("TIMER0 Cleared\n"); @@ -1676,9 +1678,9 @@ TIMER_CALLBACK_MEMBER(f256_state::timer0) // // down // m_timer0_val--; // // roll over to 24 bits -// if (m_timer0_val == 0xFFFF'FFFF) +// if (m_timer0_val == 0xffff'ffff) // { -// m_timer0_val = 0xFF'FFFF; +// m_timer0_val = 0xff'ffff; // } // if (m_timer0_val == cmp) // { @@ -1697,14 +1699,14 @@ TIMER_CALLBACK_MEMBER(f256_state::timer0) // This timer is much slower than Timer0, so we can use single increments TIMER_CALLBACK_MEMBER(f256_state::timer1) { - uint8_t reg_t1 = m_iopage[0]->read(0xD658 - 0xC000); - uint32_t cmp = m_iopage[0]->read(0xD65D - 0xC000) + (m_iopage[0]->read(0xD65E - 0xC000) << 8) + - (m_iopage[0]->read(0xD65F - 0xC000) << 16); + uint8_t reg_t1 = m_iopage[0]->read(0xd658 - 0xc000); + uint32_t cmp = m_iopage[0]->read(0xd65d - 0xc000) + (m_iopage[0]->read(0xd65e - 0xc000) << 8) + + (m_iopage[0]->read(0xd65f - 0xc000) << 16); logerror("TIMER1 event %06X CMP: %06X\n", m_timer1_val, cmp); // if timer as reached value, then execute the action if (m_timer1_eq == 1) { - int8_t action = m_iopage[0]->read(0xD65C - 0xC000); + int8_t action = m_iopage[0]->read(0xd65c - 0xc000); if (action & 1) { logerror("TIMER1 Cleared\n"); @@ -1742,9 +1744,9 @@ TIMER_CALLBACK_MEMBER(f256_state::timer1) // down m_timer1_val--; // roll over to 24 bits - if (m_timer1_val == 0xFFFF'FFFF) + if (m_timer1_val == 0xffff'ffff) { - m_timer1_val = 0xFF'FFFF; + m_timer1_val = 0xff'ffff; } if (m_timer1_val == cmp) { @@ -1846,7 +1848,7 @@ void f256_state::via1_system_porta_w(u8 data) //logerror("VIA1 Write Port A - %02X\n", data); m_via_keyboard_port_a = data; - m_via_keyboard_port_b = 0xFF; + m_via_keyboard_port_b = 0xff; // scan each keyboard row u8 joy1 = m_joy[0]->read(); m_via_joy1 = joy1 | 0x80; @@ -1856,7 +1858,7 @@ void f256_state::via1_system_porta_w(u8 data) if (BIT(data, r) == 0) { uint16_t kbval = m_keyboard[r]->read(); - m_via_keyboard_port_b &= (kbval & 0xFF); + m_via_keyboard_port_b &= (kbval & 0xff); if (r == 6 || r == 0) { if (BIT(kbval,8) == 0) @@ -1979,18 +1981,18 @@ ROM_START(f256k) ROM_LOAD("sb01.bin", 0x08'4000, 0x2000, CRC(21f06e73) SHA1(bbeefb52d4b126b61367169c21599180f3358af7)) ROM_LOAD("sb02.bin", 0x08'6000, 0x2000, CRC(6ed611b9) SHA1(4a03aa286f6274e6974a3cecdedad651a58f5fb1)) ROM_LOAD("sb03.bin", 0x08'8000, 0x2000, CRC(653f849d) SHA1(65942d98f26b86499e6359170aa2d0c6e16124ff)) - ROM_LOAD("sb04.bin", 0x08'A000, 0x2000, CRC(f4aa6049) SHA1(11f02fee6ec412f0c96b27b0b149f72cf1770d15)) - ROM_LOAD("dos.bin", 0x08'C000, 0x2000, CRC(f3673c4e) SHA1(9c6b70067d7195d4a6bbd7f379b8e5382bf8cc1b)) - ROM_LOAD("pexec.bin", 0x08'E000, 0x2000, CRC(937c1374) SHA1(40566a51d2ef7321a42fe926b03dee3571c78202)) + ROM_LOAD("sb04.bin", 0x08'a000, 0x2000, CRC(f4aa6049) SHA1(11f02fee6ec412f0c96b27b0b149f72cf1770d15)) + ROM_LOAD("dos.bin", 0x08'c000, 0x2000, CRC(f3673c4e) SHA1(9c6b70067d7195d4a6bbd7f379b8e5382bf8cc1b)) + ROM_LOAD("pexec.bin", 0x08'e000, 0x2000, CRC(937c1374) SHA1(40566a51d2ef7321a42fe926b03dee3571c78202)) ROM_LOAD("3b.bin", 0x0F'6000, 0x2000, CRC(7c5d2f27) SHA1(bd1ece74b02a210cfe5a1ed15a0febefc39a1861)) ROM_LOAD("3c.bin", 0x0F'8000, 0x2000, CRC(2e2295d1) SHA1(9049b83d4506b49701669c335ded2879c7992751)) - ROM_LOAD("3d.bin", 0x0F'A000, 0x2000, CRC(97743cb7) SHA1(693fa7762528eca6a75c9ea30a603dadc4d55cf9)) - ROM_LOAD("3e.bin", 0x0F'C000, 0x2000, CRC(9012398f) SHA1(4ae1e37aa3ad4c2b498bf1797d591d7fa25a9d43)) - ROM_LOAD("3f.bin", 0x0F'E000, 0x2000, CRC(b9ddda5e) SHA1(2f21ef84a269cc2ed25c6441c9451f61dbb5b285)) + ROM_LOAD("3d.bin", 0x0F'a000, 0x2000, CRC(97743cb7) SHA1(693fa7762528eca6a75c9ea30a603dadc4d55cf9)) + ROM_LOAD("3e.bin", 0x0F'c000, 0x2000, CRC(9012398f) SHA1(4ae1e37aa3ad4c2b498bf1797d591d7fa25a9d43)) + ROM_LOAD("3f.bin", 0x0F'e000, 0x2000, CRC(b9ddda5e) SHA1(2f21ef84a269cc2ed25c6441c9451f61dbb5b285)) ROM_LOAD("docs_superbasic1.bin", 0x09'6000, 0x2000, CRC(ad6398cd) SHA1(d926ae72f8f3af2a0b15ac165bc680db2e647740)) ROM_LOAD("docs_superbasic2.bin", 0x09'8000, 0x2000, CRC(3cf07824) SHA1(b92e88a99ccf51461f45d317e3e555c5d62792eb)) - ROM_LOAD("docs_superbasic3.bin", 0x09'A000, 0x2000, CRC(838cb5df) SHA1(103b182ad76c185c4a779f4865c48c5fc71e2a14)) - ROM_LOAD("docs_superbasic4.bin", 0x09'C000, 0x2000, CRC(bf7841b9) SHA1(7dcbf77c46d680a1c47ac11ed871b832a1479e8e)) + ROM_LOAD("docs_superbasic3.bin", 0x09'a000, 0x2000, CRC(838cb5df) SHA1(103b182ad76c185c4a779f4865c48c5fc71e2a14)) + ROM_LOAD("docs_superbasic4.bin", 0x09'c000, 0x2000, CRC(bf7841b9) SHA1(7dcbf77c46d680a1c47ac11ed871b832a1479e8e)) ROM_LOAD("help.bin", 0x09'4000, 0x2000, CRC(b7d63466) SHA1(bd1dafb5849dee61fd48ece16a409e56de62f464)) // Load the file manager application @@ -1999,9 +2001,9 @@ ROM_START(f256k) ROM_LOAD("fm.02", 0x0A'4000, 0x2000, CRC(9c90cf7d) SHA1(0ed0a09f7bb1eeb0a99141e9d4625d027448b7ea)) ROM_LOAD("fm.03", 0x0A'6000, 0x2000, CRC(7dfe0934) SHA1(48d2aa2f4c926f7a81e9eab312883e4e573e7cd9)) ROM_LOAD("fm.04", 0x0A'8000, 0x2000, CRC(3bc5832d) SHA1(5a8491e4c6e4e56e4017ece97615f7eb5aa928e3)) - ROM_LOAD("fm.05", 0x0A'A000, 0x2000, CRC(48dcadc7) SHA1(52e051d5e8446deddfc469f7aed0f18fb2483715)) - ROM_LOAD("fm.06", 0x0A'C000, 0x2000, CRC(035c3c8a) SHA1(649601087b7b95a4f432f362428e98291648434c)) - ROM_LOAD("fm.07", 0x0A'E000, 0x2000, CRC(76f749d4) SHA1(a3e7e881f4c4fd39c94385de2c8d7546a2239d96)) + ROM_LOAD("fm.05", 0x0A'a000, 0x2000, CRC(48dcadc7) SHA1(52e051d5e8446deddfc469f7aed0f18fb2483715)) + ROM_LOAD("fm.06", 0x0A'c000, 0x2000, CRC(035c3c8a) SHA1(649601087b7b95a4f432f362428e98291648434c)) + ROM_LOAD("fm.07", 0x0A'e000, 0x2000, CRC(76f749d4) SHA1(a3e7e881f4c4fd39c94385de2c8d7546a2239d96)) ROM_REGION(0x0800,FONT_TAG,0) ROM_LOAD("f256jr_font_micah_jan25th.bin", 0x0000, 0x0800, CRC(6d66da85) SHA1(377dc27ff3a4ae2d80d740b2d16373f8e639eef6)) diff --git a/src/mame/f256/f256.h b/src/mame/f256/f256.h index 4a9a53ff7d5e5..fed12deff2750 100644 --- a/src/mame/f256/f256.h +++ b/src/mame/f256/f256.h @@ -101,8 +101,8 @@ class f256_state : public driver_device void via0_interrupt(int state); void via1_interrupt(int state); uint8_t m_interrupt_reg[3] = { 0, 0 ,0}; - uint8_t m_interrupt_masks[3] = { 0xFF, 0xFF, 0xFF}; - uint8_t m_interrupt_edge[3] = { 0xFF, 0xFF, 0xFF}; + uint8_t m_interrupt_masks[3] = { 0xff, 0xff, 0xff}; + uint8_t m_interrupt_edge[3] = { 0xff, 0xff, 0xff}; uint8_t m_interrupt_polarity[3] = {0, 0, 0}; // VIA0 - Atari joystick functions @@ -114,9 +114,9 @@ class f256_state : public driver_device void via0_cb2_write(u8 data); // VIA1 - Internal Keyboard - uint8_t m_via_keyboard_port_a = 0xFF; - uint8_t m_via_keyboard_port_b = 0xFF; - uint8_t m_via_joy1 = 0xFF; + uint8_t m_via_keyboard_port_a = 0xff; + uint8_t m_via_keyboard_port_b = 0xff; + uint8_t m_via_joy1 = 0xff; u8 via1_system_porta_r(); u8 via1_system_portb_r(); diff --git a/src/mame/f256/tiny_vicky.cpp b/src/mame/f256/tiny_vicky.cpp index de2590fb994b0..eaed804a7aaa6 100644 --- a/src/mame/f256/tiny_vicky.cpp +++ b/src/mame/f256/tiny_vicky.cpp @@ -36,7 +36,7 @@ rgb_t tiny_vicky_video_device::get_text_lut(uint8_t color_index, bool fg, bool g rgb_t tiny_vicky_video_device::get_lut_value(uint8_t lut_index, uint8_t pix_val, bool gamma) { - int lutAddress = 0xD000 - 0xC000 + (lut_index * 256 + pix_val) * 4; + int lutAddress = 0xd000 - 0xc000 + (lut_index * 256 + pix_val) * 4; if (!gamma) { return rgb_t(m_iopage1_ptr[lutAddress + 2], m_iopage1_ptr[lutAddress + 1], m_iopage1_ptr[lutAddress]); @@ -74,7 +74,8 @@ uint32_t tiny_vicky_video_device::screen_update(screen_device &screen, bitmap_rg uint8_t border_x = 0; uint8_t border_y = 0; rgb_t border_color = rgb_t(); - if (display_border) { + if (display_border) + { border_x = m_iopage0_ptr[0x1008]; border_y = m_iopage0_ptr[0x1009]; } @@ -84,7 +85,7 @@ uint32_t tiny_vicky_video_device::screen_update(screen_device &screen, bitmap_rg // Check the Sart of Line registers uint8_t sol_reg = m_iopage0_ptr[0x1018]; // 12-bit line - uint16_t sol_line = m_iopage0_ptr[0x1018] + ((m_iopage0_ptr[0x101A] & 0xF) << 8); + uint16_t sol_line = m_iopage0_ptr[0x1018] + ((m_iopage0_ptr[0x101a] & 0xf) << 8); uint32_t *row = topleft + y * 800; if ((sol_reg & 1) != 0 && y == sol_line) { @@ -121,13 +122,13 @@ uint32_t tiny_vicky_video_device::screen_update(screen_device &screen, bitmap_rg { if (!enable_gamma) { - background_color = rgb_t(m_iopage0_ptr[0x100F], m_iopage0_ptr[0x100E], m_iopage0_ptr[0x100D]); + background_color = rgb_t(m_iopage0_ptr[0x100f], m_iopage0_ptr[0x100e], m_iopage0_ptr[0x100d]); } else { - background_color = rgb_t(m_iopage0_ptr[0x800 + m_iopage0_ptr[0x100F]], - m_iopage0_ptr[0x400 + m_iopage0_ptr[0x100E]], - m_iopage0_ptr[m_iopage0_ptr[0x100D]]); + background_color = rgb_t(m_iopage0_ptr[0x800 + m_iopage0_ptr[0x100f]], + m_iopage0_ptr[0x400 + m_iopage0_ptr[0x100e]], + m_iopage0_ptr[m_iopage0_ptr[0x100d]]); } } // draw the border or background @@ -145,47 +146,47 @@ uint32_t tiny_vicky_video_device::screen_update(screen_device &screen, bitmap_rg if (y % 2 == 0) { // Tiny Vicky Layers for Bitmaps, Tilemaps and sprites - uint8_t LayerMgr0 = m_iopage0_ptr[0xD002 - 0xC000] & 0x7; - uint8_t LayerMgr1 = m_iopage0_ptr[0xD002 - 0xC000] >> 4; - uint8_t LayerMgr2 = m_iopage0_ptr[0xD003 - 0xC000] & 0x7; + uint8_t layer_mgr0 = m_iopage0_ptr[0xd002 - 0xc000] & 0x7; + uint8_t layer_mgr1 = m_iopage0_ptr[0xd002 - 0xc000] >> 4; + uint8_t layer_mgr2 = m_iopage0_ptr[0xd003 - 0xc000] & 0x7; // draw layers starting from the back if ((mcr & 0x20) != 0) { draw_sprites(row, enable_gamma, 3, display_border, border_x, border_y, y, (uint16_t)640, lines / 2); } - if ((mcr & 0x8) != 0 && LayerMgr2 < 3) + if ((mcr & 0x8) != 0 && layer_mgr2 < 3) { - draw_bitmap(row, enable_gamma, LayerMgr2, display_border, background_color, border_x, border_y, y, (uint16_t)640); + draw_bitmap(row, enable_gamma, layer_mgr2, display_border, background_color, border_x, border_y, y, (uint16_t)640); } - if ((mcr & 0x10) != 0 && (LayerMgr2 > 3 && LayerMgr2 < 7)) + if ((mcr & 0x10) != 0 && (layer_mgr2 > 3 && layer_mgr2 < 7)) { - draw_tiles(row, enable_gamma, LayerMgr2 & 3, display_border, border_x, y, (uint16_t)640); + draw_tiles(row, enable_gamma, layer_mgr2 & 3, display_border, border_x, y, (uint16_t)640); } if ((mcr & 0x20) != 0) { draw_sprites(row, enable_gamma, 2, display_border, border_x, border_y, y, (uint16_t)640, lines/2); } - if ((mcr & 0x8) != 0 && LayerMgr1 < 3) + if ((mcr & 0x8) != 0 && layer_mgr1 < 3) { - draw_bitmap(row, enable_gamma, LayerMgr1, display_border, background_color, border_x, border_y, y, (uint16_t)640); + draw_bitmap(row, enable_gamma, layer_mgr1, display_border, background_color, border_x, border_y, y, (uint16_t)640); } - if ((mcr & 0x10) != 0 && (LayerMgr1 > 3 && LayerMgr1 < 7)) + if ((mcr & 0x10) != 0 && (layer_mgr1 > 3 && layer_mgr1 < 7)) { - draw_tiles(row, enable_gamma, LayerMgr1 & 3, display_border, border_x, y, (uint16_t)640); + draw_tiles(row, enable_gamma, layer_mgr1 & 3, display_border, border_x, y, (uint16_t)640); } if ((mcr & 0x20) != 0) { draw_sprites(row, enable_gamma, 1, display_border, border_x, border_y, y, (uint16_t)640, lines / 2); } - if ((mcr & 0x8) != 0 && LayerMgr0 < 3) + if ((mcr & 0x8) != 0 && layer_mgr0 < 3) { - draw_bitmap(row, enable_gamma, LayerMgr0, display_border, background_color, border_x, border_y, y, (uint16_t)640); + draw_bitmap(row, enable_gamma, layer_mgr0, display_border, background_color, border_x, border_y, y, (uint16_t)640); } - if ((mcr & 0x10) != 0 && (LayerMgr0 > 3 && LayerMgr0 < 7)) + if ((mcr & 0x10) != 0 && (layer_mgr0 > 3 && layer_mgr0 < 7)) { - draw_tiles(row, enable_gamma, LayerMgr0 & 3, display_border, border_x, y, (uint16_t)640); + draw_tiles(row, enable_gamma, layer_mgr0 & 3, display_border, border_x, y, (uint16_t)640); } if ((mcr & 0x20) != 0) { @@ -213,14 +214,14 @@ uint32_t tiny_vicky_video_device::screen_update(screen_device &screen, bitmap_rg void tiny_vicky_video_device::draw_text(uint32_t *row, uint8_t mcr, bool enable_gamma, uint8_t brd_x, uint8_t brd_y, uint16_t line, uint16_t x_res, uint16_t y_res) { bool overlay = (mcr & 0x2) != 0; - uint8_t mcrh = m_iopage0_ptr[0x1001] & 0x3F; + uint8_t mcrh = m_iopage0_ptr[0x1001] & 0x3f; bool double_x = (mcrh & 0x2) != 0; bool double_y = (mcrh & 0x4) != 0; bool use_font1 = (mcrh & 0x20) != 0; bool overlay_font = (mcrh & 0x10) != 0; - int txt_line = ((double_y ? line / 2 : line) - brd_y) / CHAR_HEIGHT; + int txt_line = ((double_y ? line / 2 : line) - brd_y) / MAME_F256_CHAR_HEIGHT; // Each character is defined by 8 bytes - int font_line = ((double_y ? line / 2 : line) - brd_y) % CHAR_HEIGHT; + int font_line = ((double_y ? line / 2 : line) - brd_y) % MAME_F256_CHAR_HEIGHT; int txt_cols = double_x ? 40 : 80; // do cursor stuff @@ -254,7 +255,7 @@ void tiny_vicky_video_device::draw_text(uint32_t *row, uint8_t mcr, bool enable_ // the loop should go to txt_cols - going to 80 causes a weird alias, but the machine works this way... so. for (int col = 0; col < 80; col++) { - int x = col * CHAR_WIDTH; + int x = col * MAME_F256_CHAR_WIDTH; if (x + brd_x > x_res - 1 - brd_x) { continue; @@ -276,8 +277,8 @@ void tiny_vicky_video_device::draw_text(uint32_t *row, uint8_t mcr, bool enable_ character = m_iopage0_ptr[0x1012]; } - uint8_t fg_color_index = (color & 0xF0) >> 4; - uint8_t bg_color_index = (color & 0x0F); + uint8_t fg_color_index = (color & 0xf0) >> 4; + uint8_t bg_color_index = (color & 0x0f); rgb_t fg_color = get_text_lut(fg_color_index, true, enable_gamma); rgb_t bg_color = get_text_lut(bg_color_index, false, enable_gamma); @@ -325,18 +326,18 @@ void tiny_vicky_video_device::device_reset() } void tiny_vicky_video_device::draw_bitmap(uint32_t *row, bool enable_gamma, uint8_t layer, bool bkgrnd, rgb_t bgndColor, uint8_t borderXSize, uint8_t borderYSize, uint16_t line, uint16_t width) { - uint8_t reg = m_iopage0_ptr[(0xD100 - 0xC000) + layer * 8]; + uint8_t reg = m_iopage0_ptr[(0xd100 - 0xc000) + layer * 8]; // check if the bitmap is enabled if ((reg & 0x01) == 0) { return; } uint8_t lut_index = (reg >> 1) & 7; // 8 possible LUTs - constexpr int base_offset = 0xD101 - 0xC000; + constexpr int base_offset = 0xd101 - 0xc000; int bitmapAddress = (m_iopage0_ptr[base_offset + layer * 8] + (m_iopage0_ptr[base_offset + 1 + layer * 8] << 8) + (m_iopage0_ptr[base_offset + 2 + layer * 8] << 16) - ) & 0x3F'FFFF; + ) & 0x3f'ffff; rgb_t color_val = 0; int offsetAddress = bitmapAddress + (line/2) * width/2; @@ -360,7 +361,7 @@ void tiny_vicky_video_device::draw_sprites(uint32_t *row, bool enable_gamma, uin // There are 64 possible sprites to choose from. for (int s = 63; s > -1; s--) { - int addr_sprite = 0xD900 - 0xC000 + s * 8; + int addr_sprite = 0xd900 - 0xc000 + s * 8; uint8_t reg = m_iopage0_ptr[addr_sprite]; // if the set is not enabled, we're done. uint8_t sprite_layer = (reg & 0x18) >> 3; @@ -387,12 +388,12 @@ void tiny_vicky_video_device::draw_sprites(uint32_t *row, bool enable_gamma, uin // TODO Fix this when Vicky II fixes the LUT issue uint8_t lut_index = ((reg & 6) >> 1); - //int lut_address = 0xD000 - 0xC000 + lut_index * 0x400; + //int lut_address = 0xd000 - 0xc000 + lut_index * 0x400; //bool striding = (reg & 0x80) == 0x80; int sprite_address = (m_iopage0_ptr[addr_sprite + 1] + (m_iopage0_ptr[addr_sprite + 2] << 8) + - (m_iopage0_ptr[addr_sprite + 3] << 16)) & 0x3F'FFFF; + (m_iopage0_ptr[addr_sprite + 3] << 16)) & 0x3f'ffff; int posX = m_iopage0_ptr[addr_sprite + 4] + (m_iopage0_ptr[addr_sprite + 5] << 8) - 32; posX *= 2; @@ -452,7 +453,7 @@ void tiny_vicky_video_device::draw_sprites(uint32_t *row, bool enable_gamma, uin void tiny_vicky_video_device::draw_tiles(uint32_t *row, bool enable_gamma, uint8_t layer, bool bkgrnd, uint8_t borderXSize, uint16_t line, uint16_t width) { // There are four possible tilemaps to choose from - int addr_tile_addr = 0xD200 - 0xC000 + layer * 12; + int addr_tile_addr = 0xd200 - 0xc000 + layer * 12; int reg = m_iopage0_ptr[addr_tile_addr]; // if the set is not enabled, we're done. if ((reg & 0x01) == 00) @@ -463,11 +464,11 @@ void tiny_vicky_video_device::draw_tiles(uint32_t *row, bool enable_gamma, uint8 int tileSize = (smallTiles ? 8 : 16); int strideLine = tileSize * 16; - uint8_t scrollMask = smallTiles ? 0xF : 0xF; // Tiny Vicky bug: this should be 0xE + uint8_t scrollMask = smallTiles ? 0xf : 0xf; // Tiny Vicky bug: this should be 0xe - int tilemapWidth = (m_iopage0_ptr[addr_tile_addr + 4] + (m_iopage0_ptr[addr_tile_addr + 5] << 8)) & 0x3FF; // 10 bits - //int tilemapHeight = VICKY.ReadWord(addrTileCtrlReg + 6) & 0x3FF; // 10 bits - int tilemapAddress = (m_iopage0_ptr[addr_tile_addr + 1] + (m_iopage0_ptr[addr_tile_addr + 2] << 8) + (m_iopage0_ptr[addr_tile_addr + 3] << 16)) & 0x3F'FFFF; + int tilemapWidth = (m_iopage0_ptr[addr_tile_addr + 4] + (m_iopage0_ptr[addr_tile_addr + 5] << 8)) & 0x3ff; // 10 bits + //int tilemapHeight = VICKY.ReadWord(addrTileCtrlReg + 6) & 0x3ff; // 10 bits + int tilemapAddress = (m_iopage0_ptr[addr_tile_addr + 1] + (m_iopage0_ptr[addr_tile_addr + 2] << 8) + (m_iopage0_ptr[addr_tile_addr + 3] << 16)) & 0x3f'ffff; // the tilemapWindowX is 10 bits and the scrollX is the lower 4 bits. The IDE combines them. int tilemapWindowX = m_iopage0_ptr[addr_tile_addr + 8] + (m_iopage0_ptr[addr_tile_addr + 9] << 8); @@ -477,13 +478,13 @@ void tiny_vicky_video_device::draw_tiles(uint32_t *row, bool enable_gamma, uint8 uint8_t scrollY = (tilemapWindowY & scrollMask) & scrollMask; if (smallTiles) { - tilemapWindowX = ((tilemapWindowX & 0x3FF0) >> 1) + scrollX + 8; - tilemapWindowY = ((tilemapWindowY & 0x3FF0) >> 1) + scrollY; + tilemapWindowX = ((tilemapWindowX & 0x3ff0) >> 1) + scrollX + 8; + tilemapWindowY = ((tilemapWindowY & 0x3ff0) >> 1) + scrollY; } else { - tilemapWindowX = (tilemapWindowX & 0x3FF0) + scrollX; - tilemapWindowY = (tilemapWindowY & 0x3FF0) + scrollY; + tilemapWindowX = (tilemapWindowX & 0x3ff0) + scrollX; + tilemapWindowY = (tilemapWindowY & 0x3ff0) + scrollY; } int tileXOffset = tilemapWindowX % tileSize; @@ -508,9 +509,9 @@ void tiny_vicky_video_device::draw_tiles(uint32_t *row, bool enable_gamma, uint8 int strides[8]; for (int i = 0; i < 8; i++) { - tilesetPointers[i] = (m_iopage0_ptr[0xD280 - 0xC000 + i * 4] + (m_iopage0_ptr[0xD280 - 0xC000 + i * 4 + 1] << 8) + - (m_iopage0_ptr[0xD280 - 0xC000 + i * 4 + 2] << 16)) & 0x3F'FFFF; - uint8_t tilesetConfig = m_iopage0_ptr[0xD280 - 0xC000 + i * 4 + 3]; + tilesetPointers[i] = (m_iopage0_ptr[0xd280 - 0xc000 + i * 4] + (m_iopage0_ptr[0xd280 - 0xc000 + i * 4 + 1] << 8) + + (m_iopage0_ptr[0xd280 - 0xc000 + i * 4 + 2] << 16)) & 0x3f'ffff; + uint8_t tilesetConfig = m_iopage0_ptr[0xd280 - 0xc000 + i * 4 + 3]; strides[i] = (tilesetConfig & 8) != 0 ? strideLine : tileSize; } for (int i = 0; i < tilemapItemCount; i++) @@ -570,17 +571,17 @@ void tiny_vicky_video_device::draw_tiles(uint32_t *row, bool enable_gamma, uint8 void tiny_vicky_video_device::draw_mouse(uint32_t *row, bool enable_gamma, uint16_t line, uint16_t width, uint16_t height) { - uint8_t mouse_reg = m_iopage0_ptr[0xD6E0 - 0xC000]; + uint8_t mouse_reg = m_iopage0_ptr[0xd6e0 - 0xc000]; bool MousePointerEnabled = (mouse_reg & 3) != 0; if (MousePointerEnabled) { - int PosX = m_iopage0_ptr[0xD6E0 - 0xC000 + 2] + (m_iopage0_ptr[0xD6E0 - 0xC000 + 3] << 8); - int PosY = m_iopage0_ptr[0xD6E0 - 0xC000 + 4] + (m_iopage0_ptr[0xD6E0 - 0xC000 + 5] << 8); + int PosX = m_iopage0_ptr[0xd6e0 - 0xc000 + 2] + (m_iopage0_ptr[0xd6e0 - 0xc000 + 3] << 8); + int PosY = m_iopage0_ptr[0xd6e0 - 0xc000 + 4] + (m_iopage0_ptr[0xd6e0 - 0xc000 + 5] << 8); if (line >= PosY && line < PosY + 16) { - int ptr_addr = 0xCC00 - 0xC000; + int ptr_addr = 0xcc00 - 0xc000; // Mouse pointer is a 16x16 icon int colsToDraw = PosX < width - 16 ? 16 : width - PosX; diff --git a/src/mame/f256/tiny_vicky.h b/src/mame/f256/tiny_vicky.h index bc21b82560cfc..ad4b25e657af4 100644 --- a/src/mame/f256/tiny_vicky.h +++ b/src/mame/f256/tiny_vicky.h @@ -3,8 +3,8 @@ #ifndef MAME_F256_TINY_VICKY_H #define MAME_F256_TINY_VICKY_H -#define CHAR_HEIGHT 8 -#define CHAR_WIDTH 8 +#define MAME_F256_CHAR_HEIGHT 8 +#define MAME_F256_CHAR_WIDTH 8 //#include @@ -12,8 +12,6 @@ class tiny_vicky_video_device : public device_t { public: tiny_vicky_video_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - tiny_vicky_video_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock = 0); - //tiny_vicky_video_device() = default; // screen update uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); @@ -47,6 +45,7 @@ class tiny_vicky_video_device : public device_t return m_sol_irq_handler.bind(); }; protected: + tiny_vicky_video_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); // device-level overrides virtual void device_start() override ATTR_COLD; virtual void device_reset() override ATTR_COLD;