Tuesday, July 31, 2012

A YUMmy New Game


I wanted to write another game for the Replica 1, and after considering a few alternatives, I decided to write a computer version of YUM, a game that is popular with our family.


YUM is a dice game, similar to games known as Yahtzee, Yacht and Generala. Each player rolls five dice up to three times and then applies the dice toward a category to claim points. The game has 12 rounds during which each player attempts to claim the most points in each category.

The winner is the person scoring the most points at the end of the game. This version supports up to three players of which any can be human or computer players.

It would be a little frustrating to write in BASIC and tedious in assembler so I wrote it in C using the CC65 6502 compiler/assembler. This had the advantage that I could develop and test it on a desktop Linux system.



There is nothing particularly novel about the code. The computer players play a relatively good game based on some simple rules. The game could support more than three players by changing a compile-time constant -- the only limitation is that the screen size only conveniently fits a table of scores for three players.



Because it was intended to run on the Replica 1 it was kept small and efficient to run within the 32K memory limit and only use uppercase characters and fit on a 40x24 character screen.





The source is released under an Apache license. Both the source code and a binary that will run on a Replica 1system  can be found at here.

If you want to run it on a real Apple 1 or similar, you will need to have just over 16K of RAM. With a little effort I could probably get the code size down a little to fit in 16K (the Replica 1 has 32K).





For my next Replica 1 project I am eagerly awaiting the Apple Cassette Interface kits that Vince Briel is offering. I expect to be one of the first beta testers for this, and I have a cassette tape player ready to go.


Saturday, July 21, 2012

Getting Info About the System


I recently added a few more features to JMON. The main one is a new iNfo command which displays information about the system it is running on. Here is sample output:

         CPU TYPE: 65C02
        CPU SPEED: 2.0 MHZ
RAM DETECTED FROM: $0000 TO $7FFF
       NMI VECTOR: $0F00
     RESET VECTOR: $FF00
   IRQ/BRK VECTOR: $0100
         ACI CARD: NOT PRESENT
       CFFA1 CARD: NOT PRESENT
   MULTI I/O CARD: PRESENT
        BASIC ROM: PRESENT
     KRUSADER ROM: PRESENT
       WOZMON ROM: PRESENT

The way some of this information was generated is somewhat interesting. I'll explain a bit about how the code was implemented.

To determine the CPU type I used some code from the Western Design Center manual for the 65xx series processors. The code first distinguishes between 6502 and 65C02 processors by the behavior of the negative flag in decimal mode. The 65C02 fixed the behavior to make the flag valid (also V and C) while the 6502 did not. It then tries a 65816 instruction which will change the carry flag but is an unimplemented instruction and hence a NOP on the 65C02. From this it determines if it is running on a 6502, 65C02, or 65816 processor.

There are different manufacturers of 65C02. I don't know of any easy way to distinguish between a Rockwell and WDC 65C02. Thw only added instructions on the WDC are STP and WAI which both stop the CPU from running. They require either a reset or an interrupt to restart the CPU.

To find the range of RAM the code does the following. Starting from address zero, it in turn writes all ones, all zeroes, and alternating ones and zeroes to each memory location. If the same data is read back, it is considered RAM. The original data at the location is then written back to avoid corrupting what is in memory (namely, JMON). This is done until memory is found that cannot be written to and read back with the same data. I then stop, so the test only checks for contiguous RAM starting at zero.

A wrinkle is to avoid writing to the area of memory where the code itself is running since it would get corrupted in the middle of execution. I do this by avoiding testing the 256 byte page where the memory test code resides.

Next is the CPU speed. We want to determine the approximate clock speed of the CPU. But how, since we have no reference to actual time? The trick I used is to make use of a serial port, which is available when a Multi I/O board is present. If we send some characters out the serial port and see how many CPU cycles it takes, we can determine how fast the CPU is running since the serial port works at baud rates that are independent of the CPU clock speed. The code is calculated to give a value that is approximately the clock speed in megahertz to two significant figures.

For testing if certain ROMS are present, like the Krusader assembler, we can check the first few bytes for known data.

For expansion cards, like the CFFA1, they may have ID bytes in hardware (the CFFA1 does) or we can look at the hardware registers like the 6551 on the Multi I/O board and check for behavior of the registers, such as specific bits that can or can't be changed. I wrote tests for the cards that I have, the CFFA1 flash card, Multi I/O card, and ACI Apple Cassette Interface (the latter I don't yet have).

