Bootstrapping an SBC

Topics related to the SBC- series of printed circuit boards, designed by Daryl Rictor and popular with many 6502.org visitors.
User avatar
BigEd
Posts: 11463
Joined: 11 Dec 2008
Location: England
Contact:

Bootstrapping an SBC

Post by BigEd »

It's often seen as a stumbling block that EPROM programmers are expensive, and yet an SBC needs somehow to have some software to get started.

One approach is to use a single-stepping circuit and toggle the bootstrap into RAM. This is historically authentic but error-prone and tedious!

If the SBC uses an EEPROM, it could be made to be programmable in-place(*), once you've got a way to get your code into the SBC.

Or, combining the two approaches, it would be possible to toggle the bootstrap into EEPROM, so you only need to get it right once.

But in any case the bootstrap should be short. I found myself wondering how short, and this is what I came up with - 27 bytes of utterly untested machine code!

Code: Select all

        ;; sketch of a minimal bootstrap
        ;; suitable to be toggled into an eeprom
        ;; loads up to 256 bytes, to be placed in zero page
        ;; this is minimal! no error checking!
        ;;
        ;; this bootstrap will load a bigger second-stage bootstrap from serial port
        ;; a typical second stage might load a monitor in srecord format
        ;;

        .ORG $FFE5 ; (manually) place the bootstrap up against the reset vector (Edit: Nope! 2 bytes out!)

        ;; for info on 6850 see http://www.electronics.dit.ie/staff/tscarff/6800/6850acia/6850.htm
        .DEFINE         SERIAL_STATUS_REG  $FE08
        .DEFINE         SERIAL_DATA_REG    $FE09

        .DEFINE         EOF                $EA   ; NOP opcode to indicate end of program
                                                 ; (must avoid this value even as a data byte)

bootstrap:
        ; master-reset the UART
        LDA #$03
        STA SERIAL_STATUS_REG

        LDX #0
readbyte:
        LDA SERIAL_STATUS_REG   ; bit 0 tells us if there is a byte to read
        ROR
        BCC readbyte
        LDA SERIAL_DATA_REG
        CMP #EOF    ; check for end of second stage
        BEQ 65536   ; jump to second stage at bottom of zero page
        STA 0,X
        INX
        BNE readbyte

        .word bootstrap  ; the 6502 reset vector
In hex, that's

Code: Select all

FFE5   A9 03
FFE7   8D 08 FE
FFEA   A2 00
FFEC   AD 08 FE
FFEF   6A
FFF0   90 FA
FFF2   AD 09 FE
FFF5   C9 EA
FFF7   F0 07
FFF9   95 00
FFFB   E8
FFFC   D0 EE
FFFE   E5 FF
Any comments or ideas on bootstrapping?

(*) Edit: I think some EEPROMs are particularly easy to program, but I might be mistaken.
Last edited by BigEd on Tue Feb 09, 2010 7:07 pm, edited 1 time in total.
User avatar
8BIT
Posts: 1787
Joined: 30 Aug 2002
Location: Sacramento, CA
Contact:

Post by 8BIT »

27 bytes would not be too hard to do by hand. My COSMAC ELF used a hex keypad to bootstrap a program into ram. I used to write 25-80 bytes using that method.

For my first sbc, I built an eeprom programmer on a breadboard using 4 74LS373 connected to a PC parallel port. One held the data byte, two held the address, and one held the control bits (cs,rd,wr). The cost was under $15 as I used a scrap printer cable.

I had some trouble with the parallel port strobe line not strobing the latches right. I think I ended up using another handshake line for the strobe. I wrote the PC programmer code in QuickBASIC, using the Zicor 28C256 datasheet.

The process was no too complicated, as I recall. However, I had scrounged some 28C256's from a scrapped telecom key system, and I discovered that they had been write protected using a software lock. It took me a while to discover that and to write the unlock code, but I ended up getting it to work. New devices ship unlocked, so that should not even be a factor.

After my SBC-2 was up and running, I scrapped the PC programmer and created a programmer using a 6522 and two 74LS373's. The info on that is on my website under IO Devices.

An even easier solution is right here as well. I am willing to help anyone with programming an EEPROM. For the cost of return postage, I will program anything I'm able. I'm sure there are others here that would also be willing to assist. Just email or PM me with your device to be sure its one I can program.

Once an EEPROM is in a system, it could be reprogrammed in-system if designed to allow it. I have done that also with my SBC-2 system.

Daryl
Last edited by 8BIT on Tue Feb 09, 2010 1:09 pm, edited 1 time in total.
User avatar
dclxvi
Posts: 362
Joined: 11 Mar 2004

Post by dclxvi »

The reset vector is at $FFFC, not $FFFE, so your code would have to start at $FFE3.

22 (untested) bytes is what I came up with. 253 bytes are always sent, which are stored on the stack (!) The order the bytes are stored in memory is the reverse of the order they were sent (!!) The RTS uses the last two bytes sent/pushed to jump to the appropriate place in the routine stored on the stack. RTI could be used instead, if you wanted to set up the flags before jumping.

Code: Select all

FFE8 A2 03    LDX #3
     8E xx xx STX status
     9A       TXS
