Welcome, Guest. Please login or register.


Author Topic: Easy relocatable code in basic (Read 22109 times)

Offline gflorez

  • EP addict
  • *
  • Posts: 3614
  • Country: es
    • Támogató Támogató
Easy relocatable code in basic
« on: 2014.August.14. 01:06:14 »
I'm interested in relocatable code, programs that can work independently of the configuration of the EP.

The problem is when you want to make it easily in Basic. RESTORE or ALLOCATE can give you spare memory for your code, but the direction can be different if you have been running another program before or have made immediately a reset.

But if you want the code to work on every EP you must think about relocatable modules.

No, I talk about tiny code with some jumps or calls inside. The Z80 wasn't engineered with relocatable code in mind( except the useful JP(HL) widely used in the EXOS, or the relative jumps, too shorts to be useful).

Then I've though about an easy way to do the trick:

  100 ALLOCATE 20
  110 CODE ORIGEN=HEX$("00,00,00,01,00,02,00,03,00,04,00,05,00,06,00,07,00,08,00,09")
  120 LET CODH=INT(ORIGEN/255)
  130 LET CODL=REM(ORIGEN,255)
  140 FOR A=0 TO 9
  150   READ B,C
  160   LET DIREC=(B*255)+C+ORIGEN
  170   LET H=PEEK(DIREC)
  180   LET L=PEEK(DIREC+1)
  190   LET L=L+CODL
  200   LET H=H+CODH+INT(L/255)
  210   LET L=REM(L,255)
  215   PRINT DIREC,PEEK(DIREC),PEEK(DIREC+1)
  220   POKE DIREC,H
  230   POKE (DIREC+1),L
  240 NEXT A
  250 DATA 0,0,0,2,0,4,0,6,0,8,0,10,0,12,0,14,0,16,0,18
  255 PRINT
  260 FOR A=0 TO 9
  270   PRINT ORIGEN+(A*2),PEEK(ORIGEN+(A*2)),PEEK(ORIGEN+(A*2)+1)
  280 NEXT A

In lines 100-110 we put a test code in the Basic variable memory as usual.
In 120-130 we extract the H and L bytes of the new ORG direction.

Then, in the 140-240 loop we read from DATA in line 250 the absolute directions(ORG=0) we need to relocate .

Then the  content of the memory is compared before and after.

Offline Zozosoft

  • Global Moderator
  • EP addict
  • *
  • Posts: 14775
  • Country: hu
    • http://enterprise.iko.hu/
Re: Easy relocatable code in basic
« Reply #1 on: 2014.August.14. 14:45:37 »
The 255 values are wrong, use 256!

Offline gflorez

  • EP addict
  • *
  • Posts: 3614
  • Country: es
    • Támogató Támogató
Re: Easy relocatable code in basic
« Reply #2 on: 2014.August.14. 16:18:33 »
Oh sorry. I'm on holidays without the real thing... no excuses.....Error is my second name....
 
The program fixed:

  100 ALLOCATE 20
  110 CODE ORIGEN=HEX$("00,00,00,01,00,02,00,03,00,04,00,05,00,06,00,07,00,08,00,09")
  120 LET CODH=INT(ORIGEN/256)
  130 LET CODL=REM(ORIGEN,256)
  140 FOR A=0 TO 9
  150   READ B,C
  160   LET DIREC=(B*256)+C+ORIGEN
  170   LET H=PEEK(DIREC)
  180   LET L=PEEK(DIREC+1)
  190   LET L=L+CODL
  200   LET H=H+CODH+INT(L/256)
  210   LET L=REM(L,256)
  215   PRINT DIREC,PEEK(DIREC),PEEK(DIREC+1)
  220   POKE DIREC,H
  230   POKE (DIREC+1),L
  240 NEXT A
  250 DATA 0,0,0,2,0,4,0,6,0,8,0,10,0,12,0,14,0,16,0,18
  255 PRINT
  260 FOR A=0 TO 9
  270   PRINT ORIGEN+(A*2),PEEK(ORIGEN+(A*2)),PEEK(ORIGEN+(A*2)+1)
  280 NEXT A

Offline Zozosoft

  • Global Moderator
  • EP addict
  • *
  • Posts: 14775
  • Country: hu
    • http://enterprise.iko.hu/
