10 ;KEYCODE3.M65›20 ;Rewritten 11/87 by Bob Hardy›30 ;from an original program›40 ;by Bob Hardy›50 ;›60 ;Revision of 4/30/89›70 ;›80 ;›90 .OPT OBJ›0100 .OPT NO LIST›0110 .INCLUDE #D8:SYSEQU.M65›0120 .INCLUDE #D8:MACROLIB.M65›0130 .INCLUDE #D8:GREQU.M65›0140 .INCLUDE #D8:GRAPHICS.M65›0150 ;›0160 ;---------›0170 ; Equates›0180 ;---------›0190 ;›0200 ;IOCB LOCATIONS›0210 ;--------------›0220 ;›0230 ; The IOCBs are the Atari's I/O›0240 ; channels. They are a 'safe'›0250 ; way to do I/O in that they are›0260 ; always compatible and always›0270 ; 'legal'. The worst you can do›0280 ; with IOCBs is an I/O error.›0290 ; There are no 'illegal' calls.›0300 ;›0310 ;ICCOM = $0342 ;command›0320 ;ICBAL = $0344 ;buf. adr., lo›0330 ;ICBAH = $0345 ;buf. adr., hi›0340 ;ICBLL = $0348 ;buf. len., lo›0350 ;ICBLH = $0349 ;buf. len., hi›0360 ;ICAX1 = $034A ;AUX1›0370 ;ICAX2 = $034B ;AUX2›0380 ;›0390 ;OS REGISTERS, ETC.›0400 ;------------------›0410 ;›0420 ; These are too complex to try›0430 ; to document here. For details›0440 ; see 'Mapping The Atari' from›0450 ; COMPUTE! books.›0460 ;›0470 ;WARMST = $08›0480 BOOT? = $09›0490 POKMSK = $10›0500 ;LMARGN = $52›0510 ;SAVMSC = $58›0520 INVFLG = $02B6›0530 SHFLOK = $02BE›0540 ;COLOR1 = $02C5 ;(709)›0550 ;COLOR2 = $02C6 ;(710)›0560 ;COLOR4 = $02C8 ;(712)›0570 CRSINH = $02F0›0580 CH1 = $02F2›0590 CHREG = $02FC ;(764)›0600 DSPFLG = $02FE›0610 CONSOL = $D01F›0620 IRQEN = $D20E›0630 PUTBYTES = $0B›0640 ;›0650 ;VECTORS›0660 ;-------›0670 ;›0680 COLDST = $0244›0690 KEYDEL = $02F1›0700 ;CIOV = $E456›0710 WARMSV = $E474›0720 ;›0730 ;ZERO-PAGE 2-BYTE POINTERS›0740 ;-------------------------›0750 ;›0760 SCRPTR = $CB›0770 TXPTR = $CD›0780 ;›0790 ;KEYPRESS VALUES:›0800 ;----------------›0810 ;›0820 ; CONSOLE KEYS›0830 ;›0840 SELECT = 5›0850 START = 6›0860 ;›0870 ; ATASCII CHARACTERS›0880 ;›0890 SPACE = $20›0900 ;EOL = $9B›0910 ;›0920 ; CHREG VALUES›0930 ;›0940 NOKEY = $FF›0950 ;›0960 ;›0970 *= $4000›0980 ;›0990 TOP›1000 CLC ›1010 CLD ›1020 JSR NOBREAK ; Disable BREAK›1030 LDA SAVMSC ; Store start›1040 STA SCRPTR ; adr of screen›1050 LDA SAVMSC+1 ;memory in ZPG›1060 STA SCRPTR+1 ;screen pointer›1070 JSR SETUP ; Print opening›1080 ; message and›1090 ; wait for›1100 ; START keypress›1110 ;›1120 RESTART›1130 JSR NOBREAK ;Kill BREAK›1140 LDA #0 ;Turn cursor›1150 STA CRSINH ;on, normal›1160 STA DSPFLG ;CTRL chars›1170 STA COLOR4 ;Black border›1180 LDA #2 ;Left margin=2›1190 STA LMARGN›1200 STA COLOR2 ;Gray backgrnd›1210 LDA #$0A ;White letters›1220 STA COLOR1›1230 LDX # MAINSCRN ;main scrn›1250 LDA #90›1260 JSR PRINT›1270 JSR OPENK ;OPEN K:›1280 LDA #NOKEY ;Clear key reg›1290 STA CHREG›1300 LDA #0 ;Clear Inverse›1310 STA INVFLG ;lock.›1320 LDA #64 ;Set all CAPS›1330 STA SHFLOK›1340 JSR KEYCHK ;Wait for key-›1350 JSR KEYIN ;press & get key›1360 JSR CLOSE1 ;Close K:›1370 LDA CH1 ;Get last key›1380 STA KEYBUF ;accepted &›1390 ; store it.›1400 JSR MAKEINT ;ATASCII code›1410 ; is converted›1420 ; to internal›1430 ; code and›1440 ; stored in›1450 ; INTBUF›1460 LDA KEYBUF ;Recover›1470 ; keyboard code›1480 JSR MAKEDEC ;Convert to›1490 ; ATASCII digits›1500 LDY #2›1510 ;›1520 MOVKEYDEC›1530 LDA ATAHUNS,Y ;Move the›1540 STA KEYBDEC,Y ;result to›1550 DEY ; KEYBDEC›1560 BPL MOVKEYDEC›1570 LDA KEYBUF ;Get keyboard›1580 JSR HEXCONV ;code and›1590 LDY #2 ;convert to HEX›1600 ;›1610 MOVKEYHEX›1620 LDA ATAHUNS,Y ;Move the›1630 STA KEYBHEX,Y ;result to›1640 DEY ; KEYBHEX›1650 BPL MOVKEYHEX›1660 LDA INTBUF ;Get internal›1670 JSR MAKEDEC ;code & convert›1680 LDY #2 ;to ATASCII›1690 ;›1700 MOVHARDEC›1710 LDA ATAHUNS,Y ;Store the›1720 STA HARDDEC,Y ;result in›1730 DEY ; HARDDEC›1740 BPL MOVHARDEC›1750 LDA INTBUF ;Get internal›1760 JSR HEXCONV ;code & convert›1770 LDY #2 ;TO HEX›1780 ;›1790 MOVHARDHEX›1800 LDA ATAHUNS,Y ;Move the›1810 STA HARDHEX,Y ;result to›1820 DEY ; HARDHEX›1830 BPL MOVHARDHEX›1840 LDA ATBUF ;Get ATASCII›1850 JSR MAKEDEC ;charcode and›1860 LDY #2 ;convert to DEC›1870 ;›1880 MOVATDEC›1890 LDA ATAHUNS,Y ;Store the›1900 STA ATDEC,Y ; result in›1910 DEY ; ATDEC›1920 BPL MOVATDEC›1930 LDA ATBUF ;Get ATASCII›1940 JSR HEXCONV ;Convert to HEX›1950 LDY #2›1960 ;›1970 MOVATHEX›1980 LDA ATAHUNS,Y ;and store the›1990 STA ATHEX,Y ;result in ATHEX›2000 DEY ›2010 BPL MOVATHEX›2020 LDA #1 ;Turn cursor off›2030 STA CRSINH›2040 LDX # ATAMSG ;message›2060 LDA #ATALEN ;msg. length›2070 JSR PRINT›2080 LDA SAVMSC ;Add $0170 to›2090 CLC ;scrn ptr›2100 ADC #$70 ;low byte...›2110 STA SCRPTR›2120 LDA SAVMSC+1 ;high byte...›2130 ADC #1›2140 STA SCRPTR+1›2150 LDA INTBUF ;Get char &›2160 LDY #0 ;poke it into›2170 STA (SCRPTR),Y ;scrn RAM›2180 LDX # KEYMSG ;ware message›2200 LDA #KEYBLEN ;msg. length›2210 JSR PRINT›2220 JSR OPENK ;Clear any›2230 LDA #NOKEY ;keypresses...›2240 STA CHREG›2250 BNE QUITS?›2260 DONTQUIT›2270 JMP NOQUIT›2280 ;›2290 ; Is the user finished?›2300 ;›2310 QUITS?›2320 LDA CONSOL ;Select press?›2330 CMP #SELECT›2340 BNE DONTQUIT ;Nope.›2350 LDX # QUITMSG ;Get user to›2370 LDA #QMSGLEN ;confirm.›2380 JSR PRINT›2390 JSR KEYCHK ;Wait for key.›2400 JSR KEYIN ;Get keypress.›2410 LDA ATBUF›2420 AND #$7F ;ASCII only›2430 CMP #'Y ;Was it "Y"?›2440 BEQ EXIT ;Yupper!›2450 JSR SCRPUT ;Nope. Print it›2460 JSR CLOSE1›2470 LDA #EOL ;Print an EOL›2480 JSR SCRPUT›2490 JSR GR.0 ;purify screen›2500 JMP RESTART ;and restart.›2510 ALLDONE?›2520 JMP QUITS?›2530 NOQUIT›2540 LDA CHREG ;No...ANY key?›2550 CMP #NOKEY›2560 BEQ ALLDONE? ;No...›2570 JSR KEYIN ;Yes!›2580 JSR CLOSE1 ;CLOSE K:›2590 LDA ATBUF ;Print the›2600 JSR SCRPUT ;key pressed›2610 JMP RESTART ;and restart.›2620 ;›2630 ; We're outa here.›2640 ;›2650 EXIT›2660 JSR SCRPUT ;Print the key›2670 JSR CLOSE1 ;Close K:›2680 JSR CLOSE0 ;Close E:›2690 LDA #NOKEY ;Clear CHREG›2700 STA CHREG›2710 LDA #$FF ;Normal RESET›2720 STA WARMST ;status.›2730 LDA #1 ;Tell OS disk›2740 STA BOOT? ;boot was OK›2750 LDA #0 ;and no reboot›2760 STA COLDST ;on warmstart.›2770 JSR GR.0 ;Purify screen.›2780 JMP WARMSV ;Do warmstart.›2790 ;›2800 ;-------------------------------›2810 ;›2820 ; Subroutines -- what make the›2830 ; flow of the program work.›2840 ;›2850 ;-------------------------------›2860 ;›2870 ;This is a general purpose›2880 ;"Put bytes to E:"›2890 ;subroutine.›2900 ;›2910 ;Text address lo,hi is stored›2920 ;upon entry in x,y.›2930 ;Text length lo is stored›2940 ;in A. Text length hi is›2950 ;always assumed to be zero.›2960 ;›2970 PRINT›2980 STX ICBAL ;Adrlo=X›2990 LDX #0 ;IOCB#0 (E:)›3000 STA ICBLL,X ;Lenlo=A›3010 TXA ;Lenhi=0›3020 STA ICBLH,X›3030 TYA ;Adrhi=Y›3040 STA ICBAH,X›3050 LDA #PUTBYTES ;Put cmnd.›3060 STA ICCOM,X›3070 JSR CIOV›3080 JMP NOBREAK›3090 ;›3100 ;This subroutine prints the›3110 ;character stored in the›3120 ;accumulator to the screen.›3130 ;›3140 SCRPUT›3150 PHA ;Save A Reg.›3160 LDX #0 ;IOCB #0›3170 TXA ›3180 STA ICBLL,X ;LEN=0›3190 STA ICBLH,X›3200 LDA #PUTBYTES ;Put cmnd.›3210 STA ICCOM,X›3220 PLA ;Restore A and›3230 JMP CIOV ;print it.›3240 ;›3250 ; Do we or do we not have a›3260 ; keypress? KEYCHK waits until›3270 ; we get one.›3280 ;›3290 KEYCHK›3300 LDA CHREG ;Any keypress?›3310 CMP #NOKEY›3320 BEQ KEYCHK ;Nope.›3330 RTS ;Yep!›3340 ;›3350 ; We have a keypress. Let's›3360 ; read it through IOCB #1.›3370 ; (where the keyboard happens›3380 ; to already be open!)›3390 ;›3400 KEYIN›3410 LDX #$10 ;IOCB #1›3420 LDA #7 ;Get bytes›3430 STA ICCOM,X›3440 LDA #1 ;Lenlo=1›3450 STA ICBLL,X›3460 LDA #0 ;Lenhi=0›3470 STA ICBLH,X›3480 LDA # ATBUF›3510 STA ICBAH,X›3520 JMP CIOV›3530 ;›3540 ; Open the keyboard. Nothing›3550 ; visible happens, but you can›3560 ; read from the keyboard now.›3570 ;›3580 OPENK›3590 OPEN 1,4,0,"K:"›3600 RTS ›3610 ;›3620 ; Close IOCB #1. End-of-file.›3630 ; We got our keypress. G'bye!›3640 ;›3650 CLOSE1›3660 CLOSE 1›3670 RTS ›3680 ;›3690 ; Close IOCB #0. We're exiting.›3700 ;›3710 CLOSE0›3720 CLOSE 0›3730 RTS ›3740 ;›3750 ; Turn ATASCII keycode into›3760 ; hardware (internal) code›3770 ; and store the result in›3780 ; INTBUF.›3790 ;›3800 MAKEINT›3810 LDA ATBUF ;Get ATASCII›3820 BMI FIXHI ;If inv, fix.›3830 ;›3840 LOKEY›3850 CMP #32 ;Key>31?›3860 BCS MIDKEY ;Yes.›3870 CLC ;No - add 64.›3880 ADC #64›3890 STA INTBUF ;Conversion›3900 RTS ;complete.›3910 ;›3920 MIDKEY›3930 CMP #96 ;Key>95?›3940 BCS HIKEY ;Yes - fix.›3950 SEC ;No - subtract›3960 SBC #32 ;32 from key.›3970 STA INTBUF ;Conversion›3980 RTS ;complete.›3990 ;›4000 HIKEY›4010 CMP #128 ;Key>127?›4020 BCS FIXHI ;Yes.›4030 STA INTBUF ;No - conversion›4040 RTS ;unnecessary.›4050 ;›4060 FIXHI›4070 AND #$7F ;Clear bit 7›4080 JSR LOKEY ;Go do usual›4090 ORA #$80 ;conversion,›4100 STA INTBUF ;reset bit 7,›4110 RTS ;and done.›4120 ;›4130 ; We don't want any BREAK errors›4140 ; crippling the program, so...›4150 ;›4160 NOBREAK›4170 LDA POKMSK ;Disable the›4180 AND #$7F ;BREAK key›4190 STA POKMSK›4200 STA IRQEN›4210 RTS ›4220 ;›4230 ; We want a nice display for the›4240 ; user to look at, and we want›4250 ; the user to understand what is›4260 ; going on. We'll dress up the›4270 ; screen a bit and print out our›4280 ; explanatory message.›4290 ;›4300 SETUP›4310 LDY #0 ;Black screen›4320 STY COLOR2 ;and border›4330 STY COLOR4›4340 LDA #10 ;White text›4350 STA COLOR1›4360 LDA # INTROTX›4390 STA TXPTR+1›4400 ;›4410 FASTPRNT›4420 LDA (TXPTR),Y ;Get scrntext›4430 CMP #128 ;Last char?›4440 BEQ STARTPRS ;Yes-chk START›4450 STA (SCRPTR),Y ;No, move›4460 INY ;char to scrmem›4470 BNE FASTPRNT›4480 INC SCRPTR+1 ;Step up SCRPTR›4490 INC TXPTR+1 ; and TXPTR›4500 BNE FASTPRNT›4510 ;›4520 STARTPRS›4530 LDA CONSOL ; START pressed?›4540 CMP #START›4550 BNE STARTPRS ;Nope!›4560 RTS ; Yes!›4570 ;›4580 GR.0 ; Keep the macro›4590 GRAPHICS 0 ;from needlessly›4600 RTS ;being reassembled›4610 ;›4620 ;-------------------------------›4630 ;›4640 ; Buffers, text & storage space›4650 ;›4660 ;-------------------------------›4670 ;›4680 KEYBUF›4690 .DS 1›4700 INTBUF›4710 .DS 1›4720 ATBUF›4730 .DS 1›4740 ;›4750 MAINSCRN›4760 .BYTE 125,EOL,"Keycode Getter",EOL›4770 .BYTE "Written by Bob Hardy with MAC/65",EOL,EOL›4780 .BYTE "Press a key for which you want codes:",EOL,EOL›4790 ATAMSG›4800 .BYTE EOL,EOL›4810 .BYTE "ATASCII:",EOL›4820 .BYTE "Char: ",EOL›4830 .BYTE "Dec: "›4840 ;›4850 ATDEC›4860 .BYTE " Hex: $"›4870 ;›4880 ATHEX›4890 .BYTE " ",EOL,EOL›4900 ATALEN = *-ATAMSG›4910 ;›4920 KEYMSG›4930 .BYTE "Hardware code:",EOL›4940 .BYTE "Dec: "›4950 HARDDEC›4960 .BYTE " Hex: $"›4970 ;›4980 HARDHEX›4990 .BYTE " ",EOL,EOL›5000 ;›5010 .BYTE "Keyboard code:",EOL›5020 .BYTE "Dec: "›5030 ;›5040 KEYBDEC›5050 .BYTE " Hex: $"›5060 ;›5070 KEYBHEX›5080 .BYTE " ",EOL,EOL,EOL,EOL›5090 .BYTE "Press to continue.",EOL›5100 .BYTE "Press