00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00262 #include "StdAfx.h"
00263 #include "AliM1543C.h"
00264 #include "System.h"
00265 #include "VGA.h"
00266
00267 #ifdef DEBUG_PIC
00268 bool pic_messages = false;
00269 #endif
00270
00271
00272 #define IPus 847
00273
00274 u32 ali_cfg_data[64] = {
00275 0x153310b9,
00276 0x0200000f,
00277 0x060100c3,
00278 0x00000000,
00279 0x00000000,
00280 0x00000000,
00281 0x00000000,
00282 0x00000000,
00283 0x00000000,
00284 0x00000000,
00285 0x00000000,
00286 0x00000000,
00287 0x00000000,
00288 0x00000000,
00289 0x00000000,
00290 0x00000000,
00291 0, 0, 0, 0, 0,
00292 0x00000200,
00293 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00294 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00295 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00296 };
00297
00298 u32 ali_cfg_mask[64] = {
00299 0x00000000,
00300 0x00000000,
00301 0x00000000,
00302 0x00000000,
00303 0x00000000,
00304 0x00000000,
00305 0x00000000,
00306 0x00000000,
00307 0x00000000,
00308 0x00000000,
00309 0x00000000,
00310 0x00000000,
00311 0x00000000,
00312 0x00000000,
00313 0x00000000,
00314 0x00000000,
00315 0xffcfff7f,
00316 0xff00cbdf,
00317 0xffffffff,
00318 0x000000ff,
00319 0xffff8fff,
00320 0xf0ffff00,
00321 0x030f0d7f,
00322 0, 0, 0, 0, 0, 0, 0, 0, 0,
00323 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00324 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00325 };
00326
00330 CAliM1543C::CAliM1543C(CConfigurator* cfg, CSystem* c, int pcibus, int pcidev) : CPCIDevice(cfg, c, pcibus, pcidev)
00331 {
00332 if(theAli != 0)
00333 FAILURE(Configuration, "More than one Ali");
00334 theAli = this;
00335 }
00336
00340 void CAliM1543C::init()
00341 {
00342 add_function(0, ali_cfg_data, ali_cfg_mask);
00343
00344 int i;
00345 char* filename;
00346
00347 add_legacy_io(1, 0x61, 1);
00348
00349 state.reg_61 = 0;
00350
00351 add_legacy_io(2, 0x70, 4);
00352 cSystem->RegisterMemory(this, 2, U64(0x00000801fc000070), 4);
00353 for(i = 0; i < 4; i++)
00354 state.toy_access_ports[i] = 0;
00355 for(i = 0; i < 256; i++)
00356 state.toy_stored_data[i] = 0;
00357
00358 state.toy_stored_data[0x17] = myCfg->get_bool_value("vga_console") ? 1 : 0;
00359
00360 if(state.toy_stored_data[0x17] && !theVGA)
00361 {
00362 printf("! CONFIGURATION WARNING ! vga_console set to true, but no VGA card installed.\n");
00363 state.toy_stored_data[0x17] = 0;
00364 }
00365
00366 ResetPCI();
00367
00368
00369 add_legacy_io(6, 0x40, 4);
00370 for(i = 0; i < 3; i++)
00371 state.pit_status[i] = 0x40;
00372 for(i = 0; i < 9; i++)
00373 state.pit_counter[i] = 0;
00374
00375 add_legacy_io(7, 0x20, 2);
00376 add_legacy_io(8, 0xa0, 2);
00377 add_legacy_io(30, 0x4d0, 2);
00378
00379
00380 cSystem->RegisterMemory(this, 20, U64(0x00000801f8000000), 1);
00381
00382 for(i = 0; i < 2; i++)
00383 {
00384 state.pic_mode[i] = 0;
00385 state.pic_intvec[i] = 0;
00386 state.pic_mask[i] = 0;
00387 state.pic_asserted[i] = 0;
00388 }
00389
00390
00391 add_legacy_io(27, 0x3bc, 4);
00392 filename = myCfg->get_text_value("lpt.outfile");
00393 if(filename)
00394 {
00395 lpt = fopen(filename, "ab");
00396 }
00397 else
00398 {
00399 lpt = NULL;
00400 }
00401
00402 lpt_reset();
00403
00404 myRegLock = new CMutex("ali-reg");
00405
00406 myThread = 0;
00407
00408 printf("%s: $Id: AliM1543C.cpp,v 1.65 2008/03/14 15:30:50 iamcamiel Exp $\n",
00409 devid_string);
00410 }
00411
00412 void CAliM1543C::start_threads()
00413 {
00414 if(!myThread)
00415 {
00416 myThread = new Poco::Thread("ali");
00417 printf(" %s", myThread->getName().c_str());
00418 StopThread = false;
00419 myThread->start(*this);
00420 }
00421 }
00422
00423 void CAliM1543C::stop_threads()
00424 {
00425 StopThread = true;
00426 if(myThread)
00427 {
00428 printf(" %s", myThread->getName().c_str());
00429 myThread->join();
00430 delete myThread;
00431 myThread = 0;
00432 }
00433 }
00434
00438 CAliM1543C::~CAliM1543C()
00439 {
00440 stop_threads();
00441
00442 if(lpt)
00443 fclose(lpt);
00444 }
00445
00460 u32 CAliM1543C::ReadMem_Legacy(int index, u32 address, int dsize)
00461 {
00462 if(dsize != 8 && index != 20)
00463 {
00464 FAILURE_4(InvalidArgument,
00465 "%s: DSize %d reading from legacy memory range # %d at address %02x\n",
00466 devid_string, dsize, index, address);
00467 }
00468
00469 int channel = 0;
00470 switch(index)
00471 {
00472 case 1: return reg_61_read();
00473 case 2: return toy_read(address);
00474 case 6: return pit_read(address);
00475 case 8: channel = 1;
00476 case 7: return pic_read(channel, address);
00477 case 20: return pic_read_vector();
00478 case 30: return pic_read_edge_level(address);
00479 case 27: return lpt_read(address);
00480 }
00481
00482 return 0;
00483 }
00484
00503 void CAliM1543C::WriteMem_Legacy(int index, u32 address, int dsize, u32 data)
00504 {
00505 if(dsize != 8)
00506 {
00507 FAILURE_4(InvalidArgument,
00508 "%s: DSize %d writing to legacy memory range # %d at address %02x\n",
00509 devid_string, dsize, index, address);
00510 }
00511
00512 int channel = 0;
00513 switch(index)
00514 {
00515 case 1: reg_61_write((u8) data); return;
00516 case 2: toy_write(address, (u8) data); return;
00517 case 6: pit_write(address, (u8) data); return;
00518 case 8: channel = 1;
00519 case 7: pic_write(channel, address, (u8) data); return;
00520 case 30: pic_write_edge_level(address, (u8) data); return;
00521 case 27: lpt_write(address, (u8) data); return;
00522 }
00523 }
00524
00539 u8 CAliM1543C::reg_61_read()
00540 {
00541 #if 0
00542 static long read_count = 0;
00543 if(!(state.reg_61 & 0x20))
00544 {
00545 if(read_count % 1500 == 0)
00546 state.reg_61 |= 0x20;
00547 }
00548 else
00549 {
00550 state.reg_61 &= ~0x20;
00551 }
00552
00553 read_count++;
00554 #else
00555 state.reg_61 &= ~0x20;
00556 state.reg_61 |= (state.pit_status[2] & 0x80) >> 2;
00557 #endif
00558 return state.reg_61;
00559 }
00560
00564 void CAliM1543C::reg_61_write(u8 data)
00565 {
00566 state.reg_61 = (state.reg_61 & 0xf0) | (((u8) data) & 0x0f);
00567 }
00568
00572 u8 CAliM1543C::toy_read(u32 address)
00573 {
00574
00575
00576 return(u8) state.toy_access_ports[address];
00577 }
00578
00582 void CAliM1543C::toy_write(u32 address, u8 data)
00583 {
00584 time_t ltime;
00585 struct tm stime;
00586 static long read_count = 0;
00587 static long hold_count = 0;
00588
00589
00590 state.toy_access_ports[address] = (u8) data;
00591
00592 switch(address)
00593 {
00594 case 0:
00595 if((data & 0x7f) < 14)
00596 {
00597 state.toy_stored_data[0x0d] = 0x80;
00598
00599
00600 time(<ime);
00601 gmtime_s(&stime, <ime);
00602 if(state.toy_stored_data[0x0b] & 4)
00603 {
00604
00605
00606 state.toy_stored_data[0] = (u8) (stime.tm_sec);
00607 state.toy_stored_data[2] = (u8) (stime.tm_min);
00608 if(state.toy_stored_data[0x0b] & 2)
00609 state.toy_stored_data[4] = (u8) (stime.tm_hour);
00610 else
00611
00612 state.toy_stored_data[4] = (u8) (((stime.tm_hour / 12) ? 0x80 : 0) | (stime.tm_hour % 12));
00613 state.toy_stored_data[6] = (u8) (stime.tm_wday + 1);
00614 state.toy_stored_data[7] = (u8) (stime.tm_mday);
00615 state.toy_stored_data[8] = (u8) (stime.tm_mon + 1);
00616 state.toy_stored_data[9] = (u8) (stime.tm_year % 100);
00617 }
00618 else
00619 {
00620
00621
00622 state.toy_stored_data[0] = (u8) (((stime.tm_sec / 10) << 4) | (stime.tm_sec % 10));
00623 state.toy_stored_data[2] = (u8) (((stime.tm_min / 10) << 4) | (stime.tm_min % 10));
00624 if(state.toy_stored_data[0x0b] & 2)
00625 state.toy_stored_data[4] = (u8) (((stime.tm_hour / 10) << 4) | (stime.tm_hour % 10));
00626 else
00627 {
00628 state.toy_stored_data[4] = (u8)
00629 (
00630 ((stime.tm_hour / 12) ? 0x80 : 0) |
00631 (((stime.tm_hour % 12) / 10) << 4) | ((stime.tm_hour % 12) % 10)
00632 );
00633 }
00634
00635 state.toy_stored_data[6] = (u8) (stime.tm_wday + 1);
00636 state.toy_stored_data[7] = (u8) (((stime.tm_mday / 10) << 4) | (stime.tm_mday % 10));
00637 state.toy_stored_data[8] = (u8) ((((stime.tm_mon + 1) / 10) << 4) | ((stime.tm_mon + 1) % 10));
00638 state.toy_stored_data[9] = (u8) ((((stime.tm_year % 100) / 10) << 4) | ((stime.tm_year % 100) % 10));
00639 }
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668 if(state.toy_stored_data[0x0a] & 0x80)
00669 {
00670
00671
00672 hold_count--;
00673 if(hold_count == 0)
00674 {
00675 state.toy_stored_data[0x0a] &= ~0x80;
00676 read_count = 0;
00677 }
00678 }
00679 else
00680 {
00681
00682
00683
00684
00685
00686 read_count++;
00687 if(read_count > 1000000 / (IPus * 3))
00688 {
00689 state.toy_stored_data[0x0a] |= 0x80;
00690 hold_count = (2228 / (IPus * 3)) + 1;
00691 }
00692 }
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715 }
00716
00717 state.toy_access_ports[1] = state.toy_stored_data[data & 0x7f];
00718
00719
00720 if(data == 0x0c)
00721 state.toy_stored_data[data & 0x7f] = 0;
00722 break;
00723
00724 case 1:
00725 if(state.toy_access_ports[0] == 0x0b && data & 0x040)
00726 state.toy_stored_data[0x0c] = 0xf0;
00727 state.toy_stored_data[state.toy_access_ports[0] & 0x7f] = (u8) data;
00728 break;
00729
00730 case 2:
00731 state.toy_access_ports[3] = state.toy_stored_data[0x80 + (data & 0x7f)];
00732 break;
00733
00734 case 3:
00735 state.toy_stored_data[0x80 + (state.toy_access_ports[2] & 0x7f)] = (u8) data;
00736 break;
00737 }
00738 }
00739
00768 u8 CAliM1543C::pit_read(u32 address)
00769 {
00770
00771
00772 u8 data;
00773 data = 0;
00774 return data;
00775 }
00776
00780 void CAliM1543C::pit_write(u32 address, u8 data)
00781 {
00782
00783
00784 if(address == 3)
00785 {
00786 if(data != 0)
00787 {
00788 state.pit_status[address] = data;
00789 if((data & 0xc0) >> 6 != 3)
00790 {
00791 state.pit_status[(data & 0xc0) >> 6] = data & 0x3f;
00792 state.pit_mode[(data & 0xc0) >> 6] = (data & 0x30) >> 4;
00793 }
00794 else
00795 {
00796 state.pit_status[address] = 0xc0;
00797 }
00798 }
00799 }
00800 else
00801 {
00802 switch(state.pit_mode[address])
00803 {
00804 case 0:
00805 break;
00806
00807 case 1:
00808 case 3:
00809 state.pit_counter[address] = (state.pit_counter[address] & 0xff) |
00810 data <<
00811 8;
00812 state.pit_counter[address + PIT_OFFSET_MAX] = state.pit_counter[address];
00813 if(state.pit_mode[address] == 3)
00814 {
00815 state.pit_mode[address] = 2;
00816 }
00817 else
00818 state.pit_status[address] &= ~0xc0;
00819 break;
00820
00821 case 2:
00822 state.pit_counter[address] = (state.pit_counter[address] & 0xff00) | data;
00823
00824
00825 if((state.pit_status[address] & 0x30) >> 4 == 3
00826 && state.pit_counter[address] == 0)
00827 {
00828 state.pit_counter[address] = 65536;
00829 }
00830
00831 state.pit_counter[address + PIT_OFFSET_MAX] = state.pit_counter[address];
00832 state.pit_status[address] &= ~0xc0;
00833 break;
00834 }
00835 }
00836 }
00837
00838 #define PIT_FACTOR 5000
00839 #define PIT_DEC(p) p = (p < PIT_FACTOR ? 0 : p - PIT_FACTOR);
00840
00849 void CAliM1543C::pit_clock()
00850 {
00851 int i;
00852 for(i = 0; i < 3; i++)
00853 {
00854
00855
00856 if(state.pit_status[i] & 0x40)
00857 continue;
00858 PIT_DEC(state.pit_counter[i]);
00859 switch((state.pit_status[i] & 0x0e) >> 1)
00860 {
00861 case 0:
00862 if(!state.pit_counter[i])
00863 {
00864 state.pit_status[i] |= 0xc0;
00865 }
00866 break;
00867
00868 case 3:
00869 if(!state.pit_counter[i])
00870 {
00871 if(state.pit_status[i] & 0x80)
00872 {
00873 state.pit_status[i] &= ~0x80;
00874 }
00875 else
00876 {
00877 state.pit_status[i] |= 0x80;
00878 if(i == 0)
00879 {
00880 pic_interrupt(0, 0);
00881
00882 }
00883 }
00884
00885 state.pit_counter[i] = state.pit_counter[i + PIT_OFFSET_MAX];
00886 }
00887
00888
00889 PIT_DEC(state.pit_counter[i]);
00890 break;
00891
00892 default:
00893 break;
00894 }
00895 }
00896 }
00897
00901 void CAliM1543C::run()
00902 {
00903 try
00904 {
00905 for(;;)
00906 {
00907 Poco::Thread::sleep(1);
00908 if(StopThread)
00909 return;
00910 do_pit_clock();
00911 }
00912 }
00913
00914 catch(Poco::Exception & e)
00915 {
00916 printf("Exception in Ali thread: %s.\n", e.displayText().c_str());
00917
00918
00919 }
00920 }
00921
00922 #define PIT_RATIO 1
00923
00932 void CAliM1543C::do_pit_clock()
00933 {
00934 static int pit_counter = 0;
00935 if(pit_counter++ >= PIT_RATIO)
00936 {
00937 pit_counter = 0;
00938 pit_clock();
00939 }
00940 }
00941
00942 #define PIC_STD 0
00943 #define PIC_INIT_0 1
00944 #define PIC_INIT_1 2
00945 #define PIC_INIT_2 3
00946
00950 u8 CAliM1543C::pic_read(int index, u32 address)
00951 {
00952 u8 data;
00953
00954 data = 0;
00955
00956 if(address == 1)
00957 data = state.pic_mask[index];
00958
00959 #ifdef DEBUG_PIC
00960 if(pic_messages)
00961 printf("%%PIC-I-READ: read %02x from port %"LL "d on PIC %d\n", data,
00962 address, index);
00963 #endif
00964 return data;
00965 }
00966
00970 u8 CAliM1543C::pic_read_edge_level(int index)
00971 {
00972 return state.pic_edge_level[index];
00973 }
00974
00978 u8 CAliM1543C::pic_read_vector()
00979 {
00980 if(state.pic_asserted[0] & 1)
00981 return state.pic_intvec[0];
00982 if(state.pic_asserted[0] & 2)
00983 return state.pic_intvec[0] + 1;
00984 if(state.pic_asserted[0] & 4)
00985 {
00986 if(state.pic_asserted[1] & 1)
00987 return state.pic_intvec[1];
00988 if(state.pic_asserted[1] & 2)
00989 return state.pic_intvec[1] + 1;
00990 if(state.pic_asserted[1] & 4)
00991 return state.pic_intvec[1] + 2;
00992 if(state.pic_asserted[1] & 8)
00993 return state.pic_intvec[1] + 3;
00994 if(state.pic_asserted[1] & 16)
00995 return state.pic_intvec[1] + 4;
00996 if(state.pic_asserted[1] & 32)
00997 return state.pic_intvec[1] + 5;
00998 if(state.pic_asserted[1] & 64)
00999 return state.pic_intvec[1] + 6;
01000 if(state.pic_asserted[1] & 128)
01001 return state.pic_intvec[1] + 7;
01002 }
01003
01004 if(state.pic_asserted[0] & 8)
01005 return state.pic_intvec[0] + 3;
01006 if(state.pic_asserted[0] & 16)
01007 return state.pic_intvec[0] + 4;
01008 if(state.pic_asserted[0] & 32)
01009 return state.pic_intvec[0] + 5;
01010 if(state.pic_asserted[0] & 64)
01011 return state.pic_intvec[0] + 6;
01012 if(state.pic_asserted[0] & 128)
01013 return state.pic_intvec[0] + 7;
01014 return 0;
01015 }
01016
01020 void CAliM1543C::pic_write(int index, u32 address, u8 data)
01021 {
01022 int level;
01023 int op;
01024 #ifdef DEBUG_PIC
01025 if(pic_messages)
01026 printf("%%PIC-I-WRITE: write %02x to port %"LL "d on PIC %d\n", data,
01027 address, index);
01028 #endif
01029 switch(address)
01030 {
01031 case 0:
01032 if(data & 0x10)
01033 state.pic_mode[index] = PIC_INIT_0;
01034 else
01035 state.pic_mode[index] = PIC_STD;
01036 if(data & 0x08)
01037 {
01038
01039
01040 }
01041 else
01042 {
01043
01044
01045 op = (data >> 5) & 7;
01046 level = data & 7;
01047 switch(op)
01048 {
01049 case 1:
01050
01051
01052 state.pic_asserted[index] = 0;
01053
01054
01055 if(index == 1)
01056 state.pic_asserted[0] &= ~(1 << 2);
01057
01058
01059 if(!state.pic_asserted[0])
01060 cSystem->interrupt(55, false);
01061 #ifdef DEBUG_PIC
01062 pic_messages = false;
01063 #endif
01064 break;
01065
01066 case 3:
01067
01068
01069 state.pic_asserted[index] &= ~(1 << level);
01070
01071
01072 if((index == 1) && (!state.pic_asserted[1]))
01073 state.pic_asserted[0] &= ~(1 << 2);
01074
01075
01076 if(!state.pic_asserted[0])
01077 cSystem->interrupt(55, false);
01078 #ifdef DEBUG_PIC
01079 pic_messages = false;
01080 #endif
01081 break;
01082 }
01083 }
01084
01085 return;
01086
01087 case 1:
01088 switch(state.pic_mode[index])
01089 {
01090 case PIC_INIT_0:
01091 state.pic_intvec[index] = (u8) data & 0xf8;
01092 state.pic_mode[index] = PIC_INIT_1;
01093 return;
01094
01095 case PIC_INIT_1:
01096 state.pic_mode[index] = PIC_INIT_2;
01097 return;
01098
01099 case PIC_INIT_2:
01100 state.pic_mode[index] = PIC_STD;
01101 return;
01102
01103 case PIC_STD:
01104 state.pic_mask[index] = data;
01105 state.pic_asserted[index] &= ~data;
01106 return;
01107 }
01108 }
01109 }
01110
01114 void CAliM1543C::pic_write_edge_level(int index, u8 data)
01115 {
01116 state.pic_edge_level[index] = data;
01117 }
01118
01119 #define DEBUG_EXPR (index != 0 || (intno != 0 && intno > 4))
01120
01124 void CAliM1543C::pic_interrupt(int index, int intno)
01125 {
01126 #ifdef DEBUG_PIC
01127 if(DEBUG_EXPR)
01128 {
01129 printf("%%PIC-I-INCOMING: Interrupt %d incomming on PIC %d", intno, index);
01130 pic_messages = true;
01131 }
01132 #endif
01133
01134
01135 if(state.pic_mask[index] & (1 << intno))
01136 {
01137 #ifdef DEBUG_PIC
01138 if(DEBUG_EXPR)
01139 printf(" (masked)\n");
01140 pic_messages = false;
01141 #endif
01142 return;
01143 }
01144
01145 if(state.pic_asserted[index] & (1 << intno))
01146 {
01147 #ifdef DEBUG_PIC
01148 if(DEBUG_EXPR)
01149 printf(" (already asserted)\n");
01150 #endif
01151 return;
01152 }
01153
01154 #ifdef DEBUG_PIC
01155 if(DEBUG_EXPR)
01156 printf("\n");
01157 #endif
01158 state.pic_asserted[index] |= (1 << intno);
01159
01160 if(index == 1)
01161 pic_interrupt(0, 2);
01162 if(index == 0)
01163 cSystem->interrupt(55, true);
01164 }
01165
01169 void CAliM1543C::pic_deassert(int index, int intno)
01170 {
01171 if(!(state.pic_asserted[index] & (1 << intno)))
01172 return;
01173
01174
01175 state.pic_asserted[index] &= !(1 << intno);
01176 if(index == 1 && state.pic_asserted[1] == 0)
01177 pic_deassert(0, 2);
01178 if(index == 0 && state.pic_asserted[0] == 0)
01179 cSystem->interrupt(55, false);
01180 }
01181
01182 static u32 ali_magic1 = 0xA111543C;
01183 static u32 ali_magic2 = 0xC345111A;
01184
01188 int CAliM1543C::SaveState(FILE* f)
01189 {
01190 long ss = sizeof(state);
01191 int res;
01192
01193 if(res = CPCIDevice::SaveState(f))
01194 return res;
01195
01196 fwrite(&ali_magic1, sizeof(u32), 1, f);
01197 fwrite(&ss, sizeof(long), 1, f);
01198 fwrite(&state, sizeof(state), 1, f);
01199 fwrite(&ali_magic2, sizeof(u32), 1, f);
01200 printf("%s: %d bytes saved.\n", devid_string, (int) ss);
01201 return 0;
01202 }
01203
01207 int CAliM1543C::RestoreState(FILE* f)
01208 {
01209 long ss;
01210 u32 m1;
01211 u32 m2;
01212 int res;
01213 size_t r;
01214
01215 if(res = CPCIDevice::RestoreState(f))
01216 return res;
01217
01218 r = fread(&m1, sizeof(u32), 1, f);
01219 if(r != 1)
01220 {
01221 printf("%s: unexpected end of file!\n", devid_string);
01222 return -1;
01223 }
01224
01225 if(m1 != ali_magic1)
01226 {
01227 printf("%s: MAGIC 1 does not match!\n", devid_string);
01228 return -1;
01229 }
01230
01231 fread(&ss, sizeof(long), 1, f);
01232 if(r != 1)
01233 {
01234 printf("%s: unexpected end of file!\n", devid_string);
01235 return -1;
01236 }
01237
01238 if(ss != sizeof(state))
01239 {
01240 printf("%s: STRUCT SIZE does not match!\n", devid_string);
01241 return -1;
01242 }
01243
01244 fread(&state, sizeof(state), 1, f);
01245 if(r != 1)
01246 {
01247 printf("%s: unexpected end of file!\n", devid_string);
01248 return -1;
01249 }
01250
01251 r = fread(&m2, sizeof(u32), 1, f);
01252 if(r != 1)
01253 {
01254 printf("%s: unexpected end of file!\n", devid_string);
01255 return -1;
01256 }
01257
01258 if(m2 != ali_magic2)
01259 {
01260 printf("%s: MAGIC 1 does not match!\n", devid_string);
01261 return -1;
01262 }
01263
01264 printf("%s: %d bytes restored.\n", devid_string, (int) ss);
01265 return 0;
01266 }
01267
01299 void CAliM1543C::lpt_reset()
01300 {
01301 state.lpt_data = ~0;
01302 state.lpt_status = 0xd8;
01303 state.lpt_control = 0x0c;
01304 state.lpt_init = false;
01305 }
01306
01310 u8 CAliM1543C::lpt_read(u32 address)
01311 {
01312 u8 data = 0;
01313 switch(address)
01314 {
01315 case 0:
01316 data = state.lpt_data;
01317 break;
01318
01319 case 1:
01320 data = state.lpt_status;
01321 if((state.lpt_status & 0x80) == 0 && (state.lpt_control & 0x01) == 0)
01322 {
01323 if(state.lpt_status & 0x40)
01324 {
01325 state.lpt_status &= ~0x40;
01326 }
01327 else
01328 {
01329 state.lpt_status |= 0x40;
01330 state.lpt_status |= 0x80;
01331 }
01332 }
01333 break;
01334
01335 case 2:
01336 data = state.lpt_control;
01337 }
01338
01339 #ifdef DEBUG_LPT
01340 printf("%%LPT-I-READ: port %d = %x\n", address, data);
01341 #endif
01342 return data;
01343 }
01344
01348 void CAliM1543C::lpt_write(u32 address, u8 data)
01349 {
01350 #ifdef DEBUG_LPT
01351 printf("%%LPT-I-WRITE: port %d = %x\n", address, data);
01352 #endif
01353 switch(address)
01354 {
01355 case 0:
01356 state.lpt_data = data;
01357 break;
01358
01359 case 1:
01360 break;
01361
01362 case 2:
01363 if((data & 0x04) == 0)
01364 {
01365 state.lpt_init = true;
01366 state.lpt_status = 0xd8;
01367 }
01368 else
01369 {
01370 if(data & 0x08)
01371 {
01372 if(data & 0x01)
01373 {
01374 state.lpt_status &= ~0x80;
01375
01376
01377 if(lpt && state.lpt_init)
01378 fputc(state.lpt_data, lpt);
01379 if(state.lpt_control & 0x10)
01380 {
01381 pic_interrupt(0, 7);
01382 }
01383 }
01384 else
01385 {
01386
01387
01388 }
01389 }
01390 }
01391
01392 state.lpt_control = data;
01393 }
01394 }
01395
01399 void CAliM1543C::check_state()
01400 {
01401 if(myThread && !myThread->isRunning())
01402 FAILURE(Thread, "ALi thread has died");
01403 }
01404
01405 CAliM1543C* theAli = 0;