Retro Challenge update #7

HD6309_computer_30_4_2017_2_small

Today is the last day of the Retrochallenge 2017/04! Yesterday I tried to get the HD6309 computer up and running. The short version is that it still doesn’t run properly but it is “doing things”. By this I mean it behaves erratically.

When ordering the components, the AT28C64B I had planned to use was out of stock, so I ordered an AT28C256. They come in the same DIP28 package and use two additional pins (1 and 26) for addressing that are labeled not connected on the AT28C64B. So I wired those to ground on the back of the board.

To test the board, I wrote a program that lights up the LEDs connected to OUT1 and OUT2 pins of the SC16C550 UART and continuously sends 0xAA on the TX line. This seems like a small test but for this to work, the CPU, ROM, UART and two GALs must be fully working. Of course, it “didn’t work”.

Using an oscilloscope, I checked for clock signals. They were all there. Then I checked to see if the CPU was toggling its address lines: yes! The ROM_CS and IO_CS lines on the memory decoder GAL are next. Yes, they have activity too! So its very likely the program is actually running and trying to access the UART.

The SC16C550B UART

At this point, the main suspect is the UART. So I started looking at the schematic to see if I had made any mistakes in connecting up the data lines, address lines or the read/write lines. They all seemed fine. The I spotted a potential mistake… Can you see it?

UART_reset_problem

Anyone, anyone? Bueller? The reset pin on the component does not have a negation bar but the driving reset signal does. It is very uncommon to have an active high reset but I’m also quite meticulous when it comes to making schematic symbols. To be sure this is a problem, I checked the SC16C550B datasheet:

UART_reset_problem_datasheet

It is indeed an active high reset! So, I cut the reset trace going to the UART on the back of the board and connected it to ground. This way, the UART won’t be reset but I hope by writing to all the necessary registers I can put the UART in a defined state. This assumes that the UART doesn’t contain any internal/non-accessible flip-flops that need to be reset for it to function properly.

Almost working?

With the UART reset fix in place, I tried again. Something is happening on the UART TX line but the LEDs still won’t light up :-/ . At least the UART is doing something!

The first thing to check is the baud rate. Using my oscilloscope I measured the on time of the narrowest part of the bit pattern. Remember I’m sending 0xAA? I chose that because the bit pattern is ‘10101010’, which is ideal for measuring.

I expected to be close to 9600 baud, but it was way off! Hmm, that’s not a good sign. The registers of the UART aren’t receiving data correctly or correct data. This also explains why the LEDs aren’t lighting up. To make matters worse, the behaviour of the system changes every time I press the reset button.

The reset line has a 10uF timing capacitor on. This gives a long reset time but it also means that the voltage on the reset pin rises very slowly — too slowly perhaps. So I replaced the capacitor with a 100nF one. This didn’t fix the problem.

As an extra precaution, I inserted some NOP instructions between the UART accesses to increase the time between writes. That did seem to change the behaviour but everything is still unpredictable.

Unfortunately, this is one of those cases where a lot of things can cause this. Here’s a list of causes in order of hopefulness:

  1. The UART interface won’t work properly without a reset pulse.
  2. Bad solder joints.
  3. The data or address lines aren’t stable when data is written to UART.
  4. The CPU isn’t reading the ROM correctly.
  5. The CPU isn’t working properly.

Next up…

I’ll first try and see if I can write data to the 8-bit expansion port. This will give me an idea if the bus timings are okay and that the CPU is behaving correctly.

Retro Challenge update #6

Yesterday was our king‘s birthday and everything stops, including delivery services. The PCB and components I needed for the HD6309 computer still hadn’t turned up. I did have tracking available on both packages, but until the last minute, they kept showing May 1st. Luckily, this afternoon, both packages arrived!

I quickly assembled the board. It went well, except for soldering the 12MHz CPU oscillator; I ordered the wrong package :-/ — it’s a lot smaller than the 7x5mm footprint I used. The UART has a 7+ MHz oscillator with 7x5mm footprint so I think I’ll use that.