I tested the new info command with 6502, 65C02, and 65816 processors and 1 MHz and 2 MHz crystal oscillators. I also tested it on the POM1 emulator. A screenshot under POM1 is shown below.

Info Command Running on the POM1 Emulator

With these changes I am running out of features to add to JMON so I am considering it to be feature complete and calling it version 1.0.

I noticed it recently exceeded 8K in size, so it no longer fits in a single 8K EPROM. I could reduce it to under 8K by disabling some features. The disassembler has some reasonably large tables (which the assembler also uses).

Saturday, July 14, 2012

JMON Trace Function


I've implemented one of the features missing from JMON, and one that I had been relying on Krusader's mini monitor for: an instruction trace function. This function allows you to single step through a program, see a disassembly of the current instruction, and see the values of the hardware registers. This feature is almost indispensable for debugging code. Krusader does this but I wanted to write my own.

I can think of at least three ways to single step code. One is a hardware solution. The Apple 1 manual actually shows a circuit that does this, and presumably Woz used this circuit to debug the Apple 1. This approach is very useful for bringing up new hardware that may not yet be working, but it is complex and expensive.

A second approach is the use the breakpoint instruction (BRK). By inserting a BRK instruction in code, when executed it can jump to the break vector which can run code which shows the current values of the registers. You can then replace the BRK with the original instruction and place a BRK at the next instruction, and continue execution. A disadvantage of this approach is that it only works for code in RAM and not ROM, since the program memory must be written to with the BRK instruction.

A third approach, and the one I used, is to look at the next instruction to be executed, copy it to a buffer, and execute it in place. The instruction can be followed by code that jumps back into the trace code in the monitor program. This approach has the advantage of working even for code that is in ROM.

To make this work there are a couple of wrinkles. Some instructions change the flow of control (e.g. JMP and JSR) and would jump out of the trace code. To trace these I simulate instead of execute them, doing the equivalent of what the instruction would do. For example. a JMP instruction just needs to update the value of the program counter. These special instructions are JMP, JSR, RTS, RTI, and BRK. Similar are the branch instructions. Initially I thought I would simulate these, looking at the CPU registers to determine whether the branch was taken or not. This would get a little complex as there are about 8 branch instructions to simulate, each checking a different condition. Instead I use a simpler approach that can use the same code for all branches. I execute the branch instruction in the buffer, but I adjust the branch destination so it jumps to a known location in the trace code. Whether the branch is taken or not, it stays under control of the trace code.

My trace function produces similar output to Krusader's mini monitor. You can set the register values use the Register command, including the Program Counter. The "." command traces/executes one instruction.

The breakpoint feature of JMON works in conjunction with this. If a breakpoint is hit, it updates the register values and you can single step as desired. You can also use the Go command to execute from the current program counter address.

It took a little work to get all of this correct for all instructions. It leveraged the previous work on the disassembler and mini assembler. For example, I needed to know the length of each instruction and this information was already available in tables used by the disassembler.

A sample session is shown below. Commands entered by the user are in bold. The actual trace commands "." are not echoed.

JMON MONITOR 0.99 BY JEFF TRANTER
? R
A-00 X-00 Y-00 S-0140 P-00 ........
0000   00          BRK
A-00 X-00 Y-00 S-0140 P-00 ........
PC-6000
? R
A-00 X-00 Y-B0 S-0140 P-00 ........
6000   EA          NOP
A-Esc
? A-00 X-00 Y-B0 S-0140 P-30 ..-B....
6001   A9 01       LDA   #$01
? A-01 X-00 Y-B0 S-0140 P-30 ..-B....
6003   A0 01       LDY   #$01
? A-01 X-00 Y-01 S-0140 P-30 ..-B....
6005   A2 01       LDX   #$01
? A-01 X-01 Y-01 S-0140 P-30 ..-B....
6007   08          PHP
? A-01 X-01 Y-01 S-013F P-30 ..-B....
6008   68          PLA
? A-30 X-01 Y-01 S-0140 P-30 ..-B....
6009   38          SEC
? A-30 X-01 Y-01 S-0140 P-31 ..-B...C
600A   18          CLC
? A-30 X-01 Y-01 S-0140 P-30 ..-B....
600B   69 01       ADC   #$01
? A-31 X-01 Y-01 S-0140 P-30 ..-B....
600D   F8          SED
? A-31 X-01 Y-01 S-0140 P-38 ..-BD...
600E   69 10       ADC   #$10
? A-41 X-01 Y-01 S-0140 P-38 ..-BD...
6010   D8          CLD
? A-41 X-01 Y-01 S-0140 P-30 ..-B....
6011   4C 17 60    JMP   $6017
? A-41 X-01 Y-01 S-0140 P-30 ..-B....
6017   20 15 60    JSR   $6015
? A-41 X-01 Y-01 S-013E P-30 ..-B....
6015   EA          NOP
? A-41 X-01 Y-01 S-013E P-30 ..-B....
6016   60          RTS
? A-41 X-01 Y-01 S-0140 P-30 ..-B....
601A   A9 28       LDA   #$28


