Post by Malban on Aug 3, 2018 13:18:25 GMT -5
Spinner
In Vectrex "words" the controller uses button 1 and button 2. Both buttons are connected to the spinners rotary two bit gray code encoder.
The Gray code after Frank Gray, is an ordering of the binary numeral system such that two successive values differ in only one bit (binary digit).
What it boils down to is, that while rotating the paddle, contacts are rotated on a disk inside the encoder. Each contact is placed over a circular lane. The lanes are contructed such that each lane is half way an insulater and the other half is conductive. The lanes are displaced by 90 degrees.
The result looks like following picture I found:
(picture stolen from: www.danielvik.com/2015/01/colecovision-driving-module.html)
When rotating and reading values from the contacts (button 1 and button 2), the resulting 2 bit values are such that they differ only ever in one bit:
00
01
11
10
To get a "direction" from the readings you must compare previous readings with the current readings of the paddle.
Transitions which are in the above order, e.g. "00->01" or "01->11" are an indicator that you rotated the wheel clockwise.
Transitions in the opposite order, e.g. "11->01" or "10->11" indicate the wheel was rotated counter clockwise.
Transitions which are not allowed, e.g. "00->11" are "errors" that should be discarded.
A possible problem with "vectrex":
Usually you do your "input" readings once per game round, that means about every 30000 cycles (or 50 times per second). If you are able to spin the spinner so fast that you "overstep" one gray code (with above example disk, more than 90 degrees in 1/50 of a second) the grey code will "hickup" and the reading is false.
Following code was provided a long time ago by "Christopher L. Tumber". It was given to the public - even if I can't remember when and where.
;read_spinner
;A routine by Christopher L. Tumber
;
;This routine reads the spinner. It requires one variable named
;
;old_spinner
;
;Which stores the previous spinner value.
;
;This routine branches to two locations as follows:
;
;player_plus: - Rotates/moves the player "plus" (ie: counter-clockwise)
;player_minus: - Rotates/moves the player "minus" (ie: clockwise)
read_spinner:
lda #$00
ldb $c816
beq not_a2
lda #$02
not_a2:
ldb $c817
beq not_b2
inca
not_b2:
cmpa old_spinner
beq no_spinner_move
ldb old_spinner
sta old_spinner
cmpa #$00
bne not_spin1
cmpb #$01
beq player_plus
not_spin1:
cmpa #$01
bne not_spin2
cmpb #$03
beq player_plus
not_spin2:
cmpa #$03
bne not_spin3
cmpb #$02
beq player_plus
not_spin3:
cmpa #$02
bne not_spin4
cmpb #$00
beq player_plus
not_spin4:
cmpa #$00
bne not_spin5
cmpb #$02
beq player_minus
not_spin5:
cmpa #$02
bne not_spin6
cmpb #$03
beq player_minus
not_spin6:
cmpa #$03
bne not_spin7
cmpb #$01
beq player_minus
not_spin7:
cmpa #$01
bne not_spin8
cmpb #$00
beq player_minus
not_spin8:
no_spinner_move:
rts
player_plus:
player_minus:
Regards
Malban