After assembling the board, the first thing I checked is that there were no shorts. Without fitting the CPU, EPROM and GALs, I applied 5V to the board. Setting a very low current limit is advisable to save components from releasing their magic smoke. The current meter on my power supply is an old analogue one with a bent needle; I estimate the current to be around 20 mA. This is to be expected as there is a power LED:

hd6309_computer_pcb_28_4_2017

So far so good!

Next up…

I have the programming files for the memory decoder GAL done. I need to create the IO decoder GAL files, create a few additiona test programs, and adapt the bootloader I showed previously to use the SCC16C550 UART.

Lots to do, so little time!

 

Retro Challenge update #5

This week I exchanged the Z80 core in my RC2014 Z80 computer emulator, with an MC6809 core. I couldn’t seem to find a decent HD6309 core but, as you probably know from the previous blog posts, the HD6309 will run MC6809 binaries! For the time being, I’ll have to live without all the fancy new HD6309 instructions in the emulator but at least I’ll be able to write simple programs for the HD6309 computer.

The hardware the emulator mimics is just the MC6809 core and a very simple UART. The UART isn’t based on any existing design but has a simple interface. It has a transmit and receive register and a status register for the transmitter and receiver. The UART serves as a placeholder for the actual SC16C550B UART. I’ll adapt the bootloader to suit the actual hardware later. The first goal is to get a simple bootloader working.

6809/6309 instruction set

I had never programmed in 6809 assembler until this weekend ūüôā . The only CPUs I have assembler experience with is the Z80, AVR, ARM Cortex and 16-bit/32-bit x86. They have a very different notation, especially when it comes to the addressing modes.

For instance, loading the AX register with the memory contents of the address in the DI register on the x86 is:

MOV AX,ES:[DI]

On the 6809/6309, loading the A register with the memory contents of the address in the X register is:

LDA ,X

The 6809 will also allow you to increment the X register by one in the same instruction:

LDA ,X+

or by two:

LDA ,X++

I also created a few bugs related to immediate versus indirect loads. On the 6809/6309, loading the X register with a number ($1234), the syntax should be:

LDX #$1234

and not:

LDX $1234

which will load the 16-bit register X with the memory contents at address $1234.

It seems that there aren’t very many online resources that have example programs for the 6809/6309, so it took me a while to get the details figured out. I must say that, even without the additional 6309 instructions, the capabilities of the 6809 are already impressive.

Bootloader

The bootloader is nothing fancy. It checks the RAM (0x0000 .. 0xDFFF) by writing the all-zeros and all-ones pattern to each location and reads it back. If the memory check fails, it will send ‘E’ to the UART and stop. It will continue if the test was successful.

The next step is to setup the stack pointer, so we’re able to call subroutines, and write the startup banner to the UART to show the operator the computer is working.

The loader will wait for a two-byte start address and a two-byte end address, describing the block of memory to be loaded. The addresses are formatted most-significant byte first. The start and end addresses are printed to the console via the UART.

After obtaining the start and end addresses, the loader expects to receive the bytes that make up the memory block. The end address is one byte past the block; it does not get written. When the block is complete, the loader jumps to the start of the block.

; HD6309 COMPUTER - Retrochallenge 04/2017
;
; BOOTLOADER V1.0
; By Niels A. Moseley
;

; ==================================================
; SYSTEM CONSTANTS
; ==================================================

RAMSTART  EQU $0000
RAMEND    EQU $E000
STACK     EQU $DFF0

; ==================================================
; UART ADDRESSES
; ==================================================
SERIALTX  EQU $E000
SERIALRX  EQU $E001
SERIALTXS EQU $E002
SERIALRXS EQU $E003


; ==================================================
; MONITOR ADDRESSES
; ==================================================
LDENDADDR EQU $DFFE
JMPADDR   EQU $DFFC

    ORG $F000   ; START OF ROM

; ==================================================
; OUTPUT A CHARACTER TO THE CONSOLE
; BLOCKS ON UART TX FULL
; ==================================================
OUTC:
    PSHS B
OUTC_1:
    LDB SERIALTXS
    BNE OUTC_1
    STA SERIALTX
    PULS B
    RTS

; ==================================================
; GET A CHARACTER FROM THE CONSOLE
; BLOCKS ON UART RX EMPTY
; ==================================================    

INBYTE:
    PSHS B
INBYTE_1:
    LDB SERIALRXS
    BEQ INBYTE_1
    LDA SERIALRX
    PULS B
    RTS

; ==================================================
; WRITE A REGISTER AS HEX TO UART
; BLOCKS ON UART TX FULL
; ==================================================        
PRINTAHEX:
    PSHS A
    PSHS A
    ; convert MS nibble
    LSRA
    LSRA
    LSRA
    LSRA
    CMPA #9
    BLS PRINTAHEX_1
    ADDA #7             ; 'A'-'9'-1 : 65 - 57 - 1 = 7
PRINTAHEX_1:
    ADDA #'0'
    JSR OUTC
    ; convert LS nibble
    PULS A
    ANDA #$0F
    CMPA #9
    BLS PRINTAHEX_2
    ADDA #7
PRINTAHEX_2:
    ADDA #'0'
    JSR OUTC
    PULS A
    RTS

; ==================================================
; PRINT STRING POINTED TO BY X
; BLOCKS ON UART TX FULL
; ==================================================     
PRINTSTRING:
    PSHS A
PRINTSTRING_1:
    LDA ,X+
    BEQ PS_END
    JSR OUTC
    JMP PRINTSTRING_1
PS_END:
    PULS A
    RTS
    
; ==================================================
; DUMMY INTERRUPT SERVICE ROUTINE
; ==================================================

DUMMYISR:
    RTI
    
; ==================================================
; START OF PROGRAM
; ==================================================

START:
    ORCC #%01010000 ; disable interrupts
    
    ; CHECK MEMORY 0 .. 0xDFFF
    LDX #RAMSTART
MEMCHKLP:
    CLRA
    STA ,X
    LDA ,X
    CMPA #$00
    BNE MEMERROR     ; jump if not zero
    LDA #$FF
    STA ,X
    LDA ,X+
    CMPA #$FF
    BNE MEMERROR     ; jump if not equal
    CMPX #RAMEND
    BNE MEMCHKLP
    JMP MEMOK
    
MEMERROR:
    LDA #'E'
    STA SERIALTX
STOP:    
    JMP STOP
    
    ; PRINT THE SIGN-ON MESSAGE
MEMOK:    
    LDS #STACK      ; LOAD THE STACK
    LDX #SIGNON
    JSR PRINTSTRING

; ==================================================    
; START OF UPLOAD CODE
; ==================================================    
;
; PROTOCOL:
; * LOAD START ADDRESS, MSB FIRST
; * LOAD END ADDRESS, MSB FIRST
; * DATA 
; * JUMP TO START ADDRESS
;   
    
BOOTLOADER:
    CLRB
    JSR INBYTE
    TFR A,B    
    JSR INBYTE
    EXG A,B
    STD JMPADDR ; store jump address

    ; print the load address
    LDX #LOADADDRSTR
    JSR PRINTSTRING
    JSR PRINTAHEX
    EXG A,B
    JSR PRINTAHEX
    LDX #EOLSTR
    JSR PRINTSTRING
    
    ; get end address bytes
    JSR INBYTE
    TFR A,B
    JSR INBYTE
    EXG A,B    
    STD LDENDADDR   ; store length
    
    ; print the end address
    LDX #ENDADDRSTR
    JSR PRINTSTRING
    JSR PRINTAHEX
    EXG A,B
    JSR PRINTAHEX
    LDX #EOLSTR
    JSR PRINTSTRING
    
    ; load the program
    LDX JMPADDR
