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/ide/internal.h" 3351f233ecSMark Cave-Ayland #include "hw/input/adb.h" 3451f233ecSMark Cave-Ayland 3551f233ecSMark Cave-Ayland /* Bits in ACR */ 3651f233ecSMark Cave-Ayland #define SR_CTRL 0x1c /* Shift register control bits */ 3751f233ecSMark Cave-Ayland #define SR_EXT 0x0c /* Shift on external clock */ 3851f233ecSMark Cave-Ayland #define SR_OUT 0x10 /* Shift out if 1 */ 3951f233ecSMark Cave-Ayland 4051f233ecSMark Cave-Ayland /* Bits in IFR and IER */ 4151f233ecSMark Cave-Ayland #define IER_SET 0x80 /* set bits in IER */ 4251f233ecSMark Cave-Ayland #define IER_CLR 0 /* clear bits in IER */ 4351f233ecSMark Cave-Ayland 4451f233ecSMark Cave-Ayland #define CA2_INT 0x01 4551f233ecSMark Cave-Ayland #define CA1_INT 0x02 4651f233ecSMark Cave-Ayland #define SR_INT 0x04 /* Shift register full/empty */ 4751f233ecSMark Cave-Ayland #define CB2_INT 0x08 4851f233ecSMark Cave-Ayland #define CB1_INT 0x10 4951f233ecSMark Cave-Ayland #define T2_INT 0x20 /* Timer 2 interrupt */ 5051f233ecSMark Cave-Ayland #define T1_INT 0x40 /* Timer 1 interrupt */ 5151f233ecSMark Cave-Ayland 5251f233ecSMark Cave-Ayland /* Bits in ACR */ 5351f233ecSMark Cave-Ayland #define T1MODE 0xc0 /* Timer 1 mode */ 5451f233ecSMark Cave-Ayland #define T1MODE_CONT 0x40 /* continuous interrupts */ 5551f233ecSMark Cave-Ayland 5651f233ecSMark Cave-Ayland /* VIA registers */ 5751f233ecSMark Cave-Ayland #define VIA_REG_B 0x00 5851f233ecSMark Cave-Ayland #define VIA_REG_A 0x01 5951f233ecSMark Cave-Ayland #define VIA_REG_DIRB 0x02 6051f233ecSMark Cave-Ayland #define VIA_REG_DIRA 0x03 6151f233ecSMark Cave-Ayland #define VIA_REG_T1CL 0x04 6251f233ecSMark Cave-Ayland #define VIA_REG_T1CH 0x05 6351f233ecSMark Cave-Ayland #define VIA_REG_T1LL 0x06 6451f233ecSMark Cave-Ayland #define VIA_REG_T1LH 0x07 6551f233ecSMark Cave-Ayland #define VIA_REG_T2CL 0x08 6651f233ecSMark Cave-Ayland #define VIA_REG_T2CH 0x09 6751f233ecSMark Cave-Ayland #define VIA_REG_SR 0x0a 6851f233ecSMark Cave-Ayland #define VIA_REG_ACR 0x0b 6951f233ecSMark Cave-Ayland #define VIA_REG_PCR 0x0c 7051f233ecSMark Cave-Ayland #define VIA_REG_IFR 0x0d 7151f233ecSMark Cave-Ayland #define VIA_REG_IER 0x0e 7251f233ecSMark Cave-Ayland #define VIA_REG_ANH 0x0f 7351f233ecSMark Cave-Ayland 7451f233ecSMark Cave-Ayland /** 7551f233ecSMark Cave-Ayland * MOS6522Timer: 7651f233ecSMark Cave-Ayland * @counter_value: counter value at load time 7751f233ecSMark Cave-Ayland */ 7851f233ecSMark Cave-Ayland typedef struct MOS6522Timer { 7951f233ecSMark Cave-Ayland int index; 8051f233ecSMark Cave-Ayland uint16_t latch; 8151f233ecSMark Cave-Ayland uint16_t counter_value; 8251f233ecSMark Cave-Ayland int64_t load_time; 8351f233ecSMark Cave-Ayland int64_t next_irq_time; 8451f233ecSMark Cave-Ayland uint64_t frequency; 8551f233ecSMark Cave-Ayland QEMUTimer *timer; 8651f233ecSMark Cave-Ayland } MOS6522Timer; 8751f233ecSMark Cave-Ayland 8851f233ecSMark Cave-Ayland /** 8951f233ecSMark Cave-Ayland * MOS6522State: 9051f233ecSMark Cave-Ayland * @b: B-side data 9151f233ecSMark Cave-Ayland * @a: A-side data 9251f233ecSMark Cave-Ayland * @dirb: B-side direction (1=output) 9351f233ecSMark Cave-Ayland * @dira: A-side direction (1=output) 9451f233ecSMark Cave-Ayland * @sr: Shift register 9551f233ecSMark Cave-Ayland * @acr: Auxiliary control register 9651f233ecSMark Cave-Ayland * @pcr: Peripheral control register 9751f233ecSMark Cave-Ayland * @ifr: Interrupt flag register 9851f233ecSMark Cave-Ayland * @ier: Interrupt enable register 9951f233ecSMark Cave-Ayland * @anh: A-side data, no handshake 10051f233ecSMark Cave-Ayland * @last_b: last value of B register 10151f233ecSMark Cave-Ayland * @last_acr: last value of ACR register 10251f233ecSMark Cave-Ayland */ 10351f233ecSMark Cave-Ayland typedef struct MOS6522State { 10451f233ecSMark Cave-Ayland /*< private >*/ 10551f233ecSMark Cave-Ayland SysBusDevice parent_obj; 10651f233ecSMark Cave-Ayland /*< public >*/ 10751f233ecSMark Cave-Ayland 10851f233ecSMark Cave-Ayland MemoryRegion mem; 10951f233ecSMark Cave-Ayland /* VIA registers */ 11051f233ecSMark Cave-Ayland uint8_t b; 11151f233ecSMark Cave-Ayland uint8_t a; 11251f233ecSMark Cave-Ayland uint8_t dirb; 11351f233ecSMark Cave-Ayland uint8_t dira; 11451f233ecSMark Cave-Ayland uint8_t sr; 11551f233ecSMark Cave-Ayland uint8_t acr; 11651f233ecSMark Cave-Ayland uint8_t pcr; 11751f233ecSMark Cave-Ayland uint8_t ifr; 11851f233ecSMark Cave-Ayland uint8_t ier; 11951f233ecSMark Cave-Ayland uint8_t anh; 12051f233ecSMark Cave-Ayland 12151f233ecSMark Cave-Ayland MOS6522Timer timers[2]; 12251f233ecSMark Cave-Ayland uint64_t frequency; 12351f233ecSMark Cave-Ayland 12451f233ecSMark Cave-Ayland qemu_irq irq; 12551f233ecSMark Cave-Ayland } MOS6522State; 12651f233ecSMark Cave-Ayland 12751f233ecSMark Cave-Ayland #define TYPE_MOS6522 "mos6522" 12851f233ecSMark Cave-Ayland #define MOS6522(obj) OBJECT_CHECK(MOS6522State, (obj), TYPE_MOS6522) 12951f233ecSMark Cave-Ayland 13051f233ecSMark Cave-Ayland typedef struct MOS6522DeviceClass { 13151f233ecSMark Cave-Ayland DeviceClass parent_class; 13251f233ecSMark Cave-Ayland 133*d638fd5cSMark Cave-Ayland DeviceReset parent_reset; 13451f233ecSMark Cave-Ayland void (*set_sr_int)(MOS6522State *dev); 13551f233ecSMark Cave-Ayland void (*portB_write)(MOS6522State *dev); 13651f233ecSMark Cave-Ayland void (*portA_write)(MOS6522State *dev); 13751f233ecSMark Cave-Ayland /* These are used to influence the CUDA MacOS timebase calibration */ 13851f233ecSMark Cave-Ayland uint64_t (*get_timer1_counter_value)(MOS6522State *dev, MOS6522Timer *ti); 13951f233ecSMark Cave-Ayland uint64_t (*get_timer2_counter_value)(MOS6522State *dev, MOS6522Timer *ti); 14051f233ecSMark Cave-Ayland uint64_t (*get_timer1_load_time)(MOS6522State *dev, MOS6522Timer *ti); 14151f233ecSMark Cave-Ayland uint64_t (*get_timer2_load_time)(MOS6522State *dev, MOS6522Timer *ti); 14251f233ecSMark Cave-Ayland } MOS6522DeviceClass; 14351f233ecSMark Cave-Ayland 14451f233ecSMark Cave-Ayland #define MOS6522_DEVICE_CLASS(cls) \ 14551f233ecSMark Cave-Ayland OBJECT_CLASS_CHECK(MOS6522DeviceClass, (cls), TYPE_MOS6522) 14651f233ecSMark Cave-Ayland #define MOS6522_DEVICE_GET_CLASS(obj) \ 14751f233ecSMark Cave-Ayland OBJECT_GET_CLASS(MOS6522DeviceClass, (obj), TYPE_MOS6522) 14851f233ecSMark Cave-Ayland 1492e3e5c7eSMark Cave-Ayland extern const VMStateDescription vmstate_mos6522; 1502e3e5c7eSMark Cave-Ayland 15151f233ecSMark Cave-Ayland uint64_t mos6522_read(void *opaque, hwaddr addr, unsigned size); 15251f233ecSMark Cave-Ayland void mos6522_write(void *opaque, hwaddr addr, uint64_t val, unsigned size); 15351f233ecSMark Cave-Ayland 15451f233ecSMark Cave-Ayland #endif /* MOS6522_H */ 155