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
00132 #if defined(DEBUG_SYM)
00133 #define DEBUG_SYM_REGS
00134 #define DEBUG_SYM_SCRIPTS
00135 #endif
00136 #include "StdAfx.h"
00137 #include "Sym53C895.h"
00138 #include "System.h"
00139 #include "Disk.h"
00140 #include "SCSIBus.h"
00141
00143 #define R_SCNTL0 0x00
00144 #define R_SCNTL0_ARB1 0x80
00145 #define R_SCNTL0_ARB0 0x40
00146 #define R_SCNTL0_START 0x20
00147 #define R_SCNTL0_WATN 0x10
00148 #define R_SCNTL0_EPC 0x08
00149 #define R_SCNTL0_AAP 0x02
00150 #define R_SCNTL0_TRG 0x01
00151 #define SCNTL0_MASK 0xFB
00152
00154 #define R_SCNTL1 0x01
00155 #define R_SCNTL1_CON 0x10
00156 #define R_SCNTL1_RST 0x08
00157 #define R_SCNTL1_IARB 0x02
00158
00160 #define R_SCNTL2 0x02
00161 #define R_SCNTL2_SDU 0x80
00162 #define R_SCNTL2_CHM 0x40
00163 #define R_SCNTL2_SLPMD 0x20
00164 #define R_SCNTL2_SLPHBEN 0x10
00165 #define R_SCNTL2_WSS 0x08
00166 #define R_SCNTL2_VUE0 0x04
00167 #define R_SCNTL2_VUE1 0x02
00168 #define R_SCNTL2_WSR 0x01
00169 #define SCNTL2_MASK 0xF2
00170 #define SCNTL2_W1C 0x09
00171
00173 #define R_SCNTL3 0x03
00174 #define R_SCNTL3_EWS 0x08
00175
00177 #define R_SCID 0x04
00178 #define R_SCID_ID 0x0F
00179 #define SCID_MASK 0x6F
00180
00182 #define R_SXFER 0x05
00183
00185 #define R_SDID 0x06
00186 #define R_SDID_ID 0x0F
00187 #define SDID_MASK 0x0F
00188
00190 #define R_GPREG 0x07
00191 #define GPREG_MASK 0x1F
00192
00194 #define R_SFBR 0x08
00195
00197 #define R_SOCL 0x09
00198 #define R_SOCL_ACK 0x40
00199 #define R_SOCL_ATN 0x20
00200
00202 #define R_SSID 0x0A
00203 #define R_SSID_VAL 0x80
00204 #define R_SSID_ID 0x0F
00205
00207 #define R_SBCL 0x0B
00208 #define R_SBCL_REQ 0x80
00209 #define R_SBCL_ACK 0x40
00210 #define R_SBCL_BSY 0x20
00211 #define R_SBCL_SEL 0x10
00212 #define R_SBCL_ATN 0x08
00213 #define R_SBCL_MSG 0x04
00214 #define R_SBCL_CD 0x02
00215 #define R_SBCL_IO 0x01
00216 #define R_SBCL_PHASE 0x07
00217
00219 #define R_DSTAT 0x0C
00220 #define R_DSTAT_DFE 0x80
00221 #define R_DSTAT_MDPE 0x40
00222 #define R_DSTAT_BF 0x20
00223 #define R_DSTAT_ABRT 0x10
00224 #define R_DSTAT_SSI 0x08
00225 #define R_DSTAT_SIR 0x04
00226 #define R_DSTAT_IID 0x01
00227 #define DSTAT_RC 0x7D
00228 #define DSTAT_FATAL 0x7D
00229
00231 #define R_SSTAT0 0x0D
00232 #define R_SSTAT0_RST 0x02
00233 #define R_SSTAT0_SDP0 0x01
00234
00236 #define R_SSTAT1 0x0E
00237 #define R_SSTAT1_SDP1 0x01
00238
00240 #define R_SSTAT2 0x0F
00241 #define R_SSTAT2_LDSC 0x02
00242
00244 #define R_DSA 0x10
00245
00247 #define R_ISTAT 0x14
00248 #define R_ISTAT_ABRT 0x80
00249 #define R_ISTAT_SRST 0x40
00250 #define R_ISTAT_SIGP 0x20
00251 #define R_ISTAT_SEM 0x10
00252 #define R_ISTAT_CON 0x08
00253 #define R_ISTAT_INTF 0x04
00254 #define R_ISTAT_SIP 0x02
00255 #define R_ISTAT_DIP 0x01
00256 #define ISTAT_MASK 0xF0
00257 #define ISTAT_W1C 0x04
00258
00260 #define R_CTEST0 0x18
00261
00263 #define R_CTEST1 0x19
00264 #define R_CTEST1_FMT 0xF0
00265 #define R_CTEST1_FFL 0x0F
00266
00268 #define R_CTEST2 0x1A
00269 #define R_CTEST2_DDIR 0x80
00270 #define R_CTEST2_SIGP 0x40
00271 #define R_CTEST2_CIO 0x20
00272 #define R_CTEST2_CM 0x10
00273 #define R_CTEST2_SRTCH 0x08
00274 #define R_CTEST2_TEOP 0x04
00275 #define R_CTEST2_DREQ 0x02
00276 #define R_CTEST2_DACK 0x01
00277 #define CTEST2_MASK 0x08
00278
00280 #define R_CTEST3 0x1B
00281 #define R_CTEST3_REV 0xf0
00282 #define R_CTEST3_FLF 0x08
00283 #define R_CTEST3_CLF 0x04
00284 #define R_CTEST3_FM 0x02
00285 #define CTEST3_MASK 0x0B
00286
00288 #define R_TEMP 0x1C
00289
00291 #define R_DFIFO 0x20
00292
00294 #define R_CTEST4 0x21
00295
00297 #define R_CTEST5 0x22
00298 #define R_CTEST5_ADCK 0x80
00299 #define R_CTEST5_BBCK 0x40
00300 #define CTEST5_MASK 0x3F
00301
00303 #define R_CTEST6 0x23
00304
00306 #define R_DBC 0x24
00307
00309 #define R_DCMD 0x27
00310
00312 #define R_DNAD 0x28
00313
00315 #define R_DSP 0x2C
00316
00318 #define R_DSPS 0x30
00319
00321 #define R_SCRATCHA 0x34
00322
00324 #define R_DMODE 0x38
00325 #define R_DMODE_MAN 0x01
00326
00328 #define R_DIEN 0x39
00329 #define DIEN_MASK 0x7D
00330
00332 #define R_SBR 0x3A
00333
00335 #define R_DCNTL 0x3B
00336 #define R_DCNTL_SSM 0x10
00337 #define R_DCNTL_STD 0x04
00338 #define R_DCNTL_IRQD 0x02
00339 #define R_DCNTL_COM 0x01
00340 #define DCNTL_MASK 0xFB
00341
00343 #define R_ADDER 0x3C
00344
00346 #define R_SIEN0 0x40
00347 #define SIEN0_MASK 0xFF
00348
00350 #define R_SIEN1 0x41
00351 #define SIEN1_MASK 0x17
00352
00354 #define R_SIST0 0x42
00355 #define R_SIST0_MA 0x80
00356 #define R_SIST0_CMP 0x40
00357 #define R_SIST0_SEL 0x20
00358 #define R_SIST0_RSL 0x10
00359 #define R_SIST0_SGE 0x08
00360 #define R_SIST0_UDC 0x04
00361 #define R_SIST0_RST 0x02
00362 #define R_SIST0_PAR 0x01
00363 #define SIST0_RC 0xFF
00364 #define SIST0_FATAL 0x8F
00365
00367 #define R_SIST1 0x43
00368 #define R_SIST1_SBMC 0x10
00369 #define R_SIST1_STO 0x04
00370 #define R_SIST1_GEN 0x02
00371 #define R_SIST1_HTH 0x01
00372 #define SIST1_RC 0x17
00373 #define SIST1_FATAL 0x14
00374
00376 #define R_SLPAR 0x44
00377
00379 #define R_SWIDE 0x45
00380
00382 #define R_MACNTL 0x46
00383 #define MACNTL_MASK 0x0F
00384
00386 #define R_GPCNTL 0x47
00387
00389 #define R_STIME0 0x48
00390
00392 #define R_STIME1 0x49
00393 #define R_STIME1_GEN 0x0F
00394 #define STIME1_MASK 0x7F
00395
00397 #define R_RESPID 0x4A
00398
00400 #define R_STEST0 0x4C
00401
00403 #define R_STEST1 0x4D
00404 #define STEST1_MASK 0xCC
00405
00407 #define R_STEST2 0x4E
00408 #define R_STEST2_SCE 0x80
00409 #define R_STEST2_ROF 0x40
00410 #define R_STEST2_DIF 0x20
00411 #define R_STEST2_SLB 0x10
00412 #define R_STEST2_SZM 0x08
00413 #define R_STEST2_AWS 0x04
00414 #define R_STEST2_EXT 0x02
00415 #define R_STEST2_LOW 0x01
00416 #define STEST2_MASK 0xBF
00417
00419 #define R_STEST3 0x4F
00420 #define R_STEST3_TE 0x80
00421 #define R_STEST3_STR 0x40
00422 #define R_STEST3_HSC 0x20
00423 #define R_STEST3_DSI 0x10
00424 #define R_STEST3_S16 0x08
00425 #define R_STEST3_TTM 0x04
00426 #define R_STEST3_CSF 0x02
00427 #define R_STEST3_STW 0x01
00428 #define STEST3_MASK 0xFF
00429
00431 #define R_SIDL 0x50
00432
00434 #define R_STEST4 0x52
00435
00437 #define R_SODL 0x54
00438
00440 #define R_SBDL 0x58
00441
00443 #define R_SCRATCHB 0x5C
00444
00446 #define R_SCRATCHC 0x60
00447
00449 #define R8(a) state.regs.reg8[R_##a]
00450
00452 #define R16(a) state.regs.reg16[R_##a / 2]
00453
00455 #define R32(a) state.regs.reg32[R_##a / 4]
00456
00463 #define TB_R8(a, b) ((R8(a) & R_##a##_##b) == R_##a##_##b)
00464
00472 #define SB_R8(a, b, c) R8(a) = (R8(a) &~R_##a##_##b) | (c ? R_##a##_##b : 0)
00473
00482 #define WRM_R8(a, b) R8(a) = (R8(a) &~a##_MASK) | ((b) & a##_MASK)
00483
00494 #define WRMW1C_R8(a, b) \
00495 R8(a) = (R8(a) &~a##_MASK &~a##_W1C) | \
00496 ((b) & a##_MASK) | \
00497 (R8(a) &~(b) & a##_W1C)
00498
00505 #define RAISE(a, b) set_interrupt(R_##a, R_##a##_##b)
00506
00514 #define RDCLR_R8(a) R8(a) &= ~a##_RC
00515
00519 #define GET_DEST() (R8(SDID) & R_SCID_ID)
00520
00524 #define SET_DEST(a) R8(SDID) = (a) & R_SCID_ID
00525
00529 #define GET_DBC() (R32(DBC) & 0x00ffffff)
00530
00534 #define SET_DBC(a) \
00535 R32(DBC) = (R32(DBC) & 0xff000000) | \
00536 ((a) & 0x00ffffff)
00537
00541 u32 sym_cfg_data[64] =
00542 {
00543 0x000c1000,
00544 0x02000001,
00545 0x01000000,
00546 0x00000000,
00547 0x00000001,
00548 0x00000000,
00549 0x00000000,
00550 0x00000000,
00551 0x00000000,
00552 0x00000000,
00553 0x00000000,
00554 0x00000000,
00555 0x00000000,
00556 0x00000000,
00557 0x00000000,
00558 0x401101ff,
00559 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00560 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00561 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00562 };
00563
00567 u32 sym_cfg_mask[64] = {
00568 0x00000000,
00569 0x00000157,
00570 0x00000000,
00571 0x0000ffff,
00572 0xffffff00,
00573 0xffffff00,
00574 0xfffff000,
00575 0x00000000,
00576 0x00000000,
00577 0x00000000,
00578 0x00000000,
00579 0x00000000,
00580 0x00000000,
00581 0x00000000,
00582 0x00000000,
00583 0x000000ff,
00584 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00585 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00586 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00587 };
00588
00597 void CSym53C895::run()
00598 {
00599 try
00600 {
00601 for(;;)
00602 {
00603 mySemaphore.wait();
00604 if(StopThread)
00605 return;
00606 while(state.executing)
00607 {
00608 MUTEX_LOCK(myRegLock);
00609 execute();
00610 MUTEX_UNLOCK(myRegLock);
00611 }
00612 }
00613 }
00614
00615 catch(Poco::Exception & e)
00616 {
00617 printf("Exception in SYM thread: %s.\n", e.displayText().c_str());
00618
00619
00620 }
00621 }
00622
00629 CSym53C895::CSym53C895(CConfigurator* cfg, CSystem* c, int pcibus, int pcidev) : CDiskController(cfg, c, pcibus, pcidev, 1, 16), mySemaphore(0, 1)
00630 {
00631
00632
00633 CSCSIBus* a = new CSCSIBus(cfg, c);
00634 scsi_register(0, a, 7);
00635 }
00636
00642 void CSym53C895::init()
00643 {
00644 add_function(0, sym_cfg_data, sym_cfg_mask);
00645
00646 ResetPCI();
00647
00648 chip_reset();
00649
00650 myRegLock = new CMutex("sym-reg");
00651
00652 myThread = 0;
00653
00654 printf("%s: $Id: Sym53C895.cpp,v 1.33 2008/03/25 16:05:30 iamcamiel Exp $\n",
00655 devid_string);
00656 }
00657
00661 void CSym53C895::start_threads()
00662 {
00663 if(!myThread)
00664 {
00665 myThread = new Poco::Thread("sym");
00666 printf(" %s", myThread->getName().c_str());
00667 StopThread = false;
00668 myThread->start(*this);
00669 if(state.executing)
00670 mySemaphore.set();
00671 }
00672 }
00673
00677 void CSym53C895::stop_threads()
00678 {
00679 StopThread = true;
00680 if(myThread)
00681 {
00682 printf(" %s", myThread->getName().c_str());
00683 mySemaphore.set();
00684 myThread->join();
00685 delete myThread;
00686 myThread = 0;
00687 }
00688 }
00689
00695 CSym53C895::~CSym53C895()
00696 {
00697 stop_threads();
00698 delete scsi_bus[0];
00699 }
00700
00706 void CSym53C895::chip_reset()
00707 {
00708 state.executing = false;
00709 state.wait_reselect = false;
00710 state.irq_asserted = false;
00711 state.gen_timer = 0;
00712 memset(state.regs.reg32, 0, sizeof(state.regs.reg32));
00713 R8(SCNTL0) = R_SCNTL0_ARB1 | R_SCNTL0_ARB0;
00714 R8(DSTAT) = R_DSTAT_DFE;
00715
00716
00717 R8(CTEST1) = R_CTEST1_FMT;
00718 R8(CTEST2) = R_CTEST2_DACK;
00719 R8(CTEST3) = (u8) (pci_state.config_data[0][2] << 4) & R_CTEST3_REV;
00720 R8(MACNTL) = 0xD0;
00721 R8(GPCNTL) = 0x0F;
00722 R8(STEST0) = 0x03;
00723 }
00724
00730 void CSym53C895::register_disk(class CDisk* dsk, int bus, int dev)
00731 {
00732 CDiskController::register_disk(dsk, bus, dev);
00733 dsk->scsi_register(0, scsi_bus[0], dev);
00734 }
00735
00737 static u32 sym_magic1 = 0x53C895CC;
00739 static u32 sym_magic2 = 0xCC53C895;
00740
00744 int CSym53C895::SaveState(FILE* f)
00745 {
00746 long ss = sizeof(state);
00747 int res;
00748
00749 if(res = CPCIDevice::SaveState(f))
00750 return res;
00751
00752 fwrite(&sym_magic1, sizeof(u32), 1, f);
00753 fwrite(&ss, sizeof(long), 1, f);
00754 fwrite(&state, sizeof(state), 1, f);
00755 fwrite(&sym_magic2, sizeof(u32), 1, f);
00756 printf("%s: %d bytes saved.\n", devid_string, (int) ss);
00757 return 0;
00758 }
00759
00763 int CSym53C895::RestoreState(FILE* f)
00764 {
00765 long ss;
00766 u32 m1;
00767 u32 m2;
00768 int res;
00769 size_t r;
00770
00771 if(res = CPCIDevice::RestoreState(f))
00772 return res;
00773
00774 r = fread(&m1, sizeof(u32), 1, f);
00775 if(r != 1)
00776 {
00777 printf("%s: unexpected end of file!\n", devid_string);
00778 return -1;
00779 }
00780
00781 if(m1 != sym_magic1)
00782 {
00783 printf("%s: MAGIC 1 does not match!\n", devid_string);
00784 return -1;
00785 }
00786
00787 fread(&ss, sizeof(long), 1, f);
00788 if(r != 1)
00789 {
00790 printf("%s: unexpected end of file!\n", devid_string);
00791 return -1;
00792 }
00793
00794 if(ss != sizeof(state))
00795 {
00796 printf("%s: STRUCT SIZE does not match!\n", devid_string);
00797 return -1;
00798 }
00799
00800 fread(&state, sizeof(state), 1, f);
00801 if(r != 1)
00802 {
00803 printf("%s: unexpected end of file!\n", devid_string);
00804 return -1;
00805 }
00806
00807 r = fread(&m2, sizeof(u32), 1, f);
00808 if(r != 1)
00809 {
00810 printf("%s: unexpected end of file!\n", devid_string);
00811 return -1;
00812 }
00813
00814 if(m2 != sym_magic2)
00815 {
00816 printf("%s: MAGIC 1 does not match!\n", devid_string);
00817 return -1;
00818 }
00819
00820 printf("%s: %d bytes restored.\n", devid_string, (int) ss);
00821 return 0;
00822 }
00823
00827 void CSym53C895::WriteMem_Bar(int func, int bar, u32 address, int dsize, u32 data)
00828 {
00829 void* p;
00830
00831 switch(bar)
00832 {
00833 case 0:
00834 case 1:
00835 address &= 0x7f;
00836 switch(dsize)
00837 {
00838 case 8:
00839 MUTEX_LOCK(myRegLock);
00840 #if defined(DEBUG_SYM_REGS)
00841 printf("SYM: Write to register %02x: %02x. \n", address, data);
00842 #endif
00843 if(address >= R_SCRATCHC)
00844 {
00845 state.regs.reg8[address] = (u8) data;
00846 MUTEX_UNLOCK(myRegLock);
00847 break;
00848 }
00849
00850 switch(address)
00851 {
00852
00853
00854 case R_SXFER:
00855 case R_DSA:
00856 case R_DSA + 1:
00857 case R_DSA + 2:
00858 case R_DSA + 3:
00859 case R_CTEST0:
00860 case R_TEMP:
00861 case R_TEMP + 1:
00862 case R_TEMP + 2:
00863 case R_TEMP + 3:
00864 case R_DSP:
00865 case R_DSP + 1:
00866 case R_DSP + 2:
00867 case R_DSPS:
00868 case R_DSPS + 1:
00869 case R_DSPS + 2:
00870 case R_DSPS + 3:
00871 case R_SCRATCHA:
00872 case R_SCRATCHA + 1:
00873 case R_SCRATCHA + 2:
00874 case R_SCRATCHA + 3:
00875 case R_DMODE:
00876 case R_SBR:
00877 case R_GPCNTL:
00878 case R_STIME0:
00879 case R_RESPID:
00880 case R_RESPID + 1:
00881 case R_STEST0:
00882 case R_SCRATCHB:
00883 case R_SCRATCHB + 1:
00884 case R_SCRATCHB + 2:
00885 case R_SCRATCHB + 3:
00886 state.regs.reg8[address] = (u8) data;
00887 break;
00888
00889 case R_SCNTL0:
00890
00891 write_b_scntl0((u8) data);
00892 break;
00893
00894 case R_SCNTL1:
00895
00896 write_b_scntl1((u8) data);
00897 break;
00898
00899 case R_SCNTL2:
00900 WRMW1C_R8(SCNTL2, (u8) data);
00901 break;
00902
00903 case R_SCNTL3:
00904
00905 write_b_scntl3((u8) data);
00906 break;
00907
00908 case R_SCID:
00909 WRM_R8(SCID, (u8) data);
00910 break;
00911
00912 case R_SDID:
00913 WRM_R8(SDID, (u8) data);
00914 break;
00915
00916 case R_GPREG:
00917 WRM_R8(GPREG, (u8) data);
00918 break;
00919
00920 case R_ISTAT:
00921 write_b_istat((u8) data);
00922 break;
00923
00924 case R_CTEST2:
00925 WRM_R8(CTEST2, (u8) data);
00926 break;
00927
00928 case R_CTEST3:
00929 write_b_ctest3((u8) data);
00930 break;
00931
00932 case R_CTEST4:
00933 write_b_ctest4((u8) data);
00934 break;
00935
00936 case R_CTEST5:
00937 write_b_ctest5((u8) data);
00938 break;
00939
00940 case R_DSP + 3:
00941 state.regs.reg8[address] = (u8) data;
00942 post_dsp_write();
00943 break;
00944
00945 case R_DIEN:
00946 WRM_R8(DIEN, (u8) data);
00947 eval_interrupts();
00948 break;
00949
00950 case R_DCNTL:
00951 write_b_dcntl((u8) data);
00952 break;
00953
00954 case R_SIEN0:
00955 R8(SIEN0) = (u8) data;
00956 eval_interrupts();
00957 break;
00958
00959 case R_SIEN1:
00960 WRM_R8(SIEN1, (u8) data);
00961 eval_interrupts();
00962 break;
00963
00964 case R_MACNTL:
00965 WRM_R8(MACNTL, (u8) data);
00966 break;
00967
00968 case R_STIME1:
00969 WRM_R8(STIME1, (u8) data);
00970 state.gen_timer = (R8(STIME1) & R_STIME1_GEN) * 30;
00971 break;
00972
00973 case R_STEST1:
00974 WRM_R8(STEST1, (u8) data);
00975 break;
00976
00977 case R_STEST2:
00978 write_b_stest2((u8) data);
00979 break;
00980
00981 case R_STEST3:
00982 write_b_stest3((u8) data);
00983 break;
00984
00985 case R_DSTAT:
00986 case R_SSTAT0:
00987 case R_SSTAT1:
00988 case R_SSTAT2:
00989
00990 break;
00991
00992 default:
00993 FAILURE_2(NotImplemented,
00994 "SYM: Write to unknown register at %02x with %08x.\n", address,
00995 data);
00996 }
00997
00998 MUTEX_UNLOCK(myRegLock);
00999 break;
01000
01001 case 16:
01002 WriteMem_Bar(0, 1, address + 0, 8, (data >> 0) & 0xff);
01003 WriteMem_Bar(0, 1, address + 1, 8, (data >> 8) & 0xff);
01004 break;
01005
01006 case 32:
01007 WriteMem_Bar(0, 1, address + 0, 8, (data >> 0) & 0xff);
01008 WriteMem_Bar(0, 1, address + 1, 8, (data >> 8) & 0xff);
01009 WriteMem_Bar(0, 1, address + 2, 8, (data >> 16) & 0xff);
01010 WriteMem_Bar(0, 1, address + 3, 8, (data >> 24) & 0xff);
01011 break;
01012 }
01013 break;
01014
01015 case 2:
01016 p = (u8*) state.ram + address;
01017 switch(dsize)
01018 {
01019 case 8: *((u8*) p) = (u8) data; break;
01020 case 16: *((u16*) p) = (u16) data; break;
01021 case 32: *((u32*) p) = (u32) data; break;
01022 }
01023 break;
01024 }
01025 }
01026
01030 u32 CSym53C895::ReadMem_Bar(int func, int bar, u32 address, int dsize)
01031 {
01032 u32 data = 0;
01033 void* p;
01034
01035 switch(bar)
01036 {
01037 case 0:
01038 case 1:
01039 address &= 0x7f;
01040 switch(dsize)
01041 {
01042 case 8:
01043 MUTEX_LOCK(myRegLock);
01044 if(address >= R_SCRATCHC)
01045 {
01046 data = state.regs.reg8[address];
01047 MUTEX_UNLOCK(myRegLock);
01048 break;
01049 }
01050
01051 switch(address)
01052 {
01053 case R_SCNTL0:
01054 case R_SCNTL1:
01055 case R_SCNTL2:
01056 case R_SCNTL3:
01057 case R_SCID:
01058 case R_SXFER:
01059 case R_SDID:
01060 case R_GPREG:
01061 case R_SFBR:
01062 case R_SSID:
01063 case R_SBCL:
01064 case R_SSTAT0:
01065 case R_SSTAT1:
01066 case R_SSTAT2:
01067 case R_DSA:
01068 case R_DSA + 1:
01069 case R_DSA + 2:
01070 case R_DSA + 3:
01071 case R_ISTAT:
01072 case R_CTEST0:
01073 case R_CTEST1:
01074 case R_CTEST3:
01075 case R_TEMP:
01076 case R_TEMP + 1:
01077 case R_TEMP + 2:
01078 case R_TEMP + 3:
01079 case R_CTEST4:
01080 case R_CTEST5:
01081 case R_DBC:
01082 case R_DBC + 1:
01083 case R_DBC + 2:
01084 case R_DCMD:
01085 case R_DNAD:
01086 case R_DNAD + 1:
01087 case R_DNAD + 2:
01088 case R_DNAD + 3:
01089 case R_DSP:
01090 case R_DSP + 1:
01091 case R_DSP + 2:
01092 case R_DSP + 3:
01093 case R_DSPS:
01094 case R_DSPS + 1:
01095 case R_DSPS + 2:
01096 case R_DSPS + 3:
01097 case R_DMODE:
01098 case R_DIEN:
01099 case R_SBR:
01100 case R_DCNTL:
01101 case R_SIEN0:
01102 case R_SIEN1:
01103 case R_MACNTL:
01104 case R_GPCNTL:
01105 case R_STIME0:
01106 case R_STIME1:
01107 case R_RESPID:
01108 case R_RESPID + 1:
01109 case R_STEST0:
01110 case R_STEST1:
01111 case R_STEST2:
01112 case R_STEST3:
01113 case R_STEST4:
01114 case R_SBDL:
01115 case R_SBDL + 1:
01116 data = state.regs.reg8[address];
01117 break;
01118
01119 case R_DSTAT:
01120 data = read_b_dstat();
01121 break;
01122
01123 case R_CTEST2:
01124 data = read_b_ctest2();
01125 break;
01126
01127 case R_DFIFO:
01128 data = R8(DBC) & 0x7f;
01129 break;
01130
01131 case R_SCRATCHA:
01132 case R_SCRATCHA + 1:
01133 case R_SCRATCHA + 2:
01134 case R_SCRATCHA + 3:
01135 data = read_b_scratcha(address - R_SCRATCHA);
01136 break;
01137
01138 case R_SIST0:
01139 case R_SIST1:
01140 data = read_b_sist(address - R_SIST0);
01141 break;
01142
01143 case R_SCRATCHB:
01144 case R_SCRATCHB + 1:
01145 case R_SCRATCHB + 2:
01146 case R_SCRATCHB + 3:
01147 data = read_b_scratchb(address - R_SCRATCHB);
01148 break;
01149
01150 default:
01151 FAILURE_2(NotImplemented,
01152 "SYM: Attempt to read from unknown register at %02x\n", dsize,
01153 address);
01154 }
01155
01156 MUTEX_UNLOCK(myRegLock);
01157 #if defined(DEBUG_SYM_REGS)
01158 printf("SYM: Read frm register %02x: %02x. \n", address, data);
01159 #endif
01160 break;
01161
01162 case 16:
01163 data = (ReadMem_Bar(0, 1, address + 0, 8) << 0) & 0x00ff;
01164 data |= (ReadMem_Bar(0, 1, address + 1, 8) << 8) & 0xff00;
01165 break;
01166
01167 case 32:
01168 data = (ReadMem_Bar(0, 1, address + 0, 8) << 0) & 0x000000ff;
01169 data |= (ReadMem_Bar(0, 1, address + 1, 8) << 8) & 0x0000ff00;
01170 data |= (ReadMem_Bar(0, 1, address + 2, 8) << 16) & 0x00ff0000;
01171 data |= (ReadMem_Bar(0, 1, address + 3, 8) << 24) & 0xff000000;
01172 break;
01173 }
01174 break;
01175
01176 case 2:
01177 p = (u8*) state.ram + address;
01178 switch(dsize)
01179 {
01180 case 8: return *((u8*) p);
01181 case 16: return *((u16*) p);
01182 case 32: return *((u32*) p);
01183 }
01184 break;
01185 }
01186
01187 return data;
01188 }
01189
01196 u32 CSym53C895::config_read_custom(int func, u32 address, int dsize, u32 data)
01197 {
01198 if(address >= 0x80)
01199 return ReadMem_Bar(func, 1, address - 0x80, dsize);
01200 else
01201 return data;
01202 }
01203
01210 void CSym53C895::config_write_custom(int func, u32 address, int dsize,
01211 u32 old_data, u32 new_data, u32 data)
01212 {
01213 if(address >= 0x80)
01214 WriteMem_Bar(func, 1, address - 0x80, dsize, data);
01215 }
01216
01232 void CSym53C895::write_b_scntl0(u8 value)
01233 {
01234 bool old_start = TB_R8(SCNTL0, START);
01235
01236 WRM_R8(SCNTL0, value);
01237
01238 if(TB_R8(SCNTL0, START) && !old_start)
01239 FAILURE(NotImplemented, "SYM: Don't know how to start arbitration sequence");
01240
01241 if(TB_R8(SCNTL0, TRG))
01242 FAILURE(NotImplemented, "SYM: Don't know how to operate in target mode");
01243 }
01244
01261 void CSym53C895::write_b_scntl1(u8 value)
01262 {
01263 bool old_iarb = TB_R8(SCNTL1, IARB);
01264 bool old_con = TB_R8(SCNTL1, CON);
01265 bool old_rst = TB_R8(SCNTL1, RST);
01266
01267 R8(SCNTL1) = value;
01268
01269
01270
01271 if(TB_R8(SCNTL1, RST) != old_rst)
01272 {
01273 SB_R8(SSTAT0, SDP0, false);
01274 SB_R8(SSTAT1, SDP1, false);
01275 R16(SBDL) = 0;
01276 R8(SBCL) = 0;
01277
01278 SB_R8(SSTAT0, RST, !old_rst);
01279
01280
01281 if(!old_rst)
01282 RAISE(SIST0, RST);
01283 }
01284 }
01285
01292 void CSym53C895::write_b_scntl3(u8 value)
01293 {
01294 R8(SCNTL3) = value;
01295
01296
01297
01298 if(!TB_R8(SCNTL3, EWS))
01299 SB_R8(SCNTL2, WSR, false);
01300 }
01301
01318 void CSym53C895::write_b_istat(u8 value)
01319 {
01320 bool old_srst = TB_R8(ISTAT, SRST);
01321 bool old_sem = TB_R8(ISTAT, SEM);
01322 bool old_sigp = TB_R8(ISTAT, SIGP);
01323
01324 WRMW1C_R8(ISTAT, value);
01325
01326 if(TB_R8(ISTAT, ABRT))
01327 {
01328
01329
01330 RAISE(DSTAT, ABRT);
01331 }
01332
01333 if(TB_R8(ISTAT, SRST) && !old_srst)
01334 {
01335
01336
01337 chip_reset();
01338 }
01339
01340
01341
01342
01343
01344 if(TB_R8(ISTAT, SIGP))
01345 {
01346 if(state.wait_reselect)
01347 {
01348
01349
01350 R32(DSP) = state.wait_jump;
01351 state.wait_reselect = false;
01352 state.executing = true;
01353 mySemaphore.set();
01354 }
01355 }
01356
01357 eval_interrupts();
01358 }
01359
01372 u8 CSym53C895::read_b_ctest2()
01373 {
01374 SB_R8(CTEST2, CIO, pci_state.config_data[0][4] != 0);
01375 SB_R8(CTEST2, CM, pci_state.config_data[0][5] != 0);
01376 SB_R8(CTEST2, SIGP, TB_R8(ISTAT, SIGP));
01377 SB_R8(ISTAT, SIGP, false);
01378
01379
01380 return R8(CTEST2);
01381 }
01382
01396 void CSym53C895::write_b_ctest3(u8 value)
01397 {
01398 WRM_R8(CTEST3, value);
01399
01400
01401
01402
01403
01404 if((value >> 1) & 1)
01405 FAILURE(NotImplemented, "SYM: Don't know how to handle FM mode");
01406 }
01407
01418 void CSym53C895::write_b_ctest4(u8 value)
01419 {
01420 R8(CTEST4) = value;
01421
01422 if((value >> 4) & 1)
01423 FAILURE(NotImplemented, "SYM: Don't know how to handle SRTM mode");
01424 }
01425
01444 void CSym53C895::write_b_ctest5(u8 value)
01445 {
01446 WRM_R8(CTEST5, value);
01447
01448 if((value >> 7) & 1)
01449 FAILURE(NotImplemented, "SYM: Don't know how to do Clock Address increment");
01450
01451 if((value >> 6) & 1)
01452 FAILURE(NotImplemented,
01453 "SYM: Don't know how to do Clock Byte Counter decrement");
01454 }
01455
01462 u8 CSym53C895::read_b_dstat()
01463 {
01464 u8 retval = R8(DSTAT);
01465
01466 RDCLR_R8(DSTAT);
01467
01468
01469 eval_interrupts();
01470
01471
01472 return retval;
01473 }
01474
01481 u8 CSym53C895::read_b_sist(int id)
01482 {
01483 u8 retval = state.regs.reg8[R_SIST0 + id];
01484
01485 if(id)
01486 RDCLR_R8(SIST1);
01487 else
01488 RDCLR_R8(SIST0);
01489
01490 eval_interrupts();
01491
01492 return retval;
01493 }
01494
01507 void CSym53C895::write_b_dcntl(u8 value)
01508 {
01509 WRM_R8(DCNTL, value);
01510
01511
01512 if(value & R_DCNTL_STD)
01513 {
01514 state.executing = true;
01515 mySemaphore.set();
01516 }
01517
01518
01519 eval_interrupts();
01520 }
01521
01529 u8 CSym53C895::read_b_scratcha(int reg)
01530 {
01531 if(TB_R8(CTEST2, SRTCH))
01532 {
01533
01534
01535 return(u8) (pci_state.config_data[0][4] >> (reg * 8)) & 0xff;
01536 }
01537 else
01538 return state.regs.reg8[R_SCRATCHA + reg];
01539 }
01540
01548 u8 CSym53C895::read_b_scratchb(int reg)
01549 {
01550 if(TB_R8(CTEST2, SRTCH))
01551 {
01552
01553
01554 return(u8) (pci_state.config_data[0][5] >> (reg * 8)) & 0xff;
01555 }
01556 else
01557 return state.regs.reg8[R_SCRATCHB + reg];
01558 }
01559
01571 void CSym53C895::write_b_stest2(u8 value)
01572 {
01573 WRM_R8(STEST2, value);
01574
01575
01576
01577 if(TB_R8(STEST2, LOW))
01578 FAILURE(NotImplemented, "SYM: I don't like LOW level mode");
01579 }
01580
01588 void CSym53C895::write_b_stest3(u8 value)
01589 {
01590 WRM_R8(STEST3, value);
01591
01592
01593
01594 }
01595
01601 void CSym53C895::post_dsp_write()
01602 {
01603 if(!TB_R8(DMODE, MAN))
01604 {
01605 state.executing = true;
01606 mySemaphore.set();
01607
01608
01609 }
01610 }
01611
01615 void CSym53C895::check_state()
01616 {
01617 if(myThread && !myThread->isRunning())
01618 FAILURE(Thread, "SYM thread has died");
01619
01620 if(state.gen_timer)
01621 {
01622 state.gen_timer--;
01623 if(!state.gen_timer)
01624 {
01625 state.gen_timer = (R8(STIME1) & R_STIME1_GEN) * 30;
01626 RAISE(SIST1, GEN);
01627 return;
01628 }
01629 }
01630
01652 if(state.disconnected)
01653 {
01654 if(!TB_R8(SCNTL2, SDU))
01655 {
01656
01657
01658
01659 state.disconnected = 0;
01660 return;
01661 }
01662
01663 state.disconnected--;
01664 if(!state.disconnected)
01665 {
01666
01667
01668
01669
01670 RAISE(SIST0, UDC);
01671 return;
01672 }
01673 }
01674 }
01675
01682 int CSym53C895::check_phase(int chk_phase)
01683 {
01684 int real_phase = scsi_get_phase(0);
01685
01686 if(real_phase == SCSI_PHASE_ARBITRATION)
01687 {
01688 #if defined(DEBUG_SYM_SCRIPTS)
01689 printf("Phase check... selection time-out!\n");
01690 #endif
01691 RAISE(SIST1, STO);
01692 scsi_free(0);
01693 state.select_timeout = false;
01694 return -1;
01695 }
01696
01697 if(real_phase == SCSI_PHASE_FREE && state.disconnected)
01698 {
01699 #if defined(DEBUG_SYM_SCRIPTS)
01700 printf("Phase check... disconnected!\n");
01701 #endif
01702 state.disconnected = 1;
01703 R32(DSP) -= 8;
01704 return -1;
01705 }
01706
01707 if (real_phase == chk_phase)
01708 return 1;
01709 else
01710 return 0;
01711 }
01712
01748 void CSym53C895::execute_bm_op()
01749 {
01750 bool indirect = (R8(DCMD) >> 5) & 1;
01751 bool table_indirect = (R8(DCMD) >> 4) & 1;
01752 int opcode = (R8(DCMD) >> 3) & 1;
01753 int scsi_phase = (R8(DCMD) >> 0) & 7;
01754
01755 #if defined(DEBUG_SYM_SCRIPTS)
01756 printf("SYM: INS = Block Move (i %d, t %d, opc %d, phase %d\n", indirect,
01757 table_indirect, opcode, scsi_phase);
01758 #endif
01759
01760 if(check_phase(scsi_phase)>0)
01761 {
01762 #if defined(DEBUG_SYM_SCRIPTS)
01763 printf("SYM: Ready for transfer.\n");
01764 #endif
01765
01766 u32 start;
01767 u32 count;
01768
01769 if(table_indirect)
01770 {
01771 u32 add = R32(DSA) + sext_u32_24(R32(DSPS));
01772
01773 add &= ~0x03;
01774 #if defined(DEBUG_SYM_SCRIPTS)
01775 printf("SYM: Reading table at DSA(%08x)+DSPS(%08x) = %08x.\n",
01776 R32(DSA), R32(DSPS), add);
01777 #endif
01778 do_pci_read(add, &count, 4, 1);
01779 count &= 0x00ffffff;
01780 do_pci_read(add + 4, &start, 4, 1);
01781 }
01782 else if(indirect)
01783 {
01784 FAILURE(NotImplemented, "SYM: Unsupported: indirect addressing");
01785 }
01786 else
01787 {
01788 start = R32(DSPS);
01789 count = GET_DBC();
01790 }
01791
01792 #if defined(DEBUG_SYM_SCRIPTS)
01793 printf("SYM: %08x: MOVE Start/count %x, %x\n", R32(DSP) - 8, start,
01794 count);
01795 #endif
01796 R32(DNAD) = start;
01797 SET_DBC(count);
01798 if(count == 0)
01799 {
01800
01801
01802 RAISE(DSTAT, IID);
01803 return;
01804 }
01805
01806 if((size_t) count > scsi_expected_xfer(0))
01807 {
01808 #if defined(DEBUG_SYM_SCRIPTS)
01809 printf("SYM: xfer %d bytes, max %d expected, in phase %d.\n", count,
01810 scsi_expected_xfer(0), scsi_phase);
01811 #endif
01812 count = (u32) scsi_expected_xfer(0);
01813 }
01814
01815 u8* scsi_data_ptr = (u8*) scsi_xfer_ptr(0, count);
01816 u8* org_sdata_ptr = scsi_data_ptr;
01817
01818 switch(scsi_phase)
01819 {
01820 case SCSI_PHASE_COMMAND:
01821 case SCSI_PHASE_DATA_OUT:
01822 case SCSI_PHASE_MSG_OUT:
01823 do_pci_read(R32(DNAD), scsi_data_ptr, 1, count);
01824 R32(DNAD) += count;
01825 break;
01826
01827 case SCSI_PHASE_STATUS:
01828 case SCSI_PHASE_DATA_IN:
01829 case SCSI_PHASE_MSG_IN:
01830 do_pci_write(R32(DNAD), scsi_data_ptr, 1, count);
01831 R32(DNAD) += count;
01832 break;
01833 }
01834
01835 R8(SFBR) = *org_sdata_ptr;
01836 scsi_xfer_done(0);
01837 return;
01838 }
01839 }
01840
01841
01842
01843
01844
01845
01846
01847
01848
01849
01850
01851
01852
01853
01854
01855
01856
01857
01858
01859
01860
01861
01862
01863
01864
01865
01866
01867
01868
01869
01870
01871
01872
01873
01874
01875
01876
01877
01878
01879
01880
01881
01882
01883
01884
01885
01886
01887
01888
01889
01890
01891
01892
01893
01894
01895
01896
01897
01898
01899
01900
01901
01902
01903
01904
01905
01906
01907
01908
01909
01910
01911
01912
01913
01914
01915
01916
01917
01918 void CSym53C895::execute_io_op()
01919 {
01920 int opcode = (R8(DCMD) >> 3) & 7;
01921 bool relative = (R8(DCMD) >> 2) & 1;
01922 bool table_indirect = (R8(DCMD) >> 1) & 1;
01923 bool atn = (R8(DCMD) >> 0) & 1;
01924 int destination = (GET_DBC() >> 16) & 0x0f;
01925 bool sc_carry = (GET_DBC() >> 10) & 1;
01926 bool sc_target = (GET_DBC() >> 9) & 1;
01927 bool sc_ack = (GET_DBC() >> 6) & 1;
01928 bool sc_atn = (GET_DBC() >> 3) & 1;
01929
01930 R32(DNAD) = R32(DSPS);
01931
01932 u32 dest_addr = R32(DNAD);
01933
01934 if(relative)
01935 dest_addr = R32(DSP) + sext_u32_24(R32(DNAD));
01936
01937 #if defined(DEBUG_SYM_SCRIPTS)
01938 printf("SYM: INS = I/O (opc %d, r %d, t %d, a %d, dest %d, sc %d%d%d%d\n",
01939 opcode, relative, table_indirect, atn, destination, sc_carry,
01940 sc_target, sc_ack, sc_atn);
01941 #endif
01942 if(table_indirect)
01943 {
01944 u32 io_addr = R32(DSA) + sext_u32_24(GET_DBC());
01945 io_addr &= ~3;
01946 #if defined(DEBUG_SYM_SCRIPTS)
01947 printf("SYM: Reading table at DSA(%08x)+DBC(%08x) = %08x.\n",
01948 R32(DSA), sext_u32_24(GET_DBC()), io_addr);
01949 #endif
01950
01951 u32 io_struc;
01952 do_pci_read(io_addr, &io_struc, 4, 1);
01953 destination = (io_struc >> 16) & 0x0f;
01954 #if defined(DEBUG_SYM_SCRIPTS)
01955 printf("SYM: table indirect. io_struct = %08x, new dest = %d.\n",
01956 io_struc, destination);
01957 #endif
01958 }
01959
01960 switch(opcode)
01961 {
01962 case 0:
01963 #if defined(DEBUG_SYM_SCRIPTS)
01964 printf("SYM: %08x: SELECT %d.\n", R32(DSP) - 8, destination);
01965 #endif
01966 SET_DEST(destination);
01967 if(!scsi_arbitrate(0))
01968 {
01969
01970
01971 printf("scsi bus busy...\n");
01972 R32(DSP) -= 8;
01973 return;
01974 }
01975
01976 state.select_timeout = !scsi_select(0, destination);
01977 if(!state.select_timeout)
01978 SB_R8(SCNTL2, SDU, true);
01979 return;
01980
01981 case 1:
01982 #if defined(DEBUG_SYM_SCRIPTS)
01983 printf("SYM: %08x: WAIT DISCONNECT\n", R32(DSP) - 8);
01984 #endif
01985
01986
01987 scsi_free(0);
01988 return;
01989
01990 case 2:
01991 #if defined(DEBUG_SYM_SCRIPTS)
01992 printf("SYM: %08x: WAIT RESELECT\n", R32(DSP) - 8);
01993 #endif
01994 if(TB_R8(ISTAT, SIGP))
01995 {
01996 #if defined(DEBUG_SYM_SCRIPTS)
01997 printf("SYM: SIGP set before wait reselect; jumping!\n");
01998 #endif
01999 R32(DSP) = dest_addr;
02000 }
02001 else
02002 {
02003 state.wait_reselect = true;
02004 state.wait_jump = dest_addr;
02005 state.executing = false;
02006 }
02007
02008 return;
02009
02010 case 3:
02011 #if defined(DEBUG_SYM_SCRIPTS)
02012 printf("SYM: %08x: SET %s%s%s%s\n", R32(DSP) - 8,
02013 sc_carry ? "carry " : "", sc_target ? "target " : "",
02014 sc_ack ? "ack " : "", sc_atn ? "atn " : "");
02015 #endif
02016 if(sc_ack)
02017 SB_R8(SOCL, ACK, true);
02018 if(sc_atn)
02019 {
02020 if(!TB_R8(SOCL, ATN))
02021 {
02022 SB_R8(SOCL, ATN, true);
02023
02024
02025
02026
02027 }
02028 }
02029
02030 if(sc_target)
02031 SB_R8(SCNTL0, TRG, true);
02032 if(sc_carry)
02033 state.alu.carry = true;
02034 return;
02035
02036 case 4:
02037 #if defined(DEBUG_SYM_SCRIPTS)
02038 printf("SYM: %08x: CLEAR %s%s%s%s\n", R32(DSP) - 8,
02039 sc_carry ? "carry " : "", sc_target ? "target " : "",
02040 sc_ack ? "ack " : "", sc_atn ? "atn " : "");
02041 #endif
02042 if(sc_ack)
02043 SB_R8(SOCL, ACK, false);
02044 if(sc_atn)
02045 {
02046 if(TB_R8(SOCL, ATN))
02047 {
02048 SB_R8(SOCL, ATN, false);
02049
02050
02051
02052
02053 }
02054 }
02055
02056 if(sc_target)
02057 SB_R8(SCNTL0, TRG, false);
02058 if(sc_carry)
02059 state.alu.carry = false;
02060 return;
02061
02062 break;
02063 }
02064 }
02065
02103 void CSym53C895::execute_rw_op()
02104 {
02105 int opcode = (R8(DCMD) >> 3) & 7;
02106 int oper = (R8(DCMD) >> 0) & 7;
02107 bool use_data8_sfbr = (GET_DBC() >> 23) & 1;
02108 int reg_address = ((GET_DBC() >> 16) & 0x7f);
02109 u8 imm_data = (u8) (GET_DBC() >> 8) & 0xff;
02110 u8 op_data;
02111
02112 #if defined(DEBUG_SYM_SCRIPTS)
02113 printf("SYM: INS = R/W (opc %d, oper %d, use %d, add %d, imm %02x\n",
02114 opcode, oper, use_data8_sfbr, reg_address, imm_data);
02115 #endif
02116 if(use_data8_sfbr)
02117 imm_data = R8(SFBR);
02118
02119 if(oper != 0)
02120 {
02121 if(opcode == 5 || reg_address == 0x08)
02122 {
02123 op_data = R8(SFBR);
02124 #if defined(DEBUG_SYM_SCRIPTS)
02125 printf("SYM: %08x: sfbr (%02x) ", R32(DSP) - 8, op_data);
02126 #endif
02127 }
02128 else
02129 {
02130 op_data = (u8) ReadMem_Bar(0, 1, reg_address, 8);
02131 #if defined(DEBUG_SYM_SCRIPTS)
02132 printf("SYM: %08x: reg%02x (%02x) ", R32(DSP) - 8, reg_address,
02133 op_data);
02134 #endif
02135 }
02136 }
02137
02138 u16 tmp16;
02139
02140 switch(oper)
02141 {
02142 case 0:
02143 op_data = imm_data;
02144 #if defined(DEBUG_SYM_SCRIPTS)
02145 printf("SYM: %08x: %02x ", R32(DSP) - 8, imm_data);
02146 #endif
02147 break;
02148
02149 case 1:
02150 tmp16 = (op_data << 1) + (state.alu.carry ? 1 : 0);
02151 state.alu.carry = (tmp16 >> 8) & 1;
02152 op_data = tmp16 & 0xff;
02153 #if defined(DEBUG_SYM_SCRIPTS)
02154 printf("<< 1 = %02x ", op_data);
02155 #endif
02156 break;
02157
02158 case 2:
02159 op_data |= imm_data;
02160 #if defined(DEBUG_SYM_SCRIPTS)
02161 printf("| %02x = %02x ", imm_data, op_data);
02162 #endif
02163 break;
02164
02165 case 3:
02166 op_data ^= imm_data;
02167 #if defined(DEBUG_SYM_SCRIPTS)
02168 printf("^ %02x = %02x ", imm_data, op_data);
02169 #endif
02170 break;
02171
02172 case 4:
02173 op_data &= imm_data;
02174 #if defined(DEBUG_SYM_SCRIPTS)
02175 printf("& %02x = %02x ", imm_data, op_data);
02176 #endif
02177 break;
02178
02179 case 5:
02180 tmp16 = (op_data >> 1) + (state.alu.carry ? 0x80 : 0x00);
02181 state.alu.carry = op_data & 1;
02182 op_data = tmp16 & 0xff;
02183 #if defined(DEBUG_SYM_SCRIPTS)
02184 printf(">> 1 = %02x ", op_data);
02185 #endif
02186 break;
02187
02188 case 6:
02189 tmp16 = op_data + imm_data;
02190 state.alu.carry = (tmp16 > 0xff);
02191 op_data = tmp16 & 0xff;
02192 #if defined(DEBUG_SYM_SCRIPTS)
02193 printf("+ %02x = %02x (carry %d) ", imm_data, op_data, state.alu.carry);
02194 #endif
02195 break;
02196
02197 case 7:
02198 tmp16 = op_data + imm_data + (state.alu.carry ? 1 : 0);
02199 state.alu.carry = (tmp16 > 0xff);
02200 op_data = tmp16 & 0xff;
02201 #if defined(DEBUG_SYM_SCRIPTS)
02202 printf("+ %02x (w/carry) = %02x (carry %d) ", imm_data, op_data,
02203 state.alu.carry);
02204 #endif
02205 break;
02206 }
02207
02208 if(opcode == 6 || reg_address == 0x08)
02209 {
02210 #if defined(DEBUG_SYM_SCRIPTS)
02211 printf("-> sfbr.\n");
02212 #endif
02213 R8(SFBR) = op_data;
02214 }
02215 else
02216 {
02217 #if defined(DEBUG_SYM_SCRIPTS)
02218 printf("-> reg%02x.\n", reg_address);
02219 #endif
02220 WriteMem_Bar(0, 1, reg_address, 8, op_data);
02221 }
02222 }
02223
02298 void CSym53C895::execute_tc_op()
02299 {
02300 int opcode = (R8(DCMD) >> 3) & 7;
02301 int scsi_phase = (R8(DCMD) >> 0) & 7;
02302 bool relative = (GET_DBC() >> 23) & 1;
02303 bool carry_test = (GET_DBC() >> 21) & 1;
02304 bool interrupt_fly = (GET_DBC() >> 20) & 1;
02305 bool jump_if = (GET_DBC() >> 19) & 1;
02306 bool cmp_data = (GET_DBC() >> 18) & 1;
02307 bool cmp_phase = (GET_DBC() >> 17) & 1;
02308 int cmp_mask = (GET_DBC() >> 8) & 0xff;
02309 int cmp_dat = (GET_DBC() >> 0) & 0xff;
02310 u32 dest_addr;
02311
02312
02313
02314
02315
02316 bool do_it;
02317
02318
02319 if(relative)
02320 dest_addr = R32(DSP) + sext_u32_24(R32(DSPS));
02321 else
02322 dest_addr = R32(DSPS);
02323
02324 #if defined(DEBUG_SYM_SCRIPTS)
02325 printf("SYM: %08x: if (", R32(DSP) - 8);
02326 #endif
02327 if(carry_test)
02328 {
02329
02330 #if defined(DEBUG_SYM_SCRIPTS)
02331 printf("(%scarry)", jump_if ? "" : "!");
02332 #endif
02333 do_it = (state.alu.carry == jump_if);
02334 }
02335 else if(cmp_data || cmp_phase)
02336 {
02337
02338 do_it = true;
02339 if(cmp_data)
02340 {
02341
02342 #if defined(DEBUG_SYM_SCRIPTS)
02343 printf("((data & 0x%02x) %s 0x%02x)", (~cmp_mask) & 0xff,
02344 jump_if ? "==" : "!=", cmp_dat &~cmp_mask);
02345 #endif
02346 if(((R8(SFBR) &~cmp_mask) == (cmp_dat &~cmp_mask)) != jump_if)
02347 do_it = false;
02348 #if defined(DEBUG_SYM_SCRIPTS)
02349 if(cmp_phase)
02350 printf(" && ");
02351 #endif
02352 }
02353
02354 if(cmp_phase)
02355 {
02356
02357 #if defined(DEBUG_SYM_SCRIPTS)
02358 printf("(phase %s %d)", jump_if ? "==" : "!=", scsi_phase);
02359 #endif
02360 if((check_phase(scsi_phase)>0) != jump_if)
02361 do_it = false;
02362 }
02363 }
02364 else
02365 {
02366
02367
02368 do_it = jump_if;
02369 }
02370
02371 #if defined(DEBUG_SYM_SCRIPTS)
02372 printf(") ");
02373 #endif
02374 switch(opcode)
02375 {
02376 case 0:
02377 #if defined(DEBUG_SYM_SCRIPTS)
02378 printf("jump %x\n", R32(DSPS));
02379 #endif
02380 if(do_it)
02381 {
02382 #if defined(DEBUG_SYM_SCRIPTS)
02383 printf("SYM: Jumping %08x...\n", dest_addr);
02384 #endif
02385 R32(DSP) = dest_addr;
02386 }
02387
02388 return;
02389 break;
02390
02391 case 1:
02392 #if defined(DEBUG_SYM_SCRIPTS)
02393 printf("call %d\n", R32(DSPS));
02394 #endif
02395 if(do_it)
02396 {
02397 #if defined(DEBUG_SYM_SCRIPTS)
02398 printf("SYM: Calling %08x...\n", dest_addr);
02399 #endif
02400 R32(TEMP) = R32(DSP);
02401 R32(DSP) = dest_addr;
02402 }
02403
02404 return;
02405 break;
02406
02407 case 2:
02408 #if defined(DEBUG_SYM_SCRIPTS)
02409 printf("return %d\n", R32(DSPS));
02410 #endif
02411 if(do_it)
02412 {
02413 #if defined(DEBUG_SYM_SCRIPTS)
02414 printf("SYM: Returning %08x...\n", R32(TEMP));
02415 #endif
02416 R32(DSP) = R32(TEMP);
02417 }
02418
02419 return;
02420 break;
02421
02422 case 3:
02423 #if defined(DEBUG_SYM_SCRIPTS)
02424 printf("interrupt%s.\n", interrupt_fly ? " on the fly" : "");
02425 #endif
02426 if(do_it)
02427 {
02428 #if defined(DEBUG_SYM_SCRIPTS)
02429 printf("SYM: Interrupt with vector %x...\n", R32(DSPS));
02430 #endif
02431 if(interrupt_fly)
02432 RAISE(ISTAT, INTF);
02433 else
02434 RAISE(DSTAT, SIR);
02435 }
02436
02437 return;
02438 break;
02439
02440 default:
02441 FAILURE_1(NotImplemented,
02442 "SYM: Transfer Control Instruction with opcode %d is RESERVED.\n",
02443 opcode);
02444 }
02445 }
02446
02478 void CSym53C895::execute_ls_op()
02479 {
02480 bool is_load = (R8(DCMD) >> 0) & 1;
02481 bool no_flush = (R8(DCMD) >> 1) & 1;
02482 bool dsa_relative = (R8(DCMD) >> 4) & 1;
02483 int regaddr = (GET_DBC() >> 16) & 0x7f;
02484 int byte_count = (GET_DBC() >> 0) & 7;
02485 u32 memaddr;
02486
02487
02488 if(dsa_relative)
02489 memaddr = R32(DSA) + sext_u32_24(R32(DSPS));
02490 else
02491 memaddr = R32(DSPS);
02492
02493 #if defined(DEBUG_SYM_SCRIPTS)
02494 printf("SYM: dsa_rel: %d, DSA: %04x, DSPS: %04x, mem %04x.\n",
02495 dsa_relative, R32(DSA), R32(DSPS), memaddr);
02496 #endif
02497 if(is_load)
02498 {
02499 #if defined(DEBUG_SYM_SCRIPTS)
02500 printf("SYM: %08x: Load reg%02x", R32(DSP) - 8, regaddr);
02501 if(byte_count > 1)
02502 printf("..%02x", regaddr + byte_count - 1);
02503 printf("from %x.\n", memaddr);
02504 #endif
02505
02506 for(int i = 0; i < byte_count; i++)
02507 {
02508 u8 dat;
02509 do_pci_read(memaddr + i, &dat, 1, 1);
02510 #if defined(DEBUG_SYM_SCRIPTS)
02511 printf("SYM: %02x -> reg%02x\n", dat, regaddr + i);
02512 #endif
02513 WriteMem_Bar(0, 1, regaddr + i, 8, dat);
02514 }
02515 }
02516 else
02517 {
02518 #if defined(DEBUG_SYM_SCRIPTS)
02519 printf("SYM: %08x: Store reg%02x", R32(DSP) - 8, regaddr);
02520 if(byte_count > 1)
02521 printf("..%02x", regaddr + byte_count - 1);
02522 printf("to %x.\n", memaddr);
02523 #endif
02524
02525 for(int i = 0; i < byte_count; i++)
02526 {
02527 u8 dat = (u8) ReadMem_Bar(0, 1, regaddr + i, 8);
02528 #if defined(DEBUG_SYM_SCRIPTS)
02529 printf("SYM: %02x <- reg%02x\n", dat, regaddr + i);
02530 #endif
02531 do_pci_write(memaddr + i, &dat, 1, 1);
02532 }
02533 }
02534 }
02535
02558 void CSym53C895::execute_mm_op()
02559 {
02560 u32 temp_shadow;
02561 do_pci_read(R32(DSP), &temp_shadow, 4, 1);
02562 R32(DSP) += 4;
02563
02564 #if defined(DEBUG_SYM_SCRIPTS)
02565 printf("SYM: %08x: Memory Move %06x bytes from %08x to %08x.\n",
02566 R32(DSP) - 12, GET_DBC(), R32(DSPS), temp_shadow);
02567 #endif
02568
02569
02570
02571 void* buf = malloc(GET_DBC());
02572 do_pci_read(R32(DSPS), buf, 1, GET_DBC());
02573 do_pci_write(temp_shadow, buf, 1, GET_DBC());
02574 free(buf);
02575 return;
02576 }
02577
02597 void CSym53C895::execute()
02598 {
02599 int optype;
02600 int opcode;
02601 bool is_load_store;
02602
02603 #if defined(DEBUG_SYM_SCRIPTS)
02604 printf("SYM: INS @ %x \n",R32(DSP));
02605 #endif
02606
02607
02608 do_pci_read(R32(DSP), &R32(DBC), 4, 1);
02609 do_pci_read(R32(DSP) + 4, &R32(DSPS), 4, 1);
02610
02611
02612 R32(DSP) += 8;
02613
02614 #if defined(DEBUG_SYM_SCRIPTS)
02615 printf("SYM: INS = %x, %x, %x \n", R8(DCMD), GET_DBC(), R32(DSPS));
02616 #endif
02617
02618
02619
02620
02621
02622
02623
02624 optype = (R8(DCMD) >> 6) & 3;
02625 switch(optype)
02626 {
02627 case 0:
02628 execute_bm_op();
02629 break;
02630
02631 case 1:
02632 opcode = (R8(DCMD) >> 3) & 7;
02633 if(opcode < 5)
02634 execute_io_op();
02635 else
02636 execute_rw_op();
02637 break;
02638
02639 case 2:
02640 execute_tc_op();
02641 break;
02642
02643 case 3:
02644 is_load_store = (R8(DCMD) >> 5) & 1;
02645 if(is_load_store)
02646 execute_ls_op();
02647 else
02648 execute_mm_op();
02649 break;
02650 }
02651
02652
02653 if(TB_R8(DCNTL, SSM))
02654 {
02655 #if defined(DEBUG_SYM_SCRIPTS)
02656 printf("SYM: Single step...\n");
02657 #endif
02658 RAISE(DSTAT, SSI);
02659 }
02660 }
02661
02690 void CSym53C895::set_interrupt(int reg, u8 interrupt)
02691 {
02692
02693 switch(reg)
02694 {
02695 case R_DSTAT:
02696 if(TB_R8(ISTAT, DIP) || TB_R8(ISTAT, SIP))
02697 {
02698 state.dstat_stack |= interrupt;
02699
02700
02701 }
02702 else
02703 {
02704 R8(DSTAT) |= interrupt;
02705
02706
02707 }
02708 break;
02709
02710 case R_SIST0:
02711 if(TB_R8(ISTAT, DIP) || TB_R8(ISTAT, SIP))
02712 {
02713 state.sist0_stack |= interrupt;
02714
02715
02716 }
02717 else
02718 {
02719 R8(SIST0) |= interrupt;
02720
02721
02722 }
02723 break;
02724
02725 case R_SIST1:
02726 if(TB_R8(ISTAT, DIP) || TB_R8(ISTAT, SIP))
02727 {
02728 state.sist1_stack |= interrupt;
02729
02730
02731 }
02732 else
02733 {
02734 R8(SIST1) |= interrupt;
02735
02736
02737 }
02738 break;
02739
02740 case R_ISTAT:
02741
02742
02743 R8(ISTAT) |= interrupt;
02744 break;
02745
02746 default:
02747 FAILURE_1(NotImplemented, "set_interrupt reg %02x!!\n", reg);
02748 }
02749
02750
02751 eval_interrupts();
02752
02753
02754 }
02755
02761 void CSym53C895::eval_interrupts()
02762 {
02763
02764
02765 bool will_assert = false;
02766
02767
02768
02769 bool will_halt = false;
02770
02771
02772
02773
02774
02775
02776
02777
02778
02779 if(!R8(SIST0) && !R8(SIST1) && !R8(DSTAT))
02780 {
02781 R8(SIST0) |= state.sist0_stack;
02782 R8(SIST1) |= state.sist1_stack;
02783 R8(DSTAT) |= state.dstat_stack;
02784 state.sist0_stack = 0;
02785 state.sist1_stack = 0;
02786 state.dstat_stack = 0;
02787 }
02788
02789
02790 if(R8(DSTAT) & DSTAT_FATAL)
02791 {
02792
02793 will_halt = true;
02794
02795
02796
02797
02798 SB_R8(ISTAT, DIP, true);
02799
02800
02801
02802 if(R8(DSTAT) & R8(DIEN) & DSTAT_FATAL)
02803 {
02804 will_assert = true;
02805
02806
02807 }
02808 }
02809 else
02810 {
02811
02812 SB_R8(ISTAT, DIP, false);
02813 }
02814
02815
02816 if(R8(SIST0) || R8(SIST1))
02817 {
02818
02819 SB_R8(ISTAT, SIP, true);
02820
02821
02822 if((R8(SIST0) & (SIST0_FATAL | R8(SIEN0)))
02823 || (R8(SIST1) & (SIST1_FATAL | R8(SIEN1))))
02824 {
02825
02826 will_halt = true;
02827
02828
02829
02830
02831 if((R8(SIST0) & R8(SIEN0)) || (R8(SIST1) & R8(SIEN1)))
02832 {
02833 will_assert = true;
02834
02835
02836 }
02837 }
02838 }
02839 else
02840 {
02841
02842 SB_R8(ISTAT, SIP, false);
02843 }
02844
02845
02846 if(TB_R8(ISTAT, INTF))
02847 {
02848
02849 will_assert = true;
02850
02851
02852 }
02853
02854
02855 if(TB_R8(DCNTL, IRQD))
02856 {
02857 will_assert = false;
02858
02859
02860 }
02861
02862
02863 if(will_halt)
02864 state.executing = false;
02865
02866
02867 if(will_assert != state.irq_asserted)
02868 {
02869
02870
02871 do_pci_interrupt(0, will_assert);
02872 state.irq_asserted = will_assert;
02873 }
02874 }