ZIF socket giving me headaches.

For discussing the 65xx hardware itself or electronics projects.
User avatar
cbmeeks
Posts: 1254
Joined: 17 Aug 2005
Location: Soddy-Daisy, TN USA
Contact:

ZIF socket giving me headaches.

Post by cbmeeks »

I fired up my SBC again and starting writing more code.

When I built my SBC, I made a mistake and put a DIP socket in the ROM. Later, I decided to put a ZIF socket in but I didn't want to pull out the DIP socket. I should have used the ZIF socket initially.

Not that it would have mattered too much...seems the ZIF socket is a piece of crap. I'm going to test it tonight but I think some of the pins are not making a connection.

Unfortunately, I don't have another ZIF socket. Good ones are surprisingly expensive.

So, I was wondering if there is another way. A way to quickly get new code over to my AT28C256.
Another foobar on my part is that I didn't create an easy way to program the EEPROM in circuit.

Now I'm wondering what my options are.

What would be cool would be a way to add an upload to my make/build process.

Worse case, I might make a small board that has wires going to my programmer and my SBC. I could just turn off the SBC when programming. Not sure what running the SBC will do to my programmer, however.

Something else I've considered is to use an Arduino or something similar in the loop. Either as direct ROM (albeit, slow) or as a programmer.

I have one of those fancy ESP32's as well. That thing is wireless and might be fast enough for general purpose ROM. And it has 32 GPIO, IIRC. Just need voltage translation.

What are you guys doing to quickly get code into your SBC?

PS

My long-term goal is to write a minimal monitor that will pull new code over serial. But, I need a faster way of getting that minimal monitor installed.

Thanks!
Cat; the other white meat.
Chromatix
Posts: 1462
Joined: 21 May 2018

Re: ZIF socket giving me headaches.

Post by Chromatix »

Do you have /WE wired up to your EEPROM? The AT28C256 is programmable over the standard CPU bus if so, and doesn't require a high programming voltage to be applied externally. You'll need to load the programming routine and the new contents of the EEPROM (in 64-byte pages) into RAM, over a serial line or something, since the chip will be unavailable for reading during the programming cycle, even if you don't overwrite certain parts of it. You may also need to disable interrupts so that the CPU doesn't try to read the vector table, if that is in the EEPROM.

Assuming you haven't enabled Software Data Protection on the chip, the writing algorithm is as follows:

Code: Select all

Load/copy flashing code into RAM.
Load first page (64 bytes) of new data into RAM.
Disable interrupts.
Repeat:
    Write new data into EEPROM.
    Load next page (64 bytes) of data, if any, into RAM
    Read and compare last byte of current page, repeat until it matches (this signifies that the page-write cycle is complete).
When last page written, re-enable interrupts and return control.
User avatar
floobydust
Posts: 1394
Joined: 05 Mar 2013

Re: ZIF socket giving me headaches.

Post by floobydust »

As noted, writing to the AT28C256 insitu is very easy. You can do byte write or page write mode. Note that you need to sample the toggle bit which is actively toggling when the chip is writing the contents internally. You do need the write line connected to the write signal generated from the system (treat it the same as RAM). My SBC uses a jumper to either connect the WR to +5V or the Write signal.

Based on the above, you need to have interrupts disabled, You also need to have the code doing the write and sensing the toggle bit running from RAM. Here's a short routine that accomplishes a Byte write to the EEPROM (which is copied from EEPROM and RAM and called as a JSR):

Code: Select all

BYTE_WRS        SEI                     ;Disable interrupts
                LDA     (SRCL)          ;Get source byte
                STA     (TGTL)          ;Write to target byte
                LDA     (TGTL)          ;Read target byte (EEPROM)
                AND     #%01000000      ;Mask off bit 6 - toggle bit
BYTE_WLP        STA     TEMP3           ;Store in Temp location
                LDA     (TGTL)          ;Read target byte again (EEPROM)
                AND     #%01000000      ;Mask off bit 6 - toggle bit
                CMP     TEMP3           ;Compare to last read (toggles if write mode)
                BNE     BYTE_WLP        ;Branch back if not done
                CLI                     ;Re-enable interrupts
BYTE_WRE        RTS                     ;Return to caller
My current Monitor supports programming the EEPROM insitu and can write any length from RAM to ROM, but of course you need to be careful where you are writing to. Current Monitor also supports a single byte EEPROM edit for patching. Both Monitor routines use the code snippet above which is copied into Page Zero first. Once the source and target locations are set, just JSR to the routine and it does the rest.

My Monitor also supports Xmodem-CRC for upload and download, which is what I use to get code down to the board. The code also handles S19 records automagically, so I can easily write code on the PC, download it to the SBC and then write it to the EEPROM. Note: This assumes you're NOT trying to overwrite the actual Monitor itself! I recently wrote a simple Flash utility which does replace the Monitor code, albeit it does rely on the BIOS not being touched. However, if the Monitor code is replaced with bad code, the SBC will likely crash after the BIOS init completes and shows it's boot message.
Chromatix
Posts: 1462
Joined: 21 May 2018

Re: ZIF socket giving me headaches.

Post by Chromatix »

The "toggle bit" output is only one method of detecting write completion; the chip inverts the most-significant bit of the last-written byte, relative to its true value, until the write is complete. So it is sufficient (and uses less code) to compare the written location to the value written until they match:

Code: Select all

BYTE_WRS        SEI                     ;Disable interrupts
                LDA     (SRCL)          ;Get source byte
                STA     (TGTL)          ;Write to target byte
BYTE_WLP        CMP     (TGTL)          ;Read target byte (EEPROM)
                BNE     BYTE_WLP        ;Branch back if write not done
                CLI                     ;Re-enable interrupts
BYTE_WRE        RTS                     ;Return to caller
Or, for a simpler way of detecting the toggle-bit without relying on knowing the last value written:

Code: Select all

BYTE_WRS        SEI                     ;Disable interrupts
                LDA     (SRCL)          ;Get source byte
                STA     (TGTL)          ;Write to target byte
BYTE_WLP        LDA     (TGTL)          ;Read target byte (EEPROM)
                CMP     (TGTL)          ;Re-read target byte (EEPROM)
                BNE     BYTE_WLP        ;Branch back if write not done
                CLI                     ;Re-enable interrupts
BYTE_WRE        RTS                     ;Return to caller
Last edited by Chromatix on Fri Feb 08, 2019 8:22 pm, edited 1 time in total.
nyef
Posts: 235
Joined: 28 Jul 2013

Re: ZIF socket giving me headaches.

Post by nyef »

As far as a minimal monitor goes, how about something like this? http://pygmy.utoh.org/3ins4th.html Very quick to implement a version of for a 6502 or similar, and from there you can do a whole lot as long as you have some RAM.
User avatar
GARTHWILSON
Forum Moderator
Posts: 8773
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: ZIF socket giving me headaches.

Post by GARTHWILSON »

cbmeeks wrote:
Not that it would have mattered too much...seems the ZIF socket is a piece of crap. I'm going to test it tonight but I think some of the pins are not making a connection.

Unfortunately, I don't have another ZIF socket. Good ones are surprisingly expensive.
[ . . . ]

What are you guys doing to quickly get code into your SBC?
I think Textool is the ZIF socket brand I've had a lot of trouble with, but Aries and one other that has no visible name on it, were fine.

When I developed the software in around 1990 for the automated test equipment at work which used a 65c02 SBC on STD bus, the SBC did not have room for ZIF sockets. After I had the initial Forth kernel working, I could develop the rest in RAM, totally interactively, and every so often I would round up all my latest additions and run them through the metacompiler and re-program the EPROMs. Those EPROMs were in and out of the regular sockets many times, but definitely not every day as I continued developing.

Similarly, if you have a way to get your assembled or compiled code into RAM to test and debug, or better yet, assemble or compile it on the SBC itself, your EEPROM won't have to come out and make a trip to the programmer very often. You will probably need at least some kind of working monitor program in the EEPROM though.
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
Chromatix
Posts: 1462
Joined: 21 May 2018

Re: ZIF socket giving me headaches.

Post by Chromatix »