LOADLP:
    CMPX LDENDADDR
    BEQ LDEND
    JSR INBYTE
    STA ,X+
    JMP LOADLP
        
LDEND:
    LDX #LOADEDSTR
    JSR PRINTSTRING
    JMP [JMPADDR]

SIGNON:
    .db 12                              ; form feed
    .ascii "HD6309 Bootloader v1.0"
    .db 13,10
    .ascii "By Niels Moseley"
    .db 13,10,0
    
LOADADDRSTR:
    .asciz "Start: $"

ENDADDRSTR:
    .asciz "End  : $"

LOADEDSTR:
    .ascii "Loaded!"    ; note: must be followed by 13,10,0!!
EOLSTR:    
    .db 13,10,0
    
; ==================================================    
; RESET AND INTERRUPT VECTOR TABLE
; ==================================================

    ORG $FFF2
SWI3VECTOR:  FDB DUMMYISR
SWI2VECTOR:  FDB DUMMYISR
FIRQVECTOR:  FDB DUMMYISR
IRQVECTOR:   FDB DUMMYISR
SWIVECTOR:   FDB DUMMYISR
NMIVECTOR:   FDB DUMMYISR
RESETVECTOR: FDB START


The mandatory screenshot of the bootloader running in the emulator, waiting for the start address:

emulator_bootloader

A simple test program

I wrote a simple test program to test the bootloader. It prints a simple banner and echos all the characters coming in from the UART.

; ==================================================
; SYSTEM CONSTANTS
; ==================================================

RAMSTART  EQU $0000
RAMEND    EQU $E000
STACK     EQU $DFF0

; ==================================================
; UART ADDRESSES
; ==================================================
SERIALTX  EQU $E000
SERIALRX  EQU $E001
SERIALTXS EQU $E002
SERIALRXS EQU $E003


    ORG $0000   ; START OF RAM

    JMP START
    
; ==================================================
; OUTPUT A CHARACTER TO THE CONSOLE
; BLOCKS ON UART TX FULL
; ==================================================
OUTC:
    PSHS B
OUTC_1:
    LDB SERIALTXS
    BNE OUTC_1
    STA SERIALTX
    PULS B
    RTS

; ==================================================
; GET A CHARACTER FROM THE CONSOLE
; BLOCKS ON UART RX EMPTY
; ==================================================    

INBYTE:
    PSHS B
INBYTE_1:
    LDB SERIALRXS
    BEQ INBYTE_1
    LDA SERIALRX
    PULS B
    RTS

; ==================================================
; WRITE A REGISTER AS HEX TO UART
; BLOCKS ON UART TX FULL
; ==================================================        
PRINTAHEX:
    PSHS A
    PSHS A
    ; convert MS nibble
    LSRA
    LSRA
    LSRA
    LSRA
    CMPA #9
    BLS PRINTAHEX_1
    ADDA #7             ; 'A'-'9'-1 : 65 - 57 - 1 = 7
PRINTAHEX_1:
    ADDA #'0'
    JSR OUTC
    ; convert LS nibble
    PULS A
    ANDA #$0F
    CMPA #9
    BLS PRINTAHEX_2
    ADDA #7
PRINTAHEX_2:
    ADDA #'0'
    JSR OUTC
    PULS A
    RTS

; ==================================================
; PRINT STRING POINTED TO BY X
; BLOCKS ON UART TX FULL
; ==================================================     
PRINTSTRING:
    PSHS A
PRINTSTRING_1:
    LDA ,X+
    BEQ PS_END
    JSR OUTC
    JMP PRINTSTRING_1
PS_END:
    PULS A
    RTS
    
; ==================================================
; START OF PROGRAM
; ==================================================
    
START:
    ORCC #%01010000 ; disable interrupts    
    LDS #STACK      ; LOAD THE STACK
    LDX #SIGNON
    JSR PRINTSTRING
    
    ; echo input to the output
