Here are some notes on design and theory of operation of the Superboard ///. This was gleaned from looking at the circuit and I may have got some details wrong. Refer to the schematic diagram that is included on the CD.
All parts on the board are through-hole, making it easy to assemble. All ICs are socketed, and the board is silk-screened with component designations and values. Vince Briel says that the blue solder mask used is a tribute to the blue color scheme that Ohio Scientific used in their line of computers. About half of the board is taken up by the 53 keyboard keys.
Power comes in as +5V via the USB port through the USB to serial FTDI board. Vince Briel recommends a 1000 mA or more USB power supply but the USB 2 standard calls for 500 mA from a host (computer) and the board typically takes about 115 mA, in my measurements. Note that the power switch comes after the USB to serial board, so the serial board is always on and takes some power. The power LED is after the power switch.
The original Superboard took a lot more power and was specified as needing a 5 volt 3 amp power supply. Power consumption depended a lot on the amount of RAM, e.g. whether 4K or 8K was installed. I remember on mine that a lot of the chips on the board ran quite hot, especially the 2114 RAM chips. On the Superboard ///, the only chip that gets warm at all is the 6850, which is the only non-CMOS chip on the board.
An LM3940 voltage regulator IC converts the 5V from the USB port to 3.3V. All circuitry runs on 3.3V except for the 6850 ACIA.
The USB to serial board is a low cost off the shelf FTDI board. These can be ordered from various suppliers from China and the SKU on the package matched one from http://www.banggood.com. There are some units on the market which have fake FTDI chips; this seems to be a legitimate one. It also just happens to have a blue solder mask that nicely matches the main board. It looks like Vince replaced the original right angle header on the board with a straight one, as it appears to have been hand soldered.
The DTR line of the USB to serial board goes via a cap to a transistor switch to the RESET line of the Propeller switch. This allows the Propeller to be reset from the serial port as part of the protocol for in-circuit programming. Arduino boards use a similar scheme. On Linux systems you may find that when you open the serial port it toggles DTR and resets the system, which is annoying. You can disable this using this command:
stty -F /dev/ttyUSB0 -hup -clocal raw
The Parallax Propeller chip is an interesting device that contains eight 32-bit processors which can run independently and communicate via shared memory. It has hardware on-board to assist with generating video signals in software. a serial port, and can load a program from an external serial ROM on powerup.
The Propeller CPU does some of the emulation, most notably generation of composite video in one of two video modes, and emulation of the ROM and video RAM for the 6502. It runs at 5 MHz. On reset it loads its firmware from the serial EEPROM, a 24LC256 32Kx8 serial EEPROM. This is a standard feature of the Propeller. With the Propeller development tools (which are free) you can reprogram either the Propeller or the EEPROM via the serial port from a host computer. All of the source files for the firmware are included on the Superboard /// CD.
Vince Briel, with help from Jac Goudsmit, wrote the firmware for the Propeller chip which is included on the CD. They had to use some creativity to implement the emulation in real-time and within the available pin contraints on the Propeller CPU chip. I have not looked closely at the code. It is written in the BASIC-like SPIN programming language as well as some assembly language.
The video by default is monochrome with 25 lines by 25 characters. If you hold down the BREAK key on powerup, it uses a 32x32 video mode that some models of OSI computers also supported. However, BASIC always only uses 24x24 characters for display. The Superboard /// supports the same character set font as the Superboard II, offering 255 characters including a number that could be used for games and graphics.
The BREAK key on the key board goes to an input of the Propeller so simulate reset operation. The software requires holding it down for 3 seconds to avoid accidentally hitting it. Contrary to what the manual says, on reset you do not lose any program in memory. A BASIC warm start ("W" from the boot menu) will preserve any BASIC program in memory. The random screen on powerup is simulated in software to act like the original Superboard (interestingly, the one I owned had a powerup reset circuit and did not do this, it also had a 3 second delay on the BREAK key). At the upper left of the "random screen" is the firmware version number (currently 0.06).
The serial port transmit and receive lines go to the Propeller chip. Another Propeller i/o pin directly generates the composite video output (in software). Other Propeller i/o pins control some of the address lines and the data lines for the 6502, as well as some control signals such as R/W, RESET, and CLOCK. The 1 MHz clock for the 6502 is completely generated by the Propeller in software.
The 6502 is a Western Design Center 65C02. It is clocked at 1 MHz for compatibility with the Superboard II but can run at higher speeds (mine is a 14 MHz part). It runs at 3.3V. Between the Propeller chip, glue logic, RAM, etc. it runs in a standard fashion even though some hardware like the ROM is emulated by the Propeller. Incidentally, the 65C02 has some additional instructions over the original 6502 that can be quite useful. It is backwards compatible, with the new instructions using what were invalid/unused opcode on the original 6502. It is also much lower power than the original 6502.
The RAM uses a real RAM chip rather than being emulated. It is an AS6C1008, which is a 128K x 8 chip but only 32K is used as this was the maximum that the Superboard II supported.
The 6850 ACIA provides the serial interface. This is the same chip that was used on the original Superboard II, ensuring software compatibility. It is made by Motorola and was the standard UART at the time for the 6800 series of CPUs. It is interesting that Ohio Scientific did not use the more powerful 6551 ACIA that was made by Motorola for the 6502 series (it may not have been available at the time, or possibly it was more expensive). The 6850 is the only chip that runs on +5V, and is no longer manufactured, so new old stock chips have to be obtained. Mine has a date code of 8507 (the seventh week of 1985). It runs at 9600 baud, unlike the 300 baud of the original Superboard. On the Superboard II is was usually used for the cassette tape interface. Since the baud clock is being generated by the Propeller chip, you could change it in the Propeller firmware, although there is no hardware handshaking and the 6502 when running BASIC cannot keep up to 9600 bps and needs delays added to avoid data loss.
The keyboard circuit is similar to the original Superboard II. The key switches are arranged in rows and columns. A register can select one of 8 rows of keys and drive it low. The register is then read back to detect which, if any, keys in each column of that row are pressed. The software scans each row in turn to detect key presses. This is a simple design but has some side effects, most notably that there is no latching or typeahead of keys pressed, you can only tell if a key is pressed at the time it is scanned. It does mean that you can detect if multiple keys are pressed simultaneously, and independently detect the left and right shift keys. The BREAK key is not part of the keyboard scanning circuit.
SHIFT LOCK is a latching key and is typically on to enable uppercase characters only as BASIC did not recognize lowercase characters in keywords or commands. The keyboard circuit uses a few discrete TTL chips for the read and write registers and for address decoding. The keyboard row and column signals are also brought out to a 16-pin DIP connector (not included) on the board so that you could connect an external keyboard, if desired. The original Superboard II did not have this connector.
The keys are high quality units made by Cherry, and the key caps are custom and made by WASD Keyboards. The latching SHIFT LOCK key is no longer manufactured, so when the supply runs out Vince will have to ship small slide switches instead (there is a place on the board to install one).
More address decoding is done by a 7HC138 decoder, and some of the signals go back to the Propeller CPU to help it identify when certain blocks of addresses are selected so that ROM and video memory can be emulated. This reduces the number of signals that need to go to the Propeller CPU.
A 40-pin expansion connector brings most of the important signals out so that in theory peripherals devices could be added. It is similar to the expansion connector on the original Superboard II, but uses a different connector since it is not electrically compatible with the Superboard II, using 3.3V rather than 5V levels. It would be an interesting project to interface the Superboard /// with one of the original Ohio Scientific floppy disk controllers so that it could run the disk operating system.
The original Superboard II has a cassette tape interface that ran at 300 baud and followed the Kansas City Standard for storing data on audio tapes. This circuitry is not included on the Superboard ///, as the higher speed serial port is a more convenient way to transfer files. There is a 10-pin connector that brings out the relevant signals so you could implement a tape interface if you desired.
That's pretty much it. There's not a lot of circuitry on the board, especially compared to the original Superboard II, which has to do things like generating the video using discrete logic, and used more than 70 ICs. You could even simplify the design by replacing the 6 TTL chips with a PAL, for example, but that would take away some of the retro design.
By the way, the name Superboard ///, is clearly derived from wanting to be the logical successor of the Superboard II, and calling it /// is a nod to the (infamous) Apple /// computer which was the successor to the Apple II.
Showing posts with label 65C02. Show all posts
Showing posts with label 65C02. Show all posts
Sunday, February 1, 2015
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:
And here are a couple screen shots of JMON running on the desktop version of the POM1 emulator:
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.
Below is a picture of JMON running on my Android phone:
| POM1 Running on an Android Phone |
![]() |
| 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
Tuesday, June 26, 2012
Using the 65816 Processor
The Western Design Center 65816 is a 6502 family processor. It is backwards software compatible with the 6502 and 65C02 and was used on a number of computers including the Apple IIGS.
I've been playing with one using the CPU adaptor board I built for my Replica 1.
The 65816 comes up in "emulation mode" where it is software compatible with the 6502 and 65C02. It also implements a number of new instructions, some of which are in the 65C02 and some are new ones.
You can switch the 65816 to "native mode" at any time under software control. Native mode offers 16-bit X and Y registers and accumulator, a 24-bit address space (16 megabytes), new instructions and new addressing modes. In native mode you independently configure whether the accumulator and index registers are 8 or 16-bit. Zero page (now called direct page) and the stack can be relocated anywhere in memory.
The chip is not electrically compatible with the 6502 or 65C02. The 65802 was plug-in compatible with the 6502 but is no longer being made. The 65816 is almost compatible. The adaptor I constructed makes it compatible, or at least compatible enough for the Replica 1.
There are some limitations of the adaptor: the system still only has 16 address lines so 16MB addressing is not possible. The extra 8 high order address lines are ignored. Some hardware pins are also not supported, such as SO and SYNC, but these are not used on the Replica 1.
The only compatibility issue I have run onto is with the CFFA1 compact flash adaptor. It gives an "I/O" error. I suspect it is either due to instruction timing differences or more likely the timing of the clock signals generated by the adaptor is not quite right. I need to investigate further.
Having 16-bit registers is a nice luxury and you can still use 8-bits when you need it, by switching modes, which can save speed and code size.
There are even two new memory copy instructions which can copy a range of memory, up to the full address space, in a single instruction.
I wrote three small demo programs, available here. They compile with the CA65 assembler which fully supports the 65816 instruction set. It even has a "smart" mode where the assembler tracks whether the CPU is in 8 or 16-bit accumulator and index registers modes and generates the code accordingly.
Demo 1 uses some of the new instructions in emulation mode and then switches to native mode, first with 8-bit accumulator and index registers, and then switches to 16-bit. What can be confusing is that an instruction like PHA can push 1 or 2 bytes on the stack depending on the mode selected. An instruction like LDA #$1234 is only valid in 16-bit accumulator mode. As you can imagine, existing 8-bit 6502 machine code will soon break if run in 16-bit mode.
Demo 2 uses the MVP (MOve Positive) instruction. First it copies an overlapping range of memory, demonstrating how it can be used to fill a range of memory, in this case with zeroes. Then it does the more commonly uses copy of a range of memory from one area to another. With this single instruction you can move any amount of memory up to the full 24MB address space, taking 7 cycles per byte copied.
Demo 3 is an example taken from the Western Design Center manual which determines the CPU type: 6502, 65C02, or 65816. I extended it to be a complete program which displays the result on the Replica 1.
Links
Here are some useful links related to the 65816:
- http://en.wikipedia.org/wiki/WDC_65816/65802
- http://www.zophar.net/fileuploads/2/10538ivwiu/65816info.txt
- http://www.defence-force.org/computing/oric/coding/annexe_2/
- http://www.smwiki.net/wiki/65c816
- http://www.zophar.net/documents/65816.html
The definitive manual is Programming the 65816 Including the 6502, 65C02 and 65802 and is available as a free download from Western Design Center's web site, as is the data sheet.
Monday, June 25, 2012
Replica 1 Now Running With 65816 CPU
I've now built the 65816 CPU adaptor board described here. The parts arrived last week, I finished wiring it up today, and I powered it up with the Replica 1 for the first time. I was amazed to see that it came up in the Woz Monitor.
I was a little concerned that the design was too simple, and if it did not work for some reason, it could not be made to work.
So far it looks good. I am able to run all the 6502 code I tried and my first quick test of some 65816 instructions, including going into and out of 65816 native mode, appears to work.
I built mine on a protoboard and used two 40-pin DIP headers and a short piece of ribbon cable to attach it to the Replica 1 CPU socket.
| 65815 Adaptor Board Attached to Replica 1 |
I'll report here as I learn more about the 65816 and get some code examples running on it.
Oh, and my copy of The New Apple II User's Guide arrived today from amazon.com. I'll post a review once I get a chance to read it (all 700+ pages!)
Thursday, May 10, 2012
The 65816 CPU
The 65816 is a 16-bit processor that is an enhanced version of the 65C02.
It has software compatibility with the 65C02 (and hence 6502) as well as new registers, instructions, and addressing modes. Most notably it has 16-bit registers and the ability to address 24 bits (16 megabytes) of memory. It was used in some computers such as the Apple IIGS and the chip is still manufactured by Western Design Center.
The chip is not hardware compatible with the 65C02. There was a 65802 version of the processor that was pin-compatible with the 65C02. Unfortunately, these are no longer manufactured and hard to obtain.
The 65816 and 6502 have very similar pinouts. It would be cool if you could build an adaptor to put a 65816 in a 6502 socket. A web search reveals that some designs for such an adaptor are around.
This one by Daryl Rictor dates to 2004. It uses three chips plus the 65816. It even has a PCB layout. However, it comes with the caveat "I have not actually built or tested this design. Use it at your own risk." I'm doubtful that such a circuit would work the first time (no circuit of any complexity does).
A more promising design is this one by Ruud Baltissen. He reports that he used it with a VIC-20 and it worked well. It only uses one chip in addition to the 65816.
I'm seriously thinking of building this circuit and trying it on a Replica 1. There are some limitations, like not being able to address more that 16 bits of memory, but it would be fun to try out the new instructions in the 65816. For example, there is a single instruction that can copy a range of memory. The 65816 (actually a W65C816S6PG-14) chip is under $10 from Mouser so it's not a big investment to lose if it doesn't work.
Wednesday, March 28, 2012
A 65C02 Disassembler
I just wrote a disassembler that runs on the Replica 1. I did it mostly for a personal programming challenge as there are lots of them around. Woz did one for the Apple 1 -- I think it was published in Byte and was probably the one included in the Apple II ROMs.
Years ago on my first computer (a 6502-based Ohio Scientific) I wrote one, first in BASIC and then in machine language. I remember it used a somewhat simplified format, e.g. STAX $nn for STA $nn,X and JMPI $1234 for JMP ($1344) etc. It was written on paper and hand assembled. Once I had a disassembler it made it much easier to catch errors in hand assembled code.
My implementation is in assembler, written for the CC65 cross-assembler. It supports all 65C02 mnemonics including the Western Digital only opcodes. The output is virtually identically to Krusader's disassembler. To test it I captured the output of my disassembler and Krusader's and checked for any differences.
I have a standalone version which disassembles memory a screen at a time. I also integrated it into my JMON machine language monitor program to which I added a new U (unassemble) command.
Here is a screen shot with some sample output:
| Screen Shot of Dissembler Output |
And here is an example of some 65C02 instructions being disassembled:
| some 65C02 Instructions |
I didn't look at any other disassembler implementations, but there are only so many ways to do it. About half of the information is in data structures or tables.
I have one lookup table of all the instruction mnemonics. They are 3 characters each and there are 71 of them including all the 65C02 instructions. I have another table of all 256 possible opcodes. For each opcode, the table has two entries - the instruction (an index into the previously described table) and an entry listing the addressing mode. Thus, for a given op code, say $EA, I can look up in the table that is is a NOP instruction, using implicit addressing mode, and the mnemonic is "NOP". Another small table lists the number of instruction bytes for each addressing mode. For example, for implicit addressing it is one byte. There are 16 possible addressing modes.
I initially included the number of instruction bytes in the table of opcodes until I realized that for a given addressing mode it was always the same so I could use a small lookup table based on the addressing mode.
The major part that is hardcoded rather than in tables is the logic that displays the instruction operands appropriately given the addressing mode. The total size is about 1.5K including all utility routines of which a little over half is code and the rest is data. It will run out of ROM if desired.
If one really wanted to optimize the code for size I suppose you could reduce the size of the opcode table by taking advantage of the fact that over a quarter of it is not valid opcodes (instructions ending with hex value 3, 7, B, and F, for example) but this would complicate the logic for the table lookup, and once you add 65C02 instructions many of the invalid opcodes are used.
Adding 65C02 support did not add much code although handling the SMB, RMB, BBR, and BBS instructions was a little complex due to the funky format they have.
I put in an assemble time option so that the output can contain only the instructions and not the memory data bytes, so you could feed the output into an assembler. Here is an example of it running in that mode:
JSR $0540
LDX #$94
LDY #$08
JSR $0579
JSR $0540
LDA #$80
STA $37
LDA #$02
STA $38
JSR $0540
LDA #$17
PHA
JSR $02B7
PLA
SEC
SBC #$01
BNE $029A
LDX #$6F
LDY #$08
JSR $0579
JSR $055F
CMP #$20
BEQ $0295
The code is licensed under Apache license so you are free to use it if you wish. This first version can be considered beta -- it is complete but may still have bugs.
The standalone version and the version of JMON with the disassembler can be downloaded from these link:
https://docs.google.com/open?id=0B54TLlZjWIytQ2duZThPR1hSLWV4ekllencwV29VZw
Labels:
6502,
65C02,
Apple 1,
Disassembler,
Replica 1
Saturday, March 3, 2012
The 65C02
The 65C02 microprocessor is an upgraded CMOS version of the MOS Technology 6502 8-bit CPU. Over the years it has been manufactured by Western Design Center, NCR, GTE, Rockwell, Synertek and Sanyo. It is electrically compatible with the 6502 and offers lower power consumption due to the use of CMOS technology.
The most interesting feature is that it supports some new instructions. The references listed later cover this in more detail, but briefly the new features are:
Four additional instructions are available on 65C02s manufactured by Rockwell and WDC:
Two additional instructions are available on 65C02s manufactured by WDC:
Any unused opcodes are handled as NOPs by the 65C02 (with the 6502 the behaviour was undocumented).
Your Replica 1 may have come with a 65C02. If not (mine didn't) you can order one and replace the 6502 with a 65C02. While no longer manufactured, it is available as NOS (New Old Stock) from suppliers such as Jameco. I ordered one and received a Rockwell R65C02P2 which can run up to 2 MHz and has a date code from 2003.
Some computers, such as the Apple IIc, shipped with a 65C02. The Apple 2GS, last of the Apple 2 series, used a 16-bit version of the 6502 processor called the 65C816.
The 65C02 will continue to run all existing 6502 code but you can also experiment with the new 65C02 instructions. You CPU will also consume less power and run cooler.
The version of the Krusader Assembler burned into ROM on the Replica 1 does not support the 65C02 but there is a 65C02 version. You can download that version from here and program it into an EPROM (if you have the facility to do so) or run it from RAM.
One quirk of Krusader: it wants the INC and DEC instructions to be called INA and DEA. It also doesn't support the Rockwell/WDC-specific instructions BBR, BBS, SMB. and RMB or the WDC-only STP and WAI.
Here is a screen shot showing Krusader assembling some 65C02 code:
And disassembling:
The CA65 cross-assembler also supports 65C02 instructions. You need to use the processor directive .PSC02 to enable it. Below is an assembler listing showing some 65C02 instructions (the code does not do anything meaningful):
ca65 V2.13.3 - (C) Copyright 1998-2012 Ullrich von Bassewitz
Main file : 65c02.s
Current file: 65c02.s
000000r 1 .PSC02
000000r 1 80 00 BRA next
000002r 1 65 01 next: ADC $01
000004r 1 25 02 AND $02
000006r 1 C5 03 CMP $03
000008r 1 45 04 EOR $04
00000Ar 1 A5 05 LDA $05
00000Cr 1 05 06 ORA $06
00000Er 1 E5 07 SBC $07
000010r 1 85 08 STA $08
000012r 1 89 12 BIT #$12
000014r 1 34 34 BIT $34,X
000016r 1 3C 78 56 BIT $5678,X
000019r 1 3A DEC
00001Ar 1 1A INC
00001Br 1 DA PHX
00001Cr 1 5A PHY
00001Dr 1 FA PLX
00001Er 1 7A PLY
00001Fr 1 64 12 STZ $12
000021r 1 74 12 STZ $12,X
000023r 1 9C 56 34 STZ $3456
000026r 1 9E 56 34 STZ $3456,X
000029r 1 14 12 TRB $12
00002Br 1 1C 56 34 TRB $3456
00002Er 1 04 12 TSB $12
000030r 1 0C 56 34 TSB $3456
References
Finally, here are some good references for information on the 65C02:
The most interesting feature is that it supports some new instructions. The references listed later cover this in more detail, but briefly the new features are:
- a new zero page addressing mode for ADC, AND, CMP, EOR, LDA ORA, SBC, and STA instructions
- new accumulator DEC and INC instructions
- JMP (abs,X) addressing mode
- BRA (branch always) instruction
- PHX PHY PLX PLY (push or pull X or Y register)
- STZ (store zero) instruction
- TRB (test and reset bits) instruction
- TSB (test and set bits) instructions
Four additional instructions are available on 65C02s manufactured by Rockwell and WDC:
- BBR BBS (branch on bit reset or set)
- RMB SMB (reset or set memory bit)
Two additional instructions are available on 65C02s manufactured by WDC:
- STP (stop the processor)
- WAI (wait for interrupt)
Any unused opcodes are handled as NOPs by the 65C02 (with the 6502 the behaviour was undocumented).
Your Replica 1 may have come with a 65C02. If not (mine didn't) you can order one and replace the 6502 with a 65C02. While no longer manufactured, it is available as NOS (New Old Stock) from suppliers such as Jameco. I ordered one and received a Rockwell R65C02P2 which can run up to 2 MHz and has a date code from 2003.
| 65C02 on Replica (along with original 6502) |
The 65C02 will continue to run all existing 6502 code but you can also experiment with the new 65C02 instructions. You CPU will also consume less power and run cooler.
The version of the Krusader Assembler burned into ROM on the Replica 1 does not support the 65C02 but there is a 65C02 version. You can download that version from here and program it into an EPROM (if you have the facility to do so) or run it from RAM.
One quirk of Krusader: it wants the INC and DEC instructions to be called INA and DEA. It also doesn't support the Rockwell/WDC-specific instructions BBR, BBS, SMB. and RMB or the WDC-only STP and WAI.
Here is a screen shot showing Krusader assembling some 65C02 code:
| Krusader Assembling 65C02 Code |
And disassembling:
| Krusader Disassembling 65C02 Code |
The CA65 cross-assembler also supports 65C02 instructions. You need to use the processor directive .PSC02 to enable it. Below is an assembler listing showing some 65C02 instructions (the code does not do anything meaningful):
ca65 V2.13.3 - (C) Copyright 1998-2012 Ullrich von Bassewitz
Main file : 65c02.s
Current file: 65c02.s
000000r 1 .PSC02
000000r 1 80 00 BRA next
000002r 1 65 01 next: ADC $01
000004r 1 25 02 AND $02
000006r 1 C5 03 CMP $03
000008r 1 45 04 EOR $04
00000Ar 1 A5 05 LDA $05
00000Cr 1 05 06 ORA $06
00000Er 1 E5 07 SBC $07
000010r 1 85 08 STA $08
000012r 1 89 12 BIT #$12
000014r 1 34 34 BIT $34,X
000016r 1 3C 78 56 BIT $5678,X
000019r 1 3A DEC
00001Ar 1 1A INC
00001Br 1 DA PHX
00001Cr 1 5A PHY
00001Dr 1 FA PLX
00001Er 1 7A PLY
00001Fr 1 64 12 STZ $12
000021r 1 74 12 STZ $12,X
000023r 1 9C 56 34 STZ $3456
000026r 1 9E 56 34 STZ $3456,X
000029r 1 14 12 TRB $12
00002Br 1 1C 56 34 TRB $3456
00002Er 1 04 12 TSB $12
000030r 1 0C 56 34 TSB $3456
References
Finally, here are some good references for information on the 65C02:
Subscribe to:
Posts (Atom)


