From 708869815db37b34d15d255df543fe4ae29dc027 Mon Sep 17 00:00:00 2001 From: Jeff Parsons Date: Tue, 22 Nov 2016 16:54:45 -0800 Subject: [PATCH] Fixed DL11 for RT-11, and added more message capabilities --- docs/pcx86/examples/pcx86-dbg.js | 14 +++---- docs/pcx86/examples/pcx86.js | 12 +++--- modules/pdp11/lib/bus.js | 18 ++++----- modules/pdp11/lib/cpustate.js | 28 ++++++++++++-- modules/pdp11/lib/defines.js | 8 ++-- modules/pdp11/lib/device.js | 2 +- modules/pdp11/lib/messages.js | 48 +++++++++++++++--------- modules/pdp11/lib/pc11.js | 2 +- modules/pdp11/lib/rk11.js | 17 ++++++--- modules/pdp11/lib/rl11.js | 2 +- modules/pdp11/lib/serialport.js | 63 +++++++++++++++++--------------- modules/shared/lib/keys.js | 8 ++-- 12 files changed, 135 insertions(+), 87 deletions(-) diff --git a/docs/pcx86/examples/pcx86-dbg.js b/docs/pcx86/examples/pcx86-dbg.js index 7755492b7..cd3b3f3d8 100644 --- a/docs/pcx86/examples/pcx86-dbg.js +++ b/docs/pcx86/examples/pcx86-dbg.js @@ -44,8 +44,8 @@ http://pcjs.org/modules/shared/lib/save.js (C) Jeff Parsons 2012-2016 */ var l,aa,ba={163840:[40,1,8,,254],184320:[40,1,9,,252],327680:[40,2,8,,255],368640:[40,2,9,,253],737280:[80,2,9,,249],1228800:[80,2,15,,249],1474560:[80,2,18,,240],2949120:[80,2,36,,240],21368320:[615,4,17],2494464:[203,2,12,512],5242880:[256,2,40,256],10485760:[512,2,40,256]},p={uo:1,dl:3,vo:26," ":32,"!":33,'"':34,"#":35,$:36,"%":37,"&":38,"'":39,"(":40,")":41,"*":42,"+":43,",":44,"-":45,".":46,"/":47,0:48,1:49,2:50,3:51,4:52,5:53,6:54,7:55,8:56,9:57,":":58,";":59,"<":60,"=":61,">":62,"?":63,"@":64, -ue:65,Bi:66,Ci:67,Di:68,E:69,Ei:70,Fi:71,Gi:72,Hi:73,Ii:74,Ji:75,Ki:76,Li:77,Mi:78,Ni:79,Oi:80,Q:81,Pi:82,Qi:83,Ri:84,Si:85,Ti:86,Ui:87,Vi:88,Wi:89,og:90,"[":91,"\\":92,"]":93,"^":94,_:95,"`":96,ve:97,ol:98,ql:99,d:100,e:101,Al:102,Bl:103,Cl:104,Dl:105,Tm:106,k:107,Um:108,Ym:109,n:110,en:111,p:112,q:113,r:114,lo:115,t:116,oo:117,po:118,qo:119,x:120,y:121,z:122,"{":123,"|":124,"}":125,"~":126},ca={};ca[186]=p[";"];ca[187]=p["="];ca[188]=p[","];ca[189]=p["-"];ca[190]=p["."];ca[191]=p["/"];ca[192]=p["`"]; -ca[219]=p["["];ca[220]=p["\\"];ca[221]=p["]"];ca[222]=p["'"];ca[173]=p["-"];var da={};da[p["1"]]=p["!"];da[p["2"]]=p["@"];da[p["3"]]=p["#"];da[p["4"]]=p.$;da[p["5"]]=p["%"];da[p["6"]]=p["^"];da[p["7"]]=p["&"];da[p["8"]]=p["*"];da[p["9"]]=p["("];da[p["0"]]=p[")"];da[186]=p[":"];da[187]=p["+"];da[188]=p["<"];da[189]=p._;da[190]=p[">"];da[191]=p["?"];da[192]=p["~"];da[219]=p["{"];da[220]=p["|"];da[221]=p["}"];da[222]=p['"'];da[173]=p._;da[61]=p["+"];da[59]=p[":"]; +ue:65,Bi:66,Ci:67,Di:68,E:69,Ei:70,Fi:71,Gi:72,Hi:73,Ii:74,Ji:75,Ki:76,Li:77,Mi:78,Ni:79,Oi:80,Q:81,Pi:82,Qi:83,Ri:84,Si:85,Ti:86,Ui:87,Vi:88,Wi:89,og:90,"[":91,"\\":92,"]":93,"^":94,_:95,"`":96,ve:97,ol:98,ql:99,d:100,e:101,Al:102,Bl:103,Cl:104,Dl:105,Tm:106,k:107,Um:108,Ym:109,n:110,en:111,p:112,q:113,r:114,lo:115,t:116,oo:117,po:118,qo:119,x:120,y:121,z:122,"{":123,"|":124,"}":125,"~":126,wo:127},ca={};ca[186]=p[";"];ca[187]=p["="];ca[188]=p[","];ca[189]=p["-"];ca[190]=p["."];ca[191]=p["/"]; +ca[192]=p["`"];ca[219]=p["["];ca[220]=p["\\"];ca[221]=p["]"];ca[222]=p["'"];ca[173]=p["-"];var da={};da[p["1"]]=p["!"];da[p["2"]]=p["@"];da[p["3"]]=p["#"];da[p["4"]]=p.$;da[p["5"]]=p["%"];da[p["6"]]=p["^"];da[p["7"]]=p["&"];da[p["8"]]=p["*"];da[p["9"]]=p["("];da[p["0"]]=p[")"];da[186]=p[":"];da[187]=p["+"];da[188]=p["<"];da[189]=p._;da[190]=p[">"];da[191]=p["?"];da[192]=p["~"];da[219]=p["{"];da[220]=p["|"];da[221]=p["}"];da[222]=p['"'];da[173]=p._;da[61]=p["+"];da[59]=p[":"]; function ea(a,b){var c;if(a){b||(b=10);var d=a.charAt(0),e=0>=1;return c}function ha(a,b,c){var d="";if(!b||4>=8;return(c?"0b":"")+d} function ia(a,b,c){var d="";b?11>=3;return(c?"0o":"")+d}function r(a,b,c){var d="";b?8=e?48:55),d=String.fromCharCode(e)+d;a>>=4}return(c?"0x":"")+d}function u(a){return r(a,2,!0)}function v(a){return r(a,4,!0)} @@ -93,7 +93,7 @@ function Pb(a,b,c,d,e){a.N.font=a.fa;a.N.fillStyle=a.Ea;a.N.fillText(b,a.C,a.U); function Rb(a,b,c){bb.call(this,"Bus",a,Rb);this.F=b;this.ha=c;this.N=a.busWidth||20;this.W=Math.pow(2,this.N);this.Eg=this.Gb=this.W-1|0;this.La=32==this.N||20>=this.N?12:24>=this.N?14:15;this.Sb=1<>2;this.A=this.Sb-1;this.U=this.W/this.Sb|0;this.ga=this.U-1;this.B=[];this.C=[];this.L=this.V=!1;this.aa=[];this.ea=[];a=new B;Sb(a,this.ha);this.sa=Array(this.U);for(b=0;b>>a.La;0g&&(n=g);if(k&&k.size){if(k.type==d&&k.controller==e){if(f+g<=k.Fa)return k.Qe+=k.Fa-f,k.Fa=f,!0;if(f>=k.Fa+k.Qe){n=k.size-(f-m);n>g&&(n=g);k.Qe=f-k.Fa+n;f=m+a.Sb;g-=n;h++;continue}}return Wb(a,1,f,g)}f=new B(f,n,a.Sb,d,e);Sb(f,a.ha,k);a.sa[h++]=f;f=m+a.Sb;g-=n}return 0>=g?(Xb(a.F),a.F.la.Ib||a.status(Math.floor(c/1024)+"Kb "+Yb[d]+" at "+r(b)),!0):Wb(a,2,b,c)} -var Nb,$b={Hk:20,count:8,Ko:1,type:3},ac=0,bc;for(bc in $b){var cc=$b[bc];$b[bc]={vh:(1<>>this.La;0>>a.La;0>>=a.La;0>>a.La;0>>this.La].pc(a&this.A,a)}; l.na=function(a){var b=a&this.A,c=(a&this.Gb)>>>this.La;return b!=this.A?this.sa[c].sf(b,a):this.sa[c++].pc(b,a)|this.sa[c&this.ga].pc(0,a+1)<<8};function mc(a,b){var c=b&a.A,d=(b&a.Gb)>>>a.La;return c!=a.A?a.sa[d].gg(c,b):a.sa[d++].re(c,b)|a.sa[d&a.ga].re(0,b+1)<<8}l.oa=function(a){var b=a&this.A,c=(a&this.Gb)>>>this.La;if(b=kg&&(this.cb=this.Da=2);this.ka=a.scaleTimers||!1;this.Ub=a.rtcDate;this.Db=!1;a.sound&&(this.sb=this.Ea=null,window&&(this.sb=window.AudioContext|| -window.webkitAudioContext),this.sb&&(this.Ea=new this.sb));this.reset(!0);xb(this)}jb(X);var vk=5150.9,kg=5170,uk={5150:5150,5160:5160,5170:kg,att6300:5160.101,mpc1600:5150.101,z150:5160.15,compaq:5150.102,other:vk,deskpro386:5180},xk="sw1",Bk="sw2",Ck={jl:1,ONE:0,Io:64,Go:128,xo:192,Lc:192,Xg:6},Dk={Ho:16,to:32,yo:48,Lc:48,Xg:4},zk=1,Ak=4,Ek={5150:[{},{}]};Ek[5150][0][zk]={Lc:192,gd:{1:0,2:64,3:128,4:192},Pd:"Number of Floppy Drives"};Ek[5150][0][3]={Lc:2,gd:{0:0,1:2},Pd:"FPU"}; +window.webkitAudioContext),this.sb&&(this.Ea=new this.sb));this.reset(!0);xb(this)}jb(X);var vk=5150.9,kg=5170,uk={5150:5150,5160:5160,5170:kg,att6300:5160.101,mpc1600:5150.101,z150:5160.15,compaq:5150.102,other:vk,deskpro386:5180},xk="sw1",Bk="sw2",Ck={jl:1,ONE:0,Jo:64,Ho:128,yo:192,Lc:192,Xg:6},Dk={Io:16,to:32,zo:48,Lc:48,Xg:4},zk=1,Ak=4,Ek={5150:[{},{}]};Ek[5150][0][zk]={Lc:192,gd:{1:0,2:64,3:128,4:192},Pd:"Number of Floppy Drives"};Ek[5150][0][3]={Lc:2,gd:{0:0,1:2},Pd:"FPU"}; Ek[5150][0][Ak]={Lc:48,gd:{0:0,1:16,2:32,3:48,none:0,tv:16,color:32,cga:32,mda:48,mono:48,ega:0,vga:0},Pd:"Monitor Type"};Ek[5150][0][5]={Lc:12,gd:{16:0,32:4,48:8,64:12},Pd:"Base Memory (16Kb Increments)"};Ek[5150][1][6]={Lc:31,gd:{0:0,32:1,64:2,96:3,128:4,160:5,192:6,224:7,256:8,288:9,320:10,352:11,384:12,416:13,448:14,480:15,512:16,544:17,576:18},Pd:"Expansion Memory (32Kb Increments)"};Ek[5160]=[{},{}];Ek[5160][0][zk]=Ek[5150][0][zk];Ek[5160][0][3]=Ek[5150][0][3];Ek[5160][0][Ak]=Ek[5150][0][Ak]; Ek[5160][0][5]={Lc:12,gd:{64:0,128:4,192:8,256:12},Pd:"Base Memory (64Kb Increments)"};Ek[5160][1][6]=Ek[5150][1][6];Ek[5160.101]=[{},{}];Ek[5160.101][0][5]={Lc:143,gd:{128:1,256:130,512:8,640:141},Pd:"Base Memory (128Kb Increments)"};Ek[5160.101][0][3]={Lc:16,gd:{0:0,1:16},Pd:"FPU"};Ek[5160.101][1][2]={Lc:1,gd:{0:0,1:1},Pd:"Floppy Type"};Ek[5160.101][1][zk]=Ek[5150][0][zk];Ek[5160.101][1][Ak]=Ek[5150][0][Ak];l=X.prototype; l.Pb=function(a,b,c){switch(b){case xk:return this.qa[b]=c,Fk(this,0,b),!0;case Bk:if(5150==(this.ja|0)||5160.101==this.ja)return this.qa[b]=c,Fk(this,1,b),!0;break;case "swdesc":return this.qa[b]=c,!0}return!1}; @@ -431,7 +431,7 @@ b,this.Pa]);a.set(4,[this.Ya,this.W,this.qb,this.Ca,this.ya]);this.ja>=kg&&(a.se l.restore=function(a){var b,c;b=a[0];Array.isArray(b[0])?this.C=b[0]:(this.C[0][0]=b[0],this.C[1][0]=b[1]&15,this.C[0][1]=b[2],this.C[1][1]=b[3]&15);Tk(this);b=a[1];for(c=0;c=f;f++){var g="pcjs-bitCell";f||(g+=" pcjs-bitCellLeft");d+='
'+f+"
\n"}e.innerHTML=d;jl(a,b,c,!0)}function kl(a,b,c){if(b=(a=Ek[a.ja|0])&&a[b])for(var d in b)if(a=b[d],a.Lc&1<b;b++){if(128==cp(a,e,c+0,1)){d.cg=cp(a,e,c+8,4);(e=bp(a,d.cg))&&(f=!0);break}c+=16}if(!f)return}d.Jf||(d.Jf=cp(a,e,19,2)||cp(a,e,32,4),d.If=cp(a,e,14,2),d.th=d.If+cp(a,e,22,2)*cp(a,e,16,1),d.Dh=cp(a,e,17,2),d.Mf=cp(a,e,13,1));d.rh=d.th+((32*d.Dh+(d.Va-1))/d.Va|0);d.$m=(d.Jf-d.rh)/d.Mf|0;d.Gg=4084>=d.$m?12:16;d.Gl=12==d.Gg?4086:65526;b=[];for(e=d.th;e>=8;f+=2;if(k)for(;m--;)ap(d,f,1),254>=k?(n=k,t=ap(d,f+1),f+=3):(n=ap(d,f+3,1),t=ap(d,f+4),f+=6),d.yd[n]&&(d.yd[n].we[h]=[t]),d.A[h]=[n,t],h++;else h+=m}(g=dp(e,Yo,c))&&ep(e,g+c);g=dp(e,Zo,c);h=dp(e,Wo,c);g&&h&&ep(e,g,g+h)}}}} -function mp(a,b,c,d,e){var f,g=a.C.length,h=b.Va/32|0;b.Mo=d+"\\";for(var k=0;kF)break;for(var C=q.rh+(F-2)*q.Mf,D=0;DF)break;for(var C=q.rh+(F-2)*q.Mf,D=0;D>3,1),d?e=16==b.Gg?e<<8:c&7?e<<4:(e&15)<<8:c&7&&(e>>=4));return e} function bp(a,b){var c=a.ub*a.lb,d=b/c|0;return dg)break;e|=g<=f)break;e+=String.fromCharCode(f)}return e}function gp(a,b,c,d,e,f){a||(a={sector:d,length:e,data:[],pattern:f});a.Hl=b;a.Il=c;a.ud=a.Zc=0;a.Wa=!1;return a} function hp(a,b){b="action=open&volume="+b+("&mode="+a.mode);b+="&chs="+a.Bb+":"+a.ub+":"+a.lb+":"+a.Va;b+="&machine="+a.controller.gf();b+="&user="+a.controller.ie();return Ba()+"/api/v1/disk?"+b} @@ -644,7 +644,7 @@ l.restore=function(a){var b=0,c="unsupported restore format";if(a&&0b?-2!=b&&this.controller.Na("Unable to restore disk '"+this.ga+": "+c):jp(this);return b}; l.toJSON=function(){var a;a=0;for(var b;b=bp(this,a++);)up(b);a=JSON.stringify(this.A,function(a,b){if("file"!=a)return b});a=a.replace(/,"length":512/gm,"").replace(/,"pattern":0/gm,"");a=a.replace(/"(sector|length|data|pattern)":/gm,"$1:");a=a.replace(/,"[^"]*":([0-9]+|true|false)/gm,"");a=a.replace(/(sector|length|data|pattern):/gm,'"$1":');return a=a.replace(/([\]}]),/gm,"$1,\n")}; function up(a){var b=a.data,c=b.length;if(c<<2==a.length){for(var d=c-1,e=b[d],f=0;d--&&b[d]===e;)f++;f++&&(b.length=c-f,a.pattern=e)}}function vp(a){bb.call(this,"FDC",a,vp,524288);this.dmaRead=this.el;this.dmaWrite=this.fl;this.dmaFormat=this.vl;this.U=a.autoMount||null;this.fa=a.sortBy||"name";"none"==this.fa&&(this.fa=null);this.B=[];this.ia=!La("Mobi")&&window&&"FileReader"in window}jb(vp);aa={}; -var wp={3:{Ud:3,ge:0,name:aa.Fo},4:{Ud:2,ge:1,name:aa.Do},5:{Ud:9,ge:7,name:aa.Jo},6:{Ud:9,ge:7,name:aa.zo},7:{Ud:2,ge:0,name:aa.Bo},8:{Ud:1,ge:2,name:aa.Eo},10:{Ud:2,ge:7,name:aa.Ao},13:{Ud:6,ge:7,name:aa.wo},15:{Ud:3,ge:0,name:aa.Co}};l=vp.prototype; +var wp={3:{Ud:3,ge:0,name:aa.Go},4:{Ud:2,ge:1,name:aa.Eo},5:{Ud:9,ge:7,name:aa.Ko},6:{Ud:9,ge:7,name:aa.Ao},7:{Ud:2,ge:0,name:aa.Co},8:{Ud:1,ge:2,name:aa.Fo},10:{Ud:2,ge:7,name:aa.Bo},13:{Ud:6,ge:7,name:aa.xo},15:{Ud:3,ge:0,name:aa.Do}};l=vp.prototype; l.Pb=function(a,b,c){var d=this;switch(b){case "listDisks":this.qa[b]=c;if(this.fa){b=[];for(a=0;a'+b+"");a.innerHTML=b}};return!0;case "descDisk":case "listDrives":return this.qa[b]=c,c.onchange=function(){var a=ea(c.value,10);null!=a&&xp(d,a)},!0;case "loadDrive":return this.qa[b]=c,c.onclick=function(){var a=d.qa.listDisks;a&&yp(d,a.options[a.selectedIndex].text,a.value)},!0;case "saveDrive":if(!this.ia){c.parentNode.removeChild(c);break}this.qa[b]=c;c.onclick=function(){var a=d.qa.listDrives;a&&a.options&&d.A&& ((a=d.A[ea(a.value,10)||0])?(a=a.za)?(a=Na(tp(a),"octet-stream",!0,a.Ug.replace(".json",".img")),w(a)):d.Na("No diskette loaded in drive."):d.Na("No diskette drive selected."))};return!0;case "mountDrive":if(this.ia)return this.qa[b]=c,c.addEventListener("change",function(){var a=c.children[0];a.children[1].disabled=!a.children[0].files.length}),c.onsubmit=function(a){if(a=a.currentTarget[1].files[0]){var b=a.name;yp(d,ja(b,!0),b,a)}return!1},!0;c.parentNode.removeChild(c)}return!1}; diff --git a/docs/pcx86/examples/pcx86.js b/docs/pcx86/examples/pcx86.js index 3f25fa2a7..480290af4 100644 --- a/docs/pcx86/examples/pcx86.js +++ b/docs/pcx86/examples/pcx86.js @@ -44,8 +44,8 @@ http://pcjs.org/modules/shared/lib/save.js (C) Jeff Parsons 2012-2016 */ var l,ba,ca={163840:[40,1,8,,254],184320:[40,1,9,,252],327680:[40,2,8,,255],368640:[40,2,9,,253],737280:[80,2,9,,249],1228800:[80,2,15,,249],1474560:[80,2,18,,240],2949120:[80,2,36,,240],21368320:[615,4,17],2494464:[203,2,12,512],5242880:[256,2,40,256],10485760:[512,2,40,256]},n={Tm:1,Sj:3,Um:26," ":32,"!":33,'"':34,"#":35,$:36,"%":37,"&":38,"'":39,"(":40,")":41,"*":42,"+":43,",":44,"-":45,".":46,"/":47,0:48,1:49,2:50,3:51,4:52,5:53,6:54,7:55,8:56,9:57,":":58,";":59,"<":60,"=":61,">":62,"?":63,"@":64, -Jd:65,wh:66,xh:67,yh:68,E:69,zh:70,Ah:71,Bh:72,Ch:73,Dh:74,Eh:75,Fh:76,Gh:77,Ih:78,Kh:79,Mh:80,Q:81,Ph:82,Rh:83,Th:84,Vh:85,Xh:86,Zh:87,ai:88,ci:89,vf:90,"[":91,"\\":92,"]":93,"^":94,_:95,"`":96,Ld:97,bk:98,ck:99,d:100,e:101,mk:102,nk:103,pk:104,qk:105,Bl:106,k:107,Cl:108,Fl:109,n:110,Kl:111,p:112,q:113,r:114,Mm:115,t:116,Pm:117,Qm:118,Rm:119,x:120,y:121,z:122,"{":123,"|":124,"}":125,"~":126},da={};da[186]=n[";"];da[187]=n["="];da[188]=n[","];da[189]=n["-"];da[190]=n["."];da[191]=n["/"];da[192]=n["`"]; -da[219]=n["["];da[220]=n["\\"];da[221]=n["]"];da[222]=n["'"];da[173]=n["-"];var p={};p[n["1"]]=n["!"];p[n["2"]]=n["@"];p[n["3"]]=n["#"];p[n["4"]]=n.$;p[n["5"]]=n["%"];p[n["6"]]=n["^"];p[n["7"]]=n["&"];p[n["8"]]=n["*"];p[n["9"]]=n["("];p[n["0"]]=n[")"];p[186]=n[":"];p[187]=n["+"];p[188]=n["<"];p[189]=n._;p[190]=n[">"];p[191]=n["?"];p[192]=n["~"];p[219]=n["{"];p[220]=n["|"];p[221]=n["}"];p[222]=n['"'];p[173]=n._;p[61]=n["+"];p[59]=n[":"]; +Jd:65,wh:66,xh:67,yh:68,E:69,zh:70,Ah:71,Bh:72,Ch:73,Dh:74,Eh:75,Fh:76,Gh:77,Ih:78,Kh:79,Mh:80,Q:81,Ph:82,Rh:83,Th:84,Vh:85,Xh:86,Zh:87,ai:88,ci:89,vf:90,"[":91,"\\":92,"]":93,"^":94,_:95,"`":96,Ld:97,bk:98,ck:99,d:100,e:101,mk:102,nk:103,pk:104,qk:105,Bl:106,k:107,Cl:108,Fl:109,n:110,Kl:111,p:112,q:113,r:114,Mm:115,t:116,Pm:117,Qm:118,Rm:119,x:120,y:121,z:122,"{":123,"|":124,"}":125,"~":126,Vm:127},da={};da[186]=n[";"];da[187]=n["="];da[188]=n[","];da[189]=n["-"];da[190]=n["."];da[191]=n["/"]; +da[192]=n["`"];da[219]=n["["];da[220]=n["\\"];da[221]=n["]"];da[222]=n["'"];da[173]=n["-"];var p={};p[n["1"]]=n["!"];p[n["2"]]=n["@"];p[n["3"]]=n["#"];p[n["4"]]=n.$;p[n["5"]]=n["%"];p[n["6"]]=n["^"];p[n["7"]]=n["&"];p[n["8"]]=n["*"];p[n["9"]]=n["("];p[n["0"]]=n[")"];p[186]=n[":"];p[187]=n["+"];p[188]=n["<"];p[189]=n._;p[190]=n[">"];p[191]=n["?"];p[192]=n["~"];p[219]=n["{"];p[220]=n["|"];p[221]=n["}"];p[222]=n['"'];p[173]=n._;p[61]=n["+"];p[59]=n[":"]; function ea(a,b){var c;if(a){b||(b=10);var d=a.charAt(0),e=0=e?48:55),d=String.fromCharCode(e)+d;a>>=4}return(c?"0x":"")+d}function ga(a,b){var c=a,d=a.lastIndexOf("/");0<=d&&(c=a.substr(d+1));d=c.indexOf("&");0":">",'"':""","'":"'"};function ka(a){return a.replace(/[&<>"']/g,function(a){return ja[a]})}function la(a){return String.prototype.trim?a.trim():a.replace(/^\s+|\s+$/g,"")} @@ -81,7 +81,7 @@ function sb(a,b,c,d,e){a.G.font=a.P;a.G.fillStyle=a.qa;a.G.fillText(b,a.D,a.K);a function ub(a,b,c){Ka.call(this,"Bus",a,ub);this.A=b;this.Ia=c;this.D=a.busWidth||20;this.L=Math.pow(2,this.D);this.ba=this.Fa=this.L-1|0;this.da=32==this.D||20>=this.D?12:24>=this.D?14:15;this.xb=1<>2;this.B=this.xb-1;this.H=this.L/this.xb|0;this.C=this.H-1;this.I=[];this.K=[];this.S=[];this.P=[];a=new u;vb(a,this.Ia);this.R=Array(this.H);for(b=0;b>>a.da;0g&&(q=g);if(k&&k.size){if(k.type==d&&k.controller==e){if(f+g<=k.he)return k.Ge+=k.he-f,k.he=f,!0;if(f>=k.he+k.Ge){q=k.size-(f-m);q>g&&(q=g);k.Ge=f-k.he+q;f=m+a.xb;g-=q;h++;continue}}return zb(a,1,f,g)}f=new u(f,q,a.xb,d,e);vb(f,a.Ia,k);a.R[h++]=f;f=m+a.xb;g-=q}return 0>=g?(e=a.A,e.Pa&-2147483648&&Ab(e),a.A.ea.Nb||a.status(Math.floor(c/1024)+"Kb "+Bb[d]+" at "+fa(b)),!0):zb(a,2,b,c)} -var qb,Cb={Cj:20,count:8,jn:1,type:3},Db=0,Eb;for(Eb in Cb){var Fb=Cb[Eb];Cb[Eb]={sg:(1<>>this.da;0>>a.da;0>>=a.da;0>>a.da;0>>this.da].Wb(a&this.B,a)}; l.ga=function(a){var b=a&this.B,c=(a&this.Fa)>>>this.da;return b!=this.B?this.R[c].Ae(b,a):this.R[c++].Wb(b,a)|this.R[c&this.C].Wb(0,a+1)<<8};function Pb(a,b){var c=b&a.B,d=(b&a.Fa)>>>a.da;return c!=a.B?a.R[d].hf(c,b):a.R[d++].Ed(c,b)|a.R[d&a.C].Ed(0,b+1)<<8}l.fa=function(a){var b=a&this.B,c=(a&this.Fa)>>>this.da;if(b=Se&&(this.Ea=this.pa=2);this.Z=a.scaleTimers||!1;this.Xa=a.rtcDate;this.Oa=!1;a.sound&&(this.La=this.qa=null,window&&(this.La=window.AudioContext|| -window.webkitAudioContext),this.La&&(this.qa=new this.La));this.reset(!0);t(this)}Ta(U);var Ci=5150.9,Se=5170,Bi={5150:5150,5160:5160,5170:Se,att6300:5160.101,mpc1600:5150.101,z150:5160.15,compaq:5150.102,other:Ci,deskpro386:5180},Ei="sw1",Ii="sw2",Ji={Yj:1,ONE:0,gn:64,en:128,Wm:192,lc:192,eg:6},Ki={fn:16,Sm:32,Xm:48,lc:48,eg:4},Gi=1,Hi=4,W={5150:[{},{}]};W[5150][0][Gi]={lc:192,Nc:{1:0,2:64,3:128,4:192},ed:"Number of Floppy Drives"};W[5150][0][3]={lc:2,Nc:{0:0,1:2},ed:"FPU"}; +window.webkitAudioContext),this.La&&(this.qa=new this.La));this.reset(!0);t(this)}Ta(U);var Ci=5150.9,Se=5170,Bi={5150:5150,5160:5160,5170:Se,att6300:5160.101,mpc1600:5150.101,z150:5160.15,compaq:5150.102,other:Ci,deskpro386:5180},Ei="sw1",Ii="sw2",Ji={Yj:1,ONE:0,hn:64,fn:128,Xm:192,lc:192,eg:6},Ki={gn:16,Sm:32,Ym:48,lc:48,eg:4},Gi=1,Hi=4,W={5150:[{},{}]};W[5150][0][Gi]={lc:192,Nc:{1:0,2:64,3:128,4:192},ed:"Number of Floppy Drives"};W[5150][0][3]={lc:2,Nc:{0:0,1:2},ed:"FPU"}; W[5150][0][Hi]={lc:48,Nc:{0:0,1:16,2:32,3:48,none:0,tv:16,color:32,cga:32,mda:48,mono:48,ega:0,vga:0},ed:"Monitor Type"};W[5150][0][5]={lc:12,Nc:{16:0,32:4,48:8,64:12},ed:"Base Memory (16Kb Increments)"};W[5150][1][6]={lc:31,Nc:{0:0,32:1,64:2,96:3,128:4,160:5,192:6,224:7,256:8,288:9,320:10,352:11,384:12,416:13,448:14,480:15,512:16,544:17,576:18},ed:"Expansion Memory (32Kb Increments)"};W[5160]=[{},{}];W[5160][0][Gi]=W[5150][0][Gi];W[5160][0][3]=W[5150][0][3];W[5160][0][Hi]=W[5150][0][Hi]; W[5160][0][5]={lc:12,Nc:{64:0,128:4,192:8,256:12},ed:"Base Memory (64Kb Increments)"};W[5160][1][6]=W[5150][1][6];W[5160.101]=[{},{}];W[5160.101][0][5]={lc:143,Nc:{128:1,256:130,512:8,640:141},ed:"Base Memory (128Kb Increments)"};W[5160.101][0][3]={lc:16,Nc:{0:0,1:16},ed:"FPU"};W[5160.101][1][2]={lc:1,Nc:{0:0,1:1},ed:"Floppy Type"};W[5160.101][1][Gi]=W[5150][0][Gi];W[5160.101][1][Hi]=W[5150][0][Hi];l=U.prototype; l.zb=function(a,b,c){switch(b){case Ei:return this.la[b]=c,Li(this,0,b),!0;case Ii:if(5150==(this.ca|0)||5160.101==this.ca)return this.la[b]=c,Li(this,1,b),!0;break;case "swdesc":return this.la[b]=c,!0}return!1}; @@ -414,7 +414,7 @@ b,this.za]);a.set(4,[this.Da,this.S,this.Ja,this.oa,this.ma]);this.ca>=Se&&(a.se l.restore=function(a){var b,c;b=a[0];Array.isArray(b[0])?this.D=b[0]:(this.D[0][0]=b[0],this.D[1][0]=b[1]&15,this.D[0][1]=b[2],this.D[1][1]=b[3]&15);Wi(this);b=a[1];for(c=0;c=f;f++){var g="pcjs-bitCell";f||(g+=" pcjs-bitCellLeft");d+='
'+f+"
\n"}e.innerHTML=d;mj(a,b,c,!0)}function nj(a,b,c){if(b=(a=W[a.ca|0])&&a[b])for(var d in b)if(a=b[d],a.lc&1<b&&-2!=b&&this.controller.Ba("Unable to restore disk '"+this.B+": "+c);return b}; l.toJSON=function(){var a;a=0;for(var b;b=km(this,a++);)sm(b);a=JSON.stringify(this.A,function(a,b){if("file"!=a)return b});a=a.replace(/,"length":512/gm,"").replace(/,"pattern":0/gm,"");a=a.replace(/"(sector|length|data|pattern)":/gm,"$1:");a=a.replace(/,"[^"]*":([0-9]+|true|false)/gm,"");a=a.replace(/(sector|length|data|pattern):/gm,'"$1":');return a=a.replace(/([\]}]),/gm,"$1,\n")}; function sm(a){var b=a.data,c=b.length;if(c<<2==a.length){for(var d=c-1,e=b[d],f=0;d--&&b[d]===e;)f++;f++&&(b.length=c-f,a.pattern=e)}}function tm(a){Ka.call(this,"FDC",a,tm);this.dmaRead=this.Tj;this.dmaWrite=this.Uj;this.dmaFormat=this.hk;this.K=a.autoMount||null;this.W=a.sortBy||"name";"none"==this.W&&(this.W=null);this.C=[];this.Y=!za("Mobi")&&window&&"FileReader"in window}Ta(tm);ba={}; -var um={3:{gd:3,wd:0,name:ba.dn},4:{gd:2,wd:1,name:ba.bn},5:{gd:9,wd:7,name:ba.hn},6:{gd:9,wd:7,name:ba.Ym},7:{gd:2,wd:0,name:ba.$m},8:{gd:1,wd:2,name:ba.cn},10:{gd:2,wd:7,name:ba.Zm},13:{gd:6,wd:7,name:ba.Vm},15:{gd:3,wd:0,name:ba.an}};l=tm.prototype; +var um={3:{gd:3,wd:0,name:ba.en},4:{gd:2,wd:1,name:ba.cn},5:{gd:9,wd:7,name:ba.jn},6:{gd:9,wd:7,name:ba.Zm},7:{gd:2,wd:0,name:ba.an},8:{gd:1,wd:2,name:ba.dn},10:{gd:2,wd:7,name:ba.$m},13:{gd:6,wd:7,name:ba.Wm},15:{gd:3,wd:0,name:ba.bn}};l=tm.prototype; l.zb=function(a,b,c){var d=this;switch(b){case "listDisks":this.la[b]=c;if(this.W){b=[];for(a=0;a'+b+"");a.innerHTML=b}};return!0;case "descDisk":case "listDrives":return this.la[b]=c,c.onchange=function(){var a=ea(c.value,10);null!=a&&vm(d,a)},!0;case "loadDrive":return this.la[b]=c,c.onclick=function(){var a=d.la.listDisks;a&&wm(d,a.options[a.selectedIndex].text,a.value)},!0;case "saveDrive":if(!this.Y){c.parentNode.removeChild(c);break}this.la[b]=c;c.onclick=function(){var a=d.la.listDrives;a&&a.options&&d.B&&((a=d.B[ea(a.value, 10)||0])?(a=a.ta)?(a=Aa(rm(a),"octet-stream",!0,a.th.replace(".json",".img")),r(a)):d.Ba("No diskette loaded in drive."):d.Ba("No diskette drive selected."))};return!0;case "mountDrive":if(this.Y)return this.la[b]=c,c.addEventListener("change",function(){var a=c.children[0];a.children[1].disabled=!a.children[0].files.length}),c.onsubmit=function(a){if(a=a.currentTarget[1].files[0]){var b=a.name;wm(d,ga(b,!0),b,a)}return!1},!0;c.parentNode.removeChild(c)}return!1}; diff --git a/modules/pdp11/lib/bus.js b/modules/pdp11/lib/bus.js index eca42c0b1..95ae13c45 100644 --- a/modules/pdp11/lib/bus.js +++ b/modules/pdp11/lib/bus.js @@ -277,7 +277,7 @@ BusPDP11.IOController = { } } if (b >= 0) { - if (DEBUGGER && this.dbg && this.dbg.messageEnabled(afn[BusPDP11.IOHANDLER.MSG_CATEGORY])) { + if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP11.BUS | afn[BusPDP11.IOHANDLER.MSG_CATEGORY])) { this.dbg.printMessage(afn[BusPDP11.IOHANDLER.NAME] + ".readByte(" + this.dbg.toStrBase(addr) + "): " + this.dbg.toStrBase(b), true, !bus.nDisableFaults); } return b; @@ -358,7 +358,7 @@ BusPDP11.IOController = { } } if (fWrite) { - if (DEBUGGER && this.dbg && this.dbg.messageEnabled(afn[BusPDP11.IOHANDLER.MSG_CATEGORY])) { + if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP11.BUS | afn[BusPDP11.IOHANDLER.MSG_CATEGORY])) { this.dbg.printMessage(afn[BusPDP11.IOHANDLER.NAME] + ".writeByte(" + this.dbg.toStrBase(addr) + "," + this.dbg.toStrBase(b) + ")", true, !bus.nDisableFaults); } return; @@ -397,7 +397,7 @@ BusPDP11.IOController = { } } if (w >= 0) { - if (DEBUGGER && this.dbg && this.dbg.messageEnabled(afn[BusPDP11.IOHANDLER.MSG_CATEGORY])) { + if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP11.BUS | afn[BusPDP11.IOHANDLER.MSG_CATEGORY])) { this.dbg.printMessage(afn[BusPDP11.IOHANDLER.NAME] + ".readWord(" + this.dbg.toStrBase(addr) + "): " + this.dbg.toStrBase(w), true, !bus.nDisableFaults); } return w; @@ -441,7 +441,7 @@ BusPDP11.IOController = { } } if (fWrite) { - if (DEBUGGER && this.dbg && this.dbg.messageEnabled(afn[BusPDP11.IOHANDLER.MSG_CATEGORY])) { + if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP11.BUS | afn[BusPDP11.IOHANDLER.MSG_CATEGORY])) { this.dbg.printMessage(afn[BusPDP11.IOHANDLER.NAME] + ".writeWord(" + this.dbg.toStrBase(addr) + "," + this.dbg.toStrBase(w) + ")", true, !bus.nDisableFaults); } return; @@ -1265,7 +1265,7 @@ BusPDP11.prototype.getMemorySize = function(type) }; /** - * addIOHandlers(start, end, fnReadByte, fnWriteByte, fnReadWord, fnWriteWord, msgCategory, sName) + * addIOHandlers(start, end, fnReadByte, fnWriteByte, fnReadWord, fnWriteWord, message, sName) * * Add I/O notification handlers to the master list (aIOHandlers). The start and end addresses are typically * relative to the starting IOPAGE address, but they can also be absolute; we simply mask all addresses with @@ -1285,11 +1285,11 @@ BusPDP11.prototype.getMemorySize = function(type) * @param {function(number,number)|null|undefined} fnWriteByte * @param {function(number)|null|undefined} fnReadWord * @param {function(number,number)|null|undefined} fnWriteWord - * @param {number} [msgCategory] + * @param {number} [message] * @param {string} [sName] * @return {boolean} (true if entire range successfully registered, false if any conflicts) */ -BusPDP11.prototype.addIOHandlers = function(start, end, fnReadByte, fnWriteByte, fnReadWord, fnWriteWord, msgCategory, sName) +BusPDP11.prototype.addIOHandlers = function(start, end, fnReadByte, fnWriteByte, fnReadWord, fnWriteWord, message, sName) { for (var addr = start; addr <= end; addr += 2) { var off = addr & BusPDP11.IOPAGE_MASK; @@ -1297,7 +1297,7 @@ BusPDP11.prototype.addIOHandlers = function(start, end, fnReadByte, fnWriteByte, Component.warning("I/O address already registered: " + str.toHexLong(addr)); return false; } - this.aIOHandlers[off] = [fnReadByte, fnWriteByte, fnReadWord, fnWriteWord, sName || "unknown", msgCategory, false]; + this.aIOHandlers[off] = [fnReadByte, fnWriteByte, fnReadWord, fnWriteWord, sName || "unknown", message || MessagesPDP11.BUS, false]; if (MAXDEBUG) this.log("addIOHandlers(" + str.toHexLong(addr) + ")"); } return true; @@ -1356,7 +1356,7 @@ BusPDP11.prototype.addIOTable = function(component, table) for (var iReg = 0; iReg < nRegs; iReg++, addr += 2) { if (sReg && nRegs > 1) sReg = afn[4] + iReg; - if (!this.addIOHandlers(addr, addr, fnReadByte, fnWriteByte, fnReadWord, fnWriteWord, afn[7] || component.bitsMessage || MessagesPDP11.BUS, sReg || component.idComponent)) { + if (!this.addIOHandlers(addr, addr, fnReadByte, fnWriteByte, fnReadWord, fnWriteWord, afn[7] || component.bitsMessage, sReg || component.idComponent)) { return false; } } diff --git a/modules/pdp11/lib/cpustate.js b/modules/pdp11/lib/cpustate.js index 4577e1943..8e8fd3695 100644 --- a/modules/pdp11/lib/cpustate.js +++ b/modules/pdp11/lib/cpustate.js @@ -111,6 +111,7 @@ Component.subclass(CPUStatePDP11, CPUPDP11); * @typedef {{ * vector: number, * priority: number, + * message: number, * next: (Trigger|null) * }} Trigger */ @@ -767,16 +768,17 @@ CPUStatePDP11.prototype.setSP = function(addr) }; /** - * addTrigger(vector, priority) + * addTrigger(vector, priority, message) * * @this {CPUStatePDP11} * @param {number} vector * @param {number} priority + * @param {number} [message] * @return {Trigger} */ -CPUStatePDP11.prototype.addTrigger = function(vector, priority) +CPUStatePDP11.prototype.addTrigger = function(vector, priority, message) { - var trigger = {vector: vector, priority: priority, next: null}; + var trigger = {vector: vector, priority: priority, message: message || 0, next: null}; if (DEBUG) this.aTriggers.push(trigger); return trigger; }; @@ -842,14 +844,34 @@ CPUStatePDP11.prototype.removeTrigger = function(trigger) CPUStatePDP11.prototype.setTrigger = function(trigger) { this.insertTrigger(trigger); + /* * See the writeXCSR() function for an explanation of why signalling an INTQ hardware interrupt condition * should be done using INTQ_DELAY rather than setting INTQ directly. */ this.opFlags |= PDP11.OPFLAG.INTQ_DELAY; + + if (trigger.message && this.messageEnabled(trigger.message | MessagesPDP11.INT)) { + this.printMessage("setInterrupt(vector=" + str.toOct(trigger.vector) + ",priority=" + trigger.priority + ")", true, true); + } return false; }; +/** + * clearTrigger(trigger) + * + * @this {CPUStatePDP11} + * @param {Trigger} trigger + */ +CPUStatePDP11.prototype.clearTrigger = function(trigger) +{ + this.removeTrigger(trigger); + + if (trigger.message && this.messageEnabled(trigger.message | MessagesPDP11.INT)) { + this.printMessage("clearInterrupt(vector=" + str.toOct(trigger.vector) + ",priority=" + trigger.priority + ")", true, true); + } +}; + /** * checkTriggers(priority) * diff --git a/modules/pdp11/lib/defines.js b/modules/pdp11/lib/defines.js index c61a5969d..72d07dd61 100644 --- a/modules/pdp11/lib/defines.js +++ b/modules/pdp11/lib/defines.js @@ -492,10 +492,10 @@ var PDP11 = { PPS: 0o177554, // PC11 Punch Status Register PPB: 0o177556, // PC11 Punch Buffer Register - RCSR: 0o177560, // Display Terminal: Receiver Status Register - RBUF: 0o177562, // Display Terminal: Receiver Data Buffer Register - XCSR: 0o177564, // Display Terminal: Transmitter Status Register - XBUF: 0o177566, // Display Terminal: Transmitter Data Buffer Register + RCSR: 0o177560, // DL11 Display Terminal: Receiver Status Register + RBUF: 0o177562, // DL11 Display Terminal: Receiver Data Buffer Register + XCSR: 0o177564, // DL11 Display Terminal: Transmitter Status Register + XBUF: 0o177566, // DL11 Display Terminal: Transmitter Data Buffer Register CNSW: 0o177570, // Console (Front Panel) Switch/Display Register diff --git a/modules/pdp11/lib/device.js b/modules/pdp11/lib/device.js index fa33c1b73..6d038e96e 100644 --- a/modules/pdp11/lib/device.js +++ b/modules/pdp11/lib/device.js @@ -90,7 +90,7 @@ DevicePDP11.prototype.initBus = function(cmp, bus, cpu, dbg) device.interruptKW11(); }); - this.kw11.trigger = cpu.addTrigger(PDP11.KW11.VEC, PDP11.KW11.PRI); + this.kw11.trigger = cpu.addTrigger(PDP11.KW11.VEC, PDP11.KW11.PRI, MessagesPDP11.KW11); bus.addIOTable(this, DevicePDP11.UNIBUS_IOTABLE); bus.addResetHandler(this.reset.bind(this)); diff --git a/modules/pdp11/lib/messages.js b/modules/pdp11/lib/messages.js index 080177085..94659475a 100644 --- a/modules/pdp11/lib/messages.js +++ b/modules/pdp11/lib/messages.js @@ -34,23 +34,30 @@ var MessagesPDP11 = { CPU: 0x00000001, - TRAP: 0x00000010, - FAULT: 0x00000020, - BUS: 0x00000040, - MEMORY: 0x00000080, - MMU: 0x00000100, - ROM: 0x00000200, - DEVICE: 0x00000400, - PANEL: 0x00000800, - KEYBOARD: 0x00010000, - KEYS: 0x00020000, - PAPER: 0x00100000, - DISK: 0x00200000, - RK11: 0x00400000, - RL11: 0x00800000, - SERIAL: 0x01000000, - SPEAKER: 0x02000000, - COMPUTER: 0x04000000, + TRAP: 0x00000002, + FAULT: 0x00000004, + INT: 0x00000008, + BUS: 0x00000010, + MEMORY: 0x00000020, + MMU: 0x00000040, + ROM: 0x00000080, + DEVICE: 0x00000100, + PANEL: 0x00000200, + KEYBOARD: 0x00000400, + KEYS: 0x00000800, + PC11: 0x00001000, + PAPER: 0x00001000, + DISK: 0x00002000, + READ: 0x00004000, + WRITE: 0x00008000, + RK11: 0x00010000, + RL11: 0x00020000, + DL11: 0x00040000, + SERIAL: 0x00040000, + KW11: 0x00080000, + TIMER: 0x00080000, + SPEAKER: 0x01000000, + COMPUTER: 0x02000000, LOG: 0x10000000, WARN: 0x20000000, BUFFER: 0x40000000, @@ -75,6 +82,7 @@ MessagesPDP11.CATEGORIES = { "cpu": MessagesPDP11.CPU, "trap": MessagesPDP11.TRAP, "fault": MessagesPDP11.FAULT, + "int": MessagesPDP11.INT, "bus": MessagesPDP11.BUS, "memory": MessagesPDP11.MEMORY, "mmu": MessagesPDP11.MMU, @@ -83,11 +91,17 @@ MessagesPDP11.CATEGORIES = { "panel": MessagesPDP11.PANEL, "keyboard": MessagesPDP11.KEYBOARD, // "kbd" is also allowed as shorthand for "keyboard"; see doMessages() "key": MessagesPDP11.KEYS, // using "key" instead of "keys", since the latter is a method on JavasScript objects + "pc11": MessagesPDP11.PC11, "paper": MessagesPDP11.PAPER, "disk": MessagesPDP11.DISK, + "read": MessagesPDP11.READ, + "write": MessagesPDP11.WRITE, "rk11": MessagesPDP11.RK11, "rl11": MessagesPDP11.RL11, + "dl11": MessagesPDP11.DL11, "serial": MessagesPDP11.SERIAL, + "kw11": MessagesPDP11.KW11, + "timer": MessagesPDP11.TIMER, "speaker": MessagesPDP11.SPEAKER, "computer": MessagesPDP11.COMPUTER, "log": MessagesPDP11.LOG, diff --git a/modules/pdp11/lib/pc11.js b/modules/pdp11/lib/pc11.js index 53c761153..2079b0676 100644 --- a/modules/pdp11/lib/pc11.js +++ b/modules/pdp11/lib/pc11.js @@ -280,7 +280,7 @@ PC11.prototype.initBus = function(cmp, bus, cpu, dbg) } } - this.triggerReaderInterrupt = this.cpu.addTrigger(PDP11.PC11.RVEC, PDP11.PC11.PRI); + this.triggerReaderInterrupt = this.cpu.addTrigger(PDP11.PC11.RVEC, PDP11.PC11.PRI, MessagesPDP11.PC11); this.timerReaderAdvance = this.cpu.addTimer(function readyReader() { pc11.advanceReader(); diff --git a/modules/pdp11/lib/rk11.js b/modules/pdp11/lib/rk11.js index 097835138..fd2336930 100644 --- a/modules/pdp11/lib/rk11.js +++ b/modules/pdp11/lib/rk11.js @@ -290,7 +290,7 @@ RK11.prototype.initBus = function(cmp, bus, cpu, dbg) */ this.initController(); - this.triggerInterrupt = this.cpu.addTrigger(PDP11.RK11.VEC, PDP11.RK11.PRI); + this.triggerInterrupt = this.cpu.addTrigger(PDP11.RK11.VEC, PDP11.RK11.PRI, MessagesPDP11.RK11); bus.addIOTable(this, RK11.UNIBUS_IOTABLE); bus.addResetHandler(this.reset.bind(this)); @@ -931,6 +931,10 @@ RK11.prototype.processCommand = function() } addr = (((this.csr & PDP11.RK11.RKCS.MEX)) << (16 - PDP11.RK11.RKCS.SHIFT.MEX)) | this.bar; nWords = (0x10000 - this.wcr) & 0xffff; + if (DEBUG && this.messageEnabled(MessagesPDP11.READ)) { + var pos = ((((iCylinder << 1) + iHead) * drive.nSectors) + iSector) * 256; + this.printMessage((fnReadWrite == this.readData? "readData" : "writeData") + "(pos=" + pos + ",addr=" + str.toOct(addr) + ",bytes=" + (nWords * 2) + ")", true, true); + } fInterrupt = fnReadWrite.call(this, drive, iCylinder, iHead, iSector, nWords, addr, this.endReadWrite.bind(this)); break; @@ -952,8 +956,6 @@ RK11.prototype.processCommand = function() } }; - - /** * endReadWrite(err, iCylinder, iHead, iSector, nWords, addr) * @@ -1002,6 +1004,7 @@ RK11.prototype.readData = function(drive, iCylinder, iHead, iSector, nWords, add nWords = 0; } + var sWords = ""; while (nWords--) { if (!sector) { sector = drive.disk.seek(iCylinder, iHead, iSector + 1); @@ -1011,12 +1014,16 @@ RK11.prototype.readData = function(drive, iCylinder, iHead, iSector, nWords, add } ibSector = 0; } - var b0, b1; + var b0, b1, data; if ((b0 = drive.disk.read(sector, ibSector++)) < 0 || (b1 = drive.disk.read(sector, ibSector++)) < 0) { err = PDP11.RK11.RKER.NXS; break; } - var data = this.bus.setWordDirect(addr, b0 | (b1 << 8)); + this.bus.setWordDirect(addr, data = b0 | (b1 << 8)); + if (DEBUG && this.messageEnabled(MessagesPDP11.READ) && sWords.length < 56) { + sWords += str.toOct(data) + ' '; + if (sWords.length >= 56) this.printMessage(sWords + '\n', true); + } if (this.bus.checkFault()) { err = PDP11.RK11.RKER.NXM; break; diff --git a/modules/pdp11/lib/rl11.js b/modules/pdp11/lib/rl11.js index 57498f5e0..a78ae03e0 100644 --- a/modules/pdp11/lib/rl11.js +++ b/modules/pdp11/lib/rl11.js @@ -290,7 +290,7 @@ RL11.prototype.initBus = function(cmp, bus, cpu, dbg) */ this.initController(); - this.triggerInterrupt = this.cpu.addTrigger(PDP11.RL11.VEC, PDP11.RL11.PRI); + this.triggerInterrupt = this.cpu.addTrigger(PDP11.RL11.VEC, PDP11.RL11.PRI, MessagesPDP11.RL11); bus.addIOTable(this, RL11.UNIBUS_IOTABLE); bus.addResetHandler(this.reset.bind(this)); diff --git a/modules/pdp11/lib/serialport.js b/modules/pdp11/lib/serialport.js index 9d1059cd8..2bcee3518 100644 --- a/modules/pdp11/lib/serialport.js +++ b/modules/pdp11/lib/serialport.js @@ -36,6 +36,7 @@ if (NODE) { var str = require("../../shared/lib/strlib"); var web = require("../../shared/lib/weblib"); var Component = require("../../shared/lib/component"); + var Keys = require("../../shared/lib/keys"); var State = require("../../shared/lib/state"); var PDP11 = require("./defines"); var MessagesPDP11 = require("./messages"); @@ -195,26 +196,24 @@ SerialPortPDP11.prototype.setBinding = function(sType, sBinding, control, sValue this.bindings[sBinding] = this.controlIOBuffer = control; /* - * By establishing an onkeypress handler here, we make it possible for DOS commands like - * "CTTY COM1" to more or less work (use "CTTY CON" to restore control to the DOS console). + * An onkeydown handler is required for certain keys that browsers tend to consume themselves; + * for example, BACKSPACE is often defined as going back to the previous web page, and certain + * CTRL keys are often used for browser shortcuts (usually on Windows-based browsers). */ control.onkeydown = function onKeyDown(event) { - /* - * This is required in addition to onkeypress, because it's the only way to prevent - * BACKSPACE (keyCode 8) from being interpreted by the browser as a "Back" operation; - * moreover, not all browsers generate an onkeypress notification for BACKSPACE. - * - * A related problem exists for Ctrl-key combinations in most Windows-based browsers - * (eg, IE, Edge, Chrome for Windows, etc), because keys like Ctrl-C and Ctrl-S have - * special meanings (eg, Copy, Save). To the extent the browser will allow it, we - * attempt to disable that default behavior when this control receives an onkeydown - * event for one of those keys (probably the only event the browser generates for them). - */ event = event || window.event; + var fProcess = false; var keyCode = event.keyCode; - if (keyCode === 0x08 || event.ctrlKey && keyCode >= 0x41 && keyCode <= 0x5A) { + if (keyCode == Keys.KEYCODE.BS) { + fProcess = true; + keyCode = Keys.ASCII.DEL; + } + else if (event.ctrlKey && keyCode >= Keys.ASCII.A && keyCode <= Keys.ASCII.Z) { + fProcess = true; + keyCode -= (Keys.ASCII.A - Keys.ASCII.CTRL_A); + } + if (fProcess) { if (event.preventDefault) event.preventDefault(); - if (keyCode > 0x40) keyCode -= 0x40; serial.receiveData(keyCode); } return true; @@ -285,7 +284,7 @@ SerialPortPDP11.prototype.initBus = function(cmp, bus, cpu, dbg) var serial = this; - this.triggerReceiveInterrupt = this.cpu.addTrigger(PDP11.DL11.RVEC, PDP11.DL11.PRI); + this.triggerReceiveInterrupt = this.cpu.addTrigger(PDP11.DL11.RVEC, PDP11.DL11.PRI, MessagesPDP11.DL11); this.timerReceiveInterrupt = this.cpu.addTimer(function readyReceiver() { if (!(serial.rcsr & PDP11.DL11.RCSR.RD)) { @@ -315,7 +314,7 @@ SerialPortPDP11.prototype.initBus = function(cmp, bus, cpu, dbg) } }); - this.triggerTransmitInterrupt = this.cpu.addTrigger(PDP11.DL11.XVEC, PDP11.DL11.PRI); + this.triggerTransmitInterrupt = this.cpu.addTrigger(PDP11.DL11.XVEC, PDP11.DL11.PRI, MessagesPDP11.DL11); this.timerTransmitInterrupt = this.cpu.addTimer(function readyTransmitter() { serial.xcsr |= PDP11.DL11.XCSR.READY; @@ -584,7 +583,15 @@ SerialPortPDP11.prototype.transmitByte = function(b) */ if (this.iLogicalCol > 0) this.iLogicalCol--; } - else { + else if (b) { + /* + * RT-11 outputs lots of NULL characters, at least after a "D 56=5015" (0x0A0D) command has + * been issued, hence the "if (b)" check above. + * + * TODO: Also consider a check for Keys.ASCII.CTRL_C, because by default, RT-11 outputs "raw" + * CTRL_C characters, which we capture below and render as . RT-11 does this for other keys + * as well, such as CTRL_K () and CTRL_L (). + */ var s = str.toASCIICode(b); // formerly: String.fromCharCode(b); var nChars = s.length; // formerly: (b >= 0x20? 1 : 0); if (b < 0x20 && nChars == 1) nChars = 0; @@ -698,7 +705,7 @@ SerialPortPDP11.prototype.writeXCSR = function(data, addr) if (data & PDP11.DL11.XCSR.TIE) { this.cpu.setTrigger(this.triggerTransmitInterrupt); } else { - this.cpu.removeTrigger(this.triggerTransmitInterrupt); + this.cpu.clearTrigger(this.triggerTransmitInterrupt); } } this.xcsr = (this.xcsr & ~PDP11.DL11.XCSR.WMASK) | (data & PDP11.DL11.XCSR.WMASK); @@ -726,16 +733,14 @@ SerialPortPDP11.prototype.readXBUF = function(addr) SerialPortPDP11.prototype.writeXBUF = function(data, addr) { data &= PDP11.DL11.XBUF.DATA; - if (data) { - this.transmitByte(data); - this.xcsr &= ~PDP11.DL11.XCSR.READY; - /* - * NOTE: When debugging issues involving the SerialPort, such as debugging code between a pair of - * transmitted bytes, you can pass 0 instead of getBaudTimeout() to setTimer() to minimize the amount - * of time spent waiting for XCSR.READY to be set again. - */ - this.cpu.setTimer(this.timerTransmitInterrupt, this.getBaudTimeout(this.nBaudTransmit)); - } + this.transmitByte(data); + this.xcsr &= ~PDP11.DL11.XCSR.READY; + /* + * NOTE: When debugging issues involving the SerialPort, such as debugging code between a pair of + * transmitted bytes, you can pass 0 instead of getBaudTimeout() to setTimer() to minimize the amount + * of time spent waiting for XCSR.READY to be set again. + */ + this.cpu.setTimer(this.timerTransmitInterrupt, this.getBaudTimeout(this.nBaudTransmit)); }; /* diff --git a/modules/shared/lib/keys.js b/modules/shared/lib/keys.js index ddf95d8c4..ca9921917 100644 --- a/modules/shared/lib/keys.js +++ b/modules/shared/lib/keys.js @@ -49,7 +49,7 @@ var Keys = { '`': 96, a: 97, b: 98, c: 99, d: 100, e: 101, f: 102, g: 103, h: 104, i: 105, j: 106, k: 107, l: 108, m: 109, n: 110, o: 111, p: 112, q: 113, r: 114, s: 115, t: 116, u: 117, v: 118, w: 119, - x: 120, y: 121, z: 122, '{':123, '|':124, '}':125, '~':126 + x: 120, y: 121, z: 122, '{':123, '|':124, '}':125, '~':126, DEL: 127 }, /* * Browser keyCodes we must pay particular attention to. For the most part, these are non-alphanumeric @@ -62,10 +62,10 @@ var Keys = { * them using ASCII codes (eg, the LEFT arrow key uses the ASCII code for '%' or 37). */ KEYCODE: { - /* 0x08 */ BS: 8, + /* 0x08 */ BS: 8, // BACKSPACE /* 0x09 */ TAB: 9, - /* 0x0A */ LF: 10, // TODO: Determine if any key actually generates this - /* 0x0D */ CR: 13, + /* 0x0A */ LF: 10, // LINE FEED (TODO: Determine if any key actually generates this) + /* 0x0D */ CR: 13, // CARRIAGE RETURN /* 0x10 */ SHIFT: 16, /* 0x11 */ CTRL: 17, /* 0x12 */ ALT: 18,