Deathshadow's Madness
Madness and you, perfect together

12 November 2012 · Revision 0.9 RC 1

Here it is, the first public release... the initial candidate to be called version 1.

Code cleaned up, distributions built

Went through and made three distribution files -- a flat PRG file, a D64 image with the PRG file on it.

Tested on actual hardware

While some testing was done with my real C64, most of the testing was done in VICE for expediency sake. I put a good three hours into playing it on the '64 which let me find and squash a few more minor bugs and glitches.

Eaten ghosts smoother animation

On the DOS version to make the ghosts move slower I just updated thier positions half as often. This looked good at the 160x100 CGA graphics, but on the 64 felt a little ... I dunno... jerky. Since they're sprites and can be moved the full 320x200, I just move them 1 pixel instead of the normal gameplay's two. This required a little bit of 'cleanup' when they exit 'slow' mode.

8 November 2012 · Revision 0.6 Beta

Opening theme and better sound FX

Finally got the theme playback working. The code could be prettier but everything I've tried to optimize it has actually resulted in larger code. It's 'good enough', I can live with that. Tweaked most of the sounds to what sounded good to my ears, though my inexperience with the SID is probably showing. Sounds far better IMHO than the Atarisoft one, and that's really my only goal.

AI Bugs squashed

The bugs in the ghosts chase and flee logic turned out to be as simple as some typecasting issues. CC65 wasn't doing some subtractions or ABS on certain values correctly, just forcing (int) on a few of them cleared that right up. There were also a few places where I had typed = instead of ==, a common mistake when going back and forth between Pascal and C.

Better/tighter random numbers

Rather than use the library random number generator, I've gone ahead and tossed in a somewhat simpler one. The PC version used a random 0..9, I've gone with 0..15 here so I can use an 'and' instead of a modulo to get that random value from the updating seed. Unlike the original pac-man I throw a bit of randomness into the behaviors so it's not always predictable -- an example would be the four points where in the real game the ghosts cannot turn upwards. I've got a 1 in 8 chance in this version for that to be ignored. Strict pursuit/flee logic is predictable, and that can reduce replay value.

4 November 2012 · Revision 0.5 Beta

Functionality Complete

It has sound, the ghosts chase you around, it has scorekeeping. All that remains is debugging the game logic, making a few enhancements over the PC version, and doing a few of the fancier bits like flashing the map at end of level and the intro theme. For those of you unaware, that's what BETA is supposed to mean -- functionality complete, just waiting on the gee ain't it neat fit and trim and a proper debugging/testing.

Score Math and Blitting Fixed

Binary Coded Decimal really was the answer, letting me get my needed 8 digits in the same 4 bytes as a long, but with far, FAR faster math for adding to the score and even faster conversion to indexes to the font bitmaps. I made a special copy of just the numbers for the gameplay scorekeeping that has no shifts -- so it MUST land on a byte-wide boundary restricting them to 4px wide. I padded them out to 16 bytes apiece (even though only 10 is used) and made a special optimized machine language routine for them. This resulted in a factor of six speed improvement clearing out any and all 'stuttering' that was happening as pellets were eaten.

CC65 Optimizer WORKING!

While I'm no longer able to do a 'soft reset' on exit, and have to do a 'hard reset' instead, using the -Oi command line option I was able to get a stable running 'optimized' version of the program running. This took it from 18k to 12k, making room for the theme code and other enhancements. Net result is a base executable of around 16k total size before my re-linker gets hold of it, and a 44k PRG file after all the data is plugged into place and the origin moved.

1 November 2012 · Revision 0.4 Alpha

Menu and Gameplay functional

It now runs as a playable game. It still lacks sound so I'm not willing to call it a BETA yet... Memory use is through the roof though... I'm at 21k used out of the 23k available for code space so I'm going to HAVE to go back and redo some stuff in assembly NOT becuase I need it faster, but becuase I need it slower. Some mundane stuff like setting up the menu colors and so forth could also have their static values moved into that bottom data area where I've got around 7k still free. I also need to look at CC65's optimizer. So far attempts to use it have resulted in unstable crashes -- need to research the command line flags more.

Score Math and Blitting too slow!

On the slower levels it's not as noticeable, just some oddball 'frame stuttering' -- but at faster levels it's disastrously bad. At first I thought I was just plain out of CPU once the game logic was in place, but I've isolated it to the math of adding the score and the time it takes to draw it on the screen. The solution to both is probably for me to switch to BCD instead of trying to use a 32 bit long -- but that means I have to learn how to do BCD math on the 6502. I was aware it was going to suck at doing 32 bit math, particularly from C -- I just wasn't aware how badly it sucked.

