[comp.sys.handhelds] Reposting of CHIP48

paul+@andrew.cmu.edu (Paul J. Dujmich) (10/05/90)

Here is the CHIP 48 package as I got it from the bboard a while back.

Paul
----------------------------------------------------------------------------
From: gson@niksula.hut.fi (Andreas Gustafsson)
Subject: CHIP48 - A CHIP-8 interpreter for the HP48SX (version 2.20)
Date: 3 Sep 90 16:16:05 GMT

This is the first release of CHIP-48, a CHIP-8 interpreter for the HP48SX.

For those who don't remember, the CHIP-8 programming language was used
in a number of home computers based on RCA's CDP1802 processor in the
late 1970's.  It's a small, interpreted language designed specifically
for writing simple video games.  It has less than 40 instructions,
including arithmetic, control flow, graphics, and sound.  The
instructions are all 16 bits long and are executed by a very compact
virtual machine interpreter (the 1802 implementation was 512 bytes long).
A simple Pong-style game can usually be written in about 256 bytes of
CHIP-8 and would usually be written directly in hexadecimal.

This posting includes documentation on CHIP-8 (terse but reasonably
complete), CHIP-48 itself, and a sample game.  Write more and post
them to comp.sys.handhelds!

Make sure you have your calculator backed up before you try running
CHIP-48.  The interpreter was written for a HP48SX with the Revision A
ROM.  It appears that it does _not_ work with other ROM revisions.
Hopefully users with newer ROMs will make the necessary changes and
mail them to me.


* Technical specification

The CHIP-8 virtual machine is byte-addressable and has an address
space of 4 kB at addresses 000-FFF hex.  However, addresses 000-1FF
are reserved (this is where the CHIP-8 interpreter used to reside).
Therefore, the CHIP-8 program itself begins at address 200.  All
instructions are 16 bits long and by convention instructions always
start at an even address.

The machine has 16 8-bit general-purpose registers called V0..VF.  The
VF register is modified by certain instructions and works as a carry
flag and sprite collision indicator.  There is also a 16-bit pointer
register I (though only the low 12 bits are generally used).

A CHIP-8 program displays graphics by drawing sprites that are 8
pixels wide and 1..15 pixels high.  The screen resolution is 32 by 64
pixels.  The origin is the upper left corner of the screen, and all
coordinates are positive.  The sprites are stored in big-endian
format, i.e., the most significant bit corresponds to the leftmost
pixel.  All drawing is done in XOR mode.  If this causes one or
more pixels to be erased, VF is set to 01, otherwise 00.

There are two timers: the delay timer and the sound timer.  Both
timers count down about 60 times per second when nonzero; the speaker
will beep whenever the sound timer is nonzero.

In the instruction table below, NNN is a 12-bit address, KK is an
8-bit constant, and X and Y are 4-bit register numbers.  Hex
characters represent themselves.  The two first characters of the
instruction code form the lower-address byte of the instruction, the
first character being the more significant nibble.

0NNN    Call 1802 machine code subroutine at NNN
00E0    Clear display
00EE    Return from subroutine
1NNN    Jump to NNN
2NNN    Call subroutine at NNN
3XKK    Skip next instruction if VX == KK
4XKK    Skip next instruction if VX != KK
5XY0    Skip next instruction if VX == VY
6XKK    VX := KK
7XKK    VX := VX + KK
8XY0    VX := VY, VF may change
8XY1    VX := VX or VY, VF may change
8XY2    VX := VX and VY, VF may change
8XY3    VX := VX xor VY, VF may change *
8XY4    VX := VX + VY, VF := carry
8XY5    VX := VX - VY, VF := not borrow
8XY6    VX := VX shr 1, VF := carry
8XY7    VX := VY - VX, VF := not borrow *
8XYE    VX := VX shl 1, VF := carry
9XY0    Skip next instruction if VX != VY
ANNN    I := NNN
BNNN    Jump to NNN+V0
CXKK    VX := pseudorandom_number and KK
DXYN    Show N-byte sprite from M(I) at coords (VX,VY), VF := collision
EX9E    Skip next instruction if key VX pressed
EXA1    Skip next instruction if key VX not pressed
FX07    VX := delay_timer
FX0A    wait for keypress, store hex value of key in VX
FX15    delay_timer := VX
FX18    sound_timer := VX
FX1E    I := I + VX
FX29    Point I to 5-byte font sprite for hex character VX
FX33    Store BCD representation of VX in M(I)..M(I+2)
FX55    Store V0..VX in memory starting at M(I)
FX65    Read V0..VX from memory starting at M(I)

The instructions marked with * may have been undocumented (but
functional) in the original CHIP-8 interpreter for the 1802.


* Notes on the HP48SX implementation

