LoadSeg should load the file into memory and fix all the relocatable sections from the hunk data. The resulting seglist is a BCPL pointer, so to get to the start of the hunk code you need to multiply this address by 4, and the code starts at offset 4.
After this, for the purposes of your code, the OS likely isn't needed. However, it may be that the game file you've loaded needs certain OS functions. Though if it only uses ROM based libraries and no extra disk IO loading files for example, it should be OK.
Here is a standalone example which saves the passed CLI arguments, loads a file (gameexe) and calls it with the original passed CLI arguments. If you want to pass "blank" arguments, set d0 to 1 and point a0 to a string containing a CR and null terminator (dc.b 10,0)
This example assembles in Devpac, but should generally be compatible with other assemblers.
Code:
_LVOOpenLibrary equ -552
_LVOCloseLibrary equ -414
_LVOLoadSeg equ -150
_LVOUnLoadSeg equ -156
output loadsegexample
_Start:
move.l d0,_DOSArgLen ; Save DOS Cli arguments to pass to loaded file
move.l a0,_DOSArgs
movea.l 4.w,a6 ; ExecBase
moveq #0,d0
lea _DOSName,a1
jsr _LVOOpenLibrary(a6) ; Open dos.library
move.l d0,_DOSBase
beq.s .NoDOS
movea.l _DOSBase,a6 ; This is for clarity in case this code is elsewhere as I could just move.l d0,a6
move.l #_GameFilename,d1
jsr _LVOLoadSeg(a6) ; Load the game file
move.l d0,_GameSegList
beq.s .NotLoadedFile ; If things are zero, we didn't get a file loaded
lsl.l #2,d0 ; BPTR = address / 4, so multiply by 4
addq.l #4,d0
move.l d0,_GameFile ; Pointer to first segment code
; Call our trainer initialisation code
jsr _TrainerStart
; Call the loaded code
move.l _DOSArgLen,d0 ; Argument Length
movea.l _DOSArgs,a0 ; Arguments
movea.l _GameFile,a4
jsr (a4) ; Code starts at second long into seglist
; Call our trainer shutdown code
jsr _TrainerEnd
; Tidy up by unloading the file and closing the dos.library
movea.l _DOSBase,a6
move.l _GameSegList,d1
jsr _LVOUnLoadSeg(a6) ; Unload the game
.NotLoadedFile:
movea.l 4.w,a6 ; ExecBase
movea.l _DOSBase,a1
jsr _LVOCloseLibrary(a6) ; Close dos.library
.NoDOS:
moveq #0,d0
rts
; Our trainer...
_TrainerStart:
rts
_TrainerEnd:
rts
; Data
even
_GameSegList: dc.l 0 ; BCPL pointer to seglist
_GameFile: dc.l 0 ; Pointer to first segment data (the trainer probably needs this for patching?)
_DOSArgLen: dc.l 0
_DOSArgs: dc.l 0
_DOSBase: dc.l 0
_DOSName: dc.b 'dos.library',0
_GameFilename: dc.b 'gameexe',0