MAME: Mouse, and other pointing devices

want to talk about MESS/model b/beebem/b-em/electrem/elkulator? do it here!
Post Reply
User avatar
Pernod
Posts: 1318
Joined: Fri Jun 08, 2012 10:01 pm
Location: Croydon, UK
Contact:

MAME: Mouse, and other pointing devices

Post by Pernod » Sun Sep 10, 2017 10:56 am

What are the differences between the AMX mouse and that provided with the M512, apart from the obvious 3 vs 2 buttons. I see from various sources that you should be able to use an AMX mouse with the M512 but looking at the code in b-em they are wired differently so this can't possibly be true, can anyone clarify?

Is anyone familiar with the mouse code in b-em? I'm struggling to understand exactly what is required, specifically when to assert/clear the CB lines. I also don't know the significance of the variables mouse_ff, mx, my so can anyone explain?

I do have the AMX mouse moving in MAME but it's sluggish, and the M512 mouse with GEM just wobbles around the middle of screen so I'm clearly not understanding something.
Last edited by Pernod on Tue Aug 21, 2018 4:49 pm, edited 1 time in total.
- Nigel

BBC Model B, ATPL Sidewise, Acorn Speech, 2xWatford Floppy Drives, AMX Mouse, Viglen case, BeebZIF, etc.

User avatar
Pernod
Posts: 1318
Joined: Fri Jun 08, 2012 10:01 pm
Location: Croydon, UK
Contact:

Re: MAME: Mouse

Post by Pernod » Sun Apr 29, 2018 4:10 pm

Pernod wrote:Is anyone familiar with the mouse code in b-em? I'm struggling to understand exactly what is required, specifically when to assert/clear the CB lines. I also don't know the significance of the variables mouse_ff, mx, my so can anyone explain?
How is the distance moved by the mouse determined? Is it the number of interrupts triggered on CB1/CB2, and if so how is the frequency of interrupts determined?

In MAME the mouse input returns dx and dy values every time the mouse is moved, the greater the dx/dy the larger the movement, and can be +ve/-ve depending on direction. These easily allow me to set PB for direction but how often should I pulse the CB lines? I currently just pulse the CB lines on every movement but this doesn't allow for variable speed pointer movement.
- Nigel

BBC Model B, ATPL Sidewise, Acorn Speech, 2xWatford Floppy Drives, AMX Mouse, Viglen case, BeebZIF, etc.

Coeus
Posts: 1083
Joined: Mon Jul 25, 2016 11:05 am
Contact:

Re: MAME: Mouse

Post by Coeus » Sun Apr 29, 2018 5:23 pm

Pernod wrote:In MAME the mouse input returns dx and dy values every time the mouse is moved, the greater the dx/dy the larger the movement, and can be +ve/-ve depending on direction.
That is very similar to the way the Allegro 5 port interfaces to Allegro - Allegro generates a mouse event with delta x (dx) and delta y (dy) so, in mouse.c B-Em then does this:

Code: Select all

void mouse_axes(ALLEGRO_EVENT *event)
{
    mx += event->mouse.dx;
    my += event->mouse.dy;
    log_debug("mouse: axes event, dx=%d, mx=%d, dy=%d, my=%d", event->mouse.dx, mx, event->mouse.dy, my);
}
The variables mx and my are the amount of movement desired. As mouse events arrive from Allegro the movement is added to these variables and as the movement is picked up by the software running on the emulated BBC they move towards zero. Once they reach zero the emulated BBC micro sees the mouse as static.

Looking at the AMX mouse case first there is this function:

Code: Select all

