<commit_before>/* Copyright (c) 2013-2014 <NAME>
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "gba.h"

#include "gba-gpio.h"
#include "gba-sensors.h"
#include "gba-serialize.h"

#include <time.h>

static void _readPins(struct GBACartridgeGPIO* gpio);
static void _outputPins(struct GBACartridgeGPIO* gpio, unsigned pins);

static void _rtcReadPins(struct GBACartridgeGPIO* gpio);
static unsigned _rtcOutput(struct GBACartridgeGPIO* gpio);
static void _rtcProcessByte(struct GBACartridgeGPIO* gpio);
static void _rtcUpdateClock(struct GBACartridgeGPIO* gpio);
static unsigned _rtcBCD(unsigned value);

static void _gyroReadPins(struct GBACartridgeGPIO* gpio);

static void _rumbleReadPins(struct GBACartridgeGPIO* gpio);

static void _lightReadPins(struct GBACartridgeGPIO* gpio);

static const int RTC_BYTES[8] = {
	0, // Force reset
	0, // Empty
	7, // Date/Time
	0, // Force IRQ
	1, // Control register
	0, // Empty
	3, // Time
	0 // Empty
};

void GBAGPIOInit(struct GBACartridgeGPIO* gpio, uint16_t* base) {
	gpio->gpioDevices = GPIO_NONE;
	gpio->direction = GPIO_WRITE_ONLY;
	gpio->gpioBase = base;
	gpio->pinState = 0;
	gpio->direction = 0;
}

void GBAGPIOWrite(struct GBACartridgeGPIO* gpio, uint32_t address, uint16_t value) {
	switch (address) {
	case GPIO_REG_DATA:
		gpio->pinState &= ~gpio->direction;
		gpio->pinState |= value;
		if (gpio->readWrite) {
			uint16_t old = gpio->gpioBase[0];
			old &= ~gpio->direction;
			gpio->gpioBase[0] = old | gpio->pinState;
		}
		_readPins(gpio);
		break;
	case GPIO_REG_DIRECTION:
		gpio->direction = value;
		break;
	case GPIO_REG_CONTROL:
		gpio->readWrite = value;
		break;
	default:
		GBALog(gpio->p, GBA_LOG_WARN, "Invalid GPIO address");
	}
}

void GBAGPIOInitRTC(struct GBACartridgeGPIO* gpio) {
	gpio->gpioDevices |= GPIO_RTC;
	gpio->rtc.bytesRemaining = 0;
<commit_msg>GBA: Fix GPIO being readable when set to write-only<commit_after>/* Copyright (c) 2013-2014 <NAME>
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "gba.h"

#include "gba-gpio.h"
#include "gba-sensors.h"
#include "gba-serialize.h"

#include <time.h>

static void _readPins(struct GBACartridgeGPIO* gpio);
static void _outputPins(struct GBACartridgeGPIO* gpio, unsigned pins);

static void _rtcReadPins(struct GBACartridgeGPIO* gpio);
static unsigned _rtcOutput(struct GBACartridgeGPIO* gpio);
static void _rtcProcessByte(struct GBACartridgeGPIO* gpio);
static void _rtcUpdateClock(struct GBACartridgeGPIO* gpio);
static unsigned _rtcBCD(unsigned value);

static void _gyroReadPins(struct GBACartridgeGPIO* gpio);

static void _rumbleReadPins(struct GBACartridgeGPIO* gpio);

static void _lightReadPins(struct GBACartridgeGPIO* gpio);

static const int RTC_BYTES[8] = {
	0, // Force reset
	0, // Empty
	7, // Date/Time
	0, // Force IRQ
	1, // Control register
	0, // Empty
	3, // Time
	0 // Empty
};

void GBAGPIOInit(struct GBACartridgeGPIO* gpio, uint16_t* base) {
	gpio->gpioDevices = GPIO_NONE;
	gpio->direction = GPIO_WRITE_ONLY;
	gpio->gpioBase = base;
	gpio->pinState = 0;
	gpio->direction = 0;
}

void GBAGPIOWrite(struct GBACartridgeGPIO* gpio, uint32_t address, uint16_t value) {
	switch (address) {
	case GPIO_REG_DATA:
		gpio->pinState &= ~gpio->direction;
		gpio->pinState |= value;
		_readPins(gpio);
		break;
	case GPIO_REG_DIRECTION:
		gpio->direction = value;
		break;
	case GPIO_REG_CONTROL:
		gpio->readWrite = value;
		break;
	default:
		GBALog(gpio->p, GBA_LOG_WARN, "Invalid GPIO address");
	}
	if (gpio->readWrite) {
		uint16_t old = gpio->gpioBase[0];
		old &= ~gpio->direction;
		gpio->gpioBase[0] = old | gpio->pinState;
	} else {
		gpio->gpioBase[0] = 0;
	}
}

void GBAGPIOInitRTC(struct GBACartridgeGPIO* gpio) {
	gpio->gpioDevices |= GPIO_RTC;
	gpio->rtc.bytesRemaining = 0;

{'fraction_non_alphanumeric': 0.1212567501227295, 'fraction_numerical': 0.01718213058419244, 'mean_word_length': 4.605226960110041, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 44, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1157603', 'n_tokens_mistral': 1584, 'n_tokens_neox': 1481, 'n_words': 393}