6502 machine language + Apple ][+ ROM, 12 (11? 10? 9?) bytes
CE 06 80 F0 01 A2 0B A9 00 4C 24 ED
Should start at $8000
. Crashes to the system monitor when the count reaches 0.
C6 B6 F0 01 A2 0B A9 00 4C 24 ED
Should start at $B1
. This saves a byte since I can use the (two-byte) zero-page version of DEC
, but overwrites the critical Applesoft routine CHRGET
; you'll need to load it and call it from the monitor, and use CTRL+BReturn to re-initialize BASIC once you're done. Not sure if this invalidates it or not.
CE 06 80 F0 01 A2 0B 4C 26 ED
Should start at $8000
. This doesn't initialize $9E
, saving two bytes. However, this means you must not call it with a negative address (or, if you call it from the monitor, you have to call the monitor with a positive address). If you do, Applesoft's CALL
routine will store FF
in $9E
, causing it to add 65280 to the number when printing it. Again, not sure if this invalidates the solution or not.
C6 B6 F0 01 A2 0B 4C 26 ED
Should start at $B1
. This is a combination of the above two programs, saving a total of three bytes; you'll have to call the monitor with a positive address, load it and run it from there, and use Ctrl+BReturn to re-initialize BASIC once you're done.
Note that these programs only modify the program in memory; re-loading the program from disk will reset the countdown. This works because the Apple ][ (and ][+, //e, and //c) have no memory protection system whatsoever; the program (and its self-modifications) will stay in memory even after it exits, so you can keep running it from memory until you overwrite that memory with something else.
Sample run
]BLOAD COUNT THEN BRK
]CALL 32768
10
]CALL 32768
9
]CALL 32768
8
]CALL 32768
7
]CALL 32768
6
]CALL 32768
5
]CALL 32768
4
]CALL 32768
3
]CALL 32768
2
]CALL 32768
1
]CALL 32768
8008- A=80 X=9D Y=00 P=36 S=EE
*
Explanation
DEC NUM+1 ; Decrement the LDX instruction's operand
BEQ NUM+1 ; If it is now zero, branch to it; 00 is the opcode for the BRK instruction, which causes the program to crash to the monitor
NUM LDX #$0B ; Load the X register with 0x0A; the operand has already been decremented once
LDA #$00 ; Load the accumulator with 0
JMP $ED24 ; Jump to $ED24, an Applesoft ROM routine which prints A (high byte),X (low byte) in decimal
Explanation of 10 byte version
DEC NUM+1 ; Decrement the LDX instruction's operand
BEQ NUM+1 ; If it is now zero, branch to it; 00 is the opcode for the BRK instruction, which causes the program to crash to the monitor
NUM LDX #$0B ; Load the X register with 0x0A; the operand has already been decremented once
JMP $ED26 ; Jump to $ED26, which is two bytes into the Applesoft routine at $ED24. The two skipped bytes would store the accumulator in $9E
Variants
Prints ERR
and beeps when count reaches 0
Normal - 15 bytes
CE 06 80 F0 07 A2 0B A9 00 4C 24 ED 4C 2D FF
Overwrites CHRGET
- 14 bytes
C6 B6 F0 07 A2 0B A9 00 4C 24 ED 4C 2D FF
Doesn't initialize $9E
- 13 bytes
CE 06 80 F0 05 A2 0B 4C 26 ED 4C 2D FF
Overwrites CHRGET
and doesn't initialize $9E
- 12 bytes
C6 B6 F0 05 A2 0B 4C 26 ED 4C 2D FF
Freezes when count reaches 0
Normal - 12 bytes
CE 06 80 F0 FE A2 0B A9 00 4C 24 ED
Overwrites CHRGET
- 11 bytes
C6 B6 F0 FE A2 0B A9 00 4C 24 ED
Doesn't initialize $9E
- 10 bytes
CE 06 80 F0 FE A2 0B 4C 26 ED
Overwrites CHRGET
and doesn't initialize $9E
- 9 bytes
C6 B6 F0 FE A2 0B 4C 26 ED