6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Mon Nov 11, 2024 11:28 pm

All times are UTC




Post new topic Reply to topic  [ 25 posts ]  Go to page Previous  1, 2
Author Message
PostPosted: Sat Sep 05, 2020 3:20 am 
Offline

Joined: Sun Apr 26, 2020 3:08 am
Posts: 357
Also, there were DOS loaders that moved DOS itself into the language card. This would have required an address change to all subroutine calls.

I also created a hex changer program that checks for any 3 byte instruction, then checks if the address is a call within the program itself, or outside and if within, it then asks if you want to change the high byte to the new location's address.

For example, the prompts are:

Original start address: $2000
Original ending address: $4FFF
New location address high byte: $80

Say a program normally loads at $2000, but you want the program to run at $8000. Each 3 byte instruction looks at the 3rd byte and compares it to the range $20-$4F. If it falls within the range, then the high byte number is subtracted from $20 and added to $80.

My program also checks for 2 byte immediate instructions, which can also have a byte that falls within the range. Since that byte can also be a value that can fall within the range of the program, a prompt is also issued to change it.

It has saved me a ton of time instead of entering the program into an assembler and re-assembling it.


Top
 Profile  
Reply with quote  
PostPosted: Sat Sep 05, 2020 2:28 pm 
Offline

Joined: Sun Jun 29, 2014 5:42 am
Posts: 352
BigEd wrote:
The later revisions of Acorn's OS for the BBC Micro series also had a scheme for relocation: ROM code is normally assembled to run at 8000, but when run on the second processor can be loaded and run at B800 - if fixed up. I haven't looked at the code which does the fixing up.

The ability to specify a relocation table was only present in MOS 3.50 (for the Master).

It's only intended to be used with 6502 code.

The technical details of this are included in an appendix to the MOS 3.50 User Guide:
http://mdfs.net/System/ROMs/AcornMOS/Ma ... /UserGuide

It uses a very compact bitmap, with one bit for each byte in the ROM that has a value between 0x7F and 0xBF (language ROMs in the BBC are located at 0x8000 and are 16K long). The bit indicates whether the corresponding byte needs correcting with a fixed offset when copied across the tube.

Dave


Top
 Profile  
Reply with quote  
PostPosted: Sat Sep 05, 2020 2:31 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10977
Location: England
Thanks for the details Dave!


Top
 Profile  
Reply with quote  
PostPosted: Sat Sep 05, 2020 5:00 pm 
Offline
User avatar

Joined: Sat Dec 01, 2018 1:53 pm
Posts: 727
Location: Tokyo, Japan
IamRob wrote:
Also, there were DOS loaders that moved DOS itself into the language card. This would have required an address change to all subroutine calls.

Yup, but Apple II DOS already knew how to do that anyway. On a "master" diskette DOS was always loaded into relatively low memory (low enough that it would work on a 16K machine) and relocated itself to the top of RAM for that particular machine.

When you did an `INIT` to format a new diskette, the DOS was written out as-is from memory and, when booted on another machine, would still load at the same location as it had been on the machine that did the `INIT`. If you had more memory than that machine, your extra memory was wasted (at least if you were programming in BASIC) because it loaded at a lower location than necessary. If you didn't have as much memory as the original machine, you simply couldn't boot that diskette.

These diskettes were known as "slave" diskettes. If you wanted a diskette that would load DOS low and relocate it, so it would work (and work optimally) on any machine, you used a program called `MASTER CREATE` to tweak the DOS on that diskette to do its relocating load thing.

_________________
Curt J. Sampson - github.com/0cjs


Top
 Profile  
Reply with quote  
PostPosted: Sun Sep 06, 2020 2:02 pm 
Offline

Joined: Thu Mar 12, 2020 10:04 pm
Posts: 704
Location: North Tejas
I got the EXEC command working on the 6502. The code to open the file, copy the "resident" portion to the top of RAM and do the relocation adjustments was substantially larger than the resident portion which reads lines from the script file, passes the commands to FLEX and cleans up after itself. About 256 bytes versus about 150 (plus 320 for the file control block.)

Being twisted, I had to try executing another EXEC command from a script. Well, chaining from one script to another worked, but when the latter finished, the first instance of EXEC never regained control. I had forgotten that FLEX stores some system state in static variables, so the second instance of EXEC causes the first to be forgotten.

I am now pondering whether to find a fix for this as nested scripts can be useful in the same way that nested include files are sometimes handy.


Top
 Profile  
Reply with quote  
PostPosted: Wed Sep 09, 2020 9:10 pm 
Offline

Joined: Sun Feb 22, 2004 9:01 pm
Posts: 104
hoglet wrote:
The ability to specify a relocation table was only present in MOS 3.50 (for the Master).
It's only intended to be used with 6502 code.
The technical details of this are included in an appendix to the MOS 3.50 User Guide:
http://mdfs.net/System/ROMs/AcornMOS/Ma ... /UserGuide

