| |
jamiefuller Account closed
Registered: Mar 2018 Posts: 25 |
NEOS mouse, losing my hair...
Hi All,
Please can anyone help, I am trying to read the signal from the NEOS mouse, I have this bit working based on some code from the c64-wiki and a working mouse pointer.
But no matter what I do it massively interferes with the keyboard.
I have heard the mouse works with GEOS so it must be theoretically possible (unless the NEOS only works with GEOS in joystick mode).
The source code is below and also on pastebin, I've tried to make it as readable as possible but my code isn't always the tidiest. :)
https://pastebin.com/SSbUbvhx
basically it runs every frame to poll the mouse, it puts the values into some variables (set to the screen in this example to make it visible)
the background colour should only change if the W key is being pressed, but it triggers even when not pressing due to the mouse.
Would be grateful of any advice.
Thanks
Jamie
VIC_SPRITE_MSB=$D010
VIC_SPRITE_ENABLE=$D015
VIC_SPRITE_YEXPAND=$D017
VIC_SPRITE_PRIORITY=$D01B
VIC_SPRITE_MULTICOLOUR=$D01C
VIC_SPRITE_XEXPAND=$D01D
VIC_BORDERCOLOUR=$D020
VIC_BGCOLOUR= $D021
VIC_BGCOLOUR_MC1=$D022
VIC_BGCOLOUR_MC2=$D023
VIC_SPRITE_MC1= $D025
VIC_SPRITE_MC2= $D026
CIA_1 = $dc00 ; CIA#1 (Port Register A)
CIA_2 = $dc01 ; CIA#2 (Port Register B)
CIA_ddra = $dc02 ; CIA#1 (Data Direction Register A)
CIA_ddrb = $dc03 ; CIA#2 (Data Direction Register B)
XPADDLE= $d419
MOUSEX= $0400
MOUSEY= $0401
MOUSEX_SPEED= $0428 ;$19
MOUSEY_SPEED= $0429 ;$1a
MDBUTTON= $0459
; 10 SYS2064
*=$0801
BYTE $0B, $08, $0A, $00, $9E, $32, $30, $36, $34, $00, $00, $00
*=$0810
init
; copy sprite data to sprite location
ldy #$3F
@in10 lda spritedata,y
sta $0340,y
dey
bpl @in10
lda #$0D ;set sprite pointer
sta $07F8
lda #$01 ;switch on sprite 1
sta VIC_SPRITE_ENABLE
lda #$07 ;set sprite colour to yellow
sta $D027
lda #%01111111
sta $DC0D ;"Switch off" interrupts signals from CIA-1
and $D011
sta $D011 ;Clear most significant bit in VIC's raster register
lda #$51
sta $D012 ; set raster to occour 1 lines down
lda #<irq_handler
sta $0314 ; set low bit of start
lda #>irq_handler
sta $0315 ; set high bit of start
lda #%00000001
sta $D01A
@endloop
jmp @endloop
irq_handler
LDA #$00
STA VIC_BORDERCOLOUR
jsr handlekeyboard
jsr handlemouseneos
JSR DRAWSPRITE
INC VIC_BORDERCOLOUR
asl $D019
JMP $EA31
DRAWSPRITE
lda MOUSEX
clc
adc #$0C
asl a
pha
bcc @ds10
lda VIC_SPRITE_MSB
ora #$01
bne @ds20
@ds10 lda VIC_SPRITE_MSB
and #$FE
@ds20 sta VIC_SPRITE_MSB
pla
sta $D000 ; sprite X
clc
lda MOUSEY
adc #$32
sta $D001 ; sprite y
rts
handlekeyboard
lda #$0
sta CIA_ddra ;Port A data direction register.
lda #$0
sta CIA_ddrb ;Port B data direction register.
@up
lda #%11111101 ;
sta CIA_1
lda CIA_2 ; load column information
and #%00000010 ; test 'w' key
bne @noup ; zero flag is not set -> skip next command
inc VIC_BGCOLOUR
@noup
rts
handlemouseneos
@LC020 jsr @LC100
lda #$00
bcc @LC029
lda #$02
@LC029 sta MDBUTTON
jsr @LC190
lda CIA_2 ; left button
and #$10
BNE @RT
INC MDBUTTON
@RT
rts
@LC100 ; READ MOUSE
lda #$10
sta CIA_ddrb ;Port B data direction register.
LDA #$ef
sta CIA_2 ;PORT B
lda CIA_2 ;PORT B, read 4 bits
asl a
asl a
asl a
asl a
sta MOUSEX_SPEED ; TIMES BY 16 AND STORE AT $19
LDA #$10
sta CIA_2
lda CIA_2 ; read 4 bits
and #$0F
ora MOUSEX_SPEED
sta MOUSEX_SPEED
LDA #$EF
sta CIA_2
lda CIA_2
asl a
asl a
asl a
asl a
sta MOUSEY_SPEED
LDA #$10
sta CIA_2
lda CIA_2
and #$0F
ora MOUSEY_SPEED
sta MOUSEY_SPEED
lda XPADDLE
cmp #$FF
rts
@LC190 ; TRANSLATE BASED ON SPEED
lda MOUSEX_SPEED
bmi @LC1A2
sec
lda MOUSEX
sbc MOUSEX_SPEED
bcs @LC1AF
lda #$00
beq @LC1AF
@LC1A2 sec
lda MOUSEX
sbc MOUSEX_SPEED
bcs @LC1AD
cmp #$A0
bcc @LC1AF
@LC1AD lda #$9F
@LC1AF sta MOUSEX
lda MOUSEY_SPEED
bmi @LC1C0
sec
lda MOUSEY
sbc MOUSEY_SPEED
bcs @LC1CD
lda #$00
beq @LC1CD
@LC1C0 sec
lda MOUSEY
sbc MOUSEY_SPEED
bcs @LC1CB
cmp #$C8
bcc @LC1CD
@LC1CB lda #$C7
@LC1CD sta MOUSEY
rts
spritedata
byte $FC,$00,$00,$F0,$00,$00,$F0,$00,$00,$D8,$00,$00,$8C,$00,$00,$86,$00,$00,$03
bytes 63
|
|
| |
chatGPZ
Registered: Dec 2001 Posts: 11100 |
check the test program in the VICE repo:
https://sourceforge.net/p/vice-emu/code/HEAD/tree/testprogs/mou.. |
| |
Krill
Registered: Apr 2002 Posts: 2825 |
This will likely not fix the keyboard interference problem, but you might want to set $dc02 (CIA#1 DDRA, keyboard matrix column select) to output, like this:
handlekeyboard
lda #$ff ; output
sta CIA_ddra ; $DC02, Port A data direction register.
lda #$0
sta CIA_ddrb ; $DC03, Port B data direction register. That said, you can try if setting $DC03 and $DC01 to $ff helps.
This sets the keyboard matrix row bits to output, but you can still read the current line states. However, actively driving these lines might or might not reduce mouse interference. Note that this is the same trick which makes it possible to distinguish left shift from shift lock on "most" C-64s.
But, is the other control port not an option? This would likely help. |
| |
chatGPZ
Registered: Dec 2001 Posts: 11100 |
id' also check the mouse first, then the keyboard. else the keyboard scanner might unintentionally wiggle the select line of the mouse (forgot which that was) and the mouse goes into next state. if you call the keyboard scanner after checking the mouse, there is a maximum time (one frame) before the mouse is checked, which will hopefully make the statemachine time out/restart correctly. |
| |
TWW
Registered: Jul 2009 Posts: 541 |
Hello
Can you explain how his neos mouse works compared to the standard C= mouse works?
Normally only mouse-clicks interfere with keyboard scan but this can easily be avoided. |
| |
chatGPZ
Registered: Dec 2001 Posts: 11100 |
one line at the joystick port is output (the select line, which is "fire") and the directional bits are input. now you invert the select line, and then read 4 bits from the directional lines. you get 4 nibbles, which then form the x-delta and y-delta
as said, look at https://sourceforge.net/p/vice-emu/code/HEAD/tree/testprogs/mou.. |
| |
jamiefuller Account closed
Registered: Mar 2018 Posts: 25 |
Thanks for the posts,
Quoting Groepazcheck the test program in the VICE repo:
Thanks for the link, that code looks almost identical to the code within the c64-wiki, I added back in some of the code I had intentionally dropped but still no luck :( My mouse driver works but it just messes up the keyboard, The example on the VICE works but doesn't test the keyboard
Quoting KrillBut, is the other control port not an option? This would likely help. Thanks, I've tried it in both ports, both cause the same problem. |
| |
chatGPZ
Registered: Dec 2001 Posts: 11100 |
the code in the c64wiki is also ripped from "mouse cheese" i think, so indeed, its the same thing :)
that said, i'm not sure if interference with the keyboard can be avoided completely. the mouse will always "see" changes on the select line, and it will always put out some value on the directional lines. so basically you will get the same problems as with someone wiggling a joystick while you are typing. (except they will persist when the mouse is not being moved). the best bet is probably to write your own keyboard scanner, and not use any keys that use the problematic i/o lines. |
| |
jamiefuller Account closed
Registered: Mar 2018 Posts: 25 |
Quote: the code in the c64wiki is also ripped from "mouse cheese" i think, so indeed, its the same thing :)
that said, i'm not sure if interference with the keyboard can be avoided completely. the mouse will always "see" changes on the select line, and it will always put out some value on the directional lines. so basically you will get the same problems as with someone wiggling a joystick while you are typing. (except they will persist when the mouse is not being moved). the best bet is probably to write your own keyboard scanner, and not use any keys that use the problematic i/o lines.
Yeah that was my concern :( I am writing a game that requires both mouse and keyboard, I am using the standard "wasd" for movement so I am really tied into them. thanks anyway, My game works perfectly with a 1351 mouse but I wanted to add neos support too, but I guess it's out of the question. |
| |
JackAsser
Registered: Jun 2002 Posts: 1987 |
I have done a great deal of research into this for Eye of the Beholder and have a close to perfect solution now. PM me for ingo. I don’t have time for a big write up atm. |
| |
JackAsser
Registered: Jun 2002 Posts: 1987 |
Quote: I have done a great deal of research into this for Eye of the Beholder and have a close to perfect solution now. PM me for ingo. I don’t have time for a big write up atm.
Nm, though it was about 1351 only.. |
| |
Krill
Registered: Apr 2002 Posts: 2825 |
Quoting JackAsserI have done a great deal of research into this for Eye of the Beholder and have a close to perfect solution now. PM me for ingo. I don’t have time for a big write up atm. And here i found myself equally awed by an unexpected solution and annoyed by not even giving the slightest hint of its nature. :) |
| |
chatGPZ
Registered: Dec 2001 Posts: 11100 |
whats there to research for 1351? =D |
| |
jamiefuller Account closed
Registered: Mar 2018 Posts: 25 |
Quote: Nm, though it was about 1351 only..
:) |
| |
JackAsser
Registered: Jun 2002 Posts: 1987 |
Quote: whats there to research for 1351? =D
Alot |
| |
JackAsser
Registered: Jun 2002 Posts: 1987 |
Quote: Alot
The three most important realisations that are not so well documented are:
1) polling once per frame is WAY insufficient. At least 100hz to handle swift motion.
2) The SID-ADCs do not have a bit 0 jitter but an additive 0/1 jitter which means you can’t simply mask or shift it away like all reference implementations. A jitter between 15-16 will still jitter after an lsr-operation between 7-8 instead.
3) you helped me here Groepaz and it’s not so well documented (well it is if you know WHIC doc to read ;) ) either which is how long you need to wait after polling the keyboard and setting up the control lines for the mouse. I.e. how often the SID scans. |
| |
chatGPZ
Registered: Dec 2001 Posts: 11100 |
Quote:The SID-ADCs do not have a bit 0 jitter but an additive 0/1 jitter which means you can’t simply mask or shift it away like all reference implementations.
hu? i can assure you that my test code that does just that is rock stable without jitter here. sure your mouse isnt just fubar? or are you using some kind of adapter thing that doesnt work exactly right? :)
that said, the SID ADC counter is exactly as much "jittering" as the system clock. the mouse creates the jitter that you see :) |
| |
JackAsser
Registered: Jun 2002 Posts: 1987 |
Quote: Quote:The SID-ADCs do not have a bit 0 jitter but an additive 0/1 jitter which means you can’t simply mask or shift it away like all reference implementations.
hu? i can assure you that my test code that does just that is rock stable without jitter here. sure your mouse isnt just fubar? or are you using some kind of adapter thing that doesnt work exactly right? :)
that said, the SID ADC counter is exactly as much "jittering" as the system clock. the mouse creates the jitter that you see :)
Hmms ok. I’ve tried with both 1351 and micromys. Both shows the same jitter |
| |
chatGPZ
Registered: Dec 2001 Posts: 11100 |
try connecting a paddle - when you dont move it, you'll get a stable value (unless that paddle is really crazy dirty or sth). 1351 dont use a resistor, they wait until they "see" the start of the sampling period, and then pull down the line for a while. and that is not perfectly synced with the c64 (obviously) -> jitter |
| |
JackAsser
Registered: Jun 2002 Posts: 1987 |
Quote: try connecting a paddle - when you dont move it, you'll get a stable value (unless that paddle is really crazy dirty or sth). 1351 dont use a resistor, they wait until they "see" the start of the sampling period, and then pull down the line for a while. and that is not perfectly synced with the c64 (obviously) -> jitter
Thanks for the in-depth explanation. Non the less it requires some trickery to filter it out. All 1351 implementations I’ve seen don’t do this. |
| |
chatGPZ
Registered: Dec 2001 Posts: 11100 |
because there is no need :) i have never seen a problem that would suggest it at least - the textbook example code works just fine. (even polling at 50Hz works fine if you dont move too fast :=P) |
| |
JackAsser
Registered: Jun 2002 Posts: 1987 |
https://youtu.be/Ej5INd5P8yU This has been fixed now but you clearly see the jitter here. |
| |
chatGPZ
Registered: Dec 2001 Posts: 11100 |
never seen this in the time i worked on micromys, its just rock stable here =P |
| |
JackAsser
Registered: Jun 2002 Posts: 1987 |
Quote: never seen this in the time i worked on micromys, its just rock stable here =P
This was with a micromys... same with 1351. So perhaps it is my ADCs then? |
| |
chatGPZ
Registered: Dec 2001 Posts: 11100 |
no idea really. v4 has some problems, but those are related to the wraparound of the counter, so you will see a "jump" of two pixels instead of one every now and then - but that should be it.
perhaps check with another C64? :) |
| |
JackAsser
Registered: Jun 2002 Posts: 1987 |
Quote: no idea really. v4 has some problems, but those are related to the wraparound of the counter, so you will see a "jump" of two pixels instead of one every now and then - but that should be it.
perhaps check with another C64? :)
Yes. This is a v2 iirc. My sid chip sounds borked anyway. It got a taste of an Amiga powersupply (c128 have the same connector). Maybe that fried the ADCs abit also. :) |
| |
chatGPZ
Registered: Dec 2001 Posts: 11100 |
LOL |
| |
MagerValp
Registered: Dec 2001 Posts: 1055 |
@JackAsser: I saw the same thing as you regarding jitter, and dividing by two doesn't help. In my driver I decrease the delta by one (decrement if positive delta, increment for negative), which gets rid of it. |
| |
JackAsser
Registered: Jun 2002 Posts: 1987 |
Quote: @JackAsser: I saw the same thing as you regarding jitter, and dividing by two doesn't help. In my driver I decrease the delta by one (decrement if positive delta, increment for negative), which gets rid of it.
Yes, dividing doesn't help as the jitter is additive. Increasing / Decreasing like you do will remove the possibility for very slow motion though. I did that first but was very unsatisfied by the result. I have a more elaborate filtering in place now. |
| |
chatGPZ
Registered: Dec 2001 Posts: 11100 |
i find this really surprising to hear... never heard about this problem, and i've used/tested a lot of mouse things in the time i worked in micromys, tested on various C64s too. *shrug*. perhaps change the ADC caps? :) |
| |
JackAsser
Registered: Jun 2002 Posts: 1987 |
Quote: i find this really surprising to hear... never heard about this problem, and i've used/tested a lot of mouse things in the time i worked in micromys, tested on various C64s too. *shrug*. perhaps change the ADC caps? :)
Yeah, I'll investigate it further from a HW standpoint. Meanwhile my SW solution will remain in place. |
| |
chatGPZ
Registered: Dec 2001 Posts: 11100 |
it actually makes sense to get a +/- 1 additive jitter due to how the ADC works.(*) and i really wonder now why i never saw this happen :)
(*) actually due to how the ADC _and_ the mouse works... you'd expect it to get even worse. which probably is the reason for why bit 0 is undefined for the mouse data. but... but... *shrug* |
| |
JackAsser
Registered: Jun 2002 Posts: 1987 |
Quote: it actually makes sense to get a +/- 1 additive jitter due to how the ADC works.(*) and i really wonder now why i never saw this happen :)
(*) actually due to how the ADC _and_ the mouse works... you'd expect it to get even worse. which probably is the reason for why bit 0 is undefined for the mouse data. but... but... *shrug*
I only observe a 0/+1 jitter. If I poll POTX and output the value to screen I can see it wiggle between say $12 and $13. If I move the mouse ever so slightly it will wiggle between $13 and $14. Also the jitter is not everywhere but only between frequent spans within the valid values perfectly repetitive. I can f.e. have it rock solid between say (values just made up here because I don't know the exact value) 10-17, the jitterish numbers between 18-1f, then stable again between 20-27 etc. |
| |
JackAsser
Registered: Jun 2002 Posts: 1987 |
@jamie: Did you ever found the cause of the problem?
I’m having the same issue.. |
| |
jamiefuller Account closed
Registered: Mar 2018 Posts: 25 |
Quote: @jamie: Did you ever found the cause of the problem?
I’m having the same issue..
Sorry but I didn't. I believe there is no reliable way. And have never seen anything actually work with both keyboard and neos mouse. I gave up eventually and.restricted the game (portal) to 1351 mouse only which works much happier with the keyboard. |
| |
JackAsser
Registered: Jun 2002 Posts: 1987 |
Quote: Sorry but I didn't. I believe there is no reliable way. And have never seen anything actually work with both keyboard and neos mouse. I gave up eventually and.restricted the game (portal) to 1351 mouse only which works much happier with the keyboard.
Was this behaviour confirmed on real HW? I’m inches away from testing myself. |
| |
JackAsser
Registered: Jun 2002 Posts: 1987 |
Confirmed here @5:45: https://youtu.be/z5znM56lgGw |
| |
JackAsser
Registered: Jun 2002 Posts: 1987 |
I really don't get NEOS. Toggling clk to get higher and lower nibbles, that's fine. But how do you know if you're reading X or Y? |
| |
JackAsser
Registered: Jun 2002 Posts: 1987 |
Quote: I really don't get NEOS. Toggling clk to get higher and lower nibbles, that's fine. But how do you know if you're reading X or Y?
Fyi:
”you know what
you are reading because the state machine in the neos mouse resets when you
dont toggle clk for a couple hundred cycles or so. and yeah, it interfers with
the keyboard. and you can only use the right button as intended. it sux :)
guess thats why it never became popular =)”
I’ll drop support for it. Sorry NEOS-users.
It will support joy-mode though. |
| |
Oswald
Registered: Apr 2002 Posts: 5017 |
well, you could make a cia timer interrupt to poke the mice every couple hundred cycles :P :) but I havent even heard of this mouse so far, so I guess its not so important. |
| |
ChristopherJam
Registered: Aug 2004 Posts: 1370 |
Quoting OswaldI havent even heard of this mouse so far, so I guess its not so important.
It's the only c64 mouse I have :''''(
(but seriously, nice work on the port thus far Jackie - totally understand the need for triage!) |
| |
JackAsser
Registered: Jun 2002 Posts: 1987 |
Quote: well, you could make a cia timer interrupt to poke the mice every couple hundred cycles :P :) but I havent even heard of this mouse so far, so I guess its not so important.
The problem is not reading the mouse. That works very well. The problem is the mouse driving random crap on the bus. When it's deactive, i.e. timeouted in the internal state machine it should release the bus, but it doesn't. Hence it will always intefere with the keyboard no matter what. It's even stated in the user manual that you must LOAD+RUN _before_ plugging_ in the mouse because the keyboard is destroyed.
So no, there are limits to what crap I will support. :D |
| |
Oswald
Registered: Apr 2002 Posts: 5017 |
point taken :) |
| |
ChristopherJam
Registered: Aug 2004 Posts: 1370 |
I started wondering if one could clear the interference by clocking the data some more before the mouse had a chance to move again, but then realised a) the lines are active low, so a delta of zero would actually be bad and b) the keyboard itself is going to produce spurious clocks from row or column 4.
So I dropped that idea before starting to write experimental code. |
| |
soci
Registered: Sep 2003 Posts: 473 |
Connect it to a user port 4 player adapter instead.
That's how I avoid keyboard interference of Amiga mice in Funkpaint. |
| |
JackAsser
Registered: Jun 2002 Posts: 1987 |
Quote: Connect it to a user port 4 player adapter instead.
That's how I avoid keyboard interference of Amiga mice in Funkpaint.
That is a viable solution indeed. I might just add that. Amiga mouse eats too much cpu I think. |
| |
Martin Piper
Registered: Nov 2007 Posts: 631 |
Does GEOS or any other software support the mouse without issue? |
| |
JackAsser
Registered: Jun 2002 Posts: 1987 |
Quote: Does GEOS or any other software support the mouse without issue?
Not as far as I know, also it’s even stated in the manual that the keyboard is in conflict. |
| |
JackAsser
Registered: Jun 2002 Posts: 1987 |
Quote: Connect it to a user port 4 player adapter instead.
That's how I avoid keyboard interference of Amiga mice in Funkpaint.
RMB is out of the question that way right? |
| |
soci
Registered: Sep 2003 Posts: 473 |
Depends. The PTV adapter will likely work without the right button.
With the adapter I use the right button could work on port 3. However it has all signals are routed through a CPLD which makes position transmission is impossible.
So in practice only the left button will be available and that blocks the position transmission while it's pressed.
As long as the interface uses short clicks only this is not a big problem. Dragging might be worked around by long-click lock style drag with click to release. |
| |
JackAsser
Registered: Jun 2002 Posts: 1987 |
Quote: Depends. The PTV adapter will likely work without the right button.
With the adapter I use the right button could work on port 3. However it has all signals are routed through a CPLD which makes position transmission is impossible.
So in practice only the left button will be available and that blocks the position transmission while it's pressed.
As long as the interface uses short clicks only this is not a big problem. Dragging might be worked around by long-click lock style drag with click to release.
That rules it out, no way I’m gonna support that kind of crap. :D |
| |
Martin Piper
Registered: Nov 2007 Posts: 631 |
Quote: Not as far as I know, also it’s even stated in the manual that the keyboard is in conflict.
Glad I never bought one of those then. |