IMD 1.15: 16/05/2007 8:43:12 FIXSSDD SOURCE V1.0 1/5/85 AAAFIXSSDD HEXc GENFIX DO FIXSSDD COM$SYSS1 AST AHEXCOM OM #$ACT COMt!"%&'()*+,FIXSSDD BAK./0123456789:;<=FIXSSDD BAKU>?@BCDEFGHIFIXSSDD ASJKLMNOPQRSTUVWXYFIXSSDD ASZ[FIXSSDD BA\]^_`abcdefghijkFIXSSDD BAlmnopqrstuvwxyz{RAMS10 AS SYSS1 ASTBFIXSSDD BAa|}~FIXSSDD ASTFIXSSDD BA?>=:10010000C36701C35C010D0A20436F707972696790 :100110006874201B67131B4720313938342046751B :10012000747572652053797374656D732C20383241 :1001300038204E6F622048696C6C204176656E7580 :10014000652C200D0A50696E6F6C65204341203983 :10015000343536340D0A2056312E301A216301CD44 :10016000E402C91B73300031E1120E0CCD05007C96 :10017000B7C27A017DFE30D2830121FC06CDE402B4 :10018000C300001EFF0E2DCD0500CDEF01216F072E :10019000CDE402211B08CDE402CDFF03ED5BEA03B1 :1001A0002AED01373FED52CAC701ED53ED0113139C :1001B0000E09CD05003A8B0ACD880321D108CDE484 :1001C00002CD0403CDF302119C01D5CDD802FE0B64 :1001D000CA2F02FE8ACA2F02FE0ACA5902FE8CCA20 :1001E0005902FE0DCA5303CDC802C3CB0100002142 :1001F000FC01CDE402212402CDE402C91B7A3124A2 :10020000342B701B7A32342037701B7A332D203315 :10021000701B7A352A2030701B7A362D2030701BE7 :1002200073301A001B66001B7A3426342F700021AD :100230008B0A3A850AFE00280321930A7EFE2028B5 :1002400014F53D77F1CDBE033A8B0ACD8803CD047A :1002500003CDF302C9CDC802C9218B0A3A850AFE33 :1002600000280F21930A3A960AC61F477EB8282015 :10027000180A3A840AC61F477EB82814F53C77F15D :10028000CDBE033A8B0ACD8803CD0403CDF302C95A :10029000CDC802C93A960AFE0028153A850AFE0121 :1002A000280E3E0132850A3E2032930ACDF302C960 :1002B000CDC802C93A850AFE0028093E0032850AE7 :1002C000CDF302C9CDC802C91E070E02CD0500C973 :1002D0001E1A0E02CD0500C91EFF0E06CD0500FE3A :1002E0000028F5C97E23FE00C80E025FE5CD05009B :1002F000E118F1218E0A3A850AFE01280321860AB7 :10030000CDE402C93A8B0AD620876F2600ED5BE662 :1003100003195E23562A2F03373FED52CA2E03EDF1 :10032000532F031A32960A130E09CD0500C9C900CE :100330000021D108CDE4023A8B0AD620876F26002F :10034000ED5BE603195E23561A32960A130E09CDA9 :100350000500C9218303CDE4023A8B0AD620876FBA :100360002600ED5BE803195E2356EB117003D5E917 :10037000ED5BEA032AED01373FED52C0CD3103CDED :10038000F302C91B73351A00F5C604322A02322C57 :1003900002F1D6202AEA035E2356EB5F16001919F4 :1003A0005E2356EBE511030019366A212702CDE4DE :1003B00002E1E5CDE402E111030019366BC9F5C68F :1003C00004322A02322C02F1D6202AEA035E235696 :1003D000EB5F160019195E2356EBE5212702CDE4E9 :1003E00002E1CDE402C900000000000011F7030E95 :1003F00009CD0500C300001B73301A1B65002421C2 :100400001C0422E60321220422E80321690822EACF :10041000033E0332840A3E21328B0AC9B109B10975 :10042000740928043104EC033E41CD4604CD3A045E :10043000C93E42CD4604CD3A04C9214104CDE4026F :10044000C91B73331A0032D30B324D0CD6413250D4 :10045000FDCDD6043A50FDCDAB04CA750421AA0BDC :100460003DCA670421250CCD9306CDE204F5CDD617 :1004700004F1FE4EC83E44CDF704CD0C05CD360543 :10048000F50E0DCD0500F1FE5121820D2813B72187 :10049000A60C280D21170DCD9306CDA706CDD604A9 :1004A000C9CD9306CD9E06CDD604C947C53250FDB1 :1004B000CD1006C1C2CD04783C32D80611D8060E44 :1004C00011CD05003CC2CF04AFB4C2D204AFC9AF56 :1004D0003CC93E02B7C921DD04CD9306C91B733266 :1004E0001A00CDB006E65FFE59CAF104FE4EC2E224 :1004F00004F5CDB706F1C9FE53CA04053E0C3251CE :10050000FD0605C93E053251FD060AC97832CF06FF :10051000F6FF32CE063A51FDFE0CCA2205FE0EC28F :10052000350578FE05C2350521C106180011C8063B :10053000010700EDB0C921BB0ACD7E063E01324D58 :10054000FDCAD0906C2A00521A00ACD9306AF3290C9 :1005500012324EFDAF32A4053C32A3053A51FDF6EE :10056000023251FDCDA5053AA4054FCDE705210086 :1005700040224BFDDB00324AFDCD2506C284053EFC :100580002AC389053E45329012CD7106CD6906C851 :100590003A4EFD3CFE28C251053A9012B72001C9DF :1005A000F6FFC900001102402ACC06ED4BC806ED4B :1005B000B03E0132A60B3ACF063D47C5D5FDE12A34 :1005C000CC06ED4BC806EDB021A60B343A51FDFE2A :1005D000057ECADA05FD77761800C110DEEB010250 :1005E00040ED42220040C9210140ED5BCA06193AA4 :1005F000CF0647ED5BC8063A4EFD7723712B1910E5 :10060000F9C93A0200672E5AE9115701CD0206C90D :10061000116001CD0206C9115A01CD0206C9115D52 :1006200001CD0206C93E02328C12116301CD0206D1 :10063000C8218C1235C22A06F6FFC9C9116601CD40 :100640000206C9116C01CD0206C9116901CD02066D :10065000C9C5D5E578B1CA65061ABEF513230BF1F5 :10066000CA5406F6FFE1D1C1C9CDBA06E65FFE5114 :10067000C9C5D5E55F0E02CD0500E1D1C1C9C5D51B :10068000E5EB0E09CD0500E1D1C1C93E1ACDB70693 :10069000C300007EB7C8E5CDB706E12318F5CDB09D :1006A00006FE0DC29E06C9CDB006FE1BC2A706C936 :1006B000CDBA06B728FAC95F18021EFF0E06C30599 :0806C00000A0047500EC0D0020 :1006D800003F3F3F3F3F3F3F3F3F3F3F3F0000001E :1006E8000000000000000000000000000000000002 :1006F8000000000046495853534444207265717500 :10070800697265732043502F4D20332E58206F7225 :1007180020677265617465722E0D0A436F70797275 :1007280069676874201B67131B47203139383420E8 :100738004675747572652053797374656D732C20D2 :10074800383238204E6F622048696C6C20417665DB :100758006E75652C2050696E6F6C65204341203999 :10076800343536340D0A001B73301A1B3D20202007 :10077800202020202020202020202020202020533E :10078800696E676C652053696465642053696E6798 :100798006C652044656E73697479204469736B20B5 :1007A80046697875702050726F6772616D0D0A2006 :1007B8002020202020202020202020202020202031 :1007C8002020202020204F73626F726E65204558CC :1007D8004543555449564520436F6D70757465728D :1007E8002053797374656D0D0A2020202020202065 :1007F80020202020202020202020202020202020F1 :100808002020202020202020202020202020563199 :100818002E30001B73321A20202020202020202078 :10082800201B67131B4720313938342046757475EF :1008380072652053797374656D732C2038323820B3 :100848004E6F622048696C6C204176656E75652C28 :100858002050696E6F6C6520434120393435363439 :1008680000CB081B73311A1B3D202020201B6B2056 :10087800466978204469736B20696E2044726976F2 :10088800652041201B6B000D0A20201B6B20466948 :1008980078204469736B20696E20447269766520FC :1008A80042201B6B000D0A20201B6B20524554551B :1008B800524E20544F2043502F4D201B6B000D0AE1 :1008C8000D0A2473089108AF081B73351A202020DD :1008D8002020202020202020202020202020202010 :1008E8002020202055736520746865204152524F9E :1008F80057206B65797320746F20706F7369746902 :100908006F6E207468650D0A20202020202020208A :10091800202020202020202020202020202020638C :100928007572736F72206E65787420746F207468A6 :100938006520646573697265642063686F696365BF :100948000D0A2020202020202020202020202020C8 :10095800202020202020202020202020202020208F :100968002020202020202020206F7200001B7336BA :100978001A20202020202020202020202020202075 :1009880020202020202020202020507265737320F2 :1009980052455455524E20746F2052657475726ECC :1009A80020746F2043502F4D24001B73361A2020CB :1009B800202020202020202020202020202020202F :1009C8002020496E736572742061204469736B65D9 :1009D80074746520696E2073656C65637465642042 :1009E800647269766520616E640D0A2020202020DB :1009F80020202020202020202020202020202020EF :100A08002020202050726573732052455455524E51 :100A180020746F20737461727420666978696E67D8 :100A28000D0A0D0A1B5E5741524E494E473A201B8C :100A38006A446F206E6F7420617474656D707420E1 :100A4800746F206669782061207472756C792064EF :100A58006F75626C65207369646564206469736B83 :100A6800212049742077696C6C20626520444553C5 :100A780054524F594544211B6B1B712400001B73B2 :0E0A8800311B3D2020001B73321B3D2020003F :100A9700001B73321A1B7331241B73330D0A0A0AA6 :100AA700202020202020202020202020202020203F :100AB700202020001B73351A0D0A2020202020201B :100AC700202020202020202020202020202020201F :100AD7002020507265737320616E6420486F6C64C8 :100AE700205120746F205175697420466978696EAA :100AF700671B73331A20202020202020 Generation procedure for Executive FIXSSDD V1.0 DAB 12/29/84 T generat objec cod fo FIXSSDD th followin file ar needed: FIXSSDD.ASM, SYSS1.AST, RAMS10.ASM, ACT.COM and HEXCOM.COM. All of these files are on disk 1 of the FIXSSDD release diskette. FIXSSDD is generated with the command lines: ACT FIXSSDD S=SYSS1 HEXCOM FIXSSDD If a listing is desired, enter the following command line: ACT FIXSSDD S=SYSS1 R=F L UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUDD((DTTT(D((DDDDL4x| | ` 0 0 TUUUUUA202020204D :100B070020202020202020202020202020202020DE :100B1700202020202020547261636B20466978656D :100B2700643A0D0A20202020202020202020202089 :100B3700202020202020203020202020202020209E :100B4700203120202020202020202032202020207B :100B57002020202020332020202020202020200D8E :100B67000A20202020202020202020202020202094 :100B77002020202030313233343536373839303180 :100B87003233343536373839303132333435363716 :100B97003839303132333435363738390D0A240095 :100BA7000000001B73321A20202020202020202044 :100BB700202020202020202020204469736B65748A :100BC700746520696E204472697665205820636FCA :100BD7006E7461696E7320696E666F726D61746998 :100BE7006F6E2E0D0A20202020202020202020207C :100BF7002020202020202020202020202049732072 :100C07006974204F4B20746F206F76657277726915 :100C170074652069742028792F6E293F20001B7383 :100C2700321A2020202020202020202020202020B1 :100C3700202020204469736B6574746520696E20D9 :100C470044726976652058204D415920636F6E7450 :100C570061696E20696E666F726D6174696F6E2E61 :100C67000D0A2020202020202020202020202020A6 :100C77002020202020202020202049732069742054 :100C87004F4B20746F206F76657277726974652099 :100C970069742028792F6E293F20000D0A0A001B4E :100CA70073321A20202020202020202020202020DE :100CB7002020202020202020202020466978696ECF :100CC7006720636F6D706C6574656420737563630B :100CD70065737366756C6C792E0D0A2020202020B1 :100CE70020202020202020202020202020202020FD :100CF70020202020202050726573732052455455C0 :100D0700524E20746F20636F6E74696E75652E0086 :100D17001B73321A20202020202020202020202072 :100D270020202020202020202020202020202020BC :100D370020204572726F72207768696C652066693A :100D470078696E672E0D0A20202020202020202081 :100D5700202020202020202020202020202020208C :100D67002020202050726573732045534320746FF1 :100D770020636F6E74696E75652E001B73321A20BF :100D8700202020202020202020202020202020205C :100D97002020202020202020202020202020204626 :100DA7004958494E472041424F525445442E0D0A57 :100DB700202020202020202020202020202020202C :100DC70020202020202020202020205072657373AF :100DD7002052455455524E20746F20636F6E7469CC :100DE7006E75652E004E4E4E4E4E4E4E4E4E4E4E2C :100DF7004E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E0C :100E07004E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4EFB :100E17004E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4EEB :100E27004E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4EDB :100E37004E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4ECB :100E47004E4E4E4E4E4E4E4E4E00000000000000DD :100E57000000000000F5F5F5FE00000103F74E4E17 :100E67004E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E9B :100E77004E4E4E4E00000000000000000000000033 :100E8700F5F5F5FBE5E5E5E5E5E5E5E5E5E5E5E5C5 :100E9700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5FB :100EA700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5EB :100EB700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5DB :100EC700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5CB :100ED700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5BB :100EE700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5AB :100EF700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E59B :100F0700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E58A :100F1700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E57A :100F2700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E56A :100F3700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E55A :100F4700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E54A :100F5700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E53A :100F6700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E52A :100F7700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E51A :100F8700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E50A :100F9700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5FA :100FA700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5EA :100FB700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5DA :100FC700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5CA :100FD700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5BA :100FE700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5AA :100FF700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E59A :10100700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E589 :10101700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E579 :10102700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E569 :10103700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E559 :10104700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E549 :10105700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E539 :10106700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E529 :10107700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E519 :10108700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E509 :10109700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5F9 :1010A700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E9 :1010B700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5D9 :1010C700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5C9 :1010D700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5B9 :1010E700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5A9 :1010F700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E599 :10110700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E588 :10111700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E578 :10112700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E568 :10113700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E558 :10114700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E548 :10115700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E538 :10116700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E528 :10117700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E518 :10118700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E508 :10119700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5F8 :1011A700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E8 :1011B700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5D8 :1011C700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5C8 :1011D700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5B8 :1011E700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5A8 :1011F700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E598 :10120700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E587 :10121700E5E5E5E5E5E5E5AE5E5E5E5E5E5E5E5E577 :10122700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E567 :10123700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E557 :10124700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E547 :10125700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E537 :10126700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E527 :10127700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E517 :0A128700E5E5E5E5F70000000000D2 :00010010 E5E5E5E5E5E5E5E5E5E5E5E5E5E558 :10114700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E548 :10115700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E538 :10116700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E528 :10117700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E518 :10118700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E508 :10119700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5F8 :1011A700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E8 :1011B700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5D8 :1011C700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5C8 :1011D700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5B8 :1011E700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5A8 :1011F700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E598 :10120700E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E587 :10121700E5E5E5E5E5E5E5g\ Copyright gG 1984 Future Systems, 828 Nob Hill Avenue, Pinole CA 94564 V1.0!cs01 |z}0҃!-!o![*7?RS : ͈! // YY S!!$z1$4+pz24 7pz3- 3pz5* 0pz6- 0ps0fz4&4/p! : (! ~ (=w;: ͈! : (! : G~(  : G~(2 > 2 : ( >2 (~#_! : (! : o&[^#V*/7?R.S/2  !: o&[^#V2  !: o&[^#Vp[*7?R1s52*2, *^#V_^#V6j!'6k2*2, *^#V_^#V!' s0e$!"!""!i">2 >!2 ɱ t (1>AF:>BF:!As32 2M A2P:Pͫu! =g!% ͓N>D 6 Q! (! ( ! ͓͓ͧ͞G2Px<2<ɯ<>!͓s2Ͱ_YNͷS> 2Q>2Q x22:Q "5x5!! ~>2M  ! ͓22N2<2:Q2Qͥ:O!@"K2J%„>*É>E2qi:N<(Q: @*K>2 :=G*K! 4:Q~wv@B"@!@[:G[:Nw#q+:g.ZW`Z]>2c!5*flixe# Tͺ_Q_ >ͷ~ͷ#Ͱ žͰ§ͺ(_u ????????????FIXSSDD requires CP/M 3.X or greater. Copyright gG 1984 Future Systems, 828 Nob Hill Avenue, Pinole CA 94564 s0= Single Sided Single Density Disk Fixup Program Osborne EXECUTIVE Computer System V1.0s2 gG 1984 Future Systems, 828 Nob Hill Avenue, Pinole CA 94564s1= k Fix Disk in Drive A k k Fix Disk in Drive B k k RETURN TO CP/M k $ss5 Use the ARROW keys to position the cursor next to the desired choice ors6 Press RETURN to Return to CP/M$s6 Insert a Diskette in selected drive and Press RETURN to start fixing ^WARNING: jDo not attempt to fix a truly double sided disk! It will be DESTROYED!kq$s1= s2= s2s1$s3 s5 Press and Hold Q to Quit Fixings3 Track Fixed: 0 1 2 3 0123456789012345678901234567890123456789 $s2 Diskette in Drive X contains information. Is it OK to overwrite it (y/n)? s2 Diskette in Drive X MAY contain information. Is it OK to overwrite it (y/n)? s2 Fixing completed successfully. Press RETURN to continue.s2 Error while fixing. Press ESC to continue.s2 FIXING ABORTED. Press RETURN to continue.NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNAACT I 808x Copyright SORCIM Corp. 1981 S/N- 007,Version 3.5EEV SorcALL ASMFilenameHEXFilenamePRNτ?1;͟4199!42 ͣ'6 #6 #6͎ 4!:f'*:;'*:;'F<*99>T29>2a$o*9|LH&*9*9*9(%b;'*9*9(%! ͩ"e:U&*:;'!HHF*|ʧ&!"F*e:|:9!B6 29!l$ Last error occurred on Page 123 Total LOST references were !?="9*9"929go"9*9&"9>s2K2:2:͎ 2929292929292929292Q:go"9!e:"^:"9*9":"9:92:5:9=29>2929>T29> 2K*9196:94H*:"9*9"9*9X!.X:9͓*9 "9:9:9*9}eG:9=__ͻ$#D> 24d"`:~G&vG!.#%fh"c:2e:*9"nx(:9¶ x= :9:9x(=:c:G 6)!K="9! B629>22>22J! :9ĭ!$:9ĭFUnterminated IF nest. IUnterminated MACRO definition. !.~O#%~wy<#%J*9*9 ~w# œ~?ʜp ^#V#N#F r+s 9'n!ͭ~24#W$OToo many PROCs in program. *9?9' "9*9 "9yx  !e: f':d:_ :9¶!"f:":>(=*9"n!%4:c:#%^#V>SE>E24\*^:}!e:"^:2d::9 e::d: !9>wd:G::ʁ!4 W † :9 ͓!9~wÁn>-24>O>Y>S>E>A24*n|c~c=ͅ"::s2:ͨ :9ʽ:9>Y:9>F24292929͗!T.:9>P?*9~24 ͒ | >P24 R::9pͬ% ͬ/ƒͺ:9Ҿp %ҭ!f'!9~G?2:>N*nͻ,#!94:9ʤ>Ov ͼ ðv":"9:s2:2:> 2:Dv"9:s2:G::’*:9'> ʔ>#2:!4wðv:rG:e:N:9*:°>L24ð!e:~"^:*92~c!e:~"^:2*92ͬc!e:"^:v | } >W24>2[:\> ͒"\:, ::*^:w\>S24\*9e:':9 b *9?9'>O "9 *n~*!99ʽ f'ͬ-™ ͬ+ ͭ>UN!9{_~wͬ,ʋ N'*n#~T L@ C D F G M R͒:9@S ͒U͍f:9@͍^!9F6:96 I :9@I ͍!9~w*9~>S## C>E>S~29*9#N# f'! f'! W$Unknown CPU: '' ͓!46'#*9ͩ Of' ;' !) ͍'!4>!O$͓' 2929v}29| :9ͤ=D !94:e:- *9?>L͇ "9< ####>*9##"9'!:͡':92:*9:*9 f'"9x #"95%*9~w##s#r*9##h'%0+  3 Ƃ~ G >@w!:͆>w :9ē*9#"9 *c3 ~ ʪ(~w##^#V*9ʠ w#Ò ͤO:9= y*9#%N#Fx w# Ò *9"9|~ : # !"96!"9*9"9!9"9*9;'*9!9f'*9zV  6 s#r#Z ,;  >P ) s#r#"9x29O:9Gʃ ˆ =29} :9¶29>F:9ʴ ¶} :e:b !94:9¶vz°n:9ē:929*9"9*:":Y*9"9*9"9>L >S24!::9w:9 {: :9Ox~ :92*:*:":":͙ x (::2:>*9G:92:":!"9*9|? *n~}:} 1"9F::O@°yw*:#::w#s#rx ʴx@´>w:9x>D :9>:9:[:O::G!d:yO4Q Jx2::[:*\: lMW͛%O::_G͆%!:w{=@~6*^:w#"^:!d:4 ::W{2:[: !46^#þ':9M*9##(%"f:!46=##þ' ͩʝV=ʝ#^=ʝ>V24*^:s#r+y *^:>A+w¬ͩOGx!46V*n+6:d:2d:*^::9y#% Aw# "^:*n+~#:9(=*9"n*94;'::;>~;7ʧ*7ʧ 7ʧ:9¡ ڧ'.!_ʚ;Œ:9¯> #„òaژ{Ҙ #V#Ҟ#:9ʲ*9"9 ʵ>!;?~   7ȷy#:9ʲ*9ͤõ#N f'VA>#"'#~'"# x)+pV9 B#0+> !"9"9"9!9!;~ p ~# f}| fO!~ʌ#7y,+-*/()><=^&[] : \(%*9*99'+~ y¹*99'"929*9.:9g"9"9:9 *9*99' "9>a*<<4:9W~#29  F  Rf> z > : "<<> `i"9!429z29 >=9'ҁͪ> !\#!7\\\ END Statement Missing !><\#6y  !W$ACT stopped by user. *99'"9"9\ f'ͻ#$!Ve%!VC f'>2a$!C͂$f$!>="<<6 Pass 1 - Reading D:FILENAME.EXT ;}; ͒:r >Uá*9"n|’7*nͩڤ?>E247go!"t."r!9"jz>Sͼ2l K*h};9'+~ffbMb*h};9' *f;9';A:@2s"tb*h9'+~H"h> 2l!z#%9'F#N   de~# ʼ+"n>2l!;"f!};"h6>2q>E*j24!"tt>2s7ͬ ; +-------------------------------+ ; | | ; | SHELLY SYSTEXT | ; | | ; +-------------------------------+ ; I/O PORTS SYS_DTA = 00H ;System PIA data A SYS_CNA = 01H ;System PIA control A SYS_DTB = 02H ;System PIA data B SYS_CNB = 03H ;System PIA control B TIM_CT0 = 04H ;8253 Timer counter 1 TIM_CT1 = 05H ;8253 Timer counter 2 TIM_CT2 = 06H ;8253 Timer counter 3 TIM_CNL = 07H ;8253 Timer control register DSK_CMD = 08H ;Floppy disk DISK COMMAND REG (WRITE) DSK_STS = DSK_CMD ;STATUS REG (READ) DSK_TRK = DSK_CMD+1 ;TRACK REG DSK_SEC = DSK_CMD+2 ;SECTOR REG DSK_DAT = DSK_CMD+3 ;DATA REG (R/W) SIO_DTA = 0CH ;SIO data reg A SIO_CNA = 0DH ;SIO control reg A SIO_DTB = 0EH ;SIO data reg B SIO_CNB = 0FH ;SIO control reg B PAR_DTA = 10H ;Parallel port PIA data A PAR_CNA = 11H ;Control register A PAR_DTB = 12H ;Parallel port PIA data B PAR_CNB = 13H ;Control register B KEYBD = 14H ;Keyboard PAGE  ;SYSTEM PIA COMMANDS ;DATA A: +---+---+---+---+---+---+---+---+ ; | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ; +---+---+---+---+---+---+---+---+ ; | | | | | | | | ; ROM enable <-+ | | | | | | | ; VIDEO enable <---+ | | | | | | ; Bank 6 enable <------+ | | | | | ; Bank 5 enable <----------+ | | | | ; Bank 4 enable <--------------+ | | | ; Bank 3 enable <------------------+ | | ; Bank 2 enable <----------------------+ | ; Bank 1 enable <--------------------------+ ;DATA B: +---+---+---+---+---+---+---+---+ ; | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ; +---+---+---+---+---+---+---+---+ ; | | | | | | | | ; RI(act low) <+ | | | | | | | ; DSR(act low) <---+ | | | | | | ; TX clock select <----+ | | | | | ; RX clock select <--------+ | | | | ; Speaker <--------------------+ | | | ; Drive B (act low) <--------------+ | | ; Drive A (act low) <------------------+ | ; Double density (act low) <---------------+ ;Data DATA_INIT = 1000_0000B ;Enable ROM DATB_INIT = 0000_0111B ;Deselect drives A & B, single density ;spkr off ;Direction DIRA_INIT = 1111_1111B ;Select all lines as outputs DIRB_INIT = 0011_1111B ;Select RI & DSR as inputs, rest as outputs ;Masks ROM_BANK = 1000_0000B ;ROM bank VID_BANK = 0100_0000B ;VIDEO bank SPEAKER = 0000_1000B ;Speaker bit PAGE ;SYSTEM PIA CONTROL REGISTERS ; +---+---+---+---+---+---+---+---+ ; | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ; +---+---+---+---+---+---+---+---+ ; | | | | | | | | ; INTERRUPT FLAGS: | | | | | | | | ; A: DMA Interrupt | | | | | | | | ; B: Real time clock interrupt <---+ | | | | | | | ; | | | | | | | ; Not used <-------+ | | | | | | ; | | | | |  | ; CONTROL 2: | | | | | | ; A: 110 = 64 columns, 111 = 80 columns | | | | | | ; B: 110 = 60 Hz, 111 = 50 Hz <---+---+---+ | | | ; | | | ; DDRA: | | | ; A & B: 1 = Data register, 0 = Direction register <--+ | | ; | | ; CONTROL 1: | | ; A: DMA interrupt request (hw) | | ; B: Real time clock interrupt | | ; | | ; 1 = active high <--------------------------------+ | ; 1 = enable <------------------------------------+ ;Control CA_DAT = 00_110_1_00B ;64 columns ;enable DATA reg ;Disable interrupts CA_DIR = 00_110_0_00B ;64 columns ;enable DIRECTION reg ;disable interrupts CA_64C = 00_110_1_01B ;64 columns ;enable data reg ;enable interrupts CB_DAT = 00_110_1_10B ;60Hz ;enable DATA reg ;Disable interrupts CB_DIR = 00_110_0_10B ;60Hz ;enable DIRECTION reg ;disable interrupts CB_A 60H = 00_110_1_11B ;60Hz ;enable data reg ;Enable interrupts ;Control masks COL_MSK = 00_001_0_00B ;64/80 Column mask INT_MSK = 00_000_0_01B ;Interrupt enable mask PAGE ;SERIAL PORT -- SIO COMMANDS ;SIO WRITE REGISTERS ;WRITE REG 0: +---+---+---+---+---+---+---+---+ ; | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ; +---+---+---+---+---+---+---+---+ ; | | | | | | | | ;CRC RESET CODES: | | | | | | | | ; Null 0 0 | | | | | | ; Reset Rx CRC checker 0 1 | | | | | | ; Reset Tx CRC generator 1 0 | | | | | | ; Reset Tx Underrun/EOM latch 1 1 | | | | | | ;COMMAND BITS: | | | | | | ; Null 0 0 0 | | | ; Send Abort 0 0 1 | | | ; Reset EXT/Status interrupt 0 1 0 | | | ; Channel reset 0 1 1 | | | ; Enable int on next Rx character 1 0 0 | | | ; Reset Tx int pending 1 0 1 | | | ; Error reset 1 1 0 | | | ; Return from int (Chan A only) 1 1 1 | | | ;POINTER BITS: | | | ; Register 0 0 0 0 ; Register 1 0 0 1 ; Register 2 0 1 0 ; Register 3 0 1 1 ; Register 4 1 0 0 ; Register 5 1 0 1 ; Register 6 1 1 0 ; Register 7 1 1 1 ;WRITE REG 1: +---+---+---+---+---+---+---+---+ ; | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ; +---+---+---+---+---+---+---+---+ ; | | | | | | | | ;WAIT/READY: | | | | | | | | ; Wait/Ready Enable <-+ | | | | | | | ; ~Wait/Ready Function <--+ | | | | | | ; Wait/Ready on Rx/Tx <------+ | | | | | ;Rx INTERRUPT MODE: | | | | | ; Rx interrupts disabled 0 0 | | | ; Rx int on first char 0 1 | | | ; Int on all Rx chars 1 0 | | | ; Int on all Rx chars 1 1 | | | ;Status Affects Vector (Chan B only) <--------------+ | | ;Tx Int Enable <---------------------------------------+ | ;Ext Int Enable <-------------------------------------------+ PAGE ;WRITE REG 2: +---+---+---+---+---+---+---+---+ ; | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ; +---+---+---+---+---+---+---+---+ ; | | | | | | | | ; | | | | | | | | ;Interrupt Vector <--------------+---+---+---+---+---+---+---+ ;WRITE REG 3: +---+---+---+---+---+---+---+---+ ; | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ; +---+---+---+---+---+---+---+---+ ; | | | | | | | | ;RECEIVER BITS/CHARA0 :Q:zzB~G#4V#^6Z6T]#%>2rxß*n+ͭ"n#~G:l x+~!9Oʃ!:Pʃ!9Lʃ>2r^#V#F>ßG> x,\]/*$+^^^&()=<> <= >= < > ~-ANDDEFEQGT GE HIGHLE LOWLT MODNE NOTORREVSHLSHRXOR+%>N>2r>#ß:px2p%x2pU+ͭڒ{ڒ#~"n*n+:s*n2s"n,> *n|ͻ#"n#~ ʺ*n+~ȷ+"n*f;9'>O+~2r+~+^+V"f:r2r2s=#%~+fo>>2s&:s*f<;9'>Sr#s#w#:rw#"fG*h;9'>Sp#"h>2q*h};9'+"h~!#%9nu d)0<D {ozg) {oz {oz#!)#!)##?##? 9'l3>2q}l:rG>2rx x> 24 ) ) 5%)5%) ͭ%) E=%) ͩ)z|5%ڻ PY ͩ)):*9 f':9="9$"9 !W$  Memory OVERFLOW Stopped ACT!/q#p# *9(%:9"9:~%"n::::`:97͆`i?ځ'ځ!d3r+s+7!`3Fx!.H!d0R!2Ͱ2b:!?GN#xy_y_ѯ°#7# y÷y?>E2:2:1>w##^#VO:9#y2r>U724*9*98*9*9:9'b! =# cSh= :|:9 ^= :~ w “9'ʺ# µ¥þÐ7!6> oD# 9'7ȷ0 :?[$b#b.b~J%# ~#,4J%~#o$4f'HO$:9@Õ!9~w*9z^:4 |.> 24.5:9 :4!?怰G:9W:9O@:9ʺyzz>@GzGG&z>+24*94~# !4> #6 #6#2*9#"9!4O$H> 245!4:G~=> w# 56 #6:9@!4\!94:9l$*9:9Gʅw#xl͜lx29"9*9:9q<•!z8$Ҹ:9@29!W$G29!"9List file write error. *9}J%: !f'* A ÀCP/M Version 3.0COPYRIGHT 1982, DIGITAL RESEARCH251082654321!9"k1G \!m!w# š!v6H#6E#6X!e6C#6O#6M<<&:g.".g"?S:2n!`w #4o"c*e{ozg"hj:]@*c"\y!5C*^N{zb+"^*^*`*h"!j4&"h"y:b<5*kG!gwxS0  *cN,*cN{zҽ{,*c*e{ozg ~*c#"c> :[ >  X N*c>:> !:q#G*eDM*h ERROR: $DISK READ$LOAD ADDRESS LESS THAN 100$DISK WRITE$LOAD ADDRESS $ERROR ADDRESS $INVALID HEX DIGIT$CHECKSUM ERROR $FIRST ADDRESS $LAST ADDRESS $BYTES READ $RECORDS WRITTEN $CANNOT OPEN SOURCE FILE$DIRECTORY FULL$CANNOT CLOSE FILE$HEXCOM VERS: 3.00 $ LDK A,0FFH STO A,CLZA ;SET TO IGNORE LEADING ZERO RET CLZA: DB '0' WBOOT: LDK A,'Z'-40H CALL COUT JMP WBOOTE PRINT: LD A,[HL] ORA A RZ PUSH HL CALL COUT POP HL INC HL JR PRINT GVCHR: ; Read a char: allow only carriage return. ; CALL C1 ;Get a char CMP CR ;Is it Carriage return? JNZ GVCHR ;No, get another ; RET ;Yes, return GET_ESC: ; Wait for user to enter ESC ; :GE: CALL C1 CMP ESC JNZ :GE ; RET C1: CALL CIN ORA A JRZ C1 RET COUT: MOV E,A JR F6 CIN: LDK E,0FFH F6: LDK C,06H JMP SYS TITLE 'CONSTANTS' ;DOUBLE DENSITY PARAMETERS DDPARM: DW DLIFMT ;LIFMT FOR DOUBLE DENSITY DW DOUBTO ;TRKOFS FOR DD DW DFORDAT ;FORDAT FOR DD DB 0 ;OSBORNE FORMAT ;SINGLE DENSITY PARAMETERS SDPARM: DW SLIFMT ;LIFMT FOR SINGLE DENSITY DW SINGTO ;TRKOFS FOR SD DW SFORDAT ;FORDAT&*9"2<29*9#"9&!\! \4>2$:9>B>20:0294:OJ%>$!4".%~*.>  ʄ>sw#UҚDښڛnpf'*99'ڼA6m#6a#6c#6 ###".6:9o:9=29bH:9!0*.6 #C*9!?~: ~ ~w 9'*9DM !?~Ex1}1Fd] d#KT]f 6 ^#VogʉNs#FrYP+y>!4".29|^#V#~/#oy&&".:9=29•5>Ë:9H#^*.&O:9:9:9:::?:92@/7N#F:@+w:9+w+p+qr+s*9#"9~#foþ' no ERRORs, 1234 Labels, h bytes not used. Program LWA = h. *Error page 999SYMBOL TABLE *Error page 999 SORCIM 808x Assembler ver 3.5E mm/dd/yy hh:mm Page 999 ~':9*:9'":Oi`) ))6 2:2:͎ *:"9p : f'::p : f'*:^ ͙ ~ *: ^ "::9:9w"*O::Q:#%9'!!*:"O:G_ :9:9<"#"" >!y2Q:&!!y2Q::Q: Q:G!!:"""#"z P!:N:'6 #6  :r!*O::Q:#%"O:2Q:2N:!):*@5w#}B!|6!!!B5u!"@5:9:9·"!!>12':*:"O: (!*@5B5!!B5V$!:929!!W$Hex file write error.  9'!p#9' "O:N:2N:yW :Q:O!):#%:9:9—"*O:x#%"O:!:~#f" #Oog5#o"_j#I"::O*O:9'Š":M:y2M:> "O:">\#!]#> *6"> *6"::O>*:":Y:"X:r!*@5B5!!"\#5#>>?:Z:y2Z:>\#yp ~ ###t#^#r# &#y?H#"N#_Pt#r#\r#@_t#\j#t#zK͛%O:Y:_G͆%!X:w{=#r!2X::Y:W{2Y:bzWu# Y w# ##7! wD$ѷ$ #7D$ѷ$ $D$7:k$`$l$f$>2k$>b$:k$O$2a$2k$O ͻ$~# ¡$Ù$ ͻ$x“$> _xUү$ͻ$Ä$|ͻ$ ͻ$ ~Oʹ#!$`$$ ?? OPEN error - l$!;6#e%!;l$:9%V:9͍zɅo$MDy_xW{z/W{/_xzW{_=%>  L%~ J%J%# S% As%@O:q#p#f'>.f'xy%%ɷ”%!%#%~?BK!xʾ% ô%BJ~0%:%A%[% #%+FyR&:p &x &Bʯ&N&Ql&Hʆ& :pBʯ&Ql&Hʆ&yG&A&;&5&'V&V&dV& V&V&7N&~0Q& Q&# =e&~0R&R&_ #M&)))l&~0R&:&AR&GR&_# M&))))Æ&~0R&R&)o# ²&M&&'&'&'&'}0>02'>0]T< &=kbG:''> x>2'0~0~0#y'z{x7# A'9'h' +~ x['x~# h'x~aڅ'{҅'# u'~#Í'7#Ö'zq#ã'O:'=@I±' ®'V|'}'Ɛ'@'ɯ2(#~:+:\'~@8(##(ͬ#<~>:7:(.$(~.#$(y^(!S:( ^(:(7x7~i(#.^(*V(>?a(~# :(G>  a(x!8(|8(;8(=8(:8(@ʖ(#ʖ(*ʖ(?›(2(a({ w!d:6͹-2e:>I24\..(>.c3]-Cͥ-M..c-3͓-c>d.cle3͓-c A m( (me3͓-(-3͓-͒"f:cme3͓-g-à,..͒Xx.c>I*͹-..e3M-M.>!.c3-ڰ)ͥ-*-3>)O- M."-.c3-ڰ)͹-3-- M.>!.cs-e3l- *n+~)͹-M.cs-3@-C*n"9e3\-)ͥ-M..cs-͹-g-3-*ͥ-3-(s-e3\-)ͥ-M..J,3-j*:-ʉ**3 *--"-ڰ*ͥ-.cs-3 -*3-a* \s-s-3-ڃ*:-ƒ*3-a*Ã*s-s-3-ڃ*3-ڃ*:-ƒ*a*s-s-3@-ڃ*͹-..c>H2+3@-++3 *n-+͹-M.cs-~[.+"nÝ,s-s-3-M+3-M+͹-(s-3-^+,s-3)-ڀ+͹-M.>!.͒"g:cs-e3:+O-ڧ+M.e3-Cͥ-.c:+>s-͒"f:́.Ó+H͹->!.c3-+:- ͹-(s-+>d.,Ce3\-Cͥ-M.>!..c3=-*,ͥ-M.͒"f:G,s-e3I-Cͥ-M.͒"f:́..>c3=-l,ͥ-M..cs-e3]-Cͥ-M..c3-ښ,ͥ-.cs-͹-͒"f:c3@-,3-,͹-M.>!.cs-3-,͹-M.>!.3@-Ccs-3 --3-Cͥ-.cs-e3m-;-M.e3l-;-͹-M.cs-3->:->3%->͹-M.>.8,͒"f:́.c!b:55>*9"n*`:##"`:~2d:#~2e:-CM.ͥ-.-ʹ-!d:4-4:9 *nͭ"ny_b#V"-|-͒x.}2-]Cͬ,=-@!.!g:Fw#p*f:"g:*d:o"e::9>C >$24:9>C >#:.*-}o|-^.!e:w͒د†.z†.[.}|†.|<:4 >V24ASMHEX080808085Z80 =+CADD ADICADCJACIANA#ANDANIASEG.ASSERT6BIT@CALLCBITCCCLCCMA/CMC?#CMPCMCNZCNCCPECPOCPDRCPDCPIRCPI#CPICPU3CPCSEG.CZDAA'DAD DA&DBE%DB%DCE%DCRDCX DC%@#DEC DIDJNZDSEG.DS!DW&ECHO5EIEJECT:ELSE=ENDM<endm<ENDIF=END(ENTRY,EQU+ERR;EXT-EXXBEXHLTvIDENT0IF=IM0FIM1VIM2^#INCINDRINDINIRINIINRINXIN,C@IN#JMPJNZJMJCJNCJPEJPOJPJZJRC8JRNC0JRNZ JRZ(JRLDAX LDA:LDDRLDDLDIRLDI#LDKrLD :*KFLHLD*LINK2LIST8"LKLOC#LXIMACRO5MVISMOVWG@(MSG9NEGDNOPORG"ORAORI"OROTDROTIROT,CAOUTDOUTIOUTPAGE:PCHLPOPPROC$PUSHRALRARRCREPT5RETIMRETNERETRIM RLC#RLCRLDo"RLRMRNCRNZRPERPORPRRC#RRCRRDgRRRSTRZSBBCSBCBSBITSBISET+@SHLD"SIM0SLA SPACE7SPHLSRA(SRL8STAXSTA2STC7sSTO2"Cp63SUBSUITITLE1USE/VFD)XCHG#XORXRAXRIXTHL'*M%6[HL]6[IX[IYB C D E H $L -AA?IR AFA6PSWA6SP!6IX$IYdBC B DE D HL$H$AFA6SP!6IX$IYdBC DE HL$[SP]!6[IX]$[IY]d[BC] [DE] [HL]$(((() )%)-))0)3)+G)(((+++*B),U,(,`))*!*8*,6Kl#([ uX" F a T E w  2ͮ8>2k$!"R:ͬ#<@27a5:2$:29͈8*9!\ f'"9"9:94!Vͪ5:95!zͪ5!Af'!~6!l$2!T l$!.7:9f$6!=5$h'*ABS *CODE *DATA !"5!~ 8#O 65͹8!?="9l9 8}6:929l96ͭ8^#VPY##$!\ ?'\!5$ ?? Hex or Prn file name same as Input = 5@R6H=06H=6LO7L=06L=CON:6L=LP:6L=6L6O7PS(7SLA7S=_7S\7R=07R=S7R=F7R7!.7\'8\V!.7z! 77:929Ô5!.V7Ô5>29!RE".>L2.P!:͡'Ô5Í5:9ï6>`2i$:9ï6! 7z7:9ï6PRN;729Ô5;7"9Ô5:;7d!x8872Ô5P;72`i+~=7#%8{7':!d8$YPf'7Sf'!8l$!288!R88!d88Command input errorNO source file specified, ABORTMal-formed numberIll-formed filenamePS > 99SL < 60/!'> :!'!8f' Page *%"9"9OD9T9 .9}|:k99~ 9 9, 9; 9|.9 .9.9a 9{ 9 w#86#8:k9(9~ .9.9#96#86go~<9ѯx~ O9 S9#D9~'d9"d92k96#2k95~#ʇ9<+w#_^#Vѯ7TTTTTTTTTTTTTTTTT=99hhhh?=???99?=?9 :9999990099 ?\:e:`: prompt/command response JMP X30D2 ; end  ',* < < < N O - F I L E M E N U > > >  D Open Document File | Y DELETE a file | H Set HELP LEVEL  N Open Non-document File | E RENAME a file | L Change Drive  X EXIT to System | O COPY a file | R Run a program  F Directory + | P   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  M Run MailMerge S Run SpellStar < < < N O - F I L E M E N U > > >   A  is terminated in a ; byte of 0. ; ; ENTRY: ; HL ==> string ; EXIT: ; None. ; LD A,[HL] ;Load current char INC HL ;Bump ptr to next char CMP 0 ;Is current byte 0 (end of string)? RZ ;Yes, return ; LK C,2 ;No, tell BDOS to send char to console MOV E,A PUSH HL ;Save ptr to next char in string CALL BDOS POP HL ;Restore ptr JR OUT_STRING ;and do next char... PAGE SET_CURSOR: ; Place the cursor next to the currently selected option. ; ; ENTRY: ; SIDE = 0 if on main menu side (always true in COPY) ; PUT_CURSOR is a cursor positioning string which is patched with ; the line number of the current selection (relative 32) in Y_COORD. ; ; EXIT: ; None. ; PROC LK HL,PUT_SUB_COORD ;Point at cursor positioning ;string for sub menu LD A,SIDE ;Are we on sub menu side? CMP 1 ; JRZ :SUB_SIDE ;Yes...position cursor there ; ;No. LK HL,PUT_CURSOR ;Point at cursor positioning ;string for main menu. :SUB_SIDE: CALL OUT_STRING ;Position cursor RET ;and return PAGE CMD_DESC: ; Display command description for currently selected command. ; Command description is NOT re-displayed if it has already been ; displayed. ; ; ; The first two bytes of a menu data structure is a pointer to a ; table of pointers to the command descriptions for that menu. ; ; ENTRY: ; Y_COORD = line # of current command ; ; EXIT: ; Sets NUM_SUB_CMDS according to number of sub-commands for command ; description (not used in COPY). ; PROC LD A,Y_COORD ;Load line # of current ;selection (relative-32). SUB 32 ;Make A relative 0 ADD A ;Double it to index into ;pointer table. MOV L,A ;Load it to HL LK H,0 LD DE,MENU_TABLE ;Load address of pointer table ADD HL,DE ;Index to pointer for current ;selection. LD E,[HL] ;Load pointer to current INC HL LD D,[HL] LD HL,O_SUB_MN ;Load address of last-displayed ;command description. STC CMC SBC HL,DE ;Is it same as new one? JZ :NO_DSP ;Yes, don't re-display it ; ;No. Display it STO DE,O_SUB_MN ;Save description as last LD A,[DE] ;Load number of subcommands for ;this menu STO A,NUM_SUB_CMDS ;Save it INC DE ;Bump DE to beginning of ;command description display ;data. LK C,PR_STR_FN ;Tell BDOS to print description CALL BDOS RET ;and return ; :NO_DSP: RET ;Current same as last, so don't display it ; ; ; Local storage for address of last command description displayed: ; O_SUB_MN: DW 0 PAGE F_CMD_DESC: ; Display general direction message and force re-display of command ; description for currently selected command. ; ; Command description IS re-displayed even if it has already been ; displayed. ; ; This routine is called after DO_COMMAND processes the current command. ; DO_COMMAND erases the command description and general directions and ; they must be restored even though the description has already been ; displayed. ; ; The first two bytes of a menu data structure is a pointer to a ; table of pointers to the command descriptions for that menu. ; ; ENTRY: ; Y_COORD = line # of current command ; ; EXIT: ; Sets NUM_SUB_CMDS according to number of sub-commands for command ; description (not used in COPY). ; ; PROC LK HL,DIR_MSG ;Display general (arrow key) directions CALL OUT_STRING LD A,Y_COORD ;Load line # of current ;selection (relative-32). SUB 32 ;Make A relative 0 ADD A ;Double it to index into ;pointer table. MOV L,A ;Load it to HL LK H,0 LD DE,MENU_TABLE ;Load address of pointer table ADD HL,DE ;Index to pointer for current ;selection. LD E,[HL] ;Load pointer to current INC HL LD D,[HL] LD A,[DE] ;Load number of subcommands for ;this menu STO A,NUM_SUB_CMDS ;Save it INC DE ;Bump DE to beginning of ;command description display ;data. LK C,PR_STR_FN ;Tell BDOS to print description CALL BDOS RET ;and return PAGE DO_COMMAND: ; Process the currently selected command on the currently selected ; menu. ; ; Clears current command description but re-displays it only if ; menu has NOT changed. ; ; ENTRY: ; Y_COORD = line # of current command. ; COM_TABLE = address of table of pointers to command routine for ; current menu. ; ; EXIT: ; None. ; PROC LK HL,:CLR_W_5 ;Clear command description for current CALL OUT_STRING ;command. LD A,Y_COORD ;Load line # of current command. SUB 32 ;Make relative - 0 ADD A ;Double to index into command ptr table MOV L,A LK H,0 LD DE,COM_TABLE ;Index into command table ADD HL,DE LD E,[HL] ;Load ptr to command routine INC HL LD D,[HL] EX DE,HL ;Put ptr in HL LK DE,:DO_RET ;Load address of return point PUSH DE ;and save as return address JMP [HL] ;Jump to command routine ; :DO_RET: ;Return point from command routine. LD DE,MAIN ;Has main menu changed? LD HL,OLD_MN STC CMC  A SBC HL,DE RNZ ;Yes, command descr must have changed, ;so return to driver without ;re-displaying it. CALL F_CMD_DESC ;Force re-display of command ;description and general directions CALL SET_CURSOR ;and reposition cursor at current ;choice RET ; ; String used to clear window 5: ; :CLR_W_5: DB ESC,'s5','Z'-40h,0 PAGE HI_CURR: ; Highlight (in reverse video) current command string on screen. ; ; ENTRY: ; A = line # (relative-32) of command string in window 1 ; Assumes ATT_OFS-th char of command string is attribute byte of attribute ; definition escape sequence (ESC-G-X) ; ; EXIT: ; None. ; PROC IF TVI912 :ATT_OFS = 3 ;Offset in command string to attribute ;byte :INV_ON = 'j' ;Reverse video on attribute char :INV_OFF = 'k' ;Reverse video off attribute char ENDIF IF TVI950 :ATT_OFS = 4 ;Offset in command string to attribute ;byte :INV_ON = '4' ;Reverse video on attribute char :INV_OFF = '0' ;Reverse video off attribute char ENDIF PUSH AF ;Save line # ADI W1BIAS ;Add bias for window 1 STO A,W_PCH_1 ;Save absolute line # in window defn STO A,W_PCH_2 ;string: begin and end line POP AF ;Restore line # SUB 32 ;Make it relative-0 LD HL,MAIN ;Get address of command line table LD E,[HL] ; INC HL ; LD D,[HL] ; EX HL,DE ;Put cmd line table addr in HL MOV E,A ;Index into it by cmd # LK D,0 ; ADD HL,DE ; ADD HL,DE ; LD E,[HL] ;Load addr of cmd line INC HL ; LD D,[HL] ; EX HL,DE ;Put it in HL PUSH HL ;Save addr LK DE,:ATT_OFS ;Index into cmd line string to attribute ADD HL,DE ;byte STO :INV_ON,[HL] ;Set attribute byte to reverse video LK HL,W_STR ;Set window for current line CALL OUT_STRING ; POP HL ;Restore address of cmd string PUSH HL ;Save it CALL OUT_STRING ;Display cmd string in reverse video POP HL ;restore cmd string addr LK DE,:ATT_OFS ;Index back to attribute byte ADD HL,DE ; STO :INV_OFF,[HL] ;Set it to normal RET ;and return PAGE UN_HI_CR: ; Remove highlighting from command string on screen ; ; ENTRY: ; A = line # (relative-32) of command string in window 1 ; ; EXIT: ; None. ; PUSH AF ;Save line # ADI W1BIAS ;Add bias for window 1 STO A,W_PCH_1 ;Save absolute line # in window defn STO A,W_PCH_2 ;string: begin and end line POP AF ;Restore line # SUB 32 ;Make it relative-0 LD HL,MAIN ;Get address of command line table LD E,[HL] ; INC HL ; LD D,[HL] ; EX HL,DE ;Put cmd line table addr in HL MOV E,A ;Index into it by cmd # LK D,0 ; ADD HL,DE ; ADD HL,DE ; LD E,[HL] ;Load addr of cmd line INC HL ; LD D,[HL] ; EX HL,DE ;Put it in HL PUSH HL ;Save it LK HL,W_STR ;Define window for current line CALL OUT_STRING ;Redisplay cmd string in normal mode POP HL ;Restore addr of cmd str CALL OUT_STRING ;Redisplay cmd string in normal mode RET ;and return PAGE ;------------------------------------------------------------------------------ ; Local storage for driver data structures follows. ; ; MENU_TABLE is a pointer to the table of pointers to command ; descriptions for each command in the current menu. ; MENU_TABLE: DW 0 ; ; COM_TABLE is a pointer to a table of pointers to command routines ; for each command in the current menu. ; COM_TABLE: DW 0 ; ; MAIN is a pointer to the current menu. ; MAIN: DW 0 PAGE EXIT: ; Program exit point. Program returns to CP/M from here: ; Sends termination string to console: sets window 0, clears screen ; and enables fn. key xlate. ; ; ENTRY: ; None. ; ; EXIT: ; None. ; LK DE,GOOD_BYE ;Send termination string to ;console. LK C,PR_STR_FN CALL BDOS JMP WBOOTE ;and warm start. ; GOOD_BYE: DB ESC,'s','0','Z'-040h ; ; For TVI 912 emulation, include string to enable fn. key xlate: ; IF TVI912 DB ESC,'e',0 ENDIF DB '$' PAGE SETM1: ; Make main menu the current menu. ; Main menu allows selection of drive A or B for fixing. ; ; ENTRY: ; None. ; ; EXIT: ; Parameters set for main menu. ; PROC LK HL,MENU1 ;Point to description table STO HL,MENU_TABLE ;for main menu LK HL,COM1 ;Point to routine table for STO HL,COM_TABLE ;main menu LK HL,MAIN1 ;Point to main menu data STO HL,MAIN ;structure. LK A,NO_OPT_1 ;Set # options for main menu STO A,NUM_OPTIONS LK A,33 ;Make Drive B the default ;selection. STO A,Y_COORD RET ;and return PAGE ;------------------------------------------------------------------------------ ; Menu command description and routine tables follow: ; MENU1: ;Table for main menu DW FIX_MSG DW FIX_MSG DW RET_CPM COM1: DW FIX_A ;Table for main menu DW FIX_B DW EXIT PAGE FIX_A: ; Format, drive A selected. ; Do format. ; LK A,'A' ;Specify drive A ; LK B,'D' ;Specify double-density CALL FIXIT ;Format the disk CALL CLR_W_3 ;Erase message window RET FIX_B: ; Format, dr Aive B selected. ; Do format. ; LK A,'B' ;Specify drive B ; LK B,'D' ;Specify double-density CALL FIXIT ;Format the disk CALL CLR_W_3 ;Erase message window RET PAGE CLR_W_3: ; Routine to clear window 3. Window 3 is used for execution ; status while performing an operation. ; LK HL,:CLR_3_STR ;Point at string to clear window CALL OUT_STRING ;and send to console. RET ; :CLR_3_STR: ; String to clear window 3. Selects window 3 and sends clear screen ; character. ; DB ESC,'s3',CLR_SCR,0 PAGE FIXIT: ; Disk fix routine ;ENTRY ; A = Disk to format ('A' or 'B') ;EXIT ;NONE PROC :LOOP: STO A,D_FMT_D STO A,D_FMT_D2 SUI 'A' STO A,SDISK CALL CLR_W_2 LD A,SDISK ;See if destination disk contains info CALL CK_INFO JZ :BLK_DSK ;No...format it ; LK HL,DSK_FMT ;Assume it does DEC A ;Does it (i.e., is A = 1) ? JZ :ASK ;It does, ask user if it should be ;overwritten ; LK HL,DK_MB_FMT ;Disk MAY have info. Ask user if it ;should be overwritten. :ASK: CALL PRINT CALL Y_N PUSH AF ;Save response CALL CLR_W_2 ;Clear question POP AF ;Restore response CMP 'N' ;No, RZ ;Don't format ; ;Yes, format disk :OVRD: :BLK_DSK: LK A,'D' ;Set density specification 850102 CALL STSAVTYP ;SET DENSITY CALL SETPARM ;SET PARAMITERS CALL FIXDSK ;Fix DISKETTE PUSH AF ;Save return code from FIXDSK LK C,0DH ;so the disk system can be reset. CALL SYS ;The disk system must be reset since ;the disk has effectively been changed ;by formatting it. POP AF ;Restore return code from FIXDSK CPI 'Q' LDK HL,ABTFMT ;FORMAT aborted JRZ :DONE ;If aborted ORA A LDK HL,GDFMT ;FORMAT completed successfully JRZ :DONE ;IF NO ERRORS :BAD: LDK HL,BDFMT ;ERROR IN FORMAT CALL PRINT CALL GET_ESC CALL CLR_W_2 RET ; :DONE: CALL PRINT CALL GVCHR CALL CLR_W_2 RET ; PAGE CK_INFO: ; Checks to see if there is info on disk. Calls sense density routine ; to see if the disk is formatted. If it is not formatted, there is no ; info. ; If disk is formatted, checks for files in directory. ; ; ENTRY: ; A = # of disk on which to check for info ; 0 means drive A, ; 1 means drive B. ; ; EXIT: ; A = 0 if disk has no info, ; A = 1 if disk has info and ; A = 2 if disk MAY HAVE info (i.e., can't be determined). ; Additionally: ; Z flag set if disk has no info ; Z flag clear if disk has or may have info. ; ; SIDE EFFECT: ; SDISK set to disk # (whatever A is on entry) ; PROC MOV B,A ;Save drive spec in B PUSH BC ;Save on stk STO A,SDISK ;Select disk for SENDEN CALL SENDEN ;Check for unformatted disk. Z is clear ;if disk no formatted. POP BC ;Restore disk # JNZ :NO_INFO ;Return code indicating no info ; MOV A,B ;Restore disk # to A INC A ;Make disk # relative-one per BDOS STO A,AMB_FCB ;Put drive spec in FCB for search for first LK DE,AMB_FCB ;Point at ambiguous FCB to check for any files. LK C,SRC_FIRST ;Tell BDOS to do search-for-first. CALL SYS ;Returns A = 0FFh if no files or if error INC A ;A = 0FFH? JNZ :INFO_FOUND ;No... ; XOR A ;Check for error. OR H ;Is H = 0? JNZ :CANT_TELL ;No, error occurred. ; :NO_INFO: ;No error, no info. XOR A ;Clear A and set Z flag RET ; :INFO_FOUND: ;Info on disk XOR A ;Return Z clear and A = 1 INC A RET :CANT_TELL: ;May be info. LK A,2 ;Return A = 2 and Z clear OR A RET PAGE CLR_W_2: PROC LK HL,:CLR_2_STR CALL PRINT RET ; :CLR_2_STR: DB ESC,'s2','Z'-40h,0 PAGE Y_N: PROC :YNLP: CALL C1 AND 5FH CMP 'Y' JZ :ECHO ; CMP 'N' JNZ :YNLP ; :ECHO: PUSH AF CALL COUT POP AF RET PAGE STSAVTYP: ;SET SAVTYP FOR FORMAT ;ENTRY ;A = 'S' FOR SINGLE DENSITY ;EXIT ;B = # OF SECTORS/TRACK PROC CPI 'S' JZ :SING ;IF SINGLE DENSITY ;DOUBLE DENSITY LDK A,DDTYP STO A,SAVTYP LDK B,5 ;SECTORS/TRACK RET ;SINGLE DENSITY :SING: LDK A,SDTYP STO A,SAVTYP LDK B,10 ;SECTORS/TRACK RET PAGE SETPARM: ;SET UP PARAMETERS THAT DEPEND ON DENSITY ;ENTRY ;B = # OF SECTORS/TRACK ;SAVTYP = SET ;EXIT ;PARAMETERS SET PROC MOV A,B STO A,NMSEC ;SECTORS/TRACK ORI 0FFH STO A,OSBFMT ;INITIALIZE TO NON-OSBORNE FORMAT ;CHECK FOR STANDARD OSBORNE DENSITIES LD A,SAVTYP ;DOUBLE DENSITY CPI DDTYP JZ :DD ;IF DOUBLE DENSITY SAVTYP 841006 ; CPI DSTYP ;DSDD uses same parameters as ssdd 841006 JNZ :2 ;Not dsdd 841006 ; :DD: MOV A,B ;VERIFY # OF SECTORS CPI DSEC JNZ :2 ;IF WRONG # OF SECTORS LDK HL,DDPARM ;DOUBLE DENSITY PARAMETERS JR :1 ;SINGLE DENSITY ;MOVE OSBORNE PARAMETERS TO PARM :1: LDK DE,PARM LDK BC,7 LDIR ;SET UP REMAINING PARAMETERS :2: RET PAGE FIXDSK: ; Fix SSDD disk. ;EXIT ;A = 0 IF NO ERRORS ; OFFH IF ERROR ; 'C'-40H IF ABORT PROC LDK HL,PFORMAT ;FORMAT MESSAGE CALL STRCON LDK A,1 STO A,SAVSEC ;SET SECTOR CALL RHOME ;HOME DRIVE JNZ :ERR ;ERROR RETURN ;FORMAT ANAD VERIFY ENTIRE DISK LDK HL,CRLF5S CALL PRINT XRA A ;START WITH TRACK 0 STO A,FMTERR ;NO ERRORS YET ;TRACK LOOP :TLOOP: STO A,SAVTRK ;UPDATE TRACK NUMBER XOR A ;Start with logical 841229 STO A,:LSIDE ;side 0 841229 INC A ;and physical 841229 STO A,:SIDE ;side 1 841229 LD A,SAVTYP ;Set side 1 in SAVTYP 841229 OR 0000_0010B ; 841229 STO A,SAVTYP :SLOOP: ;Top of side loop 841005 CALL FMTINT ;INITIALIZE FORMAT BUFFER(BUFF) LD A,:LSIDE ;Load logical side MOV C,A ;Pass it in C CALL STRK ;SET NEW TRACK and logical side ;INTO DATA IF NOT FMT_FIX LDK BC,BUFF ;POINT TO FWA OF BUFFER CALL RFORMAT ;FORMAT ONE TRACK ENDIF IF FMT_FIX LK HL,BUFF ;Point at buffer STO HL,DMADR ;save as DMA address IN SYS_DTA ;Get bank mask for TPA STO A,DMA_BANK ;and save as DMA bank CALL RFORMAT ;Format the track ENDIF JNZ :1 ;IF ERROR ; We don't verify since it doesn't matter if the format on ; side 1 is good. LDK A,'*' JMP :2 ;IF GOOD :1: LDK A,'E' STO A,FMTERR ;SET ERROR FLAG :2: CALL CONOUT ;OUTPUT INDICATOR CALL CKABORT RZ ;RETURN IF ABORT LD A,SAVTRK ;Go to next track INC A CMP MTRK JNZ :TLOOP ;CONTINUE TILL ALL TRACKS ;FINAL CHECK LD A,FMTERR ORA A JRNZ :ERR ;IF ERROR RET ;RETURN A=0 IF NO ERROR, A=0FFH IF ERROR :ERR: ORI 0FFH RET ;RETURN ERROR :SIDE: DB 0 ; 841005 :LSIDE: DB 0 ;Logical side PAGE FMTINT: ;MOVE FORMAT DATA TO HIGH RAM BUFFER ;SET BUFFER TO BE: ;0,1 = LENTH OF BUFFER ;2->END = BUFFER ;ENTRY ;NONE ;EXIT ;NONE PROC ;COPY 1ST SECTOR LDK DE,BUFF+2 ;FWA FOR DATA LD HL,FORDAT ;FWA OF DATA LD BC,LIFMT ;NUMBER OF BYTES LDIR ;MOVE LDK A,1 STO A,SECTOR ;SET SECTOR LD A,NMSEC ;SECTORS/TRACK DEC A MOV B,A ;COPY REMAINING SECTORS :LOOP: PUSH BC PUSH DE POP IY ;IY = FWA OF THIS SECTOR ;MAKE ONE SECTOR LD HL,FMTSD LD BC,LISEC LDIR ;MOVE ;SET SECTOR NUMBER LDK HL,SECTOR ;INC SECTOR INC [HL] ;CHECK FOR DENSITY LD A,SAVTYP CMP SDTYP ;SINGLE DENSITY? LD A,[HL] ;A = SECTOR JZ :S ;IF SINGLE STO A,[IY+(DFSECN-DFMTSD)] ;DOUBLE JR :1 :S:; STO A,[IY+(SFSECN-SFMTSD)] ;SINGLE :1: POP BC DJNZ :LOOP ;IF MORE SECTORS ;SET LENTH OF BUFFER IN BUFFER EX DE,HL LDK BC,BUFF+2 SBC HL,BC ;GET LENGTH STO HL,BUFF ;SET LENGTH INTO BUFFER RET PAGE STRK: ;SET TRACK NUMBERS AND SIDE INTO DATA 841005 ;ENTRY ; C = Logical side ; ;EXIT ;NONE PROC LDK HL,BUFF+1 LD DE,TRKOFS ADD HL,DE LD A,NMSEC MOV B,A ;B = # OF SECTORS LD DE,LISEC LD A,SAVTRK :2: STO A,[HL] ;UPDATE TRACK CELL INC HL ;Point to SIDE CELL 841005 STO C,[HL] ;Store side byte in side cell 841005 DEC HL ;Point back at TRACK CELL 841005 ADD HL,DE ;POINT TO NEXT DJNZ :2 ;IF NOT DONE RET TITLE 'CALLS TO ROM RESIDENT ROUTINES' GOROM: ;UTILITY IN CBIOS IS JUMPED TO THAT MOVES THE STACK AND SWITCHES IN THE ROM ;ENTRY ;DE = THE ADDRESS TO CALL IN THE ROM ;EXIT *NOTE* ; The exit conditions in the rom determine what the regesters will be PROC LD A,2 MOV H,A ;HIGH ORDER BYTE OF BIOS LDK L,5AH ;LOW ORDER BYTE FOR ROM JUMP ROUTINE JMP [HL] RHOME: ;HOME THE DISK DRIVE ;ENTRY ;NONE ;EXIT ;A = 0 IF NO ERROR ;ZBIT = RESET IF ERROR PROC LDK DE,RHM_RTN CALL GOROM RET SENDEN: ;SENCE THE DENSITY, SECTOR SIZE, AND NUMBER OF SECTORS ON ONE TRACK ;ENTRY ;NONE ;EXIT ;ZBIT = SET IF GOOD ;B = NUMBER OF SECTORS PER TRACK ;SAVTYP = SECTOR SIZE AND DENSITY PROC LDK DE,SEN_RTN CALL GOROM RET RREAD: ;READ SECTOR ;ENTRY ;B = NUMBER OF SECTORS ;SDISK = DRIVE ;DMADR = DMA ADRESS ;SAVTRK = TRACK ;SAVSEC = SECTOR ;SAVTYP = DENSITY AND SECTOR SIZE ;EXIT ;HL = NEXT DMA ADDR IF GOOD TRANSFER PROC LDK DE,RD_RTN CALL GOROM RET RWRITE: ;WRITE SECTOR ;ENTRY ;B = NUMBER OF SECTORS ;SDISK = DRIVE ;DMADR = DMA ADRESS ;SAVTRK = TRACK ;SAVSEC = SECTOR ;SAVTYP = DENSITY AND SECTOR SIZE ;EXIT ;HL = NEXT DMA ADDR IF GOOD TRANSFER ;A = 0 IF NO ERROR ;ZBIT = RESET IF ERROR PROC LDK DE,WRT_RTN CALL GOROM RET RFORMAT: ;FORMAT TRACK ;ENTRY ;NONE ;EXIT ;A = 0 IF NO ERROR ;ZBIT = RESET IF ERROR PROC LDK A,2 ;RETRY ONCE FOR FORMAT ERROR STO A,ERCOUNT :LOOP: LDK DE,FMT_RTN CALL GOROM RZ ;RETURN IF NO ERROR LK HL,ERCOUNT DEC [HL] JNZ :LOOP ;RETRY ORI 0FFH ;INDICATE ERROR RET RSETTRK: ;SET THE TRACK REGESTER TO SAVTRK ;ENTRY ;SAVTRK = TRACK NUMBER ;EXIT ;NONE ; Routine no longer implemented in ROM PROC ; LDK DE,184H ; CALL GOROM RET RSDRV: ;SELECT THE DRIVE IN SDISK ;ENTRY ;SDISK = DRIVE TO SELECT ;EXIT ;NONE PROC LDK DE,SDRV_RTN CALL GOROM RET RSTEPOUT: ;STEP HEAD OUT ONE TRACK ;ENTRY ;NONE ;EXIT ;NONE PROC LDK DE,STP_O_RTN CALL GOROM RET RSTEP: ;STEP HEAD ONE TRACK IN DIRECTION LACTER: | | | | | | | | ; 5 bits 0 0 | | | | | | ; 6 bits 0 1 | | | | | | ; 7 bits 1 0 | | | | | | ; 8 bits 1 1 | | | | | | ;Auto Enables <--------------------------+ | | | | | ;Enter Hunt Phase (not used) <---------------+ | | | | ;Rx CRC Enable <---------------------------------+ | | | ;Address Search Mode (not used) <--------------------+ | | ;SYNC Char Load Inhibit (not used) <---------------------+ | ;Rx Enable <---------------------------------------------+ ;WRITE REG 4: +---+---+---+---+---+---+---+---+ ; | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ; +---+---+---+---+---+---+---+---+ ; | | | | | | | | ;CLOCK MODE: | | | | | | | | ; X1 Clock Mode 0 0 | | | | AST STEPPED ;ENTRY ;NONE ;EXIT ;NONE PROC LDK DE,STP_RTN CALL GOROM RET TITLE 'USEFUL PROC"S' COMPSEG: ;COMPARE THE DATA IN THE TWO BUFFERS. ;ENTRY ;BC = NUMBER OF BYTES ;DE = FIRST BUFFER ;HL = SECOND BUFFER ;EXIT ;A = 0 IF NO ERRORS ;ZBIT RESET IF ERROR PROC PUSHAL :1: MOV A,B ;CHECK BC FOR ZERO ORA C JZ :2 ;GOOD RETURN LD A,[DE] CMP [HL] PUSH AF INC DE INC HL DEC BC POP AF JZ :1 ORI 0FFH ;INDICATE ERROR :2: POPALL RET PAGE CKABORT: ;CHECK IF ABORT CHARACTER HAS BEEN PRESSED ;ENTRY ;NONE ;EXIT ;A = CHARACTER ;ZBIT = SET IF ABORT CHARACTER PRESSED PROC CALL CIN ;CHECK FOR CHARACTER ANI 5FH ;MAKE UPPER CASE CPI 'Q' RET PAGE CONOUT: ;OUTPUT CHARACTER TO CONSOLE ;ENTRY ;A = CHARACTER PROC PUSHAL MOV E,A MVI C,2 CALL SYS POPALL RET PAGE STRCON: ;OUTPUT MESSAGE TO CONSOLE ;ENTRY ;HL = FWA OF MESSAGE ;EXIT ;NONE PROC PUSHAL EX DE,HL ;VALUE TO DE LDK C,9 ;STRING CALL SYS  ;BDOS POPALL RET PAGE WBOOT: LDK A,'Z'-40H CALL COUT JMP WBOOTE PRINT: LD A,[HL] ORA A RZ PUSH HL CALL COUT POP HL INC HL JR PRINT GVCHR: ; Read a char: allow only carriage return. ; CALL C1 ;Get a char CMP CR ;Is it Carriage return? JNZ GVCHR ;No, get another ; RET ;Yes, return GET_ESC: ; Wait for user to enter ESC ; :GE: CALL C1 CMP ESC JNZ :GE ; RET C1: CALL CIN ORA A JRZ C1 RET COUT: MOV E,A JR F6 CIN: LDK E,0FFH F6: LDK C,06H JMP SYS TITLE 'CONSTANTS' ;DOUBLE DENSITY PARAMETERS DDPARM: DW DLIFMT ;LIFMT FOR DOUBLE DENSITY DW DOUBTO ;TRKOFS FOR DD DW DFORDAT ;FORDAT FOR DD DB 0 ;OSBORNE FORMAT ;SINGLE DENSITY PARAMETERS ;SDPARM: DW SLIFMT ;LIFMT FOR SINGLE DENSITY ; DW SINGTO ;TRKOFS FOR SD ; DW SFORDAT ;FORDAT FOR SD ; DB 0 ;OSBORNE FORMAT ;PARAMETERS STORED HERE PARM: LISEC: ;LISEC = LIFMT LIFMT: DS 2 TRKOFS: DS 2 FMTSD: ;FMTSD = FORDAT FORDAT: DS 2 OSBFMT: DS 1 ;OSBFMT = 0 IF OSBORNE FORMAT, OTHERWISE 0FFH NMSEC: DS 1 ;# OF SECTORS/TRACK TRKLEN: DS 2 ;# OF BYTES/TRACK NUMTRK: DS 1 ;# OF TRACKS/BLOCK NUMBLK: DS 1 ;# OF BLOCKS/DISK PTRKLEN: DS 2 ; 841006 NSIDES: DS 1 ; 841006 OVRD_FLAG: DS 1 ;True if check for formatted destination disk ;should be overridden PAGE ; Data and all message constants AMB_FCB: ;Ambiguous FCB to search for files in the ;directory of a disk DB 0 DB '????????','???','?' DB 0,0,0 DB 0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0 DB 0,0,0,0 ;***** SYSTEM MESSAGES OS_BAD_MSG: db 'FIXSSDD requires CP/M 3.X or greater.',cr,lf DB 'Copyright ' DB ESC,VSGH,CP_RG_CH,ESC,VEGH ;Set graphics mode, show ;copyright char and clr ;graphics DB ' 1984 Future Systems, 828 Nob Hill Avenue, ' DB 'Pinole CA 94564',cr,lf,0 SCR_TOP: DB ESC,'s','0','Z'-040h,ESC,'=',32,32 DB ' Single Sided Single Density Disk Fixup Program' D cr,lf D  Osborn EXECUTIV Compute System' DB CR,LF DB ' V1.0' DB 0 COPYR_MSG: DB ESC,'s2',CLR_SCR ; DB ' ' ; DB ESC,VSGH,CP_RG_CH,ESC,VEGH ;Set graphics mode, show ;copyright char and clr ;graphics ; DB ' 1983 Osborne Computer Corporation, 26538 Danti Court, ' ; DB 'Hayward, CA 94545',cr,lf DB ' ' DB ESC,VSGH,CP_RG_CH,ESC,VEGH ;Set graphics mode, show ;copyright char and clr ;graphics DB ' 1984 Future Systems, 828 Nob Hill Avenue, ' DB 'Pinole CA 94564',0 NO_OPT_1: = 3 IF TVI912 MAIN1: DW MAIN_1_L DB ESC,'s','1','Z'-040h,ESC,'=',32,32 MN_1_A: DB ' ',ESC,'k Fix Disk in Drive A ',ESC,'k',0,CR,LF MN_1_B: DB ' ',ESC,'k Fix Disk in Drive B ',ESC,'k',0,CR,LF MN_1_C: DB ' ',ESC,'k RETURN TO CP/M ',ESC,'k',0,CR,LF DB CR,LF D '$' ENDIF MAIN_1_L: DW MN_1_A DW MN_1_B DW MN_1_C DIR_MSG: db ESC,'s5','Z'-40h db ' Use the ARROW keys to position the',cAr,lf db ' cursor next to the desired choice',cr,lf db ' or',0 RET_CPM: db 0 db ESC,'s6','Z'-40h db ' Press RETURN to Return to CP/M$' FIX_MSG: db 0 db ESC,'s6','Z'-40h db ' Insert a Diskette in selected drive and',cr,lf db ' Press RETURN to start fixing',cr,lf db cr,lf db ESC,'^WARNING: ',ESC,'jDo not attempt to fix a truly double ' db 'sided disk! It will be DESTROYED!',ESC,'k',ESC,'q$' PAGE NUM_OPTIONS DB 0 ;# OF OPTIONS in current ;main menu SIDE: DB 0 ;0-LEFT MENU, 1- RIGHT PUT_CURSOR: DB ESC,'s','1',ESC,'=' ;MAIN MENU CURSOR POSITION Y_COORD: DB 32 X_COORD: DB 32 DB 0 PUT_SUB_CURSOR: DB ESC,'s','2',ESC,'=' ;MAIN MENU CURSOR POSITION Y_SUB_COORD: DB 32 X_SUB_COORD: DB 32 DB 0 NUM_SUB_CMDS: DS 1 ;# OF COMMANDS IN SUB MENU NUL_MSG: M_EXIT: DB 0 DB ESC,'s','2','Z'-040h DB ESC,'s','1' DB '$' PAGE CRLF5S: DB ESC,'s3',cr,lf,lf,lf DB ' ',0 PFORMAT: DB ESC,'s5','Z'-40h DB cr,lf DB ' Press and Hold Q to Quit Fixing' DB ESC,'s','3','Z'-040h DB ' Track Fixed:',cr,lf DB ' 0 1 2 3 ' DB CR,LF DB ' 0123456789012345678901234567890123456789',cr,lf DB '$' SECTOR: DB 0 ;FOR FORMAT SOURCE: DB 0 ;SOURCE DRIVE FOR COPY TRACK: DB 0 ;ACTIVE LOGICAL TRACK BLOCK: DB 0 ;ACTIVE BLOCK NUMBER DSK_FMT: DB ESC,'s2','Z'-40h DB ' Diskette in Drive ' D_FMT_D: DB 'X' ;Filled in by FMAT or KOPY DB ' contains information.',cr,lf DB ' Is it OK to overwrite it (y/n)? ',0 DK_MB_FMT: DB ESC,'s2','Z'-40h DB ' Diskette in Drive ' D_FMT_D2: DB 'X' ;Filled in by FMAT or KOPY DB ' MAY contain information.',cr,lf DB ' Is it OK to overwrite it (y/n)? ',0 END: DB CR,LF,LF DB 0 GDFMT: DB ESC,'s','2','Z'-040h DB ' Fixing completed successfully.',cr,lf DB ' Press RETURN to continue.' DB 0 BDFMT: DB ESC,'s','2','Z'-040h DB ' Error while fixing.',cr,lf DB ' Press ESC to continue.' DB 0 ABTFMT: DB ESC,'s','2','Z'-040h DB ' FIXING ABORTED.',cr,lf DB ' Press RETURN to continue.' DB 0 PAGE DFORDAT: ;DOUBLE DENSITY FORMAT DATA FOR IBM 3740. *NOTE* ;NO INDEX MARK IS USED ; **** GAP 1 **** DFMTSD: ECHO 100 ! DB 04EH ENDM ECHO 12 ! DB 0 ENDM DB 0F5H,0F5H,0F5H DB 0FEH ;ID ADDRESS MARK DFTRKN: DB 0 ;TRACK DOUBTO = *-DFORDAT DB 0 ;SIDE DFSECN: DB 1 ;SECTOR DB 3 ;SECTOR LENTH DB 0F7H ;CRC ; **** GAP 2 **** ECHO 22 ! DB 04EH ENDM ECHO 12 ! DB 0 ENDM DB 0F5H,0F5H,0F5H DB 0FBH ;DATA ADDRESS MARK ; **** DATA **** ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM DFCRC2: DB 0F7H ;CRC DFMTEND = * DLIFMT = *-DFORDAT DLISEC = *-DFMTSD ERCOUNT: DB 0 ;ERROR COUNTER LBUFF1: DW 0 ;HOLD FBA IN BUFF1 MACHTYPE: DB 0 ;MACHINE DENSITY ; 0 = Undefined ; 1 = Single ; 2 = Double FMTERR: DB 0 ;FORMAT ERROR FLAG ;BUFFS: DS 7000 ;SAVE BUFFER DS 40*2 STACK: DS 0 ;STACK HERE ; END SD: ECHO 100 ! DB 04EH ENDM ECHO 12 ! DB 0 ENDM DB 0F5H,0F5H,0F5H DB 0FEH ;ID ADDRESS MARK DFTRKN: DB 0 ;TRACK DOUBTO = *-DFORDAT DB 0 ;SIDE DFSECN: DB 1 ;SECTOR DB 3 ;SECTOR LENTH DB 0F7H ;CRC ; **** GAP 2 **** ECHO 22 ! DB 04EH ENDM ECHO 12 ! DB 0 ENDM DB 0F5H,0F5H,0F5H DB 0FBH ;DATA ADDRESS MARK ; **** DATA **** E;.Date: 12/29/84 ;.Last Modified: DAB ;.Title: Executive Single Sided Single Density Disk Fixup ; Utility (FIXSSDD) ;.Comments: V1.0 ; +---------------+ ; | | ; | EXECUTIVE | ; | DISK | ; | UTILITY | ; | | ; +---------------+ ; ; (c) 1984 Future Systems ; 828 Nob Hill Avenue ; Pinole, CA 94564 ; ; This program is intended to solve a problem encountered by ; users of Future Systems' Double Sided Disk Drive upgrade ; for the OCC Executive. ; ; The problem is experienced when a user takes a disk formatted ; double sided and puts it in a single sided system. If the disk ; is reformatted or copied to with the full disk copy program ; COPY (which reformats the destination disk) and placed back in ; the double sided system, the double sided system will mistakenly ; recognize the disk as double sided. ; ; This has to do with how the routine SENDEN determines whether ; a disk is double or single sided. The mechanism used is as follows: ; First, SENDEN tries toA read side 1 (the 'second side' which single ; sided disks don't have). If side 1 can't be read, the disk is ; obviously single sided. However, if it can be read, the disk isn't ; necessarily double sided. ; ; In fact, the disk may have once been formatted double sided ; and then reformatted single sided. To discriminate between ; a truly double sided disk and one which has been reformatted ; single density, a special technique is necessary. Fortunately, ; floppy disk formats provide a means for this. Each physical sector ; on the disk has a header. This header contains (among other things) ; the track number, sector number and side number (0 or 1). ; ; A truly double sided disk is formatted so that sectors on side ; 0 have headers indicating side 0 and sectors on side 1 have headers ; indicating side 1. An obvious (?) mechanism to allow recognition ; of single sided disks is to format both sides but to format sectors ; on side 1 so that they indicate side 0 instead of 1. This is ; in fact what COPY V1.2 does. ; ; Thus, if SENDEN can read side 1, it checks to see if a sector on ; side 1 is marked side 1 or 0. If it's 0, the disk is single sided. ; If it's 1, the disk is double sided. ; ; The only hitch is in the case mentioned above, where a single ; sided system is used to reformat a double sided disk. A single ; sided system is incapable of formatting side 1 in any manner. ; Thus the disk still has sectors on side 1 marked side 1. ; When SENDEN in the double sided system, checks the disk, it still ; thinks it is double sided, even though the user intends that ; the disk be considered single sided. ; ; When the user does a directory on the disk, she will get ; garbage, since the directory is on track 1 for a double ; sided system and on track 3 for a single sided system. ; ; This program fixes up a single sided disk (which is mistakenly ; recognized) by reformatting side 1 so that each sector header ; indicates side 0. This results in SENDEN correctly recognizing ; the disk as single sided. ; ; It cannot be overstated that this program should be run only ; on single sided disks. It will destroy double sided disks! page ; include High RAM data structure definitions: LINK RAMS10.ASM ;RAM memory locations and constants ; ; Conditional assembly equates: ; ; ; Generation toggles: ; BETA_TEST = true ; ; ROM terminal emulation supported: ; IF BETA_TEST TVI950 = false ENDIF IF NOT BETA_TEST TVI950 = true ENDIF TVI912 = not TVI950 ; ; ROM format fix supported: ; IF BETA_TEST FMT_FIX = true ENDIF IF NOT BETA_TEST FMT_FIX = false ENDIF ; ; Copy and format data areas: ; BUFF = 4000H ;VERIFY BUFFER(5120 BYTES) BUFF1 = BUFF+5120 SSMASK = 0000_0010B ;Side select mask 841006 SDTYP = 0000_0101B ;SINGLE DENSITY SAVTYP DDTYP = 0000_1100B ;DOUBLE DENSITY SAVTYP DSTYP = DDTYP OR SSMASK ;Double sided savtyp 841006 DSEC = 5 ;DOUBLE DENSITY SECTORS/TRACK SSEC = 10 ;SINGLE DENSITY SECTORS/TRACK ; ; ROM JMP vectors: ; RHM_RTN = 157h ;RDRV (Home drive) SEN_RTN = 160h ;SENDEN (Sense density) RD_RTN = 15Ah ;RSEC (Read physical sector from disk) WRT_RTN = 15Dh ;WSEC (Write physical sector to disk) FMT_RTN = 163h ;FORMAT (Format track) SDRV_RTN = 166h ;SELDRV (Select drive) STP_O_RTN = 16Ch ;STEP OUT (Step drive out) STP_RTN = 169h ;STEP (Step drive in same direction as last ;step) ; ; BDOS function numbers: ; PR_STR_FN = 9 ;BDOS print string function OS_VER_FN = 12 ;BDOS version number function SRC_FIRST = 17 ;BDOS search for first matching file SET_ER_MD = 45 ;BDOS set error mode (CP/M Plus only) ; ; Macro definitions: ; PUSHAL MACRO PUSH BC PUSH DE PUSH HL ENDM POPALL MACRO POP HL POP DE POP BC ENDM ; ; Character definitions: ; CTRL_G = 'G' - 40h CTRL_H = 'H' - 40h CTRL_J = 'J' - 40h CTRL_K = 'K' - 40h CTRL_L = 'L' - 40h CTRL_S = 'S' - 40h CTRL_Z = 'Z' - 40h ;Control-Z ; ; Executive definitions: ; CP_RG_CH = CTRL_S ;Copyright character ; ; CP/M definitios: ; WBOOTE = 0000H ;Warm boot emtry point TPA_Base = 0100h ;Base of TPA EOF_Mark = CTRL_Z ;CP/M logical end-of-file marker CPM_PLUS = 30h ;Value returned by function 12 is greater than ;or equal to this if running CP/M Plus. ; ; Console definitions: ; BELL_Char = CTRL_G ;Char to ring bell. CLR_SCR = CTRL_Z ;Char to clear screen (or current window) ;VEGH ;Clear Graphics mode esc seqn defined in ;systext ;VSGH ;Set Graphics mode esc seqn defined in ;systext ;VWDEF ;Define window esc seqn defined in systext ; ; Keyboard definitions: ; RAW_UP = 8ah ;Untranslated cursor up char RAW_DOWN = 8ch ;Untranslated cursor down char PAGE ORG TPA_Base ;Start code at base of TPA JMP START ;Jump around copyright and version stamp ;to start of code. JMP SW0 ;Entry pt to set window 0 for debugging ; ; Copyright and version stamp: ; DB cr,lf DB ' Copyright ' DB ESC,VSGH,CP_RG_CH,ESC,VEGH ;Set graphics Amode, show ;copyright char and clr ;graphics DB ' 1984 Future Systems, 828 Nob Hill Avenue, ',cr,lf DB 'Pinole CA 94564',cr,lf DB ' V1.0',EOF_Mark SW0: LK HL,W0S ;Set window 0 CALL OUT_STRING RET W0S: DB ESC,'s0',0 PAGE START: ;Start of COPY main program. LDK SP,STACK ;Set up local stack PROC ; ; Make sure CP/M Plus is running. ; LK C,OS_VER_FN ;Get OS version # CALL BDOS MOV A,H ;Check for H = 0 OR A JNZ :OS_BAD ;H ne 0, not running CP/M ; MOV A,L ;Check for L => 30 CMP CPM_PLUS ; JNC :OS_OK ;L => 30... ; :OS_BAD: ;Not running CP/M 3.X or greater LK HL,OS_BAD_MSG ;Print message and quit CALL OUT_STRING JMP 0 ;Warm Boot... ; :OS_OK: ;OS ok, continue... LK E,0FFh ;Set BDOS error return mode to RETURN ERRORS LK C,SET_ER_MD ; CALL SYS PAGE ; Menu screen driver begins here: ; BDOS EQU 0005h ;BDOS entry point UP EQU CTRL_K ;TVI character for cursor up DOWN EQU CTRL_J ;TVI char for cursor down RIGHT EQU CTRL_L ;TVI char for cursor right LEFT EQU CTRL_H ;TVI char for cursor left ENTER EQU cr ;Char entered by user to execute command PAGE PROC START1: ; ; Driver initialization code: ; CALL SET_STUFF ;Initialize windows used by driver LK HL,SCR_TOP ;Display program name and vers num CALL OUT_STRING LK HL,COPYR_MSG ;Display copyright message CALL OUT_STRING CALL SET_M1 ;Make current menu menu #1: main menu: ;Select copy or format :COPY: ; ; Return point for driver function execution ; ; ; See if current menu has already been displayed: ; LD DE,MAIN ;Load address of current menu LD HL,OLD_MN ;and compare with address of last ;menu displayed. STC CMC SBC HL,DE JZ :NO_DSP ;Menu already displayed, don't re- ;display. ; STO DE,OLD_MN ;Menu must be displayed. Save address ;of menu as last displayed. INC DE ;Bump ptr past address of command INC DE ;string table to start of menu display ;data. LK C,PR_STR_FN ;Tell BDOS to print it. CALL BDOS LD A,Y_COORD ;Hilight default selection CALL HI_CURR LK HL,DIR_MSG ;Display arrow key directions CALL OUT_STRING CALL CMD_DESC ;Display command description for ;this menu's default selection CALL SET_CURSOR ;Set cursor next to default selection. ; ; Branch point if current menu already displayed: ; :NO_DSP: LK DE,:COPY ;Load address of top of driver loop PUSH DE ;and push on stack as return address ;for the next user command. ; ; Wait for user to enter char and process accordingly: ; :GET_CH: ;Return here if invalid char entered. CALL GET_CHAR ;Wait for char to A CMP UP ;Is it TVI cursor up char? JZ MOVE_UP ;Yes, move up. ; ;No. CMP RAW_UP ;Is it raw (untranslated) up char? JZ MOVE_UP ;Yes, move up. ; CMP DOWN ;Is it TVI move down? JZ MOVE_DOWN ;Yes... ; ;No. CMP RAW_DOWN ;Is it raw down char? JZ MOVE_DOWN ;Yes... ; ; CMP RIGHT ;Horizontal motion not supported. ; JZ MOVE_RIGHT ; CMP 08Bh ; JZ MOVE_RIGHT ; CMP LEFT ; JZ MOVE_LEFT ; CMP 08Dh ; JZ MOVE_LEFT ; CMP ENTER ;Is it enter command? JZ DO_COMMAND ;Yes, process current command. ; CALL BEEP ;Char invalid. Ring bell. JMP :GET_CH ;and wait for another char... ; ; Local storage to save address of last menu displayed. ; OLD_MN: DW 0 PAGE SET_STUFF: ; Initialize driver: set up necessary windows. Disable function key ; translation. ; ; ENTRY: ; None. ; EXIT: ; Windows initialized. ; LK HL,INIT_STRING ;Point at window init string. CALL OUT_STRING ;Send it to console LK HL,XL_OFF ;Point at fn key xlate off string CALL OUT_STRING ;send it RET ;and return. ; INIT_STRING: ;Windows for screen driver. Window 4 is defined on ;the fly to display command string in reverse video. W1BIAS = 4 ;Bias into window 1 ; ; Window 1 is used for current menu: ; DB ESC,VWDEF,'1',32+W1BIAS,32+20 ,32+11 ,32+80 ; ; Window 2 is used for completion or error message reporting: ; DB ESC,VWDEF,'2',32+20 ,32 ,32+23 ,32+80 ; ; Window 3 is used for execution status while performing commands ; (such as copy or format): ; DB ESC,VWDEF,'3',32+13,32,32+19,32+80 ; ; Window 5 is used for general directions applicable to all commands: ; DB ESC,VWDEF,'5',32+10,32+0,32+16,32+80 ; ; Window 6 is used for command specific directions: ; DB ESC,VWDEF,'6',32+13,32+0,32+16,32+80 ; ; Reselect window zero after defining windows: ; DB ESC,'s','0','Z'-040h D 0 ; ; String to disable fn. key xlate: ; XL_OFF: IF TVI950 DB 0 ENDIF IF TVI912 DB ESC,'f',0 ENDIF ; ; String to define window 4: ; W_STR: DB ESC,VWDEF,'4' ;String to define window used for W_PCH_1: DB 32+6,32+20 ;displaying cmd string in reverse W_PCH_2: DB 32+15,32+80,0 ;video PAGE MOVE_UP: ; User entered cursor up key. Make selection above the current in menu ; the new current selection if the top most selection is not alreAady ; current. In other words, move up if not at tup. ; ; ENTRY: ; Y_COORD = line # of current selection. ; Current selection is highlighted on screen. ; ; EXIT: ; Y_COORD = line # of current selection. ; Current selection is highlighted on screen. ; PROC L HL,Y_COOR ;Poin a lin o curren selection ;for 'main' menu. LD A,SIDE ;What side are we on (left or right)? CMP 0 ; JRZ :LEFT ;We're on left (main) side... ; ;We're on right (sub command side) LK HL,Y_SUB_COORD ;Point at line # for sub menu. :LEFT: LD A,[HL] ;Load line # of current selection CMP 32 ;Are we at top? JRZ :AT_TOP ;Yes... ; ;No. PUSH AF ;Save line number of old selection DEC A ;Compute and save new selection STO A,[HL] POP AF ;Restore line # of old selection CALL UN_HI_CR ;Un highlight it LD A,Y_COORD ;Load line # of current CALL HI_CURR ;and highlight it CALL CMD_DESC ;Print description for new command CALL SET_CURSOR ;Place cursor next to current selection RET ;and return ; :AT_TOP: ;Can't go up 'cause we're already at ;top. CALL BEEP ;Ring the bell RET ;and return PAGE MOVE_DOWN: ; User entered cursor down key. Make selection below the current in menu ; the new current selection if the botttom most selection is not already ; current. In other words, move down if not at bottom. ; ; ENTRY: ; Y_COORD = line # of current selection. ; Current selection is highlighted on screen. ; ; EXIT: ; Y_COORD = line # of current selection. ; Current selection is highlighted on screen. ; PROC LK HL,Y_COORD ;Point at line # for main menu LD A,SIDE ;Are we on the main menu side? CMP 0 JRZ :LEFT ;Yes... ; ;No. LK HL,Y_SUB_COORD ;Point at line # for sub-menu LD A,NUM_SUB_CMDS ;Load # of sub-commands. ADD A,31 ;Bias by 32 MOV B,A ;and save in B LD A,[HL] ;Load line # of current selection CMP B ;Are they the same (are we at bottom)? JRZ :AT_BOTTOM ;Yes... ; JR :9 ;No... ; :LEFT: ;Main menu is current. ; ; Are we at bottom? ; LD A,NUM_OPTIONS ;Load total # of commands ADD A,31 ;Bias by 32 MOV B,A ;save in B LD A,[HL] ;Load line # of current selection CMP B ;Are they the same? JRZ :AT_BOTTOM ;Yes...at bottom already... ; :9: ;Not at bottom yet. PUSH AF ;Save line # of old setting INC A ;Bump to next one down STO A,[HL] ;Save in appropriate data structure ;(main or sub) POP AF ;Restore old line # CALL UN_HI_CR ;Un highlight current LD A,Y_COORD ;load line # of current CALL HI_CURR ;Highlight it CALL CMD_DESC ;Display description for current ;command CALL SET_CURSOR ;Place cursor next to current RET ;selection and return. ; :AT_BOTTOM: ;Current selection is the bottom one. ;Can't move down any more. CALL BEEP ;Ring bell RET ;and return. PAGE MOVE_RIGHT: ; Move right not implemented. ; LD A,NUM_SUB_CMDS CMP 0 JRZ :6 ;NO SUB MENU ! LD A,SIDE CMP 1 JRZ :6 LK A,1 STO A,SIDE LK A,32 STO A,Y_SUB_COORD CALL SET_CURSOR RET :6: CALL BEEP RET PAGE MOVE_LEFT: ; Move left not implemented. ; LD A,SIDE CMP 0 JRZ :7 LK A,0 STO A,SIDE CALL SET_CURSOR RET :7: CALL BEEP RET PAGE BEEP: ; Ring the bell as a warning. ; ; ENTRY: ; None. ; EXIT: ; None. ; LK E,BELL_Char LK C,2 CALL BDOS ;Tell BDOS to print char RET PAGE CLS: ; Clear the current window on the screen. ; ; ENTRY: ; None. ; EXIT: ; None. ; LK E,CLR_SCR LK C,2 CALL BDOS ;Tell BDOS to print char RET PAGE GET_CHAR: ; Wait for user to enter char. ; Uses BDOS direct console I/O so no chars are filtered. ; ; ENTRY: ; None. ; EXIT: ; A = character entered. ; LK E,0FFh ;Ask BDOS for a char LK C,6 CALL BDOS ;BDOS returns 0 if no chars CMP 0 ;Is there a char? JRZ GET_CHAR ;No, ask again. RET ;Yes. Return. PAGE OUT_STRING: ; Send string pointed to by HL to console. String is terminated in a ; byte of 0. ; ; ENTRY: ; HL ==> string ; EXIT: ; None. ; LD A,[HL] ;Load current char INC HL ;Bump ptr to next char CMP 0 ;Is current byte 0 (end of string)? RZ ;Yes, return ; LK C,2 ;No, tell BDOS to send char to console MOV E,A PUSH HL ;Save ptr to next char in string CALL BDOS POP HL ;Restore ptr JR OUT_STRING ;and do next char... PAGE SET_CURSOR: ; Place the cursor next to the currently selected option. ; ; ENTRY: ; SIDE = 0 if on main menu side (always true in COPY) ; PUT_CURSOR is a cursor positioning string which is patched with ; the line number of the current selection (relative 32) in Y_COORD. ; ; EXIT: ; None. ; PROC LK HL,PUT_SUB_COORD ;Point at cursor positioning ;string for sub menu LD A,SIDE ;Are we on sub menu side? CMP 1 ; JRZ :SUB_SIDE ;Yes...position cursor there ; ;No. LK HL,PUT_CURSOR ;Point at cursor positioning ;string for main menu. :SUB_SIDE: CALL OUT_STARING ;Position cursor RET ;and return PAGE CMD_DESC: ; Display command description for currently selected command. ; Command description is NOT re-displayed if it has already been ; displayed. ; ; ; The first two bytes of a menu data structure is a pointer to a ; table of pointers to the command descriptions for that menu. ; ; ENTRY: ; Y_COORD = line # of current command ; ; EXIT: ; Sets NUM_SUB_CMDS according to number of sub-commands for command ; description (not used in COPY). ; PROC LD A,Y_COORD ;Load line # of current ;selection (relative-32). SUB 32 ;Make A relative 0 ADD A ;Double it to index into ;pointer table. MOV L,A ;Load it to HL LK H,0 LD DE,MENU_TABLE ;Load address of pointer table ADD HL,DE ;Index to pointer for current ;selection. LD E,[HL] ;Load pointer to current INC HL LD D,[HL] LD HL,O_SUB_MN ;Load address of last-displayed ;command description. STC CMC SBC HL,DE ;Is it same as new one? JZ :NO_DSP ;Yes, don't re-display it ; ;No. Display it STO DE,O_SUB_MN ;Save description as last LD A,[DE] ;Load number of subcommands for ;this menu STO A,NUM_SUB_CMDS ;Save it INC DE ;Bump DE to beginning of ;command description display ;data. LK C,PR_STR_FN ;Tell BDOS to print description CALL BDOS RET ;and return ; :NO_DSP: RET ;Current same as last, so don't display it ; ; ; Local storage for address of last command description displayed: ; O_SUB_MN: DW 0 PAGE F_CMD_DESC: ; Display general direction message and force re-display of command ; description for currently selected command. ; ; Command description IS re-displayed even if it has already been ; displayed. ; ; This routine is called after DO_COMMAND processes the current command. ; DO_COMMAND erases the command description and general directions and ; they must be restored even though the description has already been ; displayed. ; ;;.Date: 12/29/84 ;.Last Modified: DAB ;.Title: Executive Single Sided Single Density Disk Fixup ; Utility (FIXSSDD) ;.Comments: V1.0 ; +---------------+ ; | | ; | EXECUTIVE | ; | DISK | ; | UTILITY | ; | | ; +---------------+ ; ; (c) 1984 Future Systems ; 828 Nob Hill Avenue ; Pinole, CA 94564 ; ; This program is intended to solve a problem encountered by ; users of Future Systems' Double Sided Disk Drive upgrade ; for the OCC Executive. ; ; The problem is experienced when a user takes a disk formatted ; double sided and puts it in a single sided system. If the disk ; is reformatted or copied to with the full disk copy program ; COPY (which reformats the destination disk) and placed back in ; the double sided system, the double sided system will mistakenly ; recognize the disk as double sided. ; ; This has to do with how the routine SENDEN determines whether ; a disk is double or single sided. The mechanism used is as follows: ; First, SENDEN tries to read side 1 (the 'second side' which single ; sided disks don't have). If side 1 can't be read, the disk is ; obviously single sided. However, if it can be read, the disk isn't ; necessarily double sided. ; ; In fact, the disk may have once been formatted double sided ; and then reformatted single sided. To discriminate between ; a truly double sided disk and one which has been reformatted ; single density, a special technique is necessary. Fortunately, ; floppy disk formats provide a means for this. Each physical sector ; on the disk has a header. This header contains (among other things) ; the track number, sector number and side number (0 or 1). ; ; A truly double sided disk is formatted so that sectors on side ; 0 have headers indicating side 0 and sectors on side 1 have headers ; indicating side 1. An obvious (?) mechanism to allow recognition ; of single sided disks is to format both sides but to format sectors ; on side 1 so that they indicate side 0 instead of 1. This is ; in fact what COPY V1.2 does. ; ; Thus, if SENDEN can read side 1, it checks to see if a sector on ; side 1 is marked side 1 or 0. If it's 0, the disk is single sided. ; If it's 1, the disk is double sided. ; ; The only hitch is in the case mentioned above, where a single ; sided system is used to reformat a double sided disk. A single ; sided system is incapable of formatting side 1 in any manner. ; Thus the disk still has sectors on side 1 marked side 1. ; When SENDEN in the double sided system, checks the disk, it still ; thinks it is double sided, even though the user intends that ; the disk be considered single sided. ; ; When the user does a directory on the disk, she will get ; garbage, since the directory is on track 1 for a double ; sided system and on track 3 for a single sided system. ; ; This program fixes up a single sided disk (which is mistakenly ; recognized) by reformatting side 1 so that each sector header ; indicates side 0. This results in SENDEN correctly recognizing ; theA disk as single sided. ; ; It cannot be overstated that this program should be run only ; on single sided disks. It will destroy double sided disks! page ; include High RAM data structure definitions: LINK RAMS10.ASM ;RAM memory locations and constants ; ; Conditional assembly equates: ; ; ; Generation toggles: ; BETA_TEST = true ; ; ROM terminal emulation supported: ; IF BETA_TEST TVI950 = false ENDIF IF NOT BETA_TEST TVI950 = true ENDIF TVI912 = not TVI950 ; ; ROM format fix supported: ; IF BETA_TEST FMT_FIX = true ENDIF IF NOT BETA_TEST FMT_FIX = false ENDIF ; ; Copy and format data areas: ; BUFF = 4000H ;VERIFY BUFFER(5120 BYTES) BUFF1 = BUFF+5120 SSMASK = 0000_0010B ;Side select mask 841006 SDTYP = 0000_0101B ;SINGLE DENSITY SAVTYP DDTYP = 0000_1100B ;DOUBLE DENSITY SAVTYP DSTYP = DDTYP OR SSMASK ;Double sided savtyp 841006 DSEC = 5 ;DOUBLE DENSITY SECTORS/TRACK SSEC = 10 ;SINGLE DENSITY SECTORS/TRACK ; ; ROM JMP vectors: ; RHM_RTN = 157h ;RDRV (Home drive) SEN_RTN = 160h ;SENDEN (Sense density) RD_RTN = 15Ah ;RSEC (Read physical sector from disk) WRT_RTN = 15Dh ;WSEC (Write physical sector to disk) FMT_RTN = 163h ;FORMAT (Format track) SDRV_RTN = 166h ;SELDRV (Select drive) STP_O_RTN = 16Ch ;STEP OUT (Step drive out) STP_RTN = 169h ;STEP (Step drive in same direction as last ;step) ; ; BDOS function numbers: ; PR_STR_FN = 9 ;BDOS print string function OS_VER_FN = 12 ;BDOS version number function SRC_FIRST = 17 ;BDOS search for first matching file SET_ER_MD = 45 ;BDOS set error mode (CP/M Plus only) ; ; Macro definitions: ; PUSHAL MACRO PUSH BC PUSH DE PUSH HL ENDM POPALL MACRO POP HL POP DE POP BC ENDM ; ; Character definitions: ; CTRL_G = 'G' - 40h CTRL_H = 'H' - 40h CTRL_J = 'J' - 40h CTRL_K = 'K' - 40h CTRL_L = 'L' - 40h CTRL_S = 'S' - 40h CTRL_Z = 'Z' - 40h ;Control-Z ; ; Executive definitions: ; CP_RG_CH = CTRL_S ;Copyright character ; ; CP/M definitios: ; WBOOTE = 0000H ;Warm boot emtry point TPA_Base = 0100h ;Base of TPA EOF_Mark = CTRL_Z ;CP/M logical end-of-file marker CPM_PLUS = 30h ;Value returned by function 12 is greater than ;or equal to this if running CP/M Plus. ; ; Console definitions: ; BELL_Char = CTRL_G ;Char to ring bell. CLR_SCR = CTRL_Z ;Char to clear screen (or current window) ;VEGH ;Clear Graphics mode esc seqn defined in ;systext ;VSGH ;Set Graphics mode esc seqn defined in ;systext ;VWDEF ;Define window esc seqn defined in systext ; ; Keyboard definitions: ; RAW_UP = 8ah ;Untranslated cursor up char RAW_DOWN = 8ch ;Untranslated cursor down char PAGE ORG TPA_Base ;Start code at base of TPA JMP START ;Jump around copyright and version stamp ;to start of code. JMP SW0 ;Entry pt to set window 0 for debugging ; ; Copyright and version stamp: ; DB cr,lf DB ' Copyright ' DB ESC,VSGH,CP_RG_CH,ESC,VEGH ;Set graphics mode, show ;copyright char and clr ;graphics DB ' 1984 Future Systems, 828 Nob Hill Avenue, ',cr,lf DB 'Pinole CA 94564',cr,lf DB ' V1.0',EOF_Mark SW0: LK HL,W0S ;Set window 0 CALL OUT_STRING RET W0S: DB ESC,'s0',0 PAGE START: ;Start of COPY main program. LDK SP,STACK ;Set up local stack PROC ; ; Make sure CP/M Plus is running. ; LK C,OS_VER_FN ;Get OS version # CALL BDOS MOV A,H ;Check for H = 0 OR A JNZ :OS_BAD ;H ne 0, not running CP/M ; MOV A,L ;Check for L => 30 CMP CPM_PLUS ; JNC :OS_OK ;L => 30... ; :OS_BAD: ;Not running CP/M 3.X or greater LK HL,OS_BAD_MSG ;Print message and quit CALL OUT_STRING JMP 0 ;Warm Boot... ; :OS_OK: ;OS ok, continue... LK E,0FFh ;Set BDOS error return mode to RETURN ERRORS LK C,SET_ER_MD ; CALL SYS PAGE ; Menu screen driver begins here: ; BDOS EQU 0005h ;BDOS entry point UP EQU CTRL_K ;TVI character for cursor up DOWN EQU CTRL_J ;TVI char for cursor down RIGHT EQU CTRL_L ;TVI char for cursor right LEFT EQU CTRL_H ;TVI char for cursor left ENTER EQU cr ;Char entered by user to execute command PAGE PROC START1: ; ; Driver initialization code: ; CALL SET_STUFF ;Initialize windows used by driver LK HL,SCR_TOP ;Display program name and vers num CALL OUT_STRING LK HL,COPYR_MSG ;Display copyright message CALL OUT_STRING CALL SET_M1 ;Make current menu menu #1: main menu: ;Select copy or format :COPY: ; ; Return point for driver function execution ; ; ; See if current menu has already been displayed: ; LD DE,MAIN ;Load address of current menu LD HL,OLD_MN ;and compare with address of last ;menu displayed. STC CMC SBC HL,DE JZ :NO_DSP ;Menu already displayed, don't re- ;display. ; STO DE,OLD_MN ;Menu must be displayed. Save address ;of menu as last displayed. INC DE ;Bump ptr past address of command INC DE ;string table to start of menu display ;data. LK CA,PR_STR_FN ;Tell BDOS to print it. CALL BDOS LD A,Y_COORD ;Hilight default selection CALL HI_CURR LK HL,DIR_MSG ;Display arrow key directions CALL OUT_STRING CALL CMD_DESC ;Display command description for ;this menu's default selection CALL SET_CURSOR ;Set cursor next to default selection. ; ; Branch point if current menu already displayed: ; :NO_DSP: LK DE,:COPY ;Load address of top of driver loop PUSH DE ;and push on stack as return address ;for the next user command. ; ; Wait for user to enter char and process accordingly: ; :GET_CH: ;Return here if invalid char entered. CALL GET_CHAR ;Wait for char to A CMP UP ;Is it TVI cursor up char? JZ MOVE_UP ;Yes, move up. ; ;No. CMP RAW_UP ;Is it raw (untranslated) up char? JZ MOVE_UP ;Yes, move up. ; CMP DOWN ;Is it TVI move down? JZ MOVE_DOWN ;Yes... ; ;No. CMP RAW_DOWN ;Is it raw down char? JZ MOVE_DOWN ;Yes... ; ; CMP RIGHT ;Horizontal motion not supported. ; JZ MOVE_RIGHT ; CMP 08Bh ; JZ MOVE_RIGHT ; CMP LEFT ; JZ MOVE_LEFT ; CMP 08Dh ; JZ MOVE_LEFT ; CMP ENTER ;Is it enter command? JZ DO_COMMAND ;Yes, process current command. ; CALL BEEP ;Char invalid. Ring bell. JMP :GET_CH ;and wait for another char... ; ; Local storage to save address of last menu displayed. ; OLD_MN: DW 0 PAGE SET_STUFF: ; Initialize driver: set up necessary windows. Disable function key ; translation. ; ; ENTRY: ; None. ; EXIT: ; Windows initialized. ; LK HL,INIT_STRING ;Point at window init string. CALL OUT_STRING ;Send it to console LK HL,XL_OFF ;Point at fn key xlate off string CALL OUT_STRING ;send it RET ;and return. ; INIT_STRING: ;Windows for screen driver. Window 4 is defined on ;the fly to display command string in reverse video. W1BIAS = 4 ;Bias into window 1 ; ; Window 1 is used for current menu: ; DB ESC,VWDEF,'1',32+W1BIAS,32+20 ,32+11 ,32+80 ; ; Window 2 is used for completion or error message reporting: ; DB ESC,VWDEF,'2',32+20 ,32 ,32+23 ,32+80 ; ; Window 3 is used for execution status while performing commands ; (such as copy or format): ; DB ESC,VWDEF,'3',32+13,32,32+19,32+80 ; ; Window 5 is used for general directions applicable to all commands: ; DB ESC,VWDEF,'5',32+10,32+0,32+16,32+80 ; ; Window 6 is used for command specific directions: ; DB ESC,VWDEF,'6',32+13,32+0,32+16,32+80 ; ; Reselect window zero after defining windows: ; DB ESC,'s','0','Z'-040h D 0 ; ; String to disable fn. key xlate: ; XL_OFF: IF TVI950 DB 0 ENDIF IF TVI912 DB ESC,'f',0 ENDIF ; ; String to define window 4: ; W_STR: DB ESC,VWDEF,'4' ;String to define window used for W_PCH_1: DB 32+6,32+20 ;displaying cmd string in reverse W_PCH_2: DB 32+15,32+80,0 ;video PAGE MOVE_UP: ; User entered cursor up key. Make selection above the current in menu ; the new current selection if the top most selection is not already ; current. In other words, move up if not at tup. ; ; ENTRY: ; Y_COORD = line # of current selection. ; Current selection is highlighted on screen. ; ; EXIT: ; Y_COORD = line # of current selection. ; Current selection is highlighted on screen. ; PROC L HL,Y_COOR ;Poin a lin o curren selection ;for 'main' menu. LD A,SIDE ;What side are we on (left or right)? CMP 0 ; JRZ :LEFT ;We're on left (main) side... ; ;We're on right (sub command side) LK HL,Y_SUB_COORD ;Point at line # for sub menu. :LEFT: LD A,[HL] ;Load line # of current selection CMP 32 ;Are we at top? JRZ :AT_TOP ;Yes... ; ;No. PUSH AF ;Save line number of old selection DEC A ;Compute and save new selection STO A,[HL] POP AF ;Restore line # of old selection CALL UN_HI_CR ;Un highlight it LD A,Y_COORD ;Load line # of current CALL HI_CURR ;and highlight it CALL CMD_DESC ;Print description for new command CALL SET_CURSOR ;Place cursor next to current selection RET ;and return ; :AT_TOP: ;Can't go up 'cause we're already at ;top. CALL BEEP ;Ring the bell RET ;and return PAGE MOVE_DOWN: ; User entered cursor down key. Make selection below the current in menu ; the new current selection if the botttom most selection is not already ; current. In other words, move down if not at bottom. ; ; ENTRY: ; Y_COORD = line # of current selection. ; Current selection is highlighted on screen. ; ; EXIT: ; Y_COORD = line # of current selection. ; Current selection is highlighted on screen. ; PROC LK HL,Y_COORD ;Point at line # for main menu LD A,SIDE ;Are we on the main menu side? CMP 0 JRZ :LEFT ;Yes... ; ;No. LK HL,Y_SUB_COORD ;Point at line # for sub-menu LD A,NUM_SUB_CMDS ;Load # of sub-commands. ADD A,31 ;Bias by 32 MOV B,A ;and save in B LD A,[HL] ;Load line # of current selection CMP B ;Are they the same (are we at bottom)? JRZ :AT_BOTTOM ;Yes... ; JR :9 ;No...A ; :LEFT: ;Main menu is current. ; ; Are we at bottom? ; LD A,NUM_OPTIONS ;Load total # of commands ADD A,31 ;Bias by 32 MOV B,A ;save in B LD A,[HL] ;Load line # of current selection CMP B ;Are they the same? JRZ :AT_BOTTOM ;Yes...at bottom already... ; :9: ;Not at bottom yet. PUSH AF ;Save line # of old setting INC A ;Bump to next one down STO A,[HL] ;Save in appropriate data structure ;(main or sub) POP AF ;Restore old line # CALL UN_HI_CR ;Un highlight current LD A,Y_COORD ;load line # of current CALL HI_CURR ;Highlight it CALL CMD_DESC ;Display description for current ;command CALL SET_CURSOR ;Place cursor next to current RET ;selection and return. ; :AT_BOTTOM: ;Current selection is the bottom one. ;Can't move down any more. CALL BEEP ;Ring bell RET ;and return. PAGE MOVE_RIGHT: ; Move right not implemented. ; LD A,NUM_SUB_CMDS CMP 0 JRZ :6 ;NO SUB MENU ! LD A,SIDE CMP 1 JRZ :6 LK A,1 STO A,SIDE LK A,32 STO A,Y_SUB_COORD CALL SET_CURSOR RET :6: CALL BEEP RET PAGE MOVE_LEFT: ; Move left not implemented. ; LD A,SIDE CMP 0 JRZ :7 LK A,0 STO A,SIDE CALL SET_CURSOR RET :7: CALL BEEP RET PAGE BEEP: ; Ring the bell as a warning. ; ; ENTRY: ; None. ; EXIT: ; None. ; LK E,BELL_Char LK C,2 CALL BDOS ;Tell BDOS to print char RET PAGE CLS: ; Clear the current window on the screen. ; ; ENTRY: ; None. ; EXIT: ; None. ; LK E,CLR_SCR LK C,2 CALL BDOS ;Tell BDOS to print char RET PAGE GET_CHAR: ; Wait for user to enter char. ; Uses BDOS direct console I/O so no chars are filtered. ; ; ENTRY: ; None. ; EXIT: ; A = character entered. ; LK E,0FFh ;Ask BDOS for a char LK C,6 CALL BDOS ;BDOS returns 0 if no chars CMP 0 ;Is there a char? JRZ GET_CHAR ;No, ask again. RET ;Yes. Return. PAGE OUT_STRING: ; Send string pointed to by HL to console. String is terminated in a ; byte of 0. ; ; ENTRY: ; HL ==> string ; EXIT: ; None. ; LD A,[HL] ;Load current char INC HL ;Bump ptr to next char CMP 0 ;Is current byte 0 (end of string)? RZ ;Yes, return ; LK C,2 ;No, tell BDOS to send char to console MOV E,A PUSH HL ;Save ptr to next char in string CALL BDOS POP HL ;Restore ptr JR OUT_STRING ;and do next char... PAGE SET_CURSOR: ; Place the cursor next to the currently selected option. ; ; ENTRY: ; SIDE = 0 if on main menu side (always true in COPY) ; PUT_CURSOR is a cursor positioning string which is patched with ; the line number of the current selection (relative 32) in Y_COORD. ; ; EXIT: ; None. ; PROC LK HL,PUT_SUB_COORD ;Point at cursor positioning ;string for sub menu LD A,SIDE ;Are we on sub menu side? CMP 1 ; JRZ :SUB_SIDE ;Yes...position cursor there ; ;No. LK HL,PUT_CURSOR ;Point at cursor positioning ;string for main menu. :SUB_SIDE: CALL OUT_STRING ;Position cursor RET ;and return PAGE CMD_DESC: ; Display command description for currently selected command. ; Command description is NOT re-displayed if it has already been ; displayed. ; ; ; The first two bytes of a menu data structure is a pointer to a ; table of pointers to the command descriptions for that menu. ; ; ENTRY: ; Y_COORD = line # of current command ; ; EXIT: ; Sets NUM_SUB_CMDS according to number of sub-commands for command ; description (not used in COPY). ; PROC LD A,Y_COORD ;Load line # of current ;selection (relative-32). SUB 32 ;Make A relative 0 ADD A ;Double it to index into ;pointer table. MOV L,A ;Load it to HL LK H,0 LD DE,MENU_TABLE ;Load address of pointer table ADD HL,DE ;Index to pointer for current ;selection. LD E,[HL] ;Load pointer to current INC HL LD D,[HL] LD HL,O_SUB_MN ;Load address of last-displayed ;command description. STC CMC SBC HL,DE ;Is it same as new one? JZ :NO_DSP ;Yes, don't re-display it ; ;No. Display it STO DE,O_SUB_MN ;Save description as last LD A,[DE] ;Load number of subcommands for ;this menu STO A,NUM_SUB_CMDS ;Save it INC DE ;Bump DE to beginning of ;command description display ;data. LK C,PR_STR_FN ;Tell BDOS to print description CALL BDOS RET ;and return ; :NO_DSP: RET ;Current same as last, so don't display it ; ; ; Local storage for address of last command description displayed: ; O_SUB_MN: DW 0 PAGE F_CMD_DESC: ; Display general direction message and force re-display of command ; description for currently selected command. ; ; Command description IS re-displayed even if it has already been ; displayed. ; ; This routine is called after DO_COMMAND processes the current command. ; DO_COMMAND erases the command description and general directions and ; they must be restored even though the description has already been ; displayed. ; ;A The first two bytes of a menu data structure is a pointer to a ; table of pointers to the command descriptions for that menu. ; ; ENTRY: ; Y_COORD = line # of current command ; ; EXIT: ; Sets NUM_SUB_CMDS according to number of sub-commands for command ; description (not used in COPY). ; ; PROC LK HL,DIR_MSG ;Display general (arrow key) directions CALL OUT_STRING LD A,Y_COORD ;Load line # of current ;selection (relative-32). SUB 32 ;Make A relative 0 ADD A ;Double it to index into ;pointer table. MOV L,A ;Load it to HL LK H,0 LD DE,MENU_TABLE ;Load address of pointer table ADD HL,DE ;Index to pointer for current ;selection. LD E,[HL] ;Load pointer to current INC HL LD D,[HL] LD A,[DE] ;Load number of subcommands for ;this menu STO A,NUM_SUB_CMDS ;Save it INC DE ;Bump DE to beginning of ;command description display ;data. LK C,PR_STR_FN ;Tell BDOS to print description CALL BDOS RET ;and return PAGE DO_COMMAND: ; Process the currently selected command on the currently selected ; menu. ; ; Clears current command description but re-displays it only if ; menu has NOT changed. ; ; ENTRY: ; Y_COORD = line # of current command. ; COM_TABLE = address of table of pointers to command routine for ; current menu. ; ; EXIT: ; None. ; PROC LK HL,:CLR_W_5 ;Clear command description for current CALL OUT_STRING ;command. LD A,Y_COORD ;Load line # of current command. SUB 32 ;Make relative - 0 ADD A ;Double to index into command ptr table MOV L,A LK H,0 LD DE,COM_TABLE ;Index into command table ADD HL,DE LD E,[HL] ;Load ptr to command routine INC HL LD D,[HL] EX DE,HL ;Put ptr in HL LK DE,:DO_RET ;Load address of return point PUSH DE ;and save as return address JMP [HL] ;Jump to command routine ; :DO_RET: ;Return point from command routine. LD DE,MAIN ;Has main menu changed? LD HL,OLD_MN STC CMC SBC HL,DE RNZ ;Yes, command descr must have changed, ;so return to driver without ;re-displaying it. CALL F_CMD_DESC ;Force re-display of command ;description and general directions CALL SET_CURSOR ;and reposition cursor at current ;choice RET ; ; String used to clear window 5: ; :CLR_W_5: DB ESC,'s5','Z'-40h,0 PAGE HI_CURR: ; Highlight (in reverse video) current command string on screen. ; ; ENTRY: ; A = line # (relative-32) of command string in window 1 ; Assumes ATT_OFS-th char of command string is attribute byte of attribute ; definition escape sequence (ESC-G-X) ; ; EXIT: ; None. ; PROC IF TVI912 :ATT_OFS = 3 ;Offset in command string to attribute ;byte :INV_ON = 'j' ;Reverse video on attribute char :INV_OFF = 'k' ;Reverse video off attribute char ENDIF IF TVI950 :ATT_OFS = 4 ;Offset in command string to attribute ;byte :INV_ON = '4' ;Reverse video on attribute char :INV_OFF = '0' ;Reverse video off attribute char ENDIF PUSH AF ;Save line # ADI W1BIAS ;Add bias for window 1 STO A,W_PCH_1 ;Save absolute line # in window defn STO A,W_PCH_2 ;string: begin and end line POP AF ;Restore line # SUB 32 ;Make it relative-0 LD HL,MAIN ;Get address of command line table LD E,[HL] ; INC HL ; LD D,[HL] ; EX HL,DE ;Put cmd line table addr in HL MOV E,A ;Index into it by cmd # LK D,0 ; ADD HL,DE ; ADD HL,DE ; LD E,[HL] ;Load addr of cmd line INC HL ; LD D,[HL] ; EX HL,DE ;Put it in HL PUSH HL ;Save addr LK DE,:ATT_OFS ;Index into cmd line string to attribute ADD HL,DE ;byte STO :INV_ON,[HL] ;Set attribute byte to reverse video LK HL,W_STR ;Set window for current line CALL OUT_STRING ; POP HL ;Restore address of cmd string PUSH HL ;Save it CALL OUT_STRING ;Display cmd string in reverse video POP HL ;restore cmd string addr LK DE,:ATT_OFS ;Index back to attribute byte ADD HL,DE ; STO :INV_OFF,[HL] ;Set it to normal RET ;and return PAGE UN_HI_CR: ; Remove highlighting from command string on screen ; ; ENTRY: ; A = line # (relative-32) of command string in window 1 ; ; EXIT: ; None. ; PUSH AF ;Save line # ADI W1BIAS ;Add bias for window 1 STO A,W_PCH_1 ;Save absolute line # in window defn STO A,W_PCH_2 ;string: begin and end line POP AF ;Restore line # SUB 32 ;Make it relative-0 LD HL,MAIN ;Get address of command line table LD E,[HL] ; INC HL ; LD D,[HL] ; EX HL,DE ;Put cmd line table addr in HL MOV E,A ;Index into it by cmd # LK D,0 ; ADD HL,DE ; ADD HL,DE ; LD E,[HL] ;Load addr of cmd line INC HL ; LD D,[HL] ; EX HL,DE ;Put it in HL PUSH HL ;Save it LK HL,W_STR ;Define window for current line CALL OUT_STRING ;Redisplay cmd string in normal mode POP HL ;Restore addr of cmd str CALL OUT_STRING ;Redisplay cmd string in normal mode RET ;and return PAGE ;------------------------------------A------------------------------------------ ; Local storage for driver data structures follows. ; ; MENU_TABLE is a pointer to the table of pointers to command ; descriptions for each command in the current menu. ; MENU_TABLE: DW 0 ; ; COM_TABLE is a pointer to a table of pointers to command routines ; for each command in the current menu. ; COM_TABLE: DW 0 ; ; MAIN is a pointer to the current menu. ; MAIN: DW 0 PAGE EXIT: ; Program exit point. Program returns to CP/M from here: ; Sends termination string to console: sets window 0, clears screen ; and enables fn. key xlate. ; ; ENTRY: ; None. ; ; EXIT: ; None. ; LK DE,GOOD_BYE ;Send termination string to ;console. LK C,PR_STR_FN CALL BDOS JMP WBOOTE ;and warm start. ; GOOD_BYE: DB ESC,'s','0','Z'-040h ; ; For TVI 912 emulation, include string to enable fn. key xlate: ; IF TVI912 DB ESC,'e',0 ENDIF DB '$' PAGE SETM1: ; Make main menu the current menu. ; Main menu allows selection of drive A or B for fixing. ; ; ENTRY: ; None. ; ; EXIT: ; Parameters set for main menu. ; PROC LK HL,MENU1 ;Point to description table STO HL,MENU_TABLE ;for main menu LK HL,COM1 ;Point to routine table for STO HL,COM_TABLE ;main menu LK HL,MAIN1 ;Point to main menu data STO HL,MAIN ;structure. LK A,NO_OPT_1 ;Set # options for main menu STO A,NUM_OPTIONS LK A,33 ;Make Drive B the default ;selection. STO A,Y_COORD RET ;and return PAGE ;------------------------------------------------------------------------------ ; Menu command description and routine tables follow: ; MENU1: ;Table for main menu DW FIX_MSG DW FIX_MSG DW RET_CPM COM1: DW FIX_A ;Table for main menu DW FIX_B DW EXIT PAGE FIX_A: ; Format, drive A selected. ; Do format. ; LK A,'A' ;Specify drive A ; LK B,'D' ;Specify double-density CALL FIXIT ;Format the disk CALL CLR_W_3 ;Erase message window RET FIX_B: ; Format, drive B selected. ; Do format. ; LK A,'B' ;Specify drive B ; LK B,'D' ;Specify double-density CALL FIXIT ;Format the disk CALL CLR_W_3 ;Erase message window RET PAGE CLR_W_3: ; Routine to clear window 3. Window 3 is used for execution ; status while performing an operation. ; LK HL,:CLR_3_STR ;Point at string to clear window CALL OUT_STRING ;and send to console. RET ; :CLR_3_STR: ; String to clear window 3. Selects window 3 and sends clear screen ; character. ; DB ESC,'s3',CLR_SCR,0 PAGE FIXIT: ; Disk fix routine ;ENTRY ; A = Disk to format ('A' or 'B') ;EXIT ;NONE PROC :LOOP: STO A,D_FMT_D STO A,D_FMT_D2 SUI 'A' STO A,SDISK CALL CLR_W_2 LD A,SDISK ;See if destination disk contains info CALL CK_INFO JZ :BLK_DSK ;No...format it ; LK HL,DSK_FMT ;Assume it does DEC A ;Does it (i.e., is A = 1) ? JZ :ASK ;It does, ask user if it should be ;overwritten ; LK HL,DK_MB_FMT ;Disk MAY have info. Ask user if it ;should be overwritten. :ASK: CALL PRINT CALL Y_N PUSH AF ;Save response CALL CLR_W_2 ;Clear question POP AF ;Restore response CMP 'N' ;No, RZ ;Don't format ; ;Yes, format disk :OVRD: :BLK_DSK: LK A,'D' ;Set density specification 850102 CALL STSAVTYP ;SET DENSITY CALL SETPARM ;SET PARAMITERS CALL FIXDSK ;Fix DISKETTE PUSH AF ;Save return code from FIXDSK LK C,0DH ;so the disk system can be reset. CALL SYS ;The disk system must be reset since ;the disk has effectively been changed ;by formatting it. POP AF ;Restore return code from FIXDSK CPI 'Q' LDK HL,ABTFMT ;FORMAT aborted JRZ :DONE ;If aborted ORA A LDK HL,GDFMT ;FORMAT completed successfully JRZ :DONE ;IF NO ERRORS :BAD: LDK HL,BDFMT ;ERROR IN FORMAT CALL PRINT CALL GET_ESC CALL CLR_W_2 RET ; :DONE: CALL PRINT CALL GVCHR CALL CLR_W_2 RET ; PAGE CK_INFO: ; Checks to see if there is info on disk. Calls sense density routine ; to see if the disk is formatted. If it is not formatted, there is no ; info. ; If disk is formatted, checks for files in directory. ; ; ENTRY: ; A = # of disk on which to check for info ; 0 means drive A, ; 1 means drive B. ; ; EXIT: ; A = 0 if disk has no info, ; A = 1 if disk has info and ; A = 2 if disk MAY HAVE info (i.e., can't be determined). ; Additionally: ; Z flag set if disk has no info ; Z flag clear if disk has or may have info. ; ; SIDE EFFECT: ; SDISK set to disk # (whatever A is on entry) ; PROC MOV B,A ;Save drive spec in B PUSH BC ;Save on stk STO A,SDISK ;Select disk for SENDEN CALL SENDEN ;Check for unformatted disk. Z is clear ;if disk no formatted. POP BC ;Restore disk # JNZ :NO_INFO ;Return code indicating no info ; MOV A,B ;Restore disk # to A INC A ;Make disk # relative-one per BDOS STO A,AMB_FCB ;Put drive spec in FCB for search for first LK DE,AMB_FCB ;Point at ambiguous FCB to check for any files. LK C,SRC_FIRST ;Tell BDOS to do searcAh-for-first. CALL SYS ;Returns A = 0FFh if no files or if error INC A ;A = 0FFH? JNZ :INFO_FOUND ;No... ; XOR A ;Check for error. OR H ;Is H = 0? JNZ :CANT_TELL ;No, error occurred. ; :NO_INFO: ;No error, no info. XOR A ;Clear A and set Z flag RET ; :INFO_FOUND: ;Info on disk XOR A ;Return Z clear and A = 1 INC A RET :CANT_TELL: ;May be info. LK A,2 ;Return A = 2 and Z clear OR A RET PAGE CLR_W_2: PROC LK HL,:CLR_2_STR CALL PRINT RET ; :CLR_2_STR: DB ESC,'s2','Z'-40h,0 PAGE Y_N: PROC :YNLP: CALL C1 AND 5FH CMP 'Y' JZ :ECHO ; CMP 'N' JNZ :YNLP ; :ECHO: PUSH AF CALL COUT POP AF RET PAGE STSAVTYP: ;SET SAVTYP FOR FORMAT ;ENTRY ;A = 'S' FOR SINGLE DENSITY ;EXIT ;B = # OF SECTORS/TRACK PROC CPI 'S' JZ :SING ;IF SINGLE DENSITY ;DOUBLE DENSITY LDK A,DDTYP STO A,SAVTYP LDK B,5 ;SECTORS/TRACK RET ;SINGLE DENSITY :SING: LDK A,SDTYP STO A,SAVTYP LDK B,10 ;SECTORS/TRACK RET PAGE SETPARM: ;SET UP PARAMETERS THAT DEPEND ON DENSITY ;ENTRY ;B = # OF SECTORS/TRACK ;SAVTYP = SET ;EXIT ;PARAMETERS SET PROC MOV A,B STO A,NMSEC ;SECTORS/TRACK ORI 0FFH STO A,OSBFMT ;INITIALIZE TO NON-OSBORNE FORMAT ;CHECK FOR STANDARD OSBORNE DENSITIES LD A,SAVTYP ; CPI SDTYP ; JZ :SING ;IF SINGLE DENSITY SAVTYP ;DOUBLE DENSITY CPI DDTYP JZ :DD ;IF DOUBLE DENSITY SAVTYP 841006 ; CPI DSTYP ;DSDD uses same parameters as ssdd 841006 JNZ :2 ;Not dsdd 841006 ; :DD: MOV A,B ;VERIFY # OF SECTORS CPI DSEC JNZ :2 ;IF WRONG # OF SECTORS LDK HL,DDPARM ;DOUBLE DENSITY PARAMETERS JR :1 ;SINGLE DENSITY ;:SING: MOV A,B ;VERIFY SECTORS/TRACK ; CPI SSEC ; JNZ :2 ;IF NOT STANDARD SINGLE DENSITY ; ; LDK HL,SDPARM ;SINGLE DENSITY PARAMETERS ;MOVE OSBORNE PARAMETERS TO PARM :1: LDK DE,PARM LDK BC,7 LDIR ;SET UP REMAINING PARAMETERS :2:; CALL STRKLEN ;SET NUMBER OF BYTES PER TRACK ; CALL SNUMTRK ;SET NUMBER OF TRACKS PER BLOCK ; CALL SNUMBLK ;SET NUMBER OF BLOCKS PER DRIVE RET PAGE ; FIXDSK: ;FORMAT ONE DISK ; ; If disk is to be ssdd, both sides are formatted, but ; side 1 is formatted so that side byte in sector header ; says side 0. This is done so SENDEN routine in ROM can ; discriminate between a dsdd disk reformatted to ssdd ; and a dsdd disk. ; ;ENTRY ; FDENS set 1 if disk should be formatted dsdd, else 0 for ssdd ;EXIT ;A = 0 IF NO ERRORS ; OFFH IF ERROR ; 'C'-40H IF ABORT PROC LDK HL,PFORMAT ;FORMAT MESSAGE CALL STRCON LDK A,1 STO A,SAVSEC ;SET SECTOR CALL RHOME ;HOME DRIVE JNZ :ERR ;ERROR RETURN ;FORMAT AND VERIFY ENTIRE DISK LDK HL,CRLF5S CALL PRINT XRA A ;START WITH TRACK 0 STO A,FMTERR ;NO ERRORS YET ;TRACK LOOP :TLOOP: STO A,SAVTRK ;UPDATE TRACK NUMBER XOR A ;Start with logical 841229 STO A,:LSIDE ;side 0 841229 INC A ;and physical 841229 STO A,:SIDE ;side 1 841229 LD A,SAVTYP ;Set side 1 in SAVTYP 841229 ; AND 1111_1101B OR 0000_0010B ; 841229 STO A,SAVTYP :SLOOP: ;Top of side loop 841005 CALL FMTINT ;INITIALIZE FORMAT BUFFER(BUFF) LD A,:LSIDE ;Load logical side MOV C,A ;Pass it in C CALL STRK ;SET NEW TRACK and logical side ;INTO DATA IF NOT FMT_FIX LDK BC,BUFF ;POINT TO FWA OF BUFFER CALL RFORMAT ;FORMAT ONE TRACK ENDIF IF FMT_FIX LK HL,BUFF ;Point at buffer STO HL,DMADR ;save as DMA address IN SYS_DTA ;Get bank mask for TPA STO A,DMA_BANK ;and save as DMA bank CALL RFORMAT ;Format the track ENDIF JNZ :1 ;IF ERROR ; ; Skip verify if physical side 1 and logical side 0 ; LD A,:LSIDE ;Verify if logical side 1 OR A ; JNZ :VER ; ; LD A,:SIDE ;Don't verify if physical side OR A ;1 JNZ :NOVER ; ; :VER:; CALL VERIFY JNZ :1 ;If error :NOVER: LDK A,'*' JMP :2 ;IF GOOD :1: LDK A,'E' STO A,FMTERR ;SET ERROR FLAG :2: CALL CONOUT ;OUTPUT INDICATOR LK A,'H' - 040h ;Backspace 841005 CALL CONOUT ; 841005 CALL CKABORT RZ ;RETURN IF ABORT LD A,:SIDE ;Is this not side 0? 841005 OR A ; 841005 JNZ :NXTTRK ;Yes... 841005 ; INC A ;No. Bump side indicator841005 STO A,:SIDE ; 841005 ; LD A,FDENS ;Are we formatting dsdd? ; OR A ; ; JRZ :SS ;No, leave logical sied at 0 ; ; STO A,:LSIDE ;Yes, set logical side to 1 :SS: LD A,SAVTYP ;Toggle side bit in 841005 XOR 0000_0010B ;SAVTYP to change 841005 STO A,SAVTYP ;physical side 841005 JMP :SLOOP ;And do side 1 841005 :NXTTRK: LK A,'L' - 040H ;Advance to next space 841005 CALL CONOUT ; 841005 LD A,SAVTRK INC A CMP MTRK JNZ :TLOOP ;CONTINUE TILL ALL TRACKS ;FINAL CHECK LD A,FMTERR ORA A JRNZ :ERR ;IF ERROR ; CALL STPODRV ;VERIFY ALL TRACKS RET ;RETURN A=0 IF NO ERROR, A=0FFH IF ERROR :ERR: ORI 0FFH RET ;RETURN ERROR :SIDE: DB 0 ; 841005 :LSIDE: DB 0 ;LogicaAl side PAGE FMTINT: ;MOVE FORMAT DATA TO HIGH RAM BUFFER ;SET BUFFER TO BE: ;0,1 = LENTH OF BUFFER ;2->END = BUFFER ;ENTRY ;NONE ;EXIT ;NONE PROC ;COPY 1ST SECTOR LDK DE,BUFF+2 ;FWA FOR DATA LD HL,FORDAT ;FWA OF DATA LD BC,LIFMT ;NUMBER OF BYTES LDIR ;MOVE LDK A,1 STO A,SECTOR ;SET SECTOR LD A,NMSEC ;SECTORS/TRACK DEC A MOV B,A ;COPY REMAINING SECTORS :LOOP: PUSH BC PUSH DE POP IY ;IY = FWA OF THIS SECTOR ;MAKE ONE SECTOR LD HL,FMTSD LD BC,LISEC LDIR ;MOVE ;SET SECTOR NUMBER LDK HL,SECTOR ;INC SECTOR INC [HL] ;CHECK FOR DENSITY LD A,SAVTYP CMP SDTYP ;SINGLE DENSITY? LD A,[HL] ;A = SECTOR JZ :S ;IF SINGLE STO A,[IY+(DFSECN-DFMTSD)] ;DOUBLE JR :1 :S:; STO A,[IY+(SFSECN-SFMTSD)] ;SINGLE :1: POP BC DJNZ :LOOP ;IF MORE SECTORS ;SET LENTH OF BUFFER IN BUFFER EX DE,HL LDK BC,BUFF+2 SBC HL,BC ;GET LENGTH STO HL,BUFF ;SET LENGTH INTO BUFFER RET PAGE STRK: ;SET TRACK NUMBERS AND SIDE INTO DATA 841005 ;ENTRY ; C = Logical side ; ;EXIT ;NONE PROC LDK HL,BUFF+1 LD DE,TRKOFS ADD HL,DE LD A,NMSEC MOV B,A ;B = # OF SECTORS LD DE,LISEC LD A,SAVTRK :2: STO A,[HL] ;UPDATE TRACK CELL INC HL ;Point to SIDE CELL 841005 STO C,[HL] ;Store side byte in side cell 841005 DEC HL ;Point back at TRACK CELL 841005 ADD HL,DE ;POINT TO NEXT DJNZ :2 ;IF NOT DONE RET TITLE 'CALLS TO ROM RESIDENT ROUTINES' GOROM: ;UTILITY IN CBIOS IS JUMPED TO THAT MOVES THE STACK AND SWITCHES IN THE ROM ;ENTRY ;DE = THE ADDRESS TO CALL IN THE ROM ;EXIT *NOTE* ; The exit conditions in the rom determine what the regesters will be PROC LD A,2 MOV H,A ;HIGH ORDER BYTE OF BIOS LDK L,5AH ;LOW ORDER BYTE FOR ROM JUMP ROUTINE JMP [HL] RHOME: ;HOME THE DISK DRIVE ;ENTRY ;NONE ;EXIT ;A = 0 IF NO ERROR ;ZBIT = RESET IF ERROR PROC LDK DE,RHM_RTN CALL GOROM RET SENDEN: ;SENCE THE DENSITY, SECTOR SIZE, AND NUMBER OF SECTORS ON ONE TRACK ;ENTRY ;NONE ;EXIT ;ZBIT = SET IF GOOD ;B = NUMBER OF SECTORS PER TRACK ;SAVTYP = SECTOR SIZE AND DENSITY PROC LDK DE,SEN_RTN CALL GOROM RET RREAD: ;READ SECTOR ;ENTRY ;B = NUMBER OF SECTORS ;SDISK = DRIVE ;DMADR = DMA ADRESS ;SAVTRK = TRACK ;SAVSEC = SECTOR ;SAVTYP = DENSITY AND SECTOR SIZE ;EXIT ;HL = NEXT DMA ADDR IF GOOD TRANSFER PROC LDK DE,RD_RTN CALL GOROM RET RWRITE: ;WRITE SECTOR ;ENTRY ;B = NUMBER OF SECTORS ;SDISK = DRIVE ;DMADR = DMA ADRESS ;SAVTRK = TRACK ;SAVSEC = SECTOR ;SAVTYP = DENSITY AND SECTOR SIZE ;EXIT ;HL = NEXT DMA ADDR IF GOOD TRANSFER ;A = 0 IF NO ERROR ;ZBIT = RESET IF ERROR PROC LDK DE,WRT_RTN CALL GOROM RET RFORMAT: ;FORMAT TRACK ;ENTRY ;NONE ;EXIT ;A = 0 IF NO ERROR ;ZBIT = RESET IF ERROR PROC LDK A,2 ;RETRY ONCE FOR FORMAT ERROR STO A,ERCOUNT :LOOP: LDK DE,FMT_RTN CALL GOROM RZ ;RETURN IF NO ERROR LK HL,ERCOUNT DEC [HL] JNZ :LOOP ;RETRY  ORI 0FFH ;INDICATE ERROR RET RSETTRK: ;SET THE TRACK REGESTER TO SAVTRK ;ENTRY ;SAVTRK = TRACK NUMBER ;EXIT ;NONE ; Routine no longer implemented in ROM PROC ; LDK DE,184H ; CALL GOROM RET RSDRV: ;SELECT THE DRIVE IN SDISK ;ENTRY ;SDISK = DRIVE TO SELECT ;EXIT ;NONE PROC LDK DE,SDRV_RTN CALL GOROM RET RSTEPOUT: ;STEP HEAD OUT ONE TRACK ;ENTRY ;NONE ;EXIT ;NONE PROC LDK DE,STP_O_RTN CALL GOROM RET RSTEP: ;STEP HEAD ONE TRACK IN DIRECTION LAST STEPPED ;ENTRY ;NONE ;EXIT ;NONE PROC LDK DE,STP_RTN CALL GOROM RET TITLE 'USEFUL PROC"S' COMPSEG: ;COMPARE THE DATA IN THE TWO BUFFERS. ;ENTRY ;BC = NUMBER OF BYTES ;DE = FIRST BUFFER ;HL = SECOND BUFFER ;EXIT ;A = 0 IF NO ERRORS ;ZBIT RESET IF ERROR PROC PUSHAL :1: MOV A,B ;CHECK BC FOR ZERO ORA C JZ :2 ;GOOD RETURN LD A,[DE] CMP [HL] PUSH AF INC DE INC HL DEC BC POP AF JZ :1 ORI 0FFH ;INDICATE ERROR :2: POPALL RET PAGE  CKABORT: ;CHECK IF ABORT CHARACTER HAS BEEN PRESSED ;ENTRY ;NONE ;EXIT ;A = CHARACTER ;ZBIT = SET IF ABORT CHARACTER PRESSED PROC CALL CIN ;CHECK FOR CHARACTER ANI 5FH ;MAKE UPPER CASE CPI 'Q' RET PAGE CONOUT: ;OUTPUT CHARACTER TO CONSOLE ;ENTRY ;A = CHARACTER PROC PUSHAL MOV E,A MVI C,2 CALL SYS POPALL RET PAGE STRCON: ;OUTPUT MESSAGE TO CONSOLE ;ENTRY ;HL = FWA OF MESSAGE ;EXIT ;NONE PROC PUSHAL EX DE,HL ;VALUE TO DE LDK C,9 ;STRING CALL SYS ;BDOS POPALL RET PAGE WBOOT: LDK A,'Z'-40H CALL COUT JMP WBOOTE PRINT: LD A,[HL] ORA A RZ PUSH HL CALL COUT POP HL INC HL JR PRINT GVCHR: ; Read a char: allow only carriage return. ; CALL C1 ;Get a char CMP CR ;Is it Carriage return? JNZ GVCHR ;No, get another ; RET ;Yes, return GET_ESC: ; Wait for user to enter ESC ; :GE: CALL C1 CMP ESC JNZ :GE ; RET C1: CALL CIN ORA A JRZ C1 RET COUT: MOV E,A JR F6 CIN:A LDK E,0FFH F6: LDK C,06H JMP SYS TITLE 'CONSTANTS' ;DOUBLE DENSITY PARAMETERS DDPARM: DW DLIFMT ;LIFMT FOR DOUBLE DENSITY DW DOUBTO ;TRKOFS FOR DD DW DFORDAT ;FORDAT FOR DD DB 0 ;OSBORNE FORMAT ;SINGLE DENSITY PARAMETERS ;SDPARM: DW SLIFMT ;LIFMT FOR SINGLE DENSITY ; DW SINGTO ;TRKOFS FOR SD ; DW SFORDAT ;FORDAT FOR SD ; DB 0 ;OSBORNE FORMAT ;PARAMETERS STORED HERE PARM: LISEC: ;LISEC = LIFMT LIFMT: DS 2 TRKOFS: DS 2 FMTSD: ;FMTSD = FORDAT FORDAT: DS 2 OSBFMT: DS 1 ;OSBFMT = 0 IF OSBORNE FORMAT, OTHERWISE 0FFH NMSEC: DS 1 ;# OF SECTORS/TRACK TRKLEN: DS 2 ;# OF BYTES/TRACK NUMTRK: DS 1 ;# OF TRACKS/BLOCK NUMBLK: DS 1 ;# OF BLOCKS/DISK PTRKLEN: DS 2 ; 841006 NSIDES: DS 1 ; 841006 OVRD_FLAG: DS 1 ;True if check for formatted destination disk ;should be overridden PAGE ; Data and all message constants AMB_FCB: ;Ambiguous FCB to search for files in the ;directory of a disk DB 0 DB '????????','???','?' DB 0,0,0 DB 0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0 DB 0,0,0,0 ;***** SYSTEM MESSAGES OS_BAD_MSG: db 'FIXSSDD requires CP/M 3.X or greater.',cr,lf DB 'Copyright ' DB ESC,VSGH,CP_RG_CH,ESC,VEGH ;Set graphics mode, show ;copyright char and clr ;graphics DB ' 1984 Future Systems, 828 Nob Hill Avenue, ' DB 'Pinole CA 94564',cr,lf,0 SCR_TOP: DB ESC,'s','0','Z'-040h,ESC,'=',32,32 DB ' Single Sided Single Density Disk Fixup Program' D cr,lf D Osborn EXECUTIV Compute System' DB CR,LF DB ' V1.0' DB 0 COPYR_MSG: DB ESC,'s2',CLR_SCR ; DB ' ' ; DB ESC,VSGH,CP_RG_CH,ESC,VEGH ;Set graphics mode, show ;copyright char and clr ;graphics ; DB ' 1983 Osborne Computer Corporation, 26538 Danti Court, ' ; DB 'Hayward, CA 94545',cr,lf DB ' ' DB ESC,VSGH,CP_RG_CH,ESC,VEGH ;Set graphics mode, show ;copyright char and clr ;graphics DB ' 1984 Future Systems, 828 Nob Hill Avenue, ' DB 'Pinole CA 94564',0 NO_OPT_1: = 3 IF TVI912 MAIN1: DW MAIN_1_L DB ESC,'s','1','Z'-040h,ESC,'=',32,32 MN_1_A: DB ' ',ESC,'k Fix Disk in Drive A ',ESC,'k',0,CR,LF MN_1_B: DB ' ',ESC,'k Fix Disk in Drive B ',ESC,'k',0,CR,LF MN_1_C: DB ' ',ESC,'k RETURN TO CP/M ',ESC,'k',0,CR,LF DB CR,LF D '$' ENDIF MAIN_1_L: DW MN_1_A DW MN_1_B DW MN_1_C DIR_MSG: db ESC,'s5','Z'-40h db ' Use the ARROW keys to position the',cr,lf db ' cursor next to the desired choice',cr,lf db ' or',0 RET_CPM: db 0 db ESC,'s6','Z'-40h db ' Press RETURN to Return to CP/M$' FIX_MSG: db 0 db ESC,'s6','Z'-40h db ' Insert a Diskette in selected drive and',cr,lf db ' Press RETURN to start fixing',cr,lf db cr,lf db ESC,'^WARNING: ',ESC,'jDo not attempt to fix a truly double ' db 'sided disk! It will be DESTROYED!',ESC,'k',ESC,'q$' PAGE NUM_OPTIONS DB 0 ;# OF OPTIONS in current ;main menu SIDE: DB 0 ;0-LEFT MENU, 1- RIGHT PUT_CURSOR: DB ESC,'s','1',ESC,'=' ;MAIN MENU CURSOR POSITION Y_COORD: DB 32 X_COORD: DB 32 DB 0 PUT_SUB_CURSOR: DB ESC,'s','2',ESC,'=' ;MAIN MENU CURSOR POSITION Y_SUB_COORD: DB 32 X_SUB_COORD: DB 32 DB 0 NUM_SUB_CMDS: DS 1 ;# OF COMMANDS IN SUB MENU NUL_MSG: M_EXIT: DB 0 DB ESC,'s','2','Z'-040h DB ESC,'s','1' DB '$' PAGE CRLF5S: DB ESC,'s3',cr,lf,lf,lf DB ' ',0 PFORMAT: DB ESC,'s5','Z'-40h DB cr,lf DB ' Press and Hold Q to Quit Fixing' DB ESC,'s','3','Z'-040h DB ' Track Fixed:',cr,lf DB ' 0 1 2 3 ' DB CR,LF DB ' 0123456789012345678901234567890123456789',cr,lf DB '$' SECTOR: DB 0 ;FOR FORMAT SOURCE: DB 0 ;SOURCE DRIVE FOR COPY TRACK: DB 0  ;ACTIVE LOGICAL TRACK BLOCK: DB 0 ;ACTIVE BLOCK NUMBER DSK_FMT: DB ESC,'s2','Z'-40h DB ' Diskette in Drive ' D_FMT_D: DB 'X' ;Filled in by FMAT or KOPY DB ' contains information.',cr,lf DB ' Is it OK to overwrite it (y/n)? ',0 DK_MB_FMT: DB ESC,'s2','Z'-40h DB ' Diskette in Drive ' D_FMT_D2: DB 'X' ;Filled in by FMAT or KOPY DB ' MAY contain information.',cr,lf DB ' Is it OK to overwrite it (y/n)? ',0 END: DB CR,LF,LF DB 0 GDFMT: DB ESC,'s','2','Z'-040h DB ' Fixing completed successfully.',cr,lf DB ' Press RETURN to continue.' DB 0 BDFMT: DB ESC,'s','2','Z'-040h DB ' Error while fixing.',cr,lf DB ' Press ESC to continue.' DB 0 ABTFMT: DB ESC,'s','2','Z'-040h DB ' FIXING ABORTED.',cr,lf DB ' Press RETURN toA continue.' DB 0 PAGE DFORDAT: ;DOUBLE DENSITY FORMAT DATA FOR IBM 3740. *NOTE* ;NO INDEX MARK IS USED ; **** GAP 1 **** DFMTSD: ECHO 100 ! DB 04EH ENDM ECHO 12 ! DB 0 ENDM DB 0F5H,0F5H,0F5H DB 0FEH ;ID ADDRESS MARK DFTRKN: DB 0 ;TRACK DOUBTO = *-DFORDAT DB 0 ;SIDE DFSECN: DB 1 ;SECTOR DB 3 ;SECTOR LENTH DB 0F7H ;CRC ; **** GAP 2 **** ECHO 22 ! DB 04EH ENDM ECHO 12 ! DB 0 ENDM DB 0F5H,0F5H,0F5H DB 0FBH ;DATA ADDRESS MARK ; **** DATA **** ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM DFCRC2: DB 0F7H ;CRC DFMTEND = * DLIFMT = *-DFORDAT DLISEC = *-DFMTSD ERCOUNT: DB 0 ;ERROR COUNTER LBUFF1: DW 0 ;HOLD FBA IN BUFF1 MACHTYPE: DB 0 ;MACHINE DENSITY ; 0 = Undefined ; 1 = Single ; 2 = Double FMTERR: DB 0  ;FORMAT ERROR FLAG ;BUFFS: DS 7000 ;SAVE BUFFER DS 40*2 STACK: DS 0 ;STACK HERE ; END **** DFMTSD: ECHO 100 ! DB 04EH ENDM ECHO 12 ! DB 0 ENDM DB 0F5H,0F5H,0F5H DB 0FEH ;ID ADDRESS MARK DFTRKN: DB 0 ;TRACK DOUBTO = *-DFORDAT DB 0 ;SIDE DFSECN: DB 1 ;SECTOR DB 3 ;SECTOR LENTH DB 0F7H ;CRC ; **** GAP 2 **** ECHO 22 ! DB 04EH ENDM ECHO 12 ! DB 0 ENDM DB 0F5H,0F5H,0F5H DB 0FBH ;DATA ADDRESS MARK ; **** DATA **** ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM DFCRC2: DB 0F7H ;CRC DFMTEND = * DLIFMT = *-DFORDAT DLISEC = *-DFMTSD ERCOUNT: DB 0 ;ERROR COUNTER LBUFF1: DW 0 ;HOLD FBA IN BUFF1 MACHTYPE: DB 0 ;MACHINE DENSITY ; 0 = Undefined ; 1 = Single ; 2 = Double FMTERR: DB 0  The first two bytes of a menu data structure is a pointer to a ; table of pointers to the command descriptions for that menu. ; ; ENTRY: ; Y_COORD = line # of current command ; ; EXIT: ; Sets NUM_SUB_CMDS according to number of sub-commands for command ; description (not used in COPY). ; ; PROC LK HL,DIR_MSG ;Display general (arrow key) directions CALL OUT_STRING LD A,Y_COORD ;Load line # of current ;selection (relative-32). SUB 32 ;Make A relative 0 ADD A ;Double it to index into ;pointer table. MOV L,A ;Load it to HL LK H,0 LD DE,MENU_TABLE ;Load address of pointer table ADD HL,DE ;Index to pointer for current ;selection. LD E,[HL] ;Load pointer to current INC HL LD D,[HL] LD A,[DE] ;Load number of subcommands for ;this menu STO A,NUM_SUB_CMDS ;Save it INC DE ;Bump DE to beginning of ;command description display ;data. LK C,PR_STR_FN ;Tell BDOS to print description CALL BDOS RET ;and return PAGE DO_COMMAND: ; Process the currently selected command on the currently selected ; menu. ; ; Clears current command description but re-displays it only if ; menu has NOT changed. ; ; ENTRY: ; Y_COORD = line # of current command. ; COM_TABLE = address of table of pointers to command routine for ; current menu. ; ; EXIT: ; None. ; PROC LK HL,:CLR_W_5 ;Clear command description for current CALL OUT_STRING ;command. LD A,Y_COORD ;Load line # of current command. SUB 32 ;Make relative - 0 ADD A ;Double to index into command ptr table MOV L,A LK H,0 LD DE,COM_TABLE ;Index into command table ADD HL,DE LD E,[HL] ;Load ptr to command routine INC HL LD D,[HL] EX DE,HL ;Put ptr in HL LK DE,:DO_RET ;Load address of return point PUSH DE ;and save as return address JMP [HL] ;Jump to command routine ; :DO_RET: ;Return point from command routine. LD DE,MAIN ;Has main menu changed? LD HL,OLD_MN STC CMC SBC HL,DE RNZ ;Yes, command descr must have changed, ;so return to driver without ;re-displaying it. CALL F_CMD_DESC ;Force re-display of command ;description and general directions CALL SET_CURSOR ;and reposition cursor at current ;choice RET ; ; String used to clear window 5: ; :CLR_W_5: DB ESC,'s5','Z'-40h,0 PAGE HI_CURR: ; Highlight (in reverse video) current command string on screen. ; ; ENTRY: ; A = line # (relative-32) of command string in window 1 ; Assumes ATT_OFS-th char of command string is attribute byte of attribute ; definition escape sequence (ESC-G-X) ; ; EXIT: ; None. ; PROC IF TVI912 :ATT_OFS = 3 ;Offset in command string to attribute ;byte :INV_ON = 'j' ;Reverse video on attribute char :INV_OFF = 'k' ;Reverse video off attribute char ENDIF IF TVI950 :ATT_OFS = 4 ;Offset in command string to attribute ;byte :INV_ON = '4' ;Reverse video on attribute char :INV_OFF = '0' ;Reverse video Aoff attribute char ENDIF PUSH AF ;Save line # ADI W1BIAS ;Add bias for window 1 STO A,W_PCH_1 ;Save absolute line # in window defn STO A,W_PCH_2 ;string: begin and end line POP AF ;Restore line # SUB 32 ;Make it relative-0 LD HL,MAIN ;Get address of command line table LD E,[HL] ; INC HL ; LD D,[HL] ; EX HL,DE ;Put cmd line table addr in HL MOV E,A ;Index into it by cmd # LK D,0 ; ADD HL,DE ; ADD HL,DE ; LD E,[HL] ;Load addr of cmd line INC HL ; LD D,[HL] ; EX HL,DE ;Put it in HL PUSH HL ;Save addr LK DE,:ATT_OFS ;Index into cmd line string to attribute ADD HL,DE ;byte STO :INV_ON,[HL] ;Set attribute byte to reverse video LK HL,W_STR ;Set window for current line CALL OUT_STRING ; POP HL ;Restore address of cmd string PUSH HL ;Save it CALL OUT_STRING ;Display cmd string in reverse video POP HL ;restore cmd string addr LK DE,:ATT_OFS ;Index back to attribute byte ADD HL,DE ; STO :INV_OFF,[HL ;RAMS10.ASM TITLE 'Monitor RAM Storage.' ; Used to assemble ROM resident and CBIOS ORG MRAM ; Disk operation temps and control DMABANK DS 1 ;Bank for read/write disk DMADR DS 2 ;Address for read/write disk ; Note order of xxxSEC,xxxTRK,xxxDSK must be maintained ; along with length (1,2,1). SAVSEC DS 1 ;last sector requested SAVTRK DS 2 ;last track requested SDISK DS 1 ;selected disk drive (0,1) SAVTYP DS 1 ;SELECTED TYPE (sector size) IE_ADR: DS 1 CURPOS: DS 2 ;Current cursor position ; VARIABLES FOR HIGH RAM ROUTINES TEMSAV DS 1 ;Used by jump bank routine SRCBANK DS 1 ;Source bank for block move DESTBANK DS 1 ;Destination bank for block move ;JMPSPOT and JMPADDR must stay next to each other JMPSPOT DS 1 ;To be filled in with a JMP instruction by the ROM JMPADDR DS 2 ;Address to jump to for BANKJMP and BANKCALL JMPBANK DS 1 ;Bank to jump to for BANKJMP and BANKCALL EMRAM = * ; INTERRUPT VARIABLES USR_BNK DS 1 ;User's bank on interrupt bank switch DS 2 I_POL_BANK: DS 1 I_POL_ADR: DS 2 USR_STK: DS 2 ;save current stk ptr ; Interrupt stack DS 30*2 ISTK: DS 0 ; ROM and BIOS stack DS 30*2 BIOSTK: ROMSTK: DS 0 HIBUFF: DS 100H qpppp(p:pÈpÙpqKK7p+pCf+L;LMp@p#D*Pv:6O~`opyL`opop Zp~~wyL`…pDM2v6P[jKKDhËp:pv*g5iڳp*k5+++͓lڶp*i5"g52pv!vͭj1)*6"6!6Þ!dp!d"6>26!"6:6*v:vpviK2q!vj*vK2qqf!vv͉d>267ɯ2v{͹qq6q{͹q*q7?Cqͧq{xq͹qͶqʆqͧq>2v͹qͶqsqE7:v7͹qSʝqD q͹q-7+vM"v#{ʿq2'K? ܔ ڿq7*qɾ#45qs6RqhqwqÑq&rSrqqqqrrërrqq r9s{IQ0 ENTER space OR NEW LINE SPACING (1-9): LEFT MARGIN COLUMN NUMBERumn)? (ESCAPE for cursor col RIGHT For decimal tab stop enter "#" and decimal point column  SE] ;Set it to normal RET ;and return PAGE UN_HI_CR: ; Remove highlighting from command string on screen ; ; ENTRY: ; A = line # (relative-32) of command string in window 1 ; ; EXIT: ; None. ; PUSH AF ;Save line # ADI W1BIAS ;Add bias for window 1 STO A,W_PCH_1 ;Save absolute line # in window defn STO A,W_PCH_2 ;string: begin and end line POP AF ;Restore line # SUB 32 ;Make it relative-0 LD HL,MAIN ;Get address of command line table LD E,[HL] ; INC HL ; LD D,[HL] ; EX HL,DE ;Put cmd line table addr in HL MOV E,A ;Index into it by cmd # LK D,0 ; ADD HL,DE ; ADD HL,DE ; LD E,[HL] ;Load addr of cmd line INC HL ; LD D,[HL] ; EX HL,DE ;Put it in HL PUSH HL ;Save it LK HL,W_STR ;Define window for current line CALL OUT_STRING ;Redisplay cmd string in normal mode POP HL ;Restore addr of cmd str CALL OUT_STRING ;Redisplay cmd string in normal mode RET ;and return PAGE ;------------------------------------------------------------------------------ ; Local storage for driver data structures follows. ; ; MENU_TABLE is a pointer to the table of pointers to command ; descriptions for each command in the current menu. ; MENU_TABLE: DW 0 ; ; COM_TABLE is a pointer to a table of pointers to command routines ; for each command in the current menu. ; COM_TABLE: DW 0 ; ; MAIN is a pointer to the current menu. ; MAIN: DW 0 PAGE EXIT: ; Program exit point. Program returns to CP/M from here: ; Sends termination string to console: sets window 0, clears screen ; and enables fn. key xlate. ; ; ENTRY: ; None. ; ; EXIT: ; None. ; LK DE,GOOD_BYE ;Send termination string to ;console. LK C,PR_STR_FN CALL BDOS JMP WBOOTE ;and warm start. ; GOOD_BYE: DB ESC,'s','0','Z'-040h ; ; For TVI 912 emulation, include string to enable fn. key xlate: ; IF TVI912 DB ESC,'e',0 ENDIF DB '$' PAGE SETM1: ; Make main menu the current menu. ; Main menu alloA ws selection of drive A or B for fixing. ; ; ENTRY: ; None. ; ; EXIT: ; Parameters set for main menu. ; PROC LK HL,MENU1 ;Point to description table STO HL,MENU_TABLE ;for main menu LK HL,COM1 ;Point to routine table for STO HL,COM_TABLE ;main menu LK HL,MAIN1 ;Point to main menu data STO HL,MAIN ;structure. LK A,NO_OPT_1 ;Set # options for main menu STO A,NUM_OPTIONS LK A,33 ;Make Drive B the default ;selection. STO A,Y_COORD RET ;and return PAGE ;------------------------------------------------------------------------------ ; Menu command description and routine tables follow: ; MENU1: ;Table for main menu DW FIX_MSG DW FIX_MSG DW RET_CPM COM1: DW FIX_A ;Table for main menu DW FIX_B DW EXIT PAGE FIX_A: ; Format, drive A selected. ; Do format. ; LK A,'A' ;Specify drive A ; LK B,'D' ;Specify double-density CALL FIXIT ;Format the disk CALL CLR_W_3 ;Erase message window RET FIX_B: ; Format, drive B selected. ; Do format. ; LK A,'B' ;Specify drive B ; LK B,'D' ;Specify double-density CALL FIXIT ;Format the disk CALL CLR_W_3 ;Erase message window RET PAGE CLR_W_3: ; Routine to clear window 3. Window 3 is used for execution ; status while performing an operation. ; LK HL,:CLR_3_STR ;Point at string to clear window CALL OUT_STRING ;and send to console. RET ; :CLR_3_STR: ; String to clear window 3. Selects window 3 and sends clear screen ; character. ; DB ESC,'s3',CLR_SCR,0 PAGE FIXIT: ; Disk fix routine ;ENTRY ; A = Disk to format ('A' or 'B') ;EXIT ;NONE PROC :LOOP: STO A,D_FMT_D STO A,D_FMT_D2 SUI 'A' STO A,SDISK CALL CLR_W_2 LD A,SDISK ;See if destination disk contains info CALL CK_INFO JZ :BLK_DSK ;No...format it ; LK HL,DSK_FMT ;Assume it does DEC A ;Does it (i.e., is A = 1) ? JZ :ASK ;It does, ask user if it should be ;overwritten ; LK HL,DK_MB_FMT ;Disk MAY have info. Ask user if it ;should be overwritten. :ASK: CALL PRINT CALL Y_N PUSH AF ;Save response CALL CLR_W_2 ;Clear question POP AF ;Restore response CMP 'N' ;No, RZ ;Don't format ; ;Yes, format disk :OVRD: :BLK_DSK: LK A,'D' ;Set density specification 850102 CALL STSAVTYP ;SET DENSITY CALL SETPARM ;SET PARAMITERS CALL FIXDSK ;Fix DISKETTE PUSH AF ;Save return code from FIXDSK LK C,0DH ;so the disk system can be reset. CALL SYS ;The disk system must be reset since ;the disk has effectively been changed ;by formatting it. POP AF ;Restore return code from FIXDSK CPI 'Q' LDK HL,ABTFMT ;FORMAT aborted JRZ :DONE ;If aborted ORA A LDK HL,GDFMT ;FORMAT completed successfully JRZ :DONE ;IF NO ERRORS :BAD: LDK HL,BDFMT ;ERROR IN FORMAT CALL PRINT CALL GET_ESC CALL CLR_W_2 RET ; :DONE: CALL PRINT CALL GVCHR CALL CLR_W_2 RET ; PAGE CK_INFO: ; Checks to see if there is info on disk. Calls sense density routine ; to see if the disk is formatted. If it is not formatted, there is no ; info. ; If disk is formatted, checks for files in directory. ; ; ENTRY: ; A = # of disk on which to check for info ; 0 means drive A, ; 1 means drive B. ; ; EXIT: ; A = 0 if disk has no info, ; A = 1 if disk has info and ; A = 2 if disk MAY HAVE info (i.e., can't be determined). ; Additionally: ; Z flag set if disk has no info ; Z flag clear if disk has or may have info. ; ; SIDE EFFECT: ; SDISK set to disk # (whatever A is on entry) ; PROC MOV B,A ;Save drive spec in B PUSH BC ;Save on stk STO A,SDISK ;Select disk for SENDEN CALL SENDEN ;Check for unformatted disk. Z is clear ;if disk no formatted. POP BC ;Restore disk # JNZ :NO_INFO ;Return code indicating no info ; MOV A,B ;Restore disk # to A INC A ;Make disk # relative-one per BDOS STO A,AMB_FCB ;Put drive spec in FCB for search for first LK DE,AMB_FCB ;Point at ambiguous FCB to check for any files. LK C,SRC_FIRST ;Tell BDOS to do searc| | ; X16 Clock Mode 0 1 | | | | | | ; X32 Clock Mode 1 0 | | | | | | ; X64 Clock Mode 1 1 | | | | | | ;SYNC MODE: (not used) | | | | | | ; 8 Bit Sync char 0 0 | | | | ; 16 Bit Sync char 0 1 | | | | ; SDLC Mode 1 0 | | | | ; Ext Sync mode 1 1 | | | | ;STOP BITS: | | | | ; SYNC Mode Enable 0 0 | | ; 1 Stop Bit/Char 0 1 | | ; 1.5 Stop Bits/Char 1 0 | | ; 2 Stop Bits/Char 1 1 | | ;PARITY: | | ; Parity Even/Odd <--------------------------------+ | ; Parity Enable <------------------------------------+ PAGE ;WRITE REG 5: +---+---+---+---+---+---+---+---+ ; | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ; +---+---+---+---+---+---+---+---+ ; | | | | | | A! | | ;DTR <---------------------------+ | | | | | | | ;Tx BITS/CHARACTER: | | | | | | | ; 5 Bits 0 0 | | | | | ; 6 Bits 0 1 | | | | | ; 7 Bits 1 0 | | | | | ; 8 Bits 1 1 | | | | | ;Send Break <--------------------------------+ | | | | ;Tx Enable <------------------------------------+ | | | ;CRC Type (not used) <-------------------------------+ | | ;RTS <---------------------------------------------------+ | ;Tx CRC Enable <---------------------------------------------+ ;WRITE REG 6: +---+---+---+---+---+---+---+---+ ; (not used) | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ; +---+---+---+---+---+---+---+---+ ; | | | | | | | | ; | | | | | | | | ;Transmit Sync char <------------+---+---+---+---+---+---+---+ ;WRITE REG 7: +---+---+---+---+---+---+---+---+ ; (not used) | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ; +---+---+---+---+---+---+---+---+ ; | | | | | | | | ; | | | | | | | | ;Receive Sync char <------------+---+---+---+---+---+---+---+ PAGE ;SIO READ REGISTERS ;READ REG 0: +---+---+---+---+---+---+---+--+ ; | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0| ; +---+---+---+---+---+---+---+--+ ; | | | | | | | | ;Break/Abort <----------------+ | | | | | | | ;Tx Underrun/EOM <--------------------+ | | | | | | ;CTS <------------------------+ | | | | | ;Sync/Hunt <----------------------------+ | | | | ;DCD <--------------------------------+ | | | ;Tx Buffer Empty <------------------------------------+ | | ;Int Pending (Chan A only) <-----------------------------+ | ;Rx Character Available <------------------------------------+ ;READ REG 1: +---+---+---+---+---+---+---+--+ ; | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0| ; +---+---+---+---+---+---+---+--+ ; | | | | | | | | ;End of Frame <-----------------+ | | | | | | | ;CRC/Framing Error <-----------------+ | | | | | | ;Rx Overrun Error <---------------------+ | | | | | ;Parity Error <-----------------------------+ | | | | ;Residue codes (not used) <----------------------+---+---+  | ;All Sent <---------------------------------------------+ ;READ REG 2: +---+---+---+---+---+---+---+--+ ; | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0| ; +---+---+---+---+---+---+---+--+ ; | | | | | | | | ;Interrupt vector <--------------+---+---+---+---+---+---+---+ PAGE ;SIO Control constants REG0 = 0000_0000B ;Select register 0 REG1 = 0000_0001B ;Select register 1 REG2 = 0000_0010B ;Select register 2 REG3 = 0000_0011B ;Select register 3 REG4 = 0000_0100B ;Select register 4 REG5 = 0000_0101B ;Select register 5 REG6 = 0000_0110B ;Select register 6 REG7 = 0000_0111B ;Select register 7 INT_CNL = 0000_0000B ;Interrupt control (Reg 1) ; no interrupts RCV_CNL = 1110_0001B ;Logic control (Reg 3) ; 8 Bits/char, Auto enables on, Rx enable, ; Sync char hunt inhibit disabled BAS_CNL = 0100_0100B ;Basic control values (Reg 4) ; X16 Clock, 1 Stop bit, No parity TX_CNL_A = 1110_1000B ;Transmit control for (Reg 5) ; Channel A: DTR on, 8 Bits/char, RTS off TX_CNL_B = 1110_1010B ;Transmit control for (Reg 5) ; Channel B: DTR on, 8 Bits/char, RTS on SIO_I_IN = 000_10_111B ;Command to write to SIO WR1 to set: ; Interrupt on all Rx chars (parity ; affects vector) ; Status affects vector ; Tx Int. Enable ; External Int. Enable ;Masks SI.RRDY = 0000_0001B ;Receive char ready (Read Reg 0) SI.TRDY = 0000_0100B ;Transmit buffer empty (Read Reg 0) PAGE ;8253 TIMER ;CONTROL REG: +---+---+---+---+---+---+---+---+ ; | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ; +---+---+---+---+---+---+---+---+ ; | | | | | | | | ;Select Counter <----------------+---+ | | | | | | ;READ/LOAD: | | | | | | ; !A" Counter Latching 0 0 | | | | ; R/L Most Significant Byte only 0 1 | | | | ; R/L Least Significant Byte only 1 0 | | | | ; R/L Both Bytes 1 1 | | | | ;MODE <------------------------------------------+---+---+ | ;BCD <------------------------------------------------------+ ;Control COUNTA = 0011_0110B ;Select counter 0, 2 bytes, Mode 3 COUNTB = 0111_0110B ;Select counter 1, 2 bytes, Mode 3 ;SETBAUD Codes ; (Code is a table offset. Table entries are 8253 count values neccessary to produce the desired baud rate) BD1200 = 8 ;Code for 1200 baud PAGE ;PARALLEL PORT CONSTANTS ;port ctl register constants. PA.CDR = 00101010b ;to address port a direction PA.CDT = 00101110b ;to address port a data and set ;port a in input program handshake mode. PB.CDR = 00000000b ;to address port b direction PB.CDT = 00000100b ;to address port b data ;direction register constants PA.DRO = 0FFh ;port a output mode PA.DRI = 00h ;port a input mode PB.DR = 0BFh ;port b direction PB.DTO = 00000010b ;port b data for output PB.DTI = 00001011b ;port b data for input PP.ORDY = 01000000b ;output rdy bit in pib PP.IRDY = 10000000b ;input rdy bit in pia ctl reg STRB = 00100000b ;strobe bit in port b ;port modes PP.OUT = 1 PP.IN = 2 ;IEEE control codes IE_TALK = 40h ;make talker IE_UTLK = 5Fh ;make untalk IE_LSTN = 20h ;make listener IE_ULST = 3Fh ;make unlisten PAGE ;VIDEO CONSTANTS FWAVM = 0C000h ;LVMEM = 128*23 + 80 ;Length of video memory ;VIDEND = FWAVM+LVMEM-1 ;End of video memory VMROWS = 24 ;24 Rows VMCOLS = 80 ;80 Columns RESERVED = 0 ;Window 0 is reserved (always set to full screen) ;NVDL = 24 ;LVDIS = 128*NVDL ;Length of Display memory ;VFLO = -22 ;First line video offset VLL = 128 ;Length of one video line ;VLDL = 64 ;Length of displayed char/line ;FWASM = FWAVM+VLDL ;Status info ;NLINE = 24 ;Number of lines MODEMSK = 0F0H ;Mask video mode bits MODEOFF = 1000H ;Offset from video character address to mode address ;MASKS REVMODE = 1000_0000B ;Reverse bit = high bit of character HAFMODE = 1000_0000B ;Half intensity bit = high bit of mode address UNDMODE = 0100_0000B ;Underline bit BLMODE = 0010_0000B ;Blink bit ALTMODE = 0001_0000B ;Alternate character set bit REV_CUR = 1000_0000B ;Reverse video (block) cursor UND_CUR = 0100_0000B ;Underline cursor INV_CUR = 0000_0000B ;Invisible cursor BLK_CUR = 0010_0000B ;Blinking cursor PAGE RTC_OFL = 18H ;RTC overflow counter port SIXTY_HZ = 60 ;Decimal 60 Hz (ticks/sec) FIFTY_HZ = 50 ;50 Hz (ticks/sec) SEC_MIN = 60H ;BCD seconds/minute MIN_HR = 60H ;minutes/hr HR_DAY = 24H ;Hours/day PAGE ;KEYBOARD CONSTANTS KL_LEN = 3 ;KEY LIST LENTH KLE_LEN = 2 ;KEY LIST ENTRY LENTH KL_USED = 7 ;KEYLIST ENTRY USED KY_SRVD = 6 ;KEY SERVICED ONCE KROW_M = 38H ;ROW NUMBER MASK KCOL_M = 7H ;COL NUMBER MASK RPTCTR = 1 ;REPEAT COUNT ROW0_M = 81H ;MASK FOR ADDRESSING ROW 0 DB_CT = 1 ;DEBOUNCE COUNT IRPTCT = 24 ;INITIAL REPEAT COUNT (400MS) SRPTCT = 3 ;SECOND REPEAT COUNT (100MS) DAB9/17 ;Reduced to half original value to ;speed repeat. TOT_ROW = 8 ;TOTAL ROWS TOT_COL = 8 CTL_KY = 2 ;COLUMN NUMBER OF CTL,ALPHA AND SHIFT KEYS ALPH_KY = 3 SHFT_KY = 4 PAGE ;BUFFER HANDLING EQUATES MX_CH_BF = 10H ;Max number of chars in a buffer BF_OV_HD = 4 ;No. bytes overhead in buffer D_RT_LEN = 6 ;No of bytes in Device List Root data structure NO_DEVS = 5 ;Number of devices NO_BUFS = 40 ;Number of buffers THR_HOLD = 4 ;Number of buffers to reserve for high priority ;devices HI_PRIOR = 80H ;High priority bit to indicate ;high priority buffers can be used PAGE ;CONTROL CHARACTERS CR = 0Dh ;^M, CR = Carriage Return LF = 0Ah ;^J, LF = Line Feed CRLF = '_'-40H ;^_, CR and LF BKS = 08h ;^H, Backspace CBELL: = 'G'-40h ;Ring the Bell MCUP: = 'K'-40h ;Move cursor up MCRIGH: = 'L'-40h ;Move cursor right VDWN: = 'V'-40H ;Move cursor down VLIN: = '_'-40H ;New line (CR,LF) VCLRS: = 'Z'-40h ;Clear and home cursor VHOME: = '^'-40h ;Home Cursor ETX = 'C' - 40h ;ASCII ETX char ACK = 'F' - 40h ;ASCII ACK char XON = 'Q' - 40h ;ASCII XON (DC1) char XOFF = 'S' - 40h ;ASCII XOFF (DC3) char ;ESCAPE SEQUENCE CHARACTERS ESC = 1Bh ;^[, ESC = Escape VLOCK: = '#' ;Lock Keyboard VUNLK: = '"' ;Unlock Keyboard VCAD: = '=' ;Cursor Addressing VSAD: = 'S' ;Screen Addressing VINC: = 'Q' ;Insert Char VDELC: = 'W' ;Delete char VINL: = 'E' ;Insert line VDELL: = 'R' ;Delete line VCEOL: = 'T' ;Clear to end of line VCEOS: = 'Y' ;Clear to end of screen (window) VSAL: = 'a' ;Start alternate character set VEAL: = 'A' ;End VSHI: = ')' ;Start half intensity VEHI: = '(' ;End VSGH: = 'g' ;Start graphics VEGH: = 'G' ;End VRON: = 'b' ;Set "A#reverse video background (black on white) VROFF: = 'd' ;Clear reverse video background (set to white on black) VCTYP: = '.' ;Cursor type define VSRV: = 'j' ;Start reverse video VERV: = 'k' ;End reverse video VSUL: = 'l' ;Start underline VEUL: = 'm' ;End underline VSBL: = '^' ;Start Blink VEBL: = 'q' ;End blink EKC: = '>' ;Enable key click DKC: = '<' ;Disable key click EFKT: = 'e' ;Enable function key translate DFKT: = 'f' ;Disable Function key translate VWDEF: = 'z' ;Window define VWSET: = 's' ;Window set VOFF: = 'o' ;Define X-Y offset VBACK: = 'x' ;Define background attributes UNDBIT: = 0000_1000B ;Underline bit ALTBIT: = 0001_0000B ; REVBIT: = 0000_0100B ;Reverse video bit BLKBIT: = 0000_0010B ;Blink bit HAFBIT: = 0000_0001B ;Half intensity bit PAGE ;BOOT CONSTANTS BOOTADDR: = 4000H ;Boot load address for P-System BIOSBANK = 0000_0000B ;BIOS bank BOOTBANK = 0000_0000B ;Boot strap loader bank TEMPBUF = 0CC00H ;Temporary buffer in video bank  ; used for DMA address when booting system PROD_CODE = 2 ;Shelly product code written on boot sector PAGE ;INTERRUPT CONSTANTS SIO_I_TBL = 0FFE0H ;Location in RAM of SIO interrupt vector ;Must be in high RAM and end in 0 INTVEC = 0FFFEH ;Other interrupt's vector ;Interrupt Device Numbers KBD_DEV = 0 ;Keyboard device number S_CH_A_I = 1 ;Device number for Serial channel A input S_CH_B_I = 2 ;Device number for Serial channel B input S_CH_A_O = 3 ;Device number for Serial channel A output S_CH_B_O = 4 ;Device number for Serial channel B output PAGE ;ROM's RAM VALUES ;Flags for console and function key table flags SYS_TBL: = 0 ;Use system table APP_TBL: = 1 ;Use application table NO_TBL: = 2 ;Don't use translation table (function key only) PAGE ;TABLE DEFINITION LOCATIONS ;SYSTEM TRACK LOCATIONS KCTRK = 2 ;Track for keyboard and character font definitions KEYSEC = 17 ;Sector for keyboard definition CHARSEC = 20 ;Sector for character font definition ALTSEC = 30 ;Sector for alternate character font definition ;RAM LOCATIONS RAMTBL = 2000H ;Keyboard and console table pointers CHRFONT = 0000H ;Character font RAM location ALTFONT = 800H ;Alternate character font RAM location PAGE ; CP/M DEFINITIONS SVER = 14 ERSIZE = 64 ; default = 64k version CVER = 22 ;CPM version number CBIOSV = SVER ;cbios version NDSKS = 2 K = 1024 ABTC = 'C'-40h ;Abort character ;DRIVE DEFINITIONS LSECB = 256 ;Length of a sector MTRK = 40 ;Maximum tracks MSEC = 10 ;Maximum Sectors FMTCHR = 0E5h ;Data format char ; Set CP/M symbols. IOBYTE = 3 CDISK = 4 ;Current logged-in CPM disk SYS = 5 ;CPM Monitor call address SYSL = SYS+1 ;(lwa of CP/m) TIMPTR = 40h ;points to where time kept DBUF = 80h ;Default disk buffer OM#LRAM = SYSL SYSR = 0 ;return to system SYSDSK = CDISK ;Contains current system disk # SYSDAT = 10h ;Date in ddmmyy SYSTIM = SYSDAT+3 ;Time in hhmmss ORGP = 100h ;Transient program origin ;EOL ;does not exist in CP/M EOM = '$' ;End of Message (for system function) EOF = 'Z'-40h ;End of File L$PRU = 128 ;Bytes per floppy sector FCB = 5Ch ;SYSTEM DEFAULT FILE CONTROL BLOCK FCB_NR = FCB+32 ;Next Record = LRN F_EX = 12 ;Extend field F_S2 = 14 ;CPM system usage **used with 2.0 SIZ funct** F_RC = 15 ;Record count (0 to 128) F_NR = 32 ;Next record ordinal in FCB F_RRF = 33 ;r0,r1,r2 (random field) in FCB L_FILEN = 8 ;length of File name L_FILEX = 3 ;length of filename suffix L_FCB = 36 ;length of entire FCB (comp with 2.0) DMA = 80h ;WHERE SECTORS ARE READ TBUFF = DMA ;where CCP puts command line PAGE ; FIRMWARE RAM DEFINITIONS ;TEMPBUF: = HSTBUF ;* TEMPBUF WILL BE THE SAME AREA AS THE SPACE ; RESERVED FOR KEYBOARD AND CONSOLE TABLES -- ; IT CAN ONLY BE USED BEFORE THESE AREAS ARE INITIALIZED PAGE ; True/False definitions FALSE = 0 TRUE = not FALSE ; Defined function codes ROMVEC = 100h ;Start of rom vector MONRAM = 2000H COMJMP = 0FD40H ;Common memory jump vectors (BANKJMP,BANKMOVE,BANKCALL,DMA READ and WRITE) MRAM = 0FD4Ah ;High memory area for variables used by ROM and BIOS HI_ROUT = 0FEF0H ;High memory routines moved from ROM TAB = 09h ;TAB ERC = 7FH ;Illegal key @FREQ = 4000 ;freq of processor SCLFRE = @FREQ/22 ;for DELAY routine Bad = 0FFH ;Entry in keybd table if key is invalid BADKEY = Bad ; TOG_ALT_SET = 0FEh ;Entry in keybd table if key is used to ;toggle alternate char set KEYTBL: = 2800H-140H ;Key code location ROMVER: = 0FEH ;ROM version number location ;Cold Boot Masks SP_KEY = 0000_0100b ;Load keyboard translation code from disk SP_CHAR = 0000_0010B ;Load character font from disk SP_ALT = 0000_0001B ;Load alternate character font from disk PAGE ;MACROS ; ALIGN Set origin to even boundary. ALIGN MACRO SIZ,O DS (*%2+(%1)-1)/(%1)*(%1)-*%2 #A$ ENDM PUSHAL MACRO PUSH BC PUSH DE PUSH HL ENDM POPALL MACRO POP HL POP DE POP BC ENDM ; Endx SYSTEXT PAGE PRINT: LD A,[HL] ORA A RZ PUSH HL CALL COUT POP HL INC HL JR PRINT GVCHR: ; Read a char: allow only carriage return. ; CALL C1 ;Get a char CMP CR ;Is it Carriage return? JNZ GVCHR ;No, get another ; RET ;Yes, return GET_ESC: ; Wait for user to enter ESC ; :GE: CALL C1 CMP ESC JNZ :GE ; RET C1: CALL CIN ORA A JRZ C1 RET COUT: MOV E,A JR F6 CIN: LDK E,0FFH F6: LDK C,06H JMP SYS TITLE 'CONSTANTS' ;DOUBLE DENSITY PARAMETERS DDPARM: DW DLIFMT ;LIFMT FOR DOUBLE DENSITY DW DOUBTO ;TRKOFS FOR DD DW DFORDAT ;FORDAT FOR DD DB 0 ;OSBORNE FORMAT ;SINGLE DENSITY PARAMETERS SDPARM: DW SLIFMT ;LIFMT FOR SINGLE DENSITY DW SINGTO ;TRKOFS FOR SD DW SFORDAT ;FORDATh-for-first. CALL SYS ;Returns A = 0FFh if no files or if error INC A ;A = 0FFH? JNZ :INFO_FOUND ;No... ; XOR A ;Check for error. OR H ;Is H = 0? JNZ :CANT_TELL ;No, error occurred. ; :NO_INFO: ;No error, no info. XOR A ;Clear A and set Z flag RET ; :INFO_FOUND: ;Info on disk XOR A ;Return Z clear and A = 1 INC A RET :CANT_TELL: ;May be info. LK A,2 ;Return A = 2 and Z clear OR A RET PAGE CLR_W_2: PROC LK HL,:CLR_2_STR CALL PRINT RET ; :CLR_2_STR: DB ESC,'s2','Z'-40h,0 PAGE Y_N: PROC :YNLP: CALL C1 AND 5FH CMP 'Y' JZ :ECHO ; CMP 'N' JNZ :YNLP ; :ECHO: PUSH AF CALL COUT POP AF RET PAGE STSAVTYP: ;SET SAVTYP FOR FORMAT ;ENTRY ;A = 'S' FOR SINGLE DENSITY ;EXIT ;B = # OF SECTORS/TRACK PROC CPI 'S' JZ :SING ;IF SINGLE DENSITY ;DOUBLE DENSITY LDK A,DDTYP STO A,SAVTYP LDK B,5 ;SECTORS/TRACK RET ;SINGLE DENSITY :SING: LDK A,SDTYP STO A,SAVTYP LDK B,10 ;SECTORS/TRACK RET PAGE SETPARM: ;SET UP PARAMETERS THAT DEPEND ON DENSITY ;ENTRY ;B = # OF SECTORS/TRACK ;SAVTYP = SET ;EXIT ;PARAMETERS SET PROC MOV A,B STO A,NMSEC ;SECTORS/TRACK ORI 0FFH STO A,OSBFMT ;INITIALIZE TO NON-OSBORNE FORMAT ;CHECK FOR STANDARD OSBORNE DENSITIES LD A,SAVTYP ;DOUBLE DENSITY CPI DDTYP JZ :DD ;IF DOUBLE DENSITY SAVTYP 841006 ; CPI DSTYP ;DSDD uses same parameters as ssdd 841006 JNZ :2 ;Not dsdd 841006 ; :DD: MOV A,B ;VERIFY # OF SECTORS CPI DSEC JNZ :2 ;IF WRONG # OF SECTORS LDK HL,DDPARM ;DOUBLE DENSITY PARAMETERS JR :1 ;SINGLE DENSITY ;MOVE OSBORNE PARAMETERS TO PARM :1: LDK DE,PARM LDK BC,7 LDIR ;SET UP REMAINING PARAMETERS :2: RET PAGE FIXDSK: ; Fix SSDD disk. ;EXIT ;A = 0 IF NO ERRORS ; OFFH IF ERROR ; 'C'-40H IF ABORT PROC LDK HL,PFORMAT ;FORMAT MESSAGE CALL STRCON LDK A,1 STO A,SAVSEC ;SET SECTOR CALL RHOME ;HOME DRIVE JNZ :ERR ;ERROR RETURN ;FORMAT AND VERIFY ENTIRE DISK LDK HL,CRLF5S CALL PRINT XRA A ;START WITH TRACK 0 STO A,FMTERR ;NO ERRORS YET ;TRACK LOOP :TLOOP: STO A,SAVTRK ;UPDATE TRACK NUMBER XOR A ;Start with logical 841229 STO A,:LSIDE ;side 0 841229 INC A ;and physical 841229 STO A,:SIDE ;side 1 841229 LD A,SAVTYP ;Set side 1 in SAVTYP 841229 OR 0000_0010B ; 841229 STO A,SAVTYP :SLOOP: ;Top of side loop 841005 CALL FMTINT ;INITIALIZE FORMAT BUFFER(BUFF) LD A,:LSIDE ;Load logical side MOV C,A ;Pass it in C CALL STRK ;SET NEW TRACK and logical side ;INTO DATA IF NOT FMT_FIX LDK BC,BUFF ;POINT TO FWA OF BUFFER CALL RFORMAT ;FORMAT ONE TRACK ENDIF IF FMT_FIX LK HL,BUFF ;Point at buffer STO HL,DMADR ;save as DMA address IN SYS_DTA ;Get bank mask for TPA STO A,DMA_BANK ;and save as DMA bank CALL RFORMAT ;Format the track ENDIF JNZ :1 ;IF ERROR ; We don't verify since it doesn't matter if the format on ; side 1 is good. LDK A,'*' JMP :2 ;IF GOOD :1: LDK A,'E' STO A,FMTERR ;SET ERROR FLAG :2: CALL CONOUT ;OUTPUT INDICATOR CALL CKABORT RZ ;RETURN IF ABORT LD A,SAVTRK ;Go to next track INC A CMP MTRK JNZ :TLOOP ;CONTINUE TILL ALL TRACKS ;FINAL CHECK LD A,FMTERR ORA A JRNZ :ERR ;IF ERROR RET ;RETURN A=0 IF NO ERROR, A=0FFH IF ERROR :ERR: ORI 0FFH RET ;RETURN ERROR :SIDE: DB 0 ; 841005 :LSIDE: DB 0 ;Logical side PAGE FMTINT: ;MOVE FORMAT DATA TO HIGH RAM BUFFER ;SET BUFFER TO BE: ;0,1 = LENTH OF BUFFER ;2->END = BUFFER ;ENTRY ;NONE ;EXIT ;NONE PROC ;COPY 1ST SECTOR LDK DE,BUFF+2 ;FWA FOR DATA LD HL,FORDAT ;FWA OF DATA LD BC,LIFMT ;NUMBER OF BYTES LDIR ;MOVE LDK A,1 STO A,SECTOR ;SET SECTOR LD A,NMSEC ;SECTORS/TRACK DEC A MOV B,A ;COPY REMAINING SECTORS :LOOP: PUSH BC PUSH DE POP IY ;IY = FWA OF THIS SECTOR ;MAKE ONE SECTOR LD HL,FMTSD LD BC,LISEC L$A%DIR ;MOVE ;SET SECTOR NUMBER LDK HL,SECTOR ;INC SECTOR INC [HL] ;CHECK FOR DENSITY LD A,SAVTYP CMP SDTYP ;SINGLE DENSITY? LD A,[HL] ;A = SECTOR JZ :S ;IF SINGLE STO A,[IY+(DFSECN-DFMTSD)] ;DOUBLE JR :1 :S:; STO A,[IY+(SFSECN-SFMTSD)] ;SINGLE :1: POP BC DJNZ :LOOP ;IF MORE SECTORS ;SET LENTH OF BUFFER IN BUFFER EX DE,HL LDK BC,BUFF+2 SBC HL,BC ;GET LENGTH STO HL,BUFF ;SET LENGTH INTO BUFFER RET PAGE STRK: ;SET TRACK NUMBERS AND SIDE INTO DATA 841005 ;ENTRY ; C = Logical side ; ;EXIT ;NONE PROC LDK HL,BUFF+1 LD DE,TRKOFS ADD HL,DE LD A,NMSEC MOV B,A ;B = # OF SECTORS LD DE,LISEC LD A,SAVTRK :2: STO A,[HL] ;UPDATE TRACK CELL INC HL ;Point to SIDE CELL 841005 STO C,[HL] ;Store side byte in side cell 841005 DEC HL ;Point back at TRACK CELL 841005 ADD HL,DE ;POINT TO NEXT DJNZ :2 ;IF NOT DONE RET TITLE 'CALLS TO ROM RESIDENT ROUTINES' GOROM: ;UTILITY IN CBIOS IS JUMPED TO THAT MOVES THE STACK AND SWITCHES IN THE ROM ;ENTRY ;DE = THE ADDRESS TO CALL IN THE ROM ;EXIT *NOTE* ; The exit conditions in the rom determine what the regesters will be PROC LD A,2 MOV H,A ;HIGH ORDER BYTE OF BIOS LDK L,5AH ;LOW ORDER BYTE FOR ROM JUMP ROUTINE JMP [HL] RHOME: ;HOME THE DISK DRIVE ;ENTRY ;NONE ;EXIT ;A = 0 IF NO ERROR ;ZBIT = RESET IF ERROR PROC LDK DE,RHM_RTN CALL GOROM RET SENDEN: ;SENCE THE DENSITY, SECTOR SIZE, AND NUMBER OF SECTORS ON ONE TRACK ;ENTRY ;NONE ;EXIT ;ZBIT = SET IF GOOD ;B = NUMBER OF SECTORS PER TRACK ;SAVTYP = SECTOR SIZE AND DENSITY PROC LDK DE,SEN_RTN CALL GOROM RET RREAD: ;READ SECTOR ;ENTRY ;B = NUMBER OF SECTORS ;SDISK = DRIVE ;DMADR = DMA ADRESS ;SAVTRK = TRACK ;SAVSEC = SECTOR ;SAVTYP = DENSITY AND SECTOR SIZE ;EXIT ;HL = NEXT DMA ADDR IF GOOD TRANSFER PROC LDK DE,RD_RTN CALL GOROM RET RWRITE: ;WRITE SECTOR ;ENTRY ;B = NUMBER OF SECTORS ;SDISK = DRIVE ;DMADR = DMA ADRESS ;SAVTRK = TRACK ;SAVSEC = SECTOR ;SAVTYP = DENSITY AND SECTOR SIZE ;EXIT ;HL = NEXT DMA ADDR IF GOOD TRANSFER ;A = 0 IF NO ERROR ;ZBIT = RESET IF ERROR PROC LDK DE,WRT_RTN CALL GOROM RET RFORMAT: ;FORMAT TRACK ;ENTRY ;NONE ;EXIT ;A = 0 IF NO ERROR ;ZBIT = RESET IF ERROR PROC LDK A,2 ;RETRY ONCE FOR FORMAT ERROR STO A,ERCOUNT :LOOP: LDK DE,FMT_RTN CALL GOROM RZ ;RETURN IF NO ERROR LK HL,ERCOUNT DEC [HL] JNZ :LOOP ;RETRY ORI 0FFH ;INDICATE ERROR RET RSETTRK: ;SET THE TRACK REGESTER TO SAVTRK ;ENTRY ;SAVTRK = TRACK NUMBER ;EXIT ;NONE ; Routine no longer implemented in ROM PROC ; LDK DE,184H ; CALL GOROM RET RSDRV: ;SELECT THE DRIVE IN SDISK ;ENTRY ;SDISK = DRIVE TO SELECT ;EXIT ;NONE PROC LDK DE,SDRV_RTN CALL GOROM RET RSTEPOUT: ;STEP HEAD OUT ONE TRACK ;ENTRY ;NONE ;EXIT ;NONE PROC LDK DE,STP_O_RTN CALL GOROM RET RSTEP: ;STEP HEAD ONE TRACK IN DIRECTION LAST STEPPED ;ENTRY ;NONE ;EXIT ;NONE PROC LDK DE,STP_RTN CALL GOROM RET TITLE 'USEFUL PROC"S' COMPSEG: ;COMPARE THE DATA IN THE TWO BUFFERS. ;ENTRY ;BC = NUMBER OF BYTES ;DE = FIRST BUFFER ;HL = SECOND BUFFER ;EXIT ;A = 0 IF NO ERRORS ;ZBIT RESET IF ERROR PROC PUSHAL :1: MOV A,B ;CHECK BC FOR ZERO ORA C JZ :2 ;GOOD RETURN LD A,[DE] CMP [HL] PUSH AF INC DE INC HL DEC BC POP AF JZ :1 ORI 0FFH ;INDICATE ERROR :2: POPALL RET PAGE CKABORT: ;CHECK IF ABORT CHARACTER HAS BEEN PRESSED ;ENTRY ;NONE ;EXIT ;A = CHARACTER ;ZBIT = SET IF ABORT CHARACTER PRESSED PROC CALL CIN ;CHECK FOR CHARACTER ANI 5FH ;MAKE UPPER CASE CPI 'Q' RET PAGE CONOUT: ;OUTPUT CHARACTER TO CONSOLE ;ENTRY ;A = CHARACTER PROC PUSHAL MOV E,A MVI C,2 CALL SYS POPALL RET PAGE STRCON: ;OUTPUT MESSAGE TO CONSOLE ;ENTRY ;HL = FWA OF MESSAGE ;EXIT ;NONE PROC PUSHAL EX DE,HL ;VALUE TO DE LDK C,9 ;STRING CALL SYS  ;BDOS POPALL RET PAGE WBOOT: LDK A,'Z'-40H CALL COUT JMP WBOOTE PRINT: LD A,[HL] ORA A RZ PUSH HL CALL COUT POP HL INC HL JR PRINT GVCHR: ; Read a char: allow only carriage return. ; CALL C1 ;Get a char CMP CR ;Is it Carriage return? JNZ GVCHR ;No, get another ; RET ;Yes, return GET_ESC: ; Wait for user to enter ESC ; :GE: CALL C1 CMP ESC JNZ :GE ; RET C1: CALL CIN ORA A JRZ C1 RET COUT: MOV E,A JR F6 CIN: LDK E,0FFH F6: LDK C,06H JMP SYS TITLE 'CONSTANTS' ;DOUBLE DENSITY PARAMETERS DDPARM: DW DLIFMT ;LIFMT FOR DOUBLE DENSITY DW DOUBTO ;TRKOFS FOR DD DW DFORDAT ;FORDAT FOR DD DB 0 ;OSBORNE FORMAT ;PARAMETERS STORED HERE PARM: LISEC: ;LISEC = LIFMT LIFMT: DS 2 TRKOFS: DS 2 FMTSD: ;FMTSD = FORDAT FORDAT: DS 2 OSBFMT: DS 1 ;OSBFMT = 0 IF OSBORNE FORMAT, OTHERWISE 0FFH NMSEC: DS 1 ;# OF SECTORS/TRACK TRKLEN: DS 2 ;# OF BYTES/TRACK NUMTRK: DS 1 ;# OF TRACKS/BLOCK NUMBLK: D%A&S 1 ;# OF BLOCKS/DISK PTRKLEN: DS 2 ; 841006 NSIDES: DS 1 ; 841006 OVRD_FLAG: DS 1 ;True if check for formatted destination disk ;should be overridden PAGE ; Data and all message constants AMB_FCB: ;Ambiguous FCB to search for files in the ;directory of a disk DB 0 DB '????????','???','?' DB 0,0,0 DB 0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0 DB 0,0,0,0 ;***** SYSTEM MESSAGES OS_BAD_MSG: db 'FIXSSDD requires CP/M 3.X or greater.',cr,lf DB 'Copyright ' DB ESC,VSGH,CP_RG_CH,ESC,VEGH ;Set graphics mode, show ;copyright char and clr ;graphics DB ' 1984 Future Systems, 828 Nob Hill Avenue, ' DB 'Pinole CA 94564',cr,lf,0 SCR_TOP: DB ESC,'s','0','Z'-040h,ESC,'=',32,32 DB ' Single Sided Single Density Disk Fixup Program' D cr,lf D Osborn EXECUTIV Compute System' DB CR,LF DB ' V1.0' DB 0 COPYR_MSG: DB ESC,'s2',CLR_SCR ; DB ' ' ; DB ESC,VSGH,CP_RG_CH,ESC,VEGH ;Set graphics mode, show ;copyright char and clr ;graphics ; DB ' 1983 Osborne Computer Corporation, 26538 Danti Court, ' ; DB 'Hayward, CA 94545',cr,lf DB ' ' DB ESC,VSGH,CP_RG_CH,ESC,VEGH ;Set graphics mode, show ;copyright char and clr ;graphics DB ' 1984 Future Systems, 828 Nob Hill Avenue, ' DB 'Pinole CA 94564',0 NO_OPT_1: = 3 IF TVI912 MAIN1: DW MAIN_1_L DB ESC,'s','1','Z'-040h,ESC,'=',32,32 MN_1_A: DB ' ',ESC,'k Fix Disk in Drive A ',ESC,'k',0,CR,LF MN_1_B: DB ' ',ESC,'k Fix Disk in Drive B ',ESC,'k',0,CR,LF MN_1_C: DB ' ',ESC,'k RETURN TO CP/M ',ESC,'k',0,CR,LF DB CR,LF D '$' ENDIF MAIN_1_L: DW MN_1_A DW MN_1_B DW MN_1_C DIR_MSG: db ESC,'s5','Z'-40h db ' Use the ARROW keys to position the',cr,lf db ' cursor next to the desired choice',cr,lf db ' or',0 RET_CPM: db 0 db ESC,'s6','Z'-40h db ' Press RETURN to Return to CP/M$' FIX_MSG: db 0 db ESC,'s6','Z'-40h db ' Insert a Diskette in selected drive and',cr,lf db ' Press RETURN to start fixing',cr,lf db cr,lf db ESC,'^WARNING: ',ESC,'jDo not attempt to fix a truly double ' db 'sided disk! It will be DESTROYED!',ESC,'k',ESC,'q$' PAGE NUM_OPTIONS DB 0 ;# OF OPTIONS in current ;main menu SIDE: DB 0 ;0-LEFT MENU, 1- RIGHT PUT_CURSOR: DB ESC,'s','1',ESC,'=' ;MAIN MENU CURSOR POSITION Y_COORD: DB 32 X_COORD: DB 32 DB 0 PUT_SUB_CURSOR: DB ESC,'s','2',ESC,'=' ;MAIN MENU CURSOR POSITION Y_SUB_COORD: DB 32 X_SUB_COORD: DB 32 DB 0 NUM_SUB_CMDS: DS 1 ;# OF COMMANDS IN SUB MENU NUL_MSG: M_EXIT: DB 0 DB ESC,'s','2','Z'-040h DB ESC,'s','1' DB '$' PAGE CRLF5S: DB ESC,'s3',cr,lf,lf,lf DB ' ',0 PFORMAT: DB ESC,'s5','Z'-40h DB cr,lf DB ' Press and Hold Q to Quit Fixing' DB ESC,'s','3','Z'-040h DB ' Track Fixed:',cr,lf DB ' 0 1 2 3 ' DB CR,LF DB ' 0123456789012345678901234567890123456789',cr,lf DB '$' SECTOR: DB 0 ;FOR FORMAT SOURCE: DB 0 ;SOURCE DRIVE FOR COPY TRACK: DB 0 ;ACTIVE LOGICAL TRACK BLOCK: DB 0 ;ACTIVE BLOCK NUMBER DSK_FMT: DB ESC,'s2','Z'-40h DB ' Diskette in Drive ' D_FMT_D: DB 'X' ;Filled in by FMAT or KOPY DB ' contains information.',cr,lf DB ' Is it OK to overwrite it (y/n)? ',0 DK_MB_FMT: DB ESC,'s2','Z'-40h DB ' Diskette in Drive ' D_FMT_D2: DB 'X' ;Filled in by FMAT or KOPY DB ' MAY contain information.',cr,lf DB ' Is it OK to overwrite it (y/n)? ',0 END: DB CR,LF,LF DB 0 GDFMT: DB ESC,'s','2','Z'-040h DB ' Fixing completed successfully.',cr,lf DB ' Press RETURN to continue.' DB 0 BDFMT: DB ESC,'s','2','Z'-040h DB ' Error while fixing.',cr,lf DB ' Press ESC to continue.' DB 0 ABTFMT: DB ESC,'s','2','Z'-040h DB ' FIXING ABORTED.',cr,lf DB ' Press RETURN to continue.' DB 0 PAGE DFORDAT: ;DOUBLE DENSITY FORMAT DATA FOR IBM 3740. *NOTE* ;NO INDEX MARK IS USED ; **** GAP 1 **** DFMTSD: ECHO 100 ! DB 04EH ENDM ECHO 12 ! DB 0 ENDM DB 0F5H,0F5H,0F5H DB 0FEH ;ID ADDRESS MARK DFTRKN: DB 0 ;TRACK DOUBTO = *-DFORDAT DB 0 ;SIDE DFSECN: DB 1 ;SECTOR DB 3 ;SECTOR LENTH DB 0F7H ;CRC ; **** GAP 2 **** ECHO 22 ! DB 04EH ENDM ECHO 12 ! DB 0 ENDM DB 0F5H,0F5H,0F5H DB 0FBH ;DATA ADDRESS MARK ; **** DATA **** ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM ECHO 128 D&A'B FMTCHR ENDM ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM DFCRC2: DB 0F7H ;CRC DFMTEND = * DLIFMT = *-DFORDAT DLISEC = *-DFMTSD ERCOUNT: DB 0 ;ERROR COUNTER LBUFF1: DW 0 ;HOLD FBA IN BUFF1 MACHTYPE: DB 0 ;MACHINE DENSITY ; 0 = Undefined ; 1 = Single ; 2 = Double FMTERR: DB 0 ;FORMAT ERROR FLAG DS 40*2 STACK: DS 0 ;STACK HERE  ECHO 12 ! DB 0 ENDM DB 0F5H,0F5H,0F5H DB 0FEH ;ID ADDRESS MARK DFTRKN: DB 0 ;TRACK DOUBTO = *-DFORDAT DB 0 ;SIDE DFSECN: DB 1 ;SECTOR DB 3 ;SECTOR LENTH DB 0F7H ;CRC ; **** GAP 2 **** ECHO 22 ! DB 04EH ENDM ECHO 12 ! DB 0 ENDM DB 0F5H,0F5H,0F5H DB 0FBH ;DATA ADDRESS MARK ; **** DATA **** ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM ECHO 128 Dive B selected. ; Do format. ; LK A,'B' ;Specify drive B ; LK B,'D' ;Specify double-density CALL FIXIT ;Format the disk CALL CLR_W_3 ;Erase message window RET PAGE CLR_W_3: ; Routine to clear window 3. Window 3 is used for execution ; status while performing an operation. ; LK HL,:CLR_3_STR ;Point at string to clear window CALL OUT_STRING ;and send to console. RET ; :CLR_3_STR: ; String to clear window 3. Selects window 3 and sends clear screen ; character. ; DB ESC,'s3',CLR_SCR,0 PAGE FIXIT: ; Disk fix routine ;ENTRY ; A = Disk to format ('A' or 'B') ;EXIT ;NONE PROC :LOOP: STO A,D_FMT_D STO A,D_FMT_D2 SUI 'A' STO A,SDISK CALL CLR_W_2 LD A,SDISK ;See if destination disk contains info CALL CK_INFO JZ :BLK_DSK ;No...format it ; LK HL,DSK_FMT ;Assume it does DEC A ;Does it (i.e., is A = 1) ? JZ :ASK ;It does, ask user if it should be ;overwritten ; LK HL,DK_MB_FMT ;Disk MAY have info. Ask user if it ;should be overwritten. :ASK: CALL PRINT CALL Y_N PUSH AF ;Save response CALL CLR_W_2 ;Clear question POP AF ;Restore response CMP 'N' ;No, RZ ;Don't format ; ;Yes, format disk :OVRD: :BLK_DSK: LK A,'D' ;Set density specification 850102 CALL STSAVTYP ;SET DENSITY CALL SETPARM ;SET PARAMITERS CALL FIXDSK ;Fix DISKETTE PUSH AF ;Save return code from FIXDSK LK C,0DH ;so the disk system can be reset. CALL SYS ;The disk system must be reset since ;the disk has effectively been changed ;by formatting it. POP AF ;Restore return code from FIXDSK CPI 'Q' LDK HL,ABTFMT ;FORMAT aborted JRZ :DONE ;If aborted ORA A LDK HL,GDFMT ;FORMAT completed successfully JRZ :DONE ;IF NO ERRORS :BAD: LDK HL,BDFMT ;ERROR IN FORMAT CALL PRINT CALL GET_ESC CALL CLR_W_2 RET ; :DONE: CALL PRINT CALL GVCHR CALL CLR_W_2 RET ; PAGE CK_INFO: ; Checks to see if there is info on disk. Calls sense density routine ; to see if the disk is formatted. If it is not formatted, there is no ; info. ; If disk is formatted, checks for files in directory. ; ; ENTRY: ; A = # of disk on which to check for info ; 0 means drive A, ; 1 means drive B. ; ; EXIT: ; A = 0 if disk has no info, ; A = 1 if disk has info and ; A = 2 if disk MAY HAVE info (i.e., can't be determined). ; Additionally: ; Z flag set if disk has no info ; Z flag clear if disk has or may have info. ; ; SIDE EFFECT: ; SDISK set to disk # (whatever A is on entry) ; PROC MOV B,A ;Save drive spec in B PUSH BC ;Save on stk STO A,SDISK ;Select disk for SENDEN CALL SENDEN ;Check for unformatted disk. Z is clear ;if disk no formatted. POP BC ;Restore disk # JNZ :NO_INFO ;Return code indicating no info ; MOV A,B ;Restore disk # to A INC A ;Make disk # relative-one per BDOS STO A,AMB_FCB ;Put drive spec in FCB for search for first LK DE,AMB_FCB ;Point at ambiguous FCB to check for any files. LK C,SRC_FIRST ;Tell BDOS to do search-for-first. CALL SYS ;Returns A = 0FFh if no files or if error INC A ;A = 0FFH? JNZ :INFO_FOUND ;No... ; XOR A ;Check for error. OR H ;Is H = 0? JNZ :CANT_TELL ;No, error occurred. ; :NO_INFO: ;No error, no info. XOR A ;Clear A and set Z flag RET ; :INFO_FOUND: ;Info on disk XOR A ;Return Z clear and A = 1 INC A RET :CANT_TELL: ;May be info. LK A,2 ;Return A = 2 and Z clear OR A RET PAGE CLR_W_2: PROC LK HL,:CLR_2_STR CALL PRINT RET ; :CLR_2_STR: DB ESC,'s2','Z'-40h,0 PAGE Y_N: PROC :YNLP: CALL C1 AND 5FH CMP 'Y' JZ :ECHO ; CMP 'N' JNZ :YNLP ; :ECHO: PUSH AF CALL COUT POP AF RET PAGE STSAVTYP: ;SET SAVTYP FOR FORMAT ;ENTRY ;A = 'S' FOR SINGLE DENSITY ;EXIT ;B = # OF SECTORS/TRACK PROC CPI 'S' JZ :SING ;IF SINGLE DENSITY ;DOUBLE DENSITY LDK A,DDTYP STO A,SAVTYP LDK B,5 ;SECTORS/TRACK RET ;SINGLE DENSITY :SING: LDK A,SDTYP STO A,SAVTYP LDK B,10 ;SECTORS/TRACK RET PAGE SE'A