@@ -354,6 +354,7 @@ _: pop af
354354 cp a
355355 ret
356356
357+ .echo "lp: 0x{0:X4}" launchProgram
357358;; launchProgram [Threading]
358359;; Loads the specified file into memory as a program and starts a
359360;; new thread for it. The file must be a valid KEXC executable.
@@ -426,12 +427,18 @@ launchProgram:
426427.unknown_ver:
427428; no minimum version is specified by the executable
428429.no_minimum_ver:
430+ ; Check for a relocation table
431+ ld b , KEXC_RELOCATION_TABLE
432+ push ix \ call _getThreadHeader \ pop ix
433+ call z , .relocate
434+
429435 ; Grab header info
430436 ld b , KEXC_ENTRY_POINT
431437 push ix \ call _getThreadHeader \ pop ix
432438 jr nz , .no_entry_point
433439 push hl
434- ld b , KEXC_STACK_SIZE
440+ ; b still has KEXC_ENTRY_POINT, and KEXC_STACK_SIZE is 1 higher
441+ inc b
435442 push ix \ call _getThreadHeader \ pop ix
436443 ld c , l ; TODO: Error out if H is nonzero?
437444 jr z , _
@@ -459,14 +466,14 @@ _: ld a, b
459466 pop bc
460467 cp a
461468 ret
462- .kernel_too_low :
463- ld a , errKernelMismatch
469+ .magic_error :
470+ ld a , errNoMagic
464471 jr .error
465472.no_entry_point:
466473 ld a , errNoEntryPoint
467474 jr .error
468- .magic_error :
469- ld a , errNoMagic
475+ .kernel_too_low :
476+ ld a , errKernelMismatch
470477 jr .error
471478.error_pop2:
472479 inc sp \ inc sp
@@ -484,6 +491,42 @@ _: or 1
484491 ld a , b
485492 pop bc
486493 ret
494+ ; thrashes de, bc, and hl
495+ .relocate:
496+ ; ix = executable address
497+ ; hl = program-relative relocation table address
498+ push ix \ pop de
499+ add hl , de
500+ ; hl = absolute address of relocation table
501+ .relocation_loop:
502+ ld e , (hl)
503+ inc hl
504+ ld d , (hl)
505+ ; de = first entry in relocation table
506+ dec hl
507+ ; hl: preserved
508+ ld bc , 0
509+ call cpBCDE
510+ ret z
511+ ; de contains the program-relative address of a program-relative pointer to relocate
512+ ; need to execute, in effect, `add (ix + de), ix`
513+ push ix
514+ add ix , de
515+ push ix \ pop de
516+ pop ix
517+ ; de = absolute address of pointer to relocate
518+
519+ ; add (de), ix
520+ push ix \ pop bc
521+ ld a , (de)
522+ add a , c
523+ ld (de) , a
524+ inc de
525+ ld a , (de)
526+ add a , b
527+ ld (de) , a
528+ inc hl \ inc hl
529+ jr .relocation_loop
487530
488531;; exitThread [Threading]
489532;; Immediately terminates the running thread.
0 commit comments