Re: Easy relocatable code in basic
« Reply #3 on: 2014.August.14. 16:28:20 »
Alternate idea: do the realocation in machine code.
Write the routine in Turbo Asmon, it is can compile to BASIC program (With Allocate and CODE strings).
  ORG 0
  JR MAIN
  PUSH HL
  POP BC
  LD HL,(CALL1+1)
  ADD HL,BC
  LD (CALL1+1),HL
  LD HL,(CALL2+1)
  ADD HL,BC
  LD (CALL2+1),HL
  ...
  RET

MAIN
  ...
CALL1 CALL SUB1
  ...
CALL2 CALL SUB2
 ...

In the BASIC add a variable for the start for example MCODE
Befor it is used CALL USR(MCODE+2,MCODE) which are do the relocation.

Offline gflorez

  • EP addict
  • *
  • Posts: 3614
  • Country: es
    • Támogató Támogató
Re: Easy relocatable code in basic
« Reply #4 on: 2014.August.14. 17:01:42 »
Thanks Zozo, really your nethod is easy to implement. Only remember, I usually code by hand.....but can do bigger and better things if I begin using an assembler....

Is Turbo Asmon the best?

Offline Zozosoft

  • Global Moderator
  • EP addict
  • *
  • Posts: 14775
  • Country: hu
    • http://enterprise.iko.hu/
Re: Easy relocatable code in basic
« Reply #5 on: 2014.August.14. 17:07:42 »
Quote from: gflorez
Is Turbo Asmon the best?
Yes, for compile code to BASIC.
For native machine code programs the HEASS are the best, it is can use all memory then you can handle very large sources (with memory expansion). And it is very fast, for example EXDOS 1.3 compile only 43 seconds on 4MHz machine! It is about 300k source in plain text format.

Offline gflorez

  • EP addict
  • *
  • Posts: 3614
  • Country: es
    • Támogató Támogató
Re: Easy relocatable code in basic
« Reply #6 on: 2014.August.14. 17:22:12 »
Ok. And, about the English manual, is it important?

Offline Zozosoft

  • Global Moderator
  • EP addict
  • *
  • Posts: 14775
  • Country: hu
    • http://enterprise.iko.hu/
Re: Easy relocatable code in basic
« Reply #7 on: 2014.August.14. 20:23:57 »
Quote from: gflorez
Ok. And, about the English manual, is it important?
English manual for which program? :oops:

Offline gflorez

  • EP addict
  • *
  • Posts: 3614
  • Country: es
    • Támogató Támogató
Re: Easy relocatable code in basic
« Reply #8 on: 2014.August.15. 14:44:14 »
The two if  possible...HEASS and T-ASMON.... Or, can I begin without manuals?

Offline endi

  • EP addict
  • *
  • Posts: 7298
  • Country: hu
  • grafikus, játékfejlesztõ, programozás, scifi, tudományok, vallás
    • Honlapom
Re: Easy relocatable code in basic
« Reply #9 on: 2014.August.15. 17:05:34 »
try EP Plus. you can write asm into basic lines!
http://ep128.hu/Ep_Konyv/Ep_Plus.htm
Vigyázat! Szektás vagyok! :)

Offline BruceTanner

  • EP lover
  • *
  • Posts: 609
  • Country: gb
Re: Easy relocatable code in basic
« Reply #10 on: 2014.August.15. 17:07:33 »
For more serious amounts of machine code, EXOS supports a relocatable file format, so you can do an EXOS call to load a relocatable user program or device driver into an arbitrary block of memory.

zozo: do you know if anyone actually ever used this in practice? It would mean they would have to have a way of producing the bit stream file format. I remember at IS we used to assemble relocatable modules twice, each time with a different ORG (probably 0 and 100h but I can't actually remember) and then we wrote a little utility program that would compare the two files and thus know which bits need to be relocatable, and output the appropriate bit stream file format.

Offline Zozosoft

  • Global Moderator
  • EP addict
  • *
  • Posts: 14775
  • Country: hu
    • http://enterprise.iko.hu/
Re: Easy relocatable code in basic
« Reply #11 on: 2014.August.17. 11:00:45 »
Quote from: BruceTanner
zozo: do you know if anyone actually ever used this in practice?
Yes, BASIC command set expansions are use this format, and some EXOS system extensions are also.
But no too popular used because lack of support in assemblers. Not documented but I found the way in Asmon how possible creat relocatable code. Not too comfortable, but working :-)
At all 16 bit expressions need to set it is relocatable code or absolut value. For example:
Code: ZiLOG Z80 Assembler
  1.                 PUSH DE
  2.                 POP IY
  3.                 .CSEG
  4.                 CALL CSATSZAM
  5.                 .ASEG
  6.                 LD (7FFBH),A
  7.                 INC DE
  8.                 DEC B
  9.                 .CSEG
  10.                 JP M,ALAPOTCSINAL



