6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Thu Nov 21, 2024 10:54 pm

All times are UTC




Post new topic Reply to topic  [ 57 posts ]  Go to page Previous  1, 2, 3, 4  Next
Author Message
 Post subject: Re: Neolithic Romless
PostPosted: Fri Sep 29, 2023 6:43 am 
Offline

Joined: Mon Jan 19, 2004 12:49 pm
Posts: 983
Location: Potsdam, DE
Yes. I was thinking of what might be needed to drop in something like the cypress 32kB FRAM - FM18W08 or FM28V20 - to give enable a single programming event and then just subsequently run at power up.

I don't think it's much: would need to consider the supply voltage - this is 5v, and some of the FRAM run at 5v - and a different way to wake up the serial chips. Might just be a second button to load...

Programming that MR5A16A could be done with something with a few more I/O legs than an Arduino - a Nucleo of some flavour perhaps (as drives my eeprom programmer at the moment) - but it seems a shame to use only half of it. Not sure how you'd be able to use the top eight bits of the memory word.

Neil


Top
 Profile  
Reply with quote  
 Post subject: Re: Neolithic Romless
PostPosted: Fri Sep 29, 2023 7:46 am 
Offline

Joined: Mon Jan 19, 2004 12:49 pm
Posts: 983
Location: Potsdam, DE
Got the two ram chips on the board. The dual DIP/SOIC footprint is really handy and I happened to have some soic parts around. This courtesy of a few minutes in a second hand toaster oven and a syringe of solder paste; no template for this one. Just had one short (too much solder) and one open circuit (not enough), both easily fixed with the soldering iron.

Attachment:
neo 1.jpg
neo 1.jpg [ 297.41 KiB | Viewed 8666 times ]


Neil


Top
 Profile  
Reply with quote  
 Post subject: Re: Neolithic Romless
PostPosted: Fri Sep 29, 2023 2:18 pm 
Offline

Joined: Mon Jan 19, 2004 12:49 pm
Posts: 983
Location: Potsdam, DE
Now with added sockets. No, I didn't have any 20-pin sockets... never mind. The other SM parts added with a hot air pencil (should have done them in the oven with the ram but I didn't think).

The reset resets and the oscillator oscles. So now it's waiting on me to finish the code to convert an intel hex file into a binary blob.

Attachment:
1695996226582.jpg
1695996226582.jpg [ 468.77 KiB | Viewed 8641 times ]


Neil


Top
 Profile  
Reply with quote  
 Post subject: Re: Neolithic Romless
PostPosted: Fri Sep 29, 2023 7:59 pm 
Offline

Joined: Mon Jan 19, 2004 12:49 pm
Posts: 983
Location: Potsdam, DE
Some very fragile code that - on visual inspection - produces a binary blob which ought to program the neolithic. It's seriously dodgy code, take with two aspirins and a dose of salt. But it does appear to work with a properly formed intel 8-bit hex file.

Note: it's for Linux. I don't think Windows includes getline() but there are probably versions online if it doesn't. I'll probably just copy the blob to the \dev\ttyUSB0 port directly, but there's a mechanism to send via minicom here: https://www.dannysung.com/articles/linu ... a-minicom/

Don't forget that the comm port speed will need to be 19k2 for the boot load and something rather higher - 115k2 likely - for actual comms.

Neil

Code:
// convert an existing intel 8-bit hex file to a binary blob which can
// be used to load the Neolithic Romless 6502 processor
// three addressable uarts handle the address and data and write strobe,
// a fourth resets the processor after memory is loaded
//   - 0x0      data and strobe
//   - 0x1      address low byte
//   - 0x2      address high byte (page)
//   - 0x3      reset
//
// (c) nailed_barnacle 2023

#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>

void decode_data (uint8_t data)
{
   printf ("%02x %01x\t%01x\t%01x\n", data, data >> 4, (data & 0x0e) >> 1, data & 0x01);
}

uint8_t build_txbyte (int8_t val, int8_t target, bool first)
{
   // convert a single byte into the first packet value
   // bit 0    - always 1
   // bit 1-3   - target address
   // bit 4-7   - low nibble of val if first is true
   //         - high nibble of val if first is false
   
   uint8_t res = 1;   // bit 0 = 1
   res += (target & 7) << 1;
   if (first)
   {
      res += (val & 0x0f) << 4;
   }
   else
   {
      res += (val & 0xf0);
   }
   return res;
}