I updated this method to do relocation by byte offset, so you assemble for 0x8000 and relocate to eg 0x9182.
You build the code twice, and build a bitmap of bytes &C0-&BF that are the high bytes of addresses &8000-&BFFF,
and the loader code adjusts the address. You have to adapt your code writing to ensure that every word that
needs relocating is a 16-bit word in the code, not split over two bytes, so you have to do stuff like:
LDA word+0:STA vector+0
LDA word+1:STA vector+1
...
.word
EQUW destaddr

and not:
LDA #destaddr AND 255:STA vector+0
LDA #destaddr DIV 256:STA vector+1

The code that generates the bitmap is in SMLib.bas
and the code that relocates code is in SMJoin.bas
and SMLoad.bas

I wrote this up for Micro User back around 1990-ish, but it didn't get published, and they were progressively
dropping their 8-bit articles at that point. I need to rewrite the documentation and get it online.

_________________
--
JGH - http://mdfs.net


Top
 Profile  
Reply with quote  
PostPosted: Wed Sep 09, 2020 10:27 pm 
Offline

Joined: Mon May 01, 2017 7:13 am
Posts: 83
Rather than reinventing the wheel, I think it's more useful to understand how it's done in ELF on PC targets.

https://lwn.net/Articles/276782/


Top
 Profile  
Reply with quote  
PostPosted: Tue Dec 22, 2020 1:00 pm 
Offline

Joined: Tue Jul 05, 2005 7:08 pm
Posts: 1042
Location: near Heidelberg, Germany
BillG wrote:
White Flame wrote:
The .o65 output from ca65/ld65 generates relocation tables. These come from the linker itself, which resolves the references into the output bytes, knowing which references refer to locations within the binary itself, vs which are outside of it.


Thanks, but that looks very complicated.


I've considerably tried to keep it as simple as possible to load. You can use block load for the program and data, and relocate after loading. Here is the description of the format: http://6502.org/users/andre/o65/

Oh, and btw, the file format supports pagewise relocation, and there is a sample loader code available.

Quote:
Allow me to clarify more specifically what I am after.

The FLEX EXEC command on the 6809 loads into the Utility Command Space. It checks MEMEND and copies itself to the top of the main RAM and lowers MEMEND to protect itself. EXEC is a utility to execute a series of commands from a file. MEMEND is a FLEX system variable which contains the address of the highest usable location of user RAM.

It does its business, then restores MEMEND before exiting.

I am looking to build something similar for the 6502 and 6800 neither of which readily supports writing position independent code. EXEC for the 6800 currently loads at a fixed location just below the 32K mark, meaning it cannot be used on a machine with less than 32K of main RAM or if other "terminate and stay resident" programs are already loaded into that area.

I prefer something fairly simple which will work with code generated by most tools, though I am currently using either the FLEX ASMB assembler or my own cross assembler. I do not want to be tied to one assembler, compiler or linker. Eventually, it would be nice to be able to build a relocatable program entirely using tools hosted by FLEX. The bit map builder tool originally runs on a PC, but will later be built as a FLEX program.


I don't know what FLEX is. o65 is supported by xa65 and ca65 at least.

If you need a different type of relocatable file format, you could provide a converter from o65 to your format to increase coverage by other assemblers.

Quote:
If this works out well, I may try to create something like MOVCPM to allow the end user to move a 6502 FLEX system image without having to rebuild it from source.



I assume you don't want to relocate a "running" program, but just relocate at load time? There are so many other things to consider relocating a running program (values in variables, stack) that this looks a rather challenging task. o65 for example saves space by putting an offset to the referenced variable in the code/data section where the relocated address should go, and just adds the referenced variable to it. ... to relocate a running program you'd have to make sure to add the relocation offset (new minus old variable value, which should be constant), but also have to make sure you consider special values, like $0000 as a flag for example.

André

_________________
Author of the GeckOS multitasking operating system, the usb65 stack, designer of the Micro-PET and many more 6502 content: http://6502.org/users/andre/


Top
 Profile  
Reply with quote  
PostPosted: Tue Dec 22, 2020 2:05 pm 
Offline

Joined: Tue Jul 05, 2005 7:08 pm
Posts: 1042
Location: near Heidelberg, Germany
johnwbyrd wrote:
Rather than reinventing the wheel, I think it's more useful to understand how it's done in ELF on PC targets.

https://lwn.net/Articles/276782/



Interestingly, ELF can do "Relaxations" - shrinking/optimizing instructions at link time if the jump distance allows for it. https://www.airs.com/blog/archives/46

Is something like this implemented in the cc65 toolchain?

_________________
Author of the GeckOS multitasking operating system, the usb65 stack, designer of the Micro-PET and many more 6502 content: http://6502.org/users/andre/


Top
 Profile  
Reply with quote  
PostPosted: Tue Dec 22, 2020 2:20 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10977
Location: England
Just thinking aloud here, about the possibility of a header to an executable, which is pre-informed about the high bytes of addresses within the program, and which just does a little trickery to discover its load address (perhaps with a few bytes of code copied into page 1) and then patches the rest of the executable in memory, before jumping to the real start location.


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

All times are UTC


Who is online

Users browsing this forum: No registered users and 1 guest


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: