6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sat Apr 27, 2024 6:11 am

All times are UTC




Post new topic Reply to topic  [ 5 posts ] 
Author Message
PostPosted: Sun Mar 24, 2024 2:50 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8144
Location: Midwestern USA
This topic is about a software project I did to test a new Motorola S-record loader for my POC V1.3 unit’s firmware.  I’m posting it as a separate topic because others with 65C816 systems might find it useful.  The attached source code file is standalone, other than where it makes BIOS API calls to do I/O operations.  Everything is sufficiently commented so modifications may be made without much difficulty.  If you aren’t up to speed on the S-record format, please refer to the attached documentation.

I do all my 65C816 development in the editor/assembler that is part of the Kowalski simulator.  Code that is to be loaded directly into RAM for testing is sent to the POC unit as a Motorola S-record stream, S-records being one of the assembler’s supported object file types (the others are Intel hex and raw binary).  As originally developed by Mike Kowalski, the assembler understands the NMOS 6502 and Rockwell 65C02 instruction sets.  Since these MPUs have a 16-bit address bus, the original assembler generates one or more S1 (data) records, and one S9 (trailer) record, both having a 16-bit load address field.

Prior to V1.3, my POC units did not have “extended” RAM, so the 16-bit load address in an S1 or S9 record worked fine—all RAM was in bank $00.  That changed with V1.3, which has 128 KB of RAM.  In order to be able to load into extended RAM, I added code to V1.3’s firmware so I could specify a non-zero load bank (as well as a page offset for relocating loads).  That arrangement works...as long as I don’t forget to specify bank $01 as the load target.  Absent the bank $01 specification, code will end up in bank $00.  If the load lands on top of system areas, such as the stack or other critical data structures, the machine will go off the rails.  :(  Been there, done that...many times.  :oops:

The current version of the Kowalski assembler, as augmented by Daryl Rictor, adds support for native-mode, 65C816 assembly language.  Part of that support includes the ability to assemble programs to run in extended RAM, access to which requires 24-bit addressing.  Accordingly, if a program’s origin address is in bank $01 or higher, the assembler’s S-record output will have S2 (data) and S8 (trailer) records, which have a 24-bit load address field.

The S-record loader that is in V1.3’s present firmware only understands S1 and S9 records, and accepts, but ignores, S0 (header) and S5 (block count) records.  Reception of any other record type will cause the load operation to abort with an error.  As the original firmware was developed to fit in 8 KB of ROM, I made the loader as lean as possible, which meant only rudimentary error-checking was implemented.

Given the Kowalski assembler’s ability to work with the 816’s full address range, I decided it was time to update the loader to accept S2 and S8 records, while continuing to accept S1 and S9 records.  The new-and-improved loader is structurally different than the original, since the Motorola standard allows intermixing of S1 and S2 records in the same data stream.  That has been accommodated in the design, along with more-granular error processing.  As the Kowalski assembler doesn’t generate S0 or S5 records, the loader only has function stubs to process them.  Someone who decides to adapt this code to their system can add to those stubs if their assemblers generate those records.

The assembler inserts the starting address for program execution in the address field of a S8 or S9 record, which will be (should be) the last record in the stream.  The starting address is set to the first *=<address> declaration encountered in the source code, unless the optional .START pseudo-op is used to defined an alternate starting point (syntax is .START <label> or .START <address>).

The firmware version of the loader will continue to have the option to set an alternate bank as the load target, along with the page offset feature.  However, if the load consists of S2 and S8 records, the bank option will be ignored, since a full 24-bit address is being specified.  If the program was assembled with 16-bit address, e.g., a 65C02 program that I might wish to try out, the alternate bank will be used to determine where the load will go.

The firmware version of the present loader writes the start address in the M/L monitor’s PB (program bank) and PC (program counter) shadow registers following a successful load.  That way a simple G (run program) monitor command will start execution after loading.  I will retain that feature with the new loader.

Also attached is a program that I concocted solely to generate data to load into bank $01 RAM during testing.  All it does is generate a repeating pattern of bytes that I can easily examine with memory dumps.  This testing method proved that the new-and-improved loader works.  I also manually edited the test code’s S-record output in various ways to induce errors so I could see how well the loader handled them.  Some other shenanigans on my Linux box that drives the POC unit’s auxiliary serial port were used to create bursts of data corruption to see what the loader would do when it got non-ASCII characters in the data stream.  It all appears to work.

———————————————————————————————————————————————
Attachment:
File comment: 65C816-Compatible S-Record Loader
loader.asm [52.04 KiB]
Downloaded 63 times
Attachment:
File comment: S-Record Loader Test Data
testload.asm [1.56 KiB]
Downloaded 59 times
Attachment:
File comment: Motorola S-Record Official Definition
motorola_s_record.pdf [28.82 KiB]
Downloaded 62 times
Attachment:
File comment: S-Record Pictorial
srecord_chart.png
srecord_chart.png [ 581.42 KiB | Viewed 2511 times ]

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


Top
 Profile  
Reply with quote  
PostPosted: Sat Mar 30, 2024 7:43 pm 
Offline

Joined: Sun Nov 08, 2009 1:56 am
Posts: 387
Location: Minnesota
Quote:
the Motorola standard allows intermixing of S1 and S2 records in the same data stream.


I'm curious about this, and have so far not found any verification. Maybe I just haven't found the correct documentation yet.

It would seem that there's no real technical problem with giving each data record its own address type, as opposed to requiring that every data record in a file having the same type.

But if so, how would a stream of such mixed records be terminated? With an 'S9' or an 'S8' record? Either way, wouldn't it require that the unsuspecting reader to keep track of which record types it's actually seen? So that it knew which terminator record to expect, perhaps the one that corresponded to the highest address it had seen?

Or maybe accept any of 'S9', 'S8', or 'S7' as terminator records, possibly whichever one it sees first?


Top
 Profile  
Reply with quote  
PostPosted: Sat Mar 30, 2024 8:08 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8144
Location: Midwestern USA
teamtempest wrote:
Quote:
the Motorola standard allows intermixing of S1 and S2 records in the same data stream.

I'm curious about this, and have so far not found any verification. Maybe I just haven't found the correct documentation yet.

I believe the documentation in the Motorola manual for the 68000 made that statement.  In any case, there is no prohibition of which I am aware against intermixing S1, S2 and S3 records in the same stream.

Quote:
It would seem that there's no real technical problem with giving each data record its own address type, as opposed to requiring that every data record in a file having the same type.

There isn’t, and my latest rendition of the S-record loader (posted above) for the 65C816 handles both S1 and S2 records in the same stream, and in any order.  The loader could also be made to process S3 records, but in practice, those would not be emitted by most 65C816 assemblers.

Quote:
But if so, how would a stream of such mixed records be terminated? With an 'S9' or an 'S8' record? Either way, wouldn't it require that the unsuspecting reader to keep track of which record types it's actually seen? So that it knew which terminator record to expect, perhaps the one that corresponded to the highest address it had seen?

There is supposed to be only one terminator record in the stream, the record type being determined by the execution address to be encoded in its address field.  It is perfectly reasonable to terminate with an S9 if the execution address can be expressed in 16 bits.  My loader terminates upon receipt of an S8 or S9.

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


Top
 Profile  
Reply with quote  
PostPosted: Mon Apr 01, 2024 4:34 am 
Offline

Joined: Sun Nov 08, 2009 1:56 am
Posts: 387
Location: Minnesota
I find some confirmation of that information in (the short) Appendix C of https://www.nxp.com/docs/en/reference-manual/M68000PRM.pdf. From that it does appear that S1, S2, and S3 records can be intermixed in a single SRecord file.

However, it also speaks of S9, S8, and S7 termination records for "blocks" of the corresponding records types. Since addresses are optional in termination records, it does seem that it is possible to create a run of S1 records, terminate them with an S9 record which has no address, and then begin another run of, say, S2 records to finally be followed by an S8 record with a starting execution address. So only the final termination record needs to have a starting execution address (or somehow make provision for a default provided by the OS).

But every block of S1, S2 or S3 records has to have its own terminator record, if I'm reading this correctly. In any case, no matter how I read it, the familiar 'S19' record file, with only S1 data records and a single S9 terminator record, is valid. So are 'S28' and 'S37' files.

On the other hand, so would a 'S1S9S2S8S1S9' file be, I think.

And on the other other hand...whatever works :-)


Top
 Profile  
Reply with quote  
PostPosted: Tue Apr 02, 2024 8:17 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8144
Location: Midwestern USA
I tightened up the loader’s code a bit.  New rendition attached—assembles in the Kowalski assembler.

Attachment:
File comment: 65C816-Compatible S-Record Loader
loader.asm [47.74 KiB]
Downloaded 49 times

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


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

All times are UTC


Who is online

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