static void mouse_poll_amx(void)
{
    mouse_ff = !mouse_ff;
    if (mouse_ff) {
        uservia_set_cb1(0);
        uservia_set_cb2(0);
        return;
    }

    if (mx) {
        uservia_set_cb1(1);
        if (mx > 0) {
            mouse_portb |=  1;
            mx--;
        } else {
            mouse_portb &= ~1;
            mx++;
        }
    } else
        uservia_set_cb1(0);

    if (my) {
        uservia_set_cb2(1);
        if (my < 0) {
            mouse_portb |=  4;
            my++;
        } else {
            mouse_portb &= ~4;
            my--;
        }
    } else
        uservia_set_cb2(0);
}
This is called from the CPU emulation. It looks like it is actually every 128 instructions but I wonder if it was intended to be every 128 clock cycles. So with mouse_ff I think _ff is mnemonic for flip-flop. On half of all calls it will simply reset the CB1 and CB2 lines to zero and return and, on the other half of calls, it will see if the mouse has moved and, if it has, set up the port accordingly, which in AMX mode seems to be one bit per axis to give which direction the mouse its moving and then CB1 and/or CB2 line to generate the interrupt to say the mouse has moved one mickey. One mickey is then subtracted from mx or my as appropriate.

User avatar
tricky
Posts: 2857
Joined: Tue Jun 21, 2011 8:25 am
Contact:

Re: MAME: Mouse

Post by tricky » Mon Apr 30, 2018 6:54 am

That sounds a little fast, but I can't remember how long the docs say you can spend in an interrupt.
I guess, they would really be spread throughout the frame, but I guess you need to have a maximum interrupts to pick a minimum gap.

User avatar
Pernod
Posts: 1318
Joined: Fri Jun 08, 2012 10:01 pm
Location: Croydon, UK
Contact:

Re: MAME: Mouse

Post by Pernod » Mon Apr 30, 2018 10:58 am

I have both the AMX and M512 mouse working, using almost exact code from B-em. Though I don't use the (uservia.ifr & 0x18) check in mouse_poll_x86, I can't access the internal VIA register from the mouse device, why is it needed?

I read somewhere else that the M512 could use an AMX mouse, sounds unlikely since they are connected differently, anyone clarify?

In B-em why is mouse_poll_x86 so different from mouse_poll_amx, aren't they essentially the same hardware just connected to different PB lines?

And, how is the timing of each mouse_poll (128 cycles) determined, what's the theory behind it?
- Nigel

BBC Model B, ATPL Sidewise, Acorn Speech, 2xWatford Floppy Drives, AMX Mouse, Viglen case, BeebZIF, etc.

User avatar
tricky
Posts: 2857
Joined: Tue Jun 21, 2011 8:25 am
Contact:

Re: MAME: Mouse

Post by tricky » Mon Apr 30, 2018 6:04 pm

I don't know about the others, but 128 probably comes from scan line timing.

User avatar
Pernod
Posts: 1318
Joined: Fri Jun 08, 2012 10:01 pm
Location: Croydon, UK
Contact:

Re: MAME: Mouse

Post by Pernod » Mon Apr 30, 2018 6:43 pm

tricky wrote:I don't know about the others, but 128 probably comes from scan line timing.
I'm referring to the emulation that polls the mouse inputs to generate interrupts whilst the mouse is moving, not the polling of PB from the machine.

For the Compact should the M512 mouse implementation work, with extra button?
- Nigel

BBC Model B, ATPL Sidewise, Acorn Speech, 2xWatford Floppy Drives, AMX Mouse, Viglen case, BeebZIF, etc.

User avatar
tricky
Posts: 2857
Joined: Tue Jun 21, 2011 8:25 am
Contact:

Re: MAME: Mouse

Post by tricky » Mon Apr 30, 2018 7:34 pm

That's what I mean, beeb emulators naturally does some stuff at 128 cycle resolution, so that is a good resolution to check the PC, although it isn't really necessary on windows as you can get a timestamped history and not lose anything. The beeb doesn't/shouldn't poll ;)

Coeus
Posts: 1083
Joined: Mon Jul 25, 2016 11:05 am
Contact:

Re: MAME: Mouse

Post by Coeus » Mon Apr 30, 2018 7:55 pm

tricky wrote:That's what I mean, beeb emulators naturally does some stuff at 128 cycle resolution, so that is a good resolution to check the PC, although it isn't really necessary on windows as you can get a timestamped history and not lose anything. The beeb doesn't/shouldn't poll ;)
For the mouse, I don't think there is any magic about 128 cycles. In B-Em there is a function in 6502.c called other_stuff_poll and it is this that is run every 128 instructions. It runs the poll functions for a bunch of the slower devices.

