Page 1 of 4

Signature for ROM based programs

Posted: Sat Jan 23, 2021 8:45 am
by Stefan

Hi,

Elsewhere on this site, there was some discussion on the need for a common way to uniquely identify user-added programs stored in ROM.

A program could be identified by a "magic" string, similar to how many file formats work.

In the ROM version of X16 Edit I have for instance stored this string at address $fff0: "X16EDIT" followed by three more bytes representing the program version (major-minor-patch).

@pzembrod commented on this, and said that the place near end of ROM might not be best suited, should you want to replicate the calling addresses of the Kernal routines.

Another possibility would then be the start of ROM, i.e. $c000.

RFC:


  • Is there any need for a standard way of marking and identifying ROM based programs like this?


  • Should we use a magic string based solution as described above?


  • If so, where in ROM should we place the magic word?


  • Can we agree on a magic string format? For instance:


    • <PROGRAM NAME><NULL><VERSION>


    • where <PROGRAM NAME><NULL> is a null terminated string containing the program name


    • where <VERSION> is the program version represented by three bytes (major, minor, patch)


    • with a total length of not more than 256 bytes


    • Example: "X16EDIT",0,0,3,3 => X16EDIT version 0.3.3





Signature for ROM based programs

Posted: Sat Jan 23, 2021 10:08 am
by TomXP411

Yeah, I think it's a good idea. It's become kind of a standard to have a "magic string" at the beginning of data files, and I'm encouraging that with the container specification I'm developing. 

What I'd suggest is we encourage people to place a text description in the first 16 bytes of the ROM, so the jump address to invoke the ROM ends up being a consistent value ($C010). 


Signature for ROM based programs

Posted: Sat Jan 23, 2021 12:32 pm
by desertfish

You could also have a vector or even a single JMP instruction at $C000 that jumps to the actual entry point, followed by the name and version info and perhaps other data, followed by the program itself which it jumps to.  That way you can have the layout however you want; the start is always at $c000 


Signature for ROM based programs

Posted: Sat Jan 23, 2021 5:49 pm
by BruceMcF


5 hours ago, desertfish said:




You could also have a vector or even a single JMP instruction at $C000 that jumps to the actual entry point, followed by the name and version info and perhaps other data, followed by the program itself which it jumps to.  That way you can have the layout however you want; the start is always at $c000 



This is my preference. JMP DOSTART : .byte 8,"xforth16", 0,1,0,0

Call to entry point.

Number of bytes in name, Null terminated string, Major, Minor, Patch

Even better is a cold start is called with the carry clear, a warm start is called with the carry set.

 


Signature for ROM based programs

Posted: Sat Jan 23, 2021 10:49 pm
by Stefan

Great input!

Let's think about what you could do with a common program signature.

It could be used for instance to:


  • list ROM content, and/or


  • make a command in Basic to start ROM based programs: START("<APPNAME>").


If there would be a START command, it would also be great if you could specify start parameters, for instance like this: START("<APPNAME">, "<PARAMS>").

What is required to make this kind of functionality possible? Maybe:


  • A way to read the program name from each ROM bank


  • A fixed entry point, or at least a way to get the entry point


  • A way for the program to read start params


One solution:


  • A fixed length header containing


    • Program name


    • Program version




  • A fixed address for the main entry point


  • The start params could be a null terminated string referenced by one of the zero page registers R0-R15.


    • The string format could be inspired by how you write command line parameters


    • In the end each program would be responsible for the interpretation of the param string




But maybe I'm getting ahead of things now ?


Signature for ROM based programs

Posted: Sun Jan 24, 2021 9:57 am
by BruceMcF

An advantage of the counted+null-terminated string is it is easier to test whether there IS a harder. If count is not less than the max string length, it doesn't have a header and if count-address+count+1 does not have a zero, it doesn't have a header.

However, if $C000 is the start point, there is a structure that implies the header length almost "for free", which is:

Start0: BRA Start1 : .bye " xforth16", 0,1,0,0

Start1: ...

... where the size of the branch implies the size of the header.


Signature for ROM based programs

Posted: Sun Jan 24, 2021 10:38 am
by pzembrod

One additional feature/option to take into account: An API jump list for the ROM, similar to the Kernal jump list at $ffxx.

@Stefan and me discussed this in the context of X16Edit, and so far Stefan implemented one call without parameters at $c000 to start the editor with an empty file, and another call with a file name parameter at $c003 to open an existing file. I find a standard way to establish such an API extremely useful, and I think the beginning of the ROM would be the best place for it, because then, as Stefan wrote earlier, a ROM implementer has the option to also put a redirect copy of the Kernal API into the ROM, which a custom ROM jump list at the end of the ROM would make impossible.

I like @BruceMcF's proposal of first a start jump. The API jump list could then follow the signature string and the versions.

*= $c000

  JMP DOSTART

  .byte 8,"xforth16", 0,1,0,0

API:

  JMP FUNCTION1

  JMP FUNCTION2

...


This could be combined with the idea of a bra at $c000, defining the length of the signature block; then FUCNTION1 would have to essentially be DOSTART. I'm on the fence whether I would prefer this to the JMP + dedicated length byte, though.

I'm also on the fence whether to define a standard address for the API, e.g. $c010. In a way it would be nice, but otoh it would limit the string length, and since the API will be ROM-specific anyway, I guess there is no harm having the jump list's start address being ROM-specific, too.


Signature for ROM based programs

Posted: Sun Jan 24, 2021 12:26 pm
by desertfish

A bit off-topic perhaps:

I've not followed all of the discussion, but the API call list reminds me of:

- how most SID player routines work on the Commodore-64 where they provide at least three JMPs at the start to init the song, stop the song, and the play routine that should be called every interrupt.

- how shared libraries were implemented on the AmigaDOS operating system where you had a pointer to the library in a register and the calls for all library routines were vectored through a jump table on given documented offsets, and the library's header itself followed by the routines on another offset.  It was pretty nifty and allowed for easy runtime patching of library routines (because this structure was in RAM).


Signature for ROM based programs

Posted: Sun Jan 24, 2021 2:50 pm
by kktos


4 hours ago, pzembrod said:




One additional feature/option to take into account: An API jump list for the ROM, similar to the Kernal jump list at $ffxx.



Oh, No, please, No, not that way !!!!

That's too finite, not easily expandable.

Prefer a single point of entry and a parameter as function id.

Either a

  LDA #FUNCTION_X

  JSR ENTRYPOINT

or a more versatile:

JSR ENTRYPOINT

.db function_x

.dw parms_ptr


Signature for ROM based programs

Posted: Sun Jan 24, 2021 4:05 pm
by BruceMcF

Of course, it is a 65C02, not a 6502, so JMP (addr,X) is an option.

ROMSTART: JMP (START1,X) : .byte "xforth16",0,1,0,0

START1: .word COLDSTART,WARMSTART,COMLINE

called with LDX #op : JSR ROMSTART ... in that case, the length of the header is implicit in the lower byte of the vector table address.