@@ -354,6 +354,7 @@ _: pop af
354
354
cp a
355
355
ret
356
356
357
+ .echo "lp: 0x{0:X4}" launchProgram
357
358
;; launchProgram [Threading]
358
359
;; Loads the specified file into memory as a program and starts a
359
360
;; new thread for it. The file must be a valid KEXC executable.
@@ -426,12 +427,18 @@ launchProgram:
426
427
.unknown_ver:
427
428
; no minimum version is specified by the executable
428
429
.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
+
429
435
; Grab header info
430
436
ld b , KEXC_ENTRY_POINT
431
437
push ix \ call _getThreadHeader \ pop ix
432
438
jr nz , .no_entry_point
433
439
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
435
442
push ix \ call _getThreadHeader \ pop ix
436
443
ld c , l ; TODO: Error out if H is nonzero?
437
444
jr z , _
@@ -459,14 +466,14 @@ _: ld a, b
459
466
pop bc
460
467
cp a
461
468
ret
462
- .kernel_too_low :
463
- ld a , errKernelMismatch
469
+ .magic_error :
470
+ ld a , errNoMagic
464
471
jr .error
465
472
.no_entry_point:
466
473
ld a , errNoEntryPoint
467
474
jr .error
468
- .magic_error :
469
- ld a , errNoMagic
475
+ .kernel_too_low :
476
+ ld a , errKernelMismatch
470
477
jr .error
471
478
.error_pop2:
472
479
inc sp \ inc sp
@@ -484,6 +491,42 @@ _: or 1
484
491
ld a , b
485
492
pop bc
486
493
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
487
530
488
531
;; exitThread [Threading]
489
532
;; Immediately terminates the running thread.
0 commit comments