Item: 713 by gson at niksula.hut.fi Author: [Andreas Gustafsson] Subj: CHIP48 - A CHIP-8 interpreter for the HP48SX (version 2.20) Date: Mon Sep 10 1990 08:16 This is the first release of CHIP-48, a CHIP-8 interpreter for the HP48SX. [NB: Version 2.25, called "CHIP", plus DOC file, are on disk. -jkh-] 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 M$D,M43X82ZP86QCXLF 8*V1@>1^Q 8A_4P;XFV=@;X^*%E$/40QA$ ?,IOX0 MAQ5!GJ8K81%ED* ?81#E@A"[CH B P^$L72,H(3,11DK4&&:O@(* 3X . O M&/H1J&9@?] R >@Z!/@ X&\8^A#'#$&>I@AJ'L1A$>1IBJ#F07S', (!"($/ M%@&M+0@1Y1.%\PS^AH!' AX (" -P<# 7-[$&7PCH " ?X216#BWR(2=2 0 M%T$?'!!L&/HA+! M40=L&$NL0^L*P!)#$"T#8.3?,O"V_2T3$!;]+1,1=OPM M$Q+6^RT3%#;[9_HM00X6)X?Y#4$*%RP0<7*%'RPM41Y@9_<-41IP[1!O;P@H M$0!N G9Z#Q?$,&P82ZQ#WPG $D,M40X(@0\6 :TM"!$&40[@+Q Q%D-@9_(8 M^H%'[S$%UPIQTM[:,@&.*@T3[JA"!(*Q-&1\ *P30%TQ$&0QI"]1=&$?11?V M08R!#Z36:7T-@[$TI)L +#$4)*@(@(&/$P08^$(L,=02Y8.A#PMS/(ZA#PN# ML31$EP L,10D&/A"+#&&H1\3A1-C08*!#S,$! "X!A $!ONGX'$1M$&>9A08 M^K(8^!(8^K(P1]YQ$;1!GB;NEOU'XL;\Q^&F_N?;<1&T00ASKQT701OD:A+$ M,'$1M1 < Y!@"\??00@S$ D&<>L-;AK% 3,@"09QU0UN$L4!,S )UG&_K8[@ MEN FZPYN%<0P Y1@$,?9+%$<=ML#E6 59]CKS.(6Q6&8!"GTVQ1'%;5(%?)&/J ,*?*5\@-0T=)^@]@$R!K407JH2Y1#VN)T(# +ZXH L%Q 7.[@D[!KR[B"5JP9D$L M '/7VQ+D!\CJHWAQ$;3!,>&9)@T3H6GB **^ZF#)K;[J8)D=8V ]O!, 28T&&H0\81D&&H0\91D&& MH0\:1D&&H0\;1A#" R @G. $3 )M3$PL&$NL0\D!P(*A#]F+D2\8^8*1+VQL M&/J@$P?@-GP82T,\ ,#"BZ$/BZ$?&$-1'AWJ%6,8^!(8^H 8^K$8.UQ<7%Q< M7%Q<&$M#'P' VJ*8;"PQ%.3JMS_[\]6BF&PL,13DZK<_^_/5HIAL+#$4Y.JW M/_OSU:*8;"PQ%.3JAZ$?$0-!)IS@"!CX0!CX0 (8^A 8^B$L,30!LB8(*(&0 M;@7JIN8(#5$6F@H>EZ$/"-_B X'PK?G@H9L/'H?P+9S@&PC?411A'_9A$45A M"X#P'44AH.1):F"G#@$ # //P,S#/S \,__P_///EW">"0><<.()1Z!P)@J' MI'!J"L>H<*X*!ZUP\@I'L7 V"X>U<'H+Q[EPO@L'OG "#$?"<$8,A\9PB@S' MRG#.# ?/%<'H(QXEPO@@' MCG ""4>2<$8)]YGY8B+W\?@?'Y_Y$8\?__CY'T+T^?F?'__YF9Z>_HCXGIG^ M^/B/CQ@ D "& !,D &*!&$B(1"2$0B*"02&()!(1&1)_ PL#$@-H XX#G@ 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$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 --%