Sunday, April 24, 2022

Crystal Castles Assembler - Stacks

This is a continuing look at some of the features of the 6502 assembler Atari used for arcade games like Crystal Castles. One of the unique features, one I haven't seen in any other 6502 assembler, is the ability to define assembler level stacks. These have nothing to do with the 6502 stack, but instead are used to control the assembly process. 

You start by defining a stack using this pseudo op:

.DEFSTACK REGSAV, 4

There are two parameters. The first, in this case "REGSAV", is the name you want to give to the stack. You will use this to interact with the stack.

The second parameters, 4, is the size of the stack, so this stack will be able to hold up to 4 values.

To put a value on the stack you use the .PUSH pseudo op:

.PUSH REGSAV,1

This will push the value 1 onto the stack named REGSAV. The second parameter can also be an expression. I don't know if the original assembler allowed text strings to be pushed onto the stack but my version of the assembler only allows numbers to be pushed onto the stack. 

To get a value off the stack you use the .POP pseudo op:

.POP REGSAV,S1

This will pull the top value off the stack named REGSAV and put it into variable S1. The second parameter here must be a variable, not an expression.

You can use the .GETPOINTER pseudo op to get the stack pointer for a specific stack:

.GETPOINTER REGSAV,P1

This will put the stack pointer for stack REGSAV into variable P1. The stack pointer works from high to low, so if you declare a stack with the size 4, the initial pointer will be 4. If the pointer is 0 it means that stack is full.

Since I can only go by the source code I don't know what happens if you try to push a value onto a full stack or pull a value from an empty one. My version of the assembler currently doesn't handle these scenarios.

In a later post I will show how this features is used in the Crystal Castles source.


Sunday, April 3, 2022

Crystal Castles Assembler

When I found the Crystal Castles Source code I thought it would be cool to able to re-assemble the source so modifications could be made to the game from the original source. I didn't take long to realize that the assembler used by Atari had a lot of differences from assemblers I was familiar with. I started Googling some of the unusual pseudo ops in the source to see if I could identify an assembler that was compatible with this code. I found manuals for similar assemblers but nothing was a perfect match.

The best resource I found was the VAX MACRO and Instruction Set Reference Manual:

https://www.ece.lsu.edu/ee4720/doc/vax.pdf

It is not surprising that this assembler is close, Atari did a lot of their arcade development on DEC VAX mainframes. This became my go-to document for writing my assembler. If there was anything that was not clear from the source, but was answered in this document, I used what was in this document. 


Addressing Modes

One of the strangest differences between this assembler and other common 6502 assemblers is the syntax to define addressing modes. All the modes can be defined with prefixes to the operand, so for example, for absolute X you would do LDA AX,$1000 instead of LDA $1000,X. There are even multiple ways to define the same mode, at it appears different programmers used different ones. Here are the prefixes for the addressing modes:

# or I, - Indirect
ZX, - Explicit zero page X
ZY, - Explicit zero page Y
Z, - Explicit Zero page   
NX, - Indirect X
NY, - Indirect Y
AX, - Absolute X
AY, - Absolute Y
A, - Absolute
X, - Absolute or Zero Page X determined by the assembler 
Y, - Absolute or Zero Page Y determined by the assembler 

There are also two suffixes that can be used, (X) and (Y). You would think that these would be for indirect modes, but they are not, they are for absolute X and Y. I also found "(X" in the code. I assume this is an anomaly of the assembler where it doesn't parse the entire addressing mode identifier. 

Radix

The Atari assembler provides two different ways of controlling the radix (base) of numbers. First, the radix can be specified using a prefix on the number ^H for Hex and ^B for Binary. There is probably a prefix for octal but the Crystal Castles code doesn't use it. The second way of specifying radix is to use the .RADIX pseudo op which specifies the default radix to use when parsing numbers. For example if this is in the source:

.RADIX 16 

it will set the default radix to hex so that if a number doesn't have an explicit radix prefix it will be interpreted as hex. To avoid confusion with symbols, a hex number must start with a number if it doesn't have a prefix, so for example A5 would have to be written as 0A5. In my version of the assembler I always treat the parameter for the radix pseudo op as a decimal.

.REPT/.ENDR

The .REPT pseudo op looks pretty straight forward but there turned out to be some tricky parts to it. This pseudo-op repeats a block of code a specified number of times during assembly. It is passed one parameter which is the number of times to repeat it. 

The first interesting thing I found about it is that the Crystal Castles sources often uses it with a repeat count of zero. The basically works like a block comment, preventing the block of code from being assembled at all. 

