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


This and all of the other Apple II Technical Notes have been converted to HTML by Aaron Heiss as a public service to the Apple II community, with permission by Apple Computer, Inc. Any and all trademarks, registered and otherwise, are properties of their owners.