Tom_Neverwinter

flycast Serial test com98

Aug 26th, 2025 (edited)
40
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 17.45 KB | None | 0 0
  1. /*
  2. Dreamcast serial port.
  3. */
  4. #include <cerrno>
  5. #include <cstdlib>
  6. #include <fcntl.h>
  7. #ifndef _WIN32
  8. #include <unistd.h>
  9. #include <sys/ioctl.h>
  10. #else
  11. #include <windows.h>
  12. #include <io.h>
  13. #endif
  14. #include "types.h"
  15. #include "hw/sh4/sh4_mmr.h"
  16. #include "hw/sh4/sh4_interrupts.h"
  17. #include "cfg/option.h"
  18. #include "modules.h"
  19. #include "hw/sh4/sh4_sched.h"
  20. #include "serialize.h"
  21.  
  22. //#define DEBUG_SCIF
  23.  
  24. #ifdef DEBUG_SCIF
  25. #define SCIF_LOG(...) INFO_LOG(SH4, __VA_ARGS__)
  26. #else
  27. #define SCIF_LOG(...)
  28. #endif
  29.  
  30. SCIRegisters sci;
  31. SCIFRegisters scif;
  32.  
  33. static void updateInterrupts()
  34. {
  35. InterruptPend(sh4_SCIF_TXI, SCIF_SCFSR2.TDFE);
  36. InterruptMask(sh4_SCIF_TXI, SCIF_SCSCR2.TIE);
  37.  
  38. InterruptPend(sh4_SCIF_RXI, SCIF_SCFSR2.RDF || SCIF_SCFSR2.DR);
  39. InterruptMask(sh4_SCIF_RXI, SCIF_SCSCR2.RIE);
  40.  
  41. InterruptPend(sh4_SCIF_BRI, SCIF_SCFSR2.BRK);
  42. InterruptMask(sh4_SCIF_BRI, SCIF_SCSCR2.RIE || SCIF_SCSCR2.REIE);
  43.  
  44. InterruptPend(sh4_SCIF_ERI, SCIF_SCFSR2.ER || SCIF_SCFSR2.FER || SCIF_SCFSR2.PER);
  45. InterruptMask(sh4_SCIF_ERI, SCIF_SCSCR2.RIE || SCIF_SCSCR2.REIE);
  46. }
  47.  
  48. int SCIFSerialPort::schedCallback(int tag, int cycles, int lag, void *arg)
  49. {
  50. SCIFSerialPort& scif = *(SCIFSerialPort *)arg;
  51. if (tag == 0)
  52. {
  53. bool reschedule = scif.txDone();
  54. scif.rxSched();
  55. if (reschedule || scif.pipe != nullptr)
  56. return scif.frameSize * scif.cyclesPerBit;
  57. else
  58. return 0;
  59. }
  60. else
  61. {
  62. scif.sendBreak();
  63. return 0;
  64. }
  65. }
  66.  
  67. bool SCIFSerialPort::isTDFE() const {
  68. return (int)txFifo.size() <= 1 << (3 - SCIF_SCFCR2.TTRG);
  69. }
  70.  
  71. bool SCIFSerialPort::isRDF() const {
  72. constexpr u32 trigLevels[] { 1, 4, 8, 14 };
  73. return rxFifo.size() >= trigLevels[SCIF_SCFCR2.RTRG];
  74. }
  75.  
  76. bool SCIFSerialPort::txDone()
  77. {
  78. if (!transmitting || SCIF_SCFCR2.TFRST == 1)
  79. return false;
  80. if (txFifo.empty())
  81. {
  82. setStatusBit(TEND);
  83. transmitting = false;
  84. return false; // don't reschedule
  85. }
  86. u8 v = txFifo.front();
  87. txFifo.pop_front();
  88. if (pipe != nullptr)
  89. pipe->write(v);
  90. if (isTDFE()) {
  91. setStatusBit(TDFE);
  92. updateInterrupts();
  93. }
  94. return true;
  95. }
  96.  
  97. void SCIFSerialPort::rxSched()
  98. {
  99. if (pipe == nullptr)
  100. return;
  101.  
  102. if (pipe->available() > 0)
  103. {
  104. u8 v = pipe->read();
  105. if (SCIF_SCSCR2.RE == 0 || SCIF_SCFCR2.RFRST == 1)
  106. return;
  107. if (rxFifo.size() == 16)
  108. {
  109. // rx overrun
  110. SCIF_SCLSR2.ORER = 1;
  111. updateInterrupts();
  112. INFO_LOG(SH4, "scif: Receive overrun");
  113. }
  114. else
  115. {
  116. rxFifo.push_back(v);
  117. if (isRDF()) {
  118. setStatusBit(RDF);
  119. updateInterrupts();
  120. }
  121. }
  122. }
  123. else if (!rxFifo.empty())
  124. {
  125. setStatusBit(DR);
  126. updateInterrupts();
  127. }
  128. }
  129.  
  130. void SCIFSerialPort::updateBaudRate()
  131. {
  132. // 1 start bit, 7 or 8 data bits, optional parity bit, 1 or 2 stop bits
  133. frameSize = 1 + 8 - SCIF_SCSMR2.CHR + SCIF_SCSMR2.PE + 1 + SCIF_SCSMR2.STOP;
  134. int bauds = SH4_MAIN_CLOCK / 4 / (SCIF_SCBRR2 + 1) / 32 / (1 << (SCIF_SCSMR2.CKS * 2));
  135. cyclesPerBit = SH4_MAIN_CLOCK / bauds;
  136. INFO_LOG(SH4, "SCIF: Frame size %d cycles/bit %d (%d bauds) pipe %p", frameSize, cyclesPerBit, bauds, pipe);
  137. sh4_sched_request(schedId, frameSize * cyclesPerBit);
  138. }
  139.  
  140. // SCIF SCFTDR2 - Transmit FIFO Data Register
  141. void SCIFSerialPort::SCFTDR2_write(u8 data)
  142. {
  143. SCIF_LOG("serial out %02x %c fifo_sz %d", data, data == '\0' ? ' ' : data, (int)txFifo.size());
  144. if (SCIF_SCFCR2.TFRST == 1)
  145. return;
  146. if (SCIF_SCSMR2.CHR == 1)
  147. data &= 0x7f;
  148. if (txFifo.empty() && !transmitting && SCIF_SCSCR2.TE == 1)
  149. {
  150. if (pipe != nullptr)
  151. pipe->write(data);
  152. transmitting = true;
  153. // Need to reschedule so it doesn't happen too early (f355)
  154. sh4_sched_request(schedId, frameSize * cyclesPerBit);
  155. setStatusBit(TDFE); // immediately transfer SCFTDR2 into the shift register
  156. updateInterrupts();
  157. }
  158. else if (txFifo.size() < 16) {
  159. txFifo.push_back(data);
  160. }
  161. }
  162.  
  163. // SCIF_SCFSR2 read - Serial Status Register
  164. u16 SCIFSerialPort::readStatus()
  165. {
  166. // SCIF_LOG("SCIF_SCFSR2.read %s%s%s%s%s%s%s%s",
  167. // SCIF_SCFSR2.ER ? "ER " : "",
  168. // SCIF_SCFSR2.TEND ? "TEND " : "",
  169. // SCIF_SCFSR2.TDFE ? "TDFE " : "",
  170. // SCIF_SCFSR2.BRK ? "BRK " : "",
  171. // SCIF_SCFSR2.FER ? "FER " : "",
  172. // SCIF_SCFSR2.PER ? "PER " : "",
  173. // SCIF_SCFSR2.RDF ? "RDF " : "",
  174. // SCIF_SCFSR2.DR ? "DR" : "");
  175. statusLastRead = SCIF_SCFSR2.full;
  176. return SCIF_SCFSR2.full;
  177. }
  178.  
  179. void SCIFSerialPort::setStatusBit(StatusBit bit)
  180. {
  181. statusLastRead &= ~bit;
  182. SCIF_SCFSR2.full |= bit;
  183. }
  184.  
  185. // SCIF_SCFSR2 write - Serial Status Register
  186. void SCIFSerialPort::writeStatus(u16 data)
  187. {
  188. data = data | ~0x00f3 | ~statusLastRead;
  189. // RDF and TDFE cannot be reset until the trigger level is reached
  190. if (isRDF())
  191. data |= RDF;
  192. if (isTDFE())
  193. data |= TDFE;
  194. if (!rxFifo.empty())
  195. data |= DR;
  196. SCIF_LOG("SCIF_SCFSR2.reset %s%s%s%s%s%s%s%s",
  197. (data & ER) ? "" : "ER ",
  198. (data & TEND) ? "" : "TEND ",
  199. (data & TDFE) ? "" : "TDFE ",
  200. (data & BRK) ? "" : "BRK ",
  201. (data & FER) ? "" : "FER ",
  202. (data & PER) ? "" : "PER ",
  203. (data & RDF) ? "" : "RDF ",
  204. (data & DR) ? "" : "DR");
  205.  
  206. SCIF_SCFSR2.full &= data;
  207. statusLastRead &= data;
  208.  
  209. updateInterrupts();
  210. }
  211.  
  212. //SCIF_SCFDR2 - FIFO Data Count Register
  213. u16 SCIFSerialPort::SCFDR2_read()
  214. {
  215. u16 rv = rxFifo.size() | (txFifo.size() << 8);
  216. SCIF_LOG("SCIF: fifo count rx %d tx %d", rv & 0xff, rv >> 8);
  217.  
  218. return rv;
  219. }
  220.  
  221. //SCIF_SCFRDR2 - Receive FIFO Data Register
  222. u8 SCIFSerialPort::SCFRDR2_read()
  223. {
  224. if (rxFifo.empty()) {
  225. INFO_LOG(SH4, "Empty rx fifo read");
  226. return 0;
  227. }
  228. u8 data = rxFifo.front();
  229. rxFifo.pop_front();
  230. SCIF_LOG("serial in %02x %c", data, data);
  231. return data;
  232. }
  233.  
  234. SCIFSerialPort& SCIFSerialPort::Instance()
  235. {
  236. static SCIFSerialPort instance;
  237.  
  238. return instance;
  239. }
  240.  
  241. //SCSCR2 - Serial Control Register
  242. static u16 SCSCR2_read(u32 addr)
  243. {
  244. return SCIF_SCSCR2.full;
  245. }
  246.  
  247. void SCIFSerialPort::SCSCR2_write(u16 data)
  248. {
  249. SCIF_SCSCR2.full = data & 0x00fa;
  250. if (SCIF_SCSCR2.TE == 0)
  251. {
  252. setStatusBit(TEND);
  253. // TE must be cleared to send a break
  254. setBreak(SCIF_SCSPTR2.SPB2IO == 1 && SCIF_SCSPTR2.SPB2DT == 0);
  255. }
  256. else {
  257. setBreak(false);
  258. }
  259. updateInterrupts();
  260. SCIF_LOG("SCIF_SCSCR2= %s%s%s%s%s",
  261. SCIF_SCSCR2.TIE ? "TIE " : "",
  262. SCIF_SCSCR2.RIE ? "RIE " : "",
  263. SCIF_SCSCR2.TE ? "TE " : "",
  264. SCIF_SCSCR2.RE ? "RE " : "",
  265. SCIF_SCSCR2.REIE ? "REIE" : "");
  266. }
  267.  
  268. // SCSPTR2 - Serial Port Register
  269. static u16 SCSPTR2_read(u32 addr)
  270. {
  271. SCIF_LOG("SCIF_SCSPTR2.read %x", SCIF_SCSPTR2.full);
  272. return SCIF_SCSPTR2.full & ~0x10; // CTS active/low
  273. }
  274.  
  275. void SCIFSerialPort::setBreak(bool on)
  276. {
  277. if (on) {
  278. // tetris needs to send/receive breaks
  279. if (!sh4_sched_is_scheduled(brkSchedId))
  280. sh4_sched_request(brkSchedId, cyclesPerBit * frameSize);
  281. }
  282. else {
  283. if (sh4_sched_is_scheduled(brkSchedId))
  284. sh4_sched_request(brkSchedId, -1);
  285. }
  286. }
  287.  
  288. void SCIFSerialPort::SCSPTR2_write(u16 data)
  289. {
  290. SCIF_SCSPTR2.full = data & 0x00f3;
  291. if (SCIF_SCSPTR2.SPB2IO == 1)
  292. setBreak(SCIF_SCSPTR2.SPB2DT == 0 && SCIF_SCSCR2.TE == 0);
  293. else
  294. setBreak(false);
  295.  
  296. SCIF_LOG("SCIF_SCSPTR2= %s%s%s%s%s%s",
  297. SCIF_SCSPTR2.RTSIO ? "RTSIO " : "",
  298. SCIF_SCSPTR2.RTSDT ? "RTSDT " : "",
  299. SCIF_SCSPTR2.CTSIO ? "CTSIO " : "",
  300. SCIF_SCSPTR2.CTSDT ? "CTSDT " : "",
  301. SCIF_SCSPTR2.SPB2IO ? "SPB2IO " : "",
  302. SCIF_SCSPTR2.SPB2DT ? "SPB2DT" : "");
  303. }
  304.  
  305. // SCFCR2 - FIFO Control Register
  306. u16 SCIFSerialPort::SCFCR2_read(u32 addr)
  307. {
  308. // SCIF_LOG("SCIF_SCFCR2.read %x", SCIF_SCFCR2.full);
  309. return SCIF_SCFCR2.full;
  310. }
  311.  
  312. void SCIFSerialPort::SCFCR2_write(u16 data)
  313. {
  314. if (SCIF_SCFCR2.TFRST == 1 && !(data & 4))
  315. {
  316. // when TFRST 1 -> 0
  317. // seems to help tetris send data during sync
  318. setStatusBit(TEND);
  319. setStatusBit(TDFE);
  320. updateInterrupts();
  321. }
  322. SCIF_SCFCR2.full = data & 0x00ff;
  323. if (SCIF_SCFCR2.TFRST == 1)
  324. {
  325. txFifo.clear();
  326. if (pipe == nullptr)
  327. sh4_sched_request(schedId, -1);
  328. transmitting = false;
  329. }
  330. if (SCIF_SCFCR2.RFRST == 1)
  331. rxFifo.clear();
  332. SCIF_LOG("SCIF_SCFCR2= %s%s%sTTRG %d RTRG %d",
  333. SCIF_SCFCR2.RFRST ? "RFRST " : "",
  334. SCIF_SCFCR2.TFRST ? "TFRST " : "",
  335. SCIF_SCFCR2.MCE ? "MCE " : "",
  336. SCIF_SCFCR2.TTRG,
  337. SCIF_SCFCR2.RTRG);
  338. }
  339.  
  340. // SCBRR2 - Bit Rate Register
  341. void SCIFSerialPort::SCBRR2_write(u32 addr, u8 data)
  342. {
  343. SCIF_SCBRR2 = data;
  344. Instance().updateBaudRate();
  345. }
  346.  
  347. // SCSMR2 - Serial Mode Register
  348. void SCIFSerialPort::SCSMR2_write(u32 addr, u16 data)
  349. {
  350. SCIF_SCSMR2.full = data & 0x007b;
  351. Instance().updateBaudRate();
  352. }
  353.  
  354. void SCIFSerialPort::receiveBreak()
  355. {
  356. SCIF_LOG("Break received");
  357. setStatusBit(BRK);
  358. updateInterrupts();
  359. }
  360.  
  361. void SCIFSerialPort::sendBreak()
  362. {
  363. if (pipe != nullptr)
  364. pipe->sendBreak();
  365. }
  366.  
  367.  
  368. void SCIFSerialPort::init()
  369. {
  370. if (schedId == -1)
  371. schedId = sh4_sched_register(0, schedCallback, this);
  372. if (brkSchedId == -1)
  373. brkSchedId = sh4_sched_register(1, schedCallback, this);
  374. }
  375.  
  376. void SCIFSerialPort::term()
  377. {
  378. if (schedId != -1) {
  379. sh4_sched_unregister(schedId);
  380. schedId = -1;
  381. }
  382. if (brkSchedId != -1) {
  383. sh4_sched_unregister(brkSchedId);
  384. brkSchedId = -1;
  385. }
  386. }
  387.  
  388. void SCIFSerialPort::reset()
  389. {
  390. sh4_sched_request(brkSchedId, -1);
  391. transmitting = false;
  392. statusLastRead = 0;
  393. txFifo.clear();
  394. rxFifo.clear();
  395. updateBaudRate();
  396. }
  397.  
  398. void SCIFSerialPort::serialize(Serializer& ser)
  399. {
  400. sh4_sched_serialize(ser, schedId);
  401. sh4_sched_serialize(ser, brkSchedId);
  402. ser << statusLastRead;
  403. ser << (int)txFifo.size();
  404. for (u8 b : txFifo)
  405. ser << b;
  406. ser << (int)rxFifo.size();
  407. for (u8 b : rxFifo)
  408. ser << b;
  409. ser << transmitting;
  410. }
  411.  
  412. void SCIFSerialPort::deserialize(Deserializer& deser)
  413. {
  414. txFifo.clear();
  415. rxFifo.clear();
  416. if (deser.version() >= Deserializer::V43)
  417. {
  418. sh4_sched_deserialize(deser, schedId);
  419. sh4_sched_deserialize(deser, brkSchedId);
  420. deser >> statusLastRead;
  421. int size;
  422. deser >> size;
  423. for (int i = 0; i < size; i++)
  424. {
  425. u8 b;
  426. deser >> b;
  427. txFifo.push_back(b);
  428. }
  429. deser >> size;
  430. for (int i = 0; i < size; i++)
  431. {
  432. u8 b;
  433. deser >> b;
  434. rxFifo.push_back(b);
  435. }
  436. deser >> transmitting;
  437. }
  438. else
  439. {
  440. statusLastRead = 0;
  441. transmitting = false;
  442. }
  443. SCIF_SCBRR2 &= 0xff; // work around previous issues with dynarecs
  444. updateBaudRate();
  445. }
  446.  
  447. struct PTYPipe : public SerialPort::Pipe
  448. {
  449. void write(u8 data) override
  450. {
  451. if (config::SerialConsole) {
  452. int rc = ::write(tty, &data, 1);
  453. (void)rc;
  454. }
  455. }
  456.  
  457. int available() override {
  458. int count = 0;
  459. #if defined(__unix__) || defined(__APPLE__)
  460. if (config::SerialConsole && tty != 1)
  461. ioctl(tty, FIONREAD, &count);
  462. #endif
  463. return count;
  464. }
  465.  
  466. u8 read() override
  467. {
  468. u8 data = 0;
  469. if (tty != 1) {
  470. int rc = ::read(tty, &data, 1);
  471. (void)rc;
  472. }
  473. return data;
  474. }
  475.  
  476. void init()
  477. {
  478. if (config::SerialConsole && config::SerialPTY && tty == 1)
  479. {
  480. #if defined(__unix__) || defined(__APPLE__)
  481. tty = open("/dev/ptmx", O_RDWR | O_NDELAY | O_NOCTTY | O_NONBLOCK);
  482. if (tty < 0)
  483. {
  484. ERROR_LOG(BOOT, "Cannot open /dev/ptmx: errno %d", errno);
  485. tty = 1;
  486. }
  487. else
  488. {
  489. grantpt(tty);
  490. unlockpt(tty);
  491. NOTICE_LOG(BOOT, "Pseudoterminal is at %s", ptsname(tty));
  492. }
  493. #elif defined(_WIN32)
  494. if (AllocConsole())
  495. {
  496. SetConsoleTitle(TEXT("Flycast Serial Output"));
  497.  
  498. // Pipe stdout
  499. HANDLE hStd = GetStdHandle(STD_OUTPUT_HANDLE);
  500. tty = _open_osfhandle((intptr_t)hStd, _O_TEXT);
  501. _dup2(tty, fileno(stdout));
  502. SetStdHandle(STD_OUTPUT_HANDLE, (HANDLE)_get_osfhandle(fileno(stdout)));
  503. }
  504. else
  505. {
  506. ERROR_LOG(BOOT, "Cannot AllocConsole(): errno %d", GetLastError());
  507. }
  508. #endif
  509. }
  510. SCIFSerialPort::Instance().setPipe(this);
  511. }
  512.  
  513. void term()
  514. {
  515. if (tty != 1)
  516. {
  517. ::close(tty);
  518. tty = 1;
  519. }
  520. SCIFSerialPort::Instance().setPipe(nullptr);
  521. }
  522.  
  523. private:
  524. int tty = 1;
  525. };
  526.  
  527. #ifdef _WIN32
  528. struct COMPipe : public SerialPort::Pipe
  529. {
  530. void write(u8 data) override
  531. {
  532. if (handle != INVALID_HANDLE_VALUE) {
  533. DWORD written;
  534. WriteFile(handle, &data, 1, &written, NULL);
  535. }
  536. }
  537.  
  538. int available() override {
  539. if (handle == INVALID_HANDLE_VALUE)
  540. return 0;
  541.  
  542. DWORD errors;
  543. COMSTAT stat;
  544. ClearCommError(handle, &errors, &stat);
  545. return stat.cbInQue;
  546. }
  547.  
  548. u8 read() override
  549. {
  550. if (handle == INVALID_HANDLE_VALUE)
  551. return 0;
  552.  
  553. u8 data = 0;
  554. DWORD read_bytes;
  555. ReadFile(handle, &data, 1, &read_bytes, NULL);
  556. return data;
  557. }
  558.  
  559. void init(const char* port_name)
  560. {
  561. handle = CreateFileA(port_name,
  562. GENERIC_READ | GENERIC_WRITE,
  563. 0, NULL, OPEN_EXISTING, 0, NULL);
  564.  
  565. if (handle != INVALID_HANDLE_VALUE) {
  566. DCB dcb = {0};
  567. dcb.DCBlength = sizeof(dcb);
  568. GetCommState(handle, &dcb);
  569. dcb.BaudRate = CBR_9600;
  570. dcb.Parity = EVENPARITY;
  571. dcb.ByteSize = 8;
  572. dcb.StopBits = ONESTOPBIT;
  573. SetCommState(handle, &dcb);
  574.  
  575. SCIFSerialPort::Instance().setPipe(this);
  576. INFO_LOG(SH4, "Serial port %s opened", port_name);
  577. } else {
  578. ERROR_LOG(SH4, "Failed to open serial port %s", port_name);
  579. }
  580. }
  581.  
  582. void term()
  583. {
  584. if (handle != INVALID_HANDLE_VALUE) {
  585. CloseHandle(handle);
  586. handle = INVALID_HANDLE_VALUE;
  587. }
  588. SCIFSerialPort::Instance().setPipe(nullptr);
  589. }
  590.  
  591. private:
  592. HANDLE handle = INVALID_HANDLE_VALUE;
  593. };
  594. #endif
  595.  
  596. void setupPtyPipe()
  597. {
  598. static PTYPipe ptyPipe;
  599.  
  600. if (config::SerialConsole || config::SerialPTY)
  601. {
  602. if (SCIFSerialPort::Instance().getPipe() == nullptr)
  603. ptyPipe.init();
  604. }
  605. else
  606. {
  607. if (SCIFSerialPort::Instance().getPipe() == &ptyPipe)
  608. ptyPipe.term();
  609. }
  610. }
  611.  
  612. void setupCOMPipe()
  613. {
  614. #ifdef _WIN32
  615. static COMPipe comPipe;
  616. static bool initialized = false;
  617.  
  618. // Change "COM98" to your desired port
  619. const char* port_name = "COM98";
  620.  
  621. if (!initialized) {
  622. comPipe.init(port_name);
  623. initialized = true;
  624. }
  625. #endif
  626. }
  627.  
  628. template <typename T>
  629. class SingletonForward {
  630.  
  631. };
  632.  
  633. template<typename Ret, typename Class, typename... Args>
  634. struct SingletonForward<Ret(Class::*)(Args...)>
  635. {
  636. static Ret(*forward(Ret(*function)(u32 addr, Args...)))(u32 addr, Args...) {
  637. return function;
  638. }
  639. };
  640.  
  641. #define SINGLETON_FORWARD(accessor, function) \
  642. SingletonForward<decltype(&std::remove_reference<decltype(accessor)>::type::function)>::forward([](u32 addr, auto... args) { \
  643. return accessor.function(args...); \
  644. })
  645.  
  646. //Init term res
  647. void SCIFRegisters::init()
  648. {
  649. super::init();
  650.  
  651. // Serial Communication Interface with FIFO
  652.  
  653. //SCIF SCSMR2 0xFFE80000 0x1FE80000 16 0x0000 0x0000 Held Held Pclk
  654. setWriteHandler<SCIF_SCSMR2_addr, u16>(SCIFSerialPort::SCSMR2_write);
  655.  
  656. //SCIF SCBRR2 0xFFE80004 0x1FE80004 8 0xFF 0xFF Held Held Pclk
  657. setWriteHandler<SCIF_SCBRR2_addr, u8>(SCIFSerialPort::SCBRR2_write);
  658.  
  659. //SCIF SCSCR2 0xFFE80008 0x1FE80008 16 0x0000 0x0000 Held Held Pclk
  660. setHandlers<SCIF_SCSCR2_addr>(SCSCR2_read, SINGLETON_FORWARD(SCIFSerialPort::Instance(), SCSCR2_write));
  661.  
  662. //SCIF SCFTDR2 0xFFE8000C 0x1FE8000C 8 Undefined Undefined Held Held Pclk
  663. setWriteOnly<SCIF_SCFTDR2_addr>(SINGLETON_FORWARD(SCIFSerialPort::Instance(), SCFTDR2_write));
  664.  
  665. //SCIF SCFSR2 0xFFE80010 0x1FE80010 16 0x0060 0x0060 Held Held Pclk
  666. setHandlers<SCIF_SCFSR2_addr>(SINGLETON_FORWARD(SCIFSerialPort::Instance(), readStatus),
  667. SINGLETON_FORWARD(SCIFSerialPort::Instance(), writeStatus));
  668.  
  669. //READ only
  670. //SCIF SCFRDR2 0xFFE80014 0x1FE80014 8 Undefined Undefined Held Held Pclk
  671. setReadOnly<SCIF_SCFRDR2_addr>(SINGLETON_FORWARD(SCIFSerialPort::Instance(), SCFRDR2_read));
  672.  
  673. //SCIF SCFCR2 0xFFE80018 0x1FE80018 16 0x0000 0x0000 Held Held Pclk
  674. setHandlers<SCIF_SCFCR2_addr>(SCIFSerialPort::SCFCR2_read, SINGLETON_FORWARD(SCIFSerialPort::Instance(), SCFCR2_write));
  675.  
  676. //Read only
  677. //SCIF SCFDR2 0xFFE8001C 0x1FE8001C 16 0x0000 0x0000 Held Held Pclk
  678. setReadOnly<SCIF_SCFDR2_addr>(SINGLETON_FORWARD(SCIFSerialPort::Instance(), SCFDR2_read));
  679.  
  680. //SCIF SCSPTR2 0xFFE80020 0x1FE80020 16 0x0000 0x0000 Held Held Pclk
  681. setHandlers<SCIF_SCSPTR2_addr>(SCSPTR2_read, SINGLETON_FORWARD(SCIFSerialPort::Instance(), SCSPTR2_write));
  682.  
  683. //SCIF SCLSR2 0xFFE80024 0x1FE80024 16 0x0000 0x0000 Held Held Pclk
  684. setRW<SCIF_SCLSR2_addr, u16, 1>();
  685.  
  686. SCIFSerialPort::Instance().init();
  687.  
  688. reset(true);
  689. }
  690.  
  691. void SCIFRegisters::reset(bool hard)
  692. {
  693. super::reset();
  694.  
  695. /*
  696. SCIF SCSMR2 H'FFE8 0000 H'1FE8 0000 16 H'0000 H'0000 Held Held Pclk
  697. SCIF SCBRR2 H'FFE8 0004 H'1FE8 0004 8 H'FF H'FF Held Held Pclk
  698. SCIF SCSCR2 H'FFE8 0008 H'1FE8 0008 16 H'0000 H'0000 Held Held Pclk
  699. SCIF SCFTDR2 H'FFE8 000C H'1FE8 000C 8 Undefined Undefined Held Held Pclk
  700. SCIF SCFSR2 H'FFE8 0010 H'1FE8 0010 16 H'0060 H'0060 Held Held Pclk
  701. SCIF SCFRDR2 H'FFE8 0014 H'1FE8 0014 8 Undefined Undefined Held Held Pclk
  702. SCIF SCFCR2 H'FFE8 0018 H'1FE8 0018 16 H'0000 H'0000 Held Held Pclk
  703. SCIF SCFDR2 H'FFE8 001C H'1FE8 001C 16 H'0000 H'0000 Held Held Pclk
  704. SCIF SCSPTR2 H'FFE8 0020 H'1FE8 0020 16 H'0000*2 H'0000*2 Held Held Pclk
  705. SCIF SCLSR2 H'FFE8 0024 H'1FE8 0024 16 H'0000 H'0000 Held Held Pclk
  706. */
  707. SCIF_SCBRR2 = 0xFF;
  708. SCIF_SCFSR2.full = 0x060;
  709.  
  710. if (hard)
  711. SCIFSerialPort::Instance().setPipe(nullptr);
  712. SCIFSerialPort::Instance().reset();
  713. }
  714.  
  715. void SCIFRegisters::term()
  716. {
  717. SCIFSerialPort::Instance().term();
  718.  
  719. super::term();
  720. }
  721.  
  722. void SCIRegisters::init()
  723. {
  724. super::init();
  725.  
  726. // Serial Communication Interface
  727. setRW<SCI_SCSMR1_addr, u8>();
  728. setRW<SCI_SCBRR1_addr, u8>();
  729. setRW<SCI_SCSCR1_addr, u8>();
  730. setRW<SCI_SCTDR1_addr, u8>();
  731. setRW<SCI_SCSSR1_addr, u8, 0xf9>();
  732. setReadOnly<SCI_SCRDR1_addr, u8>();
  733. setRW<SCI_SCSPTR1_addr, u8, 0x8f>();
  734.  
  735. reset();
  736. }
  737.  
  738. void SCIRegisters::reset()
  739. {
  740. super::reset();
  741.  
  742. SCI_SCBRR1 = 0xff;
  743. SCI_SCTDR1 = 0xff;
  744. SCI_SCSSR1 = 0x84;
  745. }
Advertisement
Add Comment
Please, Sign In to add comment