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
00067 #if defined(DEBUG_SYM)
00068 #define DEBUG_SYM_REGS
00069 #define DEBUG_SYM_SCRIPTS
00070 #endif
00071 #include "StdAfx.h"
00072 #include "Sym53C810.h"
00073 #include "System.h"
00074 #include "Disk.h"
00075 #include "SCSIBus.h"
00076
00078 #define R_SCNTL0 0x00
00079 #define R_SCNTL0_ARB1 0x80
00080 #define R_SCNTL0_ARB0 0x40
00081 #define R_SCNTL0_START 0x20
00082 #define R_SCNTL0_WATN 0x10
00083 #define R_SCNTL0_EPC 0x08
00084 #define R_SCNTL0_AAP 0x02
00085 #define R_SCNTL0_TRG 0x01
00086 #define SCNTL0_MASK 0xFB
00087
00089 #define R_SCNTL1 0x01
00090 #define R_SCNTL1_CON 0x10
00091 #define R_SCNTL1_RST 0x08
00092 #define R_SCNTL1_IARB 0x02
00093
00095 #define R_SCNTL2 0x02
00096 #define R_SCNTL2_SDU 0x80
00097 #define SCNTL2_MASK 0x80
00098
00100 #define R_SCNTL3 0x03
00101 #define SCNTL3_MASK 0x77
00102
00104 #define R_SCID 0x04
00105 #define R_SCID_ID 0x07
00106 #define SCID_MASK 0x67
00107
00109 #define R_SXFER 0x05
00110
00112 #define R_SDID 0x06
00113 #define R_SDID_ID 0x07
00114 #define SDID_MASK 0x07
00115
00117 #define R_GPREG 0x07
00118 #define GPREG_MASK 0x03
00119
00121 #define R_SFBR 0x08
00122
00124 #define R_SOCL 0x09
00125 #define R_SOCL_ACK 0x40
00126 #define R_SOCL_ATN 0x20
00127
00129 #define R_SSID 0x0A
00130 #define R_SSID_VAL 0x80
00131 #define R_SSID_ID 0x07
00132
00134 #define R_SBCL 0x0B
00135 #define R_SBCL_REQ 0x80
00136 #define R_SBCL_ACK 0x40
00137 #define R_SBCL_BSY 0x20
00138 #define R_SBCL_SEL 0x10
00139 #define R_SBCL_ATN 0x08
00140 #define R_SBCL_MSG 0x04
00141 #define R_SBCL_CD 0x02
00142 #define R_SBCL_IO 0x01
00143 #define R_SBCL_PHASE 0x07
00144
00146 #define R_DSTAT 0x0C
00147 #define R_DSTAT_DFE 0x80
00148 #define R_DSTAT_MDPE 0x40
00149 #define R_DSTAT_BF 0x20
00150 #define R_DSTAT_ABRT 0x10
00151 #define R_DSTAT_SSI 0x08
00152 #define R_DSTAT_SIR 0x04
00153 #define R_DSTAT_IID 0x01
00154 #define DSTAT_RC 0x7D
00155 #define DSTAT_FATAL 0x7D
00156
00158 #define R_SSTAT0 0x0D
00159 #define R_SSTAT0_RST 0x02
00160 #define R_SSTAT0_SDP0 0x01
00161
00163 #define R_SSTAT1 0x0E
00164 #define R_SSTAT1_SDP1 0x01
00165
00167 #define R_SSTAT2 0x0F
00168 #define R_SSTAT2_LDSC 0x02
00169
00171 #define R_DSA 0x10
00172
00174 #define R_ISTAT 0x14
00175 #define R_ISTAT_ABRT 0x80
00176 #define R_ISTAT_SRST 0x40
00177 #define R_ISTAT_SIGP 0x20
00178 #define R_ISTAT_SEM 0x10
00179 #define R_ISTAT_CON 0x08
00180 #define R_ISTAT_INTF 0x04
00181 #define R_ISTAT_SIP 0x02
00182 #define R_ISTAT_DIP 0x01
00183 #define ISTAT_MASK 0xF0
00184 #define ISTAT_W1C 0x04
00185
00187 #define R_CTEST0 0x18
00188
00190 #define R_CTEST1 0x19
00191 #define R_CTEST1_FMT 0xF0
00192 #define R_CTEST1_FFL 0x0F
00193
00195 #define R_CTEST2 0x1A
00196 #define R_CTEST2_DDIR 0x80
00197 #define R_CTEST2_SIGP 0x40
00198 #define R_CTEST2_CIO 0x20
00199 #define R_CTEST2_CM 0x10
00200 #define R_CTEST2_TEOP 0x04
00201 #define R_CTEST2_DREQ 0x02
00202 #define R_CTEST2_DACK 0x01
00203
00205 #define R_CTEST3 0x1B
00206 #define R_CTEST3_REV 0xf0
00207 #define R_CTEST3_FLF 0x08
00208 #define R_CTEST3_CLF 0x04
00209 #define R_CTEST3_FM 0x02
00210 #define CTEST3_MASK 0x0B
00211
00213 #define R_TEMP 0x1C
00214
00216 #define R_DFIFO 0x20
00217
00219 #define R_CTEST4 0x21
00220
00222 #define R_CTEST5 0x22
00223 #define R_CTEST5_ADCK 0x80
00224 #define R_CTEST5_BBCK 0x40
00225 #define CTEST5_MASK 0x18
00226
00228 #define R_DBC 0x24
00229
00231 #define R_DCMD 0x27
00232
00234 #define R_DNAD 0x28
00235
00237 #define R_DSP 0x2C
00238
00240 #define R_DSPS 0x30
00241
00243 #define R_SCRATCHA 0x34
00244
00246 #define R_DMODE 0x38
00247 #define R_DMODE_MAN 0x01
00248
00250 #define R_DIEN 0x39
00251 #define DIEN_MASK 0x7D
00252
00254 #define R_SBR 0x3A
00255
00257 #define R_DCNTL 0x3B
00258 #define R_DCNTL_SSM 0x10
00259 #define R_DCNTL_STD 0x04
00260 #define R_DCNTL_IRQD 0x02
00261 #define R_DCNTL_COM 0x01
00262 #define DCNTL_MASK 0xFB
00263
00265 #define R_ADDER 0x3C
00266
00268 #define R_SIEN0 0x40
00269 #define SIEN0_MASK 0xFF
00270
00272 #define R_SIEN1 0x41
00273 #define SIEN1_MASK 0x07
00274
00276 #define R_SIST0 0x42
00277 #define R_SIST0_MA 0x80
00278 #define R_SIST0_CMP 0x40
00279 #define R_SIST0_SEL 0x20
00280 #define R_SIST0_RSL 0x10
00281 #define R_SIST0_SGE 0x08
00282 #define R_SIST0_UDC 0x04
00283 #define R_SIST0_RST 0x02
00284 #define R_SIST0_PAR 0x01
00285 #define SIST0_RC 0xFF
00286 #define SIST0_FATAL 0x8F
00287
00289 #define R_SIST1 0x43
00290 #define R_SIST1_STO 0x04
00291 #define R_SIST1_GEN 0x02
00292 #define R_SIST1_HTH 0x01
00293 #define SIST1_RC 0x07
00294 #define SIST1_FATAL 0x04
00295
00297 #define R_MACNTL 0x46
00298 #define MACNTL_MASK 0x0F
00299
00301 #define R_GPCNTL 0x47
00302
00304 #define R_STIME0 0x48
00305
00307 #define R_STIME1 0x49
00308 #define R_STIME1_GEN 0x0F
00309 #define STIME1_MASK 0x0F
00310
00312 #define R_RESPID 0x4A
00313
00315 #define R_STEST0 0x4C
00316
00318 #define R_STEST1 0x4D
00319 #define STEST1_MASK 0xC0
00320
00322 #define R_STEST2 0x4E
00323 #define R_STEST2_SCE 0x80
00324 #define R_STEST2_ROF 0x40
00325 #define R_STEST2_SLB 0x10
00326 #define R_STEST2_SZM 0x08
00327 #define R_STEST2_EXT 0x02
00328 #define R_STEST2_LOW 0x01
00329 #define STEST2_MASK 0x9B
00330
00332 #define R_STEST3 0x4F
00333 #define R_STEST3_TE 0x80
00334 #define R_STEST3_STR 0x40
00335 #define R_STEST3_HSC 0x20
00336 #define R_STEST3_DSI 0x10
00337 #define R_STEST3_TTM 0x04
00338 #define R_STEST3_CSF 0x02
00339 #define R_STEST3_STW 0x01
00340 #define STEST3_MASK 0xF7
00341
00343 #define R_SBDL 0x58
00344
00346 #define R_SCRATCHB 0x5C
00347
00349 #define R8(a) state.regs.reg8[R_##a]
00350
00352 #define R16(a) state.regs.reg16[R_##a / 2]
00353
00355 #define R32(a) state.regs.reg32[R_##a / 4]
00356
00363 #define TB_R8(a, b) ((R8(a) & R_##a##_##b) == R_##a##_##b)
00364
00372 #define SB_R8(a, b, c) R8(a) = (R8(a) &~R_##a##_##b) | (c ? R_##a##_##b : 0)
00373
00382 #define WRM_R8(a, b) R8(a) = (R8(a) &~a##_MASK) | ((b) & a##_MASK)
00383
00394 #define WRMW1C_R8(a, b) \
00395 R8(a) = (R8(a) &~a##_MASK &~a##_W1C) | \
00396 ((b) & a##_MASK) | \
00397 (R8(a) &~(b) & a##_W1C)
00398
00405 #define RAISE(a, b) set_interrupt(R_##a, R_##a##_##b)
00406
00414 #define RDCLR_R8(a) R8(a) &= ~a##_RC
00415
00419 #define GET_DEST() (R8(SDID) & R_SCID_ID)
00420
00424 #define SET_DEST(a) R8(SDID) = (a) & R_SCID_ID
00425
00429 #define GET_DBC() (R32(DBC) & 0x00ffffff)
00430
00434 #define SET_DBC(a) \
00435 R32(DBC) = (R32(DBC) & 0xff000000) | \
00436 ((a) & 0x00ffffff)
00437
00441 static u32 osym_cfg_data[64] =
00442 {
00443 0x00011000,
00444 0x02000001,
00445 0x01000001,
00446 0x00000000,
00447 0x00000001,
00448 0x00000000,
00449 0x00000000,
00450 0x00000000,
00451 0x00000000,
00452 0x00000000,
00453 0x00000000,
00454 0x00000000,
00455 0x00000000,
00456 0x00000000,
00457 0x00000000,
00458 0x401101ff,
00459 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00460 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00461 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00462 };
00463
00467 static u32 osym_cfg_mask[64] = {
00468 0x00000000,
00469 0x00000157,
00470 0x00000000,
00471 0x0000ffff,
00472 0xffffff00,
00473 0xffffff00,
00474 0x00000000,
00475 0x00000000,
00476 0x00000000,
00477 0x00000000,
00478 0x00000000,
00479 0x00000000,
00480 0x00000000,
00481 0x00000000,
00482 0x00000000,
00483 0x000000ff,
00484 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00485 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00486 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00487 };
00488
00497 void CSym53C810::run()
00498 {
00499 try
00500 {
00501 for(;;)
00502 {
00503 mySemaphore.wait();
00504 if(StopThread)
00505 return;
00506 while(state.executing)
00507 {
00508 MUTEX_LOCK(myRegLock);
00509 execute();
00510 MUTEX_UNLOCK(myRegLock);
00511 }
00512 }
00513 }
00514
00515 catch(Poco::Exception & e)
00516 {
00517 printf("Exception in SYM thread: %s.\n", e.displayText().c_str());
00518
00519
00520 }
00521 }
00522
00529 CSym53C810::CSym53C810(CConfigurator* cfg, CSystem* c, int pcibus, int pcidev) : CDiskController(cfg, c, pcibus, pcidev, 1, 7), mySemaphore(0, 1)
00530 {
00531
00532
00533 CSCSIBus* a = new CSCSIBus(cfg, c);
00534 scsi_register(0, a, 7);
00535 }
00536
00542 void CSym53C810::init()
00543 {
00544 add_function(0, osym_cfg_data, osym_cfg_mask);
00545
00546 ResetPCI();
00547
00548 chip_reset();
00549
00550 myRegLock = new CMutex("sym-reg");
00551
00552 myThread = 0;
00553
00554 printf("%s: $Id: Sym53C810.cpp,v 1.12 2008/03/25 20:46:20 iamcamiel Exp $\n",
00555 devid_string);
00556 }
00557
00561 void CSym53C810::start_threads()
00562 {
00563 if(!myThread)
00564 {
00565 myThread = new Poco::Thread("sym");
00566 printf(" %s", myThread->getName().c_str());
00567 StopThread = false;
00568 myThread->start(*this);
00569 if(state.executing)
00570 mySemaphore.set();
00571 }
00572 }
00573
00577 void CSym53C810::stop_threads()
00578 {
00579 StopThread = true;
00580 if(myThread)
00581 {
00582 printf(" %s", myThread->getName().c_str());
00583 mySemaphore.set();
00584 myThread->join();
00585 delete myThread;
00586 myThread = 0;
00587 }
00588 }
00589
00595 CSym53C810::~CSym53C810()
00596 {
00597 stop_threads();
00598 delete scsi_bus[0];
00599 }
00600
00606 void CSym53C810::chip_reset()
00607 {
00608 state.executing = false;
00609 state.wait_reselect = false;
00610 state.irq_asserted = false;
00611 state.gen_timer = 0;
00612 memset(state.regs.reg32, 0, sizeof(state.regs.reg32));
00613 R8(SCNTL0) = R_SCNTL0_ARB1 | R_SCNTL0_ARB0;
00614 R8(DSTAT) = R_DSTAT_DFE;
00615
00616
00617 R8(CTEST1) = R_CTEST1_FMT;
00618 R8(CTEST2) = R_CTEST2_DACK;
00619 R8(CTEST3) = (u8) (pci_state.config_data[0][2] << 4) & R_CTEST3_REV;
00620 R8(MACNTL) = 0x40;
00621 R8(GPCNTL) = 0x0F;
00622 R8(STEST0) = 0x03;
00623 }
00624
00630 void CSym53C810::register_disk(class CDisk* dsk, int bus, int dev)
00631 {
00632 CDiskController::register_disk(dsk, bus, dev);
00633 dsk->scsi_register(0, scsi_bus[0], dev);
00634 }
00635
00636 static u32 sym_magic1 = 0x53C810CC;
00637 static u32 sym_magic2 = 0xCC53C810;
00638
00642 int CSym53C810::SaveState(FILE* f)
00643 {
00644 long ss = sizeof(state);
00645 int res;
00646
00647 if(res = CPCIDevice::SaveState(f))
00648 return res;
00649
00650 fwrite(&sym_magic1, sizeof(u32), 1, f);
00651 fwrite(&ss, sizeof(long), 1, f);
00652 fwrite(&state, sizeof(state), 1, f);
00653 fwrite(&sym_magic2, sizeof(u32), 1, f);
00654 printf("%s: %d bytes saved.\n", devid_string, (int) ss);
00655 return 0;
00656 }
00657
00661 int CSym53C810::RestoreState(FILE* f)
00662 {
00663 long ss;
00664 u32 m1;
00665 u32 m2;
00666 int res;
00667 size_t r;
00668
00669 if(res = CPCIDevice::RestoreState(f))
00670 return res;
00671
00672 r = fread(&m1, sizeof(u32), 1, f);
00673 if(r != 1)
00674 {
00675 printf("%s: unexpected end of file!\n", devid_string);
00676 return -1;
00677 }
00678
00679 if(m1 != sym_magic1)
00680 {
00681 printf("%s: MAGIC 1 does not match!\n", devid_string);
00682 return -1;
00683 }
00684
00685 fread(&ss, sizeof(long), 1, f);
00686 if(r != 1)
00687 {
00688 printf("%s: unexpected end of file!\n", devid_string);
00689 return -1;
00690 }
00691
00692 if(ss != sizeof(state))
00693 {
00694 printf("%s: STRUCT SIZE does not match!\n", devid_string);
00695 return -1;
00696 }
00697
00698 fread(&state, sizeof(state), 1, f);
00699 if(r != 1)
00700 {
00701 printf("%s: unexpected end of file!\n", devid_string);
00702 return -1;
00703 }
00704
00705 r = fread(&m2, sizeof(u32), 1, f);
00706 if(r != 1)
00707 {
00708 printf("%s: unexpected end of file!\n", devid_string);
00709 return -1;
00710 }
00711
00712 if(m2 != sym_magic2)
00713 {
00714 printf("%s: MAGIC 1 does not match!\n", devid_string);
00715 return -1;
00716 }
00717
00718 printf("%s: %d bytes restored.\n", devid_string, (int) ss);
00719 return 0;
00720 }
00721
00725 void CSym53C810::WriteMem_Bar(int func, int bar, u32 address, int dsize, u32 data)
00726 {
00727 void* p;
00728
00729 switch(bar)
00730 {
00731 case 0:
00732 case 1:
00733 address &= 0x7f;
00734 switch(dsize)
00735 {
00736 case 8:
00737 MUTEX_LOCK(myRegLock);
00738 #if defined(DEBUG_SYM_REGS)
00739 printf("SYM: Write to register %02x: %02x. \n", address, data);
00740 #endif
00741 if(address >= R_SCRATCHB)
00742 {
00743 state.regs.reg8[address] = (u8) data;
00744 MUTEX_UNLOCK(myRegLock);
00745 break;
00746 }
00747
00748 switch(address)
00749 {
00750
00751
00752 case R_SXFER:
00753 case R_DSA:
00754 case R_DSA + 1:
00755 case R_DSA + 2:
00756 case R_DSA + 3:
00757 case R_CTEST0:
00758 case R_TEMP:
00759 case R_TEMP + 1:
00760 case R_TEMP + 2:
00761 case R_TEMP + 3:
00762 case R_DSP:
00763 case R_DSP + 1:
00764 case R_DSP + 2:
00765 case R_DSPS:
00766 case R_DSPS + 1:
00767 case R_DSPS + 2:
00768 case R_DSPS + 3:
00769 case R_SCRATCHA:
00770 case R_SCRATCHA + 1:
00771 case R_SCRATCHA + 2:
00772 case R_SCRATCHA + 3:
00773 case R_DMODE:
00774 case R_SBR:
00775 case R_GPCNTL:
00776 case R_STIME0:
00777 case R_RESPID:
00778 case R_STEST0:
00779 state.regs.reg8[address] = (u8) data;
00780 break;
00781
00782 case R_SCNTL0:
00783
00784 write_b_scntl0((u8) data);
00785 break;
00786
00787 case R_SCNTL1:
00788
00789 write_b_scntl1((u8) data);
00790 break;
00791
00792 case R_SCNTL2:
00793 WRM_R8(SCNTL2, (u8) data);
00794 break;
00795
00796 case R_SCNTL3:
00797
00798 WRM_R8(SCNTL3, (u8) data);
00799 break;
00800
00801 case R_SCID:
00802 WRM_R8(SCID, (u8) data);
00803 break;
00804
00805 case R_SDID:
00806 WRM_R8(SDID, (u8) data);
00807 break;
00808
00809 case R_GPREG:
00810 WRM_R8(GPREG, (u8) data);
00811 break;
00812
00813 case R_ISTAT:
00814 write_b_istat((u8) data);
00815 break;
00816
00817 case R_CTEST3:
00818 write_b_ctest3((u8) data);
00819 break;
00820
00821 case R_CTEST4:
00822 write_b_ctest4((u8) data);
00823 break;
00824
00825 case R_CTEST5:
00826 write_b_ctest5((u8) data);
00827 break;
00828
00829 case R_DSP + 3:
00830 state.regs.reg8[address] = (u8) data;
00831 post_dsp_write();
00832 break;
00833
00834 case R_DIEN:
00835 WRM_R8(DIEN, (u8) data);
00836 eval_interrupts();
00837 break;
00838
00839 case R_DCNTL:
00840 write_b_dcntl((u8) data);
00841 break;
00842
00843 case R_SIEN0:
00844 R8(SIEN0) = (u8) data;
00845 eval_interrupts();
00846 break;
00847
00848 case R_SIEN1:
00849 WRM_R8(SIEN1, (u8) data);
00850 eval_interrupts();
00851 break;
00852
00853 case R_MACNTL:
00854 WRM_R8(MACNTL, (u8) data);
00855 break;
00856
00857 case R_STIME1:
00858 WRM_R8(STIME1, (u8) data);
00859 state.gen_timer = (R8(STIME1) & R_STIME1_GEN) * 30;
00860 break;
00861
00862 case R_STEST1:
00863 WRM_R8(STEST1, (u8) data);
00864 break;
00865
00866 case R_STEST2:
00867 write_b_stest2((u8) data);
00868 break;
00869
00870 case R_STEST3:
00871 write_b_stest3((u8) data);
00872 break;
00873
00874 case R_DSTAT:
00875 case R_SSTAT0:
00876 case R_SSTAT1:
00877 case R_SSTAT2:
00878 case R_CTEST2:
00879
00880 break;
00881
00882 case 0x4b:
00883
00884 break;
00885
00886 default:
00887 FAILURE_2(NotImplemented,
00888 "SYM: Write to unknown register at %02x with %08x.\n", address,
00889 data);
00890 }
00891
00892 MUTEX_UNLOCK(myRegLock);
00893 break;
00894
00895 case 16:
00896 WriteMem_Bar(0, 1, address + 0, 8, (data >> 0) & 0xff);
00897 WriteMem_Bar(0, 1, address + 1, 8, (data >> 8) & 0xff);
00898 break;
00899
00900 case 32:
00901 WriteMem_Bar(0, 1, address + 0, 8, (data >> 0) & 0xff);
00902 WriteMem_Bar(0, 1, address + 1, 8, (data >> 8) & 0xff);
00903 WriteMem_Bar(0, 1, address + 2, 8, (data >> 16) & 0xff);
00904 WriteMem_Bar(0, 1, address + 3, 8, (data >> 24) & 0xff);
00905 break;
00906 }
00907 break;
00908
00909 case 2:
00910 p = (u8*) state.ram + address;
00911 switch(dsize)
00912 {
00913 case 8: *((u8*) p) = (u8) data; break;
00914 case 16: *((u16*) p) = (u16) data; break;
00915 case 32: *((u32*) p) = (u32) data; break;
00916 }
00917 break;
00918 }
00919 }
00920
00924 u32 CSym53C810::ReadMem_Bar(int func, int bar, u32 address, int dsize)
00925 {
00926 u32 data = 0;
00927 void* p;
00928
00929 switch(bar)
00930 {
00931 case 0:
00932 case 1:
00933 address &= 0x7f;
00934 switch(dsize)
00935 {
00936 case 8:
00937 MUTEX_LOCK(myRegLock);
00938 if(address >= R_SCRATCHB)
00939 {
00940 data = state.regs.reg8[address];
00941 MUTEX_UNLOCK(myRegLock);
00942 break;
00943 }
00944
00945 switch(address)
00946 {
00947 case R_SCNTL0:
00948 case R_SCNTL1:
00949 case R_SCNTL2:
00950 case R_SCNTL3:
00951 case R_SCID:
00952 case R_SXFER:
00953 case R_SDID:
00954 case R_GPREG:
00955 case R_SFBR:
00956 case R_SSID:
00957 case R_SBCL:
00958 case R_SSTAT0:
00959 case R_SSTAT1:
00960 case R_SSTAT2:
00961 case R_DSA:
00962 case R_DSA + 1:
00963 case R_DSA + 2:
00964 case R_DSA + 3:
00965 case R_ISTAT:
00966 case R_CTEST0:
00967 case R_CTEST1:
00968 case R_CTEST3:
00969 case R_TEMP:
00970 case R_TEMP + 1:
00971 case R_TEMP + 2:
00972 case R_TEMP + 3:
00973 case R_CTEST4:
00974 case R_CTEST5:
00975 case R_DBC:
00976 case R_DBC + 1:
00977 case R_DBC + 2:
00978 case R_DCMD:
00979 case R_DNAD:
00980 case R_DNAD + 1:
00981 case R_DNAD + 2:
00982 case R_DNAD + 3:
00983 case R_DSP:
00984 case R_DSP + 1:
00985 case R_DSP + 2:
00986 case R_DSP + 3:
00987 case R_DSPS:
00988 case R_DSPS + 1:
00989 case R_DSPS + 2:
00990 case R_DSPS + 3:
00991 case R_SCRATCHA:
00992 case R_SCRATCHA + 1:
00993 case R_SCRATCHA + 2:
00994 case R_SCRATCHA + 3:
00995 case R_DMODE:
00996 case R_DIEN:
00997 case R_SBR:
00998 case R_DCNTL:
00999 case R_SIEN0:
01000 case R_SIEN1:
01001 case R_MACNTL:
01002 case R_GPCNTL:
01003 case R_STIME0:
01004 case R_STIME1:
01005 case R_RESPID:
01006 case R_STEST0:
01007 case R_STEST1:
01008 case R_STEST2:
01009 case R_STEST3:
01010 case R_SBDL:
01011 data = state.regs.reg8[address];
01012 break;
01013
01014 case R_DSTAT:
01015 data = read_b_dstat();
01016 break;
01017
01018 case R_CTEST2:
01019 data = read_b_ctest2();
01020 break;
01021
01022 case R_DFIFO:
01023 data = R8(DBC) & 0x7f;
01024 break;
01025
01026 case R_SIST0:
01027 case R_SIST1:
01028 data = read_b_sist(address - R_SIST0);
01029 break;
01030
01031 case 0x17:
01032 case 0x4b:
01033 case 0x52:
01034 case 0x59:
01035
01036 data = 0;
01037 break;
01038
01039 default:
01040 FAILURE_2(NotImplemented,
01041 "SYM: Attempt to read from unknown register at %02x\n", dsize,
01042 address);
01043 }
01044
01045 MUTEX_UNLOCK(myRegLock);
01046 #if defined(DEBUG_SYM_REGS)
01047 printf("SYM: Read frm register %02x: %02x. \n", address, data);
01048 #endif
01049 break;
01050
01051 case 16:
01052 data = (ReadMem_Bar(0, 1, address + 0, 8) << 0) & 0x00ff;
01053 data |= (ReadMem_Bar(0, 1, address + 1, 8) << 8) & 0xff00;
01054 break;
01055
01056 case 32:
01057 data = (ReadMem_Bar(0, 1, address + 0, 8) << 0) & 0x000000ff;
01058 data |= (ReadMem_Bar(0, 1, address + 1, 8) << 8) & 0x0000ff00;
01059 data |= (ReadMem_Bar(0, 1, address + 2, 8) << 16) & 0x00ff0000;
01060 data |= (ReadMem_Bar(0, 1, address + 3, 8) << 24) & 0xff000000;
01061 break;
01062 }
01063 break;
01064
01065 case 2:
01066 p = (u8*) state.ram + address;
01067 switch(dsize)
01068 {
01069 case 8: return *((u8*) p);
01070 case 16: return *((u16*) p);
01071 case 32: return *((u32*) p);
01072 }
01073 break;
01074 }
01075
01076 return data;
01077 }
01078
01085 u32 CSym53C810::config_read_custom(int func, u32 address, int dsize, u32 data)
01086 {
01087 if(address >= 0x80)
01088 return ReadMem_Bar(func, 1, address - 0x80, dsize);
01089 else
01090 return data;
01091 }
01092
01099 void CSym53C810::config_write_custom(int func, u32 address, int dsize,
01100 u32 old_data, u32 new_data, u32 data)
01101 {
01102 if(address >= 0x80)
01103 WriteMem_Bar(func, 1, address - 0x80, dsize, data);
01104 }
01105
01121 void CSym53C810::write_b_scntl0(u8 value)
01122 {
01123 bool old_start = TB_R8(SCNTL0, START);
01124
01125 WRM_R8(SCNTL0, value);
01126
01127 if(TB_R8(SCNTL0, START) && !old_start)
01128 FAILURE(NotImplemented, "SYM: Don't know how to start arbitration sequence");
01129
01130 if(TB_R8(SCNTL0, TRG))
01131 FAILURE(NotImplemented, "SYM: Don't know how to operate in target mode");
01132 }
01133
01150 void CSym53C810::write_b_scntl1(u8 value)
01151 {
01152 bool old_iarb = TB_R8(SCNTL1, IARB);
01153 bool old_con = TB_R8(SCNTL1, CON);
01154 bool old_rst = TB_R8(SCNTL1, RST);
01155
01156 R8(SCNTL1) = value;
01157
01158
01159
01160 if(TB_R8(SCNTL1, RST) != old_rst)
01161 {
01162 SB_R8(SSTAT0, SDP0, false);
01163 SB_R8(SSTAT1, SDP1, false);
01164 R16(SBDL) = 0;
01165 R8(SBCL) = 0;
01166
01167 SB_R8(SSTAT0, RST, !old_rst);
01168
01169
01170 if(!old_rst)
01171 RAISE(SIST0, RST);
01172 }
01173
01174 }
01175
01192 void CSym53C810::write_b_istat(u8 value)
01193 {
01194 bool old_srst = TB_R8(ISTAT, SRST);
01195 bool old_sem = TB_R8(ISTAT, SEM);
01196 bool old_sigp = TB_R8(ISTAT, SIGP);
01197
01198 WRMW1C_R8(ISTAT, value);
01199
01200 if(TB_R8(ISTAT, ABRT))
01201 {
01202
01203
01204 RAISE(DSTAT, ABRT);
01205 }
01206
01207 if(TB_R8(ISTAT, SRST) && !old_srst)
01208 {
01209
01210
01211 chip_reset();
01212 }
01213
01214
01215
01216
01217
01218 if(TB_R8(ISTAT, SIGP))
01219 {
01220 if(state.wait_reselect)
01221 {
01222
01223
01224 R32(DSP) = state.wait_jump;
01225 state.wait_reselect = false;
01226 state.executing = true;
01227 mySemaphore.set();
01228 }
01229 }
01230
01231 eval_interrupts();
01232 }
01233
01246 u8 CSym53C810::read_b_ctest2()
01247 {
01248 SB_R8(CTEST2, CIO, pci_state.config_data[0][4] != 0);
01249 SB_R8(CTEST2, CM, pci_state.config_data[0][5] != 0);
01250 SB_R8(CTEST2, SIGP, TB_R8(ISTAT, SIGP));
01251 SB_R8(ISTAT, SIGP, false);
01252
01253
01254 return R8(CTEST2);
01255 }
01256
01270 void CSym53C810::write_b_ctest3(u8 value)
01271 {
01272 WRM_R8(CTEST3, value);
01273
01274
01275
01276
01277
01278 if((value >> 1) & 1)
01279 FAILURE(NotImplemented, "SYM: Don't know how to handle FM mode");
01280 }
01281
01292 void CSym53C810::write_b_ctest4(u8 value)
01293 {
01294 R8(CTEST4) = value;
01295
01296 if((value >> 4) & 1)
01297 FAILURE(NotImplemented, "SYM: Don't know how to handle SRTM mode");
01298 }
01299
01318 void CSym53C810::write_b_ctest5(u8 value)
01319 {
01320 WRM_R8(CTEST5, value);
01321
01322 if((value >> 7) & 1)
01323 FAILURE(NotImplemented, "SYM: Don't know how to do Clock Address increment");
01324
01325 if((value >> 6) & 1)
01326 FAILURE(NotImplemented,
01327 "SYM: Don't know how to do Clock Byte Counter decrement");
01328 }
01329
01336 u8 CSym53C810::read_b_dstat()
01337 {
01338 u8 retval = R8(DSTAT);
01339
01340 RDCLR_R8(DSTAT);
01341
01342
01343 eval_interrupts();
01344
01345
01346 return retval;
01347 }
01348
01355 u8 CSym53C810::read_b_sist(int id)
01356 {
01357 u8 retval = state.regs.reg8[R_SIST0 + id];
01358
01359 if(id)
01360 RDCLR_R8(SIST1);
01361 else
01362 RDCLR_R8(SIST0);
01363
01364 eval_interrupts();
01365
01366 return retval;
01367 }
01368
01381 void CSym53C810::write_b_dcntl(u8 value)
01382 {
01383 WRM_R8(DCNTL, value);
01384
01385
01386 if(value & R_DCNTL_STD)
01387 {
01388 state.executing = true;
01389 mySemaphore.set();
01390 }
01391
01392
01393 eval_interrupts();
01394 }
01395
01407 void CSym53C810::write_b_stest2(u8 value)
01408 {
01409 WRM_R8(STEST2, value);
01410
01411
01412
01413 if(TB_R8(STEST2, LOW))
01414 FAILURE(NotImplemented, "SYM: I don't like LOW level mode");
01415 }
01416
01424 void CSym53C810::write_b_stest3(u8 value)
01425 {
01426 WRM_R8(STEST3, value);
01427
01428
01429
01430 }
01431
01437 void CSym53C810::post_dsp_write()
01438 {
01439 if(!TB_R8(DMODE, MAN))
01440 {
01441 state.executing = true;
01442 mySemaphore.set();
01443
01444
01445 }
01446 }
01447
01451 void CSym53C810::check_state()
01452 {
01453 if(myThread && !myThread->isRunning())
01454 FAILURE(Thread, "SYM thread has died");
01455
01456 if(state.gen_timer)
01457 {
01458 state.gen_timer--;
01459 if(!state.gen_timer)
01460 {
01461 state.gen_timer = (R8(STIME1) & R_STIME1_GEN) * 30;
01462 RAISE(SIST1, GEN);
01463 return;
01464 }
01465 }
01466
01488 if(state.disconnected)
01489 {
01490 if(!TB_R8(SCNTL2, SDU))
01491 {
01492
01493
01494
01495 state.disconnected = 0;
01496 return;
01497 }
01498
01499 state.disconnected--;
01500 if(!state.disconnected)
01501 {
01502
01503
01504
01505
01506 RAISE(SIST0, UDC);
01507 return;
01508 }
01509 }
01510 }
01511
01518 int CSym53C810::check_phase(int chk_phase)
01519 {
01520 int real_phase = scsi_get_phase(0);
01521
01522 if(real_phase == SCSI_PHASE_ARBITRATION)
01523 {
01524 #if defined(DEBUG_SYM_SCRIPTS)
01525 printf("Phase check... selection time-out!\n");
01526 #endif
01527 RAISE(SIST1, STO);
01528 scsi_free(0);
01529 state.select_timeout = false;
01530 return -1;
01531 }
01532
01533 if(real_phase == SCSI_PHASE_FREE && state.disconnected)
01534 {
01535 #if defined(DEBUG_SYM_SCRIPTS)
01536 printf("Phase check... disconnected!\n");
01537 #endif
01538 state.disconnected = 1;
01539 R32(DSP) -= 8;
01540 return -1;
01541 }
01542
01543 if (real_phase == chk_phase)
01544 return 1;
01545 else
01546 return 0;
01547 }
01548
01584 void CSym53C810::execute_bm_op()
01585 {
01586 bool indirect = (R8(DCMD) >> 5) & 1;
01587 bool table_indirect = (R8(DCMD) >> 4) & 1;
01588 int opcode = (R8(DCMD) >> 3) & 1;
01589 int scsi_phase = (R8(DCMD) >> 0) & 7;
01590
01591 #if defined(DEBUG_SYM_SCRIPTS)
01592 printf("SYM: INS = Block Move (i %d, t %d, opc %d, phase %d\n", indirect,
01593 table_indirect, opcode, scsi_phase);
01594 #endif
01595
01596 if(check_phase(scsi_phase)>0)
01597 {
01598 #if defined(DEBUG_SYM_SCRIPTS)
01599 printf("SYM: Ready for transfer.\n");
01600 #endif
01601
01602 u32 start;
01603 u32 count;
01604
01605 if(table_indirect)
01606 {
01607 u32 add = R32(DSA) + sext_u32_24(R32(DSPS));
01608
01609 add &= ~0x03;
01610 #if defined(DEBUG_SYM_SCRIPTS)
01611 printf("SYM: Reading table at DSA(%08x)+DSPS(%08x) = %08x.\n",
01612 R32(DSA), R32(DSPS), add);
01613 #endif
01614 do_pci_read(add, &count, 4, 1);
01615 count &= 0x00ffffff;
01616 do_pci_read(add + 4, &start, 4, 1);
01617 }
01618 else if(indirect)
01619 {
01620 FAILURE(NotImplemented, "SYM: Unsupported: indirect addressing");
01621 }
01622 else
01623 {
01624 start = R32(DSPS);
01625 count = GET_DBC();
01626 }
01627
01628 #if defined(DEBUG_SYM_SCRIPTS)
01629 printf("SYM: %08x: MOVE Start/count %x, %x\n", R32(DSP) - 8, start,
01630 count);
01631 #endif
01632 R32(DNAD) = start;
01633 SET_DBC(count);
01634 if(count == 0)
01635 {
01636
01637
01638 RAISE(DSTAT, IID);
01639 return;
01640 }
01641
01642 if((size_t) count > scsi_expected_xfer(0))
01643 {
01644 #if defined(DEBUG_SYM_SCRIPTS)
01645 printf("SYM: xfer %d bytes, max %d expected, in phase %d.\n", count,
01646 scsi_expected_xfer(0), scsi_phase);
01647 #endif
01648 count = (u32) scsi_expected_xfer(0);
01649 }
01650
01651 u8* scsi_data_ptr = (u8*) scsi_xfer_ptr(0, count);
01652 u8* org_sdata_ptr = scsi_data_ptr;
01653
01654 switch(scsi_phase)
01655 {
01656 case SCSI_PHASE_COMMAND:
01657 case SCSI_PHASE_DATA_OUT:
01658 case SCSI_PHASE_MSG_OUT:
01659 do_pci_read(R32(DNAD), scsi_data_ptr, 1, count);
01660 R32(DNAD) += count;
01661 break;
01662
01663 case SCSI_PHASE_STATUS:
01664 case SCSI_PHASE_DATA_IN:
01665 case SCSI_PHASE_MSG_IN:
01666 do_pci_write(R32(DNAD), scsi_data_ptr, 1, count);
01667 R32(DNAD) += count;
01668 break;
01669 }
01670
01671 R8(SFBR) = *org_sdata_ptr;
01672 scsi_xfer_done(0);
01673 return;
01674 }
01675 }
01676
01677
01678
01679
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689
01690
01691
01692
01693
01694
01695
01696
01697
01698
01699
01700
01701
01702
01703
01704
01705
01706
01707
01708
01709
01710
01711
01712
01713
01714
01715
01716
01717
01718
01719
01720
01721
01722
01723
01724
01725
01726
01727
01728
01729
01730
01731
01732
01733
01734
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747
01748
01749
01750
01751
01752
01753
01754 void CSym53C810::execute_io_op()
01755 {
01756 int opcode = (R8(DCMD) >> 3) & 7;
01757 bool relative = (R8(DCMD) >> 2) & 1;
01758 bool table_indirect = (R8(DCMD) >> 1) & 1;
01759 bool atn = (R8(DCMD) >> 0) & 1;
01760 int destination = (GET_DBC() >> 16) & 0x0f;
01761 bool sc_carry = (GET_DBC() >> 10) & 1;
01762 bool sc_target = (GET_DBC() >> 9) & 1;
01763 bool sc_ack = (GET_DBC() >> 6) & 1;
01764 bool sc_atn = (GET_DBC() >> 3) & 1;
01765
01766 R32(DNAD) = R32(DSPS);
01767
01768 u32 dest_addr = R32(DNAD);
01769
01770 if(relative)
01771 dest_addr = R32(DSP) + sext_u32_24(R32(DNAD));
01772
01773 #if defined(DEBUG_SYM_SCRIPTS)
01774 printf("SYM: INS = I/O (opc %d, r %d, t %d, a %d, dest %d, sc %d%d%d%d\n",
01775 opcode, relative, table_indirect, atn, destination, sc_carry,
01776 sc_target, sc_ack, sc_atn);
01777 #endif
01778 if(table_indirect)
01779 {
01780 u32 io_addr = R32(DSA) + sext_u32_24(GET_DBC());
01781 io_addr &= ~3;
01782 #if defined(DEBUG_SYM_SCRIPTS)
01783 printf("SYM: Reading table at DSA(%08x)+DBC(%08x) = %08x.\n",
01784 R32(DSA), sext_u32_24(GET_DBC()), io_addr);
01785 #endif
01786
01787 u32 io_struc;
01788 do_pci_read(io_addr, &io_struc, 4, 1);
01789 destination = (io_struc >> 16) & 0x0f;
01790 #if defined(DEBUG_SYM_SCRIPTS)
01791 printf("SYM: table indirect. io_struct = %08x, new dest = %d.\n",
01792 io_struc, destination);
01793 #endif
01794 }
01795
01796 switch(opcode)
01797 {
01798 case 0:
01799 #if defined(DEBUG_SYM_SCRIPTS)
01800 printf("SYM: %08x: SELECT %d.\n", R32(DSP) - 8, destination);
01801 #endif
01802 SET_DEST(destination);
01803 if(!scsi_arbitrate(0))
01804 {
01805
01806
01807 printf("scsi bus busy...\n");
01808 R32(DSP) -= 8;
01809 return;
01810 }
01811
01812 state.select_timeout = !scsi_select(0, destination);
01813 if(!state.select_timeout)
01814 SB_R8(SCNTL2, SDU, true);
01815 return;
01816
01817 case 1:
01818 #if defined(DEBUG_SYM_SCRIPTS)
01819 printf("SYM: %08x: WAIT DISCONNECT\n", R32(DSP) - 8);
01820 #endif
01821
01822
01823 scsi_free(0);
01824 return;
01825
01826 case 2:
01827 #if defined(DEBUG_SYM_SCRIPTS)
01828 printf("SYM: %08x: WAIT RESELECT\n", R32(DSP) - 8);
01829 #endif
01830 if(TB_R8(ISTAT, SIGP))
01831 {
01832 #if defined(DEBUG_SYM_SCRIPTS)
01833 printf("SYM: SIGP set before wait reselect; jumping!\n");
01834 #endif
01835 R32(DSP) = dest_addr;
01836 }
01837 else
01838 {
01839 state.wait_reselect = true;
01840 state.wait_jump = dest_addr;
01841 state.executing = false;
01842 }
01843
01844 return;
01845
01846 case 3:
01847 #if defined(DEBUG_SYM_SCRIPTS)
01848 printf("SYM: %08x: SET %s%s%s%s\n", R32(DSP) - 8,
01849 sc_carry ? "carry " : "", sc_target ? "target " : "",
01850 sc_ack ? "ack " : "", sc_atn ? "atn " : "");
01851 #endif
01852 if(sc_ack)
01853 SB_R8(SOCL, ACK, true);
01854 if(sc_atn)
01855 {
01856 if(!TB_R8(SOCL, ATN))
01857 {
01858 SB_R8(SOCL, ATN, true);
01859
01860
01861
01862
01863 }
01864 }
01865
01866 if(sc_target)
01867 SB_R8(SCNTL0, TRG, true);
01868 if(sc_carry)
01869 state.alu.carry = true;
01870 return;
01871
01872 case 4:
01873 #if defined(DEBUG_SYM_SCRIPTS)
01874 printf("SYM: %08x: CLEAR %s%s%s%s\n", R32(DSP) - 8,
01875 sc_carry ? "carry " : "", sc_target ? "target " : "",
01876 sc_ack ? "ack " : "", sc_atn ? "atn " : "");
01877 #endif
01878 if(sc_ack)
01879 SB_R8(SOCL, ACK, false);
01880 if(sc_atn)
01881 {
01882 if(TB_R8(SOCL, ATN))
01883 {
01884 SB_R8(SOCL, ATN, false);
01885
01886
01887
01888
01889 }
01890 }
01891
01892 if(sc_target)
01893 SB_R8(SCNTL0, TRG, false);
01894 if(sc_carry)
01895 state.alu.carry = false;
01896 return;
01897
01898 break;
01899 }
01900 }
01901
01939 void CSym53C810::execute_rw_op()
01940 {
01941 int opcode = (R8(DCMD) >> 3) & 7;
01942 int oper = (R8(DCMD) >> 0) & 7;
01943 bool use_data8_sfbr = (GET_DBC() >> 23) & 1;
01944 int reg_address = ((GET_DBC() >> 16) & 0x7f);
01945 u8 imm_data = (u8) (GET_DBC() >> 8) & 0xff;
01946 u8 op_data;
01947
01948 #if defined(DEBUG_SYM_SCRIPTS)
01949 printf("SYM: INS = R/W (opc %d, oper %d, use %d, add %d, imm %02x\n",
01950 opcode, oper, use_data8_sfbr, reg_address, imm_data);
01951 #endif
01952 if(use_data8_sfbr)
01953 imm_data = R8(SFBR);
01954
01955 if(oper != 0)
01956 {
01957 if(opcode == 5 || reg_address == 0x08)
01958 {
01959 op_data = R8(SFBR);
01960 #if defined(DEBUG_SYM_SCRIPTS)
01961 printf("SYM: %08x: sfbr (%02x) ", R32(DSP) - 8, op_data);
01962 #endif
01963 }
01964 else
01965 {
01966 op_data = (u8) ReadMem_Bar(0, 1, reg_address, 8);
01967 #if defined(DEBUG_SYM_SCRIPTS)
01968 printf("SYM: %08x: reg%02x (%02x) ", R32(DSP) - 8, reg_address,
01969 op_data);
01970 #endif
01971 }
01972 }
01973
01974 u16 tmp16;
01975
01976 switch(oper)
01977 {
01978 case 0:
01979 op_data = imm_data;
01980 #if defined(DEBUG_SYM_SCRIPTS)
01981 printf("SYM: %08x: %02x ", R32(DSP) - 8, imm_data);
01982 #endif
01983 break;
01984
01985 case 1:
01986 tmp16 = (op_data << 1) + (state.alu.carry ? 1 : 0);
01987 state.alu.carry = (tmp16 >> 8) & 1;
01988 op_data = tmp16 & 0xff;
01989 #if defined(DEBUG_SYM_SCRIPTS)
01990 printf("<< 1 = %02x ", op_data);
01991 #endif
01992 break;
01993
01994 case 2:
01995 op_data |= imm_data;
01996 #if defined(DEBUG_SYM_SCRIPTS)
01997 printf("| %02x = %02x ", imm_data, op_data);
01998 #endif
01999 break;
02000
02001 case 3:
02002 op_data ^= imm_data;
02003 #if defined(DEBUG_SYM_SCRIPTS)
02004 printf("^ %02x = %02x ", imm_data, op_data);
02005 #endif
02006 break;
02007
02008 case 4:
02009 op_data &= imm_data;
02010 #if defined(DEBUG_SYM_SCRIPTS)
02011 printf("& %02x = %02x ", imm_data, op_data);
02012 #endif
02013 break;
02014
02015 case 5:
02016 tmp16 = (op_data >> 1) + (state.alu.carry ? 0x80 : 0x00);
02017 state.alu.carry = op_data & 1;
02018 op_data = tmp16 & 0xff;
02019 #if defined(DEBUG_SYM_SCRIPTS)
02020 printf(">> 1 = %02x ", op_data);
02021 #endif
02022 break;
02023
02024 case 6:
02025 tmp16 = op_data + imm_data;
02026 state.alu.carry = (tmp16 > 0xff);
02027 op_data = tmp16 & 0xff;
02028 #if defined(DEBUG_SYM_SCRIPTS)
02029 printf("+ %02x = %02x (carry %d) ", imm_data, op_data, state.alu.carry);
02030 #endif
02031 break;
02032
02033 case 7:
02034 tmp16 = op_data + imm_data + (state.alu.carry ? 1 : 0);
02035 state.alu.carry = (tmp16 > 0xff);
02036 op_data = tmp16 & 0xff;
02037 #if defined(DEBUG_SYM_SCRIPTS)
02038 printf("+ %02x (w/carry) = %02x (carry %d) ", imm_data, op_data,
02039 state.alu.carry);
02040 #endif
02041 break;
02042 }
02043
02044 if(opcode == 6 || reg_address == 0x08)
02045 {
02046 #if defined(DEBUG_SYM_SCRIPTS)
02047 printf("-> sfbr.\n");
02048 #endif
02049 R8(SFBR) = op_data;
02050 }
02051 else
02052 {
02053 #if defined(DEBUG_SYM_SCRIPTS)
02054 printf("-> reg%02x.\n", reg_address);
02055 #endif
02056 WriteMem_Bar(0, 1, reg_address, 8, op_data);
02057 }
02058 }
02059
02134 void CSym53C810::execute_tc_op()
02135 {
02136 int opcode = (R8(DCMD) >> 3) & 7;
02137 int scsi_phase = (R8(DCMD) >> 0) & 7;
02138 bool relative = (GET_DBC() >> 23) & 1;
02139 bool carry_test = (GET_DBC() >> 21) & 1;
02140 bool interrupt_fly = (GET_DBC() >> 20) & 1;
02141 bool jump_if = (GET_DBC() >> 19) & 1;
02142 bool cmp_data = (GET_DBC() >> 18) & 1;
02143 bool cmp_phase = (GET_DBC() >> 17) & 1;
02144 int cmp_mask = (GET_DBC() >> 8) & 0xff;
02145 int cmp_dat = (GET_DBC() >> 0) & 0xff;
02146 u32 dest_addr;
02147
02148
02149
02150
02151
02152 bool do_it;
02153
02154
02155 if(relative)
02156 dest_addr = R32(DSP) + sext_u32_24(R32(DSPS));
02157 else
02158 dest_addr = R32(DSPS);
02159
02160 #if defined(DEBUG_SYM_SCRIPTS)
02161 printf("SYM: %08x: if (", R32(DSP) - 8);
02162 #endif
02163 if(carry_test)
02164 {
02165
02166 #if defined(DEBUG_SYM_SCRIPTS)
02167 printf("(%scarry)", jump_if ? "" : "!");
02168 #endif
02169 do_it = (state.alu.carry == jump_if);
02170 }
02171 else if(cmp_data || cmp_phase)
02172 {
02173
02174 do_it = true;
02175 if(cmp_data)
02176 {
02177
02178 #if defined(DEBUG_SYM_SCRIPTS)
02179 printf("((data & 0x%02x) %s 0x%02x)", (~cmp_mask) & 0xff,
02180 jump_if ? "==" : "!=", cmp_dat &~cmp_mask);
02181 #endif
02182 if(((R8(SFBR) &~cmp_mask) == (cmp_dat &~cmp_mask)) != jump_if)
02183 do_it = false;
02184 #if defined(DEBUG_SYM_SCRIPTS)
02185 if(cmp_phase)
02186 printf(" && ");
02187 #endif
02188 }
02189
02190 if(cmp_phase)
02191 {
02192
02193 #if defined(DEBUG_SYM_SCRIPTS)
02194 printf("(phase %s %d)", jump_if ? "==" : "!=", scsi_phase);
02195 #endif
02196 if((check_phase(scsi_phase)>0) != jump_if)
02197 do_it = false;
02198 }
02199 }
02200 else
02201 {
02202
02203
02204 do_it = jump_if;
02205 }
02206
02207 #if defined(DEBUG_SYM_SCRIPTS)
02208 printf(") ");
02209 #endif
02210 switch(opcode)
02211 {
02212 case 0:
02213 #if defined(DEBUG_SYM_SCRIPTS)
02214 printf("jump %x\n", R32(DSPS));
02215 #endif
02216 if(do_it)
02217 {
02218 #if defined(DEBUG_SYM_SCRIPTS)
02219 printf("SYM: Jumping %08x...\n", dest_addr);
02220 #endif
02221 R32(DSP) = dest_addr;
02222 }
02223
02224 return;
02225 break;
02226
02227 case 1:
02228 #if defined(DEBUG_SYM_SCRIPTS)
02229 printf("call %d\n", R32(DSPS));
02230 #endif
02231 if(do_it)
02232 {
02233 #if defined(DEBUG_SYM_SCRIPTS)
02234 printf("SYM: Calling %08x...\n", dest_addr);
02235 #endif
02236 R32(TEMP) = R32(DSP);
02237 R32(DSP) = dest_addr;
02238 }
02239
02240 return;
02241 break;
02242
02243 case 2:
02244 #if defined(DEBUG_SYM_SCRIPTS)
02245 printf("return %d\n", R32(DSPS));
02246 #endif
02247 if(do_it)
02248 {
02249 #if defined(DEBUG_SYM_SCRIPTS)
02250 printf("SYM: Returning %08x...\n", R32(TEMP));
02251 #endif
02252 R32(DSP) = R32(TEMP);
02253 }
02254
02255 return;
02256 break;
02257
02258 case 3:
02259 #if defined(DEBUG_SYM_SCRIPTS)
02260 printf("interrupt%s.\n", interrupt_fly ? " on the fly" : "");
02261 #endif
02262 if(do_it)
02263 {
02264 #if defined(DEBUG_SYM_SCRIPTS)
02265 printf("SYM: Interrupt with vector %x...\n", R32(DSPS));
02266 #endif
02267 if(interrupt_fly)
02268 RAISE(ISTAT, INTF);
02269 else
02270 RAISE(DSTAT, SIR);
02271 }
02272
02273 return;
02274 break;
02275
02276 default:
02277 FAILURE_1(NotImplemented,
02278 "SYM: Transfer Control Instruction with opcode %d is RESERVED.\n",
02279 opcode);
02280 }
02281 }
02282
02314 void CSym53C810::execute_ls_op()
02315 {
02316 bool is_load = (R8(DCMD) >> 0) & 1;
02317 bool no_flush = (R8(DCMD) >> 1) & 1;
02318 bool dsa_relative = (R8(DCMD) >> 4) & 1;
02319 int regaddr = (GET_DBC() >> 16) & 0x7f;
02320 int byte_count = (GET_DBC() >> 0) & 7;
02321 u32 memaddr;
02322
02323
02324 if(dsa_relative)
02325 memaddr = R32(DSA) + sext_u32_24(R32(DSPS));
02326 else
02327 memaddr = R32(DSPS);
02328
02329 #if defined(DEBUG_SYM_SCRIPTS)
02330 printf("SYM: dsa_rel: %d, DSA: %04x, DSPS: %04x, mem %04x.\n",
02331 dsa_relative, R32(DSA), R32(DSPS), memaddr);
02332 #endif
02333 if(is_load)
02334 {
02335 #if defined(DEBUG_SYM_SCRIPTS)
02336 printf("SYM: %08x: Load reg%02x", R32(DSP) - 8, regaddr);
02337 if(byte_count > 1)
02338 printf("..%02x", regaddr + byte_count - 1);
02339 printf("from %x.\n", memaddr);
02340 #endif
02341
02342 for(int i = 0; i < byte_count; i++)
02343 {
02344 u8 dat;
02345 do_pci_read(memaddr + i, &dat, 1, 1);
02346 #if defined(DEBUG_SYM_SCRIPTS)
02347 printf("SYM: %02x -> reg%02x\n", dat, regaddr + i);
02348 #endif
02349 WriteMem_Bar(0, 1, regaddr + i, 8, dat);
02350 }
02351 }
02352 else
02353 {
02354 #if defined(DEBUG_SYM_SCRIPTS)
02355 printf("SYM: %08x: Store reg%02x", R32(DSP) - 8, regaddr);
02356 if(byte_count > 1)
02357 printf("..%02x", regaddr + byte_count - 1);
02358 printf("to %x.\n", memaddr);
02359 #endif
02360
02361 for(int i = 0; i < byte_count; i++)
02362 {
02363 u8 dat = (u8) ReadMem_Bar(0, 1, regaddr + i, 8);
02364 #if defined(DEBUG_SYM_SCRIPTS)
02365 printf("SYM: %02x <- reg%02x\n", dat, regaddr + i);
02366 #endif
02367 do_pci_write(memaddr + i, &dat, 1, 1);
02368 }
02369 }
02370 }
02371
02394 void CSym53C810::execute_mm_op()
02395 {
02396 u32 temp_shadow;
02397 do_pci_read(R32(DSP), &temp_shadow, 4, 1);
02398 R32(DSP) += 4;
02399
02400 #if defined(DEBUG_SYM_SCRIPTS)
02401 printf("SYM: %08x: Memory Move %06x bytes from %08x to %08x.\n",
02402 R32(DSP) - 12, GET_DBC(), R32(DSPS), temp_shadow);
02403 #endif
02404
02405
02406
02407 void* buf = malloc(GET_DBC());
02408 do_pci_read(R32(DSPS), buf, 1, GET_DBC());
02409 do_pci_write(temp_shadow, buf, 1, GET_DBC());
02410 free(buf);
02411 return;
02412 }
02413
02433 void CSym53C810::execute()
02434 {
02435 int optype;
02436 int opcode;
02437 bool is_load_store;
02438
02439 #if defined(DEBUG_SYM_SCRIPTS)
02440 printf("SYM: INS @ %x \n",R32(DSP));
02441 #endif
02442
02443
02444 do_pci_read(R32(DSP), &R32(DBC), 4, 1);
02445 do_pci_read(R32(DSP) + 4, &R32(DSPS), 4, 1);
02446
02447
02448 R32(DSP) += 8;
02449
02450 #if defined(DEBUG_SYM_SCRIPTS)
02451 printf("SYM: INS = %x, %x, %x \n", R8(DCMD), GET_DBC(), R32(DSPS));
02452 #endif
02453
02454
02455
02456
02457
02458
02459
02460 optype = (R8(DCMD) >> 6) & 3;
02461 switch(optype)
02462 {
02463 case 0:
02464 execute_bm_op();
02465 break;
02466
02467 case 1:
02468 opcode = (R8(DCMD) >> 3) & 7;
02469 if(opcode < 5)
02470 execute_io_op();
02471 else
02472 execute_rw_op();
02473 break;
02474
02475 case 2:
02476 execute_tc_op();
02477 break;
02478
02479 case 3:
02480 is_load_store = (R8(DCMD) >> 5) & 1;
02481 if(is_load_store)
02482 execute_ls_op();
02483 else
02484 execute_mm_op();
02485 break;
02486 }
02487
02488
02489 if(TB_R8(DCNTL, SSM))
02490 {
02491 #if defined(DEBUG_SYM_SCRIPTS)
02492 printf("SYM: Single step...\n");
02493 #endif
02494 RAISE(DSTAT, SSI);
02495 }
02496 }
02497
02526 void CSym53C810::set_interrupt(int reg, u8 interrupt)
02527 {
02528
02529 switch(reg)
02530 {
02531 case R_DSTAT:
02532 if(TB_R8(ISTAT, DIP) || TB_R8(ISTAT, SIP))
02533 {
02534 state.dstat_stack |= interrupt;
02535
02536
02537 }
02538 else
02539 {
02540 R8(DSTAT) |= interrupt;
02541
02542
02543 }
02544 break;
02545
02546 case R_SIST0:
02547 if(TB_R8(ISTAT, DIP) || TB_R8(ISTAT, SIP))
02548 {
02549 state.sist0_stack |= interrupt;
02550
02551
02552 }
02553 else
02554 {
02555 R8(SIST0) |= interrupt;
02556
02557
02558 }
02559 break;
02560
02561 case R_SIST1:
02562 if(TB_R8(ISTAT, DIP) || TB_R8(ISTAT, SIP))
02563 {
02564 state.sist1_stack |= interrupt;
02565
02566
02567 }
02568 else
02569 {
02570 R8(SIST1) |= interrupt;
02571
02572
02573 }
02574 break;
02575
02576 case R_ISTAT:
02577
02578
02579 R8(ISTAT) |= interrupt;
02580 break;
02581
02582 default:
02583 FAILURE_1(NotImplemented, "set_interrupt reg %02x!!\n", reg);
02584 }
02585
02586
02587 eval_interrupts();
02588
02589
02590 }
02591
02597 void CSym53C810::eval_interrupts()
02598 {
02599
02600
02601 bool will_assert = false;
02602
02603
02604
02605 bool will_halt = false;
02606
02607
02608
02609
02610
02611
02612
02613
02614
02615 if(!R8(SIST0) && !R8(SIST1) && !R8(DSTAT))
02616 {
02617 R8(SIST0) |= state.sist0_stack;
02618 R8(SIST1) |= state.sist1_stack;
02619 R8(DSTAT) |= state.dstat_stack;
02620 state.sist0_stack = 0;
02621 state.sist1_stack = 0;
02622 state.dstat_stack = 0;
02623 }
02624
02625
02626 if(R8(DSTAT) & DSTAT_FATAL)
02627 {
02628
02629 will_halt = true;
02630
02631
02632
02633
02634 SB_R8(ISTAT, DIP, true);
02635
02636
02637
02638 if(R8(DSTAT) & R8(DIEN) & DSTAT_FATAL)
02639 {
02640 will_assert = true;
02641
02642
02643 }
02644 }
02645 else
02646 {
02647
02648 SB_R8(ISTAT, DIP, false);
02649 }
02650
02651
02652 if(R8(SIST0) || R8(SIST1))
02653 {
02654
02655 SB_R8(ISTAT, SIP, true);
02656
02657
02658 if((R8(SIST0) & (SIST0_FATAL | R8(SIEN0)))
02659 || (R8(SIST1) & (SIST1_FATAL | R8(SIEN1))))
02660 {
02661
02662 will_halt = true;
02663
02664
02665
02666
02667 if((R8(SIST0) & R8(SIEN0)) || (R8(SIST1) & R8(SIEN1)))
02668 {
02669 will_assert = true;
02670
02671
02672 }
02673 }
02674 }
02675 else
02676 {
02677
02678 SB_R8(ISTAT, SIP, false);
02679 }
02680
02681
02682 if(TB_R8(ISTAT, INTF))
02683 {
02684
02685 will_assert = true;
02686
02687
02688 }
02689
02690
02691 if(TB_R8(DCNTL, IRQD))
02692 {
02693 will_assert = false;
02694
02695
02696 }
02697
02698
02699 if(will_halt)
02700 state.executing = false;
02701
02702
02703 if(will_assert != state.irq_asserted)
02704 {
02705
02706
02707 do_pci_interrupt(0, will_assert);
02708 state.irq_asserted = will_assert;
02709 }
02710 }