-
Notifications
You must be signed in to change notification settings - Fork 83
/
via.c
116 lines (102 loc) · 2.05 KB
/
via.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
// Commander X16 Emulator
// Copyright (c) 2019 Michael Steil
// All rights reserved. License: 2-clause BSD
#include <stdio.h>
#include <stdbool.h>
#include "via.h"
#include "ps2.h"
#include "memory.h"
//XXX
#include "glue.h"
//
// VIA#1
//
// PA0-7 RAM bank
// PB0-2 ROM bank
// PB3 IECATT0
// PB4 IECCLK0
// PB5 IECDAT0
// PB6 IECCLK
// PB7 IECDAT
// CB1 IECSRQ
static uint8_t via1registers[16];
uint8_t
via1_read(uint8_t reg)
{
return via1registers[reg];
}
void
via1_write(uint8_t reg, uint8_t value)
{
via1registers[reg] = value;
if (reg == 0) { // PB: ROM bank, IEC
memory_set_rom_bank(value & 7);
// TODO: IEC
} else if (reg == 1) { // PA: RAM bank
memory_set_ram_bank(value);
} else {
// TODO
}
}
//
// VIA#2
//
// PA0 PS/2 DAT
// PA1 PS/2 CLK
// PA2 LCD backlight
// PA3 NESJOY latch (for both joysticks)
// PA4 NESJOY joy1 data
// PA5 NESJOY joy1 CLK
// PA6 NESJOY joy2 data
// PA7 NESJOY joy2 CLK
static uint8_t via2registers[16];
static uint8_t via2pb_in;
uint8_t
via2_read(uint8_t reg)
{
if (reg == 0) {
// PB
// 0 input -> take input bit
// 1 output -> take output bit
return (via2pb_in & (via2registers[2] ^ 0xff)) |
(via2registers[0] & via2registers[2]);
} else if (reg == 1) {
// PA
uint8_t value =
(via2registers[3] & PS2_CLK_MASK ? 0 : ps2_clk_out << 1) |
(via2registers[3] & PS2_DATA_MASK ? 0 : ps2_data_out) |
0x50; // short-circuit NES/SNES contoller -> not present
return value;
} else {
return via2registers[reg];
}
}
void
via2_write(uint8_t reg, uint8_t value)
{
via2registers[reg] = value;
if (reg == 0) {
// PB
} else if (reg == 2) {
// PB DDRB
} else if (reg == 1 || reg == 3) {
// PA
ps2_clk_in = via2registers[3] & PS2_CLK_MASK ? via2registers[1] & PS2_CLK_MASK : 1;
ps2_data_in = via2registers[3] & PS2_DATA_MASK ? via2registers[1] & PS2_DATA_MASK : 1;
}
}
uint8_t
via2_pb_get_out()
{
return via2registers[2] /* DDR */ & via2registers[0]; /* PB */
}
void
via2_pb_set_in(uint8_t value)
{
via2pb_in = value;
}
void
via2_sr_set(uint8_t value)
{
via2registers[10] = value;
}