void output_txpair (int8_t val, int8_t target, FILE * fo)
{
   uint8_t first;
   uint8_t second;
   
   // output two bytes to fo
   first = build_txbyte (val, target, true);
   second = build_txbyte (val, target, false);
   fprintf (fo, "%c%c", first, second);
   decode_data (first);
   decode_data (second);
}

void output_page (uint8_t page, FILE * fo)
{
   // output a page address to uart 2
   // if we only send this when it changes, we increase tranfer speed
   // by about fifty percent
   output_txpair (page, 2, fo);
}

void output_add_data (uint8_t addr, uint8_t data, FILE * fo)
{
   // write a byte at the selected address on the current page
   output_txpair (addr, 1, fo);
   output_txpair (data, 0, fo);  // this writes to the ram
}


int main (int argc, char ** argv)
{
   // read an intel hex file and write the data into a binary file
   // such that it can be used directly to load the neolithic romless
   // processor
   
   FILE * fi;
   FILE * fo;
   char * line = NULL;
   size_t len = 0;
   ssize_t nread;
   int      record_type;
   int      record_count;
   int      record_addr;
   int      record_data;
   
   // sanity check input
   if (argc < 3)
   {
      printf ("Usage: lv8153 <input hex file> <output binary file>\r\n");
      return 1;
   }
   // open input and output files
   if (NULL == (fi = fopen (argv[1], "r")))
   {
      printf ("Can't open input file %s\n", argv[1]);
      return 1;
   }
   if (NULL == (fo = fopen (argv[2], "w")))
   {   
      printf ("Can't open output file %s\n", argv[2]);
      fclose (fi);
      return 1;
   }
   
   // now we can plough through the file one line at a time
   // this will only work for a properly formed hex file, not robust!
   // - two hex digits for payload count
   // - four hex digits for load address (high byte first)
   // - two hex digits as record type: 00 for data, 01 for end of file
   // - data as two hex digits, repeated count times
   // - two hex digits as checksum (we ignore this)
   
   while (-1 != (nread = getline (&line, &len, fi)))
   {
      sscanf (line, ":%02x%04x%02x", &record_count, &record_addr, &record_type);
      if (0 == record_type)
      {
         // only for types we understand
         // send high byte of target
         output_page ((record_addr & 0xff00) >> 8, fo);
         for (int q = 0; q < record_count; q++)
         {
            // for each data byte
            sscanf (&line[9 + (q * 2)], "%02x", &record_data);
            output_add_data (record_addr & 0xff, record_data, fo);
            record_addr++;
            if (0x00 == record_addr & 0xff)
            {
               // if the page rolls over in the middle of the line
               output_page ((record_addr & 0xff00) >> 8, fo);
            }
         }
         printf ("\n");
      }
   }
   // finally reset the processor
   output_txpair (0, 3, fo);
   fclose (fi);
   fclose (fo);
   printf ("Load complete\n");
}


Top
 Profile  
Reply with quote  
 Post subject: Re: Neolithic Romless
PostPosted: Tue Oct 03, 2023 1:35 pm 
Offline

Joined: Mon Jan 19, 2004 12:49 pm
Posts: 983
Location: Potsdam, DE
Ok, the board is built up, it looks like code is loading, and the reset and BE go high at the end of the load.

The bad news is that my initial code doesn't look like it's running. It's possible, though, that it's stuck in a loop waiting for something from the UART. It should be running Basic, so the first thing out should be the Cold/Warm start message; even by tickling the reset pin manually I don't see it.

It's also possible that my minicom setup isn't happy: On this linux box I'm setting the parameters for the load and sending it:
Code:
stty -F /dev/ttyUSB0 19200 -parity cs8 -cstopb
cat basic.bin > /dev/ttyUSB0


But then minicom needs to set the line back to 112,500 baud to talk to the processor instead of the loader hardware. Which takes an amount of time and perhaps Basic is getting bored waiting.

Next step is a tiny code that just emits constant values to the port after configuring it.

Neil

p.s. of course it's entirely possible that my conversion software isn't converting right...


