From 41f26b57c2409a9827300a7d064f218309d46582 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 6 May 2023 23:19:55 +0600 Subject: [PATCH] usb: Start work on SOF generation and frame counting --- src/include/86box/usb.h | 8 +++++++- src/usb.c | 44 ++++++++++++++++++++++++----------------- 2 files changed, 33 insertions(+), 19 deletions(-) diff --git a/src/include/86box/usb.h b/src/include/86box/usb.h index 39ddf9cf6..af1922570 100644 --- a/src/include/86box/usb.h +++ b/src/include/86box/usb.h @@ -36,7 +36,13 @@ typedef struct /* USB Host Controller device struct */ typedef struct usb_t { - uint8_t uhci_io[32], ohci_mmio[4096]; + union + { + uint8_t ohci_mmio[4096]; + uint16_t ohci_mmio_w[2048]; + uint32_t ohci_mmio_l[1024]; + }; + uint8_t uhci_io[32]; uint16_t uhci_io_base; int uhci_enable, ohci_enable; uint32_t ohci_mem_base; diff --git a/src/usb.c b/src/usb.c index 0951412d6..3310c0786 100644 --- a/src/usb.c +++ b/src/usb.c @@ -63,7 +63,7 @@ enum OHCI_HcBulkHeadED = 0x28, OHCI_HcBulkCurrentED = 0x2C, OHCI_HcDoneHead = 0x30, - OHCI_HcFMInterval = 0x34, + OHCI_HcFmInterval = 0x34, OHCI_HcFmRemaining = 0x38, OHCI_HcFmNumber = 0x3C, OHCI_HcPeriodicStart = 0x40, @@ -223,10 +223,35 @@ ohci_mmio_read(uint32_t addr, void *p) return ret; } +void +ohci_set_interrupt(usb_t* usb, uint8_t bit) +{ + if (!(usb->ohci_mmio[OHCI_HcInterruptEnable + 3] & 0x80)) + return; + + if (!(usb->ohci_mmio[OHCI_HcInterruptEnable] & bit)) + return; + + if (usb->ohci_mmio[OHCI_HcInterruptDisable] & bit) + return; + + usb->ohci_mmio[OHCI_HcInterruptStatus] |= bit; + usb_interrupt_ohci(usb); +} + void ohci_update_frame_counter(void* priv) { usb_t *dev = (usb_t *) priv; + + dev->ohci_mmio_w[OHCI_HcFmRemaining / 2] &= 0x3fff; + if (dev->ohci_mmio_w[OHCI_HcFmRemaining / 2] == 0) { + dev->ohci_mmio_w[OHCI_HcFmRemaining / 2] = dev->ohci_mmio_w[OHCI_HcFmInterval / 2] & 0x3fff; + dev->ohci_mmio_l[OHCI_HcFmRemaining / 4] &= ~(1 << 31); + dev->ohci_mmio_l[OHCI_HcFmRemaining / 4] |= dev->ohci_mmio_l[OHCI_HcFmInterval / 4] & (1 << 31); + ohci_set_interrupt(dev, OHCI_HcInterruptEnable_SO); + } + if (dev->ohci_mmio_w[OHCI_HcFmRemaining / 2]) dev->ohci_mmio_w[OHCI_HcFmRemaining / 2]--; } void @@ -257,23 +282,6 @@ ohci_port_reset_callback_2(void* priv) dev->ohci_mmio[OHCI_HcRhPortStatus2] &= ~0x10; dev->ohci_mmio[OHCI_HcRhPortStatus2 + 2] |= 0x10; } - -void -ohci_set_interrupt(usb_t* usb, uint8_t bit) -{ - if (!(usb->ohci_mmio[OHCI_HcInterruptEnable + 3] & 0x80)) - return; - - if (!(usb->ohci_mmio[OHCI_HcInterruptEnable] & bit)) - return; - - if (usb->ohci_mmio[OHCI_HcInterruptDisable] & bit) - return; - - usb->ohci_mmio[OHCI_HcInterruptStatus] |= bit; - usb_interrupt_ohci(usb); -} - static void ohci_mmio_write(uint32_t addr, uint8_t val, void *p) {