Example: Microwave clock

This is the full program listing for the microwave clock demo program. Click on the code below to convert it into a text editor with a built-in assembler, and then click RUN at the bottom to run the program. You can edit the code and rerun to see the effect of each change.

( Program metadata lives at the start of the program. )
JMPr*:0018 'BEDROCK'
  metadata/name
  metadata/authors
  metadata/descrip
  metadata/bg
  metadata/fg
  0000
  0000

( Assign names to common jump instructions. )
%CALL: JMS:;   %GOTO: JMP:;   %RETURN JMPr;
( Assign names to system device ports.      )
%SYSTEM.SLEEP   00;
( Assign names to math device ports.        )
%MATH.X         20;   %MATH.XL        21;
%MATH.Y         22;
%MATH.QUOTL     2D;   %MATH.MODL      2F;
( Assign names to clock device ports.       )
%CLOCK.HOUR     33;   %CLOCK.MINUTE   34;
%CLOCK.SECOND   35;   %CLOCK.TIMER1   38;
( Assign names to each of the screen ports. )
%SCREEN.X       50;   %SCREEN.Y       52;
%SCREEN.WIDTH   54;   %SCREEN.HEIGHT  56;
%SCREEN.PALETTE 58;   %SCREEN.SELECT  5A;
%SCREEN.SPRITE  5C;
%SCREEN.DRAW    5E;   %SCREEN.MOVE    5F;
( Quick macros for drawing to the screen.   )
%MOVE!  STD:SCREEN.MOVE ;
%DRAW!  STD:SCREEN.DRAW ;
%DRAW!* STD*:SCREEN.DRAW;

( Load the segment sprite into the sprite buffer. )
*:7FFF STD*:SCREEN.SPRITE
*:7F3F STD*:SCREEN.SPRITE
*:0000 STD*:SCREEN.SPRITE
*:0000 STD*:SCREEN.SPRITE
( Load three colours into the colour palette. )
*:0000 STD*:SCREEN.PALETTE
*:12F7 STD*:SCREEN.PALETTE
*:2010 STD*:SCREEN.PALETTE
( Set the screen width and height. )
*:0068 STD*:SCREEN.WIDTH
*:0024 STD*:SCREEN.HEIGHT
( Load a denominator into the math device. )
*:000A STD*:MATH.Y

( Redraw the clock to the screen every minute. )
@main
  ( Calculate a position for the top-left corner of the clock
    so that the clock is drawn at the center of the screen. )
  LDD*:SCREEN.WIDTH  SHR*:01 SUB*:0032 STD*:SCREEN.X
  LDD*:SCREEN.HEIGHT SHR*:01 SUB*:0010 STD*:SCREEN.Y
  ( Erase the background layer. )
  :20 DRAW!
  ( Draw the hour and minute digits. )
  LDD:CLOCK.HOUR CALL:draw-digit-pair :09 MOVE!
  LDD:CLOCK.MINUTE CALL:draw-digit-pair
  ( Draw the two dots between the hour and minute. )
  *:[B4 4A] CALL:draw-dot
  *:[47 83] CALL:draw-dot
  ( Set a timer to expire at the start of the next minute. )
  :3C LDD:CLOCK.SECOND SUB :00 STD*:CLOCK.TIMER1
  ( Sleep until a clock or screen event. )
  *:1400 STD*:SYSTEM.SLEEP GOTO:main

( Draw a pair of digits. `val` can range from decimal 0 to 99. )
@draw-digit-pair  ( val -- )
  STD:MATH.XL
  LDD:MATH.QUOTL CALL:draw-digit
  LDD:MATH.MODL  GOTO:draw-digit

( Move twice and then draw a square dot. )
@draw-dot  ( move move -- )
  MOVE! MOVE! *:[03 02] DRAW!* :42 MOVE! :61 DRAW! RETURN

( Draw a single digit to the screen. `digit` can range from 0 to 9. )
@draw-digit  ( digit -- )
  SWP:00 ADD*:digit-map LDA
  ( Segment 1 )
    CALL:~load-colour
    :05 MOVE! *:[18 07] DRAW!* *:[19 89] DRAW!*
  ( Segment 2 )
    CALL:~load-colour
    :42 MOVE! *:[1C 81] DRAW!* :46 MOVE! *:[1D c6] DRAW!*
  ( Segment 3 )
    CALL:~load-colour
    :0C MOVE! *:[1E 81] DRAW!* :46 MOVE! *:[1F 89] DRAW!*
  ( Segment 4 )
    CALL:~load-colour
    :42 MOVE! *:[1A 06] DRAW!* :44 MOVE! *:[19 89] DRAW!*
  ( Segment 5 )
    CALL:~load-colour
    :42 MOVE! *:[1C 81] DRAW!* :46 MOVE! *:[1D c6] DRAW!*
  ( Segment 6 )
    CALL:~load-colour
    :0C MOVE! *:[1E 81] DRAW!* :46 MOVE! *:[1F 89] DRAW!*
  ( Segment 7 )
    CALL:~load-colour
    :42 MOVE! *:[1A 07] DRAW!* *:[1B 0e] DRAW!* :D8 MOVE!
  POP RETURN
  &load-colour  ( map -- map )
    SHR:01 DUP AND:01 INC STD:SCREEN.SELECT RETURN

( Maps a value in the range 0..9 to a segment map. Each bit maps to a
  segment of the digit, with a segment being on if the bit is 0. )
@digit-map
  ( 0 ) 10 ( 00010000 )
  ( 1 ) B6 ( 10110110 )
  ( 2 ) 44 ( 01000100 )
  ( 3 ) 24 ( 00100100 )
  ( 4 ) A2 ( 10100010 )
  ( 5 ) 28 ( 00101000 )
  ( 6 ) 08 ( 00001000 )
  ( 7 ) B4 ( 10110100 )
  ( 8 ) 00 ( 00000000 )
  ( 9 ) 20 ( 00100000 )

( Program metadata values. )
@metadata
  &name     "Microwave clock"
  &authors  "Ben Bridle"
  &descrip  "Minimal digital clock."
  &bg       0000
  &fg       02F7