[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
New csa2 FAQs: F002KBPADJS (Part 2 of 2)
From: David Empson
015- How do I write programs which use the mouse?
The assembly language interface to the mouse firmware is documented in
three places:
- the reference material that was supplied with the AppleMouse card for
the IIe.
- the IIc Technical Reference Manual.
- the IIgs Firmware Reference Manual.
Interfacing to the mouse is somewhat complicated, especially if you want
to implement some kind of mouse cursor (usually requires writing an
interrupt handler).
The first problem is locating the mouse firmware. It could be in any
slot for a IIe or IIgs, or either of two slots for the IIc. The safest
method is just to do a slot search, looking for the mouse ID bytes:
$Cn05 = $38
$Cn07 = $18
$Cn0B = $01
$Cn0C = $20
$CnFB = $D6
On a ROM 3 IIgs, it is possible that the mouse firmware will not be
available, because this doesn't prevent the use of the mouse from GS/OS
(the Miscellaneous Toolset or Event Manager can still be used). An
AppleMouse card, if installed, is not used by the toolbox.
On a ROM 1 IIgs, the slot mouse firmware is used by the toolbox, so slot
4 must be set to "Mouse Port", or an AppleMouse card may be installed in
any slot.
Using the mouse firmware consists of calling the various parameters
provided by the firmware. An entry point table is provided in the mouse
slot. The routines common to all implementations are:
$Cn12 SETMOUSE Sets mouse mode
$Cn13 SERVEMOUSE Services mouse interrupt
$Cn14 READMOUSE Reads mouse position
$Cn15 CLEARMOUSE Clears mouse position to 0 (for delta mode)
$Cn16 POSMOUSE Sets mouse position to a user-defined pos
$Cn17 CLAMPMOUSE Sets mouse bounds in a window
$Cn18 HOMEMOUSE Sets mouse to upper-left corner of clamp win
$Cn19 INITMOUSE Resets mouse clamps to default values;
ets mouse position to 0,0
Each of the above locations contains the low byte of the entry point for
the routine. The high byte is $Cn. The usual method for calling these
routines is to set up a single subroutine which is patched with the
location of the appropriate routine as required. You could also set up
a series of subroutines for calling each routine.
The general logic would be as follows:
Locate the mouse slot by searching for the ID bytes described earlier.
Patch the slot into the following routine:
TOMOUSE LDX #$C1 ; Patch operand byte with slot in $Cn form
LDY #$10 ; Patch operand byte with slot in $n0 form
JMP $C100 ; Patch high byte of operand with slot in
; $Cn form. Low byte of operand must be
; patched with entry point from table above
You should also set up a pair of locations on zero page containing
$Cn00, which will be used to look up the table. You can then have code
as follows to call each of the routines:
MOUSEPTR EQU $00 ; (or some other pair of zero page locations)
SETMOUSE
LDY #$12 ; Offset to entry point
BNE GOMOUSE ; Go to the mouse routine - always taken
SERVEMOUSE
LDY #$13 ; Offset to entry point
BNE GOMOUSE ; Go to the mouse routine - always taken
[etc. - one routine for each mouse call you will be using]
GOMOUSE TAX ; Preserve the value in A
LDA (MOUSEPTR),Y ; Get the routine entry point
STA TOMOUSE+5 ; Patch the JMP instruction
TXA ; Restore the value in A
; The following operand bytes must be patched by the
; initialization code which detects the mouse.
TOMOUSE LDX #$C1 ; Set up slot in $Cn form in X
LDY #$10 ; Set up slot in $n0 form in Y
JMP $C100 ; Go to the mouse routine
With code like the above, your program can just use JSR INITMOUSE, etc.
to call the appropriate routine.
The mouse routines make use of screen holes for the slot containing the
mouse interface firmware/card. The screen holes are as follows:
$0478 + slot Low byte of absolute X position
$04F8 + slot Low byte of absolute Y position
$0578 + slot High byte of absolute X position
$05F8 + slot High byte of absolute Y position
$0678 + slot Reserved and used by the firmware
$06F8 + slot Reserved and used by the firmware
$0778 + slot Button 0/1 interrupt status byte
$07F8 + slot Mode byte
You can access the screen holes by getting the mouse slot number in the
$Cn form (LDX TOMOUSE+1), then indexing off the above locations minus
$C0 with X (or just AND the value with $0F and use the base addresses
directly).
The screen holes should be used only as specified by the mouse routines
below. You should never write to them, except as specified by POSMOUSE.
The interrupt status byte is defined as follows:
Bit 7 6 5 4 3 2 1 0
| | | | | | | |
| | | | | | | \--- Previously, button 1 was up (0) or down (1)
| | | | | | \----- Movement interrupt
| | | | | \------- Button 0/1 interrupt
| | | | \--------- VBL interrupt
| | | \----------- Currently, button 1 is up (0) or down (1)
| | \------------- X/Y moved since last READMOUSE
| \--------------- Previously, button 0 was up (0) or down (1)
\----------------- Currently, button 0 is up (0) or down (1)
(Button 1 is not physically present on the mouse, and is probably
only supported for an ADB mouse on the IIgs.)
The mode byte is defined as follows.
Bit 7 6 5 4 3 2 1 0
| | | | | | | |
| | | | | | | \--- Mouse off (0) or on (1)
| | | | | | \----- Interrupt if mouse is moved
| | | | | \------- Interrupt if button is pressed
| | | | \--------- Interrupt on VBL
| | | \----------- Reserved
| | \------------- Reserved
| \--------------- Reserved
\----------------- Reserved
The button and movement status are only valid after calling READMOUSE.
Interrupt status bits are only valid after SERVEMOUSE and are cleared by
READMOUSE. The appropriate screen hole information must be copied
elsewhere before enabling interrupts with CLI or PLP.
The routines are used as follows. X and Y must be set up with $Cn and
$n0 in all cases. Interrupts must be disabled before calling any of
these routines. Assume all registers are scrambled on exit unless
otherwise noted.
SETMOUSE
Sets mouse operation mode.
Entry: A = mouse operation mode ($00 to $0F) - see mode byte.
Exit: C = 1 if illegal mode entered.
Screen hole mode byte is updated.
SERVEMOUSE
Tests for interrupt from mouse and resets mouse's
interrupt line.
Exit: C = 0 if mouse interrupt occurred.
Screen hole interrupt status bits are updated to show
current status.
READMOUSE
Reads delta (X/Y) positions, updates absolute X/Y pos,
and reads button statuses from the mouse.
Exit: C = 0 (always).
Screen hole positions and button/movement status bits are
updated, interrupt status bits are cleared.
CLEARMOUSE
Resets buttons, movement and interrupt status 0.
(This routine is intended to be used for delta mouse
positioning instead of absolute positioning.)
Exit: C = 0 (always).
Screen hole positions and button/movement status bits are
updated, interrupt status bits are cleared.
POSMOUSE
Allows caller to change current mouse position.
Entry: Caller places new absolute X/Y positions directly in
appropriate screen holes.
Exit: C = 0 (always).
Screen hole positions may be updated if necessary (e.g.
clamping).
CLAMPMOUSE
Sets up clamping window for mouse user. Power up default
values are 0 to 1023 ($0000 to $03FF).
Entry: A = 0 if entering X clamps, 1 if entering Y clamps.
Clamps are entered in slot 0 screen holes as follows.
NOTE: these are NOT indexed by the mouse slot number.
$0478 = low byte of low clamp.
$04F8 = low byte of high clamp.
$0578 = high byte of low clamp.
$05F8 = high byte of high clamp.
Exit: C = 0 (always).
Screen hole position is set to top left corner of clamping
window for the IIgs.
Note: The IIgs automatically homes the mouse when this call is
made, but this doesn't happen for the IIc and AppleMouse
card.
HOMEMOUSE
Sets the absolute position to upper-left corner of
clamping window.
Exit: C = 0 (always).
Screen hole positions are updated.
INITMOUSE
Sets screen holes to default values and sets clamping win
to default value of 0 to 1023 in both X and Y directions,
resets hardware.
Exit: C = 0 (always).
Screen holes are updated.
The general method of using the mouse firmware is as follows:
- Call SETMOUSE specifying a mode of 1 (enabled, no interrupts).
- Call INITMOUSE.
- Call CLAMPMOUSE to set up the required clamps (once per ea axis).
- If necessary, call SETMOUSE again with the actual mode you want.
You must set up a ProDOS interrupt handler if you want to use the
interrupt modes.
If you are using polled mode, call READMOUSE as required to update the
mouse position and button status information.
If you are using interrupt mode, your interrupt handler should call
SERVEMOUSE to check for a mouse interrupt. If none occurred, return to
ProDOS with C=1. If one did occur, note the type of interrupt (if
necessary), then call READMOUSE to the new position information, and
copy the data elsewhere. Finally, return to ProDOS with C=0.
When your program is finished, it should disable the mouse by using
SETMOUSE with A=0, and remove the interrupt handler (if necessary).
____________________________
From: Rubywand
016- At my school we have a IIe that has some problem with its
keyboard. When you push a key it keeps on repeating until
you push another, which also repeats. Is there a cheap easy
way to fix this?
There _may_ be a fairly easy fix. If the KB Encoder IC or the IOU
IC is loose or has pins making poor contact, you could get the symptoms
described.
Open the case and locate the KB Encoder (a big, 40-pin IC on the
right side of the motherboard just to the right of three ROMs). Use a
small, thin-blade screwdriver to scootch up the IC. (You want to get
some lifting for all pins, even if you end up just removing the IC.)
Press the IC back into the socket.
Do the same with the IOU (a big, 40-pin IC just to the left of the
three ROMs).
The idea of lifting up and re-socketing each IC is to let the
socket contacts scrape a fresh connection with each pin on the IC.
--------------------
From: Bruce R. Baker
My experience is that this is more simple than it looks. You have
one stuck key. It is stuck down. Have you opened the machine and moved
the keyboard? If so you may have replaced it wrong, it is rubbing on one
of the edges. The key that is stuck is next to the edge.
If this does not apply to you, often pressing all of the keys until
it stops (because by pressing on the right key, it comes unstuck) will
work.
--------------------
From: Dave Althoff
My first suspicion is a stuck key, and if this is a beige ][e, the
first place I'd look is the [`/~] key, adjacent to the power light.
____________________________
From: tgeer@pro-gumbo.cts.com (System Administrator)
017- A while ago someone posted about how to read the joystick on
a GS in native mode. They said that it was possible to read
both paddles at once and therefore get much more accurate
readings?
Only the high bit of these locations is valid. When the high bit of
either location becomes 0 then the corresponding analog input has timed
out.
You will actually get more accurate results by reading them one after
the other with the accumulator set to 8 bits wide and the index
registers used to hold the counts (16 bits wide). This allows for a
much faster loop, giving better resolution. Assuming that this routine
is called from full native mode, the following code will do the trick:
strobe equ $C070 ; analog input timing reset
pdl0 equ $C064 ; analog input 0
pdl1 equ $C065 ; analog input 1
start php ; save processor status register
phb ; and data bank register
sep #%100000 ; make accumulator 8 bits wide
lda #0 ; make data bank = 0
pha
plb
ldx #0 ; initialize the counters
txy
lda strobe ; strobe the timing reset
loop1 inx ; increment pdl0 count
lda pdl0 ; is high bit = 0?
bmi loop1 ; no, keep checking
lda strobe ; yes, strobe the timing reset again
loop2 iny ; increment pdl1 counter
lda pdl1 ; is high bit = 0?
bmi loop2 ; no, keep checking
plb ; yes, restore data bank
plp ; and processor status register
rts ; return to caller (could be RTL)
Notice that the actual counting loops are only 9 cycles long. This
gives the best possible resolution. You will need your counters to be
16 bits wide as the results will easily overflow the capacity of an 8
bit counter.
Using memory locations as counters will only serve to slow the counting
loop down. If X and Y contain valid data before entry, you will need to
save them off to the stack and pull them back in after interpreting the
joystick results. I have used this exact method to read the analog
inputs on my Science Toolkit box which connects to the joystick port.
The results have been extremely accurate (much more than would be needed
for a game which reads the joystick).
____________________________
From: Dan DeMaggio
018- Is a Y-adapter available for my GS keyboard?
Yes. Redmond Cable has an ADB Y-connector cable for separating your
mouse from the side of your keyboard.
____________________________
From: Mark Wade
019- How do you use the Kensington TurboMouse with a IIgs?
The Version 3.0 Kensington TurboMouse ADB works fine on a later model
(post-Woz) IIgs. The Version 4.x TM will not work on a IIgs.
Dip switches:
Right handed use: (L but click, R but click lock) SW1 Up
Left handed use: (R but click, L but click lock) SW1 Down
The other switches are for what they call "chording" and
are listed as:
SW2 SW3 SW6
Command N Dn Dn Up
Command O Dn Up Dn
Command W Dn Up Up
Command S Up Dn Dn
Command P Up Dn Up
Command Q Up Up Dn
Command Z Up Up Up