FFEE AD xx xx LDA status
     4A       LSR
     90 FA    BCC $FFEE
     AD xx xx LDA data
     48       PHA
     E8       INX
     D0 F3    BNE $FFEE
     60       RTS
FFFC E8 FF    DW  $FFE8 ;reset vector
User avatar
BigEd
Posts: 11463
Joined: 11 Dec 2008
Location: England
Contact:

Post by BigEd »

Nice! I had a go with using the stack, but I didn't think of the RTS trick.

(Big oops on the reset vector!)

Cheers
Ed
kc5tja
Posts: 1706
Joined: 04 Jan 2003

Post by kc5tja »

You can get rid of that TXS instruction, since I believe S defaults to $FF upon CPU start up. At the very least, the WDC chips do.
Thowllly
Posts: 51
Joined: 22 Oct 2003
Location: Norway

Post by Thowllly »

Couldn't you also get rid of the INX if you used 0 as an EOF byte?
kc5tja
Posts: 1706
Joined: 04 Jan 2003

Post by kc5tja »

You can't use a 0-terminator, because 0 is a valid 6502 instruction, and it appears quite often in operands. It's better to transfer a fixed length chunk of binary data which, hopefully, contains valid code. :)
User avatar
BigEd
Posts: 11463
Joined: 11 Dec 2008
Location: England
Contact:

Post by BigEd »

But you could almost certainly avoid 0 in the second-stage boot - which only has to load the next stage.
kc5tja
Posts: 1706
Joined: 04 Jan 2003

Post by kc5tja »

It's entirely possible to avoid 0. The problem is, to do so, you need extra code. To load zero into the accumulator, you need to do something like:

Code: Select all

STA $01
EOR $01
and so on. You'll end up consuming more space and running into more bugs than that one little INX instruction is worth.

It also means you cannot (conveniently) access absolute addresses with a zero offset byte (e.g., $0100, $0200, $0300, etc). Again, you would have to work around this by loading X with $01, and using $02FF as your base address. More code. More opportunities for bugs.

If you can somehow get your code down below 14 bytes, you could use a 74154 to decode A0-A3 and construct a diode matrix ROM. Maybe with two chips, you can use 32 bytes of diode ROM.
User avatar
BigEd
Posts: 11463
Joined: 11 Dec 2008
Location: England
Contact:

Post by BigEd »

All true, but again, we save a byte in the bootstrap and possibly add a few bytes to the second stage. Any significant program is loaded by the second stage (presumably using a format which supports checksums) and has no such restriction.

Admittedly, saving a byte when we're already down near the 20 byte mark is hardly worth any extra inconvenience, but at this point I think it's a game of assembly golf.

(I think it must have been a typo, but I think Daryl's original response had the appearance of throwing down a challenge to reach 16 bytes.)

Cheers
Ed
kc5tja
Posts: 1706
Joined: 04 Jan 2003

Post by kc5tja »

Right -- I specified 14 bytes to give enough room for the reset vector. :)
User avatar
BigEd
Posts: 11463
Joined: 11 Dec 2008
Location: England
Contact:

Post by BigEd »

kc5tja wrote:
If you can somehow get your code down below 14 bytes, you could use a 74154 to decode A0-A3 and construct a diode matrix ROM. Maybe with two chips, you can use 32 bytes of diode ROM.
I had a thought a bit like that: I think the Apollo Guidance Computer had ROMs implemented as hard wired arrays(*) It's a suitable technology for a retro bootstrap.

In my own case, if the bootstrap is small enough, I'd like to synthesise it into the CPLD.

(*) Quick check tells me that it was hard-wired ROM but using ferrite cores. I had an idea that somewhere in the past was a ROM design using wire alone, although I can't see quite how that would be done.
kc5tja
Posts: 1706
Joined: 04 Jan 2003

Post by kc5tja »

Back when I was toying with the Kestrel-1 design, one ROM concept I had was an optical matrix, where matrix rows were illuminated by LEDs, and columns were detected by photo-diodes.

Turned out to be more expensive than I would have liked though. :(
mdpenny
Posts: 50
Joined: 24 Sep 2002
Location: Essex, UK

Post by mdpenny »

Hmm... :idea:

It's occurred to me that there's another way of achieving the same effect, and quite easily, too - especially for those of us with (almost any) 8-bit Acorn kit (and some 32-bit kit, too) :D

What I'm thinking of is the "User Port" - for those not in the know, essentially port "B" of a 6522 VIA, wired up to an IDC header under the front edge of the Beeb; a VIA expansion card was also available for most early ARM-based machines, too.

And, of course, if the SBC's VIA's "B" port is hooked up back-to-back the the "User Port", that still leaves VIA's "A" port, and its timers, available to the SBC...

--Martin
Martin Penny

.sig in beta - full release to follow.
Thowllly
Posts: 51
Joined: 22 Oct 2003
Location: Norway

Post by Thowllly »

I was looking at the docs (because I wondered if it was possible to do LSR status) and noticed that it appears that the code selects 7bit word length, if I read it right. It would be a bit dificult to write a second stage bootloader that couldn't even use load or store opcodes :)



edit: if we dont do neither TXS nor INX, and if LSR status had been possible, and if the 6850 had been in zeropage, then it would have been just 16 bytes total :P
Last edited by Thowllly on Tue Feb 09, 2010 9:56 pm, edited 1 time in total.
Post Reply