Relocatable Machine Code

Any discussions related to the creation of new hardware or software for the ZX80 or ZX81
dr beep
Posts: 2341
Joined: Thu Jun 16, 2011 8:35 am
Location: Boxmeer

Re: Relocatable Machine Code

Post by dr beep »

stefano wrote: Mon Jul 25, 2022 8:53 am The 'supercode' tools for the Spectrum used to discover the current location by calling a known position in ROM with a simple RET instruction. After that they got the address from the stack.
SO

DI
CALL 82
DEC SP
DEC SP
POP HL
EI

Was also used in the making of Z80 files in Gerton Lunter’s emulator.
User avatar
stefano
Posts: 592
Joined: Tue Dec 11, 2012 9:24 am
Contact:

Re: Relocatable Machine Code

Post by stefano »

Exactly !

https://github.com/z88dk/techdocs/blob/ ... .asm#L2470


..While I'm mentioning SuperCode, I think that a bold programmer could try to convert some of those routines, e.g.

https://github.com/z88dk/techdocs/blob/ ... .asm#L1789

https://github.com/z88dk/techdocs/blob/ ... .asm#L1904

https://github.com/z88dk/techdocs/blob/ ... .asm#L3939

https://github.com/z88dk/techdocs/blob/ ... .asm#L4870



Obviously it's not an easy task and only a small subset of routines could be converted.
David G
Posts: 449
Joined: Thu Jul 17, 2014 7:58 am
Location: 48 North

Re: Relocatable Machine Code

Post by David G »

thanks for the ideas

It's easy enough to make the 1) string tables relocatable, 2) JPs relocatable, 3) app variables relocatable

But the CALLs are not so simple. It's a mess, not sure it's worth it. Nice clean code becomes hard to follow. Using the ROM call to JP(HL) works, but then if the CALL uses the HL register on entry, have to figure out how to pass it along. I can think of several ways and got one method working, but the nice short code is now becomes much longer and harder to understand

It helps to reduce/flatten CALLs where feasible. Meaning if CALLed only once or twice, just inline the code. For sake of readability a few time i was using CALL even though the subroutine was only called once. Inlining that saves 4 bytes. If called twice, inlining makes sense for short subroutines

I created one new CALL to make the offset and call JP(HL) -- since it is used many times it make sense to make it a subroutine. For this one CALL I tried dr beep's idea
dr beep wrote: Sat Jul 23, 2022 11:53 amalter all JP/CALL and redaing of memory in the program. Last can be done with storage outside the program
...using BASIC to find all instances of this one CALL and fixup the address for the intended destination. At least i think that's what dr beep was referring to. It works fine in any case

But I'm having a lot of trouble redoing the CALLS, i got several working just fine, but have to debug the ones that don't work ... and cannot test if it is truly relocatable until all it is done ...

Maybe I should do fixups for every CALL within the app? In other words, instead of writing relocatable code, do a fixup in BASIC just before moving the code. That way the machine code is small and simple, and the BASIC "loader" program is larger. I guess that's a "hybrid" approach?

The machine code I'm starting with is just under 1K, but with the relocatable changes is over considerably over 1K. Not really a problem as we all have a lot of memory these days -- it can be copied to above RAMTOP, above 32K, to 8K or wherever one wishes and run/ BASIC can ask where you want it, fix it up, and copy the MC code there
David G
Posts: 449
Joined: Thu Jul 17, 2014 7:58 am
Location: 48 North

Re: Relocatable Machine Code

Post by David G »

The more I think about this, the better it seems. Having a relocating Loader is more scalable, as each machine code program wouldn't need to be changed. Create a robust Loader and it works all programs

1. Scan the machine code for JP, CALL or LD iNN nstructions
2. Check the operands to see if they are within the range of the M/C program
3. adjust the operand

The big problem I foresee is where data (or strings) are mixed in with the program instructions. The loader might see a bytecode in there that corresponds to one of the JP/CALL/LD opcodes. Is this why Windows executables always have separate .data and code sections?
User avatar
mrtinb
Posts: 1979
Joined: Fri Nov 06, 2015 5:44 pm
Location: Denmark
Contact:

Re: Relocatable Machine Code

Post by mrtinb »

The separation of .data and.code segments is a feature of the 8086 16-bit processor.

The Z80 is a follow up to Intels predecessor 8080/8085 line, which is their 8-bit line of processors. This line does not support segments.

You are right. Your main concern is data misinterpreted as code. Some programs have data separated in a chunk, and some programs have data spread all over the source.
Martin
https://zx.rtin.be
ZX81, Lambda 8300, Commodore 64, Mac G4 Cube
User avatar
GCHarder
Posts: 450
Joined: Sat Dec 14, 2013 7:46 pm

Re: Relocatable Machine Code

Post by GCHarder »

Here's another relocate program, I recently found, which looks interesting, unfortunately some of the listing is illegible but it may be salvageable if someone wants to try it.

https://archive.org/details/ohtsug/OHTS ... 3/mode/2up

Regards;

Greg
User avatar
XavSnap
Posts: 2072
Joined: Sat May 10, 2008 4:23 pm
Location: 'Zx81 France' Fb group.
Contact:

Re: Relocatable Machine Code

Post by XavSnap »

GCHarder wrote: Sat Jul 30, 2022 7:31 pm ...if someone wants to try it.
Out of memory error in 9260.
May be a type-in error...

Code: Select all

;------- TASM ASM mnemonics. -------
; Compile this file using:
; Set TASMOPTS = -b
; tasm -80 ThisCode.tas MyBinary.BIN
;-----------------------------------
; Zx81 Program name: VB81 XuR [relocator.bas] :
; REM   line   name: 1 REM:   453 Bytes@4082-4246

#define ORG  .org       ; TASM cross-assembler definitions
#define equ  .equ
;-----------------------------------

;------------------------------------
;-BASIC sub-routine entry.          -
;+----------------------------------+
; Lb4082  ;  <- USR BASIC Enty.
;+----------------------------------+

;------- Rom and Ram Symbols -------
RAM_PRBUFF03 equ $403F
RAM_PRBUFF05 equ $4041
RAM_PRBUFF09 equ $4045
RAM_PRBUFF07 equ $4043
RAM_PRBUFF02 equ $403E
RAM_PRBUFF00 equ $403C
RAM_CH_ADD equ $4016
DEC_TO_FP equ $14D9
FIND_INT equ $0EA7


ORG $4082 ; [@16514/@h4082]
Lb4082:
	LD BC,(RAM_PRBUFF03) ; GET PRBUFF
	PUSH BC 
	LD BC,(RAM_PRBUFF05) ; GET PRBUFF
	PUSH BC 
	LD BC,(RAM_PRBUFF09) ; GET PRBUFF
	PUSH BC 
	LD HL,(RAM_PRBUFF03) ; GET PRBUFF
	ADD HL,BC 
	DEC HL 
	LD (RAM_PRBUFF07),HL ; SET PRBUFF
	LD A,(RAM_PRBUFF02) ; GET PRBUFF
	POP DE 
	POP HL 
	POP BC 
	PUSH BC 
	PUSH HL 
	PUSH DE 
	XOR A 
	SBC HL,BC 
	LD (RAM_PRBUFF00),HL ; SET PRBUFF
	JP Z, Lb4240 ; [16960]
	POP BC 
	POP DE 
	POP HL 
	PUSH HL 
	PUSH DE 
	PUSH BC 
	JP NC, Lb40B8 ; [16568]
	LDIR 
	JR Lb40C0 ; [$40C0:16576]
Lb40B8:
	ADD HL,BC 
	DEC HL 
	EX DE,HL 
	ADD HL,BC 
	DEC HL 
	EX DE,HL 
	LDDR 
Lb40C0:
	LD A,(RAM_PRBUFF02) ; GET PRBUFF
	CP $28 ; [40-"C"]
	JP NZ, Lb4240 ; [16960]
	POP BC 
	POP HL 
	PUSH HL 
	PUSH BC 
	DEC BC 
Lb40CD:
	LD A,(HL) 
	CP $DD ; [221]
	JP Z, Lb40D7 ; [16599]
	CP $FD ; [253]
	JR NZ, Lb411F ; [$411F:16671]