I think there's scope here for a 256-byte wonder which can be loaded over the serial port into RAM, followed by the data to be flashed and periodic CRCs, and which takes over the serial port for the duration. There would need to be a (very simple) corresponding program on the other end of the serial line, of course.

If, as in the algorithm I first showed, the serial transfer of the following block is overlapped with the EEPROM write cycle of the current block, a 57600 baud serial line will nearly keep pace with the EEPROM. A "raw" CRC algorithm (without tables) can be very compact and still fast enough to work at serial speeds. Conversely, if the speed of the serial line is as little as 9600 baud, the FIFO in many UARTs will be large enough to absorb the page write cycle without losing throughput (and this is still faster than a stock 1541).
whartung
Posts: 1004
Joined: 13 Dec 2003

Re: ZIF socket giving me headaches.

Post by whartung »

nyef wrote:
As far as a minimal monitor goes, how about something like this? http://pygmy.utoh.org/3ins4th.html Very quick to implement a version of for a 6502 or similar, and from there you can do a whole lot as long as you have some RAM.
This is a great idea (I've seen it before), but I think that it really needs to have a handy 65xx assembler in the host Forth as well, and an ability to create CROSS-CODE words on the host that automagically get assembled in to the slave.

You could do something like this:

Code: Select all

    HEX
    0200 XHERE !
    CROSS-CODE SUB1
        0 # LDA
        CLC
        0A # ADC
        RTS
    END-CROSS-CODE

    CROSS-CODE SUB2
        SUB1 JSR
    END-CROSS-CODE
It essentially makes first class all of the shenanigans that you can see Frank doing in his article (defining the work, calculating the length, "comma'ing it in", etc.).

Essentially, take a stock 65xx assembler, replace HERE with XHERE, C! with XC!, etc. and assemble code. Use the 0200 (in this case) as the origin to the routine (since it sets XHERE). You can have XHERE maintained automatically by the assembler. For example, XHERE is set to 0200 at the start, and updated properly by the CROSS-CODE assembler. Also, SUB1 is set to 0200, and SUB2 would be set to 0206, etc.

Reloading the code assembles it live on the slave. By the time the assembly is done, not only is it assembled, it's already on the board.

You can also make "XALLOT", "XC,", "X,". Mind, you don't need to have a Forth on the slave, you're just using Forth concepts and commands to populate the image. No need to have the inner interpreter, move over words headers, etc. Just Franks simple driver. It's just an interesting, simple, fast cross assembler/loader with an interactive Forth command line.

There's nothing stopping you from setting XHERE manually before each routine.

Code: Select all

    HEX
    0200 XHERE !
    CROSS-CODE SUB1
        0 # LDA
        CLC
        0A ADC
        RTS
    END-CROSS-CODE

    0210 XHERE !
    CROSS-CODE SUB2
        SUB1 JSR
    END-CROSS-CODE
Or something like this.

Code: Select all

0 VARIABLE ORGVAL
: ORG DUP ORGVAL ! XHERE ! ;
: +ORG ORGVAL @ + ORG ;
Now:

Code: Select all

    HEX
    0200 ORG
    CROSS-CODE SUB1
        0 # LDA
        CLC
        0A ADC
        RTS
    END-CROSS-CODE

    10 +ORG
    CROSS-CODE SUB2
        SUB1 JSR
    END-CROSS-CODE
This does a couple of things. First, if you change the origin from 0200 to 0400, well, everything else moves as well.

But even better, if you change the "10 +ORG" to "20 +ORG", then everything else shifts as well.

The point of the individual origins is that it lets you redefine single routines, allowing you to patch tweak them and patch them in place because you have a buffer between routines, so you don't have to reassemble the entire set every single time. Just update one routine, and reload it. Hmm, how does it know to use the same origin the second time? Yea, I don't know either -- guess it needs work, but I'm sure Something Could Be Done.

I know, you could have CROSS-CODE look up and see if SUB2 is already in the dictionary. If it is, just use its existing value and ignore ORG. If you want to reassemble everything, FORGET the start (SUB1 in this case), and reload.

Wow - that was simple. That's down right clever.

So, now you're developing in assembly, ON THE BOARD, in almost real time with effectively zero turn around time.

Pretty neat!
User avatar
drogon
Posts: 1671
Joined: 14 Feb 2018
Location: Scotland
Contact:

Re: ZIF socket giving me headaches.

Post by drogon »

nyef wrote:
As far as a minimal monitor goes, how about something like this? http://pygmy.utoh.org/3ins4th.html Very quick to implement a version of for a 6502 or similar, and from there you can do a whole lot as long as you have some RAM.
Reminds me very much of the way you boot a transputer - at power on (without a ROM), it's waiting on commands down any one of it's 4 links - 3 commands: peek, poke and go. So you can poke a program into it then tell it to go. Very minimal, no ROM, done in the microcode, and if you can fit your code into the internal 2K or 4K of RAM then it's a very minimal system too.

-Gordon
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/
Chromatix
Posts: 1462
Joined: 21 May 2018

Re: ZIF socket giving me headaches.

Post by Chromatix »

Or a classic minicomputer with its toggle-switch front panel…
User avatar
drogon
Posts: 1671
Joined: 14 Feb 2018
Location: Scotland
Contact:

Re: ZIF socket giving me headaches.

Post by drogon »

Chromatix wrote:
Or a classic minicomputer with its toggle-switch front panel…
You have to draw the line somewhere... So, ok.. what's the minimal rom code to do this, and how many diodes... :)

-Gordon
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/
Chromatix
Posts: 1462
Joined: 21 May 2018

Re: ZIF socket giving me headaches.

Post by Chromatix »

Something like LDY #xx, STY/JMP $xxxx, BRA *-5. Wire your toggle switches to replace the x's, and another one to switch between STY ($8C) and JMP ($4C).
Chromatix
Posts: 1462
Joined: 21 May 2018

Re: ZIF socket giving me headaches.

Post by Chromatix »

Even better:

Code: Select all

WAI
LDY #$xx
STY $xxxx  ; switchable to JMP
BRA *-6
This allows you to use another switch or button, wired to /IRQ, to actually execute the code. Enter the routine with interrupts masked (which they are on reset or NMI); then WAI continues on IRQ, instead of going through the vector. At this point we are at 8 bytes.

A further refinement:

Code: Select all

WAI
LDY #$xx
STY $xxxx  ; switchable to JMP or LDY
STY LEDs
BRA *-9
This gives you the ability to examine memory as well as poke and execute, for the cost of three extra bytes of code, adding $AC to the opcode switch (alongside $8C and $4C), and a bunch of LEDs for a readout.
Chromatix
Posts: 1462
Joined: 21 May 2018

Re: ZIF socket giving me headaches.

Post by Chromatix »

If the goal is to build a minimal bootstrap ROM right at the top of the address space, then we must incorporate the three vectors - and we can do this within 16 bytes, so we only need a $FFFx mask and a 4-to-16 decoder to drive out diode ROM. NMI is the first vector encountered in program order, so we can include it in a JMP to replace the BRA, and the WAI then falls exactly at $FFF0:

Code: Select all

.ORG $FFF0
    WAI
    LDY #$xx ; data toggle switches on $FFF2
    STY/JMP/LDY $xxxx ; three-way opcode selection between $8C/$4C/$AC on $FFF3, address toggle switches on $FFF4-5
    STY LEDs
    JMP $FFF0 ; incorporates NMI vector
    .WORD $FFF0 ; reset vector
    .WORD $???? ; IRQ vector
That's exactly 16 bytes. Then, looking at the actual bytes involved:

Code: Select all

$CB
$A0
xx ; data toggles
$8C/4C/AC
xx ; address low toggles
xx ; address high toggles
$AC
xx ; LED low address
xx ; LED high address
$4C
$F0
$FF
$F0
$FF
xx ; IRQ low address
xx ; IRQ high address
There's a lot of bit patterns that can probably find diodes reused through OR gates from the decoder. For example:
Attachments
P1010329.JPG
User avatar
BigEd
Posts: 11463
Joined: 11 Dec 2008
Location: England
Contact:

Re: ZIF socket giving me headaches.

Post by BigEd »

We had some previous discussions on small bootstraps and minimal hardware to boot an SBC: and not quite so minimal
Post Reply