14

In quite a few programs on Atari, I found the self-programming trick:

10 GRAPHICS 0           : REM clear the screen, enter standard text mode
20 POSITION 2,4         : REM place cursor 4 lines from top of screen
30 PRINT "1000 SOUND 0, 200, 10, 15      : REM Beep"
40 PRINT "1010 FOR I=0 TO 500 : NEXT I   : REM wait a bit"
50 PRINT "1020 SOUND 0, 0, 0, 0          : REM Silence"
60 PRINT "1030 RETURN"
70 PRINT "CONT"
80 POSITION 2,0         : REM place cursor on top of screen
90 POKE 842,13          : REM The Magical POKE
100 STOP                : REM Abort program execution
110 POKE 842,12         : REM Program resumes from here. This stops the effect of the prior POKE
120 GOSUB 1000          : REM Emit the Beep
130 END

The above program appends to itself a subroutine that emits a beep, then executes it. The uses in practice were much more creative.

The key point is POKE 842,13 which causes effect similar to holding down the Return key - the cursor starts riding down the screen, executing whatever's printed out - including CONT which resumes the program.

I found memory location 842 is ICAX1 not very informatively described as The auxiliary information bytes are used to give CIO or the device any special information needed. Bits 2 and 3 are responsible for Read and Write flags when opening a file... but I didn't find anything about bit 0, plus no file is being accessed here.

So, 'from the guts side' what did that POKE do?

12

If bit 0 of location 842 is set then the keyboard scanning routine immediately returns 0x9B which is the code indicating the ENTER key has been pressed. In short, a surprisingly literal effect.

The keyboard scan is part of the "OS" ROM built into the machine. There's a source listing I'll excerpt from: Atari 800 ROM OS Source Listing

ICAX1Z is a zero page location that is a temporary copy of location 842. If you know 6502 assembly language you can quickly see that the keyboard scan routine returns 0x9B when bit 0 of ICAX1Z is set:

; SYSTEM EOL (CARRIAGE RETURN)
CR      =    $9B
;...
KGETCH: LDA  ICAX1Z    ;TEST LSB OF AUX1 FOR SPECIAL EDITOR READ MO
        LSR   A
        BCS   GETOUT
;...
GETOUT: LDA   #CR      ;PUT CR IN ATACHR
        BNE   K8       ;(UNCONDITIONAL)
;....
K8:     STA   ATACHR
K4:     JMP   RETUR1   ;ALL DONE

Additionally there are some equates which give the purpose of each bit in AUX1 portion of the I/O Control Block of each device. Most of the bits are generic (i.e., the mean the same to all devices), but $1 (bit 0) does seem to have a special meaning:

; AUX1 EQUATES
; () INDICATES WHICH DEVICES USE BIT
APPEND  =     $1          ;OPEN FOR WRITE APPEND (D), OR SCREEN READ (
DIRECT  =     $2          ;OPEN FOR DIRECTORY ACCESS (D)
OPNIN   =     $4          ;OPEN FOR INPUT (ALL DEVICES)
OPNOT   =     $8          ;OPEN FOR OUTPUT (ALL DEVICES)
OPNINO  =     OPNIN+OPNOT ;OPEN FOR INPUT AND OUTPUT (ALL DEVICES)
MXDMOD  =     $10         ;OPEN FOR MIXED MODE (E,S)
INSCLR  =     $20         ;OPEN WITHOUT CLEARING SCREEN (E,S)

The OS defines several devices including the keyboard, cassette, printer and disk each with a corresponding I/O Control Block (or IOCB). You'll notice that the normal value for 842 is 12 which means OPNIN and OPNOT are both set. The device is open for read and write access. When you POKE 13 into 842 the APPEND bit is set. For the cassette or disk that might mean you're adding to the end of a file. For the keyboard device it has the special effect you're wondering about.

Note that POKE 842,4 has no obvious effect - BASIC never tries to write to the keyboard so turning off OPNOT does nothing. But a POKE 842,8 is bad. BASIC will spew an undending stream of ERROR - 131 messages as it tries to read input from the keyboard but is denied because read access has been turned off.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.