I didn't write the original mouse code in B-Em, I just ported it from polled Allegro 4 to event-driven Allegro 5 but I did write something similar to "type" a string by simulating keystrokes and in that case I choose the timing of how long each key should spend down and how long between one key up and the next key down by experimentation but only in terms of how many of these poll calls. You'd have to ask Sarah Walker about how she did it. What you're trying to do, though, is after having raised an interrupt, allow enough time for the service routine to process it. If you're putting in a small number of interrupts then the time needed for the ISR to enter something into a buffer maybe sufficient but if you're generating many of them then ideally you also allow time for the onward processing of that so you don't overrun the buffer.

Other than experimentation you could disassemble the code the processes the interrupt and count cycles - that would gives you fastest response. Or, you could try to work out what the fastest rate could be from the mouse hardware but I wonder if that depends on how fast the use moves it across the desk.

Another avenue to explore here would be to try to get hold of the designer of SmallyMouse which is a USB to quadrature converter to enable a modern mouse to be used on the Doomsday Master System. I think it may be Simon Inns (same as BeebSCSI).

Coeus
Posts: 1083
Joined: Mon Jul 25, 2016 11:05 am
Contact:

Re: MAME: Mouse

Post by Coeus » Mon Apr 30, 2018 8:13 pm

Pernod wrote:I have both the AMX and M512 mouse working, using almost exact code from B-em. Though I don't use the (uservia.ifr & 0x18) check in mouse_poll_x86, I can't access the internal VIA register from the mouse device, why is it needed?
I think at some stage in history B-Em had the absolute mouse position rather than the relative distance it needed to move. This meant it had to keep a copy of where the guest thought the mouse was and, whenever they were different, feed in a string of interrupts to make the two coincide. That lead to logic that said "if an interrupt would be ignored, don't assert the IRQ line" because on the next call of this poll routine we would unassert it again and that mickey would be silently discarded. That would cause B-Em's version of where the guest thought the mouse was to be wrong and caused some misbehaviour which I cannot quite remember.
Pernod wrote:In B-em why is mouse_poll_x86 so different from mouse_poll_amx, aren't they essentially the same hardware just connected to different PB lines?
I don't know if the hardware is the same or different but trying the amx version of the function with the bit masks set to the PB lines on which the M512 mouse is connected doesn't work with GEM on M512. It may be that the hardware is different or it maybe that the emulation of the hardware is not perfect and the emulation has been tweaked in each case to work with the expected guest software - i.e. GEM on M512 and AMX Paint for the AMX mouse. What I have not tried is using the x86 version of the function with the AMX PB assignment to see if that one would work for both.

And, how is the timing of each mouse_poll (128 cycles) determined, what's the theory behind it?[/quote]

User avatar
Pernod
Posts: 1318
Joined: Fri Jun 08, 2012 10:01 pm
Location: Croydon, UK
Contact:

Re: MAME: Mouse

Post by Pernod » Tue May 01, 2018 2:22 pm

Coeus wrote:Other than experimentation you could disassemble the code the processes the interrupt and count cycles - that would gives you fastest response. Or, you could try to work out what the fastest rate could be from the mouse hardware but I wonder if that depends on how fast the use moves it across the desk.
Yeah, the rate is dependent on how fast the mouse is moved, I need a theoretical maximum. In Super Art you could move the mouse very fast and only see some intermediate points being detected.
Coeus wrote:I don't know if the hardware is the same or different but trying the amx version of the function with the bit masks set to the PB lines on which the M512 mouse is connected doesn't work with GEM on M512. It may be that the hardware is different or it maybe that the emulation of the hardware is not perfect and the emulation has been tweaked in each case to work with the expected guest software - i.e. GEM on M512 and AMX Paint for the AMX mouse. What I have not tried is using the x86 version of the function with the AMX PB assignment to see if that one would work for both.
I've tried the x86 version with the AMX PB assignments and works well, I won't be using the amx version which is inferior.

I've also used the x86 version to implement the Compact mouse and works for that too, though the documented PB assignments seem to be wrong. According to the NAUG on page 371 the Compact PB assignments are;
PB4 Joystick RIGHT / mouse Y-axis
PB3 Joystick UP / mouse X-axis
PB2 Joystick DOWN / mouse right button
PB1 Joystick LEFT / mouse middle button
PB0 Joystick FIRE / mouse left button