Top
 Profile  
Reply with quote  
 Post subject: Re: Neolithic Romless
PostPosted: Tue Oct 03, 2023 3:03 pm 
Offline

Joined: Fri Jul 09, 2021 10:12 pm
Posts: 741
I've had pretty good mileage using Python for serial comms - its Serial module makes it easy to switch to arbitrary baud rates on the fly, and I used that for a fileserver for the BBC Micro (6850-based) where the initial connection was 9600 baud but it stepped up to 76800 baud after an initial negotiation, and that worked well. The Python server also assembled the 6502 code automatically.

More recently I've been using similar code at a fixed baud rate (that minicom doesn't support) and having it handle the initial bootup negotiation with the 6502 system, load some code, and switch to an interactive serial terminal mode after that to allow human I/O. It's been good for that too.

You could do the same in C of course, the main thing I think is that it can be beneficial to have some custom server code here especially if you need to do things like rate changes.


Top
 Profile  
Reply with quote  
 Post subject: Re: Neolithic Romless
PostPosted: Tue Oct 03, 2023 7:15 pm 
Offline

Joined: Mon Jan 19, 2004 12:49 pm
Posts: 983
Location: Potsdam, DE
Actually, I think I might simplify things if for the time being I initialise the UART for 19k2 as well. There should be no issue with the loader chain receiving data *unless* the write pulse might still be active even with the output disabled - something I haven't thought about. Hmm.

Neil


Top
 Profile  
Reply with quote  
 Post subject: Re: Neolithic Romless
PostPosted: Fri Oct 06, 2023 4:18 pm 
Offline

Joined: Mon Jan 19, 2004 12:49 pm
Posts: 983
Location: Potsdam, DE
Hmm. A simple program to emit lots and lots of ************* (0x2A) produces output which the scope insists is at the expected 115,200 baud and decodes correctly as asterixen. Sadly, minicom produces a long string of identical characters but they're not asterixes, I tend to get % or I. I don't know if the unit is simply sending things out which can be misinterpreted, and my first attempt to output continuous 'hello world's didn't output anything. Need to look at that.

Sadly the datasheet revealed that the only divisors for the serial clock are 1, 16, and 64. Since the clock is 1,843,200 Hz, that gives me the default 115,200 or 28,800, so I can't stick it at 19k2 or 9k6 and leave it there.

It's possible that the change from the medium speed at the control line, to the fast speed in minicom, isn't necessarily working correctly. It might be that for safety, I need to receive data at the 6502 side before starting the main software, to prove the serial is running.

But the basic load and reset does appear to be working.

Neil


Top
 Profile  
Reply with quote  
 Post subject: Re: Neolithic Romless
PostPosted: Fri Oct 06, 2023 4:53 pm 
Offline
User avatar

Joined: Wed Feb 14, 2018 2:33 pm
Posts: 1488
Location: Scotland
barnacle wrote:
Hmm. A simple program to emit lots and lots of ************* (0x2A) produces output which the scope insists is at the expected 115,200 baud and decodes correctly as asterixen. Sadly, minicom produces a long string of identical characters but they're not asterixes, I tend to get % or I. I don't know if the unit is simply sending things out which can be misinterpreted, and my first attempt to output continuous 'hello world's didn't output anything. Need to look at that.

Sadly the datasheet revealed that the only divisors for the serial clock are 1, 16, and 64. Since the clock is 1,843,200 Hz, that gives me the default 115,200 or 28,800, so I can't stick it at 19k2 or 9k6 and leave it there.

It's possible that the change from the medium speed at the control line, to the fast speed in minicom, isn't necessarily working correctly. It might be that for safety, I need to receive data at the 6502 side before starting the main software, to prove the serial is running.

But the basic load and reset does appear to be working.

Neil


I've never had any issues with minicom at 115,200 bauds. That's the speed my Ruby boards sends data up at - and it can run the line flat-out too.

I'm sure you've checked the usual parity shenanigans though. Stars are good - 0x2A, or 0xAA if sent with even parity. Capital U is another - 0x55 so the parity bit ought to be zero there.

Also, serial port permissions - if not root, then you ought to be in the 'dialout' group so you can fully access the serial ports. Minicom gets a bit fussy with storing modes, etc. but I've not had issues just using it directly from the command-line:

