Message-ID: <3212@ut-sally.UUCP>
Date: Mon, 27-Aug-84 18:31:11 EDT
Article-I.D.: ut-sally.3212
Posted: Mon Aug 27 18:31:11 1984
Date-Received: Thu, 30-Aug-84 11:13:27 EDT
Organization: Ministry of Silly Walks, 1600 Pennsylvania Ave
Lines: 380
[I'm so sorry, he's from Barcelona.]
Here is a nifty little bit of assembly code I wrote to shut off the
keyclick on my Atari 800 so my roommate could sleep whilst I stayed up
all night hacking. It hasn't been thoroughly tested but works fine
with my Chameleon terminal emulator and with the basic cart. The only
problem I've found is that it won't coexist with DUP (but what does?),
apparently DUP overwrites part of it and it crashes the system on the
first CR. If you are using Atari's DOS set it up as an AUTORUN.SYS
and boot with the basic cart in. If you need to go to DUP, hit the
SYSTEM RESET first, that will reset every thing back to normal (and
bring back the keyclick). If using OS/A+, with the Basic cart
you will have to go to dos (DOS), load this, then go back to Basic (CAR),
without the cart just load it from the D1: prompt.
I have a standard Atari 800 (pre-XL vintage) with one Atari 810 drive,
this is the only configuration this code has been tested on, so if you
have something else you'll just have to give it a shot and see what happens.
This code should work on either Rev. A or B of the OS roms, I copied
the code from the Rev. A OS list and it works on my Rev. B. I'm not
familiar with the XL roms but I believe they have an option for turning
keyclick on/off, so this isn't for them anyway. It should also work on
the early 400s but I can't remember if they had a console speaker or not.
I'm turning this loose to the world at large with the condition that
my name remain on the source code. Please send any praise/suggestions/
bug reports to me (hitchens@ut-sally.{UUCP,ARPA,etc}) This code is
written for OSS's MAC/65, but can easily be converted to just about
any Atari assembler.
Bonadah,
-------------------------------------------------------------------------------
Ron Hitchens hitchens@ut-sally
[Never try to teach a pig to sing, it [.UTEXAS, domain of the
wastes your time and it annoys the pig.] Mayan SUN worshippers]
P.S. This is not an archive, just chop out everything up to here.
---------------------------- cut here ------------------
0100 ;
0110 ;Keyboard click suppressor for Atari 800, OS roms A or B (not XL)
0120 .OPT NO LIST
0130 ;
0140 ;(c) Copyright August 1984 Ron Hitchens@ut-sally
0145 ; (512)-928-4654 Reachable at University of Texas Computer Science
0147 ; Dept. PAI 1.50 Austin, Tx 78714
0150 ;
0160 ;Relocates to MEMLO, doesn't take any page 6 or any other fixed space.
0170 ;This code will turn off the keyclick produced by accesses to the
0180 ;E: or K: devices. But not the snarfing bell thru the console speaker.
0190 ;It does this by changing the pointers in the handler tables for the
0200 ;K: and E: devices to point to new code which is a copy of the ROM
0210 ;code without the calls to the keyclick routine. This code follows
0220 ;the protocol for installing device handlers, except that it doesn't
0230 ;hook itself into the reset chain. This means it will not survive
0240 ;a SYSTEM RESET, but it may be loaded again with no problem.
0250 ;Loading it again (once it is already installed) will not hurt
0260 ;anything, it just loads another copy above the current one,
0270 ;wasting a little space.
0280 ;The action of this handler should be transparent to all applications
0290 ;providing they do legal accesses to the keyboard.
0300 ;Written for MAC/65, should be compatible with assm/edit cart
0310 ;excepting maybe .OPT and .IF statements. .IF can be removed.
0320 ;
0330 ;Copyright August 1984 Ron Hitchens
0340 ;I retain the copyright to this code, permission is given to
0350 ;reproduce and distribute it freely provided this notice is included.
0360 ;
0370 ;
0380 START = $3400 ;load point
0390 MEMLO = $02E7 ;
0400 HATABS = $031A
0410 PTR1 = $64
0420 PTR2 = $68
0430 CH = $02FC
0440 HOLDCH = $7C
0450 INVFLG = $02B6
0460 ATACHR = $02FB
0470 ICAX1Z = $2A
0480 BRKKEY = $11
0490 BRKABT = $80
0500 SHFLOK = $02BE
0510 EOFERR = $88
0520 DSTAT = $4C
0530 CR = $9B
0540 ATASCI = $FEFE
0550 ;
0560 *= START ;begin code
0570 RTS
0580 ;
0590 ;-------------------
0600 ; K: HANDLER
0610 ;
0620 READK2 LDA #$FF
0630 STA CH
0640 READK
0650 KVEC = READK-START-1 ;offset from MEMLO of new table entry
0660 ;modified code executed by the handler
0670 ;see OS listing (keyboard handler)
0680 ;
0690 LDA ICAX1Z
0700 LSR A
0710 BCS GETOUT
0720 LDA #BRKABT
0730 LDX BRKKEY
0740 BEQ K7
0750 LDA CH
0760 CMP #$FF
0770 BEQ READK
0780 STA HOLDCH
0790 LDX #$FF
0800 STX CH
0810 ; this is where CLICK call was
0820 ; have do copy following code to cover all the branches back here
0830 KGETC3 TAX
0840 CPX #$C0
0850 BCC ASCC01
0860 LDX #3
0870 ASCC01 LDA ATASCI,X
0880 STA ATACHR
0890 CMP #$80
0900 BEQ READK2
0910 CMP #$81
0920 BNE KGETC1
0930 LDA INVFLG
0940 EOR #$80
0950 STA INVFLG
0960 BNE READK2
0970 BEQ READK2 ;uncond rel jump
0980 KGETC1 CMP #$82
0990 BNE K1
1000 LDA #0
1010 STA SHFLOK
1020 BEQ READK2
1030 K1 CMP #$83
1040 BNE K2
1050 LDA #$40
1060 STA SHFLOK
1070 BNE READK2
1080 K2 CMP #$84
1090 BNE K3
1100 LDA #$80
1110 STA SHFLOK
1120 BNE READK2
1130 K3 CMP #$85
1140 BNE K6
1150 LDA #EOFERR
1160 K7 STA DSTAT
1170 STA BRKKEY
1180 GETOUT LDA #CR
1190 BNE K8
1200 K6 LDA HOLDCH
1210 CMP #$40
1220 BCS K5
1230 LDA ATACHR
1240 CMP #$61
1250 BCC K5
1260 CMP #$7B
1270 BCS K5
1280 LDA SHFLOK
1290 BEQ K5
1300 ORA HOLDCH
1310 BNE KGETC3
1320 BEQ KGETC3 ;unconditional
1330 K5 JSR $FC8D
1340 BEQ K4
1350 LDA ATACHR
1360 EOR INVFLG
1370 K8 STA ATACHR
1380 K4 JMP $F634
1390 ;
1400 MYKTAB *= *+16 ;reserve handler table space
1410 KADDR = MYKTAB-START ;rel offset of new table
1420 ;-------------------
1430 ;
1440 ; E: HANDLER
1450 ;
1460 READE
1470 EVEC = READE-START-1 ; offset for E: getch entry
1480 JSR $FCB3
1490 JSR $FA88
1500 LDA $6B
1510 BNE EGETC3
1520 LDA $54
1530 STA $6C
1540 LDA $55
1550 STA $6D
1560 EPATCH = *+1
1570 EGETC1 JSR READK-START ;will be patched
1580 STY DSTAT
1590 LDA ATACHR
1600 CMP #CR
1610 BEQ EGETC2
1620 JSR $F6AD
1630 JSR $FCB3
1640 LDA $63
1650 CMP #113
1660 BNE EGETC6
1670 JSR $F90A
1680 EGETC6 BNE EGETC1
1690 BEQ EGETC1 ;uncond
1700 EGETC2 JMP $F66E
1710 JMP $F653
1720 EGETC3 JMP $F67C ;CAVEAT
1730 ;
1740 ;all references to $Fxxx addresses are unauthorized entries.
1750 ;
1760 MYETAB *= *+16
1770 EADDR = MYETAB-START
1780 ;-----------------------
1790 ;
1800 FENCE
1810 SIZE = FENCE-START
1820 .IF SIZE>255
1830 .ERROR "RESIDENT > 255"
1840 .ENDIF
1850 ; end of resident code
1860 ;
1870 ; Init code, runs once
1880 ;
1890 INIT
1900 ;lookup and move handler tables
1910 LDA #MYKTAB&$FF
1920 STA PTR2
1930 LDA #MYKTAB/256
1940 STA PTR2+1
1950 LDA #'K
1960 JSR MOVTAB
1970 STY TEMPK
1980 LDA #MYETAB&$FF
1990 STA PTR2
2000 LDA #MYETAB/256
2010 STA PTR2+1
2020 LDA #'E
2030 JSR MOVTAB
2040 STY TEMPE
2050 ;
2060 ;put new vectors in tables
2070 LDX #KVEC&$FF
2080 LDY #KVEC/256
2090 LDA #MYKTAB&$FF
2100 STA PTR2
2110 LDA #MYKTAB/256
2120 STA PTR2+1
2130 JSR INSVEC
2140 LDX #EVEC&$FF
2150 LDY #EVEC/256
2160 LDA #MYETAB&$FF
2170 STA PTR2
2180 LDA #MYETAB/256
2190 STA PTR2+1
2200 JSR INSVEC
2210 ;
2220 ;patch JSR in E: handler code
2230 CLC
2240 LDA EPATCH
2250 ADC MEMLO
2260 STA EPATCH
2270 LDA EPATCH+1
2280 ADC MEMLO+1
2290 STA EPATCH+1
2300 ;
2310 ;move the resident code
2320 LDA MEMLO
2330 STA PTR1 ;load a pointer (dest)
2340 LDA MEMLO+1
2350 STA PTR1+1
2360 LDA #START&$FF ;source pointer
2370 STA PTR2
2380 LDA #START/256
2390 STA PTR2+1
2400 LDY #SIZE
2410 L2 LDA (PTR2),Y ;OK if SIZE < 256
2420 STA (PTR1),Y
2430 DEY
2440 BNE L2
2450 LDA (PTR2),Y ;get 0th byte
2460 STA (PTR1),Y
2470 ;
2480 ;patch the pointers in HATABS to new tables
2490 LDX #KADDR&$FF
2500 LDY #KADDR/256
2510 LDA TEMPK
2520 STA TEMP
2530 JSR PCHVEC
2540 LDX #EADDR&$FF
2550 LDY #EADDR/256
2560 LDA TEMPE
2570 STA TEMP
2580 JSR PCHVEC
2590 JMP END ;skip over subroutines and finish
2600 ;
2610 MOVTAB LDY #$21 ;run backwards
2620 SRCH CMP HATABS,Y
2630 BEQ GOTIT
2640 DEY
2650 DEY
2660 DEY
2670 BPL SRCH
2680 PLA
2690 PLA
2700 RTS ;it isn't there !?!
2710 GOTIT STY TEMP ;we'll need this later
2720 LDA HATABS+1,Y ;low byte
2730 STA PTR1
2740 LDA HATABS+2,Y ;high byte
2750 STA PTR1+1
2760 LDY #15
2770 LOOP LDA (PTR1),Y
2780 STA (PTR2),Y ;copy old table to mine
2790 DEY
2800 BPL LOOP
2810 LDY TEMP
2820 RTS
2830 ;
2840 INSVEC
2850 TYA
2860 PHA
2870 TXA
2880 LDY #4 ;doing 3rd entry (getch)
2890 CLC
2900 ADC MEMLO
2910 STA (PTR2),Y
2920 PLA
2930 ADC MEMLO+1
2940 INY
2950 STA (PTR2),Y
2960 RTS
2970 ;
2980 ;
2990 ; set pointer to patched handler table
3000 PCHVEC
3010 TYA
3020 PHA
3030 TXA
3040 LDY TEMP
3050 CLC
3060 ADC MEMLO
3070 STA HATABS+1,Y
3080 PLA
3090 ADC MEMLO+1
3100 STA HATABS+2,Y
3110 RTS
3120 ;------------
3130 ;
3140 ;continue mainline INIT code
3150 END CLC
3160 LDA MEMLO
3170 ADC #SIZE&$FF
3180 STA MEMLO ;move MEMLO up past our new code
3190 LDA MEMLO+1
3200 ADC #SIZE/256
3210 STA MEMLO+1
3220 ;
3230 ; print out a msg
3240 LDA #9
3250 STA $0342
3260 LDA #MSG&$FF
3270 STA $0344
3280 LDA #MSG/256
3290 STA $0345
3300 LDA #$FF
3310 STA $0349
3320 LDX #0
3330 JSR $E456
3340 ;
3350 RTS RTS ;all finished, no keyclick, and I didn't need a screwdriver
3360 ;
3370 TEMP .BYTE 0
3380 TEMPK .BYTE 0
3390 TEMPE .BYTE 0
3400 MSG .BYTE "Keyclick disabled",$9B
3410 ;----------------
3420 ;
3430 *= $02E0
3440 .WORD RTS ;DUMMY VECTOR
3450 .WORD INIT
3460 ; set start vector to run init code
3470 ; this allows concating with other autoruns
3480 .OPT NO LIST
3490 ;suppress xref if list on
3500 ;
3510 ;---- this is the last line ----