PR#3
PREFIX /A2OSX.SRC
NEW
INC 1
AUTO 6
				.LIST OFF
*--------------------------------------
* BIN.LoadExeYA
*  in :
*   A = hMem of FilePath (PSTRING)
* out :
*   Y,A = MEMPTR	
*   X = hMem of Code Segment
*--------------------------------------
K.LoadEXEYA		>STYA K.LoadEXEYA.Filename
				>SYSCALL SYS.PStrUprYA			Y,A unmodified
				jsr K.GetMemByNameYA
				bcs K.LoadEXEYA.1		not already loaded

				>STYA ZPQuickPtr1		Save base address
				ldy #S.MEM.REFCNT
				lda (ZPQuickPtr1),y
				inc
				sta (ZPQuickPtr1),y
				
				txa
				jmp K.GetMemPtrA		X=hMem from K.GetMemByNameA
*--------------------------------------				
K.LoadEXEYA.1	>PUSHWI KrnBuf256
				>PUSHW K.LoadEXEYA.Filename
				jsr K.STAT				Look for AUXTYPE
				bcs .9
				
				>LDYA KrnBuf256+S.STAT.PRODOS.AUXTYPE
				>STYA BIN.Relocate.Start

				>PUSHYA					Push AUXTYPE
				>PUSHBI 6				S.FILEINFO.TYPE.BIN
				>PUSHBI	SYS.FOPEN.R
				>PUSHW K.LoadEXEYA.Filename

				jsr K.LoadFile
.9				bcs .99					Error Loading file

				stx K.LoadEXEYA.hMem		save hMem
				
				pha							YA=CODE+DATA size
				tya
*				clc						CC from bcs .99				

				adc BIN.Relocate.Start			Get AUXTYPE for actual Base Address
				sta BIN.Relocate.End			compute Range End=AUXTYPE+FILELEN
				pla
				adc BIN.Relocate.Start+1
				sta BIN.Relocate.End+1

				txa
				jsr K.GetMemPtrA
				>STYA ZPQuickPtr1				set ZPQuickPtr1 -> Code start

				pha								YA = actual load address
				tya
				sec
				sbc BIN.Relocate.Start
				sta BIN.Relocate.Offset			Offset=ZPQuickPtr1-AUXTYPE
				pla
				sbc BIN.Relocate.Start+1
				sta BIN.Relocate.Offset+1
				
				ldy #H.BIN.CODE.LEN				get Code Len
				lda (ZPQuickPtr1),y
				clc
				adc ZPQuickPtr1
				sta ZPQuickPtr2					Make ZPQuickPtr2 = ZPQuickPtr1 + CodeLen
				iny
				lda (ZPQuickPtr1),y
				adc ZPQuickPtr1+1
				sta ZPQuickPtr2+1
				
				jsr BIN.RelocateEXE
				
				>LDYA K.LoadEXEYA.Filename	get back bin path
				>SYSCALL SYS.NewPStrYA			make a copy of this string
				bcs .98
				
				lda K.LoadEXEYA.hMem		Keep X=hMem		
				jsr K.GetMemByIDA			X unmodified
				>STYA ZPQuickPtr1
				
				lda (ZPQuickPtr1) 
				ora #S.MEM.F.CODE		This is a code segment
				sta (ZPQuickPtr1)

				txa						Get Back hMem
				ldy #S.MEM.BIN
				sta (ZPQuickPtr1),y
							
				lda K.LoadEXEYA.hMem		
				tax						return hMEM to Caller...
				jsr K.GetMemPtrA
				clc						...and Y,A=PTR to CS
				rts
				
.98				pha
				lda K.LoadEXEYA.hMem	
				jsr K.FreeMemA			Discard Loaded Code
				pla
				
				sec
.99				rts
*--------------------------------------
K.LoadEXEYA.Filename	.BS 2
K.LoadEXEYA.hMem		.BS 1
*--------------------------------------
* BIN.InstallDRV
*  In:
*   pDrv = .DRV File Loaded Address
* Note:
*  K.LoadEXEYA called from K.LoadDrvYA
*  Already setup correctly pDrv,
*  BIN.Relocate.Start,End
*--------------------------------------
BIN.InstallDRV	ldy #H.BIN.DRV.CODE.O
				lda (pDrv),y
				clc
				adc BIN.Relocate.Start		Advance start From AUXTYPE to AUXTYPE+DRV code offset
				sta BIN.Relocate.Start
				
				iny
				lda (pDrv),y
				adc BIN.Relocate.Start+1
				sta BIN.Relocate.Start+1
				
				lda DevMgr.Free				Offset = Target DRV address-(AUXTYPE+DRV OFFSET)
				sec
				sbc BIN.Relocate.Start
				sta BIN.Relocate.Offset
				
				lda DevMgr.Free+1
				sbc BIN.Relocate.Start+1
				sta BIN.Relocate.Offset+1
				
				lda	BIN.Relocate.End			Compute DRVLen=End-start
				sec
				sbc BIN.Relocate.Start
				sta BIN.InstallDRV.DRVLen
				
				lda BIN.Relocate.End+1
				sbc BIN.Relocate.Start+1
				sta BIN.InstallDRV.DRVLen+1
				
				lda DevMgr.Free
				clc
				adc BIN.InstallDRV.DRVLen
				sta BIN.InstallDRV.DRVEnd
				tay								Save DRVEnd LO
				lda DevMgr.Free+1
				adc BIN.InstallDRV.DRVLen+1		A = DRVEnd HI
				sta BIN.InstallDRV.DRVEnd+1
				
				bcs .9					we crossed $FFFF, out of mem
				
				cpy #DevMgr.HiMem
				sbc /DevMgr.HiMem
				bcs .9					No More Room to load Driver....

				lda DevMgr.LastDevID
				inc
				cmp #K.DEV.MAX
				bne .10					No Device Handle Left
				
				lda #DEVMGR.ERROOH
				sec
				rts				
								