CHIP-8 programs are stored in the HP48SX as string objects containing
the bytes of the program in increasing address order, beginning with
the byte at 0200.  The interpreter itself is a machine code object
that should be run with the CHIP-8 program string on level 1.  4 kB of
free memory is needed.  If an error is detected during execution, the
address of the current CHIP-8 instruction is returned as a binary
integer on level 1.

The clock display should be turned off.  Otherwise, CHIP48 will not run
but will clear flag -40 so that the next attempt to run it may succeed.

To quit, press the backspace key.  Pressing ENTER restarts the CHIP-8
program, and the +/- key turns the sound off or on.

The 0NNN instruction is unimplemented (of course), except for
NNN==0E0 or 0EE.  Subroutine nesting is limited to 16 levels.

Most chip-8 programs are written for a 16-key hex keyboard with
following layout:

  1 2 3 C                                               7 8 9 /
  4 5 6 D    This keyboard is emulated on the HP48SX    4 5 6 *
  7 8 9 E    using the following keys:                  1 2 3 -
  A 0 B F                                               0 . _ +
This may cause some confusion with programs requiring numerical input.
The keys 2, 4, 6, and 8 are commonly used to represent directions.
The F key (+ on the HP48SX) is sometimes used as a Fire button.


* The interpreter

Below is a HP48SX machine code object that should be uudecoded and
then downloaded to the calculator using Kermit.

begin 644 chip
M2%!(4#0X+4',+7#J /B_BH&_>09#S@870U$""&CS@( T40!F$D@Z!  "^'U;
M$&,8^J#ZH!_ZHC\8^B%#  3 $D-!%U-!,\2B JBF$4=!@X&/- 3  ;AB8#D1
M1W<4^-)G$$=^^)MG@*$?&D,82T.5#, 24P@H 17U\!('41QAP9S&ZPCX+1CZ
M@", @J$/B[$T1-0 +#'4$D07,RTC.!%#0=8:9*B&CX!"@ \ _H*A#W&Y4!H(
M>-2)+WT&01)&",@(^/A7#8"A']N*@0^!H0]SDQ%3+7$0=1 ,;&P82ZQ#/PS
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
M.M [(#U@.F!+($R034!04%E08@                       !  !
I

end


* Sample game

Not particularly exciting, but I had to include something to show how
the interpreter is used.  Uuencode, download to HP48SX using Kermit,
and run with BRIX CHIP.  Play by pressing the keys 4 and 6.

begin 644 brix
M2%!(4#0X+4$L*E C &X%90!K!FH HPS:L7H$.D 2"'L".Q(2!FP@;1^C$-S1
M(O9@ &$ HQ+0$7 (HP[0$6! \!7P!S  $C3&#V<>: %I_Z,.UG&C$-S18 3@
MH7S^8 ;@H7P"8#^, MS1HP[6<8:$AY1@/X8"81^'$D<?$JQ& &@!1C]H_T<
M:0'6<3\!$JI''Q*J8 6 =3\ $JI@ ? 8@&!A_( 2HPS0<6#^B0,B]G4!(O9%
M8!+>$D9I_X!@@,4_ 1+*80* %3\!$N" %3\!$NZ %3\!$NA@(/ 8HPY^_X#@
M@ 1A - 1/@ 2,!+>>/](_FC_$NYX 4@": %@!/ 8:?\2<*,4]3/R9?$I8S=D
7 --%<P7R*=-% .[@ (  _ "J       "

end


* Source code availability

The source code for the interpreter is over 30 k of assembler, and to
assemble it you need my ASAP assembler which is about 25 k.  To run
the assembler, you need Perl 3.0 which is several hundred k.
Therefore, I am not posting all these to comp.sys.handhelds.  However,
the source to CHIP48 and ASAP are available by anonymous FTP from
vega.hut.fi, directory /pub/misc/hp48sx/asap.  The source to Perl 3.0
is available from numerous Unix archive sites.

Those who want to write their own machine code games may want to look
at the interpreter source for hints.  Please note that I have no
insider technical information on the HP48SX; CHIP-8 is based solely on
information posted to comp.sys.handhelds (in particular, Alonzo
Gariepy's excellent HP28S Processor Notes) and personal HP48SX machine
code hacking.


* Fine print

      CHIP-48 and BRIX are (C) Copyright 1990 Andreas Gustafsson

      Noncommercial distribution allowed, provided that this
      copyright message is preserved, and any modified versions
      are clearly marked as such.

      CHIP-48 and BRIX make use of undocumented low-level features of
      the HP48SX calculator, and may or may not cause loss of data,
      excessive battery drainage, and/or damage to the calculator
      hardware.  The Author takes no responsibility whatsoever for
      any damage caused by the use of this program.

      THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
      IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
      WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
      PURPOSE.

--
Andreas Gustafsson
Internet: gson@niksula.hut.fi
Voice: +358 0 563 5592