From 52cd458e768b8afb729ba4b3acec4832e35a19fc Mon Sep 17 00:00:00 2001 From: Wayne Warthen Date: Fri, 7 Jan 2022 14:06:15 -0800 Subject: [PATCH] Add PS2INFO - Replaced kbdinfo with more comprehensive ps2info - Started process of clarifying licensing --- Doc/ROM Applications.pdf | Bin 193894 -> 193895 bytes Doc/RomWBW Applications.pdf | Bin 229562 -> 229563 bytes Doc/RomWBW Architecture.pdf | Bin 447508 -> 447508 bytes Doc/RomWBW Disk Catalog.pdf | Bin 134794 -> 134793 bytes Doc/RomWBW Getting Started.pdf | Bin 271719 -> 277975 bytes ReadMe.md | 46 +- ReadMe.txt | 46 +- Source/Apps/Test/Build.cmd | 2 +- Source/Apps/Test/Clean.cmd | 2 +- Source/Apps/Test/Makefile | 2 +- Source/Apps/Test/kbdinfo/Build.cmd | 10 - Source/Apps/Test/kbdinfo/mseinfo.asm | 896 ------------------ Source/Apps/Test/ps2info/Build.cmd | 10 + .../Apps/Test/{kbdinfo => ps2info}/Clean.cmd | 0 .../Apps/Test/{kbdinfo => ps2info}/Makefile | 2 +- .../kbdinfo.asm => ps2info/ps2info.asm} | 640 +++++++++++-- Source/Apps/VGM/Tunes/filthy01.vgm | Bin 0 -> 27392 bytes Source/Doc/GettingStarted.md | 97 +- Source/Images/fd_zsdos.txt | 2 +- 19 files changed, 733 insertions(+), 1022 deletions(-) delete mode 100644 Source/Apps/Test/kbdinfo/Build.cmd delete mode 100644 Source/Apps/Test/kbdinfo/mseinfo.asm create mode 100644 Source/Apps/Test/ps2info/Build.cmd rename Source/Apps/Test/{kbdinfo => ps2info}/Clean.cmd (100%) rename Source/Apps/Test/{kbdinfo => ps2info}/Makefile (56%) rename Source/Apps/Test/{kbdinfo/kbdinfo.asm => ps2info/ps2info.asm} (53%) create mode 100644 Source/Apps/VGM/Tunes/filthy01.vgm diff --git a/Doc/ROM Applications.pdf b/Doc/ROM Applications.pdf index bdf95a31d360f324385c2a2582337d4ca9f002be..b1533de561942db48a49ad84e44d78774af6fa38 100644 GIT binary patch delta 10156 zcmai3ZEV)n6;Gc5+X?}n6hAnOYXyRs4eq(`mp5&B$=qgGHI8UT^og(!8r=%GOx95g zAlBJt5GyAaBxGWpfrORYeoKlA`n<%TO2!dLLjA_{RyVFv8&OaIbLhk=Q zzkA-#@1Fbm@u^3TPu+P{zT>v0OZ&QK^vpbc?8w8v9&Da@a?y=Tr!8K0U!L;4n^#}4 z^ADHp+qLHg-#YZ%{vE%(q<-R#8`ci@bnflDe5?JzS2wFK&c6NAFZREG^%W1Cx%YFw zz5nRryRO}GsQaQh-Jkiz!qK(&{Hf#oH7{JV=A}c|)=nNU>5VO)Sln^6eg3w`+<~)O z-#)$Zy`Sy*$@Zbyvu^I$^_6Sq9J%;A_bl;$+;H}t1;4-ey1RystvvJ0r7wiZ z-8Faf>P7puA8ejG>pa@^&$}i+`2J{r{Y3ZK#{JVjIQjY`pFRA;$&KFIPMuuW@r7-x z(s|y0fBls1o0mNM-MIJ1)9zgP?yK`pU3_ZCmW?M`rp+-o-O~QeSy%3U|AB|kEc@3B zGbgod?0M+$)`LHPYfeXdiu@gN&Ri-?>X|TYc8F=Fn{UBhxYC~aM{$&A57o<;9fe>Oo!>63vb!` z@+CX2y65F3kG?fy$JrmP?Or-#`OsreUH8f@YtBwy^~s+;+PwbObsINrSl`G)x~X|v zy|$xXYx+&SR=fN01zM3Z7w+=uEHHS}xE*3oGbgAbSJ960+;yJoklBo_I(Y6^zaUfasB*lIIpQ)`$o));ew` zgFNCo8u*H(k+S++UQ9oi_136lbLU?wylN4VJail~gUjiZw;}fz2=U1#&pk*gMJ^f< znUqHX(ZeB#pfZa{BA2)YiGt-$AWA536U!WF<+$4k)$yZq$1OwJIG6jLf?5JsdoM8} z302_)pGOLW2ux$NfK^^`SQVoVnVzmPu2X?SI7f*~;ez$37=Y;EQn=uSi@ma*8_g>h zxD&ibDl+5xm=r%FXt?3SedERrt`yU@15k^{LWBm~3Q;S|9Ug6rl)DN9KN6KdL_gU` zBDRbrl?Mw1HyYU#xfB$lXm5zRgkpjMDWwQ7B{L8Om~G-3X_x|)r9f~UwTecrA*m)p zC<>`mmTCyu)=>dP#n2Xix#<~5!S&WE8Lo)7N`$+%1VuV4AP7}hm{SKY%DeU{x!hkM zxJPs#C2WE2#^VyjJE}ZdAmk@UJY*q-=KBnRSLF7;R(T{y(;4L)4?)!bU~^xAke`x> z3sibhm5lY#<&jDVlDy1Vt+|)5hBTvt6^a<^L_T0GaQi?CIJLJx@TfD8k9)~jc$Gz` z@yWY942T}FJy}6nOi~g8RYce^N#cgSXTk5^JaSoGWe z0>Lu@#3ge3pnr-)blT#sFY4^+g|{LIMEr!t?$5cdAK=* zpw4{-LfFD7!D!L-MPmYhQ+cFPil9YwI)@6x;sV4$`AmPSvPJMB23!cdh9P2+B)PXh zaDRKH6Hh6JI|g4v6ID7717a>WlSfJk*xYy>w-pbPkK4-MaWD@BuvI}OO89bTc~iPT zSApQ6;8B{zc36a4(0fqxJXk4($JLb?+~Y{0BZ3Yk;zdXyPqZSJeT>`*sHTO6HVOpK z+dwf1<&tc)=-f*fdV07HKF}ZJQ3TGxD(e@#CXHy zrV&|=u-#e-3$7+09CreKE6Y(#PRy}l3S$?dbH>GwwZj+$GKr1@yKtvryBy5HSQ@pY zKrnH!9g{q!0)`uWehP|0U=HoCRQLytMDQ1^ab8>ID5z+C1%l^K0_kEAf$c$LF)lbN z<&grxT!-ywQ9=J1TRPUB<@?7J4h2-8$#|a5JC~OIH`!7z$Q$lP)iB~ z3o0mL1Z7BM1R+TnB~Wg|T(Lq5%tN^?$dj}gVd&XaAb5_JI}o!EBtsAg*yu1fEfB06 zQNX2%=Q83@T<@_4Me45sf}N;vvk{d7pd126A&zsSK*$qCQN(r>TdoK$co=m6f-@0p zN2w6oonVwni+L@6E2mybSA?Yw>Ld4jEcFd8+PM?FlSc_GgHAG0CY+_kR1^gb&m{c? zf*BXv!5Jn(U?8JpvE$& z$WJaX<*+^SISyV)5kh&OK#1+={VXo9U9femp=su(H>)756}1~8bDm5XRA5@tSs=uT z$R1Y1aEWldo?{JVJNFj|mLr6hr!nd`M)C}Jm%R6)S-{80|u#k&#K z5~v)VtdIgvPn=4EBH#wcG)C>fG^@8j$WLM-kLNF>5r+VmFnPE@2pvt}PuzGX6C?KW zb_T-V_Ewc5c;MhE0P4uO8T7@dE_YQzV1ywg^Nv5c5n&V_@?a$d7y)-GxGoj33&hzb)FqMkAm%9fM*U7{3xd= zTTSoaU{l21$UD23v{ z0ulqofZ1rJ6v#s!3L0-$0wQ`uQ~M~S;NgzfX@1Wmlv7~~Ozy4EeN_;6iWBwMmk4Hx z;AtMoIZ_~aDEJ8b^X-W^M*$;4jmY$Fg*hvRPoO^D^1#IiCQ$Az5ZqaqY6zMW0trV4 zP<;@LN-6MI$>Rdg0iwC!@)k{Qdk<0w0nw#+tYF+FDi5k3T6C=gueA~O%I2!bKk9HyN0Qx)wDS0p}2A>1zc`xn+whne&7YAo6gUiwAViiCUc zhrbX^W3>BSFdXRFKbPX5C8xG delta 11961 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 diff --git a/Doc/RomWBW Architecture.pdf b/Doc/RomWBW Architecture.pdf index 7e5baed75c8e50777c9abc4207a8892c6f2dc079..cf4ad4077501fb2046602066eb21cddad764e8d2 100644 GIT binary patch delta 600 zcmbQTLVC&y=?Qi9r}J(b2)KU#)fE}U?U(lBnqH~A8?#6*^TJ4x$Q|omNp!58GBNSX zduySmM@$1aF9bZ<+a4|>nA4CDdC@hsQpjL~xr9aIc0NtRHRV^|cTIfq$+gH#uX}Ux zydA%GBv)JykAG^X`%*Y`exi78=~qR89UUhFTE2y00 zbM&j)^|mX!(t`MJFO24IzjO8(!!gfCCnj4ORp~!7+-G?7&sx7FyZ-EX`+cjKp=Ngs zTYS;-;_o-s&Qq7#VE7`2Ay?{Ty>R#39KriNf?>voIBNMWFj#NVo1xi|9l%$yO6BIM zpQX<4#3w~C9Dh`Q`~5t=<`%8>r|-zmbBhbzHPyWMcHVT+3@86ED~XL8w<+`=PnPva zl)Gr3_T?Arskp@X=EfWU#7&Ud^l?G1OPbx*!zbOZPP;O{Hhj~Rl`+|xhn=_o&)1RD zZcn+Bx~}lO@%OK3+i%$|a`~-(Cbjl{SUqF@)NR){OER%!@tasACmAMLnwpuJnx~p1 zHS6ST*U4eL-GMIAF7}lXh?#(x8Hic7i+yD^o6BuvU}#`$Xl86~VlmxOn@OC<2uWmn z)g(46M`veOM@s{96JrBIQ#V&P3nvQ;Cu3&|H#buw10xGdLpM7G8$wE^f4|Ho3jhWM B02}}S delta 600 zcmbQTLVC&y=?Qi9{`pr71dhJ{DN?+JzbyTay?F$e_5^_d*DnngItO#YU*&bpzS@<4 zUgg}hTvZ{>vNzxF{dvTBNKD`w?>>pn`5Y`ydikath+b|e_~rMra%ZWZpF)ca*U#=Q zj@(hTUwwz%Ed84K+pk!L#vWO>>)ESVhk`)$X2D(Y2}-YK9AMLX#96;<{s-SXC*I#} zkIa~CX7|H0gPB_?{rn{VAXa5NJ5GHe=L=@LHh&1y>Q6GY&;S2)k{{+rDNL|r)17luMe|crnT=}?OX|yEh71ibGGTt*tw&4mucVeFy-Q_ zn@=Z8hWVWSv;0-P@f-O*W#+5bOC|gGgX4m&L$`UK&b!8|aYatIT>sUzTT+!)b5k4^ zo)-C=-1%<4(@AdIDQ_o5)a!cqP5!tb=ZZ^7UaRxQiDF0RJFn9zUFmW3aK&`~|3^2; z)i_*UZufjvR{W0m-0!pR?oHd0ZlHgBd+cZNuZy-RY?fqV$>L8-F*Z(2OExk$OH4LM zO=;H2*{+krc)J5#qFwAOBM>tIF*6XeY!~~=YBrbK(9p=h!qCjv(8OT6qc)Q`j}el{ z_Nqy2R*uf*My8HN1||k>hR%kLZmw>ohDI*NjwWUXu4Zmd=EfFw3O0n4O#gnFO%?$8 CZvSim diff --git a/Doc/RomWBW Disk Catalog.pdf b/Doc/RomWBW Disk Catalog.pdf index 93265d75bbe47c0a6bcd4f24328ccee2f99e5d1b..b9cc152b188cd2efe025292aa6ab4e2ae4659c02 100644 GIT binary patch delta 5385 zcmai&du-lS8OM2Fck4R_HeHd0%i7FJG{DYt?q@*d?brmILJ61!7+DRB#URp^0cMi& zh9F^JWDDb{tl5PTjd4pViUvlYAsM6!x=iHq2eX@o37SwY>(+7m9~84q?>L(1eTU+-VG{@a(mt-gHE*x}a4mz;9uid}!Z=`W8~n|kN3 zUEWwadq(Tlj(?qU)rV^~zIxBvi+(?FXyg2|%-5DyhjwoLrup@{yBga!??2&tr)_)o zoj>pB{Kn!-^NZ{6Uj4?|FTK0(z)xPhMPK>Jo~QR-vF5i6o_*=bw+{TZ`P84+UsyPH z;=ZOkPuPCWPyg99Hl_de4_5c>UACm_jLU!b_@kGf_tm#s)~vtQ4PSES;d$q`Ex7mf zN1lG?iSCErdd1qp1o<~xvdw+^M3TJ3s=t#^PjtB+RA_LJoJ?{tw*kU=GFJ-&00F;XT6)ZeWz#m z-b-#A?O!zS%K5dfi?>Z#*_ic%{nyu)U%lkzffbj&wrX_zho`R?oLhP7-IJdi|ETYg zuKzs$#ySc6Q**{8o=eSI(q=n2N=Z}q5 z&T1vOq+K2vtF&C;CoYlJDlighqg3GgOtL!DAs~b?C6^ zt=ck2Sx3Tl>%Gpqi(DB0Lj|Fj(M~zT0)2o`;XbEvr$kOl4t$^yrt{o_euVQ@Hkhye{!X0^|~1;HILRwvz>N>YOUoe7ynZb1 z6`cox=odyO6}e@WNHlV5qBscF_{1}ZFbb3KTRIxRlaAk`7Vf7F-BsxoLMGLFW4Y-d zDB7?E1Rix1kEm1|l}Nh9Rqi&7g21EbaLe;3I+U+)HyT`rb@Vrp9H*?PYuqe}SEDmV zp><4-2v%5zv%w?bys|2f6a+6+(8U$tT#CXuI6|4K)s_xPC&Np`KnB$pRK@R+L=|S9tm{}+oF90 z^d=VSvYjJfg;yc3D+s0$+fkAeHDY_r6V8wDZhO3XSTm?%|Y%E`M6g2e*!xD)3GGrD4`urH;Q+h+j5jK-*r@rs8t zdY+{+(&KH`TM%MEGXCoYtzqvc76hA8I2f{;srgj-fQDZ_-CD>Wc^_M=5J;~qOX z)mxcZ&l$2Fbly@BVhLr;TS^QtgIg9NX0p*q9f{To=OXrVL^8qT z`b=0M=qd5XBjF$MXe#e+hJ{ST0+!(_ z%XA_TEZ=2tJ$4%$8y)dMgc4VU3nJOv0D_OW=uP4k3|R~;bELiE9R)IceV7;o$Sf~a z$lS3$dHlpc7@W=Rvt)iq2l15xGVy+Z%p%3T1;IKwmT;W8X+ba2(P8Zi=C~9bWu|EE_492$9g@4gyR~Q4t#_=t RVMPu2NL1_SSajLq+Na80pL+lR delta 6311 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 Y4UY=-SuFug0LwXALR)*b!yJkK2mY>~h5!Hn delta 45384 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≺eI&g(aMBT2AxpN;IrTzc*D67nOU(^ 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 diff --git a/ReadMe.md b/ReadMe.md index 897958ea..ef48fca1 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -3,7 +3,7 @@ author: "Wayne Warthen (mailto:wwarthen@gmail.com)" classoption: - oneside colorlinks: true -date: 08 Dec 2021 +date: 03 Jan 2022 documentclass: book fontfamily: helvet fontsize: 12pt @@ -44,7 +44,7 @@ toc-depth: 1 ## Z80/Z180 System Software Version 3.1 Pre-release -08 Dec 2021 +03 Jan 2022 Wayne Warthen @@ -1357,6 +1357,48 @@ applications are no longer provided. Contributions of all kinds to RomWBW are very welcome. +# Licensing + +RomWBW is free software: you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation, either version 3 of the License, or (at your +option) any later version. + +RomWBW is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +more details. + +You should have received a copy of the GNU General Public License along +with RomWBW. If not, see . + +Portions of RomWBW were created by, contributed by, or derived from the +work of others. It is believed that these works are being used in +accordance with the intentions and/or licensing of their creators. + +If anyone feels their work is being used outside of it’s intended +licensing, please notify: + + Wayne Warthen + wwarthen@gmail.com + +RomWBW is an aggregate work. It is composed of many individual, +standalone programs that are distributed as a whole to function as a +cohesive system. Each program may have it’s own licensing which may be +different from other programs within the aggregate. + +In some cases, a single program (e.g., CP/M Operating System) is +composed of multiple components with different licenses. It is believed +that in all such cases the licenses are compatible with GPL version 3. + +RomWBW encourages code contributions from others. Contributors may +assert their own copyright in their contributions by annotating the +contributed source code appropriately. Contributors are further +encouraged to submit their contributions via the RomWBW source code +control system to ensure their contributions are clearly documented. + +All contributions to RomWBW are subject to this license. + # Getting Assistance The best way to get assistance with RomWBW or any aspect of the diff --git a/ReadMe.txt b/ReadMe.txt index 2bc55874..22459a57 100644 --- a/ReadMe.txt +++ b/ReadMe.txt @@ -1,6 +1,6 @@ RomWBW Getting Started Wayne Warthen (mailto:wwarthen@gmail.com) -08 Dec 2021 +03 Jan 2022 @@ -17,7 +17,7 @@ RomWBW Z80/Z180 System Software Version 3.1 Pre-release -08 Dec 2021 +03 Jan 2022 Wayne Warthen wwarthen@gmail.com @@ -1360,6 +1360,48 @@ applications are no longer provided. Contributions of all kinds to RomWBW are very welcome. +Licensing + +RomWBW is free software: you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation, either version 3 of the License, or (at your +option) any later version. + +RomWBW is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +more details. + +You should have received a copy of the GNU General Public License along +with RomWBW. If not, see https://www.gnu.org/licenses/. + +Portions of RomWBW were created by, contributed by, or derived from the +work of others. It is believed that these works are being used in +accordance with the intentions and/or licensing of their creators. + +If anyone feels their work is being used outside of it’s intended +licensing, please notify: + + Wayne Warthen + wwarthen@gmail.com + +RomWBW is an aggregate work. It is composed of many individual, +standalone programs that are distributed as a whole to function as a +cohesive system. Each program may have it’s own licensing which may be +different from other programs within the aggregate. + +In some cases, a single program (e.g., CP/M Operating System) is +composed of multiple components with different licenses. It is believed +that in all such cases the licenses are compatible with GPL version 3. + +RomWBW encourages code contributions from others. Contributors may +assert their own copyright in their contributions by annotating the +contributed source code appropriately. Contributors are further +encouraged to submit their contributions via the RomWBW source code +control system to ensure their contributions are clearly documented. + +All contributions to RomWBW are subject to this license. + Getting Assistance The best way to get assistance with RomWBW or any aspect of the diff --git a/Source/Apps/Test/Build.cmd b/Source/Apps/Test/Build.cmd index 139ea0c9..fb322d6b 100644 --- a/Source/Apps/Test/Build.cmd +++ b/Source/Apps/Test/Build.cmd @@ -21,7 +21,7 @@ pushd I2C && call Build || exit /b & popd pushd rzsz && call Build || exit /b & popd pushd vdctest && call Build || exit /b & popd pushd kbdtest && call Build || exit /b & popd -pushd kbdinfo && call Build || exit /b & popd +pushd ps2info && call Build || exit /b & popd goto :eof diff --git a/Source/Apps/Test/Clean.cmd b/Source/Apps/Test/Clean.cmd index 3cb2cdfa..9e1f36d9 100644 --- a/Source/Apps/Test/Clean.cmd +++ b/Source/Apps/Test/Clean.cmd @@ -16,4 +16,4 @@ pushd I2C && call Clean || exit /b 1 & popd pushd rzsz && call Clean || exit /b 1 & popd pushd vdctest && call Clean || exit /b 1 & popd pushd kbdtest && call Clean || exit /b 1 & popd -pushd kbdinfo && call Clean || exit /b 1 & popd +pushd ps2info && call Clean || exit /b 1 & popd diff --git a/Source/Apps/Test/Makefile b/Source/Apps/Test/Makefile index 3c844c01..aed32df2 100644 --- a/Source/Apps/Test/Makefile +++ b/Source/Apps/Test/Makefile @@ -1,5 +1,5 @@ OBJECTS = -SUBDIRS = DMAmon I2C inttest ppidetst ramtest tstdskng rzsz vdctest kbdtest kbdinfo +SUBDIRS = DMAmon I2C inttest ppidetst ramtest tstdskng rzsz vdctest kbdtest ps2info DEST = ../../../Binary/Apps/Test TOOLS =../../../Tools diff --git a/Source/Apps/Test/kbdinfo/Build.cmd b/Source/Apps/Test/kbdinfo/Build.cmd deleted file mode 100644 index 1f9866d6..00000000 --- a/Source/Apps/Test/kbdinfo/Build.cmd +++ /dev/null @@ -1,10 +0,0 @@ -@echo off -setlocal - -set TOOLS=../../../../Tools -set PATH=%TOOLS%\tasm32;%PATH% -set TASMTABS=%TOOLS%\tasm32 - -tasm -t180 -g3 -fFF kbdinfo.asm kbdinfo.com kbdinfo.lst || exit /b - -copy /Y kbdinfo.com ..\..\..\..\Binary\Apps\Test\ || exit /b diff --git a/Source/Apps/Test/kbdinfo/mseinfo.asm b/Source/Apps/Test/kbdinfo/mseinfo.asm deleted file mode 100644 index 506aeacf..00000000 --- a/Source/Apps/Test/kbdinfo/mseinfo.asm +++ /dev/null @@ -1,896 +0,0 @@ -; -;======================================================================= -; Mouse Information Utility (MSEINFO) -;======================================================================= -; -; Simple utility that attempts to determine the status of the mouse you -; have attached to an 8242 keyboard controller. -; -; Based on Wayne Warthen's KBDINFO program, Thanks to his great work -; on RomWBW and support to the Retrobrewcomputers community at large -; -; Additional help from these websites -; https://isdaman.com/alsos/hardware/mouse/ps2interface.htm -; -; Second PS/2 write data port info from -; https://wiki.osdev.org/%228042%22_PS/2_Controller#Second_PS.2F2_Port -; -; PS/2 Mouse initialization code in C -; http://bos.asmhackers.net/docs/mouse/snippet_2/mouse.inc -; -;======================================================================= -; -; Mouse controller port addresses (adjust as needed) -; -iocmd .equ $E3 ; keyboard controller command port address -iodat .equ $E2 ; keyboard controller data port address -; -; General operational equates (should not requre adjustment) -; -stksiz .equ $40 ; Working stack size -; -timeout .equ $00 ; Controller timeout constant -; -restart .equ $0000 ; CP/M restart vector -bdos .equ $0005 ; BDOS invocation vector -; -;======================================================================= -; - .org $100 ; standard CP/M executable -; -; - ; setup stack (save old value) - ld (stksav),sp ; save stack - ld sp,stack ; set new stack -; - call crlf - ld de,str_banner ; banner - call prtstr -; - call main ; do the real work -; -exit: - call crlf2 - ld de,str_exit - call prtstr - ;call crlf - - ; clean up and return to command processor - call crlf ; formatting - ld sp,(stksav) ; restore stack - jp restart ; return to CP/M via restart -; -; -;======================================================================= -; Main Program -;======================================================================= -; -main: -; -; Display active mouse controller port addresses -; - call crlf2 - ld de,str_cmdport - call prtstr - ld a,iocmd - call prthex - call crlf - ld de,str_dataport - call prtstr - ld a,iodat - call prthex -; -; Attempt self-test command on mouse controller -; -; Mouse controller should respond with an 0x55 on data port -; after being sent a 0xAA on the command port. -; - call crlf2 - ld de,str_ctrl_test - call prtstr - ld a,$aa ; self-test command - call put_cmd_dbg - jp c,err_ctlr_io ; handle controller error - call get_data_dbg - jp c,err_ctlr_io ; handle controller error - cp $55 ; expected value? - jp nz,err_ctlr_test ; handle self-test error - call crlf - ld de,str_ctrl_test_ok - call prtstr -; -; Send 0xA8 Mouse Enable command to 8242 controller -; - call crlf2 - ld de,str_enable_mouse - call prtstr - - ld a,$a8 ; Send Mouse Enable command to 8242 - call put_cmd_dbg - jp c,err_ctlr_io ; handle controller error - - call get_data_dbg ; Read Mouse for self-test status - jp c,err_ctlr_io ; handle controller error - cp $AA ; expected value? - jp nz,err_ctlr_test ; handle self-test error - call crlf - - call get_data_dbg ; Read Mouse for Mouse ID - jp c,err_ctlr_io ; handle controller error - cp $00 ; expected value? - jp nz,err_ctlr_test ; handle self-test error - call crlf - - - -; -; Disable translation on keyboard controller to get raw scan codes! Enable Mouse -; -; call crlf2 -; ld de,str_trans_off -; call prtstr -; ld a,$60 ; write to command register 0 -; call put_cmd_dbg -; jp c,err_ctlr_io ; handle controller error -; ld a,$00 ; xlat disabled, mouse enabled, no ints -; call put_cmd_dbg -; jp c,err_ctlr_io ; handle controller error - -; Attempt four reset commands on mouse controller -; - call crlf2 - ld de,str_mse_init - call prtstr - -; Reset Pass #1 - ld a,$ff ; Send Mouse Reset command - call put_data_dbg - jp c,err_ctlr_io ; handle controller error - - call get_data_dbg ; Read Mouse for Acknowledge - jp c,err_ctlr_io ; handle controller error - cp $fa ; expected value? - jp nz,err_ctlr_test ; handle self-test error - call crlf - ld de,str_ctrl_test_ok - call prtstr - - call get_data_dbg ; Read Mouse for self-test status - jp c,err_ctlr_io ; handle controller error - cp $AA ; expected value? - jp nz,err_ctlr_test ; handle self-test error - call crlf - - call get_data_dbg ; Read Mouse for Mouse ID - jp c,err_ctlr_io ; handle controller error - cp $00 ; expected value? - jp nz,err_ctlr_test ; handle self-test error - call crlf - -; Reset Pass #2 - ld a,$ff ; Send Mouse Reset command - call put_data_dbg - jp c,err_ctlr_io ; handle controller error - - call get_data_dbg ; Read Mouse for Acknowledge - jp c,err_ctlr_io ; handle controller error - cp $fa ; expected value? - jp nz,err_ctlr_test ; handle self-test error - call crlf - ld de,str_ctrl_test_ok - call prtstr - - call get_data_dbg ; Read Mouse for self-test status - jp c,err_ctlr_io ; handle controller error - cp $AA ; expected value? - jp nz,err_ctlr_test ; handle self-test error - call crlf - - call get_data_dbg ; Read Mouse for Mouse ID - jp c,err_ctlr_io ; handle controller error - cp $00 ; expected value? - jp nz,err_ctlr_test ; handle self-test error - call crlf - -; Reset Pass #3 - ld a,$ff ; Send Mouse Reset command - call put_data_dbg - jp c,err_ctlr_io ; handle controller error - - call get_data_dbg ; Read Mouse for Acknowledge - jp c,err_ctlr_io ; handle controller error - cp $fa ; expected value? - jp nz,err_ctlr_test ; handle self-test error - call crlf - ld de,str_ctrl_test_ok - call prtstr - - call get_data_dbg ; Read Mouse for self-test status - jp c,err_ctlr_io ; handle controller error - cp $AA ; expected value? - jp nz,err_ctlr_test ; handle self-test error - call crlf - - call get_data_dbg ; Read Mouse for Mouse ID - jp c,err_ctlr_io ; handle controller error - cp $00 ; expected value? - jp nz,err_ctlr_test ; handle self-test error - call crlf - -; Reset Pass #4 - ld a,$ff ; Send Mouse Reset command - call put_data_dbg - jp c,err_ctlr_io ; handle controller error - - call get_data_dbg ; Read Mouse for Acknowledge - jp c,err_ctlr_io ; handle controller error - cp $fa ; expected value? - jp nz,err_ctlr_test ; handle self-test error - call crlf - ld de,str_ctrl_test_ok - call prtstr - - call get_data_dbg ; Read Mouse for self-test status - jp c,err_ctlr_io ; handle controller error - cp $AA ; expected value? - jp nz,err_ctlr_test ; handle self-test error - call crlf - - call get_data_dbg ; Read Mouse for Mouse ID - jp c,err_ctlr_io ; handle controller error - cp $00 ; expected value? - jp nz,err_ctlr_test ; handle self-test error - call crlf - -; Begin setting mouse parameters, Request Microsoft Scrolling Mouse Mode - - ld a,$f3 ; Send Set Sample Rate command - call put_data_dbg - jp c,err_ctlr_io ; handle controller error - - call get_data_dbg ; Read Mouse for Acknowledge - jp c,err_ctlr_io ; handle controller error - cp $fa ; expected value? - jp nz,err_ctlr_test ; handle self-test error - call crlf - ld de,str_ctrl_test_ok - call prtstr - - ld a,$c8 ; Send Decimal 200 command - call put_data_dbg - jp c,err_ctlr_io ; handle controller error - - call get_data_dbg ; Read Mouse for Acknowledge - jp c,err_ctlr_io ; handle controller error - cp $fa ; expected value? - jp nz,err_ctlr_test ; handle self-test error - call crlf - ld de,str_ctrl_test_ok - call prtstr - - ld a,$f3 ; Send Set Sample Rate command - call put_data_dbg - jp c,err_ctlr_io ; handle controller error - - call get_data_dbg ; Read Mouse for Acknowledge - jp c,err_ctlr_io ; handle controller error - cp $fa ; expected value? - jp nz,err_ctlr_test ; handle self-test error - call crlf - ld de,str_ctrl_test_ok - call prtstr - - ld a,$64 ; Send Decimal 100 command - call put_data_dbg - jp c,err_ctlr_io ; handle controller error - - call get_data_dbg ; Read Mouse for Acknowledge - jp c,err_ctlr_io ; handle controller error - cp $fa ; expected value? - jp nz,err_ctlr_test ; handle self-test error - call crlf - ld de,str_ctrl_test_ok - call prtstr - - ld a,$f3 ; Send Set Sample Rate command - call put_data_dbg - jp c,err_ctlr_io ; handle controller error - - call get_data_dbg ; Read Mouse for Acknowledge - jp c,err_ctlr_io ; handle controller error - cp $fa ; expected value? - jp nz,err_ctlr_test ; handle self-test error - call crlf - ld de,str_ctrl_test_ok - call prtstr - - ld a,$50 ; Send Decimal 80 command - call put_data_dbg - jp c,err_ctlr_io ; handle controller error - - call get_data_dbg ; Read Mouse for Acknowledge - jp c,err_ctlr_io ; handle controller error - cp $fa ; expected value? - jp nz,err_ctlr_test ; handle self-test error - call crlf - ld de,str_ctrl_test_ok - call prtstr - - ld a,$f2 ; Send Read Device Type command - call put_data_dbg - jp c,err_ctlr_io ; handle controller error - - call get_data_dbg ; Read Mouse for Acknowledge - jp c,err_ctlr_io ; handle controller error - cp $fa ; expected value? - jp nz,err_ctlr_test ; handle self-test error - call crlf - ld de,str_ctrl_test_ok - call prtstr - - call get_data_dbg ; Read Mouse for Mouse ID - jp c,err_ctlr_io ; handle controller error - cp $03 ; detect MS Intellimouse/Microsoft Scrolling Mouse - jp z,Intellimouse - cp $00 ; expected value? ($00 if Regular PS/2 Mouse) - jp z,ReadMouseID -Intellimouse: - call crlf - ld de,str_intellimouse_ok - call prtstr -ReadMouseID: - jp nz,err_ctlr_test ; handle self-test error - call crlf - - ld a,$f3 ; Send Set Sample Rate command - call put_data_dbg - jp c,err_ctlr_io ; handle controller error - - call get_data_dbg ; Read Mouse for Acknowledge - jp c,err_ctlr_io ; handle controller error - cp $fa ; expected value? - jp nz,err_ctlr_test ; handle self-test error - call crlf - ld de,str_ctrl_test_ok - call prtstr - - ld a,$0a ; Send Decimal 10 command - call put_data_dbg - jp c,err_ctlr_io ; handle controller error - - call get_data_dbg ; Read Mouse for Acknowledge - jp c,err_ctlr_io ; handle controller error - cp $fa ; expected value? - jp nz,err_ctlr_test ; handle self-test error - call crlf - ld de,str_ctrl_test_ok - call prtstr - - ld a,$f2 ; Send Read Device Type command - call put_data_dbg - jp c,err_ctlr_io ; handle controller error - - call get_data_dbg ; Read Mouse for Acknowledge - jp c,err_ctlr_io ; handle controller error - cp $fa ; expected value? - jp nz,err_ctlr_test ; handle self-test error - call crlf - ld de,str_ctrl_test_ok - call prtstr - - call get_data_dbg ; Read Mouse for Mouse ID - jp c,err_ctlr_io ; handle controller error - cp $03 ; detect MS Intellimouse/Microsoft Scrolling Mouse - jp z,Intellimouse2 - cp $00 ; expected value? ($00 if Regular PS/2 Mouse) - jp z,ReadMouseID2 -Intellimouse2: - call crlf - ld de,str_intellimouse_ok - call prtstr -ReadMouseID2: - jp nz,err_ctlr_test ; handle self-test error - call crlf - - ld a,$e8 ; Send Set Resolution command - call put_data_dbg - jp c,err_ctlr_io ; handle controller error - - call get_data_dbg ; Read Mouse for Acknowledge - jp c,err_ctlr_io ; handle controller error - cp $fa ; expected value? - jp nz,err_ctlr_test ; handle self-test error - call crlf - ld de,str_ctrl_test_ok - call prtstr - - ld a,$03 ; Send 8 Counts/mm command - call put_data_dbg - jp c,err_ctlr_io ; handle controller error - - call get_data_dbg ; Read Mouse for Acknowledge - jp c,err_ctlr_io ; handle controller error - cp $fa ; expected value? - jp nz,err_ctlr_test ; handle self-test error - call crlf - ld de,str_ctrl_test_ok - call prtstr - - ld a,$e6 ; Send Set Scaling 1:1 command - call put_data_dbg - jp c,err_ctlr_io ; handle controller error - - call get_data_dbg ; Read Mouse for Acknowledge - jp c,err_ctlr_io ; handle controller error - cp $fa ; expected value? - jp nz,err_ctlr_test ; handle self-test error - call crlf - ld de,str_ctrl_test_ok - call prtstr - - ld a,$f3 ; Send Set Sample Rate command - call put_data_dbg - jp c,err_ctlr_io ; handle controller error - - call get_data_dbg ; Read Mouse for Acknowledge - jp c,err_ctlr_io ; handle controller error - cp $fa ; expected value? - jp nz,err_ctlr_test ; handle self-test error - call crlf - ld de,str_ctrl_test_ok - call prtstr - - ld a,$28 ; Send Decimal 40 command - call put_data_dbg - jp c,err_ctlr_io ; handle controller error - - call get_data_dbg ; Read Mouse for Acknowledge - jp c,err_ctlr_io ; handle controller error - cp $fa ; expected value? - jp nz,err_ctlr_test ; handle self-test error - call crlf - ld de,str_ctrl_test_ok - call prtstr - - ld a,$f4 ; Send Enable command - call put_data_dbg - jp c,err_ctlr_io ; handle controller error - - call get_data_dbg ; Read Mouse for Acknowledge - jp c,err_ctlr_io ; handle controller error - cp $fa ; expected value? - jp nz,err_ctlr_test ; handle self-test error - call crlf - ld de,str_ctrl_test_ok - call prtstr - -; Initialization Complete - -ReadMousePackets: - -; call check_read -; jp nz, ReadMousePackets - - call get_data_dbg ; Read Mouse for self-test status - jp c,err_ctlr_io ; handle controller error - call crlf - - call get_data_dbg ; Read Mouse for Mouse ID - jp c,err_ctlr_io ; handle controller error - call crlf - - call get_data_dbg ; Read Mouse for Mouse ID - jp c,err_ctlr_io ; handle controller error - call crlf - - call crlf - - jp ReadMousePackets - -; -done: - ret - -; -;======================================================================= -; Mouse Controller I/O Routines -;======================================================================= -; -wait_write: -; -; Wait for mouse controller to be ready for a write -; A=0 indicates success (ZF set) -; - ld b,timeout ; setup timeout constant -wait_write1: - in a,(iocmd) ; get status - ld c,a ; save status - and $02 ; isolate input buf status bit - ret z ; 0 means ready, all done - call delay ; wait a bit - djnz wait_write1 ; loop until counter exhausted - ld de,str_timeout_write ; write timeout message - call crlf - call prtstr - ld a,c ; recover last status value - call prthex - or $ff ; signal error - ret -; -wait_read: -; -; Wait for mouse controller to be ready to read a byte -; A=0 indicates success (ZF set) -; - ld b,timeout ; setup timeout constant -wait_read1: - in a,(iocmd) ; get status - ld c,a ; save status - and $01 ; isolate input buf status bit - xor $01 ; invert so 0 means ready - ret z ; if 0, all done - call delay ; wait a bit - djnz wait_read1 ; loop until counter exhausted - ld de,str_timeout_read ; write timeout message - call crlf - call prtstr - ld a,c ; recover last status value - call prthex - or $ff ; signal error - ret -; -check_read: -; -; Check for data ready to read -; A=0 indicates data available (ZF set) -; - in a,(iocmd) ; get status - and $01 ; isolate input buf status bit - xor $01 ; invert so 0 means ready - ret -; -put_cmd: -; -; Put a cmd byte from A to the mouse interface with timeout -; CF set indicates timeout error -; - ld e,a ; save incoming value - call wait_write ; wait for controller ready - jr z,put_cmd1 ; if ready, move on - scf ; else, signal timeout error - ret ; and bail out -put_cmd1: - ld a,e ; recover value to write - out (iocmd),a ; write it - or a ; clear CF for success - ret -; -put_cmd_dbg: - call put_cmd - ret c - push af - call crlf - ld de,str_put_cmd - call prtstr - call prthex - pop af - ret -; -put_data: -; -; Put a data byte from A to the mouse interface with timeout -; CF set indicates timeout error -; -; note: direct data to second PS/2 port, send $d4 to 8242 command register -; different than keyboard which uses first PS/2 port - - push af ; save contents of a - ld e,a ; save incoming value - call wait_write ; wait for controller ready - jr z,put_data0 ; if ready, move on - scf ; else, signal timeout error - ret ; and bail out -put_data0: - ld a,$d4 ; direct to second PS/2 port for mouse - out (iocmd),a ; send second port command to 8242 - pop af - -; rest of put_data is the same as for PS/2 keyboard - - ld e,a ; save incoming value - call wait_write ; wait for controller ready - jr z,put_data1 ; if ready, move on - scf ; else, signal timeout error - ret ; and bail out -put_data1: - ld a,e ; recover value to write - out (iodat),a ; write it - or a ; clear CF for success - ret -; -put_data_dbg: - call put_data - ret c - push af - call crlf - ld de,str_put_data - call prtstr - call prthex - pop af - ret - -; -; Get a data byte from the mouse interface to A with timeout -; CF set indicates timeout error -; -get_data: -; - call wait_read ; wait for byte to be ready - jr z,get_data1 ; if ready, move on - scf ; else signal timeout error - ret ; and bail out -get_data1: - in a,(iodat) ; get data byte - or a ; clear CF for success - ret -; -get_data_dbg: - call get_data - ret c - push af - call crlf - ld de,str_get_data - call prtstr - call prthex - pop af - ret -; -; Error Handlers -; -err_ctlr_io: - ld de,str_err_ctrl_io - jr err_ret -; -err_ctlr_test: - ld de,str_err_ctrl_test - jr err_ret -; -err_mse_reset: - ld de,str_err_mse_reset - jr err_ret -; -err_ret: - call crlf2 - call prtstr - or $ff ; signal error - ret -; -;======================================================================= -; Utility Routines -;======================================================================= -; -; -; Print character in A without destroying any registers -; -prtchr: - push bc ; save registers - push de - push hl - ld e,a ; character to print in E - ld c,$02 ; BDOS function to output a character - call bdos ; do it - pop hl ; restore registers - pop de - pop bc - ret -; -prtdot: -; - ; shortcut to print a dot preserving all regs - push af ; save af - ld a,'.' ; load dot char - call prtchr ; print it - pop af ; restore af - ret ; done -; -; Print a zero terminated string at (de) without destroying any registers -; -prtstr: - push af - push de -; -prtstr1: - ld a,(de) ; get next char - or a - jr z,prtstr2 - call prtchr - inc de - jr prtstr1 -; -prtstr2: - pop de ; restore registers - pop af - ret -; -; Print the value in A in hex without destroying any registers -; -prthex: - push af ; save AF - push de ; save DE - call hexascii ; convert value in A to hex chars in DE - ld a,d ; get the high order hex char - call prtchr ; print it - ld a,e ; get the low order hex char - call prtchr ; print it - pop de ; restore DE - pop af ; restore AF - ret ; done -; -; print the hex word value in hl -; -prthexword: - push af - ld a,h - call prthex - ld a,l - call prthex - pop af - ret -; -; print the hex dword value in de:hl -; -prthex32: - push bc - push de - pop bc - call prthexword - push hl - pop bc - call prthexword - pop bc - ret -; -; Convert binary value in A to ascii hex characters in DE -; -hexascii: - ld d,a ; save A in D - call hexconv ; convert low nibble of A to hex - ld e,a ; save it in E - ld a,d ; get original value back - rlca ; rotate high order nibble to low bits - rlca - rlca - rlca - call hexconv ; convert nibble - ld d,a ; save it in D - ret ; done -; -; Convert low nibble of A to ascii hex -; -hexconv: - and $0F ; low nibble only - add a,$90 - daa - adc a,$40 - daa - ret -; -; Print value of A or HL in decimal with leading zero suppression -; Use prtdecb for A or prtdecw for HL -; -prtdecb: - push hl - ld h,0 - ld l,a - call prtdecw ; print it - pop hl - ret -; -prtdecw: - push af - push bc - push de - push hl - call prtdec0 - pop hl - pop de - pop bc - pop af - ret -; -prtdec0: - ld e,'0' - ld bc,-10000 - call prtdec1 - ld bc,-1000 - call prtdec1 - ld bc,-100 - call prtdec1 - ld c,-10 - call prtdec1 - ld e,0 - ld c,-1 -prtdec1: - ld a,'0' - 1 -prtdec2: - inc a - add hl,bc - jr c,prtdec2 - sbc hl,bc - cp e - ret z - ld e,0 - call prtchr - ret -; -; Start a new line -; -crlf2: - call crlf ; two of them -crlf: - push af ; preserve AF - ld a,13 ; - call prtchr ; print it - ld a,10 ; - call prtchr ; print it - pop af ; restore AF - ret -; -; Brief delay -; -delay: - push bc - ld b,0 -delay1: - ex (sp),hl - ex (sp),hl - ex (sp),hl - ex (sp),hl - ex (sp),hl - ex (sp),hl - ex (sp),hl - ex (sp),hl - djnz delay1 - pop bc - ret -; -;======================================================================= -; Constants -;======================================================================= -; -str_banner .db "Mouse Information, v0.1",0 -str_exit .db "Done, Thank you for using MSEINFO!",0 -str_cmdport .db "Mouse Controller Command Port: 0x",0 -str_dataport .db "Mouse Controller Data Port: 0x",0 -str_timeout_write .db "Mouse Controller Write Timeout, Status: 0x",0 -str_timeout_read .db "Mouse Controller Read Timeout, Status: 0x",0 -str_err_ctrl_io .db "Mouse Controller I/O Failure",0 -str_err_ctrl_test .db "Mouse Controller Self-Test Failed",0 -str_put_cmd .db "Sent Command 0x",0 -str_put_data .db "Sent Data 0x",0 -str_get_data .db "Got Data 0x",0 -str_ctrl_test .db "Attempting Controller Self-Test",0 -str_mse_init .db "Attempting Mouse Initialization",0 -str_enable_mouse .db "Enabling Mouse in 8242 Controller",0 -str_ctrl_test_ok .db "Controller Self-Test OK",0 -str_intellimouse_ok .db "MS Intellimouse OK",0 -str_trans_off .db "Disabling Controller Translation",0 -str_mse_reset .db "Attempting Mouse Reset",0 -str_mse_reset_ok .db "Mouse Reset OK",0 -str_err_mse_reset .db "Mouse Reset Failed",0 -; -;======================================================================= -; Working data -;======================================================================= -; -stksav .dw 0 ; stack pointer saved at start - .fill stksiz,0 ; stack -stack .equ $ ; stack top -; -workbuf .fill 8 -workbuf_len .db 0 -; -;======================================================================= -; - .end - diff --git a/Source/Apps/Test/ps2info/Build.cmd b/Source/Apps/Test/ps2info/Build.cmd new file mode 100644 index 00000000..965883ce --- /dev/null +++ b/Source/Apps/Test/ps2info/Build.cmd @@ -0,0 +1,10 @@ +@echo off +setlocal + +set TOOLS=../../../../Tools +set PATH=%TOOLS%\tasm32;%PATH% +set TASMTABS=%TOOLS%\tasm32 + +tasm -t180 -g3 -fFF ps2info.asm ps2info.com ps2info.lst || exit /b + +copy /Y ps2info.com ..\..\..\..\Binary\Apps\Test\ || exit /b diff --git a/Source/Apps/Test/kbdinfo/Clean.cmd b/Source/Apps/Test/ps2info/Clean.cmd similarity index 100% rename from Source/Apps/Test/kbdinfo/Clean.cmd rename to Source/Apps/Test/ps2info/Clean.cmd diff --git a/Source/Apps/Test/kbdinfo/Makefile b/Source/Apps/Test/ps2info/Makefile similarity index 56% rename from Source/Apps/Test/kbdinfo/Makefile rename to Source/Apps/Test/ps2info/Makefile index 3525056d..33330b47 100644 --- a/Source/Apps/Test/kbdinfo/Makefile +++ b/Source/Apps/Test/ps2info/Makefile @@ -1,4 +1,4 @@ -OBJECTS = kbdinfo.com +OBJECTS = ps2info.com DEST = ../../../../Binary/Apps/Test TOOLS =../../../../Tools diff --git a/Source/Apps/Test/kbdinfo/kbdinfo.asm b/Source/Apps/Test/ps2info/ps2info.asm similarity index 53% rename from Source/Apps/Test/kbdinfo/kbdinfo.asm rename to Source/Apps/Test/ps2info/ps2info.asm index 151db818..8a517a22 100644 --- a/Source/Apps/Test/kbdinfo/kbdinfo.asm +++ b/Source/Apps/Test/ps2info/ps2info.asm @@ -1,17 +1,17 @@ ; ;======================================================================= -; Keyboard Information Utility (KBDINFO) +; PS/2 Keyboard/Mouse Information Utility (PS2INFO) ;======================================================================= ; -; Simple utility that attempts to determine the type of keyboard you -; have attached to an 8242 keyboard controller. +; Simple utility that performs simple tests of an 8242 PS/2 controller, +; keyboard, and mouse. ; ;======================================================================= ; -; Keyboard controller port addresses (adjust as needed) +; PS/2 Keyboard/Mouse controller port addresses (adjust as needed) ; -iocmd .equ $E3 ; keyboard controller command port address -iodat .equ $E2 ; keyboard controller data port address +iocmd .equ $E3 ; PS/2 controller command port address +iodat .equ $E2 ; PS/2 controller data port address ; cpumhz .equ 8 ; for time delay calculations (not critical) ; @@ -39,10 +39,6 @@ bdos .equ $0005 ; BDOS invocation vector call prtstr ; call main ; do the real work - jr z,exit ; completed all tests - ld de,str_run_failed - call crlf2 - call prtstr ; exit: call crlf2 @@ -61,7 +57,7 @@ exit: ; main: ; -; Display active keyboard controller port addresses +; Display active controller port addresses ; call crlf2 ld de,str_cmdport @@ -73,16 +69,66 @@ main: call prtstr ld a,iodat call prthex +; + call test_ctlr + jr z,main0 ; continue if ctlr OK + ld de,str_kbd_failed + call crlf2 + call prtstr + jr mainz ; bail out if ctlr fails +; +main0: + call test_kbd + jr z,main1 ; completed all tests, continue + ld de,str_kbd_failed + call crlf2 + call prtstr +; +main1: + call test_mse + jr z,main2 ; completed all tests, continue + ld de,str_mse_failed + call crlf2 + call prtstr +; +main2: + call test_kbdmse +; +mainz: + xor a + ret +; +; Test 8242 PS/2 Controller +; +test_ctlr: + call crlf2 + ld de,str_ctlr + call prtstr +; + call ctlr_test + ret nz +; + call ctlr_test_p1 + ;ret nz +; + call ctlr_test_p2 + ;ret nz +; + ret +; +; Test Keyboard +; +test_kbd: ; ; First, we attempt to contact the controller and keyboard, then -; print the keyboard identity and scan codes scupported +; print the keyboard identity and scan codes supported ; ; Run test series with translation off call crlf2 ld de,str_basic call prtstr ; - call do_basic + call test_kbd_basic ret nz ; ; We make two passes through the test series with different controller @@ -94,29 +140,78 @@ main: ld de,str_trans_off call prtstr ; - ld a,$20 ; xlat disabled, mouse disabled, no ints + ld a,$20 ; kbd enabled, xlat disabled, mouse disabled, no ints ld (ctlr_cfgval),a - call do_tests + call test_kbd_keys ; ; Run test series with translation on call crlf2 ld de,str_trans_on call prtstr ; - ld a,$60 ; xlat enabled, mouse disabled, no ints + ld a,$60 ; kbd enabled, xlat enabled, mouse disabled, no ints ld (ctlr_cfgval),a - call do_tests - + call test_kbd_keys +; + ret +; +; Test Mouse +; +test_mse: + call crlf2 + ld de,str_basic_mse + call prtstr +; + ld a,$10 ; kbd disabled, mse enabled, no ints + call ctlr_setup + ret nz +; + call mse_reset + ret nz +; + call mse_ident + ret nz +; + call mse_stream + ret nz +; + call mse_echo +; xor a ; signal success ret ; -; Perform basic keyboard tests, display keyboard identity, and -; inventory the supported scan code sets. +; Test Everything ; -do_basic: - call ctlr_test +test_kbdmse: + call crlf2 + ld de,str_kbdmse + call prtstr +; + ld a,$00 ; kbd enabled, mse enabled, no ints + call ctlr_setup ret nz ; + call kbd_reset + ret nz +; + ld a,2 + call kbd_setsc +; + call mse_reset + ret nz +; + call mse_stream + ret nz +; + call kbdmse_echo +; + xor a ; signal success + ret +; +; Perform basic keyboard tests, display keyboard identity, and +; inventory the supported scan code sets. +; +test_kbd_basic: ld a,$20 ; Xlat off for this checking call ctlr_setup ret nz @@ -129,7 +224,7 @@ do_basic: ; ld b,3 ; Loop control, 3 scan code sets ld c,1 ; Current scan code number -do_basic1: +test_kbd_basic1: ld a,c ; Scan code set to A push bc call kbd_setsc ; Attempt to set it @@ -142,12 +237,12 @@ do_basic1: call prtdecb pop af ; restore result ld de,str_sc_ok - jr z,do_basic2 + jr z,test_kbd_basic2 ld de,str_sc_fail -do_basic2: +test_kbd_basic2: call prtstr inc c - djnz do_basic1 + djnz test_kbd_basic1 ; xor a ; signal success ret @@ -156,10 +251,7 @@ do_basic2: ; desired controller setup value should be placed in ctlr_cfgval ; prior to invoking this routine. ; -do_tests: - call ctlr_test - ret nz -; +test_kbd_keys: ld a,(ctlr_cfgval) call ctlr_setup ret nz @@ -177,19 +269,19 @@ do_tests: call kbd_dispsc ;ret nz ; - call kbd_showkeys + call kbd_echo ;ret nz ; xor a ; signal success ret ; ;======================================================================= -; Keyboard/Controller Test Routines +; Controller/Keyboard/Mouse Test Routines ;======================================================================= ; -; Attempt self-test command on keyboard controller +; Attempt self-test command on PS/2 controller ; -; Keyboard controller should respond with an 0x55 on data port +; PS/2 controller should respond with an 0x55 on data port ; after being sent a 0xAA on the command port. ; ctlr_test: @@ -209,9 +301,47 @@ ctlr_test: xor a ret ; -; Keyboard controller setup +; Attempt self-test of first port of controller +; +ctlr_test_p1: + call crlf2 + ld de,str_ctlr_test_p1 + call prtstr + ld a,$ab ; self-test first port + call put_cmd_dbg + jp c,err_ctlr_to ; handle controller error + call get_data_dbg + jp c,err_ctlr_to ; handle controller error + cp $00 ; expected value? + jp nz,err_ctlr_test_p1 ; handle self-test error + call crlf + ld de,str_ctlr_test_p1_ok + call prtstr + xor a + ret +; +; Attempt self-test of second port of controller ; -; Set keyboard controller command register to value in A +ctlr_test_p2: + call crlf2 + ld de,str_ctlr_test_p2 + call prtstr + ld a,$a9 ; self-test second port + call put_cmd_dbg + jp c,err_ctlr_to ; handle controller error + call get_data_dbg + jp c,err_ctlr_to ; handle controller error + cp $00 ; expected value? + jp nz,err_ctlr_test_p2 ; handle self-test error + call crlf + ld de,str_ctlr_test_p2_ok + call prtstr + xor a + ret +; +; PS/2 controller setup +; +; Set controller command register to value in A ; ctlr_setup: push af ; save incoming value @@ -243,7 +373,7 @@ kbd_reset: jp nz,err_kbd_reset call get_data_dbg jp c,err_ctlr_to ; handle controller error - cp $AA ; Success? + cp $aa ; Success? jp nz,err_kbd_reset call crlf ld de,str_kbd_reset_ok @@ -313,7 +443,7 @@ kbd_ident4: xor a ret ; -; Display active scan code set being used +; Display keyboard active scan code set being used ; kbd_dispsc: call crlf2 @@ -344,7 +474,7 @@ kbd_dispsc: xor a ret ; -; Set active scan code set to value in A +; Set keyboard active scan code set to value in A ; kbd_setsc: ld (kbd_setsc_val),a ; Save incoming value @@ -371,10 +501,9 @@ kbd_setsc: ; kbd_setsc_val .db 0 ; -; ; Read and display raw scan codes ; -kbd_showkeys: +kbd_echo: call crlf2 ld de,str_disp_scan_codes call prtstr @@ -384,7 +513,7 @@ read_loop: call bdos cp $1B ; Escape key? ret z - call check_read + call check_read_kbd jr nz,read_loop call get_data jp c,err_ctlr_to ; handle controller error @@ -399,13 +528,255 @@ read_loop: call prtchr jr read_loop ; +; Reset Mouse +; +mse_reset: + call crlf2 + ld de,str_mse_reset + call prtstr + ld a,$f2 ; Identify mouse command + call put_data_mse_dbg + jp c,err_ctlr_to ; handle controller error + call get_data_dbg + jp c,err_ctlr_to ; handle controller error + cp $fa ; Is it an ack as expected? + jp nz,err_mse_reset + call crlf + ld de,str_mse_reset_ok + call prtstr + xor a + ret +; +; Identify Mouse +; +mse_ident: + call crlf2 + ld de,str_mse_ident + call prtstr + ld a,$f2 ; Identify mouse command + call put_data_mse_dbg + jp c,err_ctlr_to ; handle controller error + call get_data_dbg + jp c,err_ctlr_to ; handle controller error + cp $fa ; Is it an ack as expected? + jp nz,err_mse_ident + call get_data_dbg + jp c,err_ctlr_to ; handle controller error + push af + call crlf + ld de,str_mse_ident_disp + call prtstr + pop af + call prtdecb + xor a + ret +; +; Enable mouse packet streaming +; +mse_stream: + call crlf2 + ld de,str_mse_stream + call prtstr + ld a,$f4 ; Stream packets cmd + call put_data_mse_dbg + jp c,err_ctlr_to ; handle controller error + call get_data_dbg + jp c,err_ctlr_to ; handle controller error + cp $FA ; Is it an ack as expected? + jp nz,err_mse_stream + xor a + ret +; +; Read and display raw mouse packets +; +mse_echo: + call crlf2 + ld de,str_disp_mse_pkts + call prtstr + call mse_track_disp ; show mouse status + xor a + ld (msebuflen),a +mse_echo1: + ld c,$06 ; BDOS direct console I/O + ld e,$FF ; Subfunction = read + call bdos + cp $1B ; Escape key? + ret z + call check_read_mse + jr nz,mse_echo1 + call get_data + jp c,err_ctlr_to ; handle controller error + push af + ld a,(msebuflen) ; current bytes in buf + ld hl,msebuf ; start of buf + call addhla ; point to next buf pos + pop af + ld (hl),a ; save byte in buf + ld a,(msebuflen) + inc a + ld (msebuflen),a ; inc buf len + cp 3 ; got 3 bytes? + jr nz,mse_echo1 ; if not, get some more + call mse_track + call mse_track_disp + jr mse_echo1 ; and loop +; +; Read and display data from keyboard and mouse +; +kbdmse_echo: + call crlf2 + ld de,str_disp_kbdmse + call prtstr + xor a + ld (msebuflen),a + call kbdmse_track_disp +; +kbdmse_echo1: + ; Check for user abort + ld c,$06 ; BDOS direct console I/O + ld e,$FF ; Subfunction = read + call bdos + cp $1B ; Escape key? + ret z +; + call kbdmse_echo2 + call kbdmse_echo3 + jr kbdmse_echo1 +; +kbdmse_echo2: + ; Check & handle keyboard data + call check_read_kbd + ret nz + call get_data + ld (kbd_byte),a + call kbdmse_track_disp + ret +; +kbdmse_echo3: + ; Check & handle mouse data + call check_read_mse + ret nz + call get_data + jp c,err_ctlr_to ; handle controller error + push af + ld a,(msebuflen) ; current bytes in buf + ld hl,msebuf ; start of buf + call addhla ; point to next buf pos + pop af + ld (hl),a ; save byte in buf + ld a,(msebuflen) + inc a + ld (msebuflen),a ; inc buf len + cp 3 ; full packet? + ret nz ; if not, loop + call mse_track + call kbdmse_track_disp + ret +; +; Update mouse tracking stuff +; This routine assumes that msebuf has been filled with a complete +; 3 byte mouse packet. +; +mse_track: + ; Buttons... + ld a,(msebuf) + ld (mse_stat),a +; + ; X Coordinate + ld a,(msebuf+1) + ld e,a + ld d,0 + ld a,(msebuf) + and %00010000 ; sign bit + jr z,mse_track_x + ld d,$ff ; sign extend +mse_track_x: + ld hl,(mse_x) + add hl,de + ld (mse_x),hl ; save result +; + ; Y Coordinate + ld a,(msebuf+2) + ld e,a + ld d,0 + ld a,(msebuf) + and %00100000 ; sign bit + jr z,mse_track_y + ld d,$ff ; sign extend +mse_track_y: + ld hl,(mse_y) + add hl,de + ld (mse_y),hl ; save result +; + ; Reset mouse buffer + xor a + ld (msebuflen),a + ret +; +; Display current mouse tracking info (buttons and coordinates) +; +mse_track_disp: + ld a,13 ; CR only + call prtchr + ld de,str_msestat1 ; "L=" + call prtstr + ld a,(mse_stat) + and %00000001 + call updown + ld de,str_msestat2 ; ", M=" + call prtstr + ld a,(mse_stat) + and %00000100 + call updown + ld de,str_msestat3 ; ", R=" + call prtstr + ld a,(mse_stat) + and %00000010 + call updown +; + ld de,str_msestat4 ; ", X=" + call prtstr + ld hl,(mse_x) ; save result + call prthexword +; + ld de,str_msestat5 ; ", Y=" + call prtstr + ld hl,(mse_y) ; save result + call prthexword +; + ret +; +updown: + jr nz,updown1 + ld de,str_up + jr updown2 +updown1: + ld de,str_down +updown2: + call prtstr + ret +; +; Display all keyboard and mouse tracking +; +kbdmse_track_disp: + call mse_track_disp + ld a,' ' + call prtchr + ld a,'[' + call prtchr + ld a,(kbd_byte) + call prthex + ld a,']' + call prtchr + ret +; ;======================================================================= -; Keyboard Controller I/O Routines +; PS/2 Controller I/O Routines ;======================================================================= ; wait_write: ; -; Wait for keyboard controller to be ready for a write +; Wait for controller to be ready for a write ; A=0 indicates success (ZF set) ; ld a,(timeout) ; setup timeout constant @@ -427,7 +798,7 @@ wait_write1: ; wait_read: ; -; Wait for keyboard controller to be ready to read a byte +; Wait for controller to be ready to read a byte ; A=0 indicates success (ZF set) ; ld a,(timeout) ; setup timeout constant @@ -458,9 +829,29 @@ check_read: xor $01 ; invert so 0 means ready ret ; +check_read_kbd: +; +; Check for keyboard data ready to read +; A=0 indicates data available (ZF set) +; + in a,(iocmd) ; get status + and %00100001 ; isolate input buf status bit + cp %00000001 ; data ready, not mouse + ret +; +check_read_mse: +; +; Check for mouse data ready to read +; A=0 indicates data available (ZF set) +; + in a,(iocmd) ; get status + and %00100001 ; isolate input buf status bit + cp %00100001 ; data ready, is mouse + ret +; put_cmd: ; -; Put a cmd byte from A to the keyboard interface with timeout +; Put a cmd byte from A to the controller with timeout ; CF set indicates timeout error ; ld e,a ; save incoming value @@ -484,18 +875,12 @@ put_cmd_dbg: call prtstr call prthex -; ld de,str_prefix ; " " -; call prtstr -; call prthex -; ld de,str_cmdout ; "->(CMD)" -; call prtstr - pop af ret ; put_data: ; -; Put a data byte from A to the keyboard interface with timeout +; Put a data byte from A to the controller interface with timeout ; CF set indicates timeout error ; ld e,a ; save incoming value @@ -519,17 +904,41 @@ put_data_dbg: call prtstr call prthex -; ld de,str_prefix ; " " -; call prtstr -; call prthex -; ld de,str_dataout ; "->(DATA)" -; call prtstr - pop af ret +; +put_data_mse: +; +; Put a data byte from A to the mouse interface with timeout +; CF set indicates timeout error +; + ld e,a ; save incoming value + push de + + ld a,$d4 ; mouse channel prefix + call put_cmd + pop de + ret c + + ld a,e ; recover value + call put_data + ret +; +put_data_mse_dbg: + ld e,a ; save incoming value + push de + + ld a,$d4 ; mouse channel prefix + call put_cmd_dbg + pop de + ret c + + ld a,e ; recover value + call put_data_dbg + ret ; -; Get a data byte from the keyboard interface to A with timeout +; Get a data byte from the controller interface to A with timeout ; CF set indicates timeout error ; get_data: @@ -552,10 +961,6 @@ get_data_dbg: call prtstr call prthex -; ld de,str_datain ; " (DATA)->" -; call prtstr -; call prthex - pop af ret ; @@ -569,6 +974,14 @@ err_ctlr_test: ld de,str_err_ctlr_test jr err_ret ; +err_ctlr_test_p1: + ld de,str_err_ctlr_test_p1 + jr err_ret +; +err_ctlr_test_p2: + ld de,str_err_ctlr_test_p2 + jr err_ret +; err_kbd_reset: ld de,str_err_kbd_reset jr err_ret @@ -585,6 +998,18 @@ err_kbd_ident: ld de,str_err_kbd_ident jr err_ret ; +err_mse_reset: + ld de,str_err_mse_reset + jr err_ret +; +err_mse_ident: + ld de,str_err_mse_ident + jr err_ret +; +err_mse_stream: + ld de,str_err_mse_stream + jr err_ret +; err_ret: call crlf2 call prtstr @@ -648,7 +1073,6 @@ prthexpre: call prtchr pop af ret - ; ; Print the value in A in hex without destroying any registers ; @@ -779,6 +1203,17 @@ crlf: pop af ; restore AF ret ; +; Add hl,a +; +; A register is destroyed! +; +addhla: + add a,l + ld l,a + ret nc + inc h + ret +; ; Delay ~10ms ; delay: @@ -804,30 +1239,36 @@ delay1: ; Constants ;======================================================================= ; -str_banner .db "Keyboard Information v0.2, 23-Dec-2021",0 -str_exit .db "Done, Thank you for using Keyboard Information!",0 -str_cmdport .db "Keyboard Controller Command Port: ",0 -str_dataport .db "Keyboard Controller Data Port: ",0 -;str_prefix .db " ",0 -;str_cmdout .db "->(CMD)",0 -;str_dataout .db "->(DATA)",0 -;str_datain .db " (DATA)->",0 -;str_timeout_write .db "Keyboard Controller Write Timeout, Status: ",0 -;str_timeout_read .db "Keyboard Controller Read Timeout, Status: ",0 -str_err_ctlr_to .db "Keyboard Controller I/O Timeout",0 -str_err_ctlr_test .db "Keyboard Controller Self-Test Failed",0 +str_banner .db "PS/2 Keyboard/Mouse Information v0.4, 7-Jan-2022",0 +str_exit .db "Done, Thank you for using PS/2 Keyboard/Mouse Information!",0 +str_cmdport .db "Controller Command Port: ",0 +str_dataport .db "Controller Data Port: ",0 +str_err_ctlr_to .db "Controller I/O Timeout",0 +str_err_ctlr_test .db "Controller Self-Test Failed",0 str_put_cmd .db " Sent Command ",0 str_put_data .db " Sent Data ",0 str_get_data .db " Got Data ",0 str_ctlr_test .db "Attempting Controller Self-Test",0 str_ctlr_test_ok .db "Controller Self-Test OK",0 +str_ctlr_test_p1 .db "Attempting Self-Test of First Controller Port",0 +str_ctlr_test_p1_ok .db "Controller First Port Self-Test OK",0 +str_err_ctlr_test_p1 .db "Controller First Port Self-Test Failed",0 +str_ctlr_test_p2 .db "Attempting Self-Test of Second Controller Port",0 +str_ctlr_test_p2_ok .db "Controller Second Port Self-Test OK",0 +str_err_ctlr_test_p2 .db "Controller Second Port Self-Test Failed",0 str_ctlr_setup .db "Performing Controller Setup",0 +str_ctlr .db "***** Basic 8242 PS/2 Controller Tests *****",0 str_basic .db "***** Basic Keyboard Checks and Scan Code Inventory *****",0 -str_trans_off .db "***** Testing with Scan Code Translation DISABLED *****",0 -str_trans_on .db "***** Testing with Scan Code Translation ENABLED *****",0 +str_trans_off .db "***** Testing Keyboard with Scan Code Translation DISABLED *****",0 +str_trans_on .db "***** Testing Keyboard with Scan Code Translation ENABLED *****",0 +str_basic_mse .db "***** Basic Mouse Tests *****",0 +str_kbdmse .db "***** Test All Devices Combined *****",0 str_kbd_reset .db "Attempting Keyboard Reset",0 str_kbd_reset_ok .db "Keyboard Reset OK",0 str_err_kbd_reset .db "Keyboard Reset Failed",0 +str_mse_reset .db "Attempting Mouse Reset",0 +str_mse_reset_ok .db "Mouse Reset OK",0 +str_err_mse_reset .db "Mouse Reset Failed",0 str_kbd_getsc .db "Requesting Active Scan Code Set from Keyboard",0 str_kbd_dispsc .db "Active Keyboard Scan Code Set is #",0 str_err_kbd_getsc .db "Error getting Active Keyboard Scan Code Set",0 @@ -835,18 +1276,42 @@ str_kbd_setsc .db "Setting Active Keyboard Scan Code Set to #",0 str_err_kbd_setsc .db "Error setting Active Keyboard Scan Code Set",0 str_kbd_ident .db "Keyboard Identification",0 str_kbd_ident_disp .db "Keyboard Identity: ",0 +str_mse_ident .db "Mouse Identification",0 +str_mse_ident_disp .db "Mouse Identity: ",0 +str_mse_stream .db "Enable Mouse Packet Streaming",0 +str_err_mse_stream .db "Error enabling Mouse Packet Streaming",0 +str_msestat1 .db "L=",0 +str_msestat2 .db ", M=",0 +str_msestat3 .db ", R=",0 +str_msestat4 .db ", X=",0 +str_msestat5 .db ", Y=",0 +str_up .db "UP",0 +str_down .db "DN",0 str_sc_tag .db "Scan Code Set #",0 str_sc_ok .db " IS supported",0 str_sc_fail .db " IS NOT supported",0 str_err_kbd_ident .db "Error performing Keyboard Identification",0 +str_err_mse_ident .db "Error performing Mouse Identification",0 str_disp_scan_codes .db "Displaying Raw Scan Codes",13,10 .db " Press keys on test keyboard to display scan codes",13,10 .db " Press on CP/M console to end",13,10,13,10,0 -str_run_failed .db "***** HARDWARE ERROR *****",13,10,13,10 +str_disp_mse_pkts .db "Displaying Mouse Packets",13,10 + .db " Move mouse and click mouse buttons",13,10 + .db " Press on CP/M console to end",13,10,13,10,0 +str_disp_kbdmse .db "Displaying Keyboard & Mouse Activity",13,10 + .db " Press keys on test keyboard to display scan codes",13,10 + .db " Move mouse and click mouse buttons",13,10 + .db " Press on CP/M console to end",13,10,13,10,0 +str_kbd_failed .db "***** KEYBOARD HARDWARE ERROR *****",13,10,13,10 .db "A basic hardware or configuration issue prevented",13,10 - .db "Keyboard Information from completing the full set",13,10 - .db "of tests. Check your hardware and verify the port",13,10 - .db "addresses being used for the keyboard controller",0 + .db "the completion of the full set of keyboard tests.",13,10 + .db "Check your hardware and verify the port",13,10 + .db "addresses being used for the controller",0 +str_mse_failed .db "***** MOUSE HARDWARE ERROR *****",13,10,13,10 + .db "A basic hardware or configuration issue prevented",13,10 + .db "the completion of the full set of mouse tests.",13,10 + .db "Check your hardware and verify the port",13,10 + .db "addresses being used for the controller",0 ; ;======================================================================= ; Working data @@ -859,6 +1324,15 @@ stack .equ $ ; stack top workbuf .fill 8 workbuf_len .db 0 ; +msebuf .fill 5,0 +msebuflen .db 0 +; +mse_stat .db 0 +mse_x .dw 0 +mse_y .dw 0 +; +kbd_byte .db 0 +; ctlr_cfgval .db 0 ; Value for controller cmd reg 0 ; cpuscl .db cpumhz - 2 diff --git a/Source/Apps/VGM/Tunes/filthy01.vgm b/Source/Apps/VGM/Tunes/filthy01.vgm new file mode 100644 index 0000000000000000000000000000000000000000..c161e1f32d7ec584b66d79bad954a92cbe315192 GIT binary patch literal 27392 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 IywZRF2mQwCp8x;= literal 0 HcmV?d00001 diff --git a/Source/Doc/GettingStarted.md b/Source/Doc/GettingStarted.md index 92ccc134..1c31f15b 100644 --- a/Source/Doc/GettingStarted.md +++ b/Source/Doc/GettingStarted.md @@ -1083,7 +1083,7 @@ through the normal startup process just like it was started from ROM. However, your ROM has not been updated and the next time you boot your system, it will revert to the system image contained in ROM. -# Upgrading via Flash Utility +## Upgrading via Flash Utility If you do not have easy access to a ROM programmer, it is usually possible to reprogram your system ROM using the FLASH utility from @@ -1128,7 +1128,7 @@ system and boot an operating system from ROM. Do not boot from a disk device yet. Review the boot messages to see if any issues have occurred. -# Upgrading via XModem Flash Updater +## Upgrading via XModem Flash Updater Similar to using the Flash utility, the system ROM can be updated or upgraded through the ROM based updater utility. This works by @@ -1143,7 +1143,7 @@ U (Begin Update). Then initiate the Xmodem transfer of the .img or More information can be found in the ROM Applications document. -# Post Update System Image and Application update process +## Post Upgrade System Image and Application Update Process Once you are satisfied that the ROM is working well, you will need to update the system images and RomWBW custom applications on your disk @@ -1214,23 +1214,22 @@ operating system on your disk. After this is done, you will need to use `SYSCOPY` to place the ZPM3 loader image on the boot tracks of all ZPM3 - boot disks/slices. The loader image is called `CPMLDR.SYS`. + boot disks/slices. The loader image is called `ZPMLDR.SYS`. You must then copy (at a minimum) `CPM3.SYS`, `ZCCP.COM`, `ZINSTAL.ZPM`, and `STARTZPM.COM` onto the disk/slice. Assuming you copied the ZPM3 boot files onto your RAM disk at A:, you would use: ``` - A>B:SYSCOPY C:=CPMLDR.SYS + A>B:SYSCOPY C:=ZPMLDR.SYS A>B:COPY CPM3.SYS C: A>B:COPY ZCCP.COM C: A>B:COPY ZINSTAL.ZPM C: A>B:COPY STARTZPM.COM C: ``` - You may be wondering if the references to `CPMLDR.SYS` and - `CPM3.SYS` are typos. They are not. ZPM3 uses the same loader - image as CPM3. The ZPM3 main system code file is called `CPM3.SYS` + You may be wondering if the reference to `CPM3.SYS` is a typo. + It is not. The ZPM3 main system code file is called `CPM3.SYS` which is the same name as CP/M 3 uses, but the file contents are not the same. @@ -1263,29 +1262,34 @@ images. * FAT.COM * TUNE.COM -# System Update +## System Update -If the system running ROMWBW utilizes the SST39SF040 Flash chip then it is possible to do a System Update in place of -a System Upgrade in some cases. +If the system running ROMWBW utilizes the SST39SF040 Flash chip then it +is possible to do a System Update in place of a System Upgrade in some +cases. -A System Update would involve only updating the BIOS, ROM applications and CP/M system. +A System Update would involve only updating the BIOS, ROM applications +and CP/M system. -A System Update may be more favorable than a System Upgrade in cases such as: +A System Update may be more favorable than a System Upgrade in cases +such as: - Overwriting of the ROM drive is not desired. - Space is unavailable to hold a full ROMWBW ROM. - To mimimize time taken to transfer and flash a full ROM. - Configuration changes are only minor and do not impact disk applications. -The ROMWBW build process generates a system upgrade file along with the normal ROM image and can be identified by the -extension ".upd". It will be 128Kb in size. In comparison the normal ROM image will have the extension ".rom" and be -512Kb or 1024Kb in size. +The ROMWBW build process generates a system upgrade file along with +the normal ROM image and can be identified by the extension ".upd". It +will be 128Kb in size. In comparison the normal ROM image will have +the extension ".rom" and be 512Kb or 1024Kb in size. -Transferring and flashing the System Update is accomplished in the same manner as described above in *Upgrading* with -the required difference being that the flash application needs to be directed to complete a partial flash using the -/p command line switch. +Transferring and flashing the System Update is accomplished in the +same manner as described above in *Upgrading* with the required +difference being that the flash application needs to be directed to +complete a partial flash using the /P command line switch. -`E>flash write rom.upd /p` +`E>FLASH WRITE ROM.UPD /P` # RomWBW Distribution @@ -1303,7 +1307,7 @@ directories are: | Application | Description | | ----------- | -------------------------------------------------------------- | -| Binary | The final output files of the build process are placed here. Most importantly, are the ROM images with the file names ending in ".rom". | +| Binary | The final output files of the build process are placed here. Most importantly, the ROM images with the file names ending in ".rom". | | Doc | Contains various detailed documentation including the operating systems, RomWBW architecture, etc. | | Source | Contains the source code files used to build the software and ROM images. | | Tools | Contains the MS Windows programs that are used by the build process or that may be useful in setting up your system. | @@ -1327,10 +1331,11 @@ these applications are no longer provided. driver. * Ed Brindley contributed some of the code that supports the RC2014 platform. -* Phil Summers contributed Forth and BASIC in ROM, the AY-3-8910 sound -driver as well as a long list of general code enhancements. +* Phil Summers contributed the Forth and BASIC adaptations in ROM, the +AY-3-8910 sound driver as well as a long list of general code +enhancements. * Phillip Stevens contributed support for FreeRTOS. -* Curt Mayer contributed the Linux / MacOS build process. +* Curt Mayer contributed the original Linux / MacOS build process. * UNA BIOS and FDISK80 are the products of John Coffman. * FLASH4 is a product of Will Sowerbutts. * CLRDIR is a product of Max Scane. @@ -1341,6 +1346,50 @@ the SN76489 sound driver. Contributions of all kinds to RomWBW are very welcome. +# Licensing + +RomWBW is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +RomWBW is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with RomWBW. If not, see . + +Portions of RomWBW were created by, contributed by, or derived from +the work of others. It is believed that these works are being used +in accordance with the intentions and/or licensing of their creators. + +If anyone feels their work is being used outside of it's intended +licensing, please notify: + +> Wayne Warthen +> wwarthen@gmail.com + +RomWBW is an aggregate work. It is composed of many individual, +standalone programs that are distributed as a whole to function as +a cohesive system. Each program may have it's own licensing which +may be different from other programs within the aggregate. + +In some cases, a single program (e.g., CP/M Operating System) is +composed of multiple components with different licenses. It is +believed that in all such cases the licenses are compatible with +GPL version 3. + +RomWBW encourages code contributions from others. Contributors +may assert their own copyright in their contributions by +annotating the contributed source code appropriately. Contributors +are further encouraged to submit their contributions via the RomWBW +source code control system to ensure their contributions are clearly +documented. + +All contributions to RomWBW are subject to this license. + # Getting Assistance The best way to get assistance with RomWBW or any aspect of the diff --git a/Source/Images/fd_zsdos.txt b/Source/Images/fd_zsdos.txt index 0d7c71ae..333d6526 100644 --- a/Source/Images/fd_zsdos.txt +++ b/Source/Images/fd_zsdos.txt @@ -47,7 +47,7 @@ d_cpm22/u0/XSUB.COM 0: # Add Tune sample files # ../../Binary/Apps/Tunes/*.pt? 3: -../../Binary/Apps/Tunes/*.mym 3: +#../../Binary/Apps/Tunes/*.mym 3: ../../Binary/Apps/Tunes/*.vgm 3: # # Add OS image