forked from OldSkoolCode/Sega-Nuclear-Rush
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathVRDRV.ASM
executable file
·283 lines (265 loc) · 7.66 KB
/
VRDRV.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
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
*****************************************************************************
* Copyright (C) 1993 SEGA OF AMERICA INC.
* All Rights Reserved
*
* VRrev3.S - GENESIS VR Hat Tracker related routines
*
* Ver: 3.6(12/28/93) (based on 3rd rev of the protocol)
* modified for old ONOSENDAI
* Author: Unni Pillai (SOA)
*
* MODS:
* UP 04/29/93 Started
* UP 05/05/93
* UP 07/28/93 New routines HMD_INIT_RDY & HMD_DATA
* UP 08/10/93-08/19/93
* KLM 08/30/93 Cleaned up code and made it suitable for Nuclear Rush
* UP 10/13/93
* UP 12/14/93 Included equate.s
* UP 12/21/93 Made I/O lines = hi upon crash exits
* UP 12/28/93 Added delay = 5seconds before IDLE after RESET
* (in HMD_RESET)
* KLM 01/01/94 Cleaned up code and made it suitable for Nuclear Rush
*****************************************************************************
xdef _HMD_INIT_RDY
xdef _HMD_DATA
xref _SYS_HMD_ERROR
Z80BusReq equ $A11100 ; bit 8 (high=BusReq)
Z80Reset equ $A11200 ; bit 8 (low=Reset)
*******************************************************************************
* HMD_INIT_RDY Head Tracker Initialization routine
*
* INITIALIZES THE HEAD TRACKER
* THIS ROUTINE MUST BE THE FIRST ACCESS TO HEAD TRACKER
* essentially this routine issues RESET to the Head Tracker
* and reads the corresponding Head Tracker identification ID
* byte. Also refer to VR.DOC/VR.TXT
*
* In: Nothing.
* Out: _SYS_HMD_ERROR.L Status:
* 0 - Normal
* 1 - Timeout occurred
* $80000001 - Hardware error
* $80000002 - Timeout while RESET
*
*
* REGISTERS: d0 used for output,
* d7 destroy
* d6 destroy
* a0 used to address I/O port
* Ver: 0.5
* Author: Unni Pillai (Peripherals Department SOA)
* Mods:
* up 12/28/93 added delay 5seconds (in routine HMD_RESET)
****************************************************************************************
_HMD_INIT_RDY:
movem.l d1-d2/d6/d7/a0,-(sp)
move.w #$100,Z80BusReq ;Z80 bus request
move.w #$100,Z80Reset ;Z80 reset line high(NORMAL RUN STATE)
btst.b #0,Z80BusReq ;Z80 bus grant acknowledge?
bne.s *-8 ;wait until bus granted
move.l #$00a10005,a0 ;port address of HMD
move.b #$60,6(a0) ;set bits 6 and 5 output TH TR = out
moveq #0,d2
moveq #0,d7
move.w #$0fff,d7
bsr HMD_IDLE
tst.l d2
bne HMD_DATA_exit
bsr HMD_RESET
tst.l d2
bne HMD_DATA_exit
move.b #$20,(a0) ;1st Id nibble request TR =1
moveq #0,d7
move.w #$0fff,d7
HMD_init_lp0:
btst.b #4,(a0) ;check TL=0
beq HMD_INIT_10
dbra d7,HMD_init_lp0
bra HMD_FAIL
HMD_INIT_10:
move.b (a0),d1
and.b #$0f,d1
cmp.b #$08,d1
bne HMD_FAIL
move.b #$00,(a0) ;2nd Id reserve nibble req TR=0
HMD_init_lp1:
btst.b #4,(a0) ;check TL =1
bne HMD_DATA_20
dbra d7,HMD_init_lp1
bra HMD_timeout
******************************************************************************
* HMD_DATA Head Tracker Data Routine
*
* THIS DRIVER READS THE HEAD TRACKER DATA
* ACCESS THIS ROUTINE FROM WITHIN THE V_INT
* Head Tracker supports a 60HZ frame rate.
* Head Tracker must be plugged into I/O port 2.
*
* In: Nothing.
* Out: _SYS_HMD_ERROR.L Status:
* 0 - Normal
* 1 - Timeout occurred
* $80000001 - Hardware error
* $80000002 - Time out while RESET
*
* D0.L Data:
* xxxx|xxxx|xxxx|L R X8 Y8|X7 X6 X5 X4|X3 X2 X1 X0|Y7 Y6 Y5 Y4|Y3 Y2 Y1 Y0
* X0-X8 represent absolute YAW values from 0 to 360 degrees in HEX
* Y0-Y7 represents absolute PITCH values from 0to +/- 30 degrees
* Y8 is sign bit look up Y8 = 0
* look down Y8 = 1
*
* REGISTERS: d0 used for output,
* d2 used for output
* d7 destroyed
* d6 destroyed
* a0 used to address I/O port
* Ver: 0.5
* Author: Unni Pillai (Peripherals Department SOA)
* Mods:
* Unni Pillai 08/11/93
* Unni Pillai 12/21/93
****************************************************************************************
_HMD_DATA:
movem.l d1-d2/d6/d7/a0,-(sp)
move.w #$100,Z80BusReq ;Z80 bus request
move.w #$100,Z80Reset ;Z80 reset line high(NORMAL RUN STATE)
btst.b #0,Z80BusReq ;Z80 bus grant acknowledge?
bne.s *-8 ;wait until bus granted
move.l #$00a10005,a0 ; port address of HMD
move.b #$60,6(a0) ; set bits 6 and 5 output TH TR = out
moveq #0,d0 ; debounce delay for port switching
moveq #0,d2
HMD_DATA_20:
move.b #$20,(a0) ;1st data req TR=1
moveq #0,d7
move.w #$0fff,d7 ;max timeout = 40958 cycles
HMD_data_lp2:
btst.b #4,(a0) ;check TL=0
beq HMD_DATA_30
dbra d7,HMD_data_lp2
bra HMD_timeout
HMD_DATA_30:
move.b (a0),d0 ;d0=xxxx|L R X8 Y8
move.b #$00,(a0) ;2nd data req TR=0
lsl.l #8,d0 ;d0=xxxx|L R X8 Y8|X7 X6 X5 X4|X3 X2 X1 X0
HMD_data_lp3:
btst.b #4,(a0) ;check TL=1
bne HMD_DATA_40
dbra d7,HMD_data_lp3
bra HMD_timeout
HMD_DATA_40:
move.b (a0),d0 ;d0=L R X8 Y8|xxxx|X7 X6 X5 X4
move.b #$20,(a0) ;3rd req XLow
lsl.b #4,d0 ;d0=L R X8 Y8|X7 X6 X5 X4|xxxx
lsl.l #4,d0 ;d0=L R X8 Y8|X7 X6 X5 X4|xxxx|xxxx
HMD_data_lp4:
btst.b #4,(a0)
beq HMD_DATA_50
dbra d7,HMD_data_lp4
bra HMD_timeout
HMD_DATA_50:
move.b (a0),d0 ;d0=L R X8 Y8|X7 X6 X5 X4|xxxx|X3 X2 X1 X0
move.b #$00,(a0) ;4th req YHigh
lsl.b #4,d0 ;d0=L R X8 Y8|X7 X6 X5 X4|X3 X2 X1 X0|xxxx
lsl.l #4,d0 ;d0=L R X8 Y8|X7 X6 X5 X4|X3 X2 X1 X0|xxxx|xxxx
HMD_data_lp5:
btst.b #4,(a0)
bne HMD_DATA_60
dbra d7,HMD_data_lp5
bra HMD_timeout
HMD_DATA_60:
move.b (a0),d0 ;d0=L R X8 Y8|X7 X6 X5 X4|X3 X2 X1 X0|xxxx|Y7 Y6 Y5 Y4
move.b #$20,(a0) ;5th req YLOW
lsl.b #4,d0 ;d0=L R X8 Y8|X7 X6 X5 X4|X3 X2 X1 X0|Y7 Y6 Y5 Y4|xxxx
lsl.l #4,d0 ;d0=L R X8 Y8|X7 X6 X5 X4|X3 X2 X1 X0|Y7 Y6 Y5 Y4|xxxx|xxxx
HMD_data_lp6:
btst.b #4,(a0)
beq HMD_DATA_70
dbra d7,HMD_data_lp6
bra HMD_timeout
HMD_DATA_70:
move.b (a0),d0 ;d0=L R X8 Y8|X7 X6 X5 X4|X3 X2 X1 X0|Y7 Y6 Y5 Y4|xxxx|Y3 Y2 Y1 Y0
lsl.b #4,d0
lsr.l #4,d0
moveq #0,d2 ;d0=L R X8 Y8|X7 X6 X5 X4|X3 X2 X1 X0|Y7 Y6 Y5 Y4|Y3 Y2 Y1 Y0
bsr HMD_IDLE
HMD_DATA_exit:
move.l d2,_SYS_HMD_ERROR
move.w #0,Z80BusReq
movem.l (sp)+,d1-d2/d6/d7/a0
rts
********************************************************************
* HMD_IDLE sets the Head Tracker and Genesis into IDLE state
* in: a0 (address of I/O port 2 $00a10005)
* d7 timeout counter
* out: -
*********************************************************************
HMD_IDLE:
move.b #$60,(a0)
moveq #0,d6
nop
idle_lp:
btst.b #4,(a0)
bne idle_ack
dbra d7,idle_lp
bra HMD_ID_FAIL
idle_ack:
move.b (a0),d6
and.b #$7f,d6
cmp.b #$70,d6
bne HMD_ID_FAIL
rts
*************************************************************************
* HMD_RESET issues reset to the Head Tracker
* in: a0 (address of I/O port 2 $00a10005)
* d7 timer counter
* out: -
* mods:
* up 12/28/93 added 5sec delay work with ONOSENDAI
*********************************************************************
HMD_RESET:
move.b #$40,(a0) ;reset req TH=1 TR=0
moveq #0,d6
move.w #$fffe,d6
reset_lp:
btst.b #4,(a0)
beq reset_exit
dbra d6,reset_lp
bra HMD_rst_FAIL
reset_exit:
bsr HMD_IDLE
moveq #0,d5
move.w #65,d5
sec5_dly:
moveq #0,d6
move.w #$fffe,d6
ms8_dly:
dbra d6,ms8_dly
dbra d5,sec5_dly
rts
HMD_ID_FAIL:
move.l #$80000001,d2
move.b #$60,(a0) ;set TH, TR = 1 and exit
rts
HMD_FAIL:
move.l #$80000001,_SYS_HMD_ERROR
move.b #$60,(a0)
move.w #0,Z80BusReq
movem.l (sp)+,d1-d2/d6/d7/a0
rts
HMD_rst_FAIL:
move.l #$80000002,d2
move.b #$60,(a0)
rts
****************************************************************************
* HMD_timeout
* returns d2.l = 1 to indicate timeout occurred
****************************************************************************
HMD_timeout:
move.l #1,_SYS_HMD_ERROR
move.b #$60,(a0)
move.w #0,Z80BusReq
movem.l (sp)+,d1-d2/d6/d7/a0
rts