From d09f917eb7a68c3961787b8fb30ba343375efb00 Mon Sep 17 00:00:00 2001 From: Eric Rangell Date: Sun, 29 Jul 2018 09:44:35 -0400 Subject: [PATCH] Release 1.0.2 --- .DS_Store | Bin 12292 -> 12292 bytes DSK/ANN0TEST.DSK | Bin 143360 -> 143360 bytes DSK/README.md | 116 ++- SRC/.DS_Store | Bin 8196 -> 8196 bytes .../UserInterfaceState.xcuserstate | Bin 22689 -> 39226 bytes SRC/A2NoSlotMidi/MIDIDRVR.OBJ | Bin 744 -> 601 bytes SRC/A2NoSlotMidi/MIDIDRVR.OBJ.dsk | Bin 143360 -> 143360 bytes SRC/A2NoSlotMidi/MIDIDRVR.OBJ.map | 4 +- SRC/A2NoSlotMidi/Makefile | 5 +- SRC/A2NoSlotMidi/main.lst | 740 ++++++++---------- SRC/A2NoSlotMidi/main.o | Bin 6713 -> 5353 bytes SRC/A2NoSlotMidi/main.s | 206 ++--- SRC/A2NoSlotMidi/make/V2Make.scpt | Bin 5030 -> 4802 bytes 13 files changed, 544 insertions(+), 527 deletions(-) diff --git a/.DS_Store b/.DS_Store index f8a4d98381f74ed00c93db78feb70664dc5d18b0..e7c2e0a4012540669486e3db44478cb82311edf5 100644 GIT binary patch delta 1351 zcmeIwPe{{Y7zgm@i*xKzv)_ig-{z(>txa2mKW)y;DDY1aC6#}|4s+^H7_Hg*O{Iji z+)d5uy<~KWuzw!yW1WxEt51YNznFYog_ybpZ%CVP@S zcY-D-=c>&GEv+F%88Y+(dNiDf4C_tdgl>p0<$Eh_!x4R??N}l*7&AKcKOUsq%te(rYR5L27)bA21;wMNm-;7u?tYAF8kserZvMdTdR5w4^=u;~+ZF zDOGyVi+<=Bz#!r^6n`#pi+Z$S)s Tonq3ROf7q7|7}t%+burGjg&S56|-sGRW-_A(aNY_+_ zMPV80PCIKjsQ2_o_UmUg{?${@Yb@C=TSC{8P0_gCABnYTr(@#u)cVO>{Fpt+7c9A8 z{9UfUi503oSqVw4F%dAkDs#2MHn3t@iOH>fdZgE^sGC@+r1Z)M!l7<0oGJy_7D?GH zwik7 zOEz4_7;fP%9^w(EFpX!%DeH_ZyxhXe`=4HL>%ywfT_yHOciu2lRtPV7){&z+%gUKs zNfR`Z`MI@%F~uV6Qr*fb(X|StRJSfqbV-&aPi;}^U&u=`P10j}E{NvnJ$)2B-)I2@ zD^{Z2fqWFe11}0u0zb-7j)0Jly>o%nMYj&y0wv|;vBNAiK(s(E+9@I-b zSiwSImJO7>coBuDg-TE2MLhU(QNcs61ffH4$dai09+3tA}3%=fh6Gv*p?D@uRrk= z=gVwaeo;edZraZ(VYXarY|gS;u6}Tn1&7%}CBPP5tOi)2=3d&UyozCPuzDH=9lT*~C9hbXz-xz6Rzherv&B%2kdt z;|R0m+u9<>8Z&HW+-HVi86nGvSjH6#AOf)JXD7CQ5$xC*WTD)p5p7&ZmQQ?BhI&yxmIGf5~G#qtt4*z zeYq~)*{TQ;Y2|7k@pt6~E0BVtQAA6UIU%WwE06m~Z#mmx1t9lcXk5ig-3m+%0)-UA zU0QVM9sfxIb{=_G%M6)-BQ$$mnD-V0iUCSQg}5?Mjl2tpT9!Gg?piwsZ3Tij5E$&aF&iH{RTQ?jfcH67bEtDTed%0CJL1|*G}K-;j2Y42p3`uVhG|7 z#8-%I(Eq9FwZcl<>Bl3sx?zpsP%+bx^HCHdSpxwp49FuB*BZxvAWD9D3! z%*7WhIHW=j6%n16@MQtA>Qfc6=2Kvo$*6|$n;yHrS zXg8i&9kwY=X-yNF#xZ|QOFVaxk~RWG~xy8ygIng!~E|a#_XjEH#$ou Je`Xp-{{hENutWd= diff --git a/DSK/README.md b/DSK/README.md index b52f890..a628674 100644 --- a/DSK/README.md +++ b/DSK/README.md @@ -11,4 +11,118 @@ Each MIDI file should have a type of $D7 and a suffix of .MID The program "CHANGETYPE" can be used to change the type of a file. -2018-JUL-26: Tested MIDIDRVR.OBJ on real hardware - the code to change the Annunciator works. The Negative Logic does not work yet. + +TEST PLAN: + + +GIVEN wiring has 2 inverters (positive logic), and MIDI OUT circuit is hooked up to AN0 + +WHEN you boot the DSK and select option 1 (Test MIDI OUT) + +THEN chord plays on a connected MIDI instrument + + +GIVEN 9018:02 + +WHEN 9000G + +THEN BRK is hit, displays address 9026 + +WHEN 9003G + +THEN BRK is hit, displays address 90A2 + + +GIVEN 9018:01, and wiring has 1 inverter (negative logic) and MIDI OUT circuit is hooked up to AN0 + +WHEN 900EG + +THEN plays a chord on the connected MIDI Instrument + + +GIVEN negative logic MIDI OUT circuit + +WHEN + +LOAD TESTCHORD + +15 POKE 9*4096+16+8,1 : CALL 9*4096 + +RUN + +THEN chord plays on connected MIDI instrument + + +GIVEN midi out circuit is connected to AN1 + +WHEN + +9017:01 + +9014G + +900EG N 9011G + +THEN short duration chord plays on connected MIDI instrument + + +GIVEN midi out circuit is connected to AN2 + +WHEN + +9017:02 + +9014G + +900EG N 9011G + +THEN short duration chord plays on connected MIDI instrument + + +GIVEN midi out circuit is connected to AN3 + +WHEN + +9017:03 + +9014G + +900EG N 9011G + +THEN short duration chord plays on connected MIDI instrument + + +GIVEN midi out circuit can play a chord + +WHEN + +900EG N 900BG + +THEN very short duration chord plays on connected MIDI instrument (due to all sounds off message) + + +GIVEN midi out circuit can play a chord, and driver is loaded at $9000 + +WHEN you enter the following Applesoft BASIC program and run it + +10 P=36868: M=36867 : REM P=ADDRESS TO POKE MIDI BYTE, M=CALL TO MIDI OUT DRIVER + +20 FOR N = 60 TO 72 : REM NOTE NUMBERS FOR MIDDLE C THRU ONE OCTAVE ABOVE MIDDLE C + +30 POKE P,144: CALL M: REM 144 (0X90) IS THE MIDI MESSAGE FOR NOTE ON + +40 POKE P,N: CALL M: REM FIRST DATABYTE OF NOTE ON MESSAGE IS NOTE NUMBER + +50 POKE P,64: CALL M: REM SECOND DATABYTE IS VELOCITY OF KEYPRESS (0=127) + +60 FOR DE=1 TO 250: NEXT : REM DELAY LOOP + +70 POKE P,N : CALL M : REM USING RUNNING STATUS - MESSAGE IS STILL NOTE ON, BUT NEW DATABYTES + +80 POKE P,0: CALL M : REM VELOCITY OF 0 TURNS A NOTE OFF + +90 NEXT N: REM REPEAT FOR EACH NOTE IN CHROMATIC SCALE + + +THEN you hear a chromatic scale played on your MIDI instrument. + diff --git a/SRC/.DS_Store b/SRC/.DS_Store index 60d726d572920c64b53a6afe740494b94a595a8b..faea55d54bb1a0e3042d4abf901b9c6eb9e5244c 100644 GIT binary patch delta 1283 zcmcJMO>9h27>2*sPu(wQPiOQ@ds|G5>Xh+Us?|~>+7eWej#7e|xfeIaO!ZEuSQwV9``!0F=X~FJpWa|^u)h_2 zb@gBY*!d#L9KRUIn;Y;})l@sTL2(&nXGgy^=-wPq}wv{Ghc zIBD9>TX##PD`lBIt({3L5x3WwUAFo%Um8=SPxSexSJl)9hsNd?2zIe^uW)8MQ%jF5 z(S%Q1-yN}bcU#H5Ln6OmY-yR~O@=zQC1F_GEYlD-G|oESGATD^oF!eRdK;RSl_!@= zZnLd@rU?I7SUHusZKoACgw46FGiI_3#ljIYCJa{FR;WgE=CW*0JP9TcTF_0SRO zqoZ_!&e0{hN`rKV?$UjFK#%AtJ)`IJf?m@H`b=Nx8wiXdNO<5yIV#{sC8|(^`KUuZ z8nGNJ(SlWI#}4`BZVFuz%jT7a2yU!;WW$9#=HM=MT)DS08jXjSHoDe0$2Wtw_ua^;kx7$A+*SHRFaA-yTv~n|riE z1Xzq3lAhuc-K$U1R7yh2{&Klq!3v~6&MnucX_^?8^JeI?Sg{ksbKV@T))XZ%GUwKE z9V?DvL^@|LHn1L-^QB$Pr3eWtn#1ddiguY=O;J- delta 1216 zcmb`EOH30{6o$|517=1Zw*}gZbf8iR4T6gDP(*FQLktoOp@Kp*g&B1sl*g2piK(yX zhVXDSCK@$SH;Nl2Y}CZKQ4);_u?uzK#-IybxY5Lg(c9LrQ8(x;X6`xvy>o89@3il< zZ=w;>-Q5pTAz8%^m*r)X37ZPt#ibjqM{J+9&6b_0tl%|SwTkuFmSL?(Z}74KQ*Y9{ z0wH5iuMUKClR=(J%2=7>@fK|;-{OlTr=&8)u2`RJ>%uH0HQC|hymg?%=o>IXBg`X7 zk!Ux|#g%qVoNwsSjDv=*u^CB@C2kkzZPBEvUl(sp9EklgkLSxQAT^uDQ9a%%Pzq&c z%FRcNpcd=!bxN_sG}+%3=+L_&$@StYyhJIJSiRgbsP~&jPcXjGu2e{JYiCb)w;l|c zvALC7Io}_hyDMOZ8hiDixYO*f;oQZodAmC-lSG-cmV8u4?W9vLjnF8K(KubEn{vVH@ALx%K!F2JaI8WuRwEAu*oYF8p&XT{K`rXA6OCxa zUbLYd8oCig4~B696F6swh4Z+AtGI?+xQ%H%v@WLY6OPpCl$r%c`G0csIw?xgW=~7c z$oAx~SzlVQ-8!D`4=bu);M0fwLxvVQyfOsv29%>mhOrxVqXNfix%2FiL$sMX& z&6NZc7B7`NRhEUfc$TLYND^BT5xz4Ei&TXz6}IG9S-e3}*>WL9ij`&Mio%u&b0Q6k z-CHU}oFE*{g84VWd^u7D?@YL$ zA{+Ve3gT-}6eGSF71&yZY5{%+cB2W+@M8}SAb?JRUKi+l(GL?L979+rIEhmj#Tdqg zj7eO=4a?>@lknoKxSYd+jaxI09NE0^#A;sXeEF?Y>dXb3?2Ak%@~_Lni$L~2iG>$| V?4O9mJuX4~OP1R)v`Bz+KLPUk55E8a diff --git a/SRC/A2NoSlotMidi.xcodeproj/project.xcworkspace/xcuserdata/ericrangell.xcuserdatad/UserInterfaceState.xcuserstate b/SRC/A2NoSlotMidi.xcodeproj/project.xcworkspace/xcuserdata/ericrangell.xcuserdatad/UserInterfaceState.xcuserstate index 97d0fb8fe8a6da44e2d5e0e440cf59ec2564e05a..e29c4e9f0056242d21213be85d3e8ead751187ae 100644 GIT binary patch delta 20758 zcmeHvcU)7~-|#)>Ze;`rGeFq52nmFZ$dV1R_X-doih_W9>^Gb&I&$y0z9; zt5w^&w{=vlqt$BFYVEG=du{@X+TZ&;&*%Mop1)orB)MmO_d4g$z6I>w3TN9={Ez(O zIgY*b@D{-m9AQh?5%z=w(TnI!^db5Z{RlroK?D$CL^zQ~q!Ss$AR?28S1c5*efsfDU>FJe!$g<_lVJ|bg?TU^mclAn4~M~4 zI0BA?diWNc1>c6V;T-r5d>1Z(`lWCgTm{#`jc_YG2oJ%};TP~rco-gmN8t&04xWcM z;7xc7-iF`8@8BJH7e0l5!oNs@1SBLGk|o_q57LwLBE3l;(wFQ-_9pv~eaU{LA2FF! zl7VC}8A-;HX=FN?K^BrlWHDJoYROu%jvPgf){|q%vE(>%JUM|B$ahEsIhUMA&LU%-HMxoWh&(_ZBoC3FlNZRZ$cyA9@-lga{F=N;-Xgyz?~zZ*pUGb+f&vsv z^`y)wYs!IgrM##)D7w;b&I-9eM>!{9#W5} zAF0RGuhehU-!!Bdx(D5pwxn%nDeXqP(;l>f_NSG!iVmPd=`eZ#9ZzS_g>)%hMc2{8 z>1I7Wo}NHYqTit3q7C!{dNIA6UO}&-*V7-+8|lyKFX%7n!}JmQD1D4RPM@Gp(x>Rl z^cDJR`YL^gzEA%^|42Wkf2Mz-|DvBUfMFSq;Ta1?$~Z7Cj4LB&yqVsNg7IgROehn{ z^k-t2SSFLnVzQYWCYRCYG5Jg>Q^r&=4a`tx7}Ll!F~ga0%y?!3gP1p%Y0PwH4)YFU zVCFLOm_^Jo=6&V^W+StS+01NVwlcezkC?s8m&{@22y>J<##~^&VlFaYGdGx<%q`|V z^8@pMdCc;xIcvdMvo@?f>%cm*F04E2!TPYidbTgyk5#fNHi!*o!`TQnoy}kev6*ZZ zo6Y91xojz0#x}A|>~OZ3ZDCv45$s5IBCBTw7O@6)E<2B%&n{r!Wf!uG*u`uIyNX@S zu3^`*>)74w$LuHU9(FJLDZ7u|&wj=pV2`rL*yHSV_8ayFdy~Dz>Tk2(vfr@}*+=Y; z>|^!`M{zXAa4g4hJlBKk$(eEHoCRmc*>etDAFeOgkMrXcoIj`JR9pZT&P8yMTz@W# z8^C38*<22n%jI$TTme_eRdO1ximT>oxRKl_ZZtQB8_SL3#&Z+6Dcn@<4Q?8@h+C}Z zmT*hCW!!RZ1=r54T}!J{c@995qM4vzgCpHbZ^LqYkDg}c7M2dKayOrTehQV^gmHz$ zIZ){q7#8Ff7OZqrhpOC^_@z>-m2P25rCWtWhFe2S4?>jzueN%{hpA#i;)8?y0z*Rs z{L~5RFu&Nq&=|j1Ww0tHCNMrOHcXXoUXhU#u2SU>)#!#PS`0Vo06$y%|481JcB#O( z+X?1^)mcX;Ynii);S)whV|oZ?h9``ga`*7`GGsDRkMfM1oa$z+c37HbOyh{wm7d;( z899TDtUBx4%er@;zJ@q)JkPPx3B=iGS*Io5uGsM zjJt=w5>Hs58&=aes&hhrZ~QnQurwnlURT|!YaFI&9PlvAg<`JVG8LPmm|cQ{-v#EO`z)u#4DvT_vxR-(dH3 zn=t-^!1PX(biQ}Kk#_|1GejVvCW46IVyrNRTt;GO=pmtlFpi-H)WdO51QAF0t|cOg z{zMcpfQTkyh*&`)SP9mGjUW|l1-rFGJQn=~B9TZUl8F?-9t-_U!5};oh6}xfnzH2h zfdgxFt&Pnw&03A&X^(deS9&i3*|;uatscHH4O^#fs)Ggy7YB;a8n7Nti6ETXBO?!g8^&8J1hm_o|Rc za_SpL#cQiZ)YWN?K%665h*n|*R>_gXC}K1*#?ad})h!US-9rezK#U{C&3VbgYP6#T zUyM!fP6ae^XF0LLaNki*uO!+rSMVo&*AyM%6hdEdL}^SwMq^GxV{5vuM%UH8&e-nv zTDxi94~UIewPTu_HDgv19}uBuiOm?SEyPx08!@V+rm=d&Pz+mMc3M%ZZm71URWr0n zPzox6FzoBq$eZT)kl1DLce1C5k1%NdPIjG-KPEmg=$!gd#2)-u=hV0V%Vhl&6Lu1g zq(>1`1U066kU*RvM00+SnBPu}#(YqirvH*STp{r_JeGT!Wi-}kR}x2v(9Q?u;saB! zW5jX8L%A0b#N!KYnt#3PVS_o|?&I)1J7#G?2M-yKWm&C^xh46ObvJfHE zvJN(H`$P%)JLX27w{!|2of^GZy zQ9$q9i5Bn#K7@27wrAc#j*z<&_<~+So{%pT@ZPH^?QYn;}RLL}HBvvKRA4GuxLa9(D zl)s`%Ce7&*{cft!`3Q)XV~J4lnl`*7_a+IikQlr@{PiH0=n3+OQJ{d>Dtf^xO^db! zzc*_eG_AUkS}eNNg3^RzF(}E)$idpO5)>1mre|fKyh37=k&`~6Ra4cVec_rqK$%Da z6JC{Al7L326%-W`+i~NtyHgrHpDHdmw4Ym$N;P3Z7caD6FyXrj)Pg!t4|GDkpc4iQ zLso$ypaHXUn9v}!VDto`rZ7!g+nTS_jxy|#IV2RDykt5Sq@rwHUA?iTYt9j1tT^XL zFba$YV}zl?FriUsS|u8DFaaA`(Tq2Xrq#eWkMiM6Fi$lyxNC~(;7zPhV204z4rU4? za93w<$51dE7*>Kg;2mM4FkZk$%cv$`9$1L=3(N-#z`MdIVYD!&11usuz!G6BUS%BC zuc6)wgPDt?9;^cEUhBG^NCxi-6EIj4g@PB@ct($jHp-KU@|(dH93phm-Du)Ez-E(? zGeNNp><~fTE}(WSY1mO!NUY)-hqW{|XcKe|t=i`F#(p*0E|_zm}0_M4-SbKe-6G7rV7(vV0;9ecnyt{7~|8z8yMqh7>(yn(lc84#)wAO z$``=p*T!DKW3LJ`@YpxSAl4F(Hu^Vxr-Sp1Zr=RTBsalr5n3aEz7^gQYD`SLD?-%J9s7zsd!VPtZ#=6!sZt(jc~Zw&?IbWH$sg0Vu_O!O)ECkEklxrYU;Z5 zAC82hpTjdo*!BXR@o>URh5-t2D&e~tA~*?7hHY?)utP8G6h0Jo2_LP7Z@_7AIu7sO z6m|=r2z!LR!oL5$G&o@1i?qwo4Ao|8TCs^5mebmdDf(}M(hqm;R0YExbB`|L3k`7I zb42C~AHP6kAzWla#FS>4mn_up_ z4PyJc7H)?-;7<4<+yy^^yM+V7LE(__x$uSXrEqvH;eqYRUi=e-y;3r^L>9sk{IeGO zCZkGuimGAM<>w|q4E#ka(9)#WRBHzfYZy}@k^g(QBpiTinyc$^4+-w^l5SQ=-2Z)0 z94;}mXj@DZJ9X>x8iVxzHbbXHF#(M=!mHa1okmQ=K(uW*Jk>TE7cyFIcnla;Jh#~J zBs?t&@+sk1J3J#C7e&f(_y}$Dm`qJG78Wci`j$=$*`RIiQl$&<3ikW(D|iuJf|rF8 z!b#zjaC#N|8eWCh;C11Qa8@`coEK-aYiicEh59)i{1?93~-f#DlSp)wEXE zi-tB=JG#|4L2fPnb^(45@4@@<2l#;K2_M2opp6&>pTM7rG{dUv8%5bKGESPSZ5~=Q zRGcIZM`*>vFw!+fK#PsdaSeLRDB-ejfx{8oCE?0BJl)Um7x*juP0T^y9~cbnXk3t~ z*0o~YZ^AjGNwo?w?S|%#Y0~DlV#tJxc=%U^83Pm31|=rP86yq&4F3HJ5+(%jz?JYH zFR+Jvy!Dk)FHj%WILwsTkR(Y}NL;%U$T<2X8m=U1agqOfFE9+dO;4N`8cjXP zky66O1R-AHa{{0c`Sr#k*@(Seg5hA!HU=MmCYN@P^n* zatpbQ+<|M0ACbGskI6mcr{sRTIVM&b50gj9<3=GSU{^h{!1TTAH+f1h?^07lPR9HmW!>bAl zUP@=WCf-bL|F@1Wa+t1;yUD$TZwIE&C*&RkBnVg`U~S!jiM5a1kAMvV{SffOU;*>; zc=8MKgs9>o1&?4F9wUz96&xG9|~&_ zkR#yMK|UlOlMnGH1l;lOSB7>)edMp?pCZl=VH%0|PTYj`2zZENACjr2!FW6#{4bGy zC)FrOQP07rumpHL4+klZ;!WY8;h}}Ao-(H_U-ZP}^?lLPhO&K*DuwBX^Y*U!9VwaE z^Z?`4PB|mc`$dzS!ikzG1E8=O?en6=oASjiln(-Z+l^EZYOG(+0t}(%zIw`!!k*_n zNk-?`BqY#NIo$(4DxWG8aW?7#RfIrfr#qxdu{)&7 zsB)?Tf&K_YAzU--$^oba09OV>Zvu< zI^1Ba{8Cti(_cu!`_yKP!An(NY73D#_flLIl5Ga39{H>7uKURLJ5}pt6f^-%;Nii@?-f z0nb+4tqS}~{nsbleu>L=nY>SrPa0WAWR0#*`SiWN6W^wjUTvP=Cz z{Ym|WfChmo1gigs#a)`k^05Sg8Y~j8?uB&Q)i70ejf|uvn2|I#-F2C-6<)=>? zi}t2{XkP>x5EzQUFa#R^Lv6K7LFqs`2umrA4ao5SSe$%bo20|(NZi|G1Zb@6EuBVy zj>aC5j-jzuwIVR$x&G4w>Eu_H)mVVlKd-=cp*@IxEhYvp)nB_h7SY8f3*Pmhj27!O zK&+3_l?aUPf~i`BsfNZ9Fb08fFJP*t8wmZYRbgBsr5nW>DFS1~65_}eM$zh8qlF&z z8XmYbN{)_hfFwS9P)h2kDf@3q6GpkK2;zPnAm;8PjB4u!#(hhA3YUsP2mnx z1#H9h-Q<{_Mo;gO<0%LTopNjvsaaT#>9^_G^c(~bKAVNW&0zBdWlJp+x|O( z{L-!(y&C7Tox5rXyn&<5u5C4XgDC2Ph%Vk@upc)r5brSr2CKwf27H)6++zsBvaUC! zSo9`(H{rX1-b`Cfl`^g)pma}jJq@C^j#A-EaAQwW|$@GOGo#DGB>i!-DlO^v!? z+m5+G5Ko_`&*M;oK0}|SvH6;ZziyoXRxwhi>ptL-X~2>S$;7S!{>A}K zxL(@WQi1EcxT4UiRn)W$=|1kMY2303$%L+PLB?@-P+;K8!#Y{>EB(7@8Gb`xMLUfH zv34UJ41e1?CYvPiZ;{hDbzCVZ&JkM}C~oO8B$2|<41?=9@%g#WDVB-rn;9d9R%x3N zSS4C696GP=hIHX;NPEWYo7(ovN#cSrL1%g}J#hu7`;_sWd&X&vrut3?W5$?^)rpsS z8Rk3qq;@JXW64-O$B3~;02hsom@u{&6UGjKb=@&>#F)q!27wJCz}SOhfS(h+;Xe`G z2>0W=f6!fvx-lLv7WG8n{jNoQ#6_{K{-FD!eek0F#6>rWi*7V7`kZ5>|AAx1HGf_d zCFxpI#i$A2l}rGGL&GfyY+K0$F~JDzK;Z04^2bD&#A0iOq_I;hq=suAJ?&nIC=+e! zvb{o5j=SXIW~)dhj!7nbS2OX0;UL)g(*Z}PdihLz+UXi@J8MMrW{*srh>tS{8I!DJ-6CS zHB*NzFjK>5nOX$)A+R5T&pMcT!h;!%zyVSB58^CksCTyEft|#cX=XS)oVZFlGfa2_H)kC3!N_#!O+R7PS~_r?`TMz%c}lB5(wO(=QXO zheBk*^!H~b?d)Q~4CXD71#dFge&HS;=%Ts}R73>pTJ%5cmp#i>sM6 z%vxq0v!2<2z$FAOBXAo5Y<_T|tdsKF7;!g}*^a=Kb_TQU>n_Ug7AgNRgPC;|ftxQV z|0#1oq~tzkKl2#^I48W0z&9PtK@;U~yr6uMFLRtZ{V#ouRL5`{seTJn{d;fEe#|A2 z>KMT9x>NlsbB(#qOhw>(1nwem$4Kig$urVfZ+G;K^EO=sy3O2qh0b>wJoFv{_c31W zo(etlkiofVcN#uno?)lM{KPzEerA4Qer0}RerNt*{$y}S_z-~~5qN^YQv`lN09!w7 z`tb9=5hOM+e>4BE1PfTmk}Sp2EW@%0;td!x1RW6cMNo}k41$9YEJtt%f}?~QX*V;> znwga85kA$@)J@4)E7SAG6_PTnWO;_YD&FRW4zhNp=AR51y(+p7lbN3XTp=0LW!3u_ zZG`rDF4wGRsqYSfn`y|e6_R0{LtMMh=xu8Ly+YF5HKV6-M!YT1pcvZSr?7oYegCYG zjP2^%*Vy;fjje8&_?yN&du{%Dt)}Lc`PHVr|5Qkpbj~jtrylYCqpMr$HO<-@@pz;7 zrMg~=&kXr@Kb3?}vX~xs$34tAAp{kYkzD|5i~#2cq+_S6XsK>$?UXAvl8wiC7TceV zVh6C%Yz!OA#vw=|NFhig$RLP0&mqX;6E185=yt*d;qB$;M_jPh?dyk=>8@$>*g|7& z!xrG&2KM~VxlPxAa<*24qk^quHEb1I&DOA51kDk&K+qCF34&G#S|ez)7TB@%A{^`x z{Aq|#grHP}13`PC2t#cDDk!5^oJZrcHtZM?6x)?x0y|!4M$k?ucqPxWayCf16po$5 z;;ectJDF``r?6AmH`r{fQ0kr3PPr(Fp8Bd9b{LTUV>5(60zLuOx@p{S3) zVMO1ZdI>M-a@g!a_6rjvpNo(Lh>#o>Aqjk)E>uJpn@+G7MCeYkr`Xf%8TKrDjy;cH z5Q4!7h9DSJho2u7?W9odWQCCsKP_|p~PK7x_R0^;Ld2u6$Fa1HWhk-5X(Gr{w{ z2v2_zo*zVbqF#r``Df34TxUw$y9>0RSX@q9%RXg)W`ALSWq)ITXa7Jj7C|h}@dyq? zFag0t1e4aXf3eSugnPyT&JmlnWCT-8luJP{72$pD*D04JsgtC2uEkk$)<#%4D-qUo z3@axUVa<3QR@?nugB&?rGF!_zaWc-CbKzV$Ifq3h6TvJ5vk}A-Hx zd_;5?I0{aIGx)CJ1#lJLRm3M4@omNL!F})m_QZE4eDVE61q{PCCkDZ6SOP0yBW%HU z5Cu3NE`rPPb;BL_qTz9T#qcY9!SEj5@TBn0i!Jjl0KwAK3@<{#**=50-1zw z59UetOAkoDlwOctmfnzlC;dtKi!Eu(*-C6}Y#nUK2nO8Eh<{;1JlbQoQ?Qy!q4>>hkaN8*!dVm?1evP8gsduaSJgTx7Q6J zGsV~!9O(|yRnz#Z-4c-M*AkEyC@{2Xj*f0~F#Sx=Hg# zFXx6>k1}#nwPUn3G5AOtK4;#1nt#IolqVkh)CvF}8gRspt}hXUuP+b47cwmwXT}R( z!VJb2FbCi(m~pt&lg4D=YnVCASX`9Y#T;VJFz4{?$&1Woe0%a5zB&1TdBi-%>9+o7 zoNNEidf|Kuv9ob-ew@9)UNc*6)^4`JY=_xivtwpw%`ThWGP`Z|*qktj=9D>O&YAZx z$9L4sUCia??&hB6-sZmMz0LcY`*kp0W;ya7qEqhqX zEyFBxE%Pl4EsHHnEk{^Rw47o&$8x*nKFiN64_bb1`K9F%%VU-|ET2k9iJc@sqLu_p zLM7pnNXanCD9J>LAekg-lT4KuB+DeLBx@w=BpW1KB)cV-B-bR*ta@0PS?MjTBvvj~ zeXROfDXf%M{jCzLGOTi}Dyb})e>mJsY*51|%>muuN>*>}jtyfvE zv0i7r!FrqZPU~IPyR8pcKd^pc<80$?lWLP`Gty?V%~YFdHgDRzW%IVphc*XozOXrL zbIj(1%_*DnHaBg)x4Ccgz~+(7FE+pFZT_(N%jR!sA8D+#SXwQumDWoKOGinkN~cL@ zNM}lCNoPynk4`(*o6`*iz3_F48h_NDgK z_FDTod!79d`_cAe?Z?|sw13n7E&I3a=h!c^Utzz}ewF_4+VX#dm!IPea( z4)zX?4l)NXhdvJe4xtVi4tWmc4jPAQ2d&;=g2N04gTp+B1r7@x7CWqRSmUtHVS~f_ z4jUalbU5j7+2OXsV~0N+{&M)+k#K~LJsr&*Egh{KZ5(YK106FRTO4OPzU4UIae?DP z$2E@Y9p7`@=(yQ&tK;X6Cmqi@UU0nVc-ire<3q`3Y?0ZN}S4^YMg4F>YWBVH8_oQ(mPFaTHv(I={={7PMe*!Iqh)z(CMht zMW;(nmz}hnM~#)>myUi0%bw65LuKgS{5sdmnFzD zWks@D*-%-dY`CmNHdZ!XHc=+XCduZ?mdZBhWgo~k$+pV2%XZ2>l^v9QF8fk;MD~^J zn(Q0dP1$YPec1!qBiUowPqL@7XU;vGt(*E-ib4|Z;F9_HNSY;gYE`8yZN#la=iWuQy8ORh`4OQB1#OQ}n_ zi++g9P?tuR;VvyMBV0zgjB%OmvfO2h%PE(CTs>Wtu7R#WuA#2su95iiTZwDAYo%+o ztJby7wbd25PIH~%I@5KQ>pa&5t_xikyDoKIk-#ut|wei zxt@2u>-vw}Ol~Q+l1t@watFD$yqCO>+)wVWm#gGa@)&uXJVBl$PmveMi{+*A3b{sJ zEpL*y$VbRW%g4&c%V)_K%a_Sl$UEe#9){qk=tUorEc5ZcDQ}!cF0Zt zh1(IgV{RwhuDE^ecGc~=+YfG!+#b6J=#4wJXU+G^;oa>c+caY$1RUXo|Gr!>FVj}8R?nendw>V zsr78~Z1!yR9N{_2bByOW&zYX9JU{T<>bc!>r{^xu{hmiWZ+hPG{Kw1Q%h}7@E5R$( ztHJASuO(jFymokf==G7;$6kB9KK0t~b-?S8*B4%gy}t3f>2=%dJFmN5_q=}adg%3| z*AuU&Uix3We)G2R_VAAJF7mGT9`8NhdxQ60@5|ngd>9`~ABm5(kIcu}$JNKz$ImCg zXMj(vPrOf}PqI&{Pp(giPnl1JkH)9kr^#oO&lsO^J`;S}e5U$L^O@l@(`UKQI-ear zpZM(c+2`|_&tadVKF57d`keN;?sM1YXP>`({>Eo-px&4F?dfaoYw2s{>*ed`JJ2`V zx58KBTkWg$t@G9SHu#S59q&8Q7x}jNPW7GUJHvN}@9AFFz1(}n^(yaG=g0f?^mFj@ z_3Pv3=cn`w^b7V2^NaLL^-K2~{sSj;WygvO}~%*PWU}jNEEJ$z6ymx zrBEwE6#6hlx*}guq9|8r6xE6*#VExX#W=+TMVn%(Vwz%xVy0rDVufO*VwGZz;seDd z#TLaj#SX=1io=Ryij#^nic5;G71tFv6}SCaf0=)Tf0BQmf1!Vgf4RTLzsA4Lztw+~ z|5*R={uBL?f1CeQ|E2!N{O>C*m99#qvcED~uZ&YBD3g_`$};6(nag=BVbX^z&66 zsx_*0s`peIRhw0NRQps1RG+I3tB$I!s-6Y(2yhSZ3h)i+6W|x13Xj) z8&DKb5>Osc8BiUd4X6vy1q=xo8qgRpJfJ0DR>0DLPXf*b+zR+L&@9j`P#u^VI5-dm z&Io)n@U6f_flC8d1a<_j30xPrC2*HM@Z-R}f%^jw1fB}~D)3U^mB6ckw*$Wmyc>8g z@Q1+P)r1ek9I`ItRLIqkn<2MD?u7gh z@-XDbkSC!av`45}s70t}s849`(7vIHP-SRU=#bFn&=H}dL&t?q2%Ql+Gjvwy?9ip5 z%R}2kJ3=>yZVTNJ`eEq7(9@x3L(hkP75Yu+t7(h(cy973E|1%Y2g{+1>vRP72#FkHQ~d}e zuMt#4&j|Af%LuCohX|(#=LmU(dqkgzkcg;==!n>e_=wbq^oT(b*%7%BWf8+7hDWqS zjEoo^F(<+hF+bwnh{X|`Beq5CjMx?Nam1d8&m)dUoQgObaUtSj#J3T5BEFBfAMsnn z9}#~==>LxF8EFwIiL{QCNA`aC9&7^RQe6!l5efvC@;4o4k} zIvaH%>QdC#QP-mGM?Hvo6!m04!+7SWPu>uB5PdC@DQS4XdlelL1s z^ycVe(dVNtMqi1(8vQVajp-3%7GoJ>9Wyg#Ud*zXJuwGkZpHi_%f#}rX0evB*0Iu9 zmsq!0&sgu+;8=ZFY(#8SY)tHDu}5Ps#$JiN7JDQ1cIl*wnMn(i79}lCTAH*WX-Cqoq>q#KChbo;m~=AfOw#$J zi%D0Kt|fhwEJ=dMr$sT)#1NZpkBN$Q2vTdB8GzfHZ9`ZSGC zGfT5fvre;3b4Zh=xu&_Nd8PTLMWzi%i%lDtmXwy7mXVf~mYY_PR-9Ivrb`==HZ-j% z?Rwe|X%EwWO#3N4C%rPgD!nGXE?s{p{Y?6~^b6^iGV(I2GHNnvGjti3Gwx)3pK(9q z;h^e4O@o>TwGJ9J=xHX%Bs1wuE^|WWjLeytvohyoDYN=#4akbgiqG1UbtLOj*4J6r zvu$>y?qWSeDMWCvyEW{=HYmVGe$`y8tr*Bs9rZ+%X$ z9KRg@992$WPHfJgobnt^PEAf-&fuJ(IZZh&Ig@hQa^A?9p7UnTten|7hMajhpX6N0 z1-ah2sku$L@8+(~-H`i!?xx)BxjS<|%KbR^Nbd36leu5#-p_rQ`#AS$?ytFjY9jDY#egL&2W~e;4*FbSiWybSv~M^eOCJ z*ssuEUl>&wT^LuGP?%JhT9{s#S(sfortsauy@fZ6xFWxzyrQb2x*}asL(%Y}mZFhG zql?}sno(pZnpd>4XiL%dq7RF97wsw9S9GB0^P=-b7mKbGT`js^bhGH&qPs=+iY<#n zipz>o@!H}O#Se-f6+bTise~w@OW2YgC6*;tCDIbTU5R%|uacmW_>#nul#=w4%#xgv z{F0)Q`jR0f!%Bviw3du28B;R8WMawcl7l7pN-av&rA4KvbaLtJ(s`u|N*9$bFKsVf zRl25hN9nH8{iO#=50#!Ny-|9*^iJu$(g&qKmi|=wOBr3pmh~tzFO!s6mr2X)${flD zl$DpYm95j4ohbXMTvpzz+^^ifJfJ+JJghvjJgPjsJhQy0yrjIod{p_^@(JZa`Q-Ac z<@0V{ZKVSZ|!l@#vqNZYc#g>Y_6$dH~ReV`-yy9fV znTm52w<^A?xLfgaB~{5*_NX+klvLVO+EqGM_Nwet*{@RXUl~xTt_-dWtBk0utejT4 zvGPpiZyLEKN|UHb*5qqSG-aAfjaE~q8LVm0jMGfiys4R`nWLGjS)f^{S*zKu*{?aH zIj^~>xuUtIxuLnOxudzK`BU?E6;TDN=qj$NXO%^jq{_O=xyrXHx~ib6p$b(ktlC<& zx9V2aJ$=>vs^6=bYMW}iYR78lYI(IswRd$ubx?I^bwqVkbxd`9bwYJcbzXHrb#e9X z>MyDfS0AlDQ8S<>ttO);vnHozOU>SzeKnue9MY<_G1@roKy8wCkM@Z6nD&JBbZtUy zPHkarNo{#;b!}~}u69W6@Y>O}sCGu}g4!ju%WL&3YuDCpsQsXJQ|+$W{k11*&(>b3 zy;OUx_D1dP+V5(As{O6@&)UE1$U3Huuj^SSt#hgCQ|Dh7P#07eUe~`ax-PbEP+e|a zL0xfOMO{^$wyv(OwQgM9#5z>hR`+JzthzaMbL-~U9j?1w_pF|&x2l)c+t)kQyVSeY zd(`{a2kYy@>Lcq1)F;#@*QeDFs?Vw)TfeUUT>aJh+x3s@|JKnuPS;asp|jOF=wv!q zotw@>*Gm_qi_{I!#p(v?(sYA#*}6PkfvytY-fPlL(6#B_(9O`jrJJi;pj)I{s#~sG zr`x34B_s;TLO%X`4Yl}>CN$tbanOwaP{AZYKLsB!oguu1FRIVMf3;?pa22sgg~CxR zN<|r{0F|R^G!l(Q2u(%P&N$e!)B)drtlVp=-PFgr=@ua1bR!nx8+^1@CzsZWps>y36 zZ=1Yh@`samPyS-^;mJoQpJ+>L%WcbVD{L!it8W|J*3j12Hok3Qo6t77ZFbu`ZFAce cOtG2bJ*CeSrKvm*q3NA}YI^VbJtg4(06x}RB>(^b delta 9886 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 GMBxu>mideT literal 744 zcmb8qy=xRf7zXf1Bp6er5d$W1K{yOtWn~fMAQlp~h>cv}iUpg9rk`Q3+$J#coaI#( zmtuuk?)&z>!xdt2M627sz{Xlzac=fpZJlEF_ZIs;^Z54}(GTgrp}$e}ztR6m|4tSD z+bZlSo?Zo;qFBE2Uh=>1)74)OgYWATT&8-LAJDw^LVo^~UZ!7vm|ccxp!fK0pIaXz zyejJ#yjbfb*Kw|=xt`>Doa<4pA}_oLjQ45w7(}eO|Im^yYys1t`d_1s}Wy>M7kFC7Zh1&0cCg=ahG9<|57 z+~f9ZLmvFPeZvNsTBaIJJyV?~&J@!mnG%|Lra8?b(}HH1X-QMaRG_I?**xQ|zN@@d z)Sn<*$i>(`F2vSx5w?vBuw~qO+r=%nRorUZ#4WZ@Uaz*Y%XwHTm5xe0LkQgWo m1%?tsg^|EWVx%w@7)y*5CIS@@ssL+Wxpinr0WHJ({YjQ$^SpDP) zCyrfTdi}zewK5Z0uP5|MPk`9NvQ~NmLzf4T^x#^xk|8q!WNFHTE(9kInG=D`2}0)h zAamT1IS$bVk2faXvI?sST`R#Bn@oWCI%|T0;e-sJBQsV3 zU6!ztz4iLa-L2*~s3I@?tX`1dzQ|7z}4Cd&pMADm0) z<%7?_aC8<&ErIa0C2eQfCaS*H17!lO1X>QX7-%6-8dY@;b^<&O-5N6-D`PxaXU4Ot zK##Z&8}38vIGjm+vo^R5N*lZ*vIE`|*#qy3?1K+P4#1Nlli+#Eahc`8RZlAP=6!AT z_H $(SRCDIRS)/ASMPARMS.txt" + # For any files you generated in the gen target above, you should # add rules in genclean to remove those generated files when you # clean your build. diff --git a/SRC/A2NoSlotMidi/main.lst b/SRC/A2NoSlotMidi/main.lst index 5fe7b9b..b239bb6 100644 --- a/SRC/A2NoSlotMidi/main.lst +++ b/SRC/A2NoSlotMidi/main.lst @@ -3,20 +3,20 @@ Main file : main.s Current file: main.s 000000r 1 ;------------------------------------------------------------------------- -000000r 1 ; +000000r 1 ; APPLE ][ SERIES ANNUNCIATOR MIDI DRIVER +000000r 1 ; Copyright © 1998-2018 Eric Rangell. MIT License. +000000r 1 ;-------------------------------------------------------------------------; 000000r 1 ; main.s 000000r 1 ; A2NoSlotMidi -000000r 1 ; -000000r 1 ; Created by Eric Rangell on 7/17/18. -000000r 1 ;------------------------------------------------------------------------- -000000r 1 ; APPLE MIDI DRIVER THROUGH ANNUNCIATOR 0 -000000r 1 ; Copyright © 1998-2018 Eric Rangell. MIT License. +000000r 1 ; Created by Eric Rangell on 17 JULY 2018. +000000r 1 ; VERSION 1.0.1 released 26 JULY 2018 +000000r 1 ; VERSION 1.0.2 released 29 JULY 2018 000000r 1 ;------------------------------------------------------------------------- 000000r 1 ; THIS DRIVER IMPLEMENTS ASYNCHRONOUS SERIAL DATA TRANSMISSION -000000r 1 ; THROUGH THE APPLE ANNUNCIATOR 0 OUTPUT PORT OF THE GAME CONNECTOR +000000r 1 ; THROUGH AN APPLE ][ ANNUNCIATOR OUTPUT PORT OF THE GAME CONNECTOR 000000r 1 ; USING 32 CYCLES PER BIT TO ACHIEVE A 31.25K MIDI BAUD RATE. 000000r 1 ; -000000r 1 ; //GS USERS NEED TO RUN THIS PROGRAM IN NORMAL SPEED MODE +000000r 1 ; APPLE //GS USERS NEED TO RUN THIS PROGRAM IN NORMAL SPEED MODE (1MHZ) 000000r 1 ; 000000r 1 ; THE OUTPUT IS INITIALIZED TO A HIGH LOGIC VOLTAGE. WHEN IT GOES 000000r 1 ; LOW FOR 32 MICROSECONDS, THAT INDICATES THE START BIT OF A MIDI BYTE. @@ -38,15 +38,13 @@ Current file: main.s 000000r 1 ; $900E = SEND A TEST MESSAGE - C MAJOR CHORD NOTE ONS 000000r 1 ; $9011 = SEND A TEST MESSAGE - C MAJOR CHORD NOTE OFFS 000000r 1 ; -000000r 1 ; IF THE FOLLOWING ROUTINES ARE USED, THEY SHOULD BE CALLED IMMEDIATELY AFTER BLOADING -000000r 1 ; THE BINARY, THEN THE INITIALIZE ROUTINE SHOULD BE CALLED AT $9000. +000000r 1 ; IF THE FOLLOWING ROUTINE IS USED, IT SHOULD BE CALLED IMMEDIATELY AFTER BLOADING +000000r 1 ; THE BINARY. AT THE END, IT WILL CALL THE INIT ROUTINE FOR THE SELECTED ANNUNCIATOR. 000000r 1 ; 000000r 1 ; $9014 = CHANGE ANNUNCIATOR - MODIFIES CODE TO USE DIFFERENT ANNUNCIATOR 000000r 1 ; $9017 = ANNUNCIATOR TO USE: 0-3 - only looks at least significant 2 bits -000000r 1 ; DO NOT RUN MORE THAN ONCE - BLOAD THE PROGRAM IF NEED TO CHANGE AGAIN. 000000r 1 ; -000000r 1 ; $9018 = CHANGE LOGIC (POSITIVE OR NEGATIVE LOGIC FOR WIRING) -000000r 1 ; $901B = SET BIT 7 TO USE NEGATIVE LOGIC (ONLY ONE INVERTER IN THE MIDI CIRCUIT) +000000r 1 ; $9018 = SET TO 1 TO USE NEGATIVE LOGIC (ONLY ONE INVERTER IN THE MIDI CIRCUIT) 000000r 1 ;------------------------------------------------------------------------- 000000r 1 ; Enhancements for 2018: 000000r 1 ; 1. Disable interrupts during critical timing sections, preserve interrupt status @@ -83,391 +81,343 @@ Current file: main.s 00000Er 1 4C rr rr JMP TESTMSG1 ;SEND TEST MESSAGE 1 - C MAJOR CHORD ON 000011r 1 TEST2: 000011r 1 4C rr rr JMP TESTMSG2 ;SEND TEST MESSAGE 2 - C MAJOR CHORD OFF -000014r 1 ; 000014r 1 CHNGANNC: 000014r 1 4C rr rr JMP CHGANNC ;RECONFIGURE PROGRAM TO USE ANNUNCIATOR NUMBER IN NEXT BYTE 000017r 1 ANNC2USE: 000017r 1 00 .byte $00 ;ONLY LEAST SIGNIFICANT 2 BITS ARE USED -000018r 1 CHNGLOGC: -000018r 1 4C rr rr JMP CHGLOGIC ;RECONFIGURE PROGRAM TO USE POSITIVE OR NEGATIVE LOGIC -00001Br 1 LOGICBYT: -00001Br 1 00 .byte $00 ;SET HIGH BIT TO 1 TO USE NEGATIVE LOGIC, ELSE POSITIVE LOGIC (DEFAULT) -00001Cr 1 ;--------------------------------------------------------------------------- -00001Cr 1 00 SAVENBYT: .byte $00 ;SAVE AREA FOR NUMBYTES -00001Dr 1 00 TEMPA: .byte $00 -00001Er 1 00 TEMPX: .byte $00 -00001Fr 1 ;ANNPAIR: .byte $00 ; ANNUNCIATOR NUMBER TIMES 2 (1=C05A, 2=C05C, 3=C05E) -00001Fr 1 ;--------------------------------------------------------------------------- -00001Fr 1 2C 59 C0 INIT: BIT AN0ON -000022r 1 60 RTS -000023r 1 ;--------------------------------------------------------------------------- -000023r 1 ; CRITICAL TIMING SECTION BELOW MUST NOT CROSS A PAGE BOUNDARY -000023r 1 ;--------------------------------------------------------------------------- -000023r 1 XMITBITS: -000023r 1 08 PHP ;SAVE CURRENT INTERRUPT STATUS -000024r 1 78 SEI ;MASK INTERRUPTS DURING CRITICAL TIMING SECTION -000025r 1 2C 58 C0 MOD9: BIT AN0OFF ;4 CYCLES - TRANSMIT START BIT - ALWAYS LOW -000028r 1 20 rr rr JSR DELAY22 ;6+22 -00002Br 1 BIT0: -00002Br 1 2C 58 C0 BIT AN0OFF ;4 -00002Er 1 20 rr rr JSR DELAY22 ;6+22 -000031r 1 BIT1: -000031r 1 2C 58 C0 BIT AN0OFF ;4 -000034r 1 20 rr rr JSR DELAY22 ;6+22 -000037r 1 BIT2: -000037r 1 2C 58 C0 BIT AN0OFF ;4 -00003Ar 1 20 rr rr JSR DELAY22 ;6+22 -00003Dr 1 BIT3: -00003Dr 1 2C 58 C0 BIT AN0OFF ;4 -000040r 1 20 rr rr JSR DELAY22 ;6+22 -000043r 1 BIT4: -000043r 1 2C 58 C0 BIT AN0OFF ;4 -000046r 1 20 rr rr JSR DELAY22 ;6+22 -000049r 1 BIT5: -000049r 1 2C 58 C0 BIT AN0OFF ;4 -00004Cr 1 20 rr rr JSR DELAY22 ;6+22 -00004Fr 1 BIT6: -00004Fr 1 2C 58 C0 BIT AN0OFF ;4 -000052r 1 20 rr rr JSR DELAY22 ;6+22 -000055r 1 BIT7: -000055r 1 2C 58 C0 BIT AN0OFF ;4 -000058r 1 20 rr rr JSR DELAY22 ;6+22 -00005Br 1 2C 59 C0 MOD10: BIT AN0ON ;4 ;TRANSMIT STOP BIT - ALWAYS HIGH -00005Er 1 20 rr rr JSR DELAY22 ;6+22 -000061r 1 28 PLP ;4 ;RESTORE SAVED INTERRUPT STATUS -000062r 1 60 RTS ;TOTAL TIME INTERRUPTS DISABLED: 324 MICROSECONDS -000063r 1 ;----------------------------------------------------------------------- -000063r 1 DELAY22: -000063r 1 EA NOP ;WAIT 22 CYCLES -000064r 1 EA NOP -000065r 1 EA NOP -000066r 1 EA NOP -000067r 1 EA NOP -000068r 1 EA NOP -000069r 1 EA NOP -00006Ar 1 EA NOP -00006Br 1 60 RTS -00006Cr 1 ;--------------------------------------------------------------------------- -00006Cr 1 XMITMSG: -00006Cr 1 A5 D7 LDA NUMBYTES ;SAVE NUMBER OF BYTES -00006Er 1 8D rr rr STA SAVENBYT ;BECAUSE WE WILL CLOBBER IT -000071r 1 A0 00 LDY #$00 ;Y WILL BE AN INDEX INTO THE DATA AREA -000073r 1 XMITLOOP: -000073r 1 B1 CE LDA (DATAPTR),Y ;GET A DATA BYTE -000075r 1 20 rr rr JSR XMITONE -000078r 1 C8 INY ;POINT TO NEXT BYTE -000079r 1 C6 D7 DEC NUMBYTES ;DECREMENT COUNTER -00007Br 1 A5 D7 LDA NUMBYTES ;CHECK IF ZERO -00007Dr 1 D0 F4 BNE XMITLOOP ;LOOP UNTIL DONE SENDING ALL BYTES -00007Fr 1 AD rr rr LDA SAVENBYT -000082r 1 85 D7 STA NUMBYTES ;RESTORE ORIGINAL VALUE OF NUMBYTES -000084r 1 60 RTS -000085r 1 ;--------------------------------------------------------------------------- -000085r 1 XMITONE: -000085r 1 8D rr rr STA TEMPA ;SAVE A AND X REGISTERS -000088r 1 8E rr rr STX TEMPX -00008Br 1 ; -00008Br 1 0A ASL A ;SHIFT BIT INTO CARRY -00008Cr 1 AA TAX ;SAVE CURRENT IMAGE OF DATA BYTE -00008Dr 1 A9 00 LDA #$00 ;ZERO OUT ACCUMULATOR FOR ADD -00008Fr 1 69 58 MOD1: ADC #TESTDAT1 -0000EFr 1 85 CF STA DATAPTR+1 -0000F1r 1 20 rr rr JSR SENDMSG -0000F4r 1 60 RTS -0000F5r 1 ;----------------------------------------------------------------------- -0000F5r 1 TESTMSG2: -0000F5r 1 A9 07 LDA #7 -0000F7r 1 85 D7 STA NUMBYTES -0000F9r 1 A9 rr LDA #TESTDAT2 -0000FFr 1 85 CF STA DATAPTR+1 -000101r 1 20 rr rr JSR SENDMSG -000104r 1 60 RTS -000105r 1 ;----------------------------------------------------------------------- -000105r 1 QUIET: -000105r 1 A9 90 LDA #$90 -000107r 1 85 D7 STA NUMBYTES -000109r 1 A9 rr LDA #QUIETMSG -00010Fr 1 85 CF STA DATAPTR+1 -000111r 1 20 rr rr JSR SENDMSG -000114r 1 60 RTS -000115r 1 ;----------------------------------------------------------------------- -000115r 1 CHGANNC: -000115r 1 AD rr rr LDA ANNC2USE -000118r 1 29 03 AND #$03 ;KEEP ONLY 2 LEAST SIGNIFICANT BITS -00011Ar 1 0A ASL ;MULTIPLY BY 2 -00011Br 1 48 PHA ;SAVE THIS VALUE FOR EACH MOD BEING DONE BELOW -00011Cr 1 18 CLC -00011Dr 1 6D rr rr ADC MOD1+1 ;MODIFY LOW BYTE OF EACH ANNUNCIATOR ADDRESS IN CODE ABOVE -000120r 1 8D rr rr STA MOD1+1 -000123r 1 ; -000123r 1 68 PLA ;GET VALUE TO ADD -000124r 1 48 PHA ;SAVE IT AGAIN -000125r 1 18 CLC -000126r 1 6D rr rr ADC MOD2+1 -000129r 1 8D rr rr STA MOD2+1 -00012Cr 1 ; -00012Cr 1 68 PLA ;GET VALUE TO ADD -00012Dr 1 48 PHA ;SAVE IT AGAIN -00012Er 1 18 CLC -00012Fr 1 6D rr rr ADC MOD3+1 -000132r 1 8D rr rr STA MOD3+1 -000135r 1 ; -000135r 1 68 PLA ;GET VALUE TO ADD -000136r 1 48 PHA ;SAVE IT AGAIN -000137r 1 18 CLC -000138r 1 6D rr rr ADC MOD4+1 -00013Br 1 8D rr rr STA MOD4+1 -00013Er 1 ; -00013Er 1 68 PLA ;GET VALUE TO ADD -00013Fr 1 48 PHA ;SAVE IT AGAIN -000140r 1 18 CLC -000141r 1 6D rr rr ADC MOD5+1 -000144r 1 8D rr rr STA MOD5+1 -000147r 1 ; -000147r 1 68 PLA ;GET VALUE TO ADD -000148r 1 48 PHA ;SAVE IT AGAIN -000149r 1 18 CLC -00014Ar 1 6D rr rr ADC MOD6+1 -00014Dr 1 8D rr rr STA MOD6+1 -000150r 1 ; -000150r 1 68 PLA ;GET VALUE TO ADD -000151r 1 48 PHA ;SAVE IT AGAIN -000152r 1 18 CLC -000153r 1 6D rr rr ADC MOD7+1 -000156r 1 8D rr rr STA MOD7+1 -000159r 1 ; -000159r 1 68 PLA ;GET VALUE TO ADD -00015Ar 1 48 PHA ;SAVE IT AGAIN -00015Br 1 18 CLC -00015Cr 1 6D rr rr ADC MOD8+1 -00015Fr 1 8D rr rr STA MOD8+1 -000162r 1 ; -000162r 1 68 PLA ;GET VALUE TO ADD -000163r 1 48 PHA ;SAVE IT AGAIN -000164r 1 18 CLC -000165r 1 6D rr rr ADC MOD9+1 -000168r 1 8D rr rr STA MOD9+1 -00016Br 1 ; -00016Br 1 68 PLA ;GET VALUE TO ADD -00016Cr 1 48 PHA ;SAVE IT AGAIN -00016Dr 1 18 CLC ;ADD AN EXTRA 1 TO GET ANNUNCIATOR ON ADDRESS -00016Er 1 6D rr rr ADC MOD10+1 -000171r 1 8D rr rr STA MOD10+1 -000174r 1 ; -000174r 1 68 PLA ;GET VALUE TO ADD -000175r 1 18 CLC ;ADD AN EXTRA 1 TO GET ANNUNCIATOR ON ADDRESS -000176r 1 6D rr rr ADC INIT+1 -000179r 1 8D rr rr STA INIT+1 -00017Cr 1 60 RTS -00017Dr 1 ;----------------------------------------------------------------------- -00017Dr 1 CHGLOGIC: -00017Dr 1 AD rr rr LDA LOGICBYT -000180r 1 10 6B BPL POSITIVE ; HIGH BIT DETERMINES POSITIVE OR NEGATIVE LOGIC -000182r 1 AD rr rr LDA MOD1+1 -000185r 1 29 FE AND #$FE ;SET THE LEAST SIGNIFICANT BIT TO 1 TO GET C059, C05B, C05D, C05F -000187r 1 09 01 ORA #$01 -000189r 1 8D rr rr STA MOD1+1 -00018Cr 1 AD rr rr LDA MOD2+1 -00018Fr 1 29 FE AND #$FE -000191r 1 09 01 ORA #$01 -000193r 1 8D rr rr STA MOD2+1 -000196r 1 AD rr rr LDA MOD3+1 -000199r 1 29 FE AND #$FE -00019Br 1 09 01 ORA #$01 -00019Dr 1 8D rr rr STA MOD3+1 -0001A0r 1 AD rr rr LDA MOD4+1 -0001A3r 1 29 FE AND #$FE -0001A5r 1 09 01 ORA #$01 -0001A7r 1 8D rr rr STA MOD4+1 -0001AAr 1 AD rr rr LDA MOD5+1 -0001ADr 1 29 FE AND #$FE -0001AFr 1 09 01 ORA #$01 -0001B1r 1 8D rr rr STA MOD5+1 -0001B4r 1 AD rr rr LDA MOD6+1 -0001B7r 1 29 FE AND #$FE -0001B9r 1 09 01 ORA #$01 -0001BBr 1 8D rr rr STA MOD6+1 -0001BEr 1 AD rr rr LDA MOD7+1 -0001C1r 1 29 FE AND #$FE -0001C3r 1 09 01 ORA #$01 -0001C5r 1 8D rr rr STA MOD7+1 -0001C8r 1 AD rr rr LDA MOD8+1 -0001CBr 1 29 FE AND #$FE -0001CDr 1 09 01 ORA #$01 -0001CFr 1 8D rr rr STA MOD8+1 -0001D2r 1 AD rr rr LDA MOD9+1 -0001D5r 1 29 FE AND #$FE -0001D7r 1 09 01 ORA #$01 -0001D9r 1 8D rr rr STA MOD9+1 -0001DCr 1 AD rr rr LDA MOD10+1 -0001DFr 1 29 FE AND #$FE ;ZERO THE LEAST SIGNIFICANT BIT TO GET C058, C05A, C05C, C05E -0001E1r 1 8D rr rr STA MOD10+1 -0001E4r 1 AD rr rr LDA INIT+1 -0001E7r 1 29 FE AND #$FE -0001E9r 1 8D rr rr STA INIT+1 -0001ECr 1 60 RTS -0001EDr 1 POSITIVE: -0001EDr 1 AD rr rr LDA MOD1+1 -0001F0r 1 29 FE AND #$FE ;ZERO THE LEAST SIGNIFICANT BIT TO GET C058, C05A, C05C, C05E -0001F2r 1 8D rr rr STA MOD1+1 -0001F5r 1 AD rr rr LDA MOD2+1 -0001F8r 1 29 FE AND #$FE -0001FAr 1 8D rr rr STA MOD2+1 -0001FDr 1 AD rr rr LDA MOD3+1 -000200r 1 29 FE AND #$FE -000202r 1 8D rr rr STA MOD3+1 -000205r 1 AD rr rr LDA MOD4+1 -000208r 1 29 FE AND #$FE -00020Ar 1 8D rr rr STA MOD4+1 -00020Dr 1 AD rr rr LDA MOD5+1 -000210r 1 29 FE AND #$FE -000212r 1 8D rr rr STA MOD5+1 -000215r 1 AD rr rr LDA MOD6+1 -000218r 1 29 FE AND #$FE -00021Ar 1 8D rr rr STA MOD6+1 -00021Dr 1 AD rr rr LDA MOD7+1 -000220r 1 29 FE AND #$FE -000222r 1 8D rr rr STA MOD7+1 -000225r 1 AD rr rr LDA MOD8+1 -000228r 1 29 FE AND #$FE -00022Ar 1 8D rr rr STA MOD8+1 -00022Dr 1 AD rr rr LDA MOD9+1 -000230r 1 29 FE AND #$FE -000232r 1 8D rr rr STA MOD9+1 -000235r 1 AD rr rr LDA MOD10+1 -000238r 1 29 FE AND #$FE -00023Ar 1 09 01 ORA #$01 ;SET THE LEAST SIGNIFICANT BIT TO 1 TO GET C059, C05B, C05D, C05F -00023Cr 1 8D rr rr STA MOD10+1 -00023Fr 1 AD rr rr LDA INIT+1 -000242r 1 29 FE AND #$FE -000244r 1 09 01 ORA #$01 -000246r 1 8D rr rr STA INIT+1 -000249r 1 60 RTS -00024Ar 1 ;----------------------------------------------------------------------- -00024Ar 1 TESTDAT1: -00024Ar 1 90 3C 40 40 .byte $90,$3C,$40,$40,$40,$43,$40 -00024Er 1 40 43 40 -000251r 1 TESTDAT2: -000251r 1 90 3C 00 40 .byte $90,$3C,$00,$40,$00,$43,$00 -000255r 1 00 43 00 -000258r 1 QUIETMSG: -000258r 1 B0 78 00 B0 .byte $B0,$78,$00,$B0,$79,$00,$B0,$7B,$00 -00025Cr 1 79 00 B0 7B -000260r 1 00 -000261r 1 B1 78 00 B1 .byte $B1,$78,$00,$B1,$79,$00,$B1,$7B,$00 -000265r 1 79 00 B1 7B -000269r 1 00 -00026Ar 1 B2 78 00 B2 .byte $B2,$78,$00,$B2,$79,$00,$B2,$7B,$00 -00026Er 1 79 00 B2 7B -000272r 1 00 -000273r 1 B3 78 00 B3 .byte $B3,$78,$00,$B3,$79,$00,$B3,$7B,$00 -000277r 1 79 00 B3 7B -00027Br 1 00 -00027Cr 1 B4 78 00 B4 .byte $B4,$78,$00,$B4,$79,$00,$B4,$7B,$00 -000280r 1 79 00 B4 7B -000284r 1 00 -000285r 1 B5 78 00 B5 .byte $B5,$78,$00,$B5,$79,$00,$B5,$7B,$00 -000289r 1 79 00 B5 7B -00028Dr 1 00 -00028Er 1 B6 78 00 B6 .byte $B6,$78,$00,$B6,$79,$00,$B6,$7B,$00 -000292r 1 79 00 B6 7B -000296r 1 00 -000297r 1 B7 78 00 B7 .byte $B7,$78,$00,$B7,$79,$00,$B7,$7B,$00 -00029Br 1 79 00 B7 7B -00029Fr 1 00 -0002A0r 1 B8 78 00 B8 .byte $B8,$78,$00,$B8,$79,$00,$B8,$7B,$00 -0002A4r 1 79 00 B8 7B -0002A8r 1 00 -0002A9r 1 B9 78 00 B9 .byte $B9,$78,$00,$B9,$79,$00,$B9,$7B,$00 -0002ADr 1 79 00 B9 7B -0002B1r 1 00 -0002B2r 1 BA 78 00 BA .byte $BA,$78,$00,$BA,$79,$00,$BA,$7B,$00 -0002B6r 1 79 00 BA 7B -0002BAr 1 00 -0002BBr 1 BB 78 00 BB .byte $BB,$78,$00,$BB,$79,$00,$BB,$7B,$00 -0002BFr 1 79 00 BB 7B -0002C3r 1 00 -0002C4r 1 BC 78 00 BC .byte $BC,$78,$00,$BC,$79,$00,$BC,$7B,$00 -0002C8r 1 79 00 BC 7B -0002CCr 1 00 -0002CDr 1 BD 78 00 BD .byte $BD,$78,$00,$BD,$79,$00,$BD,$7B,$00 -0002D1r 1 79 00 BD 7B -0002D5r 1 00 -0002D6r 1 BE 78 00 BE .byte $BE,$78,$00,$BE,$79,$00,$BE,$7B,$00 -0002DAr 1 79 00 BE 7B -0002DEr 1 00 -0002DFr 1 BF 78 00 BF .byte $BF,$78,$00,$BF,$79,$00,$BF,$7B,$00 -0002E3r 1 79 00 BF 7B -0002E7r 1 00 -0002E8r 1 ;---------------- -0002E8r 1 ; END OF PROGRAM -0002E8r 1 ;---------------- -0002E8r 1 .endproc -0002E8r 1 +0000DBr 1 0A ASL A ;SHIFT BIT INTO CARRY +0000DCr 1 AA TAX ;SAVE CURRENT IMAGE OF DATA BYTE +0000DDr 1 A9 00 LDA #$00 ;ZERO OUT ACCUMULATOR FOR ADD +0000DFr 1 69 58 MOD5: ADC #TESTDAT1 +000136r 1 85 CF STA DATAPTR+1 +000138r 1 20 rr rr JSR SENDMSG +00013Br 1 60 RTS +00013Cr 1 ;----------------------------------------------------------------------- +00013Cr 1 TESTMSG2: +00013Cr 1 A9 07 LDA #7 +00013Er 1 85 D7 STA NUMBYTES +000140r 1 A9 rr LDA #TESTDAT2 +000146r 1 85 CF STA DATAPTR+1 +000148r 1 20 rr rr JSR SENDMSG +00014Br 1 60 RTS +00014Cr 1 ;----------------------------------------------------------------------- +00014Cr 1 QUIET: +00014Cr 1 A9 90 LDA #$90 +00014Er 1 85 D7 STA NUMBYTES +000150r 1 A9 rr LDA #QUIETMSG +000156r 1 85 CF STA DATAPTR+1 +000158r 1 20 rr rr JSR SENDMSG +00015Br 1 60 RTS +00015Cr 1 ;----------------------------------------------------------------------- +00015Cr 1 CHGANNC: +00015Cr 1 AD rr rr LDA ANNC2USE +00015Fr 1 29 03 AND #$03 ;KEEP ONLY 2 LEAST SIGNIFICANT BITS +000161r 1 0A ASL ;MULTIPLY BY 2 +000162r 1 48 PHA ;SAVE THIS VALUE FOR EACH MOD BEING DONE BELOW +000163r 1 18 CLC +000164r 1 69 58 ADC #C{yV&A!Rfb zf|Znnpb_bE6qhPBiiwzX;}{k}76l}Ns1Xs3qa+G(i!hmeUt)6aJ?HP9p{n0`=k$Hw zeg8lIGEDQDRVzN^oJ-5+Jo&7UPeeXf%V*a|or`|VIWO}sP%ox_k@_Xkr={TikE2dX z?O!M~ZQeWWL#Il8=*-ro-+SdU=gO`V-rSaud>`6a;(T4z=cJck=hlikHO}YaCasXV z>Y!qie5poO)dtxbv1%k+6l8U>6*ZD2f^52EY9vbq*<8ugNVYi0u9QrT9B(6}*~DLN z5=tX%fm~tIcI78{3>V2lHO_x+=|@yPfb@J{&W!UO;+EO6+zOKxNa6>RA!?k@uDnpe zdUn1cey!}yY2^I$tK>AgP|G1xzx;>iYZ|`Vh^v2WGJTawD1FG(M}I2T&h#}Bs}amK zEHU-bpG_`NBPG|d#MDQBKDk7Vl>CAvraroQa)}x#S;G=jAH9BZi5e;S6-!Kg^w*P1 z)JVwt^l$n#V8-p@TeDtO%W#**pW|XxY!o){6Oer(x z{8w+WGQWHy^xUmp?h5D6wR-#6oV$&BJ9QKF4(grMyP(VOhHkkBymo5#-a_}!3g4Xb zo9{!Fqi(++{x~)IfR`)KPL$q7=A1va8C6Fggtk++{DGc&;*anH)V7CwaIxwh%sIb) z3s+H>Ka3;D<}|n7pOI>F&bQ?Y483d2$!)XM{#F{Rp^^EEs1ZDbd!^ShzB$Dxjz*#n=ZCibeg-nwIRa*ysqsyFFMiR~t} z%=r!bL5MsF%^!f~4niF@a|k|7O+2N((8-*1I*e31Ee$$ZCY}BYLgWZEe-xT~2I{Dp zWAJHe;#u{DPUfW3b4az*ZqC5;M3H^>*@=g%t@zHNVU_Vpp#|N=^r3O-hk%cgyv2| z9W`?XK21&hOMRh}IqCEkQtcEEI$0*2-UcD^E;RohH1}_)qh{WRPg4_T)fYOMlTPQ5 zYNzi6oh*}19Uw$Hq4_RouG@cJO1-0IdXT57iC*=EPUfUjA5!fkZ*g4ZmPx06k_Wv$ z4SbrK7@Bg2n-kKo|D^JjG%FxkCNKU`-0dyY#Ml&qIU$S}37LRkne);A7It4DUzv0M zM;~B^+5b&>9+;DFZwT2FI=>d$_M6b;XN)=Lm#@ROxf??l2-%lY*WVPfcXc~8_q&k1 zq0g()Q?vPyyw7pnZWVw%=Pi>f=n*p7$as{Dzu@@O)aat+_U<;bAH}g++Cudrnfgm)!ER+^j}eJ?cll&taBY)*MW87v91H_#M`=UomjWJ zlj}OMPIBw_%TBCwomeNit-HQ6^mXkk`3%+VUF39;(*=&?;B=AG1&-w4bdl2q&W>(! zy2|11a&WrI=>}(K4>>*L^nfEdI6dU_fFn6LJ>>L&^H?uAz2x+QBRM#| zyrBK63iN+1*c0KRNy2NDfXvIsM>B4o*Kg z{op)4K+XU;1K>yw&Hy=`6ykeoqqBnM}ZoI!9T2WOC+L2&jCkuyZj z5IB;9Gepi1IFf@iM9vU6`-aIGCTAEN$-x;WXBZsG!5JoJ7@YkhV1jF2+| zj^yBskTU|#6Qksek~0d9e|h?reB>`8 zHvjgdx&H1PL{d7FFuj!aC^E zux@I8ZBt`;V^f1p$`{1zVl9=GB{H9>Lxm1zXX)$`9cJq=M~6#gU8-It2C7S?>a~SJ zOA@IC6*^SvFiVF^beOHf933vz;hQ>KRw_fqOgl_Dzc_rEREF)G$cZSaN-c<&HKg?H aPn+M^SfZ2g74e2teXKfOl5DQ4bN>f|7j>`z literal 6713 zcmZvg33OED8HVpalaNg6>27OlmuY+2(}lw!K|ot=4PgjrlT08J&Y*39dU|TA*q(CQ zgW8QHfWU>Ih+vG_mpjQsplr(OQc+Pvl%i-|T2aK-6pJWBAm0*`agahxT17@RMqE~8#YT@D>W!TF!pI+V)4 zSS)_={+7eX3QcUUo4NGR_Z(-`vClfr1t(%ykDV%TOm*suxRzPuEch}aYaHWMiZrWK zSNRo9ShNORKk~CHVXZ+{<7b7~iZ#g6es&zz8f4S_>@=)3$TEI*HhQhW^PQnfS%2vd zSh5C7m#F;sE8>3gX_23bjGpsJxY*2nqGtBb&a#WezmSgkmy3*Uv=Yni6E(?S!pduK z8DeW3Gx|!Fh??ZwktNokaHOXI(EU^Y9zhQ}}NzNNtVhu`u%MwwO{N2bBYfv(u zC88#I^~e%yP;xCxL{0MdBTKA7$sbuFYLb5%Sz--J78us(iAgTBLGaRuL)juNo4HR< zOmguVW#Sz3%_b=`vzMrzyv}^eUghL+BY%^VE2t}}E_D@kHMLoF_8QfmwaPn6b#Dx= z{sr*GIi`J`Ryov7>(w8mCN~(|FY?sveJ##0_uZ^j_qM1WrS{xHPd(JC{uDKTt2vuA zy9aTOX=-B^b#}Wx1GmfOa&7y1i*wAXZi8D_(k~$u=a`aSW#sx)y?#}P+UTjzQr(>O zCB}|)1279PHI8JCSw5h(C3)4{kg9i^szYtus6I<|H(9UDw9k|b%*|R`vPCtwRn^<3 z>QEcEtIty19o8$e%4bRj=IvTrvQss;OV!)0>QEc^sLxW}z1AzU!e>eb=02@0xl1*7 zx2kuKszYu3tNJX}z1MnWUgR?+19QLDmfWwJdqCAYpz2T?A5@>Ex(`{e%!xizGB6Kn zZOI|k+#{;qVO59P_^A3U)qTu*WtRF($-q3KwIxSYbC0WfPZ)cr8Hd_Tb~i=TrsH;| z9CMWFy>t_>F!7kO7wsfF<{;HOA$3(jop{u}WIki-9;PNw2JZmH$i-nd zFLO7qa5vPZSGgOi_gc7{X?8c_ah2D(8>;t4xErYxkGeOx8*1{@8M_gO-JIrb-ZG!C zdvB&Tz0KWFy?4UhWbJOm<0|iRH&pMva5qvX9(C_?H`L_t8M_gO-F%?C$uErg?{@f$ zIN}`htwpiV**(UoC5zQhZBjjFNlf1N=PtEg@2b^kkasA_9OEvF;WOexYmzzU^5x{M zAa5mkZrHQI=Sc?Ms)#koz-uON4SCm-cSG3In5)!?77qDNd{hT#F}K_^^@n3 zmm_Z=>^b1`Bm-|SVofsehRC~(yp7~-3VV+DJjuY@9I+-Dcw5NZO5Qf|wue1m_j!_m zwpyuxnNx}3oIf%7)^MRnhasFe(ycf++{9wh_k zJ#wh-`w_L0fioPg1@k8vI3JKhb^ja>z7+(ul7X`zTnpw+GH@2g<^5}z>Mn|?l?

N`{1>&Rr}zjZ)2PG&2M90oAx1>>s{TZeNLP9A(y^u+v4B0*F`?Y>ZW#b z+R15G4szwRlhdvoX2f1=O$>~(imM(I-$mvoJa^-Z9)1@5b%IPAfOF3J+$>}DiTRF&;(@jpda*!*h zo1AXtZ0jMXhnybeAXiQgIX%ijuAClndX%%hmz-X5dXvw_09ZU29R( z8mdy6LR=$LT5OM4D-~Pj+p^+{skN2mwY3#R6;nlvtto4$PsvJky0QW%mC&k+VmV^d z#r5SgQnfe%tfsD9j@e?nn@Lrf`huGDr>e_mmX#GC8EX%v_8@kgJv+}H#@oXL zdze^=rqZ#(s7|NrEThyO%IsmBJ)CC`gx;aN%1AA>FK)i%2YvZLv^+DKaCU~fB*mh diff --git a/SRC/A2NoSlotMidi/main.s b/SRC/A2NoSlotMidi/main.s index df7d44e..2c4ffcd 100644 --- a/SRC/A2NoSlotMidi/main.s +++ b/SRC/A2NoSlotMidi/main.s @@ -1,18 +1,18 @@ ;------------------------------------------------------------------------- -; +; APPLE ][ SERIES ANNUNCIATOR MIDI DRIVER +; Copyright © 1998-2018 Eric Rangell. MIT License. +;-------------------------------------------------------------------------; ; main.s ; A2NoSlotMidi -; -; Created by Eric Rangell on 7/17/18. -;------------------------------------------------------------------------- -; APPLE MIDI DRIVER THROUGH ANNUNCIATOR 0 -; Copyright © 1998-2018 Eric Rangell. MIT License. +; Created by Eric Rangell on 17 JULY 2018. +; VERSION 1.0.1 released 26 JULY 2018 +; VERSION 1.0.2 released 29 JULY 2018 ;------------------------------------------------------------------------- ; THIS DRIVER IMPLEMENTS ASYNCHRONOUS SERIAL DATA TRANSMISSION -; THROUGH THE APPLE ANNUNCIATOR 0 OUTPUT PORT OF THE GAME CONNECTOR +; THROUGH AN APPLE ][ ANNUNCIATOR OUTPUT PORT OF THE GAME CONNECTOR ; USING 32 CYCLES PER BIT TO ACHIEVE A 31.25K MIDI BAUD RATE. ; -; //GS USERS NEED TO RUN THIS PROGRAM IN NORMAL SPEED MODE +; APPLE //GS USERS NEED TO RUN THIS PROGRAM IN NORMAL SPEED MODE (1MHZ) ; ; THE OUTPUT IS INITIALIZED TO A HIGH LOGIC VOLTAGE. WHEN IT GOES ; LOW FOR 32 MICROSECONDS, THAT INDICATES THE START BIT OF A MIDI BYTE. @@ -34,15 +34,13 @@ ; $900E = SEND A TEST MESSAGE - C MAJOR CHORD NOTE ONS ; $9011 = SEND A TEST MESSAGE - C MAJOR CHORD NOTE OFFS ; -; IF THE FOLLOWING ROUTINES ARE USED, THEY SHOULD BE CALLED IMMEDIATELY AFTER BLOADING -; THE BINARY, THEN THE INITIALIZE ROUTINE SHOULD BE CALLED AT $9000. +; IF THE FOLLOWING ROUTINE IS USED, IT SHOULD BE CALLED IMMEDIATELY AFTER BLOADING +; THE BINARY. AT THE END, IT WILL CALL THE INIT ROUTINE FOR THE SELECTED ANNUNCIATOR. ; ; $9014 = CHANGE ANNUNCIATOR - MODIFIES CODE TO USE DIFFERENT ANNUNCIATOR ; $9017 = ANNUNCIATOR TO USE: 0-3 - only looks at least significant 2 bits -; DO NOT RUN MORE THAN ONCE - BLOAD THE PROGRAM IF NEED TO CHANGE AGAIN. ; -; $9018 = CHANGE LOGIC (POSITIVE OR NEGATIVE LOGIC FOR WIRING) -; $901B = SET BIT 7 TO USE NEGATIVE LOGIC (ONLY ONE INVERTER IN THE MIDI CIRCUIT) +; $9018 = SET TO 1 TO USE NEGATIVE LOGIC (ONLY ONE INVERTER IN THE MIDI CIRCUIT) ;------------------------------------------------------------------------- ; Enhancements for 2018: ; 1. Disable interrupts during critical timing sections, preserve interrupt status @@ -79,22 +77,28 @@ TEST1: JMP TESTMSG1 ;SEND TEST MESSAGE 1 - C MAJOR CHORD ON TEST2: JMP TESTMSG2 ;SEND TEST MESSAGE 2 - C MAJOR CHORD OFF - ; CHNGANNC: JMP CHGANNC ;RECONFIGURE PROGRAM TO USE ANNUNCIATOR NUMBER IN NEXT BYTE ANNC2USE: .byte $00 ;ONLY LEAST SIGNIFICANT 2 BITS ARE USED -CHNGLOGC: - JMP CHGLOGIC ;RECONFIGURE PROGRAM TO USE POSITIVE OR NEGATIVE LOGIC -LOGICBYT: - .byte $00 ;SET HIGH BIT TO 1 TO USE NEGATIVE LOGIC, ELSE POSITIVE LOGIC (DEFAULT) +NEGLOGIC: + .byte $00 ;SET TO 1 TO USE NEGATIVE LOGIC, OTHERWISE LEAVE 0 FOR POSITIVE LOGIC (DEFAULT). DO NOT USE ANY OTHER VALUES! ;--------------------------------------------------------------------------- -SAVENBYT: .byte $00 ;SAVE AREA FOR NUMBYTES -TEMPA: .byte $00 -TEMPX: .byte $00 -;ANNPAIR: .byte $00 ; ANNUNCIATOR NUMBER TIMES 2 (1=C05A, 2=C05C, 3=C05E) +MAJVER: .byte $01 ;BYTES USED TO TRACK VERSION OF RELEASED EXECUTABLES +MINVER: .byte $02 ;NIBBLES ARE USED FOR THE VERSION NUMBER ($0102 = VERSION 1.0.2) +ASAVE: .byte $00 ;SAVE AREA FOR ACCUMULATOR +SAVENBYT: .byte $00 ;SAVE AREA FOR NUMBYTES ;--------------------------------------------------------------------------- -INIT: BIT AN0ON +INIT: LDA NEGLOGIC + AND #$FE + BEQ OK2INIT + BRK ;ABEND IF NEGLOGIC NOT 0 OR 1 +OK2INIT: + LDA #RA!NUb8FD&Wg z!oc_+2n511i%Lopa};8u6^!%}3kra;`jc1kh`TE!mogv&9>;=$oXq6JlFa58Nr7eF#hDJwTqFE6I|-R@M&ldc7C@`~p* zeM^koVb2Pjq2PZmXzFHlF6(MRHZ^YZ)dd-lMuxHl2R;IfVZlWf9kh`n?@?@{ffK0E zDWkIjgF-?bHJH%I6(N%=lQU4F3Wc0PH#%jN-sVwj;kQV`9(I|{R`&q*A=m;2BN%J} dgNXtA9|mi(br@_N#=-KtA{q-AZ+Baln?ECJfe!!x