gigatron/rom/Apps/Smallest/Smallest.gcl
2025-01-28 19:17:01 +03:00

106 lines
4.6 KiB
Plaintext

{
The smallest vCPU application
-----------------------------
1. Gives identifiable visual feedback:
- Draws two colored lines (one vertical, one horizontal)
- Continuously blinks a pixel
2. Is interactive:
- Shifts the screen when a button is pressed, restores when released
- Changes line color when this button is an arrow button
3. Behaves consistent and doesn't crash:
- Is compatible with all ROM versions, past, present and future
- Doesn't rely on undocumented features
- Doesn't accidentally clobber system variables (*)
4. Is as small as possible
- Occupies 6 bytes of RAM (3 vCPU instructions)
- Loads at a non-intrusive memory location
| * file: Apps/Smallest.gt1
|
| 0207 21 0e LDW frameCount |!.|
| 0209 f3 17 DOKE vPC+1 |..|
| 020b 90 05 BRA $0207 |..|
| * 6 bytes
|
| * start at $0207
Application
-----------
When a program uses features that are only available from a certain
ROM version, it should check the romType variable before using these.
At least it shouldn't crash, and preferably it gives the user some
feedback, no matter how simple. See the discussion on GT1 file
compatibility in Docs/GT1-files.txt, which suggests blinking a pixel.
This tiny loop can be used for this signaling function. The program
enters it when it encounters an insufficient romType value.
It can be placed directly after the romType check if that's the
first thing the program does when starting at location $0200.
A check and branch takes 7 bytes, this loop adds 6 for a total of 13.
For it to be this small:
- Each instruction does multiple things
- All bytes in vPC and vAC are significant
- The page is fixed (2) and exactly right for the purpose
Annotated source code
---------------------
}
gcl0x { GCL version }
*=$0207 { Only works well on page 2 }
[do
_frameCount { Read zero page [$0d] (frame counter) in vACL, and
zero page [$0e] in vACH (serial input port) }
_vPCH: { Write vAC as word to address (vACL<<8) + vPCH }
{ A vertical line of two pixels wide is formed
at a rate of 1 scanline per video frame.
The first pixel color depends on vertical position.
The second pixel comes from the input port,
and defaults to 255, or white. }
{ A horizontal line is displayed when vACL is 1:
[$0102] is set to 1, causing the video indirection
table page to become visible as the second scanline.
This shows as a regular row of colored pixels. }
{ [$0103] is set to 255 (typically), causing the
screen to shift right 1 pixel. The memory locations
at page offset 0xff become visible, showing as
another vertical line of random colors on the left. }
{ Because of the pixel shift, on the second scanline
memory location [$01ff] of the channel 1 oscillator
shows itself as a blinking pixel. }
{ When buttons are pressed, the white line changes.
Only the arrow buttons affect the lower bits and
give a color change. Once every 2 seconds, the
horizontal shift position changes as well. }
{ When vACL is 0, the zero page variables 'channel'
and 'sample' are clobbered. These are temporaries
for sound generation. There is no lasting effect. }
{ (*) There is still some clobbering, bacause the
soundTable is touched each time vACL becomes 7.
[$702] affects sample pulse[0] which isn't audible.
More worrisome is the changing of [$703], or
sawtooth[0] because SYS_Unpack_56 uses those values
for shifting right. This affects the Pictures
application and Racer (but it doesn't cause them
to crash). The soundTable is initialized during
cold reboot, but not again at soft reset on ROM
versions before ROM v4. }
loop] { Loop forever }