As part of my testing I modified the code to stay in trace mode and ran the Woz monitor and Apple BASIC under the trace code. They executed correctly, although a little slower than normal.

The code supports 65C02 instructions without any extra coding except the BBR and BBS commands which would need some additional branch instruction support. Some 65816 instructions should work but the new instructions which change flow of control would fail and it doesn't understand the variable length of instructions depending on the CPU mode (but it would be quite straightforward to add).

This new trace function should prove useful for debugging future code I write. As always, the code can be found here.

Tuesday, July 10, 2012

Android version of POM1 Emulator

I earlier talked about the POM1 Apple 1 Emulator. John Corrado recently ported it to Android so it runs on Android devices like phones and tablets. It's quite cool to see Apple 1 code running on a phone. It's also quite shocking how much computer power has improved - my phone has at least 1000 times the computing power and resources of the Apple 1.

Below is a picture of JMON running on my Android phone:

POM1 Running on an Android Phone
And here are a couple screen shots of JMON running on the desktop version of the POM1 emulator:

JMON Help Screen
JMON Disassembly Feature

You can get the Android version from the Google Play app store. Look for "pom1". The POM1 simulator is maintained at pom1.sourceforge.net.



I mentioned planning to add 65C02 support to the mini assembler in JMON. Well, that only took about an hour, as it only involved adding support for the two new addressing modes. It now supports 65C02 instructions, other than the BBR and BBS instructions which have a special syntax.



While I was adding 65C02 support I thought I would write a little quick reference like I did for the 65816. I've almost finished the one page document which outlines the new software features of the 65C02 over the 6502. It will be available for download here.

Monday, July 9, 2012

Implementing A Mini Assembler


One of the features missing from JMON was a "mini assembler" like the one included in the Apple II computers.

I implemented one with roughly the same features and limitations as the one in the Apple II, i.e. it assembles simple 6502 assembly language code where all numeric values are in hex and there is no support for symbols or labels.

It is very handy for writing short assembly language programs where you don't want to fire up a cross-assembler or even Krusader.

In conjunction with the disassembler you can verify the program you entered and then run it.

The code leveraged the data tables in the JMON disassembler. Most of the work is parsing the entered code to validate it and determine the addressing mode.

While I only implemented 6502 support in this first version, because it uses the tables from my disassembler, it does accept 65C02 and even 65816 instructions that use the standard 6502 addressing modes. It just doesn't yet understand the new addressing modes for the 65C02 or 65816.

A sample session is shown below, where the user entered text is in bold.

? A 6F00
6F00: CLD
6F01: CLI
6F02: LDY #7F
6F04: STY D012
6F07: LDA #A7
6F09: STA D011
6F0C: STA D013
6F0F: LDA #5C
6F11: JSR 6FEF
6F14: JSR 6F1B
6F17: BCC 6F0F
6F19: BCS 6F14
6F1B: JSR 6EE5
6F1E: LDY #01
6F20: DEY
6F21: BMI 6F1B
6F23: JSR 6EBE
6F26: STA 0200,Y
6F29: CMP #0D
6F2B: BEQ 6F38
6F2D: CMP #5F
6F2F: BEQ 6F20
6F31: CMP #1B
6F33:

It provides meaningful error messages and checks the validity of the code. Below are some error messages:

