From 029341aeb2b65ecc2c7463706f264d0b13e13e56 Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Sun, 23 Jun 2024 04:19:38 +1000 Subject: [PATCH] srcclean and manual cleanup. --- hash/gameking3.xml | 2 +- hash/sony_news.xml | 2 +- src/devices/cpu/f2mc16/f2mc16.cpp | 2 +- src/devices/cpu/m68000/m68000musashi.cpp | 0 src/devices/cpu/m68000/m68000musashi.h | 0 src/devices/cpu/pic16x8x/16x8xdsm.cpp | 516 ++-- src/devices/cpu/pic16x8x/16x8xdsm.h | 92 +- src/devices/cpu/pic16x8x/pic16x8x.cpp | 2831 +++++++++++----------- src/devices/cpu/pic16x8x/pic16x8x.h | 638 ++--- src/devices/cpu/z80/z80dasm.cpp | 4 +- src/devices/cpu/z80/z80dasm.h | 2 +- src/mame/alpha/equites.cpp | 4 +- src/mame/alpha/splendor.cpp | 6 +- src/mame/apple/macquadra630.cpp | 2 +- src/mame/aristocrat/caswin.cpp | 2 +- src/mame/benesse/challenge_gear.cpp | 2 +- src/mame/bmc/popobear.cpp | 2 +- src/mame/kaneko/expro02.cpp | 8 +- src/mame/misc/magicard.cpp | 8 +- src/mame/nec/pc8801.cpp | 2 +- src/mame/nokia/mikromikko2.cpp | 4 +- src/mame/sega/fd1094.cpp | 8 +- src/mame/sinclair/chloe.cpp | 4 +- src/mame/sinclair/specnext.cpp | 36 +- src/mame/tch/wheelfir.cpp | 29 +- src/mame/tecmo/bombjack.cpp | 16 +- src/mame/tecmo/gaiden.cpp | 16 +- 27 files changed, 2117 insertions(+), 2121 deletions(-) mode change 100755 => 100644 src/devices/cpu/m68000/m68000musashi.cpp mode change 100755 => 100644 src/devices/cpu/m68000/m68000musashi.h diff --git a/hash/gameking3.xml b/hash/gameking3.xml index caab194c60a..26f539655d8 100644 --- a/hash/gameking3.xml +++ b/hash/gameking3.xml @@ -122,5 +122,5 @@ see gameking.xml for information about cartridge types - + diff --git a/hash/sony_news.xml b/hash/sony_news.xml index 3e32ccf3817..eca2bb13846 100644 --- a/hash/sony_news.xml +++ b/hash/sony_news.xml @@ -12,7 +12,7 @@ license:CC0-1.0 The floppies can boot on both CISC and RISC systems due to some bootloader magic, but the MO image is only for the first wave of RISC NEWS machines (NWS-3000 series) diff --git a/src/devices/cpu/f2mc16/f2mc16.cpp b/src/devices/cpu/f2mc16/f2mc16.cpp index 07684dadab0..5f583b59272 100644 --- a/src/devices/cpu/f2mc16/f2mc16.cpp +++ b/src/devices/cpu/f2mc16/f2mc16.cpp @@ -1304,7 +1304,7 @@ void f2mc16_device::execute_run() m_pc = read_16(uVecAddr); m_pcb = read_8(uVecAddr + 2); bFoundVec = true; -// printf("RETI vector chain to %02x%04x\n", m_pcb, m_pc); + //printf("RETI vector chain to %02x%04x\n", m_pcb, m_pc); break; } } diff --git a/src/devices/cpu/m68000/m68000musashi.cpp b/src/devices/cpu/m68000/m68000musashi.cpp old mode 100755 new mode 100644 diff --git a/src/devices/cpu/m68000/m68000musashi.h b/src/devices/cpu/m68000/m68000musashi.h old mode 100755 new mode 100644 diff --git a/src/devices/cpu/pic16x8x/16x8xdsm.cpp b/src/devices/cpu/pic16x8x/16x8xdsm.cpp index 6f20d03eaf2..09c44a354fc 100644 --- a/src/devices/cpu/pic16x8x/16x8xdsm.cpp +++ b/src/devices/cpu/pic16x8x/16x8xdsm.cpp @@ -1,258 +1,258 @@ -// license:BSD-3-Clause -// copyright-holders: Grull Osgo -/************************************************************************ - - Microchip PIC16X8x Emulator - - Based on MAME's PIC16C5x cpu_device dissasm developed by Tony La Porta. - -A Address to jump to. -B Bit address within an 8-bit file register. -D Destination select (0 = store result in W (accumulator)) - (1 = store result in file register) -F Register file address. -K Literal field, constant data. - -Includes Flags ID's on SFR registers where possible. - -************************************************************************/ - -#include "emu.h" -#include "16x8xdsm.h" - -#include -#include - -const u8 pic16x8x_disassembler::sfr_bank0[16] = { 0, 0, 0, 1, 0, 2, 3, 0, 0, 0, 0, 4, 0, 0, 0, 0}; - -const char *const pic16x8x_disassembler::sfregs[12] = -{ - "INDF", "TMR0", "PCL", "STATUS", "FSR", "PORTA", "PORTB", "Reg$07", "EEDATA", "EEADDR", "PCLATH", "INTCON" -}; - -const char *const pic16x8x_disassembler::dest[2] = { "W", "Reg" }; - -const char *const pic16x8x_disassembler::reg_flags[9][8] = -{ - {"0", "1", "2", "3", "4", "5", "6", "7"}, // no flags - {"C", "DC", "Z", "PD", "TO", "RP0", "RP1", "IRP"}, // status - {"RA0", "RA1", "RA2", "RA3", "RA4/T0CKI", "5", "6", "7"}, // portA - {"RB0/INT", "RB1", "RB2", "RB3", "RB4", "RB5", "RB6", "RB7"}, // portB - {"RBIF", "INTF", "T0IF", "RBIE", "INTE", "T0IE", "EEIE", "GIE"}, // intcon - {"PS0", "PS1", "PS2", "PSA", "T0SE", "T0CS", "INTEDG", "RBPU"}, // option - {"RA0", "RA1", "RA2", "RA3", "RA4", "5", "6", "7"}, // trisa - {"RB0", "RB1", "RB2", "RB3", "RB4", "RB5", "RB6", "RB7"}, // trisb - {"RD", "WR", "WREN", "WRERR", "EEIF", "5", "6", "7"} // eecon -}; - -const char *const pic16x8x_disassembler::PIC16X8xFormats[] = -{ - "00000000000000", "nop", - "00000000001000", "return", - "00000000001001", "retfie", - "00000000100000", "nop", - "00000001000000", "nop", - "00000001100000", "nop", - "00000001100011", "sleep", - "00000001100100", "clrwdt", - "0000001fffffff", "movwf %F", - "00000100000000", "clrw", - "0000011fffffff", "clrf %F", - "000010dfffffff", "subwf %F,%D", - "000011dfffffff", "decf %F,%D", - "000100dfffffff", "iorwf %F,%D", - "000101dfffffff", "andwf %F,%D", - "000110dfffffff", "xorwf %F,%D", - "000111dfffffff", "addwf %F,%D", - "001000dfffffff", "movf %F,%D", - "001001dfffffff", "comf %F,%D", - "001010dfffffff", "incf %F,%D", - "001011dfffffff", "decfsz %F,%D", - "001100dfffffff", "rrf %F,%D", - "001101dfffffff", "rlf %F,%D", - "001110dfffffff", "swapf %F,%D", - "001111dfffffff", "incfsz %F,%D", - "0100bbbfffffff", "bcf %F,%B", - "0101bbbfffffff", "bsf %F,%B", - "0110bbbfffffff", "btfsc %F,%B", - "0111bbbfffffff", "btfss %F,%B", - "110100kkkkkkkk", "retlw %K", - "110101kkkkkkkk", "retlw %K", - "110110kkkkkkkk", "retlw %K", - "110111kkkkkkkk", "retlw %K", - "100aaaaaaaaaaa", "call %A", - "101aaaaaaaaaaa", "goto %A", - "110000kkkkkkkk", "movlw %K", - "110001kkkkkkkk", "movlw %K", - "110010kkkkkkkk", "movlw %K", - "110011kkkkkkkk", "movlw %K", - "111000kkkkkkkk", "iorlw %K", - "111001kkkkkkkk", "andlw %K", - "111010kkkkkkkk", "xorlw %K", - "111100kkkkkkkk", "sublw %K", - "111101kkkkkkkk", "sublw %K", - "111110kkkkkkkk", "addlw %K", - "111111kkkkkkkk", "addlw %K", - nullptr -}; - -pic16x8x_disassembler::pic16x8x_disassembler() -{ - const char *p; - const char *const *ops; - u16 mask, bits; - int bit; - - ops = PIC16X8xFormats; - while (*ops) - { - p = *ops; - mask = 0; bits = 0; bit = 13; - while (*p && bit >= 0) - { - switch (*p++) - { - case '1': mask |= 1<= 0) - { - osd_printf_debug("{%c/%d}",*cp,bit); - switch (*cp) - { - case 'a': a <<=1; a |= ((code & (1< +#include + +const u8 pic16x8x_disassembler::sfr_bank0[16] = { 0, 0, 0, 1, 0, 2, 3, 0, 0, 0, 0, 4, 0, 0, 0, 0}; + +const char *const pic16x8x_disassembler::sfregs[12] = +{ + "INDF", "TMR0", "PCL", "STATUS", "FSR", "PORTA", "PORTB", "Reg$07", "EEDATA", "EEADDR", "PCLATH", "INTCON" +}; + +const char *const pic16x8x_disassembler::dest[2] = { "W", "Reg" }; + +const char *const pic16x8x_disassembler::reg_flags[9][8] = +{ + {"0", "1", "2", "3", "4", "5", "6", "7"}, // no flags + {"C", "DC", "Z", "PD", "TO", "RP0", "RP1", "IRP"}, // status + {"RA0", "RA1", "RA2", "RA3", "RA4/T0CKI", "5", "6", "7"}, // portA + {"RB0/INT", "RB1", "RB2", "RB3", "RB4", "RB5", "RB6", "RB7"}, // portB + {"RBIF", "INTF", "T0IF", "RBIE", "INTE", "T0IE", "EEIE", "GIE"}, // intcon + {"PS0", "PS1", "PS2", "PSA", "T0SE", "T0CS", "INTEDG", "RBPU"}, // option + {"RA0", "RA1", "RA2", "RA3", "RA4", "5", "6", "7"}, // trisa + {"RB0", "RB1", "RB2", "RB3", "RB4", "RB5", "RB6", "RB7"}, // trisb + {"RD", "WR", "WREN", "WRERR", "EEIF", "5", "6", "7"} // eecon +}; + +const char *const pic16x8x_disassembler::PIC16X8xFormats[] = +{ + "00000000000000", "nop", + "00000000001000", "return", + "00000000001001", "retfie", + "00000000100000", "nop", + "00000001000000", "nop", + "00000001100000", "nop", + "00000001100011", "sleep", + "00000001100100", "clrwdt", + "0000001fffffff", "movwf %F", + "00000100000000", "clrw", + "0000011fffffff", "clrf %F", + "000010dfffffff", "subwf %F,%D", + "000011dfffffff", "decf %F,%D", + "000100dfffffff", "iorwf %F,%D", + "000101dfffffff", "andwf %F,%D", + "000110dfffffff", "xorwf %F,%D", + "000111dfffffff", "addwf %F,%D", + "001000dfffffff", "movf %F,%D", + "001001dfffffff", "comf %F,%D", + "001010dfffffff", "incf %F,%D", + "001011dfffffff", "decfsz %F,%D", + "001100dfffffff", "rrf %F,%D", + "001101dfffffff", "rlf %F,%D", + "001110dfffffff", "swapf %F,%D", + "001111dfffffff", "incfsz %F,%D", + "0100bbbfffffff", "bcf %F,%B", + "0101bbbfffffff", "bsf %F,%B", + "0110bbbfffffff", "btfsc %F,%B", + "0111bbbfffffff", "btfss %F,%B", + "110100kkkkkkkk", "retlw %K", + "110101kkkkkkkk", "retlw %K", + "110110kkkkkkkk", "retlw %K", + "110111kkkkkkkk", "retlw %K", + "100aaaaaaaaaaa", "call %A", + "101aaaaaaaaaaa", "goto %A", + "110000kkkkkkkk", "movlw %K", + "110001kkkkkkkk", "movlw %K", + "110010kkkkkkkk", "movlw %K", + "110011kkkkkkkk", "movlw %K", + "111000kkkkkkkk", "iorlw %K", + "111001kkkkkkkk", "andlw %K", + "111010kkkkkkkk", "xorlw %K", + "111100kkkkkkkk", "sublw %K", + "111101kkkkkkkk", "sublw %K", + "111110kkkkkkkk", "addlw %K", + "111111kkkkkkkk", "addlw %K", + nullptr +}; + +pic16x8x_disassembler::pic16x8x_disassembler() +{ + const char *p; + const char *const *ops; + u16 mask, bits; + int bit; + + ops = PIC16X8xFormats; + while (*ops) + { + p = *ops; + mask = 0; bits = 0; bit = 13; + while (*p && bit >= 0) + { + switch (*p++) + { + case '1': mask |= 1<= 0) + { + osd_printf_debug("{%c/%d}",*cp,bit); + switch (*cp) + { + case 'a': a <<=1; a |= ((code & (1< Op; -}; - -#endif +// license:BSD-3-Clause +// copyright-holders: Grull Osgo +/* + + Microchip PIC16X8x Emulator + + Based on MAME's PIC16C5x cpu_device dissasm developed by Tony La Porta. + + +*/ + +#ifndef MAME_CPU_PIC16X8X_16X8XDSM_H +#define MAME_CPU_PIC16X8X_16X8XDSM_H + +#pragma once + +class pic16x8x_disassembler : public util::disasm_interface +{ +public: + pic16x8x_disassembler(); + virtual ~pic16x8x_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + struct PIC16X8xOpcode { + u16 mask; // instruction mask + u16 bits; // constant bits + u16 extcode; // value that gets extension code + const char *parse; // how to parse bits + const char *fmt; // instruction format + + PIC16X8xOpcode(u16 m, u16 b, u16 e, const char *p, const char *f) : mask(m), bits(b), extcode(e), parse(p), fmt(f) {} + }; + + static const u8 sfr_bank0[16]; + static const char *const sfregs[12]; + static const char *const dest[2]; + static const char *const reg_flags[9][8]; + static const char *const PIC16X8xFormats[]; + + std::vector Op; +}; + +#endif diff --git a/src/devices/cpu/pic16x8x/pic16x8x.cpp b/src/devices/cpu/pic16x8x/pic16x8x.cpp index af62420bd30..e96be15b109 100644 --- a/src/devices/cpu/pic16x8x/pic16x8x.cpp +++ b/src/devices/cpu/pic16x8x/pic16x8x.cpp @@ -1,1418 +1,1413 @@ -// license:BSD-3-Clause -// copyright-holders:Grull Osgo -/**************************************************************************************** - - Microchip PIC16x8x Emulator - - https://ww1.microchip.com/downloads/en/DeviceDoc/30445D.pdf - - Based on MAME's PIC16C5x/62x cpu devices developed by Tony La Porta - and improvements to SFR's accesss made by ajrhacker. - - Preliminary version to give support to magicle and other games - on misc/magicard.cpp driver, providing some protection level via I2C bus. - - Coded and partially tested: - - All instruction set and disassembler. - - I/O Ports. - - WDT. - - Timer/Counter. - - All (4) interrupt sources. - - Input lines. - - Internal EEPROM with default and NVRAM functionality. - - ToDo: - - Verify if data ram addreess map mirroring is properly coded acording to datasheet description. - - - Choose wich is the best option to set the config word, if via set instruction or from dump data or some sort of combination via default options. - - - Improve the debug section. - - - Verify eeprom write sequence (see datashhet) - - Improvements: - - SFR's Flag description (bit oriented instructions) in disassembler where possible. - -****************************************************************************************/ - -#include "emu.h" -#include "pic16x8x.h" -#include "16x8xdsm.h" - -DEFINE_DEVICE_TYPE(PIC16CR83, pic16cr83_device, "pic16cr83", "Microchip PIC16CR83") -DEFINE_DEVICE_TYPE(PIC16CR84, pic16cr84_device, "pic16cr84", "Microchip PIC16CR84") -DEFINE_DEVICE_TYPE(PIC16F83, pic16f83_device, "pic16f83", "Microchip PIC16F83") -DEFINE_DEVICE_TYPE(PIC16F84, pic16f84_device, "pic16f84", "Microchip PIC16F84") -DEFINE_DEVICE_TYPE(PIC16F84A, pic16f84a_device, "pic16f84a", "Microchip PIC16F84A") - -/**************************************************************************** - * Internal Memory Maps - ****************************************************************************/ - -void pic16x8x_device::rom_9(address_map &map) -{ - map(0x000, 0x1ff).rom(); -} - -void pic16x8x_device::rom_10(address_map &map) -{ - map(0x000, 0x3ff).rom(); -} - - -/* Notes from datasheet: - The address depends on the device used. -Devices with 36 bytes ends at 2Fh, devices with -68 bytes ends at 4Fh.*/ - -void pic16x8x_device::core_regs(address_map &map, u8 mirror) -{ - map(0x00, 0x00).noprw().mirror(mirror); // Not an actual register, reading indirectly (FSR=0) returns 0 - map(0x01, 0x01).rw(FUNC(pic16x8x_device::tmr0_r), FUNC(pic16x8x_device::tmr0_w)); - map(0x02, 0x02).rw(FUNC(pic16x8x_device::pcl_r), FUNC(pic16x8x_device::pcl_w)).mirror(mirror); - map(0x03, 0x03).rw(FUNC(pic16x8x_device::status_r), FUNC(pic16x8x_device::status_w)).mirror(mirror); - map(0x04, 0x04).rw(FUNC(pic16x8x_device::fsr_r), FUNC(pic16x8x_device::fsr_w)).mirror(mirror); - map(0x05, 0x05).rw(FUNC(pic16x8x_device::porta_r), FUNC(pic16x8x_device::porta_w)); - map(0x06, 0x06).rw(FUNC(pic16x8x_device::portb_r), FUNC(pic16x8x_device::portb_w)); - map(0x07, 0x07).noprw().mirror(mirror); // Not an actual register, returns 0 - map(0x08, 0x08).rw(FUNC(pic16x8x_device::eedata_r), FUNC(pic16x8x_device::eedata_w)); - map(0x09, 0x09).rw(FUNC(pic16x8x_device::eeadr_r), FUNC(pic16x8x_device::eeadr_w)); - map(0x0a, 0x0a).rw(FUNC(pic16x8x_device::pclath_r), FUNC(pic16x8x_device::pclath_w)).mirror(mirror); - map(0x0b, 0x0b).rw(FUNC(pic16x8x_device::intcon_r), FUNC(pic16x8x_device::intcon_w)).mirror(mirror); - map(0x81, 0x81).rw(FUNC(pic16x8x_device::option_r), FUNC(pic16x8x_device::option_w)); - map(0x85, 0x85).rw(FUNC(pic16x8x_device::trisa_r), FUNC(pic16x8x_device::trisa_w)); - map(0x86, 0x86).rw(FUNC(pic16x8x_device::trisb_r), FUNC(pic16x8x_device::trisb_w)); - map(0x88, 0x88).rw(FUNC(pic16x8x_device::eecon1_r), FUNC(pic16x8x_device::eecon1_w)); - map(0x89, 0x89).rw(FUNC(pic16x8x_device::eecon2_r), FUNC(pic16x8x_device::eecon2_w)); -} - -void pic16x8x_device::ram_6(address_map &map) -{ - // 0x00 - 0x0b SFR's Bank 0 - // 0x0c - 0x2f GPR's - // 0x80 - 0x8b SFR's Bank 1 - // 0x8c - 0xaf GPR Mirrored to 0x0c - 0x2f - core_regs(map, 0x80); - map(0x0c, 0x2f).ram().mirror(0x80); -} - -void pic16x8x_device::ram_7(address_map &map) -{ - // 0x00 - 0x0b SFR's Bank 0 - // 0x0c - 0x4f GPR's - // 0x80 - 0x8b SFR's Bank 1 - // 0x8c - 0xcf GPR Mirrored to 0x0c - 0x4f - core_regs(map, 0x80); - map(0x0c, 0x4f).ram().mirror(0x80); -} - - -pic16x8x_device::pic16x8x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int program_width, address_map_constructor program_map, address_map_constructor data_map) - : cpu_device(mconfig, type, tag, owner, clock) - , device_nvram_interface(mconfig, *this) - , m_region(*this, DEVICE_SELF) - , m_program_config("program", ENDIANNESS_LITTLE, 16, program_width, -1, program_map) - , m_data_config("data", ENDIANNESS_LITTLE, 8, 8, 0, data_map) - , m_program_width(program_width) - , m_CONFIG(0x3fff) - , m_read_port(*this, 0) - , m_write_port(*this) -{ -} - -pic16x83_device::pic16x83_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) - : pic16x8x_device(mconfig, type, tag, owner, clock, 9, address_map_constructor(FUNC(pic16x8x_device::rom_9), this), address_map_constructor(FUNC(pic16x8x_device::ram_6), this)) -{ -} - -pic16x84_device::pic16x84_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) - : pic16x8x_device(mconfig, type, tag, owner, clock, 10, address_map_constructor(FUNC(pic16x8x_device::rom_10), this), address_map_constructor(FUNC(pic16x8x_device::ram_7), this)) -{ -} - -pic16cr83_device::pic16cr83_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : pic16x83_device(mconfig, PIC16CR83, tag, owner, clock) -{ -} - -pic16cr84_device::pic16cr84_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : pic16x84_device(mconfig, PIC16CR84, tag, owner, clock) -{ -} - -pic16f83_device::pic16f83_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : pic16x83_device(mconfig, PIC16F83, tag, owner, clock) -{ -} - -pic16f84_device::pic16f84_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : pic16x84_device(mconfig, PIC16F84, tag, owner, clock) -{ -} - -pic16f84a_device::pic16f84a_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : pic16x84_device(mconfig, PIC16F84A, tag, owner, clock) -{ -} - -device_memory_interface::space_config_vector pic16x8x_device::memory_space_config() const -{ - return space_config_vector - { - std::make_pair(AS_PROGRAM, &m_program_config), - std::make_pair(AS_DATA, &m_data_config) - }; -} - -std::unique_ptr pic16x8x_device::create_disassembler() -{ - return std::make_unique(); -} - - -/* Notes about NVRAM / PIC eeprom data - -Dump size is 4280 Bytes, 16 bits wide. -0000h-03ffh is program data -0400h-3fffh is dummy data -4000h-400fh is user and config data -4010h-41ffh is dummy data -4200h-4280h is eeprom data - -NVRAM saved data is 8 bits wide, in accordance with the data width -of the EEPROM memory of the PIC. -This means that we need to perform the conversion from the default -NVRAM dumped data to the NVRAM saved data. -*/ - -void pic16x8x_device::nvram_default() -{ - u16 dump_size = 0x4280; - u16 eeprom_dump = 0x4200; - - // populate from a memory region if present - if (m_region.found()) - { - if( m_region->bytes() != dump_size ) // pic memory dump total size - { - fatalerror( "Region '%s' wrong size (expected size = 0x%X)\n", tag(), dump_size ); - } - - if( m_region->bytewidth() != 2 ) // pic memory dumps are 16 bits wide - { - fatalerror( "Region '%s' needs to be an 16-bit region\n", tag() ); - } - - // Get default NVRAM data from memory region - memcpy(m_buff, m_region->base() + eeprom_dump, m_internal_eeprom_size * 2); - - // Data width conversion - for (u8 i=0; i < m_internal_eeprom_size; i++) - m_eeprom_data[i] = m_buff[i] & 0x00ff; - } - -} - -bool pic16x8x_device::nvram_read(util::read_stream &file) -{ - auto const [err, actual] = read(file, m_eeprom_data, m_internal_eeprom_size); - return !err && (actual == m_internal_eeprom_size); -} - -bool pic16x8x_device::nvram_write(util::write_stream &file) -{ - auto const [err, actual] = write(file, m_eeprom_data, m_internal_eeprom_size); - return !err && (actual == m_internal_eeprom_size); -} - - -// EEPROM data access -u8 pic16x8x_device::m_eeread(offs_t offs) -{ - return m_eeprom_data[offs]; -} - -void pic16x8x_device::m_eewrite(offs_t offs, u8 data) -{ - m_eeprom_data[offs] = data & m_data_mask; -} - - -// ******** The following is the STATUS flag register definition. ******** -// | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | -// | IRP | RP1 | RP0 | T0| PD| Z | DC | C | - -// IRP Register Bank Select - Unimplemented on this device -constexpr u8 RP1_FLAG = 0x40; // Register Bank Select Bit 1 -constexpr u8 RP0_FLAG = 0x20; // Register Bank Select Bit 0 - // 00 = Bank 0 (00h-7fh) - // 01 = Bank 1 (80h-ffh) - // 10 = Bank 2 (100h-17fh) - // 11 = Bank 3 (180h-1ffh) - // Each bank is 128 bytes. Only bit RP0 is used by the PIC16F8X. RP1 should be mantained clear. -constexpr u8 TO_FLAG = 0x10; // TO Time Out flag (WatchDog) -constexpr u8 PD_FLAG = 0x08; // PD Power Down flag -constexpr u8 Z_FLAG = 0x04; // Z Zero Flag -constexpr u8 DC_FLAG = 0x02; // DC Digit Carry/Borrow flag (Nibble) -constexpr u8 C_FLAG = 0x01; // C Carry/Borrow Flag (Byte) - -#define RP0 (m_STATUS & RP0_FLAG) -#define TO (m_STATUS & TO_FLAG) -#define PD (m_STATUS & PD_FLAG) -#define ZERO (m_STATUS & Z_FLAG) -#define DC (m_STATUS & DC_FLAG) -#define CARRY (m_STATUS & C_FLAG) - - -// ******** The following is the OPTION flag register definition. ******** -// | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | -// | RBPU | INTEDG | T0CS | T0SE | PSA | PS2 | PS1 | PS0 | -constexpr u8 RBPU_FLAG = 0x80; // RBPU PORTB Pull-up Enable bit -constexpr u8 INTEDG_FLAG = 0x40; // INTEDG Interrupt Edge Select bit - // 1 = Interrupt on rising edge of RB0/INT pin - // 0 = Interrupt on falling edge of RB0/INT pin -constexpr u8 T0CS_FLAG = 0x20; // T0CS Timer 0 clock source select - // 1 = Transition on RA4/T0CKI pin - // 0 = Internal instruction cycle clock (CLKOUT) -constexpr u8 T0SE_FLAG = 0x10; // T0SE Timer 0 clock source edge select - // 1 = Increment on high-to-low transition on RA4/T0CKI pin - // 0 = Increment on low-to-high transition on RA4/T0CKI pin -constexpr u8 PSA_FLAG = 0x08; // PSA Prescaler Assignment bit - // 1 = Prescaler is assigned to the WDT - // 0 = Prescaler is assigned to the Timer0 module -constexpr u8 PS_REG = 0x07; // PS Prescaler Rate select - -#define RBPU (m_OPTION & RBPU_FLAG) -#define INTEDG (m_OPTION & INTEDG_FLAG) -#define T0CS (m_OPTION & T0CS_FLAG) -#define T0SE (m_OPTION & T0SE_FLAG) -#define PSA (m_OPTION & PSA_FLAG) -#define PS (m_OPTION & PS_REG) - - -// ******** The following is the CONFIG Flag register definition. ******** -// | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | -// | CP | WDTE | FOSC | - // CP Code Protect (ROM read protect) -constexpr u8 WDTE_FLAG = 0x04; // WDTE WatchDog Timer enable -constexpr u8 FOSC_FLAG = 0x03; // FOSC Oscillator source select - -#define WDTE (m_CONFIG & WDTE_FLAG) -#define FOSC (m_CONFIG & FOSC_FLAG) - - -// ******** The following is the INTCON flag register definition. ******** -// | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | -// | GIE | EEIE | T0IE | INTE | RBIE | T0IF | INTF | RBIF | - -constexpr u8 GIE_FLAG = 0x80; -constexpr u8 EEIE_FLAG = 0x40; -constexpr u8 T0IE_FLAG = 0x20; -constexpr u8 INTE_FLAG = 0x10; -constexpr u8 RBIE_FLAG = 0x08; -constexpr u8 T0IF_FLAG = 0x04; -constexpr u8 INTF_FLAG = 0x02; -constexpr u8 RBIF_FLAG = 0x01; - -#define GIE (m_INTCON & GIE_FLAG) -#define EEIE (m_INTCON & EEIE_FLAG) -#define T0IE (m_INTCON & T0IE_FLAG) -#define INTE (m_INTCON & INTE_FLAG) -#define RBIE (m_INTCON & RBIE_FLAG) -#define T0IF (m_INTCON & T0IF_FLAG) -#define INTF (m_INTCON & INTF_FLAG) -#define RBIF (m_INTCON & RBIF_FLAG) - -// ******** The following is the EECON1 Flag register definition. ******** -// | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | -// | | | | EEIF | WRERR | WREN | WR | RD | - -constexpr u8 EEIF_FLAG = 0x10; -constexpr u8 WRERR_FLAG = 0x08; -constexpr u8 WREN_FLAG = 0x04; -constexpr u8 EEWR_FLAG = 0x02; -constexpr u8 EERD_FLAG = 0x01; - -#define EEIF (m_EECON1 & EEIF_FLAG) -#define WRERR (m_EECON1 & WRERR_FLAG) -#define WREN (m_EECON1 & WREN_FLAG) -#define EEWR (m_EECON1 & EEWR_FLAG) -#define EERD (m_EECON1 & EERD_FLAG) - -/************************************************************************ - * Fixed Vectors - ************************************************************************/ - -constexpr u8 RESET_VECTOR = 0x00; -constexpr u8 INT_VECTOR = 0x04; - -/************************************************************************ - * Shortcuts - ************************************************************************/ - -#define RISING_EDGE_RB0 (( (int)(RB0_in - m_old_RB0) > 0) ? 1 : 0) -#define FALLING_EDGE_RB0 (( (int)(RB0_in - m_old_RB0) < 0) ? 1 : 0) - -#define M_RDEEPROM(A) m_eeread(A) -#define M_WREEPROM(A,V) m_eewrite(A, V) - -#define CLR(flagreg, flag) (flagreg &= u8(~flag)) -#define SET(flagreg, flag) (flagreg |= (flag)) - -#define ADDR ((m_opcode.b.l & 0x7f) | (RP0 << 2)) -#define BITPOS ((m_opcode.w >> 7) & 7) - - -void pic16x8x_device::calc_zero_flag() -{ - if (m_ALU == 0) - SET(m_STATUS, Z_FLAG); - else - CLR(m_STATUS, Z_FLAG); -} - -void pic16x8x_device::calc_add_flags(u8 augend) -{ - calc_zero_flag(); - - if (augend > m_ALU) - SET(m_STATUS, C_FLAG); - else - CLR(m_STATUS, C_FLAG); - - if ((augend & 0x0f) > (m_ALU & 0x0f)) - SET(m_STATUS, DC_FLAG); - else - CLR(m_STATUS, DC_FLAG); -} - -void pic16x8x_device::calc_sub_flags(u8 minuend) -{ - calc_zero_flag(); - - if (minuend < m_ALU) - CLR(m_STATUS, C_FLAG); - else - SET(m_STATUS, C_FLAG); - - if ((minuend & 0x0f) < (m_ALU & 0x0f)) - CLR(m_STATUS, DC_FLAG); - else - SET(m_STATUS, DC_FLAG); -} - -void pic16x8x_device::set_pc(u16 addr) -{ - m_PCL = addr & m_program_mask; -} - -/* -Notes about Stack (from datasheet) -After the stack has been PUSHed eight times, the ninth -push overwrites the value that was stored from the first -push. The tenth push overwrites the second push (and -so on) -*/ - -u16 pic16x8x_device::pop_stack() -{ - m_stack_pointer = (m_stack_pointer - 1) & 0x0f; - u16 data = m_STACK[m_stack_pointer]; - return data & m_program_mask; -} - -void pic16x8x_device::push_stack(u16 data) -{ - m_STACK[m_stack_pointer] = data & m_program_mask; - m_stack_pointer = (m_stack_pointer + 1) & 0x0f; -} - -void pic16x8x_device::store_result(u8 addr, u8 data) -{ - if (m_opcode.b.l & 0x80) - store_regfile(addr, data); - else - m_W = data; - -} - -// *** Special function registers (SFR's) *** - -// *** SFR Access *** -u8 pic16x8x_device::get_regfile(u8 addr) -{ - if (addr == 0) - { // Indirect addressing - addr = m_FSR & m_data_mask; - } - return m_data.read_byte(addr); -} - -void pic16x8x_device::store_regfile(u8 addr, u8 data) -{ - if (addr == 0) - { // Indirect addressing - addr = m_FSR & m_data_mask; - } - m_data.write_byte(addr, data); -} - -// *** SFR Functions *** -u8 pic16x8x_device::tmr0_r() -{ - return m_TMR0; -} - -void pic16x8x_device::tmr0_w(u8 data) -{ - m_delay_timer = 2; // Timer increment is inhibited for 2 cycles - if (PSA == 0) m_prescaler = 0; // Must clear the Prescaler - m_TMR0 = data; -} - -u8 pic16x8x_device::pcl_r() -{ - return m_PCL; -} - -void pic16x8x_device::pcl_w(u8 data) -{ - m_PCL = data; - set_pc((m_PCLATH << 8) | data); - m_inst_cycles++; -} - -u8 pic16x8x_device::status_r() -{ - return m_STATUS; -} - -void pic16x8x_device::status_w(u8 data) -{ - m_STATUS = (m_STATUS & (TO_FLAG | PD_FLAG)) | (data & u8(~(TO_FLAG | PD_FLAG))); -} - -u8 pic16x8x_device::fsr_r() -{ - return m_FSR | (uint8_t)(~m_data_mask); -} - -void pic16x8x_device::fsr_w(u8 data) -{ - m_FSR = data | u8(~m_data_mask); -} - -u8 pic16x8x_device::porta_r() -{ - u8 data = m_read_port[PORTA](PORTA, 0xff); - data &= m_port_tris[PORTA]; - data |= (u8(~m_port_tris[PORTA]) & m_port_data[PORTA]); - return data & 0x1f; // 5-bit port (only lower 5 bits used) -} - -void pic16x8x_device::porta_w(u8 data) -{ - data &= 0x1f; // 5-bit port (only lower 5 bits used) - m_write_port[PORTA](PORTA, data & u8(~m_port_tris[PORTA]) & 0x1f, u8(~m_port_tris[PORTA]) & 0x1f); - m_port_data[PORTA] = data; -} - -u8 pic16x8x_device::portb_r() -{ - u8 data = m_read_port[PORTB](PORTB, 0xff); - data &= m_port_tris[PORTB]; - data |= (u8(~m_port_tris[PORTB]) & m_port_data[PORTB]); - return data; -} - -void pic16x8x_device::portb_w(u8 data) -{ - m_write_port[PORTB](PORTB, data & u8(~m_port_tris[PORTB]), u8(~m_port_tris[PORTB])); - m_port_data[PORTB] = data; -} - -u8 pic16x8x_device::eedata_r() -{ - return m_EEDATA; -} - -void pic16x8x_device::eedata_w(u8 data) -{ - m_EEDATA = data; -} - -u8 pic16x8x_device::eeadr_r() -{ - return m_EEADR; -} - -void pic16x8x_device::eeadr_w(u8 data) -{ - m_EEADR = data; -} - -u8 pic16x8x_device::pclath_r() -{ - return m_PCLATH; -} - -void pic16x8x_device::pclath_w(u8 data) -{ - m_PCLATH = data; -} - -u8 pic16x8x_device::intcon_r() -{ - return m_INTCON; -} - -void pic16x8x_device::intcon_w(u8 data) -{ - m_INTCON = data; -} - -u8 pic16x8x_device::trisa_r() -{ - return m_port_tris[PORTA]; -} - -void pic16x8x_device::trisa_w(u8 data) -{ - if (m_port_tris[PORTA] != data) - { - m_port_tris[PORTA] = data | 0xe0; - m_write_port[PORTA](PORTA, m_port_data[PORTA] & u8(~m_port_tris[PORTA]) & 0x1f, u8(~m_port_tris[PORTA]) & 0x1f); - } -} - -u8 pic16x8x_device::trisb_r() -{ - return m_port_tris[PORTB]; -} - -void pic16x8x_device::trisb_w(u8 data) -{ - if (m_port_tris[PORTB] != data) - { - m_port_tris[PORTB] = data; - m_write_port[PORTB](PORTB, m_port_data[PORTB] & u8(~m_port_tris[PORTB]), u8(~m_port_tris[PORTB])); - } -} - -u8 pic16x8x_device::eecon1_r() -{ - return m_EECON1; -} - -void pic16x8x_device::eecon1_w(u8 data) -{ - if (!((data & WREN_FLAG) && EEWR)) // The WR bit will be inhibited from being set unless the WREN bit is set.(from datasheet) - CLR(data, EEWR); // Clear the flag if it don't meet the requirements - - m_EECON1 = data; // update register - - if (EERD) // cheack flag condition to read eeprom - { - m_EEDATA = M_RDEEPROM(m_EEADR); // do eeprom read - CLR(m_EECON1, EERD_FLAG); // clear read enable flag - } - - if (WREN && EEWR && (m_EECON2 == 0xff)) // check flags conditions to write eeprom - { - M_WREEPROM(m_EEADR, data); // do eeprom write - CLR(m_EECON1, EEWR_FLAG); // clear write enable flag - SET(m_EECON1, EEIF_FLAG); // assuming write was done, set EEIF - } -} - -u8 pic16x8x_device::eecon2_r() -{ - return m_EECON2; -} - -void pic16x8x_device::eecon2_w(u8 data) -{ - if((m_EECON2!=0x55) & (data==0x55)) - m_EECON2 = data; - else if((m_EECON2==0x55) & (data==0xAA)) - m_EECON2 = 0xff; - else - m_EECON2 = data; -} - -u8 pic16x8x_device::option_r() -{ - return m_OPTION; -} - -void pic16x8x_device::option_w(u8 data) -{ - m_OPTION = data; -} - -/************************************************************************ - * Emulate the Instructions - ************************************************************************/ - -void pic16x8x_device::illegal() -{ - logerror("PIC16x8x: PC=%03x, Illegal opcode = %04x\n", m_PREVPC, m_opcode.w); -} - -/* - Note: - According to the manual, if the STATUS register is the destination for an instruction that affects the Z, DC or C bits - then the write to these three bits is disabled. These bits are set or cleared according to the device logic. - To ensure this is correctly emulated, in instructions that write to the file registers, always change the status flags - *after* storing the result of the instruction. - e.g. CALCULATE_*, SET(STATUS,*_FLAG) and CLR(STATUS,*_FLAG) should appear as the last steps of the instruction emulation. -*/ - -void pic16x8x_device::addlw() -{ - // New - m_ALU = m_opcode.b.l + m_W; - m_W = m_ALU; - calc_zero_flag(); -} - -void pic16x8x_device::addwf() -{ - u8 augend = get_regfile(ADDR); - m_ALU = augend + m_W; - store_result(ADDR, m_ALU); - calc_add_flags(augend); -} - -void pic16x8x_device::andlw() -{ - m_ALU = m_opcode.b.l & m_W; - m_W = m_ALU; - calc_zero_flag(); -} - -void pic16x8x_device::andwf() -{ - m_ALU = get_regfile(ADDR) & m_W; - store_result(ADDR, m_ALU); - calc_zero_flag(); -} - -void pic16x8x_device::bcf() -{ - m_ALU = get_regfile(ADDR); - m_ALU &= ~(1 << BITPOS); - store_regfile(ADDR, m_ALU); -} - -void pic16x8x_device::bsf() -{ - m_ALU = get_regfile(ADDR); - m_ALU |= 1 << BITPOS; - store_regfile(ADDR, m_ALU); -} - -void pic16x8x_device::btfss() -{ - if (BIT(get_regfile(ADDR), BITPOS)) - { - set_pc(m_PCL + 1); - m_inst_cycles++; // Add NOP cycles - } -} - -void pic16x8x_device::btfsc() -{ - if (!BIT(get_regfile(ADDR), BITPOS)) - { - set_pc(m_PCL + 1); - m_inst_cycles++; // Add NOP cycles - } -} - -void pic16x8x_device::call() -{ - push_stack(m_PCL); - set_pc(((m_PCLATH & 0x18) << 8 ) | (m_opcode.w & 0x07ff)); -} - - -void pic16x8x_device::clrw() -{ - m_W = 0; - SET(m_STATUS, Z_FLAG); -} - -void pic16x8x_device::clrf() -{ - store_regfile(ADDR, 0); - SET(m_STATUS, Z_FLAG); -} - -void pic16x8x_device::clrwdt() -{ - m_WDT = 0; - if (PSA) m_prescaler = 0; - SET(m_STATUS, TO_FLAG); - SET(m_STATUS, PD_FLAG); -} - -void pic16x8x_device::comf() -{ - m_ALU = u8(~(get_regfile(ADDR))); - store_result(ADDR, m_ALU); - calc_zero_flag(); -} - -void pic16x8x_device::decf() -{ - m_ALU = get_regfile(ADDR) - 1; - store_result(ADDR, m_ALU); - calc_zero_flag(); -} - -void pic16x8x_device::decfsz() -{ - m_ALU = get_regfile(ADDR) - 1; - store_result(ADDR, m_ALU); - if (m_ALU == 0) - { - set_pc(m_PCL + 1); - m_inst_cycles++; // Add NOP cycles - } -} - -void pic16x8x_device::goto_op() -{ - set_pc(((m_PCLATH & 0x18) << 8 ) | (m_opcode.w & 0x07ff)); -} - -void pic16x8x_device::incf() -{ - m_ALU = get_regfile(ADDR) + 1; - store_result(ADDR, m_ALU); - calc_zero_flag(); -} - -void pic16x8x_device::incfsz() -{ - m_ALU = get_regfile(ADDR) + 1; - store_result(ADDR, m_ALU); - if (m_ALU == 0) - { - set_pc(m_PCL + 1); - m_inst_cycles++; // Add NOP cycles - } -} - -void pic16x8x_device::iorlw() -{ - m_ALU = m_opcode.b.l | m_W; - m_W = m_ALU; - calc_zero_flag(); -} - -void pic16x8x_device::iorwf() -{ - m_ALU = get_regfile(ADDR) | m_W; - store_result(ADDR, m_ALU); - calc_zero_flag(); -} - -void pic16x8x_device::movf() -{ - m_ALU = get_regfile(ADDR); - store_result(ADDR, m_ALU); - calc_zero_flag(); -} - -void pic16x8x_device::movlw() -{ - m_W = m_opcode.b.l; -} - -void pic16x8x_device::movwf() -{ - store_regfile(ADDR, m_W); -} - -void pic16x8x_device::nop() -{ - // Do nothing -} - -void pic16x8x_device::retfie() // new for 16x8x -{ - // New - set_pc(pop_stack()); - m_irq_in_progress = false; -} - -void pic16x8x_device::retlw() -{ - m_W = m_opcode.b.l; - set_pc(pop_stack()); -} - -void pic16x8x_device::retrn() // new for 16x8x -{ - set_pc(pop_stack()); -} - -void pic16x8x_device::rlf() -{ - m_ALU = get_regfile(ADDR); - int carry = BIT(m_ALU, 7); - m_ALU <<= 1; - if (m_STATUS & C_FLAG) m_ALU |= 1; - store_result(ADDR, m_ALU); - - if (carry) - SET(m_STATUS, C_FLAG); - else - CLR(m_STATUS, C_FLAG); -} - -void pic16x8x_device::rrf() -{ - m_ALU = get_regfile(ADDR); - int carry = BIT(m_ALU, 0); - m_ALU >>= 1; - if (m_STATUS & C_FLAG) m_ALU |= 0x80; - store_result(ADDR, m_ALU); - - if (carry) - SET(m_STATUS, C_FLAG); - else - CLR(m_STATUS, C_FLAG); -} - -void pic16x8x_device::sleepic() -{ - if (WDTE) m_WDT = 0; - if (PSA) m_prescaler = 0; - SET(m_STATUS, TO_FLAG); - CLR(m_STATUS, PD_FLAG); -} - -void pic16x8x_device::sublw() // new for 16x8x : Substract W from literal -{ - // New - u8 minuend = m_opcode.b.l; - m_ALU = minuend - m_W; - m_W = m_ALU; - calc_sub_flags(minuend); -} - -void pic16x8x_device::subwf() // Substract W from f -{ - u8 minuend = get_regfile(ADDR); - m_ALU = minuend - m_W; - store_result(ADDR, m_ALU); - calc_sub_flags(minuend); -} - -void pic16x8x_device::swapf() -{ - u8 reg = get_regfile(ADDR); - m_ALU = reg << 4 | reg >> 4; - store_result(ADDR, m_ALU); -} - -void pic16x8x_device::xorlw() -{ - m_ALU = m_W ^ m_opcode.b.l; - m_W = m_ALU; - calc_zero_flag(); -} - -void pic16x8x_device::xorwf() -{ - m_ALU = get_regfile(ADDR) ^ m_W; - store_result(ADDR, m_ALU); - calc_zero_flag(); -} - - -/*********************************************************************** - * Opcode Table (Cycles, Instruction) - ***********************************************************************/ - -const pic16x8x_device::pic16x8x_opcode pic16x8x_device::s_opcode_main[128]= -{ - {1, &pic16x8x_device::nop },{1, &pic16x8x_device::movwf },{1, &pic16x8x_device::clrw },{1, &pic16x8x_device::clrf }, // 00 - {1, &pic16x8x_device::subwf },{1, &pic16x8x_device::subwf },{1, &pic16x8x_device::decf },{1, &pic16x8x_device::decf }, // 04 - {1, &pic16x8x_device::iorwf },{1, &pic16x8x_device::iorwf },{1, &pic16x8x_device::andwf },{1, &pic16x8x_device::andwf }, // 08 - {1, &pic16x8x_device::xorwf },{1, &pic16x8x_device::xorwf },{1, &pic16x8x_device::addwf },{1, &pic16x8x_device::addwf }, // 0C - {1, &pic16x8x_device::movf },{1, &pic16x8x_device::movf },{1, &pic16x8x_device::comf },{1, &pic16x8x_device::comf }, // 10 - {1, &pic16x8x_device::incf },{1, &pic16x8x_device::incf },{1, &pic16x8x_device::decfsz },{1, &pic16x8x_device::decfsz }, // 14 - {1, &pic16x8x_device::rrf },{1, &pic16x8x_device::rrf },{1, &pic16x8x_device::rlf },{1, &pic16x8x_device::rlf }, // 18 - {1, &pic16x8x_device::swapf },{1, &pic16x8x_device::swapf },{1, &pic16x8x_device::incfsz },{1, &pic16x8x_device::incfsz }, // 1C - {1, &pic16x8x_device::bcf },{1, &pic16x8x_device::bcf },{1, &pic16x8x_device::bcf },{1, &pic16x8x_device::bcf }, // 20 - {1, &pic16x8x_device::bcf },{1, &pic16x8x_device::bcf },{1, &pic16x8x_device::bcf },{1, &pic16x8x_device::bcf }, - {1, &pic16x8x_device::bsf },{1, &pic16x8x_device::bsf },{1, &pic16x8x_device::bsf },{1, &pic16x8x_device::bsf }, // 28 - {1, &pic16x8x_device::bsf },{1, &pic16x8x_device::bsf },{1, &pic16x8x_device::bsf },{1, &pic16x8x_device::bsf }, - {1, &pic16x8x_device::btfsc },{1, &pic16x8x_device::btfsc },{1, &pic16x8x_device::btfsc },{1, &pic16x8x_device::btfsc }, // 30 - {1, &pic16x8x_device::btfsc },{1, &pic16x8x_device::btfsc },{1, &pic16x8x_device::btfsc },{1, &pic16x8x_device::btfsc }, - {1, &pic16x8x_device::btfss },{1, &pic16x8x_device::btfss },{1, &pic16x8x_device::btfss },{1, &pic16x8x_device::btfss }, // 38 - {1, &pic16x8x_device::btfss },{1, &pic16x8x_device::btfss },{1, &pic16x8x_device::btfss },{1, &pic16x8x_device::btfss }, - {2, &pic16x8x_device::call },{2, &pic16x8x_device::call },{2, &pic16x8x_device::call },{2, &pic16x8x_device::call }, // 40 - {2, &pic16x8x_device::call },{2, &pic16x8x_device::call },{2, &pic16x8x_device::call },{2, &pic16x8x_device::call }, - {2, &pic16x8x_device::call },{2, &pic16x8x_device::call },{2, &pic16x8x_device::call },{2, &pic16x8x_device::call }, // 48 - {2, &pic16x8x_device::call },{2, &pic16x8x_device::call },{2, &pic16x8x_device::call },{2, &pic16x8x_device::call }, - {2, &pic16x8x_device::goto_op },{2, &pic16x8x_device::goto_op },{2, &pic16x8x_device::goto_op },{2, &pic16x8x_device::goto_op }, // 50 - {2, &pic16x8x_device::goto_op },{2, &pic16x8x_device::goto_op },{2, &pic16x8x_device::goto_op },{2, &pic16x8x_device::goto_op }, - {2, &pic16x8x_device::goto_op },{2, &pic16x8x_device::goto_op },{2, &pic16x8x_device::goto_op },{2, &pic16x8x_device::goto_op }, // 58 - {2, &pic16x8x_device::goto_op },{2, &pic16x8x_device::goto_op },{2, &pic16x8x_device::goto_op },{2, &pic16x8x_device::goto_op }, - {1, &pic16x8x_device::movlw },{1, &pic16x8x_device::movlw },{1, &pic16x8x_device::movlw },{1, &pic16x8x_device::movlw }, // 60 - {1, &pic16x8x_device::movlw },{1, &pic16x8x_device::movlw },{1, &pic16x8x_device::movlw },{1, &pic16x8x_device::movlw }, - {2, &pic16x8x_device::retlw },{2, &pic16x8x_device::retlw },{2, &pic16x8x_device::retlw },{2, &pic16x8x_device::retlw }, // 68 - {2, &pic16x8x_device::retlw },{2, &pic16x8x_device::retlw },{2, &pic16x8x_device::retlw },{2, &pic16x8x_device::retlw }, - {1, &pic16x8x_device::iorlw },{1, &pic16x8x_device::iorlw },{1, &pic16x8x_device::andlw },{1, &pic16x8x_device::andlw }, // 70 - {1, &pic16x8x_device::xorlw },{1, &pic16x8x_device::xorlw },{1, &pic16x8x_device::xorlw },{1, &pic16x8x_device::xorlw }, // 74 - {1, &pic16x8x_device::sublw },{1, &pic16x8x_device::sublw },{1, &pic16x8x_device::sublw },{1, &pic16x8x_device::sublw }, // 78 - {1, &pic16x8x_device::addlw },{1, &pic16x8x_device::addlw },{1, &pic16x8x_device::addlw },{1, &pic16x8x_device::addlw } // 7C -}; - -const pic16x8x_device::pic16x8x_opcode pic16x8x_device::s_opcode_00x[128]= -{ - {1, &pic16x8x_device::nop },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, // 00 - {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, - {2, &pic16x8x_device::retrn },{2, &pic16x8x_device::retfie },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, // 08 - {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, - {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, // 10 - {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, - {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, // 18 - {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, - {1, &pic16x8x_device::nop },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, // 20 - {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, - {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, // 28 - {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, - {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, // 30 - {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, - {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, // 38 - {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, - {1, &pic16x8x_device::nop },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, // 40 - {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, - {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, // 48 - {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, - {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, // 50 - {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, - {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, // 58 - {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, - {1, &pic16x8x_device::nop },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::sleepic }, // 60 - {1, &pic16x8x_device::clrwdt },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, - {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, // 68 - {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, - {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, // 70 - {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, - {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, // 78 - {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal } -}; - - -/**************************************************************************** - * Inits CPU emulation - ****************************************************************************/ - -enum -{ - PIC16X8x_PC=1, PIC16X8x_W, PIC16X8x_ALU, PIC16X8x_WDT, PIC16X8x_PSCL, PIC16X8x_CONFIG -}; - -void pic16x8x_device::device_start() -{ - space(AS_PROGRAM).cache(m_program); - space(AS_DATA).specific(m_data); - - m_program_mask = (1 << m_program_width) - 1; - m_data_mask = 0xff; - m_status_mask = 0xff; - m_PCL = 0; - m_PREVPC = 0; - m_W = 0; - m_OPTION = 0; - m_ALU = 0; - m_WDT = 0; - m_TMR0 = 0; - m_STATUS = ~m_status_mask; - m_FSR = 0; - std::fill(std::begin(m_port_data), std::end(m_port_data), 0); - std::fill(std::begin(m_port_tris), std::end(m_port_tris), 0); - std::fill(std::begin(m_STACK), std::end(m_STACK), 0); - m_prescaler = 0; - m_opcode.w = 0; - m_delay_timer = 0; - m_rtcc = 0; - m_count_cycles = 0; - m_inst_cycles = 0; - m_stack_pointer = 0; - m_debugger_temp = 0; - m_portb_chdetect_temp = 0xff; - m_irq_in_progress = false; - - // save states - save_item(NAME(m_PCL)); - save_item(NAME(m_PREVPC)); - save_item(NAME(m_CONFIG)); - save_item(NAME(m_W)); - save_item(NAME(m_OPTION)); - save_item(NAME(m_ALU)); - save_item(NAME(m_WDT)); - save_item(NAME(m_TMR0)); - save_item(NAME(m_STATUS)); - save_item(NAME(m_FSR)); - save_item(NAME(m_port_data)); - save_item(NAME(m_port_tris)); - save_item(NAME(m_EEDATA)); - save_item(NAME(m_EEADR)); - save_item(NAME(m_EECON1)); - save_item(NAME(m_EECON2)); - save_item(NAME(m_PCLATH)); - save_item(NAME(m_INTCON)); - save_item(NAME(m_STACK)); - save_item(NAME(m_prescaler)); - save_item(NAME(m_opcode.w)); - save_item(NAME(m_delay_timer)); - save_item(NAME(m_rtcc)); - save_item(NAME(m_count_cycles)); - save_item(NAME(m_inst_cycles)); - save_item(NAME(m_stack_pointer)); - save_item(NAME(m_old_RB0)); - save_item(NAME(m_irq_in_progress)); - save_item(NAME(m_eeprom_data)); - - - // debugger - state_add( PIC16X8x_PC, "PC", m_PCL).mask(0xfff).formatstr("%03X"); - state_add( PIC16X8x_W, "W", m_W).formatstr("%02X"); - state_add( PIC16X8x_ALU, "ALU", m_ALU).formatstr("%02X"); - state_add( PIC16X8x_WDT, "WDT", m_WDT).formatstr("%04X"); - state_add( PIC16X8x_CONFIG, "CNF", m_CONFIG).formatstr("%04X"); - state_add( PIC16X8x_PSCL, "PSCL", m_debugger_temp).callimport().formatstr("%3s"); - - state_add( STATE_GENPC, "GENPC", m_PCL).noshow(); - state_add( STATE_GENPCBASE, "CURPC", m_PREVPC).noshow(); - state_add( STATE_GENFLAGS, "GENFLAGS", m_OPTION).formatstr("%13s").noshow(); - - set_icountptr(m_icount); -} - - -void pic16x8x_device::state_import(const device_state_entry &entry) -{ - switch (entry.index()) - { - case PIC16X8x_PSCL: - m_prescaler = m_debugger_temp; - break; - } -} - -void pic16x8x_device::state_export(const device_state_entry &entry) -{ - switch (entry.index()) - { - } -} - -void pic16x8x_device::state_string_export(const device_state_entry &entry, std::string &str) const -{ - switch (entry.index()) - { - case PIC16X8x_PSCL: - str = string_format("%c%02X", ((m_OPTION & 0x08) ? 'W' : 'T'), m_prescaler); - break; - - case STATE_GENFLAGS: - str = string_format("%01x%c%c%c%c%c %c%c%c%03x", - (m_STATUS & 0xe0) >> 5, - m_STATUS & 0x10 ? '.':'O', // WDT Overflow - m_STATUS & 0x08 ? 'P':'D', // Power/Down - m_STATUS & 0x04 ? 'Z':'.', // Zero - m_STATUS & 0x02 ? 'c':'b', // Nibble Carry/Borrow - m_STATUS & 0x01 ? 'C':'B', // Carry/Borrow - - m_OPTION & 0x20 ? 'C':'T', // Counter/Timer - m_OPTION & 0x10 ? 'N':'P', // Negative/Positive - m_OPTION & 0x08 ? 'W':'T', // WatchDog/Timer - m_OPTION & 0x08 ? (1<<(m_OPTION&7)) : (2<<(m_OPTION&7))); - break; - } -} - - -/**************************************************************************** - * Reset registers to their initial values - ****************************************************************************/ - -void pic16x8x_device::reset_regs() -{ - set_pc(RESET_VECTOR); - m_port_tris[PORTA] = 0x1f; - m_port_tris[PORTB] = 0xff; - m_OPTION = T0CS_FLAG | T0SE_FLAG | PSA_FLAG | PS_REG; - m_PREVPC = m_PCL; - m_STATUS = 0x18; - m_PCL = 0; - m_prescaler = 0; - m_delay_timer = 0; - m_inst_cycles = 0; - m_count_cycles = 0; - m_stack_pointer = 0; - m_portb_chdetect_temp = 0xff; - m_old_RB0 = 0; -} - -void pic16x8x_device::set_config(u16 data) -{ - logerror("Writing %04x to the PIC16x8x configuration bits\n", data); - m_CONFIG = (data & 0x3fff); -} - -void pic16x8x_device::watchdog_reset() -{ - SET(m_STATUS, TO_FLAG | PD_FLAG | Z_FLAG | DC_FLAG | C_FLAG); - reset_regs(); -} - -void pic16x8x_device::device_reset() -{ - reset_regs(); - CLR(m_STATUS, RP0_FLAG); - CLR(m_STATUS, RP1_FLAG); - - // Setting TO_FLAG from Config Word - if(WDTE) - SET(m_STATUS, TO_FLAG); - else - CLR(m_STATUS, TO_FLAG); - - SET(m_STATUS, PD_FLAG); - store_regfile(3, m_STATUS); - store_regfile(4, m_FSR); -} - - -/**************************************************************************** - * WatchDog - ****************************************************************************/ - -void pic16x8x_device::update_watchdog(int counts) -{ - /* - WatchDog is set up to count 18,000 (0x464f hex) ticks to provide - the timeout period of 0.018ms based on a 4MHz input clock. - Note: the 4MHz clock should be divided by the PIC16C5x_CLOCK_DIVIDER - which effectively makes the PIC run at 1MHz internally. - - If the current instruction is CLRWDT or SLEEP, don't update the WDT - */ - - if ((m_opcode.w != 3) && (m_opcode.w != 4)) - { - u16 old_WDT = m_WDT; - - m_WDT -= counts; - - if (m_WDT > 0x464f) - { - m_WDT = 0x464f - (0xffff - m_WDT); - } - - if (((old_WDT != 0) && (old_WDT < m_WDT)) || (m_WDT == 0)) - { - if (PSA) - { - m_prescaler++; - if (m_prescaler >= (1 << PS)) - { // Prescale values from 1 to 128 - m_prescaler = 0; - CLR(m_STATUS, TO_FLAG); - watchdog_reset(); - } - } - else - { - CLR(m_STATUS, TO_FLAG); - watchdog_reset(); - } - } - } -} - - -/**************************************************************************** - * Update Timer - ****************************************************************************/ - -void pic16x8x_device::update_timer(int counts) -{ - if (m_delay_timer > 0) - { // Timer increment is inhibited - int dt = m_delay_timer; - m_delay_timer -= m_inst_cycles; - counts -= dt; - } - - if (m_delay_timer > 0 || counts <= 0) - return; - - if (PSA == 0) - { // if PSA is cleared, prescaler is assigned to timer - m_prescaler += counts; - if (m_prescaler >= (2 << PS)) - { // Prescale values from 2 to 256 - m_TMR0 += (m_prescaler / (2 << PS)); - if(m_TMR0 == 0) - SET(m_INTCON, T0IF_FLAG); - m_prescaler %= (2 << PS); // Overflow prescaler - } - } - else - { - m_TMR0 += counts; - if(m_TMR0 == 0) - SET(m_INTCON, T0IF_FLAG); - } -} - -void pic16x8x_device::execute_set_input(int line, int state) -{ - u8 RB0_in; - switch (line) - { - // RTCC/RA4_T0CKI pin - case PIC16x8x_T0CKI: - if (T0CS && state != m_rtcc) - { // Count mode, edge triggered - if ((T0SE && !state) || (!T0SE && state)) - m_count_cycles++; - } - m_rtcc = state; - break; - - case PIC16x8x_RB0INT: - RB0_in = state; - if (INTEDG) - { /* Interrupt on Rising edge RB0 input */ - if (RISING_EDGE_RB0) - { - SET(m_INTCON, INTF_FLAG); - } - } - else - { /* Interrupt on Falling edge RB0 input */ - if (FALLING_EDGE_RB0) - { - SET(m_INTCON, INTF_FLAG); - } - } - m_old_RB0 = RB0_in; - break; - - default: - break; - } -} - -/*------------------------------------------------- - check_irqs - check for and process IRQs --------------------------------------------------*/ - -void pic16x8x_device::check_irqs() -{ - // if something is in progress, we do nothing - if (m_irq_in_progress) - return; - - if(m_read_port[PORTB](PORTB, 0xf0) != m_portb_chdetect_temp) - { - m_portb_chdetect_temp = m_read_port[PORTB](PORTB, 0xf0); - SET(m_INTCON, RBIF_FLAG); - } - - else if(GIE && RBIE && RBIF) - { - push_stack(m_PCL); - set_pc(INT_VECTOR); - standard_irq_callback(0, m_PCL); - m_irq_in_progress = true; - } - - else if(GIE && INTE && INTF) - { - push_stack(m_PCL); - set_pc(INT_VECTOR); - standard_irq_callback(1, m_PCL); - m_irq_in_progress = true; - } - - else if(GIE && T0IE && T0IF) - { - push_stack(m_PCL); - set_pc(INT_VECTOR); - standard_irq_callback(2, m_PCL); - m_irq_in_progress = true; - } - - else if(GIE && EEIE && EEIF) - { - push_stack(m_PCL); - set_pc(INT_VECTOR); - standard_irq_callback(3, m_PCL); - m_irq_in_progress = true; - } -} - - -/**************************************************************************** - * Execute IPeriod. Return 0 if emulation should be stopped - ****************************************************************************/ - -void pic16x8x_device::execute_run() -{ - do - { - // check interrupts - check_irqs(); - - if (PD == 0) - { // Sleep Mode - m_count_cycles = 0; - m_inst_cycles = 1; - debugger_instruction_hook(m_PCL); - } - else - { - m_PREVPC = m_PCL; - - debugger_instruction_hook(m_PCL); - - m_opcode.w = m_program.read_word(m_PCL); - set_pc(m_PCL + 1); - - if ( (m_opcode.w & 0x3f80) != 0x0000) - { // Do all opcodes except the 00? ones - m_inst_cycles = s_opcode_main[((m_opcode.w >> 7) & 0x7f)].cycles; - (this->*s_opcode_main[((m_opcode.w >> 7) & 0x7f)].function)(); - } - else - { // Opcode 0x00? has many opcodes in its minor nibble - m_inst_cycles = s_opcode_00x[(m_opcode.b.l & 0x7f)].cycles; - (this->*s_opcode_00x[(m_opcode.b.l & 0x7f)].function)(); - } - - update_timer(T0CS ? m_count_cycles : m_inst_cycles); - m_count_cycles = 0; - } - - if (WDTE) - { - update_watchdog(m_inst_cycles); - } - - m_icount -= m_inst_cycles; - - } while (m_icount > 0); -} +// license:BSD-3-Clause +// copyright-holders:Grull Osgo +/**************************************************************************************** + + Microchip PIC16x8x Emulator + + https://ww1.microchip.com/downloads/en/DeviceDoc/30445D.pdf + + Based on MAME's PIC16C5x/62x cpu devices developed by Tony La Porta + and improvements to SFR's accesss made by ajrhacker. + + Preliminary version to give support to magicle and other games + on misc/magicard.cpp driver, providing some protection level via I2C bus. + + Coded and partially tested: + - All instruction set and disassembler. + - I/O Ports. + - WDT. + - Timer/Counter. + - All (4) interrupt sources. + - Input lines. + - Internal EEPROM with default and NVRAM functionality. + + ToDo: + - Verify if data ram addreess map mirroring is properly coded acording to datasheet description. + + - Choose wich is the best option to set the config word, if via set instruction or from dump data or some sort of combination via default options. + + - Improve the debug section. + + - Verify eeprom write sequence (see datashhet) + + Improvements: + - SFR's Flag description (bit oriented instructions) in disassembler where possible. + +****************************************************************************************/ + +#include "emu.h" +#include "pic16x8x.h" +#include "16x8xdsm.h" + +DEFINE_DEVICE_TYPE(PIC16CR83, pic16cr83_device, "pic16cr83", "Microchip PIC16CR83") +DEFINE_DEVICE_TYPE(PIC16CR84, pic16cr84_device, "pic16cr84", "Microchip PIC16CR84") +DEFINE_DEVICE_TYPE(PIC16F83, pic16f83_device, "pic16f83", "Microchip PIC16F83") +DEFINE_DEVICE_TYPE(PIC16F84, pic16f84_device, "pic16f84", "Microchip PIC16F84") +DEFINE_DEVICE_TYPE(PIC16F84A, pic16f84a_device, "pic16f84a", "Microchip PIC16F84A") + +/**************************************************************************** + * Internal Memory Maps + ****************************************************************************/ + +void pic16x8x_device::rom_9(address_map &map) +{ + map(0x000, 0x1ff).rom(); +} + +void pic16x8x_device::rom_10(address_map &map) +{ + map(0x000, 0x3ff).rom(); +} + + +/* Notes from datasheet: + The address depends on the device used. +Devices with 36 bytes ends at 2Fh, devices with +68 bytes ends at 4Fh.*/ + +void pic16x8x_device::core_regs(address_map &map, u8 mirror) +{ + map(0x00, 0x00).noprw().mirror(mirror); // Not an actual register, reading indirectly (FSR=0) returns 0 + map(0x01, 0x01).rw(FUNC(pic16x8x_device::tmr0_r), FUNC(pic16x8x_device::tmr0_w)); + map(0x02, 0x02).rw(FUNC(pic16x8x_device::pcl_r), FUNC(pic16x8x_device::pcl_w)).mirror(mirror); + map(0x03, 0x03).rw(FUNC(pic16x8x_device::status_r), FUNC(pic16x8x_device::status_w)).mirror(mirror); + map(0x04, 0x04).rw(FUNC(pic16x8x_device::fsr_r), FUNC(pic16x8x_device::fsr_w)).mirror(mirror); + map(0x05, 0x05).rw(FUNC(pic16x8x_device::porta_r), FUNC(pic16x8x_device::porta_w)); + map(0x06, 0x06).rw(FUNC(pic16x8x_device::portb_r), FUNC(pic16x8x_device::portb_w)); + map(0x07, 0x07).noprw().mirror(mirror); // Not an actual register, returns 0 + map(0x08, 0x08).rw(FUNC(pic16x8x_device::eedata_r), FUNC(pic16x8x_device::eedata_w)); + map(0x09, 0x09).rw(FUNC(pic16x8x_device::eeadr_r), FUNC(pic16x8x_device::eeadr_w)); + map(0x0a, 0x0a).rw(FUNC(pic16x8x_device::pclath_r), FUNC(pic16x8x_device::pclath_w)).mirror(mirror); + map(0x0b, 0x0b).rw(FUNC(pic16x8x_device::intcon_r), FUNC(pic16x8x_device::intcon_w)).mirror(mirror); + map(0x81, 0x81).rw(FUNC(pic16x8x_device::option_r), FUNC(pic16x8x_device::option_w)); + map(0x85, 0x85).rw(FUNC(pic16x8x_device::trisa_r), FUNC(pic16x8x_device::trisa_w)); + map(0x86, 0x86).rw(FUNC(pic16x8x_device::trisb_r), FUNC(pic16x8x_device::trisb_w)); + map(0x88, 0x88).rw(FUNC(pic16x8x_device::eecon1_r), FUNC(pic16x8x_device::eecon1_w)); + map(0x89, 0x89).rw(FUNC(pic16x8x_device::eecon2_r), FUNC(pic16x8x_device::eecon2_w)); +} + +void pic16x8x_device::ram_6(address_map &map) +{ + // 0x00 - 0x0b SFR's Bank 0 + // 0x0c - 0x2f GPR's + // 0x80 - 0x8b SFR's Bank 1 + // 0x8c - 0xaf GPR Mirrored to 0x0c - 0x2f + core_regs(map, 0x80); + map(0x0c, 0x2f).ram().mirror(0x80); +} + +void pic16x8x_device::ram_7(address_map &map) +{ + // 0x00 - 0x0b SFR's Bank 0 + // 0x0c - 0x4f GPR's + // 0x80 - 0x8b SFR's Bank 1 + // 0x8c - 0xcf GPR Mirrored to 0x0c - 0x4f + core_regs(map, 0x80); + map(0x0c, 0x4f).ram().mirror(0x80); +} + + +pic16x8x_device::pic16x8x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int program_width, address_map_constructor program_map, address_map_constructor data_map) + : cpu_device(mconfig, type, tag, owner, clock) + , device_nvram_interface(mconfig, *this) + , m_region(*this, DEVICE_SELF) + , m_program_config("program", ENDIANNESS_LITTLE, 16, program_width, -1, program_map) + , m_data_config("data", ENDIANNESS_LITTLE, 8, 8, 0, data_map) + , m_program_width(program_width) + , m_CONFIG(0x3fff) + , m_read_port(*this, 0) + , m_write_port(*this) +{ +} + +pic16x83_device::pic16x83_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) + : pic16x8x_device(mconfig, type, tag, owner, clock, 9, address_map_constructor(FUNC(pic16x8x_device::rom_9), this), address_map_constructor(FUNC(pic16x8x_device::ram_6), this)) +{ +} + +pic16x84_device::pic16x84_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) + : pic16x8x_device(mconfig, type, tag, owner, clock, 10, address_map_constructor(FUNC(pic16x8x_device::rom_10), this), address_map_constructor(FUNC(pic16x8x_device::ram_7), this)) +{ +} + +pic16cr83_device::pic16cr83_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : pic16x83_device(mconfig, PIC16CR83, tag, owner, clock) +{ +} + +pic16cr84_device::pic16cr84_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : pic16x84_device(mconfig, PIC16CR84, tag, owner, clock) +{ +} + +pic16f83_device::pic16f83_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : pic16x83_device(mconfig, PIC16F83, tag, owner, clock) +{ +} + +pic16f84_device::pic16f84_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : pic16x84_device(mconfig, PIC16F84, tag, owner, clock) +{ +} + +pic16f84a_device::pic16f84a_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : pic16x84_device(mconfig, PIC16F84A, tag, owner, clock) +{ +} + +device_memory_interface::space_config_vector pic16x8x_device::memory_space_config() const +{ + return space_config_vector + { + std::make_pair(AS_PROGRAM, &m_program_config), + std::make_pair(AS_DATA, &m_data_config) + }; +} + +std::unique_ptr pic16x8x_device::create_disassembler() +{ + return std::make_unique(); +} + + +/* Notes about NVRAM / PIC eeprom data + +Dump size is 4280 Bytes, 16 bits wide. +0000h-03ffh is program data +0400h-3fffh is dummy data +4000h-400fh is user and config data +4010h-41ffh is dummy data +4200h-4280h is eeprom data + +NVRAM saved data is 8 bits wide, in accordance with the data width +of the EEPROM memory of the PIC. +This means that we need to perform the conversion from the default +NVRAM dumped data to the NVRAM saved data. +*/ + +void pic16x8x_device::nvram_default() +{ + u16 dump_size = 0x4280; + u16 eeprom_dump = 0x4200; + + // populate from a memory region if present + if (m_region.found()) + { + if (m_region->bytes() != dump_size) // pic memory dump total size + { + fatalerror("Region '%s' wrong size (expected size = 0x%X)\n", tag(), dump_size); + } + + if (m_region->bytewidth() != 2) // pic memory dumps are 16 bits wide + { + fatalerror("Region '%s' needs to be an 16-bit region\n", tag()); + } + + // Get default NVRAM data from memory region + memcpy(m_buff, m_region->base() + eeprom_dump, m_internal_eeprom_size * 2); + + // Data width conversion + for (u8 i = 0; i < m_internal_eeprom_size; i++) + m_eeprom_data[i] = m_buff[i] & 0x00ff; + } +} + +bool pic16x8x_device::nvram_read(util::read_stream &file) +{ + auto const [err, actual] = read(file, m_eeprom_data, m_internal_eeprom_size); + return !err && (actual == m_internal_eeprom_size); +} + +bool pic16x8x_device::nvram_write(util::write_stream &file) +{ + auto const [err, actual] = write(file, m_eeprom_data, m_internal_eeprom_size); + return !err && (actual == m_internal_eeprom_size); +} + + +// EEPROM data access +u8 pic16x8x_device::m_eeread(offs_t offs) +{ + return m_eeprom_data[offs]; +} + +void pic16x8x_device::m_eewrite(offs_t offs, u8 data) +{ + m_eeprom_data[offs] = data & m_data_mask; +} + + +// ******** The following is the STATUS flag register definition. ******** +// | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | +// | IRP | RP1 | RP0 | T0| PD| Z | DC | C | + +// IRP Register Bank Select - Unimplemented on this device +constexpr u8 RP1_FLAG = 0x40; // Register Bank Select Bit 1 +constexpr u8 RP0_FLAG = 0x20; // Register Bank Select Bit 0 + // 00 = Bank 0 (00h-7fh) + // 01 = Bank 1 (80h-ffh) + // 10 = Bank 2 (100h-17fh) + // 11 = Bank 3 (180h-1ffh) + // Each bank is 128 bytes. Only bit RP0 is used by the PIC16F8X. RP1 should be mantained clear. +constexpr u8 TO_FLAG = 0x10; // TO Time Out flag (WatchDog) +constexpr u8 PD_FLAG = 0x08; // PD Power Down flag +constexpr u8 Z_FLAG = 0x04; // Z Zero Flag +constexpr u8 DC_FLAG = 0x02; // DC Digit Carry/Borrow flag (Nibble) +constexpr u8 C_FLAG = 0x01; // C Carry/Borrow Flag (Byte) + +#define RP0 (m_STATUS & RP0_FLAG) +#define TO (m_STATUS & TO_FLAG) +#define PD (m_STATUS & PD_FLAG) +#define ZERO (m_STATUS & Z_FLAG) +#define DC (m_STATUS & DC_FLAG) +#define CARRY (m_STATUS & C_FLAG) + + +// ******** The following is the OPTION flag register definition. ******** +// | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | +// | RBPU | INTEDG | T0CS | T0SE | PSA | PS2 | PS1 | PS0 | +constexpr u8 RBPU_FLAG = 0x80; // RBPU PORTB Pull-up Enable bit +constexpr u8 INTEDG_FLAG = 0x40; // INTEDG Interrupt Edge Select bit + // 1 = Interrupt on rising edge of RB0/INT pin + // 0 = Interrupt on falling edge of RB0/INT pin +constexpr u8 T0CS_FLAG = 0x20; // T0CS Timer 0 clock source select + // 1 = Transition on RA4/T0CKI pin + // 0 = Internal instruction cycle clock (CLKOUT) +constexpr u8 T0SE_FLAG = 0x10; // T0SE Timer 0 clock source edge select + // 1 = Increment on high-to-low transition on RA4/T0CKI pin + // 0 = Increment on low-to-high transition on RA4/T0CKI pin +constexpr u8 PSA_FLAG = 0x08; // PSA Prescaler Assignment bit + // 1 = Prescaler is assigned to the WDT + // 0 = Prescaler is assigned to the Timer0 module +constexpr u8 PS_REG = 0x07; // PS Prescaler Rate select + +#define RBPU (m_OPTION & RBPU_FLAG) +#define INTEDG (m_OPTION & INTEDG_FLAG) +#define T0CS (m_OPTION & T0CS_FLAG) +#define T0SE (m_OPTION & T0SE_FLAG) +#define PSA (m_OPTION & PSA_FLAG) +#define PS (m_OPTION & PS_REG) + + +// ******** The following is the CONFIG Flag register definition. ******** +// | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | +// | CP | WDTE | FOSC | + // CP Code Protect (ROM read protect) +constexpr u8 WDTE_FLAG = 0x04; // WDTE WatchDog Timer enable +constexpr u8 FOSC_FLAG = 0x03; // FOSC Oscillator source select + +#define WDTE (m_CONFIG & WDTE_FLAG) +#define FOSC (m_CONFIG & FOSC_FLAG) + + +// ******** The following is the INTCON flag register definition. ******** +// | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | +// | GIE | EEIE | T0IE | INTE | RBIE | T0IF | INTF | RBIF | + +constexpr u8 GIE_FLAG = 0x80; +constexpr u8 EEIE_FLAG = 0x40; +constexpr u8 T0IE_FLAG = 0x20; +constexpr u8 INTE_FLAG = 0x10; +constexpr u8 RBIE_FLAG = 0x08; +constexpr u8 T0IF_FLAG = 0x04; +constexpr u8 INTF_FLAG = 0x02; +constexpr u8 RBIF_FLAG = 0x01; + +#define GIE (m_INTCON & GIE_FLAG) +#define EEIE (m_INTCON & EEIE_FLAG) +#define T0IE (m_INTCON & T0IE_FLAG) +#define INTE (m_INTCON & INTE_FLAG) +#define RBIE (m_INTCON & RBIE_FLAG) +#define T0IF (m_INTCON & T0IF_FLAG) +#define INTF (m_INTCON & INTF_FLAG) +#define RBIF (m_INTCON & RBIF_FLAG) + +// ******** The following is the EECON1 Flag register definition. ******** +// | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | +// | | | | EEIF | WRERR | WREN | WR | RD | + +constexpr u8 EEIF_FLAG = 0x10; +constexpr u8 WRERR_FLAG = 0x08; +constexpr u8 WREN_FLAG = 0x04; +constexpr u8 EEWR_FLAG = 0x02; +constexpr u8 EERD_FLAG = 0x01; + +#define EEIF (m_EECON1 & EEIF_FLAG) +#define WRERR (m_EECON1 & WRERR_FLAG) +#define WREN (m_EECON1 & WREN_FLAG) +#define EEWR (m_EECON1 & EEWR_FLAG) +#define EERD (m_EECON1 & EERD_FLAG) + +/************************************************************************ + * Fixed Vectors + ************************************************************************/ + +constexpr u8 RESET_VECTOR = 0x00; +constexpr u8 INT_VECTOR = 0x04; + +/************************************************************************ + * Shortcuts + ************************************************************************/ + +#define RISING_EDGE_RB0 (( (int)(RB0_in - m_old_RB0) > 0) ? 1 : 0) +#define FALLING_EDGE_RB0 (( (int)(RB0_in - m_old_RB0) < 0) ? 1 : 0) + +#define M_RDEEPROM(A) m_eeread(A) +#define M_WREEPROM(A,V) m_eewrite(A, V) + +#define CLR(flagreg, flag) (flagreg &= u8(~flag)) +#define SET(flagreg, flag) (flagreg |= (flag)) + +#define ADDR ((m_opcode.b.l & 0x7f) | (RP0 << 2)) +#define BITPOS ((m_opcode.w >> 7) & 7) + + +void pic16x8x_device::calc_zero_flag() +{ + if (m_ALU == 0) + SET(m_STATUS, Z_FLAG); + else + CLR(m_STATUS, Z_FLAG); +} + +void pic16x8x_device::calc_add_flags(u8 augend) +{ + calc_zero_flag(); + + if (augend > m_ALU) + SET(m_STATUS, C_FLAG); + else + CLR(m_STATUS, C_FLAG); + + if ((augend & 0x0f) > (m_ALU & 0x0f)) + SET(m_STATUS, DC_FLAG); + else + CLR(m_STATUS, DC_FLAG); +} + +void pic16x8x_device::calc_sub_flags(u8 minuend) +{ + calc_zero_flag(); + + if (minuend < m_ALU) + CLR(m_STATUS, C_FLAG); + else + SET(m_STATUS, C_FLAG); + + if ((minuend & 0x0f) < (m_ALU & 0x0f)) + CLR(m_STATUS, DC_FLAG); + else + SET(m_STATUS, DC_FLAG); +} + +void pic16x8x_device::set_pc(u16 addr) +{ + m_PCL = addr & m_program_mask; +} + +/* +Notes about Stack (from datasheet) +After the stack has been PUSHed eight times, the ninth +push overwrites the value that was stored from the first +push. The tenth push overwrites the second push (and +so on) +*/ + +u16 pic16x8x_device::pop_stack() +{ + m_stack_pointer = (m_stack_pointer - 1) & 0x0f; + u16 data = m_STACK[m_stack_pointer]; + return data & m_program_mask; +} + +void pic16x8x_device::push_stack(u16 data) +{ + m_STACK[m_stack_pointer] = data & m_program_mask; + m_stack_pointer = (m_stack_pointer + 1) & 0x0f; +} + +void pic16x8x_device::store_result(u8 addr, u8 data) +{ + if (m_opcode.b.l & 0x80) + store_regfile(addr, data); + else + m_W = data; + +} + +// *** Special function registers (SFR's) *** + +// *** SFR Access *** +u8 pic16x8x_device::get_regfile(u8 addr) +{ + if (addr == 0) + { // Indirect addressing + addr = m_FSR & m_data_mask; + } + return m_data.read_byte(addr); +} + +void pic16x8x_device::store_regfile(u8 addr, u8 data) +{ + if (addr == 0) + { // Indirect addressing + addr = m_FSR & m_data_mask; + } + m_data.write_byte(addr, data); +} + +// *** SFR Functions *** +u8 pic16x8x_device::tmr0_r() +{ + return m_TMR0; +} + +void pic16x8x_device::tmr0_w(u8 data) +{ + m_delay_timer = 2; // Timer increment is inhibited for 2 cycles + if (PSA == 0) m_prescaler = 0; // Must clear the Prescaler + m_TMR0 = data; +} + +u8 pic16x8x_device::pcl_r() +{ + return m_PCL; +} + +void pic16x8x_device::pcl_w(u8 data) +{ + m_PCL = data; + set_pc((m_PCLATH << 8) | data); + m_inst_cycles++; +} + +u8 pic16x8x_device::status_r() +{ + return m_STATUS; +} + +void pic16x8x_device::status_w(u8 data) +{ + m_STATUS = (m_STATUS & (TO_FLAG | PD_FLAG)) | (data & u8(~(TO_FLAG | PD_FLAG))); +} + +u8 pic16x8x_device::fsr_r() +{ + return m_FSR | (uint8_t)(~m_data_mask); +} + +void pic16x8x_device::fsr_w(u8 data) +{ + m_FSR = data | u8(~m_data_mask); +} + +u8 pic16x8x_device::porta_r() +{ + u8 data = m_read_port[PORTA](PORTA, 0xff); + data &= m_port_tris[PORTA]; + data |= (u8(~m_port_tris[PORTA]) & m_port_data[PORTA]); + return data & 0x1f; // 5-bit port (only lower 5 bits used) +} + +void pic16x8x_device::porta_w(u8 data) +{ + data &= 0x1f; // 5-bit port (only lower 5 bits used) + m_write_port[PORTA](PORTA, data & u8(~m_port_tris[PORTA]) & 0x1f, u8(~m_port_tris[PORTA]) & 0x1f); + m_port_data[PORTA] = data; +} + +u8 pic16x8x_device::portb_r() +{ + u8 data = m_read_port[PORTB](PORTB, 0xff); + data &= m_port_tris[PORTB]; + data |= (u8(~m_port_tris[PORTB]) & m_port_data[PORTB]); + return data; +} + +void pic16x8x_device::portb_w(u8 data) +{ + m_write_port[PORTB](PORTB, data & u8(~m_port_tris[PORTB]), u8(~m_port_tris[PORTB])); + m_port_data[PORTB] = data; +} + +u8 pic16x8x_device::eedata_r() +{ + return m_EEDATA; +} + +void pic16x8x_device::eedata_w(u8 data) +{ + m_EEDATA = data; +} + +u8 pic16x8x_device::eeadr_r() +{ + return m_EEADR; +} + +void pic16x8x_device::eeadr_w(u8 data) +{ + m_EEADR = data; +} + +u8 pic16x8x_device::pclath_r() +{ + return m_PCLATH; +} + +void pic16x8x_device::pclath_w(u8 data) +{ + m_PCLATH = data; +} + +u8 pic16x8x_device::intcon_r() +{ + return m_INTCON; +} + +void pic16x8x_device::intcon_w(u8 data) +{ + m_INTCON = data; +} + +u8 pic16x8x_device::trisa_r() +{ + return m_port_tris[PORTA]; +} + +void pic16x8x_device::trisa_w(u8 data) +{ + if (m_port_tris[PORTA] != data) + { + m_port_tris[PORTA] = data | 0xe0; + m_write_port[PORTA](PORTA, m_port_data[PORTA] & u8(~m_port_tris[PORTA]) & 0x1f, u8(~m_port_tris[PORTA]) & 0x1f); + } +} + +u8 pic16x8x_device::trisb_r() +{ + return m_port_tris[PORTB]; +} + +void pic16x8x_device::trisb_w(u8 data) +{ + if (m_port_tris[PORTB] != data) + { + m_port_tris[PORTB] = data; + m_write_port[PORTB](PORTB, m_port_data[PORTB] & u8(~m_port_tris[PORTB]), u8(~m_port_tris[PORTB])); + } +} + +u8 pic16x8x_device::eecon1_r() +{ + return m_EECON1; +} + +void pic16x8x_device::eecon1_w(u8 data) +{ + if (!((data & WREN_FLAG) && EEWR)) // The WR bit will be inhibited from being set unless the WREN bit is set.(from datasheet) + CLR(data, EEWR); // Clear the flag if it don't meet the requirements + + m_EECON1 = data; // update register + + if (EERD) // cheack flag condition to read eeprom + { + m_EEDATA = M_RDEEPROM(m_EEADR); // do eeprom read + CLR(m_EECON1, EERD_FLAG); // clear read enable flag + } + + if (WREN && EEWR && (m_EECON2 == 0xff)) // check flags conditions to write eeprom + { + M_WREEPROM(m_EEADR, data); // do eeprom write + CLR(m_EECON1, EEWR_FLAG); // clear write enable flag + SET(m_EECON1, EEIF_FLAG); // assuming write was done, set EEIF + } +} + +u8 pic16x8x_device::eecon2_r() +{ + return m_EECON2; +} + +void pic16x8x_device::eecon2_w(u8 data) +{ + if ((m_EECON2 != 0x55) & (data == 0x55)) + m_EECON2 = data; + else if ((m_EECON2 == 0x55) & (data == 0xaa)) + m_EECON2 = 0xff; + else + m_EECON2 = data; +} + +u8 pic16x8x_device::option_r() +{ + return m_OPTION; +} + +void pic16x8x_device::option_w(u8 data) +{ + m_OPTION = data; +} + +/************************************************************************ + * Emulate the Instructions + ************************************************************************/ + +void pic16x8x_device::illegal() +{ + logerror("PIC16x8x: PC=%03x, Illegal opcode = %04x\n", m_PREVPC, m_opcode.w); +} + +/* + Note: + According to the manual, if the STATUS register is the destination for an instruction that affects the Z, DC or C bits + then the write to these three bits is disabled. These bits are set or cleared according to the device logic. + To ensure this is correctly emulated, in instructions that write to the file registers, always change the status flags + *after* storing the result of the instruction. + e.g. CALCULATE_*, SET(STATUS,*_FLAG) and CLR(STATUS,*_FLAG) should appear as the last steps of the instruction emulation. +*/ + +void pic16x8x_device::addlw() +{ + // New + m_ALU = m_opcode.b.l + m_W; + m_W = m_ALU; + calc_zero_flag(); +} + +void pic16x8x_device::addwf() +{ + u8 augend = get_regfile(ADDR); + m_ALU = augend + m_W; + store_result(ADDR, m_ALU); + calc_add_flags(augend); +} + +void pic16x8x_device::andlw() +{ + m_ALU = m_opcode.b.l & m_W; + m_W = m_ALU; + calc_zero_flag(); +} + +void pic16x8x_device::andwf() +{ + m_ALU = get_regfile(ADDR) & m_W; + store_result(ADDR, m_ALU); + calc_zero_flag(); +} + +void pic16x8x_device::bcf() +{ + m_ALU = get_regfile(ADDR); + m_ALU &= ~(1 << BITPOS); + store_regfile(ADDR, m_ALU); +} + +void pic16x8x_device::bsf() +{ + m_ALU = get_regfile(ADDR); + m_ALU |= 1 << BITPOS; + store_regfile(ADDR, m_ALU); +} + +void pic16x8x_device::btfss() +{ + if (BIT(get_regfile(ADDR), BITPOS)) + { + set_pc(m_PCL + 1); + m_inst_cycles++; // Add NOP cycles + } +} + +void pic16x8x_device::btfsc() +{ + if (!BIT(get_regfile(ADDR), BITPOS)) + { + set_pc(m_PCL + 1); + m_inst_cycles++; // Add NOP cycles + } +} + +void pic16x8x_device::call() +{ + push_stack(m_PCL); + set_pc(((m_PCLATH & 0x18) << 8 ) | (m_opcode.w & 0x07ff)); +} + + +void pic16x8x_device::clrw() +{ + m_W = 0; + SET(m_STATUS, Z_FLAG); +} + +void pic16x8x_device::clrf() +{ + store_regfile(ADDR, 0); + SET(m_STATUS, Z_FLAG); +} + +void pic16x8x_device::clrwdt() +{ + m_WDT = 0; + if (PSA) m_prescaler = 0; + SET(m_STATUS, TO_FLAG); + SET(m_STATUS, PD_FLAG); +} + +void pic16x8x_device::comf() +{ + m_ALU = u8(~(get_regfile(ADDR))); + store_result(ADDR, m_ALU); + calc_zero_flag(); +} + +void pic16x8x_device::decf() +{ + m_ALU = get_regfile(ADDR) - 1; + store_result(ADDR, m_ALU); + calc_zero_flag(); +} + +void pic16x8x_device::decfsz() +{ + m_ALU = get_regfile(ADDR) - 1; + store_result(ADDR, m_ALU); + if (m_ALU == 0) + { + set_pc(m_PCL + 1); + m_inst_cycles++; // Add NOP cycles + } +} + +void pic16x8x_device::goto_op() +{ + set_pc(((m_PCLATH & 0x18) << 8 ) | (m_opcode.w & 0x07ff)); +} + +void pic16x8x_device::incf() +{ + m_ALU = get_regfile(ADDR) + 1; + store_result(ADDR, m_ALU); + calc_zero_flag(); +} + +void pic16x8x_device::incfsz() +{ + m_ALU = get_regfile(ADDR) + 1; + store_result(ADDR, m_ALU); + if (m_ALU == 0) + { + set_pc(m_PCL + 1); + m_inst_cycles++; // Add NOP cycles + } +} + +void pic16x8x_device::iorlw() +{ + m_ALU = m_opcode.b.l | m_W; + m_W = m_ALU; + calc_zero_flag(); +} + +void pic16x8x_device::iorwf() +{ + m_ALU = get_regfile(ADDR) | m_W; + store_result(ADDR, m_ALU); + calc_zero_flag(); +} + +void pic16x8x_device::movf() +{ + m_ALU = get_regfile(ADDR); + store_result(ADDR, m_ALU); + calc_zero_flag(); +} + +void pic16x8x_device::movlw() +{ + m_W = m_opcode.b.l; +} + +void pic16x8x_device::movwf() +{ + store_regfile(ADDR, m_W); +} + +void pic16x8x_device::nop() +{ + // Do nothing +} + +void pic16x8x_device::retfie() // new for 16x8x +{ + // New + set_pc(pop_stack()); + m_irq_in_progress = false; +} + +void pic16x8x_device::retlw() +{ + m_W = m_opcode.b.l; + set_pc(pop_stack()); +} + +void pic16x8x_device::retrn() // new for 16x8x +{ + set_pc(pop_stack()); +} + +void pic16x8x_device::rlf() +{ + m_ALU = get_regfile(ADDR); + int carry = BIT(m_ALU, 7); + m_ALU <<= 1; + if (m_STATUS & C_FLAG) m_ALU |= 1; + store_result(ADDR, m_ALU); + + if (carry) + SET(m_STATUS, C_FLAG); + else + CLR(m_STATUS, C_FLAG); +} + +void pic16x8x_device::rrf() +{ + m_ALU = get_regfile(ADDR); + int carry = BIT(m_ALU, 0); + m_ALU >>= 1; + if (m_STATUS & C_FLAG) m_ALU |= 0x80; + store_result(ADDR, m_ALU); + + if (carry) + SET(m_STATUS, C_FLAG); + else + CLR(m_STATUS, C_FLAG); +} + +void pic16x8x_device::sleepic() +{ + if (WDTE) m_WDT = 0; + if (PSA) m_prescaler = 0; + SET(m_STATUS, TO_FLAG); + CLR(m_STATUS, PD_FLAG); +} + +void pic16x8x_device::sublw() // new for 16x8x : Substract W from literal +{ + // New + u8 minuend = m_opcode.b.l; + m_ALU = minuend - m_W; + m_W = m_ALU; + calc_sub_flags(minuend); +} + +void pic16x8x_device::subwf() // Substract W from f +{ + u8 minuend = get_regfile(ADDR); + m_ALU = minuend - m_W; + store_result(ADDR, m_ALU); + calc_sub_flags(minuend); +} + +void pic16x8x_device::swapf() +{ + u8 reg = get_regfile(ADDR); + m_ALU = reg << 4 | reg >> 4; + store_result(ADDR, m_ALU); +} + +void pic16x8x_device::xorlw() +{ + m_ALU = m_W ^ m_opcode.b.l; + m_W = m_ALU; + calc_zero_flag(); +} + +void pic16x8x_device::xorwf() +{ + m_ALU = get_regfile(ADDR) ^ m_W; + store_result(ADDR, m_ALU); + calc_zero_flag(); +} + + +/*********************************************************************** + * Opcode Table (Cycles, Instruction) + ***********************************************************************/ + +const pic16x8x_device::pic16x8x_opcode pic16x8x_device::s_opcode_main[128]= +{ + {1, &pic16x8x_device::nop },{1, &pic16x8x_device::movwf },{1, &pic16x8x_device::clrw },{1, &pic16x8x_device::clrf }, // 00 + {1, &pic16x8x_device::subwf },{1, &pic16x8x_device::subwf },{1, &pic16x8x_device::decf },{1, &pic16x8x_device::decf }, // 04 + {1, &pic16x8x_device::iorwf },{1, &pic16x8x_device::iorwf },{1, &pic16x8x_device::andwf },{1, &pic16x8x_device::andwf }, // 08 + {1, &pic16x8x_device::xorwf },{1, &pic16x8x_device::xorwf },{1, &pic16x8x_device::addwf },{1, &pic16x8x_device::addwf }, // 0C + {1, &pic16x8x_device::movf },{1, &pic16x8x_device::movf },{1, &pic16x8x_device::comf },{1, &pic16x8x_device::comf }, // 10 + {1, &pic16x8x_device::incf },{1, &pic16x8x_device::incf },{1, &pic16x8x_device::decfsz },{1, &pic16x8x_device::decfsz }, // 14 + {1, &pic16x8x_device::rrf },{1, &pic16x8x_device::rrf },{1, &pic16x8x_device::rlf },{1, &pic16x8x_device::rlf }, // 18 + {1, &pic16x8x_device::swapf },{1, &pic16x8x_device::swapf },{1, &pic16x8x_device::incfsz },{1, &pic16x8x_device::incfsz }, // 1C + {1, &pic16x8x_device::bcf },{1, &pic16x8x_device::bcf },{1, &pic16x8x_device::bcf },{1, &pic16x8x_device::bcf }, // 20 + {1, &pic16x8x_device::bcf },{1, &pic16x8x_device::bcf },{1, &pic16x8x_device::bcf },{1, &pic16x8x_device::bcf }, + {1, &pic16x8x_device::bsf },{1, &pic16x8x_device::bsf },{1, &pic16x8x_device::bsf },{1, &pic16x8x_device::bsf }, // 28 + {1, &pic16x8x_device::bsf },{1, &pic16x8x_device::bsf },{1, &pic16x8x_device::bsf },{1, &pic16x8x_device::bsf }, + {1, &pic16x8x_device::btfsc },{1, &pic16x8x_device::btfsc },{1, &pic16x8x_device::btfsc },{1, &pic16x8x_device::btfsc }, // 30 + {1, &pic16x8x_device::btfsc },{1, &pic16x8x_device::btfsc },{1, &pic16x8x_device::btfsc },{1, &pic16x8x_device::btfsc }, + {1, &pic16x8x_device::btfss },{1, &pic16x8x_device::btfss },{1, &pic16x8x_device::btfss },{1, &pic16x8x_device::btfss }, // 38 + {1, &pic16x8x_device::btfss },{1, &pic16x8x_device::btfss },{1, &pic16x8x_device::btfss },{1, &pic16x8x_device::btfss }, + {2, &pic16x8x_device::call },{2, &pic16x8x_device::call },{2, &pic16x8x_device::call },{2, &pic16x8x_device::call }, // 40 + {2, &pic16x8x_device::call },{2, &pic16x8x_device::call },{2, &pic16x8x_device::call },{2, &pic16x8x_device::call }, + {2, &pic16x8x_device::call },{2, &pic16x8x_device::call },{2, &pic16x8x_device::call },{2, &pic16x8x_device::call }, // 48 + {2, &pic16x8x_device::call },{2, &pic16x8x_device::call },{2, &pic16x8x_device::call },{2, &pic16x8x_device::call }, + {2, &pic16x8x_device::goto_op },{2, &pic16x8x_device::goto_op },{2, &pic16x8x_device::goto_op },{2, &pic16x8x_device::goto_op }, // 50 + {2, &pic16x8x_device::goto_op },{2, &pic16x8x_device::goto_op },{2, &pic16x8x_device::goto_op },{2, &pic16x8x_device::goto_op }, + {2, &pic16x8x_device::goto_op },{2, &pic16x8x_device::goto_op },{2, &pic16x8x_device::goto_op },{2, &pic16x8x_device::goto_op }, // 58 + {2, &pic16x8x_device::goto_op },{2, &pic16x8x_device::goto_op },{2, &pic16x8x_device::goto_op },{2, &pic16x8x_device::goto_op }, + {1, &pic16x8x_device::movlw },{1, &pic16x8x_device::movlw },{1, &pic16x8x_device::movlw },{1, &pic16x8x_device::movlw }, // 60 + {1, &pic16x8x_device::movlw },{1, &pic16x8x_device::movlw },{1, &pic16x8x_device::movlw },{1, &pic16x8x_device::movlw }, + {2, &pic16x8x_device::retlw },{2, &pic16x8x_device::retlw },{2, &pic16x8x_device::retlw },{2, &pic16x8x_device::retlw }, // 68 + {2, &pic16x8x_device::retlw },{2, &pic16x8x_device::retlw },{2, &pic16x8x_device::retlw },{2, &pic16x8x_device::retlw }, + {1, &pic16x8x_device::iorlw },{1, &pic16x8x_device::iorlw },{1, &pic16x8x_device::andlw },{1, &pic16x8x_device::andlw }, // 70 + {1, &pic16x8x_device::xorlw },{1, &pic16x8x_device::xorlw },{1, &pic16x8x_device::xorlw },{1, &pic16x8x_device::xorlw }, // 74 + {1, &pic16x8x_device::sublw },{1, &pic16x8x_device::sublw },{1, &pic16x8x_device::sublw },{1, &pic16x8x_device::sublw }, // 78 + {1, &pic16x8x_device::addlw },{1, &pic16x8x_device::addlw },{1, &pic16x8x_device::addlw },{1, &pic16x8x_device::addlw } // 7C +}; + +const pic16x8x_device::pic16x8x_opcode pic16x8x_device::s_opcode_00x[128]= +{ + {1, &pic16x8x_device::nop },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, // 00 + {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, + {2, &pic16x8x_device::retrn },{2, &pic16x8x_device::retfie },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, // 08 + {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, + {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, // 10 + {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, + {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, // 18 + {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, + {1, &pic16x8x_device::nop },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, // 20 + {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, + {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, // 28 + {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, + {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, // 30 + {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, + {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, // 38 + {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, + {1, &pic16x8x_device::nop },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, // 40 + {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, + {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, // 48 + {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, + {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, // 50 + {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, + {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, // 58 + {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, + {1, &pic16x8x_device::nop },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::sleepic }, // 60 + {1, &pic16x8x_device::clrwdt },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, + {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, // 68 + {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, + {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, // 70 + {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, + {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal }, // 78 + {1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal },{1, &pic16x8x_device::illegal } +}; + + +/**************************************************************************** + * Inits CPU emulation + ****************************************************************************/ + +enum +{ + PIC16X8x_PC=1, PIC16X8x_W, PIC16X8x_ALU, PIC16X8x_WDT, PIC16X8x_PSCL, PIC16X8x_CONFIG +}; + +void pic16x8x_device::device_start() +{ + space(AS_PROGRAM).cache(m_program); + space(AS_DATA).specific(m_data); + + m_program_mask = (1 << m_program_width) - 1; + m_data_mask = 0xff; + m_status_mask = 0xff; + m_PCL = 0; + m_PREVPC = 0; + m_W = 0; + m_OPTION = 0; + m_ALU = 0; + m_WDT = 0; + m_TMR0 = 0; + m_STATUS = ~m_status_mask; + m_FSR = 0; + std::fill(std::begin(m_port_data), std::end(m_port_data), 0); + std::fill(std::begin(m_port_tris), std::end(m_port_tris), 0); + std::fill(std::begin(m_STACK), std::end(m_STACK), 0); + m_prescaler = 0; + m_opcode.w = 0; + m_delay_timer = 0; + m_rtcc = 0; + m_count_cycles = 0; + m_inst_cycles = 0; + m_stack_pointer = 0; + m_debugger_temp = 0; + m_portb_chdetect_temp = 0xff; + m_irq_in_progress = false; + + // save states + save_item(NAME(m_PCL)); + save_item(NAME(m_PREVPC)); + save_item(NAME(m_CONFIG)); + save_item(NAME(m_W)); + save_item(NAME(m_OPTION)); + save_item(NAME(m_ALU)); + save_item(NAME(m_WDT)); + save_item(NAME(m_TMR0)); + save_item(NAME(m_STATUS)); + save_item(NAME(m_FSR)); + save_item(NAME(m_port_data)); + save_item(NAME(m_port_tris)); + save_item(NAME(m_EEDATA)); + save_item(NAME(m_EEADR)); + save_item(NAME(m_EECON1)); + save_item(NAME(m_EECON2)); + save_item(NAME(m_PCLATH)); + save_item(NAME(m_INTCON)); + save_item(NAME(m_STACK)); + save_item(NAME(m_prescaler)); + save_item(NAME(m_opcode.w)); + save_item(NAME(m_delay_timer)); + save_item(NAME(m_rtcc)); + save_item(NAME(m_count_cycles)); + save_item(NAME(m_inst_cycles)); + save_item(NAME(m_stack_pointer)); + save_item(NAME(m_old_RB0)); + save_item(NAME(m_irq_in_progress)); + save_item(NAME(m_eeprom_data)); + + + // debugger + state_add( PIC16X8x_PC, "PC", m_PCL).mask(0xfff).formatstr("%03X"); + state_add( PIC16X8x_W, "W", m_W).formatstr("%02X"); + state_add( PIC16X8x_ALU, "ALU", m_ALU).formatstr("%02X"); + state_add( PIC16X8x_WDT, "WDT", m_WDT).formatstr("%04X"); + state_add( PIC16X8x_CONFIG, "CNF", m_CONFIG).formatstr("%04X"); + state_add( PIC16X8x_PSCL, "PSCL", m_debugger_temp).callimport().formatstr("%3s"); + + state_add( STATE_GENPC, "GENPC", m_PCL).noshow(); + state_add( STATE_GENPCBASE, "CURPC", m_PREVPC).noshow(); + state_add( STATE_GENFLAGS, "GENFLAGS", m_OPTION).formatstr("%13s").noshow(); + + set_icountptr(m_icount); +} + + +void pic16x8x_device::state_import(const device_state_entry &entry) +{ + switch (entry.index()) + { + case PIC16X8x_PSCL: + m_prescaler = m_debugger_temp; + break; + } +} + +void pic16x8x_device::state_export(const device_state_entry &entry) +{ + switch (entry.index()) + { + } +} + +void pic16x8x_device::state_string_export(const device_state_entry &entry, std::string &str) const +{ + switch (entry.index()) + { + case PIC16X8x_PSCL: + str = string_format("%c%02X", ((m_OPTION & 0x08) ? 'W' : 'T'), m_prescaler); + break; + + case STATE_GENFLAGS: + str = string_format("%01x%c%c%c%c%c %c%c%c%03x", + (m_STATUS & 0xe0) >> 5, + m_STATUS & 0x10 ? '.':'O', // WDT Overflow + m_STATUS & 0x08 ? 'P':'D', // Power/Down + m_STATUS & 0x04 ? 'Z':'.', // Zero + m_STATUS & 0x02 ? 'c':'b', // Nibble Carry/Borrow + m_STATUS & 0x01 ? 'C':'B', // Carry/Borrow + + m_OPTION & 0x20 ? 'C':'T', // Counter/Timer + m_OPTION & 0x10 ? 'N':'P', // Negative/Positive + m_OPTION & 0x08 ? 'W':'T', // WatchDog/Timer + m_OPTION & 0x08 ? (1<<(m_OPTION&7)) : (2<<(m_OPTION&7))); + break; + } +} + + +/**************************************************************************** + * Reset registers to their initial values + ****************************************************************************/ + +void pic16x8x_device::reset_regs() +{ + set_pc(RESET_VECTOR); + m_port_tris[PORTA] = 0x1f; + m_port_tris[PORTB] = 0xff; + m_OPTION = T0CS_FLAG | T0SE_FLAG | PSA_FLAG | PS_REG; + m_PREVPC = m_PCL; + m_STATUS = 0x18; + m_PCL = 0; + m_prescaler = 0; + m_delay_timer = 0; + m_inst_cycles = 0; + m_count_cycles = 0; + m_stack_pointer = 0; + m_portb_chdetect_temp = 0xff; + m_old_RB0 = 0; +} + +void pic16x8x_device::set_config(u16 data) +{ + logerror("Writing %04x to the PIC16x8x configuration bits\n", data); + m_CONFIG = (data & 0x3fff); +} + +void pic16x8x_device::watchdog_reset() +{ + SET(m_STATUS, TO_FLAG | PD_FLAG | Z_FLAG | DC_FLAG | C_FLAG); + reset_regs(); +} + +void pic16x8x_device::device_reset() +{ + reset_regs(); + CLR(m_STATUS, RP0_FLAG); + CLR(m_STATUS, RP1_FLAG); + + // Setting TO_FLAG from Config Word + if (WDTE) + SET(m_STATUS, TO_FLAG); + else + CLR(m_STATUS, TO_FLAG); + + SET(m_STATUS, PD_FLAG); + store_regfile(3, m_STATUS); + store_regfile(4, m_FSR); +} + + +/**************************************************************************** + * WatchDog + ****************************************************************************/ + +void pic16x8x_device::update_watchdog(int counts) +{ + /* + WatchDog is set up to count 18,000 (0x464f hex) ticks to provide + the timeout period of 0.018ms based on a 4MHz input clock. + Note: the 4MHz clock should be divided by the PIC16C5x_CLOCK_DIVIDER + which effectively makes the PIC run at 1MHz internally. + + If the current instruction is CLRWDT or SLEEP, don't update the WDT + */ + + if ((m_opcode.w != 3) && (m_opcode.w != 4)) + { + u16 old_WDT = m_WDT; + + m_WDT -= counts; + + if (m_WDT > 0x464f) + { + m_WDT = 0x464f - (0xffff - m_WDT); + } + + if (((old_WDT != 0) && (old_WDT < m_WDT)) || (m_WDT == 0)) + { + if (PSA) + { + m_prescaler++; + if (m_prescaler >= (1 << PS)) + { // Prescale values from 1 to 128 + m_prescaler = 0; + CLR(m_STATUS, TO_FLAG); + watchdog_reset(); + } + } + else + { + CLR(m_STATUS, TO_FLAG); + watchdog_reset(); + } + } + } +} + + +/**************************************************************************** + * Update Timer + ****************************************************************************/ + +void pic16x8x_device::update_timer(int counts) +{ + if (m_delay_timer > 0) + { // Timer increment is inhibited + int dt = m_delay_timer; + m_delay_timer -= m_inst_cycles; + counts -= dt; + } + + if (m_delay_timer > 0 || counts <= 0) + return; + + if (PSA == 0) + { // if PSA is cleared, prescaler is assigned to timer + m_prescaler += counts; + if (m_prescaler >= (2 << PS)) + { // Prescale values from 2 to 256 + m_TMR0 += (m_prescaler / (2 << PS)); + if(m_TMR0 == 0) + SET(m_INTCON, T0IF_FLAG); + m_prescaler %= (2 << PS); // Overflow prescaler + } + } + else + { + m_TMR0 += counts; + if(m_TMR0 == 0) + SET(m_INTCON, T0IF_FLAG); + } +} + +void pic16x8x_device::execute_set_input(int line, int state) +{ + u8 RB0_in; + switch (line) + { + // RTCC/RA4_T0CKI pin + case PIC16x8x_T0CKI: + if (T0CS && state != m_rtcc) + { // Count mode, edge triggered + if ((T0SE && !state) || (!T0SE && state)) + m_count_cycles++; + } + m_rtcc = state; + break; + + case PIC16x8x_RB0INT: + RB0_in = state; + if (INTEDG) + { /* Interrupt on Rising edge RB0 input */ + if (RISING_EDGE_RB0) + { + SET(m_INTCON, INTF_FLAG); + } + } + else + { /* Interrupt on Falling edge RB0 input */ + if (FALLING_EDGE_RB0) + { + SET(m_INTCON, INTF_FLAG); + } + } + m_old_RB0 = RB0_in; + break; + + default: + break; + } +} + +/*------------------------------------------------- + check_irqs - check for and process IRQs +-------------------------------------------------*/ + +void pic16x8x_device::check_irqs() +{ + // if something is in progress, we do nothing + if (m_irq_in_progress) + return; + + if (m_read_port[PORTB](PORTB, 0xf0) != m_portb_chdetect_temp) + { + m_portb_chdetect_temp = m_read_port[PORTB](PORTB, 0xf0); + SET(m_INTCON, RBIF_FLAG); + } + else if (GIE && RBIE && RBIF) + { + push_stack(m_PCL); + set_pc(INT_VECTOR); + standard_irq_callback(0, m_PCL); + m_irq_in_progress = true; + } + else if (GIE && INTE && INTF) + { + push_stack(m_PCL); + set_pc(INT_VECTOR); + standard_irq_callback(1, m_PCL); + m_irq_in_progress = true; + } + else if (GIE && T0IE && T0IF) + { + push_stack(m_PCL); + set_pc(INT_VECTOR); + standard_irq_callback(2, m_PCL); + m_irq_in_progress = true; + } + else if (GIE && EEIE && EEIF) + { + push_stack(m_PCL); + set_pc(INT_VECTOR); + standard_irq_callback(3, m_PCL); + m_irq_in_progress = true; + } +} + + +/**************************************************************************** + * Execute IPeriod. Return 0 if emulation should be stopped + ****************************************************************************/ + +void pic16x8x_device::execute_run() +{ + do + { + // check interrupts + check_irqs(); + + if (PD == 0) + { // Sleep Mode + m_count_cycles = 0; + m_inst_cycles = 1; + debugger_instruction_hook(m_PCL); + } + else + { + m_PREVPC = m_PCL; + + debugger_instruction_hook(m_PCL); + + m_opcode.w = m_program.read_word(m_PCL); + set_pc(m_PCL + 1); + + if ( (m_opcode.w & 0x3f80) != 0x0000) + { // Do all opcodes except the 00? ones + m_inst_cycles = s_opcode_main[((m_opcode.w >> 7) & 0x7f)].cycles; + (this->*s_opcode_main[((m_opcode.w >> 7) & 0x7f)].function)(); + } + else + { // Opcode 0x00? has many opcodes in its minor nibble + m_inst_cycles = s_opcode_00x[(m_opcode.b.l & 0x7f)].cycles; + (this->*s_opcode_00x[(m_opcode.b.l & 0x7f)].function)(); + } + + update_timer(T0CS ? m_count_cycles : m_inst_cycles); + m_count_cycles = 0; + } + + if (WDTE) + { + update_watchdog(m_inst_cycles); + } + + m_icount -= m_inst_cycles; + + } while (m_icount > 0); +} diff --git a/src/devices/cpu/pic16x8x/pic16x8x.h b/src/devices/cpu/pic16x8x/pic16x8x.h index 52456dbb3d6..3fae420ef3b 100644 --- a/src/devices/cpu/pic16x8x/pic16x8x.h +++ b/src/devices/cpu/pic16x8x/pic16x8x.h @@ -1,319 +1,319 @@ -// license:BSD-3-Clause -// copyright-holders:Grull Osgo -/************************************************************************ - - Microchip PIC16x8x Emulator - - Based on MAME's PIC16C5x/62x cpu devices developed by Tony La Porta - and improvements to SFR's accesss made by ajrhacker. - - -************************************************************************/ - -#ifndef MAME_CPU_PIC16X8X_PIC16X8X_H -#define MAME_CPU_PIC16X8X_PIC16X8X_H - -#pragma once - -// input lines -enum -{ - PIC16x8x_T0CKI = 0, - PIC16x8x_RB0INT -}; - -DECLARE_DEVICE_TYPE(PIC16CR83, pic16cr83_device) -DECLARE_DEVICE_TYPE(PIC16CR84, pic16cr84_device) -DECLARE_DEVICE_TYPE(PIC16F83, pic16f83_device) -DECLARE_DEVICE_TYPE(PIC16F84, pic16f84_device) -DECLARE_DEVICE_TYPE(PIC16F84A, pic16f84a_device) - -class pic16x8x_device : public cpu_device, public device_nvram_interface -{ - -// i/o ports - enum - { - PORTA = 0, - PORTB - }; - -public: - // port a, 5 bits, 2-way - auto read_a() { return m_read_port[PORTA].bind(); } - auto write_a() { return m_write_port[PORTA].bind(); } - - // port b, 8 bits, 2-way - auto read_b() { return m_read_port[PORTB].bind(); } - auto write_b() { return m_write_port[PORTB].bind(); } - - /**************************************************************************** - * Function to configure the CONFIG register. This is actually hard-wired - * during ROM programming, so should be called in the driver INIT, with - * the value if known (available in HEX dumps of the ROM). - ****************************************************************************/ - void set_config(u16 data); - - void core_regs(address_map &map, u8 mirror = 0); - - void ram_6(address_map &map); - void rom_9(address_map &map); - void ram_7(address_map &map); - void rom_10(address_map &map); - -protected: - // construction/destruction - pic16x8x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int program_width, address_map_constructor program_map, address_map_constructor data_map); - - // device-level overrides - virtual void device_start() override; - virtual void device_reset() override; - - // device_execute_interface overrides - /************************************************************************** - * Internal Clock divisor - * - * External Clock is divided internally by 4 for the instruction cycle - * times. (Each instruction cycle passes through 4 machine states). This - * is handled by the cpu execution engine. - **************************************************************************/ - virtual u64 execute_clocks_to_cycles(u64 clocks) const noexcept override { return (clocks + 4 - 1) / 4; } - virtual u64 execute_cycles_to_clocks(u64 cycles) const noexcept override { return (cycles * 4); } - virtual u32 execute_min_cycles() const noexcept override { return 1; } - virtual u32 execute_max_cycles() const noexcept override { return 2; } - virtual u32 execute_input_lines() const noexcept override { return 1; } - virtual bool execute_input_edge_triggered(int inputnum) const noexcept override { return inputnum == PIC16x8x_T0CKI; } - virtual void execute_run() override; - virtual void execute_set_input(int line, int state) override; - - // device_memory_interface overrides - virtual space_config_vector memory_space_config() const override; - - // device_nvram_interface implementation - virtual bool nvram_read(util::read_stream &file) override; - virtual bool nvram_write(util::write_stream &file) override; - virtual void nvram_default() override; - - // device_state_interface overrides - virtual void state_import(const device_state_entry &entry) override; - virtual void state_export(const device_state_entry &entry) override; - virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; - - // device_disasm_interface overrides - virtual std::unique_ptr create_disassembler() override; - - u8 m_eeprom_data[0x40]; - u16 m_buff[0x40]; - - optional_memory_region m_region; - - // address spaces - address_space_config m_program_config; - address_space_config m_data_config; - - int m_program_width; - -private: - - memory_access<13, 1, -1, ENDIANNESS_LITTLE>::cache m_program; - memory_access< 8, 0, 0, ENDIANNESS_LITTLE>::specific m_data; - - /******************** CPU Internal Registers *******************/ - u16 m_PCL; - u16 m_PREVPC; - u8 m_W; - u8 m_OPTION; - u16 m_CONFIG; - u8 m_ALU; - u16 m_WDT; - u8 m_TMR0; - u8 m_STATUS; - u8 m_FSR; - u8 m_EEDATA; - u8 m_EEADR; - u8 m_PCLATH; - u8 m_INTCON; - u8 m_EECON1; - u8 m_EECON2; - u8 m_port_data[2]; - u8 m_port_tris[2]; - u16 m_STACK[8]; - u16 m_prescaler; // Note: this is really an 8-bit register - PAIR16 m_opcode; - int m_icount; - int m_delay_timer; - int m_rtcc; - u8 m_count_cycles; - u8 m_data_mask; - u16 m_program_mask; - u8 m_status_mask; - u8 m_inst_cycles; - u8 m_stack_pointer; - u8 m_old_RB0; - u8 m_portb_chdetect_temp; - bool m_irq_in_progress; - - const u8 m_internal_eeprom_size = 0x40; - - // i/o handlers - devcb_read8::array<2> m_read_port; - devcb_write8::array<2> m_write_port; - - // For debugger - int m_debugger_temp; - - // opcode table entry - typedef void (pic16x8x_device::*pic16x8x_ophandler)(); - struct pic16x8x_opcode - { - u8 cycles; - pic16x8x_ophandler function; - }; - - static const pic16x8x_opcode s_opcode_main[128]; - static const pic16x8x_opcode s_opcode_00x[128]; - - void check_irqs(); - - // EEPROM data access - u8 m_eeread(offs_t offs); - void m_eewrite(offs_t offs, u8 data); - - //void update_internalram_ptr(); - void calc_zero_flag(); - void calc_add_flags(u8 augend); - void calc_sub_flags(u8 minuend); - u16 pop_stack(); - void push_stack(u16 data); - void set_pc(u16 addr); - u8 get_regfile(u8 addr); - void store_regfile(u8 addr, u8 data); - void store_result(u8 addr, u8 data); - u8 tmr0_r(); - void tmr0_w(u8 data); - u8 pcl_r(); - void pcl_w(u8 data); - u8 status_r(); - void status_w(u8 data); - u8 fsr_r(); - void fsr_w(u8 data); - u8 porta_r(); - void porta_w(u8 data); - u8 portb_r(); - void portb_w(u8 data); - u8 eedata_r(); - void eedata_w(u8 data); - u8 eeadr_r(); - void eeadr_w(u8 data); - u8 pclath_r(); - void pclath_w(u8 data); - u8 intcon_r(); - void intcon_w(u8 data); - u8 trisa_r(); - void trisa_w(u8 data); - u8 trisb_r(); - void trisb_w(u8 data); - u8 eecon1_r(); - void eecon1_w(u8 data); - u8 eecon2_r(); - void eecon2_w(u8 data); - u8 option_r(); - void option_w(u8 data); - void reset_regs(); - void watchdog_reset(); - void update_watchdog(int counts); - void update_timer(int counts); - - void illegal(); - void addlw(); // new for 16x8x - void addwf(); - void andwf(); - void andlw(); - void bcf(); - void bsf(); - void btfss(); - void btfsc(); - void call(); - void clrw(); - void clrf(); - void clrwdt(); - void comf(); - void decf(); - void decfsz(); - void goto_op(); - void incf(); - void incfsz(); - void iorlw(); - void iorwf(); - void movf(); - void movlw(); - void movwf(); - void nop(); - void retfie(); // new for 16x8x - void retlw(); - void retrn(); // new for 16x8x - can´t use return as mnemonic - Others PIC's uses "returns", should I use it? - void rlf(); - void rrf(); - void sleepic(); - void sublw(); // new for 16x8x - void subwf(); - void swapf(); - void xorlw(); - void xorwf(); -}; - - -class pic16x83_device : public pic16x8x_device -{ -public: - // construction/destruction - pic16x83_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); //, int program_width); -}; - -class pic16x84_device : public pic16x8x_device -{ -public: - // construction/destruction - pic16x84_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); //, int program_width); -}; - -class pic16cr83_device : public pic16x83_device -{ -public: - // construction/destruction - pic16cr83_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); -}; - - -class pic16cr84_device : public pic16x84_device -{ -public: - // construction/destruction - pic16cr84_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); -}; - - -class pic16f83_device : public pic16x83_device -{ -public: - // construction/destruction - pic16f83_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); -}; - - -class pic16f84_device : public pic16x84_device -{ -public: - // construction/destruction - pic16f84_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); -}; - - -class pic16f84a_device : public pic16x84_device -{ -public: - // construction/destruction - pic16f84a_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); -}; - -#endif // MAME_CPU_PIC16X8X_PIC16X8X_H +// license:BSD-3-Clause +// copyright-holders:Grull Osgo +/************************************************************************ + + Microchip PIC16x8x Emulator + + Based on MAME's PIC16C5x/62x cpu devices developed by Tony La Porta + and improvements to SFR's accesss made by ajrhacker. + + +************************************************************************/ + +#ifndef MAME_CPU_PIC16X8X_PIC16X8X_H +#define MAME_CPU_PIC16X8X_PIC16X8X_H + +#pragma once + +// input lines +enum +{ + PIC16x8x_T0CKI = 0, + PIC16x8x_RB0INT +}; + +DECLARE_DEVICE_TYPE(PIC16CR83, pic16cr83_device) +DECLARE_DEVICE_TYPE(PIC16CR84, pic16cr84_device) +DECLARE_DEVICE_TYPE(PIC16F83, pic16f83_device) +DECLARE_DEVICE_TYPE(PIC16F84, pic16f84_device) +DECLARE_DEVICE_TYPE(PIC16F84A, pic16f84a_device) + +class pic16x8x_device : public cpu_device, public device_nvram_interface +{ + +// i/o ports + enum + { + PORTA = 0, + PORTB + }; + +public: + // port a, 5 bits, 2-way + auto read_a() { return m_read_port[PORTA].bind(); } + auto write_a() { return m_write_port[PORTA].bind(); } + + // port b, 8 bits, 2-way + auto read_b() { return m_read_port[PORTB].bind(); } + auto write_b() { return m_write_port[PORTB].bind(); } + + /**************************************************************************** + * Function to configure the CONFIG register. This is actually hard-wired + * during ROM programming, so should be called in the driver INIT, with + * the value if known (available in HEX dumps of the ROM). + ****************************************************************************/ + void set_config(u16 data); + + void core_regs(address_map &map, u8 mirror = 0); + + void ram_6(address_map &map); + void rom_9(address_map &map); + void ram_7(address_map &map); + void rom_10(address_map &map); + +protected: + // construction/destruction + pic16x8x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int program_width, address_map_constructor program_map, address_map_constructor data_map); + + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + + // device_execute_interface overrides + /************************************************************************** + * Internal Clock divisor + * + * External Clock is divided internally by 4 for the instruction cycle + * times. (Each instruction cycle passes through 4 machine states). This + * is handled by the cpu execution engine. + **************************************************************************/ + virtual u64 execute_clocks_to_cycles(u64 clocks) const noexcept override { return (clocks + 4 - 1) / 4; } + virtual u64 execute_cycles_to_clocks(u64 cycles) const noexcept override { return (cycles * 4); } + virtual u32 execute_min_cycles() const noexcept override { return 1; } + virtual u32 execute_max_cycles() const noexcept override { return 2; } + virtual u32 execute_input_lines() const noexcept override { return 1; } + virtual bool execute_input_edge_triggered(int inputnum) const noexcept override { return inputnum == PIC16x8x_T0CKI; } + virtual void execute_run() override; + virtual void execute_set_input(int line, int state) override; + + // device_memory_interface overrides + virtual space_config_vector memory_space_config() const override; + + // device_nvram_interface implementation + virtual bool nvram_read(util::read_stream &file) override; + virtual bool nvram_write(util::write_stream &file) override; + virtual void nvram_default() override; + + // device_state_interface overrides + virtual void state_import(const device_state_entry &entry) override; + virtual void state_export(const device_state_entry &entry) override; + virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; + + // device_disasm_interface overrides + virtual std::unique_ptr create_disassembler() override; + + u8 m_eeprom_data[0x40]; + u16 m_buff[0x40]; + + optional_memory_region m_region; + + // address spaces + address_space_config m_program_config; + address_space_config m_data_config; + + int m_program_width; + +private: + + memory_access<13, 1, -1, ENDIANNESS_LITTLE>::cache m_program; + memory_access< 8, 0, 0, ENDIANNESS_LITTLE>::specific m_data; + + /******************** CPU Internal Registers *******************/ + u16 m_PCL; + u16 m_PREVPC; + u8 m_W; + u8 m_OPTION; + u16 m_CONFIG; + u8 m_ALU; + u16 m_WDT; + u8 m_TMR0; + u8 m_STATUS; + u8 m_FSR; + u8 m_EEDATA; + u8 m_EEADR; + u8 m_PCLATH; + u8 m_INTCON; + u8 m_EECON1; + u8 m_EECON2; + u8 m_port_data[2]; + u8 m_port_tris[2]; + u16 m_STACK[8]; + u16 m_prescaler; // Note: this is really an 8-bit register + PAIR16 m_opcode; + int m_icount; + int m_delay_timer; + int m_rtcc; + u8 m_count_cycles; + u8 m_data_mask; + u16 m_program_mask; + u8 m_status_mask; + u8 m_inst_cycles; + u8 m_stack_pointer; + u8 m_old_RB0; + u8 m_portb_chdetect_temp; + bool m_irq_in_progress; + + const u8 m_internal_eeprom_size = 0x40; + + // i/o handlers + devcb_read8::array<2> m_read_port; + devcb_write8::array<2> m_write_port; + + // For debugger + int m_debugger_temp; + + // opcode table entry + typedef void (pic16x8x_device::*pic16x8x_ophandler)(); + struct pic16x8x_opcode + { + u8 cycles; + pic16x8x_ophandler function; + }; + + static const pic16x8x_opcode s_opcode_main[128]; + static const pic16x8x_opcode s_opcode_00x[128]; + + void check_irqs(); + + // EEPROM data access + u8 m_eeread(offs_t offs); + void m_eewrite(offs_t offs, u8 data); + + //void update_internalram_ptr(); + void calc_zero_flag(); + void calc_add_flags(u8 augend); + void calc_sub_flags(u8 minuend); + u16 pop_stack(); + void push_stack(u16 data); + void set_pc(u16 addr); + u8 get_regfile(u8 addr); + void store_regfile(u8 addr, u8 data); + void store_result(u8 addr, u8 data); + u8 tmr0_r(); + void tmr0_w(u8 data); + u8 pcl_r(); + void pcl_w(u8 data); + u8 status_r(); + void status_w(u8 data); + u8 fsr_r(); + void fsr_w(u8 data); + u8 porta_r(); + void porta_w(u8 data); + u8 portb_r(); + void portb_w(u8 data); + u8 eedata_r(); + void eedata_w(u8 data); + u8 eeadr_r(); + void eeadr_w(u8 data); + u8 pclath_r(); + void pclath_w(u8 data); + u8 intcon_r(); + void intcon_w(u8 data); + u8 trisa_r(); + void trisa_w(u8 data); + u8 trisb_r(); + void trisb_w(u8 data); + u8 eecon1_r(); + void eecon1_w(u8 data); + u8 eecon2_r(); + void eecon2_w(u8 data); + u8 option_r(); + void option_w(u8 data); + void reset_regs(); + void watchdog_reset(); + void update_watchdog(int counts); + void update_timer(int counts); + + void illegal(); + void addlw(); // new for 16x8x + void addwf(); + void andwf(); + void andlw(); + void bcf(); + void bsf(); + void btfss(); + void btfsc(); + void call(); + void clrw(); + void clrf(); + void clrwdt(); + void comf(); + void decf(); + void decfsz(); + void goto_op(); + void incf(); + void incfsz(); + void iorlw(); + void iorwf(); + void movf(); + void movlw(); + void movwf(); + void nop(); + void retfie(); // new for 16x8x + void retlw(); + void retrn(); // new for 16x8x - can´t use return as mnemonic - Others PIC's uses "returns", should I use it? + void rlf(); + void rrf(); + void sleepic(); + void sublw(); // new for 16x8x + void subwf(); + void swapf(); + void xorlw(); + void xorwf(); +}; + + +class pic16x83_device : public pic16x8x_device +{ +public: + // construction/destruction + pic16x83_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); //, int program_width); +}; + +class pic16x84_device : public pic16x8x_device +{ +public: + // construction/destruction + pic16x84_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); //, int program_width); +}; + +class pic16cr83_device : public pic16x83_device +{ +public: + // construction/destruction + pic16cr83_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); +}; + + +class pic16cr84_device : public pic16x84_device +{ +public: + // construction/destruction + pic16cr84_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); +}; + + +class pic16f83_device : public pic16x83_device +{ +public: + // construction/destruction + pic16f83_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); +}; + + +class pic16f84_device : public pic16x84_device +{ +public: + // construction/destruction + pic16f84_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); +}; + + +class pic16f84a_device : public pic16x84_device +{ +public: + // construction/destruction + pic16f84a_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); +}; + +#endif // MAME_CPU_PIC16X8X_PIC16X8X_H diff --git a/src/devices/cpu/z80/z80dasm.cpp b/src/devices/cpu/z80/z80dasm.cpp index 6970d55c28d..5f76a8d2f64 100644 --- a/src/devices/cpu/z80/z80dasm.cpp +++ b/src/devices/cpu/z80/z80dasm.cpp @@ -23,7 +23,7 @@ static const char *const s_mnemonic[] = "rrc" ,"rrca","rrd" ,"rst" ,"sbc" ,"scf" ,"set" ,"sla" , "sll" ,"sra" ,"srl" ,"sub" ,"xor " // z80n - ,"swap","mirr","test", + ,"swap","mirr","test", "bsla","bsra","bsrl","bsrf","brlc","mul" ,"otib","nreg", "pxdn","pxad","stae","ldix","ldws","lddx","lirx","lprx", "ldrx" @@ -41,7 +41,7 @@ const u32 z80_disassembler::s_flags[] = 0 ,0 ,0 ,STEP_OVER,0 ,0 ,0 ,0 , 0 ,0 ,0 ,0 ,0 // z80n - ,0 ,0 ,0 , + ,0 ,0 ,0 , 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , 0 diff --git a/src/devices/cpu/z80/z80dasm.h b/src/devices/cpu/z80/z80dasm.h index aa4f8fb43e1..0a8983e3f15 100644 --- a/src/devices/cpu/z80/z80dasm.h +++ b/src/devices/cpu/z80/z80dasm.h @@ -41,7 +41,7 @@ protected: zRRC ,zRRCA ,zRRD ,zRST ,zSBC ,zSCF ,zSET ,zSLA , zSLL ,zSRA ,zSRL ,zSUB ,zXOR // z80n - ,zSWAP ,zMIRR ,zTEST , + ,zSWAP ,zMIRR ,zTEST , zBSLA ,zBSRA ,zBSRL ,zBSRF ,zBRLC ,zMUL ,zOTIB ,zNREG , zPXDN ,zPXAD ,zSTAE ,zLDIX ,zLDWS ,zLDDX ,zLIRX ,zLPRX , zLDRX diff --git a/src/mame/alpha/equites.cpp b/src/mame/alpha/equites.cpp index 71ef414a0d3..5a2835fdbc2 100644 --- a/src/mame/alpha/equites.cpp +++ b/src/mame/alpha/equites.cpp @@ -555,8 +555,8 @@ TIMER_DEVICE_CALLBACK_MEMBER(equites_state::scanline_cb) { int scanline = param; - // all games but bullfgtr have both valid - // bullfgtr definitely expects to vblank from 2, reversing will make it to run at half speed. + // all games but bullfgtr have both valid + // bullfgtr definitely expects to vblank from 2, reversing will make it to run at half speed. if(scanline == 232) // vblank-in irq m_maincpu->set_input_line(2, HOLD_LINE); diff --git a/src/mame/alpha/splendor.cpp b/src/mame/alpha/splendor.cpp index 25b10e4e788..a05f7f2162c 100644 --- a/src/mame/alpha/splendor.cpp +++ b/src/mame/alpha/splendor.cpp @@ -400,12 +400,12 @@ TIMER_DEVICE_CALLBACK_MEMBER(splendor_state::scanline_cb) { int scanline = param; - // vblank-in irq + // vblank-in irq if(scanline == 224) m_maincpu->set_input_line(2, HOLD_LINE); - // vblank-out irq or sprite DMA end, applies bg scroll writes - // and checks debug flag (if available) for screen freeze. + // vblank-out irq or sprite DMA end, applies bg scroll writes + // and checks debug flag (if available) for screen freeze. if(scanline == 32) m_maincpu->set_input_line(1, HOLD_LINE); } diff --git a/src/mame/apple/macquadra630.cpp b/src/mame/apple/macquadra630.cpp index 1d27f000d70..825c9923d92 100644 --- a/src/mame/apple/macquadra630.cpp +++ b/src/mame/apple/macquadra630.cpp @@ -29,7 +29,7 @@ the 53C96's transfer count is zero. The earlier ROM has the same logic as previous (and later!) 53C96 machines and works fine. - Video in chips + Video in chips ****************************************************************************/ diff --git a/src/mame/aristocrat/caswin.cpp b/src/mame/aristocrat/caswin.cpp index ecdfbb0136e..a2db6684e80 100644 --- a/src/mame/aristocrat/caswin.cpp +++ b/src/mame/aristocrat/caswin.cpp @@ -171,7 +171,7 @@ uint32_t caswin_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap m_tilemap->set_scroll_rows(32); // TODO: still some cutoffs / object change flashing - // goofy rowscroll, expects to wraparound over its own canvas ... + // goofy rowscroll, expects to wraparound over its own canvas ... for (int i = 0; i < 32; i ++) { const u16 scroll_data = m_vram[i]; diff --git a/src/mame/benesse/challenge_gear.cpp b/src/mame/benesse/challenge_gear.cpp index 84c4fb86f38..26d97712c0b 100644 --- a/src/mame/benesse/challenge_gear.cpp +++ b/src/mame/benesse/challenge_gear.cpp @@ -37,7 +37,7 @@ A04 --|16 17|-- A03 -------- */ - + namespace { class challenge_gear_state : public driver_device diff --git a/src/mame/bmc/popobear.cpp b/src/mame/bmc/popobear.cpp index 33104f7a4ca..c553d00a430 100644 --- a/src/mame/bmc/popobear.cpp +++ b/src/mame/bmc/popobear.cpp @@ -442,7 +442,7 @@ void popobear_state::main_map(address_map &map) map(0x280000, 0x2fffff).ram().share("spriteram"); // unknown boundaries map(0x300000, 0x3fffff).ram().w(FUNC(popobear_state::vram_w)).share("vram"); // tile definitions + tilemaps - // TODO: is the 48xxxx block entirely from AIA90423? + // TODO: is the 48xxxx block entirely from AIA90423? map(0x480000, 0x48001f).ram().share("vregs"); map(0x480031, 0x480031).w(FUNC(popobear_state::irq_ack_w)); map(0x480034, 0x480035).nopr(); // uses bset/bclr to write, which causes a read (ignored) diff --git a/src/mame/kaneko/expro02.cpp b/src/mame/kaneko/expro02.cpp index febb62eb1b5..1e03062778d 100644 --- a/src/mame/kaneko/expro02.cpp +++ b/src/mame/kaneko/expro02.cpp @@ -916,8 +916,8 @@ uint8_t expro02_state::comad_okim6295_r() void expro02_state::expro02(machine_config &config) { - static constexpr XTAL CPU_CLOCK = XTAL(12'000'000); - static constexpr XTAL VDP_CLOCK = XTAL(16'000'000); + static constexpr XTAL CPU_CLOCK = XTAL(12'000'000); + static constexpr XTAL VDP_CLOCK = XTAL(16'000'000); /* basic machine hardware */ M68000(config, m_maincpu, CPU_CLOCK); @@ -926,7 +926,7 @@ void expro02_state::expro02(machine_config &config) /* video hardware */ SCREEN(config, m_screen, SCREEN_TYPE_RASTER); - m_screen->set_raw(VDP_CLOCK / 3, 341, 0, 256, 262, 0, 224); // ~60 Hz + m_screen->set_raw(VDP_CLOCK / 3, 341, 0, 256, 262, 0, 224); // ~60 Hz m_screen->set_screen_update(FUNC(expro02_state::screen_update)); m_screen->set_palette(m_palette); @@ -971,7 +971,7 @@ void expro02_state::comad(machine_config &config) m_view2->set_invert_flip(1); m_view2->set_offset(-256, -216, 256, 224); - // FIXME: can't be 0 seconds + // FIXME: can't be 0 seconds subdevice("watchdog")->set_time(attotime::from_seconds(0)); } diff --git a/src/mame/misc/magicard.cpp b/src/mame/misc/magicard.cpp index 3beab19dc5a..c0165e17418 100644 --- a/src/mame/misc/magicard.cpp +++ b/src/mame/misc/magicard.cpp @@ -1103,7 +1103,7 @@ void hotslots_state::magicle(machine_config &config) { hotslots_base(config); - pic16f84_device &pic(PIC16F84(config, "pic16f84", 4000000)); + pic16f84_device &pic(PIC16F84(config, "pic16f84", 4000000)); pic.set_config(0x3ffa); // No protect - No Watchdog - HS Clock pic.read_b().set(FUNC(hotslots_state::pic_portb_r)); pic.write_b().set(FUNC(hotslots_state::pic_portb_w)); @@ -1657,7 +1657,7 @@ ROM_START( quingo ) ROM_REGION( 0x0200, "sereeprom", 0 ) // Serial EPROM ROM_LOAD16_WORD_SWAP("quingo_24c04a.bin", 0x0000, 0x0200, BAD_DUMP CRC(d5e82b49) SHA1(7dbdf7d539cbd59a3ac546b6f50861c4958abb3a) ) // all AA & 55 - + ROM_REGION16_LE( 0x4280, "pic16f84", 0 ) // borrowed from magicle to avoid I2C bus error ROM_LOAD("magicle_5.03_pic16f84_code.bin", 0x0000, 0x0800, BAD_DUMP CRC(22965864) SHA1(c421a9e9fac7c9c5dc01adda620dc8f5f16d94ba) ) ROM_END @@ -1747,7 +1747,7 @@ ROM_START( bigdeal0 ) ROM_REGION( 0x0200, "sereeprom", 0 ) // Serial EPROM ROM_LOAD16_WORD_SWAP("big_deal_24c04a.bin", 0x0000, 0x0200, BAD_DUMP CRC(d5e82b49) SHA1(7dbdf7d539cbd59a3ac546b6f50861c4958abb3a) ) // all AA & 55 - + ROM_REGION16_LE( 0x4280, "pic16f84", 0 ) // borrowed from magicle to avoid I2C bus error ROM_LOAD("magicle_5.03_pic16f84_code.bin", 0x0000, 0x0800, BAD_DUMP CRC(22965864) SHA1(c421a9e9fac7c9c5dc01adda620dc8f5f16d94ba) ) ROM_END @@ -1837,7 +1837,7 @@ ROM_START( belslots ) ROM_REGION( 0x0200, "sereeprom", 0 ) // Serial EPROM ROM_LOAD16_WORD_SWAP("bel_slots_exp_24c04a.bin", 0x0000, 0x0200, BAD_DUMP CRC(d5e82b49) SHA1(7dbdf7d539cbd59a3ac546b6f50861c4958abb3a) ) // all AA & 55 - + ROM_REGION16_LE( 0x4280, "pic16f84", 0 ) // borrowed from magicle to avoid I2C bus error ROM_LOAD("magicle_5.03_pic16f84_code.bin", 0x0000, 0x0800, BAD_DUMP CRC(22965864) SHA1(c421a9e9fac7c9c5dc01adda620dc8f5f16d94ba) ) ROM_END diff --git a/src/mame/nec/pc8801.cpp b/src/mame/nec/pc8801.cpp index 8947d11cc13..a9c91f05291 100644 --- a/src/mame/nec/pc8801.cpp +++ b/src/mame/nec/pc8801.cpp @@ -814,7 +814,7 @@ void pc8801_state::palram_w(offs_t offset, uint8_t data) // p8suite Analog RGB test cross bars (reportedly works in 24 kHz / 80 column only) // NB: it uses a bunch of non-waitstate related opcodes to cycle time it right, // implying a stress-test for Z80 opcode cycles. - m_screen->update_partial(m_screen->vpos()); + m_screen->update_partial(m_screen->vpos()); } diff --git a/src/mame/nokia/mikromikko2.cpp b/src/mame/nokia/mikromikko2.cpp index 17c341a64f1..5d7f35ef1a9 100644 --- a/src/mame/nokia/mikromikko2.cpp +++ b/src/mame/nokia/mikromikko2.cpp @@ -229,9 +229,9 @@ void mm2_state::mm2(machine_config &config) m_pit->set_clk<1>(16_MHz_XTAL/8); m_pit->set_clk<2>(16_MHz_XTAL/8); m_pit->out_handler<0>().set(m_pic, FUNC(pic8259_device::ir0_w)); - //m_pit->out_handler<1>().set()); MPSC ch B line clock + //m_pit->out_handler<1>().set()); MPSC ch B line clock //m_pit->out_handler<2>().set()); Beep control - + I8274(config, m_mpsc, 16_MHz_XTAL/4); m_mpsc->out_int_callback().set(m_pic, FUNC(pic8259_device::ir1_w)); diff --git a/src/mame/sega/fd1094.cpp b/src/mame/sega/fd1094.cpp index 199e23762ea..c38ca087bce 100644 --- a/src/mame/sega/fd1094.cpp +++ b/src/mame/sega/fd1094.cpp @@ -24,10 +24,10 @@ The decryption can logically be split in two parts. The first part consists of a series of conditional XORs and bitswaps, controlled by the decryption key, which will be described in the next paragraph. The second part does a - replacement of several values with FFFF. This last step is done to prevent - usage of any PC-relative opcode, which would easily allow an intruder to dump - decrypted values from program space. The FFFF replacement may affect either - ~300 values or ~5000, depending on the decryption key. + replacement of several values with FFFF. This last step is done to prevent + usage of any PC-relative opcode, which would easily allow an intruder to dump + decrypted values from program space. The FFFF replacement may affect either + ~300 values or ~5000, depending on the decryption key. The main part of the decryption can itself be subdivided in five consecutive steps. The first one is executed only if bit 15 of the encrypted value is 1; diff --git a/src/mame/sinclair/chloe.cpp b/src/mame/sinclair/chloe.cpp index 111315990e0..6cb1d43e13e 100644 --- a/src/mame/sinclair/chloe.cpp +++ b/src/mame/sinclair/chloe.cpp @@ -1,7 +1,7 @@ // license:BSD-3-Clause // copyright-holders:Andrei I. Holub /********************************************************************** - Chloe 280SE + Chloe 280SE **********************************************************************/ #include "emu.h" @@ -725,7 +725,7 @@ INPUT_PORTS_START(chloe) PORT_BIT(0xe820, IP_ACTIVE_LOW, IPT_UNUSED) PORT_START("IO_LINE5") /* 0xDFFE */ - PORT_BIT(0x0001, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("p P \"") PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P') PORT_CHAR('"') + PORT_BIT(0x0001, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("p P \"") PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P') PORT_CHAR('"') PORT_BIT(0x0002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("o O ;") PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O') PORT_CHAR(';') PORT_CODE(KEYCODE_COLON) PORT_BIT(0x0004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("i I Ins") PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') diff --git a/src/mame/sinclair/specnext.cpp b/src/mame/sinclair/specnext.cpp index 28fcfc0446f..12d37074e5f 100644 --- a/src/mame/sinclair/specnext.cpp +++ b/src/mame/sinclair/specnext.cpp @@ -7,7 +7,7 @@ Issue 2B (Kickstarter 1), Issue 2D, Issue 2E, Issue 2H, Issue 4 (Kickstarter 2) Current implementation is based on Issue 4. Only limited difference - tracked through PORT_CONFIG + tracked through PORT_CONFIG TODO: * improve zxnDMA @@ -270,7 +270,7 @@ private: bool port_eff7_io_en() const { return BIT(internal_port_enable(), 26); } bool port_ctc_io_en() const { return BIT(internal_port_enable(), 27); } - u8 port_7ffd_bank() const { return (((nr_8f_mapping_mode_pentagon() || nr_8f_mapping_mode_profi()) ? 0 : BIT(m_port_dffd_data, 3)) << 6) | ((!nr_8f_mapping_mode_pentagon() ? BIT(m_port_dffd_data, 2) : (nr_8f_mapping_mode_pentagon_1024_en() && BIT(m_port_7ffd_data, 5))) << 5) | ((nr_8f_mapping_mode_pentagon() ? BIT(m_port_7ffd_data, 6, 2) : (m_port_dffd_data & 3)) << 3) | (m_port_7ffd_data & 7); } + u8 port_7ffd_bank() const { return (((nr_8f_mapping_mode_pentagon() || nr_8f_mapping_mode_profi()) ? 0 : BIT(m_port_dffd_data, 3)) << 6) | ((!nr_8f_mapping_mode_pentagon() ? BIT(m_port_dffd_data, 2) : (nr_8f_mapping_mode_pentagon_1024_en() && BIT(m_port_7ffd_data, 5))) << 5) | ((nr_8f_mapping_mode_pentagon() ? BIT(m_port_7ffd_data, 6, 2) : (m_port_dffd_data & 3)) << 3) | (m_port_7ffd_data & 7); } bool port_7ffd_shadow() const { return BIT(m_port_7ffd_data, 3); } bool port_7ffd_locked() const { return (nr_8f_mapping_mode_pentagon_1024_en() || (nr_8f_mapping_mode_profi() && BIT(m_port_dffd_data, 4))) ? 0 : BIT(m_port_7ffd_data, 5); } bool port_1ffd_special() const { return BIT(m_port_1ffd_data, 0); } @@ -2695,22 +2695,22 @@ void specnext_state::map_io(address_map &map) map(0x000b, 0x000b).mirror(0xff00).lrw8(NAME([this]() { return dma_r(1); }), NAME([this](u8 data) { dma_w(1, data); })); map(0x006b, 0x006b).mirror(0xff00).lrw8(NAME([this]() { return dma_r(0); }), NAME([this](u8 data) { dma_w(0, data); })); - map(0x0bdf, 0x0bdf).mirror(0xf000).lr8(NAME([this]() -> u8 { return m_io_mouse[0]->read(); })); // #fbdf - map(0x0fdf, 0x0fdf).mirror(0xf000).lr8(NAME([this]() -> u8 { return ~m_io_mouse[1]->read(); })); // #ffdf - map(0x0adf, 0x0adf).mirror(0xf000).lr8(NAME([this]() -> u8 { return 0x80 | (m_io_mouse[2]->read() & 0x07); })); // #fadf + map(0x0bdf, 0x0bdf).mirror(0xf000).lr8(NAME([this]() -> u8 { return m_io_mouse[0]->read(); })); // #fbdf + map(0x0fdf, 0x0fdf).mirror(0xf000).lr8(NAME([this]() -> u8 { return ~m_io_mouse[1]->read(); })); // #ffdf + map(0x0adf, 0x0adf).mirror(0xf000).lr8(NAME([this]() -> u8 { return 0x80 | (m_io_mouse[2]->read() & 0x07); })); // #fadf // TODO resolve conflicts mf+joy+DAC: 1f, 3f //map(0x001f, 0x001f).mirror(0xff00).lr8(NAME([]() -> u8 { return 0x00; /* Joy1,2*/ })).lw8(NAME([this](u8 data) { - // if (m_nr_08_dac_en) - // m_dac[0]->data_w(data); + // if (m_nr_08_dac_en) + // m_dac[0]->data_w(data); //})); map(0x00f1, 0x00f1).mirror(0xff00).lw8(NAME([this](u8 data) { if (m_nr_08_dac_en) m_dac[0]->data_w(data); })); //map(0x003f, 0x003f).mirror(0xff00).lw8(NAME([this](u8 data) { - // if (m_nr_08_dac_en) - // m_dac[0]->data_w(data); + // if (m_nr_08_dac_en) + // m_dac[0]->data_w(data); //})); map(0x000f, 0x000f).mirror(0xff00).lw8(NAME([this](u8 data) { if (m_nr_08_dac_en) @@ -3186,15 +3186,15 @@ void specnext_state::machine_reset() m_port_dffd_data = 0; m_port_eff7_data = 0; /* TODO don't use inherited - port_fe_reg = 0x00; - port_ff_reg = 0x00; - port_7ffd_reg = 0x00; - port_dffd_reg = 0x00; - port_dffd_reg_6 = 0; - port_1ffd_reg = 0x00; - port_1ffd_special_old = 0; - port_eff7_reg_2 = 0; - port_eff7_reg_3 = 0; + port_fe_reg = 0x00; + port_ff_reg = 0x00; + port_7ffd_reg = 0x00; + port_dffd_reg = 0x00; + port_dffd_reg_6 = 0; + port_1ffd_reg = 0x00; + port_1ffd_special_old = 0; + port_eff7_reg_2 = 0; + port_eff7_reg_3 = 0; */ m_nr_02_generate_mf_nmi = 0; m_nr_02_generate_divmmc_nmi = 0; diff --git a/src/mame/tch/wheelfir.cpp b/src/mame/tch/wheelfir.cpp index e497251ac22..875fed41425 100644 --- a/src/mame/tch/wheelfir.cpp +++ b/src/mame/tch/wheelfir.cpp @@ -273,7 +273,7 @@ void wheelfir_state::do_blit() float scale_u_step; float scale_v_step; - + // calculate u zoom (horizontal source scale) const int d1u = ((m_blitter_data[0x0a] & 0x1f00) >> 8) | ((m_blitter_data[0x08] & 0x0100) >> 3); @@ -301,7 +301,7 @@ void wheelfir_state::do_blit() scale_u_step = 100.f / scale_u; scale_v_step = 100.f / scale_v; - + // do the draw int y = dst_y0; @@ -833,6 +833,19 @@ void wheelfir_state::kongball(machine_config& config) } +void wheelfir_state::init_pwball() +{ + m_force_extra_irq1 = true; + //m_disable_raster_irq = true; +} + +void wheelfir_state::init_kongball() +{ + m_force_extra_irq1 = true; + m_disable_raster_irq = true; // the raster interrupt points outside of code +} + + ROM_START( wheelfir ) ROM_REGION( 0x100000, "maincpu", 0 ) // 68000 Code ROM_LOAD16_BYTE( "tch1.u19", 0x00001, 0x80000, CRC(33bbbc67) SHA1(c2ecc0ab522ee442076ea7b9536aee6e1fad0540) ) @@ -959,18 +972,6 @@ ROM_END } // anonymous namespace -void wheelfir_state::init_pwball() -{ - m_force_extra_irq1 = true; -// m_disable_raster_irq = true; -} - -void wheelfir_state::init_kongball() -{ - m_force_extra_irq1 = true; - m_disable_raster_irq = true; // the raster interrupt points outside of code -} - GAME( 199?, wheelfir, 0, wheelfir, wheelfir, wheelfir_state, empty_init, ROT0, "TCH", "Wheels & Fire", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS ) GAME( 199?, pwball, 0, wheelfir, pwball, wheelfir_state, init_pwball, ROT0, "TCH", "Power Ball (prototype)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS ) // mostly complete diff --git a/src/mame/tecmo/bombjack.cpp b/src/mame/tecmo/bombjack.cpp index b79e6beea72..c899413004d 100644 --- a/src/mame/tecmo/bombjack.cpp +++ b/src/mame/tecmo/bombjack.cpp @@ -87,10 +87,10 @@ public: protected: // constants - static XTAL constexpr CLOCK_X1 = 4_MHz_XTAL, - CLOCK_X2 = 12_MHz_XTAL; - static u16 constexpr HTOTAL = 384, HBSTART = 256, HBEND = 0, - VTOTAL = 264, VBSTART = 240, VBEND = 16; + static inline constexpr XTAL CLOCK_X1 = 4_MHz_XTAL; + static inline constexpr XTAL CLOCK_X2 = 12_MHz_XTAL; + static inline constexpr u16 HTOTAL = 384, HBSTART = 256, HBEND = 0; + static inline constexpr u16 VTOTAL = 264, VBSTART = 240, VBEND = 16; // initialization virtual void machine_start() override; @@ -313,7 +313,7 @@ TILE_GET_INFO_MEMBER(bombjack_state::get_bg_tile_info) set_bg_tile_info(attr, code, color, flipx, flipy); tileinfo.set(1, code, color, (flipx ? TILE_FLIPX : 0) | - (flipy ? TILE_FLIPY : 0)); + (flipy ? TILE_FLIPY : 0)); } void bombjack_state::set_fg_tile_info(u8 const attr, u16 &code, u8 &color, bool &flipx, bool &flipy) @@ -340,14 +340,14 @@ TILE_GET_INFO_MEMBER(bombjack_state::get_fg_tile_info) set_fg_tile_info(attr, code, color, flipx, flipy); tileinfo.set(0, code, color, (flipx ? TILE_FLIPX : 0) | - (flipy ? TILE_FLIPY : 0)); + (flipy ? TILE_FLIPY : 0)); } bool bombjack_state::large_sprite(int const index, u8 const attr) { bool const reverse = m_spritectrl[0] > m_spritectrl[1]; return (index > m_spritectrl[reverse ? 1 : 0]) && - (index <= m_spritectrl[reverse ? 0 : 1]); + (index <= m_spritectrl[reverse ? 0 : 1]); } bool calorie_state::large_sprite(int const index, u8 const attr) @@ -852,7 +852,7 @@ ROM_START( bombjack2 ) ROM_REGION( 0x2000, "bgmaps", 0 ) // schematics specify 2764, final board has a smaller ROM in place ROM_LOAD( "02_p04t.bin", 0x0000, 0x1000, CRC(398d4a02) SHA1(ac18a8219f99ba9178b96c9564de3978e39c59fd) ) - ROM_RELOAD( 0x1000, 0x1000) + ROM_RELOAD( 0x1000, 0x1000) ROM_END ROM_START( bombjackt ) diff --git a/src/mame/tecmo/gaiden.cpp b/src/mame/tecmo/gaiden.cpp index 98fb3ada0b9..0ad65156ee9 100644 --- a/src/mame/tecmo/gaiden.cpp +++ b/src/mame/tecmo/gaiden.cpp @@ -682,7 +682,7 @@ INPUT_PORTS_END static GFXDECODE_START( gfx_gaiden ) - GFXDECODE_ENTRY( "txtiles", 0, gfx_8x8x4_packed_msb, 0x100, 16 ) // tiles 8x8 + GFXDECODE_ENTRY( "txtiles", 0, gfx_8x8x4_packed_msb, 0x100, 16 ) // tiles 8x8 GFXDECODE_ENTRY( "bgtiles", 0, gfx_8x8x4_row_2x2_group_packed_msb, 0x000, 0x100 ) // tiles 16x16 GFXDECODE_ENTRY( "fgtiles", 0, gfx_8x8x4_row_2x2_group_packed_msb, 0x000, 0x100 ) // tiles 16x16 (only colors 0x00-0x0f and 0x80-0x8f are used) GFXDECODE_END @@ -714,7 +714,7 @@ static const gfx_layout mastninj_spritelayout = }; static GFXDECODE_START( gfx_mastninj ) - GFXDECODE_ENTRY( "txtiles", 0, gfx_8x8x4_packed_msb, 0x000, 16 ) // tiles 8x8 + GFXDECODE_ENTRY( "txtiles", 0, gfx_8x8x4_packed_msb, 0x000, 16 ) // tiles 8x8 GFXDECODE_ENTRY( "bgtiles", 0, mastninj_tile2layout, 0x300, 16 ) // tiles 16x16 GFXDECODE_ENTRY( "fgtiles", 0, mastninj_tile2layout, 0x200, 16 ) // tiles 16x16 GFXDECODE_ENTRY( "sprites", 0, mastninj_spritelayout, 0x100, 16 ) // sprites 16x16 @@ -743,7 +743,7 @@ static const gfx_layout drgnbowl_spritelayout = }; static GFXDECODE_START( gfx_drgnbowl ) - GFXDECODE_ENTRY( "txtiles", 0, gfx_8x8x4_packed_msb, 0, 16 ) // tiles 8x8 + GFXDECODE_ENTRY( "txtiles", 0, gfx_8x8x4_packed_msb, 0, 16 ) // tiles 8x8 GFXDECODE_ENTRY( "bgtiles", 0x00000, drgnbowl_tile2layout, 0x300, 16 ) // tiles 16x16 GFXDECODE_ENTRY( "bgtiles", 0x20000, drgnbowl_tile2layout, 0x200, 16 ) // tiles 16x16 GFXDECODE_ENTRY( "sprites", 0, drgnbowl_spritelayout, 0x100, 16 ) // sprites 16x16 @@ -1058,7 +1058,7 @@ ROM_START( shadoww ) ROM_LOAD16_BYTE( "shadowa_2.4s", 0x00001, 0x20000, CRC(f3f08921) SHA1(df6bb7302714e0eab12cbd0a7f2a4ca751a600e1) ) ROM_REGION( 0x10000, "audiocpu", 0 ) - ROM_LOAD( "gaiden_3.4b", 0x0000, 0x10000, CRC(75fd3e6a) SHA1(3333e84ed4983caa133e60a8e8895fa897ab4949) ) // Audio CPU is a Z80 + ROM_LOAD( "gaiden_3.4b", 0x0000, 0x10000, CRC(75fd3e6a) SHA1(3333e84ed4983caa133e60a8e8895fa897ab4949) ) // Audio CPU is a Z80 ROM_REGION( 0x010000, "txtiles", 0 ) ROM_LOAD( "gaiden_5.7a", 0x000000, 0x10000, CRC(8d4035f7) SHA1(3473456cdd24e312e3073586d7e8f24eb71bbea1) ) // 8x8 tiles @@ -1095,7 +1095,7 @@ ROM_START( shadowwa ) ROM_LOAD16_BYTE( "shadoww_2.4s", 0x00001, 0x20000, CRC(9b9d6b18) SHA1(75068611fb1de61120be8bf840f61d90c0dc86ca) ) ROM_REGION( 0x10000, "audiocpu", 0 ) - ROM_LOAD( "gaiden_3.4b", 0x0000, 0x10000, CRC(75fd3e6a) SHA1(3333e84ed4983caa133e60a8e8895fa897ab4949) ) // Audio CPU is a Z80 + ROM_LOAD( "gaiden_3.4b", 0x0000, 0x10000, CRC(75fd3e6a) SHA1(3333e84ed4983caa133e60a8e8895fa897ab4949) ) // Audio CPU is a Z80 ROM_REGION( 0x010000, "txtiles", 0 ) ROM_LOAD( "gaiden_5.7a", 0x000000, 0x10000, CRC(8d4035f7) SHA1(3473456cdd24e312e3073586d7e8f24eb71bbea1) ) // 8x8 tiles @@ -1132,7 +1132,7 @@ ROM_START( gaiden ) ROM_LOAD16_BYTE( "gaiden_2.4s", 0x00001, 0x20000, CRC(454f7314) SHA1(231296423870f00ea2e545faf0fbb37577430a4f) ) ROM_REGION( 0x10000, "audiocpu", 0 ) - ROM_LOAD( "gaiden_3.4b", 0x0000, 0x10000, CRC(75fd3e6a) SHA1(3333e84ed4983caa133e60a8e8895fa897ab4949) ) // Audio CPU is a Z80 + ROM_LOAD( "gaiden_3.4b", 0x0000, 0x10000, CRC(75fd3e6a) SHA1(3333e84ed4983caa133e60a8e8895fa897ab4949) ) // Audio CPU is a Z80 ROM_REGION( 0x010000, "txtiles", 0 ) ROM_LOAD( "gaiden_5.7a", 0x000000, 0x10000, CRC(8d4035f7) SHA1(3473456cdd24e312e3073586d7e8f24eb71bbea1) ) // 8x8 tiles @@ -1169,7 +1169,7 @@ ROM_START( ryukendn ) ROM_LOAD16_BYTE( "ryukendn_2.4s", 0x00001, 0x20000, CRC(9e99f522) SHA1(b2277d8934b5e6e2f556aee5092f5d1050774a34) ) ROM_REGION( 0x10000, "audiocpu", 0 ) - ROM_LOAD( "3.4b", 0x0000, 0x10000, CRC(6b686b69) SHA1(f0fa553acb3945f8dbbf466073c8bae35a0375ef) ) // Audio CPU is a Z80 + ROM_LOAD( "3.4b", 0x0000, 0x10000, CRC(6b686b69) SHA1(f0fa553acb3945f8dbbf466073c8bae35a0375ef) ) // Audio CPU is a Z80 ROM_REGION( 0x010000, "txtiles", 0 ) ROM_LOAD( "hn27512p.7a", 0x000000, 0x10000, CRC(765e7baa) SHA1(4d0a50f091b284739b6d9a8ceb4f81999da445fc) ) // 8x8 tiles @@ -1216,7 +1216,7 @@ ROM_START( ryukendna ) ROM_LOAD16_BYTE( "2.4s", 0x00001, 0x20000, CRC(a93a8256) SHA1(6bf6c189f82cb9341d3427a822de83cbaed27bc0) ) ROM_REGION( 0x10000, "audiocpu", 0 ) - ROM_LOAD( "3.4b", 0x0000, 0x10000, CRC(6b686b69) SHA1(f0fa553acb3945f8dbbf466073c8bae35a0375ef) ) // Audio CPU is a Z80 + ROM_LOAD( "3.4b", 0x0000, 0x10000, CRC(6b686b69) SHA1(f0fa553acb3945f8dbbf466073c8bae35a0375ef) ) // Audio CPU is a Z80 ROM_REGION( 0x010000, "txtiles", 0 ) ROM_LOAD( "hn27512p.7a", 0x000000, 0x10000, CRC(765e7baa) SHA1(4d0a50f091b284739b6d9a8ceb4f81999da445fc) ) // 8x8 tiles