-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathnv_joystick_code.asm
221 lines (198 loc) · 6.74 KB
/
nv_joystick_code.asm
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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
//////////////////////////////////////////////////////////////////////////////
// nv_joystick_code.asm
// Copyright(c) 2021 Neal Smith.
// License: MIT. See LICENSE file in root directory.
//////////////////////////////////////////////////////////////////////////////
// Joystick handling code.
// The following subroutines should be called from the main engine
// as follows
// JoyInit: Call once before main loop and before other routines
// JoyScan: Call once every raster frame through the main loop
// JoyIsXxx: Call whenever joystick state is needed
// JoyCleanup: Call at end of program after main loop to clean up
//
// Note: Due to the design of the C64 joystick input (on port 1) also
// looks like keyboard input so if looking for keyboard input at the
// same time as joystick input on port 1 you will have a bad time.
// The best strategy if possible is to not look for keyboard
// characters that the joystick produces while the joystick is
// in use. Examples are:
// <space> key: indistinguishable from joystick 1 fire button.
// others, TBD:
//////////////////////////////////////////////////////////////////////////////
#importonce
#if !NV_C64_UTIL_DATA
.error "Error - nv_joystick_code.asm: NV_C64_UTIL_DATA not defined. Import nv_c64_util_data.asm"
#endif
// the #if above doesn't seem to always work so..
// if data hasn't been imported yet, import it into default location
#importif !NV_C64_UTIL_DATA "nv_c64_util_default_data.asm"
#import "nv_joystick_macs.asm"
#import "nv_screen_macs.asm"
.const JOY_PORT1_ADDR = $DC01 // 56321
.const JOY_PORT2_ADDR = $DC00 // 56320
.const JOY_UP_MASK = $01
.const JOY_DOWN_MASK = $02
.const JOY_LEFT_MASK = $04
.const JOY_RIGHT_MASK = $08
.const JOY_FIRE_MASK = $10
.const JOY_PORT_1_ID = $00
.const JOY_PORT_2_ID = $01
////////////////////
// some joystick variables
nv_joy_port1_state: .byte $00
nv_joy_port2_state: .byte $00
//////////////////////////////////////////////////////////////////////////////
// JoyInit
// initialize everything needed for joystick reading
JoyInit:
{
lda #$00
sta nv_joy_port1_state
sta nv_joy_port2_state
rts
}
// JoyInit - End
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// JoyScan
// scans the joystick ports and sets bits in nv_joy_port1_state and
// nv_joy_port2_state
JoyScan:
{
lda JOY_PORT1_ADDR
eor #$FF
sta nv_joy_port1_state
//nv_screen_poke_hex_byte_a(5, 0, true)
lda JOY_PORT2_ADDR
eor #$7F
sta nv_joy_port2_state
//nv_screen_poke_hex_byte_a(7, 0, true)
rts
}
// JoyScan - End
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// subroutine to put the current state of joysticks into x, y regs
// x gets port 1 state and y gets port 2 state.
// note this routine assumes that JoyScan is being called regularly
JoyCurStateXY:
{
ldx nv_joy_port1_state
ldy nv_joy_port2_state
rts
}
// JoyCurStateXY end
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// subroutine that determines if both joysticks are at rest
// if either joystick is firing or being pushed in any direction
// then this will set accum to non zero. if there is no activity
// on either joystick then this will set accum to zero
// note this routine assumes that JoyScan is being called regularly
// Accum: changes (zero for no activity or nonzero for activity)
// X Reg: no change
// Y Reg: no change
JoyIsAnyActivity:
{
lda nv_joy_port1_state
ora nv_joy_port2_state
rts
}
//////////////////////////////////////////////////////////////////////////////
// subroutine to determine if the joystick is in up state for a particular
// joystick port.
// params:
// x reg: the ID for joystick port for which the state is wanted
// accum: upon return will be 0 if its not in up state or non zero if is
// accum: changes
// x reg: unchanged
// y reg: unchanged
JoyIsUp:
{
lda #JOY_UP_MASK
and nv_joy_port1_state, x
rts
}
//
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// subroutine to determine if the joystick is in down state for a particular
// joystick port.
// params:
// x reg: the ID for joystick port for which the state is wanted
// accum: upon return will be 0 if its not in down state or nonzero if is
// accum: changes
// x reg: unchanged
// y reg: unchanged
JoyIsDown:
{
lda #JOY_DOWN_MASK
and nv_joy_port1_state, x
rts
}
//
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// subroutine to determine if the joystick is in left state for a particular
// joystick port.
// params:
// x reg: the ID for joystick port for which the state is wanted
// accum: upon return will be 0 if its not in left state or nonzero if is
// accum: changes
// x reg: unchanged
// y reg: unchanged
JoyIsLeft:
{
lda #JOY_LEFT_MASK
and nv_joy_port1_state, x
rts
}
//
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// subroutine to determine if the joystick is in right state for a particular
// joystick port.
// params:
// x reg: the ID for joystick port for which the state is wanted
// accum: upon return will be 0 if its not in right state or nonzero if is
// accum: changes
// x reg: unchanged
// y reg: unchanged
JoyIsRight:
{
lda #JOY_RIGHT_MASK
and nv_joy_port1_state, x
rts
}
//
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// subroutine to determine if the joystick fire button is pressed for a
// particular joystick port.
// params:
// x reg: the ID for joystick port for which the state is wanted
// accum: upon return will be 0 if its not firing or nonzero if is
// accum: changes
// x reg: unchanged
// y reg: unchanged
JoyIsFiring:
{
lda #JOY_FIRE_MASK
and nv_joy_port1_state, x
rts
}
//
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// JoyCleanup
// cleans up everything needed for joystick reading
JoyCleanup:
{
lda #$00
sta nv_joy_port1_state
sta nv_joy_port2_state
rts
}
// JoyCleanup - End
//////////////////////////////////////////////////////////////////////////////