406 lines
8.8 KiB
Plaintext
406 lines
8.8 KiB
Plaintext
' ########### start ###########
|
|
' avr:mega48
|
|
' ########### end ###########
|
|
'
|
|
' ******************************************************************
|
|
' Mouse for ATARI and AMIGA
|
|
' 2018-03-09 (c) Paolo Iocco
|
|
' ******************************************************************
|
|
'
|
|
' Circuit diagram
|
|
' ---------------
|
|
' ATtiny 48 / 88 / Mega 168 / Mega 328 Pin map
|
|
' +-\/-+
|
|
' +5V---| 100K |--->1|o |28<-PC5-ADC5-----X_Pot
|
|
' RxD>---------PD0--2| |27<-PC4-ADC4-----Y_Pot
|
|
' TxD<---------PD1--3| |26 PC3 ADC3
|
|
' LED<---------PD2--4| |25 PC2 ADC2
|
|
' PS2-CLK------PD3--5| |24<-PC1-ADC1-----L_Fire
|
|
' PS2-DAT------PD4--6| |23<-PC0-ADC0-----R_Fire
|
|
' VCC 7| |22 GND
|
|
' GND 8| |21 AREF
|
|
' --9| |20 VCC
|
|
' -10| |19 PB5 SCK
|
|
' YB<----------PD5-11| |18 PB4 MISO
|
|
' YA<----------PD6-12| |17 PB3 MOSI
|
|
' XA<----------PD7-13| |16--PB2---------->RB
|
|
' XB<----------PB0-14| |15--PB1---------->LB
|
|
' +----+
|
|
' -------------------------------------------------------------
|
|
' 8MHz internal: (http://www.engbedded.com/fusecalc/)
|
|
' LFuse: 0xe2; HFuse: 0xdf;
|
|
' avrdude -B 10 -c USBasp -p ATmega48 -U lfuse:w:0xe2:m -U hfuse:w:0xdf:m
|
|
'
|
|
' ******************************************************************
|
|
|
|
'----------------------------------------------------------------------
|
|
'
|
|
' DB9 STANDARDS
|
|
' ~~~~~~~~~~~~~
|
|
'
|
|
' Atari ST AMIGA
|
|
'
|
|
' +---------> YB +---------> XB
|
|
' | +-------> YA | +-------> YA
|
|
' | | +-----> XA | | +-----> XA
|
|
' | | | +---> XB | | | +---> YB
|
|
' | | | | | | | |
|
|
' _____________ _____________
|
|
' 5 \ x o o o o / 1 5 \ x o o o o / 1
|
|
' \ o o o o / \ o o o o /
|
|
' 9 `~~~~~~~' 6 9 `~~~~~~~' 6
|
|
' | | | | | | | |
|
|
' | | | +----> Left Button | | | +----> Left Button
|
|
' | | +------> Power | | +------> Power
|
|
' | +--------> Ground | +--------> Ground
|
|
' +----------> Right Button +----------> Right Button
|
|
|
|
#chip mega48,8
|
|
|
|
#define PS2Clock PORTD.3
|
|
#define PS2Data PORTD.4
|
|
#define led PORTD.2
|
|
#define XB PORTB.0
|
|
#define XA PORTD.7
|
|
#define YA PORTD.6
|
|
#define YB PORTD.5
|
|
#define LB PORTB.1
|
|
#define RB PORTB.2
|
|
#define R_Fire PORTC.0
|
|
#define L_Fire PORTC.1
|
|
#define X_Pot PORTC.5
|
|
#define Y_Pot PORTC.4
|
|
#define bias_f 60 ' bias for analog read - fast
|
|
#define bias_s 15 ' bias for analog read - slow
|
|
#define pulse 500 us
|
|
|
|
#define USART_BAUD_RATE 9600
|
|
#define USART_BLOCKING
|
|
#define PS2_DELAY 10 ms
|
|
|
|
dir led out ' ON: mouse; OFF: joystick
|
|
dir RB out
|
|
dir LB out
|
|
dir XA out
|
|
dir YA out
|
|
dir XB out
|
|
dir XB out
|
|
dir R_Fire in
|
|
dir L_Fire in
|
|
dir X_Pot in
|
|
dir Y_Pot in
|
|
DIR PS2Clock IN
|
|
DIR PS2Data IN
|
|
|
|
dim slow as byte
|
|
|
|
'Startup routine
|
|
Startup:
|
|
set led on ' debug without mouse
|
|
wait 1 s
|
|
set led off
|
|
wait 200 ms
|
|
HSerPrint "Restarted"
|
|
HSerPrintCRLF
|
|
HSerPrintCRLF
|
|
'goto Joystick
|
|
|
|
MouseHandler:
|
|
HSerPrint "Mouse"
|
|
HSerPrintCRLF
|
|
' *********************************************************************
|
|
' * Mouse section
|
|
' *********************************************************************
|
|
set led on ' try with mouse
|
|
'Try and Init Mouse
|
|
'mouse = PS2ReadByte ' Self-test passed
|
|
'if mouse <> 0xaa then goto Joystick
|
|
'mouse = PS2ReadByte ' Mouse ID
|
|
'if mouse <> 0x00 then goto Joystick
|
|
|
|
PS2WriteByte 0xff ' Reset command
|
|
mouse = PS2ReadByte ' Acknowledge
|
|
'if mouse <> 0xfa then goto Joystick
|
|
mouse = PS2ReadByte ' Self-test passed
|
|
'if mouse <> 0xaa then goto Joystick
|
|
mouse = PS2ReadByte ' Mouse ID
|
|
'if mouse <> 0x00 then goto Joystick
|
|
|
|
'PS2WriteByte 0xff ' Reset command
|
|
'mouse = PS2ReadByte ' Acknowledge
|
|
'if mouse <> 0xfa then goto Joystick
|
|
'mouse = PS2ReadByte ' Self-test passed
|
|
'if mouse <> 0xaa then goto Joystick
|
|
'mouse = PS2ReadByte ' Mouse ID
|
|
'if mouse <> 0x00 then goto Joystick
|
|
|
|
PS2WriteByte 0xfa ' Enter Stream Mode
|
|
mouse = PS2ReadByte ' Acknowledge
|
|
'if mouse <> 0xfa then goto Joystick
|
|
|
|
'Main Mouse routine
|
|
Loop:
|
|
do
|
|
|
|
' ------------------------
|
|
' D7 D6 D5 D4 D3 D2 D1 D0 (The D0 bit (LSB) is sent first)
|
|
' ------------------------
|
|
'(1) YV XV YS XS 1 0 R L (overflow, sign, buttons)
|
|
'(2) X7 X6 X5 X4 X3 X2 X1 X0 (X movement; -128 to +127)
|
|
'(3) Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 (Y movement; -128 to +127)
|
|
|
|
'L = Left Button State (1 = pressed down)
|
|
'R = Right Button State (1 = pressed down)
|
|
'XS = Direction of X movement (1 = LEFT)
|
|
'YS = Direction of Y movement (1 = UP)
|
|
'XV = Overflow of X movement value (1 = X overflow occured)
|
|
'YV = Overflow of Y movement value (1 = Y overflow occured)
|
|
'X7,...,X0 : X movement; 8-bit 2's-complement signed byte (-128 to +127)
|
|
'Y7,...,Y0 : Y movement; 8-bit 2's-complement signed byte (-128 to +127)
|
|
|
|
'Here are examples of data sent to the host (PC):
|
|
'------------------------------------------------
|
|
'(The least-significant bit of each data byte is sent first.)
|
|
'Move Left 1 unit : 0x18, 0xFF, 0x00
|
|
'Move Right 1 unit : 0x08, 0x01, 0x00
|
|
'Move Down 1 unit : 0x28, 0x00, 0xFF
|
|
'Move Up 1 unit : 0x08, 0x00, 0x01
|
|
'Press Left Button : 0x09, 0x00, 0x00
|
|
'Release Left Button : 0x08, 0x00, 0x00
|
|
'Press Right Button : 0x0C, 0x00, 0x00
|
|
'Release Right Button : 0x08, 0x00, 0x00
|
|
|
|
'13. Interpret the direction bits (explained in the Mouse Interface section)
|
|
'14. Interpret the X and Y motion bytes
|
|
'15. Update cumulative X,Y motion and display on LCD
|
|
'16. Repeat steps 1-15 indefinitely
|
|
|
|
mouse = PS2ReadByte
|
|
mouse_x = PS2ReadByte
|
|
mouse_y = PS2ReadByte
|
|
|
|
HSerPrint "CTL: "
|
|
HSerPrint mouse
|
|
HSerPrint "; X: "
|
|
HSerPrint mouse_x
|
|
HSerPrint "; Y: "
|
|
HSerPrint mouse_y
|
|
HSerPrintCRLF
|
|
|
|
if mouse.0 then
|
|
gosub LeftButtonON
|
|
else
|
|
gosub LeftButtonOFF
|
|
end if
|
|
|
|
if mouse.1 then
|
|
gosub RightButtonON
|
|
else
|
|
gosub RightButtonOFF
|
|
end if
|
|
|
|
if mouse.2 then
|
|
gosub MidButtonON
|
|
else
|
|
gosub MidButtonOFF
|
|
end if
|
|
|
|
if mouse_x <> 0 then gosub MMove_x
|
|
if mouse_y <> 0 then gosub MMove_y
|
|
|
|
loop
|
|
|
|
LeftButtonON:
|
|
set LB off
|
|
return
|
|
LeftButtonOFF:
|
|
set LB on
|
|
return
|
|
|
|
RightButtonON:
|
|
set RB off
|
|
return
|
|
RightButtonOFF:
|
|
set RB on
|
|
return
|
|
|
|
MidButtonON:
|
|
'set MB off
|
|
return
|
|
MidButtonOFF:
|
|
'set MB on
|
|
return
|
|
|
|
MMove_x:
|
|
if mouse.4 then
|
|
set XA on
|
|
wait 1 ms
|
|
set XB on
|
|
wait 1 ms
|
|
set XA off
|
|
wait 1 ms
|
|
set XB off
|
|
wait 1 ms
|
|
else
|
|
set XB on
|
|
wait 1 ms
|
|
set XA on
|
|
wait 1 ms
|
|
set XB off
|
|
wait 1 ms
|
|
set XA off
|
|
wait 1 ms
|
|
end if
|
|
return
|
|
|
|
MMove_y:
|
|
if mouse.5 then
|
|
set YA on
|
|
wait 1 ms
|
|
set YB on
|
|
wait 1 ms
|
|
set YA off
|
|
wait 1 ms
|
|
set YB off
|
|
wait 1 ms
|
|
else
|
|
set YB on
|
|
wait 1 ms
|
|
set YA on
|
|
wait 1 ms
|
|
set YB off
|
|
wait 1 ms
|
|
set YA off
|
|
wait 1 ms
|
|
end if
|
|
return
|
|
|
|
' *********************************************************************
|
|
' * Joystick section
|
|
' *********************************************************************
|
|
Joystick:
|
|
HSerPrint "Joystick"
|
|
HSerPrintCRLF
|
|
' read zero positions
|
|
zero_x = ReadAD(ADC5)
|
|
zero_y = ReadAD(ADC4)
|
|
' do main loop
|
|
do
|
|
' ** buttons **
|
|
LeftButton(L_Fire)
|
|
RightButton(R_Fire)
|
|
|
|
' ** movement **
|
|
X_Pos = ReadAD(ADC5)
|
|
Y_Pos = ReadAD(ADC4)
|
|
|
|
slow=0
|
|
if X_Pos < (zero_x - bias_f) then Move_x (0)
|
|
if (X_Pos >= (zero_x - bias_f)) and (X_Pos < (zero_x - bias_s)) then
|
|
Move_x (0)
|
|
slow=1
|
|
end if
|
|
if (X_Pos > (zero_x + bias_s)) and (X_Pos <= (zero_x + bias_f)) then
|
|
Move_x (1)
|
|
slow=1
|
|
end if
|
|
if X_Pos > (zero_x + bias_f) then Move_x (1)
|
|
|
|
if Y_Pos < (zero_y - bias_f) then Move_y (0)
|
|
if (Y_Pos >= (zero_y - bias_f)) and (Y_Pos < (zero_y - bias_s)) then
|
|
Move_y (0)
|
|
slow=1
|
|
end if
|
|
if (Y_Pos > (zero_y + bias_s)) and (Y_Pos <= (zero_y + bias_f)) then
|
|
Move_y (1)
|
|
slow=1
|
|
end if
|
|
if Y_Pos > (zero_y + bias_f) then Move_y (1)
|
|
|
|
|
|
'ACK Blink
|
|
SET led ON
|
|
Wait 10 us
|
|
SET led OFF
|
|
if slow=1 then
|
|
wait 40 ms
|
|
else
|
|
wait 100 us
|
|
end if
|
|
|
|
Loop
|
|
|
|
' *********************************************************************
|
|
' * Common sub section
|
|
' *********************************************************************
|
|
|
|
sub LeftButton(in status)
|
|
'if status then
|
|
' set LB off
|
|
'else
|
|
' set LB on
|
|
'end if
|
|
SetWith( LB, status )
|
|
wait 1 ms
|
|
end sub
|
|
|
|
sub RightButton(in status)
|
|
'if status then
|
|
' set RB off
|
|
'else
|
|
' set RB on
|
|
'end if
|
|
SetWith( RB, status )
|
|
wait 1 ms
|
|
end sub
|
|
|
|
' ***********************
|
|
' generate the x movement
|
|
sub Move_x(in direction)
|
|
if direction then
|
|
set XA on
|
|
wait pulse
|
|
set XB on
|
|
wait pulse
|
|
set XA off
|
|
wait pulse
|
|
set XB off
|
|
wait pulse
|
|
else
|
|
set XB on
|
|
wait pulse
|
|
set XA on
|
|
wait pulse
|
|
set XB off
|
|
wait pulse
|
|
set XA off
|
|
wait pulse
|
|
end if
|
|
end sub
|
|
|
|
' ***********************
|
|
' generate the y movement
|
|
sub Move_y(in direction)
|
|
if direction then
|
|
set YA on
|
|
wait pulse
|
|
set YB on
|
|
wait pulse
|
|
set YA off
|
|
wait pulse
|
|
set YB off
|
|
wait pulse
|
|
else
|
|
set YB on
|
|
wait pulse
|
|
set YA on
|
|
wait pulse
|
|
set YB off
|
|
wait pulse
|
|
set YA off
|
|
wait pulse
|
|
end if
|
|
end sub
|
|
|
|
end
|