ECHOE:
    JSR INBYTE
    JSR OUTC
    JMP ECHOE
    
SIGNON:
    .ascii "Hello from a loaded program!"
    .db 13,10,0,0

And here is the screenshot of it working in the emulator:

emulator_bootloader2

Toolchain

I’m using the LWTOOLS toolchain. I’m pretty impressed by the quality of the software. Although I haven’t tried them yet, it does offer support for the additional instructions the HD6309 offers over the MC6809.

Up next…

I’m running a little behind; I still need to make the configuration files for the GALs and order most of the components. This will be unnecessary if the PCB does not arrive on time — fingers crossed!

P.S. This week I’ll create a repository on my GITHUB account that will hold the emulator source code and the two 6809 programs; stay tuned!

 

Retro Challenge update #4

Today I finished the PCB layout of the HD6309 computer! As expected, it took longer than expected to route all the signals of the board. To make life a little easier, I did the pin swapping dance in KiCAD more than a few times, especially on the ATF16V8 GALs. This is the final design:

HD6309_PCB_final

The board is a mix of through-hole and surface mount (SMD) parts. Many hobbyists shy away, almost religiously, from using SMD. After practicing a few times, I can solder 0805 resistors and capacitors, and QFP packages down to 0.5mm (I haven’t tried smaller yet) pin pitch with ease! Full disclosure: I have had cataract surgery on both eyes and have trembling hands; if I can do it, you can too. All that is needed is a cheap hot air station, such as the Atten 858D, some tweezers and flux. Having solder paste in a syringe makes solder 0805 resistors and capacitors easier. I don’t use a microscope — I only have small monocular that I use for final inspection.

To solder the LQFPs and TSSOPs, I use the following steps:

  1. apply flux to the PCB.
  2. using a regular iron, apply solder to all the pads.
  3. align the part with the pads and use a regular soldering iron to tack one or two pins to keep the part in place.
  4. if needed, check the part alignment with a magnifying glass and repeat step 3 if alignment is not to your liking.
  5. apply flux to pins of IC.
  6. heat the part and PCB with the hot air station until all pins have been soldered.
  7. if needed, check pins using a magnifying glass.
  8. touch pins that haven’t been soldered properly with a regular iron (rarely needed).

I don’t use the drag soldering technique or an SMD stencil with solder paste because I find it bends the pins or produces solder bridges.

This static RAM expansion board was done using the technique outlined above:sram_example

Up next

The board is on its way to Eurocircuits.com and will be returned to me on the 27th of April, which leaves very little time to populate the board and test everything :-/

For the time being, I’ll concentrate on programming the ATF16V8B GALs, write an emulator and create a UART bootloader for the HD6309 computer.

Hmm, I should really think of a name for this project.. Any suggestions?

Retro Challenge #3

The HD6309 computer’s schematic is getting to a stage where I can share it. Beware, it most likely will contain errors!HD6309P_Schematic_8_4_2017

Here is a PDF version: HD6309 Computer schematic.

Schematic walkthough

At the top left is the HD6309 processor. I have kept the interface complexity to a minimum. The memory interfaces are fast enough to do away with wait-states, so the MRDY is tied to VCC as are the IRQ and NMI interrupt signals. Only the fast interrupt signal is currently used (by the UART). In this design, DMA support is not used, so BS and BA are ignored, and DMA/BREQ is tied high. The CPU halting capability, useful for single-stepping the CPU, is also not used and tied high to VCC.

The top level address decoding is handled by U4, an ATF16V8B programmable logic chip (GAL). I have a few of these and they should program fine with my TL866 programming. Note: the ATF16V8C does not!

The decoder emits chip select signals for the RAM, ROM and IO spaces. In addition, it creates separate READ and WRITE signals from the CPU’s R/W and E signal. The documentation mentions the need for gating R/W with E to avoid writing incorrect values into the RAM or peripherals. This is done inside the GAL.