6000: LDA #1234
INVALID OPERAND
6000: LDA (1234)
INVALID ADDRESSING MODE
6000: BNE 7000
RELATIVE BRANCH OUT OF RANGE
6000: LDB
INVALID INSTRUCTION

I tested it as I built up the code, but the final test was to disassemble about a thousand lines of JMON code and then feed that back to the assembler and confirm that it accepted it and generated the same code.

I'll probably add support for the rest of the 65C02 instructions in future and maybe also the 65816.

As always, the code is available here.

Saturday, July 7, 2012

65816 Disassembly - 8 and 16 bit modes


Today I made JMON a little smarter about 65816 disassembly. It now handles 8-bit and 16-bit instructions, looking at SEP and REP instructions to determine what mode the CPU is currently in. Of course, it cannot always get this correct as it doesn't know if code could be called when the CPU is in a specified mode. It starts in all 8-bit mode. This is similar to how the CC65 assembler works in "auto" mode unless you use assembler directives to explicitly set the mode.

While I was testing this I noticed the SEP instruction was disassembled as CPX. There is actually an error in the Western Design Center manual in Chapter 19, Instruction Lists, which I had copied when I entered the op codes. The byte $E2 is SEP but is listed as CPX.

Here is sample disassembly output from JMON showing all 4 combinations of 8 and 16-bit accumulator and index register modes (I've manually added spaces to highlight where the mode changes).

JMON MONITOR 0.97 BY JEFF TRANTER
? U 60B9
60B9   E2 30       SEP   #$30
60BB   09 12       ORA   #$12
60BD   29 12       AND   #$12
60BF   49 12       EOR   #$12
60C1   69 12       ADC   #$12
60C3   89 12       BIT   #$12
60C5   A9 12       LDA   #$12
60C7   C9 12       CMP   #$12
60C9   E9 12       SBC   #$12
60CB   A0 12       LDY   #$12
60CD   A2 12       LDX   #$12
60CF   C0 12       CPY   #$12
60D1   E0 12       CPX   #$12


60D3   C2 30       REP   #$30
60D5   09 34 12    ORA   #$1234
60D8   29 34 12    AND   #$1234
60DB   49 34 12    EOR   #$1234
60DE   69 34 12    ADC   #$1234
60E1   89 34 12    BIT   #$1234
60E4   A9 34 12    LDA   #$1234
60E7   C9 34 12    CMP   #$1234
60EA   E9 34 12    SBC   #$1234
60ED   A0 34 12    LDY   #$1234
60F0   A2 34 12    LDX   #$1234
60F3   C0 34 12    CPY   #$1234
60F6   E0 34 12    CPX   #$1234


60F9   C2 20       REP   #$20
60FB   E2 10       SEP   #$10
60FD   09 34 12    ORA   #$1234
6100   29 34 12    AND   #$1234
6103   49 34 12    EOR   #$1234
6106   69 34 12    ADC   #$1234
6109   89 34 12    BIT   #$1234
610C   A9 34 12    LDA   #$1234
610F   C9 34 12    CMP   #$1234
6112   E9 34 12    SBC   #$1234
6115   A0 12       LDY   #$12
6117   A2 12       LDX   #$12
6119   C0 12       CPY   #$12
611B   E0 12       CPX   #$12


611D   E2 20       SEP   #$20
611F   C2 10       REP   #$10
6121   09 12       ORA   #$12
6123   29 12       AND   #$12
6125   49 12       EOR   #$12
6127   69 12       ADC   #$12
6129   89 12       BIT   #$12
612B   A9 12       LDA   #$12
612D   C9 12       CMP   #$12
612F   E9 12       SBC   #$12
6131   A0 34 12    LDY   #$1234
6134   A2 34 12    LDX   #$1234
6137   C0 34 12    CPY   #$1234
613A   E0 34 12    CPX   #$1234

Friday, July 6, 2012

65816 Support added to JMON


The other day I added 65816 support to the disassembler in my JMON program. It doesn't currently handle instructions that are of different lengths in 8-bit and 16-bit modes. The code can also now be configured at build time whether to support the 6502, 65C02, additional Rockwell 65C02 instructions, and 65816. The was an extension of my existing code and not based on any part of the DEBUG16 program.

The code now also has a new Options command that allows configuring a few things and will likely support more in the future.

Tuesday, July 3, 2012

DEBUG16 - 65816 Disassembler and Trace Utility


Now that my Replica 1 is running with a 65816 processor, I wanted to try a program that was more substantial than the small demo programs I had tried.

The manual Programming the 65816 Including the 6502, 65C02 and 65802 available from The Western Design Center has a chapter describing and giving the source code for a program called DEBUG16. The program can perform disassembly and instruction tracing of 65816 machine code. It is about 1700 lines of assembler code. I thought I would try porting it to my Replica 1 using the CC65 assembler.

The first step was copying and pasting the assembler listings from the PDF file for the manual. That gave me a text file with the assembler listing of the original code.

Then I stripped out the the listing portion of the file to generate an assembler source file. It needed some changes to port it to the CC65 assembler, due to differences in it's assembler directives. After making a number of changes I had a file which would assemble and I could compare to the original listing.

It turns out there are a number of typographical as well as logic errors in the listing in the manual. A Google search shows at least one other person tried getting this code to work (about 10 years ago) and noticed the errors. After some detective work I think I was able to determine what the errors were, and obtained a file which could successfully build and generated the same code as in the original listing.

The original code was intended for running on an Apple //e with a 65816 card. The Apple specific code (e.g. for input and output) was clearly indicated in the source. I made the necessary changes to the input/output code to work on the Replica 1.

Next, I wrote a small main routine to call the LIST routine which disassembles 65816 code (I had it disassemble itself). Somewhat to my surprise, it actually produced reasonable output on the first try. I found a few errors in the code, such as an instruction or two that were disassembled incorrectly. I fixed that, although there may be some issues with a few instructions. It is at least correct enough for 6502 code that I can disassemble my entire JMON program and get the same output as from the 6502 disassembler that I wrote.

A sample of the output is shown here:

00:6013   08        PHP                                               
00:6014   18        CLC                                               
00:6015   FB        XCE                                               
00:6016   08        PHP                                               
00:6017   0B        PHD                                               
00:6018   F40000    PEA     $0000                                     
00:601B   2B        PLD                                               
00:601C   C220      REP     #$20                                      
00:601E   E210      SEP     #$10                                      
00:6020   649D      STZ     $9D                                       
00:6022   A580      LDA     $80                                       
00:6024   8584      STA     $84                                       
00:6026   A682      LDX     $82                                       
00:6028   8686      STX     $86                                       
00:602A   A780      LDA     [$80]                                     
00:602C   AA        TAX                                               
00:602D   8687      STX     $87                                       
00:602F   207762    JSR     $6277                                     
00:6032   204760    JSR     $6047                                     
00:6035   208F60    JSR     $608F                                     
00:6038   20CD61    JSR     $61CD                                     
00:603B   9005      BCC     $6042                                     
00:603D   20D462    JSR     $62D4                                     
00:6040   80DA      BRA     $601C                                     
00:6042   2B        PLD                                               
00:6043   28        PLP                                               
00:6044   FB        XCE                                               
00:6045   28        PLP                                               
00:6046   60        RTS                                               
00:6047   201D62    JSR     $621D                                     
00:604A   E230      SEP     #$30                                      
00:604C   A000      LDY     #$00                                      
00:604E   A586      LDA     $86                                       
00:6050   20F761    JSR     $61F7

The other function of DEBUG16 is a trace facility that allows stepping through 65816 code and seeing the current value of registers and disassembled instructions. This code has significantly more dependencies on Apple II functions and is harder to port. I spent some time on it, but it is tricky to debug the code as the 65816 changes in and out of native mode and 8/16 bit data and index register modes, and existing debug tools I have like Krusader's mini-monitor will not work in the 65816's native mode. I set this aside to look at later.

So the current status is that the disassembly routine is working well although it has not been tested exhaustively for all 65816 instructions. The trace function has not yet been tested or debugged. The code is available here.

While I was playing with the 65816, I took the time to make a little 65816 quick reference document. It can be printed on one double-sides page, and lists the register model, new addressing modes and instructions, and some other specifics of the 65816. It is most useful if you are familiar with the 6502 and are looking for a quick summary of what is added by the 65816. You can get it here in both OpenOffice.org and PDF formats.