?? portio.c,v
字號:
case 27:
if (!x_dsp_mars)
writebio(0x304, 0);
else
writebio(0x308, 0);
return;
// loc_2EA7C
case 28:
if (!x_dsp_mars)
writebio(0x304, 1);
else
writebio(0x308, 1);
return;
// loc_2EA8D
case 29:
if (!x_dsp_mars)
writebio(0x308, 0);
else
writebio(0xffff, 0);
return;
// loc_2EA97
/* (hmm, like 29 but use ", 1" instead */
case 30:
if (!x_dsp_mars)
writebio(0x308, 1);
else
writebio(0xffff, 1);
return;
// loc_2EAA8
case 31:
if (!x_dsp_mars)
writebio(0x302, 0);
else
writebio(0xffff, 0);
return;
// loc_2EAB2
case 32:
if (!x_dsp_mars)
writebio(0x302, 1);
else
writebio(0xffff, 1);
return;
case 33: case 34: case 37: case 38:
return;
default: die( "x_output: %d - not implemented\n", state );
}
}
// Needs finishing.
int x_input(int arg)
{
unsigned char al;
switch (arg) {
case 0x38: // loc_2E6A2
if (!x_dsp_mars)
al = readbio(0x1120);
else
al = readbio(0xffff);
if (al != 0) return 1;
if (!x_dsp_mars)
readbio(0x1120);
else
readbio(0xffff);
return 0;
case 0x39: // loc_2E67D
if (!x_dsp_mars)
al = readbio(0x1120);
else
al = readbio(0xffff);
if (al == 0) return 1;
if (!x_dsp_mars)
readbio(0x1120);
else
readbio(0xffff);
return 0;
case 0x3e: // loc_2E671
return 0;
case 0x40: // loc_2E667
printf( "x_input: error 0x%x - not implemented!\n", arg );
break;
case 0x41:
if (cell_active == 1) return 0; // loc_2E6D1
if (!x_dsp_mars) {
al = readbio(0x1140);
if (al != 0) {
al = readbio(0x1140);
return 0;
}
else { // loc_2E6D7
return 1;
}
}
else {
al = readbio(0x1110);
if (!al) return 1;
readbio(0x1110);
return 0;
}
default: /* 6d1 */
return 0;
}
return 0;
}
void dp_regandor (unsigned int port, unsigned int val1, unsigned int val2)
{
dp_regwrite (port, ((dp_regread (port) & val1) | val2));
}
//========================================================================
//
//
void dp_board_enable (void)
{
if (CpqFlag== 1) {
// Compaq specific stuff perhaps?
if (ComAddress == BaseAddress) {
if ((word_59ED7 != 0xCCB0) && (word_59ED7 != 0xCDB0))
BaseAddress = 0xEC;
else
BaseAddress = 0xBC;
}
else if ((BaseAddress != 0xEC) && (BaseAddress != 0xBC))
BaseAddress = BaseAddress & 0xFFF8;
}
x_chip_version = 0;
BaseAddressIndex = BaseAddress;
// ToshibaFlag = 1; // I don't think so!
BaseAddressData = BaseAddress + 1;
BaseAddress2 = BaseAddress + 2;
Init_Mars();
dp_regwrite (0xCB, 8);
if (x_dsp_mars == 1) return;
// I think my card has a mars chipset so this stuff
// probably doesn't matter (yet).
//dp_dsp_regread_poll(6, 0xC0, 2);
// etc...
}
void process_ring(void)
{
printf( "Ring came?!\n" );
#if 1
dp_int_regwrite(0xd8, 0xff);
if (dp_ring_int_count > 1) {
dp_bamil_rd7 = 2;
dp_ring_int = 1;
dp_init_local_phone_timer();
return;
}
dp_ring_int_count++;
if ((dp_sleep == 1) && (dp_ring_int_count == 1))
dp_regwrite(0xCB, 8);
x_wakeup();
#endif
}
int
dp_dsp_isr(void)
{
int i, todo;
// edi = 0xd7
i = dp_int_regread(0xd7);
todo = i & 0xff;
if ((!todo) || (todo == 0xff))
goto failexit;
// ----------------------------------
// Not in asm code!
if (todo == 8)
printf( "+" ); // What is the significance of todo = 8?
else
printf( "[ISR:%x]", todo);
// ----------------------------------
if (x_dsp_mars == 1)
Write_mdm_word(0x3c, 0x101);
dp_int_regwrite(0xd7, 0xff);
// esi = 0xd8
if (todo & 2)
process_ring();
if (todo & 8) {
dp_int_regwrite(0xD8, 8);
dp_byte_c = dp_int_regread(0x32);
dp_byte_d = dp_int_regread(0x33);
dp_byte_e = dp_int_regread(0x34);
dp_byte_f = dp_int_regread(0x35);
}
//printf("dp_byte_f = %x.\n", dp_byte_f);
if (todo & 4)
process_v34();
if (todo & 0x40) {
int i;
i = dp_int_regread(0xbc);
// esi = 0xbd
dp_int_regwrite(0xbd, i);
dp_int_regwrite(0xbd, ~i); /* they used not on lower byte only */
if (i & 0x18) {
printf( "What do you want to do with cellphone?\n" );
#if 0
cell_isr();
x_wakeup();
#endif
}
}
/* E52 */
dp_int_regwrite(0xd7, dp_bamil_rd7);
outb_p(BaseValue, BaseAddressIndex);
return 1;
failexit:
outb_p(BaseValue, BaseAddressIndex);
return 0;
}
/* Ugly, feel free to rewrite it to be really readable. But I do not care - this function is not critical in any way */
int
dp_dsp_rom_checksum(void)
{
int i;
dp_byte_f = 0;
dp_modem_command(0x10, 0, 0);
l94E:
if (dp_byte_f == 5)
goto l972;
i = x_elapsed_time(dp_cmd_timer);
if (i<64)
goto l94E;
if (dp_byte_f != 5)
goto l987;
l972:
dp_version = dp_byte_e << 8 | dp_byte_d;
goto l98E;
l987:
dp_version = 0;
l98E:
dp_byte_f = 0;
dp_modem_command(0x14, 0, 0);
l99D:
if (dp_byte_f == 3)
goto l9C1;
i = x_elapsed_time(dp_cmd_timer);
if (i < 0xc8)
goto l99D;
if (dp_byte_f != 3)
goto l9CA;
l9C1:
return dp_read_dsp_ram(0x49);
l9CA:
printf( "Returning zero, checksum failed?\n" );
return 0;
}
int
dp_change_mercury_gain(int a0, int a4, int a8, int aC)
{
int res;
//printf( "Change mercury gain: %x, %x, %x, %x =", a0, a4, a8, aC );
dp_regwrite(0x32, aC);
dp_modem_command_long(0x2f, 1, a0, a4, a8);
res = dp_read_dsp_ram(0x3a);
//printf( "%x\n", res );
return res;
}
void
dp_set_mercury_gain(void)
{
dp_change_mercury_gain(homol[0xF30-HBASE],
homol[0xF31-HBASE],
homol[0xF32-HBASE],
homol[0xF33-HBASE]);
}
int
readbio(int arg)
{
int var, res;
if ((arg & 0xf00) == 0xf00)
return 0;
if ((arg & 0xf00) == 0x100)
var = 0xbb;
else {
if ((arg & 0xf00) == 0x200)
var = 0xdc;
else
var = 0xb9;
}
res = dp_regread(var) & arg;
#ifdef LT_DEBUG
printf( "[readbio: %x]", res );
#endif
return res;
}
void
writebio(int val, int strange)
{
int ebx = val;
int addr;
//printf( "writebio(%x, %x)\n", val, strange);
#if 0
if ((val & 0xff) > 0x80)
return;
#endif
val = (val & 0xffffff00) | 0xb9;
if ((val & 0xf00) != 0x100)
goto l482;
val = (val & 0xffffff00) | 0xbb;
l441:
addr = val & 0xff;
if (strange == 1) {
if (!(val & 0x1000))
goto l457;
}
if ((strange != 0) || (!(val & 0x1000))) {
strange = dp_regread(addr) & ((~ebx) & 0xff);
dp_regwrite(addr, strange);
return;
}
l457:
strange = dp_regread(addr) | (ebx & 0xff);
dp_regwrite(addr, strange);
return;
l482:
if ((val & 0xf00) == 0x200) {
val = (val & 0xffffff00) | 0xdc;
goto l441;
}
if ((val & 0xf00) != 0x300)
goto l441;
writebiom(ebx, strange);
return;
}
void
writebiom(int val, int strange)
{
int al;
al = val & 0x0f;
if ((strange == 1) && (!(val & 0x1000)))
goto do_and;
if ((strange) || (!(val & 0x1000))) {
homol[0xF33-HBASE] &= ~al;
dp_set_mercury_gain();
return;
}
do_and:
homol[0xF33-HBASE] |= al;
dp_set_mercury_gain();
return;
}
//=================================================================
// Time functions.
unsigned int x_current_time(void)
{
// Returns the number of milliseconds since boot up.
// Machine code takes number of ticks (100nS apart)
// and multiplies them by 10000 to get the numer of milliseconds.
// open /proc/uptime for reading. Hard coded file name! ;)
FILE* fpUptime = fopen("/proc/uptime", "r");
if (fpUptime != NULL) {
// Read values from file.
double uptime, idletime;
fscanf (fpUptime, "%lf %lf", &uptime, &idletime);
// Close file.
fclose(fpUptime);
// Convert float value of seconds to milliseconds.
return (unsigned int) (uptime * 1000) + 3;
}
else {
// Failure.
fprintf(stderr, "ltmodem: could not open /proc/uptime for reading.\n");
return 0;
}
}
// Returns time elapsed from an absolute time to now
// in milliseconds.
int x_elapsed_time(unsigned int from)
{
dp_dsp_isr(); // Bodge for use with 'soft' IRQ!
// uses eax - ecx so result must be 32 bit.
return (x_current_time() - from);
}
// Sleeps for 'howlong' milliseconds.
void x_sleep(int howlong)
{
usleep(howlong * 1000);
}
void wait_for_core_read(void)
{
dp_cmd_timer = x_current_time();
// Wait for bit to be set, timing out after 100 milliseconds.
while ((dp_regread(0xD8) & 0x10) == 0)
{
if (x_elapsed_time(dp_cmd_timer) >= 0x64) break;
}
}
// This is complete!
void dp_init_local_phone_timer(void)
{
dp_local_phone_timer = x_current_time();
}
// Probably cellphone related, so not bothered about this.
void cell_init (void)
{
}
// Used by dp_init_variables.
void dp_init_blacklist(void){
dp_failures = 0;
dp_blacklist_calls = 0;
// Clears/sets up some locations around 59A94?
/* {
int ecx = 0;
int edx;
int* eax = unk_59A94; // Table start address + 0x14(?)
for (edx = 0x18; edx>0; edx--){
*(eax - 0x14) = 0; // byte
*eax = 0; // 32 bit dword
*(eax + 4) = 0; // byte
eax = eax + 0x20;
}
} */
}
// Complete!
void dp_init_local_phone_state(void){
dp_init_local_phone_timer();
byte_59EBA = 0;
}
void writecioc (unsigned int arg1, unsigned int arg2)
{
// Read reg D5h until bit 2 is set, or time has exceeded 500 milliseconds.
unsigned int startTime = x_current_time();
while ((dp_regread(0xd5) & 2) == 0)
{
if (x_elapsed_time(startTime) >= 0x1f4) break;
}
dp_regwrite(0x2b, arg1);
dp_regwrite(0x2a, arg2);
}
// Empty for now.
void set_boardid(void){}
void x_output_deinit(void){}
// Used to continously monitor port activity.
void continous_monitoring(int monitor_type, int monitoring_interval){
// Iteration loop variable.
unsigned int i;
// Main monitoring loop.
while (1) {
// Monitor registers or I/O depending on current setting.
if (monitor_type & 1) {
// Re-scan device.
pci_scan_bus(pacc);
modem_dev = scan_device(modem_dev->dev);
// Show the hex.
show_hex_dump(modem_dev);
}
if (monitor_type & 2) {
// Get access to all of I/O space.
if (iopl(3) < 0) {
perror("ltmodem: iopl()");
fprintf(stderr, "This program must be run as root.\n");
}
else {
// Read the ports.
printf("I/O ports\n ");
// Loop for each known port.
for (i=1;i<=io_cnt;i++) {
unsigned int j;
printf( "%x: ", io_address[i] );
for (j=0; j<io_length[i]; j++) {
// Read each byte, one at a time.
printf("%2x ", inb(io_address[i] + j));
if ( !((j+1)%16) )
printf( "\n%x: ", io_address[i] + j + 1);
}
putchar('\n');
}
// Free the ports.
iopl(0);
}
}
// Wait for the configured amount of time.
usleep(monitoring_interval * 1000);
}
}
void set_modem_io(void)
{
unsigned int i;
/* value input by user. */
unsigned int input = 0;
unsigned int offset = 0;
/* CR input after first char. */
char trash;
if (io_cnt > 0) {
printf("I/O ports found:\n");
for(i=1; i<=io_cnt; i++){
printf("%d - I/O port at %x.\n", i, io_address[i]);
}
// Select the port.
printf ("Port to write long word at (in hex): ");
scanf ("%x%c", &input, &trash);
// Write the value.
if ((input > 0) && (input <= io_cnt)) {
// Allow user to write to selected I/O port.
i = input;
printf ("Write to %x, enter value (in hex): ", io_address[i]);
scanf ("%x%c", &input, &trash);
// Get offset to use.
printf ("Offset to use (in hex): ");
scanf ("%x%c", &offset, &trash);
printf ("Writing %2x to I/O port %x + %x.\n",
input, io_address[i], offset);
// Write value to port.
outb_p (input, (io_address[i] + offset));
///* Delay 10ms. */
usleep(10000);
/* Read back the port. */
printf("Read back value: %2x.\n", inb_p(io_address[i] + offset));
}
}
}
void dp_run_rom (void)
{
// Dummy for now.
}
@1.3log@Added a Pavel diff for dp_modem_command.@text
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -