page	, 132
	subttl	Copyright (c) 2020, the ACME Software Deli

; ============================================================================
;   This program is distributed in the hope that it will be useful, but
;   WITHOUT ANY WARRANTY; without even the implied warranty of
;   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE
;
;   Permission to use for any purpose, modify, copy, and make enhancements
;   and derivative works of the software is granted if attribution is given to
;   R.M. Gillmore, dba the ACME Software Deli, as the author
;
;   While the ACME Software Deli does not work for money, there is nonetheless a
;   a significant amount of work involved.  The ACME Software Deli maintains the
;   rights to all code written, though it may be used and distributed as long as
;   the following conditions are maintained.
;
;   1.  The copyright statement at the top of each code block is maintained in
;       your distribution.
;   2.  You do not identify yourself as the ACME Software Deli
;   3.  Any changes made to the software are sent to the ACME Software Deli
; ============================================================================
	page

	name	loadExecAsmModule
	.186

plmLibrary_Data	segment	public	'Data'
	; because DOS corrupts the stack variables, we will save them before we
	; execute the interrupt, then restore them when DOS returns to us

	stackPtr	dw	?
	stackSeg	dw	?
plmLibrary_Data	ends

plmLibrary_Code	segment	public	'Code'
ifndef SMALL
	db	'@(#)ldXcAsm.a86   $Author: rmgillmore $ $Date:: 2025-05-04 19:35:39#$:', 0
endif
	plmLibrary_CGroup	group	plmLibrary_Code
	plmLibrary_DGroup	group	plmLibrary_Data

	assume	cs:plmLibrary_CGroup, ds:plmLibrary_DGroup

	public	loadExecAsm

loadExecAsmFrame	struc
	LoadExec_OldFrame	Dw	?
	LoadExec_RtnAddr	Dw	?
	LoadExec_ProgramSpecPtr	Dd	?	; the program specification
	LoadExec_ParamBlockPtr	Dd	?	; the program parameter block
loadExecAsmFrame	ends

loadExecAsm	proc	near
	Push	Bp
	Mov	Bp, Sp
	Push	Ds			; DS must be preserved

	Mov	Ax, plmLibrary_DGroup
	Mov	Ds, Ax

	Mov	Ax, Ss			; save the stack registers
	Mov	stackSeg, Ax
	Mov	Ax, Sp
	Mov	stackPtr, Ax

	Lds	Dx, Ss:[Bp].LoadExec_ProgramSpecPtr
	Les	Bx, Ss:[Bp].LoadExec_ParamBlockPtr
	Mov	Ax, 4b00h		; We want to load and execute the specified app
	Int	21h			; using DOS to do it
	PushF				; save the flags (we only want carry, really)
	Pop	Bx
	Cli				; no interruptions restoring the stack

	; we need to preserve AX and BX (AX holds the DOS return code, BX holds the flags)

	Mov	Cx, plmLibrary_DGroup
	Mov	Ds, Cx

	Mov	Cx, stackSeg		; restore the stack registers
	Mov	Ss, Cx
	Mov	Cx, stackPtr
	Mov	Sp, Cx

	Sti				; allow interrupts again

	Push	Bx
	PopF

	Jc	loadExecAsm_End
	Xor	Ax, Ax			; no error, ensure AX is clear

loadExecAsm_End:
	Pop	Ds
	Pop	Bp
	Ret
loadExecAsm	endp

plmLibrary_Code	ends
	end