The GAL also generates the signals (RAM_MAP and RAM_FIX) for the memory mapper. The top address bits (A15..A19) of the 1MB static RAM are set to the all-zero word by the 74HC(T)541 line driver (U8) or to a programmable word by the 74HC(T)574 register (U7). The contents of register U7 can be set by the CPU.

The IO space is decoded by a second ATF16V8B GAL (U2). It generates the chip selects for the SC16C550B UART (U11) and the buffered expansion port (P3 and P4). Note the different number of pins on the two connectors. This was done so that a user would have no problems knowing which way ’round to plug in an expansion board.

The interrupt line of the UART is connected to /INT of the CPU through a transistor. The transistor provides the needed inversion and it’s also an open collector output so other devices can pull /INT low, should this be needed in the future.

An 8K EEPROM (U12) is connected to the CPU. Only the top 4K of this memory is mapped into the address space of the CPU, at $F000.

Will it float or will it sink?

Using programmable logic for address decoding and other essential parts of the circuit de-risks the design to a large extent. Murphy, of course, dictates that the flexibility will be in the wrong part of the circuit ūüôā

The next step is to layout a PCB for the computer. I hope I can get the design out the door in time to build a working computer before the end of April!

Next time: layout of the PCB!

Retro Challenge #2

Memory layout

chip

In the last article, I mentioned the fact that there are no special IO instructions that handle peripherals. This choice on the part of the microprocessor designers is understandable: Why spend time=money on IO instructions when the MC6809/HD6309 has a rich set of memory addressing modes?

This decision does, however, reduce the maximum available program memory from a full 64K to something less. How much less depends on the complexity of the address decoding scheme: full or partial decoding.

In a fully decoded address decoder, all address lines (A0..A15) are used by the decoder so it can uniquely assign addresses to a peripheral or memory chip. Most small designs choose to simplify the address decoder by using only a few address lines, say A13..A15. This means that addresses are partitioned in blocks, in this case blocks of 16K.

Using this scheme, each block of address space can be assigned to a single chip, such as a RAM, ROM or peripheral. This coarse division is not a problem for memory; we want to have large blocks of ROM and RAM. For peripherals, however, the story is different. For example, it is wasteful to assign a 16K block just to address a UART.

Luckily, we can subdivide one block by adding a second address decoder.When the first address decoder detects the address falls within this block, it activates the second address decoder. This decoder uses the lesser significant address lines to select smaller blocks, or even individual addresses if desired. In this way, we can make more efficient use of the address space, while keeping the address decoder logic simple.

Address space of the HD6309 computer

We know from the HD6309 datasheet that the interrupt vector table, including the reset vector, resides at the very top of memory. If we have a block of RAM there, we’ll have a problem with booting the system because the RAM will contain gibberish at startup: a ROM is needed there to supply a reset vector. However, the ROM will also contain the various other interrupt vectors. The HD6309, unlike more modern processors, does not provide a way to relocate the interrupt vector table, making them fixed — quite inflexible! We’ll have to revisit that issue another time.

Apart from the top most address positions containing the reset and other vectors, we’re free to divide the address space the way we see fit. So, I’ve come up with a few features I’d like to have:

  • A banked RAM system, to allow more than 64K to be used.
  • A 4K ROM at the top of memory to supply the vector table and a few support routines.
  • A fixed/unmapped portion of RAM to allow for an operating system to save its stack and other context data.
  • Use a Microchip/Atmel ATF16V8B GAL as the first address decoder to reduce the IC count.
  • Use a second address decoder to subdivide I/O addressing space.

Given these features I arrived at the following memory map:

memlayout

The 32K paged RAM block can be swapped out for any one of multiple 32K RAM blocks in a large, i.e. >64K, RAM. This will be done by a special peripheral, consisting of an N-bit register. The register will provide the top N bits to the RAM chip. When the CPU accesses the fixed RAM portion, the top N bits to the RAM will be set to zero.

