From 9de1e4093bc9b6b752d6c4921c0ce5b5f866f7fb Mon Sep 17 00:00:00 2001 From: zeromus Date: Fri, 24 Feb 2012 20:40:02 +0000 Subject: [PATCH] forgot to add --- PsxHawk.Core/psx.sio.cpp | 102 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 PsxHawk.Core/psx.sio.cpp diff --git a/PsxHawk.Core/psx.sio.cpp b/PsxHawk.Core/psx.sio.cpp new file mode 100644 index 0000000000..1df663cfc6 --- /dev/null +++ b/PsxHawk.Core/psx.sio.cpp @@ -0,0 +1,102 @@ +/* +this file contains the sio subsystem emulation. +*/ + +#include "psx.h" +#include +#include +#include + + +static u8 getPrescaler(const u32 prescaler_type) +{ + static const u8 prescalers[] = {0,1,16,64}; + return prescalers[prescaler_type]; +} + + +//information in this file is derived from observatoins in mednafen and mame + +void PSX::SioController::Reset() +{ + status.TX_EMPTY = 1; + status.TX_RDY = 1; + status.RX_RDY = 0; + status.OVERRUN = 0; + status.IRQ = 0; +} + +float PSX::SioController::CalculateBaud() +{ + return (float)PSX_CLOCK / this->baud_reg / getPrescaler(mode.prescaler_type); +} + +void PSX::sio_wr(const int size, const u32 addr, const u32 val) +{ + assert(size==2); + assert((addr&1)==0); + DEBUG_SIO("sio write size %d addr %08X = %08X\n",size,addr,val); + const u32 portnum = (addr>>4)&1; + SioController &port = sio[portnum]; + + switch(addr&0xF) + { + case 0x00: + break; + case 0x08: + port.mode.value = val; + printf("baud set to approx %f\n",port.CalculateBaud()); + break; + case 0x0A: + { + SioController::ControlReg reg; + reg.value = val; + if(reg.RESET) + { + DEBUG_SIO("reset port %d\n",portnum); + port.Reset(); + } + if(reg.IACK) + { + port.status.IRQ = 0; + port.control.IACK = 0; + //todo - irq sync + } + + //check for rising edge of DTR signal and alert the appropriate port + if(port.control.DTR == 0 && reg.DTR == 1) + { + sio_dtr(port.control.PORT_SEL); + } + + //replicate stored bits + port.control.TX_IENA = reg.RX_IENA; + port.control.RX_IENA = reg.RX_IENA; + port.control.DSR_IENA = reg.DSR_IENA; + port.control.DTR = reg.DTR; + port.control.PORT_SEL = reg.PORT_SEL; + } + break; + case 0x0E: + port.baud_reg = val; + printf("baud set to approx %f\n",port.CalculateBaud()); + break; + default: + DEBUG_SIO("UNHANDLED\n"); + } +} + +void PSX::sio_dtr(const u32 port) +{ +} + +u32 PSX::sio_rd(const int size, const u32 addr) +{ + assert(size==2); + assert((addr&1)==0); + u32 ret = 0; + DEBUG_SIO("sio read size %d addr %08X = %08X\n",size,addr,ret); + const u32 port = (addr>>4)&1; + + return 0; +}