Lb40D7:
	INC HL 
	DEC BC 
	LD A,(HL) 
	CP $CB ; [203]
	JP Z, Lb422C ; [16940]
	CP $21 ; [33-"5"]
	JP Z, Lb422C ; [16940]
	CP $22 ; [34-"6"]
	JP Z, Lb41F2 ; [16882]
	CP $2A ; [42-"E"]
	JP Z, Lb41F2 ; [16882]
	CP $36 ; [54-"Q"]
	JP Z, Lb422C ; [16940]
	CP $09 ; [9]
	JR Z, Lb411C ; [$411C:16668]
	CP $19 ; [25-";"]
	JR Z, Lb411C ; [$411C:16668]
	CP $29 ; [41-"D"]
Lb40FD:
	JR Z, Lb411C ; [$411C:16668]
	CP $39 ; [57-"T"]
	JR Z, Lb411C ; [$411C:16668]
	CP $23 ; [35-"7"]
	JR Z, Lb411C ; [$411C:16668]
	CP $2B ; [43-"F"]
	JR Z, Lb411C ; [$411C:16668]
	CP $E1 ; [225]
	JR Z, Lb411C ; [$411C:16668]
	CP $E3 ; [227]
	JR Z, Lb411C ; [$411C:16668]
	CP $E5 ; [229]
	JR Z, Lb411C ; [$411C:16668]
	CP $F9 ; [249]
	JP NZ, Lb41DE ; [16862]
Lb411C:
	JP Lb41CB ; [16843]
Lb411F:
	CP $ED ; [237]
	JR Z, Lb412B ; [$412B:16683]
	CP $CB ; [203]
	JP Z, Lb41DE ; [16862]
	JP Lb414A ; [16714]
Lb412B:
	INC HL 
	DEC BC 
	LD A,(HL) 
	CP $4B ; [75]
	JR Z, Lb4147 ; [$4147:16711]
	CP $5B ; [91]
	JR Z, Lb4147 ; [$4147:16711]
	CP $7B ; [123]
	JR Z, Lb4147 ; [$4147:16711]
	CP $43 ; [67]
	JR Z, Lb4147 ; [$4147:16711]
	CP $53 ; [83]
	JR Z, Lb4147 ; [$4147:16711]
	CP $73 ; [115]
	JP NZ, Lb41CB ; [16843]
Lb4147:
	JP Lb41F2 ; [16882]
Lb414A:
	CP $3F ; [63-"Z"]
	JP C, Lb4157 ; [16727]
	CP $C1 ; [193]
	JP NC, Lb4157 ; [16727]
	JP Lb41CB ; [16843]
Lb4157:
	CP $00 ; [0]
	JR Z, Lb416F ; [$416F:16751]
	CP $02 ; [2]
	JR Z, Lb416F ; [$416F:16751]
	CP $12 ; [18-">"]
	JR Z, Lb416F ; [$416F:16751]
	CP $08 ; [8]
	JR Z, Lb416F ; [$416F:16751]
	CP $0A ; [10]
	JR Z, Lb416F ; [$416F:16751]
	CP $1A ; [26-","]
	JR NZ, Lb4172 ; [$4172:16754]
Lb416F:
	JP Lb41CB ; [16843]
Lb4172:
	AND $0F 
	CP $02 ; [2]
	JP Z, Lb41F2 ; [16882]
	CP $0A ; [10]
	JP Z, Lb41F2 ; [16882]
	CP $06 ; [6]
	JP Z, Lb41DE ; [16862]
	CP $0E ; [14-":"]
	JP Z, Lb41DE ; [16862]
	LD A,(HL) 
	CP $3F ; [63-"Z"]
	JP NC, Lb419F ; [16799]
	AND $0F 
	CP $00 ; [0]
	JP Z, Lb41DE ; [16862]
	CP $01 ; [1]
	JP Z, Lb422C ; [16940]
	CP $08 ; [8]
	JP Z, Lb41DE ; [16862]
Lb419F:
	LD A,(HL) 
	CP $C3 ; [195]
	JP Z, Lb41F2 ; [16882]
	CP $D3 ; [211]
	JP Z, Lb41DE ; [16862]
	CP $DB ; [219]
	JP Z, Lb41DE ; [16862]
	CP $BF ; [191]
	JP NC, Lb41B7 ; [16823]
	JP Lb41CB ; [16843]
Lb41B7:
	AND $0F 
	CP $04 ; [4]
	JR Z, Lb41C8 ; [$41C8:16840]
	CP $0C ; [12-"£"]
	DEC H 
	RLCA 
	CP $0D ; [13-"$"]
	JR Z, Lb41C8 ; [$41C8:16840]
	JP Lb41CB ; [16843]