Quote
It would mean they would have to have a way of producing the bit stream file format. I remember at IS we used to assemble relocatable modules twice, each time with a different ORG (probably 0 and 100h but I can't actually remember) and then we wrote a little utility program that would compare the two files and thus know which bits need to be relocatable, and output the appropriate bit stream file format.
Very interesting idea! Unfortunatelly this utility not published :-(
Now I thinking write similar one :-)

Offline lgb

  • EP addict
  • *
  • Posts: 3563
  • Country: hu
  • æðsta yfirmaður
    • http://lgb.hu/
Re: Easy relocatable code in basic
« Reply #12 on: 2014.August.17. 13:39:23 »
Quote
Very interesting idea! Unfortunatelly this utility not published :-(
Now I thinking write similar one :-)

I used the same trick with my very elementary "original" CP/M to EP128 porting: I had the disassembled CP/M BDOS from the Net, I assembled it with ORG 0 and ORG 100h. I wrote a simple python script (running on PC): where the byte values were different I stored the positions inside a table and I used ORG 0 version, so I simply had to add the offset. Since I was about relocating to positions on 256 byte boundaries, I only needed to deal with the high bytes (of course the theory works with even byte granulities, but it needs two tables, as some ops may use only low an and high bytes, and such).

Offline gflorez

  • EP addict
  • *
  • Posts: 3614
  • Country: es
    • Támogató Támogató
Re: Easy relocatable code in basic
« Reply #13 on: 2014.August.18. 01:06:44 »
Its amazing, I`m not the only one thinking about these "odd" things!

I remember that the Interlace mode program is in fact another relocatable module. Loading not needing  permisions, implantig their code in System  like real virus do....

Offline gflorez

  • EP addict
  • *
  • Posts: 3614
  • Country: es
    • Támogató Támogató
Re: Easy relocatable code in basic
« Reply #14 on: 2018.April.25. 17:36:39 »
I want to convert a MSX machine code application to Enterprise, it is SETalk, the voice synth.

On MSX it is loaded by a Basic program at a fixed address, but now I want it to work on every Enterprise.

I have been thinking about real relocatable code, not relocatable conversion like it is explained at the beginning on this thread.

---

The real problem I found about doing relocatable code with the Z80 is the impossibility to read the PC register to know the address of the instruction the processor is actually executing.

CALL and JP are the worst instructions to convert to relocatable, but we at least have JP (HL), that eases a lot the conversion.

Also, IS-Basic lets to pass a 16 bit number to the HL register pair on a machine code program created with the command CODE ROUTINE=HEX$("XX","XX", etc), and then the routine called with CALL USR(ROUTINE,ROUTINE)(Thanks Zozo for the tip).

Now we have the start address passed to HL. The routine has been assembled with a ORG 0000h.

Code: [Select]
SETALK:         PUSH    AF
                PUSH    BC
                PUSH    DE
                PUSH    HL


                CALL    PROG

                POP     HL
                POP     DE
                POP     BC
                POP     AF
                               

I have though that something like this will serve me to do a call:

Code: [Select]
SETALK:         PUSH    AF
                PUSH    BC
                PUSH    DE
                PUSH    HL          ; is good to store another copy of the start address just in case

                LD      DE, RET1 ; we need the relative address of the return
                PUSH    HL
                ADD      HL, DE
                EXX      DE, HL
                POP      HL
                PUSH    DE          ; Now we have the absolute return address on the stack
                PUSH    HL
                LD      DE,PROG
                ADD      HL,DE
                POP      DE         
                JP      (HL)        ; We still have the start address on DE, but we can
                                    ; pass more data by the stack if we remember to POP it
                                    ; inside the simulated call
                ;CALL    PROG

ret1:           POP     HL
                POP     DE
                POP     BC
                POP     AF
                               


But surely you know an easier way....