6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sat Nov 23, 2024 5:35 am

All times are UTC




Post new topic Reply to topic  [ 17 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Fri Feb 08, 2019 4:30 pm 
Offline
User avatar

Joined: Wed Aug 17, 2005 12:07 am
Posts: 1250
Location: Soddy-Daisy, TN USA
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.


Top
 Profile  
Reply with quote  
PostPosted: Fri Feb 08, 2019 5:02 pm 
Offline

Joined: Mon May 21, 2018 8:09 pm
Posts: 1462
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:
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.


Top
 Profile  
Reply with quote  
PostPosted: Fri Feb 08, 2019 6:11 pm 
Offline
User avatar

Joined: Tue Mar 05, 2013 4:31 am
Posts: 1385
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:
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.

_________________
Regards, KM
https://github.com/floobydust


Top
 Profile  
Reply with quote  
PostPosted: Fri Feb 08, 2019 6:21 pm 
Offline

Joined: Mon May 21, 2018 8:09 pm
Posts: 1462
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:
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:
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.

Top
 Profile  
Reply with quote  
PostPosted: Fri Feb 08, 2019 8:06 pm 
Offline

Joined: Sun Jul 28, 2013 12:59 am
Posts: 235
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.


Top
 Profile  
Reply with quote  
PostPosted: Fri Feb 08, 2019 8:15 pm 
Online
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8544
Location: Southern California
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?


Top
 Profile  
Reply with quote  
PostPosted: Fri Feb 08, 2019 8:36 pm 
Offline

Joined: Mon May 21, 2018 8:09 pm
Posts: 1462
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).


Top
 Profile  
Reply with quote  
PostPosted: Fri Feb 08, 2019 10:35 pm 
Offline

Joined: Sat Dec 13, 2003 3:37 pm
Posts: 1004
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:
    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:
    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:
0 VARIABLE ORGVAL
: ORG DUP ORGVAL ! XHERE ! ;
: +ORG ORGVAL @ + ORG ;

Now:
Code:
    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!


Top
 Profile  
Reply with quote  
PostPosted: Sat Feb 09, 2019 10:24 am 
Offline
User avatar

Joined: Wed Feb 14, 2018 2:33 pm
Posts: 1488
Location: Scotland
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/


Top
 Profile  
Reply with quote  
PostPosted: Sat Feb 09, 2019 10:39 am 
Offline

Joined: Mon May 21, 2018 8:09 pm
Posts: 1462
Or a classic minicomputer with its toggle-switch front panel…


Top
 Profile  
Reply with quote  
PostPosted: Sat Feb 09, 2019 10:45 am 
Offline
User avatar

Joined: Wed Feb 14, 2018 2:33 pm
Posts: 1488
Location: Scotland
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/


Top
 Profile  
Reply with quote  
PostPosted: Sat Feb 09, 2019 10:55 am 
Offline

Joined: Mon May 21, 2018 8:09 pm
Posts: 1462
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).


Top
 Profile  
Reply with quote  
PostPosted: Sat Feb 09, 2019 11:49 am 
Offline

Joined: Mon May 21, 2018 8:09 pm
Posts: 1462
Even better:
Code:
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:
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.


Top
 Profile  
Reply with quote  
PostPosted: Sat Feb 09, 2019 2:00 pm 
Offline

Joined: Mon May 21, 2018 8:09 pm
Posts: 1462
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:
.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:
$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
P1010329.JPG [ 5.32 MiB | Viewed 1434 times ]
Top
 Profile  
Reply with quote  
PostPosted: Sat Feb 09, 2019 8:45 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10986
Location: England
We had some previous discussions on small bootstraps and minimal hardware to boot an SBC:
and not quite so minimal


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 17 posts ]  Go to page 1, 2  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 33 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: