Sunday, 7th March 2010
In an attempt to solve the screen resolution problem issue I've bought a very cheap 320×240 pixel graphical LCD – a PG320240H-P9 on eBay for $24. Part of the reason for its cheapness may be down to its the lack of a controller; you need to constantly refresh the LCD with pixel data yourself (easier to use modules have integrated controllers that refresh the display for you from some on-board RAM). If I manage to get it working I'll have a 128×64 pixel graphical LCD going spare – finding a use for it could make an interesting project.
I have a bit of a soft spot for the CHIP-8 programming language, having previously written an few implementations. The CHIP-8 environment requires just under 3.5KB of RAM, and my recent investment in an ATmega644P boasting 4KB of RAM provided me with a microcontroller that was up to the task.
Beyond the ATmega644P and LCD the hardware is pretty simple; a potentiometer is provided to adjust the speed of the interpreter when it's running, from 1/8th speed up to 8× speed. Sound is output using a piezo transducer, which I've taped to the hard plastic lid from a tube of chocolates to amplify it. Games rely on a 4×4 hex keypad for input, and as I do not have a 4×4 keypad – hex or otherwise – I assembled my own on another breadboard. I don't even have sixteen switches of the same type, hence the mixture in the above photo. A schematic of the hardware can be downloaded in PDF format.
When you reset the circuit a list of all of the programs stored on the microcontroller is shown on the LCD. The 64KB of flash memory on the ATmega644P is enough to store the code for the interpreter and all of the CHIP-8 and SCHIP games available on the Internet. For a change I've decided to have a go at designing a variable width font rather than use one of my existing fixed-width fonts; I don't think it looks too shabby.
When a game has been selected a (gramatically incorrect) summary of the game is shown. To the right of the screen is a 4×4 grid informing the player which key does what; arrows for directional controls, a diamond for "fire" or confirmation actions and a tick/cross for yes/no input. There doesn't seem to be any particular convention for keypad input in CHIP-8/SCHIP games, which makes this feature invaluable!
Wednesday, 24th September 2008
The CHIP-8/SCHIP interpreter now seems happy enough to run games, though the lack of settings to control how fast or slow they run makes things rather interesting.
First of all, I've hacked together a painfully simple read-only file system. Each file is prefixed with a 13-byte header; 8 bytes for the filename (padded with spaces), 3 bytes for the extension (padded with spaces) and two bytes for the file size. The above file listing can be generated by typing *. at the BASIC prompt.
I've written a new sprite drawing routine that scales sprites up to double size when in CHIP-8 mode; this allows CHIP-8 games to fill the entire screen. Unlike the existing sprite code, which I've retained for SCHIP games, it runs entirely from ROM; the existing sprite code has to be copied to RAM as it uses some horrible self-modifying code tricks. I should probably rewrite that bit next.
As for the bug I mentioned in the last post, it was because of this:
; --- snip --- ; Group 9: ; * 9XY0 - Skips the next instruction if VX doesn't equal VY. InstructionGroup.9 call GetRegisterX ld b,a call GetRegisterY cp b jp nz,SkipNextInstruction ; Group A: ; * ANNN - Sets I to the address NNN. InstructionGroup.A call GetLiteralNNN ld (DataPointer),hl jp ExecutedInstruction ; --- snip ---
If an instruction in the form 9XY0 is executed and VX == VY, rather than jumping to ExecutedInstruction the code runs on and executes the instruction as if it had been an ANNN as well, which ended up destroying the data pointer. Adding a jp ExecutedInstruction after the jp nz,SkipNextInstruction fixed the bug.
One other advantage of the zoomed sprites is that "half-pixel" scrolls also work correctly:
...not that I've seen any game that uses them.
The last two screenshots show two versions of the game Blinky, one as a regular CHIP-8 program and the other taking advantages of the SCHIP extensions.
Monday, 22nd September 2008
The only major hardware modification since last time is the addition of another 32KB SRAM.
This appears as two 16KB pages in the $4000..$7FFF slot. Currently only the first page is used for OS variables and scratch space, freeing up the upper 32KB entirely for BBC BASIC's use.
One other minor hardware addition is support for a dual-coloured LED on the control port. This LED will be used to signify file access - reads by a green LED and writes by a red LED. As such I haven't implemented a proper file system, but typing SAVE "FILE" or LOAD "FILE" at the prompt will transfer data between the Z80 RAM and a 24LC256 32KB EEPROM. The routines do not pay attention to any file name specified - the first two bytes on the EEPROM indicate the file size, and the rest of the EEPROM is the file. I think some sort of simplified version of FAT may work well, as the EEPROM has a natural page size of 64 bytes which could be used in place of clusters.
Adding the second 32KB SRAM required soldering wires to the underside of the stripboard, not something I'd recommend!
As I have not yet added any graphical commands to BBC BASIC, and as porting assembly programs to this hardware is going to be a bit of a pain until I decide on the way the OS is going to work, I decided to try and port Vinegar to the system. Vinegar is a CHIP-8 and SCHIP interpreter - CHIP-8 programs being simple bytecode and so relatively simple to interpret.
The code I had written was difficult to port, however, being inefficiently and messily written, so I ended up rewriting all of it apart from the sprite drawing routines. The TI-83+ LCD follows the usual trend of storing 8 horizontal pixels in each byte of video memory. The LCD I have stores 8 vertical pixels in each byte of video memory, which means that each 8×8 pixel block in memory needs to be rotated by 90° before being sent to the LCD hardware. This is understandably very slow, and not helped by the Z80 only running at 2MHz. To further complicate issues, games rely on two 60Hz timers, and I have no timing hardware. The current version of the interpreter has some bugs, but is good enough to run some SCHIP programs.
CHIP-8 programs are displayed squashed in the top-left hand corner, as they're designed to run in a 64×32 video mode unlike SCHIP's 128×64 (happily, the resolution of the LCD) - typically, the one thing I really did need to fix for the new hardware, the sprite code, is the only thing I copied over. In reality, CHIP-8 graphics would need to be scaled up to fit the screen. Working out a way of getting the system to operate at 10MHz would really be a welcome upgrade!
Monday, 27th February 2006
It's not as if I didn't already have an excess of projects, but anyway...
The binaries are here. I've tested them fairly extensively on my TI-83 Plus, but be warned that (as it's beta) they might cause odd crashes. Back up any important files!