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

332 lines
8.3 KiB
Plaintext

{-----------------------------------------------------------------------+
| 2019-06-16 (marcelk) This is the revived version of the first demo |
| for the Gigatron and early GCL, as shown at the |
| Hack42 presentation. Only updated so that it |
| builds again. Original from November 30, 2017. |
+-----------------------------------------------------------------------}
gcl0x
{
Gigatron RAM map
----------------
+------------------------------------+---------------------+
page 0 | System and program variables <-|-> vCPU stack at top |
+------------------------------------+--+------------------+
page 1 | Video frame indirection table | Channel 1 at top |
+---------------------------------------+------------------+
page 2 | Shift table for sound | Channel 2 at top |
+---------------------------------------+------------------+
page 3 | vCPU code 248| Channel 3 at top |
| +------------------+
page 4 | | Channel 4 at top |
| +------------------+
page 5-7 |0 159 160 255|
+---------------------------+------------------------------+
page 8-127 | 120 lines of 160 pixels | Extra video/code/data at top |
+---------------------------+------------------------------+
page 128-255 | Not used in the 32K system: mirror of page 0-127 |
+----------------------------------------------------------+
}
{-----------------------------------------------------------------------+
| RAM page 3 |
+-----------------------------------------------------------------------}
$0300:
{-
First setup all subroutine definitions and variables, without making
calls. This way allows use of vLR to hop from page to page during setup,
with minimal overhead. At the end, run the main loop.
-}
[def
{-
DrawChar(Char)
Draw a 5x8 character on screen with the built-in font.
`Char' must be in the 32-127 range (this is not checked)
-}
{Map ASCII code to offset in font table}
Char 82- [if<0 50+ i= \font32up
else i= \font82up] fontData= {Select low or high page}
i i+ tmp= tmp+ i+ {Multiply by 5}
fontData+ fontData= {Add to page address to reach bitmap data for Char}
$800 Pos+ q= {Where to stop the inner drawing loop}
{Draw 6 vertical slices: 5 using font data, the last with all-zeros}
5 i= [do
[if<>0 fontData 0? fontData<++ else 0] bits=
Pos p=
{Draw vertical slice}
[do
bits 128& [if=0 0 {Black} else Color] p.
bits bits+ bits=
p>++
p q- if<0loop]
Pos<++
i 1- i= if>=0loop]
ret
] DrawChar=
[def
{-
DrawText(Text,Pos)
Draw a zero-terminated text string to the screen.
Character 10 acts as newline.
There is no check for running off screen.
-}
push
[do
Text, Char= {Next character to be printed}
if<>0 {Zero termination}
Text<++ {Advance text pointer}
Char 10^ [if=0 Pos<. $800 Pos+ Pos=
else DrawChar!]
loop]
pop ret
] DrawText=
[def
{-
Startup message
-}
{XXX move this to a ROM table}
{XXX display the counted memory}
{XXX Make ROM version readable by applications}
{XXX display number of free bytes}
{ *** Gigatron 32K *** }
$20# $20# $20# $2a# $2a# $2a# $20# $47# $69# $67# $61# $74# $72# $6f# $6e#
$20# $33# $32# $4b# $20# $2a# $2a# $2a# 10#
{TTL color computer ROM v0 }
$54# $54# $4c# $20# $63# $6f# $6c# $6f# $72# $20# $63# $6f# $6d# $70# $75#
$74# $65# $72# $20# $52# $4f# $4d# $20# $76# $30# $20# $20# 10# 0#
] Welcome=
{-----------------------------------------------------------------------+
|}\vLR>++ ret{ RAM page 4 |
+-----------------------------------------------------------------------}
$0400:
[def
{-
ClearScreen(Pos)
Clear screen from current position to bottom right
-}
Pos p=
Pos 255| 255- {XXX Is there a better way to clear the low byte?}
i= $8001 i+ i=
0 \sysArgs0. \sysArgs1. {Black}
[do
p [do
\sysArgs4: \SYS_VDrawBits_134 134!! {Clears 8 pixels vertically}
$800 p+ p= if>0loop]
i+ p=
255& 160^ if<>0loop]
ret
] ClearScreen=
[def
{-
RunPart1
-}
{Get X from scanline table}
ShiftControl, X=
{Enable gravity after a while}
120^ [if=0 10 BallA=]
{Random height adjustment}
Height 88- [if>0 \entropy, 16& if<>0 Height 1- Height=]
Height 118- [if<0 \entropy, 128& if<>0 Height<++]
{J=($08+H)<<8}
Height $08+ J>.
{X drawing position is 1 pixel outside the visible area}
X 160+ 255& p=
{Clear vertical line}
$1000 p+ V=
[do 1 V.
V>++
V if>0loop]
{Star}
\entropy, 127& A= A 111- [if>0 119 A=]
A 16+ A>. p A<.
2 {Red} A.
{Draw vertical line to bottom of screen}
J p+ V=
63 V. {First pixel white}
V>++
X 8& Height+ C= {Begin of checkerboard}
[do [C 1+ C= 8& if=0 42 else 32] V. {Checkerboard colors}
V>++
V if>0loop]
{Wait for vertical blank to start}
[do \videoY, 1& if=0loop]
{Scroll screen 1 pixel}
X 1+ ShiftControl.
RunPart2!
] RunPart1=
{-----------------------------------------------------------------------+
|}\vLR>++ ret{ RAM page 5 |
+-----------------------------------------------------------------------}
$0500:
[def
{-
DrawImage -- Draw full-screen image on screen (~1.5 seconds)
-}
Image p= {Addres in ROM for image data}
$0800 q= {Pos points in video memory}
[do
{Draw slice}
[do
p \sysArgs6: \SYS_Read3_40 40!! {Read 3 bytes from ROM}
\SYS_Unpack_56 56!! {Unpack to 4 bytes}
q \sysArgs4: \SYS_Draw4_30 30!! {Write 4 bytes to screen}
$80 p+ p=
q>++ q
if>0loop]
{Advance to next slice}
$c403 p+ p=
$8804 q+ q=
255& 160^ if<>0loop]
ret
] DrawImage=
[def
{-
RandomTest -- Entropy tester
-}
$0121 ShiftControl=
[do
\SYS_Random_34 34!! p=
[if<0 $8000 p+ p=]
{If on-screen, increase pixel color}
$800 p+ p= [if>0 p, 1+ p!]
{Scrolling}
\frameCount, ShiftControl.
loop]
] RandomTest=
[def
{-
RunPart2
-}
{Clear ball}
OldPixel Ball.
{Update ball position and velocity}
BallA BallV+ BallV= {Update velocity with gravity}
BallY BallV+ BallY= {Update height with velocity}
{Check new ball position}
X 50+ Ball=
BallY>, Ball>.
Ball, OldPixel=
{Reverse if we're hitting something}
OldPixel 2- [if>0
0 BallV- BallV=
BallY BallV+ BallY=
10 \soundTimer. {1/6th second of sound}
X 50+ Ball=
BallY>, Ball>.
Ball, OldPixel=
]
{Draw the ball}
63 {White} Ball.
RunPart1!
] RunPart2=
{-----------------------------------------------------------------------+
|}\vLR>++ ret{ RAM page 6 |
+-----------------------------------------------------------------------}
$0600:
{--- Setup ---}
[def
{-
Wait -- Wait Delay number of frames (range 1..255)
-}
\frameCount, Delay+ 255& tmp=
[do \frameCount, tmp- if<>0loop]
ret
] Wait=
{Opening sound for 2 seconds}
120 \soundTimer.
{ 2019-06-16 (marcelk) Removed because images are not part of ROM interface
{Draw images}
$800 Pos=
\packedBaboon Image= DrawImage call
60 Delay= Wait call
\packedParrot Image= DrawImage call
Wait call
\packedJupiter Image= DrawImage call
Wait call
}
{Display welcome text}
8 {Green2} Color=
$800 Pos=
Welcome Text=
DrawText!
Wait!
{Wait for sound to stop}
[do \soundTimer, if<>0loop]
{Flash welcome text in several colors}
62 Color= {Pen color}
[do
$800 Pos= {Pen position at top of screen}
Welcome Text=
DrawText!
Color 8^ if<>0 Color 9- Color= loop]
{Wait 2.5 seconds}
150 Delay= Wait!
{ClearScreen}
ClearScreen!
{X shift starting from line 8}
$0111 ShiftControl=
{Ball acceleration BallA, height Y and velocity BallV}
0 J=
BallA= BallV= OldPixel=
$1800 BallY= Ball=
90 Height=
{--- Run ---}
RunPart1!
RandomTest!
{-----------------------------------------------------------------------+
| End |
+-----------------------------------------------------------------------}