With the proposed layout, we’ll have a total of 56K simultaneously addressable RAM!

That’s all for this time! Next up: schematics!

Retro Challenge #1

Today is April 1st; the start of the Retro Challenge 2017/04! (no joke).

During this Retro Challenge period, I am going to design and hopefully build a working computer around the HD6309 8-bit CPU.

I had ordered HD63C09P and HD63C09EP devices from different sellers on eBay. Some of the HD6309 CPUs showed up on my doorstep yesterday! Perfect timing!

HD6309P

Details of the HD63C09P

The Hitachi HD6309 is a powerful 8-bit microprocessor that is an enhanced version of the well-known Motorola MC6809. The processor is pin compatible with the MC6809. Although there are some subtle differences, systems designed for the MC6809 will most likely also run with an HD6309.

63C09P_pinout

HD6309P pinout

There are two versions of the HD6309; one with a built-in crystal oscillator/clock generator and one without. The latter version has the letter ‘E’ in the suffix of the part name, which probably means ‘External’. While the ‘E’ version is more flexible, it is also harder to use because it requires an externally generated quadrature clock and DMA handling logic — buyer beware!

The version I have is the HD63C09P, with the ‘C’ indicating that it will run at an internal clock rate of 3 MHz. The internal clock is generated from a 4x higher external clock or crystal connected to the XTAL and EXTAL pins.

The address space is 64K and all peripherals are memory mapped. Slow memory or peripherals can be accomodated by stretching the clock using the MRDY pin. The datasheet states that the maximum stretch duration is 5 microseconds. While this may be correct for the MC6809, I doubt this is true for a fully-static CMOS design like the HD6309.

What goes where in memory is mostly up to the system designer, except for the HD6309 interrupt vector table. This is fixed at the top of the memory map:6309_vectors

Two signals, BA and BS, tell the user about the state of the processor:6309_state

These signals are used by external DMA logic to figure out when the bus is available for use by another bus master.

Internal structure

The internal structure of the HD6309 is shown by the figure below:

hd6309_internals.png

Note that this figure, taken from the official datasheet, does not show the extended features of the HD6309. It seems these features were never officially documented by Hitachi.

The programming model, showing the registers, is shown in the following figure:

HD6309_programming_model

Again, this is a copy from the official documentation. The HD6309 contains several additional registers not shown.

The 6309 has a two 8-bit accumulators (A and B) for computational use. These accumulators can by combined to form a 16-bit accumulator ‘D’. In addition, two 16-bit index registers, X and Y, are available for easy memory access. The CPU also has two stack pointers, S and U.

Extensions

The HD6309 has more registers and instructions than a MC6809. Here is a brief overview of them:

  • Two additional 8-bit registers: E and F.
  • An additional 16-bit register W formed by combining E and F.
  • A 32-bit register Q formed by combining D and W.
  • 16×16 multiplication instruction.
  • 32/16 bit and 16/8 bit hardware division instructions.
  • Interruptable memory-to-memory block moves.
  • Inter-register arithmetic and logical operations.
  • Byte manipulation instructions.
  • Single-bit operations.
  • Several new indexed addressing modes.
  • Illegal opcode trap interrupt.
  • Division-by-zero trap interrupt.
  • 16-bit arithmetic instructions.

When the 6309 starts or is reset, the CPU is in emulation mode; it behaves mostly as a 6809. Through a set of special instructions, the 6309 can be switched into native mode. In native mode, a few additional features become available and many instructions execute in fewer clock cycles.

You can find more information about all the different enhancements in ‘ The 6309 Book: Inside the 6309‘ by Chris Burke.

Related literature

Next..

This post was a general overview of the hardware and software capabilities of the HD6309 processor, mainly to get myself acquainted with the HD6309. The next steps are to figure out which peripherals are needed and what the memory map of the computer will look like.