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 3051f233ecSMark Cave-Ayland #include "exec/memory.h" 3151f233ecSMark Cave-Ayland #include "hw/sysbus.h" 3251f233ecSMark Cave-Ayland #include "hw/input/adb.h" 33db1015e9SEduardo Habkost #include "qom/object.h" 3451f233ecSMark Cave-Ayland 356c726698SMark Cave-Ayland #define MOS6522_NUM_REGS 16 366c726698SMark Cave-Ayland 3751f233ecSMark Cave-Ayland /* Bits in ACR */ 3851f233ecSMark Cave-Ayland #define SR_CTRL 0x1c /* Shift register control bits */ 3951f233ecSMark Cave-Ayland #define SR_EXT 0x0c /* Shift on external clock */ 4051f233ecSMark Cave-Ayland #define SR_OUT 0x10 /* Shift out if 1 */ 4151f233ecSMark Cave-Ayland 4251f233ecSMark Cave-Ayland /* Bits in IFR and IER */ 4351f233ecSMark Cave-Ayland #define IER_SET 0x80 /* set bits in IER */ 4451f233ecSMark Cave-Ayland #define IER_CLR 0 /* clear bits in IER */ 4551f233ecSMark Cave-Ayland 46d05bacbfSMark Cave-Ayland #define CA2_INT_BIT 0 47d05bacbfSMark Cave-Ayland #define CA1_INT_BIT 1 48d05bacbfSMark Cave-Ayland #define SR_INT_BIT 2 /* Shift register full/empty */ 49d05bacbfSMark Cave-Ayland #define CB2_INT_BIT 3 50d05bacbfSMark Cave-Ayland #define CB1_INT_BIT 4 51d05bacbfSMark Cave-Ayland #define T2_INT_BIT 5 /* Timer 2 interrupt */ 52d05bacbfSMark Cave-Ayland #define T1_INT_BIT 6 /* Timer 1 interrupt */ 53d05bacbfSMark Cave-Ayland 54d05bacbfSMark Cave-Ayland #define CA2_INT BIT(CA2_INT_BIT) 55d05bacbfSMark Cave-Ayland #define CA1_INT BIT(CA1_INT_BIT) 56d05bacbfSMark Cave-Ayland #define SR_INT BIT(SR_INT_BIT) 57d05bacbfSMark Cave-Ayland #define CB2_INT BIT(CB2_INT_BIT) 58d05bacbfSMark Cave-Ayland #define CB1_INT BIT(CB1_INT_BIT) 59d05bacbfSMark Cave-Ayland #define T2_INT BIT(T2_INT_BIT) 60d05bacbfSMark Cave-Ayland #define T1_INT BIT(T1_INT_BIT) 6151f233ecSMark Cave-Ayland 62ebe5bca2SMark Cave-Ayland #define VIA_NUM_INTS 5 63ebe5bca2SMark Cave-Ayland 6451f233ecSMark Cave-Ayland /* Bits in ACR */ 6551f233ecSMark Cave-Ayland #define T1MODE 0xc0 /* Timer 1 mode */ 6651f233ecSMark Cave-Ayland #define T1MODE_CONT 0x40 /* continuous interrupts */ 6751f233ecSMark Cave-Ayland 6851f233ecSMark Cave-Ayland /* VIA registers */ 6951f233ecSMark Cave-Ayland #define VIA_REG_B 0x00 7051f233ecSMark Cave-Ayland #define VIA_REG_A 0x01 7151f233ecSMark Cave-Ayland #define VIA_REG_DIRB 0x02 7251f233ecSMark Cave-Ayland #define VIA_REG_DIRA 0x03 7351f233ecSMark Cave-Ayland #define VIA_REG_T1CL 0x04 7451f233ecSMark Cave-Ayland #define VIA_REG_T1CH 0x05 7551f233ecSMark Cave-Ayland #define VIA_REG_T1LL 0x06 7651f233ecSMark Cave-Ayland #define VIA_REG_T1LH 0x07 7751f233ecSMark Cave-Ayland #define VIA_REG_T2CL 0x08 7851f233ecSMark Cave-Ayland #define VIA_REG_T2CH 0x09 7951f233ecSMark Cave-Ayland #define VIA_REG_SR 0x0a 8051f233ecSMark Cave-Ayland #define VIA_REG_ACR 0x0b 8151f233ecSMark Cave-Ayland #define VIA_REG_PCR 0x0c 8251f233ecSMark Cave-Ayland #define VIA_REG_IFR 0x0d 8351f233ecSMark Cave-Ayland #define VIA_REG_IER 0x0e 8451f233ecSMark Cave-Ayland #define VIA_REG_ANH 0x0f 8551f233ecSMark Cave-Ayland 8651f233ecSMark Cave-Ayland /** 8751f233ecSMark Cave-Ayland * MOS6522Timer: 8851f233ecSMark Cave-Ayland * @counter_value: counter value at load time 8951f233ecSMark Cave-Ayland */ 9051f233ecSMark Cave-Ayland typedef struct MOS6522Timer { 9151f233ecSMark Cave-Ayland int index; 9251f233ecSMark Cave-Ayland uint16_t latch; 9351f233ecSMark Cave-Ayland uint16_t counter_value; 9451f233ecSMark Cave-Ayland int64_t load_time; 9551f233ecSMark Cave-Ayland int64_t next_irq_time; 9651f233ecSMark Cave-Ayland uint64_t frequency; 9751f233ecSMark Cave-Ayland QEMUTimer *timer; 9851f233ecSMark Cave-Ayland } MOS6522Timer; 9951f233ecSMark Cave-Ayland 10051f233ecSMark Cave-Ayland /** 10151f233ecSMark Cave-Ayland * MOS6522State: 10251f233ecSMark Cave-Ayland * @b: B-side data 10351f233ecSMark Cave-Ayland * @a: A-side data 10451f233ecSMark Cave-Ayland * @dirb: B-side direction (1=output) 10551f233ecSMark Cave-Ayland * @dira: A-side direction (1=output) 10651f233ecSMark Cave-Ayland * @sr: Shift register 10751f233ecSMark Cave-Ayland * @acr: Auxiliary control register 10851f233ecSMark Cave-Ayland * @pcr: Peripheral control register 10951f233ecSMark Cave-Ayland * @ifr: Interrupt flag register 11051f233ecSMark Cave-Ayland * @ier: Interrupt enable register 11151f233ecSMark Cave-Ayland * @anh: A-side data, no handshake 11251f233ecSMark Cave-Ayland * @last_b: last value of B register 11351f233ecSMark Cave-Ayland * @last_acr: last value of ACR register 11451f233ecSMark Cave-Ayland */ 115db1015e9SEduardo Habkost struct MOS6522State { 11651f233ecSMark Cave-Ayland /*< private >*/ 11751f233ecSMark Cave-Ayland SysBusDevice parent_obj; 11851f233ecSMark Cave-Ayland /*< public >*/ 11951f233ecSMark Cave-Ayland 12051f233ecSMark Cave-Ayland MemoryRegion mem; 12151f233ecSMark Cave-Ayland /* VIA registers */ 12251f233ecSMark Cave-Ayland uint8_t b; 12351f233ecSMark Cave-Ayland uint8_t a; 12451f233ecSMark Cave-Ayland uint8_t dirb; 12551f233ecSMark Cave-Ayland uint8_t dira; 12651f233ecSMark Cave-Ayland uint8_t sr; 12751f233ecSMark Cave-Ayland uint8_t acr; 12851f233ecSMark Cave-Ayland uint8_t pcr; 12951f233ecSMark Cave-Ayland uint8_t ifr; 13051f233ecSMark Cave-Ayland uint8_t ier; 13151f233ecSMark Cave-Ayland 13251f233ecSMark Cave-Ayland MOS6522Timer timers[2]; 13351f233ecSMark Cave-Ayland uint64_t frequency; 13451f233ecSMark Cave-Ayland 13551f233ecSMark Cave-Ayland qemu_irq irq; 136*d4454e41SMark Cave-Ayland uint8_t last_irq_levels; 137db1015e9SEduardo Habkost }; 13851f233ecSMark Cave-Ayland 13951f233ecSMark Cave-Ayland #define TYPE_MOS6522 "mos6522" 140a489d195SEduardo Habkost OBJECT_DECLARE_TYPE(MOS6522State, MOS6522DeviceClass, MOS6522) 14151f233ecSMark Cave-Ayland 142db1015e9SEduardo Habkost struct MOS6522DeviceClass { 14351f233ecSMark Cave-Ayland DeviceClass parent_class; 14451f233ecSMark Cave-Ayland 145d638fd5cSMark Cave-Ayland DeviceReset parent_reset; 14651f233ecSMark Cave-Ayland void (*portB_write)(MOS6522State *dev); 14751f233ecSMark Cave-Ayland void (*portA_write)(MOS6522State *dev); 14851f233ecSMark Cave-Ayland /* These are used to influence the CUDA MacOS timebase calibration */ 14951f233ecSMark Cave-Ayland uint64_t (*get_timer1_counter_value)(MOS6522State *dev, MOS6522Timer *ti); 15051f233ecSMark Cave-Ayland uint64_t (*get_timer2_counter_value)(MOS6522State *dev, MOS6522Timer *ti); 15151f233ecSMark Cave-Ayland uint64_t (*get_timer1_load_time)(MOS6522State *dev, MOS6522Timer *ti); 15251f233ecSMark Cave-Ayland uint64_t (*get_timer2_load_time)(MOS6522State *dev, MOS6522Timer *ti); 153db1015e9SEduardo Habkost }; 15451f233ecSMark Cave-Ayland 15551f233ecSMark Cave-Ayland 1562e3e5c7eSMark Cave-Ayland extern const VMStateDescription vmstate_mos6522; 1572e3e5c7eSMark Cave-Ayland 15851f233ecSMark Cave-Ayland uint64_t mos6522_read(void *opaque, hwaddr addr, unsigned size); 15951f233ecSMark Cave-Ayland void mos6522_write(void *opaque, hwaddr addr, uint64_t val, unsigned size); 16051f233ecSMark Cave-Ayland 161409e9f71SMark Cave-Ayland void hmp_info_via(Monitor *mon, const QDict *qdict); 162409e9f71SMark Cave-Ayland 16351f233ecSMark Cave-Ayland #endif /* MOS6522_H */ 164