-
Notifications
You must be signed in to change notification settings - Fork 0
/
kscan.c
143 lines (109 loc) · 3.51 KB
/
kscan.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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#include "kscan.h"
#ifdef TI99
unsigned char kscan(unsigned char mode) {
KSCAN_MODE = mode;
__asm__ volatile ("LWPI >83E0\n\tBL @>000E\n\tLWPI >8300");
return KSCAN_KEY;
}
#endif
#ifdef COLECO
// coleco and sms are very different here
#ifdef SMS
// note: we have two fire buttons, A and B
// for now, I'm defining them the same as regular fire (18),
// but if I ever want to split up them, I can update this.
static volatile __sfr __at 0xdc pad0;
static volatile __sfr __at 0xdd pad1;
extern unsigned char pause;
// TODO: reset reads as bit 0x10 on pad1 - do we need to manually handle reset in software?
// For SMS, all modes except 2 read controller 1, and 2 reads controller 2
unsigned char kscan(unsigned char mode) {
unsigned char key;
KSCAN_KEY = 0xff;
if (mode == KSCAN_MODE_RIGHT) {
key = pad1;
if ((key&0x08)==0) KSCAN_KEY=JOY_FIRE2;
if ((key&0x04)==0) KSCAN_KEY=JOY_FIRE; // todo: make it possible to read both at once?
} else {
key = pad0;
if ((key&0x20)==0) KSCAN_KEY=JOY_FIRE2;
if ((key&0x10)==0) KSCAN_KEY=JOY_FIRE; // todo: make it possible to read both at once?
}
key=pad1;
if (key&0x10) KSCAN_KEY='#'; // reset - TODO: maybe I don't want this here now that I have checkReset?
if (pause) { pause=0; KSCAN_KEY='*'; }
if ((mode == KSCAN_MODE_LEFT) || (mode == KSCAN_MODE_RIGHT)) {
joystfast(mode);
}
if (KSCAN_KEY != 0xff) {
KSCAN_STATUS |= KSCAN_MASK;
} else {
KSCAN_STATUS = 0;
}
return KSCAN_KEY;
}
#else
// Coleco
#define SELECT 0x2a
// fire buttons are all the same for the moment. Note that 2 and 3 read
// via the keypad, but 1 has a dedicated bit and could be overlapped
// note: keys index 8 and 4 are fire 2 and fire 3, respectively
// for now, I'm defining them the same as regular fire (18),
// but if I ever want to split up them, I can update this.
extern const unsigned char keys[16];
// FIRE 1 returns as bit 0x40 being low
static volatile __sfr __at 0xfc port0;
static volatile __sfr __at 0xff port1;
static volatile __sfr __at 0x80 port2;
static volatile __sfr __at 0xc0 port3;
// For Coleco, all modes except 2 read controller 1, and 2 reads controller 2
unsigned char kscan(unsigned char mode) {
unsigned char key;
port2 = SELECT; // select keypad
if (mode == KSCAN_MODE_RIGHT) {
key = port1;
} else {
key = port0;
}
// bits: xFxxNNNN (F - active low fire 2, NNNN - index into above table)
// if reading joystick, the fire2 button overrides
// Note this limits us not to read keypad and fire2 at the same time,
// which honestly I will probably want later. (Also see below for
// where FIRE1 overrides this.)
if ((key&0x40) == 0) {
KSCAN_KEY = JOY_FIRE2;
} else {
KSCAN_KEY = keys[key & 0xf];
}
if ((mode == KSCAN_MODE_LEFT) || (mode == KSCAN_MODE_RIGHT)) {
joystfast(mode);
}
if (KSCAN_KEY != 0xff) {
KSCAN_STATUS |= KSCAN_MASK;
} else {
KSCAN_STATUS = 0;
}
return KSCAN_KEY;
}
#endif
#endif
#ifdef GBA
#include <tursigb.h>
// fire buttons are all the same for the moment. Note that 2 and 3 read
// via the keypad, but 1 has a dedicated bit and could be overlapped
// this is pretty much the same as kscanfast but it returns a value and sets status
// it also reads the joysticks, though I'm not sure why...
// For GBA, all modes except 2 read the only controller, and 2 reads nothing
unsigned char kscan(unsigned char mode) {
kscanfast(mode);
if (mode == KSCAN_MODE_LEFT) {
joystfast(mode);
}
if (KSCAN_KEY != 0xff) {
KSCAN_STATUS |= KSCAN_MASK;
} else {
KSCAN_STATUS = 0;
}
return KSCAN_KEY;
}
#endif