src/gb/sio.c (view raw)
1/* Copyright (c) 2013-2016 Jeffrey Pfau
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6#include "sio.h"
7
8#include "gb/gb.h"
9#include "gb/io.h"
10#include "gb/serialize.h"
11
12void _GBSIOProcessEvents(struct mTiming* timing, void* context, uint32_t cyclesLate);
13
14void GBSIOInit(struct GBSIO* sio) {
15 sio->pendingSB = 0xFF;
16 sio->event.context = sio;
17 sio->event.name = "GB SIO";
18 sio->event.callback = _GBSIOProcessEvents;
19}
20
21void GBSIOReset(struct GBSIO* sio) {
22 sio->nextEvent = INT_MAX;
23 sio->remainingBits = 0;
24}
25
26void GBSIODeinit(struct GBSIO* sio) {
27 UNUSED(sio);
28 // Nothing to do yet
29}
30
31void _GBSIOProcessEvents(struct mTiming* timing, void* context, uint32_t cyclesLate) {
32 UNUSED(cyclesLate);
33 struct GBSIO* sio = context;
34 --sio->remainingBits;
35 sio->p->memory.io[REG_SB] &= ~(8 >> sio->remainingBits);
36 sio->p->memory.io[REG_SB] |= sio->pendingSB & ~(8 >> sio->remainingBits);
37 if (!sio->remainingBits) {
38 sio->p->memory.io[REG_IF] |= (1 << GB_IRQ_SIO);
39 sio->p->memory.io[REG_SC] = GBRegisterSCClearEnable(sio->p->memory.io[REG_SC]);
40 GBUpdateIRQs(sio->p);
41 } else {
42 mTimingSchedule(timing, &sio->event, sio->period);
43 }
44}
45
46void GBSIOWriteSC(struct GBSIO* sio, uint8_t sc) {
47 sio->period = 0x1000; // TODO Shift Clock
48 if (GBRegisterSCIsEnable(sc)) {
49 if (GBRegisterSCIsShiftClock(sc)) {
50 mTimingSchedule(&sio->p->timing, &sio->event, sio->period);
51 }
52 sio->remainingBits = 8;
53 }
54}
55