To get the mouse to work with the Compact/Prodest 128S Welcome disks the PB assignments I used are:
PB4 mouse right button
PB3 mouse middle button
PB2 mouse Y-axis
PB1 mouse left button
PB0 mouse X-axis
Can anyone comment on this? Am not sure of right/middle buttons as no software to clarify.

Looking at other mouse implementations in MAME I'm surprised none of the others seem to be as complicated as this, not even Archimedes and Amiga which also use quadrature mice. The Atari ST may do something similar as it's polling the mouse inputs at 500Hz. I think I need to find my AMX mouse and do some real-time comparison, and look into how SmallyMouse works.
- Nigel

BBC Model B, ATPL Sidewise, Acorn Speech, 2xWatford Floppy Drives, AMX Mouse, Viglen case, BeebZIF, etc.

User avatar
Pernod
Posts: 1318
Joined: Fri Jun 08, 2012 10:01 pm
Location: Croydon, UK
Contact:

Re: MAME: Mouse

Post by Pernod » Tue May 01, 2018 9:02 pm

Since the AMX mouse is supposed to work with GEM on the M512, and it currently doesn't, I'm going to look more at how SmallyMouse2 is implemented. I shouldn't need a different implementation depending on which software is trying to read the mouse.

I also added the Marconi RB2 with inconsistent results. The MEDL Trackerball Utilities mostly worked but Paintball thought I had Select permanently pressed so was always in Draw mode, even though the buttons worked correctly with the other utilities on the disc. Also tested with Icon Art Master (Micro-Draw) but the pointer wouldn't move, so failed.

If I get the complete quadrature process implemented from SmallyMouse2 then I'd hope the above issues will be resolved, with a single implementation.
- Nigel

BBC Model B, ATPL Sidewise, Acorn Speech, 2xWatford Floppy Drives, AMX Mouse, Viglen case, BeebZIF, etc.

Coeus
Posts: 1083
Joined: Mon Jul 25, 2016 11:05 am
Contact:

Re: MAME: Mouse

Post by Coeus » Wed May 02, 2018 7:01 pm

You've got my intrigued now. I found an easy to understand description of how quadrature rotation sensors work on Wikipedia - https://en.wikipedia.org/wiki/Rotary_encoder, then "Incremental rotary encoder" so I will have another look at the B-Em code in that light.

User avatar
hoglet
Posts: 7634
Joined: Sat Oct 13, 2012 6:21 pm
Location: Bristol
Contact:

Re: MAME: Mouse

Post by hoglet » Wed May 02, 2018 7:15 pm

I had problems a couple of years ago getting a quadrature trackball work with an M512/GEM.

See this post for a few more details:
http://www.stardot.org.uk/forums/viewto ... 66#p104466

May or may not be relevant to your current issue.

Dave

Coeus
Posts: 1083
Joined: Mon Jul 25, 2016 11:05 am
Contact:

Re: MAME: Mouse

Post by Coeus » Wed May 02, 2018 7:44 pm

hoglet wrote:I had problems a couple of years ago getting a quadrature trackball work with an M512/GEM....
Thanks Dave.

Working through the explanation in Wikipedia, there's a table of expected values. It only gives one cycle and one direction but for the clockwork direction two cycles would be:

Code: Select all

A  B
0  0
0  1
1  1
1  0
0  0
0  1
1  1
1  0
so on the assumption A is connected to CB1, i.e. the one that generates the interrupt, and B is connected to PB3, i.e. the standard data line that does not then if software only ever examines PB3 when it gets an interrupt it will always see it as high for the clockwise direction. So what about anti-clockwise. The table for that should be:

Code: Select all

A  B
0  0
1  0
1  1
0  1
0  0
1  0
1  1
0  1
so this time whenever the software responds to the interrupt it will see PB3 as low. That means even though the mouse is generating proper quadrature, because it is only being sampled once per cycle it does look like the CB1 line is the "a movement has happened" line and the PB3 line is "which direction". Interestingly, though, if the lines were simply exchanged so A was connected to PB3 and B to CB1 it would work just as well but the direction detected would simply be the opposite. So, I think this is what the mouse_amx function in B-Em was doing - taking advantage of simple sampling.

