#include <stdio.h>
#include "kernel.h"
#include "bbc.h"

#include "general.h"
#include "Externals.h"

extern u_char RdDisk(u_int ax);

static BOOL shiftstatus;

u_char ReadRow(int ikmax, u_char *generic, u_char *modifier)
{
u_char ik, vx= 0;

if(!shiftstatus)
	for(ik=0; ik<ikmax; ik++)
		{
		char g= generic[ik];
		char m= modifier[ik];
		if(m == 0xff)
			{
			if((_kernel_osbyte(121, g, 0) & 0xff)== 0xff)
				vx|= 1<<ik;
			continue;
			}
		if((g > 127) && (_kernel_osbyte(121, g, 0) & 0xff)== 0xff)
				{
				vx|= 1<<ik;
				continue;
				}
		if(	(m > 127) && (m != 0xfe) && !((m == (g | 0x80)) && (g>127)) &&
			((_kernel_osbyte(121, m, 0) & 0xff)== 0xff))
			vx|= 1<<ik;
		}
else	for(ik=0; ik<ikmax; ik++)
		{
		u_char g= generic[ik];
		u_char m= modifier[ik];
		if(m == 0xff)
			{
			if((_kernel_osbyte(121, g, 0) & 0xff)== 0xff)
				vx|= 1<<ik;
			continue;
			}
		if((g < 128) && ((_kernel_osbyte(121, g ^ 0x80, 0) & 0xff)== 0xff))
				{
				vx|= 1<<ik;
				continue;
				}
		if(	(m < 128) && !((m == (g & 0x7f)) && (g<128)) &&
			((_kernel_osbyte(121, m ^ 0x80, 0) & 0xff)== 0xff))
			vx|= 1<<ik;
		}
return(vx);
}

BOOL ReadShift(int ikmax, u_char *generic, u_char *modifier)
{
u_char ik;
if(shiftstatus)
	for(ik=0; ik<ikmax; ik++)
		{
		u_char m= modifier[ik];
		u_char g= generic[ik];
		if(m == 0xfe) continue;
		if((m == 0xff) && ((_kernel_osbyte(121, g, 0) & 0xff)== 0xff))
			return(TRUE);
		if((m < 128) && ((_kernel_osbyte(121, m ^ 0x80, 0) & 0xff)== 0xff))
			return(TRUE);
		}
else	for(ik=0; ik<ikmax; ik++)
		{
		u_char m= modifier[ik];
		if(m == 0xfe) continue;
		if(m == 0xff) continue;
		if((m > 127) && ((_kernel_osbyte(121, m, 0) & 0xff)== 0xff))
			return(TRUE);
		}
return(FALSE);
}