Code:
minicom -D /dev/ttyUSB0 -b 115200


I do sometimes have issues with the cheap USB serial dongles I use though - sometimes they need unplugging from both ends - complete power-down and powering up again. I think if they're back-powered from the SBC then they sometimes get confused...

I'm sure you'll get there in the end though..

Cheers,
-Gordon

_________________
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/


Top
 Profile  
Reply with quote  
 Post subject: Re: Neolithic Romless
PostPosted: Fri Oct 06, 2023 5:34 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10985
Location: England
A thought - send some number of characters (maybe 8) then a space, and repeat. Do you get characters in groups of 8, or something else? If you're getting the right number of characters, I can only imagine something is wrong with, say, stop bits, or parity. Set both sides to 8-N-1 if you can.


Top
 Profile  
Reply with quote  
 Post subject: Re: Neolithic Romless
PostPosted: Fri Oct 06, 2023 5:50 pm 
Offline

Joined: Fri Jul 09, 2021 10:12 pm
Posts: 741
I've had this kind of thing too when sending a long string of identical characters, if the receiver tries to start listening in while the data is already being sent - it is possible for the receiver to be out of sync with the start and stop bits, so it sees valid but incorrect data. As Ed said, pausing between characters, at least occasionally, might fix that, and you could chose a character value that's unambiguous, e.g. 255 (just one clear bit, the start bit) or 0 (just one set bit, the stop bit) - with 8N1 at least.


Top
 Profile  
Reply with quote  
 Post subject: Re: Neolithic Romless
PostPosted: Fri Oct 06, 2023 7:04 pm 
Offline

Joined: Mon Jan 19, 2004 12:49 pm
Posts: 983
Location: Potsdam, DE
Yeah, that's my next thought but something for tomorrow. The USB adaptor is an FDTI USB-serial SIL connector, so that shouldn't be an issue. It feels like it's missing out on the start bit somehow. But asterixen are usually safe. 0x55 in 8-n-1 can pick up anywhere, so it doesn't tell me a lot...

When I get the 'hello world', over the weekend perhaps, I'll know more.

One concern I have still is that some mischance of incoming data might trigger the address 8513 - the data sheet doesn't mention whether the SOUT pin is still active with the output pins disabled, but if it is, there's a chance for some really subtle bugs: it might need a more sophisticated mixing of the RnW from the processor to actively block the SOUT 'write' pulse.

Neil

p.s. I'm in dialout and tty groups.


Top
 Profile  
Reply with quote  
 Post subject: Re: Neolithic Romless
PostPosted: Fri Oct 06, 2023 7:25 pm 
Offline

Joined: Fri Jul 09, 2021 10:12 pm
Posts: 741
To illustrate, these are all valid interpretations of an 8N1 stream of asterisks, depending which bit you consider to be the start bit:

Code:
00101010010010101001...
0010101001 = 42 (*)
   0101001001 = 37 (%)
     0100100101 = 73 (I)
       0010010101 = 82 (R)


One way it could get out of sync would be if the transmitter started using the higher baud rate before the receiver did. Once it is in sync there shouldn't be a problem.


Top
 Profile  
Reply with quote  
 Post subject: Re: Neolithic Romless
PostPosted: Fri Oct 06, 2023 7:30 pm 
Offline

Joined: Mon Jan 19, 2004 12:49 pm
Posts: 983
Location: Potsdam, DE
Yep, the second and the third are the ones I've seen. And yes, it does start transmitting at the higher rate before the receiver changes over, which might be some seconds later.

This is why I think any use of this will require some recognised _received_ character (or character string: +++ perhaps) before it starts transmitting; thereafter everything should be in sync. Everything's running at 8n1.

Neil


Top
 Profile  
Reply with quote  
 Post subject: Re: Neolithic Romless
PostPosted: Fri Oct 06, 2023 7:34 pm 
Offline

Joined: Fri Jul 09, 2021 10:12 pm
Posts: 741
Yes that should be good. Otherwise as I said, bytes 0 and 255 don't have any risk of misinterpretation. You could also send a break, or just leave healthy gaps between bytes during initial connection phase.


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

All times are UTC


Who is online

Users browsing this forum: No registered users and 52 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: