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