//  IFUProms.bcpl

external [ JunkIOProms; IFUProms ]
get "DoradoProms.defs"

structure Mouse[
	blank bit 8
	MX1 bit
	MX2 bit
	MY1 bit
	MY2 bit
	MX1dly bit
	MX2dly bit
	MY1dly bit
	MY2dly bit
	]

//The Mouse Prom places a number to indicate X and Y mouse motion as follows:
	// Prom=0:	Y=0,		X=0
	// Prom=1:	Y=0,		X=X+1
	// Prom=2:	Y=0,		X=X-1
	// Prom=3:	Y=Y+1,	X=0
	// Prom=4:	Y=Y+1,	X=X+1
	// Prom=5:	Y=Y+1,	X=X-1
	// Prom=6:	Y=Y-1,	X=0
	// Prom=7:	Y=Y-1,	X=X+1
	// Prom=8:	Y=Y-1,	X=X-1

let IFUProms(mem) be
	[
	let buff = vec 300
	if StEq(mem,"IFU") then mem!0 = DoAll
	if StEq(mem,"DSel") & ICtype eq MC10139 then//define the Data Select Prom
		[
		MakeDataSelect(buff)
		Header("Data-Select",8,buff,32,8)
		PromCommand("IFU-a06")
		]
	]

and JunkIOProms(mem) be
	[
	let buff = vec 300
	if StEq(mem,"JunkIO") then mem!0 = DoAll
	if StEq(mem,"IFU") then mem!0 = DoAll
	if StEq(mem,"Mouse-Motion") & ICtype eq MC10149 then//define the MouseMotion Prom
		[
		MakeMouseMotion(buff)
		Header("Mouse-Motion",4,buff,256,12)
		PromCommand("IFU-i03")
		]

	if StEq(mem,"Keyboard-Map") & ICtype eq I3601 then//define the KeyboardMap Prom
		[
		MakeKeyboardMap(buff)
		Header("Keyboard-Map",8,buff,128,8)
		PromCommand("IFU-k05")
		PromCommand("IFU-l05","4")  //command for right nibble
		]
	]

and MakeMouseMotion(buff) be
	[
	Zero(buff,256)
	let Ydir,Xdir = nil,nil
	for addr = 0 to 255 do
		[ 
		Xdir = 0
		if addr<<Mouse.MX1 ne addr<<Mouse.MX1dly then
			Xdir = (addr<<Mouse.MX1 xor addr<<Mouse.MX2) + 1			//+1 or +2
		if addr<<Mouse.MX2 ne addr<<Mouse.MX2dly then
			Xdir = (addr<<Mouse.MX1 xor addr<<Mouse.MX2 xor 1) + 1	//+2 or +1

		Ydir = 0
		if addr<<Mouse.MY1 ne addr<<Mouse.MY1dly then
			Ydir = (addr<<Mouse.MY1 xor addr<<Mouse.MY2) + 1			//+1 or +2
		if addr<<Mouse.MY2 ne addr<<Mouse.MY2dly then
			Ydir = (addr<<Mouse.MY1 xor addr<<Mouse.MY2 xor 1) + 1	//+2 or +1

		buff!addr = 3*Ydir + Xdir
		]
	]


and MakeKeyboardMap(buff) be
	[
	let Map = table
		[
		08; 00; 16; 29; 36; 30; 37; 11		//addr=00
		52; 46; 60; 53; 63; 49; 05; 61		//addr=08
		28; 20; 21; 25; 22; 26; 56; 45		//addr=16
		31; 57; 58; 59; 62; 41; 51; 33		//addr=24
		24; 12; 13; 02; 14; 03; 38; 19 		//addr=32
		23; 27; 55; 54; 34; 50; 04; 06		//addr=40
		01; 09; 10; 17; 18; 44; 39; 47		//addr=48
		15; 43; 40; 32; 35; 48; 07; 42		//addr=56
		]

	Zero(buff,256)
	for val = 0 to 63 do
		for addr = 0 to 63 do if Map!addr eq val then buff!val = addr
	for val = 64 to 127 do
		buff!val = (val-64) xor #60
	for val = 0 to 127 do
		buff!val = buff!val xor #77
	]

and MakeDataSelect(buff) =valof  //define data select control for instructions types  
	[
	let TableDef = table
		[                                                                       
		#377; #377; #377; #377; #377; #367; #263; #221
		#377; #377; #377; #377; #377; #377; #225; #204
		#377; #377; #377; #377; #377; #377; #167; #063
		#377; #377; #377; #377; #377; #377; #073; #031
		]
	MoveBlock(buff,TableDef,32)
	]