That suggests that the mouse driver in GEM is doing something else. Maybe it is polling? Or running a timer after the interrupt and sampling the PB3 line a second time in response to the same interrupt hoping to see a high to low transition (clockwise) or low to high transition (anti-clockwise). Or even a hybrid where it responds to the interrupt and then polls to wait for the transition.

All this suggests that the correct software implementation will only change one thing on each call, i.e. either state of the CB1 interrupt line or the state of the PB3 line. I will try that and see what happens.

User avatar
hoglet
Posts: 7634
Joined: Sat Oct 13, 2012 6:21 pm
Location: Bristol
Contact:

Re: MAME: Mouse

Post by hoglet » Wed May 02, 2018 7:48 pm

According to Jonathan's side, the direction signals of an AMX mouse feed in to D0 and D2.
http://mdfs.net/Info/Comp/BBC/Mouse/

Dave

User avatar
hoglet
Posts: 7634
Joined: Sat Oct 13, 2012 6:21 pm
Location: Bristol
Contact:

Re: MAME: Mouse

Post by hoglet » Wed May 02, 2018 8:03 pm

The source code for the 6502.SYS driver is here:
http://www.cowsarenotpurple.co.uk/bbcco ... l#6502list

It looks like it actively tries to detect a track ball vs a mouse, and this seems to change how it interprets the signals:

Code: Select all

2B8F LDA userport               ; Load VIA input reg B - tracker ball?
2B92 STA &2C2B                  ; store it at orb_copy
2B95 AND #&18                   ; Mask it - these bits always hi for AMX
2B97 CMP #&18                   ; Both set? - if either low must be trackball
2B99 BEQ &2BAA                  ; Yes! - AMX no new_irq_code2
2B9B LDA #0                     ; Mark as tracker ball by storing 0
2B9D STA &2C27                  ; in AMX to override default
2BA0 LDA #8                     ; y quad signal is different to default
2BA2 STA &2C28                  ; store it in RAM - in mouse_x_quad
2BA5 LDA #&10                   ; and x quad signal is different too
2BA7 STA &2C29                  ; store it in RAM in mouse_x_quad
.new_irq_code2
2BAA LDA &2C2A                  ; masked int flag reg copy - ifr_copy

What is present on D3 and D4?

This bit is also interesting:

Code: Select all

2C14 LDA &FE6C                  ; Read real peripheral control register
2C17 AND #&0F                   ; preserve the bottom nibble but set
2C19 ORA &2C2E                  ; the remainder to our copy in pcr_copy
2C1C STA &FE6C                  ; Re-write peripheral control register
2C1F LDA #&18                   ; Load CB1 and CB2 active edge bits
2C21 STA &FE6D                  ; write IFR to clear our interrupt
2C24 LDA &FC                    ; Recover A to interrupt entry state
2C26 RTI                        ; Return from interrupt
So I think the interrupting edge of CB1/CB2 is repeatedly toggled.

Dave

Coeus
Posts: 1083
Joined: Mon Jul 25, 2016 11:05 am
Contact:

Re: MAME: Mouse

Post by Coeus » Wed May 02, 2018 8:23 pm

hoglet wrote:According to Jonathan's side, the direction signals of an AMX mouse feed in to D0 and D2.
http://mdfs.net/Info/Comp/BBC/Mouse/
That's consistent with what B-Em is doing. I was using the M512 mouse as the example. Even if we get the same emulation code to work with both they still appear to be connected to different pins.

User avatar
hoglet
Posts: 7634
Joined: Sat Oct 13, 2012 6:21 pm
Location: Bristol
Contact:

Re: MAME: Mouse

Post by hoglet » Wed May 02, 2018 8:44 pm

