From d815c226f467ad3784d75b414556c5b70e3bd659 Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Sun, 23 Dec 2012 10:46:16 -0800 Subject: [PATCH 01/11] More polish on the pdp11_dmc and addition of DMC11 to the PDP10 documentation --- PDP11/pdp11_dmc.c | 18 +++++++----------- doc/pdp10_doc.doc | Bin 84480 -> 95232 bytes 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/PDP11/pdp11_dmc.c b/PDP11/pdp11_dmc.c index a1bbfaee..602ca456 100644 --- a/PDP11/pdp11_dmc.c +++ b/PDP11/pdp11_dmc.c @@ -415,10 +415,10 @@ UNIT_STATS dmp_stats[DMP_NUMDEVICE]; CTLR dmc_ctrls[] = { - { &dmc_csrs[0], &dmc_dev[0], Initialised, Idle, 0, 0, &dmc_line[0], &dmc_receive_queues[0], &dmc_transmit_queues[0], &dmc_stats[0], INVALID_SOCKET, -1, 30, DMC }, - { &dmc_csrs[1], &dmc_dev[1], Initialised, Idle, 0, 0, &dmc_line[1], &dmc_receive_queues[1], &dmc_transmit_queues[1], &dmc_stats[1], INVALID_SOCKET, -1, 30, DMC }, - { &dmc_csrs[2], &dmc_dev[2], Initialised, Idle, 0, 0, &dmc_line[2], &dmc_receive_queues[2], &dmc_transmit_queues[2], &dmc_stats[2], INVALID_SOCKET, -1, 30, DMC }, - { &dmc_csrs[3], &dmc_dev[3], Initialised, Idle, 0, 0, &dmc_line[3], &dmc_receive_queues[3], &dmc_transmit_queues[3], &dmc_stats[3], INVALID_SOCKET, -1, 30, DMC }, + { &dmc_csrs[0], &dmc_dev[0], Initialised, Idle, 0, 0, &dmc_line[0], &dmc_receive_queues[0], &dmc_transmit_queues[0], &dmc_stats[0], INVALID_SOCKET, 30, DMC }, + { &dmc_csrs[1], &dmc_dev[1], Initialised, Idle, 0, 0, &dmc_line[1], &dmc_receive_queues[1], &dmc_transmit_queues[1], &dmc_stats[1], INVALID_SOCKET, 30, DMC }, + { &dmc_csrs[2], &dmc_dev[2], Initialised, Idle, 0, 0, &dmc_line[2], &dmc_receive_queues[2], &dmc_transmit_queues[2], &dmc_stats[2], INVALID_SOCKET, 30, DMC }, + { &dmc_csrs[3], &dmc_dev[3], Initialised, Idle, 0, 0, &dmc_line[3], &dmc_receive_queues[3], &dmc_transmit_queues[3], &dmc_stats[3], INVALID_SOCKET, 30, DMC }, #ifdef DMP { &dmp_csrs[0], &dmp_dev[0], Initialised, Idle, 0, 0, &dmp_line[0], &dmp_receive_queues[0], &dmp_transmit_queues[0], &dmp_stats[0], INVALID_SOCKET, -1, 30, DMP } #endif @@ -518,10 +518,6 @@ t_stat dmc_showpeer (FILE* st, UNIT* uptr, int32 val, void* desc) { fprintf(st, "peer=%s", controller->line->transmit_host); } - else - { - fprintf(st, "peer Unspecified"); - } return SCPE_OK; } @@ -553,7 +549,7 @@ t_stat dmc_showspeed (FILE* st, UNIT* uptr, int32 val, void* desc) } else { - fprintf(st, "speed=unrestricted"); + fprintf(st, "speed=0 (unrestricted)"); } return SCPE_OK; @@ -693,7 +689,7 @@ t_stat dmc_setstats (UNIT* uptr, int32 val, char* cptr, void* desc) t_stat dmc_showconnectpoll (FILE* st, UNIT* uptr, int32 val, void* desc) { CTLR *controller = dmc_get_controller_from_unit(uptr); - fprintf(st, "connect poll=%d", controller->connect_poll_interval); + fprintf(st, "connectpoll=%d", controller->connect_poll_interval); return SCPE_OK; } @@ -714,7 +710,7 @@ t_stat dmc_setconnectpoll (UNIT* uptr, int32 val, char* cptr, void* desc) t_stat dmc_showlinemode (FILE* st, UNIT* uptr, int32 val, void* desc) { CTLR *controller = dmc_get_controller_from_unit(uptr); - fprintf(st, "line mode=%s", controller->line->isPrimary? "PRIMARY" : "SECONDARY"); + fprintf(st, "linemode=%s", controller->line->isPrimary? "PRIMARY" : "SECONDARY"); return SCPE_OK; } diff --git a/doc/pdp10_doc.doc b/doc/pdp10_doc.doc index baddd5ff26c0ab48121769540f063bf439ad4206..930f7458f6753370043ae3161be68cee9ced1380 100644 GIT binary patch literal 95232 zcmeF42VfLc`oM=ykO(RuQgrCSOAjQWscArf6q5~t(l*J4tR&f(O$b3yP;7Xf*!9GQ zy@K7dV*v{)R{cX{ zA(wYM*tM%$;9R8dc7S`;mk+z>WBDA`TYqoqvxj{e}wCAIl^@< zFpO_$)|Vb+7?;!JNA;6fB7gSiZy0?D7k`LhtR&nsd=~O~X1-xak2#A^`D@MRUg4s@wQ z-y(zB;qS@1E<4PELu-_LRjXCnhCF z^OsdnIK3!$!bF#uU*O8k%88D4ReH<{UsaW_(OWauEc4Yi)p_Su)|)lHdT*J>bl28a zc|Cr!-e=YmvN$(yqUrZF)RlQ+%~EfTyRIqLbk~%d<-W3pYEMnQyWZ=o866#6KrCFY zBF1u$S=&%r<@Hy3%1v*LnKWut3K>dFk2M?Xy!G{-8nd*?Eb^6l>gvrrv$&zQ#yc-M zE0B|zvf<8q!UIMZdg`jZen07&UcXuCsq+xs+&Xtny{A0Ztf=#NOkagrR_U&rOQtD^ zyQayk_0;*f!B<-E_SQ(r-Ky*ovc8gN{Jx6%Mt28mABffC8=&# z6{4!3!A}XKj$+MfU%9tJK0T^fmV{%?a<4>P+E7nOzlgoeQzLg#js#kT-%}-ZQY&?; z%1WJDxziPie2@+4TOv~FHdgwoLra2)DjMo)bft1nxet-46p!_k)!WU**|2KLy;5F3 zjYHa;yVN(|qskK6-VnE{0F?<{t5#F=SGvi2smBtSZcK8@E)Jz@DD~G<@m^$K>#I}g zg%>lP^e5(+#RcPCM`aY{n7PGfVNt=<-0Yleb6`d>#{*-{qjFsn3rbujA&N5cUDM5i z@n%N;baQfUes-*xGp(>Fr?}WGC^B>N3a8}ea4t7LYf4FWZvF%_ll$mh=9JvLTo;kL z3QS4RiYhmU`^KAjIYn6$i8&)PcS^2ndaOA<*Of1EjwjL#voNEG?pZP=qsS~QDJm=| z&LR11qRr3EA74Z&Ie9txu6UDVIcerh<;X0am@#FFSyYgjQ{9Bv(asZ9!L|baaXIZAEq%(-H-?=jfpO$ zw354gKKjS&mwre;@ex5?qu1||rd(U+tM=9Nl}P>WDtZ%l1wxt9)w#{DyE{F@?oojb zU0dfRPFvf#8_)uE-i1n6qM+zoVOgY*U84^`##!bJpE)ooE@hxOqtcwQ(Cl%5IdOVn zP7%VHY|f}M2hMi+%2Gy*NK8&nOCL4RY||qtDmVs=7yT4<0L^JaPEpQyGbFIY*rrEH z&z__dG0stm5@&LhHN1@Xxa%9xUd_ijDzSBOCaE~%lcKT;OCrRSq+=SfhukIWn8+W4 zU0sB@l673Edx#4eQ_}d9sFE7=r{Bydch}Z4Ohkw^rFF56(6Nq)8ed0aHFMB!G2?TF zM~HMp>mnVgBOMv#@}mFE7*}pyq!>r)7}NGp_*5NZYE)rXQj%HdM*W&D{xyp{?s7?@ z&{Y&EiPY95k*1SK+bxO0hMKZUNue-O3TZlp^gR?JU8j&9m3=gYaLF(xCP-dGRlT>i z%CkVqk$rTeMABQAi0Wj?@uQ-$^F&luW693W$}2RpsNy<|DOwFF>PCY5H#WJQR>i!r%ir$m$DQ%dGl{L57#zasn%A`F+X?MrOsG^CK$ZGeoW>I0{ zh=jzE35lr*iD?|>B_<~%rpTG}M6lkrLMvOG`+;eL@Sf;vh#<)tFmuEV+D)p9>yobVDy*?>9YD!^pBGr{)PGLkb z3+ucXkTe)M9Vrn@2PCzuMAH*3C6JU7RWvO*DJh|7niQ?dS6ka;W_$hf5aaYnX;>;D zsby7|o@nWWq!CeB*%TzpT~{9Hyjccgg#T-R2)o0NH+ zTT|OmAE6Cex**%4gPut9ug)K2~ko0vfB8{XgMw(YV0_(e1&b>IK#T*(nRlj(x0iU>`{i?C(~pfkR2vK2WI!4pgdv zBT2PPOQN>CHYqV7N`1@@6kH#c)i$W;^ihS!aWIdWnd7jkHaXF8SY2MBi=*$XbYeE=sIMvKnyN2}CrRfrX?9uN>~eR#lA$`!35i30FRw0>E5U={m4$(n zl4jS|I}YlaB%Ls0NKa_O8?H=7X)YDsxfo0`hqR{IG65?0%$Lcv7^pG+;nK2X((dug z3>}jwDr#~u&6cmqf;5xzj*`}@`b|?b#vCD#l$fdwHO$mv>gi5?Vvsp-wY%0oJh~(^ zgFx2c46s+T4Z&43@vkQ}9l>sn+x`-U>frLU?gRz#PNBK3>pvFHV6Zj`p{z;3C zW@t-E;2%!r1;(~$m(+v|i3w^bYCb+SD%mAu#OIa@ZyicVn+L^BND0f&he64})#$66 zr)DkMN{E&~+~M~Sd3mdEN#+)2I~2OLiKIxjaNE>Zw(b_INz(*O+5ls}3|p~g7RMwR zV%Df?=46T~?h>3SGW)J-!qb2Za*Ji=naxDiCHh^=GSRQ9PRrairn}1TlUZ0;;9?&$ zH{D5a#Wd8)TwbaA;vAPbR$n;G%*f7G({M{`<4&sdVn~v@uTc*uxd{d6`nh-;%FCIx z1Y90g|D&CeHlCrHx#B94oXId0lE_r1t;|Xzr!gOYhfEm7ab#y&T5vFCN}qw7qS^9H zEI4ZS0!c=SL#~A8!fzLqZl*?IN6L0dB@UgnSaCPil1mJ>swRdtsfyjTRW%l}c<>Oo zhp8}jGrHxt2I{8XS1WB+`)|-*xfr-}m3IqQQ-ktinK6lpiNj?AJkL{CH%`SdV}_muk?YVkEOrT3KKvXZ*c?zqs)GP^S?+}^6-q}x+hhtx?> z>4drl90Gn1*{vxf-DWZvA!N;b=I*wn@EK{NujRm@TGgy+sK#{}o$srO^DMyoh72j4 zr%dvSpP){+zOHtml}e~meC8F})gr1f)~xh3+VObH84Tx2 zZAgC0l#^SeAVDNyJ2~YUAUQuhK1x)Y{A04{P^wiAvGR}zxF=MC^vMJh7a!4B(9u%K9sA$|;%h^`9RDnaG ziSqW>x@8f<(%zUhsGlgM8l^P31;vFKSz^HWrS#3-pe!mh;9TjMOv|;mU03mZ+Qq^>wrkg98uxY%}*G4Db?q=cecIbWE? z*`#y~xH=z;6xBrApsbpx@l!G;h@`EHRwgQ{+;|pa#wMkVPD(oroh%N^;n7hUS&8xS z8CgkbQBf(WQBiKC-UE4)RudhSD~6I>_0|M6wJnP1sGLl>F3E|yYLM~4EOq1A3?TS0`{h-M)X*@DcOpSawR8(1maemBP`mi5}e4AH$>A=S0`;I zBg-tUVpf8Lil*8ZYneEC#dHc@EiQD)jT8zut{B#~&Q=OGIx4H!zFy|T9+9f$e(NH> zbn9lTmd%D*CJ4?FbHCWYk^o;(Cw{Utu{e`+A}Q7&7-)2)D!+E)jE>6AED~EzLX~^` zWp&*Q{dT zukzECRUK0kxw!hnuj-a27YmDy48JHVSmG{MExS&}V?V8)u(<`zhs`aZwFQG^6iNk! z4*`MYTM;z%uxm5>KET({u8(XXj;1 zQ;~SXteAiaqfM8nX<4p7Sly8vc8nFKFzd);5=W<|%+$45n1zsJNdT2swQgRxJ zN^`b*wde*kkqeb3N>sdS)wP&?qJEXW#*Su9R*faL7eUv zeb^eZszQ&)mTn^3dZie%TSr$Zh0)^^5#@%A5Y}{A&)CXkMOZQ*<5q4qYgfu7<{-a7 z9a=+%%%uZkn_NH~x*dd#KfzEs0>UxWD3dI7pu)P{En8Mdl_~rlZf2`0KgeXaQNG+$ z>!~THwj^iPAWLFV#RZcln5nTzGU}tXx457;+)eNN4ELn>5KnV4J5v}(GpSDETKPc~P()(wcLtjgoA3*@V` zp`t=syKUiE;l_!PV^^_NhTQ|z5XfpTR+w0nV9i{V*f_I>@L@S4xN<_M+y-L}3pI{t zbujG-s6nH$Ca+iArJVMist;DX7tqV9?R0IM!U`i5m^yM~N~#@4e6&o4>U95=xow>? zOsFhvrN}Ae15#=&IIv3x3bYPYMPj1c!@hl&Bq#k&yP7QXOR~gVu%6bYE~;n(cSH`J zL^2tA_Jif73eY48q$D$6LE$ud*&3ouSIfc*ZWka)40-88gp@kRmxB;FPLVNIB~DDT zqUw=e%z3GBk+Vud&FZ3~l1GhB8pZkQ(uL6spQGh_ZDo_+TP7O>L{e&awr6Eg>7ykU z39YI|LeSF49ev1FpV-sZ1khd})PX~1g)*_NnWvSgw*SRCwOs(HS`iy<0TG4XC?*2V zJG@$y&z8CfDJ&S8!MZMDrn6&+sP)QWemkfLoj|))P{8qx<>jxHi9PcPNy^d!VJS)Z zC5~Y21VkYf6v@!V*NBBp-`T z>O{>uM6K(>%Kj*2IAE^j;s=(YG#NuuU#(?PQ_VVMszT>7W4sl%ICoYQBm?o{KIGON3SZbCT}`IWN_rphGx6%V4%oQvyI;!;x!>ANZ@-W)4( zT6JB0LoE#_(^KZ=E{1k2Bikou?-oOnVops@o=g*G*6d|xlg^UPza!_nH#%g4vBbU9 zV_-8|GtnsnRf~y`QD#(BNRcQF`}IbdF_z&&y-Aan*mc~&$jNR|7O2YQbm5)Oo~|k(MiGhpREsu1}^V zIYqez_%XC~EIw$e8IPw7c)?IdmatFDiuVUyoSAfjr=|*F2t$n;#8oZLS2aSpD=uKbI&w(ymqen@H3F&MSAlTkm~xi`QqK@@QHk8T;J`r9C#5Q%&tbrDWRKYFnc< z`2BQD*Z~0-8;Pli8t{2Ck5F?aX#zy6#jFe%v2#mBILgI@6xjjh#(S&;s55Mhhr1U< zMln3w$Q3ib#!~%Mhgt^`V@bBmSk}KiRgk_H4Cx5MVm+zTlp-eQ=;+k0!$G6wKamFD zfO=IkOeJq6CCl~UDHmsnOt+KhG-6<3sapeXK>9KhmbQ=46&%B5h9mOSKA@Z;6$i$b z^2p0cGlq!ACXGCdevw&HEK7t$z@Dlmb&qv9NiJs>rAg*soQApfyB^wRORg4 z0&+n<)p7_i%N?r7Y)DikXBjErn#E+&=8~!*6)eh>KmHBI7N`kajABXALYR%a@uZha zO3ogqT9G8JMp>*>*+wje94iCdDwYjLQb3i-f8tj9TA(OV3nHZ&-rXI0ws!07YGqjO z=h7Cs)!Py3Z{63eEtPb4OyGZ^zpE_o-v4w-{!_hOr}p36+5bbm*|G(H2i=)=_wVS= zt?QF5?{d`LQiTzVp~h@s*9HBjL~pxLYxGPZW0<64@q7Hk)v|tI;Ic;O;4rKLDW_3z z!P{Z$>kU=bL@4`c_L#HFT^uCrd8k(@VB4|)A{IuC&a%X4om9KIh}X@&F1_FB=RX3o2JubH!io%E;`hQrNMn0LTBbJZ(=%nxCKs%E zPvAzs(zr603Z5cpT47Wr+e+embu!}Pt6(O8cMAR8{OMS0l2pTDv2qbfMuIUa0|C1N z8!d{+Gb6+j;dFFVdM1O2Hh9>h9pyOCqP4x3GzclO*ts&ZV4bqmTji~{CTYrWVV9Pp z1qI|;`=^j9%fqNDZjjgQ2NO){b; zUut=p^<~{MXcKZ)9PnkB!mK(GgVh3eOD4Zyij@%itF&)-j|s@!jH#PnS#tO|v1}wy zb~@u_`*0Nx*+?!N35vf@+H%1Jm6UA32qxvN(atNeKBQd4Ac0jsu|%qunX$)p=Ru5e z3+0sdC3&(G9F5o4Ft^fld8*hu#LR()i^GDf)YPbzU+Fb&<<^S}EX}J2Uo0VIxLg@o z6YZ>rnbLYwjarqKiL11HEBx_s?&`&o>9G>#Fx^*~YVZsfUN~v8ay~kmbpl+>DjrcW z%z4VZ)fCIp4yEjO@*q*Y=SRGlBatLi6atH_Q|ghZ)TCJir5?F3U0H<*xrH)e@y^GD z^VrQwyHtqW+Kmv0xzFl(U~NIVJ$g&}uB@plYu1`O?RKj>c&kc>nY!0+2^G~BJg`M> z;_Z-*!WI>JjP!87nJp6-m%W9ph)GA&aKwI;^@vwUMsy28prxKlw``kME;UuRc3Y6O zW`wCX%-}8w)bSWc=0sl77DF3EaOFkM<7Dk6+_4mAuXUqr*zH7H(_KtE*l3pp_SA=5 zN@ZGhsA`U?YdV*L*j6CTAW*DEFO6Kc4oj)12C5n>-9X(R=-Sd=5EMQ$o~z@bL75#} z^Hvt;eQXJo=MaMtpib=qJ5C4GfE|!Ii_G=anvBfK>e($6tVxuIwWMTkwq)g4uT$z$ zSRyUsX-Dz0ur&cU2eM!boAvOLv;f&194pf`H=C7J-y(>0UW7w4g zh!s}5C4!1Ww2@Qk|2j*QsUORZYNa#sypoBzI9mN?qNuPG7Au*pI&PB{PqiIEt?uj= zdP<=)4aqm&d^S_a2A;s&b+@}*S}|BQ6wVM-^lmog_KHnZryhx-{Z<|COykv zVY@eW%Vco|OWU?2Xdm7xRD6}2;Xx0YG{11sP1AF9oVB*t0&`dKfM`Ldh@jck;|hkh zB!E5^udZyN+dX(*cAhJX^>U`8AsWrj4P!=$t00?sHzCAv6>MICAZjf|nPq_`V#}W3 zX*%|t$cTs0!!n}`?y^-<4aANXt!z-n>H6lDru~%-EGCuv@PW}CMAy*EP+=@)tEqIn z+GYDIp474IAN81z8s8iaZAJ#!#?Rn~@Z#!yaq5dw1+1iCttj26eH!tsg5gj?A*iU7 z*hL9i)8YnYjj9KTv?}uG-Qc*B^fvKo_dFRg?4dCz7d8Adl8Vv^ze$AZ$1Q+iq82nU zH+d>z0eTRPE02Z~BU{ZZ-()b(Skr^l>_Ft3`-n&FWOJL6RUEI{Q%|20OI32Aq%Nh4 z*BgCRL6wKidcsmPRhX>wBU8bYv1{CQbxorFc@RVl9%Txt(#bwNG&|c7^&V<9_;}*y z#%u3Q$rM*n?lh_X?BYC2g(P~AIpF#hmw#phgzlENn4q;{90sHgVyn^hUapv)bY}(8yn!czwhY>5AZ;R;<>~U1dd)RJBZu?LqCt#MPl^va!zeUGrLbXDAew58bOxLm41$xiJyHJNYG zF}2o{cB5Q*k_ch#2QMsP43{BT#ziS+VNOobI4Qws$-O-{QqN=rrku6`L`mFM657_) zPyb3P&6?M$0n1fe87l$l!I#c8Uv|#~8lbHFP>U48%BIzLF@n^l0Hv8_?a8*Kox63c zDzy8b)&r_l5TDeO)-25m-6;*rA}K7GGG$y%bTk`$XocibH>TiJUsnMJxr@>{rjjX% zR_(}EQ<}0oht$$|mVjJ7U)9hcp7lYFGwjt1Ug1&Rj!fidCk{j1=X6 zd($iG65C&BKxyOC|Iix3x5d?po-nL*cR@)4&|O zp4Tv-Dlp=RS$Rcp0I<5~t?()vRHl&i^+;&0v@CgU&gvLS9R@aUsSaE3u42ambtVIV zZcR+i!aA*Ifm_N#`^h7iSYAoNewCA-!Q&pmW2-MaPDsa_QjnD~Wnw|GYjiSy(N-@~ z9W#l)V9d$E8^dD`Xog@A)v1}3+mWldoRO>4q61IODzhXY0kzG;ZBJbhbGbZSYpvvC z7g0Y_4Rw^9jdk&6F*}Z#v#}XYo|d3~uzR&Kax;H-JnWB(l)ANTe6_+DAI)nV3hYS4 zRV1Di*?q}gba$Dw2U%8(kLINj`F1dw*3mO$;zdW3*D&PRmw291dL&!6WZhk&kQpA@ zlua}kB3M8ft_(Y{2sII(TtOUc8w}->twa#l%PN0aIUeDz z&;{5PE_-uPbds{jg^n2?U0jegImcyZM7M8c?9nBVlXk_#+i!~q4Mz~Qh#8z42O71k zx3ici9YL3!X6w-Q**Tddcxop48dX&V1`VcjjP@chpLij{8oE?1xz`6`S1Xoa-_(!hRzgu>Tvh)sg4wRB60TsX~6(8;VRBOTGm7Z*^+G$s2x0x zXaK5VA%&$+C>thtXJ$rrrpTTsReBe@emsc?s$@H|H1~PBS*lXo?Z;`+i-OYA zF+7m6JCIK9T)~uPL8sIn+kE}{6!K)Ricd|8r(Oc<3QFIp9w?7xDs3PYH^!83BV?03 z<+Epv($YnX$-|rC2a;!5SVf;YA|6+xJW;r(Xt{|kXS8>R)nK(UHHip)Y%#QFT5;=s znORWaQj-TgPs{lX+z_&PTw-LYglUOXL7gZYWsfsq zSN9h?!->|h9+2Q=RQe?m%E?0uE@Hz?(r$s(>Nq3pZh{69AVIi@C(@gN3qGU&`DzEnQAIZ%IPl*&frMci)PI=^H zWwAx9rkpndVOBL8+?kn>;LT+w&nZB)ryGSSrg#fN%nK=Rb2pj0CzU&1wj0u7l`+76 zZ0QqNiCF6a-x7(c=RDZlA-fp%xUZyGwQ+Quj*2!wU5Of05oddJsqxmn~lTU}NLfhcF0ZLljX zbiW9jKC~yE%P4=beZ_!4pUYH(&;_m9A`)u+wDRpOT4z?qDidEnaZ~i#e&^B%mMrcRZ$#@(;X4Mx|$uZV{{_alfe%t{L-48%Ah; zWl^|FT5H=#$X41m%(JXl-l)vVP#ZFCsbSV~;+Ii_%puC$>}iwbT;`W~tnl1}8|nY-|Y+*Lq?lX6pD7@y9BqsS@Wz)|8wKX@D)>>dde0 zQd5?AYkTz+jA3~*P78Zp&5USXI+LXz`K4=F?L2&IteGjn0$RXfayxni0aTx%gNt)d z_xX_Pyv>IYynakS)TB2<1-le0op?}mfTD~%z1i7$IZJKx#g+|paeH+pBvio^Qjt); zs)lNL=YV?XJTxaNA;Q?TuD!H@-YqgI$m^NGBFh;xdqO0QNY){m6C6uo?xv`JYLD@6W;R-TjMe`4aIJ&U z*!(7A$IGC?-*AV6Ox`2(o4KQ`)kw@6>wyp+yk*}v8@4zli_zi;Q5&0-zh`=Dt+OIR zw$eJ&o+QG{n{U9rAVn>4As&Y*VIaxZt1t8_}U`vkDb@=@pR;HAM`1UxjZAN=J zpO;Wd)H#z@Q?_6GL_}nROQ)$G(crzzfl05uCTq>#Sv&}+yI`QOnXx6XX^v%s;U>n|{s$8OA$RM{fR<7o2C8QT^Dn@f-y39yeA+11N4 zT^Yq$xw%SMI0jXj*@D5!h7z|@@0KB>e}h1uXBw{3a0FE~V`W&+pU8pV%Y<5`n9UYU z9Ny+p@#Z9~1}akaR(QlY%vdZ#iPTxHuaO<20k5(Oq3mL7FC{@#7Nu;;K+{GtmV#~_ zvgH%oy1Id7Ro?oK`Ai$pxsm?Gy?WP6V7kl_Gi%678V*6&BFqg+f_wG*qeO6iiQkzo zXCf3*@)*Y?gG?ekAI?tRkW(YpJ^QDaepr4s7LR393T;NVq_U*Or^v*Tw0=m%G7TN| zFB?{pk|k#BOWCxWWqSbix};1OR6M%iApjjqzpv_y#XE6z?f-NI2nGsm25;sz1SU$g8@M#!FEHJ_IFK zXVW5KS%K8%vE8cF0;;au^Hj@?Ki_%*irpD@t0i6_p?X4k0fiUn)u_GgcJ1oMYvogXaF$m}Z;p|ebQUM7*G#k7IMz(J#cl>pvixMHKx5}+ z^QEk`lDazf?BM z*LpKwP(=nd6^r!Z)B;irt;^aD6IW#K?N&RX=h6jhhKp;>TEo9EgZEFGVn*iI|Eclcf5p-Y;XlrwT%nk7@R?dXXH)rL>g4yv=Nc891p@S^=gq$WdPh!)Y0bx6`A znyuasB;B!r$)plq_*Q)}Ajr0U=^v76q%q88n~7|GVhvvUtoT?(?z&L&AcEQyr-oFP zbR~!sT-UR+Z1(Op5u8;Zl#uh$aokt3*(oS@C1V^nB1mfsy>2#?rbK4L(y~!TKI;dB z^c%Dh8(Y74Q@B^OoW!B>Yt^bFOST(`{Ve&#Q`qZXkU#GD?40o#?CD&Tn4Bt%cjfaj zYEe#RR(5Wd>_g=3IOJa^g~z#}ioAJD)geuHg<1emriL`ifYu>Tk_o3x;^LUsq}0lu z8tW%%Wc;zLUtX6g<^r#BE0sP;+i%UVBf}Uk1+TBJLPEiXZ+W>ni|O*}8KPC<2*D31?v8+w?NDgn8r{ntO)_506 zyHoquhE?+Jd8%37{M9rp_y7ry70K@4IxktQ_Aqpbz(OLUOqm|(4>2ag@2`TxJ z2)c&Vx!5KaRaERMPRMbD7HPKj)@h@~tJZ8XL_IaHIP!JLhJLkEx|JPyd|S35IPYn7 zW=hlsaFL%(@pJgm9QupwCD#2{b#lvoaqL$R#e|DPjCS3mY#l-OHzg8vAA;x6Jhd?y zMI~uOD05J>>@tc=r<&OZYVE%CskwvNsw!Ec=Bk=>g} zO)}t^o#?JACj%LlH-(hSQ)2-?I$1f!MUbo_Tt|T?2rQ$T&WxpqzGA6KZ)l32Neh*J zt6$V+iCoL^v{QCm6eIGi=0wxCKAmR!q}N;(2lB&?{~YO*Rh zwJJ*m4XrU*|FUD%?;4SqsL7fp_M4%3EEzG@G23Ax79XF)zk#?(OT}tUp!5WUjh~fb z3`vfZSBOxy(sLBHD8rQ#RIP!yQKz}o4Ry*dXR*PWX)2n5R)wxmbx_Xx>y>e!&--}x zjT~3`WT3G|Aes2cpd<4Eu9A;xwlMGtIoUPOPFO}d-qelE`CYPl8TRZI0@>4Odt?Ox|SRp%7L(mR26vz3gZyYTvJjLRNUJf|J7xo>Ecrr9gP$8Mqh<5E%su3WuMs z@cMa*z-mi&jgY9_@@!|7N>Bu*wLd0;W1gMtFY3>er)wq;WnseZ-6f&F4zVcr zFBJf_EIKkcg9}(-DlG0ywPvNlrmLW0q)30mGzkgI5=}5@^Gmr|+3GF1vIwSBm?fL= zB`#9V4lE>F0fWm&ay8(z)mN=|`8w9ZBv8Ons{%Q8nZ=sPv|QT-%+|!CWIdarvL}%_ zpt>SP1@C0~)sEGoVr!>Ri)%sRODon}fPycPQLQlWCYd-Iw%*`aMPCbfjf`?{S}$F) zo_W>{!hX%F3=>v!7hPyg>9wXT;f&lc zLs!TaL@S)`tTAb&_%R%BxQmmGE_M!hXgKgY2GuqEI1vxaJ=Mm*V# zvy<0ml<{1N{UZqoASi1+F-AHL+rw&w@?c>#55J)UnlK|4Xv0c8gP`B(;Y_v+Coa*9 zwjA%MS=zolbQHVW8NFjHBTG-D8Dr=gdGdo);^4OKqJsu<$uG)^`&QMA~pIJT6v8z>l;dMJnYm+v`FcNzUWw%J%^gqQJf50Q9f9w?8oH6M#M zF^^EQFO&^(x8H58^J*s)SV6EKsX3Y7ytud5DbPi*vOqP!b|Wnd;(kHQ`iO__ce@8&>5nj3w-&` zm(RWP<=Q*e-m>^0&{J zYmI_QZB_n`Wpkg=cOvXUJ=qUd#PM-SJtGM zkZjm@5~3pGC8OmKQijMOdK%QP)W2QdL-;-vq~6ovFK{+&gdgE2xS3ykzXkrZk72~Z z<^1~lHuwx)pgl-?k+w3HcCZ58fT7*ES69FOH{{?4=at{~;0tHed;cJE;XZL@G~{55 z^Ge78{cb-adR=Fu?W64$3^BTN>aLHrw2>nts++Ozvd7wWTeh+7Og?AvX|$mt+IKVB z4Q}He+{Wl5eRUt`1AU<%q(T~`!zdUHV?gS292^Em!!a-eX2L9(4K?6{T38Ne!k^(R z_zRp3(k9MjUZ{`u#*yIW zyEBRbBKtLPJKP0#!+r2KxF24DSK&3-1e@V?cmv*qx8Mi(5q^T7;TPBiG&7?EbOaLy zz(5!T+cvGgXZ_79Z(hFg=9Qc7*|f;NXr^^$^2(bHEwOp%PHHSr_U3B!3pDa?U8_3v z<8;gsQvWsewdeZSQ;oK6{L=0HTiqvG9_#u`T?~dHAUb*ULWz<8JdlVCC&4adL? zm=BGx0GePS91n|NF`NK@g-c;2Tn1OdRj?Y?!0qrX?09>_+YjIU@D*>Lz2WR-JC@b$ zSZ1A>VV!aGdHJf#_nc=RxFqe%mXKG~3YK`CrEOP%EI*{@Ny3 z(_UE!A@+jNNBZ6dcn+S27hoeudw2<6hA&|Ud<9>_-{CuGLpx~;?Vvv#42OUT17ILX zn;Hy5AOkYt^LJi;=h4-VUUl(RCp}uXy6)w7UY-*;<0w(9zUsa`y<KEXallFcHeZ0~N3YmcmJJGAx5rK=j0E za5`KA*TQvhJ=_F0!#Y?GPr>`}0elD_L2JhUJmwmE8vi$T`t55?ORiYQ96@p|%f9*g z+H-5zQ%h}~&e!evHQgs#9+mn_U3?6mfav{CVHfP# zelTGGjDy4Ax7Yt;@Ipk^6s@bphw*6q)-#Dc_xRTJ=;m8z%Q{H6`V3vF2(8}eC-reS z90A#o1INQ6SPU1z#c&B+3M=6<5S#D{xDpsr&28>wTCAi0)h-+X=Txi##mrM9lMXsvXg?h`F*rT$VEeV{Lh zjo%**hS4wv#=)|nY9G-x8 z;MeK@>+mw{x%PE^4%cBL)MxWGwx{~glDScnHHGyOS@m!( zrKoij=ZZ_DHI>$_-DrJrAXZIe$^HKI|6g^VXjv`*A!69QEHv>ZKS&H{S!FLSJ;Ut)~n5erP}12OJCY;Cy%(-iEIISucb#SPHkn zYM6Nl<2{r@KNFv!Gkae;4??`CtvqcJb%2>y)+ku$p4nS;o|BvhNWvZmH$ zsIkv@@%S>l2YWPiY}dI}$Ie#3YH+t@wVkCE%;Hm8f^m?Hzdym`zVvyx2cCtE@FCnu zUET}P2OGwIP!9{BC-r&|*!A4sMEAosIA{RtypTAQbwhXuK7h~RC+Ii~+Y#d7Jm?<7 zoB-~D2jE%Q1a}Q5KG*@94#jTx6Z!}i!Gc)Qi8G7~VLf~cF$vhEiNpyH!i7n!K_s*G z3_qqYR~gA17LHHF?nuLDHHtP3`;TUx0#CxEG30G5YtwKG{0Lpg5e^!m=V9~@$OblW_ipSxU|BU~yPV)BBms`5+CB1P@#Z zSHY)X*Jqyrtlxvw>veEFtc5S(fPsdQ3?)zxe}P-zY4`*>4Pp%dCcq3>3OfzQ-yaA6 zIe`SlF1n+?)WvP^CUhQ*?GD9I3oGGq_za?kus#fV&;*yki|`HXN1v9yo&-O@k8lY6 zdLrb)xgh=gLD&k?-~Xucy(ELM`j@)c4~~Egcnw7N?t;PST^B3_(ZzRzt&hLr`)lZA z(aRshC$I~8pqmFkHi*711Y2h>=KFZ`_5}Dn*Zuc04fvW&~ap$lWOjL%u{ zZ><0Sn(F&CGWeGZ7gqmL7hVvX>3nzq#CCcaUV&YZf*my-P6V;3E&|)G`U|$zRBWrG z;7M2qKY-X<-AABXU<4cm3*aKS2YyZ2_x?Tqvh??U5yI+U>f%jkhh01zjuHD97QtUZ z?B%ua7<>xtvR2hYL=_y%PDbO2lq_B?7G-`kI2%>Z&i z=2i9305`zDQTlr&>Yue-^}l;12dzvrtp24gUV`?_b7kH;09;T4=YTyAzLoDkfIT0M z9!I+XdtSVN@7Kc(kmZ;k*Yo}GBd{-FSq6KD;7Zu3^P&I!pad=?v_ zYbJdaCV>ychjAL54iCe27?_2h2+oD|@FNV%#s+`|AU=$Yr% zI33=Bn90~B5C;j61fyXL)K0PpwCmBXGpVm< z9Cc>blU+x4{n&Lfh`Jc;sFy{2|1(?$_rp&PSsPzPJO~LEau9M)$dzAn@OzGJdqnAk z4sH7DXVV| zf4UKAcS0-rZ&1fX?7vR${_dJ&cRj_-x1 zK3BtQumcXJF7n`7*Z@*DKZ0F1c751&A+rC@DYuY=kTx80<<}f+cc$}+^C0rl+HZR$ zB+!F|*415RgO54-_sM{_@1 z1NXyPcoLq2FX0`TE-GsS4WzD+Gqo93;N8*E(BL2;h<&#ekr&Du7=zu{Ex>oRxH9M zg`45p#YpG`#xBQ* zQ|9L19-yv;jZ4j~1?NhCyc#xwQNkJ@l)y5$6W)jYregoYB3KO@;XCL@d&q%f;dHnG zq@An>X)9mAm(Xh(^8tv1qv06%-&Pp0=eroV2x5ZmiI=!g9!HrNDcgsb6o zXp222cG*0rf^$J^w42~&co<%XFQJo%`8%XRAsh>*!40q;K8K#zb|F#;=^}p|@Wfo8 zlKAr59_W~*?qv+$3p^41+mGi!M4jk;ClxzejMmI z4|@+@$5t16y*>7N5{TVi2G7(mKZKC_|L;5qsh9tnB3SiL-K+jDb#Xs)DSJ-!Io~%N z$NUYRWPT-ctgqo4h-0o54|$LeOJFI;9P9yzZP0VEaeT^rtPl>GADows<$H0Xo}c~K z$m{=GMuVC~)xSMgE~8$m7X;_bi}-#J^W{D;5oGQ>2hN7o@FsLxNS#9o_~Bw$3tOPg z@r(m75o$r^-4}zoNYB6jzlrs~raWQwZ~H>VQ7<=v_(V3qPY}15^**SFvq5|%*TF6j zpGhCcfND4!#D{V{j5!hi3LFczPvvyJKMb~SWoIxSzx4?B^B+;SU^8gpsPVrI2B2C1}mYw!NY23Z57G?@N-l~2C;w)(?`!ODv@!O<8`vq3aC_yxxtQZUk=l{xc=o`2{6TvnQXGeIZ=`Gg zj`KHAW;@xl@Xz~N5hnbe$~LTvft=_6KziZf{uhqdwA1BJMi9M`#iJZ=ge|ZG zjP^Y90VX8E5l{$opcard#2^alK8x+l z5{qnImYD2VN{u#0v>{BXBZeqrqT%80a>HxX7;_C%S%wFq$2tyfqn?OpXB=?N4x`64 zV~rz*^0bPfege%jCQmfgGkWrCZr0DJxhI*#(^jQX-eMYJgB?gtR2pse8ShM^4S67q zRQa{Ge$FIj>YsUYb9R=|PNg!d#Z<)JInZdQQ)wHTN?W6kE=eC}67u>}_oO~Xk>)jgsYRHbMa8h<-n_DWLyL^_gZm(fAR>1r`f8LxW~vdhr+p%L=hU|TAE zBubNv_ojD9jsjT(z)zK>*}Q9bGEYGODNv}0&| z=!o%*c#@;>E#@d)#n71;I)%p2siQ&FQ#zLs)e3pZ#JL9{yA16d8c*jQ^aJ_1uC_dW zs()}$ezGgu$e8o>uB-U$O8?V;a@J#1&M=mGpt{l#^|a07zcib8XoZ)71qK2(xqLM;g-{FjeUqH z#+YY*yK60$p`Usr2m5XkUrPNI3VzL zMhP$4DpGjqPhDss-IhJdulC8<7LSIE9A0`#7o#WP*R-Dn68@kT!b?x+LXNvFyRyS9 zknnw42ruov3pwt#Y(>XeAmRHS5jj87zPpg)Zp)T*ngxvUMhPwWoHnUeD_|7vC_S{v zsHL{+sD07oY#ih|4=QFJ+P1cmohC-6@k;_NzfC5srJJGNTWfS{wzZhlcqMJ9PQ_uj z7kPlYaB@5JP)B9c4lqty{@?*W5vCu*&H;QLljW+X-acJuSAavK-NzSOPvhquQad-k#sQBS|yxc$Du`#Z=gr!*>8Ovs z=#e=5lIvWbUOsAU@AIn89(2uHod!2~7x!EGQJ*mfJbJ~!o2TT|Y> z=lRkPK0l#{_pp->-27bolt*UF`TOD95od&vBRYgc3?T)o(MFXqI`fqmcX``McX>pOONp!2e8zWn~ialhPl z=8x~4|B2b_uQzpk{Qa!MpRIgv{9{XHU z-)kq{lX$`Y-A;eK;K8EXGRt3ly8BC$a^4(KI{3uv&pB@Prb8~i{GctVQ(pdiucA$9 zb8b8PhNpMk`FP@n%L~??xH|Tuoc1+o=TGr|SbEhB2_FG$qf6nlN&8{U}M z@5$Jz_ty9P_|pZwpT6s?1K!Pj%75hIL9ebj<<`63Heb8@Pp=O6GWP9Re;a)4xHBgl zwe{uihrgfm*`J1XX`9}B<}bYa*7q-@OBVKJ>uqzHPm*kJpI+d5GquMf-8MIx^}e!U z^ZRsaSibr8OXKqTK2dYp!QL}2++4Woh?jB~_kH7oC2bzR-+fxo&DE#5k6GGl^R+*Z zcztwL|Bb8HOei|{$!W9BP2Ifw*24zx|KkTg?>hL98*kq9#rm%O_a894;Eh>3>z>OR z{8iHt=dJnt?SsEdxV35Gp)1>8{ME9%9vXhmJ9nS;{ksn=-&B%adeWT512-M_=9%YD z+H}!{*K~V)+N_U<=gz6wkn`uB4=%4A-u;KpTh~>2|2FlQnah*%#-6{W_fzlmIs3+f zjfLlZn_Bn&xQ?sOICtTrb4#zxJz(xBYddyoIBP}m>z=m#OJDnLNx`FMpZej$Uw41J zXl?eJH(zqay>}hg5Vd;lnHL|u=AOH5^PTYe{Z$#YYpND3uXQEf`hDM9|8z`;#qH)C zd+?^u{(k>M3o~9Y)_i&LbyF`)es27Ux4!eV_rfE-JMQxN_r7+^$Qg^y_~n_E8*a_N z{^csq9n)5IEI*{L|A)KZIJV6H`r5uLo=p2>$63!;-21?`EzwWCf7B;CcK+$sS5G}N z?aI?%{BX{`xAuSI%ek-Y^VG$6em?1kK96oX_MkUpLYVw`EzsZhUes}M8KUmex zh%TS@V*4Atlh$oME#`~&7YvSht?Q1_Yp*?M%!kkZZNPK;+3c{_)-Rr_Wq{*v_2~Oz62IZ|MZj4=dJXue$WZ z&YyqNyGP2@r?k)Y> zd~|h}1&ixm*l$7iGtOAmb7kYI&27G@dw%o`*U|0?-yC{LQ+n=W$9`N|wC?k=Mbn;q z;LHQoKk`s+mxh#XlP7#tlie@r``-CI_RY=g@sj@^OICFG{EMP(n;S0r>7>brP2C!w z(|^jJ@{+F^H0-YxXWrxOdcq}BKkfR<{Hi;T@6?cf^GgfQ?05gfr@Cx7blD;Me|+&* zqc4x?chouk-oN;Q=o8xAe8Z%t*1CT1%qTc?NBzX!6CPSJar)gKUuZ0zod53H!rKph z`{8G=yZy`_%MW(F_~6n}34`waAtUXvRd!@D2VoVvAf zN4xx9_y4@_kiR@ou)5>D-mRyP*r)rrl>OegsPLxCy7YVb!!Msny1MY}>aH_pj5@XL z5AT1rzUMiAzo*yxd7IC>DcSvV_K!1{jhSBmz>N0ae!lu|$1FH^`+l9j`SGkzWFsd04=uE{#McwNV1pLr_U``7ZQpR+ffmhsT@ zEBDPku5{9%1sk^AfAT&ZQs=GMvTe{!t1^}qSFZW&@}c`b^XK}QBcB=4Z~KPYA=PJ{ zHgx9eW$xlbdRL8GG41oOAKiEL*7yD~qi{vi19_GEUNP$Go_Skt*)a9C^6ZSyH@T;7 z%Dn87W8OZ!V$x-g-&%OkqV&~$y7qc)S;zJnZ?>H}>y&T)RuSFlfDIF`{JiG-cixIy zx6gr}4m{|+CFO^`wD5(WZ>U*${`%#Ai(0bz#vSJz_Tgovckh4ig+qVt_}269Uz7a6 zy0-KG_We6gOm1rb!h_d*^Ii7nJFZ!|GB#sE_3Bq=)GT~zz4y(&k6+U3;17B{7~k;1 zY12C&nDy}fsoM+kD$e^T#dlBLlWz^a;qj5D-2L;)$MXA6JjHd)wDGAUHn@7VjeT+D zE&q5nFY&XS;d2J<9C^*O=_k+mVbe9nnEP)V@gBmV?o)JazjeD(O1?dzZCZyvE&Xmuw@vr89dz01 z>a+LhdE5<|-t3(ZFIl(tm3>d|b>Eq%csn0@-;~r{9Y(#ftNQureTLrp-lNxl=RLjs zDLW_ToU~$G%;cdz)~#9_gs5g$GonObzJq+xz%G=#IKlN+y1Qc`rozon%wCx zSKNBuJx4!0eRl2j$LtvAu8Mno`ac%ummT=rCC@(p^pj_fm|x*u|JwYjt8QF-=dj`) zr>^@kV_o{XMK2wCV#E7aAHQX5+e0Xoa=UzJN5yq+A z?TzRcS6p!qSNbwY4+|T~wC$mWWXE7^*&=ye9!u=8?E8}%JNtYu-{1Y5p>LnQ@zz(` zE&Fg}bn4-QkKF!w^lh=7<4pRm6TOgK!Wx4lWt0yfL{UHr*>N`5|GenNZ@dx_Wy6B?O(=ZAh?kS`A`HiU>3MR z@*qE9EI(r-KV>36XVK5pub7utTg&T>vl8_yXXRCw^14HL<(<6tN?v^ZA?OWJOYY=DCF%4xK?=8EfAeC9gc=$ zU?vc?F$ajA{jj`34R{(77Y?s0f=b{CI^$T7iSSEI%Rhmw(3#fU7t&x9jE1o=1AK5M zoCSXYnVzqKzrm}p2{ywU@Dp@kIz9jf!C)8)!&c}_myU&rFbO6@9#q3kunwMvXJ7+thn;W` z{kb3XheP0SSOgctrLYn%2l-LQpP(1h*Mp!B^n%b zD`kXna0FyP7L>tKxD2j@tKe#ozH&gcYu5qO&fj&wkosL0JbJ-~|4-j9_%oeu2OWyP zjyrnuue1hqJWiw_a(skw@K-1VGzS0R&{?u%iM;BuJ6@c&JI>`)ccb$T?$tNqx$0)L z+d+@zv;B@3bv|l`L=gVh*65<{!Eg`!*7x*qA8?5~b|EvbcT$t_$f96RRZy)Y6l$2BS-yU1=*lI^QI19 zq&2p2@pw+oA#d`lEXR|#-sEi>C2y(ZP2S-29(fz% z$Q#QVYUnwJPZ?@fgA6S{f(#`&WKxEXOF@Q;9UwzPCLLOaf@?uke<^qVPw-(J&iI!3TA)2u_6Ma28w$m%u8x z7H)^T;9*z`&%*QYI=lrR!>8~Cd24q746u}JWNyYSq zd6*@~L4WGPgvpQ((r)TtDVzrP!=vyXd;(nuQ>QQ)j)aHcao7es;Mw8i8x9`L>I*Cz ztKZZ-ka~@Q=P=k_hU5%n3hzu{7=w!^B3rltZibiORcM=woFN%TLNQE*dT4}e;Cgrx zo`R3zQ!pnn?87Itp)X(=_Rwi?8{7_KvDXfVMQ|eQhb`0x2Eq`S0`lgdMQ|eA05`)s z@E-gCZ7|CYpMyyVCsos*;2n5RpsjuaG4olGfT~913Xj5*&|v{>52UYkqIdl^^dp`> zXkG>=BISfWkk5fI6jDJXsT|I2I-IuIZy~k!hC3i zt6&wp2rt1l_zXJjhjxdtFb;~K7*2*|a5vloTj5iX--z!Ec~A($d+_^$;Dvc`9-I#k z!Nc$tybb%HNxQ;GNQF`;gC(#OZiUq_gT_}1eS4!JAr<8JDGQ+p%Ao?TfU96D$nRA4 zK8U=*S+D}Gg&W{ecnrRP9k72NR_`GRQosdM!4C~^7Mu+?!>#ZXJOeTT-U=Q2A}<&O zLts2igkxYPEP<2YR#**hz+2F%9}n!p2uOt@aDfkwgG=EucnqF^ZLl3W_s4>OAutT4 zKt3#hg|HGXhmEiazJ_n1J7)9#kN`>WJ^Ta*A42r_jwr+zp??SMVx|WHWpOTj3Wl7$pyYo**OZK*)j|kP)^J z=D}jf8BAVbJ~Y8!;2c;Dx5HcT4#;nu^?~!@B3K7c!PoG2U}KRH4TE3^OoAzJ5}W~R z;0|~io`tXA8|XWXHV#oSv|q@CNl*#L!ntrh+z$`IOYkcE0>*GgWf%d|;Al7jmcRvY z5%>?B^1Dw>a3Nd_cf-B#2D}BhCyn+H1Bb%V zFas9CBDe%r!lUpwY=zI^XZQsM#d9yD!YG&piy%9JHV=2eUGO1%0{?(r@PF-{3w%`7 zoyYIYWbzsmK%twpK*WL>%zgk-<}bLWPc$qY`C?&q`J&zyX|IrrW< z_jexm+;h(V+?PFx;|VfxGYg8K1UAA$un(Sxv+&RGC0vG4V`xVp6XrrGl))45eRvgK zhd1F2d;xvNa?U^#oP<+gNoM2#888>BVHNC!gYXXg1}x(U2SZ>eH&Z zC>(?1a1lO-p;I^}a5pT2t?(qAf?vX4;0oM2mE#8T4Uk+|4Qt?supI_Xqn%Hs?SDa2;PQw;LjlMM;|nwu>qvRY;b|R1N{+r6!yY?I0dKSb7+Bn zPVxbx!2x%{Qdkd1Vci1S8`uZW!+Cfg#xEq_Pz$SJ7wm?s&Lf=B-f%8R-%fV7iyAMe) z7V@DGPM5GR94)1vfs61tyyfCp!pVD?1c(2GOK@8mV=I^k^Wj0*07u~;VRQxOBTR+q zkPS{qSiv!Z$uJcby2%6NLm`w`QWsz?+z$yWsdF#~?to>G5066w9E3ygK70U?RU97} z4T-P_?u06+fv4daH~~M0e}|8N8$C5M41u9A2QtA8E8!_UV@((kk6i-sJsC?vnTOYHjJ-hSEM>k@<|XI%X3XfJ5Pt(~ zAtISKycKSP+d<|JXTfa91er&aIYgO1Y#V@WF_5$kW{w0#gE3#0W@ny-`JcOC1<3r+ zQ=@ct;va`2lNl?*C-52EJOw)!mcUZj0uAs6`~v<9zJ#GunS%l+$oD$silba<+>V_o zcIRmjyHmd9BzEVJEW$%Jh~2pk#O^!*Vt4)S(?5O`QZPZ$A<>1`4U!L95@i&{+IN@~uyj!%~K);=s7*{Ns z@^p@ru$44KakoPZl8N>|SB%{Lv#db-nfU!C&JM$s$_AWV%j~)7thv{w#@2iA^YG{2 zVdD8Tlja_&J%WM5Fgk;wxb|v`5^0bvx-&!uD3KkSpx5u zN`*afP3@OzX1`P_?uly>*ukF0zVsfxPQ@veJxSm9tn4e5KIxi-m3j$ zZ=^ZT(rZ)GRTX!hh5hp^d8|uNV}A#y=5-A@HNBkDXhFlKYqW?)3mUeo64G14!3plA z6YHgd-7jgWkLb0j{wtN1`UrIDBl1|6fc`oTnhI~NZ+MF-EgR==%N3<%v!Z3=JZ`xn z;R0znXn1_|q){`R(v$WePuFV_J!u#6u1K(8dJdX0UrqXP!zsiMY&Z3&0z`dzza)NiLmIMZYpC1|&bM5sNhB_RTtz&$H6o#|XH309;6cdkfvwtuxGL?Rcse?_hZ@STG&>YF`Q6 z(ohnW(KPEFERH}Ot*?Y`XDEr(SR^{w8-Y4nUkTmHP!hIyBz&!nkTRm%7fPbphC~ND z>67~I&@U<~Q%7|`NC<*5PBsy3Zl95Ph{xG1uTR}0J zz1PK1_FflbT-HyF+{vpcT9vWv{ks_Q-s|!Vl(&C;Tb6Kp3d>IrE`o3ogyWOY9hZA+ z_dmU5M4(^1_Yk#E!bOliK}OTR2XWFrJT`5O)~i>OCf}gdU*f@KT+dXHgps_rrE2x! zdtBZFo(D6G4Z3fZA{HmRFOd>Yl_HZJqqx{F?+{tRS-qP7vQ;0}OL!xc_*~;t|9zJw z?3}?3NSV!%7HfpnY>8<5me!nBr=2iNG!+ry7V)T71&?o4Yjz$?D<(cW52v}=mQT#g zL84>UtX7lR6cuTfN3N7J5-%(D@-K%spj7Zkm|H7nE!m-BkBy8li&L@B3=n%7Z#i)h zlk78Re1oaJ2Puw;Fk7QZu~}>W>e@fu%Vefa974OmF6f*jM;28M+8mtOk%86 z`^fuVj8fyueY`3uPb}?Thmy)wDPP|H&Mz(`Yiat?im-CDB8@Z;S5N6FA@4LxDeI*s zrI642g-QuCjOscjdUJx-a@PEDgg#xB{qc`(J@8tbI%a*eTL?9l!hDS~>ZMI*jhRc^ zZ#!(2E#ih+w1Cem>A!~m-?#)uSevYewZq!_^;Jo}ArErC3*B-0nIH;rb2l!K;}rdY z-gX33jm~h&_LvstV`GN1{4s4C&GUo7kYwOQV%XQu_MW^K88uvAo{sP)x^spPD8(Kg1b zx?jbT9VM5xmOp8GbOj?`Z+|!|((UM-Q5;Qm94$&5&3YVJjbr@o(<^%K8eaZCUjnW4 zg^}_lP(Np4z4@UXUtFGFYI|X8v^ILg%l|4T;q>7&eDz5e~ zAho6$q>ld)RDaCQ(w|~hGOXZQ5q=N+bbP5xPJFR=mg2|bORFsAN+rGxzYbppR5DtS z_~oqRvYX6zYR+_L;+Q0Rj;o@!Jio?WWnWy)i<|V{C2is)tfZr$y0&tKt4ytX|K`0c z>B*Ld`pX?f?wSe}R??7_UsYyzy4J3BOElN@$4t7OmMm9cmAl$qQe&TAQsOEsw&%L5 zir6<5w84``OBt!<*N-M{xbzE?T5kMJ-L#L+s99|(XDL_deZ-d@Nc^x1mq54#!X*$c zfp7_gOCVeV;Sva!K)3|LB@ixwa0zs_1cKTBVpp5bojJGNG067h)7byFT|Su3Hml#Z zdD!4wgHU!mo|;otwz`CcO(1gsTR`mDZ6Fsrwu4+G-3?+-9{{oG4})A3c^za9;3S9* z{s-{3^<`U*Yo@!ZrdUmwiCru+u;R-ct@tuqsN2hNDlRq!^#_v(Nx!5m$Q*)vR6&v; z(+85JMXs9iVikexi2EZM*5lJOJL|GJ1!SjGkaby>v@dgJrZ3Bwmzg~`M{Scij5N0I zMxz{Gbf!^a;>$d>p)0ktqb2y+yuy1%&O6-gwXcM*5a^Q*WG~ z-ksglOZL-qc2iGgbEUkD{NB+`y)k}z>D|;z^6WpB88AtwQU6&~>z%1D6Zx(pQ&?(0 zLr>~(SL=)D8T%W0MtOEMeG~oCcUw2pH^EQu)^6$<=ZBGBdpGrr^TW^^*iAj-{4n(T zc2mzdo`#;ZMct_{#`$6B$y{xB^sb*D1C)-m!ClwWKV6SR*o8|VTms<|2$w*(1i~c{ zE`h(v5-@C184qECD%(QFW2V9Ru{WfY;qajiH(mvtZaHNPb=G9#*uPk zquB3aM<>7lkn!pu;8qvyn;-_X*sOLK3d7*CoF)4kOPZgF^K(|3rpZG_zrv*#7@2&?tx{H2l-F{g-`^=Py)-L6kKpG zltDSPa_i9wd^c3WN~nTrsDWCLFst$FU=6H=``~_92M@r5P!H>218js%@DMxLm)R;e08 z!G-AhYgUsXZDF6t7_-{*gucI=O6|@$<=IE&-j-Koiv-4{t2@u+Ea;l+p_$v`mvn@p zQbC|?z4VY{IBSjXUxu=;f0%e??@Vko%E15kK(oQs`2Rri--94l2sQtr=r}L`WxpI1tK7FN$3BzTOH`UY;8b;kJ@gFt8M-vv*EPDO155bN(6SA8PzkUlz+r zi!;&l%U%1GlzoBfY4z=){_jowlNK)$LXBU}SLv7kTCTJC_l{SJLDDbHvGkeJj!0gl zE=zrq<0{)@J-&Bb;pM;m5|~;rImcaFRajhY&nYf1F03go%BfjX&bP0Yra99bOLFE7 zv#Sl+`4wzrn|-#cq^8t9tH@QuSG0zCzKB&2$``TR>NePPcVTS>AGgv!i&fw%D0jJ+ zSLIihuJMTdRivg*y}dnae8G$A8_;$7lVB^{`WL~9swWra*W_1ok8yEkO>u>t4KDo5 z^l8KH8<&zkcIJd};}d7jnvtG3Zgz5dVp`g`35hAm$rHyXrKHc8IU#wSQFKMsUCnS| zEzwsjsVE;deJauG-y&OBTvF}3DoLxYa&0{+WJluEvmMQ(OPP0 zE7YF0D5|BUA_z+DRjt-mRBLaW?|(9xB#6A;exE*{j^{UbIrpA>=4^BBxf5BJOta>i z&hn|TR201`3$dJ41%DM36v(|x@b1P=IZDi+&n>h<+_T#$cMHL>yv&6-Hd2U6qTi5y zLn?Qz+_iA;BX1U3N6{!xh|H!+p<}7)uiENripEd3z|wG}T;6grte3ZRC>1g3D@>r7 zvtegh%S8k&C;Us6#_-f&A-3}g2f7HI=&E7E)eyncmU=fK_HaV4>OxH7(C=ABvAh-} z1gDGZEamH2mYy6}H&lpCoOn8{q7Y-*VMmIpsGT(Smd4NS<<6#~PF`8Qj7u+f!?tlL zPb~d1o^D(kKauemxqX_A+MMUeGNHa9*%5b>N>$r#A; z1lzKbg!2h~SjxhduYTFChX7;ZSKq*BWCd9c&? z$&5>5&Kb8UxL>v2HA^-P5gE6Q1!fm457QK8mv<9m=;KRc;ve5%vaPyRSmI|)bII;U zFZ$$uF5axhle-P4$+qZWMd9Scn&&AMeS8~6CG~IU=i}>}Q`7R4sfAxiXt1weaG<|x zTG_L5@s>x=WDmu`U-htaDn2AY?Oy7TfU*t=RM%FnT6{vFnqRqkBV(LFHHp!$k)K6e z-$6;47WN)-5v`*;N4N4wj8E@he30s9TfI1fU^UX#yVO?cun_faTd(4KxF}wK)zZs5VenE?uWw@iOtqy;T}$KU=#e?eE^ZpnZV46^ z7E#d&9U>Y>MYl_c@Q5CfoRpcCG{U2QdfJH0^pupOOtpiXlUd)i0UnW^b6#_Mr(VwF zPUHRNm^x|sZt_rVCq>%cICta7?jt*ntX{bKwX~jTEncGm)Yb)Q%qN%(k(J)eT&a>g zEqsh{EPVHgaSykl#Z|DxcY^$`5030 zw8M)oubNNZtbRYax?;Qhb&b}79&gT+HoD74FYjErbNb4iD~BH)p4dLocewm8hL82& z`F|{3*`Mow_*kWLHL$QWUNt1!)_g+g95H6{qlJ+yOQW$N|DNdtdA#>ijw~q`Lm}6% zl3X$DeM5y%XWy<8S}LuCJy}`eVoVAv%;OQ+sZmp+bQ>tLjVQ0ke&<{6In_j6SylV7 zls;QcER_wyP-L$dlKqr?H58eybOZV)icCbtI2O0z-ZARZ+h+e4C1^gaUAc|zIwOha zRC30GdmfE#m?7EamYlKRUX;cbH?5AUo$gs~aa}TbA&YCMA=&?`;_{qce#^R`eIbh~ z$&l=SQ&G*C;nsP-tq^VPgjfeVdm%EAk0YqSZI?Nm;esqoz*|_1)!2eBk&m;u;-Joc zJx*QvdW8DwcI!$vY}@9+?2~l!~cm8KJQ~!<-XiO-8ZwUjjgcWV=gqG zn~e4nmcms{neL`)XZe)d@tiSzA!~D@A=&??+N}D_iqb_gg%ySJ24%;YWOzcoa*OOmAC%20|EnXv!gDLR=Q$|rVn}wmCHKM&%H}XAn_K>%ESJ0W=hV=iXK}SR zB>P`gT%L2wZ&_bjypToJ+K}x3|B6ai>ZbaCn_Ea@fHDl3$i^zH#+UdCd+;^(As2E0 zmxlwmj4QZmtK(UQ+)>VS(q~KxKeyJYdvedHjv}>7{p=_k}=qhA|Jv^c}2d3r&BLrk;{i_B>Ue~ z^FJO@e8j}5QDsov; zNAV4A;3j@WMeek%U=15ohArgXxIG-;17G;rQ{?`vlvm_ytY63?Z)`~Rzp2P&Nd+SW z?a=`pF&INI6sbrvF z9{Z4s{WySwI0QM@b{KN5P0q88bL0!bF`l2Wu(E~UxrDd~(GH8T0p?YOsD_#df+@ds zus|Y8SCKyP9Ul9qp8Cp5{bfmQ-QRsIRLkaBzK8$o$gBNRpTqv$CwYH+=vDm+S$+?u zRp@|G4fPR>D0D(1Qjm(tP_Y#2@fi+OX~1uASh<8dFrnz|V2_4qg4XDQK8`tuvpp2` ze0G5P>K1FY+A?eP{4yJzsg1Cml&|Rnp^(pReKu$Hys4y!$pU^mo^m2qm;%1Ub1}!l8UOfh0`AO6Ku^c8p+Z{U6G!gW-sMe@)Cqwy~G<4;bb=AF!Tmie1*ASpy~_hEk5jFua3>_z|-7D^c=IAZtN?%z=tJwGEY^6U$Nf0C|v= zqC%;P@u$c+mhDDjHuTUHrcF?N3)@sRS#Kgyhx#JxPY6QM2?H@4^C9ciav1B@A=VdA zzuv|^$h!7DEf;AOfR&+0TqZ20MLmY-|0GAu*9L_E5 z{AFR4O3Y;fjjiK6EhO8QTR=F`Qk)S3*=qWsKVHWwX{3?0xhKwY*zF6Vr7Z2b`7t$57OBs$2uo6GO*u@mE9z)k+=xU0-7D>?89*RzOJ&D)` zV;7Xm`h7gWyi#4!9@b|!qY2@7bH1i=3$jb9*@EhZg;<0yunQ+~3Y8;-Xoe9mv~eL{ z>bdMAj2UKQhO>ibo6sr8asRU4kR3jn2xvb6MlwAMUtl%D@aF@!uG~6zLjLnLEdGagezrYLJ@Zv9b^TWjbWLQI zPQ^0p#2MU%Z5-buh(QY8!YX`?OL%}<Y1{}vgCUrXHINnf2yQ}FWG5=HGnzwI z>aH+W>^#=5_hgKNzk1WMdmD0Q!`g@^zsd?YU>7YxwuWC&wXbXy41bZ+kG={kXdK2y za-8*#lW37xM}v`#<}}X0k;dbMAOvGDhCnu|_fUmKB^#Ib;4+HJyQtNLveeM(jIGa$ z^`^8wV=HXOdRJPXu{9>KuAwEGz!$Prw#8^Hz?Zm*Drt12=!pqfjeRH{m6aYM%781d zNGDQshivK-V3ASMP<)EO;>1NK7Ww#E92Tld!M-W zljRg7%kGId%POZJL+L#c=ac0Wq&`_rL87b@dD`BxN+d{>y|=6q2@)ZE>Ge11t*x44 za{X0BoqOY&8h70xC+lWM6QzZk|63Qc77Blw7O&dguBNv7-QTd;p>T82@97+4b-Q)x zV@BN`!_J$xU$c%9FLUlK5hbh?q3Z6`s^Y+JsU7$&wU(c^YejGLjd4(S-s!2v-gV6h zx*Mo)YRbI;`?y#Wt%ER=e-bEah|A|}b{432@72(C*zHp}`fi&)CSGh9vuINbbFa&< z?VYiA`S{Pje%sS=--%5t6CU1ecO<@LwufU%gOmPumxTS0xx>A}$GaCSS{bwcR?GUH zS6y58djGrNjwjc4ojReabJM=>+bsC~)6cfo34SB1?bLTVzd!D$j6v--h0mCk=|1bd zBM(9}`vXULXZ@K~>A=WNx--sKr_K)fVPE987fn9dP_0||^^5lxcwU(G(WlLWI;@F_ zG@qFB`J8XAW#4bL&#`5r+^w~5H+rxB)MW>{?~1?gvf)ziq`z6_@cm}&+X=y?2qQ@dgwHK(-fG9xY!)q z2b&ZNpRtSlclM6SDOSqVKXKKqG=C5pO`pQ=GOQ#bTZ@%eyvevB1zxDWL+l4>Y zg^Vk>e_?x_cN>4^d1$qdL-N@-PqaGy(b->jtsB?Q#WlNbt>E_tZ}++u9^r0wyUFki zo?q$eHhAlNr$K%`85zqyA82jY^VO(?fGHW4?Z=%x8rAac*_FIvwocl;+-2Q+Yk$qZ zSAX0$DOVz=taY>duvhgH-&YA=^lqS~U#r#mZpp)2)qm&n?r*Q{xo^sAY3p~dSvR?f z|K?9^4>&}>(PP=BppBt(C+@3wtj~rG-T{H;FW1;`tKOpffkQ)d*ZQ>5q`q=>#hHeC zDmq=R>GFNnfM!R=9(tIawrK9&+(k8CwsEz3aDMc(V=-r5e&?ENM%bHb?zO5FPh31V z&c5+Q+or$S#f7~+qe0!;wPW);ogNyfUs(Otuv2&TWOR6aZ;0vo*t4zsIqphQ*H5y3 z*hM`#;C|l1wLN`IIWXFZ+w#l~&sWjYreia-3&;!LwO+EXUYdRkYUKH`Iq!W+eZxy%}>>OyH7A@~AZSeM`u*u!RPj73` zcD}8jZGzoPA9THD8|s;oJ@owQbEm@{BC;0_nKMtB80Mn8K5l-5Zbe*h=*98F>vi9F z_mtbcm0|7+^Onx-@kaYd_4Lll8iI;N}0Inp&h_sCy? z(IG!~9a{hRqCNW$^bEOqVf!ARZUIqs&(x^#XN5b>>y00{bJQj4kze0k_DRiqqnAyM zIME_LanoBBj+h>)G-K(oO%sC_1k@ec?bMo)N4oA0zFP76h>D-pp1#&A?9H8r247nq zI{akl*3q-~9Bgpy#Hkq#0|H0i88B^Een|7Lo%b#{G~i<6?&C+;xa~0g&dR%8Tl;o5 z7svFuw5)=+jmQ0lt#d~F(0KD`jbf*m7Ir@RnI=kC#Yg{>i4vl5(Wr+X+UxzbimO|3 zTXbbKKxb9*IxdfL*1x7z>M5J_Yqd%f&00(S9~nyE=IW-3wbJ((L#K+&XUS6v{}z?b zPX0MoFUY^|d5G4GBo^Zq^&^rLkCh86D2i^C z1@or(8vC#xS5e!NJ7ly%YqZ5+Oh-08#2T!_LEMBDd1!;mu!A2uUAaTGmQMoIq$KY(UrO}V0c%~iBHcNhHt{$iW_IT3i(v9sRt9- zHMkRF4nEC`+fSPGMw)cA58E{5p;6o<#n6mto0cDU;VqeIs#N`WYo(>miHN2V(Iz5_ zAff|AG=zx85Yagz$|IuwMD!jJEhQp%B9hZmxy0jH7!MVS*9793gf}o9GqDKoVine4 zGd{&`?7<-`8s!mI&fq&-#x>l<18A+8@rM;`;0AZpLqh~16p?6!ICMd8^uw_dD;{nBGLZ4g_l@JIyi&_

wH-KZVth;A5wWH+i> zk7`s4OvE(Y#eH~GXOEm)6x_yesyne)ME zoW&w>2w^{V zQ_uI}G`@pvC<7rhM< zhZI%N9MMQa;Sh!83gqDk9zu>o8Y2+P@ga1Pl>fv?`Z;XINt}T;ivAEzsEV4c8QWk~ z8&1M;oWesCz_Tsw0z;6F37CXU_*gDuh#&Xx2O?s5%8Dtml>cH@R^c;z(~brL`5a&< z#v%)gupF0h9hEy!XYeW`stFj&sBR+WU>?51CA`y_T*X>!!Y#--VwWzoE=1{gi@`@d zX-?SJn@R?4B3%l65QsP=U^eFC^S+cjZ2D2o@K0hk5>udu)j*!~ArRp>3ORdu71v=m zh%OGgrh{o>xPt4@4q;@9hG>kJ&=+Hn1!K1|Y^V^gz}UU)Wjzf@{e4cYde&6A^oyCN-f>tihPY%qT|MX8yY?C z!?7~mT#-DM-{2erCHYIK(fAK0U<&kDfQ48N`Hl4}Iyv(Vgb{oTjmN8)fQeA~vRUm( z&$Ql?b_R_Xjk&hLZ!B%=&^ys>Rze7xA`O{XjdeJO3$UkKbwV`SLOyeT1e$}s)mK*d>a(^xUv zysVLORbyH>ji{gPt28q;Wk%6dzt~Ul*7pif>gj*+Q(W}neu{I+LEic-xm|qZgwjE4 zh`K0fpuaM;C}>9j@l_2l2F(vNMBk$%xai7+7^5pZM@DB}cqNfuNB^HjO0~_G1C=*5 zidKK3i4s;p@Ujqp>6?TpJ?yk{tLRlwAh+}t6C2;pW-ZT=4*b`CKpD~;m3vEUS7X@%d6Q6 zcismO;jmtOBXa*E^T?#~-Y53%-5lFo>8LpR`4CjPjnS#@bM1d>4}KR@{7B z2@_$J)7N~KGCxYunwTmY{f+)g6}?-O;-E~@`$j3T5e|GzJI?fAY00t$ODmS`SX#5} z#*+R>3}8uLBvM$)EFHnpp5=J`jwt1o8uFAj>8VK`UB(O_k(4UvQVQ#jZ!mWitUK!$ zXDZI&thIm``+mHvU4`pz*&p=z{VSz#y?0Ah{x@kRgvpD@rOa=+9M)^|x@e_yCAE)6 zD?g56syB^S_PWa4m*KKBx+SN~e6~~g*u_`*?%7TWDs@WZm!2tMfu&B-J=-Y^n~M{6=-E#3 zFLjE0w`WS2U#U~lpY0UiQm5>Ewo_#5G8Cn|-lqFABrK45kCIaopY4>A(s$Rdf3{Of zO5a^y@NB1)l)k&Z?QtQ7}{y^csd1JIP)Z&u?$^ykx z{%@Lmf70o4?*YcYg`F>LPNYGG>$fK<&e~CI=}#mnJ++1VLIx^shP7_2xyXHg7Fkww zp4|7>#=gUq`N>L3r4}>&3jfE%6@+F9{n%t>tl1#eMP>biWTmaOe1=}w<#AR4J*uZ! zIy;6n)sG#l#8}C%FWG|@1=i6t%F{m>tc+D==tmAwbY}AjlQE?zZS}iT6kpk?D49Ht zjMayQDOURYR3$+9YqM{fa!8q-(LkS-skm8ta8CQd{WH^trw<&lc|)cWr|`)AjsF8p Cnh@^* From 8d2fabb1664345b1c1adc326965df063c1be7186 Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Sun, 23 Dec 2012 11:28:46 -0800 Subject: [PATCH 02/11] Fixes to avoid compiler warnings when building with MinG. Still won't build - see issue #21 --- display/win32.c | 2 +- makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/display/win32.c b/display/win32.c index 45c5e453..3eb26802 100644 --- a/display/win32.c +++ b/display/win32.c @@ -278,7 +278,7 @@ ws_init2(void) { } #ifdef THREADS -static volatile init_done; +static volatile int init_done; static DWORD msgthread_id; static DWORD WINAPI diff --git a/makefile b/makefile index a27f63a4..be69d984 100644 --- a/makefile +++ b/makefile @@ -729,7 +729,7 @@ ifeq ($(WIN32),) DISPLAY_OPT = endif else - DISPLAYL = ${DISPLAYD}/display.c $(DISPLAYD)/w32.c + DISPLAYL = ${DISPLAYD}/display.c $(DISPLAYD)/win32.c DISPLAY_OPT = -DUSE_DISPLAY endif From 34e0523ba8904b77905b5e9c813752058f338896 Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Mon, 24 Dec 2012 09:23:19 -0800 Subject: [PATCH 03/11] Set version to 4.0-0 Beta --- scp.c | 3 +++ sim_rev.h | 12 ++++++++++++ 2 files changed, 15 insertions(+) diff --git a/scp.c b/scp.c index fb48f579..11676794 100644 --- a/scp.c +++ b/scp.c @@ -2315,6 +2315,9 @@ if (cptr && (*cptr != 0)) fprintf (st, "%s simulator V%d.%d-%d", sim_name, vmaj, vmin, vpat); if (vdelt) fprintf (st, " delta %d", vdelt); +#if defined(SIM_VERSION_MODE) +fprintf (st, " %s", SIM_VERSION_MODE); +#endif if (flag) fprintf (st, " [%s, %s, %s]", sim_si64, sim_sa64, sim_snet); #if defined(SIM_GIT_COMMIT_ID) diff --git a/sim_rev.h b/sim_rev.h index 91c549b4..6ddd3b96 100644 --- a/sim_rev.h +++ b/sim_rev.h @@ -27,10 +27,22 @@ #ifndef _SIM_REV_H_ #define _SIM_REV_H_ 0 +#ifndef SIM_MAJOR #define SIM_MAJOR 4 +#endif +#ifndef SIM_MINOR #define SIM_MINOR 0 +#endif +#ifndef SIM_PATCH #define SIM_PATCH 0 +#endif +#ifndef SIM_DELTA #define SIM_DELTA 0 +#endif + +#ifndef SIM_VERSION_MODE +#define SIM_VERSION_MODE "Beta" +#endif /* The comment section below reflects the manual editing process which was in place From 9333e1f5e6b68720b97026eae5bc1bdb1546ad14 Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Wed, 26 Dec 2012 09:02:12 -0800 Subject: [PATCH 04/11] Update of pdp11_dmc --- PDP11/pdp11_dmc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/PDP11/pdp11_dmc.c b/PDP11/pdp11_dmc.c index 602ca456..67347cf5 100644 --- a/PDP11/pdp11_dmc.c +++ b/PDP11/pdp11_dmc.c @@ -340,13 +340,13 @@ REG dmp_reg[] = { MTAB dmc_mod[] = { { MTAB_XTD | MTAB_VDV, 0, "PEER", "PEER=address:port" ,&dmc_setpeer, &dmc_showpeer, NULL }, - { MTAB_XTD | MTAB_VDV, 0, "SPEED", "SPEED" ,&dmc_setspeed, &dmc_showspeed, NULL }, + { MTAB_XTD | MTAB_VDV, 0, "SPEED", "SPEED=bits/sec (0=unrestricted)" ,&dmc_setspeed, &dmc_showspeed, NULL }, #ifdef DMP { MTAB_XTD | MTAB_VDV, 0, "TYPE", "TYPE" ,&dmc_settype, &dmc_showtype, NULL }, #endif - { MTAB_XTD | MTAB_VDV, 0, "LINEMODE", "LINEMODE" ,&dmc_setlinemode, &dmc_showlinemode, NULL }, + { MTAB_XTD | MTAB_VDV, 0, "LINEMODE", "LINEMODE={PRIMARY|SECONDARY}" ,&dmc_setlinemode, &dmc_showlinemode, NULL }, { MTAB_XTD | MTAB_VDV | MTAB_NMO, 0, "STATS", "STATS" ,&dmc_setstats, &dmc_showstats, NULL }, - { MTAB_XTD | MTAB_VDV, 0, "CONNECTPOLL", "CONNECTPOLL" ,&dmc_setconnectpoll, &dmc_showconnectpoll, NULL }, + { MTAB_XTD | MTAB_VDV, 0, "CONNECTPOLL", "CONNECTPOLL=seconds" ,&dmc_setconnectpoll, &dmc_showconnectpoll, NULL }, { MTAB_XTD | MTAB_VDV, 006, "ADDRESS", "ADDRESS", &set_addr, &show_addr, NULL }, { MTAB_XTD |MTAB_VDV, 0, "VECTOR", "VECTOR", &set_vec, &show_vec, NULL }, { 0 }, From 59871d90b85b2cf35a9632297f1a2f47a64dcaf8 Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Wed, 26 Dec 2012 10:23:07 -0800 Subject: [PATCH 05/11] Removed the DEV_NET flag from pdp11_dmc --- PDP11/pdp11_dmc.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/PDP11/pdp11_dmc.c b/PDP11/pdp11_dmc.c index 67347cf5..0ac328ee 100644 --- a/PDP11/pdp11_dmc.c +++ b/PDP11/pdp11_dmc.c @@ -370,16 +370,16 @@ DEVICE dmc_dev[] = { { "DMC0", &dmc0_unit, dmca_reg, dmc_mod, DMC_UNITSPERDEVICE, DMC_RDX, 8, 1, DMC_RDX, 8, NULL,NULL,&dmc_reset,NULL,&dmc_attach,&dmc_detach, - &dmc0_dib, DEV_FLTA | DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_NET | DEV_DEBUG, 0, dmc_debug }, + &dmc0_dib, DEV_FLTA | DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_DEBUG, 0, dmc_debug }, { "DMC1", &dmc1_unit, dmcb_reg, dmc_mod, DMC_UNITSPERDEVICE, DMC_RDX, 8, 1, DMC_RDX, 8, NULL,NULL,&dmc_reset,NULL,&dmc_attach,&dmc_detach, - &dmc1_dib, DEV_FLTA | DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_NET | DEV_DEBUG, 0, dmc_debug }, + &dmc1_dib, DEV_FLTA | DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_DEBUG, 0, dmc_debug }, { "DMC2", &dmc2_unit, dmcc_reg, dmc_mod, DMC_UNITSPERDEVICE, DMC_RDX, 8, 1, DMC_RDX, 8, NULL,NULL,&dmc_reset,NULL,&dmc_attach,&dmc_detach, - &dmc2_dib, DEV_FLTA | DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_NET | DEV_DEBUG, 0, dmc_debug }, + &dmc2_dib, DEV_FLTA | DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_DEBUG, 0, dmc_debug }, { "DMC3", &dmc3_unit, dmcd_reg, dmc_mod, DMC_UNITSPERDEVICE, DMC_RDX, 8, 1, DMC_RDX, 8, NULL,NULL,&dmc_reset,NULL,&dmc_attach,&dmc_detach, - &dmc3_dib, DEV_FLTA | DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_NET | DEV_DEBUG, 0, dmc_debug } + &dmc3_dib, DEV_FLTA | DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_DEBUG, 0, dmc_debug } }; #ifdef DMP @@ -387,7 +387,7 @@ DEVICE dmp_dev[] = { { "DMP", &dmp_unit, dmp_reg, dmc_mod, DMP_UNITSPERDEVICE, DMC_RDX, 8, 1, DMC_RDX, 8, NULL,NULL,&dmc_reset,NULL,&dmc_attach,&dmc_detach, - &dmp_dib, DEV_FLTA | DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_NET | DEV_DEBUG, 0, dmc_debug } + &dmp_dib, DEV_FLTA | DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_DEBUG, 0, dmc_debug } }; #endif From af93ca96c383b1b862033eb1ca1595c123ac8db6 Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Wed, 26 Dec 2012 10:51:19 -0800 Subject: [PATCH 06/11] Added /dev/ttyAMAn devices as possible serial port lines on *nix systems. Fixed reset disconnect logic for serial lines --- sim_serial.c | 9 +++++++++ sim_tmxr.c | 8 +------- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/sim_serial.c b/sim_serial.c index 1bba576f..ff9ba2b9 100644 --- a/sim_serial.c +++ b/sim_serial.c @@ -897,6 +897,15 @@ for (i=0; (ports < max) && (i < 64); ++i) { close (port); } } +for (i=0; (ports < max) && (i < 64); ++i) { + sprintf (list[ports].name, "/dev/ttyAMA%d", i); + port = open (list[ports].name, O_RDWR | O_NOCTTY | O_NONBLOCK); /* open the port */ + if (port != -1) { /* open OK? */ + if (isatty (port)) /* is device a TTY? */ + ++ports; + close (port); + } + } for (i=1; (ports < max) && (i < 64); ++i) { sprintf (list[ports].name, "/dev/tty.serial%d", i); port = open (list[ports].name, O_RDWR | O_NOCTTY | O_NONBLOCK); /* open the port */ diff --git a/sim_tmxr.c b/sim_tmxr.c index 3299b695..441300af 100644 --- a/sim_tmxr.c +++ b/sim_tmxr.c @@ -901,14 +901,8 @@ if ((lp->destination) && (!lp->serport)) { if (lp->connecting) sim_close_sock (lp->connecting, 0); lp->connecting = sim_connect_sock (lp->destination, "localhost", NULL); - lp->ipad = malloc (1 + strlen (lp->destination)); - strcpy (lp->ipad, lp->destination); - lp->cnms = sim_os_msec (); } -else { - tmxr_init_line (lp); /* initialize line state */ - } -lp->conn = FALSE; /* remove connection flag */ +tmxr_init_line (lp); /* initialize line state */ /* Revise the unit's connect string to reflect the current attachments */ lp->mp->uptr->filename = _mux_attach_string (lp->mp->uptr->filename, lp->mp); /* No connections or listeners exist, then we're equivalent to being fully detached. We should reflect that */ From 33a2ec9e35d9509e48785926818403604cfea8d1 Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Wed, 26 Dec 2012 10:55:35 -0800 Subject: [PATCH 07/11] Fixed missing ipad setup for outgoing connections --- sim_tmxr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sim_tmxr.c b/sim_tmxr.c index 441300af..966bfd84 100644 --- a/sim_tmxr.c +++ b/sim_tmxr.c @@ -783,6 +783,8 @@ for (i = 0; i < mp->lines; i++) { /* check each line in se lp->conn = TRUE; /* record connection */ lp->sock = lp->connecting; /* it now looks normal */ lp->connecting = 0; + lp->ipad = realloc (lp->ipad, 1+strlen (lp->destination)); + strcpy (lp->ipad, lp->destination); lp->cnms = sim_os_msec (); break; case -1: /* failed connection */ From ac53fd10a68c782bb5397db367e4fe5c2eaedef1 Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Wed, 26 Dec 2012 11:50:10 -0800 Subject: [PATCH 08/11] VAX 8600 Simulator from Matt Burke --- VAX/vax610_defs.h | 1 + VAX/vax630_defs.h | 1 + VAX/vax730_defs.h | 1 + VAX/vax750_defs.h | 1 + VAX/vax780_defs.h | 1 + VAX/vax860_abus.c | 718 ++++++++++++++++ VAX/vax860_defs.h | 522 ++++++++++++ VAX/vax860_sbia.c | 355 ++++++++ VAX/vax860_stddev.c | 1154 ++++++++++++++++++++++++++ VAX/vax860_syslist.c | 125 +++ VAX/vax_cpu1.c | 4 +- VAX/vax_defs.h | 2 + VAX/vaxmod_defs.h | 1 + Visual Studio Projects/VAX860.vcproj | 479 +++++++++++ makefile | 24 +- 15 files changed, 3385 insertions(+), 4 deletions(-) create mode 100644 VAX/vax860_abus.c create mode 100644 VAX/vax860_defs.h create mode 100644 VAX/vax860_sbia.c create mode 100644 VAX/vax860_stddev.c create mode 100644 VAX/vax860_syslist.c create mode 100644 Visual Studio Projects/VAX860.vcproj diff --git a/VAX/vax610_defs.h b/VAX/vax610_defs.h index d90b9f83..55735c3c 100644 --- a/VAX/vax610_defs.h +++ b/VAX/vax610_defs.h @@ -81,6 +81,7 @@ #define MT_IORESET 55 /* I/O Bus Reset */ #define MT_TBDATA 59 /* Translation Buffer Data */ #define MT_MBRK 60 /* microbreak */ +#define MT_MAX 63 /* last valid IPR */ /* Memory */ diff --git a/VAX/vax630_defs.h b/VAX/vax630_defs.h index 9e91fa1a..145ab38c 100644 --- a/VAX/vax630_defs.h +++ b/VAX/vax630_defs.h @@ -87,6 +87,7 @@ #define MT_IORESET 55 /* I/O Bus Reset */ #define MT_TBDATA 59 /* Translation Buffer Data */ #define MT_MBRK 60 /* microbreak */ +#define MT_MAX 63 /* last valid IPR */ /* CPU */ diff --git a/VAX/vax730_defs.h b/VAX/vax730_defs.h index 46905c0d..e17d6a5d 100644 --- a/VAX/vax730_defs.h +++ b/VAX/vax730_defs.h @@ -94,6 +94,7 @@ #define MT_SBITA 53 /* SBI timeout addr */ #define MT_SBIQC 54 /* SBI timeout clear */ #define MT_UBINIT 55 /* Unibus Init */ +#define MT_MAX 63 /* last valid IPR */ /* Machine specific reserved operand tests */ diff --git a/VAX/vax750_defs.h b/VAX/vax750_defs.h index b186b78b..9552279f 100644 --- a/VAX/vax750_defs.h +++ b/VAX/vax750_defs.h @@ -115,6 +115,7 @@ #define MT_CAER 39 /* Cache error */ #define MT_ACCS 40 /* FPA control */ #define MT_IORESET 55 /* Unibus Init */ +#define MT_MAX 63 /* last valid IPR */ /* Machine specific reserved operand tests */ diff --git a/VAX/vax780_defs.h b/VAX/vax780_defs.h index 8305a58c..a3506d5c 100644 --- a/VAX/vax780_defs.h +++ b/VAX/vax780_defs.h @@ -120,6 +120,7 @@ #define MT_SBITA 53 /* SBI timeout addr */ #define MT_SBIQC 54 /* SBI timeout clear */ #define MT_MBRK 60 /* microbreak */ +#define MT_MAX 63 /* last valid IPR */ /* Machine specific reserved operand tests */ diff --git a/VAX/vax860_abus.c b/VAX/vax860_abus.c new file mode 100644 index 00000000..c2d6f4a2 --- /dev/null +++ b/VAX/vax860_abus.c @@ -0,0 +1,718 @@ +/* vax860_abus.c: VAX 8600 A-Bus + + Copyright (c) 2011-2012, Matt Burke + This module incorporates code from SimH, Copyright (c) 2004-2008, Robert M Supnik + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the name(s) of the author(s) shall not be + used in advertising or otherwise to promote the sale, use or other dealings + in this Software without prior written authorization from the author(s). + + abus bus controller + + 26-Dec-2012 MB First Version +*/ + +#include "vax_defs.h" + +/* SBIA registers */ + +#define SBIER_TMO 0x00001000 /* timeout */ +#define SBIER_STA 0x00000C00 /* timeout status (0) */ +#define SBIER_CNF 0x00000100 /* error confirm */ +#define SBIER_MULT 0x00000004 /* multiple errors */ +#define SBIER_TMOW1C (SBIER_TMO|SBIER_STA|SBIER_CNF|SBIER_MULT) + +/* PAMM */ + +#define PAMM_IOA0 0x18 /* I/O adapter 0 */ +#define PAMM_IOA1 0x19 /* I/O adapter 1 */ +#define PAMM_IOA2 0x1A /* I/O adapter 2 */ +#define PAMM_IOA3 0x1B /* I/O adapter 3 */ +#define PAMM_NXM 0x1F /* Non-existant address */ + +#define PAMACC_ADDR 0x3FF00000 /* PAMM address */ +#define PAMACC_CODE 0x0000001F /* Configuration code */ + +#define PAMLOC_ADDR 0x3FF00000 /* PAMM address */ + +/* MBOX registers */ + +#define MSTAT1_V_CYC 26 /* MBOX cycle type */ +#define MSTAT1_M_CYC 0xF +#define MSTAT1_CPRD 0xE /* CP read */ + +#define MSTAT2_NXM 0x00000008 /* CP NXM */ + +#define MERG_V_MME 8 /* Mem mgmt en */ + +#define MDCTL_RW 0x00006F0F /* MBOX data control */ + +/* EBOX registers */ + +#define EBCS_MFTL 0x00008000 /* MBOX fatal error */ + +#define EHMSTS_PROCA 0x00020000 /* Process abort */ + +#define EHSR_VMSE 0x00000020 /* VMS entered */ + +/* VAX 8600 boot device definitions */ + +struct boot_dev { + char *name; + int32 code; + int32 let; + }; + +uint32 nexus_req[NEXUS_HLVL]; /* nexus int req */ +uint32 pamloc = 0; +uint32 cswp = 0; +uint32 ehsr = 0; +uint32 mdctl = 0; +int32 sys_model = 0; +char cpu_boot_cmd[CBUFSIZE] = { 0 }; /* boot command */ + +static struct boot_dev boot_tab[] = { + { "RP", BOOT_MB, 0 }, + { "HK", BOOT_HK, 0 }, + { "RL", BOOT_RL, 0 }, + { "RQ", BOOT_UDA, 1 << 24 }, + { "TQ", BOOT_TK, 1 << 24 }, + { "CS", BOOT_CS, 0 }, + { NULL } + }; + +extern int32 R[16]; +extern int32 PSL; +extern int32 ASTLVL, SISR; +extern int32 mapen, pme, trpirq; +extern int32 in_ie; +extern int32 mchk_va, mchk_ref; +extern int32 crd_err, mem_err, hlt_pin; +extern int32 tmr_int, tti_int, tto_int, csi_int; +extern uint32 sbi_er; +extern jmp_buf save_env; +extern int32 p1; +extern int32 sim_switches; +extern DEVICE *sim_devices[]; +extern FILE *sim_log; +extern CTAB *sim_vm_cmd; +extern int32 fault_PC; /* fault PC */ +extern UNIT cpu_unit; + +void uba_eval_int (void); +t_stat abus_reset (DEVICE *dptr); +t_stat vax860_boot (int32 flag, char *ptr); +t_stat vax860_boot_parse (int32 flag, char *ptr); +t_stat cpu_boot (int32 unitno, DEVICE *dptr); + +extern t_stat (*nexusR[NEXUS_NUM])(int32 *dat, int32 ad, int32 md); +extern t_stat (*nexusW[NEXUS_NUM])(int32 dat, int32 ad, int32 md); +extern int32 intexc (int32 vec, int32 cc, int32 ipl, int ei); +extern int32 iccs_rd (void); +extern int32 nicr_rd (void); +extern int32 icr_rd (t_bool interp); +extern int32 todr_rd (void); +extern int32 rxcs_rd (void); +extern int32 rxdb_rd (void); +extern int32 txcs_rd (void); +extern int32 stxcs_rd (void); +extern int32 stxdb_rd (void); +extern void iccs_wr (int32 dat); +extern void nicr_wr (int32 dat); +extern void todr_wr (int32 dat); +extern void rxcs_wr (int32 dat); +extern void txcs_wr (int32 dat); +extern void txdb_wr (int32 dat); +extern void stxcs_wr (int32 data); +extern void stxdb_wr (int32 data); +extern void init_mbus_tab (void); +extern void init_ubus_tab (void); +extern void init_nexus_tab (void); +extern t_stat build_mbus_tab (DEVICE *dptr, DIB *dibp); +extern t_stat build_ubus_tab (DEVICE *dptr, DIB *dibp); +extern t_stat build_nexus_tab (DEVICE *dptr, DIB *dibp); +extern void sbi_set_tmo (int32 pa); +extern int32 sbia_rd (int32 pa, int32 lnt); +extern void sbia_wr (int32 pa, int32 val, int32 lnt); +extern t_stat sbi_rd (int32 pa, int32 *val, int32 lnt); +extern t_stat sbi_wr (int32 pa, int32 val, int32 lnt); + +/* ABUS data structures + + abus_dev A-Bus device descriptor + abus_unit A-Bus unit + abus_reg A-Bus register list +*/ + +UNIT abus_unit = { UDATA (NULL, 0, 0) }; + +REG abus_reg[] = { + { NULL } + }; + +DEVICE abus_dev = { + "ABUS", &abus_unit, abus_reg, NULL, + 1, 16, 16, 1, 16, 8, + NULL, NULL, &abus_reset, + NULL, NULL, NULL, + NULL, 0 + }; + +/* Special boot command, overrides regular boot */ + +CTAB vax860_cmd[] = { + { "BOOT", &vax860_boot, RU_BOOT, + "bo{ot} {/R5:flg} boot device\n" }, + { NULL } + }; + +/* The VAX 8600 has three sources of interrupts + + - internal device interrupts (CPU, console, clock) + - nexus interupts (e.g. MBA, UBA) + - external device interrupts (Unibus) + + Internal devices vector to fixed SCB locations. + + Nexus interrupts vector to an SCB location based on this + formula: SCB_NEXUS + ((IPL - 0x14) * 0x40) + (TR# * 0x4) + + External device interrupts do not vector directly. + Instead, the interrupt handler for a given UBA IPL + reads a vector register that contains the Unibus vector + for that IPL. + +/* Find highest priority vectorable interrupt */ + +int32 eval_int (void) +{ +int32 ipl = PSL_GETIPL (PSL); +int32 i, t; + +static const int32 sw_int_mask[IPL_SMAX] = { + 0xFFFE, 0xFFFC, 0xFFF8, 0xFFF0, /* 0 - 3 */ + 0xFFE0, 0xFFC0, 0xFF80, 0xFF00, /* 4 - 7 */ + 0xFE00, 0xFC00, 0xF800, 0xF000, /* 8 - B */ + 0xE000, 0xC000, 0x8000 /* C - E */ + }; + +if (hlt_pin) /* hlt pin int */ + return IPL_HLTPIN; +if ((ipl < IPL_MEMERR) && mem_err) /* mem err int */ + return IPL_MEMERR; +if ((ipl < IPL_CRDERR) && crd_err) /* crd err int */ + return IPL_CRDERR; +if ((ipl < IPL_CLKINT) && tmr_int) /* clock int */ + return IPL_CLKINT; +uba_eval_int (); /* update UBA */ +for (i = IPL_HMAX; i >= IPL_HMIN; i--) { /* chk hwre int */ + if (i <= ipl) /* at ipl? no int */ + return 0; + if (nexus_req[i - IPL_HMIN]) /* req != 0? int */ + return i; + } +if ((ipl < IPL_TTINT) && (tti_int || tto_int || csi_int)) /* console int */ + return IPL_TTINT; +if (ipl >= IPL_SMAX) /* ipl >= sw max? */ + return 0; +if ((t = SISR & sw_int_mask[ipl]) == 0) + return 0; /* eligible req */ +for (i = IPL_SMAX; i > ipl; i--) { /* check swre int */ + if ((t >> i) & 1) /* req != 0? int */ + return i; + } +return 0; +} + +/* Return vector for highest priority hardware interrupt at IPL lvl */ + +int32 get_vector (int32 lvl) +{ +int32 i, l; + +if (lvl == IPL_MEMERR) { /* mem error? */ + mem_err = 0; + return SCB_MEMERR; + } +if (lvl == IPL_CRDERR) { /* CRD error? */ + crd_err = 0; + return SCB_CRDERR; + } +if (lvl == IPL_CLKINT) { /* clock? */ + tmr_int = 0; /* clear req */ + return SCB_INTTIM; /* return vector */ + } +if (lvl > IPL_HMAX) { /* error req lvl? */ + ABORT (STOP_UIPL); /* unknown intr */ + } +if ((lvl <= IPL_HMAX) && (lvl >= IPL_HMIN)) { /* nexus? */ + l = lvl - IPL_HMIN; + for (i = 0; nexus_req[l] && (i < NEXUS_NUM); i++) { + if ((nexus_req[l] >> i) & 1) { + nexus_req[l] = nexus_req[l] & ~(1u << i); + return SCB_NEXUS + (l << 6) + (i << 2); /* return vector */ + } + } + } +if (lvl == IPL_TTINT) { /* console? */ + if (tti_int) { /* input? */ + tti_int = 0; /* clear req */ + return SCB_TTI; /* return vector */ + } + if (tto_int) { /* output? */ + tto_int = 0; /* clear req */ + return SCB_TTO; /* return vector */ + } + if (csi_int) { /* console storage? */ + csi_int = 0; /* clear req */ + return SCB_CSI; /* return vector */ + } + } +return 0; +} + +/* Used by CPU */ + +void rom_wr_B (int32 pa, int32 val) +{ +return; +} + +/* Read 8600 specific IPR's */ + +int32 ReadIPR (int32 rg) +{ +int32 val; + +switch (rg) { + + case MT_ICCS: /* ICCS */ + val = iccs_rd (); + break; + + case MT_NICR: /* NICR */ + val = nicr_rd (); + break; + + case MT_ICR: /* ICR */ + val = icr_rd (FALSE); + break; + + case MT_TODR: /* TODR */ + val = todr_rd (); + break; + + case MT_ACCS: /* ACCS (not impl) */ + val = 0; + break; + + case MT_RXCS: /* RXCS */ + val = rxcs_rd (); + break; + + case MT_RXDB: /* RXDB */ + val = rxdb_rd (); + break; + + case MT_TXCS: /* TXCS */ + val = txcs_rd (); + break; + + case MT_SID: /* SID */ + if (sys_model) + val = VAX860_SID | VAX865_TYP | VAX860_PLANT | VAX860_SN; + else + val = VAX860_SID | VAX860_TYP | VAX860_PLANT | VAX860_SN; + break; + + case MT_PAMACC: /* PAMACC */ + if (ADDR_IS_REG (pamloc)) + val = PAMM_IOA0; /* SBIA */ + else if (ADDR_IS_MEM (pamloc)) { + if (MEMSIZE < MAXMEMSIZE) + val = (pamloc >> 23); /* 4MB Boards */ + else + val = (pamloc >> 25); /* 16MB Boards */ + } + else val = PAMM_NXM; /* NXM */ + val = val | (pamloc & PAMACC_ADDR); + break; + + case MT_PAMLOC: /* PAMLOC */ + val = pamloc & PAMLOC_ADDR; + break; + + case MT_MDCTL: /* MDCTL */ + val = mdctl & MDCTL_RW; + + case MT_EHSR: /* EHSR */ + val = ehsr & EHSR_VMSE; + break; + + case MT_CSWP: /* CSWP */ + val = cswp & 0xF; + break; + + case MT_MERG: /* MERG */ + val = 0; + break; + + case MT_STXCS: /* STXCS */ + val = stxcs_rd (); + break; + + case MT_STXDB: /* STXDB */ + val = stxdb_rd (); + break; + + default: + RSVD_OPND_FAULT; + } + +return val; +} + +/* Write 8600 specific IPR's */ + +void WriteIPR (int32 rg, int32 val) +{ +switch (rg) { + + case MT_ICCS: /* ICCS */ + iccs_wr (val); + break; + + case MT_NICR: /* NICR */ + nicr_wr (val); + break; + + case MT_TODR: /* TODR */ + todr_wr (val); + break; + + case MT_ACCS: /* ACCS (not impl) */ + break; + + case MT_RXCS: /* RXCS */ + rxcs_wr (val); + break; + + case MT_TXCS: /* TXCS */ + txcs_wr (val); + break; + + case MT_TXDB: /* TXDB */ + txdb_wr (val); + break; + + case MT_PAMACC: /* PAMACC (not impl) */ + break; + + case MT_PAMLOC: /* PAMLOC */ + pamloc = val & PAMLOC_ADDR; + break; + + case MT_MDCTL: /* MDCTL */ + mdctl = val & MDCTL_RW; + break; + + case MT_EHSR: /* EHSR */ + ehsr = val & EHSR_VMSE; + break; + + case MT_CSWP: /* CSWP */ + cswp = val & 0xF; + break; + + case MT_MERG: /* MERG (not impl) */ + break; + + case MT_CRBT: /* CRBT (not impl) */ + break; + + case MT_STXCS: /* STXCS */ + stxcs_wr (val); + break; + + case MT_STXDB: /* STXDB */ + stxdb_wr (val); + break; + + default: + RSVD_OPND_FAULT; + } + +return; +} + +/* ReadReg - read register space + + Inputs: + pa = physical address + lnt = length (BWLQ) + Output: + longword of data +*/ + +int32 ReadReg (int32 pa, int32 lnt) +{ +int32 nexus, val; + +if (ADDR_IS_SBIA (pa)) return sbia_rd (pa, lnt); /* SBI adapter space? */ +if (ADDR_IS_REG (pa)) { /* reg space? */ + if (sbi_rd (pa, &val, lnt) == SCPE_OK) + return val; + } +MACH_CHECK (MCHK_RD_F); /* machine check */ +return 0; +} + +/* WriteReg - write register space + + Inputs: + pa = physical address + val = data to write, right justified in 32b longword + lnt = length (BWLQ) + Outputs: + none +*/ + +void WriteReg (int32 pa, int32 val, int32 lnt) +{ +int32 nexus; + +if (ADDR_IS_SBIA (pa)) { /* SBI adapter space? */ + sbia_wr (pa, val, lnt); + SET_IRQL; + return; +} +if (ADDR_IS_REG (pa)) { /* reg space? */ + if (sbi_wr (pa, val, lnt) == SCPE_OK) + return; + } +mem_err = 1; /* interrupt */ +eval_int (); +return; +} + +/* Machine check */ + +int32 machine_check (int32 p1, int32 opc, int32 cc, int32 delta) +{ +int32 acc; +int32 mstat1, mstat2, mear, ebcs, merg, ehmsts; + +mstat1 = (MSTAT1_CPRD << MSTAT1_V_CYC); /* MBOX Status 1 */ +mstat2 = MSTAT2_NXM; /* MBOX Status 2 */ +mear = mchk_va; /* Memory error address */ +merg = (mchk_ref << MERG_V_MME); /* MBOX error generation word */ +ebcs = EBCS_MFTL; /* EBOX control/status */ +ehmsts = EHMSTS_PROCA; /* Error handling microcode status */ + +cc = intexc (SCB_MCHK, cc, 0, IE_SVE); /* take exception */ +acc = ACC_MASK (KERN); /* in kernel mode */ +in_ie = 1; +SP = SP - 92; /* push 25 words */ +Write (SP, 88, L_LONG, WA); /* # bytes */ +Write (SP + 4, ehmsts, L_LONG, WA); /* EHM.STS */ +Write (SP + 8, 0, L_LONG, WA); /* EVMQSAV */ +Write (SP + 12, ebcs, L_LONG, WA); /* EBCS */ +Write (SP + 16, 0, L_LONG, WA); /* EDPSR */ +Write (SP + 20, 0, L_LONG, WA); /* CSLINT */ +Write (SP + 24, 0, L_LONG, WA); /* IBESR */ +Write (SP + 28, 0, L_LONG, WA); /* EBXWD1 */ +Write (SP + 32, 0, L_LONG, WA); /* EBXWD2 */ +Write (SP + 36, 0, L_LONG, WA); /* IVASAV */ +Write (SP + 40, 0, L_LONG, WA); /* VIBASAV */ +Write (SP + 44, 0, L_LONG, WA); /* ESASAV */ +Write (SP + 48, 0, L_LONG, WA); /* ISASAV */ +Write (SP + 52, 0, L_LONG, WA); /* CPC */ +Write (SP + 56, mstat1, L_LONG, WA); /* MSTAT1 */ +Write (SP + 60, mstat2, L_LONG, WA); /* MSTAT2 */ +Write (SP + 64, 0, L_LONG, WA); /* MDECC */ +Write (SP + 68, merg, L_LONG, WA); /* MERG */ +Write (SP + 72, 0, L_LONG, WA); /* CSHCTL */ +Write (SP + 76, mear, L_LONG, WA); /* MEAR */ +Write (SP + 80, 0, L_LONG, WA); /* MEDR */ +Write (SP + 84, 0, L_LONG, WA); /* FBXERR */ +Write (SP + 88, 0, L_LONG, WA); /* CSES */ +in_ie = 0; +sbi_er = sbi_er & ~SBIER_TMOW1C; /* clr SBIER etc */ +ehsr = ehsr | EHSR_VMSE; /* VMS entered */ +return cc; +} + +/* Console entry */ + +int32 con_halt (int32 code, int32 cc) +{ +ABORT (STOP_HALT); +return cc; +} + +/* Special boot command - linked into SCP by initial reset + + Syntax: BOOT {/R5:val} + + Sets up R0-R5, calls SCP boot processor with effective BOOT CPU +*/ + +t_stat vax860_boot (int32 flag, char *ptr) +{ +t_stat r; + +r = vax860_boot_parse (flag, ptr); /* parse the boot cmd */ +if (r != SCPE_OK) /* error? */ + return r; +strncpy (cpu_boot_cmd, ptr, CBUFSIZE); /* save for reboot */ +return run_cmd (flag, "CPU"); +} + +/* Parse boot command, set up registers - also used on reset */ + +t_stat vax860_boot_parse (int32 flag, char *ptr) +{ +char gbuf[CBUFSIZE]; +char *slptr, *regptr; +int32 i, r5v, unitno; +DEVICE *dptr; +UNIT *uptr; +DIB *dibp; +uint32 ba; +t_stat r; + +regptr = get_glyph (ptr, gbuf, 0); /* get glyph */ +if (slptr = strchr (gbuf, '/')) { /* found slash? */ + regptr = strchr (ptr, '/'); /* locate orig */ + *slptr = 0; /* zero in string */ + } +dptr = find_unit (gbuf, &uptr); /* find device */ +if ((dptr == NULL) || (uptr == NULL)) + return SCPE_ARG; +dibp = (DIB *) dptr->ctxt; /* get DIB */ +if (dibp == NULL) + ba = 0; +else + ba = dibp->ba; +unitno = (int32) (uptr - dptr->units); +r5v = 0; +if ((strncmp (regptr, "/R5:", 4) == 0) || + (strncmp (regptr, "/R5=", 4) == 0) || + (strncmp (regptr, "/r5:", 4) == 0) || + (strncmp (regptr, "/r5=", 4) == 0)) { + r5v = (int32) get_uint (regptr + 4, 16, LMASK, &r); + if (r != SCPE_OK) + return r; + } +else if (*regptr != 0) + return SCPE_ARG; +for (i = 0; boot_tab[i].name != NULL; i++) { + if (strcmp (dptr->name, boot_tab[i].name) == 0) { + R[0] = boot_tab[i].code; + if (dptr->flags & DEV_MBUS) { + R[1] = ba + TR_MBA0; + R[2] = unitno; + } + else { + R[1] = TR_UBA; + R[2] = boot_tab[i].let | (ba & UBADDRMASK); + } + R[3] = unitno; + R[4] = 0; + R[5] = r5v; + return SCPE_OK; + } + } +return SCPE_NOFNC; +} + +/* Bootstrap - finish up bootstrap process */ + +t_stat cpu_boot (int32 unitno, DEVICE *dptr) +{ +t_stat r; + +printf ("Loading boot code from vmb.exe\n"); +if (sim_log) fprintf (sim_log, + "Loading boot code from vmb.exe\n"); +r = load_cmd (0, "-O vmb.exe 200"); +if (r != SCPE_OK) + return r; +SP = PC = 512; +return SCPE_OK; +} + +/* A-Bus reset */ + +t_stat abus_reset (DEVICE *dptr) +{ +sim_vm_cmd = vax860_cmd; +return SCPE_OK; +} + +/* Build dib_tab from device list */ + +t_stat build_dib_tab (void) +{ +uint32 i; +DEVICE *dptr; +DIB *dibp; +t_stat r; + +init_nexus_tab (); +init_ubus_tab (); +init_mbus_tab (); +for (i = 0; (dptr = sim_devices[i]) != NULL; i++) { /* loop thru dev */ + dibp = (DIB *) dptr->ctxt; /* get DIB */ + if (dibp && !(dptr->flags & DEV_DIS)) { /* defined, enabled? */ + if (dptr->flags & DEV_NEXUS) { /* Nexus? */ + if (r = build_nexus_tab (dptr, dibp)) /* add to dispatch table */ + return r; + } + else if (dptr->flags & DEV_MBUS) { /* Massbus? */ + if (r = build_mbus_tab (dptr, dibp)) + return r; + } + else { /* no, Unibus device */ + if (r = build_ubus_tab (dptr, dibp)) /* add to dispatch tab */ + return r; + } /* end else */ + } /* end if enabled */ + } /* end for */ +return SCPE_OK; +} + +t_stat cpu_set_model (UNIT *uptr, int32 val, char *cptr, void *desc) +{ +if (cptr == NULL) return SCPE_ARG; +if (strcmp(cptr, "8600") == 0) + sys_model = 0; +else if (strcmp(cptr, "8650") == 0) + sys_model = 1; +else + return SCPE_ARG; +return SCPE_OK; +} + +t_stat cpu_show_model (FILE *st, UNIT *uptr, int32 val, void *desc) +{ +fprintf (st, "model=%s", (sys_model ? "8650" : "8600")); +return SCPE_OK; +} diff --git a/VAX/vax860_defs.h b/VAX/vax860_defs.h new file mode 100644 index 00000000..f12cb954 --- /dev/null +++ b/VAX/vax860_defs.h @@ -0,0 +1,522 @@ +/* vax860_defs.h: VAX 8600 model-specific definitions file + + Copyright (c) 2011-2012, Matt Burke + This module incorporates code from SimH, Copyright (c) 2004-2008, Robert M Supnik + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the name(s) of the author(s) shall not be + used in advertising or otherwise to promote the sale, use or other dealings + in this Software without prior written authorization from the author(s). + + 26-Dec-2012 MB First Version + + This file covers the VAX 8600, the fourth VAX. + + System memory map + + 0000 0000 - 1FFF FFFF main memory + + 2000 0000 - 2001 FFFF SBI0 adapter space + 2002 0000 - 200F FFFF reserved + 2008 0000 - 2008 00BF SBI0 registers + 2008 00C0 - 200F FFFF reserved + 2010 0000 - 2013 FFFF Unibus address space, Unibus 0 + 2014 0000 - 2017 FFFF Unibus address space, Unibus 1 + 2018 0000 - 201B FFFF Unibus address space, Unibus 2 + 201C 0000 - 201F FFFF Unibus address space, Unibus 3 + 2020 0000 - 21FF FFFF reserved + + 2200 0000 - 2201 FFFF SBI1 adapter space + 2202 0000 - 220F FFFF reserved + 2208 0000 - 2208 00BF SBI1 registers + 2208 00C0 - 220F FFFF reserved + 2210 0000 - 2213 FFFF Unibus address space, Unibus 4 + 2214 0000 - 2217 FFFF Unibus address space, Unibus 5 + 2218 0000 - 221B FFFF Unibus address space, Unibus 6 + 221C 0000 - 221F FFFF Unibus address space, Unibus 7 + 2220 0000 - 23FF FFFF reserved + + 2400 0000 - 2401 FFFF SBI2 adapter space + 2402 0000 - 240F FFFF reserved + 2408 0000 - 2408 00BF SBI2 registers + 2408 00C0 - 240F FFFF reserved + 2410 0000 - 2413 FFFF Unibus address space, Unibus 8 + 2414 0000 - 2417 FFFF Unibus address space, Unibus 9 + 2418 0000 - 241B FFFF Unibus address space, Unibus 10 + 241C 0000 - 241F FFFF Unibus address space, Unibus 11 + 2420 0000 - 25FF FFFF reserved + + 2600 0000 - 2601 FFFF SBI3 adapter space + 2602 0000 - 260F FFFF reserved + 2608 0000 - 2608 00BF SBI3 registers + 2608 00C0 - 260F FFFF reserved + 2610 0000 - 2613 FFFF Unibus address space, Unibus 12 + 2614 0000 - 2617 FFFF Unibus address space, Unibus 13 + 2618 0000 - 261B FFFF Unibus address space, Unibus 14 + 261C 0000 - 261F FFFF Unibus address space, Unibus 15 + 2620 0000 - 3FFF FFFF reserved +*/ + +#ifndef FULL_VAX +#define FULL_VAX 1 +#endif + +#ifndef _VAX_860_DEFS_H_ +#define _VAX_860_DEFS_H_ 1 + +/* Microcode constructs */ + +#define VAX860_SID (4 << 24) /* system ID */ +#define VAX860_TYP (0 << 23) /* sys type: 8600 */ +#define VAX865_TYP (1 << 23) /* sys type: 8650 */ +#define VAX860_ECO (7 << 19) /* ucode revision */ +#define VAX860_PLANT (0 << 12) /* plant (Salem NH) */ +#define VAX860_SN (1234) +#define CON_HLTPIN 0x0200 /* external CPU halt */ +#define CON_HLTINS 0x0600 /* HALT instruction */ +#define MCHK_RD_F 0x00 /* read fault */ +#define MCHK_RD_A 0xF4 /* read abort */ +#define MCHK_IBUF 0x0D /* read istream */ +#define VER_UCODE 0x1 /* Microcode version */ + +/* Interrupts */ + +#define IPL_HMAX 0x17 /* highest hwre level */ +#define IPL_HMIN 0x14 /* lowest hwre level */ +#define IPL_HLVL (IPL_HMAX - IPL_HMIN + 1) /* # hardware levels */ +#define IPL_SMAX 0xF /* highest swre level */ + +/* SBI Nexus constants */ + +#define NEXUS_NUM 16 /* number of nexus */ +#define MCTL_NUM 2 /* number of mem ctrl */ +#define MBA_NUM 2 /* number of MBA's */ +#define TR_MCTL0 1 /* nexus assignments */ +#define TR_MCTL1 2 +#define TR_UBA 3 +#define TR_MBA0 8 +#define TR_MBA1 9 +#define TR_CI 14 +#define NEXUS_HLVL (IPL_HMAX - IPL_HMIN + 1) +#define SCB_NEXUS 0x100 /* nexus intr base */ +#define SBI_FAULTS 0xFC000000 /* SBI fault flags */ + +/* Internal I/O interrupts - relative except for clock and console */ + +#define IPL_CLKINT 0x18 /* clock IPL */ +#define IPL_TTINT 0x14 /* console IPL */ + +#define IPL_MCTL0 (0x15 - IPL_HMIN) +#define IPL_MCTL1 (0x15 - IPL_HMIN) +#define IPL_UBA (0x15 - IPL_HMIN) +#define IPL_MBA0 (0x15 - IPL_HMIN) +#define IPL_MBA1 (0x15 - IPL_HMIN) +#define IPL_CI (0x15 - IPL_HMIN) + +/* Nexus interrupt macros */ + +#define SET_NEXUS_INT(dv) nexus_req[IPL_##dv] |= (1 << TR_##dv) +#define CLR_NEXUS_INT(dv) nexus_req[IPL_##dv] &= ~(1 << TR_##dv) + +/* Machine specific IPRs */ + +#define MT_ACCS 40 /* FPA control */ +#define MT_PAMACC 64 +#define MT_PAMLOC 65 +#define MT_CSWP 66 +#define MT_MDECC 67 +#define MT_MENA 68 +#define MT_MDCTL 69 +#define MT_MCCTL 70 +#define MT_MERG 71 +#define MT_CRBT 72 /* Console reboot */ +#define MT_DFI 73 +#define MT_EHSR 74 +#define MT_STXCS 76 +#define MT_STXDB 77 +#define MT_ESPA 78 +#define MT_ESPD 79 +#define MT_MAX MT_ESPD /* last valid IPR */ + +/* Machine specific reserved operand tests */ + +/* 780 microcode patch 37 - only test LR<23:0> for appropriate length */ + +#define ML_LR_TEST(r) if (((uint32)((r) & 0xFFFFFF)) > 0x200000) RSVD_OPND_FAULT + +/* 780 microcode patch 38 - only test PxBR<31>=1, PxBR<30> = 0, and xBR<1:0> = 0 */ + +#define ML_PXBR_TEST(r) if (((((uint32)(r)) & 0x80000000) == 0) || \ + ((((uint32)(r)) & 0x40000003) != 0)) RSVD_OPND_FAULT +#define ML_SBR_TEST(r) if ((((uint32)(r)) & 0xC0000003) != 0) RSVD_OPND_FAULT + +/* 780 microcode patch 78 - only test xCBB<1:0> = 0 */ + +#define ML_PA_TEST(r) if ((((uint32)(r)) & 0x00000003) != 0) RSVD_OPND_FAULT + +#define LP_AST_TEST(r) if ((r) > AST_MAX) RSVD_OPND_FAULT +#define LP_MBZ84_TEST(r) if ((((uint32)(r)) & 0xF8C00000) != 0) RSVD_OPND_FAULT +#define LP_MBZ92_TEST(r) if ((((uint32)(r)) & 0x7FC00000) != 0) RSVD_OPND_FAULT + +/* CPU */ + +#define CPU_MODEL_MODIFIERS \ + { MTAB_XTD|MTAB_VDV, 0, "MODEL", "MODEL", \ + &cpu_set_model, &cpu_show_model }, +/* Memory */ + +#define MAXMEMWIDTH 25 /* max mem, 4MB boards */ +#define MAXMEMSIZE (1 << MAXMEMWIDTH) +#define MAXMEMWIDTH_X 27 /* max mem, 16MB boards */ +#define MAXMEMSIZE_X (1 << MAXMEMWIDTH_X) +#define INITMEMSIZE (1 << MAXMEMWIDTH) /* initial memory size */ +#define MEMSIZE (cpu_unit.capac) +#define ADDR_IS_MEM(x) (((uint32) (x)) < MEMSIZE) +#define MEM_MODIFIERS { UNIT_MSIZE, (1u << 23), NULL, "8M", &cpu_set_size }, \ + { UNIT_MSIZE, (1u << 24), NULL, "16M", &cpu_set_size }, \ + { UNIT_MSIZE, (1u << 25), NULL, "32M", &cpu_set_size }, \ + { UNIT_MSIZE, (1u << 25) + (1u << 24), NULL, "48M", &cpu_set_size }, \ + { UNIT_MSIZE, (1u << 26), NULL, "64M", &cpu_set_size }, \ + { UNIT_MSIZE, (1u << 27), NULL, "128M", &cpu_set_size } + +/* Unibus I/O registers */ + +#define UBADDRWIDTH 18 /* Unibus addr width */ +#define UBADDRSIZE (1u << UBADDRWIDTH) /* Unibus addr length */ +#define UBADDRMASK (UBADDRSIZE - 1) /* Unibus addr mask */ +#define IOPAGEAWIDTH 13 /* IO addr width */ +#define IOPAGESIZE (1u << IOPAGEAWIDTH) /* IO page length */ +#define IOPAGEMASK (IOPAGESIZE - 1) /* IO addr mask */ +#define UBADDRBASE 0x20100000 /* Unibus addr base */ +#define IOPAGEBASE 0x2013E000 /* IO page base */ +#define ADDR_IS_IO(x) ((((uint32) (x)) >= UBADDRBASE) && \ + (((uint32) (x)) < (UBADDRBASE + UBADDRSIZE))) +#define ADDR_IS_IOP(x) (((uint32) (x)) >= IOPAGEBASE) + +/* Nexus register space */ + +#define REGAWIDTH 17 /* REG addr width */ +#define REG_V_NEXUS 13 /* nexus number */ +#define REG_M_NEXUS 0xF +#define REG_V_OFS 2 /* register number */ +#define REG_M_OFS 0x7FF +#define REGSIZE (1u << REGAWIDTH) /* REG length */ +#define REGBASE 0x20000000 /* REG addr base */ +#define ADDR_IS_REG(x) ((((uint32) (x)) >= REGBASE) && \ + (((uint32) (x)) < (REGBASE + REGSIZE))) +#define NEXUS_GETNEX(x) (((x) >> REG_V_NEXUS) & REG_M_NEXUS) +#define NEXUS_GETOFS(x) (((x) >> REG_V_OFS) & REG_M_OFS) + +/* SBI adapter space */ + +#define SBIAWIDTH 19 +#define SBIABASE 0x20080000 +#define SBIASIZE (1u << SBIAWIDTH) +#define ADDR_IS_SBIA(x) ((((uint32) (x)) >= SBIABASE) && \ + (((uint32) (x)) < (SBIABASE + SBIASIZE))) + +/* ROM address space in memory controllers */ + +#define ROMAWIDTH 12 /* ROM addr width */ +#define ROMSIZE (1u << ROMAWIDTH) /* ROM size */ +#define ROM0BASE (REGBASE + (TR_MCTL0 << REG_V_NEXUS) + 0x1000) +#define ROM1BASE (REGBASE + (TR_MCTL1 << REG_V_NEXUS) + 0x1000) +#define ADDR_IS_ROM0(x) ((((uint32) (x)) >= ROM0BASE) && \ + (((uint32) (x)) < (ROM0BASE + ROMSIZE))) +#define ADDR_IS_ROM1(x) ((((uint32) (x)) >= ROM1BASE) && \ + (((uint32) (x)) < (ROM1BASE + ROMSIZE))) +#define ADDR_IS_ROM(x) (ADDR_IS_ROM0 (x) || ADDR_IS_ROM1 (x)) + +/* Other address spaces */ + +#define ADDR_IS_CDG(x) (0) +#define ADDR_IS_NVR(x) (0) + +/* Unibus I/O modes */ + +#define READ 0 /* PDP-11 compatibility */ +#define WRITE (L_WORD) +#define WRITEB (L_BYTE) + +/* Common CSI flags */ + +#define CSR_V_GO 0 /* go */ +#define CSR_V_IE 6 /* interrupt enable */ +#define CSR_V_DONE 7 /* done */ +#define CSR_V_BUSY 11 /* busy */ +#define CSR_V_ERR 15 /* error */ +#define CSR_GO (1u << CSR_V_GO) +#define CSR_IE (1u << CSR_V_IE) +#define CSR_DONE (1u << CSR_V_DONE) +#define CSR_BUSY (1u << CSR_V_BUSY) +#define CSR_ERR (1u << CSR_V_ERR) + +/* Timers */ + +#define TMR_CLK 0 /* 100Hz clock */ + +/* I/O system definitions */ + +#define DZ_MUXES 4 /* max # of DZV muxes */ +#define DZ_LINES 8 /* lines per DZV mux */ +#define VH_MUXES 4 /* max # of DHU muxes */ +#define DLX_LINES 16 /* max # of KL11/DL11's */ +#define DCX_LINES 16 /* max # of DC11's */ +#define MT_MAXFR (1 << 16) /* magtape max rec */ + +#define DEV_V_UBUS (DEV_V_UF + 0) /* Unibus */ +#define DEV_V_MBUS (DEV_V_UF + 1) /* Massbus */ +#define DEV_V_NEXUS (DEV_V_UF + 2) /* Nexus */ +#define DEV_V_FLTA (DEV_V_UF + 3) /* flt addr */ +#define DEV_V_FFUF (DEV_V_UF + 4) /* first free flag */ +#define DEV_UBUS (1u << DEV_V_UBUS) +#define DEV_MBUS (1u << DEV_V_MBUS) +#define DEV_NEXUS (1u << DEV_V_NEXUS) +#define DEV_FLTA (1u << DEV_V_FLTA) +#define DEV_QBUS (0) +#define DEV_Q18 (0) + +#define UNIBUS TRUE /* Unibus only */ + +#define DEV_RDX 16 /* default device radix */ + +/* Device information block + + For Massbus devices, + ba = Massbus number + lnt = Massbus ctrl type + ack[0] = abort routine + + For Nexus devices, + ba = Nexus number + lnt = number of consecutive nexi */ + +#define VEC_DEVMAX 4 /* max device vec */ + +typedef struct { + uint32 ba; /* base addr */ + uint32 lnt; /* length */ + t_stat (*rd)(int32 *dat, int32 ad, int32 md); + t_stat (*wr)(int32 dat, int32 ad, int32 md); + int32 vnum; /* vectors: number */ + int32 vloc; /* locator */ + int32 vec; /* value */ + int32 (*ack[VEC_DEVMAX])(void); /* ack routine */ + } DIB; + +/* Unibus I/O page layout - XUB,RQB,RQC,RQD float based on number of DZ's + Massbus devices (RP, TU) do not appear in the Unibus IO page */ + +#define IOBA_FLOAT (0) /* Assigned by Auto Configure */ + +#define IOBA_DZ (IOPAGEBASE + 000100) /* DZ11 */ +#define IOLN_DZ 010 +#define IOBA_XUB (IOPAGEBASE + 000330 + (020 * (DZ_MUXES / 2))) +#define IOLN_XUB 010 +#define IOBA_RQB (IOPAGEBASE + 000334 + (020 * (DZ_MUXES / 2))) +#define IOLN_RQB 004 +#define IOBA_RQC (IOPAGEBASE + IOBA_RQB + IOLN_RQB) +#define IOLN_RQC 004 +#define IOBA_RQD (IOPAGEBASE + IOBA_RQC + IOLN_RQC) +#define IOLN_RQD 004 +#define IOBA_RQ (IOPAGEBASE + 012150) /* UDA50 */ +#define IOLN_RQ 004 +#define IOBA_TS (IOPAGEBASE + 012520) /* TS11 */ +#define IOLN_TS 004 +#define IOBA_RL (IOPAGEBASE + 014400) /* RL11 */ +#define IOLN_RL 012 +#define IOBA_XQ (IOPAGEBASE + 014440) /* DEQNA/DELQA */ +#define IOLN_XQ 020 +#define IOBA_XQB (IOPAGEBASE + 014460) /* 2nd DEQNA/DELQA */ +#define IOLN_XQB 020 +#define IOBA_TQ (IOPAGEBASE + 014500) /* TMSCP */ +#define IOLN_TQ 004 +#define IOBA_XU (IOPAGEBASE + 014510) /* DEUNA/DELUA */ +#define IOLN_XU 010 +#define IOBA_CR (IOPAGEBASE + 017160) /* CD/CR/CM */ +#define IOLN_CR 010 +#define IOBA_RX (IOPAGEBASE + 017170) /* RX11 */ +#define IOLN_RX 004 +#define IOBA_RY (IOPAGEBASE + 017170) /* RXV21 */ +#define IOLN_RY 004 +#define IOBA_QDSS (IOPAGEBASE + 017400) /* QDSS */ +#define IOLN_QDSS 002 +#define IOBA_HK (IOPAGEBASE + 017440) /* RK611 */ +#define IOLN_HK 040 +#define IOBA_LPT (IOPAGEBASE + 017514) /* LP11 */ +#define IOLN_LPT 004 +#define IOBA_PTR (IOPAGEBASE + 017550) /* PC11 reader */ +#define IOLN_PTR 004 +#define IOBA_PTP (IOPAGEBASE + 017554) /* PC11 punch */ +#define IOLN_PTP 004 + +/* Interrupt assignments; within each level, priority is right to left */ + +#define INT_V_DZRX 0 /* BR5 */ +#define INT_V_DZTX 1 +#define INT_V_HK 2 +#define INT_V_RL 3 +#define INT_V_RQ 4 +#define INT_V_TQ 5 +#define INT_V_TS 6 +#define INT_V_RY 7 +#define INT_V_XU 8 +#define INT_V_DMCRX 9 +#define INT_V_DMCTX 10 +#define INT_V_LPT 0 /* BR4 */ +#define INT_V_PTR 1 +#define INT_V_PTP 2 +#define INT_V_CR 3 +#define INT_V_VHRX 4 +#define INT_V_VHTX 5 + +#define INT_DZRX (1u << INT_V_DZRX) +#define INT_DZTX (1u << INT_V_DZTX) +#define INT_HK (1u << INT_V_HK) +#define INT_RL (1u << INT_V_RL) +#define INT_RQ (1u << INT_V_RQ) +#define INT_TQ (1u << INT_V_TQ) +#define INT_TS (1u << INT_V_TS) +#define INT_RY (1u << INT_V_RY) +#define INT_XU (1u << INT_V_XU) +#define INT_LPT (1u << INT_V_LPT) +#define INT_VHRX (1u << INT_V_VHRX) +#define INT_VHTX (1u << INT_V_VHTX) +#define INT_PTR (1u << INT_V_PTR) +#define INT_PTP (1u << INT_V_PTP) +#define INT_CR (1u << INT_V_CR) +#define INT_DMCRX (1u << INT_V_DMCRX) +#define INT_DMCTX (1u << INT_V_DMCTX) +#define IPL_DZRX (0x15 - IPL_HMIN) +#define IPL_DZTX (0x15 - IPL_HMIN) +#define IPL_HK (0x15 - IPL_HMIN) +#define IPL_RL (0x15 - IPL_HMIN) +#define IPL_RQ (0x15 - IPL_HMIN) +#define IPL_TQ (0x15 - IPL_HMIN) +#define IPL_TS (0x15 - IPL_HMIN) +#define IPL_RY (0x15 - IPL_HMIN) +#define IPL_XU (0x15 - IPL_HMIN) +#define IPL_LPT (0x14 - IPL_HMIN) +#define IPL_PTR (0x14 - IPL_HMIN) +#define IPL_PTP (0x14 - IPL_HMIN) +#define IPL_CR (0x14 - IPL_HMIN) +#define IPL_VHRX (0x14 - IPL_HMIN) +#define IPL_VHTX (0x14 - IPL_HMIN) +#define IPL_DMCRX (0x15 - IPL_HMIN) +#define IPL_DMCTX (0x15 - IPL_HMIN) + +/* Device vectors */ + +#define VEC_FLOAT (0) /* Assigned by Auto Configure */ + +#define VEC_QBUS 0 +#define VEC_Q 0000 +#define VEC_PTR 0070 +#define VEC_PTP 0074 +#define VEC_XQ 0120 +#define VEC_XU 0120 +#define VEC_RQ 0154 +#define VEC_RL 0160 +#define VEC_LPT 0200 +#define VEC_HK 0210 +#define VEC_TS 0224 +#define VEC_CR 0230 +#define VEC_TQ 0260 +#define VEC_RX 0264 +#define VEC_RY 0264 +#define VEC_DZRX 0300 +#define VEC_DZTX 0304 + +/* Interrupt macros */ + +#define IVCL(dv) ((IPL_##dv * 32) + INT_V_##dv) +#define NVCL(dv) ((IPL_##dv * 32) + TR_##dv) +#define IREQ(dv) int_req[IPL_##dv] +#define SET_INT(dv) int_req[IPL_##dv] = int_req[IPL_##dv] | (INT_##dv) +#define CLR_INT(dv) int_req[IPL_##dv] = int_req[IPL_##dv] & ~(INT_##dv) +#define IORETURN(f,v) ((f)? (v): SCPE_OK) /* cond error return */ + +/* Logging */ + +#define LOG_CPU_I 0x1 /* intexc */ +#define LOG_CPU_R 0x2 /* REI */ +#define LOG_CPU_P 0x4 /* context */ + +/* Massbus definitions */ + +#define MBA_RP (TR_MBA0 - TR_MBA0) /* MBA for RP */ +#define MBA_TU (TR_MBA1 - TR_MBA0) /* MBA for TU */ +#define MBA_RMASK 0x1F /* max 32 reg */ +#define MBE_NXD 1 /* nx drive */ +#define MBE_NXR 2 /* nx reg */ +#define MBE_GOE 3 /* err on GO */ + +/* Boot definitions */ + +#define BOOT_MB 0 /* device codes */ +#define BOOT_HK 1 /* for VMB */ +#define BOOT_RL 2 +#define BOOT_UDA 17 +#define BOOT_TK 18 +#define BOOT_CS 64 + +/* Function prototypes for virtual memory interface */ + +int32 Read (uint32 va, int32 lnt, int32 acc); +void Write (uint32 va, int32 val, int32 lnt, int32 acc); + +/* Function prototypes for physical memory interface (inlined) */ + +SIM_INLINE int32 ReadB (uint32 pa); +SIM_INLINE int32 ReadW (uint32 pa); +SIM_INLINE int32 ReadL (uint32 pa); +SIM_INLINE int32 ReadLP (uint32 pa); +SIM_INLINE void WriteB (uint32 pa, int32 val); +SIM_INLINE void WriteW (uint32 pa, int32 val); +SIM_INLINE void WriteL (uint32 pa, int32 val); +void WriteLP (uint32 pa, int32 val); + +/* Function prototypes for I/O */ + +int32 Map_ReadB (uint32 ba, int32 bc, uint8 *buf); +int32 Map_ReadW (uint32 ba, int32 bc, uint16 *buf); +int32 Map_WriteB (uint32 ba, int32 bc, uint8 *buf); +int32 Map_WriteW (uint32 ba, int32 bc, uint16 *buf); + +int32 mba_rdbufW (uint32 mbus, int32 bc, uint16 *buf); +int32 mba_wrbufW (uint32 mbus, int32 bc, uint16 *buf); +int32 mba_chbufW (uint32 mbus, int32 bc, uint16 *buf); +int32 mba_get_bc (uint32 mbus); +void mba_upd_ata (uint32 mbus, uint32 val); +void mba_set_exc (uint32 mbus); +void mba_set_don (uint32 mbus); +void mba_set_enbdis (uint32 mbus, t_bool dis); +t_stat mba_show_num (FILE *st, UNIT *uptr, int32 val, void *desc); + +t_stat show_nexus (FILE *st, UNIT *uptr, int32 val, void *desc); + +void sbi_set_errcnf (void); +int32 clk_cosched (int32 wait); + +t_stat cpu_set_model (UNIT *uptr, int32 val, char *cptr, void *desc); +t_stat cpu_show_model (FILE *st, UNIT *uptr, int32 val, void *desc); + +#include "pdp11_io_lib.h" + +#endif diff --git a/VAX/vax860_sbia.c b/VAX/vax860_sbia.c new file mode 100644 index 00000000..b4649e0e --- /dev/null +++ b/VAX/vax860_sbia.c @@ -0,0 +1,355 @@ +/* vax860_sbia.c: VAX 8600 SBIA + + Copyright (c) 2011-2012, Matt Burke + This module incorporates code from SimH, Copyright (c) 2004-2008, Robert M Supnik + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the name(s) of the author(s) shall not be + used in advertising or otherwise to promote the sale, use or other dealings + in this Software without prior written authorization from the author(s). + + sbia SBI adapter + + 26-Dec-2012 MB First Version +*/ + +#include "vax_defs.h" + +/* SBIA registers */ + +#define SBICSR_MIE 0x80000000 /* master int en */ +#define SBICSR_SCOEN 0x40000000 /* SBI cycles out enable */ +#define SBICSR_SCIEN 0x20000000 /* SBI cycles in enable */ +#define SBICSR_WR (SBICSR_MIE | SBICSR_SCOEN | SBICSR_SCIEN) + +#define SBIFS_RD (0x031F0000|SBI_FAULTS) /* SBI faults */ +#define SBIFS_WR 0x03140000 +#define SBIFS_W1C 0x00080000 + +#define SBISC_RD 0xFFFF0000 /* SBI silo comp */ +#define SBISC_WR 0x7FFF0000 +#define SBISC_LOCK 0x80000000 /* lock */ + +#define SBIMT_RD 0xFFFFFF00 /* SBI maint */ +#define SBIMT_WR 0xFFFFF900 + +#define SBIER_CRDIE 0x00008000 /* SBI error, CRD IE */ +#define SBIER_CRD 0x00004000 /* CRD */ +#define SBIER_RDS 0x00002000 /* RDS */ +#define SBIER_TMO 0x00001000 /* timeout */ +#define SBIER_STA 0x00000C00 /* timeout status (0) */ +#define SBIER_CNF 0x00000100 /* error confirm */ +#define SBIER_IBRDS 0x00000080 +#define SBIER_IBTMO 0x00000040 +#define SBIER_IBSTA 0x00000030 +#define SBIER_IBCNF 0x00000008 +#define SBIER_MULT 0x00000004 /* multiple errors */ +#define SBIER_FREE 0x00000002 /* SBI free */ +#define SBIER_RD 0x0000FDFE +#define SBIER_WR 0x00008000 +#define SBIER_W1C 0x000070C0 +#define SBIER_TMOW1C (SBIER_TMO|SBIER_STA|SBIER_CNF|SBIER_MULT) +#define SBIER_IBTW1C (SBIER_IBTMO|SBIER_STA|SBIER_IBCNF) + +#define SBITMO_V_MODE 30 /* mode */ +#define SBITMO_VIRT 0x20000000 /* physical */ + +#define SBIQC_MBZ 0xC0000007 /* MBZ */ + +uint32 nexus_req[NEXUS_HLVL]; /* nexus int req */ +uint32 sbi_fs = 0; /* SBI fault status */ +uint32 sbi_sc = 0; /* SBI silo comparator */ +uint32 sbi_mt = 0; /* SBI maintenance */ +uint32 sbi_er = 0; /* SBI error status */ +uint32 sbi_tmo = 0; /* SBI timeout addr */ +uint32 sbi_csr = 0; /* SBI control/status */ + +extern int32 R[16]; +extern int32 PSL; +extern int32 ASTLVL, SISR; +extern jmp_buf save_env; +extern int32 trpirq; +extern int32 p1; +extern int32 mchk_ref; +extern int32 crd_err; +extern int32 sim_switches; +extern DEVICE *sim_devices[]; +extern FILE *sim_log; +extern int32 fault_PC; /* fault PC */ +extern UNIT cpu_unit; + +t_stat sbia_reset (DEVICE *dptr); +void sbi_set_tmo (int32 pa); +t_stat (*nexusR[NEXUS_NUM])(int32 *dat, int32 ad, int32 md); +t_stat (*nexusW[NEXUS_NUM])(int32 dat, int32 ad, int32 md); + +extern int32 intexc (int32 vec, int32 cc, int32 ipl, int ei); +extern int32 eval_int (void); + +/* SBIA data structures + + sbia_dev SBIA device descriptor + sbia_unit SBIA unit + sbia_reg SBIA register list +*/ + +UNIT sbia_unit = { UDATA (NULL, 0, 0) }; + +REG sbia_reg[] = { + { HRDATA (NREQ14, nexus_req[0], 16) }, + { HRDATA (NREQ15, nexus_req[1], 16) }, + { HRDATA (NREQ16, nexus_req[2], 16) }, + { HRDATA (NREQ17, nexus_req[3], 16) }, + { HRDATA (SBIFS, sbi_fs, 32) }, + { HRDATA (SBISC, sbi_sc, 32) }, + { HRDATA (SBIMT, sbi_mt, 32) }, + { HRDATA (SBIER, sbi_er, 32) }, + { HRDATA (SBITMO, sbi_tmo, 32) }, + { HRDATA (SBICSR, sbi_csr, 32) }, + { NULL } + }; + +DEVICE sbia_dev = { + "SBIA", &sbia_unit, sbia_reg, NULL, + 1, 16, 16, 1, 16, 8, + NULL, NULL, &sbia_reset, + NULL, NULL, NULL, + NULL, 0 + }; + +int32 sbia_rd (int32 pa, int32 lnt) +{ + int32 rg = (pa >> 2) & 0x1F; + + switch (rg) { + case 0: /* SBICNF */ + return 0x00400010; /* 8MB + SBIA Abus code */ + + case 1: /* SBICSR */ + return sbi_csr; + + case 2: /* SBIES (not impl) */ + case 3: /* SBIDCR (not impl) */ + case 4: /* DMAI CMD (not impl) */ + case 5: /* DMAI ID (not impl) */ + case 6: /* DMAA CMD (not impl) */ + case 7: /* DMAA ID (not impl) */ + case 8: /* DMAB CMD (not impl) */ + case 9: /* DMAB ID (not impl) */ + case 0xa: /* DMAC CMD (not impl) */ + case 0xb: /* DMAC ID (not impl) */ + case 0xc: /* SBIS (not impl) */ + return 0; + + case 0xd: /* SBIER */ + return sbi_er & SBIER_RD; + + case 0xe: /* SBITA */ + return sbi_tmo; + + case 0xf: /* SBIFS */ + return sbi_fs & SBIFS_RD; + + case 0x10: /* SBISC */ + return sbi_sc & SBISC_RD; + + case 0x11: /* SBIMT */ + return sbi_mt & SBIMT_RD; + } +} + +void sbia_wr (int32 pa, int32 val, int32 lnt) +{ + int32 rg = (pa >> 2) & 0x1F; + + switch (rg) { + case 0: /* SBICNF */ + break; + + case 1: /* SBICSR */ + printf ("sbi_csr wr: %08X\n", val); + sbi_csr = sbi_csr & SBICSR_WR; + break; + + case 2: /* SBIES (not impl) */ + case 3: /* SBIDCR (not impl) */ + case 4: /* DMAI CMD (not impl) */ + case 5: /* DMAI ID (not impl) */ + case 6: /* DMAA CMD (not impl) */ + case 7: /* DMAA ID (not impl) */ + case 8: /* DMAB CMD (not impl) */ + case 9: /* DMAB ID (not impl) */ + case 0xa: /* DMAC CMD (not impl) */ + case 0xb: /* DMAC ID (not impl) */ + case 0xc: /* SBIS (not impl) */ + break; + + case 0xd: /* SBIER */ + sbi_er = (sbi_er & ~SBIER_WR) | (val & SBIER_WR); + sbi_er = sbi_er & ~(val & SBIER_W1C); + if (val & SBIER_TMO) + sbi_er = sbi_er & ~SBIER_TMOW1C; + if (val & SBIER_IBTMO) + sbi_er = sbi_er & ~SBIER_IBTW1C; + if ((sbi_er & SBIER_CRDIE) && (sbi_er & SBIER_CRD)) + crd_err = 1; + else crd_err = 0; + break; + + case 0xe: /* SBITA */ + break; + + case 0xf: /* SBIFS */ + sbi_fs = (sbi_fs & ~SBIFS_WR) | (val & SBIFS_WR); + sbi_fs = sbi_fs & ~(val & SBIFS_W1C); + break; + + case 0x10: /* SBISC */ + sbi_sc = (sbi_sc & ~(SBISC_LOCK|SBISC_WR)) | (val & SBISC_WR); + break; + + case 0x11: /* SBIMT */ + sbi_mt = (sbi_mt & ~SBIMT_WR) | (val & SBIMT_WR); + break; + } +return; +} + +t_stat sbi_rd (int32 pa, int32 *val, int32 lnt) +{ +int32 nexus; + +nexus = NEXUS_GETNEX (pa); /* get nexus */ +if ((sbi_csr & SBICSR_SCOEN) && /* SBI en? */ + nexusR[nexus] && /* valid? */ + (nexusR[nexus] (val, pa, lnt) == SCPE_OK)) { + SET_IRQL; + return SCPE_OK; + } +else sbi_set_tmo (pa); /* timeout */ +return SCPE_NXM; +} + +t_stat sbi_wr (int32 pa, int32 val, int32 lnt) +{ +int32 nexus; + +nexus = NEXUS_GETNEX (pa); /* get nexus */ +if ((sbi_csr & SBICSR_SCOEN) && /* SBI en? */ + nexusW[nexus] && /* valid? */ + (nexusW[nexus] (val, pa, lnt) == SCPE_OK)) { + SET_IRQL; + return SCPE_OK; + } +else sbi_set_tmo (pa); /* timeout */ +return SCPE_NXM; +} + +/* Set SBI timeout - machine checks only on reads */ + +void sbi_set_tmo (int32 pa) +{ +if ((sbi_er & SBIER_TMO) == 0) { /* not yet set? */ + sbi_tmo = pa >> 2; /* save addr */ + if (mchk_ref == REF_V) /* virt? add mode */ + sbi_tmo |= SBITMO_VIRT | (PSL_GETCUR (PSL) << SBITMO_V_MODE); + sbi_er |= SBIER_TMO; /* set tmo flag */ + } +else sbi_er |= SBIER_MULT; /* yes, multiple */ +return; +} + +/* Set SBI error confirmation - always machine checks */ + +void sbi_set_errcnf (void) +{ +if (sbi_er & SBIER_CNF) + sbi_er |= SBIER_MULT; +else sbi_er |= SBIER_CNF; +MACH_CHECK (MCHK_RD_F); +return; +} + +/* SBI reset */ + +t_stat sbia_reset (DEVICE *dptr) +{ +sbi_fs = 0; +sbi_sc = 0; +sbi_mt = 0; +sbi_er = 0; +sbi_tmo = 0; +sbi_csr = SBICSR_SCOEN | SBICSR_SCIEN; +return SCPE_OK; +} + +/* Show nexus */ + +t_stat show_nexus (FILE *st, UNIT *uptr, int32 val, void *desc) +{ +fprintf (st, "nexus=%d", val); +return SCPE_OK; +} + +/* Init nexus tables */ + +void init_nexus_tab (void) +{ +uint32 i; + +for (i = 0; i < NEXUS_NUM; i++) { + nexusR[i] = NULL; + nexusW[i] = NULL; + } +return; +} + +/* Build nexus tables + + Inputs: + dptr = pointer to device + dibp = pointer to DIB + Outputs: + status +*/ + +t_stat build_nexus_tab (DEVICE *dptr, DIB *dibp) +{ +uint32 idx; + +if ((dptr == NULL) || (dibp == NULL)) + return SCPE_IERR; +idx = dibp->ba; +if (idx >= NEXUS_NUM) + return SCPE_IERR; +if ((nexusR[idx] && dibp->rd && /* conflict? */ + (nexusR[idx] != dibp->rd)) || + (nexusW[idx] && dibp->wr && + (nexusW[idx] != dibp->wr))) { + printf ("Nexus %s conflict at %d\n", sim_dname (dptr), dibp->ba); + if (sim_log) + fprintf (sim_log, "Nexus %s conflict at %d\n", sim_dname (dptr), dibp->ba); + return SCPE_STOP; + } +if (dibp->rd) /* set rd dispatch */ + nexusR[idx] = dibp->rd; +if (dibp->wr) /* set wr dispatch */ + nexusW[idx] = dibp->wr; +return SCPE_OK; +} diff --git a/VAX/vax860_stddev.c b/VAX/vax860_stddev.c new file mode 100644 index 00000000..129aaa31 --- /dev/null +++ b/VAX/vax860_stddev.c @@ -0,0 +1,1154 @@ +/* vax860_stddev.c: VAX 8600 standard I/O devices + + Copyright (c) 2011-2012, Matt Burke + This module incorporates code from SimH, Copyright (c) 1998-2008, Robert M Supnik + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the name(s) of the author(s) shall not be + used in advertising or otherwise to promote the sale, use or other dealings + in this Software without prior written authorization from the author(s). + + tti console input + tto console output + cs console RL02 + todr TODR clock + tmr interval timer + + 26-Dec-2012 MB First Version +*/ + +#include "vax_defs.h" +#include + +/* Terminal definitions */ + +#define RXCS_V_DTR 16 /* logical carrier */ +#define RXCS_M_DTR 0xF +#define RXCS_DTR (RXCS_M_DTR << RXCS_V_DTR) +#define RXCS_RD (CSR_DONE + CSR_IE + RXCS_DTR) /* terminal input */ +#define RXCS_WR (CSR_IE) +#define RXDB_V_LC 16 /* logical carrier */ +#define RXDB_V_IDC 8 /* ID Code */ +#define RXDB_M_IDC 0xF +#define RXDB_IDC (TXCS_M_IDC << TXCS_V_IDC) +#define TXCS_V_IDC 8 /* ID Code */ +#define TXCS_M_IDC 0xF +#define TXCS_IDC (TXCS_M_IDC << TXCS_V_IDC) +#define TXCS_WMN 0x8000 /* Write mask now */ +#define TXCS_V_TEN 16 /* Transmitter en */ +#define TXCS_M_TEN 0xF +#define TXCS_TEN (TXCS_M_TEN << TXCS_V_TEN) +#define TXCS_RD (CSR_DONE + CSR_IE + TXCS_TEN + TXCS_IDC) /* terminal output */ +#define TXCS_WR (CSR_IE + TXCS_TEN) +#define ID_CT 0 /* console terminal */ +#define ID_RS 1 /* remote services */ +#define ID_EMM 2 /* environmental monitoring module */ +#define ID_LC 3 /* logical console */ +#define ID_M_CT (1u << ID_CT) +#define ID_M_RS (1u << ID_RS) +#define ID_M_EMM (1u << ID_EMM) +#define ID_M_LC (1u << ID_LC) +#define RDY u3 + +/* Clock definitions */ + +#define TMR_CSR_ERR 0x80000000 /* error W1C */ +#define TMR_CSR_DON 0x00000080 /* done W1C */ +#define TMR_CSR_IE 0x00000040 /* int enb RW */ +#define TMR_CSR_SGL 0x00000020 /* single WO */ +#define TMR_CSR_XFR 0x00000010 /* xfer WO */ +#define TMR_CSR_RUN 0x00000001 /* run RW */ +#define TMR_CSR_RD (TMR_CSR_W1C | TMR_CSR_WR) +#define TMR_CSR_W1C (TMR_CSR_ERR | TMR_CSR_DON) +#define TMR_CSR_WR (TMR_CSR_IE | TMR_CSR_RUN) +#define TMR_INC 10000 /* usec/interval */ +#define CLK_DELAY 5000 /* 100 Hz */ +#define TMXR_MULT 1 /* 100 Hz */ + +/* Logical console definitions */ + +#define LC_NUMBY 128 /* response buffer size */ + +#define LC_IDLE 0 /* idle state */ +#define LC_READDAT 1 /* read data */ + +#define LC_V_FNC 0 /* logical console function */ +#define LC_M_FNC 0xFF +#define LC_FNCCW 0x3 /* clear warm start flag */ +#define LC_FNCCS 0x4 /* clear cold start flag */ +#define LC_FNCMV 0x12 /* microcode version */ +#define LC_FNCAC 0x13 /* array configuration */ +#define LC_FNCSS 0x30 /* snapshot file status */ +#define LC_FNCCA 0x70 /* cancel all */ +#define LC_GETFNC(x) (((x) >> LC_V_FNC) & LC_M_FNC) + +/* Console storage definitions */ + +#define STXCS_FNC 0xF +#define STXCS_V_DA 8 +#define STXCS_M_DA 0xFFFF +#define STXCS_DA (STXCS_M_DA << STXCS_V_DA) +#define STXCS_GETDA(x) (((x) >> STXCS_V_DA) & STXCS_M_DA) +#define STXCS_V_STS 24 +#define STXCS_M_STS 0xFF +#define STXCS_STS (STXCS_M_STS << STXCS_V_STS) +#define STXCS_WR (STXCS_FNC | CSR_DONE | CSR_IE | STXCS_DA) + +#define STXDB_DAT 0xFFFF + +#define RL_NUMBY 256 /* bytes/sector */ +#define RL_NUMWD 128 /* words/sector */ +#define RL_NUMSC 40 /* sectors/surface */ +#define RL_NUMSF 2 /* surfaces/cylinder */ +#define RL_NUMCY 512 /* cylinders/drive */ +#define RL02_SIZE (RL_NUMCY * RL_NUMSF * RL_NUMSC * RL_NUMWD) /* words/drive */ + +/* Parameters in the unit descriptor */ + +#define TRK u3 /* current track */ +#define STAT u4 /* status */ + +#define UNIT_V_WLK (UNIT_V_UF + 0) /* hwre write lock */ +#define UNIT_WLK (1u << UNIT_V_WLK) + +#define RLCS_DRDY 0000001 /* drive ready */ +#define RLCS_M_DRIVE 03 +#define RLCS_V_DRIVE 8 +#define RLCS_INCMP 0002000 /* incomplete */ +#define RLCS_CRC 0004000 /* CRC error */ +#define RLCS_HDE 0010000 /* header error */ +#define RLCS_NXM 0020000 /* non-exist memory */ +#define RLCS_DRE 0040000 /* drive error */ +#define RLCS_ERR 0100000 /* error summary */ +#define RLCS_ALLERR (RLCS_ERR+RLCS_DRE+RLCS_NXM+RLCS_HDE+RLCS_CRC+RLCS_INCMP) +#define RLCS_RW 0001776 /* read/write */ + +/* RL Function Codes */ + +#define RLFC_NOP 0 /* No Operation */ +#define RLFC_CONT 2 /* Continue Transaction */ +#define RLFC_ABORT 3 /* Abort Current Transfer */ +#define RLFC_STS 4 /* Read Device Status */ +#define RLFC_WRITE 5 /* Write Block Data */ +#define RLFC_READ 6 /* Read Block Data */ + +/* RL Status Codes */ + +#define RLST_COMP 1 /* Transaction Complete */ +#define RLST_CONT 2 /* Continue Transaction */ +#define RLST_ABORT 3 /* Transaction Aborted */ +#define RLST_STS 4 /* Return Device Status */ +#define RLST_HERR 80 /* Handshake Error */ +#define RLST_HDERR 81 /* Hardware Error */ + +/* RL States */ + +#define RL_IDLE 0 +#define RL_READ 1 +#define RL_WRITE 2 +#define RL_STATUS 3 +#define RL_ABORT 4 + +#define RL_CSR 0 /* CSR selected */ +#define RL_MP 1 /* MP selected */ + +/* RLDS, NI = not implemented, * = kept in STAT, ^ = kept in TRK */ + +#define RLDS_LOAD 0 /* no cartridge */ +#define RLDS_LOCK 5 /* lock on */ +#define RLDS_BHO 0000010 /* brushes home NI */ +#define RLDS_HDO 0000020 /* heads out NI */ +#define RLDS_CVO 0000040 /* cover open NI */ +#define RLDS_HD 0000100 /* head select ^ */ +#define RLDS_RL02 0000200 /* RL02 */ +#define RLDS_DSE 0000400 /* drv sel err NI */ +#define RLDS_VCK 0001000 /* vol check * */ +#define RLDS_WGE 0002000 /* wr gate err * */ +#define RLDS_SPE 0004000 /* spin err * */ +#define RLDS_STO 0010000 /* seek time out NI */ +#define RLDS_WLK 0020000 /* wr locked */ +#define RLDS_HCE 0040000 /* hd curr err NI */ +#define RLDS_WDE 0100000 /* wr data err NI */ +#define RLDS_ATT (RLDS_HDO+RLDS_BHO+RLDS_LOCK) /* att status */ +#define RLDS_UNATT (RLDS_CVO+RLDS_LOAD) /* unatt status */ +#define RLDS_ERR (RLDS_WDE+RLDS_HCE+RLDS_STO+RLDS_SPE+RLDS_WGE+ \ + RLDS_VCK+RLDS_DSE) /* errors bits */ + +int32 tti_csr = 0; /* control/status */ +int32 tti_buf = 0; /* buffer */ +int32 tti_int = 0; /* interrupt */ +int32 tto_csr = 0; /* control/status */ +int32 tto_int = 0; /* interrupt */ + +int32 tmr_iccs = 0; /* interval timer csr */ +uint32 tmr_icr = 0; /* curr interval */ +uint32 tmr_nicr = 0; /* next interval */ +uint32 tmr_inc = 0; /* timer increment */ +int32 tmr_sav = 0; /* timer save */ +int32 tmr_int = 0; /* interrupt */ +int32 tmr_use_100hz = 1; /* use 100Hz for timer */ +int32 clk_tps = 100; /* ticks/second */ +int32 tmxr_poll = CLK_DELAY * TMXR_MULT; /* term mux poll */ +int32 tmr_poll = CLK_DELAY; /* pgm timer poll */ +int32 todr_reg = 0; /* TODR register */ +struct todr_battery_info { + uint32 toy_gmtbase; /* GMT base of set value */ + uint32 toy_gmtbasemsec; /* The milliseconds of the set value */ + }; +typedef struct todr_battery_info TOY; + +int32 lc_fnc = 0; /* function */ +int32 lc_cwait = 50; /* command time */ +int32 lc_xwait = 20; /* tr set time */ +uint8 lc_buf[LC_NUMBY] = { 0 }; /* response buffer */ +int32 lc_bptr = 0; /* buffer pointer */ +int32 lc_dlen = 0; /* buffer data len */ + +int32 csi_int = 0; /* interrupt */ +int32 cso_csr = 0; /* control/status */ +int32 cso_buf = 0; /* buffer */ + +int32 rlcs_swait = 10; /* command time */ +int32 rlcs_state = RL_IDLE; /* protocol state */ +int32 rlcs_sts_reg = RL_CSR; /* status register */ +int32 rlcs_csr = 0; /* control/status */ +int32 rlcs_mp = 0; +int32 rlcs_bcnt = 0; /* byte count */ +uint16 *rlcs_buf = NULL; + +extern int32 sim_switches; +extern jmp_buf save_env; +extern UNIT cpu_unit; +extern int32 brk_req; + +t_stat tti_svc (UNIT *uptr); +t_stat tto_svc (UNIT *uptr); +t_stat clk_svc (UNIT *uptr); +t_stat tmr_svc (UNIT *uptr); +t_stat lc_svc (UNIT *uptr); +t_stat rlcs_svc (UNIT *uptr); +t_stat tti_reset (DEVICE *dptr); +t_stat tto_reset (DEVICE *dptr); +t_stat clk_reset (DEVICE *dptr); +t_stat clk_attach (UNIT *uptr, char *cptr); +t_stat clk_detach (UNIT *uptr); +t_stat tmr_reset (DEVICE *dptr); +t_stat lc_reset (DEVICE *dptr); +t_stat rlcs_reset (DEVICE *dptr); +t_stat rlcs_attach (UNIT *uptr, char *cptr); +int32 icr_rd (t_bool interp); +void tmr_incr (uint32 inc); +void tmr_sched (void); +t_stat todr_resync (void); +t_stat lc_wr_txdb (int32 data); + +extern int32 con_halt (int32 code, int32 cc); + +/* TTI data structures + + tti_dev TTI device descriptor + tti_unit TTI unit descriptor + tti_reg TTI register list +*/ + +UNIT tti_unit[] = { + { UDATA (&tti_svc, TT_MODE_8B, 0), 0 }, + { UDATA (&tti_svc, TT_MODE_8B, 0), 0 }, + { UDATA (&tti_svc, TT_MODE_8B, 0), 0 }, + { UDATA (&tti_svc, TT_MODE_8B, 0), 0 }, + }; + +REG tti_reg[] = { + { HRDATA (RXDB, tti_buf, 32) }, + { HRDATA (RXCS, tti_csr, 32) }, + { FLDATA (INT, tti_int, 0) }, + { FLDATA (DONE, tti_csr, CSR_V_DONE) }, + { FLDATA (IE, tti_csr, CSR_V_IE) }, + { URDATA (POS, tti_unit[0].pos, 10, T_ADDR_W, 0, 4, PV_LEFT) }, + { URDATA (TIME, tti_unit[0].wait, 10, 24, 0, 4, PV_LEFT) }, + { NULL } + }; + +MTAB tti_mod[] = { + { TT_MODE, TT_MODE_7B, "7b", "7B", NULL }, + { TT_MODE, TT_MODE_8B, "8b", "8B", NULL }, + { 0 } + }; + +DEVICE tti_dev = { + "TTI", tti_unit, tti_reg, tti_mod, + 4, 10, 31, 1, 16, 8, + NULL, NULL, &tti_reset, + NULL, NULL, NULL, + NULL, 0 + }; + +/* TTO data structures + + tto_dev TTO device descriptor + tto_unit TTO unit descriptor + tto_reg TTO register list +*/ + +UNIT tto_unit[] = { + { UDATA (&tto_svc, TT_MODE_8B, 0), SERIAL_OUT_WAIT }, + { UDATA (&tto_svc, TT_MODE_8B, 0), SERIAL_OUT_WAIT }, + { UDATA (&tto_svc, TT_MODE_8B, 0), SERIAL_OUT_WAIT }, + { UDATA (&tto_svc, TT_MODE_8B, 0), SERIAL_OUT_WAIT }, + }; + +REG tto_reg[] = { + { URDATA (TXDB, tto_unit[0].buf, 16, 32, 0, 4, 0) }, + { HRDATA (TXCS, tto_csr, 32) }, + { FLDATA (INT, tto_int, 0) }, + { FLDATA (DONE, tto_csr, CSR_V_DONE) }, + { FLDATA (IE, tto_csr, CSR_V_IE) }, + { URDATA (POS, tto_unit[0].pos, 10, T_ADDR_W, 0, 4, PV_LEFT) }, + { URDATA (TIME, tto_unit[0].wait, 10, 24, 0, 4, PV_LEFT + REG_NZ) }, + { NULL } + }; + +MTAB tto_mod[] = { + { TT_MODE, TT_MODE_7B, "7b", "7B", NULL }, + { TT_MODE, TT_MODE_8B, "8b", "8B", NULL }, + { TT_MODE, TT_MODE_7P, "7p", "7P", NULL }, + { 0 } + }; + +DEVICE tto_dev = { + "TTO", tto_unit, tto_reg, tto_mod, + 4, 10, 31, 1, 16, 8, + NULL, NULL, &tto_reset, + NULL, NULL, NULL, + NULL, 0 + }; + +/* TODR and TMR data structures */ + +UNIT clk_unit = { UDATA (&clk_svc, UNIT_IDLE+UNIT_FIX, sizeof(TOY)), CLK_DELAY };/* 100Hz */ + +REG clk_reg[] = { + { DRDATA (TODR, todr_reg, 32), PV_LEFT }, + { DRDATA (TIME, clk_unit.wait, 24), REG_NZ + PV_LEFT }, + { DRDATA (TPS, clk_tps, 8), REG_HIDDEN + REG_NZ + PV_LEFT }, +#if defined (SIM_ASYNCH_IO) + { DRDATA (LATENCY, sim_asynch_latency, 32), PV_LEFT }, + { DRDATA (INST_LATENCY, sim_asynch_inst_latency, 32), PV_LEFT }, +#endif + { NULL } + }; + +DEVICE clk_dev = { + "TODR", &clk_unit, clk_reg, NULL, + 1, 0, 8, 4, 0, 32, + NULL, NULL, &clk_reset, + NULL, &clk_attach, &clk_detach, + NULL, 0 + }; + +UNIT tmr_unit = { UDATA (&tmr_svc, 0, 0) }; /* timer */ + +REG tmr_reg[] = { + { HRDATA (ICCS, tmr_iccs, 32) }, + { HRDATA (ICR, tmr_icr, 32) }, + { HRDATA (NICR, tmr_nicr, 32) }, + { HRDATA (INCR, tmr_inc, 32), REG_HIDDEN }, + { HRDATA (SAVE, tmr_sav, 32), REG_HIDDEN }, + { FLDATA (USE100HZ, tmr_use_100hz, 0), REG_HIDDEN }, + { FLDATA (INT, tmr_int, 0) }, + { NULL } + }; + +DEVICE tmr_dev = { + "TMR", &tmr_unit, tmr_reg, NULL, + 1, 0, 0, 0, 0, 0, + NULL, NULL, &tmr_reset, + NULL, NULL, NULL, + NULL, 0 + }; + +/* Console storage structures + + rlcs_dev CS device descriptor + rlcs_unit CS unit list + rlcs_reg CS register list + rlcs_mod CS modifier list +*/ + +UNIT rlcs_unit = { UDATA (&rlcs_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, RL02_SIZE) }; + +REG rlcs_reg[] = { + { HRDATA (CSR, rlcs_csr, 16) }, + { HRDATA (MP, rlcs_mp, 16) }, + { DRDATA (BCNT, rlcs_bcnt, 7) }, + { DRDATA (STIME, rlcs_swait, 24), PV_LEFT }, + { NULL } + }; + +MTAB rlcs_mod[] = { + { UNIT_WLK, 0, "write enabled", "WRITEENABLED", NULL }, + { UNIT_WLK, UNIT_WLK, "write locked", "LOCKED", NULL }, + { 0 } + }; + +DEVICE rlcs_dev = { + "CS", &rlcs_unit, rlcs_reg, rlcs_mod, + 1, 10, 24, 1, 16, 16, + NULL, NULL, &rlcs_reset, + NULL, &rlcs_attach, NULL, + NULL, 0 + }; + +/* Terminal MxPR routines + + rxcs_rd/wr input control/status + rxdb_rd input buffer + txcs_rd/wr output control/status + txdb_wr output buffer +*/ + +int32 rxcs_rd (void) +{ +return (tti_csr & RXCS_RD); +} + +void rxcs_wr (int32 data) +{ +if ((data & CSR_IE) == 0) + tti_int = 0; +else if ((tti_csr & (CSR_DONE + CSR_IE)) == CSR_DONE) + tti_int = 1; +tti_csr = (tti_csr & ~RXCS_WR) | (data & RXCS_WR); +return; +} + +int32 rxdb_rd (void) +{ +int32 t = tti_buf; +t = t | ((ID_M_LC | ID_M_EMM | ID_M_CT) << RXDB_V_LC); /* char + DTR for hard-wired lines */ +tti_csr = tti_csr & ~CSR_DONE; /* clr done */ +tti_int = 0; +return t; +} + +void tto_update_int (void) +{ +int32 id = 0; + +tto_csr = tto_csr & ~TXCS_IDC; +if ((tto_csr & (ID_M_LC << TXCS_V_TEN)) && + (tto_unit[ID_LC].RDY)) /* logical console enabled and ready? */ + id = ID_LC; +else if ((tto_csr & (ID_M_EMM << TXCS_V_TEN)) && + (tto_unit[ID_EMM].RDY)) /* EMM enabled and ready? */ + id = ID_EMM; +else if ((tto_csr & (ID_M_RS << TXCS_V_TEN)) && + (tto_unit[ID_RS].RDY)) /* remote services enabled and ready? */ + id = ID_RS; +else if ((tto_csr & (ID_M_CT << TXCS_V_TEN)) && + (tto_unit[ID_CT].RDY)) /* console terminal enabled and ready? */ + id = ID_CT; +else id = 0xF; /* no lines enabled */ +tto_csr = tto_csr | (id << TXCS_V_IDC); +tto_csr = tto_csr | CSR_DONE; +if (tto_csr & CSR_IE) + tto_int = 1; +} + +int32 txcs_rd (void) +{ +return (tto_csr & TXCS_RD); +} + +void txcs_wr (int32 data) +{ +tto_csr = (tto_csr & ~TXCS_WR) | (data & TXCS_WR); +if (data & TXCS_WMN) /* updating mask? */ + tto_update_int (); +if ((data & CSR_IE) == 0) + tto_int = 0; +else if ((tto_csr & (CSR_DONE + CSR_IE)) == CSR_DONE) + tto_int = 1; +return; +} + +void txdb_wr (int32 data) +{ +int32 dest = (tto_csr >> TXCS_V_IDC) & TXCS_M_IDC; +if ((dest >= ID_CT) && (dest <= ID_LC)) { /* valid line? */ + tto_csr = tto_csr & ~CSR_DONE; /* clear flag */ + tto_int = 0; /* clear int */ + tto_unit[dest].buf = data & WMASK; + tto_unit[dest].RDY = 0; + sim_activate (&tto_unit[dest], tto_unit[dest].wait);/* activate unit */ + } +return; +} + +int32 stxcs_rd (void) +{ +return cso_csr; +} + +void stxcs_wr (int32 data) +{ +int32 fnc = data & STXCS_FNC; +cso_csr = (cso_csr & ~STXCS_WR) | (data & STXCS_WR); +cso_csr = cso_csr & ~STXCS_STS; + +switch (fnc) { + case RLFC_NOP: + break; + + case RLFC_CONT: + rlcs_bcnt = 0; + case RLFC_STS: + rlcs_state = RL_STATUS; + cso_csr = cso_csr & ~CSR_DONE; /* clear done */ + sim_activate (&rlcs_unit, rlcs_swait); + break; + + case RLFC_ABORT: + rlcs_state = RL_ABORT; + cso_csr = cso_csr & ~CSR_DONE; /* clear done */ + sim_activate (&rlcs_unit, rlcs_swait); + break; + + case RLFC_WRITE: + rlcs_state = RL_WRITE; + cso_csr = cso_csr & ~CSR_DONE; /* clear done */ + sim_activate (&rlcs_unit, rlcs_swait); + break; + + case RLFC_READ: + rlcs_state = RL_READ; + cso_csr = cso_csr & ~CSR_DONE; /* clear done */ + sim_activate (&rlcs_unit, rlcs_swait); + break; + + default: + printf ("CS: Unknown Command: %d\n", fnc); + } +} + +int32 stxdb_rd (void) +{ +return cso_buf & STXDB_DAT; +} + +void stxdb_wr (int32 data) +{ +cso_buf = data & STXDB_DAT; + +if (rlcs_state == RL_WRITE) { + rlcs_buf[rlcs_bcnt] = cso_buf; + rlcs_bcnt++; + } +} + +/* Terminal input service (poll for character) */ + +t_stat tti_svc (UNIT *uptr) +{ +int32 c; +int32 line = uptr - tti_dev.units; + +switch (line) { + + case ID_CT: /* console terminal */ + sim_activate (uptr, KBD_WAIT (uptr->wait, clk_cosched (tmr_poll))); + /* continue poll */ + if ((tti_csr & CSR_DONE) == 0) { /* prev data taken? */ + if ((c = sim_poll_kbd ()) < SCPE_KFLAG) /* no char or error? */ + return c; + if (c & SCPE_BREAK) /* break? */ + tti_buf = 0; + else tti_buf = sim_tt_inpcvt (c, TT_GET_MODE (uptr->flags)); + } + break; + + case ID_LC: /* logical console */ + if (lc_bptr > 0) { + if ((tti_csr & CSR_DONE) == 0) { /* prev data taken? */ + tti_buf = lc_buf[--lc_bptr]; /* get next byte */ + tti_buf |= (ID_LC << RXDB_V_IDC); /* source = logical console */ + if (lc_bptr == 0) /* buffer empty? */ + break; /* done */ + } + sim_activate (uptr, lc_xwait); /* schedule next */ + } + break; + } +uptr->pos = uptr->pos + 1; +tti_csr = tti_csr | CSR_DONE; +if (tti_csr & CSR_IE) + tti_int = 1; +return SCPE_OK; +} + +/* Terminal input reset */ + +t_stat tti_reset (DEVICE *dptr) +{ +tti_buf = 0; +tti_csr = 0; +tti_int = 0; +sim_activate_abs (&tti_unit[ID_CT], KBD_WAIT (tti_unit[ID_CT].wait, tmr_poll)); +return SCPE_OK; +} + +/* Terminal output service (output character) */ + +t_stat tto_svc (UNIT *uptr) +{ +int32 c; +int32 line = uptr - tto_dev.units; +t_stat r; + +switch (line) { + + case ID_CT: /* console terminal */ + c = sim_tt_outcvt (uptr->buf, TT_GET_MODE (uptr->flags)); + if (c >= 0) { + if ((r = sim_putchar_s (c)) != SCPE_OK) { /* output; error? */ + sim_activate (uptr, uptr->wait); /* retry */ + return ((r == SCPE_STALL)? SCPE_OK: r); /* !stall? report */ + } + } + break; + + case ID_LC: /* logical console */ + lc_wr_txdb (uptr->buf); + break; + } +uptr->pos = uptr->pos + 1; +uptr->RDY = 1; +tto_update_int (); +return SCPE_OK; +} + +/* Terminal output reset */ + +t_stat tto_reset (DEVICE *dptr) +{ +tto_csr = (ID_M_CT << TXCS_V_TEN) | CSR_DONE; /* console enabled + done */ +tto_int = 0; +tto_unit[ID_CT].RDY = 1; /* all lines ready */ +tto_unit[ID_RS].RDY = 1; +tto_unit[ID_EMM].RDY = 1; +tto_unit[ID_LC].RDY = 1; +sim_cancel (&tto_unit[ID_CT]); /* deactivate units */ +sim_cancel (&tto_unit[ID_RS]); +sim_cancel (&tto_unit[ID_EMM]); +sim_cancel (&tto_unit[ID_LC]); +return SCPE_OK; +} + +/* Programmable timer + + The architected VAX timer, which increments at 1Mhz, cannot be + accurately simulated due to the overhead that would be required + for 1M clock events per second. Instead, a hidden calibrated + 100Hz timer is run (because that's what VMS expects), and a + hack is used for the interval timer. + + When the timer is started, the timer interval is inspected. + + if the interval is >= 10msec, then the 100Hz timer drives the + next interval + if the interval is < 10mec, then count instructions + + If the interval register is read, then its value between events + is interpolated using the current instruction count versus the + count when the most recent event started, the result is scaled + to the calibrated system clock, unless the interval being timed + is less than a calibrated system clock tick (or the calibrated + clock is running very slowly) at which time the result will be + the elapsed instruction count. +*/ + +int32 iccs_rd (void) +{ +return tmr_iccs & TMR_CSR_RD; +} + +void iccs_wr (int32 val) +{ +if ((val & TMR_CSR_RUN) == 0) { /* clearing run? */ + sim_cancel (&tmr_unit); /* cancel timer */ + tmr_use_100hz = 0; + if (tmr_iccs & TMR_CSR_RUN) /* run 1 -> 0? */ + tmr_icr = icr_rd (TRUE); /* update itr */ + } +tmr_iccs = tmr_iccs & ~(val & TMR_CSR_W1C); /* W1C csr */ +tmr_iccs = (tmr_iccs & ~TMR_CSR_WR) | /* new r/w */ + (val & TMR_CSR_WR); +if (val & TMR_CSR_XFR) tmr_icr = tmr_nicr; /* xfr set? */ +if (val & TMR_CSR_RUN) { /* run? */ + if (val & TMR_CSR_XFR) /* new tir? */ + sim_cancel (&tmr_unit); /* stop prev */ + if (!sim_is_active (&tmr_unit)) /* not running? */ + tmr_sched (); /* activate */ + } +else if (val & TMR_CSR_SGL) { /* single step? */ + tmr_incr (1); /* incr tmr */ + if (tmr_icr == 0) /* if ovflo, */ + tmr_icr = tmr_nicr; /* reload tir */ + } +if ((tmr_iccs & (TMR_CSR_DON | TMR_CSR_IE)) != /* update int */ + (TMR_CSR_DON | TMR_CSR_IE)) + tmr_int = 0; +return; +} + +int32 icr_rd (t_bool interp) +{ +uint32 delta; + +if (interp || (tmr_iccs & TMR_CSR_RUN)) { /* interp, running? */ + delta = sim_grtime () - tmr_sav; /* delta inst */ + if (tmr_use_100hz && (tmr_poll > TMR_INC)) /* scale large int */ + delta = (uint32) ((((double) delta) * TMR_INC) / tmr_poll); + if (delta >= tmr_inc) + delta = tmr_inc - 1; + return tmr_icr + delta; + } +return tmr_icr; +} + +int32 nicr_rd () +{ +return tmr_nicr; +} + +void nicr_wr (int32 val) +{ +tmr_nicr = val; +} + +/* 100Hz base clock unit service */ + +t_stat clk_svc (UNIT *uptr) +{ +tmr_poll = sim_rtcn_calb (clk_tps, TMR_CLK); /* calibrate clock */ +sim_activate (&clk_unit, tmr_poll); /* reactivate unit */ +tmxr_poll = tmr_poll * TMXR_MULT; /* set mux poll */ +todr_reg = todr_reg + 1; /* incr TODR */ +if ((tmr_iccs & TMR_CSR_RUN) && tmr_use_100hz) /* timer on, std intvl? */ + tmr_incr (TMR_INC); /* do timer service */ +return SCPE_OK; +} + +/* Interval timer unit service */ + +t_stat tmr_svc (UNIT *uptr) +{ +tmr_incr (tmr_inc); /* incr timer */ +return SCPE_OK; +} + +/* Timer increment */ + +void tmr_incr (uint32 inc) +{ +uint32 new_icr = (tmr_icr + inc) & LMASK; /* add incr */ + +if (new_icr < tmr_icr) { /* ovflo? */ + tmr_icr = 0; /* now 0 */ + if (tmr_iccs & TMR_CSR_DON) /* done? set err */ + tmr_iccs = tmr_iccs | TMR_CSR_ERR; + else tmr_iccs = tmr_iccs | TMR_CSR_DON; /* set done */ + if (tmr_iccs & TMR_CSR_RUN) { /* run? */ + tmr_icr = tmr_nicr; /* reload */ + tmr_sched (); /* reactivate */ + } + if (tmr_iccs & TMR_CSR_IE) /* ie? set int req */ + tmr_int = 1; + else tmr_int = 0; + } +else { + tmr_icr = new_icr; /* no, update icr */ + if (tmr_iccs & TMR_CSR_RUN) /* still running? */ + tmr_sched (); /* reactivate */ + } +return; +} + +/* Timer scheduling */ + +void tmr_sched (void) +{ +tmr_sav = sim_grtime (); /* save intvl base */ +tmr_inc = (~tmr_icr + 1); /* inc = interval */ +if (tmr_inc == 0) tmr_inc = 1; +if (tmr_inc < TMR_INC) { /* 100Hz multiple? */ + sim_activate (&tmr_unit, tmr_inc); /* schedule timer */ + tmr_use_100hz = 0; + } +else tmr_use_100hz = 1; /* let clk handle */ +return; +} + +/* Clock coscheduling routine */ + +int32 clk_cosched (int32 wait) +{ +int32 t; + +t = sim_activate_time (&clk_unit); +return (t? t - 1: wait); +} + +/* 100Hz clock reset */ + +t_stat clk_reset (DEVICE *dptr) +{ +tmr_poll = sim_rtcn_init (clk_unit.wait, TMR_CLK); /* init 100Hz timer */ +sim_activate (&clk_unit, tmr_poll); /* activate 100Hz unit */ +tmxr_poll = tmr_poll * TMXR_MULT; /* set mux poll */ +if (clk_unit.filebuf == NULL) { /* make sure the TODR is initialized */ + clk_unit.filebuf = calloc(sizeof(TOY), 1); + if (clk_unit.filebuf == NULL) + return SCPE_MEM; + todr_resync (); + } +return SCPE_OK; +} + +/* CLK attach */ + +t_stat clk_attach (UNIT *uptr, char *cptr) +{ +t_stat r; + +uptr->flags = uptr->flags | (UNIT_ATTABLE | UNIT_BUFABLE); +memset (uptr->filebuf, 0, (size_t)uptr->capac); +r = attach_unit (uptr, cptr); +if (r != SCPE_OK) + uptr->flags = uptr->flags & ~(UNIT_ATTABLE | UNIT_BUFABLE); +else + uptr->hwmark = (uint32) uptr->capac; +return r; +} + +/* CLK detach */ + +t_stat clk_detach (UNIT *uptr) +{ +t_stat r; + +r = detach_unit (uptr); +if ((uptr->flags & UNIT_ATT) == 0) + uptr->flags = uptr->flags & ~(UNIT_ATTABLE | UNIT_BUFABLE); +return r; +} + +/* Interval timer reset */ + +t_stat tmr_reset (DEVICE *dptr) +{ +tmr_iccs = 0; +tmr_icr = 0; +tmr_nicr = 0; +tmr_int = 0; +tmr_use_100hz = 1; +sim_cancel (&tmr_unit); /* cancel timer */ +todr_resync (); /* resync TODR */ +return SCPE_OK; +} + +/* TODR routines */ + +int32 todr_rd (void) +{ +TOY *toy = (TOY *)clk_unit.filebuf; +struct timespec base, now, val; + +clock_gettime(CLOCK_REALTIME, &now); /* get curr time */ +base.tv_sec = toy->toy_gmtbase; +base.tv_nsec = toy->toy_gmtbasemsec * 1000000; +sim_timespec_diff (&val, &now, &base); +return (int32)(val.tv_sec*100 + val.tv_nsec/10000000); /* 100hz Clock Ticks */ +} + +void todr_wr (int32 data) +{ +TOY *toy = (TOY *)clk_unit.filebuf; +struct timespec now, val, base; + +/* Save the GMT time when set value was 0 to record the base for future + read operations in "battery backed-up" state */ + +if (-1 == clock_gettime(CLOCK_REALTIME, &now)) /* get curr time */ + return; /* error? */ +val.tv_sec = ((uint32)data) / 100; +val.tv_nsec = (((uint32)data) % 100) * 10000000; +sim_timespec_diff (&base, &now, &val); /* base = now - data */ +toy->toy_gmtbase = (uint32)base.tv_sec; +toy->toy_gmtbasemsec = base.tv_nsec/1000000; +} + +t_stat todr_resync (void) +{ +TOY *toy = (TOY *)clk_unit.filebuf; + +if (clk_unit.flags & UNIT_ATT) { /* Attached means behave like real VAX860 */ + if (!toy->toy_gmtbase) /* Never set? */ + todr_wr (0); /* Start ticking from 0 */ + } +else { /* Not-Attached means */ + uint32 base; /* behave like simh VMS default */ + time_t curr; + struct tm *ctm; + + curr = time (NULL); /* get curr time */ + if (curr == (time_t) -1) /* error? */ + return SCPE_NOFNC; + ctm = localtime (&curr); /* decompose */ + if (ctm == NULL) /* error? */ + return SCPE_NOFNC; + base = (((((ctm->tm_yday * 24) + /* sec since 1-Jan */ + ctm->tm_hour) * 60) + + ctm->tm_min) * 60) + + ctm->tm_sec; + todr_wr ((base * 100) + 0x10000000); /* use VMS form */ + } +return SCPE_OK; +} + +/* Logical console write */ + +t_stat lc_wr_txdb (int32 data) +{ +int32 i; +int32 mask = 0; + +lc_fnc = LC_GETFNC (data); /* get function */ +if (lc_bptr > 0) /* cmd in prog? */ + switch (lc_fnc) { + + case LC_FNCCA: /* cancel */ + sim_cancel (&tti_unit[ID_LC]); + lc_bptr = 0; + break; + + default: /* all others */ + return SCPE_OK; + } + +else switch (lc_fnc) { /* idle, case */ + + case LC_FNCCW: /* clear warm start flag */ + break; + + case LC_FNCCS: /* clear cold start flag */ + break; + + case LC_FNCMV: /* microcode version */ + lc_buf[2] = LC_FNCMV; + lc_buf[1] = VER_UCODE & 0xFF; /* low byte */ + lc_buf[0] = (VER_UCODE >> 8) & 0xFF; /* high byte */ + lc_bptr = 3; + sim_activate (&tti_unit[ID_LC], lc_cwait); /* sched command */ + break; + + case LC_FNCAC: /* array configuration */ + lc_buf[3] = LC_FNCAC; + if (MEMSIZE < MAXMEMSIZE) { /* 4MB Boards */ + lc_buf[2] = (MEMSIZE >> 22); /* slots in use */ + for (i = 0; i < lc_buf[2]; i++) { + mask |= (2 << (i * 2)); /* build array mask */ + } + } + else { + lc_buf[2] = (MEMSIZE >> 24); /* 16MB Boards */ + for (i = 0; i < lc_buf[2]; i++) { + mask |= (1 << (i * 2)); /* build array mask */ + } + } + lc_buf[1] = mask & 0xFF; /* slots 1 - 4 */ + lc_buf[0] = (mask >> 8) & 0xFF; /* slots 5 - 8 */ + lc_bptr = 4; + sim_activate (&tti_unit[ID_LC], lc_cwait); /* sched command */ + break; + + case LC_FNCSS: /* snapshot file status */ + lc_buf[1] = LC_FNCSS; + lc_buf[0] = 0x0; /* both invalid */ + lc_bptr = 2; + sim_activate (&tti_unit[ID_LC], lc_cwait); /* sched command */ + break; + + default: /* all others */ + printf ("TTO3: Unknown console command: %X\n", lc_fnc); + break; + } +return SCPE_OK; +} + +/* Unit service; the action to be taken depends on the transfer state: + + RL_IDLE Should never get here + RL_READ Read byte, Set STXCS + RL_WRITE Write byte, Set STXCS + RL_ABORT Set STXCS + RL_STATUS Copy requested data to STXDB, Set STXCS +*/ + +t_stat rlcs_svc (UNIT *uptr) +{ +int32 bcnt; +uint32 da; + +switch (rlcs_state) { + + case RL_IDLE: + return SCPE_IERR; + + case RL_READ: + if ((cso_csr & CSR_DONE) == 0) { /* buf ready? */ + if (rlcs_bcnt == 0) { /* read in whole block */ + da = STXCS_GETDA(cso_csr) * 512; /* get byte offset */ + if (sim_fseek (uptr->fileref, da, SEEK_SET)) + return SCPE_IOERR; + bcnt = sim_fread (rlcs_buf, sizeof (int16), RL_NUMBY, uptr->fileref); + } + if (rlcs_bcnt < RL_NUMBY) { /* more data in buffer? */ + cso_buf = rlcs_buf[rlcs_bcnt++]; /* return next word */ + cso_csr = cso_csr | CSR_DONE | /* continue */ + (RLST_CONT << STXCS_V_STS); + } + else { + cso_csr = cso_csr | CSR_DONE | /* complete */ + (RLST_COMP << STXCS_V_STS); + rlcs_state = RL_IDLE; /* now idle */ + rlcs_bcnt = 0; + } + if (cso_csr & CSR_IE) + csi_int = 1; + break; + } + sim_activate (uptr, rlcs_swait); /* schedule next */ + break; + + case RL_WRITE: + if (rlcs_bcnt < RL_NUMBY) { /* more data to buffer? */ + cso_csr = cso_csr | CSR_DONE | /* continue */ + (RLST_CONT << STXCS_V_STS); + } + else { + da = STXCS_GETDA(cso_csr) * 512; /* get byte offset */ + if (sim_fseek (uptr->fileref, da, SEEK_SET)) + return SCPE_IOERR; + bcnt = sim_fwrite (rlcs_buf, sizeof (int16), RL_NUMBY, uptr->fileref); + rlcs_state = RL_IDLE; /* now idle */ + rlcs_bcnt = 0; + cso_csr = cso_csr | CSR_DONE | /* complete */ + (RLST_COMP << STXCS_V_STS); + } + if (cso_csr & CSR_IE) + csi_int = 1; + break; + + case RL_ABORT: + if ((cso_csr & CSR_DONE) == 0) { /* buf ready? */ + cso_csr = cso_csr | CSR_DONE | /* aborted */ + (RLST_ABORT << STXCS_V_STS); + cso_buf = 0; + rlcs_bcnt = 0; + rlcs_state = RL_IDLE; + if (cso_csr & CSR_IE) + csi_int = 1; + break; + } + sim_activate (uptr, rlcs_swait); /* schedule next */ + break; + + case RL_STATUS: + if ((cso_csr & CSR_DONE) == 0) { /* buf ready? */ + switch (rlcs_sts_reg) { /* which register? */ + + case RL_CSR: + if (rlcs_csr & RLCS_ALLERR) /* any errors? */ + rlcs_csr = rlcs_csr | RLCS_ERR; /* set master error bit */ + if (rlcs_bcnt > 0) /* transfer in progress? */ + rlcs_csr = rlcs_csr & ~RLCS_DRDY; + else rlcs_csr = rlcs_csr | RLCS_DRDY; + cso_buf = rlcs_csr; + rlcs_sts_reg = RL_MP; /* MP on next read */ + break; + + case RL_MP: + if ((uptr->flags & UNIT_ATT) == 0) /* update status */ + rlcs_mp = RLDS_UNATT; + else rlcs_mp = RLDS_ATT; + cso_buf = rlcs_mp; + rlcs_sts_reg = RL_CSR; /* MP on next read */ + break; + } + cso_csr = cso_csr | CSR_DONE | /* returning status */ + (RLST_STS << STXCS_V_STS); + rlcs_state = RL_IDLE; + if (cso_csr & CSR_IE) + csi_int = 1; + break; + } + sim_activate (uptr, rlcs_swait); /* schedule next */ + break; + } +return SCPE_OK; +} + +/* Reset */ + +t_stat rlcs_reset (DEVICE *dptr) +{ +cso_buf = 0; +cso_csr = CSR_DONE; +csi_int = 0; +rlcs_state = RL_IDLE; +rlcs_csr = 0; +rlcs_sts_reg = RL_CSR; +rlcs_bcnt = 0; +if (rlcs_buf == NULL) + rlcs_buf = (uint16 *) calloc (RL_NUMBY, sizeof (uint16)); +if (rlcs_buf == NULL) + return SCPE_MEM; +sim_cancel (&rlcs_unit); /* deactivate unit */ +return SCPE_OK; +} + +t_stat rlcs_attach (UNIT *uptr, char *cptr) +{ +uint32 p; +t_stat r; + +uptr->capac = RL02_SIZE; +r = attach_unit (uptr, cptr); /* attach unit */ +if (r != SCPE_OK) /* error? */ + return r; +uptr->TRK = 0; /* cylinder 0 */ +uptr->STAT = RLDS_VCK; /* new volume */ +if ((p = sim_fsize (uptr->fileref)) == 0) { /* new disk image? */ + if (uptr->flags & UNIT_RO) /* if ro, done */ + return SCPE_OK; + return pdp11_bad_block (uptr, RL_NUMSC, RL_NUMWD); + } +return SCPE_OK; +} diff --git a/VAX/vax860_syslist.c b/VAX/vax860_syslist.c new file mode 100644 index 00000000..4df2f178 --- /dev/null +++ b/VAX/vax860_syslist.c @@ -0,0 +1,125 @@ +/* vax860_syslist.c: VAX 8600 device list + + Copyright (c) 2011-2012, Matt Burke + This module incorporates code from SimH, Copyright (c) 1998-2008, Robert M Supnik + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the name(s) of the author(s) shall not be + used in advertising or otherwise to promote the sale, use or other dealings + in this Software without prior written authorization from the author(s). + + 26-Dec-2012 MB First version +*/ + +#include "vax_defs.h" + +char sim_name[] = "VAX860"; + +extern DEVICE cpu_dev; +extern DEVICE tlb_dev; +extern DEVICE abus_dev; +extern DEVICE sbia_dev; +extern DEVICE uba_dev; +extern DEVICE mba_dev[MBA_NUM]; +extern DEVICE clk_dev; +extern DEVICE tmr_dev; +extern DEVICE tti_dev, tto_dev; +extern DEVICE rlcs_dev; +extern DEVICE cr_dev; +extern DEVICE lpt_dev; +extern DEVICE rq_dev, rqb_dev, rqc_dev, rqd_dev; +extern DEVICE rl_dev; +extern DEVICE hk_dev; +extern DEVICE rp_dev; +extern DEVICE ry_dev; +extern DEVICE ts_dev; +extern DEVICE tq_dev; +extern DEVICE tu_dev; +extern DEVICE dz_dev; +extern DEVICE xu_dev, xub_dev; + +extern int32 sim_switches; +extern UNIT cpu_unit; +extern void WriteB (uint32 pa, int32 val); + +DEVICE *sim_devices[] = { + &cpu_dev, + &tlb_dev, + &abus_dev, + &sbia_dev, + &uba_dev, + &mba_dev[0], + &mba_dev[1], + &clk_dev, + &tmr_dev, + &tti_dev, + &tto_dev, + &rlcs_dev, + &dz_dev, + &cr_dev, + &lpt_dev, + &rp_dev, + &rl_dev, + &hk_dev, + &rq_dev, + &rqb_dev, + &rqc_dev, + &rqd_dev, + &ry_dev, + &tu_dev, + &ts_dev, + &tq_dev, + &xu_dev, + &xub_dev, + NULL + }; + +/* Binary loader + + The binary loader handles absolute system images, that is, system + images linked /SYSTEM. These are simply a byte stream, with no + origin or relocation information. + + -o for memory, specify origin +*/ + +t_stat sim_load (FILE *fileref, char *cptr, char *fnam, int flag) +{ +t_stat r; +int32 val; +uint32 origin, limit; + +if (flag) /* dump? */ + return SCPE_ARG; +origin = 0; /* memory */ +limit = (uint32) cpu_unit.capac; +if (sim_switches & SWMASK ('O')) { /* origin? */ + origin = (int32) get_uint (cptr, 16, 0xFFFFFFFF, &r); + if (r != SCPE_OK) + return SCPE_ARG; + } + +while ((val = getc (fileref)) != EOF) { /* read byte stream */ + if (origin >= limit) /* NXM? */ + return SCPE_NXM; + WriteB (origin, val); /* memory */ + origin = origin + 1; + } +return SCPE_OK; +} diff --git a/VAX/vax_cpu1.c b/VAX/vax_cpu1.c index d4e3ea32..e569bee7 100644 --- a/VAX/vax_cpu1.c +++ b/VAX/vax_cpu1.c @@ -1445,7 +1445,7 @@ int32 cc; if (PSL & PSL_CUR) /* must be kernel */ RSVD_INST_FAULT; -if (prn > 63) /* reg# > 63? fault */ +if (prn > MT_MAX) /* reg# > max? fault */ RSVD_OPND_FAULT; CC_IIZZ_L (val); /* set cc's */ switch (prn) { /* case on reg # */ @@ -1576,7 +1576,7 @@ int32 val; if (PSL & PSL_CUR) /* must be kernel */ RSVD_INST_FAULT; -if (prn > 63) /* reg# > 63? fault */ +if (prn > MT_MAX) /* reg# > max? fault */ RSVD_OPND_FAULT; switch (prn) { /* case on reg# */ diff --git a/VAX/vax_defs.h b/VAX/vax_defs.h index ac2adaab..dab14708 100644 --- a/VAX/vax_defs.h +++ b/VAX/vax_defs.h @@ -738,6 +738,8 @@ void cpu_idle (void); #include "vax610_defs.h" #elif defined (VAX_620) || defined (VAX_630) #include "vax630_defs.h" +#elif defined (VAX_860) +#include "vax860_defs.h" #else /* VAX 3900 */ #include "vaxmod_defs.h" #endif diff --git a/VAX/vaxmod_defs.h b/VAX/vaxmod_defs.h index 3e56d146..020b5a72 100644 --- a/VAX/vaxmod_defs.h +++ b/VAX/vaxmod_defs.h @@ -96,6 +96,7 @@ #define MT_CONPC 42 #define MT_CONPSL 43 #define MT_IORESET 55 +#define MT_MAX 63 /* last valid IPR */ /* Memory system error register */ diff --git a/Visual Studio Projects/VAX860.vcproj b/Visual Studio Projects/VAX860.vcproj new file mode 100644 index 00000000..7fa98ba9 --- /dev/null +++ b/Visual Studio Projects/VAX860.vcproj @@ -0,0 +1,479 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/makefile b/makefile index be69d984..9c616d34 100644 --- a/makefile +++ b/makefile @@ -529,6 +529,7 @@ VAX630 = ${VAXD}/vax_cpu.c ${VAXD}/vax_cpu1.c ${VAXD}/vax_fpa.c \ VAX620_OPT = -DVM_VAX -DVAX_620 -DUSE_INT64 -DUSE_ADDR64 -I ${VAXD} -I ${PDP11D} ${NETWORK_OPT} VAX630_OPT = -DVM_VAX -DVAX_630 -DUSE_INT64 -DUSE_ADDR64 -I ${VAXD} -I ${PDP11D} ${NETWORK_OPT} + VAX730 = ${VAXD}/vax_cpu.c ${VAXD}/vax_cpu1.c ${VAXD}/vax_fpa.c \ ${VAXD}/vax_cis.c ${VAXD}/vax_octa.c ${VAXD}/vax_cmode.c \ ${VAXD}/vax_mmu.c ${VAXD}/vax_sys.c ${VAXD}/vax_syscm.c \ @@ -571,6 +572,20 @@ VAX780 = ${VAXD}/vax_cpu.c ${VAXD}/vax_cpu1.c ${VAXD}/vax_fpa.c \ VAX780_OPT = -DVM_VAX -DVAX_780 -DUSE_INT64 -DUSE_ADDR64 -I VAX -I ${PDP11D} ${NETWORK_OPT} +VAX860 = ${VAXD}/vax_cpu.c ${VAXD}/vax_cpu1.c ${VAXD}/vax_fpa.c \ + ${VAXD}/vax_cis.c ${VAXD}/vax_octa.c ${VAXD}/vax_cmode.c \ + ${VAXD}/vax_mmu.c ${VAXD}/vax_sys.c ${VAXD}/vax_syscm.c \ + ${VAXD}/vax860_stddev.c ${VAXD}/vax860_sbia.c \ + ${VAXD}/vax860_abus.c ${VAXD}/vax780_uba.c ${VAXD}/vax7x0_mba.c \ + ${VAXD}/vax860_syslist.c \ + ${PDP11D}/pdp11_rl.c ${PDP11D}/pdp11_rq.c ${PDP11D}/pdp11_ts.c \ + ${PDP11D}/pdp11_dz.c ${PDP11D}/pdp11_lp.c ${PDP11D}/pdp11_tq.c \ + ${PDP11D}/pdp11_xu.c ${PDP11D}/pdp11_ry.c ${PDP11D}/pdp11_cr.c \ + ${PDP11D}/pdp11_rp.c ${PDP11D}/pdp11_tu.c ${PDP11D}/pdp11_hk.c \ + ${PDP11D}/pdp11_vh.c ${PDP11D}/pdp11_dmc.c ${PDP11D}/pdp11_io_lib.c +VAX860_OPT = -DVM_VAX -DVAX_860 -DUSE_INT64 -DUSE_ADDR64 -I VAX -I ${PDP11D} ${NETWORK_OPT} + + PDP10D = PDP10 PDP10 = ${PDP10D}/pdp10_fe.c ${PDP11D}/pdp11_dz.c ${PDP10D}/pdp10_cpu.c \ ${PDP10D}/pdp10_ksio.c ${PDP10D}/pdp10_lp20.c ${PDP10D}/pdp10_mdfp.c \ @@ -581,7 +596,6 @@ PDP10 = ${PDP10D}/pdp10_fe.c ${PDP11D}/pdp11_dz.c ${PDP10D}/pdp10_cpu.c \ PDP10_OPT = -DVM_PDP10 -DUSE_INT64 -I ${PDP10D} -I ${PDP11D} - PDP8D = PDP8 PDP8 = ${PDP8D}/pdp8_cpu.c ${PDP8D}/pdp8_clk.c ${PDP8D}/pdp8_df.c \ ${PDP8D}/pdp8_dt.c ${PDP8D}/pdp8_lp.c ${PDP8D}/pdp8_mt.c \ @@ -743,7 +757,7 @@ TX0_OPT = -I ${TX0D} $(DISPLAY_OPT) # Build everything # ALL = pdp1 pdp4 pdp7 pdp8 pdp9 pdp15 pdp11 pdp10 \ - vax vax610 vax620 vax630 vax730 vax750 vax780 \ + vax vax610 vax620 vax630 vax730 vax750 vax780 vax860 \ nova eclipse hp2100 i1401 i1620 s3 altair altairz80 gri \ i7094 ibm1130 id16 id32 sds lgp h316 \ swtp6800mp-a swtp6800mp-a2 tx-0 @@ -869,6 +883,12 @@ ${BIN}vax780${EXE} : ${VAX780} ${SIM} ${BUILD_ROMS} ${MKDIRBIN} ${CC} ${VAX780} ${SIM} ${VAX780_OPT} $(CC_OUTSPEC) ${LDFLAGS} +vax860 : ${BIN}vax860${EXE} + +${BIN}vax860${EXE} : ${VAX860} ${SIM} ${BUILD_ROMS} + ${MKDIRBIN} + ${CC} ${VAX860} ${SIM} ${VAX860_OPT} $(CC_OUTSPEC) ${LDFLAGS} + nova : ${BIN}nova${EXE} ${BIN}nova${EXE} : ${NOVA} ${SIM} From 2751a227258a41e5da96b6d937127b3b48b0734a Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Thu, 27 Dec 2012 07:02:23 -0800 Subject: [PATCH 09/11] VAX 8600 compiler warning cleanups Addition of DMC11 to the VAX 8600 --- VAX/vax860_abus.c | 4 +--- VAX/vax860_sbia.c | 6 +++++- VAX/vax860_stddev.c | 4 ++-- VAX/vax860_syslist.c | 5 +++++ 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/VAX/vax860_abus.c b/VAX/vax860_abus.c index c2d6f4a2..0bd23cfe 100644 --- a/VAX/vax860_abus.c +++ b/VAX/vax860_abus.c @@ -473,7 +473,7 @@ return; int32 ReadReg (int32 pa, int32 lnt) { -int32 nexus, val; +int32 val; if (ADDR_IS_SBIA (pa)) return sbia_rd (pa, lnt); /* SBI adapter space? */ if (ADDR_IS_REG (pa)) { /* reg space? */ @@ -496,8 +496,6 @@ return 0; void WriteReg (int32 pa, int32 val, int32 lnt) { -int32 nexus; - if (ADDR_IS_SBIA (pa)) { /* SBI adapter space? */ sbia_wr (pa, val, lnt); SET_IRQL; diff --git a/VAX/vax860_sbia.c b/VAX/vax860_sbia.c index b4649e0e..50bdb83f 100644 --- a/VAX/vax860_sbia.c +++ b/VAX/vax860_sbia.c @@ -171,7 +171,11 @@ int32 sbia_rd (int32 pa, int32 lnt) case 0x11: /* SBIMT */ return sbi_mt & SBIMT_RD; - } + + default: /* Anything else is not impl */ + return 0; + + } } void sbia_wr (int32 pa, int32 val, int32 lnt) diff --git a/VAX/vax860_stddev.c b/VAX/vax860_stddev.c index 129aaa31..24f39c36 100644 --- a/VAX/vax860_stddev.c +++ b/VAX/vax860_stddev.c @@ -971,13 +971,13 @@ else switch (lc_fnc) { /* idle, case */ case LC_FNCAC: /* array configuration */ lc_buf[3] = LC_FNCAC; if (MEMSIZE < MAXMEMSIZE) { /* 4MB Boards */ - lc_buf[2] = (MEMSIZE >> 22); /* slots in use */ + lc_buf[2] = (uint8)(MEMSIZE >> 22); /* slots in use */ for (i = 0; i < lc_buf[2]; i++) { mask |= (2 << (i * 2)); /* build array mask */ } } else { - lc_buf[2] = (MEMSIZE >> 24); /* 16MB Boards */ + lc_buf[2] = (uint8)(MEMSIZE >> 24); /* 16MB Boards */ for (i = 0; i < lc_buf[2]; i++) { mask |= (1 << (i * 2)); /* build array mask */ } diff --git a/VAX/vax860_syslist.c b/VAX/vax860_syslist.c index 4df2f178..49767974 100644 --- a/VAX/vax860_syslist.c +++ b/VAX/vax860_syslist.c @@ -53,6 +53,7 @@ extern DEVICE tq_dev; extern DEVICE tu_dev; extern DEVICE dz_dev; extern DEVICE xu_dev, xub_dev; +extern DEVICE dmc_dev[]; extern int32 sim_switches; extern UNIT cpu_unit; @@ -87,6 +88,10 @@ DEVICE *sim_devices[] = { &tq_dev, &xu_dev, &xub_dev, + &dmc_dev[0], + &dmc_dev[1], + &dmc_dev[2], + &dmc_dev[3], NULL }; From c5e41ad6cc3afd87505a33da2a693d069e921a48 Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Thu, 27 Dec 2012 07:11:48 -0800 Subject: [PATCH 10/11] Addition of VAX 8600 to Visual Studio Solution file Avoid warning when compiling with MinGW on Windows XP --- Visual Studio Projects/Simh.sln | 9 +++++++++ makefile | 6 +++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/Visual Studio Projects/Simh.sln b/Visual Studio Projects/Simh.sln index 4452cc91..05265482 100644 --- a/Visual Studio Projects/Simh.sln +++ b/Visual Studio Projects/Simh.sln @@ -92,6 +92,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VAX630", "VAX630.vcproj", " EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TX-0", "TX-0.vcproj", "{24BC7F75-FB56-44A9-BB7C-78AE6A694D0C}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VAX860", "VAX860.vcproj", "{F5C22D72-460E-43CD-9AC6-6D6AC517BD1F}" + ProjectSection(ProjectDependencies) = postProject + {D40F3AF1-EEE7-4432-9807-2AD287B490F8} = {D40F3AF1-EEE7-4432-9807-2AD287B490F8} + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -238,6 +243,10 @@ Global {24BC7F75-FB56-44A9-BB7C-78AE6A694D0C}.Debug|Win32.Build.0 = Debug|Win32 {24BC7F75-FB56-44A9-BB7C-78AE6A694D0C}.Release|Win32.ActiveCfg = Release|Win32 {24BC7F75-FB56-44A9-BB7C-78AE6A694D0C}.Release|Win32.Build.0 = Release|Win32 + {F5C22D72-460E-43CD-9AC6-6D6AC517BD1F}.Debug|Win32.ActiveCfg = Debug|Win32 + {F5C22D72-460E-43CD-9AC6-6D6AC517BD1F}.Debug|Win32.Build.0 = Debug|Win32 + {F5C22D72-460E-43CD-9AC6-6D6AC517BD1F}.Release|Win32.ActiveCfg = Release|Win32 + {F5C22D72-460E-43CD-9AC6-6D6AC517BD1F}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/makefile b/makefile index 9c616d34..bac59a48 100644 --- a/makefile +++ b/makefile @@ -302,7 +302,11 @@ ifeq ($(WIN32),) #*nix Environments (&& cygwin) else #Win32 Environments (via MinGW32) GCC = gcc - GCC_Path := $(dir $(shell where gcc.exe)) + ifeq (XP,$(findstring XP,$(shell ver))) + GCC_Path := C:\MinGW\bin\ + else + GCC_Path := $(dir $(shell where gcc.exe)) + endif GCC_VERSION = $(word 3,$(shell $(GCC) --version)) COMPILER_NAME = GCC Version: $(GCC_VERSION) LTO_EXCLUDE_VERSIONS = 4.5.2 From 2a5caf87a70baa9d0cfbdf850fa1b079669fd5a2 Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Thu, 27 Dec 2012 10:28:57 -0800 Subject: [PATCH 11/11] Add embedded boot code support to VAX 8600 Added RQB, RQC, RQD as boot devices for VAX 8600 Added generalized R5 boot flags option to all Unibus VAX systems --- VAX/vax730_sys.c | 12 ++++++++++-- VAX/vax750_cmi.c | 12 ++++++++++-- VAX/vax780_sbi.c | 12 ++++++++++-- VAX/vax860_abus.c | 26 ++++++++++++++++++++------ 4 files changed, 50 insertions(+), 12 deletions(-) diff --git a/VAX/vax730_sys.c b/VAX/vax730_sys.c index 36c6fa1b..4cb52737 100644 --- a/VAX/vax730_sys.c +++ b/VAX/vax730_sys.c @@ -525,8 +525,16 @@ if ((strncmp (regptr, "/R5:", 4) == 0) || if (r != SCPE_OK) return r; } -else if (*regptr != 0) - return SCPE_ARG; +else + if (*regptr == '/') { + r5v = (int32) get_uint (regptr + 1, 16, LMASK, &r); + if (r != SCPE_OK) + return r; + } + else { + if (*regptr != 0) + return SCPE_ARG; + } for (i = 0; boot_tab[i].name != NULL; i++) { if (strcmp (dptr->name, boot_tab[i].name) == 0) { R[0] = boot_tab[i].code; diff --git a/VAX/vax750_cmi.c b/VAX/vax750_cmi.c index 75cc641b..e036bf8a 100644 --- a/VAX/vax750_cmi.c +++ b/VAX/vax750_cmi.c @@ -609,8 +609,16 @@ if ((strncmp (regptr, "/R5:", 4) == 0) || if (r != SCPE_OK) return r; } -else if (*regptr != 0) - return SCPE_ARG; +else + if (*regptr == '/') { + r5v = (int32) get_uint (regptr + 1, 16, LMASK, &r); + if (r != SCPE_OK) + return r; + } + else { + if (*regptr != 0) + return SCPE_ARG; + } for (i = 0; boot_tab[i].name != NULL; i++) { if (strcmp (dptr->name, boot_tab[i].name) == 0) { R[0] = boot_tab[i].code; diff --git a/VAX/vax780_sbi.c b/VAX/vax780_sbi.c index 3bc28739..76f39006 100644 --- a/VAX/vax780_sbi.c +++ b/VAX/vax780_sbi.c @@ -668,8 +668,16 @@ if ((strncmp (regptr, "/R5:", 4) == 0) || if (r != SCPE_OK) return r; } -else if (*regptr != 0) - return SCPE_ARG; +else + if (*regptr == '/') { + r5v = (int32) get_uint (regptr + 1, 16, LMASK, &r); + if (r != SCPE_OK) + return r; + } + else { + if (*regptr != 0) + return SCPE_ARG; + } for (i = 0; boot_tab[i].name != NULL; i++) { if (strcmp (dptr->name, boot_tab[i].name) == 0) { R[0] = boot_tab[i].code; diff --git a/VAX/vax860_abus.c b/VAX/vax860_abus.c index 0bd23cfe..4ef20c15 100644 --- a/VAX/vax860_abus.c +++ b/VAX/vax860_abus.c @@ -31,6 +31,12 @@ #include "vax_defs.h" +#ifdef DONT_USE_INTERNAL_ROM +#define BOOT_CODE_FILENAME "vmb.exe" +#else /* !DONT_USE_INTERNAL_ROM */ +#include "vax_vmb_exe.h" /* Defines BOOT_CODE_FILENAME and BOOT_CODE_ARRAY, etc */ +#endif /* DONT_USE_INTERNAL_ROM */ + /* SBIA registers */ #define SBIER_TMO 0x00001000 /* timeout */ @@ -93,6 +99,9 @@ static struct boot_dev boot_tab[] = { { "HK", BOOT_HK, 0 }, { "RL", BOOT_RL, 0 }, { "RQ", BOOT_UDA, 1 << 24 }, + { "RQB", BOOT_UDA, 1 << 24 }, + { "RQC", BOOT_UDA, 1 << 24 }, + { "RQD", BOOT_UDA, 1 << 24 }, { "TQ", BOOT_TK, 1 << 24 }, { "CS", BOOT_CS, 0 }, { NULL } @@ -619,8 +628,16 @@ if ((strncmp (regptr, "/R5:", 4) == 0) || if (r != SCPE_OK) return r; } -else if (*regptr != 0) - return SCPE_ARG; +else + if (*regptr == '/') { + r5v = (int32) get_uint (regptr + 1, 16, LMASK, &r); + if (r != SCPE_OK) + return r; + } + else { + if (*regptr != 0) + return SCPE_ARG; + } for (i = 0; boot_tab[i].name != NULL; i++) { if (strcmp (dptr->name, boot_tab[i].name) == 0) { R[0] = boot_tab[i].code; @@ -647,10 +664,7 @@ t_stat cpu_boot (int32 unitno, DEVICE *dptr) { t_stat r; -printf ("Loading boot code from vmb.exe\n"); -if (sim_log) fprintf (sim_log, - "Loading boot code from vmb.exe\n"); -r = load_cmd (0, "-O vmb.exe 200"); +r = cpu_load_bootcode (BOOT_CODE_FILENAME, BOOT_CODE_ARRAY, BOOT_CODE_SIZE, FALSE, 0x200); if (r != SCPE_OK) return r; SP = PC = 512;