RDROYA01@ULKYVX.BITNET (Robert Royar) (05/22/86)
I have been able to work out most of the problems I have had with the CCP's
loading programs from within another program in protected memory. I can
now load, execute and return from any program, without an error. That is,
to a point. There seems to be an upward limit to the number of programs or
command lines the captured ccp will run. I suspect that this is related to
the system stack. So, now I need to know how to set up a copy of the
system stack at program initialization, set the SSP to this. (That's easy;
simply set supervisor state, load an address into a7 and rte.) But what
isn't easy is figuring out how to copy the values on the system stack into
a protected area of my program's memory.
Currently I'm saving all the registers, the user stack pointer, and
protecting the program with settpa just before I exit to the CCP. I reset
trap #2 to branch to the code at _fix whenever a WARM START is requested,
otherwise a BDOS call is made. But the SSP points to the wrong stack area
after all the info has been loaded back into the registers because the
system does not "know" it has been captured and that its stack address may
have been changed. However, if I can copy the system stack itself, not just
the pointer, and thereby create a private stack for it to use within my
program, I should not run into problems with wild instructions (garbage)
being popped of the system stack. My question is how do I copy the system
stack once I know the value in the SSP? And should I attempt to keep up
with the stacks the system creates when it runs another program, or should I
just let it "think" everything is the same as it was before it ran the
program? Should I just set the SSP to the private stack when the program
initializes and let it keep up with everything itself from then on?
Here is the code for handling the exits and returns so far:
.globl _initv
_initv: move.w #$16,d0 *set up trap #1 from trap #2
move.w #33,d1
move.l $88,d2
move.l d2,_oldv
trap #3
move.l #hndlr,$88
rts
hndlr: movem.l d1-d7/a0-a6,regs1 * handles calls to reset
cmp.w #$0,d0
beq _fix * must have been from another program
trap #1
movem.l regs1,d1-d7/a0-a6
rte
* sets tpa limits using parameter passed in (sp) returns original high
* memory in d0.
.globl _settpa
_settpa:
movem.l d1-d7/a0-a6,regs2
move.w 4(sp),d0 * set param
move.l 6(sp),d1 * low tpa
move.l 10(sp),d2 * high tpa
move.w #$0,tpab * request current values
move.w d0,d3 * save set param
move.l d1,d4 * save low tpa value
move.w #$3f,d0
move.l #tpab,d1
trap #2
move.l high,d5 * save returned high value
move.w d3,tpab * set value for bdos passed from caller
move.l d4,low
move.l d2,high
move.w #$3f,d0
move.l #tpab,d1
trap #2
move.l d5,d0 * return old high TPA value
movem.l regs2,d1-d7/a0-a6
rts
.globl _ccp
.globl _fix
_ccp: movem.l d0-d7/a1-a7,regs3 * access to ccp through trap #4
move.l usp,a0 * save USP for later return
move.l a0,_usp
jsr $234a * address of _ccpmain on HSC board
_fix: movem.l regs3,d0-d7/a1-a7 * gets out of disasterous mistakes
move.l _usp,a0 * replace user stack pointer
move.l a0,usp
rte
.even
.data * TPA block for settpa
tpab: ds.w 1
low: ds.l 1
high: ds.l 1
.even
.bss
regs1: ds.l 14 * register storage for trap handler
regs2: ds.l 15 * register storage for settpa
regs3: ds.l 14 * register storage for _ccp and _fix
_oldv: ds.l 1 * value of original trap #2 vector
_usp: ds.l 1 * value of USP for _ccp and _fix
rdroya01@ulkyvx.bitnet