NEW
  AUTO 3,1
*--------------------------------------
				.DUMMY
				.OR FAC					15 Bytes
BIN.CmdLine		.BS 2
BIN.hMem		.BS 1
BIN.Move.Len	.BS 2
BIN.R.CS.Start	.BS 2
BIN.R.CS.End	.BS 2
BIN.R.End		.BS 2
BIN.R.Offset	.BS 2
				.ED
*--------------------------------------
* LoadLib
*  in :
*   Y,A = PTR To "LibName.o" C-String
* out :
*   A = hMem To loaded LIB
*--------------------------------------
K.LoadLib		jsr ENV.Search.LIB
				bcs .9
				>LDYAI K.Buf256

				jsr BIN.Load			Y,A = "/PATH/BIN"
				bcs .9
				
				>STYA .1+1
				stx .8+1

				txa						Pass hLib to LibLoad
				ldx #LIBMGR.LOAD
.1				jsr $ffff				SELF MODIFIED, Call LIB.LOAD function
				
				ldx .8+1
				bcs BIN.Load.Cleanup

.8				lda #$ff				SELF MODIFIED, hLib
*				clc
.9				rts
*--------------------------------------
* UnloadLib
*  in :
*   A = hMem To Lib
* out :
*--------------------------------------
K.UnloadLib		pha
				jsr K.GetMemPtr
				>STYA .2+1

				ldy #S.MEM.REFCNT
				lda (ZPMemMgrSPtr),y
				dec
				bne .8
				
.1				ldx #LIBMGR.UNLOAD
.2				jsr $ffff				Self Modified, Call LIB.UNLOAD function
				pla
				jmp K.FreeMem
				
.8				sta (ZPMemMgrSPtr),y

				pla
*				clc
				rts				
*/--------------------------------------
* # LoadDrv
* ## ASM
* **In:**
*  Y,A = PTR to "NAME.DRV [PARAM]" C-String
* ## RETURN VALUE
* none
*\--------------------------------------
K.LoadDrv		>STYA .2+1				Save "BIN\0ARGS\0\0"

				jsr ENV.Search.DRV
				bcs .9
				>LDYAI K.Buf256
				jsr BIN.Load			Y,A = "/PATH/BIN"
				bcs .9
				
				>STYA .3+1
				stx .8+1

				ldx #$ff
			
.1				inx						Skip "BIN"
.2				lda $ffff,x
				bne .1
				
				txa
				sec
				adc .2+1
				tay
				lda #0
				adc .2+2				Y,A = ARGS
				
.3				jsr $ffff				SELF MODIFIED, call Dev.Detect
				
.8				ldx #$ff				SELF MODIFIED, hMem
				jsr BIN.Load.Cleanup
				bcs .9
				
				lda #0					Make sure RC = 0 if success
				clc
.9				rts
				
BIN.Load.Cleanup
				php
				pha
				txa
				jsr K.FreeMem
				pla
				plp
BIN.Load.Cleanup.RTS				
				rts	
*--------------------------------------
* BIN.Load
*  in :
*   Y,A = /BIN/PATH (CSTR)
* out :
*   Y,A = MEMPTR	
*   X = hMem of Code Segment
*--------------------------------------
BIN.Load		>STYA BIN.CmdLine

				ldx #0
				
.1				cpx Mem.LastSlot
				beq BIN.Load.1

				inx						we will skip Slot 0...
				
				txa
				jsr MEM.GetMemByID
				
				lda (ZPMemMgrSPtr)
				bpl .1					In Use?
				
				ldy #S.MEM.BIN			any BIN PATH in this slot?	
				lda (ZPMemMgrSPtr),y
				beq .1
				
				jsr K.GetMemPtr			X unmodified, get pathname
				>STYA .3+1

				ldy #0
				