.9				lda #DEVMGR.ERROOM
				sec
				rts
				
.10				sta DevMgr.LastDevID
				
				>SYSCALL SYS.GetDevByIDA
				>STYA ZPQuickPtr2		setup Ptr2 to dest HEADER
				
				ldy	#H.BIN.DRV.HEADER.O
				lda (pDrv),y
				clc
				adc pDrv
				sta ZPQuickPtr1
				iny
				lda (pDrv),y
				adc pDrv+1
				sta ZPQuickPtr1+1		set Ptr1 to Src HEADER

				ldy #S.DEV-1
				
.1				lda (ZPQuickPtr1),y		copy header to DevMgr.Table
				sta (ZPQuickPtr2),y
				dey
				bpl .1
			
				ldy	#S.DEV.ID
				lda DevMgr.LastDevID
				sta (ZPQuickPtr2),y
				
				dey						#S.DEV.JMP+1	Setup Main JMP
				lda DevMgr.Free+1
				sta (ZPQuickPtr2),y
				tax
				
				dey						#S.DEV.JMP
				lda DevMgr.Free
				sta (ZPQuickPtr2),y
				
				sta ZPQuickPtr2			set Ptr2 to Dest CODE
				stx ZPQuickPtr2+1
				
				ldy	#H.BIN.DRV.CODE.O
				lda (pDrv),y
				clc
				adc pDrv
				sta ZPQuickPtr1
				iny
				lda (pDrv),y
				adc pDrv+1
				sta ZPQuickPtr1+1		set Ptr1 to Src CODE

				lda BIN.InstallDRV.DrvLen+1
				eor #$ff
				pha
				lda BIN.InstallDRV.DrvLen
				eor #$ff
				tax
				
				ldy #0
				
.2				inx						Move CODE in LC
				bne .3
				pla
				inc
				beq .4
				pha
				
.3				lda (ZPQuickPtr1),y
				sta (ZPQuickPtr2),y
				iny
				bne .2
				inc ZPQuickPtr1+1
				inc ZPQuickPtr2+1
				bra .2				
							
.4				ldy #H.BIN.DRV.CODE.LEN
				lda DevMgr.Free					Make Ptr1 = code start
				sta ZPQuickPtr1
				clc
				adc (pDrv),y
				sta ZPQuickPtr2
				
				iny
				lda DevMgr.Free+1
				sta ZPQuickPtr1+1
				adc (pDrv),y
				sta ZPQuickPtr2+1				Make ZPQuickPtr2 = ZPQuickPtr1 + CodeLen
				
				jsr BIN.RelocateDRV
				
				>LDYA BIN.InstallDRV.DrvEnd
				>STYA DevMgr.Free
				clc
				rts
*--------------------------------------
BIN.InstallDRV.DrvLen	.BS 2
BIN.InstallDRV.DrvEnd	.BS 2
*--------------------------------------
* BIN.Relocate___ :
*  In :
*  ZPQuickPtr1 = Ptr to Code
*  ZPQuickPtr2 = End Of Code
*--------------------------------------
BIN.Relocate.Start		.BS 2
BIN.Relocate.End		.BS 2
BIN.Relocate.Offset		.BS 2
*--------------------------------------
BIN.RelocateEXE	ldy #H.BIN.HEADER+1
				lda (ZPQuickPtr1),y
				cmp /H.BIN.HEADER.BIN65
				beq .1
				cmp /H.BIN.HEADER.DRV65
				beq .1
				
				lda #SYSMGR.ERRIBIN
				sec
				rts
				
.1				ldy #H.BIN.JMP			relocate Main JMP
				lda (ZPQuickPtr1),y
				clc
				adc BIN.Relocate.Offset
				sta (ZPQuickPtr1),y

				iny
				lda (ZPQuickPtr1),y
				adc BIN.Relocate.Offset+1
				sta (ZPQuickPtr1),y

				ldy #H.BIN.EXE.REL.TABLE	skip Header, CS.SIZE & DS.SIZE... (16 bytes)
		
				.HS 2C					bit abs
*--------------------------------------					
BIN.RelocateDRV	ldy #H.BIN.DRV.REL.TABLE
				
.1				lda (ZPQuickPtr1),y		Start Relocate JMP table
				tax						LO in X
				iny
				ora (ZPQuickPtr1),y		ORA with HI
				beq .2					$0000 = end of table
				
				dey
				txa						get back LO
				clc
				adc BIN.Relocate.Offset
				sta (ZPQuickPtr1),y

				iny
				lda (ZPQuickPtr1),y
				adc BIN.Relocate.Offset+1
				sta (ZPQuickPtr1),y

				iny

				bra .1
*--------------------------------------				
.2				tya						add current offset in Y to Ptr
				
				sec						+ 1 to skip last 00 from beq .2
				
				adc ZPQuickPtr1
				sta ZPQuickPtr1
				bcc .3	
				inc ZPQuickPtr1+1		ZPQuickPtr1=Current Code PTR
				
.3				lda (ZPQuickPtr1)		get OPCODE
				lsr						/2
				tax
				lda BIN.OPCODES,x		get OPCODE definition
				bcs .4					go get LO nibble
				lsr
				lsr						move HI -> LO
				lsr
				lsr
.4				and #$0f				
				
				bit #$8					abs addressing? 
				beq .6					no....
				
				and #7					save Opcode length...
				pha
				
				ldy #1
				lda (ZPQuickPtr1),y		Get LO
				tax						save LO in X
				
				iny						make Y point to HI

				cpx BIN.Relocate.Start
				lda (ZPQuickPtr1),y		Get HI
				sbc BIN.Relocate.Start+1
				bcc .5					addr < BIN.Relocate.Start, out of range
				
				txa						Get back LO
				cpx BIN.Relocate.End
				lda (ZPQuickPtr1),y		Get HI
				sbc BIN.Relocate.End+1
				bcs .5					addr > BIN.Relocate.End, out of range
				
				txa						Get back LO
*				clc						CC from bcs .6
				adc BIN.Relocate.Offset	add Offset to abs address
				dey
				sta (ZPQuickPtr1),y		store relocated addr LO
				iny
				lda (ZPQuickPtr1),y		Get HI
				adc BIN.Relocate.Offset+1
				sta (ZPQuickPtr1),y		store relocated addr HI
				
.5				pla						get back Opcode length...

.6				clc						A = OPCODE length
				adc ZPQuickPtr1
				sta ZPQuickPtr1
				bcc .7
				inc ZPQuickPtr1+1
				
.7				eor ZPQuickPtr2			A = ZPQuickPtr1
				bne .3
				lda ZPQuickPtr1+1
				eor ZPQuickPtr2+1
				bne .3					next opcode....
				
.8				rts
*--------------------------------------
* 65C02 OPCODES
* Bit 3 	: 1 = absolute addressing
* Bit 2-1-0 : opcode + @ length
*--------------------------------------
*					0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F
BIN.OPCODES		.HS 1.2.2.1.2.2.2.2.1.2.1.1.B.B.B.3
				.HS 2.2.2.1.2.2.2.2.1.B.1.1.B.B.B.3
				.HS B.2.2.1.2.2.2.2.1.2.1.1.B.B.B.3
				.HS 2.2.2.1.2.2.2.2.1.B.1.1.B.B.B.3
				.HS 1.2.2.1.2.2.2.2.1.2.1.1.B.B.B.3
				.HS 2.2.2.1.2.2.2.2.1.B.1.1.1.B.B.3
				.HS 1.2.2.1.2.2.2.2.1.2.1.1.B.B.B.3
				.HS 2.2.2.1.2.2.2.2.1.B.1.1.B.B.B.3
				.HS 2.2.2.1.2.2.2.2.1.2.1.1.B.B.B.3
				.HS 2.2.2.1.2.2.2.2.1.B.1.1.B.B.B.3
				.HS 2.2.2.1.2.2.2.2.1.2.1.1.B.B.B.3
				.HS 2.2.2.1.2.2.2.2.1.B.1.1.B.B.B.3
				.HS 2.2.2.1.2.2.2.2.1.2.1.1.B.B.B.3
				.HS 2.2.2.1.2.2.2.2.1.B.1.1.1.B.B.3
				.HS 2.2.2.1.2.2.2.2.1.2.1.1.B.B.B.3
				.HS 2.2.2.1.2.2.2.2.1.B.1.1.1.B.B.3
*--------------------------------------
MAN
SAVE SYS/KERNEL.S.BIN
LOAD SYS/KERNEL.S
ASM