Lb41C8:
	JP Lb41F2 ; [16882]
Lb41CB:
	INC HL 
	PUSH HL 
	PUSH BC 
	POP HL 
	LD BC,$0001 
	XOR A 
	SBC HL,BC 
	PUSH HL 
	POP BC 
	POP HL 
	JP NC, Lb40CD ; [16589]
	JP Lb4240 ; [16960]
Lb41DE:
	INC HL 
	INC HL 
	PUSH HL 
	PUSH BC 
	POP HL 
	LD BC,$0002 
	XOR A 
	SBC HL,BC 
	PUSH HL 
	POP BC 
	POP HL 
	JP P, Lb40CD ; [16589]
	JP Lb4240 ; [16960]
Lb41F2:
	INC HL 
	PUSH HL 
	LD E,(HL) 
	INC HL 
	LD D,(HL) 
	LD HL,(RAM_PRBUFF03) ; GET PRBUFF
	XOR A 
	SBC HL,DE 
	JP NC,$4317 ; [17175]
	LD HL,(RAM_PRBUFF07) ; GET PRBUFF
	XOR A 
	SBC HL,DE 
	JP C, Lb4217 ; [16919]
	EX DE,HL 
	LD E,L 
	LD E,E 
	INC A 
	LD B,B 
	ADD HL,DE 
	.db $ED,$E1  ; DATAS

	LD (HL),E 
	INC HL 
	LD (HL),D 
	INC HL 
	INC E 
	INC BC 
Lb4217:
	POP HL 
	INC HL 
	INC HL 
	PUSH HL 
	PUSH BC 
	POP HL 
	LD BC,$0003 
	XOR A 
	SBC HL,BC 
	PUSH HL 
	POP BC 
	POP HL 
	JP NC, Lb40FD ; [16637]
	JP Lb4240 ; [16960]
Lb422C:
	INC HL 
	INC HL 
	INC HL 
	INC E 
	JP (HL) 
	LD HL,($801E) 
	INC HL 
	LD (RAM_CH_ADD),HL ; SET CH-ADD
	LD A,(HL) 
	CALL DEC_TO_FP ; []*BIOS ROM*
	CALL FIND_INT ; [FIND-INT]
	RET ; ==========================

Lb4240:
	POP HL 
	POP HL 
	POP HL 
	RET ; ==========================

Lb4244: ; <16964>
	DEC DE 
	DEC DE 
	DEC DE 
.end

Code: Select all

#RELOCATOR,START ADDR:16514 LENGTH:452 11 MAY 85