.2				lda (BIN.CmdLine),y
.3				cmp $ffff,y				SELF MODIFIED
				bne .1
				iny
				ora #0
				bne .2
				
				txa
				jsr MEM.GetMemByID
				
				ldy #S.MEM.REFCNT
				lda (ZPMemMgrSPtr),y
				inc
				sta (ZPMemMgrSPtr),y

				clc
				jmp MEM.GetMEMPTR
*				 X=hMem, Y,A=Ptr
*--------------------------------------				
* STAT Already called by Filesearch in FindDRV, FindLIB
* STAT Already called by PS.Load (TXT,BIN,SYS)
*--------------------------------------				
BIN.Load.1		>LDYA K.S.STAT+S.STAT.P.AUXTYPE
				>STYA BIN.R.CS.Start

				>PUSHYA					Push AUXTYPE
				>PUSHBI S.FI.T.BIN
				>PUSHBI	O.RDONLY
				>LDYA BIN.CmdLine

				ldx #SYS.LoadFile
				jsr K.SYSCALL2.BANK 		BANK1!!! 
				bcs BIN.Load.Cleanup.RTS	Error Loading file

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

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

				txa
				jsr K.GetMemPtr
				>STYA ZPPtr1			set ZPPtr1 -> Code start

				pha						YA = actual load address
				tya
				sec
				sbc BIN.R.CS.Start
				sta BIN.R.Offset		Offset=ZPPtr1-AUXTYPE
				pla
				sbc BIN.R.CS.Start+1
				sta BIN.R.Offset+1
				
				ldy #H.BIN.CS.SIZE		get Code Len
				lda (ZPPtr1),y
				clc
				adc BIN.R.CS.Start
				sta BIN.R.CS.End		ZPPtr1 + CodeLen
				iny
				lda (ZPPtr1),y
				adc BIN.R.CS.Start+1
				sta BIN.R.CS.End+1
				
				jsr BIN.RelExe
				
				>LDYA BIN.CmdLine		get back bin path
				ldx #SYS.strdup			make a copy of this string
				jsr K.SYSCALL2.BANK
				bcs .98
				
				lda BIN.hMem			Keep X=new string hMem		
				jsr MEM.GetMemByID		X unmodified
				
				lda (ZPMemMgrSPtr) 
				ora #S.MEM.F.CODE		This is a code segment
				sta (ZPMemMgrSPtr)

				txa						Get Back Cmd line hMem
				ldy #S.MEM.BIN
				sta (ZPMemMgrSPtr),y
							
				ldx BIN.hMem			return hMEM to Caller...
				clc
				jmp MEM.GetMEMPTR		...and Y,A=PTR to CS
				
.98				ldx BIN.hMem
				jmp BIN.Load.Cleanup	Discard Loaded Code, exits CS
*/--------------------------------------
* # InsDrv
* ## C
* `void * insdrv (void * src, void * crvcsstart, void * drvcsend, void * drvend);`
* ## ASM
* **In:**
* `>PUSHW DRV.END`
* `>PUSHW DRV.CS.END`
* `>PUSHW DRV.CS.START`
* `>LDYA L.SRC`
* `>SYSCALL insdrv`
* ## RETURN VALUE
* Y,A = Ptr to installed driver
*\--------------------------------------
K.InsDrv		>STYA ZPPtr2			SRC PTR

				>PULLW BIN.R.CS.Start
				>PULLW BIN.R.CS.End
				>PULLW BIN.R.End

				lda	BIN.R.End			Compute DRVLen=End-start
				sec
				sbc BIN.R.CS.Start
				sta BIN.Move.Len
				tay
				
				lda BIN.R.End+1
				sbc BIN.R.CS.Start+1
				sta BIN.Move.Len+1

				jsr MEM.GetKrnlBuf		Y,A = LEN
				bcs .9					No More Room to load Driver
				>STYA ZPPtr1			Y,A = DST Buf for RelDrv...
				>STYA ZPPtr3			...for move...
				sty .7+1				...and for exit
				sta .8+1
				
				lda ZPPtr1
				sec
				sbc BIN.R.CS.Start
				sta BIN.R.Offset
				
				lda ZPPtr1+1
				sbc BIN.R.CS.Start+1
				sta BIN.R.Offset+1

				lda BIN.Move.Len+1
				eor #$ff
				pha
				lda BIN.Move.Len
				eor #$ff
				tax
				
				ldy #0
				
.1				inx
				bne .2
				
				pla
				inc
				beq .3
				
				pha
				
.2				lda (ZPPtr2),y
				sta (ZPPtr3),y
				iny
				bne .1
				
				inc ZPPtr2+1
				inc ZPPtr3+1
				bra .1
				
.3				jsr BIN.RelDrv			Relocate at Ptr1
.7				ldy #$ff				SELF MODIFIED
.8				lda #$ff				SELF MODIFIED
.9				rts				
*--------------------------------------
BIN.RelExe		ldy #H.BIN.T+1
				lda (ZPPtr1),y
				cmp /H.BIN.T.BIN65
				beq .1
				cmp /H.BIN.T.DRV65
				beq .1
				
				lda #E.IBIN
				sec
				rts
				
.1				ldy #H.BIN.JMP			relocate Main JMP
				jsr BIN.RelocateAtPtr1Y

				ldy #H.BIN.EXE.REL.TABLE	skip Header, CS.SIZE & DS.SIZE... (16 bytes)
		
				.HS 2C					bit abs
*--------------------------------------					
BIN.RelDrv		ldy #H.BIN.DRV.REL.TABLE

.1				iny
				lda (ZPPtr1),y			HI in A
				beq .2					$00xx = end of table
				
				dey
				jsr BIN.RelocateAtPtr1Y

				iny

				bra .1
*--------------------------------------				
.2				jsr MEM.AddYp1ToPtr1	add current offset in Y to Ptr
*										+ 1 to skip last 00 from beq .2
*										ZPPtr1=Current Code PTR

.3				lda BIN.R.CS.End		compute new CS.END to stop relocating
				clc
				adc BIN.R.Offset
				sta .7+1

				lda BIN.R.CS.End+1
				adc BIN.R.Offset+1
				sta .8+1
				
				lda (ZPPtr1)			get OPCODE
				lsr						/2
				tax
				lda BIN.65816,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
				jsr BIN.RelocateAtPtr1Y
				
.5				pla						get back Opcode length...

.6				clc						A = OPCODE length
				adc ZPPtr1
				sta ZPPtr1
				bcc .7
				inc ZPPtr1+1
				clc						Make sure exit with CC
				
.7				eor #$ff				SELF MODIFIED	A = ZPPtr1
				bne .3
				lda ZPPtr1+1
.8				eor #$ff				SELF MODIFIED
				bne .3					next opcode....
				
				rts
*--------------------------------------
BIN.RelocateAtPtr1Y
				lda (ZPPtr1),y			Get LO
				tax						save LO in X
				iny						make Y point to HI
				lda (ZPPtr1),y			Get HI
				
				cpx BIN.R.CS.Start
				sbc BIN.R.CS.Start+1
				bcc .9					addr < BIN.R.CS.Start, out of range
				
				txa						Get back LO
				cpx BIN.R.End
				lda (ZPPtr1),y			Get HI
				sbc BIN.R.End+1
				bcs .9					addr > BIN.R.End, out of range
				
				txa						Get back LO
				dey
				clc
				adc BIN.R.Offset
				sta (ZPPtr1),y

				iny
				lda (ZPPtr1),y
				adc BIN.R.Offset+1
				sta (ZPPtr1),y
				
.9				rts
*--------------------------------------
* 6502/65C02/65816 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.65816		
*	TO DO : Make 2 different tables
* http://axis.llx.com/~nparker/a2/opcodes.html
*--------------------------------------
* 65R02 OPCODES
*--------------------------------------
*					0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F
BIN.65R02		.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 USR/SRC/SYS/KERNEL.S.BIN
LOAD USR/SRC/SYS/KERNEL.S
ASM
