From 73f84694821c01c2e2780eca316cd2e9cc02436f Mon Sep 17 00:00:00 2001 From: Michaelangel007 Date: Sat, 15 Apr 2017 10:45:13 -0700 Subject: [PATCH] Initial commit --- Makefile | 8 + README.md | 5 + applewin.sh | 4 + test_mock.dsk | Bin 0 -> 143360 bytes test_mock.s | 411 ++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 428 insertions(+) create mode 100644 Makefile create mode 100644 README.md create mode 100755 applewin.sh create mode 100644 test_mock.dsk create mode 100644 test_mock.s diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..9cff3a3 --- /dev/null +++ b/Makefile @@ -0,0 +1,8 @@ +all: test_mock + +.PHONY: test_mock + +test_mock: + src2dsk test_mock.s + applewin.sh -d1 test_mock.dsk + diff --git a/README.md b/README.md new file mode 100644 index 0000000..7232e6c --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# Apple 2 Mockingboard Test + +Play a single note on both the left and right channels A. + +Source: 6502 Assembly diff --git a/applewin.sh b/applewin.sh new file mode 100755 index 0000000..d7f29d8 --- /dev/null +++ b/applewin.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +wine ../applewin_archive/1.26.2.1/Applewin.exe -no-printscreen-dlg $* & + diff --git a/test_mock.dsk b/test_mock.dsk new file mode 100644 index 0000000000000000000000000000000000000000..1cb95afa17c273d0993db285b792ad5e3db3b4f6 GIT binary patch literal 143360 zcmeI%c~}%@o;dL8lcqsv$VE&vZ`2@SjN~T9RX|!BQ-b1=m_sXvNypK|nV4NRvm4Ef zoh2^CHj~XLnY5HG4OFG8X>7_Cr4zAXt`mOi;)O*yS^NnnaRa1PUr@~KclWU^*v};0&eA%+N-@;$E1o|x*H$|pdTz}Ki zZ-G$P$d1dFs?m!kFuj*8@JHUcOy0dr#$JT5OBQBOTx^WVpi79iTFgd$A`_f0?^0Yj z@@~a7N#3Eja^+^lWtX=pszu(eXg73hSL$-gayzyut?DsSUf0{KlyoU%NNw-83XPCJ zJ`V;B#O#BJ?E4$|ZxxQ|CpiJ)_(^13S*~pVsZjB1tF^{!X*d_My3Ji#s=h0`UH!3G zJt62D`Zkc0mx^uYWu~*HD$AGML{tNN+fjDJ$;g4748v@QEj<=4Js%czd|#OF3Co>f z{+qC<=TC%1hCdnhe;+O`IZY4$7+y(*B$4s-89hZt@^0AM|9%G#d<*e0FIi``IPP)e2>09@Fvt8=xr2kb@e* zk9;)jKN2QN*ncuyY>N>RdwM!fgiB6_J5Gl?z6q;ebCx2)M1qF26fP~3lN%KtGGllx zEdQkB_4CKWoXFIa<+Q37Ip!9<^|tOXQ?KK645PakX2Oh4A9I<0V|1rJVZ4l>FRq&~ zbpq2!|I3-p-JNsXC%w#Swc9&8!ZePW=wTY$ZD+a6w?~#1nIn8tq_ipHA7rM{l`8go z{-tS1Nt46bBN!b{(y*~u?Gq1?jT=RYZe-Z37Urmi2BvXt|7IyNYE#un59CnNRIDEN zrS{BaqJe=T^FU|=v$<968Hh(VZxp}!C9C6fuOBv0Iwa>(98O3AWpe`KoztFi5t7bh z8q?{2*@V{SRP{I~kYepwh-|xR>`K+n3>-hCYFCd#X@-HoKhx4& zBcor^U8&K}yHd;VX6z%2ZQs|Z;elvhsexb8R;F-ok9MW+DKcs^A#JK$WOR+pJescE zAB@TC?=3RAO)p>WC^ELBy7j))w)mi~CX@6wG$d^z%qHK+6mq(uVF=ytN>z8jM+#&x z%8+gvEk%|$RgLDL4|tQ>)k|HIVbn~4uBd99E+cIO89L;4`m^Nj)M0mA+5hvZ_y6Kq zQ&Cm@p(_UV7138sAi!&{Vp913UI2iNDnLM;M#SLbOuQ zHCLDG4IdayW?`*&U8OI^QX@*S*0}gV!McP*TT=238*jYn=37#39o)2S`;O+8ogcNf zwcob;_8~*nef#e?c!=Ej$*|!g?n)h**7?o1-yIp1KDztvG53tkxc5Ho^!*P!_|U_d zeUFTLbo}2;n5eTR>6tX5PciH7P0+=U9>xqdo1p@Rdl-v_Nw=hoNY*oYOOn;1PfOB0 zGVETRDTSozZDxI}-gLK(vE0L$^l2&jjNy86pD{^)quvsmOcKTp&w#)9Thb?v9G>y; z@QmcamW;9RH}GxTum{GcKWKSyYk)1w~hgp}LYE=8!97GxR`r}%JO{$z?8zdwbM@Q%Rt|{snA->L`J=tc| zo>*vsMUmMkWRw({APvcFaF6IHGTF|+_;!dKd2dTcpIJ*2jeMU`WFR{y{IiXb%6oRh zRB}6wwHhKhJNk_3QLWu6W~H%?E!rb&?G~u9!{Hk%B$PRvnx$o|W)z9~jbN&C)HH0| z+A>C6mFB*ke6i6IEKTz=Z>N&&8=(d%BQk|SKvfLl=^NdeXbbi_0CW68r`uvBzuA&s zWaM1wq;yL|k#WR>8HR>FBVT0nrNh3dyw7MelouIUp&`1))^H9gw(!LVA->c4*HJiH zJy*6Uxh4p6U`EU>@81k=uxi0poDOXg(_D7wMo(@bgSLv6;0Q5;FEV8Uj&>_B1<(4% zsHdU&!4qA%zTCFq?gJ@q6RmnCtvlp6QCP0(EA3=XWAHc7l;De96MYlgZ0-|6;);pU z%*t!F7TYdBlz-Yf@CU13F=Pt45BH7HZW3)RcAx#2&Sh^i1(Py4dcXulx^IVC48)7` zjcH3%qk$zf@OUOyIi{gzYsQyiKV-jiqOIMRt6F__DER13`%Zfb*Z*&R{_Uj}d7(OJ zqRW1k+@i4itHjIv&ms0=ZFDwe$WzrNVTmJe1_FNxy-#jlx2g0mAu*P9g${i1)|$wg z*QIwQPGUTpm7X<86~ij-shCm0RV=B<_a#^Ud7WB$s`5GS67N#)G4Ehsi!aglh0p6< zu) zBfq&4lo?ExH%Kb&p(d-%B(h|^FU3M;)WF5iJc%!q(iZYFqzuENd7ed2dotky^kkR9 z?@)qf;TiGLhsm})sBX|WFCsd5TTSr)L#^Cgvd$3|wX@u-G& zxRRW?hCgG-^YK3#2^W?f_}1ZjXXorZgR*^OJ!-!3bf-*C?MGr9|&$d(u{U!6I){^I>-uaT3u|%R7t2){iQn_~2 zvbig2TCJMiX>n_58fjQjqaMCexB=QG>-11}Gn{nxy$ZIuDq+6lpD#hv-0`CRkyueP ziHR_>n#`(x#r-0oAj z5^Xe1yfD&$Nx>Uvd-EnFee1BYY>(#TXr^4~_mn2_q`HK>JMDXuW;3kjs)H+FF5bo#L@;ZmO zd>~)vsAYqoW=kdYuvSWzuVw#O0oo+67DkyAxdS@!P>+Ly4hUxsI+;1z3H==PyZ~C~ zVS*NJF5je37&`mA?9enzTctKWjqO-Vn`y4f^}%eJc`TT5XPY%Rgj`;`AQx`h7T9ZG z7yec*$aUqeUSN0G-Fq`Rb8f1gOQR>Sg(m53v$`$EVlukgY{756Mu^_7UNAud*68)+ zvhQ7n%|Bn3=Sj2`^Ca%>rP6c*X{`{KOj{~JSEXU#9|8;qOtMaxQ`m#mqKQaen4bk^ zby*fC#z4QeKnProi1F$<+2Y|NiX7|VwKLi);kWD0^rf+=4zY z$%`b_Dle8`fa&-}^eaueSc0T5lfr2-u&q_DY+tS`i%hB}`PF1_wfwxqZ&uivs%Tf! z?xG9DIP!C}jM{3*iPkq-HHZ&)zR|ekPjH01U#;0lZMAleNY&bDn&#$poEST1fz%cY zGYKPzMsjGK{F>zdokTjkaOEa>YM4B;4o3H)-$^j9Ys7chW?*+$iFzm{(^q@+r5a!Gs1r)^IV)d+ z>_uJl0DH8(#y9QgE_z^BWjh?;w<``P+sQUpmuyo?b|?@47ekvBV2iFh@N5Cr0YIV0 zU@g$IMIKm=z#XayXO32UI8A>PHyJrO!!IL3NFfeZxmK1lf5T z;8_W5X>AR3ZoQ!rdM2&Z6CU4G*KXfqu04z9c*xCHgJFNcVb}exPuTq*2R1A1?JFJZ zjI|`y7oEK6(1cwbETDAvg=)7Mx+MF64|)kbeP-7tM50 zgF%@HLqRm`fn}^iG(pYUI^FtF%V2$i#Yl^7hsi5;IV_>DMmy-)NT~YTZf#K2{heQG zG0qgu_i4sYPPi=m*-KZNPz79U(2-|Q*AATft6g-5!pVx{%9iUTR~ARiAG&XXOS?7` zob=YMfC0zhE?}~cW5hVs3R8($On|9n5Y&ToZKVYpeV=3`cp0Lv4nUZ`dZ0f*Ti~l` z2pSeW>48h5$V5pheO`+ER&>NJhjljaywvTqo#fyg@>>NWN@-y2J@X8eW&mvWnpnLl|0@RW2&6O{wZRcra5kLn&tf8;W6Eix~xxMm(=fyZRcR-=48eb(0Np=a93TH7AqCkWxbv4%32B8 z)n##TwV@?|NJ|zxK~$ucY)#kBO@kp}9kom|(-ERpahZ^XD@)dS0Pk@L=FRBzCJfE= zWgQz+mgVqeA7fg}vZQvW13p$>+ihK0meujRq}?JpGmoW0xMO8BrYqa&%3_aJJ4Bie z{-|!8)3wyK#OZp?^(yCdO>^yXx>#2`=X+$2!J{Sfb0l9TKU}@^Ez_vtbJAsTQF(Y?0mYN z#1_nKDYR!d+n=!Sc)T!gR?GB)nR&DF3OWj=+dHzSPq*hc7uxf)r?pJVo|VlOd^D|~ zBfkJP(+k(-<*%ET{lw%v)_!2JnwNhthZdAWOU!}dX3d@6!hFhPFAke<*z6p(r4T~x#9mlfu%EWi zPNo+Y%(73KWpB3U=aPcSBsY83Hrj}2vdIOr^PA@su(PMx$+Wzg)3RqxYRwy4Fpxes zZ{}lU@@#f@G&=A-W^bN3H-A?469dQd3rNoF$&>AcGp`jNjS3dmvV-!c6lPB&vkD3b zn_W1ig;qB=uMp})CKXJZmYv_sGlpAl9dZ8z_Nf;Z7p+(=Z633lVYExPT{0McU=sO6 zhM5ft(PyoU87QJZSxjro?%jKZU-x5J0hwem+f;RT%YnT+4|az)hc?$UO>c(o{Ltio z-2bXSU0x;k`p^0w@h8cA;1>DK(3_!m{B8cX{X6}1KjMGSzsdh6*zaUCJ=_4ym+0*v zSs0KvD{X^fG~6KM2916p0lBAB3g`2f-~(Ta#*F=ZDzWLh#JIyI$0JzORQ^BzHYT@qARz?^pPP zihNq}?5yYaDf|KY#NX3ePaY1E_*!x}OvcqhOqg|Blt?s6B$_DFS`UjNe@=;fU(fd{ zk?wl_lv4VsBKGs03jd8Fe;eXIQ&QM@wIU;V_9@++W7IxabKuGNPm0{6@O=urfUv@k zRC-qY&TLyC4MIS+|bNK!Df;}Zq0n?F_LUIpqepHiSHP(vz` z_Mv=E$rueB@P=axyy1Y_lH1o09F-eks*X~20p(Fj`BI4eeTXLM8#vet&OgAx({PY5 zAyVUq*_CDt`#m0h#fH*9Y#@O;(o)I(J_t*EFs?4gL7u83|61qd*jH&hd51zi^IuEz zhYh7GHqZob274Tk#95XjW(_)|@P`yg$o^}cxSU@TieB`sp$&i<11DUSuL%vv4`ema zI$GqZ-Xn^7uJ@?I-X{MNAFj%NAEHU4XT{T14^R1a);E4sU$S3;)~AqpwZU{aheCYG z2cf#0j5xTZZmr9yagujr{|BMgR`q-NfZ{)>!1v7HK60@Z3d|&5t``|EOp$Owae<@# zjh--iCT`|EAu=`qf8MxAZ3rIc!6nDrcKKY`l}kb!1`g4)6?_J6AEWisW@bzk1ZbO0 zFG#B)MYNehjMW;1=X4hus%b8wKo5Lh@5+Tv1WQy-AR5x$-7O4(w!y(}Sd(b>8SCBE z!8K6J=)=SgPe`?pf7&G81Qp{1y~sG=cBnGsPX4Jf1k0NJ7%X_sml+2;CE$z=LO#W| z&pBeLg%z;{UU-%7gB5a&3aec-tYM!5FKcK(wADuPL~!6m&bAQr&f_5%cPB#LOc+I* zL*42Hud%a4yHPMS2qDjz5UpWnu6n}jP`d%r%dGTlu7_B}9u$-OTBx`f-evKP^(B$| zR(OR3m$6R-{gL|Oj5zhgYORZG50j~3XqcDL%wD~!_ZlM~L4S_4LVxD&KBO$sapXuX zBr6PxTVZTKPvYc5N(KZ!b|rY()!;UTzJqF~ucHFd^UGQ2sCujx`a)VTHn30e?^jr* z79I@dXcmcf3HU}Q9iyhF56adH`m!8HG0X|@0mC0A0l_4HMS0|}Ve6EfH6m0})Ri7k zN}&G~2I0wM4*!LcviLKF|4M-@`7f2lpDX;=3g|+`b!=hKze|BPkR@7}R_w6i|5)Kf z9ps|-?~owW-z>p9zQ6@VU?8#u1G3Upp_0{bGN4e%+8zw7 z3i;u?9@5Ay5^ecT2@2p!qwnhAg<+dsH4lo4U41VnpI7)}VYyF%SB-EL8K{GaNHdUK zmF)Vu9(Y6q4~pQmAM|Uu@PgidJRH<<^4YKu(?&FlU~IE#dcm?9p4!Prls%pFCF)US z&o_$p8<@Z7?w5-Db_j%nUnuTm8uGQ`whe@QrMS&7Fx?-+<YG@Qo2=L>+WNUnslODQRCqSB-7gi<@7?t z6H3WRh3oBtrqPMV022=foj`0FaD>|n^(+}(n*#IR;^?D1w}C!lSQcU!m?$6=W@325 zJPC%32bLZF6D6hh6NSzUGk%#F?#LJ>FfhjJa=zSIuUcE1hN@>^GJ|spqx|#WUTBiK zjc!g|i3W2UjdT_wWpXL<2cegTOPy!os+LAt#r|Cg`m1(lho)rQlHxT^IIX}#1Gm=O zOY471ku~UT41b#5u<*4$?5#^OGcnb4*3cZ&*5j_`O(Y5uYvKTTsqQH59Q^znc&W6E= z9SXNMgGHlyvuIM2;fZMidva@!XjRQ{N0Z{#Wm;g3hr0v^JfKdaPpG-1c!oJKIeNj= z->01BW03ZMWApa2S>01BW03ZMWApa2S>01BW03ZMWApa2S>01BW0 z3ZMWApa2S>01BW03ZMWApa2S>01BW03ZMWApa2S>01BW03ZMWApa2S>01BW03ZMWA zpa2S>01BW03ZMWApa2S>01BW03ZMWApa2S>01BW03ZMWApa2S>01BW03ZMWApa2S> z01BW03ZMWApa2S>01BW03ZMWApa2S>01BW03ZMWApa2S>01BW03ZMWApa2S>01BW0 z3ZMWApa2S>01BW03ZMWApa2S>01BW03ZMWApa2S>01BW03ZMWApa2S>01BW03ZMWA zpa2S>01BW03ZMWApa2S>01BW03ZMWApa2S>01BW03ZMWApa2S>01BW03ZMWApa2S> z01BW03ZMWApa2S>01BW03ZMWApa2S>01BW03ZMWApa2S>01BYMe@VcYlxSd>%l}#2 zH?BrV)-lX*8w1;cpMFT%-~a3WX$~>JGVNcNd8I1&@oNN*wF|MmQnWW1hR&oD`*>%9Hu>%9Fj*LnLb*LnM6uk-d>uk-fDUFYqOzs}n~=sItI z!qxUCC+b^UcJJOR{6{}}CV7zYV9SAnU+>wwW7oeM>pH)fzDkLoD1ZVefC4Ch0w{n2 zDDXd1pqZ;FeXE&h?vl5f*)wkM$AY_ba9PQ1Wdh@6A|JcSWp{UHg8MA@KePJ({aU&2 z(vekea@6g;LvWLAZtocQNGuZ>QtBoVHyc;BoT0zWgv7)|C~jHw_v$xxm0MWuWk{Xd ztEU?y-NXnJ;6q64hV9jV;MCD$2D&j_IpB@^s~FJ|*@#=J=~gebsuwu1pVv3@hGvnu zTa39|H1kZeXoL-%F(^b literal 0 HcmV?d00001 diff --git a/test_mock.s b/test_mock.s new file mode 100644 index 0000000..8d28213 --- /dev/null +++ b/test_mock.s @@ -0,0 +1,411 @@ +; Mockingboard Demo Note +; Clean up by Michael Pohoreski +; http: +; Assembler: cc65 +; +; Original: +; From: Steve Nickolas +; Subject: Single tones on the Mockingboard? +; https://groups.google.com/d/msg/comp.sys.apple2/Lq3RPNX0y1g/l4Zt7NM_wsIJ +; +; References: +; http://mirrors.apple2.org.za/Apple%20II%20Documentation%20Project/Interface%20Cards/Audio/Sweet%20Microsystems%20Mockingboard/Documentation/ +; mockingboard primary routine.assy.txt +; mockingboard table access routine.assy.txt + + + __MAIN = $9000 + +; Uncomment next 2 lines for ProDOS + .word __MAIN ; 2 byte BLOAD address + .word __END - __MAIN ; 2 byte BLOAD size + +; Mockingboard Base Address + ADDR6522 = $C400 ; *** Default Mockingobard to slot 4 *** + +; Programmable Sound Generator + MOCK_TONE_LOW = $0 ; Tone Control Fine Reg 0/2/4: lo 8-bit + MOCK_TONE_HIGH = $1 ; Tone Control Coarse Reg 1/3/5: hi 4-bit + + MOCK_TONE_A_LO = $0 ; 12-bit + MOCK_TONE_A_HI = $1 + + MOCK_TONE_B_LO = $2 ; 12-bit + MOCK_TONE_B_HI = $3 + + MOCK_TONE_C_LO = $4 ; 12-bit + MOCK_TONE_C_HI = $5 + + MOCK_NOISE = $6 ; Noise Period Reg 6 : 5-bit + + ; a b x x x y y y + ; \___/ + ; C B A + ; 0=Tone Disabled + ; \___/ + ; C B A + ; 0=Noise Disabled + ; B input=0 + ; A input=0 + DISABLE_TONE_A = %000001 ; $01 + DISABLE_TONE_B = %000010 ; $02 + DISABLE_TONE_C = %000100 ; $04 + DISABLE_NOISE_A = %001000 ; $08 + DISABLE_NOISE_B = %010000 ; $10 + DISABLE_NOISE_C = %100000 ; $20 + MOCK_CHANNELS = $7 ; Disabled Chans Mask Reg 7 : 6-bit + + ; D s s s s + ; \_____/ + ; Static + ; 1=Dynamic + AMP_STATIC = %01111 + AMP_DYNAMIC = %10000 + MOCK_AMPLITUDE = $8 ; Amplitude Reg 8/9/A: 5-bit + MOCK_AMP_A = $8 + MOCK_AMP_B = $9 + MOCK_AMP_C = $A + + MOCK_ENV_LOW = $B ; Envelope Fine Reg B : lo 8-bit + MOCK_ENV_HIGH = $C ; Envelope Coarse Reg C : hi 8-bit + + ; C K A H + ; Continue + ; Attack + ; Alternate + ; Hold + ENV_CONT = %0001 + ENV_ATTACK = %0010 + ENV_ALT = %0100 + ENV_HOLD = %1000 + MOCK_ENV_TYPE = $D ; Envelope Shape Reg D : 4-bit + + MOCK_REG_FIRST = $0 + MOCK_REG_LAST = $D + MOCK_REG_NUM = $E + +; Left Speaker + MOCK1_OR_B = ADDR6522+0 ; OR Register B + MOCK1_OR_A = ADDR6522+1 ; OR Register A + MOCK1_DIR_B = ADDR6522+2 ; Data Direction Reg B + MOCK1_DIR_A = ADDR6522+3 ; Data Direction Reg A +; Right Speaker + MOCK2_OR_B = ADDR6522+0+$80 + MOCK2_OR_A = ADDR6522+1+$80 + MOCK2_DIR_B = ADDR6522+2+$80 + MOCK2_DIR_A = ADDR6522+3+$80 + + ; 6522 Commands + ; DIR BC1 BC0 + _6522_RESET = $0 ; 0 0 0 + _6522_PORT_B = $4 ; 1 0 0 + _6522_WRITE = $6 ; 1 1 0 + _6522_LATCH = $7 ; 1 1 1 + + _6522_PORT_A_OUT = $07 ; TODO: is $FF safe? + _6522_PORT_B_OUT = $FF + +; === CODE === + + .org __MAIN ; .org must come after header else offsets are wrong + +; Cleaned up code + jsr MOCK1_Init + jsr MOCK2_Init + + ldx #demo_note_1 + JSR MOCK1_Play + + ldx #demo_note_2 + JSR MOCK2_Play + + lda #$00 + jsr DelayA + + jsr MOCK1_Stop + jmp MOCK2_Stop + +; === DATA === + +; $3E = Only enable Tone A +channels = DISABLE_NOISE_C | DISABLE_NOISE_B | DISABLE_NOISE_A | DISABLE_TONE_C | DISABLE_TONE_B + +demo_note_1: + .byte $80,$00 ; [0] Tone A + .byte $80,$00 ; [2] Tone B + .byte $80,$00 ; [4] Tone C + .byte $00 ; [6] Noise + .byte channels ; [7] Disable + .byte $0F,$0F,$0F ; [8] Amp A, B, C + .byte $00 ; [B] Env Lo + .byte $00 ; [C] Env Hi + .byte $00 ; [D] Env Type + +demo_note_2: + .byte $7F,$00 ; [0] Tone A + .byte $7F,$00 ; [2] Tone B + .byte $7F,$00 ; [4] Tone C + .byte $00 ; [6] Noise + .byte channels ; [7] Disable + .byte $0F,$0F,$0F ; [8] Amp A, B, C + .byte $00 ; [B] Env Lo + .byte $00 ; [C] Env Hi + .byte $00 ; [D] Env Type + + ;Tone Control Fine 128 ($80) Register 0/2/4 + ;Tone Control Coarse 0 Register 1/3/5 + ;Noise Period 0 Register 6 + ;Enable Mask 62 ($3E) Register 7 + ;Amplitude 15 ($0F) Register 8/9/A + ;Envelope Fine 0 Register B + ;Envelope Coarse 0 Register C + ;Envelope Shape 0 Register D + +; Original code + +MB_Init: jmp MOCK1_Init +MB_Play: + ldy #$80 + ldx #MOCK_TONE_A_LO + jsr MOCK1_PokeXY + ldx #MOCK_TONE_B_LO + jsr MOCK1_PokeXY + ldx #MOCK_TONE_C_LO + jsr MOCK1_PokeXY + + ldx #MOCK_CHANNELS + ldy #$3E + jsr MOCK1_PokeXY + + ldy #$0F + inx ; X = MOCK_AMP_A + jsr MOCK1_PokeXY + inx ; X = MOCK_AMP_B + jsr MOCK1_PokeXY + inx ; X = MOCK_AMP_C + jsr MOCK1_PokeXY + + ldy #$00 + ldx #MOCK_TONE_A_HI + jsr MOCK1_PokeXY + ldx #MOCK_TONE_B_HI + jsr MOCK1_PokeXY + ldx #MOCK_TONE_C_HI + jsr MOCK1_PokeXY + + inx ; X = MOCK_NOISE + jsr MOCK1_PokeXY + + ldx #MOCK_ENV_LOW + jsr MOCK1_PokeXY + inx ; X = MOCK_ENV_HIGH + jsr MOCK1_PokeXY + inx ; X = MOCK_ENV_TYPE + jsr MOCK1_PokeXY + + lda #$00 + jsr DelayA + + jmp MOCK1_Stop + + +; ____________________ Utility ____________________ + +; ==================== +; Delay ((A * ? + ?) * (A * ? + ?) +; ==================== +DelayA: + tax + tay +@1: inx + bne @1 + iny + bne @1 + rts + +; ____________________ Mockingboard 1 ____________________ + +; ==================== +; Initialize Mockinboard +; ==================== +MOCK1_Init: + lda #_6522_PORT_B_OUT + sta MOCK1_DIR_B +; lda #_6522_PORT_A_OUT + sta MOCK1_DIR_A + ; NOTE: Intentional fall-into reset! +MOCK1_Reset: + lda #_6522_RESET ; -->+ + .byte $2C ; | +MOCK1_SetReg: ; | + lda #_6522_LATCH ;-->+ | + .byte $2C ; | | +MOCK1_SetData: ; | | + lda #_6522_WRITE ; | | + sta MOCK1_OR_B ;<--+ <--+ + lda #_6522_PORT_B + sta MOCK1_OR_B + rts + +; ==================== +; Plays one note +; IN: +; X = Register: $0 .. $D +; A = Value +; OUT: +; A = trash +; X = unchanged +; Y = trash +; ==================== +MOCK1_PokeXA: + TAY + ; NOTE: Intentional fall-into! + +; ==================== +; Poke (set) byte to Mockinboard +; IN: +; X = Register: $0 .. $D +; Y = Value +; OUT: +; A = trash +; X = unchanged +; Y = unchanged +; ==================== +MOCK1_PokeXY: + stx MOCK1_OR_A + jsr MOCK1_SetReg + sty MOCK1_OR_A + jmp MOCK1_SetData + +; ==================== +; Stop all sounds by setting all regs to zero +; ==================== +MOCK1_Stop: + LDX #mockN_off_data + ; NOTE: Intentional fall-into! + +; ==================== +; Plays one note by setting all Mockingboard registers +; IN: +; X = Low Address of registers +; Y = High Address of +; ==================== +MOCK1_Play: + STX _mock1_load_reg+1 ; *** SELF-MODIFIES! + STY _mock1_load_reg+2 +_mock1all_regs: + ldy #0 + ldx #MOCK_REG_FIRST +_mock1_load_reg: + lda mockN_off_data,X ; *** SELF-MODIFIED! + jsr MOCK1_PokeXA + inx + cpx #MOCK_REG_NUM ; BUG: $B ! + bcc _mock1_load_reg + rts + +; === DATA === +mockN_off_data: + BRK ; Reg 0,1 Tone A + BRK + BRK ; Reg 2,3 Tone B + BRK + BRK ; Reg 4,5 Tone C + BRK + BRK ; Reg 6 Noise + BRK ; Reg 7 Enable + BRK ; Reg 8 Amp A + BRK ; Reg 9 Amp B + BRK ; Reg A Amp C + BRK ; Reg B Env Low + BRK ; Reg C Env Hi + BRK ; Reg D Env Type + + +; ____________________ Mockingboard 2 ____________________ + +; ==================== +; Initialize Mockinboard +; ==================== +MOCK2_Init: + lda #_6522_PORT_B_OUT + sta MOCK2_DIR_B +; lda #_6522_PORT_A_OUT + sta MOCK2_DIR_A + ; NOTE: Intentional fall-into reset! +MOCK2_Reset: + lda #_6522_RESET ; -->+ + .byte $2C ; | +MOCK2_SetReg: ; | + lda #_6522_LATCH ;-->+ | + .byte $2C ; | | +MOCK2_SetData: ; | | + lda #_6522_WRITE ; | | + sta MOCK2_OR_B ;<--+ <--+ + lda #_6522_PORT_B + sta MOCK2_OR_B + rts + +; ==================== +; Plays one note +; IN: +; X = Register: $0 .. $D +; A = Value +; OUT: +; A = trash +; X = unchanged +; Y = trash +; ==================== +MOCK2_PokeXA: + TAY + ; NOTE: Intentional fall-into! + +; ==================== +; Poke (set) byte to Mockinboard +; IN: +; X = Register: $0 .. $D +; Y = Value +; OUT: +; A = trash +; X = unchanged +; Y = unchanged +; ==================== +MOCK2_PokeXY: + stx MOCK2_OR_A + jsr MOCK2_SetReg + sty MOCK2_OR_A + jmp MOCK2_SetData + +; ==================== +; Stop all sounds by setting all regs to zero +; ==================== +MOCK2_Stop: + LDX #mockN_off_data + ; NOTE: Intentional fall-into! + +; ==================== +; Plays one note by setting all Mockingboard registers +; IN: +; X = Low Address of registers +; Y = High Address of +; ==================== +MOCK2_Play: + STX _mock2_load_reg+1 ; *** SELF-MODIFIES! + STY _mock2_load_reg+2 +_mock2_all_regs: + ldy #0 + ldx #MOCK_REG_FIRST +_mock2_load_reg: + lda mockN_off_data,X ; *** SELF-MODIFIED! + jsr MOCK2_PokeXA + inx + cpx #MOCK_REG_NUM ; BUG: $B ! + bcc _mock2_load_reg + rts + +__END: +