From 47d14694c7d288c4e1f9b8e19628cfcbb7e97759 Mon Sep 17 00:00:00 2001 From: Jeremy Penner Date: Thu, 28 Sep 2023 22:07:10 -0400 Subject: [PATCH] PC speaker, timer reprogramming / ISR, fix IN and OUT instructions --- asm.jrt | 12 ++++----- assemble.com | Bin 12797 -> 12801 bytes beep.jrt | 27 ++++++++++++++++++++ common.jrt | 9 +++++++ readme.txt | 4 +-- swine.com | Bin 5303 -> 6108 bytes swine.jrt | 36 +++++++++++++++------------ timer.jrt | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++ zipoff.com | Bin 15462 -> 17237 bytes zipoff.jrt | 2 ++ zipstub.seg | Bin 829 -> 2052 bytes 11 files changed, 134 insertions(+), 24 deletions(-) create mode 100755 beep.jrt create mode 100755 common.jrt create mode 100755 timer.jrt diff --git a/asm.jrt b/asm.jrt index 7d34bbb..7fd4d3a 100755 --- a/asm.jrt +++ b/asm.jrt @@ -334,14 +334,14 @@ var ignoreimm : AX? oparg-reg? oparg-val @ 0x00 = and ; : >inout* ( base ) - arg2 oparg-reg? oparg-val @ 0x03 ( DX ) = and arg1 if + oparg-reg? oparg-val @ 0x03 ( DX ) = and swap-args if AL? if 8 + >t 2ret then AX? if 9 + >t 2ret then then - arg2 oparg-imm? arg1 if - AL? if >t oparg-val @ >t 2ret then - AX? if 1+ >t oparg-val @ >t 2ret then + swap-args oparg-imm? swap-args if + AL? if swap-args >t oparg-val @ >t 2ret then + AX? if swap-args 1+ >t oparg-val @ >t 2ret then then ; -2 :op IN 0xe4 >inout* ; -2 :op OUT 0xe6 >inout* ; +2 :op IN arg2 0xe4 >inout* ; +2 :op OUT 0xe6 >inout* ; diff --git a/assemble.com b/assemble.com index dd1bb142a095b72e3e606a656d4f70ddc11a71a8..c87cb60fd68bab3f367c210c7d99b3a0b7979d01 100755 GIT binary patch delta 217 zcmeyH+?b;BvP>vJ{i0#F!A*l0!%~GJnd?SN^y7{GYc+{YG*mZyZCGV=eWOYXD-)yf z=2fgIJd9H|^9#L_i?EO^mB?ZhVPa-TWSPcdArZi&YqZ}mfJxR!go%S;HS-cNR@Iw8 zzAli@3FTWzut#ITl8K|+M-3Bz~8V~j`i znHl^;Ll}NB-chQX+-ztedETglsa`ajxshWZb1u_%qY9=7<_GM@7#B>wVyFoKqdGr8 delta 213 zcmZon`J1frvP>vJ{i0#F!A*l0!%~GJnaf5?^ka?wYc+{YG*mZyZCGY>d80}TE7M=2 z&8t{bco-*a<`;S;7p5R#Az3Ps#VW$Y%#g@3jfGbtfJxtIzhMBAypaeK2g7RSC1R|q zH-UV8AfFS;SCC+l1gVS$tMoKlA_g)8rZU=Sa-gB4bfOUx!&*iWrY8*F4UaJ%(Pw7x w4-H}X#dt@lYI3`wh2&|Y4yJn1Z01IeeayK`n~f@%BA6erA7h*|`G%n;04Xd#5dZ)H diff --git a/beep.jrt b/beep.jrt new file mode 100755 index 0000000..a6ca975 --- /dev/null +++ b/beep.jrt @@ -0,0 +1,27 @@ +import timer.jrt + +:asm >spk ( div -- ) + MOV AL 0xb6 # + OUT 0x43 # AL + POP AX + OUT 0x42 # AL + MOV AL AH + OUT 0x42 # AL + IN AL 0x61 # + OR AL 0x03 # + OUT 0x61 # AL + NEXT + +:asm silence ( -- ) + IN AL 0x61 # + AND AL 0xfc # + OUT 0x61 # AL + NEXT + +: slide ( div count + -- ) + >r begin over >spk 1 sleep-csec swap r@ + swap 1- dup not until + rdrop drop drop silence ; +: boop ( div count -- ) swap >spk sleep-csec silence ; +: noise ( count -- ) + begin rand >spk 1 sleep-csec 1- dup not until drop silence ; + diff --git a/common.jrt b/common.jrt new file mode 100755 index 0000000..d10612c --- /dev/null +++ b/common.jrt @@ -0,0 +1,9 @@ +import text.jrt +import keys.jrt +import random.jrt + +: !+ ( v p -- ) dup @ AB2D$;TY4%hNy9(q&Bu`?KFln4oPj-$W5?H(^RCG z+E!5lY}!OFR+@rqp^bVC(2pn}QskTq$WS#=(8ZOjdP`M=fu=-&+yItPs@4cEgASiXSE~u5&SqYQEzHT@ekT=LaIc2kP?x~FPm2!$bEfzDCn56p&?wmd3CTogD6~_gLx>R9gQ=DoDzt?fE^@=F%3$f&H3CbwM>q)qwx38hADM z5W!CPSea5LM5lhFOfAimQ%ag6i*4NrM5B_RwQvUR58qUV*92b%+ldVDG_HNDJWN*r zn_Y0-vwV5DpONeko}TtyXopAmG?3K|7D1{YAuWAA`#oZ% z*qf?H&rvpx0g{ruKow;6JSow%KMgkGXR|t_yP(kboi;4e2KWj*-{-XsSfCvbQs_n6 zID)eP{~fqbJE1N>9g;iHt5#}6&EfKr=0Y}-(txG;YFqBKB-%a?qeEzu<}OeJP6Ktqy`mA{irR&`WMMm+Q-G1^ zrP=F5p=?ZTP@Te^^Uxe(E(OcrxZVj>I!(E>z_=Z1^(#K| z-GS6;K@pyFG@nQN=F$FH`azw%(XFkubvoEP7X~a*-wxB$cr=LZ7Do@*+ zka;)Hcm>M9V}@#sLKdowzv`l(7$5^p1~anIY}{jb$hxAC8Tf`#it=w7D~+w5wx5Q{ zOE@U{S)afx;HR-NU$V()5NYkOjW$8N=-(~elIcGJ)WR8f-vCBK;V>pMisNCw(1_zq zUW}`$=z!o$k*>hikmpw-{V=YUJbydj!aC!2z($|hh}UAD8J@3pDA^X+s;|*^8*dn6 zMtS&_K}s}}9y71vsmjbzIA;t#u9e!2CbepsH=5MD1c3uZdEn-7-eG>t%)lFFkC}y^ zm^<)CnqK#3;HWv`cVVYVw`D)Nrfw7OkUhyxc+VW*^kL(T;RYIBGreyjPs4j506S&U>i}oDb;BIzS$M$mZYWuFvxr6Bh^8J~ZK-(R zlvT+2PrlQ>Yq4dnKmhRVFm1p&kG4#R7)ouf#4y2V+K= zt;QV)VHx(CM$m)VQ4T6|i)u=r8!q4&MTg&ye<^;*cg6Q1*7I%H7XRwnuN1egZNg&S zBUQxlU4%Ms$4@BlqK+$cekOF*tbOWfR9b*aT9gMTF_;uw{ z{A_&P#-85qe7m@3bMbQPJX=H zniBpkiKF_fiT8CUF{U3({8|5X;<_@}Y&KT!i;Uw(7rxzbT^BLv^aab`C-|+zCy8ar zM6xZ}fH#u>FRYQo;2E==;Ui#)N2RrFS*_`Sjw&4MQj^%5&!9KyJCIzG7*3u}{5IK= a$R;uR53G_XQ>uMK!Pk8Q$!cF5qyHNz(8rws delta 2572 zcmYjTYitx%6rOWurn|HAo}JyIlCs7MrOL}dF~;Rxq`ZX!veJlacp2njTQ&F?;YTY5 zOlrXeTSHL7Ln0}QhR{SvkfmZsCxKu}g9MR8Fpa@T7Jd-xId^tTv$;FpJ@>rNxo76u zn3E$r%0zY~b|N9(k`^UFNCG5*B|%JrQ~^R7LP}KW5jQ~^qyZFF+C)j|V?-q!D&Q(5 z3v-o(vI%vRB|)oz6XVp?(7Ic*ywi~u@hq-=tX8S#l0@0Z>Ie3<%63Myqbv`k*@qNN z6!Sn*_nD5UNFgqw=;+sM_&5nul8{J(nTBf-AKJunb+UMqWns2juI8afOuwu_c5zqEBlmoDH}iqi?kG?LLnPfM zR-(xOjTk_q3g`)T6}*R$EcB|^B6%2#if^C_`jN;425dK9^Vm5xz>ko}0!;KGD$=|` zQiSO|4<6>vV^a}t0xY3GEA7DytwkJ*-lw!Wn4)!t$@C1Z88;^M(mDc$C^+Z3M>G8>ZBr zD+u~1NJ;$<)wg3g?rELKm51JN4g@_=?n4JsI+2emo(3x7cFc#5?vdU~)LFc zTwh&qs}kG&hMpRfqf02$Ci*}PmRz!fIXHmgWZ;G#8Msko>L8}JQ|-eO z!63ueu^>5MMvw#Q><-LN+_+HqopP|WrRFQ7EBH$Ll+E_h+ybq$RH%jvK*4rKsUyRy@n5205bz)v3xlQnO#`Q zgm6kGXJ0cipcn8u#C-+ai1>H`2NlS|bh8v?b5L!1e;OoA*E9>uOx4W6a`P#ZXyiYY zDhnIUF-YHRzGQCY+@egK_CAh+?W~FCtVE{4F__Y5&g5=2o3HTa7I`n%N|N_Vs7JGK z!Ndzm*Zw4W(}e@z2xp0hGEjzVe&{&g4@W#2*UZ9x65=XcOAGslB|f}rJ}mK2XB*{oGWi+E`0Ot=2Upi0JBUGRt5I>{LxS!_`=wuy_a)(y^3 zui08-WnsVdp_PMgtY-XCR)R*(!Wrw7>_dx1jei7nP&e{-LqjYLKU*!LBGu!CBaz}R zXfN8)#G#X%wU1r2XzcT01cHspu}HE-^a7S(w&QfLXtHPFIa{#1#T<;cgZ?LxdKR}y z9bxLWTDufOTWS}5z9e0d?xEQoyb_pPAp?r=rd%nfFdovJg)eL$rr}E29@`=Vo9W3p zcn^&PW}I+Y*oQe`Qh&^j<6B`G$EWQK^!HbxU^U-gwCkYCp2cyGE!nqu(h|yTYpvaG zS1SC1+tY9;k+TyRWrO}{-p1`-dn(6MF`#mu6#lNQ!y@i99H$LCtkJAzGvye^&1UN} z?r4uT^*G##fu2`^>f7YRoF37^m4i>6fjE$d_^DV=reSbc-#HZ4i`?}y4uzG1m5vXS zImLJC@HW#v2>f>^g_p0tf2A|N82dj+s^cts9LiI_v%@LFJ4@NfLkj_(|Pjvc%`8#@yD;;JHaY%VWSz^>!ccX32t!PkK z!5wDJi_&*a8alKG$Xx-8m(|R#PRy&WURb>d6_H5b$0#=@FLcisZ@3qXcihXyC+=@X zs~cBZH^*lu&quoPtEgK%jVsReQKUuDZ(Z@K+vSF1d3R#$X}oWg#^T!JwmyiDV)z(Q z${$NhM~t CLI PUSH AX ; + :timm ISR-DONE MOV AL 0x20 # OUT 0x20 # AL POP AX STI IRET ; + :timm CHAIN-ISR ( isr -- ) + POP AX + STI + JMP FAR CS: @+ ; } + +:asm get-cseg + PUSH CS + NEXT + +: isr>int ( isr -- int ) 2 cells + @ ; +: isr>code ( isr -- p ) 3 cells + ; +: uninstall-isr ( isr -- ) + >r r@ cell + @ r@ @ int intvect! ; +: install-isr ( isr -- ) + >r r@ isr>int intvect@ r@ ! r@ cell + ! + get-cseg r@ isr>code int intvect! ; + +var timer +0 irq :asmisr timer-isr + MOV AX CS: timer @+ + INC AX + MOV CS: timer @+ AX + AND AX 0x03 # + JZ 0 @> + ISR-DONE +0 <: + timer-isr CHAIN-ISR + +:asm set-timer-div ( div -- ) + MOV AL 0x36 # + OUT 0x43 # AL + POP AX + OUT 0x40 # AL + MOV AL AH + OUT 0x40 # AL + NEXT + +: sleep-csec ( cs -- ) + timer @ + begin dup timer @ <= until drop ; +: install-timer 0xffff 2 >> set-timer-div timer-isr install-isr ; +: uninstall-timer 0xffff set-timer-div timer-isr uninstall-isr ; + diff --git a/zipoff.com b/zipoff.com index fc20566053efa6e7f2757eeb9976669ae888ff14..11ee562634470141d719eafada4ebfd80525e33b 100755 GIT binary patch delta 4339 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 delta 2663 zcmYjTYfx0@8UDWaoV_S4C_Rf1G+8hR)ly*3-uJAq!eTJXC4fkDh+Sa8C3|6ZmrIaj z$0S2AO{URpurp1@{2*f!!w<5pnej(%HETnim`0%A&w}X> zo#%Pp>-U}adzatM^3|!z&nAkt+m|g@l?%#iu5r_hOY$t#e(3tI{iyv!{i6M}Wx_0Z zmMWjpz_2Itx~7Bky_v7Hhj}`#H*zJ57xcUMGntR| zPk=7S*!URRnGWQACq0%Y(!b1D-WAU6nZ1UKBG+dMi@pHxh#9TX$)VGe@fPQ4;2i(| z2sJ8Fc0?63f7`lQ>NS-(O2=8@ z*0`xeEG5rFs%NWtp_p>4dmb{UAF3}c3z&f|atUs*FYB}XLao3$_V=)__$L+9>1XO4 zrN1`MLCW~3a7_QU5P^(&3i^cWx-5SweYJjHszBDTe-GKZ&#Do@5ca%|ElH%^S_J_%WmCS;j$*n@0GRe z{^kyJL32~n9s8Yo56K1hEgt{novMfoJQ>7Zm-4ISWy5G;mLE^aI+hH_VvpjjuNxi` zJK?-M2k#Y9)=|v*5=B;_!_VY-jC!Bw4waGzNxvcKd#ZG*pcA;IvQUC^#WT7H2$plj zS^itIz^Zm9RS)7C%LX?`wf59UeEVzp(9C9EpN9> zrH{xJ`4NlAT;A?Bblsbtm#cY0`W?9}wbz19oYMMbk@b4JsFM}7?yN;%uBJ|vXE|ef zx}K(v_U;}wE!Xio*aixF))hD3WZg*0{=3ox{92uc4g1O2|QSG0gI*| zwiKljDC}DkBrqeQek!c$_rR90Trbw=tPasZ71bl^=Z{<0dh&O)qwoVXX<0m&9FIql zj`3HldDIYIkgu!D*NoZ>f7hzE-PGmt_V`eFn)fm$GJk8&VPvN;g~+0@*cg&m_<4(- zt~VD=Cy?L?Y|mh!`^aOh?f%wwU$eKzOR;D8l2u@P4ibKo8`F)}ZK-Mb1HNJv*-%`~ zc#-$p1U7^dGc8}{wKkENbL5&@SI&`D{uEjglL2!3w`z$^1mj3JtYR`H9!nxAfX|Wa z&XF=0wQXR@U_26v25?lTik zu=rZ92S8^>mTMz@zpcE(XV3B}9I0gk9^Y2Tl7aY0%~(8CbN3aHZ4OQqyn*i^p?b%( z6b^%klU zoLZX>33^b?@>>=Sb0tHO2xiaN{f5zkW9d!y@|4lRxm&F`h7rFgpby4*H7aeJv%Jg( zJT$DD-$e6GEOW&s@?bbYk6eNeRB;)^Ex4A@kUSEMqJgN%>S}HALp|4rz6LC};W8P91keW6?l_4%%mw zU_HFlso{gMXo8{|tW;d&6M;A#&N+2E&Jcd3i z81f&?7zl@P$QSt~w7={Wxhs&MPy8b^AHaSoJ6+l;_B%j?@>ID59u84d5AM}Thn^1w zhpU6}cyI_cgDuOgxKq|%e(nxtG0RCc)AjT*XGx0obsJcG>47aeh2Q&Wz8WAaoQeVP27T%2z zgxfCs!H-fq24R~USd7-iR^c?latf;weuz*ZSS!4Ua5q7_(1;m!AZifaLo|cvLE#dj zM-UwlKBX9{H7NX@VyIS37(i&=$#7pD74j6sboN={IV)$hnNA4BC=L+(sZiw>*tm+% z2<3{%8i#SZrsbatyA%!jGwEe+r-AM`_(f zZeI&;IYl-Y42O|y5PyPhL=wpI#gwAQpBNmhP?WZ8kr;60vB6km7*~M$Ix6`=&o}1u zpWLP}cdPTI7xbT+$t{Op mGiUiRx5y&2Lh$m%SFx7_?p@mdCUH76mPn2dd_NH!VgCbVGSA)s diff --git a/zipoff.jrt b/zipoff.jrt index 40b6ff3..d8bd29e 100755 --- a/zipoff.jrt +++ b/zipoff.jrt @@ -162,5 +162,7 @@ dbg" boot" MOV BP 0x00 # NEXT +} import common.jrt { + here s", zipstub.seg" s" zipoff.com" writeenv diff --git a/zipstub.seg b/zipstub.seg index 69721138384b7f7614f7504e5bd0b6792587cf7a..a99766938856cf72d606b509cea420cee66c28f6 100755 GIT binary patch delta 1240 zcmZ8gO-NKx6n@{k@80(+Q;7(QidNHL5f&6yT%}DVgJibQf+AjvmI+piT)h4mnu5TE z%pxeFXk$UxRAaxEnf<7v{h1X-KM;nCAee$mJLkTqOu`K3eBV9y-0z%s&TVzH^s*K~ zm6H`#U+JY(*ZAT%EQ|j>a;SFtMH)rcE>S~XBX&Ct85zYjImas#PR8CA;Umu03?ko0 z8gA^6(+J}!_Tnh9H0TEnTSI6#8d5`P1g?gsF->E-#te-jjhPz78YMo?IxQsOyHzC; z;;a$DDIJm&o|F`vXw+)VT>&dwA{$Ps8S;4SoO7ablhZNa{%D)5&PPnPh@=qmzRe0_ zK?H9YSRsWxV>j8&A||c@^k1)?%8FM6GOowkvm<4Z_V ziip&Eqv>YwzgmuMJEG#!Hpj!VVe994QP9cw2NqwgBlbO^8^nGhd&RI>H6;18U;QyQt2!dgHhf%A z@+SL~U?vI2ee?3wW43p**Ke}zeDVAd+u=L6ZzThAGFPv4Fwym}r03S)M;#?wT;tI9rI48qh6|O@NN0KV_ye8 zl>aJ!kRm3Obb%$!t26R^ocC%Ed*NW@&?1T{a~>1;RD@p}%{eemh&&2${UoNE#_K8a EAKd6+TmS$7 delta 7 OcmZn>*vq!TmKgvFSprA^