Project slightly delayed due to storm, best holiday in the world, and also having a life. I know, really, how dare I?

29 October 2012 · Revision 0.31 Alpha


I'm reserving 8 bytes in that bottom segment above the BASIC 'loader' space as a keymap that I will frequently poll to populate, skipping the normal keyboard handler. I need a MAP, not buffered input. I've found that I can avoid having joystick inputs mapped to the keyboard by actually reading for when it is a real joystick input, then using that to mask off keys. As such if you press a key that's on the same row as a joystick input while the joystick is pressed, that key is ignored. This seems to work far better than most of the methods I've come across for handling the rather unusual way they joystick and keyboard overlap each-other on the CIA chips.

Ghost and Player movement and logic

The first bit of code to bear any resemblence to it's DOS counterpart. Porting this to flat C proved interesting as the original is OOP code. Not too big a challenge though the ghost behaviors seem buggy as all hell. I've stored the ghosts positions and variable data alongside their static info in the bottom 16k page, keeping more of the code memory free. Pointing at them with a STRUCT allows me some degree of replicating the object type behavior.

26 October 2012 · Revision 0.3 Alpha


After asking around a few forums, digging through various online guides and PDF copies of old documentation, I struggled for a couple days with just how to go about matching the 120hz timing of the DOS version. Originally I thought I'd have to map out the system ISR's completely, when it turns out I had plenty of processing time to simply double the default ISR rate to 120hz, and then pass off to the system timer on every other tick.

Switched playfield encoding

The 8k it would take for a copy of the entire 'playfield' display is proving impractical, and using the tile-map to try and blit 3x3 in realtime with shifts as the PC version does is just too slow on this hardware. I finally settled on RLE encoding it -- length, value, repeat ad nasueum. With so much of the same values being sent to the screen back to back this encoding resulted in taking the 8k playfield and blank space (letting me skip having a blanking routine) and dropped it to a mere 1.85k. A little over a 4:1 reduction that had a interesting side effect -- becuase it spends less time reading from memory what to write to video RAM, it actually writes to the screen in about a third the time of a flat copy!

Note 2017, next PC version is abandoning the 3x3 playfield blitting as well.

23 October 2012 · Revision 0.2 Alpha

Improved graphics and layered sprites

Just went back and redid the graphics to better use the incresed vertical resolution. The PC version's graphics are a bit clunky, and on the 64 I've got far more to work with, so lets actually use it.

Faster/smaller assembler blit routines

I was using CC65's version of the classic C memory operations, but given that I rarely need to move more than 128 bytes and never with an overlap, I don't need most of the extra overhead of those routines. Also I require a fast OR, AND and SET routines, so let's get it together and belt those out.

19 October 2012 · Revision 0.13 Alpha

Memory Management

Created the Pascal code to make the memory configuration files, and automatically link in resources into free spots in the bottom 16k page. Determined I'd have a few static values stored just above the BASIC 'loader' so I don't have to pass as much in the zero page when working with ASM.

C Stack moved

CC65 is a bit twitchy about moving around the bits of RAM it wants to use, but I was able to re-allocate the stack location down into 0x0400..0x07FF, freeing more of that dwindling top 24k for code, vars and heap.

17 October 2012 · Revision 0.12 Alpha

Sprite Animations

Got all the sprite tiles drawn, converted and loaded into memory to be animated, tested animations.

Fonts and Font Engine

Made a glyph blitter and added kerning code, in addition to creating the font. Variable character widths were a must have given the low resolution available.

16 October 2012 · Revision 0.1 Alpha

Preliminary Build to test graphics

Got it to display the playfield and show the sprites

Play Now in Your Browser!

  • MS-DOS
    Chrome or Firefox Recommended!. Other browsers may try to run this, but it uses some advanced modern JavaScript to function properly.
  • Commodore 64
    This requires Oracle Java to work properly, which not all browsers will even let you DO in the browser anymore! Laughably, this is the one you're better off trying in IE or Safari.



W, A, S, D - or - I, J, K, M

Joystick in either port

Using port A you must start with the stick button and the other port will be disabled. Starting with space or port B's button will disable port A.

Loading Instructions

Real Hardware



Start up the C64 emulator, and simply drag PAKU.PRG to the VICE window. It will handle the load and auto-run for you.

Further Information

For running C64 games on modern systems, I suggest the use of VICE.

VICE is cross platform and can not only emulate the Commodore 64, it can also emulate all of the other 8 bit systems produced by Commodore from the PET and VIC-20 right up to the C128 and Minus/60.