Apple II Technical Notes _____________________________________________________________________________ Developer Technical Support Apple II Miscellaneous #10: 80-Column GetChar Routine Revised by: Dave Lyons September 1989 Written by: Cameron Birse December 1986 This Technical Note presents an 80-column GetChar routine. Changes since November 1988: Added discussion of single-character input on the unenhanced Apple IIe. _____________________________________________________________________________ The following is an example of how to display a string on the 80-column screen, reposition the cursor at the beginning of the string, and use the right arrow to get characters which are already there or accept new characters in their place. The routine is a simple BASIC program which displays the string and repositions the cursor before getting incoming characters. If the character input is a right arrow, the program calls the assembly language routine to get the character from screen memory at the current cursor location. 10 PRINT CHR$ (4);"bload getchar.0": REM first install assembly routine 20 B$ = "hello" 30 PRINT CHR$ (4);"pr#3" 40 PRINT B$;:B$ = "" 50 A = PEEK (1403): REM get horiz location 60 A = A - 5: REM move cursor to beginning of string 70 POKE 1403,A 80 GET A$: REM get a character 90 IF A$ = CHR$ (21) THEN GOSUB 130: REM if char is forward arrow, handle with assembly routine (GETCHAR) 100 IF A$ = CHR$ (27) THEN 170: REM if esc key then we're done 110 PRINT A$;:B$ = B$ + A$ 120 GOTO 80 130 CALL 768: REM GETCHAR 140 A = PEEK (6) 150 A$ = CHR$ (A) 160 RETURN 170 PRINT : PRINT : PRINT B$: REM and we're done An assembled listing of the assembly language GetChar routine follows. It works on the Apple IIe and later. SOURCE FILE #01 =>GETCHAR ----- NEXT OBJECT FILE NAME IS GETCHAR.0 0300: 0300 1 ORG $300 0300: C01F 2 RD80VID EQU $C01F ;80 COLUMN STATE 0300: C054 3 TXTPAGE1 EQU $C054 ;TURN OFF PAGE 2 (READ) 0300: C055 4 TXTPAGE2 EQU $C055 ;TURN ON PAGE 2 (READ) 0300: C000 5 CLR80COL EQU $C000 ;TURN OFF 80 STORE (WRITE) 0300: C001 6 SET80COL EQU $C001 ;TURN ON 80 STORE (WRITE) 0300: 0028 7 BASL EQU $28 ;BASE ADDRESS OF SCREEN LOCATION 0300: 0029 8 BASH EQU $29 0300: 057B 9 OURCH EQU $57B ;80 COLUMNS HORIZ. POSITION 0300: 05FB 10 OURCV equ $5fb ;80 col vertical pos 0300: 0006 11 char equ 6 ;place to hand character back to basic 0300: 12 * 0300: 13 ************************************************************* 0300: 14 * GETCHAR - This routine gets an ascii character from the * 0300: 15 * 80 column display memory of the Apple IIe. It assumes * 0300: 16 * that main memory is switched in and that the base addrs * 0300: 17 * of the line has already been calculated and resides * 0300: 18 * in BASL and BASH. It is meant to be called from BASIC * 0300: 19 * as follows: * 0300: 20 * CALL 768 * 0300: 21 * A = PEEK (6) * 0300: 22 * A$ = CHR$(A) * 0300: 23 * As you can see, the character is returned in location * 0300: 24 * $6 in zero page. This routine is offered as an example. * 0300: 25 * No guaranties are made regarding its fitness for any * 0300: 26 * purpose. By Cameron Birse 6/10/86 * 0300: 27 ************************************************************* 0300: 28 * 0300: 0300 29 getchr equ * ;get the char at the current cursor loc. 0300:A9 01 30 lda #$01 ;mask for horiz test 0302:2C 7B 05 31 bit OURCH ;are we in main or aux mem? 0305:D0 17 031E 32 bne main ;if bit 0 of OURCH is set, then main mem 0307: 0307 33 aux equ * 0307:AD 7B 05 34 lda OURCH ;get horiz pos. 030A:18 35 clc ;clear the carry for divide 030B:6A 36 ror a ;divide by two 030C:A8 37 tay ;put the result in y 030D:8D 01 C0 38 sta SET80COL ;turn on 80 store 0310:AD 55 C0 39 lda TXTPAGE2 ;flip to aux text page 0313:B1 28 40 lda (basl),y ;get the character 0315:85 06 41 sta char 0317:AE 54 C0 42 ldx TXTPAGE1 ;turn off aux text page 031A:8D 00 C0 43 sta CLR80COL ;turn off 80 store 031D:60 44 rts 031E: 031E 45 main equ * 031E:AD 7B 05 46 lda OURCH ;get horiz pos. 0321:18 47 clc ;clear the carry for divide 0322:6A 48 ror a ;divide by two 0323:A8 49 tay ;put the result in y 0324:B1 28 50 lda (basl),y ;get the character 0326:85 06 51 sta char 0328:60 52 rts Reading a Single Character While the 80-column firmware is active (whether in 40- or 80-column mode), the RDKEY routine on the unenhanced Apple IIe unexpectedly allows the user to press ESC and move the cursor around the screen the same way RDCHAR does. AppleSoft's GET statement uses RDKEY, so it behaves the same way. The ESC keypress is never returned, so users have problems if you use GET and expect them, for example, to press ESC to return to the previous menu. At this point, the cursor turns into an inverse plus sign (+) and your program is still waiting for a keypress. The user presses ESC a few more times, watching the cursor alternate between an inverse plus sign and an inverse blank, and then turns off the computer in search of a more exciting activity, like throwing darts at your disk. If your program can run on the unenhanced IIe, either leave the 80-column firmware turned off (PRINT CHR$(21) to make sure it's off), or read keypresses by polling the keyboard register directly: 1000 IF PEEK(-16384)<128 THEN 1000 : REM Wait for a keypress 1010 A$ = CHR$(PEEK(-16384)-128) : REM Read the key 1020 POKE -16368,0 : REM Clear the keyboard strobe or 0300: LDA $C000 ; check for a keypress 0303: BPL $0300 ; keep waiting 0306: AND #$7F ; turn off bit 7 0308: STA $C010 ; clear the keyboard strobe Note that these code fragments don't display a cursor while waiting for a key. Further Reference _____________________________________________________________________________ o Apple IIGS Firmware Reference o Apple IIe Technical Reference Manual o Apple IIc Technical Reference Manual, Second Edition