Coeus wrote:
hoglet wrote:According to Jonathan's side, the direction signals of an AMX mouse feed in to D0 and D2.
http://mdfs.net/Info/Comp/BBC/Mouse/
That's consistent with what B-Em is doing. I was using the M512 mouse as the example. Even if we get the same emulation code to work with both they still appear to be connected to different pins.
The 6502.SYS code distinguishes between a mouse and a trackball by looking at D3 and D4 - if both are high (i.e. unconnected) it's a mouse otherwise it's a trackball:
- If it's a mouse then expect the Y/X direction inputs on D0 and D2
- If it's a trackball then expect the Y/X direction inputs on D3 and D4

In either case, both edges of CB1 and CB2 end up generating interrupts and the direction input must also be toggling (as your quadrature state lists above are showing).

So if the wrong type of device is detected the direction input will appear static, which will cause the mouse not to move. Or more precisely, it will jitter by just one pixel in the direction being moved.

Looking at mouse_poll_amx(), it doesn't appear that the direction inputs are toggling, which is why this probably isn't going to work with the 6502.SYS driver. If it works with the AMX mouse ROM, then that's possibly because that is only interrupting on one edge of CB1/CB2. This is all guesswork!

Dave
Last edited by hoglet on Wed May 02, 2018 9:00 pm, edited 1 time in total.

User avatar
Pernod
Posts: 1318
Joined: Fri Jun 08, 2012 10:01 pm
Location: Croydon, UK
Contact:

Re: MAME: Mouse

Post by Pernod » Wed May 02, 2018 8:57 pm

I implemented the SmallyMouse2 method and it fixed my issues with the RB2 Tracker Ball software (Icon Art Master and MEDL Trackerball Utilities), both now work as expected.
hoglet wrote:It looks like it actively tries to detect a track ball vs a mouse, and this seems to change how it interprets the signals:

Code: Select all

2B8F LDA userport               ; Load VIA input reg B - tracker ball?
2B92 STA &2C2B                  ; store it at orb_copy
2B95 AND #&18                   ; Mask it - these bits always hi for AMX
2B97 CMP #&18                   ; Both set? - if either low must be trackball
2B99 BEQ &2BAA                  ; Yes! - AMX no new_irq_code2
2B9B LDA #0                     ; Mark as tracker ball by storing 0
2B9D STA &2C27                  ; in AMX to override default

What is present on D3 and D4?
For the AMX mouse I was only holding D1 and D4 high (0x12), missing D3. I now hold with 0x1a and GEM now works with the AMX PB assignments. Result!

I still need to tidy up my SmallyMouse code, and improve how it handles data from MAME's mouse inputs, but I now have 3 working pointer devices on the Userport (using a single quadrature method): AMX mouse, M512 mouse, and Marconi RB2, all working :)
- Nigel

BBC Model B, ATPL Sidewise, Acorn Speech, 2xWatford Floppy Drives, AMX Mouse, Viglen case, BeebZIF, etc.

Coeus
Posts: 1083
Joined: Mon Jul 25, 2016 11:05 am
Contact:

Re: MAME: Mouse

Post by Coeus » Wed May 02, 2018 11:15 pm

hoglet wrote:Looking at mouse_poll_amx(), it doesn't appear that the direction inputs are toggling, which is why this probably isn't going to work with the 6502.SYS driver. If it works with the AMX mouse ROM, then that's possibly because that is only interrupting on one edge of CB1/CB2. This is all guesswork!
That seems reasonable. I can use mouse_poll_x86 (having parametrised the masks for the X and Y dir lines) for the AMX mouse and it works but the mouse moves slower for AMX ART than in GEM which is what you'd expect if it is responding to half the number of interrupts.

User avatar
Pernod
Posts: 1318
Joined: Fri Jun 08, 2012 10:01 pm
Location: Croydon, UK
Contact:

Re: MAME: Mouse, and other pointing devices

Post by Pernod » Tue Aug 21, 2018 5:02 pm

I now support the Acorn Bitstik, and the original Graphics System works well.
0063.png
Does anyone have the software for the Bitstik 2? We seem to only have the Library discs, and the original System disc doesn't work with the Bitstik 2 ROM.
- Nigel

BBC Model B, ATPL Sidewise, Acorn Speech, 2xWatford Floppy Drives, AMX Mouse, Viglen case, BeebZIF, etc.

Post Reply