// Hardware dependent part.
// Must be implemented on target microcontroller.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <stdbool.h>

#include "hwInterface.h"

// nice routines from friend
#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
#define bitToggle(value, bit) ((value) ^= (1UL << (bit)))
#define bitWrite(value, bit, bitvalue) ((bitvalue) ? bitSet(value, bit) : bitClear(value, bit))


uint8_t timer;
void timerSet(uint8_t data) {
    timer = data;
}

void timerStart() {;};
void timerStop() {;};
void timerEnableIRQ() {;};
void timerDisableIRQ() {;};

void enableExternalInterrupt() {;};
void disableExternalInterrupt() {;};

#define pinIRQ4 3
#define pinPAL 4
#define pinNMI 6
#define pinWTF 7

#define PORT1 0
#define PORT2 1

uint8_t ports[2] = {0xFF, 0xFF};

void pinSetColumn(uint8_t num) {
    uint8_t tmp;
    tmp = ports[PORT2] &  0b11111000;
    ports[PORT2] = tmp | (num & 0b111);
}

void pinSetIRQ4(uint8_t val) {
    bitWrite(ports[PORT2], pinIRQ4, val);
}

void pinSetPAL(uint8_t val) {
    bitWrite(ports[PORT2], pinPAL, val);
}

void pinSetNMI(uint8_t val) {
    bitWrite(ports[PORT2], pinNMI, val);
}

void pinSetWTF(uint8_t val) {
    bitWrite(ports[PORT2], pinWTF, val);
}

// test pins on i8741A, used for keyboard matrix
bool T0 = true;
bool T1 = true;  

bool pinT0() {
    T0 = !T0;
    return T0;
}

bool pinT1() {
    T1 = !T1;
    return T1;
}

uint8_t portRead() {
    return ports[PORT1];
}

uint8_t busStatus;

// busSatus register flags
#define OBF 0       // Output buffer full. CPU not read data yet
#define IBF 1       // Input buffer full. CPU send data. Need to parse.
//#define F0  2       // User settable flag (not used)
#define F1  3       // data (0)/command(1) Flag. Set when CPU send data
#define ST4 4       // User settable flag
#define ST5 5       // User settable flag - SHIFT key?
#define ST6 6       // User settable flag - CODE key?
#define ST7 7       // User settable flag - CTRL key?

bool busReadOBF() {
    return bitRead(busStatus, OBF);
}

bool busReadF1() {
    return bitRead(busStatus, F1);
}

uint8_t busReadStatus() {
    return busStatus;
}

void busWriteStatus(uint8_t status) {
    busStatus = (status & 0b11110000) | (busStatus & 0b00001111);
}

uint8_t busReadData() {
    static uint8_t busIn = 0;
    return busIn;
};

void busWriteData(uint8_t data) {
    static uint8_t busOut;
    busOut = data;
    printf("busOut: 0x%02X\n", busOut);
};
