User:Stephan64

From C64-Wiki
Jump to navigationJump to search

About me[edit | edit source]

My name is Stephan Pabst, born in 1968, and I live with my family in Benningen am Neckar, near Stuttgart, in Germany. Since buying a Commodore 64 and a datasette in 1984, at the age of 15, I have regularly worked with this fascinating machine. My wife and three children (two of whom are now adults) generally share my enthusiasm for a computer that is over 40 years old with understanding and sometimes even with amusement and interest.

I initially ran my first computer on a bulky and sometimes blurry black-and-white television, and enthusiastically developed games, as well as educational programs and numerical routines. A few years later, I was able to afford a Commodore 128D (partly from the proceeds of my game "Pole Position (Tronic)", which I published in the magazine "Homecomputer") along with a Commodore 1901 color monitor, which I then programmed under the CP/M operating system, also in Turbo Pascal — but on which the C64 mode was always just a reset away (by holding down the <C=> key!).

During my studies (Master's degree in Business Information Systems and PhD in Finance) and my professional career (software developer at a major automotive supplier), I have, of course, encountered and continue to encounter much more powerful computers galore — nevertheless, the C64 remains the computer that fascinates me the most. And since 2021, I have been incorporating my experiences from more than four decades of working with this fascinating machine into my articles in the C64 Wiki.


How it all began: The Commodore 64 and accessories in the "Quelle" catalog '84/85



My Commodore 64 Projects[edit | edit source]

Commodore 64 Emulator "Y64" (Yet another Commodore 64 emulator)[edit | edit source]

Back in 1991, I had the idea that a Commodore 64 should be emulated on a PC. Since my computer at the time only had an Intel 80286 processor, and I wanted to make the best possible use of its rather modest processing power, I wrote my emulator entirely in hand-optimized Intel x86 assembler. Nothing has changed since then (it has now grown to around 40,000 lines of source code), making it extremely fast and compact.

Years later I realized that other C64 fans had similar ideas, and so I eventually named my emulator "Y64" (Yet another Commodore 64 emulator). Since the emulator can only be started under MS-DOS in Real Address Mode (but then switches to Protected Mode during operation and emulates the various memory configurations of the C64 on an 80286 processor via Local Descriptor Tables, and on the 80386 and other 32-bit processors via Paging), it will probably remain an exotic and niche product forever — albeit with capabilities that some C64 fans may have long desired for their C64 and perhaps also for an emulator...

Coupling my C64 emulator with an Arduino[edit | edit source]

Anyone wanting to learn low-level programming on an 8-bit system today will likely rarely use a C64, but rather an Arduino prototype board. It therefore makes perfect sense to connect an (emulated) C64 and an Arduino for a "cross-generational dialogue":


Coupling between my C64 emulator "Y64" and an Arduino Mega 2560 while running the game "Starquake"
Coupling between "Y64" and an Arduino while running the game "Spellbound"



The Arduino can access the RAM and all I/O chips of the emulated C64 and manipulate, process, or log their memory contents. The left image in the gallery above demonstrates such a connection while the game "Starquake" is running on the C64: The upper part of the TFT screen attached to the Arduino displays the C64's screen content, and the lower part shows a symbolic representation of the game board (explored rooms in green, unexplored rooms in red). In the right image, the Arduino visualizes the status of all characters and the location of all objects during the game "Spellbound."

Connecting my C64 emulator to the INCA measurement and calibration system[edit | edit source]

INCA is a software tool for engine development widely used in the automotive industry. Since my professional work includes implementing customer-specific extensions for INCA and integrating new measuring devices, it made sense to also integrate my C64 emulator as a "measuring device" in INCA:


Screenshot of a connection between my C64 emulator "Y64" and the INCA measurement system during the game "Gribbly's Day Out"



With this connection, INCA periodically reads game parameters, such as the character's position, as well as energy, score, or number of lives, from the C64's main memory via a serial interface and displays them as measured values. Being able to track the character's position across the entire game board is particularly helpful when navigating large mazes (in the example shown, the character "Gribbly Grobbly" is in the bottom right corner of the Gribblets' cave).

Reconstruction of Musical Notes for Melodies from C64 Games[edit | edit source]

My C64 emulator supports the targeted logging of accesses to the emulated I/O chips of the Commodore 64. This is particularly interesting for write accesses to the sound chip SID, from which the notes of a melody can be easily reconstructed and converted into a suitable file format (for example, ABC). In this way, I have extracted more than 600 melodies from over 270 games and published them in the "Miscellaneous" section of the corresponding articles in the German C64 Wiki.


Sheet music for the C64 game Robin of the Wood, reconstructed by logging all write accesses to the SID
Sheet music for the C64 game Burnin' Rubber



Incidentally, you can also learn quite a bit about the programming techniques used by game developers. For example, the background melody from the game "Robin of the Wood," shown here on the left, is played using the SID frequency parameters valid for NTSC, meaning it sounds almost a semitone lower than intended on the PAL version of the C64.

In other games, the frequency parameters are based on a more or less rounded system clock; for example, in Burnin' Rubber (right illustration), they are based on a frequency of 1.000 MHz—and on the corresponding parameters printed in the SID 6581 datasheet (http://archive.6502.org/datasheets/mos_6581_sid.pdf). During the programming of this game, the author made two typos when entering the frequency parameters: A#-3 (235.0 Hz instead of 233.1 Hz, because parameter $0F66 instead of $0F46) and D#-3 (156.2 Hz instead of 155.6 Hz, because parameter $0A3C instead of $0A32) are slightly incorrect.

Analysis of Sound Effects from C64 Games[edit | edit source]

