6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sat Sep 21, 2024 5:38 am

All times are UTC




Post new topic Reply to topic  [ 15 posts ] 
Author Message
PostPosted: Sat Jun 01, 2024 6:01 pm 
Offline

Joined: Thu Dec 26, 2002 12:29 pm
Posts: 77
Location: Occitanie, France
Hi all,
Silence for a while, but experimenting & testing of my WBC/POC system continue... I have what I thought was a simple need : fill unused areas of my test code ROM with random bytes. It is so that I can test my ROM shadowing ideas by having completely random bytes to compare between ROM and ShadowRam, to be fairly certain that : a) the copy ROM -> RAM worked OK; b) I don't have any problems with sticky address lines, etc.

In the end I found that this is non-trivial, especially as I want to use a full 32K ROM. Has anyone any ideas ? My actual code that will be lurking in the ROM is probably only a few hundred bytes, including my test routine that will be copied down to page 0200 once the shadow RAM has been filled from ROM.

I'm a linux user for decades, but I no-longer tinker will bash scripts, etc. I can generate strings of random numbers in decimal from the command prompt, but my idea to create an intel hex file with the proper hex format : is out of reach for me. It would have been nice if one of the 6502 assemblers had a " db $RND" construct ;0)

If anyone has any ideas, I'd be truly grateful.

_________________
Glenn-in-France


Top
 Profile  
Reply with quote  
PostPosted: Sat Jun 01, 2024 7:02 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10938
Location: England
It doesn't answer your question, but
- watch out because two large sets of random numbers will still have coincidental matches
- why not just count up by 13 in one case and 17 in the other case, or use any other counts really, which you can check for integrity: is each byte the value it should be

(In other words, random numbers are only one possible approach)


Top
 Profile  
Reply with quote  
PostPosted: Sat Jun 01, 2024 7:55 pm 
Offline

Joined: Thu Dec 26, 2002 12:29 pm
Posts: 77
Location: Occitanie, France
BigEd wrote:
It doesn't answer your question, but
- watch out because two large sets of random numbers will still have coincidental matches
- why not just count up by 13 in one case and 17 in the other case, or use any other counts really, which you can check for integrity: is each byte the value it should be

(In other words, random numbers are only one possible approach)

