151f233ecSMark Cave-Ayland /* 251f233ecSMark Cave-Ayland * QEMU MOS6522 VIA emulation 351f233ecSMark Cave-Ayland * 451f233ecSMark Cave-Ayland * Copyright (c) 2004-2007 Fabrice Bellard 551f233ecSMark Cave-Ayland * Copyright (c) 2007 Jocelyn Mayer 651f233ecSMark Cave-Ayland * Copyright (c) 2018 Mark Cave-Ayland 751f233ecSMark Cave-Ayland * 851f233ecSMark Cave-Ayland * Permission is hereby granted, free of charge, to any person obtaining a copy 951f233ecSMark Cave-Ayland * of this software and associated documentation files (the "Software"), to deal 1051f233ecSMark Cave-Ayland * in the Software without restriction, including without limitation the rights 1151f233ecSMark Cave-Ayland * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 1251f233ecSMark Cave-Ayland * copies of the Software, and to permit persons to whom the Software is 1351f233ecSMark Cave-Ayland * furnished to do so, subject to the following conditions: 1451f233ecSMark Cave-Ayland * 1551f233ecSMark Cave-Ayland * The above copyright notice and this permission notice shall be included in 1651f233ecSMark Cave-Ayland * all copies or substantial portions of the Software. 1751f233ecSMark Cave-Ayland * 1851f233ecSMark Cave-Ayland * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1951f233ecSMark Cave-Ayland * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 2051f233ecSMark Cave-Ayland * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 2151f233ecSMark Cave-Ayland * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 2251f233ecSMark Cave-Ayland * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 2351f233ecSMark Cave-Ayland * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 2451f233ecSMark Cave-Ayland * THE SOFTWARE. 2551f233ecSMark Cave-Ayland */ 2651f233ecSMark Cave-Ayland 2751f233ecSMark Cave-Ayland #ifndef MOS6522_H 2851f233ecSMark Cave-Ayland #define MOS6522_H 2951f233ecSMark Cave-Ayland 30588c5b0bSBALATON Zoltan #include "exec/hwaddr.h" 3151f233ecSMark Cave-Ayland #include "hw/sysbus.h" 32db1015e9SEduardo Habkost #include "qom/object.h" 3351f233ecSMark Cave-Ayland 346c726698SMark Cave-Ayland #define MOS6522_NUM_REGS 16 356c726698SMark Cave-Ayland 3651f233ecSMark Cave-Ayland /* Bits in ACR */ 3751f233ecSMark Cave-Ayland #define SR_CTRL 0x1c /* Shift register control bits */ 3851f233ecSMark Cave-Ayland #define SR_EXT 0x0c /* Shift on external clock */ 3951f233ecSMark Cave-Ayland #define SR_OUT 0x10 /* Shift out if 1 */ 4051f233ecSMark Cave-Ayland 4151f233ecSMark Cave-Ayland /* Bits in IFR and IER */ 4251f233ecSMark Cave-Ayland #define IER_SET 0x80 /* set bits in IER */ 4351f233ecSMark Cave-Ayland #define IER_CLR 0 /* clear bits in IER */ 4451f233ecSMark Cave-Ayland 45d05bacbfSMark Cave-Ayland #define CA2_INT_BIT 0 46d05bacbfSMark Cave-Ayland #define CA1_INT_BIT 1 47d05bacbfSMark Cave-Ayland #define SR_INT_BIT 2 /* Shift register full/empty */ 48d05bacbfSMark Cave-Ayland #define CB2_INT_BIT 3 49d05bacbfSMark Cave-Ayland #define CB1_INT_BIT 4 50d05bacbfSMark Cave-Ayland #define T2_INT_BIT 5 /* Timer 2 interrupt */ 51d05bacbfSMark Cave-Ayland #define T1_INT_BIT 6 /* Timer 1 interrupt */ 52d05bacbfSMark Cave-Ayland 53d05bacbfSMark Cave-Ayland #define CA2_INT BIT(CA2_INT_BIT) 54d05bacbfSMark Cave-Ayland #define CA1_INT BIT(CA1_INT_BIT) 55d05bacbfSMark Cave-Ayland #define SR_INT BIT(SR_INT_BIT) 56d05bacbfSMark Cave-Ayland #define CB2_INT BIT(CB2_INT_BIT) 57d05bacbfSMark Cave-Ayland #define CB1_INT BIT(CB1_INT_BIT) 58d05bacbfSMark Cave-Ayland #define T2_INT BIT(T2_INT_BIT) 59d05bacbfSMark Cave-Ayland #define T1_INT BIT(T1_INT_BIT) 6051f233ecSMark Cave-Ayland 61ebe5bca2SMark Cave-Ayland #define VIA_NUM_INTS 5 62ebe5bca2SMark Cave-Ayland 6351f233ecSMark Cave-Ayland /* Bits in ACR */ 6451f233ecSMark Cave-Ayland #define T1MODE 0xc0 /* Timer 1 mode */ 6551f233ecSMark Cave-Ayland #define T1MODE_CONT 0x40 /* continuous interrupts */ 6651f233ecSMark Cave-Ayland 67b793b4efSMark Cave-Ayland /* Bits in PCR */ 68b793b4efSMark Cave-Ayland #define CB2_CTRL_MASK 0xe0 69b793b4efSMark Cave-Ayland #define CB2_CTRL_SHIFT 5 70b793b4efSMark Cave-Ayland #define CB1_CTRL_MASK 0x10 71b793b4efSMark Cave-Ayland #define CB1_CTRL_SHIFT 4 72b793b4efSMark Cave-Ayland #define CA2_CTRL_MASK 0x0e 73b793b4efSMark Cave-Ayland #define CA2_CTRL_SHIFT 1 74b793b4efSMark Cave-Ayland #define CA1_CTRL_MASK 0x1 75b793b4efSMark Cave-Ayland #define CA1_CTRL_SHIFT 0 76b793b4efSMark Cave-Ayland 77b793b4efSMark Cave-Ayland #define C2_POS 0x2 78b793b4efSMark Cave-Ayland #define C2_IND 0x1 79b793b4efSMark Cave-Ayland 80b793b4efSMark Cave-Ayland #define C1_POS 0x1 81b793b4efSMark Cave-Ayland 8251f233ecSMark Cave-Ayland /* VIA registers */ 8351f233ecSMark Cave-Ayland #define VIA_REG_B 0x00 8451f233ecSMark Cave-Ayland #define VIA_REG_A 0x01 8551f233ecSMark Cave-Ayland #define VIA_REG_DIRB 0x02 8651f233ecSMark Cave-Ayland #define VIA_REG_DIRA 0x03 8751f233ecSMark Cave-Ayland #define VIA_REG_T1CL 0x04 8851f233ecSMark Cave-Ayland #define VIA_REG_T1CH 0x05 8951f233ecSMark Cave-Ayland #define VIA_REG_T1LL 0x06 9051f233ecSMark Cave-Ayland #define VIA_REG_T1LH 0x07 9151f233ecSMark Cave-Ayland #define VIA_REG_T2CL 0x08 9251f233ecSMark Cave-Ayland #define VIA_REG_T2CH 0x09 9351f233ecSMark Cave-Ayland #define VIA_REG_SR 0x0a 9451f233ecSMark Cave-Ayland #define VIA_REG_ACR 0x0b 9551f233ecSMark Cave-Ayland #define VIA_REG_PCR 0x0c 9651f233ecSMark Cave-Ayland #define VIA_REG_IFR 0x0d 9751f233ecSMark Cave-Ayland #define VIA_REG_IER 0x0e 9851f233ecSMark Cave-Ayland #define VIA_REG_ANH 0x0f 9951f233ecSMark Cave-Ayland 10051f233ecSMark Cave-Ayland /** 10151f233ecSMark Cave-Ayland * MOS6522Timer: 10251f233ecSMark Cave-Ayland * @counter_value: counter value at load time 10351f233ecSMark Cave-Ayland */ 10451f233ecSMark Cave-Ayland typedef struct MOS6522Timer { 10551f233ecSMark Cave-Ayland int index; 10651f233ecSMark Cave-Ayland uint16_t latch; 10751f233ecSMark Cave-Ayland uint16_t counter_value; 10851f233ecSMark Cave-Ayland int64_t load_time; 10951f233ecSMark Cave-Ayland int64_t next_irq_time; 11051f233ecSMark Cave-Ayland uint64_t frequency; 11151f233ecSMark Cave-Ayland QEMUTimer *timer; 11251f233ecSMark Cave-Ayland } MOS6522Timer; 11351f233ecSMark Cave-Ayland 11451f233ecSMark Cave-Ayland /** 11551f233ecSMark Cave-Ayland * MOS6522State: 11651f233ecSMark Cave-Ayland * @b: B-side data 11751f233ecSMark Cave-Ayland * @a: A-side data 11851f233ecSMark Cave-Ayland * @dirb: B-side direction (1=output) 11951f233ecSMark Cave-Ayland * @dira: A-side direction (1=output) 12051f233ecSMark Cave-Ayland * @sr: Shift register 12151f233ecSMark Cave-Ayland * @acr: Auxiliary control register 12251f233ecSMark Cave-Ayland * @pcr: Peripheral control register 12351f233ecSMark Cave-Ayland * @ifr: Interrupt flag register 12451f233ecSMark Cave-Ayland * @ier: Interrupt enable register 12551f233ecSMark Cave-Ayland * @anh: A-side data, no handshake 12651f233ecSMark Cave-Ayland * @last_b: last value of B register 12751f233ecSMark Cave-Ayland * @last_acr: last value of ACR register 12851f233ecSMark Cave-Ayland */ 129db1015e9SEduardo Habkost struct MOS6522State { 13051f233ecSMark Cave-Ayland /*< private >*/ 13151f233ecSMark Cave-Ayland SysBusDevice parent_obj; 13251f233ecSMark Cave-Ayland /*< public >*/ 13351f233ecSMark Cave-Ayland 13451f233ecSMark Cave-Ayland MemoryRegion mem; 13551f233ecSMark Cave-Ayland /* VIA registers */ 13651f233ecSMark Cave-Ayland uint8_t b; 13751f233ecSMark Cave-Ayland uint8_t a; 13851f233ecSMark Cave-Ayland uint8_t dirb; 13951f233ecSMark Cave-Ayland uint8_t dira; 14051f233ecSMark Cave-Ayland uint8_t sr; 14151f233ecSMark Cave-Ayland uint8_t acr; 14251f233ecSMark Cave-Ayland uint8_t pcr; 14351f233ecSMark Cave-Ayland uint8_t ifr; 14451f233ecSMark Cave-Ayland uint8_t ier; 14551f233ecSMark Cave-Ayland 14651f233ecSMark Cave-Ayland MOS6522Timer timers[2]; 14751f233ecSMark Cave-Ayland uint64_t frequency; 14851f233ecSMark Cave-Ayland 14951f233ecSMark Cave-Ayland qemu_irq irq; 150d4454e41SMark Cave-Ayland uint8_t last_irq_levels; 151db1015e9SEduardo Habkost }; 15251f233ecSMark Cave-Ayland 15351f233ecSMark Cave-Ayland #define TYPE_MOS6522 "mos6522" 154a489d195SEduardo Habkost OBJECT_DECLARE_TYPE(MOS6522State, MOS6522DeviceClass, MOS6522) 15551f233ecSMark Cave-Ayland 156db1015e9SEduardo Habkost struct MOS6522DeviceClass { 157*072d407bSThomas Huth SysBusDeviceClass parent_class; 15851f233ecSMark Cave-Ayland 159ed053e89SPeter Maydell ResettablePhases parent_phases; 16051f233ecSMark Cave-Ayland void (*portB_write)(MOS6522State *dev); 16151f233ecSMark Cave-Ayland void (*portA_write)(MOS6522State *dev); 16251f233ecSMark Cave-Ayland /* These are used to influence the CUDA MacOS timebase calibration */ 16351f233ecSMark Cave-Ayland uint64_t (*get_timer1_counter_value)(MOS6522State *dev, MOS6522Timer *ti); 16451f233ecSMark Cave-Ayland uint64_t (*get_timer2_counter_value)(MOS6522State *dev, MOS6522Timer *ti); 16551f233ecSMark Cave-Ayland uint64_t (*get_timer1_load_time)(MOS6522State *dev, MOS6522Timer *ti); 16651f233ecSMark Cave-Ayland uint64_t (*get_timer2_load_time)(MOS6522State *dev, MOS6522Timer *ti); 167db1015e9SEduardo Habkost }; 16851f233ecSMark Cave-Ayland 16951f233ecSMark Cave-Ayland 1702e3e5c7eSMark Cave-Ayland extern const VMStateDescription vmstate_mos6522; 1712e3e5c7eSMark Cave-Ayland 17251f233ecSMark Cave-Ayland uint64_t mos6522_read(void *opaque, hwaddr addr, unsigned size); 17351f233ecSMark Cave-Ayland void mos6522_write(void *opaque, hwaddr addr, uint64_t val, unsigned size); 17451f233ecSMark Cave-Ayland 175409e9f71SMark Cave-Ayland void hmp_info_via(Monitor *mon, const QDict *qdict); 176409e9f71SMark Cave-Ayland 17751f233ecSMark Cave-Ayland #endif /* MOS6522_H */ 178