add: data = NV_REG32(reg); NV_REG32(reg) = ((data & 0xffff0000) | (n << 8) | m); data = NV_REG32(reg);
context: static status_t exec_type2_script_mode(uint8* rom, uint16* adress, int16* size, PinsTables tabs, uint16 ram_tab, bool* exec){	status_t result = B_OK;	bool end = false;	uint8 index, byte, byte2, shift;	uint32 reg, reg2, data, data2, and_out, and_out2, or_in, or_in2, safe32, offset32, size32;	while (!end)	{		LOG(8,("INFO: $%04x ($%02x); ", *adress, rom[*adress]));		//fixme: complete (if possible) ...		switch (rom[*adress])		{		case 0x32: /* new */			*size -= (11 + ((*((uint8*)(&(rom[(*adress + 6)])))) << 2));			if (*size < 0)			{				LOG(8,("script size error, aborting!\n\n"));				end = true;				result = B_ERROR;				break;			}			/* execute */			*adress += 1;			reg = *((uint16*)(&(rom[*adress])));			*adress += 2;			index = *((uint8*)(&(rom[*adress])));			*adress += 1;			and_out = *((uint8*)(&(rom[*adress])));			*adress += 1;			byte2 = *((uint8*)(&(rom[*adress])));			*adress += 1;			size32 = ((*((uint8*)(&(rom[*adress])))) << 2);			*adress += 1;			reg2 = *((uint32*)(&(rom[*adress])));			*adress += 4;			LOG(8,("cmd 'RD idx ISA reg $%02x via $%04x, AND-out = $%02x, shift-right = $%02x,\n",				index, reg, and_out, byte2));			LOG(8,("INFO: (cont.) RD 32bit data from subtable with size $%04x, at offset (result << 2),\n",				size32));			LOG(8,("INFO: (cont.) then WR result data to 32bit reg $%08x'\n", reg2));			if (*exec && reg2)			{				translate_ISA_PCI(&reg);				NV_REG8(reg) = index;				byte = NV_REG8(reg + 1);				byte &= (uint8)and_out;				byte >>= byte2;				offset32 = (byte << 2);				data = *((uint32*)(&(rom[(*adress + offset32)])));				NV_REG32(reg2) = data;			}			*adress += size32;			break;		case 0x33: /* new */			*size -= 2;			if (*size < 0)			{				LOG(8,("script size error, aborting!\n\n"));				end = true;				result = B_ERROR;				break;			}			/* execute */			*adress += 1;			size32 = *((uint8*)(&(rom[*adress])));			*adress += 1;			/* executed 1-256 times */			if (!size32) size32 = 256;			/* remember where to start each time */			safe32 = *adress;			LOG(8,("cmd 'execute following part of this script $%03x times' (always done)\n", size32));			for (offset32 = 0; offset32 < size32; offset32++)			{				LOG(8,("\nINFO: (#$%02x) executing part of type2 script at adress $%04x...\n",					offset32, *adress));				LOG(8,("INFO: ---Not touching 'execution' mode at this time:\n"));				*adress = safe32;				result = exec_type2_script_mode(rom, adress, size, tabs, ram_tab, exec);			}			LOG(8,("INFO: ---Continuing script:\n"));			break;		case 0x34: /* new */			*size -= (12 + ((*((uint8*)(&(rom[(*adress + 7)])))) << 1));			if (*size < 0)			{				LOG(8,("script size error, aborting!\n\n"));				end = true;				result = B_ERROR;				break;			}			/* execute */			*adress += 1;			reg = *((uint16*)(&(rom[*adress])));			*adress += 2;			index = *((uint8*)(&(rom[*adress])));			*adress += 1;			and_out = *((uint8*)(&(rom[*adress])));			*adress += 1;			shift = *((uint8*)(&(rom[*adress])));			*adress += 1;			offset32 = *((uint8*)(&(rom[*adress])));			*adress += 1;			size32 = ((*((uint8*)(&(rom[*adress])))) << 1);			*adress += 1;			reg2 = *((uint32*)(&(rom[*adress])));			*adress += 4;			LOG(8,("cmd 'RD idx ISA reg $%02x via $%04x, AND-out = $%02x, shift-right = $%02x,\n",				index, reg, and_out, shift));			LOG(8,("INFO: (cont.) RD 16bit PLL frequency to pgm from subtable with size $%04x, at offset (result << 1),\n",				size32));			LOG(8,("INFO: (cont.) RD table-index ($%02x) for cmd $39'\n",				offset32));			translate_ISA_PCI(&reg);			NV_REG8(reg) = index;			byte = NV_REG8(reg + 1);			byte &= (uint8)and_out;			data = (byte >> shift);			data <<= 1;			data2 = *((uint16*)(&(rom[(*adress + data)])));			if (offset32 < 0x80)			{				bool double_f = true;				LOG(8,("INFO: Do subcmd ($39); "));				exec_cmd_39_type2(rom, offset32, tabs, &double_f);				LOG(8,("INFO: (cont. cmd $34) Doubling PLL frequency to be set for cmd $34.\n"));				if (double_f) data2 <<= 1;				LOG(8,("INFO: ---Reverting to pre-subcmd ($39) 'execution' mode.\n"));			}			else			{				LOG(8,("INFO: table index is negative, not executing subcmd ($39).\n"));			}			LOG(8,("INFO: (cont.) 'calc and set PLL 32bit reg $%08x for %.3fMHz'\n",				reg2, (data2 / 100.0)));			if (*exec && reg2)			{				float calced_clk;				uint8 m, n, p;				nv_dac_sys_pll_find((data2 / 100.0), &calced_clk, &m, &n, &p, 0);				NV_REG32(reg2) = ((p << 16) | (n << 8) | m);//fixme?				/* program 2nd set N and M scalers if they exist (b31=1 enables them) *///				if ((si->ps.card_type == NV31) || (si->ps.card_type == NV36))//					DACW(PIXPLLC2, 0x80000401);			}			log_pll(reg2);			*adress += size32;			break;		case 0x37: /* new */			*size -= 11;			if (*size < 0)			{				LOG(8,("script size error, aborting!\n\n"));				end = true;				result = B_ERROR;				break;			}			/* execute */			*adress += 1;			reg = *((uint32*)(&(rom[*adress])));			*adress += 4;			byte2 = *((uint8*)(&(rom[*adress])));			*adress += 1;			and_out = *((uint8*)(&(rom[*adress])));			*adress += 1;			reg2 = *((uint16*)(&(rom[*adress])));			*adress += 2;			index = *((uint8*)(&(rom[*adress])));			*adress += 1;			and_out2 = *((uint8*)(&(rom[*adress])));			*adress += 1;			LOG(8,("cmd 'RD 32bit reg $%08x, shift-right = $%02x, AND-out lsb = $%02x,\n",				reg, byte2, and_out));			LOG(8,("INFO: (cont.) RD 8bit ISA reg $%02x via $%04x, AND-out = $%02x, OR-in lsb result 32bit, WR-bk'\n",				index, reg2, and_out2));			if (*exec)			{				data = NV_REG32(reg);				if (byte2 < 0x80)				{					data >>= byte2;				}				else				{					data <<= (0x0100 - byte2);				}				data &= and_out;				translate_ISA_PCI(&reg2);				NV_REG8(reg2) = index;				byte = NV_REG8(reg2 + 1);				byte &= (uint8)and_out2;				byte |= (uint8)data;				NV_REG8(reg2 + 1) = byte;			}			break;		case 0x38: /* new */			*size -= 1;			if (*size < 0)			{				LOG(8,("script size error, aborting!\n\n"));				end = true;				result = B_ERROR;				break;			}			/* execute */			*adress += 1;			LOG(8,("cmd 'invert current mode'\n"));			*exec = !(*exec);			if (*exec)				LOG(8,("INFO: ---Executing following command(s):\n"));			else				LOG(8,("INFO: ---Not executing following command(s):\n"));			break;		case 0x39: /* new */			*size -= 2;			if (*size < 0)			{				LOG(8,("script size error, aborting!\n\n"));				end = true;				result = B_ERROR;				break;			}			/* execute */			*adress += 1;			data = *((uint8*)(&(rom[*adress])));			*adress += 1;			exec_cmd_39_type2(rom, data, tabs, exec);			break;		case 0x49: /* new */			size32 = *((uint8*)(&(rom[*adress + 17])));			if (!size32) size32 = 256;			*size -= (18 + (size32 << 1));			if (*size < 0)			{				LOG(8,("script size error, aborting!\n\n"));				end = true;				result = B_ERROR;				break;			}			/* execute */			*adress += 1;			reg = *((uint32*)(&(rom[*adress])));			*adress += 4;			reg2 = *((uint32*)(&(rom[*adress])));			*adress += 4;			and_out = *((uint32*)(&(rom[*adress])));			*adress += 4;			or_in = *((uint32*)(&(rom[*adress])));			*adress += 4;			size32 = *((uint8*)(&(rom[*adress])));			if (!size32) size32 = 256;			*adress += 1;			LOG(8,("cmd 'do following cmd structure $%03x time(s)':\n", size32));			for (offset32 = 0; offset32 < size32; offset32++)			{				or_in2 = *((uint8*)(&(rom[(*adress + (offset32 << 1))])));				data2 = *((uint8*)(&(rom[(*adress + (offset32 << 1) + 1)])));				LOG(8,("INFO (cont.) (#$%02x) cmd 'WR 32bit reg $%08x = $%08x, RD 32bit reg $%08x,\n",					offset32, reg2, data2, reg));				LOG(8,("INFO (cont.) AND-out $%08x, OR-in $%08x, OR-in $%08x, WR-bk'\n",					and_out, or_in, or_in2));			}			if (*exec)			{				for (index = 0; index < size32; index++)				{					or_in2 = *((uint8*)(&(rom[*adress])));					*adress += 1;					data2 = *((uint8*)(&(rom[*adress])));					*adress += 1;					NV_REG32(reg2) = data2;					data = NV_REG32(reg);					data &= and_out;					data |= or_in;					data |= or_in2;					NV_REG32(reg) = data;				}			}			else			{				*adress += (size32 << 1);			}			break;		case 0x62: /* new */			*size -= 5;			if (*size < 0)			{				LOG(8,("script size error, aborting!\n\n"));				end = true;				result = B_ERROR;				break;			}			/* execute */			*adress += 1;			reg = *((uint16*)(&(rom[*adress])));			*adress += 2;			index = *((uint8*)(&(rom[*adress])));			*adress += 1;			byte = *((uint8*)(&(rom[*adress])));			*adress += 1;			LOG(8,("cmd 'WR idx ISA reg $%02x via $%04x = $%02x'\n", index, reg, byte));			if (*exec)			{				translate_ISA_PCI(&reg);				NV_REG16(reg) = ((((uint16)byte) << 8) | index);			}			break;		case 0x63: /* new setup compared to pre-NV10 version */			*size -= 1;			if (*size < 0)			{				LOG(8,("script size error, aborting!\n\n"));				end = true;				result = B_ERROR;				break;			}			/* execute */			*adress += 1;			LOG(8,("cmd 'setup RAM config' (always done)\n"));			/* always done */			switch (si->ps.card_type)			{			case NV28:				setup_ram_config_nv28(rom);				break;			default:				setup_ram_config_nv10_up(rom);				break;			}			break;		case 0x65: /* identical to type1 */			*size -= 13;			if (*size < 0)			{				LOG(8,("script size error, aborting!\n\n"));				end = true;				result = B_ERROR;				break;			}			/* execute */			*adress += 1;			reg = *((uint32*)(&(rom[*adress])));			*adress += 4;			data = *((uint32*)(&(rom[*adress])));			*adress += 4;			data2 = *((uint32*)(&(rom[*adress])));			*adress += 4;			LOG(8,("cmd 'WR 32bit reg $%08x = $%08x, then = $%08x' (always done)\n",				reg, data, data2));			/* always done */			//remove.. illegal!?			//safe32 = CFGR(AGPCMD);			//CFGW(AGPCMD, 0x00000000);			NV_REG32(reg) = data;			NV_REG32(reg) = data2;			//CFGW(AGPCMD, safe32);			CFGW(ROMSHADOW, (CFGR(ROMSHADOW) & 0xfffffffe));			break;		case 0x69: /* identical to type1 */			*size -= 5;			if (*size < 0)			{				LOG(8,("script size error, aborting!\n\n"));				end = true;				result = B_ERROR;				break;			}			/* execute */			*adress += 1;			reg = *((uint16*)(&(rom[*adress])));			*adress += 2;			and_out = *((uint8*)(&(rom[*adress])));			*adress += 1;			or_in = *((uint8*)(&(rom[*adress])));			*adress += 1;			LOG(8,("cmd 'RD 8bit ISA reg $%04x, AND-out = $%02x, OR-in = $%02x, WR-bk'\n",				reg, and_out, or_in));			if (*exec)			{				translate_ISA_PCI(&reg);				byte = NV_REG8(reg);				byte &= (uint8)and_out;				byte |= (uint8)or_in;				NV_REG8(reg) = byte;			}			break;		case 0x6b: /* new */			*size -= 2;			if (*size < 0)			{				LOG(8,("script size error, aborting!\n\n"));				end = true;				result = B_ERROR;				break;			}			/* execute */			*adress += 1;			data = *((uint8*)(&(rom[*adress])));			*adress += 1;			data2 = *((uint16*)(&(rom[(tabs.InitScriptTablePtr + (data << 1))])));			LOG(8,("cmd 'gosub script #$%02x at adress $%04x'\n", data, data2));			if (*exec && data2)			{				result = exec_type2_script(rom, data2, size, tabs, ram_tab);				LOG(8,("INFO: ---Reverting to pre-gosub 'execution' mode.\n"));			}			break;		case 0x6e: /* identical to type1 */			*size -= 13;			if (*size < 0)			{				LOG(8,("script size error, aborting!\n\n"));				end = true;				result = B_ERROR;				break;			}			/* execute */			*adress += 1;			reg = *((uint32*)(&(rom[*adress])));			*adress += 4;			and_out = *((uint32*)(&(rom[*adress])));			*adress += 4;			or_in = *((uint32*)(&(rom[*adress])));			*adress += 4;			LOG(8,("cmd 'RD 32bit reg $%08x, AND-out = $%08x, OR-in = $%08x, WR-bk'\n",				reg, and_out, or_in));			if (*exec)			{				data = NV_REG32(reg);				data &= and_out;				data |= or_in;				NV_REG32(reg) = data;			}			break;		case 0x6f: /* new */			*size -= 2;			if (*size < 0)			{				LOG(8,("script size error, aborting!\n\n"));				end = true;				result = B_ERROR;				break;			}			/* execute */			*adress += 1;			data = (*((uint8*)(&(rom[*adress]))) << 1);			*adress += 1;			data += tabs.MacroIndexTablePtr;			offset32 = (*((uint8*)(&(rom[data]))) << 3);			size32 = *((uint8*)(&(rom[(data + 1)])));			offset32 += tabs.MacroTablePtr;			/* note: min 1, max 255 commands can be requested */			LOG(8,("cmd 'do $%02x time(s) a 32bit reg WR with 32bit data':\n", size32));			safe32 = 0;			while (safe32 < size32)			{				reg2 = *((uint32*)(&(rom[(offset32 + (safe32 << 3))])));				data2 = *((uint32*)(&(rom[(offset32 + (safe32 << 3) + 4)])));				LOG(8,("INFO: (cont.) (#$%02x) cmd 'WR 32bit reg' $%08x = $%08x\n",					safe32, reg2, data2));				safe32++; 			}			if (*exec)			{				safe32 = 0;				while (safe32 < size32)				{					reg2 = *((uint32*)(&(rom[(offset32 + (safe32 << 3))])));					data2 = *((uint32*)(&(rom[(offset32 + (safe32 << 3) + 4)])));					NV_REG32(reg2) = data2;					safe32++;				}			}			break;		case 0x36: /* new */		case 0x66: /* new */		case 0x67: /* new */		case 0x68: /* new */		case 0x6c: /* new */		case 0x71: /* identical to type1 */			LOG(8,("cmd 'END', execution completed.\n\n"));			end = true;			*size -= 1;			if (*size < 0)			{				LOG(8,("script size error!\n\n"));				result = B_ERROR;			}			/* execute */			*adress += 1; /* needed to make cmd #$33 work correctly! */			break;		case 0x72: /* identical to type1 */			*size -= 1;			if (*size < 0)			{				LOG(8,("script size error!\n\n"));				result = B_ERROR;			}			/* execute */			*adress += 1;			LOG(8,("cmd 'PGM commands'\n"));			LOG(8,("INFO: ---Executing following command(s):\n"));			*exec = true;			break;		case 0x74: /* identical to type1 */			*size -= 3;			if (*size < 0)			{				LOG(8,("script size error, aborting!\n\n"));				end = true;				result = B_ERROR;				break;			}			/* execute */			*adress += 1;			data = *((uint16*)(&(rom[*adress])));			*adress += 2;			LOG(8,("cmd 'SNOOZE for %d ($%04x) microSeconds' (always done)\n", data, data));			/* always done */			snooze(data);			break;		case 0x75: /* new */			*size -= 2;			if (*size < 0)			{				LOG(8,("script size error!\n\n"));				result = B_ERROR;			}			/* execute */			*adress += 1;			data = *((uint8*)(&(rom[*adress])));			*adress += 1;			data *= 12;			data += tabs.ConditionTablePtr;			reg = *((uint32*)(&(rom[data])));			and_out = *((uint32*)(&(rom[(data + 4)])));			data2 = *((uint32*)(&(rom[(data + 8)])));			data = NV_REG32(reg);			data &= and_out;			LOG(8,("cmd 'CHK bits AND-out $%08x reg $%08x for $%08x'\n",				and_out, reg, data2));			if (data != data2)			{				LOG(8,("INFO: ---No match: not executing following command(s):\n"));				*exec = false;			}			else			{				LOG(8,("INFO: ---Match, so this cmd has no effect.\n"));			}			break;		case 0x76: /* new */			*size -= 2;			if (*size < 0)			{				LOG(8,("script size error!\n\n"));				result = B_ERROR;			}			/* execute */			*adress += 1;			data = *((uint8*)(&(rom[*adress])));			*adress += 1;			data *= 5;			data += tabs.IOConditionTablePtr;			reg = *((uint16*)(&(rom[data])));			index = *((uint8*)(&(rom[(data + 2)])));			and_out = *((uint8*)(&(rom[(data + 3)])));			byte2 = *((uint8*)(&(rom[(data + 4)])));			LOG(8,("cmd 'CHK bits AND-out $%02x idx ISA reg $%02x via $%04x for $%02x'\n",				and_out, index, reg, byte2));			translate_ISA_PCI(&reg);			NV_REG8(reg) = index;			byte = NV_REG8(reg + 1);			byte &= (uint8)and_out;			if (byte != byte2)			{				LOG(8,("INFO: ---No match: not executing following command(s):\n"));				*exec = false;			}			else			{				LOG(8,("INFO: ---Match, so this cmd has no effect.\n"));			}			break;		case 0x78: /* identical to type1 */			*size -= 6;			if (*size < 0)			{				LOG(8,("script size error, aborting!\n\n"));				end = true;				result = B_ERROR;				break;			}			/* execute */			*adress += 1;			reg = *((uint16*)(&(rom[*adress])));			*adress += 2;			index = *((uint8*)(&(rom[*adress])));			*adress += 1;			and_out = *((uint8*)(&(rom[*adress])));			*adress += 1;			or_in = *((uint8*)(&(rom[*adress])));			*adress += 1;			LOG(8,("cmd 'RD idx ISA reg $%02x via $%04x, AND-out = $%02x, OR-in = $%02x, WR-bk'\n",				index, reg, and_out, or_in));			if (*exec)			{				translate_ISA_PCI(&reg);				NV_REG8(reg) = index;				byte = NV_REG8(reg + 1);				byte &= (uint8)and_out;				byte |= (uint8)or_in;				NV_REG8(reg + 1) = byte;			}			break;		case 0x79:			*size -= 7;			if (*size < 0)			{				LOG(8,("script size error, aborting!\n\n"));				end = true;				result = B_ERROR;				break;			}			/* execute */			*adress += 1;			reg = *((uint32*)(&(rom[*adress])));			*adress += 4;			data = *((uint16*)(&(rom[*adress])));			*adress += 2;			LOG(8,("cmd 'calculate and set PLL 32bit reg $%08x for %.3fMHz'\n", reg, (data / 100.0)));			if (*exec)			{				float calced_clk;				uint8 m, n, p;				nv_dac_sys_pll_find((data / 100.0), &calced_clk, &m, &n, &p, 0);				NV_REG32(reg) = ((p << 16) | (n << 8) | m);//fixme?				/* program 2nd set N and M scalers if they exist (b31=1 enables them) *///				if ((si->ps.card_type == NV31) || (si->ps.card_type == NV36))//					DACW(PIXPLLC2, 0x80000401);			}			log_pll(reg);			break;		case 0x7a: /* identical to type1 */			*size -= 9;			if (*size < 0)			{				LOG(8,("script size error, aborting!\n\n"));				end = true;				result = B_ERROR;				break;			}			/* execute */			*adress += 1;			reg = *((uint32*)(&(rom[*adress])));			*adress += 4;			data = *((uint32*)(&(rom[*adress])));			*adress += 4;			LOG(8,("cmd 'WR 32bit reg' $%08x = $%08x\n", reg, data));			if (*exec) NV_REG32(reg) = data;			break;		default:			LOG(8,("unknown cmd, aborting!\n\n"));			end = true;			result = B_ERROR;			break;		}	}	return result;}