Numerous C64 games underscore individual events with fascinating sound effects. A high-resolution representation of the sound output based on the write accesses to the SID allows for an analysis of these sounds. The following gallery illustrates, for example, a series of sound effects from the game "Paradroid", which play while the player unsuccessfully tries to take control of an enemy robot. These sounds are all reproduced with only one voice of the SID; The graphs depict the temporal evolution of pitch with a resolution of 0.5 ms (2000 pixels/s in the original resolution) in a musical staff format. The scale at the top and bottom of the graphs is divided into 10 ms sections. The envelope, which can, for example, cause a gradual decay, is not visible in this representation.

"Transfer" (0.279 s per pass, sounds every 0.479 s)
"Captured" (1.894 s)
"Deadlock" (2.533 s)
"Burnt Out" (1.894 s)



Background sound in the game "Paradroid" (1776 ms per pass, sounds every 1915 ms)



In this diagram, natural notes are shown in their exact positions; semitones are shown midway between their neighboring natural notes (for example, a G sharp midway between G and A). For all other notes, the vertical position is determined by the exact interval of their frequency from the next higher and next lower natural note.

Interesting sections of melodies can also be analyzed in this way. The following diagram, for example, shows the first few bars of the theme song from "Green Beret". The arpeggios of the melody (red) and the vibrato of the bass lines (green and blue) are clearly visible.

First bars of the theme song from "Green Beret" (4.50 s)



Analysis of the Executed Machine Code[edit | edit source]

Y64 offers numerous statistical functions for analyzing the operation of the 6510 microprocessor. This will be demonstrated using a short, 17-second sequence from the game "Starquake" and a 29-second move from the computer chess program "Colossus Chess". A timer is displayed in the lower right corner in each case, allowing you to establish a temporal relationship with the graphs in the following sections.

Short sequence from the game "Starquake" (17.00 s)
A move by the computer in the chess program "Colossus Chess" (29.00 s)


The Commodore 64's MOS 6510 microprocessor requires at least 2 system clock cycles per instruction (for example, for directly loading a constant into a register) and a maximum of 7 clock cycles (for example, for incrementing a memory location with absolute X-indexed addressing). If illegal opcodes are included in the analysis, the execution of a machine instruction can even take up to 8 clock cycles (for example, for the ISC instruction with indirect Y-indexed addressing).

An initial analysis of the machine instructions executed in the game "Starquake" shows that the microprocessor executes a total of 5,004,475 instructions during the 17-second sequence, or slightly more than 294,000 instructions per second. This corresponds to an average of 3.35 system clock cycles per instruction.

As with many other games, the performance figures mentioned above for "Starquake" primarily reflect the structure of the loop in which the computer periodically waits for a specific event—in the case of Starquake, for the television's electron beam to reach the bottom of the screen.

30F8: LDA $D012 ; Read number of current raster line from VIC register 18
30FB: CMP #$FA  ; and compare to raster line of the lower edge of the screen
30FD: BNE 30F8  ; jump back while lower edge of the screen not yet reached 

As long as the game character doesn't switch to an adjacent screen, this loop is executed over 1,800 times per screen refresh, which occupies the CPU for more than 80% of the time (around 16,200 out of 19,656 system clock cycles per frame refresh, not including DMA accesses by the VIC). Accordingly, the instructions executed here also dominate the instruction statistics (left image in the following gallery). If this wait loop is factored out, it becomes clear that the CPU is only fully utilized when the screen changes (right-hand diagram).

Classification of the machine instructions executed by the CPU in the sequence from "Starquake"
Percentage CPU utilization ignoring the queue time in the game "Starquake"


In contrast, the chess program "Colossus Chess" uses a CPU that is fully utilized continuously as long as it is the computer's turn. The left-hand diagram illustrates the proportions of different instruction types among the 8,060,298 machine instructions executed by the CPU (approximately 278,000 instructions per second, 3.55 system clock cycles per instruction). The middle diagram further analyzes the relative frequency of different types of conditional branches (i.e., how often a branch is triggered or not triggered based on which flags), while the right-hand diagram shows whether these are forward or backward jumps and whether the branch is actually taken or not taken.

The fact that the instruction pair BVC/BVS (branching due to the overflow flag) is executed very rarely aligns with observations from other games: Typically, this flag is primarily used to test the 6th bit of a memory cell using a BIT instruction.

However, the distribution of conditional jumps based on direction (forward or backward) and whether the tested condition was met and the jump was executed (taken) or not (not taken) is atypical. Many games contain loops that are executed many times, so the backward jump is the most frequent variant. In "Colossus Chess," this only applies to the Zero Flag test, where the "backward/taken" combination is most common at 30.17% (just ahead of backward/not taken at 28.82%).

Classification of the machine instructions executed by the CPU in the sequence from "Colossus Chess"
Proportions of the different branch commands in "Colossus Chess" (BVC/BVS with 0.00096% not visible)
Proportions for jump direction and execution in "Colossus Chess"



On the Commodore 64, such analyses could be used to optimize the machine code, since on the 6510 CPU, an unexecuted branch required only 2 system clock cycles, while an executed branch required 3 (and even 4 when crossing a page boundary). On more modern processors, such statistics form the basis for the design and testing of branch prediction[1][2][3].

Sources[edit | edit source]

  1. John L. Hennessy/David A. Patterson: "Computer Architecture — A Quantitative Approach", Morgan Kaufmann Publishers Inc., 1990, p. 272f
  2. Don Anderson/Tom Shanley: "Pentium Processor System Architecture", Mindshare Inc., 1995, p. 149f
  3. Tom Shanley: "Pentium Pro and Pentium II System Architecture", Mindshare Inc., 1998, p. 122f