Yes, thanks. I agree with point 3, understand about point 1 (but I don't think it matters here) - and I don't understand point 2. Do you mean that I can get an assembler to generate incremental bytes as "db $xx" values ? I feel so rusty at the moment...

I just wanted one set of "random" values so that the data I'd be reading when doing sequential reads from ROM, writes to HiRAM, and the final reads from HiRAM - the data bus wouldn't be doing sequential increments. The final result would be (I hope) an exact match ROM <-> HiRAM. If I leave the "empty" bits of ROM as $FF it doesn't really test much of circuitry.

_________________
Glenn-in-France


Top
 Profile  
Reply with quote  
PostPosted: Sat Jun 01, 2024 9:14 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10938
Location: England
Oh, I see, sorry, I got the wrong idea there.

srecord is a suite of utilities that can convert between various formats including adding random padding. It's got a peculiar interface which I always struggle with. But maybe something like
srec_cat /dev/null -binary -generate 0x8000 0x8100 --random
or maybe
srec_cat /dev/null -binary -generate 0x8000 0x8100 --random -output -intel

Or, maybe, something based on this
head -c 256 /dev/random | xxd --include


Top
 Profile  
Reply with quote  
PostPosted: Sat Jun 01, 2024 9:28 pm 
Offline

Joined: Sun Nov 08, 2009 1:56 am
Posts: 395
Location: Minnesota
Quote:
It would have been nice if one of the 6502 assemblers had a " db $RND" construct


An interesting idea. Not sure how generally useful, but it's not much code nor difficult to add. Though it would look more like

Code:
.byte rnd()


and if the user wanted a non-trivial number of them

Code:
.repeat count
.byte rnd()
.end


Though, hmmm, the user might want them in a certain range...that would be a little more code...


Top
 Profile  
Reply with quote  
PostPosted: Sat Jun 01, 2024 10:10 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8510
Location: Southern California
Even though the assembler itself doesn't have a random-number function, you could form it with the math and logic functions the assembler does have, even adding conditional assembly, and put it in a macro.

_________________
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: Sun Jun 02, 2024 12:26 am 
Offline
User avatar

Joined: Fri Jan 26, 2024 5:47 am
Posts: 40
Location: Prague; Czech Republic; Europe; Earth
Here is small util, which I wrote for fixing IHEX checksum, when I change some data inside.

It reads input file by lines, skip everything to first colon (':' - because I use it with something, which can number lines or make orher strange data at begin of line) and then it prints it on stdout, but with correct checksum

So you can generate something looking like IHEX file with any checksums (say simply "00" or "FF" or whatever) and fix the checksums with this script. See https://en.wikipedia.org/wiki/Intel_HEX

(like
Code:
(
  echo -n ":"; # Colon (-n means no EndOfLine on end)
  echo -n "80"; # Byte count, two hex digits
  echo -n "8000"; # Address, four hex digits
  echo -n "00"; # Record type, two hex digits
  for i in `seq 0 127`; do
      echo -n '2E';
  done; # Data. Here we generate "random" 2E for simplicity, but anything goes
  echo "FF"; # Checksum, two hex digits, next script will compute the right value, we need placeholder here
) >>test.IHEX

or even
Code:
echo ":04FFFC12345678FF" >>test.IHEX ; # 4 bytes at top of memory (12 34 56 78)

)

The script is here (I use TABs as indentation, if that will propagate)

Code:
#!/usr/bin/python -u

import argparse

def calculate_checksum(line):
   data = bytearray.fromhex(line[1:])  # exclude colon
   return ((0x100 - sum(data)) & 0xFF)

def fix_ihex_file(file_name):
   try:
      with open(file_name, 'r') as ihex_file:
         for line in ihex_file:
            colon_pos = line.find(':')
            if colon_pos != -1:
               length = int(line[colon_pos + 1:colon_pos + 3], 16)
               address = int(line[colon_pos + 3:colon_pos + 7], 16)
               rectype  = int(line[colon_pos + 7:colon_pos + 9], 16)
               data = line[colon_pos + 9:-3]  # exclude checksum
               
               new_address = address
               new_address_hex = format(new_address, '04X')
               rectype_hex = format(rectype, '02X')
               
               new_line = ":" + format(length, '02X') + new_address_hex + rectype_hex + data
               new_checksum = format(calculate_checksum(new_line), '02X')
               
               print(new_line + new_checksum)
   
   except FileNotFoundError:
      print("File not found!")

if __name__ == "__main__":
   parser = argparse.ArgumentParser(description="Fix IHEX file checksum")
   parser.add_argument("file", help="Input IHEX file")
   
   args = parser.parse_args()
   fix_ihex_file(args.file)


and use

Code:
python fix_ihex.py test.IHEX > test_fixed.IHEX

_________________
http://micro-corner.gilhad.cz/, http://8bit.gilhad.cz/6809/Expanduino/Expanduino_I.html, http://comp24.gilhad.cz/Comp24-specification.html, and many others


Top
 Profile  
Reply with quote  
PostPosted: Sun Jun 02, 2024 11:44 am 
Offline

Joined: Mon Jan 19, 2004 12:49 pm
Posts: 844
Location: Potsdam, DE
gilhad wrote:
Code:
for i in `seq 0 127`; do
      echo -n '2E';
  done; # Data. Here we generate "random" 2E for simplicity, but anything goes



But, but, but... everybody knows the correct random number is 4... https://imgs.xkcd.com/comics/random_number.png

Neil :mrgreen:


Top
 Profile  
Reply with quote  
PostPosted: Sun Jun 02, 2024 4:34 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8390
Location: Midwestern USA
Off-topic, but I’ve never been able to figure out why anyone would use Intel hex to feed code and data to a MOS Technology microprocessor.  :?:  :|

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
PostPosted: Sun Jun 02, 2024 5:06 pm 
Offline

Joined: Thu Dec 26, 2002 12:29 pm
Posts: 77
Location: Occitanie, France
Well, I'm back.
Thanks for all of the ideas, but I'm afraid my brain hurt trying to get around many of them !
As many of the tools I use daily are open-source, I thought I'd look through some of the assemblers that I've already evaluated to see if the RND() function could be easily added. And, after some false starts, I resurrected the HXA-cross-assembler by Anton Treuenfels. He has re-written the tools in Python and, although I don't like coding with Python, it's well structured and easy to understand.
I was able to easily use the internal Python getrandom() function and add the function to the assembler. Here is the result :
Code:
                    ; Hobby Cross-Assembler Demo 036
                    ; Macro Instruction Set\65C02
                    ; ok: 65C02 instruction set
 
                    ; by Anton Treuenfels
 
                    ; first created: 08/26/06
                    ; last revised:  12/11/23
                    ; -------------------------------
 
 0200  00 02 00 00          .org    $0200
 0200  02                   .byte   RND()
 0201  45                   .byte   RND()
 0202  85                   .byte   RND()
 0203  EE                   .byte   RND()
 0204  57                   .byte   RND()
 0205  6D                   .byte   RND()


Exactly what I wanted ! Thanks Anton !!

_________________
Glenn-in-France


Top
 Profile  
Reply with quote  
PostPosted: Sun Jun 02, 2024 7:05 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10938
Location: England
Hurrah for open source!


Top
 Profile  
Reply with quote  
PostPosted: Sun Jun 02, 2024 7:58 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8510
Location: Southern California
BigDumbDinosaur wrote:
Off-topic, but I’ve never been able to figure out why anyone would use Intel hex to feed code and data to a MOS Technology microprocessor.  :?:  :|

Intel Hex is what was spit out by the first 6502 assembler and also the only metacompiler I ever used, and I had to learn it, especially to figure out serious bugs in the metacompiler, so I just stayed with it.  Whatever you have, SRecord 1.65 lets you convert from one file type to another, among many, many types.  Curiously, there's even a Wilson format; but I had nothing to do with it, and I just now noticed it.

_________________
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: Sun Jun 02, 2024 8:13 pm 
Offline

Joined: Sun Nov 08, 2009 1:56 am
Posts: 395
Location: Minnesota
Quote:
I was able to easily use the internal Python getrandom() function and add the function to the assembler. Here is the result :


Glad you found the assembler easy to modify (one of the reasons for switching to Python from TAWK). If what you did meets your needs, great!

I did play around a bit with the idea myself. Here's what I came up with so far (and only lightly tested so far).

I did use Python's random module:

Code:
from random import seed, randint


I added these two functions:

Code:
def fncRnd(lo, hi=None):
   '''random integer in the range lo <= N <= hi'''
   return ( True, randint(0, lo) if hi is None else randint(lo, hi) )

def fncSeed(val=None):
   '''seed the random number generator'''
   if val is None:
      seed()
      val = randint( 0, 2^31 )
   else:
      seed( val )
   return( True, val )


I wanted SEED() to return the value it used as a seed in case someone wanted to save it and generate the same sequence later. Not really possible with Python's internal SEED() function, which doesn't return anything at all. If it is not given a value, it uses the internal clock or whatever else the hardware provides, but won't tell you what the actual value was. So I had to cheat a bit and generate one random value before I could return that value (not quite tested yet, but I think it'll work).

