If you want to reduce cost of controller by approx. 2 USD, you can replace flash PIC by OTP (One-Time-Programmable) PIC. It may be one of following PICs: PIC16C554, PIC16C558, PIC16C620, PIC16C621, PIC16C622 and some others. Them are cheaper, but you can't update firmware - you will need to replace PIC for that. Additionally, there is no OTP PIC programmers on Amiga now (June 2001), and you will need to program it elsewhere.
Optionally, you may use following parts:
| OSC | = | HS |
| WDT | = | ON |
| OSC | = | INTRC without CLKOUT |
| WDT | = | ON |
| LVP | = | OFF |
| MCLRE | = | OFF (digital I/O or something similar) |
|
Devpic will program PIC16F84(A) by following command: picprog ps2m.hex force=16382 |
|
For programming PIC16F627 or PIC16F628 you will use command: picprog ps2m.hex force=16212 sf=2 |
«FORCE» keyword describes configuration word, that contains configuration bits like OSC and WDT (and also LVP & MCLRE for PIC16F62x). Normally it can be «CW» keyword, but «FORCE» does also code deprotection if PIC was protected. Don't use that keywords when you update firmware - PIC remembers last configword. «SF» is «SmartFlash» mode of picprog, that speed ups new PIC's programming up to 5 times in comparison with PIC16F84.
OSC is an OSCillator mode (PIC can handle resonators or RC circuit), and WDT is WatchDog Timer - it is an internal PIC circuit, that automatically resets it if it hangs. WDT is required for PS/2 controller - it is used in algorithm not only for exception cases, but even for mouse waiting. LVP is a Low Voltage Programming - in this mode programmer doesn't need 12v, but we lose RB4 PIC pin. MCLRE - purpose of MCLR pin, in our case it works as general input pin (maybe useful in future versions). If you don't want to understand all this details - simply use string as described above.
If you had problems with PIC programming - forget your old devpic archive, and try new devpic release (now 1.6) with v3 hardware, it is more stable than v2.
picasm ps2m
Both firmware versions may be generated from one source because of conditional asseymbly usage. POWER variable (see line POWER equ...) defines it - 0 value is a 5-button version, and 1 value is a 4-button version. SPEED variable allows you to use different resonators, than 4MHz (see comment).
Some comments about several program parts destination:
| Label | Description |
|---|---|
| int | Interrupt handler - it is called every mouse clock (11 times per byte) and eats approximately a half of 4MHz PIC speed. After byte receiving, this routine stores received byte in recvdt and sets flag fbyte. These bytes are stored in packet buffer in «main loop». |
| start start_a |
Init code. Some details about mouse detection:
|
| m_check | It is a code, that will be executed after 2 seconds of mouse «silence». It reads mouse status and sees stream mode flag. If stream mode is disabled - this means that mouse was reconnected. In this case controller will reset it. |
| p_init |
Here is setting of initial values of «virtual sync serial port».
It is used mainly for «re-sync» if sync was lost due to electric
surge/noise (bit(s) was lost or unnecessary bit(s) was added). Additionally, this routine contains check for «alien» signal on LMB pin (for example - second joystick «fire») and disable controller. |
| schk | This routine receives bytes in packet buffer (byte1-byte4). After this it sets fpkt1 flag. |
| pchk1 |
This routine will be called after receiving of full packet. Because of controller is all
time in «main loop» simulates mouse movement, packet processing is done by
several parts. It is a first part - processing of horisontal movement. After processing
this routine sets flag for next routine (fpkt2), and without own flag (fpkt1)
it will not be processed again up to next packet receiving. Processing of movement contains calculating of mouse speed - movement will be done with this speed. |
| pchk2 | This routine is like previous, and it processes vertical movement. |
| pchk3 | This routine processes all mouse buttons (at first - standard three buttons), and then it processes additional buttons and wheel (only if these were detected). |
| tchk | It is a timer support. Controller updates mouse signals only approx. 6000 times per second. If next 1/6000 of second doesn't approach yet, controller will return to checking of next byte. |
| mchk | It is a mouse checking - as described above. |
| xchk ychk | It is realtime update of movement counters with needed speed. |
| zchk | Wheel counter update. |
| xyout | Movement counters and fourth button are simultaneously updated here. |
| cpoff | This subroutine enables controller, if it is disabled. Additionally it sets counters in default state. |
| testms | Check for Microsoft protocol(s). Both protocols are checked in one subroutine because of similarity (one byte difference). |
| send | Sending byte to mouse. Because of rare nature of this action, it is not done by interrupt engine (that also unloads interrupt routine from rare instructions). |
| bwait | It is a waiting for byte from mouse. Actually a byte receiving subroutine. |
| delayms delayus | Delays by milliseconds and fourt microseconds (in W). |