u_char EmuKbd(u_int ax)
{
u_char vr= 0;
if((_kernel_osbyte(121,113 ^ 0x80, 0) & 0xff) == 0xff)
	{
	char ip, nomfic[32];
	static const char effacement[] =
		{
		bbc_MultiPurpose, 8, 5, 10, 0, 0, 0, 0, 0, 0
		};
	bbc_tab(0,25); bbc_cursor(1);
	printf("> Command/pathname: ");
	(void) gets(nomfic);
	switch(nomfic[0])
		{
		extern void Traitk7(char *s);
		case 'K':
		case 'k':
			Traitk7(nomfic+1);
			break;
		}
	while((_kernel_osbyte(122,0,0) & 0xff)!= 0xff) ;
	bbc_tab(0,25); bbc_cursor(0);
	for(ip=0; ip<sizeof(effacement); ip++) bbc_vdu(effacement[ip]);
	}
else	{
	shiftstatus= (_kernel_osbyte(121,0 ^ 0x80, 0) & 0xff) == 0xff;
	switch(ax & 0xff)
		{
		static u_char generic01[8]=
			{
			(49 ^ 0x00), (65 ^ 0x80), (100 ^ 0x80), (82 ^ 0x80),
			(50 ^ 0x80), (34 ^ 0x80), (67 ^ 0x80), (83 ^ 0x80)
			};
		static u_char modifier01[8]=
			{
			0xfe, 0xff, 0xff, 0xff,
			0xff, 0xff, 0xff, 0xff
			};
		static u_char generic02[8]=
			{
			(84 ^ 0x80), (37 ^ 0x80), (69 ^ 0x80), (70 ^ 0x80),
			(86 ^ 0x80), (101 ^ 0x80), (85 ^ 0x80), (54 ^ 0x80)
			};
		static u_char modifier02[8]=
			{
			0xff, 0xff, 0xff, 0xff,
			0xff, 0xff, 0xff, 0xff
			};
		static u_char generic04[8]=
			{
			(55 ^ 0x80), (16 ^ 0x80), (51 ^ 0x80), (81 ^ 0x80),
			(35 ^ 0x80), (53 ^ 0x80), (99 ^ 0x80), (33 ^ 0x80)
			};
		static u_char modifier04[8]=
			{
			0xff, 0xff, 0xff, 0xff,
			0xff, 0xff, 0xff, 0xff
			};
		static u_char generic08[3]=
			{
			(66 ^ 0x80), (68 ^ 0x80), (97 ^ 0x80)
			};
		static u_char modifier08[3]=
			{
			0xff, 0xff, 0xff
			};
		static u_char generic10[8]=
			{
			(39 ^ 0x80), (48 ^ 0x80), (49 ^ 0x80), (17 ^ 0x80),
			(18 ^ 0x80), (19 ^ 0x80), (52 ^ 0x80), (36 ^ 0x80)
			};
		static u_char modifier10[8]=
			{
			0xfe,        (48 ^ 0x00), (79 ^ 0x00), (17 ^ 0x00),
			(18 ^ 0x00), (19 ^ 0x00), (36 ^ 0x00), (79 ^ 0x80)
			};
		static u_char generic20[8]=
			{
			(21 ^ 0x80), (38 ^ 0x80), (87 ^ 0x00), (87 ^ 0x80),
			(102^ 0x80), (23 ^ 0x80), (103^ 0x80), (104 ^ 0x80)
			};
		static u_char modifier20[8]=
			{
			(38 ^ 0x00), (39 ^ 0x00), (21 ^ 0x00), (93 ^ 0x00),
			(102^ 0x00), (93 ^ 0x80), (103^ 0x00), (104 ^ 0x00)
			}; 
		static u_char generic40[8]=
			{
			(73 ^ 0x80), (62 ^ 0x80), (44 ^ 0x80), (57 ^ 0x80),
			(41 ^ 0x80), (25 ^ 0x80), (121 ^ 0x80), (98 ^ 0x80)
			};
		static u_char modifier40[8]=
			{
			0xff, 0xff, 0xff, 0xff,
			0xff, 0xff, 0xff, 0xff
			};
		case 0x01:
			vr= ReadRow(8, generic01, modifier01);
			break;
		case 0x02:
			vr= ReadRow(8, generic02, modifier02);
			break;
		case 0x04:
			vr= ReadRow(8, generic04, modifier04);
			break;
		case 0x08:
			vr= ReadRow(3, generic08, modifier08);
			break;
		case 0x10:
			vr= ReadRow(8, generic10, modifier10);
			break;
		case 0x20:
			vr= ReadRow(8, generic20, modifier20);
			break;
		case 0x40:
			vr= ReadRow(8, generic40, modifier40);
			break;
		case 0x80:
			vr= (_kernel_osbyte(121, 2 ^ 0x80, 0) & 0xff) == 0xff ||
				ReadShift(8, generic01, modifier01) ||
				ReadShift(8, generic02, modifier02) || 
				ReadShift(8, generic04, modifier04) || 
				ReadShift(3, generic08, modifier08) || 
				ReadShift(8, generic10, modifier10) || 
				ReadShift(8, generic20, modifier20) || 
				ReadShift(8, generic40, modifier40) ?
				1 : 0; 
			break;
		default:
			return(TRSCode->bytes[ax]);
		}
	}
while((_kernel_osbyte(129,0,0)>>8 & 0xff)!= 0xff);
return(vr);
}

u_char (*EmuRead[SIZE_CODE>>8])(u_int ax) =
	{
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0,RdDisk,EmuKbd, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
	};