In the function dispatch table I connected the names to the functions:

Code:
   'RND':      ( fncRnd, 1, 2, 'nn2n' ),
   'ROOTFILE$':   (fncRfn, 0, 0, '2s' ),
   'SEED':      (fncSeed, 0, 1, 'n2n' ),


The table doesn't actually have to be in alphabetic order, but I find it easier to modify if it is...

If all goes well, these will be in the next release (currently trying to add 6800 and 6803 instruction sets). Though I think I need to see what happens for something like RND(63, -1)...


Top
 Profile  
Reply with quote  
PostPosted: Sun Jun 02, 2024 8:43 pm 
Offline

Joined: Thu Dec 26, 2002 12:29 pm
Posts: 77
Location: Occitanie, France
teamtempest wrote:
Quote:
If all goes well, these will be in the next release (currently trying to add 6800 and 6803 instruction sets). Though I think I need to see what happens for something like RND(63, -1)...


I'll PM you with what I did, and a few suggestions.

_________________
Glenn-in-France


Top
 Profile  
Reply with quote  
PostPosted: Mon Jun 03, 2024 10:31 pm 
Offline
User avatar

Joined: Fri Jan 26, 2024 5:47 am
Posts: 40
Location: Prague; Czech Republic; Europe; Earth
teamtempest wrote:
I wanted SEED() to return the value it used as a seed in case someone wanted to save it and generate the same sequence later. Not really possible with Python's internal SEED() function, which doesn't return anything at all. If it is not given a value, it uses the internal clock or whatever else the hardware provides, but won't tell you what the actual value was. So I had to cheat a bit and generate one random value before I could return that value (not quite tested yet, but I think it'll work).


If you use fncSeed(None), then random seed is set and then is returned random value, which have no meaning, as using it as seed would lead to different "random" sequence

I think, that the right behavior is like that - if val is missing, generate one random and then use & return it
Code:
def fncSeed(val=None):
   '''seed the random number generator'''
   if val is None:
      seed()
      val = randint( 0, 2^31 )
   seed( val )
   return( True, val )

_________________
http://micro-corner.gilhad.cz/, http://8bit.gilhad.cz/6809/Expanduino/Expanduino_I.html, http://comp24.gilhad.cz/Comp24-specification.html, and many others


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 15 posts ] 

All times are UTC


Who is online

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