The other interesting thing I found in the code was the .REPT blocks were sometimes ended using .ENDM, which ends a macro definition, instead of .ENDR. My theory on this is that if a repeat block is started inside a macro definition then it would make no sense for it to extend beyond the end of the definition, so it's possible that the assembler explicitly ends open repeat blocks at the end of a macro definition. This was probably an un-intended side effect of the way the assembler was written. 

I will cover some more differences in a latter post.







Saturday, March 19, 2022

Crystal Castles Source Files

In my last post I gave an overview of the files in the Historical Source Code  repository for Atari's Crystal Castles arcade game. In this post I will go into the files in detail. Here are the files in alphabetical order:

C00.DAT - C33.DAT : These contain the level data. I will go into these in more detail in a later post.

BITPAT.MAC: This files contains 8 bytes, represented as binary numbers in the file. The file is included into CEL.MAC and appears between two subroutines. It doesn't appear that this data is actually used by the game. It might be some sort of security or anti-piracy protection.

C99.MAC: Links together all the level data. This is assembled separately from the main program and becomes the second bank of ROMs.

CAL.MAC: Handles the display of the score and the high score screen.

CATOUT.MAC: Displays the Atari Easter egg message. Shown on the next level after you have jumped 128 times on the previous level.

CCN.MAC: 650X 'Universal' coin routine. This is a standard code library for handling the coin mechanism.

CCT.MAC: Draws the levels

CCUBE.MAC: Draws a cube on the screen. This is only used by the special display that happens when you score over 700,000 points.

CDB.MAC:  Routine to transfer level data from ROM to RAM 

CEE.MAC: EEROM routines 

CEEDEF.MAC: definitions for EEROM routines

CEL.MAC: Elevator handling 

CEN.MAC: Main game logic

CET.MAC: Auxiliary EEROM information, tables, output routines etc.

CG.MAC:  Global definitions and memory allocation

CGR.MAC: Global data and routines

CIN.MAC: Interrupt handlers

CLS.MAC: Sound and music data

CMAC.MAC: A couple macros to simplify common 6502 tasks

CMN.MAC: Main loop

CMR.MAC: Message display routines

CMS.MAC: Word data

CMTB.MAC: Message table

CRF.MAC: Root file

CRP.MAC: RPM (Rusty's POKEY Music) Driver

CSL.MAC: Symbol shape data

CSS.MAC: Test menu

CST.MAC: Self test

CSTART.MAC: Includes macros and zero page definitions

CWV.MAC: Level handling

HLL65F.MAC: High level language macros

M6502.MAC:  6502 general purpose macros


CJTB.MAC: This file is missing from the archive but is included in CRP.MAC. It it a patch to the POKEY music driver. I recreated this file from the original ROMs.

Thursday, March 10, 2022

Crystal Castles Source File Overview

Recently Historical Source Code published the original source code for a couple Atari arcade games including Crystal Castles. In this post I will give an overview of the the files that are included in the archive. The files can be found here:

 https://github.com/historicalsource/crystal-castles

The archive contains three sets of files for Crystal Castles, the one in the root directory of the repository, which I will call the master set, and two others sets called version-2 and version-3. In this post I will focus on the master set, since the other two contain some different files. Using my assembler I was able to re-assemble the master set to produce the ROMs that match the MAME ccastles1 set. I still need to determine if the other two versions of the source match up with other MAME ROM sets. The main ROM set in MAME, ccastles, does not match any of the source in the archive. The first ROM has a copyright message in it and the MAME base set also contains the phrase "PIRATES BEWARE" which is not in any of the source. 

Here is an overview of the files in the archive:

372X1.DOC 

This appears to be some sort of standard form used by Atari to document game projects, since similar files appear in the repositories for other games. The file contains all the details of the ROMs that make up the game, a description of how to assemble the files and a signoff form at the bottom.

022X1.DAT

This contains a single line of ASCII data that provides details of the ROMs that make up the game. This file is referenced in 372X1.DOC and is called the "Verification control file". I still need to study this file some more to understand the format.

372BR.RS4

This file is referenced in 372X1.DOC and 022X1.DAT so has something to do with the verification process, but I am not sure what the data in it represents.

*.MAC

The .MAC files are the macro-assembler source files for the game. Most of the files are for the fixed ROM and the first ROM bank. C99.MAC and the .DAT files are for the second ROM bank. CRF.MAC is the root file, the other files are either included in CRF.MAC, or included into other includes. There was one file missing from the archive, CJTB.MAC, which is included into CRP.MAC. To be able to re-assemble the code I had to re-create this file from existing ROMs. I will look at these in more detail in a future post.

Cxx.DAT

These files contain the level data for the game and are included into C99.MAC. This is assembled separately and forms the second bank of ROM.

*.LDA

These are the binary output of the original assembler in a format that makes them linkable to other binaries to form the final output. I need to do some more research to figure out the format of these files. 



Saturday, March 5, 2022

Crystal Castles Source Code


I recently ran across a bunch of Atari arcade source code that was added to the Historical Source Github site, including the source for one of my favorite games, Crystal Castles.


https://github.com/historicalsource/crystal-castles


I thought it would be cool to be able to re-assemble this back into the original ROMs. I started by trying to find an existing assembler that could do this, but the assembler used for this source had a lot of syntactical differences and features I couldn't find in any other 6502 assembler. I assume Atari used a VAX based assembler and I did even find documentation for a VAX assembler with similar features, but still not an exact match. 


I then thought about manually modifying the source to work with an existing assembler. I quickly realized that this wasn't feasible due to some of the odd syntax in this assembler. For example the Atari assembler has an different syntax for addressing modes. You can write Zero Page X like this: "LDA ZX,$PSTSL", you couldn't fix this with a simple search and replace. This would also have to be done for every game I wanted to re-assemble. 


So I decided the best option was to build my own assembler that could handle these files with little changes to the original source. The assembler I build is now able to reassemble the main source from the historical source repository and reproduce the MAME ccastles1 ROM set. 


I have setup a GitHub repository to hold the C# source code for my assembler as well as tool to split the output into separate ROMs and handle the checksum process. There is also a folder there with the files and instructions needed to rebuild the source. There are some small changes needed to the source which I have documented in the instructions, and there was one file missing from the Historical Source archive which I re-created from the original ROMs. 


https://github.com/danlb2000/AT6502







Sunday, January 23, 2022

IMSAI 8080 Introduction

 


A while back I acquired and IMSAI 8080 system that was headed for the trash. Many people may remember this system from the 1983 film Wargames, a personal favorite of mine. Here is a brief look at the components that came with the system, I will write some more in-depth posts on each part in the future. 



The system was in cosmetically good shape when I got it, still needed some cleaning in this picture. It powered up ok, but had some problems with the front panel that I needed to troubleshoot.



Here is a look inside. The boards there were included, front to back...

- CPU board with a Dutronics Dz80 upgrade that replaced the 8080 CPU with a Z80.
- Fully populated Z16, 16K RAM board
- Second Z16 with only 12K of RAM
- Floppy disk controller. I couldn't find any information on this one so had to reverse engineer it.
- Technical Design Labs SMB  System Monitor Board. 


Heathkit H19 dump terminal. This worked perfectly when I got it.



Innovex 10" floppy drive. I haven't tried to get this working yet.


This is a dot matrix printer that prints onto cash register style tape. There weren't any markings on it to identify the manufacturer, but I got a response from Lee Felsenstein on Facebook identify the manufacturer as  Practical Automation. 










 

Thursday, November 25, 2021

Amprix Mystery Device





Over the years I have accumulated a lot of surplus electronics. I had a bunch of these small PCBs and I had no memory of where they came from. The only marking on the board is "AMPRIX 3-1391". A Google search for Amprix doesn't turn up much, but I did find a few useful pieces of information. First I found a surplus site selling an Amprix voltage regulator. 

https://www.electronicsurplus.com/amprix-electronics-a118-2-voltage-regulator-assembly-adjustable-24vdc

I also found this site which says this was a company from Texas that existed from 1981 to 1984. 

https://opencorporates.com/companies/us_tx/0054892500

Finally I found this quote:

“Amprix designs and builds electronic components and products for the automobile aftermarkets . “

The board only has two inputs, power and ground, and 4 LEDs, so my assumption was that this was some sort of voltage monitoring device. 

Here is the schematics I traced from the PCB.



The D27 zener diode creates a reference voltage which goes through a resistor network to one input of three LM339 comparators. There is a also a variable resistor, R22, to calibrate the reference voltage. The other input of the comparators goes to the supply voltage. With this setup LED 8 and 20 will come on around 5 volts, 8 will come on alone around 9 volts, all the LEDs will go off around 11 volts and finally 14 will come on at around 13 volts. Based on the mention of automotive components and all the LEDs being off around 12 volts (auto battery voltage), this will likely a device for monitoring car batter y voltage. 

The one mystery with this circuit is LED D20, I have found no scenario which turns this one on. It is hooked to the top LM339. The non-inverted input come from the supply voltage and the inverted input from ground. For LED D20 to turn on the non-inverted would have to be higher then the inverted, and I am not sure how that could ever happen. 

My one theory is that the circuit if actually designed incorrectly. Sine I have a bunch of these they were likely surplus components, so maybe these were defective and sold as surplus.