1 REM [HEX:\
ED,4B,3F,40,C5,ED,4B,41,\
40,C5,ED,4B,45,40,C5,2A,\
3F,40,09,2B,22,43,40,3A,\
3E,40,D1,E1,C1,C5,E5,D5,\
AF,ED,42,22,3C,40,CA,40,\
42,C1,D1,E1,E5,D5,C5,D2,\
B8,40,ED,B0,18,08,09,2B,\
EB,09,2B,EB,ED,B8,3A,3E,\
40,FE,28,C2,40,42,C1,E1,\
E5,C5,0B,7E,FE,DD,CA,D7,\
40,FE,FD,20,48,23,0B,7E,\
FE,CB,CA,2C,42,FE,21,CA,\
2C,42,FE,22,CA,F2,41,FE,\
2A,CA,F2,41,FE,36,CA,2C,\
42,FE,09,28,25,FE,19,28,\
21,FE,29,28,1D,FE,39,28,\
19,FE,23,28,15,FE,2B,28,\
11,FE,E1,28,0D,FE,E3,28,\
09,FE,E5,28,05,FE,F9,C2,\
DE,41,C3,CB,41,FE,ED,28,\
08,FE,CB,CA,DE,41,C3,4A,\
41,23,0B,7E,FE,4B,28,15,\
FE,5B,28,11,FE,7B,28,0D,\
FE,43,28,09,FE,53,28,05,\
FE,73,C2,CB,41,C3,F2,41,\
FE,3F,DA,57,41,FE,C1,D2,\
57,41,C3,CB,41,FE,00,28,\
14,FE,02,28,10,FE,12,28,\
0C,FE,08,28,08,FE,0A,28,\
04,FE,1A,20,03,C3,CB,41,\
E6,0F,FE,02,CA,F2,41,FE,\
0A,CA,F2,41,FE,06,CA,DE,\
41,FE,0E,CA,DE,41,7E,FE,\
3F,D2,9F,41,E6,0F,FE,00,\
CA,DE,41,FE,01,CA,2C,42,\
FE,08,CA,DE,41,7E,FE,C3,\
CA,F2,41,FE,D3,CA,DE,41,\
FE,DB,CA,DE,41,FE,BF,D2,\
B7,41,C3,CB,41,E6,0F,FE,\
04,28,0B,FE,0C,25,07,FE,\
0D,28,03,C3,CB,41,C3,F2,\
41,23,E5,C5,E1,01,01,00,\
AF,ED,42,E5,C1,E1,D2,CD,\
40,C3,40,42,23,23,E5,C5,\
E1,01,02,00,AF,ED,42,E5,\
C1,E1,F2,CD,40,C3,40,42,\
23,E5,5E,23,56,2A,3F,40,\
AF,ED,52,D2,17,43,2A,43,\
40,AF,ED,52,DA,17,42,EB,\
5D,5B,3C,40,19,ED,E1,73,\
23,72,23,1C,03,E1,23,23,\
E5,C5,E1,01,03,00,AF,ED,\
42,E5,C1,E1,D2,FD,40,C3,\
40,42,23,23,23,1C,E9,2A,\
1E,80,23,22,16,40,7E,CD,\
D9,14,CD,A7,0E,C9,E1,E1,\
E1,C9,1B,1B,1B ]


9190 REM ---------------------
9191 REM RELOCATOR INTERFACE 
9192 REM EXAMPLE (RELOCATES RELOCATOR ITSELF)
9193 REM START ADDR: 16514
9194 REM DEST ADDR: 28000
9195 REM BLOCK LENGTH: 452
9196 REM TYPE: CODE
9197 REM RELOCATOR ENTRY: 16514
9199 REM ---------------------
9200 POKE 16448,INT(16514/256)
9210 POKE 16447,16514-256*INT(16514/256)
9220 POKE 16450,INT(28000/256) 
9230 POKE 16449,28000-256*INT (28000/256)
9240 POKE 16454,INT(452/256)
9250 POKE 16453,452-256*INT(452/256) 
9255 POKE 16446,40
9260 RAND USR 16514 
9270 PAUSE 100 
RELOCATOR.P
(1.93 KiB) Downloaded 124 times
Xavier ...on the Facebook groupe : "Zx81 France"(fr)
David G
Posts: 449
Joined: Thu Jul 17, 2014 7:58 am
Location: 48 North

Re: Relocatable Machine Code

Post by David G »

hmmm... the two bytes you have marked as "DATAS" appear to be in the regular code sequence. They make up an undocumented Z80 NOP opcode. I tried replacing with two regular NOP, but still get the 4/9260 error code
User avatar
XavSnap
Posts: 2072
Joined: Sat May 10, 2008 4:23 pm
Location: 'Zx81 France' Fb group.
Contact:

Re: Relocatable Machine Code

Post by XavSnap »

:shock:

It's not a legal opcode...

My disassembler does it itself!
It's cool.
Xavier ...on the Facebook groupe : "Zx81 France"(fr)
User avatar
1024MAK
Posts: 5341
Joined: Mon Sep 26, 2011 10:56 am
Location: Looking forward to summer in Somerset, UK...

Re: Relocatable Machine Code

Post by 1024MAK »

David G wrote: Fri Jul 29, 2022 2:13 am The more I think about this, the better it seems. Having a relocating Loader is more scalable, as each machine code program wouldn't need to be changed. Create a robust Loader and it works all programs
Rather than scanning code to try to find op codes that use absolute addresses, instead, for new programs, you have a table as part of the program. This table has details of all absolute addresses used. Then the loader can use this table to update each absolute address.

Mark
ZX81 Variations
ZX81 Chip Pin-outs
ZX81 Video Transistor Amp

:!: Standby alert :!:
There are four lights!
Step up to red alert. Sir, are you absolutely sure? It does mean changing the bulb :!:
Autumn is here. Bye bye summer 2024...
Post Reply