From 6939e91263066940e8f1816eafd720a5bbfa9f86 Mon Sep 17 00:00:00 2001 From: Marcio T Date: Fri, 19 Nov 2021 21:24:24 -0700 Subject: [PATCH] Inital commit --- README.md | 25 + images/tip1.gif | Bin 0 -> 11873 bytes images/tip2.gif | Bin 0 -> 9156 bytes x86-asm-source/2 Font.asm | 42 + x86-asm-source/2 Font.bmp | Bin 0 -> 5082 bytes x86-asm-source/ASPI.ASM | 1951 ++++++++++++++++ x86-asm-source/ASPI.INC | 399 ++++ x86-asm-source/MACROS.INC | 50 + x86-asm-source/MAKEFILE | 87 + x86-asm-source/NEW.ASM | 2 + x86-asm-source/Off.bmp | Bin 0 -> 206 bytes x86-asm-source/On.bmp | Bin 0 -> 206 bytes x86-asm-source/Proto.rc | 97 + x86-asm-source/RTF-save.RTF | 584 +++++ x86-asm-source/RTF.RTF | 571 +++++ x86-asm-source/SCSIID.ASM | 83 + x86-asm-source/Sixteen.bmp | Bin 0 -> 8566 bytes x86-asm-source/TIP.APS | Bin 0 -> 2816 bytes x86-asm-source/TIP.ASM | 3940 ++++++++++++++++++++++++++++++++ x86-asm-source/TIP.DAT | 321 +++ x86-asm-source/TIP.DSP | 128 ++ x86-asm-source/TIP.DSW | 29 + x86-asm-source/TIP.ICO | Bin 0 -> 766 bytes x86-asm-source/TIP.PLG | 6 + x86-asm-source/TIP.RC | 139 ++ x86-asm-source/TIP.TXT | 254 ++ x86-asm-source/TIP.ncb | Bin 0 -> 33792 bytes x86-asm-source/Tip.opt | Bin 0 -> 48640 bytes x86-asm-source/UPDATE.BAT | 3 + x86-asm-source/defect.asm | 41 + x86-asm-source/fewspares.asm | 42 + x86-asm-source/font.asm | 37 + x86-asm-source/font.bmp | Bin 0 -> 5082 bytes x86-asm-source/font.obj | Bin 0 -> 1133 bytes x86-asm-source/green.bmp | Bin 0 -> 206 bytes x86-asm-source/instruct.asm | 36 + x86-asm-source/locked.asm | 29 + x86-asm-source/nospares.asm | 43 + x86-asm-source/outofspares.asm | 43 + x86-asm-source/red.bmp | Bin 0 -> 206 bytes x86-asm-source/rtf.asm | 359 +++ x86-asm-source/rtf.obj | Bin 0 -> 22006 bytes x86-asm-source/sectors.asm | 44 + x86-asm-source/sectors.bin | Bin 0 -> 4096 bytes x86-asm-source/sectors.obj | Bin 0 -> 1733 bytes x86-asm-source/sixteen.asm | 167 ++ x86-asm-source/sound.bmp | Bin 0 -> 246 bytes x86-asm-source/tip-asm.sav | 3061 +++++++++++++++++++++++++ x86-asm-source/tip-rc.sav | 47 + x86-asm-source/tip-test.BAK | Bin 0 -> 61952 bytes x86-asm-source/tip.RES | Bin 0 -> 4000 bytes x86-asm-source/tip.cur | Bin 0 -> 326 bytes x86-asm-source/tip.exe | Bin 0 -> 77824 bytes x86-asm-source/tip.exe.bak | Bin 0 -> 65024 bytes x86-asm-source/tip.map | 383 ++++ x86-asm-source/tip.obj | Bin 0 -> 63543 bytes 56 files changed, 13043 insertions(+) create mode 100644 README.md create mode 100644 images/tip1.gif create mode 100644 images/tip2.gif create mode 100644 x86-asm-source/2 Font.asm create mode 100644 x86-asm-source/2 Font.bmp create mode 100644 x86-asm-source/ASPI.ASM create mode 100644 x86-asm-source/ASPI.INC create mode 100644 x86-asm-source/MACROS.INC create mode 100644 x86-asm-source/MAKEFILE create mode 100644 x86-asm-source/NEW.ASM create mode 100644 x86-asm-source/Off.bmp create mode 100644 x86-asm-source/On.bmp create mode 100644 x86-asm-source/Proto.rc create mode 100644 x86-asm-source/RTF-save.RTF create mode 100644 x86-asm-source/RTF.RTF create mode 100644 x86-asm-source/SCSIID.ASM create mode 100644 x86-asm-source/Sixteen.bmp create mode 100644 x86-asm-source/TIP.APS create mode 100644 x86-asm-source/TIP.ASM create mode 100644 x86-asm-source/TIP.DAT create mode 100644 x86-asm-source/TIP.DSP create mode 100644 x86-asm-source/TIP.DSW create mode 100644 x86-asm-source/TIP.ICO create mode 100644 x86-asm-source/TIP.PLG create mode 100644 x86-asm-source/TIP.RC create mode 100644 x86-asm-source/TIP.TXT create mode 100644 x86-asm-source/TIP.ncb create mode 100644 x86-asm-source/Tip.opt create mode 100644 x86-asm-source/UPDATE.BAT create mode 100644 x86-asm-source/defect.asm create mode 100644 x86-asm-source/fewspares.asm create mode 100644 x86-asm-source/font.asm create mode 100644 x86-asm-source/font.bmp create mode 100644 x86-asm-source/font.obj create mode 100644 x86-asm-source/green.bmp create mode 100644 x86-asm-source/instruct.asm create mode 100644 x86-asm-source/locked.asm create mode 100644 x86-asm-source/nospares.asm create mode 100644 x86-asm-source/outofspares.asm create mode 100644 x86-asm-source/red.bmp create mode 100644 x86-asm-source/rtf.asm create mode 100644 x86-asm-source/rtf.obj create mode 100644 x86-asm-source/sectors.asm create mode 100644 x86-asm-source/sectors.bin create mode 100644 x86-asm-source/sectors.obj create mode 100644 x86-asm-source/sixteen.asm create mode 100644 x86-asm-source/sound.bmp create mode 100644 x86-asm-source/tip-asm.sav create mode 100644 x86-asm-source/tip-rc.sav create mode 100644 x86-asm-source/tip-test.BAK create mode 100644 x86-asm-source/tip.RES create mode 100644 x86-asm-source/tip.cur create mode 100644 x86-asm-source/tip.exe create mode 100644 x86-asm-source/tip.exe.bak create mode 100644 x86-asm-source/tip.map create mode 100644 x86-asm-source/tip.obj diff --git a/README.md b/README.md new file mode 100644 index 0000000..84646f0 --- /dev/null +++ b/README.md @@ -0,0 +1,25 @@ +![Trouble In Paradise About Box][screenshot1] + +TIP: Trouble In Paradise +======================== + +This repository contains the source code of [Trouble in Paradise], +a diagnostic and repair tool for Iomega Zip and Jaz Drives. + +The source code in the "x86-asm-source" directory is the original source +code as graciously provided to me by Steve Gibson. I am republishing his +code in this repository with his permission. + +This repository will also eventually contain a port of the code intended +to run on classic Macintosh computers. + +Testing Screen +-------------- + +Here os the main "Trouble in Paradise" testing screen: + +![Trouble In Paradise Testing][screenshot2] + +[screenshot1]: https://github.com/marciot/grc-tip/raw/main/images/tip1.gif "TIP" +[screenshot2]: https://github.com/marciot/grc-tip/raw/main/images/tip2.gif "TIP" +[Trouble in Paradise]: https://www.grc.com/tip/clickdeath.htm \ No newline at end of file diff --git a/images/tip1.gif b/images/tip1.gif new file mode 100644 index 0000000000000000000000000000000000000000..11843b636f427e0ea86f99ca6f02c1c078445709 GIT binary patch literal 11873 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 b@AT@|vv2SIJ^c9c=hLrm|2}H~5dZ)??p1P- literal 0 HcmV?d00001 diff --git a/images/tip2.gif b/images/tip2.gif new file mode 100644 index 0000000000000000000000000000000000000000..bc301afa8ceb1c8d78bb3de2d2616984bdc50325 GIT binary patch literal 9156 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 O<Yl0028DvI4OH literal 0 HcmV?d00001 diff --git a/x86-asm-source/2 Font.asm b/x86-asm-source/2 Font.asm new file mode 100644 index 0000000..d2d09d0 --- /dev/null +++ b/x86-asm-source/2 Font.asm @@ -0,0 +1,42 @@ +.586 +.model flat, stdcall +option casemap:none +option expr32 +;------------------------------------------------------------------------------- +; Bitmap Data -- Width: 151 +; Height: 251 +; Bits/Pixel: 1 +; Colors Used: 2 +;------------------------------------------------------------------------------- +EXTERNDEF FontBitmapImage:DWORD + + .const +.RADIX 16 +;------------------------------------------------------------------------------- +FontBitmapImage LABEL DWORD + +dd 0000013DA ; 5082 original size +dd 00000044E ; 1102 compressed size +dd 034840500, 0000136D1, 0FCF81CC0, 0970FE501, 043FFD87F, 0C5F30FC0, 02E11BFF9, 0400041F5, 0BFC1CC7D, 0C07FFF7F, 0F0FFB72F, 0F4FA6FE7, 008F035B1, 01FC5B7CF, 0A7F074FF, 0CFB1807F +dd 013CD2EB7, 084F37F4F, 03014F71F, 0E3FCFF4B, 089EE5D9E, 0D43D3CC7, 0A798E027, 01E04FA9F, 0F62CECF3, 0359F27C0, 04FCB7A8B, 03F89E503, 076D92CF9, 0A3E9F962, 09F27FD3C, 063F6DB25 +dd 03B6C967E, 0CBCCFC82, 0733CA089, 079411D52, 09E636CE6, 0FC27D21E, 0352699F4, 0A46B1691, 0699F2549, 079501352, 033C4CBA6, 0EE04D491, 0BD9AFDAF, 0244CF31A, 0CFAC3E3F, 0E9F5F244 +dd 0F1F92E3F, 092267D48, 031804F2F, 0DF878D49, 0525C7001, 0D49319F9, 0F027FC3D, 013EAA4B8, 075B65C7C, 085E93F07, 0FC9FC076, 0CFA8B2E3, 027C443F8, 0853F38FE, 06C7F93CC, 0BCF3A174 +dd 07B47DDEF, 004F68F8A, 03FBBE71F, 039F02FEF, 0B1EDFC2C, 0F9CFC27E, 086B78754, 0F0480BE0, 02CFCBF8D, 00D5C07EE, 021E8545A, 0FD0F1965, 0D5FC6F59, 0D70BE01C, 0CF376795, 09FA7FB1C +dd 054C81899, 05CF12003, 0F4A7C120, 04A73BFCA, 0694008C9, 031F4FF11, 082850F4F, 01843C1CA, 0006A0E9E, 00C20E0F9, 085D244CF, 0053D237E, 0F14053CC, 00E33CC53, 0013F23D7, 0C65FD3F4 +dd 0FF27B8EA, 0FE3FA798, 0CFF1AFD9, 067E48F78, 014FD0F8C, 0DC098CF6, 098ED614F, 0C6147C80, 01C280988, 001B1014F, 0112828F9, 0FE079013, 03CA3E9A9, 04FAD2263, 03A91713F, 033885FE0 +dd 0AC83A919, 0E9A464FC, 07D589933, 0AC4B883A, 08FF80D3E, 0FF00CC49, 09E11998C, 08BD43200, 013AC6CB3, 078C6F232, 09C7E2339, 071404A2E, 01248C8BA, 0632119F1, 03632D107, 04E39B990 +dd 0CE32D1F9, 0691F1AEC, 045FD8C94, 0064FC4CB, 04501B10A, 00A43C4C9, 08D236320, 04C818990, 04691F1B3, 0B70324C9, 09908CF08, 089968BF8, 0F899689F, 087899688, 048389968, 0D23E2489 +dd 0A4044CF8, 019E11078, 0240CCD6F, 09F1A44A2, 0A6029F89, 09F1A44A2, 099688789, 089968838, 0A2B80C81, 0521B1044, 09266C679, 048944E41, 093F133E3, 09108EBC2, 0205266C6, 00EE85C76 +dd 0206C65A2, 019E5C65A, 07A127197, 0D6348846, 025A2FE8F, 0625A27E6, 05C65A27E, 095B38A02, 079896887, 083989688, 008198968, 0822E33CB, 0046C7812, 0F48E3029, 05FD48B8C, 001719E58 +dd 0901689F9, 0F901689F, 094053E48, 003243DEC, 0C5DA50F2, 03B52333C, 0202E0448, 01A7C9DC7, 027E4F1C8, 01F82BAC0, 0358061E3, 04F31FC09, 014AA35C0, 05FD3CBA5, 0E1C267B4, 01C259709 +dd 044053E9E, 0D8481A7B, 0C4407530, 00D8483A7, 0C487A7D3, 09E584FD3, 023D38BF0, 06D27C13E, 027E9F91E, 04BF89F14, 0C4E3E044, 0499E441E, 0633FC699, 0CFE21A74, 0D0870518, 067B46013 +dd 0F3C3C88C, 084F31FE4, 0DBC9200F, 0D1F84FB1, 03DA3E09E, 0FD3EC781, 0A52F1825, 0FA097F54, 031F04F2D, 089EE21E0, 07C13DA3F, 038F027B4, 0EADE0206, 099E91803, 099E63649, 0764FDD69 +dd 0A5049FBE, 0091F4FA4, 0F4F88B72, 0F113AD97, 04CF121E9, 0B3D22FE9, 0163C0A5D, 03E09FBC7, 0A9BFC9EE, 034047C01, 093869033, 0C63A7E1A, 03F7E1EBA, 0278147F9, 07093ADA9, 0126D352C +dd 011CBFA96, 0753FD124, 0FDB91259, 0C01413C4, 03C7F9A5A, 00012774E, 0CFF94913, 06C89E07F, 0F83AE7F9, 04FE05913, 00728973D, 07E034D3F, 09BA4BD4E, 0D2B0316F, 07013DC4F, 0A0E3BF8C +dd 006384E6C, 0631CE642, 051F64A60, 0798B741C, 024C5E566, 04C4BC196, 025AC1962, 052414E33, 002149332, 081C51566, 0092644E3, 03D089410, 0038D9012, 08A2EB1FB, 0600D1E6D, 012E881C6 +dd 0AC801C54, 0D501C451, 0032C4D3A, 0FF0001FE + +;------------------------------------------------------------------------------- +.RADIX 10 + +END ; end of the file diff --git a/x86-asm-source/2 Font.bmp b/x86-asm-source/2 Font.bmp new file mode 100644 index 0000000000000000000000000000000000000000..389653cbf90d0ed015b07102a74c02330744c1a7 GIT binary patch literal 5082 zcmb`KF^=;#5QVkb!sQk@0E;xKa)by-pEFUn_?sL?=SZa^I8_W}Vdc$xGbD%B4{U&F zVVV9k!+CEg%HH38|MSO%$FDg5jMq23{=w@Fe|G$V>p%UX*AMt?FFVfj#Ot9C_W4u8 zftB+-2nU8V1$K4=J2wmL45^;nSvAIjjlCHDqSqnWkq?{)NI*YO+bGMiQ-SW87=0p2^4b}@* z8$(w;t|2og)}>gdD_uudEIe43XG^TOE>Fz5Q+f@oQswfkGh@d(JQhUk%P0lSA{(Wk zSzyO9N)fxKvS7uURnOsg7<;A?2mzapEB3jJPL=Rg_RMmb{B;KVe`kTu1?;a2cCQIO zt)2Jc?32wPd)%DuHj{3Ihxf%cbPeYH+qI~E!>|$DrWoP9V(V~?Y^T}C8Iui}46xNs zxO|Y|-V3(emX7=La2d`C64=_DG0BY)vb7V=m0?5ry?3gOTHc4Pq1rbN+>8(PA*iIh6m-vEAZ* zJ~0?cw-K*{?LAPVn!81~=FX6nBu2R~G8FD?)3BXkNcBs#m3=-fhy&V`+&!Y(=&R^9BlUWi%6wy~|wj*%6`rS)_pNsO~3#?2)$ zZsdxkZn?SKEosT!a+X9_!7G-GtcpuUoFyYgab#~^-VM{phwsRdRo{``1T$xzcD%P= zJQ!L(j*)G;OikV_YeGRB>j&HIYtT1PGz+X=Fd!Gh5essJd3|ph(=3^(+HP@G$#+V2 zBaO-Bk>b=1vNdvFS^ST5N`=+|$KPdy;h zjqqRDzTlYV`zqTmat+P%T`+BAultY>?VZecKgWC?r@fftj|D0_jyX)p8 ziho7Kd>ebNn9An3L%Ai^X2oE8W%1Y=u*MOUA|WxOg6rxfW+|fIaQZpCw}M!!u)rTM^z z8b&a%!`K>PNR$M|!ttov5Ldjg%j0*2Nw8}!h0LxWV3@-WinV!cLK2^w?PxdnDf1T4 z|1DONs%PoVrf!q_m7T1lxQ#4?@sjr~43K$$!zh`gG__>DUhxbjQ`sy=WqU^u=w TEN_BYTE_CMDS) ; but if it's a LONG one .... + mov al, 10 ; then return that + .ENDIF +Exit: ret +;------------------------------------------------------------------------------- +GetCommandDetails ENDP + + +;+-----------------------------------------------------------------------------+ +;| SCSI COMMAND | +;| This executes a SCSI command through the ASPI interface. It receives a | +;| NEAR pointer to a standard SCSI command block (SCB) and a pointer and | +;| length to an IoBuffer for the command. It returns in EAX the complete | +;| three-byte sense code from the command. | +;+-----------------------------------------------------------------------------+ +SCSICommand PROC USES esi edi, Adapter:DWORD, Device:DWORD, lpCmdBlk:LPVOID, lpIoBuf:LPVOID, IoBufLen:DWORD + LOCAL AbortSRB:SRB_Abort +;------------------------------------------------------------------------------- + ZeroASPI + mov ASPI_CmdBlock.io.SRB_Cmd, SC_EXEC_SCSI_CMD ; w: ASPI command code = SC_EXEC_SCSI_CMD + movmov ASPI_CmdBlock.io.SRB_HaId, al, byte ptr Adapter ; w: ASPI host adapter number + movmov ASPI_CmdBlock.io.SRB_Target, al, byte ptr Device ; w: target's SCSI ID + movmov ASPI_CmdBlock.io.SRB_BufPointer, eax, lpIoBuf ; w: data buffer pointer + movmov ASPI_CmdBlock.io.SRB_BufLen, eax, IoBufLen ; w: data allocation length + mov ASPI_CmdBlock.io.SRB_SenseLen, SIZEOF ASPI_CmdBlock.io.SRB_SenseArea ; w: sense allocation length + mov ASPI_CmdBlock.io.SRB_Flags, SRB_EVENT_NOTIFY ; w: SCSI request flags + movmov ASPI_CmdBlock.io.SRB_PostProc, eax, hCompletionEvent + + ; assemble our scsi command block + mov esi, lpCmdBlk ; get a pointer to the scsi command + invoke GetCommandDetails, [esi] ; al == cmd_length, ah == cmd_flags + or ASPI_CmdBlock.io.SRB_Flags, ah ; w: SCSI request flags + mov ASPI_CmdBlock.io.SRB_CDBLen, al ; w: CDB Length + + ; move the command block into the ASPI structure + lea edi, ASPI_CmdBlock.io.SRB_CDBByte + movzx ecx, al + rep movsb + + ; call the ASPI manager to forward the command to the device + invoke SendASPI32CommandPtr PTR lpSendASPI32Command, ADDR ASPI_CmdBlock + invoke WaitForSingleObject, hCompletionEvent, SCSI_TIMEOUT + movzx eax, ASPI_CmdBlock.io.SRB_Status + + ; if the command did not generate any Sense Data, just return NULL + .IF (al == SS_COMP) +NoError: zero eax + + ; else, if it's *NOT* a "Sense Data" error (SS_ERR) + .ELSEIF (al != SS_ERR) + movzx eax, al + or eax, 00FFFF00h ; [00 FF FF er] + + ; okay, we have an SS_ERR condition, let's check the SENSE DATA + .ELSE ; assemble [00 ASC ASCQ SenseKey] + movzx eax, word ptr ASPI_CmdBlock.io.SRB_SenseArea[12] ; [00 00 ASCQ ASC] + swap ah, al ; [00 00 ASC ASCQ] + shl eax, 8 ; [00 ASC ASCQ 00] + mov al, ASPI_CmdBlock.io.SRB_SenseArea[2] ; [00 ASC ASCQ xSenseKey] + and al, 0Fh ; [00 ASC ASCQ SenseKey] + .IF (eax == MEDIA_CHANGE_CODE) + invoke GetDriveEntryOffset, Adapter, Device + or dword ptr [eax], MEDIA_CHANGED + jmp NoError + .ELSEIF (!eax) ; if we had NO SENSE error, but SS_ERR + mov eax, SS_ERR ; return SS_ERR + .ENDIF + .ENDIF + ret +;------------------------------------------------------------------------------- +SCSICommand ENDP + + +;+-----------------------------------------------------------------------------+ +;| ENUMERATE IOMEGA DEVICES | +;+-----------------------------------------------------------------------------+ +EnumerateIomegaDevices PROC USES ebx + LOCAL FirstInvalidAdapter:DWORD, Scsi[6]:BYTE, + InqData[96]:CHAR, Adapter:DWORD, Device:DWORD +;------------------------------------------------------------------------------- +IFE FORCE_NO_DRIVES + ; get the total adapter count + invoke HostAdapterInquiry, 0 + movzx eax, ASPI_CmdBlock.hai.HA_Count + ; see whether it completed successfully + .IF (ASPI_CmdBlock.hai.SRB_Status != SS_COMP) || (!eax) + jmp Exit + .ENDIF + mov FirstInvalidAdapter, eax + reset Adapter + reset DriveCount ; reset the global DriveCount variable + .REPEAT + ; check each adapter for "ppa3" string and small blk xfers + invoke HostAdapterInquiry, Adapter + .IF (ASPI_CmdBlock.hai.SRB_Status == SS_COMP) + ; truncate at four chars so "PPA3NT" and "ppa3" both match! + mov byte ptr ASPI_CmdBlock.hai.HA_Identifier[4], 0 + invoke lstrcmpi, ADDR ASPI_CmdBlock.hai.HA_Identifier, ADDR szPPA3 + .IF (!eax) + mov eax, dword ptr ASPI_CmdBlock.hai.HA_Unique[4] + .IF (eax < 65536) + set OldPPA3Driver + .ENDIF + .ENDIF + .ENDIF + + ; now scan the devices on this host adapter + reset Device + .REPEAT + invoke GetDeviceType, Adapter, Device + cmp eax, SS_COMP + jne TryNextDrive + ;-------------------------------------------------------------------------- + varzero Scsi + mov Scsi, SCSI_Cmd_Inquiry + mov Scsi[4], SIZEOF InqData + invoke SCSICommand, Adapter, Device, ADDR Scsi, ADDR InqData, SIZEOF InqData + check eax + jnz TryNextDrive + ;-------------------------------------------------------------------------- + mov byte ptr InqData[14], 0 + invoke lstrcmpi, ADDR szIomega, ADDR InqData[8] + check eax + jnz TryNextDrive + ;-------------------------------------------------------------------------- + mov byte ptr InqData[19], 0 + invoke lstrcmpi, ADDR szZip, ADDR InqData[16] + check eax + jz FoundZipOrJaz + ;-------------------------------------------------------------------------- + invoke lstrcmpi, ADDR szJaz, ADDR InqData[16] + check eax + jnz TryNextDrive + mov eax, JAZ_DRIVE + ;-------------------------------------------------------------------------- + ; check for ANSI SCSI to see whether we need to play + ; the Odd/Even password length game ... +FoundZipOrJaz: .IF !(byte ptr InqData[2] & 07h) + or eax, ODD_BYTE_COMPENSATION ; turn on compensation + .ENDIF + mov ebx, DriveCount + mov DriveArray[ebx*4], eax + movmov byte ptr DriveArray[ebx*4+0], al, byte ptr Adapter + movmov byte ptr DriveArray[ebx*4+1], al, byte ptr Device + inc ebx + mov DriveCount, ebx + cmp ebx, MAX_DRIVE_COUNT + jae Exit + ;-------------------------------------------------------------------------- +TryNextDrive: inc Device + .UNTIL (Device >= 16) + inc Adapter + mov eax, Adapter + .UNTIL (eax >= FirstInvalidAdapter) +;------------------------------------------------------------------------------- +ENDIF +Exit: .IF (!DriveCount) + set ErrorMode + .ENDIF + mov eax, DriveCount + ret +;------------------------------------------------------------------------------- +EnumerateIomegaDevices ENDP + + +;+-----------------------------------------------------------------------------+ +;| GET MODE PAGE | +;+-----------------------------------------------------------------------------+ +GetModePage PROC Adapter:DWORD, Device:DWORD, PageToGet:DWORD, pBuffer:PTR, BufLen:DWORD + LOCAL Scsi[6]:BYTE +;------------------------------------------------------------------------------- + varzero Scsi + mov Scsi, SCSI_Cmd_ModeSense + movmov Scsi[2], al, byte ptr PageToGet + movmov Scsi[4], al, byte ptr BufLen + invoke SCSICommand, Adapter, Device, ADDR Scsi, pBuffer, BufLen + ret +;------------------------------------------------------------------------------- +GetModePage ENDP + + +;+-----------------------------------------------------------------------------+ +;| SET MODE PAGE | +;+-----------------------------------------------------------------------------+ +SetModePage PROC USES ebx, Adapter:DWORD, Device:DWORD, pBuffer:PTR + LOCAL Scsi[6]:BYTE +;------------------------------------------------------------------------------- + varzero Scsi ; init the SCSI parameter block + mov ebx, pBuffer ; get a pointer to the top of buffer + movzx ecx, byte ptr [ebx] ; get the total length + inc ecx ; adjust it up by one + reset byte ptr [ebx] ; now clear the two reserved bytes + reset byte ptr [ebx+2] ; + mov Scsi, SCSI_Cmd_ModeSelect ; set the command + mov Scsi[1], 10h ; set the Page Format bit + mov Scsi[4], cl ; set the parameter list length + invoke SCSICommand, Adapter, Device, ADDR Scsi, pBuffer, ecx + ret +;------------------------------------------------------------------------------- +SetModePage ENDP + + +;+-----------------------------------------------------------------------------+ +;| SET ERROR RECOVERY | +;+-----------------------------------------------------------------------------+ +SetErrorRecovery PROC USES ebx, Retries:BOOL, ECC:BOOL, Testing:BOOL + LOCAL PageBuff[40]:BYTE +;------------------------------------------------------------------------------- + invoke GetModePage, CurrentAdapter, CurrentDevice, ERROR_RECOVERY_PAGE, ADDR PageBuff, SIZEOF PageBuff + lea ebx, PageBuff[4] ; get just past the header address + movzx eax, PageBuff[3] ; get the Block Descriptor Length + ; form ebx == the offset to the top of the page we've read ... + add ebx, eax + ; always turn off the PS bit (parameters savable) + and byte ptr [ebx], NOT 80h + ; set the ECC fields + mov al, 0C1h ; presume ECC suppression + .IF (ECC) + mov al, 0C8h ; enable ECC and Early Recovery + .IF (Testing) + mov al, 0CCh ; we're testing, so EER & PER + .ENDIF + .ENDIF + mov [ebx+2], al ; and set the value + ; set the retry counts + mov al, 16h ; set retries to 22 for Zip drive + .IF (JazDrive) + mov al, 64h ; and to 100 for Jaz drive + .ENDIF + .IF (!Retries) ; but if we have no retries ... + zero al ; then kill it. + .ENDIF + mov byte ptr [ebx+3], al ; set the common retry count + .IF (byte ptr [ebx+1] > 6) ; if we have a large format page ... + mov byte ptr [ebx+8], al ; then set the write count too + .ENDIF + invoke SetModePage, CurrentAdapter, CurrentDevice, ADDR PageBuff + + ; if we had an invalid field in the CDB (the EER bit was on) + .IF (eax == 00260005h) + invoke GetModePage, CurrentAdapter, CurrentDevice, ERROR_RECOVERY_PAGE, ADDR PageBuff, SIZEOF PageBuff + lea ebx, PageBuff[4] ; get just past the header address + movzx eax, PageBuff[3] ; get the Block Descriptor Length + ; form ebx == the offset to the top of the page we've read ... + add ebx, eax + ; always turn off the PS bit (parameters savable) + and byte ptr [ebx], NOT 80h + ; set the ECC fields + mov al, 0C1h ; presume ECC suppression + .IF (ECC) + mov al, 0C0h ; enable ECC *BUT*NOT* Early Recovery + .IF (Testing) + mov al, 0C4h ; we're testing, PER + .ENDIF + .ENDIF + mov [ebx+2], al ; and set the value + ; set the retry counts + mov al, 16h ; set retries to 22 for Zip drive + .IF (JazDrive) + mov al, 64h ; and to 100 for Jaz drive + .ENDIF + .IF (!Retries) ; but if we have no retries ... + zero al ; then kill it. + .ENDIF + mov byte ptr [ebx+3], al ; set the common retry count + .IF (byte ptr [ebx+1] > 6) ; if we have a large format page ... + mov byte ptr [ebx+8], al ; then set the write count too + .ENDIF + invoke SetModePage, CurrentAdapter, CurrentDevice, ADDR PageBuff + .ENDIF + ret +;------------------------------------------------------------------------------- +SetErrorRecovery ENDP + + +;------------------------------------------------------------------------------- +COMMENT ~ +;+-----------------------------------------------------------------------------+ +;| VENDOR SPECIFIC | +;+-----------------------------------------------------------------------------+ +VendorSpecific PROC USES ebx, EnableVS:BOOL + LOCAL PageBuff[40]:BYTE +;------------------------------------------------------------------------------- + invoke GetModePage, CurrentAdapter, CurrentDevice, MODES_OF_OPERATION, ADDR PageBuff, SIZEOF PageBuff + lea ebx, PageBuff[4] ; get just past the header address + movzx eax, PageBuff[3] ; get the Block Descriptor Length + add ebx, eax + ; now ebx has the offset to the top of the page we've read ... + .IF (EnableVS) + or byte ptr [ebx+2], 20h ; VSC + .ELSE + and byte ptr [ebx+2], NOT 20h ; turn off VSC bit + .ENDIF + and byte ptr [ebx], NOT 80h ; turn off the PS bit + invoke SetModePage, CurrentAdapter, CurrentDevice, ADDR PageBuff + ret +;------------------------------------------------------------------------------- +VendorSpecific ENDP + +;+-----------------------------------------------------------------------------+ +;| DISABLE CACHING | +;+-----------------------------------------------------------------------------+ +DisableCaching PROC USES ebx, Adapter:DWORD, Device:DWORD + LOCAL PageBuff[40]:BYTE +;------------------------------------------------------------------------------- + invoke GetModePage, Adapter, Device, CACHING_PAGE, ADDR PageBuff, SIZEOF PageBuff + lea ebx, PageBuff[4] ; get just past the header address + movzx eax, PageBuff[3] ; get the Block Descriptor Length + add ebx, eax + ; now ebx has the offset to the top of the page we've read ... + mov byte ptr [ebx+2], 1 ; disable all caching + invoke SetModePage, Adapter, Device, ADDR PageBuff + ret +;------------------------------------------------------------------------------- +DisableCaching ENDP +;------------------------------------------------------------------------------- +COMMENT ~ +;------------------------------------------------------------------------------- + + +;+-----------------------------------------------------------------------------+ +;| GET NON-SENSE PAGE DATA | +;|-----------------------------------------------------------------------------| +;| Given Adapter, Device, DataPage, and a Buffer to receive the data, this | +;| fills the buffer we're given and returns with the SCSI Completion Code | +;+-----------------------------------------------------------------------------+ +GetNonSenseData PROC Adapter:DWORD, Device:DWORD, DataPage:DWORD, Buffer:DWORD, BufLen:DWORD + LOCAL Scsi[6]:BYTE +;------------------------------------------------------------------------------- + varzero Scsi + mov Scsi, SCSI_Cmd_NonSenseData ; do a Non-Sense Data Read + movmov Scsi[2], al, byte ptr DataPage ; which page to read + movmov Scsi[4], al, byte ptr BufLen ; tell drive page is this long + invoke SCSICommand, Adapter, Device, ADDR Scsi, Buffer, BufLen + ret +;------------------------------------------------------------------------------- +GetNonSenseData ENDP + + +;+-----------------------------------------------------------------------------+ +;| UNLOCK ALL MEDIA | +;+-----------------------------------------------------------------------------+ +UnlockAllMedia PROC USES esi ebx + LOCAL DrivesLeft:DWORD, Scsi[6]:BYTE +;------------------------------------------------------------------------------- + ; make sure the media is not locked as we exit ... + varzero Scsi + mov Scsi, SCSI_Cmd_PreventAllow + ; setup the SCSI command block for the operation + movmov DrivesLeft, eax, DriveCount + .IF (eax) + mov esi, OFFSET DriveArray + .REPEAT + movzx ebx, byte ptr [esi] ; pickup the Adapter + movzx ecx, byte ptr [esi+1] ; pickup the DeviceID + invoke SCSICommand, ebx, ecx, ADDR Scsi, NULL, 0 + add esi, SIZEOF DWORD + dec DrivesLeft + .UNTIL (zero?) + .ENDIF + ret +;------------------------------------------------------------------------------- +UnlockAllMedia ENDP + + +;+-----------------------------------------------------------------------------+ +;| LOCK CURRENT DRIVE | +;+-----------------------------------------------------------------------------+ +LockCurrentDrive PROC + LOCAL Scsi[6]:BYTE +;------------------------------------------------------------------------------- + ; lock the media to prevent its ejection + varzero Scsi + mov Scsi, SCSI_Cmd_PreventAllow + mov Scsi[4], 1 ; set to ONE to lock the drive + invoke SCSICommand, CurrentAdapter, CurrentDevice, ADDR Scsi, NULL, 0 + ret +;------------------------------------------------------------------------------- +LockCurrentDrive ENDP + + +;+-----------------------------------------------------------------------------+ +;| SPIN UP IOMEGA CARTRIDGE | +;+-----------------------------------------------------------------------------+ +SpinUpIomegaCartridge PROC Adapter:DWORD, Device:DWORD + LOCAL Scsi[6]:BYTE +;------------------------------------------------------------------------------- + ; issue an Asynchronous START command to induce spinup + varzero Scsi + mov Scsi[0], SCSI_Cmd_StartStopUnit + mov Scsi[1], 1 ; set the IMMED bit for offline + mov Scsi[4], 1 ; start the disk spinning + invoke SCSICommand, Adapter, Device, ADDR Scsi, NULL, 0 + ret +;------------------------------------------------------------------------------- +SpinUpIomegaCartridge ENDP + + +;+-----------------------------------------------------------------------------+ +;| EJECT ALL MEDIA | +;+-----------------------------------------------------------------------------+ +EjectAllMedia PROC USES esi ebx + LOCAL DrivesLeft:DWORD +;------------------------------------------------------------------------------- + ; setup the SCSI command block for the operation + movmov DrivesLeft, eax, DriveCount + .IF (eax) + mov esi, OFFSET DriveArray + .REPEAT + movzx eax, byte ptr [esi] ; pickup the Adapter + movzx ebx, byte ptr [esi+1] ; pickup the DeviceID + invoke EjectIomegaCartridge, eax, ebx + add esi, SIZEOF DWORD + dec DrivesLeft + .UNTIL (zero?) + .ENDIF + ret +;------------------------------------------------------------------------------- +EjectAllMedia ENDP + + +;+-----------------------------------------------------------------------------+ +;| GET SPARE SECTOR COUNTS | +;|-----------------------------------------------------------------------------| +;| This returns NON-ZERO if we have trouble and posted the error message | +;| into the RichText control, else it sets the number of spares available | +;+-----------------------------------------------------------------------------+ +GetSpareSectorCounts PROC USES ebx, CheckPassword:BOOL + LOCAL Scsi[10]:BYTE, DefectHeader:DEFECT_LIST_HEADER, DiskStat[72]:BYTE +;------------------------------------------------------------------------------- + ; ask for the defect list to make sure we're able to read it +ListChk:varzero Scsi + mov Scsi[0], SCSI_Cmd_ReadDefectData + mov Scsi[2], 00011110b ; defect format, G/P bits + mov Scsi[8], 4 ; ask for only FOUR bytes + invoke SCSICommand, CurrentAdapter, CurrentDevice, ADDR Scsi, ADDR DefectHeader, SIZEOF DefectHeader + .IF (!eax) || (eax == INCOMPATIBLE_MEDIA) + ; we could read its defect list ... so show it! + invoke GetNonSenseData, CurrentAdapter, CurrentDevice, DISK_STATUS_PAGE, ADDR DiskStat, SIZEOF DiskStat + check eax + jnz ListChk + ;-------------------------------------------------------------------------- + zero ch ; clear the DRIVE_A_SUPPORT + .IF (JazDrive) + movzx eax, word ptr DiskStat[JAZ_SPARES_COUNT_OFFSET] + zero ebx + mov cl, DiskStat[JAZ_PROTECT_MODE_OFFSET] + mov edx, dword ptr DiskStat[JAZ_LAST_LBA_OFFSET] + .ELSE + .IF (DiskStat == DISK_STATUS_PAGE) + movzx eax, word ptr DiskStat[NEW_ZIP_SIDE_0_SPARES_COUNT_OFFSET] + movzx ebx, word ptr DiskStat[NEW_ZIP_SIDE_1_SPARES_COUNT_OFFSET] + mov cl, DiskStat[NEW_ZIP_PROTECT_MODE_OFFSET] + mov edx, dword ptr DiskStat[NEW_ZIP_LAST_LBA_OFFSET] + dec ch ; set the DRIVE_A_SUPPORT + .ELSE + movzx eax, word ptr DiskStat[OLD_ZIP_SIDE_0_SPARES_COUNT_OFFSET] + movzx ebx, word ptr DiskStat[OLD_ZIP_SIDE_1_SPARES_COUNT_OFFSET] + mov cl, DiskStat[OLD_ZIP_PROTECT_MODE_OFFSET] + mov edx, dword ptr DiskStat[OLD_ZIP_LAST_LBA_OFFSET] + .ENDIF + check ebx + jz NoSpares + .ENDIF + ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +; bswap edx ; save the last LBA in any event + ror edx, 8 ; [dabc] + swap dh, dl ; [dacb] + ror edx, 16 ; [cbda] + swap dh, dl ; [cbad] + ror edx, 8 ; [dcba] + ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + .IF (ch) + sub edx, DRIVE_A_SUPPORT_BIAS + .ENDIF + mov LastLBAOnCartridge, edx + swap al, ah ; make it little endian + mov Side_0_SparesCount, eax + swap bl, bh ; make it little endian + mov Side_1_SparesCount, ebx + ; compute the number of troubles we encountered during the testing + push eax + mov eax, Initial_Side_0_Spares + sub eax, Side_0_SparesCount + add eax, Initial_Side_1_Spares + sub eax, Side_1_SparesCount + mov FirmErrors, eax + pop eax + ; check to see whether we have ANY spare sectors remaining + .IF (!eax) +NoSpares: mov CartridgeStatus, DISK_TEST_FAILURE + mov eax, OFFSET szNoSpares + ; if were running give them a different error message + .IF (TestingPhase) + mov eax, OFFSET szOutOfSpares + .ENDIF + invoke SetRichEditText, ADDR hTabText, eax + jmp ErrorExit + .ENDIF + ; now let's checkout the cartridge's protection mode ... + .IF (cl & 07h) && (!(cl & 08h)) && CheckPassword ; if we have some protection mode + ; if it's simply WRITE protected ... disable that ... + .IF (cl == 2) + invoke MessageBox, hMainWnd, ADDR szDisablingWPText, ADDR szDisablingWPTitle, MB_APPLMODAL or MB_OK + mov CartridgePassword, 0 ; set pswd to null + jmp TempDisablePswd + .ENDIF + ; we need a password from the operator ... + invoke DialogBoxParam, hInst, ADDR szAppName, hMainWnd, ADDR PasswordWndProc, 0 + .IF (eax) +TempDisablePswd: invoke GetDriveEntryOffset, CurrentAdapter, CurrentDevice + push eax ; save the table entry + varzero Scsi + mov Scsi, SCSI_Cmd_CartProtect + mov Scsi[1], 08h ; request temporary unlock mode + invoke lstrlen, ADDR CartridgePassword + mov Scsi[4], al ; set THIS to the true transfer length + pop ebx ; recover the entry offset + .IF (dword ptr [ebx] & ODD_BYTE_COMPENSATION) && (al & 1) ; if password is ODD + or Scsi[1], 10h ; set the WA bit! + inc eax ; and round it up! + .ENDIF + invoke SCSICommand, CurrentAdapter, CurrentDevice, ADDR Scsi, ADDR CartridgePassword, eax + .IF (eax == SCSI_CMD_TIMED_OUT) + invoke MessageBox, hMainWnd, ADDR szCantUnlockText, ADDR szCantUnlockTitle, MB_APPLMODAL or MB_OK + jmp StillLocked + .ENDIF + jmp ListChk + .ENDIF +StillLocked: mov CartridgeStatus, DISK_PROTECTED + invoke SetRichEditText, ADDR hTabText, ADDR szLocked + jmp ErrorExit + .ENDIF + zero eax ; return zero since no error + ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + .ELSE ; trouble of some sort ... so suppress controls and + ; show the richedit control for the trouble + .IF (eax == DEFECT_LIST_READ_ERROR) + mov CartridgeStatus, DISK_Z_TRACK_FAILURE + invoke SetRichEditText, ADDR hTabText, ADDR szDefectList +ErrorExit: zero eax + dec eax ; return NON-ZERO since we have an error! + .ELSEIF (eax == MEDIA_NOT_PRESENT) + mov CartridgeStatus, DISK_NOT_PRESENT +IF DEVELOPMENT +; .ELSE +; invoke PostToScreen, eax +ENDIF + .ENDIF + .ENDIF +Exit: ret +;------------------------------------------------------------------------------- +GetSpareSectorCounts ENDP + + +;+-----------------------------------------------------------------------------+ +;| HANDLE DRIVE CHANGING | +;|-----------------------------------------------------------------------------| +;| If we're NOT in the middle of drive testing, check for any new drives | +;| going ready, eject all others, and Select the newer drive. | +;| If we *ARE* in the middle of drive testing, EJECT any new drive that's | +;| attempting to go ready. | +;+-----------------------------------------------------------------------------+ +HandleDriveChanging PROC USES esi edi ebx + LOCAL DrivesLeft:DWORD, DiskStat[72]:BYTE, Selecting:BOOL, TroubleFlag:DWORD, PriorStatus:DWORD +;------------------------------------------------------------------------------- + test hASPIDLL, -1 ; don't do ANYTHING if we didn't find + jz Exit ; the required ASPI goodies in the system + ;-------------------------------------------------------------------------- + reset Selecting ; true while we're changing selections +Rescan: movmov DrivesLeft, eax, DriveCount + check eax + jz Exit + ;-------------------------------------------------------------------------- + mov esi, OFFSET DriveArray + .REPEAT ; query the current state of the drive + .REPEAT ; clear media changed status + and dword ptr [esi], NOT MEDIA_CHANGED + movzx ebx, byte ptr [esi] ; pickup the Adapter + movzx ecx, byte ptr [esi+1] ; pickup the DeviceID + invoke GetNonSenseData, ebx, ecx, DISK_STATUS_PAGE, ADDR DiskStat, SIZEOF DiskStat + .UNTIL !(dword ptr [esi] & MEDIA_CHANGED) ; do it until NO media change! + ;-------------------------------------------------------------------------- + .IF (DiskStat == DISK_STATUS_PAGE) + movzx eax, DiskStat[NEW_DISK_STATUS_OFFSET] + .ELSE + movzx eax, DiskStat[OLD_DISK_STATUS_OFFSET] + .ENDIF + ; if the device we have is NOT the currently selected one + movzx ebx, byte ptr [esi] ; pickup the Adapter + movzx ecx, byte ptr [esi+1] ; pickup the DeviceID + .IF (ebx != CurrentAdapter) || (ecx != CurrentDevice) + ; if the disk is ANYTHING other than not present ... + .IF (al != DISK_NOT_PRESENT) + ; we have a PRESENT DISK in a non-current drive + ; if we're testing, reject it + .IF (Selecting) || (TestingPhase >= TESTING_STARTUP) + invoke EjectIomegaCartridge, ebx, ecx + ; flag that we're waiting for spindown + or dword ptr [esi], DISK_EJECTING + ; if we're not testing, and not awaiting eject + ; then set the current drive ... + .ELSEIF !(dword ptr [esi] & DISK_EJECTING) + mov CurrentAdapter, ebx + mov CurrentDevice, ecx + reset TestingPhase ; show idle + set Selecting + jmp Rescan + ; the PREVIOUS drive (if any) will be ejected on the next pass + .ENDIF + .ELSE ; the drive HAS spun down, so clear "waiting" + and dword ptr [esi], NOT DISK_EJECTING + .ENDIF + .ELSE ; we're checking the current drive ... make SURE that + ; it is *NOT* empty! If it *IS* empty, kill current + .IF (al == DISK_NOT_PRESENT) + mov CurrentAdapter, -1 + mov CurrentDevice, -1 + call SetCartridgeStatusToEAX + .ENDIF + ; if it's not already set correctly *and* either + ; the cart status is one of the pre-test ones, or + ; the NEW status from the cart is NOT "at speed" ... + .IF (eax != CartridgeStatus) && ((CartridgeStatus <= DISK_STALLED) || (eax != DISK_AT_SPEED)) + call SetCartridgeStatusToEAX + .ENDIF + .ENDIF + add esi, SIZEOF DWORD + dec DrivesLeft + .UNTIL (zero?) + ; if nothing was chosen ... set us to "Awaiting Cartridge" status + .IF (CurrentAdapter == (-1)) && (CurrentDevice == (-1)) && (al == DISK_NOT_PRESENT) && (CartridgeStatus != DISK_NOT_PRESENT) + call SetCartridgeStatusToEAX + .ENDIF +Exit: ret + +;=============================================================================== +SetCartridgeStatusToEAX: +;------------------------------------------------------------------------------- + reset JazDrive + .IF (dword ptr [esi] & JAZ_DRIVE) + set JazDrive + .ENDIF + push eax + push esi + reset TroubleFlag ; presume everything's okay + movmov PriorStatus, ebx, CartridgeStatus + mov CartridgeStatus, eax + + ; set the text of the "action initiate button" + .IF (CartridgeStatus == DISK_SPUN_DOWN) + ; set the button to "Start Disk Spinning" + mov esi, OFFSET szPressToSpin + + .ELSEIF (CartridgeStatus == DISK_TEST_UNDERWAY) + ; set the button to "Stop Testing" + mov esi, OFFSET szPressToStop + + .ELSEIF (CartridgeStatus == DISK_NOT_PRESENT) +Ejecting: invoke SetRichEditText, ADDR hTabText, ADDR szNotRunning + jmp DisableActions + + .ELSEIF (CartridgeStatus == DISK_AT_SPEED) + invoke GetSpareSectorCounts, TRUE ; update the Cart Condition + cmp eax, MEDIA_NOT_PRESENT + je Ejecting + ;-------------------------------------------------------------------------- + mov TroubleFlag, eax ; decide whether we're in trouble + mov esi, OFFSET szPressToEject ; presume trouble + .IF (!eax) + movmov Initial_Side_0_Spares, eax, Side_0_SparesCount + movmov Initial_Side_1_Spares, eax, Side_1_SparesCount + reset FirmErrors + ; check to see if we have enough spares to start + .IF (JazDrive) + cmp Side_0_SparesCount, MINIMUM_JAZ_SPARES + jb InsufficientSpares + .ELSE + cmp Side_0_SparesCount, MINIMUM_ZIP_SPARES + jb InsufficientSpares + .IF (Side_1_SparesCount < MINIMUM_ZIP_SPARES) +InsufficientSpares: invoke SetRichEditText, ADDR hTabText, ADDR szFewSpares + mov CartridgeStatus, DISK_LOW_SPARES + set TroubleFlag ; show the richedit control + mov esi, OFFSET szPressToProceed + jmp EnableTestBtn + .ENDIF + .ENDIF + ; if no trouble, get ready to start testing ... + call PrepareToBeginTesting + mov esi, OFFSET szPressToStart + .ENDIF + ; the disk *IS* at speed so enable the action button! +EnableTestBtn: invoke EnableWindow, hTestButton, TRUE + .IF (eax) + mov ActionButtonFlasher, FLASH_COUNT + invoke SetFocus, hTestButton + .ENDIF + + .ELSE ; set the button to "One Moment Please" + +DisableActions: invoke EnableWindow, hTestButton, FALSE + mov esi, OFFSET szOneMoment + + .ENDIF + ; set the Window's text based upon setting of esi + invoke SetWindowText, hTestButton, esi + ; based upon the TroubleFlag, show them the proper page set + invoke SetTabErrorMode, TroubleFlag + ; and if CartridgeStatus has changed, refresh the entire panel! + .IF (CurrentPage == PERFORM_TEST_PAGE) + zero ecx + .IF (PriorStatus == DISK_AT_SPEED) || (PriorStatus == DISK_SPUN_DOWN) || (PriorStatus >= DISK_LOW_SPARES) + not ecx + .ENDIF + .IF (CartridgeStatus == DISK_AT_SPEED) || (CartridgeStatus >= DISK_LOW_SPARES) + not ecx + .ENDIF + .IF (ecx) ; update the entire panel's data + invoke InvalidateRect, hTestMonitor, NULL, FALSE + .ELSE ; only paint the new cartridge status + invoke GetDC, hTestMonitor + mov edi, eax + invoke PaintCartStatus, edi + invoke ReleaseDC, hTestMonitor, edi + .ENDIF + ; auto change to the first tab when changing disks. +; .ELSEIF (CurrentPage == EXPLAIN_RESULTS) +; .IF (ebx == DISK_NOT_PRESENT) || (eax == DISK_NOT_PRESENT) +; invoke SendMessage, hActionTabs, TCM_SETCURSEL, 0, NULL +; .IF (eax) +; mov CurrentPage, PERFORM_TEST_PAGE +; mov ActionsSubPage, PERFORM_TEST_PAGE +; call SetCurrentWindow +; .ENDIF +; .ENDIF + .ENDIF +;------------------------------------------------------------------------------- + pop esi + pop eax + LocalReturn + +;------------------------------------------------------------------------------- +HandleDriveChanging ENDP + + +;+-----------------------------------------------------------------------------+ +;| GET ELAPSED TIME IN SECONDS | +;| Returns seconds elapsed, or -1 if we could not determine it | +;+-----------------------------------------------------------------------------+ +GetElapsedTimeInSeconds PROC USES ebx + LOCAL CurrentInstant:FILETIME +;------------------------------------------------------------------------------- + invoke GetSystemTimeAsFileTime, ADDR CurrentInstant + mov eax, dword ptr CurrentInstant + mov edx, dword ptr CurrentInstant[4] + sub eax, dword ptr StartingInstant + sbb edx, dword ptr StartingInstant[4] + mov ebx, FILE_TIME_TICKS_PER_SECOND + ; verify that the result won't overflow + .IF (edx < ebx) + roundiv ebx + .ELSE + mov eax, -1 + .ENDIF + ret +;------------------------------------------------------------------------------- +GetElapsedTimeInSeconds ENDP + + +;+-----------------------------------------------------------------------------+ +;| PREPARE TO BEGIN TESTING | +;+-----------------------------------------------------------------------------+ +PrepareToBeginTesting PROC +;------------------------------------------------------------------------------- + ; zero all of the testing variables + zero eax + mov ecx, TESTING_VARIABLE_COUNT + mov edi, OFFSET FirstTestingVariable + rep stosd + ; catch up the initial spares + movmov Initial_Side_0_Spares, eax, Side_0_SparesCount + movmov Initial_Side_1_Spares, eax, Side_1_SparesCount + reset FirmErrors + ; set the flag to enable the "test" button to call "TestTheDisk" + mov TestingPhase, READY_TO_TEST + ret +;------------------------------------------------------------------------------- +PrepareToBeginTesting ENDP + + +;+-----------------------------------------------------------------------------+ +;| BUMP ERROR COUNTS | +;+-----------------------------------------------------------------------------+ +BumpErrorCounts PROC USES ebx, ErrorCode:DWORD +;------------------------------------------------------------------------------- + mov eax, ErrorCode ; get the error code +IF DEVELOPMENT + invoke PostToScreen, eax +ENDIF + .IF (eax == BUFFER_TOO_BIG) ; if we got BUFFER TOO BIG, halt! + set UserInterrupt + .ENDIF + mov ebx, eax + and ebx, 00FF00FFh ; mask off the middle byte + .IF (ebx == 00150004h) ; if it was one of the many seek + mov eax, ebx ; errors, cvrt to seek error + .ENDIF + .IF (eax) + mov LastError, eax + .ENDIF + .IF (eax == 320003h) || (eax == 328F03h) + mov CartridgeStatus, DISK_LOW_SPARES + .ENDIF + .IF (al == 1) ; recovered error + inc SoftErrors + .ELSE + inc HardErrors + .ENDIF + ret +;------------------------------------------------------------------------------- +BumpErrorCounts ENDP + + +;+-----------------------------------------------------------------------------+ +;| READ SECTORS | +;+-----------------------------------------------------------------------------+ +ReadSectors PROC pBuffer:LPSTR, LBAtoRead:DWORD, LBACount:DWORD + LOCAL Scsi[10]:BYTE +;------------------------------------------------------------------------------- + varzero Scsi + mov Scsi, SCSI_Cmd_ReadMany + mov eax, LBAtoRead + ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +; bswap eax ; [abcd] ; convert it into BIG endian format + ror eax, 8 ; [dabc] + swap ah, al ; [dacb] + ror eax, 16 ; [cbda] + swap ah, al ; [cbad] + ror eax, 8 ; [dcba] + ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + mov dword ptr Scsi[2], eax + mov eax, LBACount ; and the NUMBER of LBA's to read + swap ah, al ; convert it into BIG endian format + mov word ptr Scsi[7], ax + swap ah, al + shl eax, LOG2_BYTES_PER_SECTOR + invoke SCSICommand, CurrentAdapter, CurrentDevice, ADDR Scsi, pBuffer, eax + ret +;------------------------------------------------------------------------------- +ReadSectors ENDP + + +;+-----------------------------------------------------------------------------+ +;| WRITE SECTORS | +;+-----------------------------------------------------------------------------+ +WriteSectors PROC pBuffer:LPSTR, LBAtoWrite:DWORD, LBACount:DWORD + LOCAL Scsi[10]:BYTE +;------------------------------------------------------------------------------- + varzero Scsi + mov Scsi, SCSI_Cmd_WriteMany + mov eax, LBAtoWrite + ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +; bswap eax ; [abcd] ; convert it into BIG endian format + ror eax, 8 ; [dabc] + swap ah, al ; [dacb] + ror eax, 16 ; [cbda] + swap ah, al ; [cbad] + ror eax, 8 ; [dcba] + ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + mov dword ptr Scsi[2], eax + mov eax, LBACount ; and the NUMBER of LBA's to read + swap ah, al ; convert it into BIG endian format + mov word ptr Scsi[7], ax + swap ah, al + shl eax, LOG2_BYTES_PER_SECTOR + invoke SCSICommand, CurrentAdapter, CurrentDevice, ADDR Scsi, pBuffer, eax + ret +;------------------------------------------------------------------------------- +WriteSectors ENDP + + +;-/////////////////////////////////////////////////////////////////////////////- +IF COPY_BUTTON_DAMAGES +;-/////////////////////////////////////////////////////////////////////////////- + +LONG_IO_XFER equ 564 ; (512+52) for Zip drives +; LONG_IO_XFER equ 550 ; (512+38) for Jaz drives + +FIRST_SECTOR_TO_HURT equ 2246 +LAST_SECTOR_TO_HURT equ 100000 +SECTOR_HURT_SPACING equ 527 + + +;+-----------------------------------------------------------------------------+ +;| READ SECTOR LONG | +;+-----------------------------------------------------------------------------+ +ReadSectorLong PROC pBuffer:LPSTR, LBAtoRead:DWORD + LOCAL Scsi[10]:BYTE +;------------------------------------------------------------------------------- + varzero Scsi + mov Scsi, SCSI_Cmd_ReadLong + mov eax, LBAtoRead + ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +; bswap eax ; convert it into BIG endian format + ror eax, 8 ; [dabc] + swap ah, al ; [dacb] + ror eax, 16 ; [cbda] + swap ah, al ; [cbad] + ror eax, 8 ; [dcba] + ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + mov dword ptr Scsi[2], eax + mov ax, LONG_IO_XFER + swap ah, al + mov word ptr Scsi[7], ax ; read LONG number of bytes + invoke SCSICommand, CurrentAdapter, CurrentDevice, ADDR Scsi, pBuffer, LONG_IO_XFER + ret +;------------------------------------------------------------------------------- +ReadSectorLong ENDP + + +;+-----------------------------------------------------------------------------+ +;| WRITE SECTOR LONG | +;+-----------------------------------------------------------------------------+ +WriteSectorLong PROC LBAtoWrite:DWORD, pBuffer:LPSTR + LOCAL Scsi[10]:BYTE +;------------------------------------------------------------------------------- + varzero Scsi + mov Scsi, SCSI_Cmd_WriteLong + mov eax, LBAtoWrite + ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +; bswap eax ; convert it into BIG endian format + ror eax, 8 ; [dabc] + swap ah, al ; [dacb] + ror eax, 16 ; [cbda] + swap ah, al ; [cbad] + ror eax, 8 ; [dcba] + ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + mov dword ptr Scsi[2], eax + mov ax, LONG_IO_XFER + swap ah, al + mov word ptr Scsi[7], ax ; read LONG number of bytes + invoke SCSICommand, CurrentAdapter, CurrentDevice, ADDR Scsi, pBuffer, LONG_IO_XFER + ret +;------------------------------------------------------------------------------- +WriteSectorLong ENDP + + +;+-----------------------------------------------------------------------------+ +;| DAMAGE THE DISK | +;+-----------------------------------------------------------------------------+ +DamageTheDisk PROC USES esi edi + LOCAL IOBuffer[LONG_IO_XFER]:BYTE +;------------------------------------------------------------------------------- + mov esi, FIRST_SECTOR_TO_HURT + .WHILE (esi <= LAST_SECTOR_TO_HURT) + + ; first we repair any prior damage + invoke ReadSectorLong, ADDR IOBuffer, esi + invoke WriteSector, esi, ADDR IOBuffer + invoke ReadSectorLong, ADDR IOBuffer, esi + + ; zap the buffer + lea edi, IOBuffer + xor dword ptr [edi + 100], 0FFFFFFFFh + xor dword ptr [edi + 104], 0FFFFFFFFh + xor dword ptr [edi + 108], 0FFFFFFFFh + xor dword ptr [edi + 112], 0FFFFFFFFh + xor dword ptr [edi + 116], 0FFFFFFFFh + xor dword ptr [edi + 120], 0FFFFFFFFh + xor dword ptr [edi + 124], 0FFFFFFFFh + xor dword ptr [edi + 128], 0FFFFFFFFh + xor dword ptr [edi + 132], 0FFFFFFFFh + xor dword ptr [edi + 136], 0FFFFFFFFh + + invoke WriteSectorLong, esi, ADDR IOBuffer + +; invoke ReadSector, ADDR IOBuffer, esi + + add esi, SECTOR_HURT_SPACING + .ENDW + ret +;------------------------------------------------------------------------------- +DamageTheDisk ENDP + +;-/////////////////////////////////////////////////////////////////////////////- +ENDIF +;-/////////////////////////////////////////////////////////////////////////////- + +;+-----------------------------------------------------------------------------+ +;| OPEN DRIVE ACCESS | +;|-----------------------------------------------------------------------------| +;| Returns TRUE on success | +;+-----------------------------------------------------------------------------+ +OpenDriveAccess PROC DriveNumber:DWORD +;------------------------------------------------------------------------------- + invoke SetErrorMode, SEM_FAILCRITICALERRORS + push eax ; stack the original error mode ... + ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + mov eax, DriveNumber + inc eax + mov OneBasedDrive, eax + add al, 'A'-1 ; cvrt 0-based drive into capital letter + mov DriveLetter, al + mov DriveRootName, al + .IF (WinNT) + invoke CreateFile, ADDR DiskDrive, GENERIC_READ or GENERIC_WRITE, + FILE_SHARE_READ or FILE_SHARE_WRITE, NULL, OPEN_EXISTING, + FILE_FLAG_WRITE_THROUGH or FILE_FLAG_NO_BUFFERING, NULL + .ELSE + invoke CreateFile, ADDR SystemVXD, GENERIC_READ or GENERIC_WRITE, + FILE_SHARE_READ or FILE_SHARE_WRITE, NULL, OPEN_EXISTING, + FILE_FLAG_WRITE_THROUGH or FILE_FLAG_NO_BUFFERING, NULL + .ENDIF + mov hDriveAccess, eax + call SetErrorMode ; restore the original error mode ... + mov eax, hDriveAccess + .IF (eax == INVALID_HANDLE_VALUE) + zero eax + .ENDIF + ret +;------------------------------------------------------------------------------- +OpenDriveAccess ENDP + + +;+-----------------------------------------------------------------------------+ +;| CLOSE DRIVE ACCESS | +;+-----------------------------------------------------------------------------+ +CloseDriveAccess PROC +;------------------------------------------------------------------------------- + mov eax, hDriveAccess + .IF (eax) + invoke CloseHandle, eax + .ENDIF + ret +;------------------------------------------------------------------------------- +CloseDriveAccess ENDP + + +;+-----------------------------------------------------------------------------+ +;| PERFORM DEVICE IO | +;|-----------------------------------------------------------------------------| +;| Returns ZERO on success, and ERROR CODE on failure | +;+-----------------------------------------------------------------------------+ +Win95DeviceIO PROC USES esi, _eax:DWORD, _ebx:DWORD, _ecx:DWORD, _edx:DWORD, _esi:DWORD, _edi:DWORD + LOCAL Registers:DEVIOCTL_REGISTERS, BytesReturned:DWORD +;------------------------------------------------------------------------------- + movmov Registers.reg_EAX, eax, _eax + .IF (ah == 44h) + mov esi, VWIN32_DIOC_DOS_IOCTL ; (1) + .ELSEIF (ah == 25h) + mov esi, VWIN32_DIOC_DOS_INT25 ; (2) + .ELSEIF (ah == 26h) + mov esi, VWIN32_DIOC_DOS_INT26 ; (3) + .ELSEIF (ah == 73h) + mov esi, VWIN32_DIOC_DOS_DRIVEINFO ; (6) + .ELSE + zero eax + jmp Exit + .ENDIF + movmov Registers.reg_EBX, eax, _ebx + movmov Registers.reg_ECX, eax, _ecx + movmov Registers.reg_EDX, eax, _edx + movmov Registers.reg_ESI, eax, _esi + movmov Registers.reg_EDI, eax, _edi + mov Registers.reg_Flags, 1 ; preset the carry + invoke DeviceIoControl, hDriveAccess, esi, ; non-zero on success + ADDR Registers, SIZEOF DEVIOCTL_REGISTERS, + ADDR Registers, SIZEOF DEVIOCTL_REGISTERS, + ADDR BytesReturned, NULL + .IF (eax) + ; DeviceIoControl succeeded, but what about the called func? + zero eax ; presume success (no carry set) + .IF (Registers.reg_Flags & 1) + ; return was CY=1, so return the function's error val + mov eax, Registers.reg_EAX + .ENDIF + .ELSE + ; DeviceIoControl failed, so return -1 + mov eax, -1 + .ENDIF +Exit: ret +;------------------------------------------------------------------------------- +Win95DeviceIO ENDP + + +;+-----------------------------------------------------------------------------+ +;| QUALIFY DRIVE | +;|-----------------------------------------------------------------------------| +;| Returns TRUE if this drive might be a Local Removable Iomega | +;+-----------------------------------------------------------------------------+ +QualifyDrive PROC + LOCAL BytesReceived:DWORD, DriveMapInfo:DRIVE_MAP_INFO, MediaID:MEDIA_ID, + DiskGeometry:DISK_GEOMETRY, PartitionInfo:PARTITION_INFORMATION +;------------------------------------------------------------------------------- + ; ask Windows what it knows about the drive + invoke GetDriveType, ADDR DriveRootName + cmp eax, DRIVE_REMOVABLE ; if it's NOT removable or FIXED + jb Disqualify ; then we're out of the game. + cmp eax, DRIVE_FIXED ; but it COULD be removable MASQUERADING + ja Disqualify ; as fixed ... so we need to check that! + ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + ; Windows says it's fixed or removable ... let's look closer ... + .IF (WinNT) + ; check to see if the media is accessible + invoke DeviceIoControl, hDriveAccess, IOCTL_STORAGE_CHECK_VERIFY, + NULL, 0, NULL, 0, ADDR BytesReceived, NULL + check eax ; returns FALSE if it's NOT accessible + jz Exit + ;-------------------------------------------------------------------------- + invoke DeviceIoControl, hDriveAccess, IOCTL_DISK_GET_DRIVE_GEOMETRY, + NULL, 0, ADDR DiskGeometry, SIZEOF DiskGeometry, ADDR BytesReceived, NULL + mov eax, DiskGeometry.MediaType + cmp eax, RemovableMedia + jne Disqualify + ;-------------------------------------------------------------------------- + invoke DeviceIoControl, hDriveAccess, IOCTL_DISK_GET_PARTITION_INFO, + NULL, 0, ADDR DiskGeometry, SIZEOF PartitionInfo, ADDR PartitionInfo, NULL + movmov PartitionOffset, eax, dword ptr PartitionInfo.StartingOffset + .ELSE + ; look more closely at a status that ISN'T foolable + mov DriveMapInfo.dmiAllocationLength, SIZEOF DRIVE_MAP_INFO + invoke Win95DeviceIO, 440Dh, OneBasedDrive, 086Fh, ADDR DriveMapInfo,0,0 + check eax ; returns an error code if the call failed + jnz Disqualify + movmov PartitionOffset, ecx, dword ptr DriveMapInfo.dmiPartitionStartRBA + ;-------------------------------------------------------------------------- + ; we found a drive, so see if it supports EJECT! + ; if not if can't be an IOMEGA removable drive + .IF (DriveMapInfo.dmiFlags & PROT_MODE_EJECT) + ; yes, now can we read its MediaID ?? + invoke Win95DeviceIO, 440Dh, OneBasedDrive, 0866h, ADDR MediaID,0,0 + .IF (eax) + ; MediaID failed, so fail our function +Disqualify: zero eax + .ELSE + ; this looks like a PERFECT candidate ... + dec eax ; set EAX to -1 for success! + .ENDIF + .ENDIF + .ENDIF +Exit: ret +;------------------------------------------------------------------------------- +QualifyDrive ENDP + + +;+-----------------------------------------------------------------------------+ +;| EXCLUSIVE ACCESS | +;|-----------------------------------------------------------------------------| +;| Returns TRUE for Success | +;+-----------------------------------------------------------------------------+ +ExclusiveAccess PROC DriveNumber:DWORD, Exclusive:BOOL + LOCAL BytesReceived +;------------------------------------------------------------------------------- +.IF (DriveNumber != (-1)) + .IF (Exclusive) + invoke OpenDriveAccess, DriveNumber + .IF (WinNT) + invoke DeviceIoControl, hDriveAccess, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, ADDR BytesReceived, NULL + .ELSE + invoke Win95DeviceIO, 440Dh, OneBasedDrive, 084Ah, 0,0,0 + .IF (eax) + ; MediaID failed, so fail our function + zero eax + .ELSE + ; this looks like a PERFECT candidate ... + dec eax ; set EAX to -1 for success! + .ENDIF + .ENDIF + .ELSE + .IF (WinNT) + invoke DeviceIoControl, hDriveAccess, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, ADDR BytesReceived, NULL + .ELSE + invoke Win95DeviceIO, 440Dh, OneBasedDrive, 086Ah, 0,0,0 + .IF (eax) + ; MediaID failed, so fail our function + zero eax + .ELSE + ; this looks like a PERFECT candidate ... + dec eax ; set EAX to -1 for success! + .ENDIF + .ENDIF + push eax + call CloseDriveAccess + pop eax + .ENDIF +.ENDIF + ret +;------------------------------------------------------------------------------- +ExclusiveAccess ENDP + + +;+-----------------------------------------------------------------------------+ +;| FILL BUFFER THROUGH ASPI | +;+-----------------------------------------------------------------------------+ +FillBufferThroughASPI PROC + LOCAL Scsi[10]:BYTE +;------------------------------------------------------------------------------- + varzero Scsi + mov Scsi, SCSI_Cmd_ReadMany + mov eax, PartitionOffset + ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +; bswap eax ; convert it into BIG endian format + ror eax, 8 ; [dabc] + swap ah, al ; [dacb] + ror eax, 16 ; [cbda] + swap ah, al ; [cbad] + ror eax, 8 ; [dcba] + ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + mov dword ptr Scsi[2], eax ; specify WHICH LBA's to read + mov Scsi[8], COMPARISON_SECTORS + invoke SCSICommand, CurrentAdapter, CurrentDevice, ADDR Scsi, pTargetBuffer, COMPARISON_BYTES + ret +;------------------------------------------------------------------------------- +FillBufferThroughASPI ENDP + + +;+-----------------------------------------------------------------------------+ +;| READ PHYSICAL SECTORS | +;|-----------------------------------------------------------------------------| +;| Returns TRUE if it succeeds | +;+-----------------------------------------------------------------------------+ +ReadPhysicalSectors PROC Sector:DWORD, Count:WORD, pBuffer:LPVOID + LOCAL DiskIO:DISKIO, BytesRead:DWORD +;------------------------------------------------------------------------------- + ; we must first read the sector containing the current Serial Number + .IF (WinNT) + mov eax, Sector ; get the starting sector number + shl eax, 9 ; multiply by 512 for starting BYTE + invoke SetFilePointer, hDriveAccess, eax, 0, FILE_BEGIN + movzx ebx, Count ; get the total sector count + shl ebx, 9 ; multiply by 512 for total bytes to read + invoke ReadFile, hDriveAccess, pBuffer, ebx, ADDR BytesRead, NULL + .ELSE + ; setup the data transfer packet + movmov DiskIO.StartSector, eax, Sector + movmov DiskIO.Sectors, ax, Count + movmov DiskIO.Buffer, eax, pBuffer + ; first try an Int25 (read) call ... for build 950 + mov ecx, OneBasedDrive + dec ecx ; cvrt into 0-baed drive number + mov ch, 25h ; perform INT_25 direct access read + invoke Win95DeviceIO, ecx, ADDR DiskIO, -1, 0, 0, 0 + check eax ; zero means we succeeded! + jz Success + ;-------------------------------------------------------------------------- + ; for SR2 and later + invoke Win95DeviceIO, 7305h, ADDR DiskIO, -1, OneBasedDrive, 0,0 + .IF (eax) ; non-zero means we failed, so return FALSE + zero eax + .ELSE ; zero means we succeeded ... to return -1 +Success: dec eax ; set EAX to -1 for success! + .ENDIF + .ENDIF + ret +;------------------------------------------------------------------------------- +ReadPhysicalSectors ENDP + + +;+-----------------------------------------------------------------------------+ +;| COMPARE BUFFERS | +;|-----------------------------------------------------------------------------| +;| Returns TRUE if the buffers are identical | +;+-----------------------------------------------------------------------------+ +CompareBuffers PROC USES esi edi +;------------------------------------------------------------------------------- + zero eax + mov ecx, COMPARISON_BYTES / 4 + mov esi, pTargetBuffer + mov edi, pSearchBuffer + repe cmpsd + .IF (zero?) + dec eax + .ENDIF + ret +;------------------------------------------------------------------------------- +CompareBuffers ENDP + + +;+-----------------------------------------------------------------------------+ +;| FIND DRIVE LETTER | +;|-----------------------------------------------------------------------------| +;| Returns the Zero-Based DOS drive letter, or -1 if not found | +;+-----------------------------------------------------------------------------+ +FindDriveLetter PROC + LOCAL DriveNumber:DWORD +;------------------------------------------------------------------------------- + ; allocate two page-aligned read buffers for source disk reads + invoke VirtualAlloc, NULL, COMPARISON_BYTES, MEM_COMMIT, PAGE_READWRITE + mov pTargetBuffer, eax + invoke VirtualAlloc, NULL, COMPARISON_BYTES, MEM_COMMIT, PAGE_READWRITE + mov pSearchBuffer, eax + ;-------------------------------------------------------------------------- + ; now search the drive letter space for the same data on a valid drive + ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + mov DriveNumber, 'Z'-'A' ; start at "Z" and work downward ... + .REPEAT + invoke OpenDriveAccess, DriveNumber + call QualifyDrive ; returns true if it might be + .IF (eax) + ; read the partition's first 8 sectors through the ASPI interface +AbsoluteRead: call FillBufferThroughASPI + .IF (!eax) + ; now read the sectors through the device driver interface + invoke ReadPhysicalSectors, 0, COMPARISON_SECTORS, pSearchBuffer + .IF (eax) ; got a TRUE return, so compare'em + call CompareBuffers ; returns TRUE for equality + .IF (eax) + ; yipeee! we found the drive! ... + call CloseDriveAccess + jmp Exit + .ELSEIF (PartitionOffset == 0) + add PartitionOffset, 20h + jmp AbsoluteRead + .ENDIF + .ENDIF + .ENDIF + .ENDIF + call CloseDriveAccess + dec DriveNumber + .UNTIL (sign?) ; 0-based, so this is past the end + ; if DriveNumber == -1, we never found the drive +Exit: invoke VirtualFree, pTargetBuffer, 0, MEM_RELEASE + invoke VirtualFree, pSearchBuffer, 0, MEM_RELEASE + mov eax, DriveNumber + ret +;------------------------------------------------------------------------------- +FindDriveLetter ENDP + + +;+-----------------------------------------------------------------------------+ +;| EJECT IOMEGA CARTRIDGE | +;+-----------------------------------------------------------------------------+ +EjectIomegaCartridge PROC Adapter:DWORD, Device:DWORD + LOCAL UnlockParams:DWORD, BytesReceived:DWORD + LOCAL Scsi[6]:BYTE +;------------------------------------------------------------------------------- + push CurrentAdapter + push CurrentDevice + movmov CurrentAdapter, eax, Adapter + movmov CurrentDevice, eax, Device + call FindDriveLetter + .IF (eax <= 'Z'-'A') + invoke OpenDriveAccess, eax + .IF (WinNT) + invoke DeviceIoControl, hDriveAccess, IOCTL_STORAGE_EJECT_MEDIA, NULL, 0, NULL, 0, ADDR BytesReceived, NULL + .ELSE + mov UnlockParams, 1 + invoke Win95DeviceIO, 440Dh, OneBasedDrive, 0848h, ADDR UnlockParams,0,0 + invoke Win95DeviceIO, 440Dh, OneBasedDrive, 0849h, 0,0,0 + .ENDIF + invoke CloseDriveAccess + .ELSE + ; Could NOT do it through the IOCTL layer ... so eject with SCSI + ; make sure the media is not locked ... + varzero Scsi + mov Scsi, SCSI_Cmd_PreventAllow + invoke SCSICommand, Adapter, Device, ADDR Scsi, NULL, 0 + ; issue an Asynchronous STOP command to induce spindown and ejection + varzero Scsi + mov Scsi[0], SCSI_Cmd_StartStopUnit + mov Scsi[1], 1 ; set the IMMED bit for offline + mov Scsi[4], 2 ; eject a Jaz disk after stopping + invoke SCSICommand, Adapter, Device, ADDR Scsi, NULL, 0 + .ENDIF + pop CurrentDevice + pop CurrentAdapter + ret +;------------------------------------------------------------------------------- +EjectIomegaCartridge ENDP + + +;+-----------------------------------------------------------------------------+ +;| PERFORM REGION TRANSFER | +;+-----------------------------------------------------------------------------+ +PerformRegionTransfer PROC USES ebx, XferCmd:DWORD, pBuffer:DWORD + LOCAL Scsi[10]:BYTE, LocalBuffer:DWORD, LocalCount:DWORD, + InitialHardErrors:DWORD, GlitchCount:DWORD, GlitchError:DWORD +;------------------------------------------------------------------------------- + reset SingleTransferLBA ; show we're testing a range ... + movmov InitialHardErrors, eax, HardErrors + varzero Scsi ; clear out the SCSI CDB + movmov Scsi, al, byte ptr XferCmd + ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + mov eax, FirstLBASector ; setup the first block to read +; bswap eax ; convert it into BIG endian format + ror eax, 8 ; [dabc] + swap ah, al ; [dacb] + ror eax, 16 ; [cbda] + swap ah, al ; [cbad] + ror eax, 8 ; [dcba] + mov dword ptr Scsi[2], eax ; specify WHICH LBA's to read + ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + mov eax, NumberOfLBAs ; and the NUMBER of LBA's to read + swap ah, al ; convert it into BIG endian format + mov word ptr Scsi[7], ax ; + invoke SetErrorRecovery, FALSE, FALSE, TRUE ; disable Retries & ECC + invoke SCSICommand, CurrentAdapter, CurrentDevice, ADDR Scsi, pBuffer, AdapterMaxBytes + ; if we failed somewhere during our transfer ... let's zero in on it + .IF (eax) + cmp eax, SS_ERR ; if it's a CONTROLLER ERROR, skip! + je Exit + cmp eax, BUFFER_TOO_BIG ; if we need to reduce the size + je Exit + cmp eax, LBA_TOO_LARGE + je Exit + ;-------------------------------------------------------------------------- + mov GlitchError, eax ; save the error which stopped us! + mov eax, SoftErrors ; get the current Soft + Hard Error count + add eax, HardErrors + mov GlitchCount, eax ; save it to see if we do FIND the glitch ... + movmov SingleTransferLBA, eax, FirstLBASector + call UpdateCurrentSector ; show what we're doing ... + movmov LocalBuffer, eax, pBuffer + movmov LocalCount, eax, AdapterMaxSectors + call ErrorSound + .REPEAT + ; setup for our series of transfer tests ... + varzero Scsi ; clear out the SCSI CDB + movmov Scsi, al, byte ptr XferCmd + ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + mov eax, SingleTransferLBA ; the single sector to xfer +; bswap eax ; convert it into BIG endian format + ror eax, 8 ; [dabc] + swap ah, al ; [dacb] + ror eax, 16 ; [cbda] + swap ah, al ; [cbad] + ror eax, 8 ; [dcba] + mov dword ptr Scsi[2], eax ; specify WHICH single LBA to read + ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + mov Scsi[8], 1 ; a single sector + ; disable all recovery techniques + invoke SetErrorRecovery, FALSE, FALSE, TRUE ; disable Retries & ECC + invoke SCSICommand, CurrentAdapter, CurrentDevice, ADDR Scsi, LocalBuffer, BYTES_PER_SECTOR + .IF (eax) + ; some sort of problem encountered! + cmp eax, SS_ERR ; if it's a CONTROLLER ERROR, skip! + je Exit + ;-------------------------------------------------------------------------- + cmp al, 1 ; did we recover? + je PostTheError + ;-------------------------------------------------------------------------- + invoke SetErrorRecovery, TRUE, FALSE, TRUE ; enable retries + invoke SCSICommand, CurrentAdapter, CurrentDevice, ADDR Scsi, LocalBuffer, BYTES_PER_SECTOR + .IF (eax) + ; failed even with retries + cmp eax, SS_ERR ; if it's a CONTROLLER ERROR, skip! + je Exit + ;-------------------------------------------------------------------------- + cmp al, 1 ; did we recover? + je PostTheError + ;-------------------------------------------------------------------------- + invoke SetErrorRecovery, TRUE, TRUE, TRUE ; enable retries AND ECC + invoke SCSICommand, CurrentAdapter, CurrentDevice, ADDR Scsi, LocalBuffer, BYTES_PER_SECTOR + .IF (eax) + ; failed with retries and ECC + cmp eax, SS_ERR ; if it's a CONTROLLER ERROR, skip! + je Exit + .ELSE ; succeeded with ECC + mov eax, 180101h ; "ECC & Retries" + .ENDIF + .ELSE ; succeeded using retries + mov eax, 170101h ; "Read with Retries" + .IF (XferCmd == SCSI_Cmd_WriteMany) + mov eax, 0C8001h ; "Wrote with Retries" + .ENDIF + .ENDIF + ;-------------------------------------------------------------------------- +PostTheError: invoke BumpErrorCounts, eax ; given eax, count the errors + invoke GetSpareSectorCounts, FALSE ; update the Cart's Condition + call UpdateRunTimeDisplay + .ENDIF + inc SingleTransferLBA + call UpdateCurrentSector + add LocalBuffer, BYTES_PER_SECTOR + call ProcessPendingMessages + dec LocalCount + .UNTIL (zero?) || (UserInterrupt) + ; now see whether we *did* found something to complain about ... + mov eax, SoftErrors + add eax, HardErrors + .IF (eax == GlitchCount) + ; we missed it ... but SOMETHING happened! So let's report it ... + push SoftErrors ; save the existing counts + push HardErrors + mov eax, GlitchError ; get the error that triggered our search + mov ebx, eax + and ebx, 00FF00FFh ; strip the ASCQ byte + .IF (ebx == 00110003h) ; if we're about to say "unrecovered read" + mov eax, 170101h ; change it to: "Read with Retries" + .ENDIF + invoke BumpErrorCounts, eax ; given eax, count the errors + pop HardErrors ; restore the counts + pop SoftErrors + inc SoftErrors ; and bump the SOFT error count + call UpdateRunTimeDisplay + .ENDIF + reset SingleTransferLBA + zero eax ; now let's return happiness to our caller + mov ebx, HardErrors ; UNLESS we had some + .IF (ebx != InitialHardErrors) ; UNRECOVERABLE errors! + dec eax ; in which case return -1 + .ENDIF + .ENDIF + ; restore standard error recovery modes +Exit: push eax + invoke SetErrorRecovery, TRUE, TRUE, FALSE ; reenable Retries & ECC + pop eax + ret +;------------------------------------------------------------------------------- +PerformRegionTransfer ENDP + + +;+-----------------------------------------------------------------------------+ +;| TEST THE DISK | +;+-----------------------------------------------------------------------------+ +TestTheDisk PROC + LOCAL TransferLength:DWORD, DataPattern:DWORD, + DriveNumber:DWORD, BlastRecoveryMode:BOOL +;------------------------------------------------------------------------------- + ; USB seems to generate insane WM_TIMER messages, so we now stop + ; the timer during data read/write processing. + call StopApplicationTimer + ; determine whether to show "Unknown Error" or the Hex code ... + invoke GetAsyncKeyState, VK_SHIFT + shl eax, 1 ; move the high bit into CY + .IF (carry?) + set UnknownErrorMode + .ENDIF + + ; determine which drive to lock + call FindDriveLetter ; returns drive letter, or -1 if not found + mov DriveNumber, eax + .IF (eax == (-1)) + mov al, "?" + .ELSE + invoke ExclusiveAccess, eax, TRUE + .IF (!eax) ; could NOT succeed in locking the drive! + mov al, byte ptr DriveNumber + add al, 'A' + mov szExclusiveDrive1, al + mov szExclusiveDrive2, al + invoke MessageBox, hMainWnd, ADDR szNoExclusiveText, ADDR szNoExclusiveTitle, MB_APPLMODAL or MB_OK + ; allow operation on an unlocked drive! + invoke GetAsyncKeyState, VK_SHIFT + shl eax, 1 ; move the high bit into CY + jnc Exit + .ENDIF + mov al, byte ptr DriveNumber + add al, 'A' + .ENDIF + mov DriveUnderTest, al +;=============================================================================== + call PreventProgramExit + invoke SetRichEditText, ADDR hTabText, ADDR szRunning + mov CartridgeStatus, DISK_TEST_UNDERWAY + mov TestingPhase, TESTING_STARTUP ; inhibit stopping now + invoke SetWindowText, hTestButton, ADDR szPressToStop + invoke InvalidateRect, hTestMonitor, NULL, FALSE + call LockCurrentDrive ; prevent media removal + + ; setup the initial maximum transfer ... + invoke HostAdapterInquiry, CurrentAdapter + mov eax, dword ptr ASPI_CmdBlock.hai.HA_Unique[4] ; get the max Xfer + .IF (!eax) || (eax > MAX_TRANSFER_PER_TEST) ; limit to our max + mov eax, MAX_TRANSFER_PER_TEST + .ENDIF +SizeIt: mov AdapterMaxBytes, eax + shr eax, 9 ; divide by Bytes/Sector + mov AdapterMaxSectors, eax + +;----------------------- Check for "Blast Recovery Mode" ----------------------- + + call CheckForPartitionTable + ; returns NON-ZERO if partition table was NOT found + .IF (eax) + call PerhapsBlastRecovery + ; returns NON-ZERO if BlastRecovery *was* performed ... + .ENDIF + mov BlastRecoveryMode, eax + check eax + jnz GetOut + +IF FORCE_STARTING_SECTOR + mov FirstLBASector, FORCE_STARTING_SECTOR ; and the starting point +ENDIF + +;------------------------- Standard Testing Operation -------------------------- + + ; log the starting time + invoke GetSystemTimeAsFileTime, ADDR StartingInstant + .REPEAT + ; compute the number of LBS and Last LBA + mov eax, LastLBAOnCartridge ; get the maximum LBA count + sub eax, FirstLBASector ; and the starting point + inc eax ; number of sectors to go + .IF (eax > AdapterMaxSectors) + mov eax, AdapterMaxSectors ; trim it to the sector count + .ENDIF + mov NumberOfLBAs, eax + + ; compute the LastLBA + add eax, FirstLBASector ; get just past the end + dec eax ; get the last one + mov LastLBASector, eax + + ; compute the percentage complete + mov edx, FirstLBASector + zero eax + div LastLBAOnCartridge + mov PercentComplete, eax + + ; uppdate the elapsed time + call GetElapsedTimeInSeconds + .IF (eax != (-1)) + mov SecondsElapsed, eax + .ENDIF + + ; get a random pattern of data to write + call GetRandomNumber + mov DataPattern, eax + mov ecx, AdapterMaxBytes + shr ecx, 2 + mov edi, pPatternBuffer + rep stosd + + ; update the cartridge's status + invoke GetSpareSectorCounts, FALSE ; update the Cart's Condition + + mov TestingPhase, READING_DATA + call UpdateRunTimeDisplay + invoke PerformRegionTransfer, SCSI_Cmd_ReadMany, pUserDataBuffer + .IF (!eax) + ;-------------------------------------------------------------------------- + mov TestingPhase, WRITING_PATT + invoke UpdateRunPhaseDisplay + invoke PerformRegionTransfer, SCSI_Cmd_WriteMany, pPatternBuffer + ;-------------------------------------------------------------------------- + mov TestingPhase, READING_PATT + invoke UpdateRunPhaseDisplay + invoke PerformRegionTransfer, SCSI_Cmd_Verify, pPatternBuffer + ;-------------------------------------------------------------------------- + mov TestingPhase, WRITING_DATA + invoke UpdateRunPhaseDisplay + invoke PerformRegionTransfer, SCSI_Cmd_WriteMany, pUserDataBuffer + ;-------------------------------------------------------------------------- + .ELSEIF (eax == BUFFER_TOO_BIG) + ; we need to make it smaller + mov eax, AdapterMaxBytes ; get the current size + halve eax + jmp SizeIt + .ENDIF + ; if we hit the end of the disk ... exit gracefully! + cmp eax, LBA_TOO_LARGE + je GetOut + ; see if everything's still okay ... + .BREAK .IF (CartridgeStatus != DISK_TEST_UNDERWAY) + ; bump the FirstLBASector up for the next transfer + mov eax, FirstLBASector + add eax, NumberOfLBAs + mov FirstLBASector, eax + .UNTIL (eax > LastLBAOnCartridge) || (UserInterrupt) + ; show that we're post-test +GetOut: reset TestingPhase + call UnlockAllMedia + invoke SetErrorRecovery, TRUE, TRUE, FALSE ; reenable Retries & ECC + + invoke SetWindowText, hTestButton, ADDR szPressToStart + mov CartridgeStatus, DISK_AT_SPEED + call AllowProgramExit + + ; compute the number of serious troubles + mov eax, FirmErrors + add eax, HardErrors + .IF (eax >= BADNESS_THRESHOLD) + mov eax, OFFSET szBadResult + .ELSEIF (UserInterrupt) + mov eax, OFFSET szInterrupted + .ELSE ; it wasn't interrupted, nor seriously bad, was it perfect? + add eax, SoftErrors + .IF (eax) + mov eax, OFFSET szExplainResult + .ELSE + mov eax, OFFSET szPerfectResult + .ENDIF + .ENDIF + invoke SetRichEditText, ADDR hTabText, eax + invoke InvalidateRect, hTestMonitor, NULL, FALSE + ; release any exclusive filesystem lock we may have on the drive +Exit: invoke ExclusiveAccess, DriveNumber, FALSE + ; if we've just un-zapped the disk ... let's eject it! + .IF (BlastRecoveryMode) + invoke EjectIomegaCartridge, CurrentAdapter, CurrentDevice + .ENDIF + ; we're done (with USB'ness) so it's safe to restart the timer + call StartApplicationTimer + ret +;------------------------------------------------------------------------------- +TestTheDisk ENDP + + +;+-----------------------------------------------------------------------------+ +;| CHECK FOR PARTITION TABLE | +;| Return NON-ZERO if partition table was NOT found! | +;+-----------------------------------------------------------------------------+ +CheckForPartitionTable PROC USES ebx + LOCAL Return:DWORD, ShiftCount:DWORD +;------------------------------------------------------------------------------- + reset Return + ; determine how many shift keys we're holding down ... + reset ShiftCount + invoke GetAsyncKeyState, VK_SHIFT + shl eax, 1 ; move the high bit into CY + .IF (carry?) + inc ShiftCount + .ENDIF + invoke GetAsyncKeyState, VK_CONTROL + shl eax, 1 ; move the high bit into CY + .IF (carry?) + inc ShiftCount + .ENDIF + invoke GetAsyncKeyState, VK_MENU + shl eax, 1 ; move the high bit into CY + .IF (carry?) + inc ShiftCount + .ENDIF + ; allocate a page-aligned read buffer for disk read + invoke GlobalAlloc, GPTR, BYTES_PER_SECTOR + mov ebx, eax + ; read the cartridge's partition table ... + invoke ReadSectors, ebx, 0, 1 + + ; only if we got a good table read *AND* it's not a partition table + .IF (ShiftCount == 3) || ((!eax) && (word ptr [ebx+01FEh] != 0AA55h)) + set Return + .ENDIF + invoke GlobalFree, ebx + mov eax, Return + ret +;------------------------------------------------------------------------------- +CheckForPartitionTable ENDP + + +;+-----------------------------------------------------------------------------+ +;| PERHAPS BLAST RECOVERY | +;|-----------------------------------------------------------------------------| +;| No partition table was found ... so give them the option of performing | +;| a "blast recovery". Return TRUE if they took the option. | +;+-----------------------------------------------------------------------------+ +PerhapsBlastRecovery PROC USES ebx esi + LOCAL StartOfFAT1:DWORD, StartOfFAT2:DWORD, + SectorsToCopy:DWORD +;------------------------------------------------------------------------------- + ; update the LBA count + invoke GetSpareSectorCounts, FALSE ; update the Cart's Condition + ; get the drive index {0-3} + mov eax, LastLBAOnCartridge + zero ebx + .WHILE (LBAMidPoints[ebx*4] < eax) && (ebx < 3) + inc ebx + .ENDW + ; patch the cartridge size into the mesage box text + ; get the starting address of the name strings + lea esi, IomegaDeviceNames[ebx*8] + + movmov dword ptr CartSize1[0], eax, [esi] + movmov dword ptr CartSize2[0], eax, [esi] + movmov dword ptr CartSize3[0], eax, [esi] + movmov dword ptr CartSize4[0], eax, [esi] + movmov dword ptr CartSize5[0], eax, [esi] + + movmov dword ptr CartSize1[4], eax, [esi+4] + movmov dword ptr CartSize2[4], eax, [esi+4] + movmov dword ptr CartSize3[4], eax, [esi+4] + movmov dword ptr CartSize4[4], eax, [esi+4] + movmov dword ptr CartSize5[4], eax, [esi+4] + + invoke MessageBox, hMainWnd, ADDR szPerhapsBlastText, ADDR szPerhapsBlastTitle, MB_APPLMODAL or MB_OKCANCEL + sub eax, IDCANCEL + jz Exit + +;=================== Restore the cartridge's Partition Table =================== + + ; make the offset to the drive's partition sector data + shl ebx, 10 ; multiply the drive index by 1024 + add ebx, pSectorData + invoke WriteSectors, ebx, 0, 1 + check eax + jnz Trouble + + ; get the number of sectors per track for the LBA offset of the + ; partition boot sector ... + mov eax, [ebx+01F6h] ; eax == 32 or 63 + mov StartOfFAT1, eax + inc StartOfFAT1 ; save the LBA sector for FAT1 + +;===================== Restore the Cartridge's Boot Sector ===================== + + add ebx, BYTES_PER_SECTOR ; skip up to the Boot Sector data + invoke WriteSectors, ebx, eax, 1 ; and send the boot sector out + check eax + jnz Trouble + +;======================= Calc the FAT recovery variables ======================= + + mov eax, MAX_SECTORS_PER_TEST + sub eax, StartOfFAT1 + mov SectorsToCopy, eax + + movzx eax, word ptr [ebx + BPB_OFFSET + SECTORS_PER_FAT] + add eax, StartOfFAT1 + invoke ReadSectors, pUserDataBuffer, eax, SectorsToCopy + check eax + jnz Trouble + + invoke WriteSectors, pUserDataBuffer, StartOfFAT1, SectorsToCopy + .IF (eax) +Trouble: invoke MessageBox, hMainWnd, ADDR szBlastTroubleText, ADDR szBlastTroubleTitle, MB_APPLMODAL or MB_OK + .ELSE + invoke MessageBox, hMainWnd, ADDR szBlastSuccessText, ADDR szBlastSuccessTitle, MB_APPLMODAL or MB_OK + .ENDIF + zero eax + dec eax +Exit: ret +;------------------------------------------------------------------------------- +PerhapsBlastRecovery ENDP + diff --git a/x86-asm-source/ASPI.INC b/x86-asm-source/ASPI.INC new file mode 100644 index 0000000..85b70b3 --- /dev/null +++ b/x86-asm-source/ASPI.INC @@ -0,0 +1,399 @@ +;+-----------------------------------------------------------------------------+ +;| ASPI.INC | +;+-----------------------------------------------------------------------------+ +BITS16 = 0 ; 1 == MS-DOS/Win16 0 == WIN32 +;------------------------------------------------------------------------------- + +LPSRB typedef PTR + +PFNPOST PROTO STDCALL + +; aspi_GetSupportInfo PROTO STDCALL +; aspi_SendCommand PROTO STDCALL :LPSRB + +GetASPI32SupportInfoProto typedef PROTO SYSCALL +GetASPI32SupportInfoPtr typedef PTR GetASPI32SupportInfoProto +SendASPI32CommandProto typedef PROTO SYSCALL :LPVOID +SendASPI32CommandPtr typedef PTR SendASPI32CommandProto +GetASPI32BufferProto typedef PROTO SYSCALL :LPVOID +GetASPI32BufferPtr typedef PTR GetASPI32BufferProto +FreeASPI32BufferProto typedef PROTO SYSCALL :LPVOID +FreeASPI32BufferPtr typedef PTR FreeASPI32BufferProto + + +;-------------------------------- SCSI Commands -------------------------------- + +SCSI_Cmd_TestUnitReady equ 00h +SCSI_Cmd_Rewind equ 01h +SCSI_Cmd_RezeroUnit equ 01h ; iomega ZIP +SCSI_Cmd_RequestSense equ 03h +SCSI_Cmd_FormatUnit equ 04h +SCSI_Cmd_ReadBlkLimits equ 05h +SCSI_Cmd_ReadSectorIDs equ 05h ; iomega ZIP +SCSI_Cmd_NonSenseData equ 06h ; iomega ZIP +SCSI_Cmd_ReassignBlocks equ 07h ; iomega ZIP +SCSI_Cmd_Read equ 08h +SCSI_Cmd_Write equ 0Ah +SCSI_Cmd_Seek equ 0Bh +SCSI_Cmd_CartProtect equ 0Ch ; iomega ZIP +SCSI_Cmd_WriteFilemarks equ 10h +SCSI_Cmd_Space equ 11h +SCSI_Cmd_Inquiry equ 12h +SCSI_Cmd_ModeSelect equ 15h +SCSI_Cmd_ReserveUnit equ 16h +SCSI_Cmd_ReleaseUnit equ 17h +SCSI_Cmd_Erase equ 19h +SCSI_Cmd_ModeSense equ 1Ah +SCSI_Cmd_LoadUnload equ 1Bh +SCSI_Cmd_StartStopUnit equ 1Bh ; iomega ZIP +SCSI_Cmd_SendDiagnostic equ 1Dh +SCSI_Cmd_PreventAllow equ 1Eh ; iomega ZIP +SCSI_Cmd_TranslateLBA equ 22h ; iomega ZIP +SCSI_Cmd_FormatTest equ 24h ; iomega ZIP +SCSI_Cmd_ReadCapacity equ 25h +SCSI_Cmd_ReadMany equ 28h ; iomega ZIP +SCSI_Cmd_WriteMany equ 2Ah ; iomega ZIP +SCSI_Cmd_Locate equ 2Bh +SCSI_Cmd_SeekMany equ 2Bh ; iomega ZIP +SCSI_Cmd_Verify equ 2Fh ; iomega ZIP +SCSI_Cmd_ReadPosition equ 34h +SCSI_Cmd_SynchCache equ 35h ; iomega ZIP +SCSI_Cmd_ReadDefectData equ 37h ; iomega ZIP +SCSI_Cmd_WriteBuffer equ 3Bh ; iomega ZIP +SCSI_Cmd_ReadBuffer equ 3Ch ; iomega ZIP +SCSI_Cmd_ReadLong equ 3Eh ; iomega ZIP +SCSI_Cmd_WriteLong equ 3Fh ; iomega ZIP +SCSI_Cmd_ReadToc equ 43h +SCSI_Cmd_WriteFieldFormat equ 0E3h ; iomega ZIP + +TEN_BYTE_CMDS equ 20h ; if >= then 10 bytes + +;------------------------------ ASPI Definitions ------------------------------- + +SENSE_LEN equ 128t ; default sense buffer length +MAX_ASPI_BLOCK_LENGTH equ 256t ; (SENSE_LEN + 80t was probably enough) + +SRB_DIR_SCSI equ 00000h ; direction determined by SCSI command +SRB_DIR_IN equ 00008h ; transfer from SCSI target to host +SRB_DIR_OUT equ 00010h ; transfer from host to SCSI target +SRB_POSTING equ 00001h ; enable ASPI posting +SRB_EVENT_NOTIFY equ 00040h ; enable ASPI event notification +SRB_ENABLE_RESIDUAL_COUNT equ 00004h ; enable residual byte count reporting +SRB_DATA_SG_LIST equ 00002h ; data buffer points to scatter-gather list + +WM_ASPIPOST equ 04d42h ; ASPI Post message + +;+-----------------------------------------------------------------------------+ +;| %%% ASPI Command Definitions %%% | +;+-----------------------------------------------------------------------------+ +SC_HA_INQUIRY equ 00000h ; host adapter inquiry +SC_GET_DEV_TYPE equ 00001h ; get device type +SC_EXEC_SCSI_CMD equ 00002h ; execute SCSI command +SC_ABORT_SRB equ 00003h ; abort an SRB +SC_RESET_DEV equ 00004h ; SCSI bus device reset +SC_GET_DISK_INFO equ 00006h ; get Disk information +SC_RESCAN_SCSI_BUS equ 00007h ; rebuild SCSI device map +SC_GETSET_TIMEOUTS equ 00008h ; get/set target timeouts + +;+-----------------------------------------------------------------------------+ +;| %%% SRB Status %%% | +;+-----------------------------------------------------------------------------+ +SS_PENDING equ 00000h ; SRB being processed +SS_COMP equ 00001h ; SRB completed without error +SS_ABORTED equ 00002h ; SRB aborted +SS_ABORT_FAIL equ 00003h ; unable to abort SRB +SS_ERR equ 00004h ; SRB completed with error +SS_INVALID_CMD equ 00080h ; invalid ASPI command +SS_INVALID_HA equ 00081h ; invalid host adapter number +SS_NO_DEVICE equ 00082h ; SCSI device not installed +SS_INVALID_SRB equ 000e0h ; invalid parameter set in SRB +SS_FAILED_INIT equ 000e4h ; ASPI for windows failed init +SS_ASPI_IS_BUSY equ 000e5h ; no resources available to execute cmd +SS_BUFFER_TO_BIG equ 000e6h ; buffer size to big to handle! + +;+-----------------------------------------------------------------------------+ +;| %%% Host Adapter Status %%% | +;+-----------------------------------------------------------------------------+ +HASTAT_OK equ 00000h ; host adapter did not detect an error +HASTAT_SEL_TO equ 00011h ; selection Timeout +HASTAT_DO_DU equ 00012h ; data overrun data underrun +HASTAT_BUS_FREE equ 00013h ; unexpected bus free +HASTAT_PHASE_ERR equ 00014h ; target bus phase sequence failure +HASTAT_TIMEOUT equ 00009h ; timed out while SRB was waiting to beprocessed. +HASTAT_COMMAND_TIMEOUT equ 0000bh ; while processing the SRB, the adapter timed out. +HASTAT_MESSAGE_REJECT equ 0000dh ; while processing SRB the adapter received a MESSAGE REJECT. +HASTAT_BUS_RESET equ 0000eh ; a bus reset was detected. +HASTAT_PARITY_ERROR equ 0000fh ; a parity error was detected. +HASTAT_REQUEST_SENSE_FAILED equ 00010h ; the adapter failed in issuing REQUEST SENSE. + + +;+-----------------------------------------------------------------------------+ +;| %%% SRB - HOST ADAPTER INQUIRY - SC_HA_INQUIRY %%% | +;+-----------------------------------------------------------------------------+ +SRB_HAInquiry struct 1t +;------------------------------------------------------------------------------- +SRB_Cmd BYTE ? ; w: ASPI command code = SC_HA_INQUIRY +SRB_Status BYTE ? ; r: ASPI command status byte +SRB_HaId BYTE ? ; w: ASPI host adapter number +SRB_Flags BYTE ? ; 0: SCSI request flags - undef - should be zero +SRB_Ext_Req_Sig WORD ? ; rw: set to AA55h by ASPI client (swapped if supported) +SRB_Ext_Buf_Len WORD ? ; rw: # of extended buf bytes desired +HA_Count BYTE ? ; r: number of host adapters present +HA_SCSI_ID BYTE ? ; r: SCSI ID of host adapter +HA_ManagerId BYTE 16t dup (?); r: string describing the manager +HA_Identifier BYTE 16t dup (?); r: string describing the host adapter +HA_Unique BYTE 16t dup (?); r: host Adapter Unique parameters +HA_Extensions WORD ? ; r: bitfield of supported extensions +;------------------------------------------------------------------------------- +SRB_HAInquiry ends +;------------------------------------------------------------------------------- +PSRB_HAInquiry typedef PTR SRB_HAInquiry + + +;+-----------------------------------------------------------------------------+ +;| %%% SRB - GET DEVICE TYPE - SC_GET_DEV_TYPE %%% | +;+-----------------------------------------------------------------------------+ +SRB_GDEVBlock struct 1t +;------------------------------------------------------------------------------- +SRB_Cmd BYTE ? ; w: ASPI command code = SC_GET_DEV_TYPE +SRB_Status BYTE ? ; r: ASPI command status byte +SRB_HaId BYTE ? ; w: ASPI host adapter number +SRB_Flags BYTE ? ; 0: SCSI request flags - undef - should be zero +SRB_Hdr_Rsvd DWORD ? ; 0: undef - reserved for expansion +SRB_Target BYTE ? ; w: target's SCSI ID +SRB_Lun BYTE ? ; w: target's LUN number +SRB_DeviceType BYTE ? ; r: target's peripheral device type +IFE BITS16 ; only under Win32 +SRB_Rsvd1 BYTE ? +ENDIF +;------------------------------------------------------------------------------- +SRB_GDEVBlock ends +;------------------------------------------------------------------------------- +PSRB_GDEVBlock typedef PTR SRB_GDEVBlock + + +IF BITS16 ; EXECUTE SCSI COMMAND DEFINITION for MS-DOS +;+-----------------------------------------------------------------------------+ +;| %%% SRB - EXECUTE SCSI COMMAND - SC_EXEC_SCSI_CMD %%% | +;+-----------------------------------------------------------------------------+ +SRB_ExecSCSICmd struct 1t +;------------------------------------------------------------------------------- +SRB_Cmd BYTE ? ; w: ASPI command code = SC_EXEC_SCSI_CMD +SRB_Status BYTE ? ; r: ASPI command status byte +SRB_HaId BYTE ? ; w: ASPI host adapter number +SRB_Flags BYTE ? ; w: SCSI request flags +SRB_Hdr_Rsvd DWORD ? ; 0: undef - reserved +SRB_Target BYTE ? ; w: target's SCSI ID +SRB_Lun BYTE ? ; w: target's LUN number +SRB_BufLen DWORD ? ; w: data allocation length +SRB_SenseLen BYTE ? ; w: sense allocation length +SRB_BufPointer LPBYTE ? ; w: data buffer pointer +SRB_LinkPointer LPVOID ? ; w: SRB link pointer +SRB_CDBLen BYTE ? ; w: CDB Length +SRB_HaStat BYTE ? ; r: host Adapter Status +SRB_TargStat BYTE ? ; r: target Status +SRB_PostProc LPPROC ? ; w: post routine +SRB_Rsvd BYTE 34 dup (?) ; 0: reserved for ASPI workspace +;------------------------------------------------------------------------------- +SRB_CDBByte BYTE 16 dup (?) ; w: SCSI CDB +;------------------------------------------------------------------------------- +SRB_SenseArea BYTE (SENSE_LEN+2) dup (?); r: request Sense buffer +;------------------------------------------------------------------------------- +SRB_ExecSCSICmd ends +;------------------------------------------------------------------------------- +PSRB_ExecSCSICmd typedef PTR SRB_ExecSCSICmd + + +ELSE ; EXECUTE SCSI COMMAND DEFINITION for WIN32 +;+-----------------------------------------------------------------------------+ +;| %%% SRB - EXECUTE SCSI COMMAND - SC_EXEC_SCSI_CMD %%% | +;+-----------------------------------------------------------------------------+ +SRB_ExecSCSICmd struct 1t +;------------------------------------------------------------------------------- +SRB_Cmd BYTE ? ; w: ASPI command code = SC_EXEC_SCSI_CMD +SRB_Status BYTE ? ; r: ASPI command status byte +SRB_HaId BYTE ? ; w: ASPI host adapter number +SRB_Flags BYTE ? ; w: SCSI request flags +SRB_Hdr_Rsvd DWORD ? ; 0: undef - reserved +SRB_Target BYTE ? ; w: target's SCSI ID +SRB_Lun BYTE ? ; w: target's LUN number +SRB_Rsvd1 WORD ? ; 0: reserved for alignment +SRB_BufLen DWORD ? ; w: data allocation length +SRB_BufPointer LPBYTE ? ; w: data buffer pointer +SRB_SenseLen BYTE ? ; w: sense allocation length +SRB_CDBLen BYTE ? ; w: CDB Length +SRB_HaStat BYTE ? ; r: host Adapter Status +SRB_TargStat BYTE ? ; r: target Status +SRB_PostProc PROCPTR ? ; w: post routine +SRB_Rsvd2 LPVOID ? ; w: reserved +SRB_Rsvd3 BYTE 16t dup (?) ; 0: reserved for alignment +;------------------------------------------------------------------------------- +SRB_CDBByte BYTE 16t dup (?) ; w: SCSI CDB +;------------------------------------------------------------------------------- +SRB_SenseArea BYTE (SENSE_LEN+2) dup (?); r: request Sense buffer +;------------------------------------------------------------------------------- +SRB_ExecSCSICmd ends +;------------------------------------------------------------------------------- +PSRB_ExecSCSICmd typedef PTR SRB_ExecSCSICmd + +ENDIF + +;+-----------------------------------------------------------------------------+ +;| %%% SRB - ABORT AN SRB - SC_ABORT_SRB %%% | +;+-----------------------------------------------------------------------------+ +SRB_Abort struct 1t +;------------------------------------------------------------------------------- +SRB_Cmd BYTE ? ; w: ASPI command code = SC_EXEC_SCSI_CMD +SRB_Status BYTE ? ; r: ASPI command status byte +SRB_HaId BYTE ? ; w: ASPI host adapter number +SRB_Flags BYTE ? ; 0: undef for command - reserved +SRB_Hdr_Rsvd DWORD ? ; 0: reserved for expansion +SRB_ToAbort LPSRB ? ; w: pointer to SRB to abort +;------------------------------------------------------------------------------- +SRB_Abort ends +;------------------------------------------------------------------------------- +PSRB_Abort typedef PTR SRB_Abort + + +;+-----------------------------------------------------------------------------+ +;| %%% SRB - BUS DEVICE RESET - SC_RESET_DEV %%% | +;+-----------------------------------------------------------------------------+ +SRB_BusDeviceReset struct 1t +;------------------------------------------------------------------------------- +SRB_Cmd BYTE ? ; w: ASPI command code = SC_EXEC_SCSI_CMD +SRB_Status BYTE ? ; r: ASPI command status byte +SRB_HaId BYTE ? ; w: ASPI host adapter number +SRB_Flags BYTE ? ; w: SCSI request flags (post enable/disable) +SRB_Hdr_Rsvd DWORD ? ; 0: reserved +SRB_Target BYTE ? ; w: target's SCSI ID +SRB_Lun BYTE ? ; w: target's LUN number +SRB_Rsvd1 BYTE 12t dup (?); 0: reserved for alignment +SRB_HaStat BYTE ? ; r: host adapter status +SRB_TargStat BYTE ? ; r: target status +SRB_PostProc PROCPTR ? ; w: post routine +SRB_Rsvd2 LPVOID ? ; 0: reserved +SRB_Rsvd3 BYTE 16t dup (?); 0: reserved +SRB_CDBByte BYTE 16t dup (?); SCSI CDB +;------------------------------------------------------------------------------- +SRB_BusDeviceReset ends +;------------------------------------------------------------------------------- +PSRB_BusDeviceReset typedef PTR SRB_BusDeviceReset + + +;+-----------------------------------------------------------------------------+ +;| %%% SRB - GET DISK INFORMATION - SC_GET_DISK_INFO %%% | +;+-----------------------------------------------------------------------------+ +SRB_GetDiskInfo struct 1t +;------------------------------------------------------------------------------- +SRB_Cmd BYTE ? ; w: ASPI command code = SC_EXEC_SCSI_CMD +SRB_Status BYTE ? ; r: ASPI command status byte +SRB_HaId BYTE ? ; w: ASPI host adapter number +SRB_Flags BYTE ? ; 0: SCSI request flags - undef +SRB_Hdr_Rsvd DWORD ? ; 0: reserved +SRB_Target BYTE ? ; w: target's SCSI ID +SRB_Lun BYTE ? ; w: target's LUN number +SRB_DriveFlags BYTE ? ; r: drive flags +SRB_Int13HDriveInfo BYTE ? ; r: host adapter int13 drive number +SRB_Heads BYTE ? ; r: preferred number of heads translation +SRB_Sectors BYTE ? ; r: preferred number of sectors translation +SRB_Rsvd1 BYTE 10t dup (?); 0: reserved +;------------------------------------------------------------------------------- +SRB_GetDiskInfo ends +;------------------------------------------------------------------------------- +PSRB_GetDiskInfo typedef PTR SRB_GetDiskInfo + + +;+-----------------------------------------------------------------------------+ +;| %%% SRB - RESCAN SCSI BUS - SC_RESCAN_SCSI_BUS (7) %%% | +;+-----------------------------------------------------------------------------+ +SRB_RescanPort struct 1t +;------------------------------------------------------------------------------- +SRB_Cmd BYTE ? ; w: ASPI command code = SC_RESCAN_SCSI_BUS +SRB_Status BYTE ? ; r: ASPI command status byte +SRB_HaId BYTE ? ; w: ASPI host adapter number +SRB_Flags BYTE ? ; 0: reserved +SRB_Hdr_Rsvd DWORD ? ; 0: reserved +;------------------------------------------------------------------------------- +SRB_RescanPort ends +;------------------------------------------------------------------------------- +PSRB_RescanPort typedef PTR SRB_RescanPort + + +;+-----------------------------------------------------------------------------+ +;| %%% SRB - GET/SET TARGET TIMEOUTS SC_GETSET_TIMEOUTS (8) %%% | +;+-----------------------------------------------------------------------------+ +SRB_GetSetTimeouts struct 1t +;------------------------------------------------------------------------------- +SRB_Cmd BYTE ? ; w: ASPI command code = SC_GETSET_TIMEOUTS +SRB_Status BYTE ? ; r: ASPI command status byte +SRB_HaId BYTE ? ; w: ASPI host adapter number +SRB_Flags BYTE ? ; 0; SCSI request flags - undef +SRB_Hdr_Rsvd DWORD ? ; 0: reserved +SRB_Target BYTE ? ; w: target's SCSI ID +SRB_Lun BYTE ? ; w: target's LUN number +SRB_Timeout DWORD ? ; w: timeout in half seconds +;------------------------------------------------------------------------------- +SRB_GetSetTimeouts ends +;------------------------------------------------------------------------------- +PSRB_GetSetTimeouts typedef PTR SRB_GetSetTimeouts + + +;+-----------------------------------------------------------------------------+ +;| %%% Iomega Sense Data %%% | +;+-----------------------------------------------------------------------------+ +IOMEGA_SENSE_DATA struct 1t +;------------------------------------------------------------------------------- +ISD_ErrorCode BYTE ? ; 70h or 71h +ISD_reserved_0 BYTE ? +ISD_SenseKey BYTE ? +ISD_Information DWORD ? +ISD_AdditionalSenseLen BYTE ? ; always 11h +ISD_reserved_1 DWORD ? +ISD_ASC BYTE ? +ISD_ASCQ BYTE ? +ISD_reserved_2 BYTE ? +ISD_SKSV BYTE ? +ISD_FormatProgress WORD ? +ISD_CurrentTrack WORD ? +ISD_Interleave BYTE ? ; always 01 +ISD_AcquireTrack WORD ? +ISD_RetryCount BYTE ? +ISD_RetryPhase BYTE ? +;------------------------------------------------------------------------------- +IOMEGA_SENSE_DATA ends + + +ScsiRequestBlock UNION +;------------------------------------------------------------------------------- +hai SRB_HAInquiry <> +gdt SRB_GDEVBlock <> +abort SRB_Abort <> +io SRB_ExecSCSICmd <> +busreset SRB_BusDeviceReset <> +gdi SRB_GetDiskInfo <> +rsb SRB_RescanPort <> +gst SRB_GetSetTimeouts <> +;------------------------------------------------------------------------------- +ScsiRequestBlock ENDS + +;------------------------ Mode Sense / Select Page ID's ------------------------ + +ERROR_RECOVERY_PAGE equ 01h +CACHING_PAGE equ 08h +MODES_OF_OPERATION equ 2Fh + +;------------------------ GRC SCSI COMMAND RETURN CODES ------------------------ + +DEFECT_LIST_READ_ERROR equ 001C0003h +LBA_TOO_LARGE equ 00210005h ; accessed a non-exist LBA +MEDIA_CHANGE_CODE equ 00280006h ; media was changed +INCOMPATIBLE_MEDIA equ 00300002h ; 2Gb / 1Gb combo on "Read Defects" +MEDIA_NOT_PRESENT equ 003A0002h +MEDIA_NOT_PRESENT equ 003A0002h +DRIVE_COMING_READY equ 00040102h +SCSI_CMD_TIMED_OUT equ 00FFFF00h +BUFFER_TOO_BIG equ 00FFFFE6h +MANUAL_INTERRUPTION equ 0FFFFFFFFh + +;-/////////////////////////////////////////////////////////////////////////////- + diff --git a/x86-asm-source/MACROS.INC b/x86-asm-source/MACROS.INC new file mode 100644 index 0000000..c892e6d --- /dev/null +++ b/x86-asm-source/MACROS.INC @@ -0,0 +1,50 @@ +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ macros.inc by: Steven M. Gibson created: 04/03/98 ³ +;ÔÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ; +pagectrl = 0 ; initialize static globals used by fancy macros +crntpage = -1 + + +varzero MACRO p1:REQ +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + invoke FillMemory, ADDR p1, SIZEOF p1, NULL +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + ENDM + +ZeroASPI MACRO +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + invoke ZeroMemory, ADDR ASPI_CmdBlock, SIZEOF ASPI_CmdBlock +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + ENDM + +;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ PAGECTL macro ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ +; pagectl PAGE_ID, STYLE, (CTRL_CONST), (hWnd) +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +pagectl MACRO p1:REQ, p2:REQ, p3, p4:= +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + IF (p1 EQ crntpage) + pagectrl = pagectrl + 1 + ELSE + pagectrl = 0 + crntpage = p1 + ENDIF + + DWORD hMainWnd, ((p2 SHL 16) + (p1 shl 8) + pagectrl), p4 + + IFNB +p3 equ ((p1 shl 8) + pagectrl) + ENDIF +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + ENDM + + +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ERRCODE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +errcode MACRO p1:REQ, p2:REQ +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +.RADIX 16 + dd p1 +.RADIX 10 + db p2,0 +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + ENDM + diff --git a/x86-asm-source/MAKEFILE b/x86-asm-source/MAKEFILE new file mode 100644 index 0000000..5d3e038 --- /dev/null +++ b/x86-asm-source/MAKEFILE @@ -0,0 +1,87 @@ +PROJECT = tip +FULLNAME = tip +OBJ_CORE = tip.obj font.obj rtf.obj sectors.obj +RESOURCES = tip.ico + +ALL: $(PROJECT).exe + +#ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +#³ Assembler and Linker Options ³ +#ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ + +# LinkerOptions = /debug +# AssemblerOptions = /c /Cx /coff /Zd /Zi /nologo + +AssemblerOptions = /c /Cx /coff /nologo +LinkerOptions = + +#ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +#³ Build Rule for Main Module ³ +#ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +tip.obj : tip.asm aspi.asm new.asm tip.dat tip.txt makefile macros.inc + ML $(AssemblerOptions) tip.asm + +#ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +#³ Build Rule for Compressed Modules ³ +#ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +font.asm : font.bmp + compress font.bmp FontBitmapImage >font.asm + +#ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +#³ Build Rule for Compressed Modules ³ +#ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +rtf.asm : rtf.rtf + compress rtf.rtf RTF_Data >rtf.asm + +#ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +#³ Build Rule for Compressed Modules ³ +#ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +sectors.asm : sectors.bin + compress sectors.bin SECTOR_Data >sectors.asm + +#ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +#³ Inference Rule for Updating Object Files ³ +#ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +.asm.obj: + ML /c /coff /nologo $< + +#ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +#³ Inference Rule for Updating Resource Files ³ +#ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +.rc.res: + RC $< + +#ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +#³ Build Rule for Executable ³ +#ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +$(PROJECT).exe: $(OBJ_CORE) $(OBJ_MORE) $(PROJECT).res + LINK $(LinkerOptions) @<nul + POSTUPX RELEASE\$(FULLNAME).exe + CHECKSUM RELEASE\$(FULLNAME).exe + WAV c:\winnt\media\click.wav +#ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + diff --git a/x86-asm-source/NEW.ASM b/x86-asm-source/NEW.ASM new file mode 100644 index 0000000..1ac9be1 --- /dev/null +++ b/x86-asm-source/NEW.ASM @@ -0,0 +1,2 @@ +compress sectors.bin SECTOR_Data >sectors.asm + diff --git a/x86-asm-source/Off.bmp b/x86-asm-source/Off.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0ca6a4234ace606cc73533b2236aeb8e4840add3 GIT binary patch literal 206 zcmZ9EF%H8p3^acYkTMyce6o=042fd&2<;@}?^5xdiks{9FGO%J JxrZoTpfCD)N=yI% literal 0 HcmV?d00001 diff --git a/x86-asm-source/On.bmp b/x86-asm-source/On.bmp new file mode 100644 index 0000000000000000000000000000000000000000..74bc519401ddbcf66a3761ef7f2900a042c18d6d GIT binary patch literal 206 zcmYj}F%H5o5Cj(#DGHGg;sunvgPxveI1SfO_zARI`74&_c?(@clVfdz#QAn-?X!J4 zKhf$c9HsHA6}mdO$RFFLopMpD2&fTbgIp0gXR!>tHrz{+w91jp%x4RLInyi#lIf3w e_FUE&(wlri^vXaz_}#nhVc@-=Hu?{}g#$j(0zC)- literal 0 HcmV?d00001 diff --git a/x86-asm-source/Proto.rc b/x86-asm-source/Proto.rc new file mode 100644 index 0000000..ac03a8f --- /dev/null +++ b/x86-asm-source/Proto.rc @@ -0,0 +1,97 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_PROPPAGE_LARGE DIALOG DISCARDABLE 0, 0, 309, 205 +STYLE WS_CHILD | WS_CAPTION +FONT 8, "MS Sans Serif" +BEGIN + LTEXT "TODO: layout property page",IDC_STATIC,73,74,90,8 + CONTROL "Tab1",IDC_TAB1,"SysTabControl32",TCS_FIXEDWIDTH | + TCS_FOCUSNEVER,13,7,283,165 +END + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + IDD_PROPPAGE_LARGE, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 302 + TOPMARGIN, 7 + BOTTOMMARGIN, 198 + END +END +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/x86-asm-source/RTF-save.RTF b/x86-asm-source/RTF-save.RTF new file mode 100644 index 0000000..83d2687 --- /dev/null +++ b/x86-asm-source/RTF-save.RTF @@ -0,0 +1,584 @@ +{\rtf1\ansi\deff0\deftab720{\fonttbl{\f0\fswiss MS Sans Serif;}{\f1\froman\fcharset2 Symbol;}{\f2\fswiss\fprq2 Arial;}{\f3\froman Times New Roman;}{\f4\fmodern\fprq1 Courier New;}{\f5\fnil Symbol;}} +{\colortbl\red0\green0\blue0;\red128\green0\blue0;\red0\green0\blue128;\red128\green0\blue128;\red0\green128\blue128;\red128\green128\blue128;\red255\green0\blue0;\red0\green128\blue0;} +\deflang1033\pard\plain\f2\fs24 [instruct] +\par \pard\qc\plain\f2\fs44\b\ul Very Important Information\plain\f2\fs44\b +\par \plain\f2\fs16 +\par \plain\f2\fs28 You \plain\f2\fs28\cf1\b\ul MUST\plain\f2\fs28 take time to read through this +\par \plain\f2\fs28\cf1\b CRUCIAL OPERATING INFORMATION +\par \plain\f2\fs28 or this program's test results will be +\par erroneous and meaningless.\plain\f2\fs22 +\par \pard\plain\f2\fs22 +\par \plain\f2\fs22\cf2\b Background:\plain\f2\fs22 +\par Iomega* Zip* and Jaz* drives cause \plain\f2\fs22\b 'Click Of Death' \plain\f2\fs22 by incorrectly writing to their removable media. This miswriting can damage the user's data, the factory-written low-level formatting, the head's positioning servo information, and the proprietary \plain\f2\fs22\b\i Z-Tracks\plain\f2\fs22 that are used internally to manage and maintain the Zip and Jaz drive's cartridge data. +\par +\par \plain\f2\fs22\b The clicking sound itself\plain\f2\fs22 is nothing more than the sound of the heads being retracted from the cartridge into the drive then immediately reinserted. This deliberate strategy is employed by the drive when it is having trouble locating, reading, or writing any of the cartridge's data. This removal and reinsertion of the heads recalibrates the head positioning mechanism, 'scrubs' the heads to remove excessive oxide deposits, and eliminates any electrostatic charge build-up on the heads. +\par +\par \pard\qc\plain\f2\fs22\cf1\b It is important for you to understand that the clicking +\par sound itself is \plain\f2\fs22\cf1\b\ul NOT\plain\f2\fs22\cf1\b the problem. The clicking is just +\par an audible indication of a drive that is having trouble +\par accessing the data on the cartridge. +\par \pard\plain\f2\fs22 +\par Incidents of Click Death have been linked to bad external power supplies, loose power connectors, excessive magnetic oxide build-up on the drive's heads, magnetic and radio interference from nearby sources, media damage from excessive wear or mistreatment, and a seemingly endless array of internal electrical and mechanical problems from causes ranging from rough handling through defective original manufacturing. +\par +\par \plain\f2\fs22\cf2\b Why is this happening all of a sudden?:\plain\f2\fs22 +\par An unbiased appraisal of recent experience with the large population of Zip -- and to a lesser extent Jaz -- drives, leads to the inescapable -- and unfortunate -- conclusion that recently manufactured Iomega products are experiencing a significantly higher incidence of problems -- both immediately after purchase and after relatively short term use in the field -- than the older versions of the Zip and Jaz drive products which established their reputation for quality and reliability. +\par +\par The \plain\f2\fs22\b Iomega Zip and Jaz\plain\f2\fs22 section of my web site contains a \plain\f2\fs22\b Q&A\plain\f2\fs22 area where I am logging many of my interactions with Iomega's customers. Though these experiences are anecdotal in nature, upon reading them one gets the clear sense that something must have gone very wrong as Iomega attempted to scale up their Zip and Jaz drive manufacturing in order to meet the huge demand \plain\f2\fs22\ul for what were originally very reliable drives\plain\f2\fs22 . +\par +\par \plain\f2\fs22\b I have a lot of respect for the design of the Zip and Jaz drives.\plain\f2\fs22 The personal computing industry \plain\f2\fs22\b desperately needs a \plain\f2\fs22\b\ul STANDARD\plain\f2\fs22 high-quality, high-capacity removable media solution -- rather than an industry fragmented by incompatible storage formats. Iomega was the first with a really terrific solution, and has had the opportunity to unite the industry through the strength of the their products' design. But it remains to be seen, as many new competitors enter this marketplace, whether Iomega will be able to cure what appear to be manufacturing quality-control problems, and hold the industry together with a single strong universal standard. +\par \plain\f2\fs22\b\i +\par \pard\qc\plain\f2\fs36\cf1\b\i I sincerely hope they can!\plain\f2\fs36\cf1 +\par \pard\plain\f2\fs22\cf2\b +\par About This Program:\plain\f2\fs22 +\par I wrote the first version of \plain\f2\fs22\b\i SpinRite\plain\f2\fs22 -- my well-known mass storage data recovery and maintenance utility -- more than eleven years ago. At the time of this writing, SpinRite is at version 5.0 and remains without peer in the industry. It was with those years of experience in mass storage maintenance that I set out to \plain\f2\fs22\b "cure"\plain\f2\fs22 whatever the problem was with these newer Iomega Zip and Jaz drives. But I soon learned, as you have seen above, that \plain\f2\fs22\b\ul there was no single cause for these problems\plain\f2\fs22 because so many different things were apparently going wrong with the Iomega drives. +\par +\par \pard\qc\plain\f2\fs22\cf2\b So instead, \plain\f2\fs22\cf2\b\ul I decided to create two programs\plain\f2\fs22\cf2\b to address the PC user's need for reliable removable mass storage +\par . . . while remaining with the Iomega standard. +\par \pard\plain\f2\fs22 +\par \plain\f2\fs22\cf1\b\ul Program 1\plain\f2\fs22\cf1\b . \plain\f2\fs22 This \plain\f2\fs22\b\i 'Trouble In Paradise'\plain\f2\fs22 freeware program is the first of the two. Since no one can 'cure' the problems which may afflict any Zip or Jaz drive without warning, the first step to assuring long data life is \plain\f2\fs22\b early detection of the POTENTIAL for the problem\plain\f2\fs22 . For example, although we can't cure cancer, early detection of cancer's signs in our bodies allows us to take extra measures to assure our survival. \plain\f2\fs22\ul Similar early detection of 'Click Death' is exactly what I've created here in Program 1. +\par \plain\f2\fs22 +\par \plain\f2\fs22\cf1\b\ul Program 2\plain\f2\fs22\cf1\b . \plain\f2\fs22 The second program, to follow this one, will be an inexpensive (but not free) tool allowing any Iomega drive user to maintain and manage \plain\f2\fs22\ul their entire collection of Zip and Jaz cartridges\plain\f2\fs22 while individually monitoring each cartridge's condition and receiving early warning of impending trouble. Please see my web site at \plain\f2\fs22\b http://grc.com\plain\f2\fs22 for news of the status of this second Program 2 \plain\f2\fs22\b . . .\plain\f2\fs22 as well as for more extensive background information about this whole issue. +\par +\par \plain\f2\fs22\cf3 (You are also invited to join our \plain\f2\fs22\cf3\b COD mailing list\plain\f2\fs22\cf3 to receive a short notice whenever something significant to Iomega Click Of Death occurs -- and to be informed when my next program (\plain\f2\fs22\cf3\b Program 2\plain\f2\fs22\cf3 ) is ready. To add yourself to this mailing list, please visit \plain\f2\fs22\cf3\b http://grc.com/codmailing.htm\plain\f2\fs22\cf3 ) +\par \plain\f2\fs22 +\par \plain\f2\fs22\cf2\b An Important Note About One Click Of Death Myth:\plain\f2\fs22 +\par There has been widespread rumor that 'Click Of Death' acts as some sort of contagion, able to be spread from one drive to another by a 'contaminated' Click Of Death afflicted cartridge. +\par +\par \plain\f2\fs22\b This actually can occur\plain\f2\fs22 , but only in \plain\f2\fs22\b\ul extremely rare cases\plain\f2\fs22 of \plain\f2\fs22\b\ul massive physical damage\plain\f2\fs22 to the mylar disk spinning inside a Zip cartridge. In these very rare -- \plain\f2\fs22\i but absolutely verified cases\plain\f2\fs22 -- the bent and torn mylar disk catches and 'beheads' any Zip drive attempting to load its heads into the cartridge. +\par +\par Please see the Iomega pages of my web site for detailed discussions \plain\f2\fs22\b\i\ul and photos!\plain\f2\fs22\b \plain\f2\fs22 of this rare and bizarre occurrence. +\par +\par However, for the most part, \plain\f2\fs22\b Zip users should not be concerned\plain\f2\fs22 about the possibility of one troubled Zip drive somehow 'infecting' or destroying another one through a 'disease carrier' cartridge. \plain\f2\fs22\b It \plain\f2\fs22\b\ul can\plain\f2\fs22\b definitely happen -- \plain\f2\fs22 but then, you can also be struck by lightning in your sleep. So the possibility should not occupy too much of your waking concern. +\par +\par What actually \plain\f2\fs22\b does\plain\f2\fs22 happen -- which has created and maintain this unfortunate myth -- is that a Click Of Death drive \plain\f2\fs22\ul miswrites to its cartridge making it start clicking\plain\f2\fs22 . Then the worried user takes this cartridge to another drive and \plain\f2\fs22\b that other drive also starts clicking!\plain\f2\fs22 But it does so only because it is now unable to read the damaged cartridge. \plain\f2\fs22\b\i\ul This does not mean that the second drive is now damaged!\plain\f2\fs22 Only the \plain\f2\fs22\ul cartridge\plain\f2\fs22 damaged by the first drive is in trouble. It is not the second drive's fault that it's unable to read the cartridge that was actually damaged by its use in the first drive. +\par +\par \plain\f2\fs22\cf2\b What Is This 'Trouble In Paradise' Program?:\plain\f2\fs22 +\par This 32-bit Windows freeware utility program, which I have named Trouble In Paradise (TIP), is a tightly monitored, non-destructive, data pattern surface tester. This program reads and writes every sector of data on the drive with surface and drive testing data patterns \plain\f2\fs22\b\ul while preserving all data originally contained on the cartridge\plain\f2\fs22 . Your data is preserved while allowing the function of the drive, and the data surfaces of the cartridge's disk(s), to be fully exercised under closely monitored conditions. +\par +\par Even if this process wasn't being used to locate potential drive and cartridge troubles, running TIP upon your cartridges from time to time \plain\f2\fs22\b will help to keep them in TIP top shape\plain\f2\fs22 . The process of reading, rewriting, and refreshing the data in every sector of the cartridge is \plain\f2\fs22\b absolutely safe \plain\f2\fs22 and is good for them, since it allows any slowly developing trouble to be spotted and handled safely before the data becomes unreadable. (Note that the second program in this series, mentioned above, will go much further in this direction, being specifically designed to support and monitor the long-term maintenance of your removable data cartridges.) +\par +\par Amazingly, throughout the entire development of this program -- from the first moment that it began working -- \plain\f2\fs22\b Not one single byte of data was ever damaged on any of my test cartridges!\plain\f2\fs22 \plain\f2\fs22\i I believe that using TIP is extremely safe\plain\f2\fs22 , and that you'll find TIP to be a useful tool to add to your personal computing experience. +\par +\par \plain\f2\fs18\cf4\b\ul Please Note\plain\f2\fs18\cf4\b :\plain\f2\fs18\cf4 \plain\f2\fs18\cf4\b Non-ATAPI Internal IDE Zip\plain\f2\fs18\cf4 drives did \plain\f2\fs18\cf4\b NOT\plain\f2\fs18\cf4 support the standard ATAPI / SCSI software interface, \plain\f2\fs18\cf4\ul so this program can not operate upon those IDE ZIP drives at all\plain\f2\fs18\cf4 . I really wish it could, but those drives conceal ALL special Iomega information. TIP does operate upon ALL OTHER internal and external ZIP and Jaz drives. +\par \plain\f2\fs22 +\par \plain\f2\fs36\cf2\b How to Use This Program: +\par \plain\f2\fs22\cf2\b +\par \plain\f2\fs18\cf3\b Please Note\plain\f2\fs18\cf3 : The contents of any of this program's pages can be copied to the Windows' clipboard at any time by pressing the "Copy" button below. +\par Graphical pages will be copied as images and scrolling text pages (like this one) will be copied as text. You can retain the text formatting by pasting the clipboard into the Windows Wordpad, or Word. If you wish to remove or ignore the formatting, paste into Notepad. +\par +\par You are completely free to share and redistribute any of this information, but providing a link to our web site would be appreciated. \plain\f4\fs18\cf0 http://grc.com\plain\f2\fs18\cf3 +\par \plain\f2\fs22\cf2\b __________________________________________________ +\par \plain\f2\fs22 +\par The trick for properly using TIP for diagnosing drive and/or cartridge problems lies in interpreting the results. +\par +\par \pard\qc\plain\f2\fs22\cf1\b You'll find that I've prepared extensive result-driven explanations which you will automatically receive when any test run has concluded. But a bit of preparation and background is still necessary before you begin: . . . +\par \pard\plain\f2\fs22 +\par \plain\f2\fs22\ul In order for this program to find no problems\plain\f2\fs22 , \plain\f2\fs22\b both\plain\f2\fs22 the Zip drive \plain\f2\fs22\b and\plain\f2\fs22 the Zip cartridge must be in perfect working condition. If either the drive or the cartridge is damaged \plain\f2\fs22\b in any way\plain\f2\fs22 this very sensitive program will show you the trouble \plain\f2\fs22\b . . .\plain\f2\fs22 but in many mild cases of trouble, TIP will be unable to determine \plain\f2\fs22\b which\plain\f2\fs22 of the two components -- the drive or the cartridge -- is actually the source of the problems. This is the bit of detective work you'll need to pursue, aided by feedback from TIP. +\par +\par One way to think of it is that with a drive that's known to be good, you can use TIP to test the condition of unknown cartridges. Or, with a cartridge that's known to be (initially) good, TIP can test a drive whose condition is unknown. Note that testing an initially good cartridge on a truly bad 'Click Of Death' drive \plain\f2\fs22\ul can create damage on the cartridge\plain\f2\fs22 , but I have deliberately designed TIP so that even in these cases your data will be safe, and you'll see this happening as the test runs so you can stop the test before the damage becomes extensive. +\par +\par The 'detective work' is not really any big deal, since it only entails reading through the result analysis that will be presented after each test, and perhaps running the test again with the same or a different cartridge, or -- if possible -- finding another drive to test with the same cartridge \plain\f2\fs22\b . . .\plain\f2\fs22 depending upon the outcome analysis. +\par +\par Aided by TIP, if you're not sure whether the drive or cartridge is causing the trouble, changing one or the other -- and seeing what happens then -- will allow you to develop a much deeper feeling for what's going on within your system than you've ever been able to get before. And you'll find that after a few experiences you'll get the hang of it and will be able to accurately judge what's happening from the way the test runs. +\par +\par \plain\f2\fs22\cf2\b Thank you very much for taking the time to read through all this material! . . . \plain\f2\fs22 I know you're probably anxious to get to it, but you needed to first be equipped with the essence of what I've learned through my research into these confusing, troubling, but very important issues. Also, \plain\f2\fs22\ul don't forget my web site\plain\f2\fs22 , since it will always contain more recent information, data, and experience than can be packaged into a static computer program such as this. +\par +\par So \plain\f2\fs22\b . . .\plain\f2\fs22 with \plain\f2\fs22\b ALL\plain\f2\fs22 of that said, please insert a cartridge into whichever Iomega drive you want to use and proceed to the \plain\f2\fs22\b Next\plain\f2\fs22 panel \plain\f2\fs22\b . . . +\par +\par \pard\qc\plain\f2\fs16\i *Iomega, Zip, and Jaz are trademarks of Iomega Corporation. +\par \pard\plain\f2\fs24 [noaspi] +\par \pard\qc\plain\f2\fs36\cf1\b This System's ASPI Drivers are +\par Not Installed or Not Functioning.\plain\f2\fs22 +\par \plain\f2\fs16 +\par \plain\f2\fs22\cf2\b To use this program, which communicates with mass storage devices through the A.S.P.I. programming interface, you must first install operating system +\par support for the ASPI device driver layer.\plain\f2\fs22\cf0 +\par \pard\plain\f2\fs22\cf0 +\par \plain\f2\fs22\cf4\b Background:\plain\f2\fs22\cf0 +\par \plain\f2\fs22 The Windows operating environments include built-in support for the \plain\f2\fs22\b A\plain\f2\fs22 dvanced \plain\f2\fs22\b S\plain\f2\fs22 CSI \plain\f2\fs22\b P\plain\f2\fs22 rogramming \plain\f2\fs22\b I\plain\f2\fs22 nterface (ASPI) which allows peripheral vendors to create ASPI-compatible drivers for use in interfacing their equipment to the operating system. But this Windows system's ASPI drivers are apparently missing or not functioning correctly at the moment. +\par +\par Out of date or incorrectly installed ASPI drivers can be the cause of drives "missing" from the system, or not being "seen" by TIP. +\par +\par \plain\f2\fs22\cf4\b How did this happen?:\plain\f2\fs22 +\par Since ASPI layer drivers are readily available, and are frequently provided in haphazard fashion by peripheral vendors, Windows systems often wind up with obsolete, oddball, missing, or out-of-synch sets of ASPI driver files. +\par +\par \plain\f2\fs22\cf4\b So what do you do?:\plain\f2\fs22 +\par Since this turns out to be a frequently encountered problem that no one else is addressing, I decided to tackle it with another free software offering that assumes full responsibility for the problem, and cures it for anyone in one step (\plain\f2\fs22\b with full 'undo'\plain\f2\fs22 if things don't work out!). I built an all-in-one automatic ASPI driver layer analysis and updating tool called: \plain\f2\fs22\b ASPI ME\plain\f2\fs22 that is freely available for your downloading and use at the URL \plain\f2\fs22\b :\plain\f2\fs22 +\par +\par \pard\qc\plain\f4\fs24 ftp://grc.com/aspi_me.exe +\par \pard\plain\f2\fs22 +\par This small and tightly written program \plain\f2\fs22\b\i\ul incorporates\plain\f2\fs22 all of the most recent ASPI drivers for Windows 95/98 & NT inside itself and will analyze and instantly update any Windows system needing ASPI driver repair \plain\f2\fs22\b . . .\plain\f2\fs22 (like this one!) +\par +\par To receive the program you may enter the URL shown above into any web browser, or simply press the URL button below to initiate a transfer of this program into this computer. +\par +\par After running \plain\f2\fs22\b ASPI ME\plain\f2\fs22 \plain\f2\fs22\b . . .\plain\f2\fs22 so that it can 'ASPI YOU' \plain\f2\fs22\b . . .\plain\f2\fs22 restart Windows so that the new files will be loaded. Finally, re-run this Trouble In Paradise (TIP.EXE) program. +\par +\par You will not see this screen again, since your machine will then be using the latest and greatest ASPI drivers \plain\f2\fs22\b . . .\plain\f2\fs22 and will have a much better chance of functioning correctly. +\par +\par The \plain\f2\fs22\b ASPI ME\plain\f2\fs22 program, like this \plain\f2\fs22\b Trouble In Paradise\plain\f2\fs22 program, is also freeware which you are encouraged to freely share and distribute to anyone who might find it useful. +\par \plain\f2\fs24 [aspiver] +\par \pard\qc\plain\f2\fs36\cf1\b This System Might Benefit +\par from the ASPI ME Utility.\plain\f2\fs22 +\par \plain\f2\fs16 +\par \plain\f2\fs22\cf2\b Some problems with ASPI-driven peripherals +\par \plain\f2\fs22\cf2\b\i (like Zip and Jaz Drives!)\plain\f2\fs22\cf2\b \plain\f2\fs22\cf2\b\ul have been cured\plain\f2\fs22\cf2\b by +\par updating to a synchronized set of drivers.\plain\f2\fs22\cf0 +\par \pard\plain\f2\fs22\cf0 +\par \plain\f2\fs22\cf4\b Background:\plain\f2\fs22\cf0 +\par \plain\f2\fs22 The Windows operating environments include built-in support for the \plain\f2\fs22\b A\plain\f2\fs22 dvanced \plain\f2\fs22\b S\plain\f2\fs22 CSI \plain\f2\fs22\b P\plain\f2\fs22 rogramming \plain\f2\fs22\b I\plain\f2\fs22 nterface (ASPI) which allows peripheral vendors to create ASPI-compatible drivers for use in interfacing their equipment to the operating system. But this Windows system's ASPI drivers are apparently missing or not functioning correctly at the moment. +\par +\par Out of date or incorrectly installed ASPI drivers can be the cause of drives "missing" from the system, or not being "seen" by TIP. +\par +\par \plain\f2\fs22\cf4\b How did this happen?:\plain\f2\fs22 +\par Since ASPI layer drivers are readily available, and are frequently provided in haphazard fashion by peripheral vendors, Windows systems often wind up with obsolete, oddball, missing, or out-of-synch sets of ASPI driver files. +\par +\par \plain\f2\fs22\cf4\b So what do you do?:\plain\f2\fs22 +\par Since this turns out to be a frequently encountered problem that no one else is addressing, I decided to tackle it with another free software offering that assumes full responsibility for the problem, and cures it for anyone in one step (\plain\f2\fs22\b with full 'undo'\plain\f2\fs22 if things don't work out!). I built an all-in-one automatic ASPI driver layer analysis and updating tool called: \plain\f2\fs22\b ASPI ME\plain\f2\fs22 that is freely available for your downloading and use at the URL \plain\f2\fs22\b :\plain\f2\fs22 +\par +\par \pard\qc\plain\f4\fs24 ftp://grc.com/aspi_me.exe +\par \pard\plain\f2\fs22 +\par This small and tightly written program \plain\f2\fs22\b\i\ul incorporates\plain\f2\fs22 all of the most recent ASPI drivers for Windows 95/98 & NT inside itself and will analyze and instantly update any Windows system needing ASPI driver repair \plain\f2\fs22\b . . .\plain\f2\fs22 (like this one!) +\par +\par To receive the program you may enter the URL shown above into any web browser, or simply press the URL button below to initiate a transfer of this program into this computer. +\par +\par After running \plain\f2\fs22\b ASPI ME\plain\f2\fs22 \plain\f2\fs22\b . . .\plain\f2\fs22 so that it can 'ASPI YOU' \plain\f2\fs22\b . . .\plain\f2\fs22 restart Windows so that the new files will be loaded. Finally, re-run this Trouble In Paradise (TIP.EXE) program. +\par +\par You will not see this screen again, since your machine will then be using the latest and greatest ASPI drivers \plain\f2\fs22\b . . .\plain\f2\fs22 and will have a much better chance of functioning correctly. +\par +\par The \plain\f2\fs22\b ASPI ME\plain\f2\fs22 program, like this \plain\f2\fs22\b Trouble In Paradise\plain\f2\fs22 program, is also freeware which you are encouraged to freely share and distribute to anyone who might find it useful. +\par \plain\f2\fs24 [ppaver] +\par \pard\qc\plain\f2\fs44\cf1\b WOW! . . . Do I Have +\par \plain\f2\fs44\cf1\b\ul GREAT NEWS\plain\f2\fs44\cf1\b for YOU! +\par \plain\f2\fs16 +\par \plain\f2\fs22\cf2\b Very soon, your external Parallel Port Zip Drive will be running \plain\f2\fs22\cf2\b\ul more than 400% faster\plain\f2\fs22\cf2\b than it does right now! +\par \pard\plain\f2\fs22\cf0 +\par That's right! This Windows system is currently using \plain\f2\fs22\cf0\b an old, obsolete (and slow!) version\plain\f2\fs22\cf0 of the Iomega Parallel Port Driver (PPA3.MPD) which runs less than \plain\f2\fs22\cf0\ul one-quarter of the speed\plain\f2\fs22\cf0 of the latest driver! You can download and install the updated driver for \plain\f2\fs22\cf0\ul free\plain\f2\fs22\cf0 and instantly gain more than \plain\f2\fs22\cf0\b FOUR TIMES the performance\plain\f2\fs22\cf0 from your current external Zip drive! +\par +\par \plain\f2\fs22\cf4\b Background: +\par \plain\f2\fs22\cf0 I discovered this problem when 'Trouble In Paradise' (TIP) was having difficulty running on many existing external Zip systems. When I tracked down the problem, it turned out that TIP was attempting to transfer 64k bytes of data at a time (for good TIP-testing performance) \plain\f2\fs22\cf0\ul but those external Zip systems \plain\f2\fs22\cf0\b\ul (like this one right here!)\plain\f2\fs22\cf0\ul could only handle a maximum transfer of 8k bytes at a time\plain\f2\fs22\cf0 ! This meant that any software trying to read or write files to the drive would need to break up the data into eight times as many smaller pieces in order to squeeze the data out through the parallel port! +\par +\par Well, of course, I enhanced TIP immediately so that it \plain\f2\fs22\cf0\b would\plain\f2\fs22\cf0 work on performance-crippled parallel port systems like this one \plain\f2\fs22\cf0\b . . .\plain\f2\fs22\cf0 but I also added this information page so you'd know what TIP had discovered here, and \plain\f2\fs22\cf0\b how you could get your system rev'ed up to 400% more Zip Drive speed!\plain\f2\fs22\cf0 +\par +\par \plain\f2\fs22\cf4\b What do you need to do? +\par \plain\f2\fs22\cf0 Although you may only need one relatively small (53k for Win95/98 or 44k for NT) driver file changed, it would probably be wisest to update your \plain\f2\fs22\cf0\b entire set\plain\f2\fs22\cf0 of Iomega files \plain\f2\fs22\cf0\b . . .\plain\f2\fs22\cf0 though this will take some downloading time. +\par +\par The newest version of the Iomega files is 5.51. You can easily determine the version of your existing Iomega files by looking at their "time of day" which encodes their version number for easy viewing. (For example, the newest updated files show that they were made at 5:51 am) +\par +\par The updated Iomega files are located on Iomega's FTP server at the following URL addresses: +\par +\par \plain\f2\fs22\cf4\b For Windows 95/98: +\par \plain\f2\fs22\cf5 For the whole set of version 5.51 Iomega Tools95 files: +\par \plain\f4\fs18\cf2 ftp://ftp.iomega.com/pub/english/w95_551.exe (2,437k)\plain\f2\fs22\cf0 +\par \plain\f2\fs22\cf5 For just the basic Iomega version 5.51 Win95/98 driver files: +\par \plain\f4\fs18\cf2 ftp://ftp.iomega.com/pub/english/w95drvr.exe (740k) +\par \plain\f2\fs22\cf0 +\par \plain\f2\fs22\cf4\b For Windows NT:\plain\f2\fs22\cf0 +\par \plain\f2\fs22\cf5 For the whole set of version 5.51 Iomega Tools files: +\par \plain\f4\fs18\cf2 ftp://ftp.iomega.com/pub/english/wnt_551.exe (2,384k)\plain\f2\fs22\cf0 +\par \plain\f2\fs22\cf5 For just the basic Iomega version 5.51 WinNT driver files: +\par \plain\f4\fs18\cf2 ftp://ftp.iomega.com/pub/english/wntdrvr.exe (718k) +\par \plain\f2\fs22\cf0 +\par To simplify things for you, I've set up the two buttons below to \plain\f2\fs22\cf0\ul automatically choose the proper operating system version of the files\plain\f2\fs22\cf0 , and start the download from Iomega's FTP server. So you only need to decide whether you want the whole Tools file set (probably a good idea) or just the updated driver files (to save on download time.) +\par +\par No matter which you choose, simply run the resulting file. +\par +\par It will unpack the replacement files into your system's "temp" directory. Then you need to run the \plain\f2\fs22\cf0\b SETUP.EXE\plain\f2\fs22\cf0 program located there to install the drivers. After restarting your system, you'll be all set with the latest and greatest files \plain\f2\fs22\cf0\b . . .\plain\f2\fs22\cf0 and your parallel port Zip drive will be running more than FOUR TIMES faster than it ever has before! +\par +\par \plain\f2\fs22\cf1 (You might want to measure the transfer time of a large file \plain\f2\fs22\cf1\b before\plain\f2\fs22\cf1 you perform the upgrade, then again afterward, to see for yourself how much your own Zip drive's performance has increased!) +\par \plain\f2\fs22\cf0 +\par \plain\f2\fs22\cf4 Also note that you will \plain\f2\fs22\cf4\ul not\plain\f2\fs22\cf4 see this screen again after you upgrade since you'll then be using a parallel port driver that's capable of transferring 64k byte blocks for much greater performance! Therefore, if you wish to save this text for any reason, you should \plain\f2\fs22\cf4\ul press the \plain\f2\fs22\cf4\b\ul Copy button\plain\f2\fs22\cf4\ul below\plain\f2\fs22\cf4 to copy the contents of this window into your system's clipboard, then paste it into Notepad, Wordpad, or any other text container where it can be saved, eMailed, or shared with others. +\par \plain\f2\fs22\cf0 +\par Best of luck to you, and I'm glad that I was able to help provide this significant performance boost for your system! Remember that this "Trouble In Paradise" program is freeware and that I encourage its distribution and sharing. You are invited to help me spread the word of this program's existence! +\par +\par \pard\qc\plain\f2\fs16\i *Iomega, Zip, and Jaz are trademarks of Iomega Corporation. +\par \pard\plain\f2\fs24 [trouble] +\par \pard\qc\plain\f2\fs44\cf1\b TIP has Not Found +\par Any Compatible Drives. +\par \plain\f2\fs16 +\par \plain\f2\fs22\cf2\b PLEASE NOTE: This program is specifically +\par designed for use with Iomega Corporation's ZIP +\par and JAZ removable media mass storage devices. +\par +\par \pard\plain\f2\fs22\cf0 This Trouble In Paradise (TIP) program has been specifically designed for use with Zip and Jaz drives. This has allowed it to take advantage of many features specific and unique to these drives. Therefore it can NOT operate on other types of drives made by other manufacturers. +\par +\par \plain\f2\fs22\cf0\b Since TIP uses the ASPI interface, it may also fail to operate on some of the older non-ATAPI IDE ZIP drives. +\par \plain\f2\fs22\cf0 +\par \plain\f2\fs22\cf0\b If you are having trouble with any other drive\plain\f2\fs22\cf0 , or wishing to maintain or recover drive data, our commercial SpinRite disk utility product ($89) is the industry's leading general purpose hard disk maintenance, repair, and recovery tool. SpinRite functions with \plain\f2\fs22\cf0\b all\plain\f2\fs22\cf0 drives of any make and model. Please see my web site for full information and purchasing details. +\par +\par If you believe that this program \plain\f2\fs22\cf0\b should\plain\f2\fs22\cf0 be seeing a drive that it is not, you can try updating this system's ASPI drivers using my automatic \plain\f2\fs22\cf0\b ASPI ME\plain\f2\fs22\cf0 program. ASPI ME is\plain\f2\fs22 another free software offering that updates and maintains a system's ASPI device driver layer in one step (\plain\f2\fs22\b with full 'undo'\plain\f2\fs22 if things don't work out.). ASPI ME is freely available for your downloading and use at the URL \plain\f2\fs22\b :\plain\f2\fs22 +\par +\par \pard\qc\plain\f4\fs24 ftp://grc.com/aspi_me.exe +\par \pard\plain\f2\fs22 +\par This small and tightly written program \plain\f2\fs22\b\i\ul incorporates\plain\f2\fs22 all of the most recent ASPI drivers for Windows 95/98 & NT inside itself and will analyze and instantly update any Windows system needing ASPI driver repair \plain\f2\fs22\b . . .\plain\f2\fs22 +\par +\par To receive the program you may enter the URL shown above into any web browser, or simply press the URL button below to initiate a transfer of this program into this computer. +\par +\par After running \plain\f2\fs22\b ASPI ME\plain\f2\fs22 \plain\f2\fs22\b . . .\plain\f2\fs22 so that it can 'ASPI YOU' \plain\f2\fs22\b . . .\plain\f2\fs22 restart Windows so that the new files will be loaded. Finally, re-run this Trouble In Paradise (TIP.EXE) program. +\par +\par You will not see this screen again, since your machine will then be using the latest and greatest ASPI drivers \plain\f2\fs22\b . . .\plain\f2\fs22 and will have a much better chance of functioning correctly. +\par +\par The \plain\f2\fs22\b ASPI ME\plain\f2\fs22 program, like this \plain\f2\fs22\b Trouble In Paradise\plain\f2\fs22 program, is also freeware which you are encouraged to freely share and distribute to anyone who might find it useful. +\par \plain\f2\fs22\cf0 +\par \pard\qc\plain\f2\fs16\i *Iomega, Zip, and Jaz are trademarks of Iomega Corporation. +\par \pard\plain\f2\fs24 [defect] +\par \pard\qc\plain\f2\fs44\b\ul Z-Track Failure!\plain\f2\fs44\b +\par \plain\f2\fs16 +\par \plain\f2\fs28\cf1 The Drive Reports that it has been +\par completely \plain\f2\fs28\cf6\ul unable to access \plain\f2\fs28\cf6\b\ul ANY\plain\f2\fs28\cf1 +\par of this Cartridge's Four "Z" Tracks. +\par \pard\plain\f2\fs22 +\par \plain\f2\fs22\cf2\b Background:\plain\f2\fs22 +\par Zip and Jaz drives are completely dependent upon private information stored in four redundant hidden cartridge disk tracks known as \plain\f2\fs22\b\i Z-tracks\plain\f2\fs22 . +\par +\par \plain\f2\fs22\cf2\b Consequence:\plain\f2\fs22 +\par When all four of these \plain\f2\fs22\b Z-tracks\plain\f2\fs22 have been damaged by a 'Click Of Death' defective writing drive, all drives (whether they are good or bad) will refuse to access \plain\f2\fs22\cf1\b\ul ANY\plain\f2\fs22 of the data contained within the cartridge \plain\f2\fs22\b . . .\plain\f2\fs22 \plain\f2\fs22\cf1\b\ul and ALL information is lost forever!\plain\f2\fs22 +\par +\par \plain\f2\fs22\cf2\b Recourse:\plain\f2\fs22 +\par \pard\qc\plain\f2\fs22\b +\par \plain\f2\fs28\b There is \plain\f2\fs28\b\ul NO KNOWN MEANS\plain\f2\fs28\b of +\par repairing or reconstituting a +\par cartridge's dead Z-tracks. +\par \plain\f2\fs22 +\par \pard\plain\f2\fs22 Perhaps Iomega can bring a cartridge's Z-tracks back to life. However, I have been told over and over by engineers within Iomega that the Z-tracks are completely inaccessible to external software utilities and that \plain\f2\fs22\b there's nothing anyone can do\plain\f2\fs22 to access the data on any cartridge that has had all four of its Z-tracks damaged. +\par +\par Depending upon the precise nature of the Z-track damage, I would think that there's an \plain\f2\fs22\ul outside chance\plain\f2\fs22 that another drive \plain\f2\fs22\ul might\plain\f2\fs22 be able to read at least one of the Z-tracks, or that even \plain\f2\fs22\ul this\plain\f2\fs22 drive might. Since Z-tracks are initially read upon insertion of the cartridge, you must eject and re-insert the cartridge hoping to eventually get one Z-track recognized. +\par +\par However, \plain\f2\fs22\ul if this drive\plain\f2\fs22 is the one which is believed to have damaged the tracks in the first place, then doing so won't repair the damage. You \plain\f2\fs22\ul must\plain\f2\fs22 use a known-good drive in order for it to re-write the bad Z-tracks, thus making the cartridge's data once again available. +\par +\par \plain\f2\fs22\b But be sure you understand: \plain\f2\fs22 This might \plain\f2\fs22\ul only\plain\f2\fs22 work if you are \plain\f2\fs22\ul extremely lucky\plain\f2\fs22 and manage to briefly get a drive to successfully read at least one of this cartridge's Z-tracks. +\par +\par \plain\f2\fs22\cf2\b And now:\plain\f2\fs22 +\par TIP can do nothing further with this cartridge in its present condition. Please eject it now and try working with another cartridge, or try this cartridge with this program on another drive to induce that drive to possibly effect Z-track repair. +\par +\par \pard\qc\plain\f2\fs16\i *Iomega, Zip, and Jaz are trademarks of Iomega Corporation. +\par \pard\plain\f2\fs24 [locked] +\par \pard\qc\plain\f2\fs44\b This Cartridge is Locked +\par \plain\f2\fs16 +\par \plain\f2\fs28\cf1 Since this program reads and writes, +\par the removable cartridge must be +\par unlocked for reading and writing. +\par \pard\plain\f2\fs22 +\par You must eject and re-insert this cartridge, then properly respond to the password dialog box, or use another cartridge that has not had write or read/write protection applied to it. +\par +\par \pard\qc\plain\f2\fs16\i *Iomega, Zip, and Jaz are trademarks of Iomega Corporation.\plain\f2\fs22 +\par \pard\plain\f2\fs24 [nospares] +\par \pard\qc\plain\f2\fs44\b This Cartridge is in +\par Serious Trouble! +\par \plain\f2\fs16 +\par \plain\f2\fs28\cf1 The drive reports that this cartridge's +\par spare sector pools have been +\par completely exhausted. +\par \pard\plain\f2\fs22 +\par \plain\f2\fs22\cf2\b Background:\plain\f2\fs22 +\par Zip and Jaz drives maintain spare sectors that are automatically called into use when an \plain\f2\fs22\ul apparently defective \plain\f2\fs22 sector is encountered during reading and writing. +\par +\par I say "\plain\f2\fs22\ul apparently defective\plain\f2\fs22 " above, since "Click Of Death" Iomega drives damage its cartridge's sectors. Then, after the sectors have been damaged, they are replaced with new sectors from the cartridge's spare sector pools! In other words, nothing was really wrong with the sectors the drive was replacing -- until it had damaged them itself, or in misreading them believed them to be damaged -- then the drive replaced those previously good sectors with spares. +\par +\par \pard\qc\plain\f2\fs22\b This destructive cycle repeats until all +\par spare sectors have been consumed ! +\par \pard\plain\f2\fs22 +\par Therefore, the fact that this cartridge's spare sectors have all been consumed, \plain\f2\fs22\b strongly suggests\plain\f2\fs22 that at some point in the past this cartridge came into contact with a bad Iomega drive. +\par (\plain\f2\fs22\ul Even if the drive it is running on now is perfectly fine.\plain\f2\fs22 ) +\par +\par \plain\f2\fs22\cf2\b Consequence:\plain\f2\fs22 +\par Since spare sectors \plain\f2\fs22\b are required\plain\f2\fs22 for safe use of any Iomega cartridge, this cartridge can not be safely tested, nor can it be safely used for storing data. +\par +\par \plain\f2\fs22\cf2\b Recourse:\plain\f2\fs22 +\par If this cartridge contains valuable data, the data should be moved to safety immediately, then the cartridge should receive a "Long Format" on a \plain\f2\fs22\b known good Iomega drive\plain\f2\fs22 (i.e. a drive which has recently passed TIP testing.) +\par +\par If the data can not be read from this cartridge on a known good drive then my commercial SpinRite utility can be used to repair and recover the cartridge's data, but \plain\f2\fs22\b\ul ONLY\plain\f2\fs22 use SpinRite with cartridges on Iomega drives that are known to be good. (SpinRite description and purchasing information can be found on my web site at: http://grc.com.) +\par +\par At the time of this writing I plan to create another utility program for users of Iomega products. It will be able to test Iomega drive products and also to perform short and long Iomega reformats. Please check my web site at http://grc.com for further information on this next product. +\par +\par \pard\qc\plain\f2\fs16\i *Iomega, Zip, and Jaz are trademarks of Iomega Corporation.\plain\f2\fs22 +\par \pard\plain\f2\fs24 [outofspares] +\par \pard\qc\plain\f2\fs44\b This Cartridge's Spare Sectors Have All Been Consumed! +\par \plain\f2\fs16 +\par \plain\f2\fs28\cf1 The drive reports that this cartridge's +\par spare sector pools have been +\par completely exhausted. +\par \pard\plain\f2\fs22 +\par \plain\f2\fs22\cf2\b Background:\plain\f2\fs22 +\par Zip and Jaz drives maintain spare sectors that are automatically called into use when an \plain\f2\fs22\ul apparently defective \plain\f2\fs22 sector is encountered during reading and writing. +\par +\par I say "\plain\f2\fs22\ul apparently defective\plain\f2\fs22 " above, since "Click Of Death" Iomega drives damage its cartridge's sectors. Then, once they've been damaged it replaces them with new sectors from the cartridge's spare sector pools. In other words, nothing was really wrong with the sectors it was replacing -- until it had damaged them itself or in misreading them believed them to be damaged -- then it replaced those previously good sectors with spares. This destructive cycle repeats until all spare sectors have been consumed. +\par +\par The primary function of this Iomega drive testing program is to induce this sort of behavior in the drive since sector damage is the most apparent symptom of a drive which is writing incorrectly to the cartridge. +\par +\par \plain\f2\fs22\cf2\b Consequence: +\par \plain\f2\fs22\b The fact that this cartridge's spare sectors have all been consumed during this simple reading and writing test, \plain\f2\fs22\b\ul STRONGLY SUGGESTS that this drive is seriously defective and should no longer be used.\plain\f2\fs22\ul +\par \plain\f2\fs22 +\par \plain\f2\fs22\cf2\b Recourse:\plain\f2\fs22 +\par If this cartridge contains valuable data, the data should be moved to safety immediately, then the cartridge should receive a "Long Format" on a \plain\f2\fs22\b known good Iomega drive\plain\f2\fs22 (i.e. a drive which has recently passed TIP testing.) +\par +\par If the data can not be read from this cartridge on a known good drive then my commercial SpinRite utility can be used to repair and recover the cartridge's data, but \plain\f2\fs22\b\ul ONLY\plain\f2\fs22 use SpinRite with cartridges on Iomega drives that are known to be good. (SpinRite description and purchasing information can be found on my web site at: http://grc.com.) +\par +\par At the time of this writing I plan to create another utility program for users of Iomega products. It will be able to test Iomega drive products and also to perform short and long Iomega reformats. Please check my web site at http://grc.com for further information on this next product. +\par +\par \pard\qc\plain\f2\fs16\i *Iomega, Zip, and Jaz are trademarks of Iomega Corporation.\plain\f2\fs22 +\par \pard\plain\f2\fs24 [fewspares] +\par \pard\qc\plain\f2\fs44\b This Cartridge Has +\par Very Few Available +\par Spare Sectors +\par \plain\f2\fs16 +\par \plain\f2\fs28\cf1 The drive reports that this cartridge's +\par spare sector pools are nearly exhausted. +\par \pard\plain\f2\fs22 +\par \plain\f2\fs22\cf2\b Background:\plain\f2\fs22 +\par Zip and Jaz drives maintain spare sectors that are automatically called into use when an \plain\f2\fs22\ul apparently defective \plain\f2\fs22 sector is encountered during reading and writing. +\par +\par I say "\plain\f2\fs22\ul apparently defective\plain\f2\fs22 " above, since "Click Of Death" Iomega drives damage its cartridge's sectors. Then, once they've been damaged it replaces them with new sectors from the cartridge's spare sector pools. In other words, nothing was really wrong with the sectors it was replacing -- until it had damaged them itself or in misreading them believed them to be damaged -- then it replaced those previously good sectors with spares. This destructive cycle repeats until all spare sectors have been consumed. +\par +\par \plain\f2\fs22\cf2\b Consequence: +\par \plain\f2\fs22 The primary function of this Iomega drive testing program is to induce this sort of erroneous spare sector allocation since sector damage is the most apparent symptom of a drive which is writing incorrectly to the cartridge. +\par +\par However, the fact that so many of this cartridge's spare sectors have \plain\f2\fs22\ul already\plain\f2\fs22 been consumed \plain\f2\fs22\b strongly suggests\plain\f2\fs22 that at some point in the past this cartridge came into contact with a bad Iomega drive . . . \plain\f2\fs22\ul even if the drive it is running on now is perfectly fine.\plain\f2\fs22 +\par +\par This means that this drive testing program might detect sectors that were damaged by some \plain\f2\fs22\ul other\plain\f2\fs22 drive, for which the drive being tested now would be erroneously and unfairly blamed. +\par +\par If no \plain\f2\fs22\ul additional\plain\f2\fs22 damage is caused by this current drive on this questionable cartridge, then you'll know this drive is working correctly, but if \plain\f2\fs22\ul new damage\plain\f2\fs22 is detected you won't know whether it was old damage only now being detected or new damage. +\par +\par \plain\f2\fs22\cf2\b Recourse:\plain\f2\fs22 +\par If you wish to proceed with the test using this questionable cartridge, press the "Press to Proceed" button in the upper right. Otherwise eject this cartridge and find another one to be used for this test. +\par +\par If your goal is to determine whether this drive is functioning properly and reliably then testing it with the best cartridge will yield the clearest and most reliable results. +\par +\par \pard\qc\plain\f2\fs16\i *Iomega, Zip, and Jaz are trademarks of Iomega Corporation.\plain\f2\fs22 +\par \pard\plain\f2\fs24 +\par [notrunning] +\par \pard\qc\plain\f2\fs44\cf2\b Insert a cartridge, +\par then press the +\par "Press to Begin" button +\par \plain\f2\fs16 +\par \plain\f2\fs28\cf1 This explanation page will help you +\par to interpret the testing results once +\par the testing is completed. +\par \pard\plain\f2\fs22 +\par \plain\f2\fs22\b Please return to this page once the testing has finished. +\par \plain\f2\fs22 +\par To start testing insert a cartridge into your Iomega drive of choice then press the "Press to Begin" button at the upper right. +\par +\par You may interrupt the testing at any time by pressing the "Press to Stop" button at the upper right. However, final result interpretations will not be available unless the test is allowed to run to its conclusion. +\par \pard\qc\plain\f2\fs16\i +\par *Iomega, Zip, and Jaz are trademarks of Iomega Corporation. +\par \pard\plain\f2\fs24 [running] +\par \pard\qc\plain\f2\fs44\cf2\b The Testing is +\par Currently Underway +\par \plain\f2\fs16 +\par \plain\f2\fs28\cf1 When the testing is completed this +\par explanation page will help you to +\par interpret the testing results. +\par \pard\plain\f2\fs22 +\par \plain\f2\fs22\b Please return to this page once the testing has finished. +\par \plain\f2\fs22 +\par You may interrupt the testing at any time by pressing the "Press to Stop" button at the upper right. However, final result interpretations will not be available unless the test is allowed to run to its conclusion. +\par \pard\qc\plain\f2\fs16\i +\par *Iomega, Zip, and Jaz are trademarks of Iomega Corporation. +\par \pard\plain\f2\fs24 [interrupted] +\par \pard\qc\plain\f2\fs44\cf2\b The Test was Interrupted before its Conclusion +\par \plain\f2\fs16 +\par \plain\f2\fs28\cf1 The condition of this drive and +\par cartridge is unknown because +\par the test was not completed. +\par \pard\plain\f2\fs22 +\par \plain\f2\fs22\cf2\b Analysis . . .\plain\f2\fs22 +\par Although the drive and cartridge appear to be reasonably fine up to the point of interruption, conclusions can not be drawn from this partial testing. To determine the condition of this drive and cartridge the test must run to its conclusion. +\par +\par You may restart the test from the beginning by pressing the "Press to Begin" button in the upper right. +\par \pard\qc\plain\f2\fs16\i +\par *Iomega, Zip, and Jaz are trademarks of Iomega Corporation. +\par \pard\plain\f2\fs24 [perfectresult] +\par \pard\qc\plain\f2\fs44\cf2\b This Drive & Cartridge are +\par in \plain\f2\fs44\cf2\b\ul PERFECT CONDITION\plain\f2\fs44\cf2\b ! +\par \plain\f2\fs16 +\par \plain\f2\fs28\cf1 The drive and cartridge have together +\par passed TIP's tests with flying colors! +\par \pard\plain\f2\fs22 +\par \plain\f2\fs22\cf2\b Congratulations!\plain\f2\fs22 +\par \plain\f2\fs22\b\ul This test could not have run any more perfectly!\plain\f2\fs22\b +\par \plain\f2\fs22 Not one single problem of any sort was detected: +\par \plain\f5\fs24\cf1 \'b7\plain\f2\fs22 \plain\f2\fs22\b\ul No\plain\f2\fs22 sectors were difficult to locate, +\par \plain\f5\fs24\cf1 \'b7\plain\f5\fs24 \plain\f2\fs22\b\ul No\plain\f2\fs22 sectors needed relocation, +\par \plain\f5\fs24\cf1 \'b7\plain\f2\fs22 \plain\f2\fs22\b\ul No\plain\f2\fs22 read or write errors of \plain\f2\fs22\ul any\plain\f2\fs22 sort occurred. +\par +\par The \plain\f2\fs22\b ONLY WAY\plain\f2\fs22 this outcome could have been reached is if this drive and cartridge are \plain\f2\fs22\b BOTH\plain\f2\fs22 in \plain\f2\fs22\b FLAWLESS\plain\f2\fs22 working condition. (There's \plain\f2\fs22\ul NO trouble\plain\f2\fs22 in your paradise!) +\par +\par \pard\qc\plain\f2\fs24\cf2\b You May Use this Drive & Cartridge +\par with \plain\f2\fs24\cf2\b\ul Total\plain\f2\fs24\cf2\b Confidence. +\par \plain\f2\fs22 +\par \plain\f2\fs16\i *Iomega, Zip, and Jaz are trademarks of Iomega Corporation. +\par \pard\plain\f2\fs24 [okayresult] +\par \pard\qc\plain\f2\fs36\cf2\b This Drive & Cartridge Appear +\par to be in Good, \plain\f2\fs36\cf2\b\i but Perhaps +\par Not Perfect\plain\f2\fs36\cf2\b , Condition +\par \plain\f2\fs16 +\par \plain\f2\fs28\cf1 The test has been somewhat inconclusive and should be \plain\f2\fs28\cf1\ul immediately\plain\f2\fs28\cf1 performed again. +\par \pard\plain\f2\fs22 +\par \plain\f2\fs22\cf2\b Analysis . . .\plain\f2\fs22 +\par A relatively small number of completely correctable read/write errors occurred during the test, and resulted in one or more apparently questionable sectors being taken out of service. +\par +\par This \plain\f2\fs22\ul can\plain\f2\fs22 be entirely normal operation for a completely healthy Zip or Jaz drive, particularly if this is the first time that a thorough disk scan of this sort has been performed after the cartridge has been in use for some time. +\par +\par However, it can also be an \plain\f2\fs22\ul early\plain\f2\fs22 indication of drive trouble. +\par +\par The test should be run again right now to see whether this pattern repeats: +\par +\par \plain\f5\fs24\cf1 \'b7\plain\f2\fs22 If \plain\f2\fs22\b\ul NO\plain\f2\fs22 additional troubles occur, then you can safely assume that the first pass actually \plain\f2\fs22\ul did\plain\f2\fs22 find and resolved a few true media defects -- which is common and expected behavior. +\par +\par \plain\f5\fs24\cf1 \'b7\plain\f2\fs22 \plain\f2\fs22\b BUT . . .\plain\f2\fs22 if rerunning this test \plain\f2\fs22\ul AGAIN\plain\f2\fs22 has apparently located some new troubles (which the last test "missed", and finds a few more "apparently bad" sectors \plain\f2\fs22\b . . .\plain\f2\fs22 then you should conclude that this drive and/or cartridge is beginning to show early signs of 'Click Of Death' behavior. +\par +\par \pard\qc\plain\f2\fs22\cf2\b If impending 'Click Of Death' seems indicated, +\par the trick now is to determine whether the +\par trouble is with the drive or with the cartridge. +\par \pard\plain\f2\fs22 +\par If you have another cartridge you should use it right away with the same drive under TIP to attempt to isolate the cause of the trouble as follows: +\par +\par \plain\f5\fs24\cf1 \'b7\plain\f2\fs22 If another cartridge behaves similarly in the same drive, the trouble is more likely with the drive -- since the drive will have been the common element in both tests which were somewhat troubled. +\par +\par \plain\f5\fs24\cf1 \'b7\plain\f2\fs22 But if a second cartridge behaves perfectly in the same drive (where the first one never did), then the trouble is more likely to be with the first cartridge -- since replacing the troubled element resolved the problems. +\par +\par \plain\f5\fs24\cf1 \'b7\plain\f2\fs22 And if you have access to a second drive, you could try using the original cartridge in this second drive to gather additional objective evidence about the true behavior of the original drive and cartridge. +\par +\par \plain\f2\fs22\cf2\b Conclusion:\plain\f2\fs22 +\par As you can see, by using TIP to exercise various combinations of Iomega drives and cartridges, it will be possible for you to reach verifiable conclusions about the condition, behavior, and reliability of your Iomega removable storage products. +\par +\par \plain\f2\fs22\cf1\b It is my sincere hope that this will result in more effective and satisfying personal computing experiences for everyone, and may help Iomega's users to enjoy their products while providing valuable feedback to Iomega. +\par \plain\f2\fs22\cf1 +\par \plain\f2\fs22\cf0 Please see the \plain\f2\fs22\cf0\b Next\plain\f2\fs22\cf0 panel in this program (by pressing the 'Next' button below) for information regarding Iomega's return policy for in-warranty and out-of-warranty drive products. +\par +\par Their official spokesman has stated that Iomega will stand behind their products and that \plain\f2\fs22\cf0\b any drives will be replaced whether they are in warranty or not!\plain\f2\fs22\cf0 This is great news for people whose Iomega drives have been dying!\plain\f2\fs22 +\par \pard\qc\plain\f2\fs16\i +\par *Iomega, Zip, and Jaz are trademarks of Iomega Corporation.\plain\f2\fs22 +\par \pard\plain\f2\fs24 [badresult] +\par \pard\qc\plain\f2\fs44\cf1\b Something is VERY +\par WRONG Somewhere. +\par \plain\f2\fs16 +\par \plain\f2\fs28\cf3 The test has encountered a suspiciously large number of problems while running! +\par \pard\plain\f2\fs22 +\par \plain\f2\fs22\cf2\b Analysis . . .\plain\f2\fs22 +\par TIP has encountered a \plain\f2\fs22\b large\plain\f2\fs22 number of data-loss related troubles, demonstrating that this drive and cartridge are not getting along together at all! +\par +\par Your task now is to determine the \plain\f2\fs22\b cause and source \plain\f2\fs22 of these troubles: +\par +\par \plain\f5\fs24\cf1 \'b7\plain\f2\fs22 \plain\f2\fs22\b Is it the drive\plain\f2\fs22 which is not operating properly and reliably, thus creating these troubles on the cartridge? +\par +\par \plain\f5\fs24\cf1 \'b7\plain\f2\fs22 Or, instead, were these troubles caused by a cartridge that had \plain\f2\fs22\b already been damaged\plain\f2\fs22 by its use in some other malfunctioning Zip drive? +\par +\par \pard\qc\plain\f2\fs22\cf2\b If you have another cartridge or drive, you should use +\par them with the same drive or cartridge to attempt +\par to isolate the cause of the trouble as follows: +\par \pard\plain\f2\fs22 +\par \plain\f5\fs24\cf1 \'b7\plain\f2\fs22 \plain\f2\fs22\b If another cartridge behaves similarly in the same drive\plain\f2\fs22 , the trouble is more likely with the drive -- since the drive will have been the common element in both tests which were somewhat troubled. +\par +\par \plain\f5\fs24\cf1 \'b7\plain\f2\fs22 But\plain\f2\fs22\b if a second cartridge behaves perfectly in the same drive \plain\f2\fs22 (where the first one had serious problems), then the trouble is more likely to be with the first cartridge -- since replacing the troubled element resolved the problems. +\par +\par \plain\f5\fs24\cf1 \'b7\plain\f2\fs22 And\plain\f2\fs22\b if you have access to a second drive\plain\f2\fs22 , you could try using the original cartridge in this second drive to gather additional objective evidence about the true behavior of the original drive and cartridge. (Although, with troubles as extensive as this first cartridge experienced, the damage may be too extreme for a test with a second drive to be conclusive.) +\par +\par \plain\f5\fs24\cf1 \'b7\plain\f2\fs22 Or \plain\f2\fs22\b if you do not have access to other equipment\plain\f2\fs22 , re-running the same TIP test on the same drive and cartridge might prove useful if TIP and the drive were able to repair some of the cartridge's initial damage. If the second use of TIP on the cartridge is substantially better than the first try, you could tentatively conclude that the cartridge was at fault, and that the drive is operating reliably. +\par +\par \plain\f2\fs22\cf2\b Conclusion:\plain\f2\fs22 +\par As you can see, by using TIP to exercise various combinations of Iomega drives and cartridges, it will be possible for you to reach verifiable conclusions about the condition, behavior, and reliability of your Iomega removable storage products. +\par +\par \plain\f2\fs22\cf1\b It is my sincere hope that this will result in more effective and satisfying personal computing experiences for everyone, and may help Iomega's users to enjoy their products while providing valuable feedback to Iomega. +\par \plain\f2\fs22\cf1 +\par \plain\f2\fs22\cf0 Please see the \plain\f2\fs22\cf0\b Next\plain\f2\fs22\cf0 panel in this program (by pressing the 'Next' button below) for information regarding Iomega's return policy for in-warranty and out-of-warranty drive products. +\par +\par Their official spokesman has stated that Iomega will stand behind their products and that \plain\f2\fs22\cf0\b any drives will be replaced whether they are in warranty or not!\plain\f2\fs22\cf0 This is great news for people whose Iomega drives have been dying!\plain\f2\fs22 +\par \pard\qc\plain\f2\fs16\i +\par *Iomega, Zip, and Jaz are trademarks of Iomega Corporation. +\par \plain\f2\fs22 +\par \pard\plain\f2\fs24 [iomegaquote] +\par \pard\qc\plain\f2\fs36\cf2\b So \plain\f2\fs36\cf2\b\ul WHAT CAN YOU DO\plain\f2\fs36\cf2\b If Your Iomega Drive Has Click Of Death?\plain\f2\fs44\cf2\b +\par \plain\f2\fs22\cf2\b +\par \plain\f2\fs44\cf1\b THERE'S FANTASTIC NEWS, +\par Directly from Iomega!\plain\f2\fs44\cf2\b +\par \plain\f2\fs16\cf0 +\par \pard\plain\f2\fs22 Iomega's customers have believed that if their drive failed after the expiration of its one-year warranty that they were out of luck. +\par +\par \pard\qc\plain\f2\fs28\cf3\b\ul But this turns out NOT to be the case at all! +\par \pard\plain\f2\fs22 \plain\f2\fs24\cf0 +\par \plain\f2\fs22\cf0 On June 16th 1998, I appeared on ZDTV's nationally televised 'Screen Savers' program to explain everything I'd learned about the Iomega Click Of Death problem. \plain\f2\fs22\cf0\b During the second half of the show we were joined -- over the telephone -- by Iomega's Spokesman and the General Manager of Zip Aftermarket Business, David Hellier. +\par +\par \plain\f2\fs22\cf0 During his telephone statement, David surprised me by telling the whole world that \plain\f2\fs22\cf0\b Iomega would replace \plain\f2\fs22\cf0\b\ul any\plain\f2\fs22\cf0\b drives suffering from CLICK OF DEATH \plain\f2\fs22\cf0\b\ul whether they are within warranty or not\plain\f2\fs22\cf0\b !!!\plain\f2\fs22\cf0 +\par +\par Here are David's exact words: +\par +\par \plain\f2\fs22\cf0\i "I\plain\f2\fs22\i f our customers have a problem specific to this issue, whether it's in or out of warranty, we're going to take care of and replace the product if necessary."\plain\f2\fs22 +\par +\par \plain\f2\fs22\cf2\b That's Right! +\par \plain\f2\fs22 This means that you are no longer stuck with bad Zip and Jaz drives \plain\f2\fs22\b . . .\plain\f2\fs22 even if you've had the drive longer than one year! I'm very glad to be able to tell you that Iomega has decided to step up to the plate and take full responsibility for this problem! +\par +\par \plain\f2\fs22\cf1\b . . . And \plain\f2\fs22\cf1\b\ul YOU\plain\f2\fs22\cf1\b can hear him say this for yourself ! +\par \plain\f2\fs22 If you are running this program while you are connected to the Internet, or if your computer "knows" how to connect to the 'Net when you click on a URL-style link, you can use the two buttons below to quickly download two short (79k and 71k) wave files to hear David Hellier's statement for yourself! +\par +\par \plain\f5\fs24\cf1 \'b7\plain\f2\fs22 The first button is his introduction of himself, by phone, during the television broadcast. The URL for this 79k wave file is: +\par +\par \pard\qc\plain\f4\fs24 ftp://grc.com/hellier1.wav +\par \pard\plain\f2\fs22 +\par \plain\f2\fs22\b . . .\plain\f2\fs22 which you are welcome to eMail to your friends, post on other web sites, announce in newsgroups, or give to Iomega's Technical Support personnel if they have not yet received the great news that \plain\f2\fs22\ul Iomega has agreed to replace any out-of-warranty Click Of Death drives!\plain\f2\fs22 +\par +\par \plain\f5\fs24\cf1 \'b7\plain\f2\fs22 The second button is the relevant excerpt from his full statement which comes as \plain\f2\fs22\b fabulous news\plain\f2\fs22 to the tens of thousands of troubled users of Iomega's products! (Iomega has estimated that perhaps as many as 100,000 users will be affected by these problems.) The URL for the 71k 2nd wave file is: +\par \pard\qc\plain\f4\fs24 ftp://grc.com/hellier2.wav +\par \pard\plain\f2\fs22 +\par \plain\f2\fs22\b . . .\plain\f2\fs22 which you are similarly welcome to share with anyone who needs to hear it! +\par +\par \pard\qc\plain\f2\fs24\cf1\b You may press the buttons below at any +\par time to download these wave files.\plain\f2\fs24\cf1 +\par \pard\plain\f2\fs22 +\par \plain\f2\fs22\cf2\b For additional background: +\par \plain\f2\fs22 David Hellier's statement was made at the end of my segment of ZDTV's (Ziff-Davis Television) 'Screen Savers' program, and links to \plain\f2\fs22\b ZDTV's RealVideo clips\plain\f2\fs22 of \plain\f2\fs22\ul my\plain\f2\fs22 segment of the program can be found at my web site, and you can also find a link to ZDTV's page which they created for the show. +\par +\par Unfortunately, the RealVideo clip provided by ZDTV's server cuts off just as David Hellier starts to make his statement -- presumably because it wasn't really relevant to the technical issues we were discussing. \plain\f2\fs22\b So if you would like to hear the AUDIO track for the ENTIRE show\plain\f2\fs22 , I have made that available on my web site at: +\par +\par \pard\qc\plain\f4\fs24 http://grc.com/clickofdeath.ram +\par \pard\plain\f2\fs22 +\par . . . which you can listen to with a RealAudio player (which is free and also available through a link on my and ZDTV's site, and directly from http://www.real.com) \plain\f2\fs22\b Just type that URL address (above) into your web browser . . . and you'll be listening to the audio track of the entire show!\plain\f2\fs22 +\par +\par \pard\qc\plain\f2\fs22\i\ul Please note that ALL of this content from the TV show is the copyrighted property of Ziff-Davis TV, at \plain\f2\fs22\ul http://zdtv.com\plain\f2\fs22\i\ul .\plain\f2\fs22 +\par \pard\plain\f2\fs22 +\par \plain\f2\fs22\cf2\b Convincing Iomega that your drive \plain\f2\fs22\cf2\b\ul Really IS Bad\plain\f2\fs22\cf2\b . . . +\par \plain\f2\fs22\cf0 Obviously, replacing up to 100,000 Zip and Jaz drives in the field, will be quite expensive for Iomega. (But let's remember that up until now it's been \plain\f2\fs22\cf0\b very expensive\plain\f2\fs22\cf0 for Iomega's customers, who frequently lost \plain\f2\fs22\cf0\b not only their drives\plain\f2\fs22\cf0 but also their data as well.) +\par +\par So, until this 'Trouble In Paradise' program has been around long enough to become known and trusted as the standard and reliable means for measuring Iomega drive health, I would not be surprised if Iomega were disinclined to take my program's word for the fact that your drives are defective. +\par +\par \pard\qc\plain\f2\fs28\cf1\b So here's a work-around to help you +\par get past this potential hurdle . . . +\par \pard\plain\f2\fs22\cf2\b +\par \plain\f2\fs22\cf0 The standard Iomega "Long Format" operation, which can be easily performed using Iomega's DOS or Windows utilities, \plain\f2\fs22\cf0\ul will fail on many 'Click Of Death" drives!\plain\f2\fs22\cf0 So this provides you with another means -- \plain\f2\fs22\cf0\i not involving ANY non-Iomega third party software\plain\f2\fs22\cf0 -- for demonstrating to them that your drive is no longer functioning as it should. +\par +\par \pard\qc\plain\f2\fs24\cf3\b Given a working cartridge, there is \plain\f2\fs24\cf3\b\ul ABSOLUTELY +\par NO REASON\plain\f2\fs24\cf3\b why an Iomega Long Format should +\par fail . . . except if the drive is no longer even +\par able to format one of its own cartridges! +\par \pard\plain\f2\fs22\cf0 +\par Since a Long Format performs a brief media recertification, this performs a less sensitive version of TIP's sensitive read/write testing \plain\f2\fs22\cf0\b . . .\plain\f2\fs22\cf0 and has the significant advantage of using \plain\f2\fs22\cf0\ul nothing\plain\f2\fs22\cf0 other than Iomega's own software. Of course, doing this will wipe out any data that was on the cartridge beforehand, and may very well damage the cartridge permanently \plain\f2\fs22\cf0\b . . .\plain\f2\fs22\cf0 but all Iomega cartridges have always had a lifetime warranty, so you can get it replaced at the same time as your Click Of Death drive. +\par +\par The Long Format provides much less feedback to you -- before, during, or after its operation -- than TIP does, so you'll never really know what's going on. It'll just fail with an error message, but that's all you'll need to show Iomega that your drive needs replacement. +\par +\par Thus, this work-around gives you an inarguable position to take when getting Iomega to acknowledge that your drive is no longer safe to use and needs to be replaced under David Hellier's replacement policy. +\par +\par \plain\f2\fs22\cf2\b In case you have trouble with Iomega's Technical Support: +\par \plain\f2\fs22 Since the Technical Support for Iomega's products has been sub-contracted to a outside company, they may be unaware of Iomega's return and replacement policies for Click Of Death drives. +\par +\par So, if you experience difficulty when dealing with Iomega's sub-contracted technical support, you may need to give David Hellier a phone call to let him know that the news of his policies have not yet filtered down to the appropriate persons handling product returns and replacements \plain\f2\fs22\b . . .\plain\f2\fs22 and ask him what you should do to get your drive replaced. +\par +\par \pard\qc\plain\f2\fs22\cf1\b You can reach David at Iomega's main number: +\par 1-801-778-1000, then ask to speak with David Hellier. +\par \pard\plain\f2\fs22 +\par Based upon the tremendous concern David demonstrated for the well-being of Iomega's customers (which you are welcome to hear for yourself -- in full -- on my web site), \plain\f2\fs22\b I am certain that David would want to know immediately if Iomega's customers were NOT receiving the treatment that he has said Iomega intends to provide to all of their customers. +\par \plain\f2\fs22 Thus, you would be doing your part \plain\f2\fs22\ul for everyone who has these problems\plain\f2\fs22 by letting David know if his policies are not being correctly implemented by MCI Call Centers, the people who are handling Iomega's Technical Support. +\par \pard\qc\plain\f2\fs96\cf1\b ~\plain\f2\fs96\b \plain\f2\fs96\cf7\b ~\plain\f2\fs96\b \plain\f2\fs96\cf2\b ~\plain\f2\fs96 +\par \pard\plain\f2\fs22\cf2\b Well, this is Goodbye For Now . . . +\par \plain\f2\fs22\cf0 I hope that you have found this 'Trouble In Paradise' Iomega drive and cartridge testing tool useful, and that it will serve as your trusted companion for the foreseeable future, providing you with tools and knowledge to increase the reliability of your Iomega data storage experiences. +\par +\par Remember to check back with my web site at http://grc.com for updates and news of other related developments in this area! +\par +\par As soon as the dust settles from this release of 'Trouble In Paradise', I'll be starting work on a new and inexpensive product which you'll be able to use to track, manage, and maintain all of your Iomega cartridges throughout their entire useful life. +\par +\par If that sounds interesting to you, you can drop by my web site and add yourself to the 'Click Of Death' mailing list so that you'll receive automatic notification when this next goodie is ready for you! The address is: http://grc.com/codmailing.htm +\par +\par Best luck to you! \plain\f2\fs32\cf2\b\i -- Steve.\plain\f2\fs22\cf0 \plain\f2\fs16\cf0 6/28/98\plain\f2\fs16 +\par \pard\qc\plain\f2\fs22 +\par \plain\f2\fs16\i *Iomega, Zip, and Jaz are trademarks of Iomega Corporation. +\par \pard\plain\f2\fs24 [EndOfText] +\par } + \ No newline at end of file diff --git a/x86-asm-source/RTF.RTF b/x86-asm-source/RTF.RTF new file mode 100644 index 0000000..541ab4c --- /dev/null +++ b/x86-asm-source/RTF.RTF @@ -0,0 +1,571 @@ +{\rtf1\ansi\ansicpg1254\deff0\deflang1033{\fonttbl{\f0\fswiss\fprq2 Arial;}{\f1\fmodern\fprq1 Courier New;}{\f2\fnil\fcharset2 Symbol;}{\f3\fnil Symbol;}{\f4\fswiss\fprq2\fcharset162{\*\fname Arial;}Arial TUR;}{\f5\fmodern\fprq1\fcharset0 Courier New;}} +{\colortbl ;\red128\green0\blue0;\red0\green0\blue128;\red128\green0\blue128;\red0\green128\blue128;\red0\green0\blue0;\red128\green128\blue128;\red255\green0\blue0;\red0\green128\blue0;} +\viewkind4\uc1\pard\f0\fs24 [instruct]\par +\pard\qc\ul\b\fs44 Very Important Information\ulnone\par +\b0\fs16\par +\fs28 You \cf1\ul\b MUST\cf0\ulnone\b0 take time to read through this\par +\cf1\b CRUCIAL OPERATING INFORMATION\par +\cf0\b0 or this program's test results will be\par +erroneous and meaningless.\fs22\par +\pard\par +\cf2\b Welcome to TIP Version 2.1:\cf0\b0\par +Version 2.1 of TIP offer several "incremental" improvements that did not warrant a jump to a version number of 3.0 (that's still to come.) Version 2.1 adds compatibility with the 250 Mb ZIP drive and with all USB Iomega drives. It also boasts an automatic self-repairing facility that allows TIP to reconstruct a cartridge's file system after being damaged by an obscure Windows 95/98 removable media bug.\par +\par +\cf2\b TIP Version 2.0 Versus the Original 1.0 Release:\cf0\b0\par +Version 2.0 of TIP is a \b significant advancement\b0 over 1.0. It far surpasses the earlier version's sensitivity to "soft errors" and provides, not only the original capability of helping users to detect drive misbehavior, but goes much further by empowering them to sensitively compare the integrity and reliability of drives and cartridges.\par +\par +\pard\qc\cf1\b Be sure to see the "EXPLAIN RESULTS" page for detailed instruction in the interpretation of TIP's error results.\par +\pard\cf0\b0\par +\cf2\b Background:\cf0\b0\par +Iomega* Zip* and Jaz* drives cause \b 'Click Of Death' \b0 by incorrectly writing to their removable media. This miswriting can damage the user's data, the factory-written low-level formatting, the head's positioning servo information, and the proprietary \b\i Z-Tracks\b0\i0 that are used internally to manage and maintain the Zip and Jaz drive's cartridge data.\par +\par +\b The clicking sound itself\b0 is nothing more than the sound of the heads being retracted from the cartridge into the drive then immediately reinserted. This deliberate strategy is employed by the drive when it is having trouble locating, reading, or writing any of the cartridge's data. This removal and reinsertion of the heads recalibrates the head positioning mechanism, 'scrubs' the heads to remove excessive oxide deposits, and eliminates any electrostatic charge build-up on the heads.\par +\par +\pard\qc\cf1\b It is important for you to understand that the clicking\par +sound itself is \ul NOT\ulnone the problem. The clicking is just\par +an audible indication of a drive that is having trouble\par +accessing the data on the cartridge. \par +\pard\cf0\b0\par +Incidents of Click Death have been linked to bad external power supplies, loose power connectors, excessive magnetic oxide build-up on the drive's heads, magnetic and radio interference from nearby sources, media damage from excessive wear or mistreatment, and a seemingly endless array of internal electrical and mechanical problems from causes ranging from rough handling through defective original manufacturing.\par +\par +\cf2\b Why is this happening all of a sudden?:\cf0\b0\par +An unbiased appraisal of recent experience with the large population of Zip -- and to a lesser extent Jaz -- drives, leads to the inescapable -- and unfortunate -- conclusion that recently manufactured Iomega products are experiencing a significantly higher incidence of problems -- both immediately after purchase and after relatively short term use in the field -- than the older versions of the Zip and Jaz drive products which established their reputation for quality and reliability.\par +\par +The \b Iomega Zip and Jaz\b0 section of my web site contains a \b Q&A\b0 area where I am logging many of my interactions with Iomega's customers. Though these experiences are anecdotal in nature, upon reading them one gets the clear sense that something must have gone very wrong as Iomega attempted to scale up their Zip and Jaz drive manufacturing in order to meet the huge demand \ul for what were originally very reliable drives\ulnone .\par +\par +\b I have a lot of respect for the design of the Zip and Jaz drives.\b0 The personal computing industry \b desperately needs a \ul STANDARD\ulnone\b0 high-quality, high-capacity removable media solution -- rather than an industry fragmented by incompatible storage formats. Iomega was the first with a really terrific solution, and has had the opportunity to unite the industry through the strength of the their products' design. But it remains to be seen, as many new competitors enter this marketplace, whether Iomega will be able to cure what appear to be manufacturing quality-control problems, and hold the industry together with a single strong universal standard.\par +\b\i\par +\pard\qc\cf1\fs36 I sincerely hope they can!\b0\i0\par +\pard\cf2\b\fs22\par +About This Program:\cf0\b0\par +I wrote the first version of \b\i SpinRite\b0\i0 -- my well-known mass storage data recovery and maintenance utility -- more than eleven years ago. At the time of this writing, SpinRite is at version 5.0 and remains without peer in the industry. It was with those years of experience in mass storage maintenance that I set out to \b "cure"\b0 whatever the problem was with these newer Iomega Zip and Jaz drives. But I soon learned, as you have seen above, that \ul\b there was no single cause for these problems\ulnone\b0 because so many different things were apparently going wrong with the Iomega drives.\par +\par +\pard\qc\cf2\b So instead, \ul I decided to create two programs\ulnone to address the PC user's need for reliable removable mass storage\par +. . . while remaining with the Iomega standard.\par +\pard\cf0\b0\par +\cf1\ul\b Program 1\ulnone . \cf0\b0 This \b\i 'Trouble In Paradise'\b0\i0 freeware program is the first of the two. Since no one can 'cure' the problems which may afflict any Zip or Jaz drive without warning, the first step to assuring long data life is \b early detection of the POTENTIAL for the problem\b0 . For example, although we can't cure cancer, early detection of cancer's signs in our bodies allows us to take extra measures to assure our survival. \ul Similar early detection of 'Click Death' is exactly what I've created here in Program 1.\par +\ulnone\par +\cf1\ul\b Program 2\ulnone . \cf0\b0 The second program, to follow this one, will be an inexpensive (but not free) tool allowing any Iomega drive user to maintain and manage \ul their entire collection of Zip and Jaz cartridges\ulnone while individually monitoring each cartridge's condition and receiving early warning of impending trouble.\par +\par +It will also be able to "field re-certify" your aging Zip and Jaz cartridges by providing FAR more sensitive defect testing than is provided by any other "generic" hard disk utilities. (Yes, including even our own SpinRite 5.0.)\par +\par +Please see our web site at \b http://grc.com\b0 for news of the status of this second program \b . . .\b0 as well as for more extensive background information about this whole issue.\par +\par +\cf3 (You are also invited to join our \b COD mailing list\b0 to receive a short notice whenever something significant to Iomega Click Of Death occurs -- and to be informed when my next program (\b Program 2\b0 ) is ready. To add yourself to this mailing list, please visit \b http://grc.com/mail.htm\b0 )\par +\cf0\par +\cf2\b An Important Note About One Click Of Death Myth:\cf0\b0\par +There has been widespread rumor that 'Click Of Death' acts as some sort of contagion, able to be spread from one drive to another by a 'contaminated' Click Of Death afflicted cartridge.\par +\par +\b This actually can occur\b0 , but only in \ul\b extremely rare cases\ulnone\b0 of \ul\b massive physical damage\ulnone\b0 to the mylar disk spinning inside a Zip cartridge. In these very rare -- \i but absolutely verified cases\i0 -- the bent and torn mylar disk catches and 'beheads' any Zip drive attempting to load its heads into the cartridge.\par +\par +Please see the Iomega pages of my web site for detailed discussions \ul\b\i and photos!\ulnone\i0 \b0 of this rare and bizarre occurrence. \par +\par +However, for the most part, \b Zip users should not be concerned\b0 about the possibility of one troubled Zip drive somehow 'infecting' or destroying another one through a 'disease carrier' cartridge. \b It \ul can\ulnone definitely happen -- \b0 but then, you can also be struck by lightning in your sleep. So the possibility should not occupy too much of your waking concern.\par +\par +What actually \b does\b0 happen -- which has created and maintained this unfortunate myth -- is that a Click Of Death drive \ul miswrites to its cartridge making it start clicking\ulnone . Then the worried user takes this cartridge to another drive and \b that other drive also starts clicking!\b0 But it does so only because it is now unable to read the damaged cartridge. \ul\b\i This does not mean that the second drive is now damaged!\ulnone\b0\i0 Only the \ul cartridge\ulnone damaged by the first drive is in trouble. It is not the second drive's fault that it's unable to read the cartridge that was actually damaged by its use in the first drive.\par +\par +\cf2\b What Is This 'Trouble In Paradise' Program?:\cf0\b0\par +This 32-bit Windows freeware utility program, which I have named Trouble In Paradise (TIP), is a tightly monitored, non-destructive, data pattern surface tester. This program reads and writes every sector of data on the drive with surface and drive testing data patterns \ul\b while preserving all data originally contained on the cartridge\ulnone\b0 . Your data is preserved while allowing the function of the drive, and the data surfaces of the cartridge's disk(s), to be fully exercised under closely monitored conditions.\par +\par +Even if this process wasn't being used to locate potential drive and cartridge troubles, running TIP upon your cartridges from time to time \b will help to keep them in TIP top shape\b0 . The process of reading, rewriting, and refreshing the data in every sector of the cartridge is \b absolutely safe \b0 and is good for them, since it allows any slowly developing trouble to be spotted and handled safely before the data becomes unreadable. (Note that the second program in this series, mentioned above, will go much further in this direction, being specifically designed to support and monitor the long-term maintenance of your removable data cartridges.)\par +\par +Amazingly, throughout the entire development of this program -- from the first moment that it began working -- \b Not one single byte of data was ever damaged on any of my test cartridges!\b0 \i I believe that using TIP is extremely safe\i0 , and that you'll find TIP to be a useful tool to add to your personal computing experience.\par +\par +\cf4\ul\b\fs18 Please Note\ulnone :\b0 \b Non-ATAPI Internal IDE Zip\b0 drives did \b NOT\b0 support the standard ATAPI / SCSI software interface, \ul so this program can not operate upon those IDE ZIP drives at all\ulnone . I really wish it could, but those drives conceal ALL special Iomega information. TIP does operate upon ALL OTHER internal and external ZIP and Jaz drives.\par +\cf0\fs22\par +\cf2\b\fs36 How to Use This Program:\par +\fs22\par +\cf3\fs18 Please Note\b0 : The contents of any of this program's pages can be copied to the Windows' clipboard at any time by pressing the "Copy" button below. Graphical pages will be copied as images and scrolling text pages (like this one) will be copied as text. You can retain the text formatting by pasting the clipboard into the Windows Wordpad, or Word. If you wish to remove or ignore the formatting, paste into Notepad.\par +\par +You are completely free to share and redistribute any of this information, but providing a link to our web site would be appreciated. \cf5\f1 http://grc.com\cf3\f0\par +\cf2\b\fs22 __________________________________________________\par +\cf0\b0\par +The trick for properly using TIP for diagnosing drive and/or cartridge problems lies in interpreting the results.\par +\par +\pard\qc\cf1\b You'll find that TIP contains extensive result-driven explanations which you will automatically receive when any test run has concluded. But a bit of preparation and background is still necessary before you begin: . . .\par +\pard\cf0\b0\par +\ul In order for this program to find no problems\ulnone , \b both\b0 the Zip drive \b and\b0 the Zip cartridge must be in perfect working condition. If either the drive or the cartridge is damaged \b in any way\b0 this very sensitive program will show you the trouble \b . . .\b0 but in many mild cases of trouble, TIP will be unable to determine \b which\b0 of the two components -- the drive or the cartridge -- is actually the source of the problems. This is the bit of detective work you'll need to pursue, aided by feedback from TIP.\par +\par +One way to think of it is that with a drive that's known to be good, you can use TIP to test the condition of unknown cartridges. Or, with a cartridge that's known to be (initially) good, TIP can test a drive whose condition is unknown. Note that testing an initially good cartridge on a truly bad 'Click Of Death' drive \ul can create damage on the cartridge\ulnone , but I have deliberately designed TIP so that even in these cases your data will be safe, and you'll see this happening as the test runs so you can stop the test before the damage becomes extensive.\par +\par +The 'detective work' is not really any big deal, since it only entails reading through the result analysis that will be presented after each test, and perhaps running the test again with the same or a different cartridge, or -- if possible -- finding another drive to test with the same cartridge \b . . .\b0 depending upon the outcome analysis.\par +\par +Aided by TIP, if you're not sure whether the drive or cartridge is causing the trouble, changing one or the other -- and seeing what happens then -- will allow you to develop a much deeper feeling for what's going on within your system than you've ever been able to get before. And you'll find that after a few experiences you'll get the hang of it and will be able to accurately judge what's happening from the way the test runs.\par +\par +\cf2\b Thank you very much for taking the time to read through all this material! . . . \cf0\b0 I know you're probably anxious to get to it, but you needed to first be equipped with the essence of what I've learned through my research into these confusing, troubling, but very important issues. Also, \ul don't forget my web site\ulnone , since it will always contain more recent information, data, and experience than can be packaged into a static computer program such as this.\par +\par +So \b . . .\b0 with \b ALL\b0 of that said, please insert a cartridge into whichever Iomega drive you want to use and proceed to the \b Next\b0 panel \b . . .\par +\par +\pard\qc\b0\i\fs16 *Iomega, Zip, and Jaz are trademarks of Iomega Corporation.\par +\pard\i0\fs24 [noaspi]\par +\pard\qc\cf1\b\fs36 This System's ASPI Drivers are\par +Not Installed or Not Functioning.\cf0\b0\fs22\par +\fs16\par +\cf2\b\fs22 To use this program, which communicates with mass storage devices through the A.S.P.I. programming interface, you must first install operating system\par + support for the ASPI device driver layer.\cf5\b0\par +\pard\par +\cf4\b Background:\cf5\b0\par +\cf0 The Windows operating environments include built-in support for the \b A\b0 dvanced \b S\b0 CSI \b P\b0 rogramming \b I\b0 nterface (ASPI) which allows peripheral vendors to create ASPI-compatible drivers for use in interfacing their equipment to the operating system. But this Windows system's ASPI drivers are apparently missing or not functioning correctly at the moment.\par +\par +Out of date or incorrectly installed ASPI drivers can be the cause of drives "missing" from the system, or not being "seen" by TIP.\par +\par +\cf4\b How did this happen?:\cf0\b0\par +Since ASPI layer drivers are readily available, and are frequently provided in haphazard fashion by peripheral vendors, Windows systems often wind up with obsolete, oddball, missing, or out-of-synch sets of ASPI driver files.\par +\par +\cf4\b So what do you do?:\cf0\b0\par +ASPI drivers are built into Windows 95 and 98, but are not part of Windows NT.\par +\par +If you are using Windows 95 or 98 and received this message then something is seriously messed up in your system. Reinstalling Windows may be necessary. If you own Adaptec controllers or software you \b\i may\b0\i0 be able to use their free \b\f1\fs24 ASPI32.EXE\b0\f0\fs22 program, located on the Adaptec web site at: http://www.Adaptec.com to fix the trouble.\par +\par +If you are using Windows NT you will need to locate a source for ASPI drivers for Windows NT. Adaptec's \b\f1\fs24 ASPI32.EXE\b0\f0\fs22 program (mentioned above) may work for you if you own Adaptec hardware or software.\par +\par +Also, the next release of this freeware (v3.0) will be re-engineered to NOT REQUIRE ASPI drivers. If all else fails, please place yourself on my eMail Notification System so that I can let you know when TIP can run without requiring ASPI drivers!\par +\fs24 [ppaver]\par +\pard\qc\cf1\b\fs44 WOW! . . . Do I Have\par +\ul GREAT NEWS\ulnone for YOU!\par +\cf0\b0\fs16\par +\cf2\b\fs22 Very soon, your external Parallel Port Zip Drive will be running \ul more than 400% faster\ulnone than it does right now!\par +\pard\cf5\b0\par +That's right! This Windows system is currently using \b an old, obsolete (and slow!) version\b0 of the Iomega Parallel Port Driver (PPA3.MPD) which runs less than \ul one-quarter of the speed\ulnone of the latest driver! You can download and install the updated driver for \ul free\ulnone and instantly gain more than \b FOUR TIMES the performance\b0 from your current external Zip drive!\par +\par +\cf4\b Background:\par +\cf5\b0 I discovered this problem when 'Trouble In Paradise' (TIP) was having difficulty running on many existing external Zip systems. When I tracked down the problem, it turned out that TIP was attempting to transfer 64k bytes of data at a time (for good TIP-testing performance) \ul but those external Zip systems \b (like this one right here!)\b0 could only handle a maximum transfer of 8k bytes at a time\ulnone ! This meant that any software trying to read or write files to the drive would need to break up the data into eight times as many smaller pieces in order to squeeze the data out through the parallel port!\par +\par +Well, of course, I enhanced TIP immediately so that it \b would\b0 work on performance-crippled parallel port systems like this one \b . . .\b0 but I also added this information page so you'd know what TIP had discovered here, and \b how you could get your system rev'ed up to 400% more Zip Drive speed!\b0\par +\par +\cf4\b What do you need to do?\par +\cf5\b0 Although you may only need one relatively small (53k for Win95/98 or 44k for NT) driver file changed, it would probably be wisest to update your \b entire set\b0 of Iomega files \b . . .\b0 though this will take some downloading time. The "IOware9x" drivers are available in various flavors and are located on Iomega's FTP server at the following URL addresses:\par +\par +\cf4\b For Windows 95/98:\par +\cf6\b0 For the whole set of IOware9x Iomega Tools files:\par +\cf2\f1\fs18 ftp://ftp.iomega.com/pub/english/ioware9x.exe (4,375k)\cf5\f0\fs22\par +\cf6 For just the basic IOware9x driver files:\par +\cf2\f1\fs18 ftp://ftp.iomega.com/pub/english/ioware9xdrv.exe (811k)\par +\cf5\f0\fs22\par +\cf4\b For Windows NT:\cf5\b0\par +\cf6 For the whole set of IOware9x Iomega NT Tools files:\par +\cf2\f1\fs18 ftp://ftp.iomega.com/pub/english/iowarent.exe (4,240k)\cf5\f0\fs22\par +\cf6 For just the basic IOware9x NT driver files:\par +\cf2\f1\fs18 ftp://ftp.iomega.com/pub/english/iowarentdrv.exe (937k)\par +\cf5\f0\fs22\par +To simplify things for you, I've set up the two buttons below to \ul automatically choose the proper operating system version of the files\ulnone , and start the download from Iomega's FTP server. So you only need to decide whether you want the whole Tools file set (probably a good idea) or just the updated driver files (to save on download time.)\par +\par +No matter which you choose, simply run the resulting file.\par +\par +It will unpack the replacement files into your system's "temp" directory. Then you need to run the \b SETUP.EXE\b0 program located there to install the drivers. After restarting your system, you'll be all set with the latest and greatest files \b . . .\b0 and your parallel port Zip drive will be running more than FOUR TIMES faster than it ever has before!\par +\par +\cf1 (You might want to measure the transfer time of a large file \b before\b0 you perform the upgrade, then again afterward, to see for yourself how much your own Zip drive's performance has increased!)\par +\cf5\par +\cf4 Also note that you will \ul not\ulnone see this screen again after you upgrade since you'll then be using a parallel port driver that's capable of transferring 64k byte blocks for much greater performance! Therefore, if you wish to save this text for any reason, you should \ul press the \b Copy button\b0 below\ulnone to copy the contents of this window into your system's clipboard, then paste it into Notepad, Wordpad, or any other text container where it can be saved, eMailed, or shared with others.\par +\cf5\par +Best of luck to you, and I'm glad that I was able to help provide this significant performance boost for your system! Remember that this "Trouble In Paradise" program is freeware and that I encourage its distribution and sharing. You are invited to help me spread the word of this program's existence!\par +\par +\pard\qc\cf0\i\fs16 *Iomega, Zip, and Jaz are trademarks of Iomega Corporation.\par +\pard\i0\fs24 [trouble]\par +\pard\qc\cf1\b\fs44 TIP has Not Found\par +Any Compatible Drives.\par +\cf0\b0\fs16\par +\cf2\b\fs22 PLEASE NOTE: This program is specifically\par +designed for use with Iomega Corporation's ZIP\par + and JAZ removable media mass storage devices.\par +\par +\pard\cf5\b0 This Trouble In Paradise (TIP) program has been specifically designed for use with Zip and Jaz drives. This has allowed it to take advantage of many features specific and unique to these drives. Therefore it can NOT operate on other types of drives made by other manufacturers.\par +\par +\b Since TIP uses the ASPI interface, it may also fail to operate on some of the older non-ATAPI IDE ZIP drives:\par +\par +\cf1 The firmware revision of IDE/ATA drives that are NOT compatible with TIP have their letter appearing before the number like 'B.09' If your firmware revision level is like this, TIP will never be able to operate on this drive. Sorry!\cf5\par +\par +If you are having trouble with any other drive\b0 , or wishing to maintain or recover drive data, our commercial SpinRite disk utility product ($89) is the industry's leading general purpose hard disk maintenance, repair, and recovery tool. SpinRite functions with \b all\b0 drives of any make and model. Please see my web site for full information and purchasing details.\par +\par +If you believe that this program \b should\b0 be seeing a drive that it is not, you may need to update your system's ASPI drivers. \cf0 ASPI drivers are built into Windows 95 and 98, but are not part of Windows NT.\par +\par +If you are using Windows 95 or 98 and received this message then something is seriously messed up in your system. Reinstalling Windows may be necessary. If you own Adaptec controllers or software you \b\i may\b0\i0 be able to use their free \b\f1\fs24 ASPI32.EXE\b0\f0\fs22 program, located on the Adaptec web site at: http://www.Adaptec.com to fix the trouble.\par +\par +If you are using Windows NT you will need to locate a source for ASPI drivers for Windows NT. Adaptec's \b\f1\fs24 ASPI32.EXE\b0\f0\fs22 program (mentioned above) may work for you if you own Adaptec hardware or software.\par +\par +Also, the next release of this freeware (v3.0) will be re-engineered to NOT REQUIRE ASPI drivers. If all else fails, please place yourself on my eMail Notification System so that I can let you know when TIP can run without requiring ASPI drivers!\cf5\par +\par +\pard\qc\cf0\i\fs16 *Iomega, Zip, and Jaz are trademarks of Iomega Corporation.\par +\pard\i0\fs24 [defect]\par +\pard\qc\ul\b\fs44 Z-Track Failure!\ulnone\par +\b0\fs16\par +\cf1\fs28 The Drive Reports that it has been\par +completely \cf7\ul unable to access \b ANY\cf1\ulnone\b0\par +of this Cartridge's Four "Z" Tracks.\par +\pard\cf0\fs22\par +\cf2\b Background:\cf0\b0\par +Zip and Jaz drives are completely dependent upon private information stored in four redundant hidden cartridge disk tracks known as \b\i Z-tracks\b0\i0 .\par +\par +\cf2\b Consequence:\cf0\b0\par +When all four of these \b Z-tracks\b0 have been damaged by a 'Click Of Death' defective writing drive, all drives (whether they are good or bad) will refuse to access \cf1\ul\b ANY\cf0\ulnone\b0 of the data contained within the cartridge \b . . .\b0 \cf1\ul\b and ALL information is lost forever!\cf0\ulnone\b0\par +\par +\cf2\b Recourse:\cf0\b0\par +\pard\qc\b\par +\fs28 There is \ul NO KNOWN MEANS\ulnone of\par +repairing or reconstituting a\par +cartridge's dead Z-tracks.\par +\b0\fs22\par +\pard Perhaps Iomega can bring a cartridge's Z-tracks back to life. However, I have been told over and over by engineers within Iomega that the Z-tracks are completely inaccessible to external software utilities and that \b there's nothing anyone can do\b0 to access the data on any cartridge that has had all four of its Z-tracks damaged.\par +\par +Depending upon the precise nature of the Z-track damage, I would think that there's an \ul outside chance\ulnone that another drive \ul might\ulnone be able to read at least one of the Z-tracks, or that even \ul this\ulnone drive might. Since Z-tracks are initially read upon insertion of the cartridge, you must eject and re-insert the cartridge hoping to eventually get one Z-track recognized.\par +\par +However, \ul if this drive\ulnone is the one which is believed to have damaged the tracks in the first place, then doing so won't repair the damage. You \ul must\ulnone use a known-good drive in order for it to re-write the bad Z-tracks, thus making the cartridge's data once again available.\par +\par +\b But be sure you understand: \b0 This might \ul only\ulnone work if you are \ul extremely lucky\ulnone and manage to briefly get a drive to successfully read at least one of this cartridge's Z-tracks.\par +\par +\cf2\b And now:\cf0\b0\par +TIP can do nothing further with this cartridge in its present condition. Please eject it now and try working with another cartridge, or try this cartridge with this program on another drive to induce that drive to possibly effect Z-track repair.\par +\par +\pard\qc\i\fs16 *Iomega, Zip, and Jaz are trademarks of Iomega Corporation.\par +\pard\i0\fs24 [locked]\par +\pard\qc\b\fs44 This Cartridge is Locked\par +\b0\fs16\par +\cf1\fs28 Since this program reads and writes,\par +the removable cartridge must be\par +unlocked for reading and writing.\par +\pard\cf0\fs22\par +You must eject and re-insert this cartridge, then properly respond to the password dialog box, or use another cartridge that has not had write or read/write protection applied to it.\par +\par +\pard\qc\i\fs16 *Iomega, Zip, and Jaz are trademarks of Iomega Corporation.\i0\fs22\par +\pard\fs24 [nospares]\par +\pard\qc\b\fs44 This Cartridge is in\par +Serious Trouble!\par +\b0\fs16\par +\cf1\fs28 The drive reports that this cartridge's\par +spare sector pools have been\par +completely exhausted.\par +\pard\cf0\fs22\par +\cf2\b Background:\cf0\b0\par +Zip and Jaz drives maintain spare sectors that are automatically called into use when an \ul apparently defective \ulnone sector is encountered during reading and writing.\par +\par +I say "\ul apparently defective\ulnone " above, since "Click Of Death" Iomega drives damage its cartridge's sectors. Then, after the sectors have been damaged, they are replaced with new sectors from the cartridge's spare sector pools! In other words, nothing was really wrong with the sectors the drive was replacing -- until it had damaged them itself, or in misreading them believed them to be damaged -- then the drive replaced those previously good sectors with spares.\par +\par +\pard\qc\b This destructive cycle repeats until all\par +spare sectors have been consumed !\par +\pard\b0\par +Therefore, the fact that this cartridge's spare sectors have all been consumed, \b strongly suggests\b0 that at some point in the past this cartridge came into contact with a bad Iomega drive.\par +(\ul Even if the drive it is running on now is perfectly fine.\ulnone )\par +\par +\cf2\b Consequence:\cf0\b0\par +Since spare sectors \b are required\b0 for safe use of any Iomega cartridge, this cartridge can not be safely tested, nor can it be safely used for storing data.\par +\par +\cf2\b Recourse:\cf0\b0\par +If this cartridge contains valuable data, the data should be moved to safety immediately, then the cartridge should receive a "Long Format" on a \b known good Iomega drive\b0 (i.e. a drive which has recently passed TIP testing.)\par +\par +If the data can not be read from this cartridge on a known good drive then my commercial SpinRite utility can be used to repair and recover the cartridge's data, but \ul\b ONLY\ulnone\b0 use SpinRite with cartridges on Iomega drives that are known to be good. (SpinRite description and purchasing information can be found on my web site at: http://grc.com.)\par +\par +At the time of this writing I plan to create another utility program for users of Iomega products. It will be able to test Iomega drive products and also to perform short and long Iomega reformats. Please check my web site at http://grc.com for further information on this next product.\par +\par +\pard\qc\i\fs16 *Iomega, Zip, and Jaz are trademarks of Iomega Corporation.\i0\fs22\par +\pard\fs24 [outofspares]\par +\pard\qc\b\fs44 This Cartridge's Spare Sectors Have All Been Consumed!\par +\b0\fs16\par +\cf1\fs28 The drive reports that this cartridge's\par +spare sector pools have been\par +completely exhausted.\par +\pard\cf0\fs22\par +\cf2\b Background:\cf0\b0\par +Zip and Jaz drives maintain spare sectors that are automatically called into use when an \ul apparently defective \ulnone sector is encountered during reading and writing.\par +\par +I say "\ul apparently defective\ulnone " above, since "Click Of Death" Iomega drives damage its cartridge's sectors. Then, once they've been damaged it replaces them with new sectors from the cartridge's spare sector pools. In other words, nothing was really wrong with the sectors it was replacing -- until it had damaged them itself or in misreading them believed them to be damaged -- then it replaced those previously good sectors with spares. This destructive cycle repeats until all spare sectors have been consumed.\par +\par +The primary function of this Iomega drive testing program is to induce this sort of behavior in the drive since sector damage is the most apparent symptom of a drive which is writing incorrectly to the cartridge.\par +\par +\cf2\b Consequence:\par +\cf0 The fact that this cartridge's spare sectors have all been consumed during this simple reading and writing test, \ul STRONGLY SUGGESTS that this drive is seriously defective and should no longer be used.\b0\par +\ulnone\par +\cf2\b Recourse:\cf0\b0\par +If this cartridge contains valuable data, the data should be moved to safety immediately, then the cartridge should receive a "Long Format" on a \b known good Iomega drive\b0 (i.e. a drive which has recently passed TIP testing.)\par +\par +If the data can not be read from this cartridge on a known good drive then my commercial SpinRite utility can be used to repair and recover the cartridge's data, but \ul\b ONLY\ulnone\b0 use SpinRite with cartridges on Iomega drives that are known to be good. (SpinRite description and purchasing information can be found on my web site at: http://grc.com.)\par +\par +At the time of this writing I plan to create another utility program for users of Iomega products. It will be able to test Iomega drive products and also to perform short and long Iomega reformats. Please check my web site at http://grc.com for further information on this next product.\par +\par +\pard\qc\i\fs16 *Iomega, Zip, and Jaz are trademarks of Iomega Corporation.\i0\fs22\par +\pard\fs24 [fewspares]\par +\pard\qc\b\fs44 This Cartridge Has\par +Very Few Available\par +Spare Sectors\par +\b0\fs16\par +\cf1\fs28 The drive reports that this cartridge's\par +spare sector pools are nearly exhausted.\par +\pard\cf0\fs22\par +\cf2\b Background:\cf0\b0\par +Zip and Jaz drives maintain spare sectors that are automatically called into use when an \ul apparently defective \ulnone sector is encountered during reading and writing.\par +\par +I say "\ul apparently defective\ulnone " above, since "Click Of Death" Iomega drives damage its cartridge's sectors. Then, once they've been damaged it replaces them with new sectors from the cartridge's spare sector pools. In other words, nothing was really wrong with the sectors it was replacing -- until it had damaged them itself or in misreading them believed them to be damaged -- then it replaced those previously good sectors with spares. This destructive cycle repeats until all spare sectors have been consumed.\par +\par +\cf2\b Consequence:\par +\cf0\b0 The primary function of this Iomega drive testing program is to induce this sort of erroneous spare sector allocation since sector damage is the most apparent symptom of a drive which is writing incorrectly to the cartridge.\par +\par +However, the fact that so many of this cartridge's spare sectors have \ul already\ulnone been consumed \b strongly suggests\b0 that at some point in the past this cartridge came into contact with a bad Iomega drive . . . \ul even if the drive it is running on now is perfectly fine.\ulnone\par +\par +This means that this drive testing program might detect sectors that were damaged by some \ul other\ulnone drive, for which the drive being tested now would be erroneously and unfairly blamed.\par +\par +If no \ul additional\ulnone damage is caused by this current drive on this questionable cartridge, then you'll know this drive is working correctly, but if \ul new damage\ulnone is detected you won't know whether it was old damage only now being detected or new damage.\par +\par +\cf2\b Recourse:\cf0\b0\par +If you wish to proceed with the test using this questionable cartridge, press the "Press to Proceed" button in the upper right. Otherwise eject this cartridge and find another one to be used for this test.\par +\par +If your goal is to determine whether this drive is functioning properly and reliably then testing it with the best cartridge will yield the clearest and most reliable results.\par +\par +\pard\qc\i\fs16 *Iomega, Zip, and Jaz are trademarks of Iomega Corporation.\i0\fs22\par +\pard\fs24\par +[notrunning]\par +\pard\qc\cf2\b\fs44 Insert a cartridge,\par +then press the\par +"Press to Begin" button\par +\cf0\b0\fs16\par +\cf1\fs28 This explanation page will help you\par +to interpret the testing results once\par +the testing is completed.\par +\pard\cf0\fs22\par +\b Please return to this page once the testing has finished.\par +\b0\par +To start testing insert a cartridge into your Iomega drive of choice then press the "Press to Begin" button at the upper right.\par +\par +You may interrupt the testing at any time by pressing the "Press to Stop" button at the upper right. However, final result interpretations will not be available unless the test is allowed to run to its conclusion.\par +\pard\qc\i\fs16\par +*Iomega, Zip, and Jaz are trademarks of Iomega Corporation.\par +\pard\i0\fs24 [running]\par +\pard\qc\cf2\b\fs44 The Testing is\par +Currently Underway\par +\cf0\b0\fs16\par +\cf1\fs28 When the testing is completed this\par +explanation page will help you to\par +interpret the testing results.\par +\pard\cf0\fs22\par +\b Please return to this page once the testing has finished.\par +\b0\par +You may interrupt the testing at any time by pressing the "Press to Stop" button at the upper right. However, final result interpretations will not be available unless the test is allowed to run to its conclusion.\par +\pard\qc\i\fs16\par +*Iomega, Zip, and Jaz are trademarks of Iomega Corporation.\par +\pard\i0\fs24 [interrupted]\par +\pard\qc\cf2\b\fs44 The Test was Interrupted before its Conclusion\par +\cf0\b0\fs16\par +\cf1\fs28 The condition of this drive and\par +cartridge is unknown because\par +the test was not completed.\par +\pard\cf0\fs22\par +\cf2\b Analysis . . .\cf0\b0\par +Although the drive and cartridge appear to be reasonably fine up to the point of interruption, conclusions can not be drawn from this partial testing. To determine the condition of this drive and cartridge the test must run to its conclusion.\par +\par +You may restart the test from the beginning by pressing the "Press to Begin" button in the upper right.\par +\pard\qc\i\fs16\par +*Iomega, Zip, and Jaz are trademarks of Iomega Corporation.\par +\pard\i0\fs24 [perfectresult]\par +\pard\qc\cf2\b\fs44 This Drive & Cartridge are\par +in \ul PERFECT CONDITION\ulnone !\par +\cf0\b0\fs16\par +\cf1\fs28 The drive and cartridge have together\par +passed TIP's tests with flying colors!\par +\pard\cf0\fs22\par +\cf2\b Congratulations!\cf0\b0\par +\ul\b This test could not have run any more perfectly!\ulnone\par +\b0 Not one single problem of any sort was detected:\par +\cf1\f2\fs24\'b7\cf0\f0\fs22 \ul\b No\ulnone\b0 sectors were difficult to locate,\par +\cf1\f2\fs24\'b7\cf0\f3 \ul\b\f0\fs22 No\ulnone\b0 sectors needed relocation,\par +\cf1\f2\fs24\'b7\cf0\f0\fs22 \ul\b No\ulnone\b0 read or write errors of \ul any\ulnone sort occurred.\par +\par +The \b ONLY WAY\b0 this outcome could have been reached is if this drive and cartridge are \b BOTH\b0 in \b FLAWLESS\b0 working condition. (There's \ul NO trouble\ulnone in your paradise!)\par +\par +\pard\qc\cf2\b\fs24 You May Use this Drive & Cartridge\par +with \ul Total\ulnone Confidence.\par +\cf0\b0\fs22\par +\pard Please note that it's rare (but terrific) for a system to pass this test without even a single "Soft Error" as yours has just done. So even if you seldom receive this perfect result, your drive and cartridges can still be in TIP top shape!\par +\par +\pard\qc\i\fs16 *Iomega, Zip, and Jaz are trademarks of Iomega Corporation.\par +\pard\i0\fs24 [explainresult]\par +\pard\qc\cf2\b\fs36 This Drive & Cartridge Appear\par +to be in Good, \i but Perhaps\par +Not Perfect\i0 , Condition\par +\cf0\b0\fs16\par +\cf1\b\f4\fs32 Interpreting the Report of\par +Soft, Firm, and Hard Errors:\par +\pard\cf5\b0\f0\fs22\par +\b\fs24 Soft Errors \b0\fs22 are just that ... soft. They come and they go, they vary in size and number from one run of TIP to the next. \ul This is completely normal behavior and is not a cause for concern.\ulnone These soft errors are the result of small defects in the recording media, or various environmental factors affecting the drive like vibration, humidity, and ambient magnetic fields. The troubled sectors can either be re-read or compensated for with the drive's built-in error correcting technologies.\par +\par +You can think of soft errors like a pen that skips while writing. Some degree of skipping is normal and expected, and you can easily go back and fill-in after the skip. But as the pen begins skipping more and more, you end up being slowed down in your work, and excessive skipping \ul\i can\ulnone\i0 be an indication of a pending failure. So it's something that's worth keeping an eye on. This is what TIP's "Soft Error" report allows you to do.\par +\par +As with all things in TIP, there's no hard and fast rule that states exactly when you might be in trouble. But after a while you'll develop a sense for the way your various Iomega drives and cartridges behave, and TIP's reporting of "soft errors" will then provide you with a valuable and extremely sensitive measure of the state of your system.\par +\par +\b\fs24 Firm Errors\b0\fs22 are soft errors that grew so large that the drive became concerned that it might soon be unable to continue recovering and correcting them. So rather than risk losing the sector's data altogether (with a hard error), the drive removed the troubled sector from further use after relocating its data into a spare safe sector.\par +\par +This automatic defective sector relocation, reported by TIP as a "Firm Error", is completely normal behavior for all Iomega drives, \ul unless it begins happening with great frequency\ulnone . Please see the "Analysis" section below, for further help with understanding the role and importance of Firm Errors.\par +\par +\b\fs24 Hard Errors\b0\fs22 are a problem. They are sectors that jumped directly from "recoverable" to "unreadable" without giving the drive the chance to rescue their data and them as defective. A healthy cartridge should \ul never\ulnone have any hard errors, and as with firm errors, a cartridge with many hard errors is a sure sign of significant trouble. The following "Analysis" section will help you to understand the significance of Hard errors.\par +\par +\cf2\b\fs24 Analysis . . .\cf0\b0\fs22\par +A relatively small number of completely correctable (\b Soft\b0 ) read/write errors occurred during the test, and may have resulted in one or more apparently questionable sectors being taken out of service, as a \b Firm Error\b0 .\par +\par +This \ul can\ulnone be entirely normal operation for a completely healthy Zip or Jaz drive, particularly if this is the first time that a thorough disk scan of this sort has been performed after the cartridge has been in use for some time.\par +\par +However, excessive soft errors or repeating firm and hard errors can also be an \ul early\ulnone indication of drive trouble.\par +\par +The test should be run again right now to see whether this pattern repeats: \par +\par +\cf1\f2\fs24\'b7\cf0\f0\fs22 As was explained above, \ul a moderate number of soft errors\ulnone is always to be expected and is \ul\b NO\ulnone\b0 cause for alarm. Soft errors will probably always be present. Only the occurrence of a huge number of these should ever be a concern.\par +\par +\cf1\f2\fs24\'b7\cf0\f0\fs22 If \ul\b NO\ulnone\b0 additional firm errors occur, you can safely assume that the first pass actually \ul did\ulnone find and resolved a few true media defects -- which is common and expected behavior.\par +\par +\cf1\f2\fs24\'b7\cf0\f0\fs22 \b BUT . . .\b0 if rerunning this test \ul AGAIN\ulnone has apparently located some new firm or hard errors (which the last test "missed", and finds a few more "apparently bad" sectors \b . . .\b0 then you should conclude that this drive and/or cartridge is beginning to show early signs of 'Click Of Death' behavior.\par +\par +\pard\qc\cf2\b If impending 'Click Of Death' seems indicated,\par +the trick now is to determine whether the\par +trouble is with the drive or with the cartridge.\par +\pard\cf0\b0\par +(Note: If your data on this cartridge is important, this might be a very good time to consider saving this data somewhere else!)\par +\par +If you have another cartridge you should use it right away with the same drive under TIP to attempt to isolate the cause of the trouble as follows:\par +\par +\cf1\f2\fs24\'b7\cf0\f0\fs22 If another cartridge behaves similarly in the same drive, the trouble is more likely with the drive -- since the drive will have been the common element in both tests which were somewhat troubled.\par +\par +\cf1\f2\fs24\'b7\cf0\f0\fs22 But if a second cartridge behaves perfectly in the same drive (where the first one never did), then the trouble is more likely to be with the first cartridge -- since replacing the troubled element resolved the problems.\par +\par +\cf1\f2\fs24\'b7\cf0\f0\fs22 And if you have access to a second drive, you could try using the original cartridge in this second drive to gather additional objective evidence about the true behavior of the original drive and cartridge.\par +\par +\cf2\b Conclusion:\cf0\b0\par +As you can see, by using TIP to exercise various combinations of Iomega drives and cartridges, it will be possible for you to reach verifiable conclusions about the condition, behavior, and reliability of your Iomega removable storage products.\par +\par +\cf1\b It is my sincere hope that this will result in more effective and satisfying personal computing experiences for everyone, and may help Iomega's users to enjoy their products while providing valuable feedback to Iomega.\par +\b0\par +\cf5 Please see the \b Next\b0 panel in this program (by pressing the 'Next' button below) for information regarding Iomega's return policy for in-warranty and out-of-warranty drive products.\par +\par +Their official spokesman has stated that Iomega will stand behind their products and that \b any drives will be replaced whether they are in warranty or not!\b0 This is great news for people whose Iomega drives have been dying!\par +\cf0\par +\pard\qc\i\fs16 *Iomega, Zip, and Jaz are trademarks of Iomega Corporation.\par +\pard\i0\fs24 [badresult]\cf5\fs22\par +\pard\qc\cf1\b\fs44 Something is VERY\par +WRONG Somewhere.\par +\cf0\b0\fs16\par +\cf3\fs28 The test has encountered a suspiciously\par +large number of "Firm" and/or\par +"Hard" errors while running!\par +\pard\cf0\fs22\par +\cf2\b Analysis . . .\cf0\b0\par +TIP has encountered a \b large\b0 number of data-loss related troubles, demonstrating that this drive and cartridge are not getting along together at all!\par +\par +Your task now is to determine the \b cause and source \b0 of these troubles:\par +\par +\cf1\f2\fs24\'b7\cf0\f0\fs22 \b Is it the drive\b0 which is not operating properly and reliably, thus creating these troubles on the cartridge?\par +\par +\cf1\f2\fs24\'b7\cf0\f0\fs22 Or, instead, were these troubles caused by a cartridge that had \b already been damaged\b0 by its use in some other malfunctioning Zip drive?\par +\par +\pard\qc\cf2\b If you have another cartridge or drive, you should use\par +them with the same drive or cartridge to attempt\par +to isolate the cause of the trouble as follows:\par +\pard\cf0\b0\par +\cf1\f2\fs24\'b7\cf0\f0\fs22 \b If another cartridge behaves similarly in the same drive\b0 , the trouble is more likely with the drive -- since the drive will have been the common element in both tests which were somewhat troubled.\par +\par +\cf1\f2\fs24\'b7\cf0\f0\fs22 But\b if a second cartridge behaves perfectly in the same drive \b0 (where the first one had serious problems), then the trouble is more likely to be with the first cartridge -- since replacing the troubled element resolved the problems.\par +\par +\cf1\f2\fs24\'b7\cf0\f0\fs22 And\b if you have access to a second drive\b0 , you could try using the original cartridge in this second drive to gather additional objective evidence about the true behavior of the original drive and cartridge. (Although, with troubles as extensive as this first cartridge experienced, the damage may be too extreme for a test with a second drive to be conclusive.)\par +\par +\cf1\f2\fs24\'b7\cf0\f0\fs22 Or \b if you do not have access to other equipment\b0 , re-running the same TIP test on the same drive and cartridge might prove useful if TIP and the drive were able to repair some of the cartridge's initial damage. If the second use of TIP on the cartridge is substantially better than the first try, you could tentatively conclude that the cartridge was at fault, and that the drive is operating reliably.\par +\par +\cf2\b Conclusion:\cf0\b0\par +As you can see, by using TIP to exercise various combinations of Iomega drives and cartridges, it will be possible for you to reach verifiable conclusions about the condition, behavior, and reliability of your Iomega removable storage products.\par +\par +\cf1\b It is my sincere hope that this will result in more effective and satisfying personal computing experiences for everyone, and may help Iomega's users to enjoy their products while providing valuable feedback to Iomega.\par +\b0\par +\cf5 Please see the \b Next\b0 panel in this program (by pressing the 'Next' button below) for information regarding Iomega's return policy for in-warranty and out-of-warranty drive products.\par +\par +Their official spokesman has stated that Iomega will stand behind their products and that \b any drives will be replaced whether they are in warranty or not!\b0 This is great news for people whose Iomega drives have been dying!\cf0\par +\pard\qc\i\fs16\par +*Iomega, Zip, and Jaz are trademarks of Iomega Corporation.\par +\i0\fs22\par +\pard\fs24 [iomegaquote]\par +\pard\qc\cf2\b\fs36 So \ul WHAT CAN YOU DO\ulnone If Your Iomega Drive Has Click Of Death?\fs44\par +\fs22\par +\cf1\fs44 THERE'S FANTASTIC NEWS,\par +Directly from Iomega!\cf2\par +\cf5\b0\fs16\par +\pard\cf0\fs22 Iomega's customers have believed that if their drive failed after the expiration of its one-year warranty that they were out of luck.\par +\par +\pard\qc\cf3\ul\b\fs28 But this turns out NOT to be the case at all!\par +\pard\cf0\ulnone\b0\fs22 \cf5\fs24\par +\fs22 On June 16th 1998, I appeared on ZDTV's nationally televised 'Screen Savers' program to explain everything I'd learned about the Iomega Click Of Death problem. \b During the second half of the show we were joined -- over the telephone -- by Iomega's Spokesman and the General Manager of Zip Aftermarket Business, David Hellier.\par +\par +\b0 During his telephone statement, David surprised me by telling the whole world that \b Iomega would replace \ul any\ulnone drives suffering from CLICK OF DEATH \ul whether they are within warranty or not\ulnone !!!\b0\par +\par +Here are David's exact words:\par +\par +\i "I\cf0 f our customers have a problem specific to this issue, whether it's in or out of warranty, we're going to take care of and replace the product if necessary."\i0\par +\par +\cf2\b That's Right!\par +\cf0\b0 This means that you are no longer stuck with bad Zip and Jaz drives \b . . .\b0 even if you've had the drive longer than one year! I'm very glad to be able to tell you that Iomega has decided to step up to the plate and take full responsibility for this problem!\par +\par +\cf1\b . . . And \ul YOU\ulnone can hear him say this for yourself !\par +\cf0\b0 If you are running this program while you are connected to the Internet, or if your computer "knows" how to connect to the 'Net when you click on a URL-style link, you can use the two buttons below to quickly download two short (79k and 71k) wave files to hear David Hellier's statement for yourself!\par +\par +\cf1\f2\fs24\'b7\cf0\f0\fs22 The first button is his introduction of himself, by phone, during the television broadcast. The URL for this 79k wave file is:\par +\par +\pard\qc\f5\fs24 http\f1 ://grc.com/hellier1.wav\par +\pard\f0\fs22\par +\b . . .\b0 which you are welcome to eMail to your friends, post on other web sites, announce in newsgroups, or give to Iomega's Technical Support personnel if they have not yet received the great news that \ul Iomega has agreed to replace any out-of-warranty Click Of Death drives!\ulnone\par +\par +\cf1\f2\fs24\'b7\cf0\f0\fs22 The second button is the relevant excerpt from his full statement which comes as \b fabulous news\b0 to the tens of thousands of troubled users of Iomega's products! (Iomega has estimated that perhaps as many as 100,000 users will be affected by these problems.) The URL for the 71k 2nd wave file is:\par +\pard\qc\f5\fs24 htt\f1 p://grc.com/hellier2.wav\par +\pard\f0\fs22\par +\b . . .\b0 which you are similarly welcome to share with anyone who needs to hear it!\par +\par +\pard\qc\cf1\b\fs24 You may press the buttons below at any\par +time to download these wave files.\b0\par +\pard\cf0\fs22\par +\cf2\b For additional background:\par +\cf0\b0 David Hellier's statement was made at the end of my segment of ZDTV's (Ziff-Davis Television) 'Screen Savers' program, and links to \b ZDTV's RealVideo clips\b0 of \ul my\ulnone segment of the program can be found at my web site, and you can also find a link to ZDTV's page which they created for the show.\par +\par +Unfortunately, the RealVideo clip provided by ZDTV's server cuts off just as David Hellier starts to make his statement -- presumably because it wasn't really relevant to the technical issues we were discussing. \b So if you would like to hear the AUDIO track for the ENTIRE show\b0 , I have made that available on my web site at:\par +\par +\pard\qc\f1\fs24 http://grc.com/clickofdeath.ram\par +\pard\f0\fs22\par +. . . which you can listen to with a RealAudio player (which is free and also available through a link on my and ZDTV's site, and directly from http://www.real.com) \b Just type that URL address (above) into your web browser . . . and you'll be listening to the audio track of the entire show!\b0\par +\par +\pard\qc\ul\i Please note that ALL of this content from the TV show is the copyrighted property of Ziff-Davis TV, at \i0 http://zdtv.com\i .\ulnone\i0\par +\pard\par +\cf2\b Convincing Iomega that your drive \ul Really IS Bad\ulnone . . .\par +\cf5\b0 Obviously, replacing up to 100,000 Zip and Jaz drives in the field, will be quite expensive for Iomega. (But let's remember that up until now it's been \b very expensive\b0 for Iomega's customers, who frequently lost \b not only their drives\b0 but also their data as well.)\par +\par +So, until this 'Trouble In Paradise' program has been around long enough to become known and trusted as the standard and reliable means for measuring Iomega drive health, I would not be surprised if Iomega were disinclined to take my program's word for the fact that your drives are defective.\par +\par +\pard\qc\cf1\b\fs28 So here's a work-around to help you\par +get past this potential hurdle . . .\par +\pard\cf2\fs22\par +\cf5\b0 The standard Iomega "Long Format" operation, which can be easily performed using Iomega's DOS or Windows utilities, \ul will fail on many 'Click Of Death" drives!\ulnone So this provides you with another means -- \i not involving ANY non-Iomega third party software\i0 -- for demonstrating to them that your drive is no longer functioning as it should.\par +\par +\pard\qc\cf3\b\fs24 Given a working cartridge, there is \ul ABSOLUTELY\par +NO REASON\ulnone why an Iomega Long Format should\par +fail . . . except if the drive is no longer even\par +able to format one of its own cartridges!\par +\pard\cf5\b0\fs22\par +Since a Long Format performs a brief media recertification, this performs a less sensitive version of TIP's sensitive read/write testing \b . . .\b0 and has the significant advantage of using \ul nothing\ulnone other than Iomega's own software. Of course, doing this will wipe out any data that was on the cartridge beforehand, and may very well damage the cartridge permanently \b . . .\b0 but all Iomega cartridges have always had a lifetime warranty, so you can get it replaced at the same time as your Click Of Death drive.\par +\par +The Long Format provides much less feedback to you -- before, during, or after its operation -- than TIP does, so you'll never really know what's going on. It'll just fail with an error message, but that's all you'll need to show Iomega that your drive needs replacement.\par +\par +Thus, this work-around gives you an inarguable position to take when getting Iomega to acknowledge that your drive is no longer safe to use and needs to be replaced under David Hellier's replacement policy.\par +\par +\cf2\b In case you have trouble with Iomega's Technical Support:\par +\cf0\b0 Since the Technical Support for Iomega's products has been sub-contracted to a outside company, they may be unaware of Iomega's return and replacement policies for Click Of Death drives.\par +\par +So, if you experience difficulty when dealing with Iomega's sub-contracted technical support, you may need to give David Hellier a phone call to let him know that the news of his policies have not yet filtered down to the appropriate persons handling product returns and replacements \b . . .\b0 and ask him what you should do to get your drive replaced.\par +\par +\pard\qc\cf1\b You can reach David at Iomega's main number:\par +1-801-778-1000, then ask to speak with David Hellier.\par +\pard\cf0\b0\par +Based upon the tremendous concern David demonstrated for the well-being of Iomega's customers (which you are welcome to hear for yourself -- in full -- on my web site), \b I am certain that David would want to know immediately if Iomega's customers were NOT receiving the treatment that he has said Iomega intends to provide to all of their customers. \b0 Thus, you would be doing your part \ul for everyone who has these problems\ulnone by letting David know if his policies are not being correctly implemented by MCI Call Centers, the people who are handling Iomega's Technical Support.\par +\pard\qc\cf1\b\fs96 ~\cf0 \cf8 ~\cf0 \cf2 ~\cf0\b0\par +\pard\cf2\b\fs22 Well, this is Goodbye For Now . . .\par +\cf5\b0 I hope that you have found this 'Trouble In Paradise' Iomega drive and cartridge testing tool useful, and that it will serve as your trusted companion for the foreseeable future, providing you with tools and knowledge to increase the reliability of your Iomega data storage experiences.\par +\par +Remember to check back with my web site at http://grc.com for updates and news of other related developments in this area!\par +\par +As soon as the dust settles from this release of 'Trouble In Paradise', I'll be starting work on a new and inexpensive product which you'll be able to use to track, manage, and maintain all of your Iomega cartridges throughout their entire useful life.\par +\par +If that sounds interesting to you, you can drop by my web site and add yourself to the 'Click Of Death' mailing list so that you'll receive automatic notification when this next goodie is ready for you! The address is: http://grc.com/mail.htm\par +\par +Best luck to you! \cf2\b\i\fs32 -- Steve.\cf5\b0\i0\fs22 \fs16 11/28/99\cf0\par +\pard\qc\fs22\par +\i\fs16 *Iomega, Zip, and Jaz are trademarks of Iomega Corporation.\par +\pard\i0\fs24 [EndOfText]\par +} + \ No newline at end of file diff --git a/x86-asm-source/SCSIID.ASM b/x86-asm-source/SCSIID.ASM new file mode 100644 index 0000000..490b056 --- /dev/null +++ b/x86-asm-source/SCSIID.ASM @@ -0,0 +1,83 @@ +Here is some code that will take a handle to an open partition and return +the SCSI ID. For example, if you opened \\.\D: and called the following +code, it will return the SCSI ID for that drive letter. + +This code is kernel-mode, but can easly be translated to native NT by +changing the ZwXxx() calls to NtXxx() calls. I assume you can make a fairly +easy Win32 implementation since this function shows the IOCTL and data +structure to use. + +Have fun... + +// Get scsi address information about a device. This includes +// the port, bus, id, and lun, as well as the shortname of the miniport +// driver that owns the device. +// +// Arguments: +// +// Handle - handle to open device. +// +// ScsiAddress - receives port, bus, id, and lun for the device described +// by Handle. +// +// ScsiAdapterName - receives pointer to buffer containing shortname +// for miniport driver that owns the device (ie, aha154x). +// The caller must free this buffer via SpMemFree(). +// +// Return Value: +// +// TRUE - scsi address information was determined successfully. +// FALSE - error determining scsi address information. + +BOOLEAN GetScsiAddress +( + IN HANDLE Handle, + OUT PSCSI_ADDRESS ScsiAddress, + OUT PWSTR *ScsiAdapterName +) +{ + NTSTATUS Status; + PWSTR MiniportName = NULL; + IO_STATUS_BLOCK IoStatusBlock; + + Status = ZwDeviceIoControlFile + ( + Handle, + NULL, + NULL, + NULL, + &IoStatusBlock, + IOCTL_SCSI_GET_ADDRESS, + NULL, + 0, + ScsiAddress, + sizeof (SCSI_ADDRESS) + ); + + if (!NT_SUCCESS(Status)) + { + KdPrint(("SETUP: Unable to get scsi address info (%lx)\n",Status)); + return (FALSE); + } + + // We can get the miniport name from the scsi port information list + // we built earlier. + + if(ScsiAddress->PortNumber < ScsiPortCount) + MiniportName = ScsiPortInfo[ScsiAddress->PortNumber].MiniportName; + else + { + // This should not happen. + ASSERT(ScsiAddress->PortNumber < ScsiPortCount); + + MiniportName = (PWSTR)TemporaryBuffer; + } + + *ScsiAdapterName = DupString(MiniportName); + + return (TRUE); +} + + + + diff --git a/x86-asm-source/Sixteen.bmp b/x86-asm-source/Sixteen.bmp new file mode 100644 index 0000000000000000000000000000000000000000..bbae1f2709c41734ef48af6dd39e8358babca079 GIT binary patch literal 8566 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 literal 0 HcmV?d00001 diff --git a/x86-asm-source/TIP.APS b/x86-asm-source/TIP.APS new file mode 100644 index 0000000000000000000000000000000000000000..ce43ccde59098f65637b054aef756a4c7a7d2222 GIT binary patch literal 2816 zcmcImOHWf#5dQ9M5%E=+F6htj zXSi_DrTQyO+_+>X3-tKSoO63Fv``Y`q;u!YoSC_E&OB}bAV)ODBA1)sD7hix1Ri0G z)R@5S_odweANzpY*Jewv7iMRwb;04Kd2ap;W8bNkUB2Jjou^KYc#9aox{GMj86to` zM3E(Ya!HKPY&N+e2M}T`;nSW;goIzq%gc*)sn7LBqwzm^Ls(0^uiNr}#J8F_pq#gn z5M+c;3RI!7+KMw{1>S`fsDcePW5k0PxXTou+w#2s<>Wrs0xf;Z?vA&?tA&kEB2jSJ zX6`LWbf%d#J7TQdQLmS_fid5)!hGH|>&Tiv$gK57#P1eCehaPx*$q&iuODO#LlTEM zgc(#(m!JsAUXTt5kjwRJCrIZ67-6gBs3$#VjBSjh%^vP;?jhHk+w>5RNsHY>>JK2; zOS23yYoZpO_#NTIg2#au)O|vv`%Xx)LVVTT=sHgv;~KACuD{9a+#XlV&lGL4#Fcj3 zFcy3+4(yPNP;!A=eA+C8Xfk@6!@kXS@bl~lo-tX#5t)>vq2t3Af8EJ1C{5vv(|?IT z?P^LxSUyC|-*EC_r74_q`tJ~`-D9O8EFZ%1DV*hilzf~=p!6g{rKgZmdKzic4?I~9 z=~I@EoYBwvFXULKJY!r^Csk6a*K4JF6>!w^hEOe!&5f0A-$nl2_;@}q1t6kYn=5%B9n zqshv+c&5=P_NnAS-SU^PU-{|koe8IM83$BUo_bWXN>^~uMmSlmRn+oIo+rt8VOcaO zETG>C>!mv_%_0taVXS$Pm7o`4!>8>C2CT%zPthn?lDyR)Or!%=$(B5P)tzJ>lCz{Q z{RYpmh+#hG@rt^}`0Dn%^LUFT?yk1w`CFU+!iXj}PIUX{{WwE3rcmsnmQ%H>U9`^n z5`t+}(?2b>hyr!??@KM)P@Q#Mx&lHZ=MaYF5GdmcCTua>Nhu=*lGc?LMo%PnD~RiD zxw4&@tOfaxRwnwsrICW4P4Y!~Pnj{D|BK07Y_M;WbtNv6-y8WJeO8^$-y`uc$gWOS x-&P+@3MN%&`#CCeD9=&g&*SHi_!E#G`NZMib$pMg0v}T6$2c#%j<54r=P$f~n_U0^ literal 0 HcmV?d00001 diff --git a/x86-asm-source/TIP.ASM b/x86-asm-source/TIP.ASM new file mode 100644 index 0000000..c0b9db0 --- /dev/null +++ b/x86-asm-source/TIP.ASM @@ -0,0 +1,3940 @@ +;+-----------------------------------------------------------------------------+ +;| TIP.ASM TROUBLE IN PARADISE 05/22/98 | +;+-----------------------------------------------------------------------------+ +; +;------------------------------------ TO DO ------------------------------------ +; +; o Inhibit Power Management during TIP ... systems are sleeping! +; +; o WINME and USB! +; +; o TIP sees Iomega CDRW as a ZIP drive! +; +; o Check operation with Jaz Traveller +; +; o Under NT4 the screensaver blanking killed TIP in mid-run. +; +; o Don't blank the results after a run and before the "view results" tab +; is presed. Somehow keep the results around longer. +; +; o Norton Anti-Virus (NAV) incompatibility. +; +; o Consider not forcing an eject of the "system" (boot) drive! +; +; o Suggest disconnection of other devices, scanners, toasters, etc. +; +; o Do NOT allow TIP to run on the main system BOOT drive!!!!!! +; +; o Remove the ASPI_VERSION Page +; +; o Tell'em about Firmware revision: B.29 won't work, 23.D does! +; +; o Add suggestion to REMOVE ALL OTHER DEVICES from drive chain +; +; o Add some cache flushing before locking for exclusive use! +; +; o Extra FAST, extra SAFE "Read-Only" mode ... (FOUR TIMES FASTER!) +; -- OR should we save this for CIA??? -- +; +; o Check for Eject-ability on 2GB Jaz while running! +; mvongunten@acm.org (Marcel) +; +; o TIP is not working with the JazJet card and the IOmegaNT.sys driver. +; The driver is invisible to the ASPI layer. +; "Earl, George" +; "James Wynn" +; Ron Charlton +; +; o TIP lockups under NT4/SP3 after using ASPI_ME with an Adaptec 1542 +; controller. Several reports of this configuration problem. +; Des Gordon +; +; o NT Startup delay ????? +; "Keating, Dan (Miami)" +; +; o "Don't Show This Anymore" option on the ASPI_ME warning screen. +; +; o Suppress Head Scrubs while running TIP? +; +; o Make ASPI_ME and TIP aware of Adaptec 4.57(1013) ... +; +; o Leave the Explain Results page in place, even AFTER they remove the +; disk, until they insert another one OR leave the Action Pages. + +;-------------------------------- Fixed in 2.2 --------------------------------- +; +; o USB drive hangs. +; +; o 250 Mb Parallel port errors at end +; +;------------------------------------- 3.0 ------------------------------------- +; +; o Fixed spastic requests for passwords once the system is running. +; +; o Updated references Iomega to w95_551 to ioware9x. +; +;------------------------------------------------------------------------------- +; +; o Division error in: ASPI.ASM -- main work loop (line 964) +; From: James Bodine +; +; o She's getting the "buffer too big" error on a SCSI Jaz drive! +; Tip-test reports "00FFFFE6" +; Dorothy Nyberg +; +; o Somehow, SERIOUS ERRORS are being missed at the end and people are +; being told that everything is fine! (On Jaz disks at least!) +; +; o NOTIFY WHEN 1.01 is ready ... Jason Strickland +; +;------------------------------------ 1.01 ------------------------------------- +; +; Fixed the links and pointers into Iomega's Site. +; +; Fixed undefined error reporting (when drives report a new error type) +; +; Added Auto-adaptive buffer sizing. It works to cure "buffer too big" +; +; Fixed nasty Adapter=0/Device=0 bug! +; +; Fixed "Copy" bug which had skewed pages! +; +; Fixed non-password Write Protected cartridge dialog. +; +; Fixed a "happened once" divison overflow error in: GetElapsedTimeInSeconds +; +; Fixed Macintosh disks reporting "needs exclusive access." +; (Of course, since we can't log the drive's file system!) +; Tim Carter +; +; Fixed the "get exclusive access to drive" logic. If it can't find the +; drive, it doesn't bother with trying to get exclusive access. +; -- Have Bennet confirm the fix! +; paullim@singnet.com.sg +; Rusty Gardhouse +; "Vince D. Kimball" +; Franz +; Harold Annen +; +; Fixed weird window background colors being used for background of +; the RichEdit controls! let "Jonathan Tham" know. +; +; Fixed 2 Gb drive troubles: "Tom D. Bruce" +; +; Fixed the re-word of the ASPI upgrade advice to down play its requirement. +; +; Fixed "Buffer Too Big" now stops TIP cold! +; +; +;------------------------------------- 1.0 ------------------------------------- +; +; Complete file system locking and unlocking system to prevent TIP's scanning +; and modification of an in-use volume, and to prevent the filesystem +; from viewing any cartridge while TIP is scanning it. +; +; Major rework of the cartridge eject system -- through the device driver +; rather than directly at the ASPI layer -- so the system KNOWS a cartridge +; has been ejected and can remove it from the file system. +; +;------------------------------------ 0.99 ------------------------------------- +; +; Eject ALL media on TIP startup! (prevent weird post-format status reads) +; +;------------------------------------ 0.98 ------------------------------------- +; +; ACTIVATE Self-Encryption! +; +; Activate PPA detection +; +; COPY button +; +; Handle Drive A: support +; +; Wheel Mouse NOT operating in Win95! +; +; Hourglass after Win95 termination +; +; Spin-Down report gets cleared! +; +; Change ASPI trouble to recommend ASPI_ME +; +;------------------------------------------------------------------------------- +; +; o determine TRUE maximum number of available JAZ relocations +; This still needs to be done, but for now I've clipped the test so if +; we are told there are more than the maximum we'll be okay. +; +; o lock drives for use under Win95/98 and NT ?????? +; o perhaps LOCKING the drive for exclusive use? +; Can't Lock drive for exclusive use, since the locking semantics are for +; LOGICAL (drive letter) devices, and there's no clear and simple API for +; determining the LOGICAL drive letter from the PHYSICAL SCSI device. +; +;------------------------------------------------------------------------------- + +include standard.inc +include aspi.inc +include richedit.inc +include commctrl.inc +include macros.inc +include winioctl.inc + +INITIAL_PAGE = INTRO_PAGE +; INITIAL_PAGE = PERFORM_TEST_PAGE ; INTRO_PAGE + + +VERSION_EXPIRATION = (2010 * 12 + 1) ; if in or after JAN 1, 2010 +; VERSION_EXPIRATION = (2004 * 12 + 10) ; if in or after OCT 1st, 2004 +; VERSION_EXPIRATION = (2003 * 12 + 7) ; if in or after JULY 1st, 2003 +; VERSION_EXPIRATION = (2000 * 12 + 10) ; if in or after OCT 1st, 2000 +; VERSION_EXPIRATION = (1999 * 12 + 7) ; if in or after JULY 1st, 1999 +; VERSION_EXPIRATION = (1998 * 12 + 10) ; if in or after OCT 1st, 1998 +;------------------------------------------------------------------------------- +SUPPRESS_LOGO_ANIMATION = 0 ; no logo +CORNER_THE_WINDOW = 0 ; place dialog in upper-left corner +SUPPRESS_STARTUP_EJECT = 0 +COPY_BUTTON_DAMAGES = 0 +DEVELOPMENT = 0 +NO_FLOATING_ANIMATION = 0 +FORCE_TROUBLE = 0 +FORCE_NO_DRIVES = 0 +MINIMUM_VERSION = 0 ; set it to zero for NO minimum version checking +FORCE_STARTING_SECTOR = 0 ; 489344 (near end of 250 Mb drive) +;------------------------------------------------------------------------------- + +EXTERNDEF FontBitmapImage :DWORD ; our floating "?" bitmap image +EXTERNDEF RTF_Data :DWORD +EXTERNDEF SECTOR_Data :DWORD + +;+-----------------------------------------------------------------------------+ +;| F U N C T I O N P R O T O T Y P E S | +;+-----------------------------------------------------------------------------+ +WndProc PROTO :HWND, :UINT, :WPARAM, :LPARAM +CenterWindow PROTO :HWND +DecompressBinary PROTO :LPVOID +AllocateSixteenColorDib PROTO Hwidth:DWORD, Vheight:DWORD +SplashTheBitmap PROTO hDC:HDC +PrepForFastBlitting PROTO :HGLOBAL +ApplicationTimerProc PROTO :HWND, :UINT, :UINT, :DWORD +EjectIomegaCartridge PROTO Adapter:DWORD, Device:DWORD +SpinUpIomegaCartridge PROTO Adapter:DWORD, Device:DWORD +SetRichEditText PROTO phRichEditControl:LPHWND, pText:LPSTR +PasswordWndProc PROTO :HWND, :UINT, :WPARAM, :LPARAM +ExclusiveAccess PROTO DriveNumber:DWORD, Exclusive:BOOL + +SetTabErrorMode PROTO DisplayMode:BOOL +EjectAllMedia PROTO ; unlock and eject all drives + +IF DEVELOPMENT +PostToScreen PROTO PostVal:DWORD +ENDIF + +;+-----------------------------------------------------------------------------+ +;| E Q U A T E S | +;+-----------------------------------------------------------------------------+ +SCSI_TIMEOUT equ 120 * 1000 ; two minutes! + +WIZARD_WINDOW_HEIGHT equ 337 ; 358 - 19 +WIZARD_WINDOW_WIDTH equ 467 ; 480 + +NUMBER_OF_FLOATERS equ 6 +VELOCITY_MULTIPLIER equ 1000 + +SMALLER_FONT_SIZE equ 8 +LARGER_FONT_SIZE equ 10 +HEADLINE_FONT_SIZE equ 21 + +SPLASH_WIDTH equ 120 +SPLASH_HEIGHT equ 258 + +COPY_LEFT equ 0 +COPY_TOP equ 0 +COPY_WIDTH equ 462 +COPY_HEIGHT equ 289 + +FONT_WIDTH equ 151 +FONT_HEIGHT equ 251 + +LOGO_1_LEFT equ 157 +LOGO_1_TOP equ 57 + +LOGO_2_LEFT equ 400 +LOGO_2_TOP equ 17 + +HYPERLINK_HEIGHT equ 248 + +FILE_TIME_TICKS_PER_SECOND equ 10000000 + +SOURCE_BITMAP_BYTE_WIDTH equ ((FONT_WIDTH+31)/32)*4 +DEST_BITMAP_BYTE_WIDTH equ (SPLASH_WIDTH / 2) +FONT_TOP_OFFSET equ SIZEOF BITMAPFILEHEADER + SIZEOF BITMAPINFOHEADER + 2*4 + ((FONT_HEIGHT-1) * SOURCE_BITMAP_BYTE_WIDTH) + +RANDOMULT equ 0B6CAEB15h + +PALETTE_SIZE equ 16 ; Splash is a 16-color bitmap + +IDB_LINEUP equ WM_APP +IDB_LINEDN equ WM_APP+1 +IDB_PAGEUP equ WM_APP+2 +IDB_PAGEDN equ WM_APP+3 +IDB_END equ WM_APP+4 +IDB_HOME equ WM_APP+5 + +FLASH_COUNT equ 16 +RANDOMULT equ 0B6CAEB15h + +FILE_COUNT equ 4 +DRIVER_DATE equ 9111 ; 12/23/97 + +; offsets to the various sector data images + +ZIP_100_PART equ 0000h +ZIP_100_BOOT equ 0200h +ZIP_250_PART equ 0400h +ZIP_250_BOOT equ 0600h +JAZ_1GB_PART equ 0800h +JAZ_1GB_BOOT equ 0A00h +JAZ_2GB_PART equ 0C00h +JAZ_2GB_BOOT equ 0E00h + +;--------------------------- Password Dialog Defines --------------------------- + +IDC_PASSWORD equ 3 + +;-------------------------- Drive Array Status Flags --------------------------- + +; +---- Device +; | +--- Adapter +; v v +JAZ_DRIVE equ 00010000h +MEDIA_CHANGED equ 00020000h +DISK_EJECTING equ 00040000h ; we've asked for eject and waiting ... +ODD_BYTE_COMPENSATION equ 00080000h ; special handling for ODD length PSWD +MAX_DRIVE_COUNT equ 16 ; we can handle up to 16 Zip/Jaz drives + +FORMAT_STATUS_PAGE equ 1 +DISK_STATUS_PAGE equ 2 + NEW_DISK_STATUS_OFFSET equ 3 ; newer offset of the Disk Status Byte + OLD_DISK_STATUS_OFFSET equ 1 ; older " " " " + +JAZ_SPARES_COUNT_OFFSET equ 68 ; offsets into DiskStat tbl +NEW_ZIP_SIDE_0_SPARES_COUNT_OFFSET equ 13 +NEW_ZIP_SIDE_1_SPARES_COUNT_OFFSET equ 17 +OLD_ZIP_SIDE_0_SPARES_COUNT_OFFSET equ 11 +OLD_ZIP_SIDE_1_SPARES_COUNT_OFFSET equ 15 +JAZ_PROTECT_MODE_OFFSET equ 21 +NEW_ZIP_PROTECT_MODE_OFFSET equ 21 +OLD_ZIP_PROTECT_MODE_OFFSET equ 19 +JAZ_LAST_LBA_OFFSET equ 5 +NEW_ZIP_LAST_LBA_OFFSET equ 5 +OLD_ZIP_LAST_LBA_OFFSET equ 3 + +DRIVE_A_SUPPORT_BIAS equ 32 ; reduce total by 32 for DRIVE A support + +MINIMUM_JAZ_SPARES equ 500 +MAXIMUM_JAZ_SPARES equ 2557 +MINIMUM_ZIP_SPARES equ 50 +MAXIMUM_ZIP_SPARES equ 126 + +BYTES_PER_SECTOR equ 512 +LOG2_BYTES_PER_SECTOR equ 9 +MAX_SECTORS_PER_TEST equ 128 +MAX_TRANSFER_PER_TEST equ (MAX_SECTORS_PER_TEST * BYTES_PER_SECTOR) +BPB_OFFSET equ 11 +SECTORS_PER_FAT equ 11 + +BADNESS_THRESHOLD equ 10 + +;------------------------------ Cartridge Status ------------------------------- + +DISK_STATUS_UNKNOWN equ 1 +DISK_AT_SPEED equ 2 +DISK_SPINNING_UP equ 3 +DISK_NOT_PRESENT equ 4 +DISK_SPUN_DOWN equ 5 +DISK_STALLED equ 6 +DISK_Z_TRACK_FAILURE equ 7 +DISK_PROTECTED equ 8 +DISK_LOW_SPARES equ 9 +DISK_TEST_UNDERWAY equ 10 +DISK_TEST_FAILURE equ 11 +;------------------------------------------------------------------------------- +LAST_CART_STATUS equ 11 + +;---------------------------- Testing Phase Status ----------------------------- + +UNTESTED equ 0 +READY_TO_TEST equ 1 +TESTING_STARTUP equ 2 +READING_DATA equ 3 +WRITING_PATT equ 4 +READING_PATT equ 5 +WRITING_DATA equ 6 + +;----------------------------- Drive Letter Search ----------------------------- + +COMPARISON_SECTORS equ 8 +COMPARISON_BYTES equ (COMPARISON_SECTORS * BYTES_PER_SECTOR) + +;+-----------------------------------------------------------------------------+ +;| NON-COMPRESSED GLOBAL DATA | +;+-----------------------------------------------------------------------------+ + .data + ALIGN 4 + +;------------------------- ANIMATION MOTION CONSTANTS -------------------------- + +xleft DWORD NUMBER_OF_FLOATERS dup (0) +ytop DWORD NUMBER_OF_FLOATERS dup (FONT_TOP_OFFSET) +xwidth DWORD NUMBER_OF_FLOATERS dup (FONT_WIDTH) +yheight DWORD NUMBER_OF_FLOATERS dup (FONT_HEIGHT) +transform DWORD NUMBER_OF_FLOATERS dup (Xform1) +Xform1 DWORD 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15 +ObjectTypes DWORD 0,1*4,2*4,3*4,4*4,5*4 +; this gives same-width objects different velocities, otherwise they +; would all be running at exactly the same speed with boring overlaps +velocities DWORD FONT_WIDTH, FONT_WIDTH+20, FONT_WIDTH+40 + DWORD FONT_WIDTH+60, FONT_WIDTH+80, FONT_WIDTH+100 + +LogoPalette WORD 0300h ; LOGPALETTE HEADER WORDS + WORD PALETTE_SIZE +SplashPalette DWORD 00A10303h, 00AD1F20h, 00B32E30h, 00B93E40h + DWORD 00BC4649h, 00C35559h, 00C65E62h, 00CB6A6Eh + DWORD 00D27A80h, 00DA8D93h, 00DF99A0h, 00E09DA4h + DWORD 00E6ABB3h, 00EDBCC5h, 00FCE1EAh, 00FEEAF1h + +FourBitMasks DWORD 0000000Fh, 000000F0h, 00000F00h, 0000F000h + DWORD 000F0000h, 00F00000h, 0F000000h, 0F0000000h + +;=============================================================================== +CommandDetailsTable LABEL BYTE ; Command +;------------------------------------------------------------------------------- +db SCSI_Cmd_RequestSense , SRB_DIR_IN ; 03 IN == get from drive +db SCSI_Cmd_FormatUnit , 0 ; 04 OUT == send to drive +db SCSI_Cmd_NonSenseData , SRB_DIR_IN ; 06 +db SCSI_Cmd_Read , SRB_DIR_IN ; 08 +db SCSI_Cmd_Write , SRB_DIR_OUT ; 0A +db SCSI_Cmd_CartProtect , SRB_DIR_OUT ; 0C +db SCSI_Cmd_Inquiry , SRB_DIR_IN ; 12 +db SCSI_Cmd_ModeSelect , SRB_DIR_OUT ; 15 +db SCSI_Cmd_ModeSense , SRB_DIR_IN ; 1A +db SCSI_Cmd_StartStopUnit , 0 ; 1B +db SCSI_Cmd_SendDiagnostic , 0 ; 1D +db SCSI_Cmd_PreventAllow , 0 ; 1E +db SCSI_Cmd_TranslateLBA , SRB_DIR_IN ; 22 +db SCSI_Cmd_FormatTest , 0 ; 24 +db SCSI_Cmd_ReadMany , SRB_DIR_IN ; 28 +db SCSI_Cmd_WriteMany , SRB_DIR_OUT ; 2A +db SCSI_Cmd_Verify , 0 ; 2F +db SCSI_Cmd_ReadDefectData , SRB_DIR_IN ; 37 +db SCSI_Cmd_ReadLong , SRB_DIR_IN ; 3E +db SCSI_Cmd_WriteLong , SRB_DIR_OUT ; 3F + +;------------------------------------------------------------------------------- +LENGTH_OF_DETAILS_TABLE = $ - CommandDetailsTable + +RichEditStreamIn EDITSTREAM + +;----------------------- Test Monitor Panel Definitions ------------------------ + +CS_Stat RECT <114, 8, 242, 28> +TP_Perc RECT < 12, 56, 409, 72> +SS_Jaz RECT < 12, 94, 409,126> +SS_Sid0 RECT < 12, 94, 409,110> +TL_Sect RECT < 75,154, 203,170> +ES_Read RECT <346,154, 409,170> +SE_Rect RECT <222,154, 255,221> + +;+-----------------------------------------------------------------------------+ +;| COMPRESSED GLOBAL DATA | +;+-----------------------------------------------------------------------------+ + ALIGN 4 +StartEncryption CHAR "SOE!" +;------------------------------------------------------------------------------- +IF VERSION_EXPIRATION +szBetaExpiredTitle CHAR "TIP Version 2.1b Has Expired . . .",0 +szBetaExpiredText CHAR "In order to insure that only the highest quality software is in use, this version 2.1b",CR +CHAR "release of 'Trouble In Paradise' was designed to expire on January 1st of 2010.",CR +CHAR "In this way, every copy can soon be replaced with a more mature edition that",CR +CHAR "gains from everything we will have learned during TIP's initial months of life.",CR +CHAR CR +CHAR "Since this program is FREEWARE, you may download the replacement release",CR +CHAR "immediately from my web site at http://grc.com. I apologize for the trouble,",CR +CHAR "and I hope this delay will not cause you any undue inconvenience.",CR +CHAR CR +CHAR "Thanks for understanding -- Steve Gibson",0 +ENDIF +;------------------------------------------------------------------------------- +include tip.dat +include tip.txt +;------------------------------------------------------------------------------- +szAppName CHAR "TIP",0 +szNullString CHAR 0 +szWindowTitle CHAR " TIP 2.1b -- Zip & Jaz Drive and Cartridge Testing System",0 + +szRedBitmap CHAR "REDBITMAP",0 +szGreenBitmap CHAR "GRNBITMAP",0 +szOffBitmap CHAR "OFFBITMAP",0 +szSoundBitmap CHAR "SOUND",0 +szWheelRollMessage CHAR "MSWHEEL_ROLLMSG",0 + +ChildRegionRect RECT <0,0, 460,285> +TabWindowRegionRect RECT <20,45, 440,270> +SplashRect RECT <14,16,138,278> +WebButton RECT <12,295,140,330> + +szCopyright_1 CHAR "Copyright (c) 2006 by",0 +szCopyright_2 CHAR "Gibson Research Corp.",0 +szCrLf CHAR CR,LF + +szASPI32DLLName CHAR "wnaspi32.dll",0 +szASPI32SupportInfo CHAR "GetASPI32SupportInfo",0 +szASPI32Command CHAR "SendASPI32Command",0 +szCloseCmd CHAR "Close",0 +szRichEditLibrary CHAR "RichEd32.Dll",0 +szIomega CHAR "Iomega",0 +szZip CHAR "Zip",0 +szJaz CHAR "Jaz",0 +szPPA3 CHAR "ppa3",0 + +szShellOpenOp CHAR "open",0 +szShellOpenFile CHAR "http://grc.com",0 +szURLHellier1 CHAR "http://grc.com/files/hellier1.wav",0 +szURLHellier2 CHAR "http://grc.com/files/hellier2.wav",0 + +szFullWin95Text CHAR "All Files for Win95/98 (4,375k)",0 +szFullWin95URL CHAR "ftp://ftp.iomega.com/pub/english.public/ioware9x.exe",0 +szMinimumWin95Text CHAR "Fewest Files for 95/98 (811k)",0 +szMinimumWin95URL CHAR "ftp://ftp.iomega.com/pub/english.public/ioware9xdrv.exe",0 + +szFullWinNTText CHAR "All Files for WinNT (4,240k)",0 +szFullWinNTURL CHAR "ftp://ftp.iomega.com/pub/english/iowarent.exe",0 +szMinimumWinNTText CHAR "Fewest Files for NT (937k)",0 +szMinimumWinNTURL CHAR "ftp://ftp.iomega.com/pub/english/iowarentdrv.exe",0 + +;------------------------------------------------------------------------------- +szWebFailedTitle CHAR "Unable to Launch a Web Browser",0 +szWebFailedText CHAR "TIP was unable to successfully launch",CR,LF + CHAR "this system's Internet web Browser.",CR,LF + CHAR CR,LF + CHAR "Please check out the http://grc.com website",CR,LF + CHAR "to find out what's new !",0 +;------------------------------------------------------------------------------- +szCantUnlockTitle CHAR "TIP was unable to UNLOCK this drive!",0 +szCantUnlockText CHAR "Trouble In Paradise was unable to successfully",CR + CHAR "remove the Read or Read/Write protection from",CR + CHAR "this cartridge. In order to use it you will need",CR + CHAR "to use the standard Iomega Password Utility, then",CR + CHAR "return to TIP for it's analysis of the drive and",CR + CHAR "cartridge. Sorry for the inconvenience!",0 +;------------------------------------------------------------------------------- +szDisablingWPTitle CHAR "Disabling Cartridge's Write Protection",0 +szDisablingWPText CHAR "The cartridge you've inserted was write protected",CR + CHAR "without a password. TIP must disable the write ",CR + CHAR "protection in order to operate. It will be restored",CR + CHAR "when the cartridge is removed from the drive.",0 +;------------------------------------------------------------------------------- +szBadFileTitle CHAR "This Program File is Damaged!",0 +szBadFileText CHAR "Whoops!! This program's original file image",CR + CHAR "has been altered somehow and is NOT SAFE",CR + CHAR "to use! Please obtain a fresh copy of tip.exe.",0 + +;------------------------------------------------------------------------------- +szNoExclusiveTitle CHAR "TIP Needs Exclusive Access to Cartridge " +szExclusiveDrive1 CHAR "X:",0 +szNoExclusiveText CHAR "TIP was unable to acquire exclusive access to cartridge " +szExclusiveDrive2 CHAR "X:",CR + CHAR "because some of the cartridge's files are open and in use,",CR + CHAR "or there is an active view into the contents of the cartridge.",CR + CHAR CR + CHAR "Please click the OK button below, close any open files or",CR + CHAR "views of the cartridge's contents, then click the ",22h,"Press to",CR + CHAR "Begin",22h, " button again to start TIP's analysis of this cartridge.",0 + +;------------------------------------------------------------------------------- +IF MINIMUM_VERSION +szVersionErrorTitle CHAR "Windows Version Trouble",0 +szVersionErrorText CHAR "This 32-bit Windows client program requires",CR,LF + CHAR "Windows 95/98 or later, or Windows NT 4.0 or",CR,LF + CHAR "later, These operating environments natively ",CR,LF + CHAR "support the ",34,"ASPI for Win32",34," subsystem which",CR,LF + CHAR "this program requires for operation.",0 +ENDIF +;------------------------------------------------------------------------------- +szPerhapsBlastTitle CHAR "Partition Table Not Found on " +CartSize1 CHAR "Zip 100 Cartridge!",0 +szPerhapsBlastText CHAR "TIP has not found a valid partition table on this " +CartSize2 CHAR "Zip 100 cartridge.",CR + CHAR CR + CHAR "If this cartridge does NOT contain a standard DOS/Windows file",CR + CHAR "system, then this is to be expected. (For example, if the cartridge is in",CR + CHAR "Macintosh format.) But if this cartridge has been recently damaged and",CR + CHAR "has just become unreadable, TIP has the ability to recreate the original",CR + CHAR "DOS/Windows FAT-16 file system partition table, boot sector, etc.",CR + CHAR CR + CHAR "You should -- ONLY -- press OK below if this cartridge has just been",CR + CHAR "damaged -- presumably by a previous troubled run of TIP. This will",CR + CHAR "recreate a standard partition table and file system on this cartridge.",CR + CHAR CR + CHAR "DO NOT PRESS OK unless you are SURE that you want to reconstitute",CR + CHAR "a damaged and lost DOS/Windows FAT-16 file system. This automatic",CR + CHAR "reconstructor is NOT COMPATIBLE with FAT-32, NTFS, Mac, or any",CR + CHAR "other non-FAT-16 file system. If you are not sure ...",CR + CHAR CR + CHAR "Press CANCEL to leave the cartridge as is, and proceed to run TIP.",0 + +;------------------------------------------------------------------------------- +szBlastTroubleTitle CHAR "Unable to Restore this " +CartSize3 CHAR "Zip 100 Cartridge's File System!",0 +szBlastTroubleText CHAR "Basic Sector Read/Write Operations on the Cartridge Have Failed!",CR + CHAR CR + CHAR 'This means that the damage on the cartridge is at a "lower level"',CR + CHAR "than TIP or the operating system is reading and writing. TIP could",CR + CHAR "not have been responsible for causing the damage to this cartridge",CR + CHAR "because TIP only performs standard read and write operations using",CR + CHAR "standard operating system I/O.",CR + CHAR CR + CHAR "The data on this cartridge *might* be salvageable through other means",CR + CHAR "but it is beyond the scope of TIP's automatic file system reconstruction.",0 + +;------------------------------------------------------------------------------- +szBlastSuccessTitle CHAR "Successfully Restored this " +CartSize4 CHAR "Zip 100 Cartridge's File System!",0 +szBlastSuccessText CHAR "TIP has successfully reconstructed this " +CartSize5 CHAR "Zip 100 cartridge's Partition",CR + CHAR "Table, FAT-16 Boot Sector, and 16-bit File Allocation Tables (FAT's).",CR + CHAR CR + CHAR "The cartridge should now be completely readable and writeable through",CR + CHAR "any standard Microsoft operating system.",0 + +;------------------------------------------------------------------------------- +szArialFontName CHAR "Arial",0 +szCourierNew CHAR "Courier New",0 + +;--------------------------- FONT CREATION CONSTANTS --------------------------- + +CurrentPage DWORD INITIAL_PAGE ; 0 -to- MAX ... the page we're seeing +PreviousPage DWORD -1 ; forces a first draw of every control +ActionsSubPage DWORD FIRST_ACTION_PAGE +;------------------------------------------------------------------------------- +OurTypeFaceSpec DWORD -9, 0, 0, 0 ; both fonts are 9 pixels high +OurFontWeight DWORD FW_NORMAL ; either bold or normal weight + BYTE 0 +OurUnderline BYTE 0, 0 +OurCharSet BYTE DEFAULT_CHARSET +OurFontPrecise BYTE OUT_RASTER_PRECIS, 0, PROOF_QUALITY +PitchAndFamily BYTE 0 +OurFontName CHAR "MS Sans Serif", 0 + +szSide0 CHAR "Side 0",0 +szSide1 CHAR "Side 1",0 +szSpaceDashSpace CHAR " - ",0 + +szBarChartPercent CHAR " %ld%% ",0 +szCenteredDecimal CHAR "%ld",0 +szCenteredHex CHAR "ErrorCode: %06lX",0 +szHoursMinsSecs CHAR "%ld:%02ld:%02ld",0 + +LBAMidPoints DWORD 350000, 1250000, 3000000 + +IomegaDeviceNames CHAR 'Zip 100 ' + CHAR 'Zip 250 ' + CHAR 'Jaz 1GB ' + CHAR 'Jaz 2GB ' + +;------------------------------ Driver FileNames ------------------------------- + +szWnaspi3295 CHAR "\wnaspi32.dll",0 +szWnaspi32NT CHAR "32\wnaspi32.dll",0 +szWinaspi CHAR "\winaspi.dll",0 +szAspi32 CHAR "32\drivers\aspi32.sys",0 +szWowpost CHAR "\wowpost.exe",0 +szApix CHAR "\iosubsys\apix.vxd",0 +szAspienum CHAR "\aspienum.vxd",0 + +DriversFor95 DWORD szWnaspi3295, szWinaspi, szApix, szAspienum +DriversForNT DWORD szWnaspi32NT, szWinaspi, szAspi32, szWowpost + +;-------------------------- Drive Letter Search Data --------------------------- + +DiskDrive CHAR "\\.\" ; used by NT to open direct drive +DriveLetter CHAR "A:",0 ; drive letter to open ... +SystemVXD CHAR "\\.\vwin32",0 +DriveRootName CHAR "A:\",0 + +;------------------------------------------------------------------------------- + ALIGN 4 +EndEncryption CHAR "EOE!" +;------------------------------------------------------------------------------- + +CurrentAdapter DWORD -1 ; the adapter that's been recognized +CurrentDevice DWORD -1 ; the device that's been recognized +RandomSeed DWORD 100 + +;---------------------------- Development Only Data ---------------------------- +IF DEVELOPMENT +POSTING_SPACE equ 5 +szLongHexFormat CHAR " %08lX ",0 ; a wsprintf format spec. +LastPostedValue DWORD -1 ; posting to the screen +LastPostedTop DWORD 0 ; the height of the posting +LastPostedLeft DWORD 0 +ENDIF + +JazDrive DWORD BOOL ; true if the current drive is JAZ +CartridgeStatus DWORD DISK_NOT_PRESENT + +;---------------------------- Win95 Sound Variables ---------------------------- + +Period WORD 0 +Duration WORD 0 +PhasorPosition WORD 0 + +;------------------------------------------------------------------------------- +CopySourceHandles LABEL HWND ; the table of RichEdit hWnds +;------------------------------------------------------------------------------- + HWND 0, 0 ; 0 (Intro Page) +hRichEdit HWND ?, ? ; 1 handle and pTextLastSet +hPPAVersion HWND ?, ? ; 2 text of the PPA version message +hRichVersion HWND ?, ? ; 3 text of the ASPI version message + HWND 0, 0 ; 4 (Trouble Page) / (Select Drive) + HWND 0, 0 ; 6 (Perform Test) +hTabText HWND ?, ? ; 7 text appearing on the perform test +hQuoteEdit HWND ?, ? ; 8 the Iomega Quote page + HWND 0, 0 ; 9 (Credits Page) +;------------------------------------------------------------------------------- + +INTRO_PAGE equ 0 +INSTRUCTION_PAGE equ 1 +PPA_VERSION_PAGE equ 2 +ASPI_VERSION_PAGE equ 3 +SELECT_DRIVE_PAGE equ 4 +PERFORM_TEST_PAGE equ 5 +EXPLAIN_RESULTS equ 6 +QUOTE_PAGE equ 7 +CREDITS_PAGE equ 8 + + +;------------------------------------------------------------------------------- + .data? +;+-----------------------------------------------------------------------------+ +;| Uninitialized Static Global Data | +;+-----------------------------------------------------------------------------+ +hMainWnd HWND ? ; +MainWndMsg MSG <> +hInst HINSTANCE ? ; and handle to our main instance +hRichEditLibrary HANDLE ? +hAccel HACCEL ? +hCompletionEvent HANDLE ? +hApplicationTimer DWORD ? +hSplashPalette HPALETTE ? +WinNT BOOL ? +OldPPA3Driver BOOL ? +BadASPIDrivers BOOL ? +MouseWheelAccrual DWORD ? ; amount of pending mouse wheel movement + +HyperlinkRect RECT +HyperlinkPoint POINT +hHyperlinkCursor HCURSOR ? +hStandardCursor HCURSOR ? +WindowFillColor DWORD ? + +WheelRollMessage DWORD ? ; wheel mouse roll message ... if any + +;------------------- Pointers to all of the richtext blocks -------------------- + +pFontBitmap LPVOID ? +pSplashDIB LPVOID ? +pRTF_Data LPVOID ?, ? ; pointer followed by stream length +pSectorData LPVOID ? +pTargetBuffer LPVOID ? +pSearchBuffer LPVOID ? + +hDriveAccess HANDLE ? +OneBasedDrive DWORD ? +PartitionOffset DWORD ? + +StreamPointer LPBYTE ? ; pointer to richedit stream +StreamEnd LPBYTE ? ; pointer to past the end of stream + +hASPIDLL HANDLE ? +lpGetASPI32SupportInfo LPVOID ? +lpSendASPI32Command LPVOID ? + +SystemTime SYSTEMTIME + +ASPI_CmdBlock ScsiRequestBlock <> + +ErrorMode BOOL ? + +hActionTabs HWND ? +hTestMonitor HWND ? +hSoundCheckbox HWND ? +hTestButton HWND ? +hExitButton HWND ? +hFullURL HWND ? +hMinURL HWND ? + +hNullPen HPEN ? +hWhitePen HPEN ? +hGrayPen HPEN ? +hDkGrayPen HPEN ? +hBlackPen HPEN ? + +hNullBrush HBRUSH ? +hWhiteBrush HBRUSH ? +hGrayBrush HBRUSH ? +hDkGrayBrush HBRUSH ? +hBlackBrush HBRUSH ? +hWindowFillBrush HBRUSH ? + +hNormalFont HFONT ? ; 00 - small / normal +hBoldFont HFONT ? ; 01 - small / bold +hDialogTextFont HFONT ? ; 10 - large / normal +hTitleFont HFONT ? ; 11 - large / bold +hHeadlineFont HFONT ? ; way big font +hFixedWidthFont HFONT ? +hDialogTextUnderlined HFONT ? + +hRedBitmap HBITMAP ? +hGreenBitmap HBITMAP ? +hOffBitmap HBITMAP ? +hSoundBitmap HBITMAP ? + +;------------------------ FastTransparentBlt Parameters ------------------------ + +PixelsPerLine DWORD ? +PixelsToBlt DWORD ? ; copied from PixelsPerLine per line +LineCount DWORD ? +SourceLineStart DWORD ? +SourceBitStart DWORD ? +DestLineStart DWORD ? +DestBitStart DWORD ? + +xform DWORD 16 dup(?) + +HorzVelocity DWORD NUMBER_OF_FLOATERS dup (?) ; 16o16 format +VertVelocity DWORD NUMBER_OF_FLOATERS dup (?) ; " " +HorzPosition DWORD NUMBER_OF_FLOATERS dup (?) ; " " +VertPosition DWORD NUMBER_OF_FLOATERS dup (?) ; " " + +ActionButtonFlasher DWORD ? + +pUserDataBuffer LPVOID ? ; pointer to user's data +pPatternBuffer LPVOID ? ; pointer to test pattern + +DriveCount DWORD ? +DriveArray DWORD MAX_DRIVE_COUNT dup (?) + +LastLBAOnCartridge DWORD ? +StartingInstant FILETIME +NumberOfLBAs DWORD ? +AdapterMaxSectors DWORD ? +AdapterMaxBytes DWORD ? + +;----------------------------- Run Time Variables ------------------------------ + +Side_0_SparesCount DWORD ? ; JAZ has only one count +Side_1_SparesCount DWORD ? ; ZIP has counts for both sides +Initial_Side_0_Spares DWORD ? +Initial_Side_1_Spares DWORD ? + +CartridgePassword CHAR 32+1 dup(?) + +FirstTestingVariable LABEL DWORD +;------------------------------------------------------------------------------- +TestingPhase DWORD ? ; 0 = not testing, no data ... +PercentComplete DWORD ? +FirstLBASector DWORD ? +LastLBASector DWORD ? +SecondsElapsed DWORD ? +SoftErrors DWORD ? +FirmErrors DWORD ? +HardErrors DWORD ? +SectorsNotFound DWORD ? +TracksNotFound DWORD ? +ElapsedTimeOfLastEstimate DWORD ? +CurrentTotalTimeEstimate DWORD ? +UserInterrupt DWORD ? +LastError DWORD ? +SingleTransferLBA DWORD ? +UnknownErrorMode DWORD ? +;------------------------------------------------------------------------------- +TESTING_VARIABLE_COUNT equ ($ - FirstTestingVariable)/SIZEOF DWORD + + + .code +;+-----------------------------------------------------------------------------+ +;| WinMain | +;|-----------------------------------------------------------------------------| +;| | +;| Startup the Windows program. If no previous instances are running then | +;| define and register a new window class, perform various initialization | +;| chores, then setup the main message loop. | +;| | +;+-----------------------------------------------------------------------------+ +Start: ; call DecryptOurselves + call VerifyFileChecksum ; THIS DOES NOT RETURN IF ERROR! + +IF VERSION_EXPIRATION +;+-----------------------------------------------------------------------------+ +;| For the Beta Test Period ... check to see if it's before April! | +;+-----------------------------------------------------------------------------+ + invoke GetLocalTime, ADDR SystemTime + movzx eax, SystemTime.wYear + imul eax, 12 ; scale the year into number of months + add ax, SystemTime.wMonth + .IF (eax >= VERSION_EXPIRATION) + invoke MessageBox, hMainWnd, ADDR szBetaExpiredText, ADDR szBetaExpiredTitle, MB_APPLMODAL or MB_OK + jmp Close + .ENDIF +ENDIF + + invoke GetVersion ; find out what platform we're running ... +IF MINIMUM_VERSION + .IF (al < MINIMUM_VERSION) + invoke MessageBox, NULL, ADDR szVersionErrorText, ADDR szVersionErrorTitle, MB_OK + invoke ExitProcess, 1 + .ENDIF +ENDIF + .IF !(eax & 80000000h) + set WinNT + .ENDIF + ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + invoke GetModuleHandle, NULL ; get our module's handle + mov hInst, eax + call CheckPriorInstances + jc Close + call RegisterWindowClasses + jc Close + call CreateStaticResources + jc Close + call CreateAppWindows + jc Close + + ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + ; so far so good. now see if we have aspi services ... + call CheckForASPI ; returns the adapter count + .IF (eax) + ; aspi is available, so count the Iomega devices + call EnumerateIomegaDevices +; .IF (eax == 1) + ; we have only one, so select it for the user +; movmov byte ptr CurrentAdapter, al, byte ptr DriveArray[0] +; movmov byte ptr CurrentDevice, al, byte ptr DriveArray[1] +; .ELSEIF (eax > 1) + ; we have more than one, so eject'em all ... +; call EjectAllMedia +; .ENDIF + .ENDIF + call InitializeWizardControls + call InitializeTheFloaterSystem + ; now startup the timer for real-time features + call StartApplicationTimer + +;----------------------- Our application's message loop ------------------------ + + invoke ShowWindow, hMainWnd, SW_NORMAL + invoke UpdateWindow, hMainWnd + ; get the main window up on to the screen + call ProcessPendingMessages + + ; now wait while we eject all of the cartridges! +IFE SUPPRESS_STARTUP_EJECT + call EjectAllMedia +ENDIF + + .WHILE TRUE + invoke GetMessage, ADDR MainWndMsg, NULL, 0, 0 + .BREAK .IF (!eax) + invoke TranslateAccelerator, hMainWnd, hAccel, ADDR MainWndMsg + .CONTINUE .IF (eax) ; skip if we handled + invoke TranslateMessage, ADDR MainWndMsg + invoke DispatchMessage, ADDR MainWndMsg + .ENDW + + .IF (hASPIDLL) ; only if we have ASPI services + call UnlockAllMedia ; within this system ... + .ENDIF + +Close: call DeleteStaticResources + invoke ExitProcess, 0 +;-/////////////////////////////////////////////////////////////////////////////- + + +;+-----------------------------------------------------------------------------+ +;| START APPLICATION TIMER | +;+-----------------------------------------------------------------------------+ +StartApplicationTimer PROC +;------------------------------------------------------------------------------- + invoke SetTimer, NULL, NULL, 50, ADDR ApplicationTimerProc + mov hApplicationTimer, eax + ret +;------------------------------------------------------------------------------- +StartApplicationTimer ENDP + + +;+-----------------------------------------------------------------------------+ +;| STOP APPLICATION TIMER | +;+-----------------------------------------------------------------------------+ +StopApplicationTimer PROC +;------------------------------------------------------------------------------- + mov eax, hApplicationTimer + .IF (eax) + invoke KillTimer, NULL, eax + reset hApplicationTimer + .ENDIF + ret +;------------------------------------------------------------------------------- +StopApplicationTimer ENDP + + +;------------------------------------------------------------------------------- +COMMENT @ +;+-----------------------------------------------------------------------------+ +;| DECRYPT OURSELVES | +;+-----------------------------------------------------------------------------+ +DecryptOurselves PROC +;------------------------------------------------------------------------------- + mov esi, OFFSET StartEncryption + .IF (dword ptr [esi] != "!EOS") + mov ecx, OFFSET EndEncryption + sub ecx, esi + shr ecx, 2 + mov edi, esi + .REPEAT + lodsd + xor eax, 0AAAAAAAAh + stosd + .UNTILCXZ + .ENDIF + ret +;------------------------------------------------------------------------------- +DecryptOurselves ENDP +;------------------------------------------------------------------------------- +COMMENT @ +;------------------------------------------------------------------------------- + + +;+-----------------------------------------------------------------------------+ +;| CHECK PRIOR INSTANCES | +;| Check to see if we're already running and if so, un-minimize it | +;| and bring it back to the top of the screen ... and terminate us | +;+-----------------------------------------------------------------------------+ +CheckPriorInstances PROC +;------------------------------------------------------------------------------- + invoke FindWindow, NULL, ADDR szWindowTitle + check eax ; clears CY + .IF (!zero?) + push eax ; save the window's hWnd + invoke ShowWindow, eax, SW_SHOWNORMAL + pop eax ; recover the window's hWnd + invoke SetWindowPos, eax, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE OR SWP_NOSIZE + stc ; return carry to abort OUR instance + .ENDIF + ret +;------------------------------------------------------------------------------- +CheckPriorInstances ENDP + + +;+-----------------------------------------------------------------------------+ +;| REGISTER WINDOW CLASSES | +;+-----------------------------------------------------------------------------+ +RegisterWindowClasses PROC + LOCAL wndclass:WNDCLASS +;------------------------------------------------------------------------------- + varzero wndclass + movmov wndclass.hInstance, eax, hInst + mov wndclass.hbrBackground, COLOR_BTNFACE + 1 + mov wndclass.lpszClassName, OFFSET szAppName + invoke LoadIcon, hInst, OFFSET szAppName + mov wndclass.hIcon, eax + mov wndclass.lpfnWndProc, OFFSET WndProc + invoke RegisterClass, ADDR wndclass + sub eax, 1 + jc Exit + +;-------------------- Register the TestMonitor Window Style -------------------- + + zero eax + mov wndclass.hbrBackground, eax + mov wndclass.lpszClassName, OFFSET szTestMonitor + mov wndclass.lpfnWndProc, OFFSET TestMonitorWndProc + invoke RegisterClass, ADDR wndclass + sub eax, 1 + jc Exit + +;---------------------- Register the 3D Sink Window Style ---------------------- + + mov wndclass.lpszClassName, OFFSET sz3DSink + mov wndclass.lpfnWndProc, OFFSET SinkWndProc + invoke RegisterClass, ADDR wndclass + sub eax, 1 + jc Exit + +Exit: ret +;------------------------------------------------------------------------------- +RegisterWindowClasses ENDP + + +;+-----------------------------------------------------------------------------+ +;| CREATE DIB PALETTE | +;| Create a 16-color palette. This is used only when the target | +;| system is running in 256-color mode. It contains the image's | +;| custom color set and is realized whenever our window is painted. | +;+-----------------------------------------------------------------------------+ +CreateDIBPalette PROC USES esi edi +;------------------------------------------------------------------------------- + mov esi, OFFSET SplashPalette ; get the palette data + mov edi, esi + mov ecx, PALETTE_SIZE ; the palette entry count + .REPEAT + lodsd ; .RGB + swap ah, al ; .RBG + ror eax, 8 ; G.RB + swap ah, al ; G.BR + rol eax, 8 ; .BRG + swap ah, al ; .BGR + stosd + .UNTILCXZ + invoke CreatePalette, ADDR LogoPalette + mov hSplashPalette, eax + ret +;------------------------------------------------------------------------------- +CreateDIBPalette ENDP + + +;+-----------------------------------------------------------------------------+ +;| CONVERT BRACKETS TO NULLS | +;| This scans the block of text converting all closing brackets ']' into | +;| NULLs so that a string compare can be used to find section blocks. | +;+-----------------------------------------------------------------------------+ +ConvertBracketsToNulls PROC USES edi, pBuffer:DWORD, nLength:DWORD +;------------------------------------------------------------------------------- + mov al, ']' ; we'll be scanning for a closing ']' + mov ecx, nLength ; for this many characters + mov edi, pBuffer ; and at this point in the buffer + .WHILE (ecx) + repne scasb ; scan to a ']' + .BREAK .IF (!zero?) ; if we didn't find one, quit + mov byte ptr [edi-1], 0 ; found one!, so nuke it + .ENDW ; and look for another + ret +;------------------------------------------------------------------------------- +ConvertBracketsToNulls ENDP + + +;+-----------------------------------------------------------------------------+ +;| CREATE STATIC RESOURCES | +;+-----------------------------------------------------------------------------+ +CreateStaticResources PROC USES ebx +;------------------------------------------------------------------------------- + invoke DecompressBinary, ADDR FontBitmapImage + mov pFontBitmap, eax + invoke PrepForFastBlitting, eax + + invoke DecompressBinary, ADDR RTF_Data + mov pRTF_Data, eax + mov pRTF_Data[4], ebx + invoke ConvertBracketsToNulls, eax, ebx + + invoke DecompressBinary, ADDR SECTOR_Data + mov pSectorData, eax + + invoke GetStockObject, NULL_PEN + mov hNullPen, eax + invoke GetStockObject, BLACK_PEN + mov hBlackPen, eax + invoke GetStockObject, WHITE_PEN + mov hWhitePen, eax + invoke CreatePen, PS_SOLID, 1, LTGRAY_COLOR + mov hGrayPen, eax + invoke CreatePen, PS_SOLID, 1, GRAY_COLOR + mov hDkGrayPen, eax + +;---------------------------- Create System Brushes ---------------------------- + + invoke GetStockObject, NULL_BRUSH + mov hNullBrush, eax + invoke GetStockObject, WHITE_BRUSH + mov hWhiteBrush, eax + invoke GetStockObject, LTGRAY_BRUSH + mov hGrayBrush, eax + invoke GetStockObject, DKGRAY_BRUSH + mov hDkGrayBrush, eax + invoke GetStockObject, BLACK_BRUSH + mov hBlackBrush, eax + + invoke GetSysColor, COLOR_BTNFACE + mov WindowFillColor, eax + invoke CreateSolidBrush, eax + mov hWindowFillBrush, eax + + call CreateAppFonts + + invoke LoadLibrary, ADDR szRichEditLibrary + mov hRichEditLibrary, eax + sub eax, 1 ; make sure the library loaded + jc Exit + + invoke LoadAccelerators, hInst, ADDR szAppName + mov hAccel, eax + + invoke LoadCursor, NULL, IDC_ARROW + mov hStandardCursor, eax + + invoke LoadCursor, hInst, ADDR szAppName + mov hHyperlinkCursor, eax + + invoke CreateEvent, NULL, FALSE, FALSE, NULL + mov hCompletionEvent, eax + + invoke LoadBitmap, hInst, ADDR szRedBitmap + mov hRedBitmap, eax + + invoke LoadBitmap, hInst, ADDR szGreenBitmap + mov hGreenBitmap, eax + + invoke LoadBitmap, hInst, ADDR szOffBitmap + mov hOffBitmap, eax + + invoke LoadBitmap, hInst, ADDR szSoundBitmap + mov hSoundBitmap, eax + + ; alloc the user-data buffer + invoke GlobalAlloc, GPTR, BYTES_PER_SECTOR * MAX_SECTORS_PER_TEST + mov pUserDataBuffer, eax + sub eax, 1 + jc Exit + + ; alloc the data pattern buffer + invoke GlobalAlloc, GPTR, BYTES_PER_SECTOR * MAX_SECTORS_PER_TEST + mov pPatternBuffer, eax + sub eax, 1 + jc Exit + +;---------------------- Allocate the Splash Animation DIB ---------------------- + + invoke AllocateSixteenColorDib, SPLASH_WIDTH, SPLASH_HEIGHT + mov pSplashDIB, eax + add eax, SIZEOF BITMAPINFOHEADER ; point to the palette + invoke MoveMemory, eax, ADDR SplashPalette, 16*4 + ; now invert the SplashPalette and Create a GDI palette in case + ; we're running on a 256-color system ... + invoke CreateDIBPalette + + ; register the "MSWHEEL_ROLLMSG" in case it's been defined ... + invoke RegisterWindowMessage, ADDR szWheelRollMessage + mov WheelRollMessage, eax + + clc +Exit: ret +;------------------------------------------------------------------------------- +CreateStaticResources ENDP + + +;+-----------------------------------------------------------------------------+ +;| SET FONT POINT SIZE | +;| nHeight = -MulDiv (PointSize, GetDeviceCaps(hDC, LOGPIXELSY), 72) | +;+-----------------------------------------------------------------------------+ +SetPointSize PROC USES edi, PointSize:DWORD +;------------------------------------------------------------------------------- +; invoke GetDC, 0 ; get a display DC +; mov edi, eax +; invoke GetDeviceCaps, eax, LOGPIXELSY ; 96 or 120 +; invoke MulDiv, PointSize, eax, 72 +; neg eax +; mov OurTypeFaceSpec, eax +; invoke ReleaseDC, 0, edi + + invoke MulDiv, PointSize, 96, 72 + neg eax + mov OurTypeFaceSpec, eax + + ret +;------------------------------------------------------------------------------- +SetPointSize ENDP + + +;+-----------------------------------------------------------------------------+ +;| CREATE APP FONTS | +;|-----------------------------------------------------------------------------| +;| This creates the four fonts we use throughout ChromaZone | +;+-----------------------------------------------------------------------------+ +CreateAppFonts PROC USES edi +;------------------------------------------------------------------------------- + ; if we're NOT running with standard "small fonts" then switch + ; us over to ARIAL for our main font displays for pixel sizing + invoke GetDC, 0 + mov edi, eax + invoke GetDeviceCaps, eax, LOGPIXELSY ; 96 or 120 + .IF (eax != 96) + invoke lstrcpy, ADDR OurFontName, ADDR szArialFontName + .ENDIF + invoke ReleaseDC, 0, edi + + ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + mov OurFontWeight, FW_NORMAL + invoke SetPointSize, SMALLER_FONT_SIZE + invoke CreateFontIndirect, ADDR OurTypeFaceSpec + mov hNormalFont, eax + + invoke SetPointSize, LARGER_FONT_SIZE + invoke CreateFontIndirect, ADDR OurTypeFaceSpec + mov hDialogTextFont, eax + + set OurUnderline + invoke CreateFontIndirect, ADDR OurTypeFaceSpec + mov hDialogTextUnderlined, eax + reset OurUnderline + + mov OurFontWeight, FW_BOLD + invoke SetPointSize, SMALLER_FONT_SIZE + invoke CreateFontIndirect, ADDR OurTypeFaceSpec + mov hBoldFont, eax + + invoke SetPointSize, LARGER_FONT_SIZE + invoke CreateFontIndirect, ADDR OurTypeFaceSpec + mov hTitleFont, eax + + ; make the larger Headline font + invoke SetPointSize, HEADLINE_FONT_SIZE + invoke lstrcpy, ADDR OurFontName, ADDR szArialFontName + invoke CreateFontIndirect, ADDR OurTypeFaceSpec + mov hHeadlineFont, eax + + ; now we work to create a fixed-width font ... + invoke SetPointSize, LARGER_FONT_SIZE + mov OurFontWeight, FW_NORMAL + mov PitchAndFamily, FIXED_PITCH + invoke lstrcpy, ADDR OurFontName, ADDR szCourierNew + invoke CreateFontIndirect, ADDR OurTypeFaceSpec + mov hFixedWidthFont, eax + + ret +;------------------------------------------------------------------------------- +CreateAppFonts ENDP + + +;+-----------------------------------------------------------------------------+ +;| CREATE APP WINDOWS | +;+-----------------------------------------------------------------------------+ +CreateAppWindows PROC +;------------------------------------------------------------------------------- + invoke GetSystemMetrics, SM_CYCAPTION ; includes Y border + add eax, WIZARD_WINDOW_HEIGHT + invoke CreateWindowEx, WS_EX_APPWINDOW or WS_EX_DLGMODALFRAME, + ADDR szAppName, ADDR szWindowTitle, DS_NOIDLEMSG or WS_POPUP or WS_CAPTION or WS_SYSMENU or WS_MINIMIZEBOX, + 0,0, WIZARD_WINDOW_WIDTH, eax, NULL, NULL, hInst, NULL + mov hMainWnd, eax + check eax + jz Exit +;------------------------------------------------------------------------------- + call CreateChildControls + jz Exit +;------------------------------------------------------------------------------- + call SetCurrentWindow + mov eax, 1 + +;------------------------------------------------------------------------------- +Exit: sub eax, 1 ; set carry if we're returning a zero + ret +;------------------------------------------------------------------------------- +CreateAppWindows ENDP + + +;+-----------------------------------------------------------------------------+ +;| DELETE STATIC RESOURCES | +;+-----------------------------------------------------------------------------+ +DeleteStaticResources PROC +;------------------------------------------------------------------------------- + call StopApplicationTimer + + invoke DeleteObject, hGrayPen + invoke DeleteObject, hDkGrayPen + invoke DeleteObject, hNormalFont + invoke DeleteObject, hDialogTextFont + invoke DeleteObject, hBoldFont + invoke DeleteObject, hTitleFont + invoke DeleteObject, hFixedWidthFont + invoke DeleteObject, hHeadlineFont + invoke DeleteObject, hDialogTextUnderlined + invoke DeleteObject, hSplashPalette + invoke DeleteObject, hRedBitmap + invoke DeleteObject, hGreenBitmap + invoke DeleteObject, hOffBitmap + invoke DeleteObject, hSoundBitmap + invoke DeleteObject, hWindowFillBrush + + invoke GlobalFree, pFontBitmap + invoke GlobalFree, pSplashDIB + invoke GlobalFree, pRTF_Data + invoke GlobalFree, pUserDataBuffer + invoke GlobalFree, pPatternBuffer + + invoke CloseHandle, hCompletionEvent ; ASPI completion notification +;------------------------------------------------------------------------------- + ; this perhaps SHOULD be done ... but it makes Win95 exit slowly! +; invoke FreeLibrary, hRichEditLibrary +;------------------------------------------------------------------------------- + mov eax, hASPIDLL + .IF (esi) + invoke FreeLibrary, eax + .ENDIF + ret +;------------------------------------------------------------------------------- +DeleteStaticResources ENDP + + +;+-----------------------------------------------------------------------------+ +;| BINARY TO DECIMAL | +;| Convert a 32-bit doubleword into its decimal equivalent | +;+-----------------------------------------------------------------------------+ +BinaryToDecimal PROC USES ebx, dest:PTR, val:DWORD, digits:DWORD, reorder:BOOL +;------------------------------------------------------------------------------- + mov ebx, dest ; determine where to store + mov ecx, digits ; and how many digits to blank + .REPEAT + mov byte ptr [ebx], SPACE + inc ebx + .UNTILCXZ + mov eax, val ; pick up the conversion value + .IF (reorder) ; abcd + ror eax, 8 ; dabc + swap ah, al ; dacb + ror eax, 16 ; cbda + swap ah, al ; cbad + ror eax, 8 ; dcba + .ENDIF + mov ecx, 10 ; convert to base 10 + .REPEAT + dec ebx ; move back to next digit + zero edx ; clear the high end for division + div ecx + add dl, '0' + mov [ebx], dl ; store the character + .UNTIL (!eax) + ret +;------------------------------------------------------------------------------- +BinaryToDecimal ENDP + + +;+-----------------------------------------------------------------------------+ +;| ASCII IZE | +;| Converts non-printing characters into SPACES, stops at the first CR. | +;+-----------------------------------------------------------------------------+ +AsciiIze PROC USES ebx, dest:LPSTR +;------------------------------------------------------------------------------- + mov ebx, dest + .WHILE (byte ptr [ebx] != CR) + .IF (byte ptr [ebx] < SPACE) || (byte ptr [ebx] > '~') + mov byte ptr [ebx], SPACE + .ENDIF + inc ebx + .ENDW + ret +;------------------------------------------------------------------------------- +AsciiIze ENDP + + +;+-----------------------------------------------------------------------------+ +;| PAINT BITMAP | +;+-----------------------------------------------------------------------------+ +PaintBitmap PROC USES ebx, hDC:HDC, xpos:DWORD, ypos:DWORD, image:PTR +;------------------------------------------------------------------------------- + mov eax, image ; point to the top of the file + mov ebx, eax ; point ebx to the bits + add ebx, [eax + BITMAPFILEHEADER.bfOffBits] + add eax, SIZEOF BITMAPFILEHEADER + zero ecx + invoke SetDIBitsToDevice, hDC, xpos, ypos, [eax + BITMAPINFOHEADER.biWidth], [eax + BITMAPINFOHEADER.biHeight], + 0, 0, 0, [eax + BITMAPINFOHEADER.biHeight], ebx, eax, DIB_RGB_COLORS + ret +;------------------------------------------------------------------------------- +PaintBitmap ENDP + + +;+-----------------------------------------------------------------------------+ +;| SET CONTROL TEXT | +;+-----------------------------------------------------------------------------+ +SetControlText PROC hDC:WPARAM, hWnd:LPARAM +;------------------------------------------------------------------------------- + invoke GetWindowLong, hWnd, GWL_ID + shr eax, TREATMENT_STYLE_SHIFT + .IF (eax == SMALL_NORMAL_TEXT) + mov eax, hNormalFont ; 00 - small / normal + .ELSEIF (eax == SMALL_BOLD_TEXT) + mov eax, hBoldFont ; 01 - small / bold + .ELSEIF (eax == LARGE_NORMAL_TEXT) + mov eax, hDialogTextFont ; 10 - large / normal + .ELSEIF (eax == LARGE_BOLD_TEXT) + mov eax, hTitleFont ; 11 - large / bold + .ELSEIF (eax == HEADLINE_TEXT) + mov eax, hHeadlineFont + .ELSEIF (eax == TERMINAL_TEXT) + mov eax, hFixedWidthFont + .ENDIF + invoke SelectObject, hDC, eax + ret +;------------------------------------------------------------------------------- +SetControlText ENDP + + +;+-----------------------------------------------------------------------------+ +;| DRAW HYPERLINK | +;+-----------------------------------------------------------------------------+ +DrawHyperlink PROC color:DWORD +;------------------------------------------------------------------------------- + invoke GetDC, hMainWnd + mov edi, eax + invoke SetBkMode, edi, TRANSPARENT + invoke SelectObject, edi, hDialogTextUnderlined + invoke SetTextColor, edi, color + invoke TextOut, edi, HyperlinkPoint.x, HyperlinkPoint.y, ADDR szCheck_2, (szCheck_3 - szCheck_2) + invoke ReleaseDC, hMainWnd, edi + ret +;------------------------------------------------------------------------------- +DrawHyperlink ENDP + + +;+-----------------------------------------------------------------------------+ +;| LAUNCH GRC WEBSITE | +;+-----------------------------------------------------------------------------+ +ExecuteURL PROC pszURL:LPSTR +;------------------------------------------------------------------------------- + invoke ShellExecute, NULL, ADDR szShellOpenOp, pszURL, NULL, NULL, SW_NORMAL + .IF (eax <= 32) + call SetToStandardCursor + invoke MessageBox, hMainWnd, ADDR szWebFailedText, ADDR szWebFailedTitle, MB_OK + .ENDIF + ret +;------------------------------------------------------------------------------- +ExecuteURL ENDP + + +;+-----------------------------------------------------------------------------+ +;| SET TO STANDARD CURSOR | +;+-----------------------------------------------------------------------------+ +SetToStandardCursor PROC +;------------------------------------------------------------------------------- + invoke SetCursor, hStandardCursor + .IF (eax == hHyperlinkCursor) + invoke DrawHyperlink, BLUE_COLOR + .ENDIF + ret +;------------------------------------------------------------------------------- +SetToStandardCursor ENDP + + +;+-----------------------------------------------------------------------------+ +;| PAINT 3D HEADLINE | +;+-----------------------------------------------------------------------------+ +Paint3DHeadline PROC USES edi esi, hdc:HDC, pszText:LPSTR, Xleft:DWORD, Ytop:DWORD +;------------------------------------------------------------------------------- + mov edi, hdc + mov esi, pszText + invoke SetBkMode, edi, TRANSPARENT + invoke SelectObject, edi, hHeadlineFont + invoke SetTextColor, edi, WHITE_COLOR + invoke lstrlen, esi + invoke TextOut, edi, Xleft, Ytop, esi, eax + invoke SetTextColor, edi, BLACK_COLOR + invoke lstrlen, esi + inc Xleft + inc Ytop + invoke TextOut, edi, Xleft, Ytop, esi, eax + ret +;------------------------------------------------------------------------------- +Paint3DHeadline ENDP + + +;+-----------------------------------------------------------------------------+ +;| WndProc | +;|-----------------------------------------------------------------------------| +;| This is the system's main window procedure | +;+-----------------------------------------------------------------------------+ +WndProc PROC USES esi edi ebx, hWnd:HWND, iMessage:UINT, wParam:WPARAM, lParam:LPARAM + LOCAL ps:PAINTSTRUCT, Rect:RECT, MousePos:POINT +;------------------------------------------------------------------------------- +mov eax, iMessage +;+-----------------------------------------------------------------------------+ +;| WM_CREATE : center the windoow | +;+-----------------------------------------------------------------------------+ +.IF (eax == WM_CREATE) + invoke CenterWindow, hWnd ; ... then return(0) + invoke GetSystemMenu, hWnd, FALSE ; get sysmenu handle + invoke DeleteMenu, eax, SC_MAXIMIZE, 0 ; remove CLOSE + +;+-----------------------------------------------------------------------------+ +;| WM_PAINT | +;+-----------------------------------------------------------------------------+ +.ELSEIF (eax == WM_PAINT) + invoke BeginPaint, hWnd, ADDR ps ; setup our paintstruct + mov edi, eax ; save our painting handle + +;--------------------- Draw the Lower Horz Button Divider ---------------------- + + invoke SelectObject, edi, hDkGrayPen + invoke MoveToEx, edi, 15, 289, NULL + invoke LineTo, edi, 446, 289 + invoke SelectObject, edi, hWhitePen + invoke LineTo, edi, 446, 290 + invoke LineTo, edi, 14, 290 + +;-------------------------- Draw the Gibson 'G' Logo --------------------------- + + .IF (CurrentPage == INTRO_PAGE) + + invoke SelectObject, edi, hDkGrayPen + invoke MoveToEx, edi, LOGO_1_LEFT+1, LOGO_1_TOP+29, NULL + invoke LineTo, edi, LOGO_1_LEFT+14, LOGO_1_TOP+29 + invoke LineTo, edi, LOGO_1_LEFT+14, LOGO_1_TOP+0 + invoke SelectObject, edi, hWhitePen + invoke LineTo, edi, LOGO_1_LEFT+12, LOGO_1_TOP+0 + invoke LineTo, edi, LOGO_1_LEFT+0, LOGO_1_TOP+12 + invoke LineTo, edi, LOGO_1_LEFT+0, LOGO_1_TOP+30 + + invoke SelectObject, edi, hDkGrayPen + invoke MoveToEx, edi, LOGO_1_LEFT+18, LOGO_1_TOP+14, NULL + invoke LineTo, edi, LOGO_1_LEFT+46, LOGO_1_TOP+14 + invoke LineTo, edi, LOGO_1_LEFT+46, LOGO_1_TOP+12 + invoke LineTo, edi, LOGO_1_LEFT+34, LOGO_1_TOP+0 + invoke SelectObject, edi, hWhitePen + invoke LineTo, edi, LOGO_1_LEFT+17, LOGO_1_TOP+0 + invoke LineTo, edi, LOGO_1_LEFT+17, LOGO_1_TOP+15 + + invoke SelectObject, edi, hDkGrayPen + invoke MoveToEx, edi, LOGO_1_LEFT+33, LOGO_1_TOP+46, NULL + invoke LineTo, edi, LOGO_1_LEFT+46, LOGO_1_TOP+46 + invoke LineTo, edi, LOGO_1_LEFT+46, LOGO_1_TOP+29 + invoke LineTo, edi, LOGO_1_LEFT+34, LOGO_1_TOP+17 + invoke SelectObject, edi, hWhitePen + invoke LineTo, edi, LOGO_1_LEFT+32, LOGO_1_TOP+17 + invoke LineTo, edi, LOGO_1_LEFT+32, LOGO_1_TOP+47 + + invoke SelectObject, edi, hDkGrayPen + invoke MoveToEx, edi, LOGO_1_LEFT+1, LOGO_1_TOP+35, NULL + invoke LineTo, edi, LOGO_1_LEFT+12, LOGO_1_TOP+46 + invoke LineTo, edi, LOGO_1_LEFT+29, LOGO_1_TOP+46 + invoke LineTo, edi, LOGO_1_LEFT+29, LOGO_1_TOP+32 + invoke SelectObject, edi, hWhitePen + invoke LineTo, edi, LOGO_1_LEFT+0, LOGO_1_TOP+32 + invoke LineTo, edi, LOGO_1_LEFT+0, LOGO_1_TOP+35 + +;------------- Paint the Splash Image Bitmap and the Web Hyperlink ------------- + + ; show the current logo bitmap +IFE SUPPRESS_LOGO_ANIMATION + invoke SplashTheBitmap, edi +ENDIF + ; paint the 3D program title + invoke Paint3DHeadline, edi, ADDR szIntroTitle, BODY_LEFT, TITLE_TOP + + ; now the rest of the stuff ..... + invoke SelectObject, edi, hDialogTextFont + invoke lstrlen, ADDR szCheck_1 + invoke TextOut, edi, BODY_LEFT, HYPERLINK_HEIGHT, ADDR szCheck_1, eax + invoke GetTextExtentPoint, edi, ADDR szCheck_1, (szCheck_2 - szCheck_1), ADDR Rect + add Rect.top, HYPERLINK_HEIGHT + invoke lstrlen, ADDR szCheck_4 + invoke TextOut, edi, BODY_LEFT, Rect.top, ADDR szCheck_4, eax + + invoke SelectObject, edi, hDialogTextUnderlined + add Rect.left, BODY_LEFT + movmov HyperlinkRect.left, eax, Rect.left + mov HyperlinkRect.top, HYPERLINK_HEIGHT + + ; draw the hyperlink text over the existing text + invoke SetTextColor, edi, BLUE_COLOR + invoke TextOut, edi, Rect.left, HYPERLINK_HEIGHT, ADDR szCheck_2, (szCheck_3 - szCheck_2) + ; save the location for dynamic recoloring + movmov HyperlinkPoint.x, eax, Rect.left + mov HyperlinkPoint.y, HYPERLINK_HEIGHT + + ; save the enclosing rectangle for hot-spot sensing + invoke GetTextExtentPoint, edi, ADDR szCheck_2, (szCheck_3 - szCheck_2), ADDR HyperlinkRect.right + mov eax, HyperlinkRect.left + add HyperlinkRect.right, eax + mov eax, HyperlinkRect.top + add HyperlinkRect.bottom, eax + .ENDIF + +;------------------------- Paint the Copyright Notice -------------------------- + + .IF (CurrentPage < CREDITS_PAGE) + invoke SetTextColor, edi, GRAY_COLOR + invoke SetBkMode, edi, TRANSPARENT + invoke SelectObject, edi, hNormalFont + invoke lstrlen, ADDR szCopyright_1 + invoke TextOut, edi, 15, 298, ADDR szCopyright_1, eax + invoke lstrlen, ADDR szCopyright_2 + invoke TextOut, edi, 15, 311, ADDR szCopyright_2, eax + .ENDIF + +;-------------------------- Draw the Gibson 'G' Logo --------------------------- + + .IF (CurrentPage == CREDITS_PAGE) + + invoke Paint3DHeadline, edi, ADDR szPage_4_Title, 12, 37 + + invoke SelectObject, edi, hDkGrayPen + invoke MoveToEx, edi, LOGO_2_LEFT+1, LOGO_2_TOP+29, NULL + invoke LineTo, edi, LOGO_2_LEFT+14, LOGO_2_TOP+29 + invoke LineTo, edi, LOGO_2_LEFT+14, LOGO_2_TOP+0 + invoke SelectObject, edi, hWhitePen + invoke LineTo, edi, LOGO_2_LEFT+12, LOGO_2_TOP+0 + invoke LineTo, edi, LOGO_2_LEFT+0, LOGO_2_TOP+12 + invoke LineTo, edi, LOGO_2_LEFT+0, LOGO_2_TOP+30 + + invoke SelectObject, edi, hDkGrayPen + invoke MoveToEx, edi, LOGO_2_LEFT+18, LOGO_2_TOP+14, NULL + invoke LineTo, edi, LOGO_2_LEFT+46, LOGO_2_TOP+14 + invoke LineTo, edi, LOGO_2_LEFT+46, LOGO_2_TOP+12 + invoke LineTo, edi, LOGO_2_LEFT+34, LOGO_2_TOP+0 + invoke SelectObject, edi, hWhitePen + invoke LineTo, edi, LOGO_2_LEFT+17, LOGO_2_TOP+0 + invoke LineTo, edi, LOGO_2_LEFT+17, LOGO_2_TOP+15 + + invoke SelectObject, edi, hDkGrayPen + invoke MoveToEx, edi, LOGO_2_LEFT+33, LOGO_2_TOP+46, NULL + invoke LineTo, edi, LOGO_2_LEFT+46, LOGO_2_TOP+46 + invoke LineTo, edi, LOGO_2_LEFT+46, LOGO_2_TOP+29 + invoke LineTo, edi, LOGO_2_LEFT+34, LOGO_2_TOP+17 + invoke SelectObject, edi, hWhitePen + invoke LineTo, edi, LOGO_2_LEFT+32, LOGO_2_TOP+17 + invoke LineTo, edi, LOGO_2_LEFT+32, LOGO_2_TOP+47 + + invoke SelectObject, edi, hDkGrayPen + invoke MoveToEx, edi, LOGO_2_LEFT+1, LOGO_2_TOP+35, NULL + invoke LineTo, edi, LOGO_2_LEFT+12, LOGO_2_TOP+46 + invoke LineTo, edi, LOGO_2_LEFT+29, LOGO_2_TOP+46 + invoke LineTo, edi, LOGO_2_LEFT+29, LOGO_2_TOP+32 + invoke SelectObject, edi, hWhitePen + invoke LineTo, edi, LOGO_2_LEFT+0, LOGO_2_TOP+32 + invoke LineTo, edi, LOGO_2_LEFT+0, LOGO_2_TOP+35 + .ENDIF + +;------------------------------------------------------------------------------- + invoke EndPaint, hWnd, ADDR ps ; returns zero if we process + + +;+-----------------------------------------------------------------------------+ +;| WM_MOUSEMOVE : change the mouse cursor when we're over the hyperlink | +;+-----------------------------------------------------------------------------+ +.ELSEIF (eax == WM_MOUSEMOVE) && (CurrentPage == INTRO_PAGE) + movsx eax, word ptr lParam + mov MousePos.x, eax + movsx eax, word ptr lParam[2] + mov MousePos.y, eax + invoke PtInRect, ADDR HyperlinkRect, MousePos + .IF (eax) + invoke SetCursor, hHyperlinkCursor + .IF (eax != hHyperlinkCursor) + invoke DrawHyperlink, RED_COLOR + .ENDIF + .ELSE + call SetToStandardCursor + .ENDIF + +;+-----------------------------------------------------------------------------+ +;| WM_LBUTTONDOWN : Launch the web browser | +;+-----------------------------------------------------------------------------+ +.ELSEIF (eax == WM_LBUTTONDOWN) || (eax == WM_LBUTTONDBLCLK) + invoke GetCursor + .IF (eax == hHyperlinkCursor) + invoke ExecuteURL, ADDR szShellOpenFile + .ENDIF + + +;+-----------------------------------------------------------------------------+ +;| WM_CTLCOLORBTN | +;+-----------------------------------------------------------------------------+ +.ELSEIF (eax == WM_CTLCOLORBTN) + invoke SetControlText, wParam, lParam + + +;+-----------------------------------------------------------------------------+ +;| WM_CTLCOLOREDIT | +;+-----------------------------------------------------------------------------+ +.ELSEIF (eax == WM_CTLCOLOREDIT) + invoke SetControlText, wParam, lParam + invoke GetWindowLong, lParam, GWL_ID + .IF (ax == IDE_INSTR) || (ax == TAB_TEXT) || (ax == IDE_QUOTE) + invoke SetBkMode, wParam, TRANSPARENT + mov eax, hNullBrush + jmp Return + .ENDIF + +;+-----------------------------------------------------------------------------+ +;| WM_CTLCOLORSTATIC : Static text | +;+-----------------------------------------------------------------------------+ +.ELSEIF (eax == WM_CTLCOLORSTATIC) + invoke SetControlText, wParam, lParam + +;+-----------------------------------------------------------------------------+ +;| WM_DESTROY : we've been asked to leave, so drop out of the message loop | +;+-----------------------------------------------------------------------------+ +.ELSEIF (eax == WM_DESTROY) + invoke PostQuitMessage, 0 ; ... then return(0) + +;+-----------------------------------------------------------------------------+ +;| WM_NOTIFY : the current tab has changed | +;+-----------------------------------------------------------------------------+ +.ELSEIF (eax == WM_NOTIFY) + ASSUME ebx:PTR NMHDR + mov ebx, lParam ; get the pointer to the NMHDR structure + .IF ([ebx].code == TCN_SELCHANGE) + ; save our PreviousPage since we're about to change it + movmov PreviousPage, eax, CurrentPage + ; it's a selection change event, so get the NEW tab + invoke SendMessage, [ebx].hwndFrom, TCM_GETCURSEL, 0, 0 + add eax, FIRST_ACTION_PAGE + mov CurrentPage, eax + mov ActionsSubPage, eax + call SetCurrentWindow + .ENDIF + ASSUME ebx:NOTHING + +;+-----------------------------------------------------------------------------+ +;| WM_COMMAND : a button was pressed | +;+-----------------------------------------------------------------------------+ +.ELSEIF (eax == WM_COMMAND) + movmov PreviousPage, eax, CurrentPage + movzx eax, word ptr wParam ; get the button control ID + .IF (eax == IDB_BACK) && (CurrentPage > 0) + dec CurrentPage + ; handle dropping into the proper of the ACTION pages + .IF (CurrentPage == LAST_ACTION_PAGE) + movmov CurrentPage, eax, ActionsSubPage + .ELSEIF (CurrentPage < LAST_ACTION_PAGE) && (CurrentPage >= FIRST_ACTION_PAGE) + mov CurrentPage, FIRST_ACTION_PAGE-1 + .ENDIF + ; handle skipping over the Drive Select page if only ONE drive + .IF (CurrentPage == SELECT_DRIVE_PAGE) && (DriveCount <= 1) + dec CurrentPage + .ENDIF + ; handle skipping over the ASPI_VERSION_PAGE + .IF ((!ErrorMode) && (CurrentPage == ASPI_VERSION_PAGE)) + dec CurrentPage + .ENDIF + ; handle skipping over the PPA_VERSION_PAGE + .IF ((!OldPPA3Driver) && (CurrentPage == PPA_VERSION_PAGE)) + dec CurrentPage + .ENDIF + call SetCurrentWindow + + .ELSEIF (eax == IDB_NEXT) && (CurrentPage < LAST_PAGE) + inc CurrentPage + ; handle skipping over the PPA_VERSION_PAGE + .IF ((!OldPPA3Driver) && (CurrentPage == PPA_VERSION_PAGE)) + inc CurrentPage + .ENDIF + ; handle skipping over the ASPI_VERSION_PAGE + .IF ((!ErrorMode) && (CurrentPage == ASPI_VERSION_PAGE)) + inc CurrentPage + .ENDIF + ; handle skipping over the Drive Select page if only ONE drive + .IF (CurrentPage == SELECT_DRIVE_PAGE) && (DriveCount <= 1) + inc CurrentPage + .ENDIF + ; handle dropping into the proper of the ACTION pages + .IF (CurrentPage == FIRST_ACTION_PAGE) + movmov CurrentPage, eax, ActionsSubPage + .ELSEIF (CurrentPage > FIRST_ACTION_PAGE) && (CurrentPage <= LAST_ACTION_PAGE) + mov CurrentPage, LAST_ACTION_PAGE+1 + .ENDIF + call SetCurrentWindow + + .ELSEIF (eax == IDB_WEB) + invoke ExecuteURL, ADDR szShellOpenFile + + .ELSEIF (eax == IDB_COPY) +IF COPY_BUTTON_DAMAGES + call DamageTheDisk +ELSE + call CopyCurrentPage +ENDIF + .ELSEIF (eax == IDB_QUIT) && (TestingPhase < TESTING_STARTUP) + invoke PostQuitMessage, 0 ; ... then return(0) + + .ELSEIF (eax == IDB_TEST) + .IF (CartridgeStatus == DISK_SPUN_DOWN) + invoke SpinUpIomegaCartridge, CurrentAdapter, CurrentDevice + + .ELSEIF (CartridgeStatus == DISK_AT_SPEED) + .IF (TestingPhase != READY_TO_TEST) + call PrepareToBeginTesting + .ENDIF + call TestTheDisk + + .ELSEIF (CartridgeStatus == DISK_TEST_UNDERWAY) + set UserInterrupt + + .ELSEIF (CartridgeStatus == DISK_Z_TRACK_FAILURE) \ + || (CartridgeStatus == DISK_TEST_FAILURE) \ + || (CartridgeStatus == DISK_PROTECTED) + invoke EjectIomegaCartridge, CurrentAdapter, CurrentDevice + + .ELSEIF (CartridgeStatus == DISK_LOW_SPARES) + mov CartridgeStatus, DISK_AT_SPEED + invoke SetRichEditText, ADDR hTabText, ADDR szNotRunning + invoke SetTabErrorMode, NULL + invoke SetWindowText, hTestButton, ADDR szPressToStart + call PrepareToBeginTesting + invoke InvalidateRect, hTestMonitor, NULL, FALSE + .ENDIF + + .ELSEIF (eax == IDB_LEFT_QUOTE) + invoke ExecuteURL, ADDR szURLHellier1 + + .ELSEIF (eax == IDB_RIGHT_QUOTE) + invoke ExecuteURL, ADDR szURLHellier2 + + .ELSEIF (eax == IDB_GET_PPA_FULL) + mov eax, OFFSET szFullWin95URL + .IF (WinNT) + mov eax, OFFSET szFullWinNTURL + .ENDIF + invoke ExecuteURL, eax + + .ELSEIF (eax == IDB_GET_PPA_DRIVERS) + mov eax, OFFSET szMinimumWin95URL + .IF (WinNT) + mov eax, OFFSET szMinimumWinNTURL + .ENDIF + invoke ExecuteURL, eax + + .ELSEIF (CurrentPage == INSTRUCTION_PAGE) + mov ebx, hRichEdit + call ScrollRichEdit + + .ELSEIF (CurrentPage == ASPI_VERSION_PAGE) + mov ebx, hRichVersion + call ScrollRichEdit + + .ELSEIF (CurrentPage == PPA_VERSION_PAGE) + mov ebx, hPPAVersion + call ScrollRichEdit + + .ELSEIF (CurrentPage == PERFORM_TEST_PAGE) || (CurrentPage == EXPLAIN_RESULTS) + mov ebx, hTabText + call ScrollRichEdit + + .ELSEIF (CurrentPage == QUOTE_PAGE) + mov ebx, hQuoteEdit + call ScrollRichEdit + + .ELSE + jmp DefaultProc + .ENDIF + jmp ReturnZero + +;+-----------------------------------------------------------------------------+ +;| WM_SYSCOMMAND : a system command was received ... | +;+-----------------------------------------------------------------------------+ +.ELSEIF (eax == WM_SYSCOMMAND) && (TestingPhase >= TESTING_STARTUP) + mov eax, wParam ; get the specific command + and eax, 0000FFF0h ; mask off the lower four bits ... + ; abort any close or screen saver attempt while we're running ... + .IF ((eax == SC_CLOSE) || (eax == SC_DEFAULT) || (eax == SC_SCREENSAVE) || (eax == SC_MONITORPOWER)) + jmp ReturnZero + .ENDIF + jmp DefaultProc + +;+-----------------------------------------------------------------------------+ +;| WM_POWERBROADCAST : a system command was received ... | +;+-----------------------------------------------------------------------------+ +.ELSEIF (eax == WM_POWERBROADCAST) && (TestingPhase >= TESTING_STARTUP) + ; deny and power changes + mov eax, BROADCAST_QUERY_DENY + jmp Return + +;+-----------------------------------------------------------------------------+ +;| MSWHEEL_ROLLMSG : a Win95 wheel mouse was rotated ... | +;+-----------------------------------------------------------------------------+ +.ELSEIF (eax == WheelRollMessage) + movsx esi, word ptr wParam + jmp RollEm + +;+-----------------------------------------------------------------------------+ +;| WM_MOUSEWHEEL : a wheel mouse was rotated ... | +;+-----------------------------------------------------------------------------+ +.ELSEIF (eax == WM_MOUSEWHEEL) ; handle accumulated Wheel Deltas + ; get the wheel delta + movsx esi, word ptr wParam[2] + ; determine which, if any, richedit control we're viewing +RollEm: .IF (CurrentPage == INSTRUCTION_PAGE) + mov ebx, hRichEdit + .ELSEIF (CurrentPage == ASPI_VERSION_PAGE) + mov ebx, hRichVersion + .ELSEIF (CurrentPage == PPA_VERSION_PAGE) + mov ebx, hPPAVersion + .ELSEIF (CurrentPage >= FIRST_ACTION_PAGE) && (CurrentPage <= LAST_ACTION_PAGE) + mov ebx, hTabText + .ELSEIF (CurrentPage == QUOTE_PAGE) + mov ebx, hQuoteEdit + .ELSE + jmp DefaultProc + .ENDIF + ; pickup the wheel delta contained within this message + add esi, MouseWheelAccrual +Notch: .IF (sdword ptr esi >= WHEEL_DELTA) + mov eax, IDB_LINEUP + call ScrollRichEdit + sub esi, WHEEL_DELTA + jmp Notch + .ELSEIF (sdword ptr esi <= -WHEEL_DELTA) + mov eax, IDB_LINEDN + call ScrollRichEdit + add esi, WHEEL_DELTA + jmp Notch + .ENDIF + ; retain any residual accrual for the next time + mov MouseWheelAccrual, esi + +;=============================================================================== +.ELSE +DefaultProc: invoke DefWindowProc, hWnd, iMessage, wParam, lParam + jmp Return ; and return the DefWindowProc's return status ... +.ENDIF +ReturnZero: zero eax ; return that we haven't handled. + jmp Return +ReturnTrue: zero eax ; show that WE'VE handled this message + not eax +;------------------------------------------------------------------------------- +Return: ret + +;+-----------------------------------------------------------------------------+ +;| Local Subroutines | +;+-----------------------------------------------------------------------------+ +ScrollRichEdit: .IF (eax == IDB_LINEUP) + invoke SendMessage, ebx, EM_SCROLL, SB_LINEUP, 0 + .ELSEIF (eax == IDB_LINEDN) + invoke SendMessage, ebx, EM_SCROLL, SB_LINEDOWN, 0 + .ELSEIF (eax == IDB_PAGEUP) + invoke SendMessage, ebx, EM_SCROLL, SB_PAGEUP, 0 + .ELSEIF (eax == IDB_PAGEDN) + invoke SendMessage, ebx, EM_SCROLL, SB_PAGEDOWN, 0 + .ELSEIF (eax == IDB_END) + invoke SendMessage, ebx, WM_VSCROLL, SB_BOTTOM, NULL + .ELSEIF (eax == IDB_HOME) + invoke SendMessage, ebx, WM_VSCROLL, SB_TOP, NULL + .ENDIF + LocalReturn +;------------------------------------------------------------------------------- +WndProc ENDP + + +;+-----------------------------------------------------------------------------+ +;| SET TAB ERROR MODE | +;+-----------------------------------------------------------------------------+ +SetTabErrorMode PROC USES edi, DisplayMode:BOOL +;------------------------------------------------------------------------------- + ; convert our boolean into the page ID that we want + .IF (DisplayMode) + mov DisplayMode, INVISIBLE_PAGE + .ELSE + mov DisplayMode, PERFORM_TEST_PAGE + .ENDIF + ; first find out which trouble mode we're currently in + invoke GetWindowLong, hTestMonitor, GWL_ID + and eax, PAGE_MASK + shr eax, PAGE_SHIFT ; convert ID to control's page number + .IF (eax != DisplayMode) + ; if it's the WRONG mode, then set the page numbers of the controls + .IF (DisplayMode == PERFORM_TEST_PAGE) + mov eax, PERFORM_TEST_PAGE SHL PAGE_SHIFT + mov edi, EXPLAIN_RESULTS SHL PAGE_SHIFT + .ELSE + mov eax, INVISIBLE_PAGE SHL PAGE_SHIFT + mov edi, ACTION_PAGES SHL PAGE_SHIFT + .ENDIF + invoke SetWindowLong, hTestMonitor, GWL_ID, eax + invoke SetWindowLong, hTabText, GWL_ID, edi + call SetCurrentWindow + .ENDIF + ret +;------------------------------------------------------------------------------- +SetTabErrorMode ENDP + + +;+-----------------------------------------------------------------------------+ +;| PASSWORD WND PROC | +;+-----------------------------------------------------------------------------+ +PasswordWndProc PROC USES esi, hWnd:HWND, iMessage:UINT, wParam:WPARAM, lParam:LPARAM +;------------------------------------------------------------------------------- +mov eax, iMessage +;------------------------------------------------------------------------------- +; WM_INITDIALOG : set the focus to the edit field +;------------------------------------------------------------------------------- +.IF (eax == WM_INITDIALOG) + invoke GetDlgItem, hWnd, IDC_PASSWORD + invoke SetFocus, eax + jmp ReturnZero + +;+-----------------------------------------------------------------------------+ +;| WM_COMMAND : a button was pressed | +;+-----------------------------------------------------------------------------+ +.ELSEIF (eax == WM_COMMAND) + movzx eax, word ptr wParam ; get the button control ID + .IF (eax == IDOK) + mov esi, 1 + jmp CloseDlg + .ELSEIF (eax == IDCANCEL) + zero esi +CloseDlg: invoke GetDlgItemText, hWnd, IDC_PASSWORD, ADDR CartridgePassword, 32 + invoke EndDialog, hWnd, esi + .ENDIF +.ELSE +ReturnZero: zero eax ; return that we haven't handled. + jmp Return +.ENDIF +ReturnNonZero: zero eax + dec eax +;------------------------------------------------------------------------------- +Return: ret +;+-----------------------------------------------------------------------------+ +PasswordWndProc ENDP + + +;+-----------------------------------------------------------------------------+ +;| CenterWindow | +;|-----------------------------------------------------------------------------| +;| This centers the HWND window on the screen | +;+-----------------------------------------------------------------------------+ +CenterWindow PROC USES ebx, hWnd:HWND ; handle of the window to center + LOCAL WndPos:RECT ; local temp structure defining wnd +;------------------------------------------------------------------------------- + invoke GetWindowRect, hWnd, ADDR WndPos ; get window dimens + + invoke GetSystemMetrics, SM_CXSCREEN ; return screen width + sub eax, WndPos.right ; now compute the + add eax, WndPos.left ; horizontal margin + halve eax ; cut it in half + push eax ; save new left + + invoke GetSystemMetrics, SM_CYSCREEN ; return screen height + pop edx ; recover the new left + sub eax, WndPos.bottom ; now compute the + add eax, WndPos.top ; vertical margin + halve eax ; cut it in half + mov ecx, eax ; save new right + + mov ebx, WndPos.right ; since we're FORCED to provide + sub ebx, WndPos.left ; a new width, let's recompute + inc ebx ; it from the existing width + + mov eax, WndPos.bottom ; and we'll do the same for + sub eax, WndPos.top ; the old and new heights + inc eax + +IF CORNER_THE_WINDOW + zero ecx + zero edx +ENDIF + invoke MoveWindow, hWnd, edx, ecx, ebx, eax, TRUE ; and move it! + ret +;------------------------------------------------------------------------------- +CenterWindow ENDP + + +;+-----------------------------------------------------------------------------+ +;| CREATE CHILD CONTROLS | +;|-----------------------------------------------------------------------------| +;| This creates all static windows for our program | +;| Now create the block of standard windows from our array ... | +;+-----------------------------------------------------------------------------+ +CreateChildControls PROC USES ebx +;------------------------------------------------------------------------------- + mov esi, OFFSET WindowCreationTable + mov edi, WINDOW_CREATION_ENTRIES + .REPEAT + push dword ptr NULL ; no window creation data + push hInst ; our local hInstance + push dword ptr [esi+32] ; Ctrl ID + mov ebx, [esi+28] ; get the parent's offset + .IF (ebx) ; if parent's offset non-null + mov ebx, [ebx] ; then load its value + .ENDIF + push ebx ; hWndParent + push dword ptr [esi+24] ; nHeight + push dword ptr [esi+20] ; nWidth + push dword ptr [esi+16] ; y + push dword ptr [esi+12] ; x + push dword ptr [esi+ 8] ; the Style + push dword ptr [esi+ 4] ; stack the window's name + push dword ptr [esi ] ; stack the ClassName + push dword ptr 0 ; NULL extended style + call CreateWindowEx + check eax ; if create failed + jz AbortedCreation ; then take us out! + ;------------------------------------------------------------ + mov ebx, [esi+36] ; get the destination offset + .IF (ebx) ; if we have a place to store + mov [ebx], eax ; the resulting hWnd, do so + .ENDIF + add esi, SIZE_OF_CREATE_ENTRY ; bump up to the next entry + dec edi + .UNTIL (zero?) + dec edi ; dec DI again to clear the ZERO flag ... +;------------------------------------------------------------------------------- +AbortedCreation: ret +;------------------------------------------------------------------------------- +CreateChildControls ENDP + + +;+-----------------------------------------------------------------------------+ +;| SET CHILD VISIBILITY | +;|-----------------------------------------------------------------------------| +;| Sets the CurrentPage based window visibility state for the window whose | +;| handle we're being handed. This is an enumeration of all hMainWnd. | +;+-----------------------------------------------------------------------------+ +SetChildVisibility PROC hWnd:HWND, lParam:LPARAM +;------------------------------------------------------------------------------- + invoke GetWindowLong, hWnd, GWL_ID ; pickup the child's ID + and eax, PAGE_MASK + shr eax, PAGE_SHIFT ; convert ID to control's page number + .IF (eax == ACTION_PAGES) ; if it's on all three pages + .IF (CurrentPage >= FIRST_ACTION_PAGE) && (CurrentPage <= LAST_ACTION_PAGE) + jmp ShowTheControl + .ENDIF + jmp HideTheControl + + .ELSEIF (eax != EVERY_PAGE); munge only if it's NOT on every page + .IF (eax == CurrentPage) +ShowTheControl: invoke GetWindowLong, hWnd, GWL_STYLE + or eax, WS_VISIBLE + .ELSE +HideTheControl: invoke GetWindowLong, hWnd, GWL_STYLE + and eax, NOT WS_VISIBLE + .ENDIF + invoke SetWindowLong, hWnd, GWL_STYLE, eax + .ENDIF + mov eax, TRUE ; return non-zero to continue enumerating ... + ret +;------------------------------------------------------------------------------- +SetChildVisibility ENDP + + +;+-----------------------------------------------------------------------------+ +;| SET NAV BUTTON ENABLE | +;+-----------------------------------------------------------------------------+ +SetNavButtonEnable PROC USES edi ebx, id:DWORD, enabled:DWORD +;------------------------------------------------------------------------------- + invoke GetDlgItem, hMainWnd, id ; get the handle + mov edi, eax ; save hWnd in EDI + mov ebx, enabled ; get the presence bitarray + mov cl, byte ptr PreviousPage ; get the PREVIOUS Page + shr ebx, cl ; "1" bit has PREVIOUS status + mov eax, enabled ; get the presence bitarray + mov cl, byte ptr CurrentPage ; get the CURRENT Page + shr eax, cl ; "1" bit has CURRNET status + xor ebx, eax ; one bit has "delta" + .IF (ebx & 1) + shr eax, 1 ; place new status into CARRY + .IF (carry?) + invoke GetWindowLong, edi, GWL_STYLE + and eax, NOT WS_DISABLED + .ELSE + invoke GetWindowLong, edi, GWL_STYLE + or eax, WS_DISABLED + .ENDIF + invoke SetWindowLong, edi, GWL_STYLE, eax + invoke InvalidateRect, edi, NULL, TRUE + .ENDIF + ret +;------------------------------------------------------------------------------- +SetNavButtonEnable ENDP + + +;+-----------------------------------------------------------------------------+ +;| This sets the visibility of windows for a given page | +;+-----------------------------------------------------------------------------+ +SetCurrentWindow PROC +;------------------------------------------------------------------------------- + invoke ValidateRect, hMainWnd, NULL + invoke LockWindowUpdate, hMainWnd + invoke EnumChildWindows, hMainWnd, ADDR SetChildVisibility, NULL + invoke LockWindowUpdate, NULL + .IF (PreviousPage >= FIRST_ACTION_PAGE) && (PreviousPage <= LAST_ACTION_PAGE)\ + && (CurrentPage >= FIRST_ACTION_PAGE) && (CurrentPage <= LAST_ACTION_PAGE) + invoke InvalidateRect, hMainWnd, ADDR TabWindowRegionRect, TRUE + .ELSE + invoke InvalidateRect, hMainWnd, ADDR ChildRegionRect, TRUE + .ENDIF + + .IF (PreviousPage >= FIRST_ACTION_PAGE) || (CurrentPage >= FIRST_ACTION_PAGE) + invoke InvalidateRect, hMainWnd, ADDR WebButton, TRUE + .ENDIF + invoke SetNavButtonEnable, IDB_BACK, BackButtonEnabled + invoke SetNavButtonEnable, IDB_NEXT, NextButtonEnabled + invoke UpdateWindow, hMainWnd + ret +;------------------------------------------------------------------------------- +SetCurrentWindow ENDP + + +;+-----------------------------------------------------------------------------+ +;| 3D SINK WndProc | +;+-----------------------------------------------------------------------------+ +SinkWndProc PROC USES esi edi, hWnd:HWND, msg:DWORD, wParam:WPARAM, lParam:LPARAM + LOCAL ps:PAINTSTRUCT, Rect:RECT +;------------------------------------------------------------------------------- + mov eax, msg +;+-----------------------------------------------------------------------------+ +;| WM_PAINT : Simply pass this onto the Dialog's Frame painter ... | +;+-----------------------------------------------------------------------------+ +.IF (eax == WM_PAINT) + invoke BeginPaint, hWnd, ADDR ps ; setup our paintstruct + mov edi, eax + invoke GetClientRect, hWnd, ADDR Rect + invoke GetWindowLong, hWnd, GWL_ID + shr eax, TREATMENT_STYLE_SHIFT + .IF (ax == THREE_DEE_BOX) + invoke DrawEdge, edi, ADDR Rect, EDGE_SUNKEN, BF_RECT + .ELSEIF (ax != NO_SINK_OUTLINE) + dec Rect.right + dec Rect.bottom + invoke MoveToEx, edi, 0, Rect.bottom, NULL + invoke SelectObject, edi, hDkGrayPen + invoke LineTo, edi, 0, 0 + invoke LineTo, edi, Rect.right, 0 + invoke SelectObject, edi, hWhitePen + invoke LineTo, edi, Rect.right, Rect.bottom + invoke LineTo, edi, -1, Rect.bottom + .ENDIF + invoke EndPaint, hWnd, ADDR ps ; returns zero if we process +.ELSE + invoke DefWindowProc, hWnd, msg, wParam,lParam +.ENDIF + ret +;------------------------------------------------------------------------------- +SinkWndProc ENDP + + +;+-----------------------------------------------------------------------------+ +;| SUNKEN FIELDS | +;+-----------------------------------------------------------------------------+ +SunkenFields PROC USES esi edi, hDC:HDC, pFirstRect:LPRECT, count:DWORD, yspacing:DWORD + LOCAL DrawRect:RECT +;------------------------------------------------------------------------------- + invoke CopyRect, ADDR DrawRect, pFirstRect ; make a local copy + mov edi, hDC + mov esi, count + .REPEAT + invoke DrawEdge, edi, ADDR DrawRect, BDR_SUNKENOUTER, BF_RECT + mov eax, yspacing + add DrawRect.top, eax + add DrawRect.bottom, eax + dec esi + .UNTIL (zero?) + ret +;------------------------------------------------------------------------------- +SunkenFields ENDP + + +;+-----------------------------------------------------------------------------+ +;| PAINT TEXT ARRAY | +;+-----------------------------------------------------------------------------+ +PaintTextArray PROC USES esi edi ebx, hdc:HDC, pArray:LPVOID, color:DWORD +;------------------------------------------------------------------------------- + mov edi, hdc + invoke SetTextColor, edi, color + mov esi, pArray + .REPEAT + add esi, SIZEOF DWORD ; skip past the coords + invoke lstrlen, esi + movzx ebx, word ptr [esi-4] + movzx ecx, word ptr [esi-2] + invoke TextOut, edi, ebx, ecx, esi, eax + invoke lstrlen, esi + inc eax ; account for the last zero + add esi, eax ; point to the next set of coords + .UNTIL !(word ptr [esi]) + ret +;------------------------------------------------------------------------------- +PaintTextArray ENDP + + +;+-----------------------------------------------------------------------------+ +;| PAINT TEST PHASE | +;+-----------------------------------------------------------------------------+ +PaintTestPhase PROC USES esi edi, hdc:HDC +;------------------------------------------------------------------------------- + mov edi, hdc + invoke CreateCompatibleDC, NULL ; and a DC for our bitmap source + mov esi, eax + invoke SelectObject, esi, hOffBitmap + push eax + ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + .IF (TestingPhase == READING_DATA) + invoke SelectObject, esi, hGreenBitmap + push eax + .ENDIF + invoke BitBlt, edi, 320, 5, 11, 11, esi, 0, 0, SRCCOPY + .IF (TestingPhase == READING_DATA) + pop eax + invoke SelectObject, esi, eax + .ENDIF + ;-------------------------------------------------------------------------- + .IF (TestingPhase == WRITING_PATT) + invoke SelectObject, esi, hRedBitmap + push eax + .ENDIF + invoke BitBlt, edi, 336, 5, 11, 11, esi, 0, 0, SRCCOPY + .IF (TestingPhase == WRITING_PATT) + pop eax + invoke SelectObject, esi, eax + .ENDIF + ;-------------------------------------------------------------------------- + .IF (TestingPhase == READING_PATT) + invoke SelectObject, esi, hGreenBitmap + push eax + .ENDIF + invoke BitBlt, edi, 336,21, 11, 11, esi, 0, 0, SRCCOPY + .IF (TestingPhase == READING_PATT) + pop eax + invoke SelectObject, esi, eax + .ENDIF + ;-------------------------------------------------------------------------- + .IF (TestingPhase == WRITING_DATA) + invoke SelectObject, esi, hRedBitmap + push eax + .ENDIF + invoke BitBlt, edi, 320,21, 11, 11, esi, 0, 0, SRCCOPY + .IF (TestingPhase == WRITING_DATA) + pop eax + invoke SelectObject, esi, eax + .ENDIF + ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + pop eax + invoke SelectObject, esi, eax + invoke DeleteDC, esi + ret +;------------------------------------------------------------------------------- +PaintTestPhase ENDP + + +;+-----------------------------------------------------------------------------+ +;| PAINT CART STATUS | +;| Paints the textual cartridge status window | +;+-----------------------------------------------------------------------------+ +PaintCartStatus PROC USES esi edi ebx, hDC:HDC + LOCAL TextSize:_SIZE +;------------------------------------------------------------------------------- + mov edi, hDC + ; set DC's default text modes + invoke SetTextColor, edi, BLACK_COLOR + invoke SelectObject, edi, hDialogTextFont + invoke SetBkMode, edi, TRANSPARENT + ; blank out any previous status display + invoke SelectObject, edi, hNullPen + invoke SelectObject, edi, hWindowFillBrush + invoke Rectangle, edi, 115, 9, 241, 27 + ; display the new cartridge status + mov eax, CartridgeStatus + dec eax + .IF (sign?) || (eax > (LAST_CART_STATUS-1)) + zero eax + .ENDIF + ; pickup the pointer to the string + .IF (DriveCount) + mov esi, CartStatStrings[eax*4] + .ELSE + mov esi, OFFSET szNoIomegaDrives + .ENDIF + invoke lstrlen, esi + lea ebx, TextSize + invoke GetTextExtentPoint32, edi, esi, eax, ebx + mov ebx, (241+115)/2 ; get the center X + halve TextSize._cx + sub ebx, TextSize._cx + invoke lstrlen, esi + invoke TextOut, edi, ebx, 9, esi, eax + ret +;------------------------------------------------------------------------------- +PaintCartStatus ENDP + + +;+-----------------------------------------------------------------------------+ +;| PAINT BAR GRAPH | +;+-----------------------------------------------------------------------------+ +PaintBarGraph PROC USES esi edi ebx, hDC:HDC, Xleft:DWORD, Ytop:DWORD, Xwidth:DWORD, Yheight:DWORD, BarColor:DWORD, BarValue:DWORD, pRightText:DWORD, Active:BOOL + LOCAL AbsoluteBarWidth:DWORD, Extent:_SIZE, PercentString[8]:CHAR +;------------------------------------------------------------------------------- + ; create a temporary drawing bitmap for double-buffererd rendering + invoke GetDC, hTestMonitor + mov esi, eax ; hold the creation DC in esi + invoke CreateCompatibleBitmap, esi, Xwidth, Yheight + swap esi, eax ; eax gets DC, esi gets bitmap + invoke ReleaseDC, hTestMonitor, eax + + ; create a context for drawing onto the double buffer bitmap + invoke CreateCompatibleDC, NULL + swap esi, eax ; eax gets bitmap, esi gets new DC + invoke SelectObject, esi, eax + push eax ; save the old bitmap to remove bitmap + invoke SetBkMode, esi, TRANSPARENT + + ; fill the entire rectangle with background gray + invoke SelectObject, esi, hNullPen + invoke SelectObject, esi, hWindowFillBrush + mov eax, Xwidth + inc eax + mov ebx, Yheight + inc ebx + invoke Rectangle, esi, 0, 0, eax, ebx + +.IF (Active) ; now fleshout the bitmap ONLY IF we're active + + ; if RightText string is non-null, paint it in darker gray + mov edi, pRightText + .IF (edi) + invoke SelectObject, esi, hDialogTextFont + invoke SetTextColor, esi, GRAY_COLOR + invoke lstrlen, edi + lea ebx, Extent + invoke GetTextExtentPoint32, esi, edi, eax, ebx + invoke lstrlen, edi + mov ebx, Xwidth ; get the total width + sub ebx, Extent._cx + halve ebx + mov ecx, Yheight + sub ecx, Extent._cy + halve ecx + invoke TextOut, esi, ebx, ecx, edi, eax + .ENDIF + + ; now paint the active portion + invoke CreateSolidBrush, BarColor + invoke SelectObject, esi, eax + push eax ; save prior brush + mov eax, Xwidth + inc eax + mul BarValue ; edx will have the new width + add eax, 80000000h ; now round it up! + adc edx, 0 + mov AbsoluteBarWidth, edx + mov eax, Yheight + inc eax + invoke Rectangle, esi, 0, 0, edx, eax + pop eax ; recover prior brush + invoke SelectObject, esi, eax ; recover newly created brush + invoke DeleteObject, eax ; delete the brush + + ; now place the floating percentage into the middle (if it fits there) + invoke SelectObject, esi, hTitleFont + invoke SetTextColor, esi, WHITE_COLOR + mov eax, 100 ; calculate the percentage + mul BarValue ; edx will have the new width + add eax, 80000000h ; now round it up! + adc edx, 0 + invoke wsprintf, ADDR PercentString, ADDR szBarChartPercent, edx + mov edi, eax + lea ebx, Extent + invoke GetTextExtentPoint32, esi, ADDR PercentString, eax, ebx + mov ebx, AbsoluteBarWidth ; get the active bar's width + sub ebx, Extent._cx + sar ebx, 1 ; scale back but keep sign + .IF (sign?) + invoke SelectObject, esi, hDialogTextFont + mov ebx, AbsoluteBarWidth + .ENDIF + mov ecx, Yheight + sub ecx, Extent._cy + halve ecx + invoke TextOut, esi, ebx, ecx, ADDR PercentString, edi + +.ENDIF + ; now blit the final result out to the screen + invoke BitBlt, hDC, Xleft, Ytop, Xwidth, Yheight, esi, 0, 0, SRCCOPY + + ; and clean up after all the work + pop eax ; recover prior bitmap + invoke SelectObject, esi, eax ; recover newly created bitmap + invoke DeleteObject, eax ; delete the bitmap + invoke DeleteDC, esi ; delete created container DC +Exit: ret +;------------------------------------------------------------------------------- +PaintBarGraph ENDP + + +;+-----------------------------------------------------------------------------+ +;| PAINT THE BAR GRAPHS | +;| This paints the two or three bar graphs on the test monitor window. | +;+-----------------------------------------------------------------------------+ +PaintTheBarGraphs PROC USES ebx, hDC:HDC, Active:BOOL +;------------------------------------------------------------------------------- + invoke PaintBarGraph, hDC, 13, 57, 395, 14, BLUE_COLOR, PercentComplete, NULL, Active + .IF (JazDrive) + mov ebx, Side_0_SparesCount + mov ecx, MAXIMUM_JAZ_SPARES + .IF (ebx > ecx) ; if Spares > MAXIMUM + mov ebx, ecx ; clip Spares down to MAX + .ENDIF + call CvrtIntoPrcnt + mov ebx, eax + invoke PaintBarGraph, hDC, 13, 95, 395, 30, RED_COLOR, ebx, NULL, Active + .ELSE + mov ebx, Side_0_SparesCount + mov ecx, MAXIMUM_ZIP_SPARES + call CvrtIntoPrcnt + invoke PaintBarGraph, hDC, 13, 95, 395, 14, RED_COLOR, eax, ADDR szSide0, Active + mov ebx, Side_1_SparesCount + mov ecx, MAXIMUM_ZIP_SPARES + call CvrtIntoPrcnt + invoke PaintBarGraph, hDC, 13, 111, 395, 14, RED_COLOR, eax, ADDR szSide1, Active + .ENDIF +;------------------------------------------------------------------------------- + ret + +;------------------------------------------------------------------------------- +CvrtIntoPrcnt: zero edx + zero eax + dec eax ; set edx:eax to [0:FFFFFFFF] + div ecx ; divide by the maximum possible + neg ebx + add ebx, ecx + mul ebx +;------------------------------------------------------------------------------- + LocalReturn + +;------------------------------------------------------------------------------- +PaintTheBarGraphs ENDP + + +;+-----------------------------------------------------------------------------+ +;| PAINT CENTERED STRING | +;| Paints a Double-Buffered string into a rectangular region | +;+-----------------------------------------------------------------------------+ +PaintCenteredString PROC USES esi edi ebx, hDC:HDC, Xleft:DWORD, Ytop:DWORD, Xwidth:DWORD, Yheight:DWORD, pText:DWORD, Active:BOOL + LOCAL Extent:_SIZE +;------------------------------------------------------------------------------- + ; create a temporary drawing bitmap for double-buffererd rendering + invoke GetDC, hTestMonitor + mov esi, eax ; hold the creation DC in esi + invoke CreateCompatibleBitmap, esi, Xwidth, Yheight + swap esi, eax ; eax gets DC, esi gets bitmap + invoke ReleaseDC, hTestMonitor, eax + + ; create a context for drawing onto the double buffer bitmap + invoke CreateCompatibleDC, NULL + swap esi, eax ; eax gets bitmap, esi gets new DC + invoke SelectObject, esi, eax + push eax ; save the old bitmap to remove bitmap + invoke SetBkMode, esi, TRANSPARENT + + ; fill the entire rectangle with background gray + invoke SelectObject, esi, hNullPen + invoke SelectObject, esi, hWindowFillBrush + mov eax, Xwidth + inc eax + mov ebx, Yheight + inc ebx + invoke Rectangle, esi, 0, 0, eax, ebx + +.IF (Active) ; now fleshout the bitmap ONLY IF we're active + + ; now place the floating string into the middle + invoke SelectObject, esi, hDialogTextFont + invoke lstrlen, pText + mov edi, eax + lea ebx, Extent + invoke GetTextExtentPoint32, esi, pText, eax, ebx + mov ebx, Xwidth ; get the region's width + sub ebx, Extent._cx + halve ebx + mov ecx, Yheight + sub ecx, Extent._cy + halve ecx + invoke TextOut, esi, ebx, ecx, pText, edi + +.ENDIF + ; now blit the final result out to the screen + invoke BitBlt, hDC, Xleft, Ytop, Xwidth, Yheight, esi, 0, 0, SRCCOPY + + ; and clean up after all the work + pop eax ; recover prior bitmap + invoke SelectObject, esi, eax ; recover newly created bitmap + invoke DeleteObject, eax ; delete the bitmap + invoke DeleteDC, esi ; delete created container DC +Exit: ret +;------------------------------------------------------------------------------- +PaintCenteredString ENDP + + +;+-----------------------------------------------------------------------------+ +;| PAINT CENTERED VALUE | +;| Paints a Double-Buffered decimal value into a rectangular region | +;+-----------------------------------------------------------------------------+ +PaintCenteredValue PROC USES esi edi, hDC:HDC, Xleft:DWORD, Ytop:DWORD, Xwidth:DWORD, Yheight:DWORD, value:DWORD, Active:BOOL + LOCAL szString[40]:CHAR +;------------------------------------------------------------------------------- + ; convert our value into a string + invoke wsprintf, ADDR szString, ADDR szCenteredDecimal, value + ; and paint it's value + invoke PaintCenteredString, hDC, Xleft, Ytop, Xwidth, Yheight, ADDR szString, Active + ret +;------------------------------------------------------------------------------- +PaintCenteredValue ENDP + + +;+-----------------------------------------------------------------------------+ +;| PAINT TEST STATISTICS | +;| This paints the two columns of testing statistics | +;| on the test monitor window. | +;+-----------------------------------------------------------------------------+ +PaintTestStatistics PROC USES esi edi ebx, hDC:HDC, Active:BOOL + LOCAL szString[40]:CHAR +;------------------------------------------------------------------------------- + mov edi, hDC + ; assemble and paint the sector testing range + mov eax, SingleTransferLBA ; are we testing a single sector? + .IF (eax) + invoke wsprintf, ADDR szString, ADDR szCenteredDecimal, eax + .ELSE + mov eax, FirstLBASector + .IF (!TestingPhase) + zero eax + .ENDIF + invoke wsprintf, ADDR szString, ADDR szCenteredDecimal, eax + invoke lstrcat, ADDR szString, ADDR szSpaceDashSpace + invoke lstrlen, ADDR szString + lea esi, szString + add esi, eax + mov eax, LastLBASector + .IF (TestingPhase == READY_TO_TEST) + mov eax, LastLBAOnCartridge + .ENDIF + invoke wsprintf, esi, ADDR szCenteredDecimal, eax + .ENDIF + invoke PaintCenteredString, edi, 76, 155, 126, 14, ADDR szString, Active + + ; show the LastError + push edi ; save our display context + mov edi, OFFSET ErrorTypeTest ; point to the top of the list +TryIt: mov eax, [edi] ; get a candidate error # + add edi, 4 + .IF (eax != (-1)) ; if we haven't hit the end + cmp eax, LastError + je ShowIt + mov al, 0 ; nope, so scan to the end + mov ecx, 40 + repne scasb ; of the string + jmp TryIt + ; it *is* unknown, so we show the value of the error + .ELSEIF (UnknownErrorMode) + invoke wsprintf, ADDR szString, ADDR szCenteredHex, LastError + lea edi, szString + .ENDIF +ShowIt: mov eax, edi + pop edi + invoke PaintCenteredString, edi, 76, 172, 126, 14, eax, Active + + ; show the elapsed time + mov eax, SecondsElapsed + call CvrtSecondsToHMSstring + invoke PaintCenteredString, edi, 76, 189, 126, 14, ADDR szString, Active + + ; see if it's time for us to estimate ... + mov edx, SecondsElapsed + mov eax, edx + sub eax, ElapsedTimeOfLastEstimate + .IF (eax > 15) + ; assemble the remaining time + mov ElapsedTimeOfLastEstimate, edx ; note this estimate time + zero eax + mov ebx, PercentComplete + .IF (ebx > edx) ; if it's safe to divide, show remaining time + roundiv ebx ; eax will have estimated completion + .ENDIF + mov CurrentTotalTimeEstimate, eax + .ELSE + mov eax, CurrentTotalTimeEstimate + .ENDIF + + ; given the current estimate time, show the remaining time! + .IF (eax) + sub eax, SecondsElapsed + .IF (carry?) ; if it went negative + zero eax ; clamp it to zero + .ENDIF + call CvrtSecondsToHMSstring + .ELSE + invoke lstrcpy, ADDR szString, ADDR szEstimating + .ENDIF + .IF (TestingPhase <= READY_TO_TEST) + invoke lstrcpy, ADDR szString, ADDR szOneMoment + .ENDIF + invoke PaintCenteredString, edi, 76, 206, 126, 14, ADDR szString, Active + + ; now show the error accumulations ... + mov esi, SoftErrors + invoke PaintCenteredValue, edi, 347, 155, 61, 14, esi, Active + mov eax, FirmErrors + add esi, eax + invoke PaintCenteredValue, edi, 347, 172, 61, 14, eax, Active + mov eax, HardErrors + add esi, eax + invoke PaintCenteredValue, edi, 347, 189, 61, 14, eax, Active + invoke PaintCenteredValue, edi, 347, 206, 61, 14, esi, Active + +;------------------------------------------------------------------------------- + ret + +CvrtSecondsToHMSstring: +;------------------------------------------------------------------------------- + mov ebx, 60 + zero edx + div ebx ; edx = seconds / eax = minutes + mov ecx, edx ; ecx = seconds + zero edx + div ebx ; edx = minutes / eax = hours + invoke wsprintf, ADDR szString, ADDR szHoursMinsSecs, eax, edx, ecx +;------------------------------------------------------------------------------- + LocalReturn + +;------------------------------------------------------------------------------- +PaintTestStatistics ENDP + + +;+-----------------------------------------------------------------------------+ +;| TEST MONITOR WND PROC | +;+-----------------------------------------------------------------------------+ +TestMonitorWndProc PROC USES esi edi, hWnd:HWND, msg:DWORD, wParam:WPARAM, lParam:LPARAM + LOCAL ps:PAINTSTRUCT, Rect:RECT +;------------------------------------------------------------------------------- + mov eax, msg +;+-----------------------------------------------------------------------------+ +;| WM_PAINT : Paint our entire test monitor window | +;+-----------------------------------------------------------------------------+ +.IF (eax == WM_PAINT) + invoke BeginPaint, hWnd, ADDR ps ; setup our paintstruct + mov edi, eax + ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + invoke SelectObject, edi, hDialogTextFont + invoke SetBkMode, edi, TRANSPARENT + invoke lstrlen, ADDR szCartStatus + invoke TextOut, edi, 12, 9, ADDR szCartStatus, eax + invoke DrawEdge, edi, ADDR CS_Stat, BDR_SUNKENOUTER, BF_RECT + invoke PaintCartStatus, edi + + ; draw the sunken rectangles + invoke DrawEdge, edi, ADDR TP_Perc, BDR_SUNKENOUTER, BF_RECT + invoke DrawEdge, edi, ADDR SE_Rect, BDR_SUNKENOUTER, BF_RECT + invoke SunkenFields, edi, ADDR TL_Sect, 4, 17 + invoke SunkenFields, edi, ADDR ES_Read, 4, 17 + .IF (JazDrive) ; draw a single LARGE rectangle + invoke DrawEdge, edi, ADDR SS_Jaz, BDR_SUNKENOUTER, BF_RECT + .ELSE ; draw a pair of smaller rectangles + invoke SunkenFields, edi, ADDR SS_Sid0, 2, 16 + .ENDIF + .IF (CartridgeStatus == DISK_AT_SPEED) || (CartridgeStatus == DISK_SPUN_DOWN) || (CartridgeStatus >= DISK_LOW_SPARES) + invoke PaintTheBarGraphs, edi, TRUE + invoke PaintTestStatistics, edi, TRUE + mov eax, BLACK_COLOR + .ELSE + invoke PaintTheBarGraphs, edi, FALSE + invoke PaintTestStatistics, edi, FALSE + mov eax, GRAY_COLOR + .ENDIF + invoke PaintTextArray, edi, ADDR TestBlackText, eax + invoke PaintTextArray, edi, ADDR TestGrayText, GRAY_COLOR + invoke PaintTestPhase, edi + + ; paint the little speaker icon + invoke CreateCompatibleDC, NULL ; and a DC for our bitmap source + mov esi, eax + invoke SelectObject, esi, hSoundBitmap + push eax + invoke BitBlt, edi, 232, 191, 16, 16, esi, 0, 0, SRCCOPY + pop eax + invoke SelectObject, esi, eax + invoke DeleteDC, esi + + ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + invoke EndPaint, hWnd, ADDR ps ; returns zero if we process +.ELSE + invoke DefWindowProc, hWnd, msg, wParam,lParam +.ENDIF + ret +;------------------------------------------------------------------------------- +TestMonitorWndProc ENDP + + +;+-----------------------------------------------------------------------------+ +;| DATA SOURCE | +;+-----------------------------------------------------------------------------+ +DataSource PROC USES ebx ecx edx, pDest:PTR SBYTE, pCount:PTR DWORD, pCompData:PTR COMP_DATA +;------------------------------------------------------------------------------- + ASSUME ebx:PTR COMP_DATA +;------------------------------------------------------------------------------- + mov ebx, pCompData + mov eax, [ebx].EndOfBuffer ; get the end of the buffer + mov edx, [ebx].SourcePointer ; get the current start + sub eax, edx ; calc the remaining amount + mov ecx, pCount ; get the pointer to the count + mov ecx, [ecx] ; and get the actual count + .IF (eax > ecx) ; if it's more than we can take + mov eax, ecx ; diminish it to the limit + .ENDIF + add [ebx].SourcePointer, eax ; bump the offset forward for next + push eax ; save the amount transferred + invoke MoveMemory, pDest, edx, eax ; move the data + pop eax ; recover the amount we moved + ret ; and return the Count that we placed into the buffer +;------------------------------------------------------------------------------- + ASSUME ebx:NOTHING +;------------------------------------------------------------------------------- +DataSource ENDP + + +;+-----------------------------------------------------------------------------+ +;| DATA SINK | +;+-----------------------------------------------------------------------------+ +DataSink PROC USES ebx ecx edx, pSource:PTR SBYTE, pCount:PTR DWORD, pCompData:PTR COMP_DATA +;------------------------------------------------------------------------------- + ASSUME ebx:PTR COMP_DATA +;------------------------------------------------------------------------------- + mov ebx, pCompData + mov eax, pCount ; get the pointer to the count + mov eax, [eax] ; and the count itself + mov edx, [ebx].SinkPointer + add [ebx].SinkPointer, eax + push eax + invoke MoveMemory, edx, pSource, eax + pop eax + ret +;------------------------------------------------------------------------------- + ASSUME ebx:NOTHING +;------------------------------------------------------------------------------- +DataSink ENDP + + +;+-----------------------------------------------------------------------------+ +;| DECOMPRESS BINARY | +;+-----------------------------------------------------------------------------+ +DecompressBinary PROC USES esi, pBitmapImage:LPVOID + LOCAL pWorkingBuffer:LPSTR, CompData:COMP_DATA +;------------------------------------------------------------------------------- + invoke GlobalAlloc, GPTR, EXP_BUFFER_SIZE + mov pWorkingBuffer, eax + mov esi, pBitmapImage ; get the original size + mov eax, [esi] ; eax has uncompressed size + push eax ; save for function return + invoke GlobalAlloc, GPTR, eax + push eax ; save pointer to return + mov CompData.SinkPointer, eax + add esi, 8 ; point to the data's start + mov CompData.SourcePointer, esi ; set the starting point + add esi, [esi-4] + mov CompData.EndOfBuffer, esi + invoke explode, ADDR DataSource, ADDR DataSink, pWorkingBuffer, ADDR CompData + invoke GlobalFree, pWorkingBuffer + pop eax ; return the saved decompressed pointer + pop ebx ; return the original file size + ret +;------------------------------------------------------------------------------- +DecompressBinary ENDP + + +GetRandomNumber: +;+-----------------------------------------------------------------------------+ +;| Simply returns a 32-bit random number | +;+-----------------------------------------------------------------------------+ + mov eax, RandomSeed + imul eax, RANDOMULT + inc eax + mov RandomSeed, eax + swap ah, al + ror eax, 8 +;------------------------------------------------------------------------------- + ret + + +;+-----------------------------------------------------------------------------+ +;| APPLICATION TIMER PROC | +;+-----------------------------------------------------------------------------+ +ApplicationTimerProc PROC hWnd:HWND, Msg:UINT, id:UINT, time:DWORD +;------------------------------------------------------------------------------- + pushad ; save ALL the regs so we return things as we found them! + ; see whether we need to animate the titlepage +IFE SUPPRESS_LOGO_ANIMATION + .IF (CurrentPage == INTRO_PAGE) + call FloatTheFloaters + .ENDIF +ENDIF + ; only if we have at least ONE Iomega drive + .IF (DriveCount) + call HandleDriveChanging + .ENDIF + ; to flash the ring around the "Start Testing" button + .IF (ActionButtonFlasher) && (CurrentPage >= FIRST_ACTION_PAGE) && (CurrentPage <= LAST_ACTION_PAGE) + invoke GetDC, hMainWnd + mov edi, eax + mov eax, hBlackPen + .IF (ActionButtonFlasher & 1) + mov eax, hGrayPen + .ENDIF + invoke SelectObject, edi, eax + invoke SelectObject, edi, hNullBrush + invoke Rectangle, edi, TEST_BUTTON_LEFT-1, TEST_BUTTON_TOP-1, TEST_BUTTON_LEFT+TEST_BUTTON_WIDTH+1, TEST_BUTTON_TOP+TEST_BUTTON_HEIGHT+1 + invoke Rectangle, edi, TEST_BUTTON_LEFT-2, TEST_BUTTON_TOP-2, TEST_BUTTON_LEFT+TEST_BUTTON_WIDTH+2, TEST_BUTTON_TOP+TEST_BUTTON_HEIGHT+2 + invoke ReleaseDC, hMainWnd, edi + dec ActionButtonFlasher + .ENDIF + popad + ret +;------------------------------------------------------------------------------- +ApplicationTimerProc ENDP + + +;+-----------------------------------------------------------------------------+ +;| INITIALIZE THE FLOATER SYSTEM | +;+-----------------------------------------------------------------------------+ +InitializeTheFloaterSystem PROC USES esi edi +;------------------------------------------------------------------------------- + zero esi ; ESI will be the OBJECT INSTANCE index + .REPEAT ; EDI will be the OBJECT CLASS index + mov edi, ObjectTypes[esi] + Call InitPositionAndVelocity + call GetValidObjectHorzPos + mov HorzPosition[esi], eax + call GetValidObjectVertPos + mov VertPosition[esi], eax + add esi, SIZEOF DWORD + .UNTIL (esi >= NUMBER_OF_FLOATERS * SIZEOF DWORD) + ; place the objects into their initial positions + call BlitTheObjects + ret +;------------------------------------------------------------------------------- +InitializeTheFloaterSystem ENDP + + +;+-----------------------------------------------------------------------------+ +;| GET VALID OBJECT HORZ POS | +;+-----------------------------------------------------------------------------+ +GetValidObjectHorzPos PROC USES ebx edx +;------------------------------------------------------------------------------- + call GetRandomNumber ; returns EAX + mov ebx, SPLASH_WIDTH + mov ecx, xwidth[edi] + dec ecx + add ebx, ecx + mul ebx + sub edx, ecx + shl edx, 16 ; convert into 16o16 + mov eax, edx + ret +;------------------------------------------------------------------------------- +GetValidObjectHorzPos ENDP + + +;+-----------------------------------------------------------------------------+ +;| GET VALID OBJECT VERT POS | +;+-----------------------------------------------------------------------------+ +GetValidObjectVertPos PROC USES ebx edx +;------------------------------------------------------------------------------- + call GetRandomNumber ; returns EAX + mov ebx, SPLASH_HEIGHT + mov ecx, yheight[edi] + dec ecx + add ebx, ecx + mul ebx + sub edx, ecx + shl edx, 16 ; convert into 16o16 + mov eax, edx + ret +;------------------------------------------------------------------------------- +GetValidObjectVertPos ENDP + + +;+-----------------------------------------------------------------------------+ +;| MIX EDX BY THREE | +;| With 1/3rd probability, this negates EDX, leaves it alone, of zeroes it. | +;+-----------------------------------------------------------------------------+ +MixEDXbyThree PROC +;------------------------------------------------------------------------------- + push edx + call GetRandomNumber ; eax + mov edx, 3 + mul edx + mov eax, edx + pop edx + .IF (!eax) + zero edx + .ELSEIF (eax == 1) + neg edx + .ENDIF + ret +;------------------------------------------------------------------------------- +MixEDXbyThree ENDP + + +;+-----------------------------------------------------------------------------+ +;| PREP FOR FAST BLITTING | +;| This BSWAPS every DWORD of the bitmap's data placing the first bitmap | +;| bits up at the high end of the DWORD and linearizing them all along. | +;+-----------------------------------------------------------------------------+ +PrepForFastBlitting PROC USES esi edi, pBitmapFile:HGLOBAL +;------------------------------------------------------------------------------- + mov eax, pBitmapFile ; get the data block + mov ecx, [eax].BITMAPFILEHEADER.bfSize ; pickup the file's size + mov esi, [eax].BITMAPFILEHEADER.bfOffBits + sub ecx, esi ; calc the total size to bswap + shr ecx, 2 ; divide by 4 for dwords + add esi, eax ; cvrt offset into actual pointer + mov edi, esi ; setup our source and destination + .REPEAT + lodsd ; [abcd] + ror eax, 8 ; [dabc] + swap ah, al ; [dacb] + ror eax, 16 ; [cbda] + swap ah, al ; [cbad] + ror eax, 8 ; [dcba] + stosd + .UNTILCXZ +Exit: ret +;------------------------------------------------------------------------------- +PrepForFastBlitting ENDP + + +;+-----------------------------------------------------------------------------+ +;| ALLOCATE SIXTEEN COLOR DIB | +;+-----------------------------------------------------------------------------+ +AllocateSixteenColorDib PROC USES ebx, Hwidth:DWORD, Vheight:DWORD +;------------------------------------------------------------------------------- + mov eax, Hwidth ; get the width + add eax, 7 ; round up to dword boundary + and eax, 0FFFFFFF8h ; (8 pixels per dword) + mul Vheight ; multiply by the number of lines + add eax, 16*4 + SIZEOF BITMAPINFOHEADER + invoke GlobalAlloc, GPTR, eax + ASSUME EAX:PTR BITMAPINFOHEADER + mov [eax].biSize, SIZEOF BITMAPINFOHEADER + movmov [eax].biWidth, ebx, Hwidth + movmov [eax].biHeight, ebx, Vheight + mov [eax].biPlanes, 1 + mov [eax].biBitCount, 4 + ASSUME EAX:NOTHING + ret +;------------------------------------------------------------------------------- +AllocateSixteenColorDib ENDP + + +;+-----------------------------------------------------------------------------+ +;| SPLASH THE BITMAP | +;+-----------------------------------------------------------------------------+ +SplashTheBitmap PROC USES esi edi ebx, hDC:HDC +;------------------------------------------------------------------------------- + mov edi, hDC + invoke SelectPalette, edi, hSplashPalette, FALSE + invoke RealizePalette, edi + mov eax, pSplashDIB + mov ebx, eax ; point ebx to the bits + add ebx, 16*4 + SIZEOF BITMAPINFOHEADER + zero ecx + zero edx + zero esi + invoke SetDIBitsToDevice, edi, 16, 18, [eax + BITMAPINFOHEADER.biWidth], [eax + BITMAPINFOHEADER.biHeight],0, 0, 0, [eax + BITMAPINFOHEADER.biHeight], ebx, eax, DIB_RGB_COLORS + ret +;------------------------------------------------------------------------------- +SplashTheBitmap ENDP + + +;+-----------------------------------------------------------------------------+ +;| FLOAT THE FLOATERS | +;+-----------------------------------------------------------------------------+ +FloatTheFloaters PROC +;------------------------------------------------------------------------------- + zero esi ; ESI is the OBJECT INSTANCE index + .REPEAT ; EDI is the OBJECT CLASS index + mov edi, ObjectTypes[esi] +;------------------------------------------------------------------------------- +DoHorz: mov eax, HorzPosition[esi] ; get the 16o16 format + add eax, HorzVelocity[esi] ; compute new location + mov HorzPosition[esi], eax ; and save it, presuming okay + shr eax, 16 ; discard the fractional part + movsx eax, ax + cmp eax, SPLASH_WIDTH + jge ReFloat + check eax + jns DoVert + neg eax ; make the offset positive + cmp eax, xwidth[edi] ; see if we're too negative + jge ReFloat + +DoVert: mov eax, VertPosition[esi] ; get the 16o16 format + add eax, VertVelocity[esi] ; compute new location + mov VertPosition[esi], eax ; and save it, presuming okay + shr eax, 16 + movsx eax, ax + cmp eax, SPLASH_HEIGHT + jge ReFloat + check eax + jns NextObject + neg eax ; make the offset positive + cmp eax, yheight[edi] ; see if we're too negative + jl NextObject + +ReFloat: Call InitPositionAndVelocity +;------------------------------------------------------------------------------- +NextObject: add esi, SIZEOF DWORD + .UNTIL (esi >= NUMBER_OF_FLOATERS * SIZEOF DWORD) + ; place the objects into their initial positions + call BlitTheObjects + ; and update the image in the window + mov esi, hMainWnd + .IF (esi) ; make sure the window exists! + invoke GetDC, esi + mov edi, eax + invoke SplashTheBitmap, eax + invoke ReleaseDC, esi, edi + .ENDIF + ret +;------------------------------------------------------------------------------- +FloatTheFloaters ENDP + + +;+-----------------------------------------------------------------------------+ +;| INIT POSITION AND VELOCITY | +;+-----------------------------------------------------------------------------+ +InitPositionAndVelocity PROC USES ebx +;------------------------------------------------------------------------------- + ; get a size-based vbelocity + mov eax, VELOCITY_MULTIPLIER + mul velocities[edi] +; mul xwidth[edi] ; EDX has the size-based velocity + mov edx, eax + ; choose a border from which to emerge + call GetRandomNumber ; returns EAX + mov ebx, eax + .IF (ebx & 1) + call GetValidObjectHorzPos + mov HorzPosition[esi], eax + .IF (ebx & 2) ; TOP EDGE + mov eax, yheight[edi] + dec eax + shl eax, 16 + neg eax + .ELSE ; BOTTOM EDGE + mov eax, (SPLASH_HEIGHT-1) SHL 16 + neg edx + .ENDIF + mov VertPosition[esi], eax + mov VertVelocity[esi], edx + Call MixEDXbyThree + mov HorzVelocity[esi], edx + .ELSE + call GetValidObjectVertPos + mov VertPosition[esi], eax + .IF (ebx & 2) ; LEFT EDGE + mov eax, xwidth[edi] + dec eax + shl eax, 16 + neg eax + .ELSE ; RIGHT EDGE + mov eax, (SPLASH_WIDTH-1) SHL 16 + neg edx + .ENDIF + mov HorzPosition[esi], eax + mov HorzVelocity[esi], edx + Call MixEDXbyThree + mov VertVelocity[esi], edx + .ENDIF + ret +;------------------------------------------------------------------------------- +InitPositionAndVelocity ENDP + + +;+-----------------------------------------------------------------------------+ +;| BLIT THE OBJECTS | +;+-----------------------------------------------------------------------------+ +BlitTheObjects PROC USES esi edi ebx +;------------------------------------------------------------------------------- + ; Zero the entire destination bitmap before summing into it ... + mov eax, pSplashDIB + add eax, SIZEOF BITMAPINFOHEADER + 16*4 + invoke ZeroMemory, eax, (SPLASH_HEIGHT * DEST_BITMAP_BYTE_WIDTH) + + ; Now BLIT the entire set of Objects into the bitmap + zero esi + .REPEAT ; ESI will be the OBJECT INSTANCE index + ; EDI will be the OBJECT CLASS index + mov edi, ObjectTypes[esi] ; EDI is the pointer to the OBJECT CLASS + + ; establish the object's translucency transformation table + invoke MoveMemory, ADDR xform, transform[edi], 16*4 + + ; let's figure out the horizontal + mov eax, HorzPosition[esi] ; get the current Horz + shr eax, 16 ; discard the fractional + movsx eax, ax ; and sign-extend it + .IF (sdword ptr eax >= 0) + ; our X coord is positive, so no left clipping + mov ebx, SPLASH_WIDTH + sub ebx, eax + mov edx, xwidth[edi] + .IF (ebx > edx) + mov ebx, edx + .ENDIF + mov edx, eax + zero eax + .ELSE + ; we have a negative X, so some of our left is clipped + mov ebx, xwidth[edi] + add ebx, eax ; EBX has the pixel count + neg eax ; EAX has the left SRC pixel + zero edx ; EDX has the left DEST pixel + .ENDIF + .IF (ebx > SPLASH_WIDTH) ; trim our blit to window width + mov ebx, SPLASH_WIDTH + .ENDIF + mov PixelsPerLine, ebx + + ; EAX has the starting pixel in the SOURCE bitmap + add eax, xleft[edi] ; add-in the source offset + mov ecx, eax ; first setup the bit mask + and cl, 1Fh ; get the lower FIVE bits + mov ebx, 80000000h ; setup the source mask + shr ebx, cl + mov SourceBitStart, ebx + + and eax, 0FFFFFFE0h ; mask off the lower five bits + shr eax, 3 ; now the byte offset + add eax, pFontBitmap + add eax, ytop[edi] ; !!! This is pre-computed !!! + mov SourceLineStart, eax + + ; EDX has the starting pixel in the DEST bitmap + mov ecx, edx + and ecx, 00000007h ; get 0-7 + shl ecx, 2 ; * 4 == 0-28 + neg ecx + add ecx, 28 ; 28 .... 0 + mov DestBitStart, ecx ; (28 for the 0th bit!) + + mov eax, pSplashDIB + add eax, SIZEOF BITMAPINFOHEADER + 16*4 + ((SPLASH_HEIGHT-1) * DEST_BITMAP_BYTE_WIDTH) + and edx, 0FFFFFFF8h + shr edx, 1 ; get the byte offset + add eax, edx + mov DestLineStart, eax + + ; let's figure out the vertical + mov eax, VertPosition[esi] ; get the current Horz + shr eax, 16 ; discard the fractional + movsx eax, ax ; and sign-extend it + .IF (sdword ptr eax >= 0) + ; our X coord is positive, so no top clipping + mov ebx, eax + imul ebx, DEST_BITMAP_BYTE_WIDTH + sub DestLineStart, ebx + mov ebx, SPLASH_HEIGHT + sub ebx, eax + mov edx, yheight[edi] + .IF (ebx > edx) + mov ebx, edx + .ENDIF + .ELSE + ; we have a negative Y, so some of our top is clipped + mov ebx, yheight[edi] + add ebx, eax ; EBX has the new line count + imul eax, SOURCE_BITMAP_BYTE_WIDTH + add SourceLineStart, eax + .ENDIF + mov LineCount, ebx + call FastTransparentBlt + add esi, SIZEOF DWORD + .UNTIL (esi >= NUMBER_OF_FLOATERS * SIZEOF DWORD) + ret +;------------------------------------------------------------------------------- +BlitTheObjects ENDP + + +;+-----------------------------------------------------------------------------+ +;| FAST TRANSPARENT BLT | +;|-----------------------------------------------------------------------------| +;| This performs an ULTRA FAST transparent BitBlt of one DIB into another. | +;|-----------------------------------------------------------------------------| +;| EAX is the working scratch register | +;| EBX contains the destination bitmap data for 8 pixels | +;| ECX has the shift over count | +;| EDX has the 4-bit pixel mask | +;| EBP has the 1-bit pixel mask | +;| ESI has the source bitmap dword pointer | +;| EDI has the dest bitmap dword pointer | +;+-----------------------------------------------------------------------------+ +FastTransparentBlt PROC USES esi edi ebp ebx +;------------------------------------------------------------------------------- +LinePrep:movmov PixelsToBlt, eax, PixelsPerLine + mov esi, SourceLineStart + mov edi, DestLineStart + mov ebp, SourceBitStart + mov ecx, DestBitStart + mov edx, FourBitMasks[ecx] + mov ebx, [edi] ; get a dword set of bitmaps from the dest + ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +; bswap ebx ; de-scramble the nibbles! + ror ebx, 8 ; [dabc] + swap bh, bl ; [dacb] + ror ebx, 16 ; [cbda] + swap bh, bl ; [cbad] + ror ebx, 8 ; [dcba] +;------------------------------------------------------------------------------- +TstPixel:.IF ([esi] & ebp) ; see if this source-bit is set + mov eax, ebx ; get the destination bitmap dword + and eax, edx ; mask out the 4-bit pixel we want + not edx ; invert the mask to zero the dest pixel + and ebx, edx ; zero the dest for eventual or-ing + not edx ; return the mask to it's positive state + shr eax, cl ; bring the pixel down to bit 0 + mov eax, xform[eax*4] ; perform the transparent transformation + shl eax, cl ; move the new pixel back up where it goes + or ebx, eax ; and OR it back into the DIB + .ENDIF + rcr ebp, 1 ; setup for the next source pixel + .IF (carry?) ; if we're done, get the next word + rcr ebp, 1 ; set the low-order bit + add esi, 4 ; bump to the next source dword + .ENDIF + ror edx, 4 ; move the mask around four bits + sub ecx, 4 ; decrease the shift-over amount by 4 + .IF (carry?) ; if we're done with this pixel + ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +; bswap ebx ; re-scramble the nibbles + ror ebx, 8 ; [dabc] + swap bh, bl ; [dacb] + ror ebx, 16 ; [cbda] + swap bh, bl ; [cbad] + ror ebx, 8 ; [dcba] + ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + mov [edi], ebx ; replace the modified dest bitmap dword + add edi, 4 ; bump up to the next dest dword + mov ebx, [edi] ; get the next dest bitmap dword + ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +; bswap ebx ; de-scramble the nibbles + ror ebx, 8 ; [dabc] + swap bh, bl ; [dacb] + ror ebx, 16 ; [cbda] + swap bh, bl ; [cbad] + ror ebx, 8 ; [dcba] + ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + mov ecx, 28 ; and reset the shift-over amount + .ENDIF + dec PixelsToBlt + jnz TstPixel + ;-------------------------------------------------------------------------- +; bswap ebx ; re-scramble the nibbles + ror ebx, 8 ; [dabc] + swap bh, bl ; [dacb] + ror ebx, 16 ; [cbda] + swap bh, bl ; [cbad] + ror ebx, 8 ; [dcba] + ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + mov [edi], ebx ; replace the modified dest bitmap dword + ;-------------------------------------------------------------------------- + sub SourceLineStart, SOURCE_BITMAP_BYTE_WIDTH + sub DestLineStart, DEST_BITMAP_BYTE_WIDTH + dec LineCount ; see if we're all done or not + jnz LinePrep + ;-------------------------------------------------------------------------- + ret +;------------------------------------------------------------------------------- +FastTransparentBlt ENDP + + +;+-----------------------------------------------------------------------------+ +;| SET RICH EDIT TEXT | +;+-----------------------------------------------------------------------------+ +SetRichEditText PROC USES esi edi ebx, phRichEditControl:LPHWND, pszSection:LPSTR + LOCAL HeaderLength:DWORD, BodyStart:DWORD, BodyLength:DWORD +;------------------------------------------------------------------------------- + ; see whether we've already set THIS text into THIS control ... + mov eax, pszSection ; get the section we're setting + mov ebx, phRichEditControl ; and address of the control's handle + cmp eax, [ebx+4] ; see if we've already set it + je Exit ; YEP! so we're all done! + ;-------------------------------------------------------------------------- + mov [ebx+4], eax ; nope, so show it set now! + + ; now check to see if we're pointing to a NULL string ?? + .IF (!byte ptr [eax]) + mov esi, eax ; setup the stream to NULL + mov edi, 1 ; set the length to 1 + jmp SetIt + .ENDIF + + ; now search to the first '[' to size the first (header) section + mov al, '[' ; search for the first '[' bracket + mov edi, pRTF_Data + mov ecx, pRTF_Data+4 + repne scasb ; and scan past the rtf header + mov eax, edi + sub eax, pRTF_Data + dec eax + mov HeaderLength, eax ; establish the header's length + + ; now scan down to the opening of the proper section + mov edi, pRTF_Data ; restart at the top of the file + mov ecx, pRTF_Data+4 +NextOne:.REPEAT + mov al, '[' ; we're looking for a new section + repne scasb ; look for the next '[' + jne Exit ; if we didn't find one ... abort + mov esi, ecx ; save our counter around the call + invoke lstrcmp, edi, pszSection + mov ecx, esi ; restore our counter after the call + .UNTIL (!eax) ; keep looking 'till we find it + + ; now find the start of the NEXT line after the section header + mov al, LF ; look for line feeds + repne scasb ; scan for next line start + jne Exit ; abort if we didn't have one! + mov BodyStart, edi ; mark the start of the body text + + ; now find the start of the NEXT section (and the end of this one) + mov al, '[' ; we're looking for a new section + repne scasb ; look for the next '[' + jne Exit ; if we didn't find one ... abort + + ; now scan BACK to the end of the PRIOR line + mov al, LF ; scan backward past line start + mov ecx, -1 ; set the scan lenght to infinity + std ; set direction to backwards + repne scasb ; and land on the CR above + cld ; restore standard forward direction + sub edi, BodyStart ; compute the Body's length + mov BodyLength, edi + add edi, HeaderLength ; get the total allocation needed + inc edi ; and add ONE more byte for '}' + + ; allocate a block of mem for stream assembly + invoke GlobalAlloc, GPTR, edi + mov esi, eax ; esi will be our stream pointer + + ; fill the allocation with the header and the section's body + invoke MoveMemory, esi, pRTF_Data, HeaderLength + mov eax, esi + add eax, HeaderLength + invoke MoveMemory, eax, BodyStart, BodyLength + mov eax, esi + add eax, HeaderLength + add eax, BodyLength + invoke MoveMemory, eax, ADDR CloseCurly, 1 + + ; setup the stream parameters and initiate the stream +SetIt: mov StreamPointer, esi ; setup the start of the stream + add edi, esi ; add the length to the start + mov StreamEnd, edi ; and set the stream's end point + mov eax, phRichEditControl + invoke SendMessage, dword ptr [eax], EM_STREAMIN, SF_RTF or SFF_PLAINRTF, ADDR RichEditStreamIn + mov eax, phRichEditControl + invoke SetWindowPos, dword ptr [eax], HWND_TOP, 0,0,0,0, SWP_FRAMECHANGED or SWP_NOMOVE or SWP_NOSIZE or SWP_NOZORDER + ; release the temporary stream assembly allocation + .IF (byte ptr [esi]) ; if we were not pointing to a NULL + invoke GlobalFree, esi + .ENDIF +Exit: ret +;------------------------------------------------------------------------------- +SetRichEditText ENDP + + +;+-----------------------------------------------------------------------------+ +;| INITIALIZE WIZARD CONTROLS | +;|-----------------------------------------------------------------------------| +;| This presets and preloads the Wizard's Child Controls | +;+-----------------------------------------------------------------------------+ +InitializeWizardControls PROC USES esi edi + LOCAL TabItem:TC_ITEM +;------------------------------------------------------------------------------- + ; prep the RichEdit controls background colors ... + mov esi, WindowFillColor + invoke SendMessage, hRichEdit, EM_SETBKGNDCOLOR, FALSE, esi + invoke SendMessage, hRichVersion, EM_SETBKGNDCOLOR, FALSE, esi + invoke SendMessage, hPPAVersion, EM_SETBKGNDCOLOR, FALSE, esi + invoke SendMessage, hTabText, EM_SETBKGNDCOLOR, FALSE, esi + invoke SendMessage, hQuoteEdit, EM_SETBKGNDCOLOR, FALSE, esi + ; set the static text for the main RichEdit control + invoke SetRichEditText, ADDR hRichEdit, ADDR szInstructions + + ; set the static text for the ASPI version problem control + .IF (BadASPIDrivers) ; if drivers are missing or non-functional + invoke SetRichEditText, ADDR hRichVersion, ADDR szNoASPI + .ELSEIF (ErrorMode) + invoke SetRichEditText, ADDR hRichVersion, ADDR szASPITrouble + .ENDIF + ; set the static text for the ASPI version problem control + invoke SetRichEditText, ADDR hPPAVersion, ADDR szPPAVersion + ; set the default text for the action page RichEdit + invoke SetRichEditText, ADDR hTabText, ADDR szNotRunning + ; set the static text for the Iomega Quote RichEdit control + invoke SetRichEditText, ADDR hQuoteEdit, ADDR szIomegaQuote + ; setup the tabs for the ACTION page + invoke InitCommonControls ; initialize the common controls + + ; loadup the tab text + varzero TabItem + mov TabItem._mask, TCIF_TEXT + mov TabItem.iImage, -1 + mov TabItem.pszText, OFFSET szActionTabOne + invoke SendMessage, hActionTabs, TCM_INSERTITEM, 0, ADDR TabItem + mov TabItem.pszText, OFFSET szActionTabTwo + invoke SendMessage, hActionTabs, TCM_INSERTITEM, 1, ADDR TabItem + ; set the tab width + invoke SendMessage, hActionTabs, TCM_SETITEMSIZE, 0, 143 + ; set the tab font + invoke SendMessage, hActionTabs, WM_SETFONT, hDialogTextFont, NULL + + ; setup the proper URL's for the PPA Driver updating + .IF (WinNT) + mov esi, OFFSET szFullWinNTText + mov edi, OFFSET szMinimumWinNTText + .ELSE + mov esi, OFFSET szFullWin95Text + mov edi, OFFSET szMinimumWin95Text + .ENDIF + invoke SetWindowText, hFullURL, esi + invoke SetWindowText, hMinURL, edi + + ret +;------------------------------------------------------------------------------- +InitializeWizardControls ENDP + + +;+-----------------------------------------------------------------------------+ +;| STREAM SOURCE | +;+-----------------------------------------------------------------------------+ +StreamSource PROC dwCookie:DWORD, pBuff:LPBYTE, cb:DWORD, pcb:LPDWORD +;------------------------------------------------------------------------------- + mov eax, StreamEnd ; get the end of the buffer + mov edx, StreamPointer ; get the current start + sub eax, edx ; calc the remaining amount + mov ecx, cb ; get the count to read + .IF (eax > ecx) ; if it's more than we have left + mov eax, ecx ; diminish it to the limit + .ENDIF + add StreamPointer, eax ; bump the offset forward for next + push eax ; save the amount transferred + invoke MoveMemory, pBuff, edx, eax ; move the data + mov eax, pcb + pop dword ptr [eax] + zero eax ; return zero to continue streaming + ret +;------------------------------------------------------------------------------- +StreamSource ENDP + +IF DEVELOPMENT +;+-----------------------------------------------------------------------------+ +;| POST TO SCREEN | +;+-----------------------------------------------------------------------------+ +PostToScreen PROC USES eax ebx esi edi, PostVal:DWORD + LOCAL PostString[20]:CHAR, Extent:_SIZE +;------------------------------------------------------------------------------- + mov eax, PostVal +; .IF (eax != LastPostedValue) + mov LastPostedValue, eax + invoke GetDC, HWND_DESKTOP + mov edi, eax + invoke SelectObject, edi, hTitleFont + invoke SelectObject, edi, hBlackPen + invoke SelectObject, edi, hBlackBrush + invoke wsprintf, ADDR PostString, ADDR szLongHexFormat, LastPostedValue + mov esi, eax + invoke TextOut, edi, 0, LastPostedTop, ADDR PostString, eax + invoke GetTextExtentPoint32, edi, ADDR PostString, esi, ADDR Extent + mov esi, Extent._cy + add esi, POSTING_SPACE + add LastPostedTop, esi + invoke GetSystemMetrics, SM_CYSCREEN + sub eax, esi + .IF (LastPostedTop > eax) + reset LastPostedTop + .ENDIF + mov eax, Extent._cx + mov ebx, Extent._cy + add ebx, LastPostedTop + invoke Rectangle, edi, 0, LastPostedTop, eax, ebx + invoke ReleaseDC, HWND_DESKTOP, edi +; .ENDIF + ret +;------------------------------------------------------------------------------- +PostToScreen ENDP +ENDIF + + +;+-----------------------------------------------------------------------------+ +;| PROCESS PENDING MESSAGES | +;|-----------------------------------------------------------------------------| +;| This allows all windows to receive and process any and all pending | +;| messages ... such as old WM_PAINT's that they may be holding ... | +;|-----------------------------------------------------------------------------| +;| Note also that this loop DELIBERATELY AVOIDS the removal of WM_QUIT | +;| messages, since they should only be removed by the GetMessage call | +;| which returns FALSE when it encounters the WM_QUIT | +;+-----------------------------------------------------------------------------+ +ProcessPendingMessages PROC USES esi + LOCAL msg:MSG +;------------------------------------------------------------------------------- +; USB seems to generate insane WM_TIMER messages, so we now stop the timer +; during data read/write processing. + .REPEAT + invoke PeekMessage, ADDR msg, NULL, 0, 0, PM_REMOVE + .IF (eax) + mov esi, eax + invoke TranslateAccelerator, hMainWnd, hAccel, ADDR msg + .IF (!eax) ; skip if we already handled it ... + invoke TranslateMessage, ADDR msg + invoke DispatchMessage, ADDR msg + .ENDIF + mov eax, esi + .ENDIF + .UNTIL (!eax) + ret +;------------------------------------------------------------------------------- +ProcessPendingMessages ENDP + + +;+-----------------------------------------------------------------------------+ +;| UPDATE RUN TIME DISPLAY | +;+-----------------------------------------------------------------------------+ +UpdateRunTimeDisplay PROC USES edi +;------------------------------------------------------------------------------- + invoke GetDC, hTestMonitor + mov edi, eax + invoke PaintTestPhase, edi + invoke PaintTheBarGraphs, edi, TRUE + invoke PaintTestStatistics, edi, TRUE + invoke ReleaseDC, hTestMonitor, edi + call ProcessPendingMessages ; paint all current status + ret +;------------------------------------------------------------------------------- +UpdateRunTimeDisplay ENDP + + +;+-----------------------------------------------------------------------------+ +;| UPDATE CURRENT SECTOR | +;+-----------------------------------------------------------------------------+ +UpdateCurrentSector PROC USES edi + LOCAL szString[40]:CHAR +;------------------------------------------------------------------------------- + invoke GetDC, hTestMonitor + mov edi, eax + invoke wsprintf, ADDR szString, ADDR szCenteredDecimal, SingleTransferLBA + invoke PaintCenteredString, edi, 76, 155, 126, 14, ADDR szString, TRUE + invoke ReleaseDC, hTestMonitor, edi + ret +;------------------------------------------------------------------------------- +UpdateCurrentSector ENDP + + +;+-----------------------------------------------------------------------------+ +;| UPDATE RUN TIME DISPLAY | +;+-----------------------------------------------------------------------------+ +UpdateRunPhaseDisplay PROC USES edi +;------------------------------------------------------------------------------- + invoke GetDC, hTestMonitor + mov edi, eax + invoke PaintTestPhase, edi + invoke ReleaseDC, hTestMonitor, edi + call ProcessPendingMessages ; paint all current status + ret +;------------------------------------------------------------------------------- +UpdateRunPhaseDisplay ENDP + + +;+-----------------------------------------------------------------------------+ +;| PREVENT PROGRAM EXIT | +;+-----------------------------------------------------------------------------+ +PreventProgramExit PROC +;------------------------------------------------------------------------------- + invoke GetSystemMenu, hMainWnd, FALSE ; get sysmenu handle + invoke DeleteMenu, eax, SC_CLOSE, MF_BYCOMMAND + invoke SendMessage, hMainWnd, WM_NCPAINT, NULL, NULL + invoke SetWindowPos, hMainWnd, 0, 0,0,0,0, + SWP_DRAWFRAME or SWP_NOMOVE or SWP_NOSIZE or SWP_NOZORDER + invoke EnableWindow, hExitButton, FALSE + ret +;------------------------------------------------------------------------------- +PreventProgramExit ENDP + + +;+-----------------------------------------------------------------------------+ +;| ALLOW PROGRAM EXIT | +;+-----------------------------------------------------------------------------+ +AllowProgramExit PROC +;------------------------------------------------------------------------------- + invoke GetSystemMenu, hMainWnd, FALSE ; get sysmenu handle + invoke AppendMenu, eax, MF_STRING, SC_CLOSE, ADDR szCloseCmd + invoke SendMessage, hMainWnd, WM_NCPAINT, NULL, NULL + invoke SetWindowPos, hMainWnd, 0, 0,0,0,0, + SWP_DRAWFRAME or SWP_NOMOVE or SWP_NOSIZE or SWP_NOZORDER + invoke EnableWindow, hExitButton, TRUE + ret +;------------------------------------------------------------------------------- +AllowProgramExit ENDP + + +;+-----------------------------------------------------------------------------+ +;| COPY CURRENT PAGE | +;+-----------------------------------------------------------------------------+ +CopyCurrentPage PROC USES ebx esi edi +;------------------------------------------------------------------------------- + mov ebx, CurrentPage ; get the page we're seeing + ; if we're trying to copy the test results page ... + .IF (ebx == PERFORM_TEST_PAGE) + ; see whether the test results are being viewed + invoke GetWindowLong, hTestMonitor, GWL_ID + .IF (eax == (INVISIBLE_PAGE SHL PAGE_SHIFT)) + ; nope, so copy from the Explantion Page instead + inc ebx + .ENDIF + .ENDIF + mov ebx, CopySourceHandles[ebx*8] ; and the RichEdit hWnd + ; okay ... now if it's a TEXT copy rather than a bitmap ... + ; EBX has the HANDLE of the control to copy from! + .IF (ebx) + ; suppress showing the selection region + invoke SendMessage, ebx, EM_HIDESELECTION, TRUE, TRUE + ; select ALL of the text + invoke SendMessage, ebx, EM_SETSEL, 0, -1 + ; copy it to the clipboard + invoke SendMessage, ebx, WM_COPY, 0, 0 + .ELSE ; no RichEdit control on this page ... so we'll snap a + ; picture of the bitmap + invoke OpenClipboard, hMainWnd + .IF (eax) + mov ebx, eax ; ebx has the clipboard handle + invoke EmptyClipboard ; free up any previous memory + invoke GetDC, hMainWnd ; pickup a source context + mov esi, eax + invoke CreateCompatibleDC, NULL + mov edi, eax ; and a destination context + invoke CreateCompatibleBitmap, esi, COPY_WIDTH, COPY_HEIGHT + invoke SelectObject, edi, eax + push eax ; save DC's orig bitmap + invoke BitBlt, edi, 0,0, COPY_WIDTH, COPY_HEIGHT, esi, COPY_LEFT, COPY_TOP, SRCCOPY + pop eax ; recover DC's orig bitmap + invoke SelectObject, edi, eax ; put it back and our new bitmap back + mov ebx, eax ; save our bitmap for handing over to clipboard + invoke DeleteDC, edi + invoke ReleaseDC, hMainWnd, esi + invoke SetClipboardData, CF_BITMAP, ebx + invoke CloseClipboard + .ENDIF + .ENDIF + + ret +;------------------------------------------------------------------------------- +CopyCurrentPage ENDP + + +;+-----------------------------------------------------------------------------+ +;| VERIFY FILE CHECKSUM | +;+-----------------------------------------------------------------------------+ +VerifyFileChecksum PROC USES ebx esi edi + LOCAL FileName[MAX_PATH]:CHAR, BytesRead:DWORD +;------------------------------------------------------------------------------- + ; load ourselves into a ram buffer ... + invoke GetModuleFileName, NULL, ADDR FileName, MAX_PATH + invoke CreateFile, ADDR FileName, GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or FILE_FLAG_SEQUENTIAL_SCAN, NULL + mov ebx, eax ; hold the file handle + invoke GetFileSize, eax, NULL ; get the size + add eax, 3 ; allocate read buffer + and eax, 0FFFFFFFCh ; an even dword size + mov edi, eax ; hold the size + invoke GlobalAlloc, GPTR, eax + push eax ; save for buffer free + mov esi, eax ; hold the buffer's start + invoke ReadFile, ebx, esi, edi, ADDR BytesRead, NULL + invoke CloseHandle, ebx + ; we have the file in RAM ... now let's sum it up! + zero ebx ; clear the sumation + mov ecx, edi + shr ecx, 2 ; divide it down by four + .REPEAT + lodsd ; pickup a dword + add ebx, eax + .UNTILCXZ + pop eax ; recover the buffer start + invoke GlobalFree, eax + .IF (ebx) + invoke MessageBox, hMainWnd, ADDR szBadFileText, ADDR szBadFileTitle, MB_APPLMODAL or MB_OK + invoke ExitProcess, -1 ; exit with ERROR! + .ENDIF + ret +;------------------------------------------------------------------------------- +VerifyFileChecksum ENDP + + +;+-----------------------------------------------------------------------------+ +;| ErrorSound | +;+-----------------------------------------------------------------------------+ +ErrorSound PROC +;------------------------------------------------------------------------------- + ; see whether we have sounds enabled + invoke SendMessage, hSoundCheckbox, BM_GETCHECK, NULL, NULL + .IF (eax == BST_CHECKED) + invoke GetVersion ; find out what platform we're running ... + .IF !(eax & 80000000h) + invoke Beep, 745, 13 + .ELSE + mov Period, 800 + mov Duration, 10 + cli + call GetPhasorPosition ; set initial angle + mov PhasorPosition, ax + .REPEAT + mov ax, Period ; update the phasor angle + sub PhasorPosition, ax + .REPEAT + call GetPhasorPosition + sub ax, PhasorPosition + .IF (carry?) + neg ax + .ENDIF + .UNTIL (ax < 100) + call ToggleSpeaker + dec Duration + .UNTIL (zero?) + sti + .ENDIF + .ENDIF +;------------------------------------------------------------------------------- + ret + +GetPhasorPosition: +;------------------------------------------------------------------------------- + mov al, 00000100B ; latch timer_0 + out TIMER_MODE, al + jmp $+2 + in al, TIMER_0 ; LSB + jmp $+2 + xchg ah, al + in al, TIMER_0 ; MSB + jmp $+2 + xchg ah, al ; finally form the count +;------------------------------------------------------------------------------- + LocalReturn + +ToggleSpeaker: +;------------------------------------------------------------------------------- + in al, SPEAKER_GATE + jmp $+2 + and al, NOT OSCILLATOR_GATE_BIT ; kill OSC Input + xor al, SPEAKER_DATA_BIT ; invert Spkr Data + out SPEAKER_GATE, al + jmp $+2 +;------------------------------------------------------------------------------- + LocalReturn + +;------------------------------------------------------------------------------- +ErrorSound ENDP + + + +;------------------------------------------------------------------------------- +include aspi.asm + +;-/////////////////////////////////////////////////////////////////////////////- +END Start +;-/////////////////////////////////////////////////////////////////////////////- diff --git a/x86-asm-source/TIP.DAT b/x86-asm-source/TIP.DAT new file mode 100644 index 0000000..d80bc71 --- /dev/null +++ b/x86-asm-source/TIP.DAT @@ -0,0 +1,321 @@ +;+-----------------------------------------------------------------------------+ +;| oo oo oo oo | +;| ^^ ^^ÄÄÄÄÄÄÄÄÄÄ Treatment Style ; 16 bits of style | +;| ^^ÄÄÄÄÄÄÄ Page (FF == ALL pages) ; up to 256 pages | +;| ^^ÄÄÄÄ Page Local ID ; up to 256 controls/page | +;+-----------------------------------------------------------------------------+ + +SMALL_NORMAL_TEXT equ 0000b +SMALL_BOLD_TEXT equ 0001b +LARGE_NORMAL_TEXT equ 0010b +LARGE_BOLD_TEXT equ 0011b +HEADLINE_TEXT equ 0100b +TERMINAL_TEXT equ 0101b +;------------------------------------------------------------------------------- + +THREE_DEE_BOX equ 0001b +NO_SINK_OUTLINE equ 0010b +;------------------------------------------------------------------------------- + +TREATMENT_STYLE_SHIFT equ 16 +PAGE_MASK equ 0000FF00h +PAGE_SHIFT equ 8 + +;-------------------------- Main Positioning Equates --------------------------- + +TITLE_TOP equ 11 +TITLE_HEIGHT equ (BODY_TOP - TITLE_TOP) + +BODY_LEFT equ 156 +BODY_TOP equ 54 +BODY_RIGHT equ 445 +BODY_BOTTOM equ 280 + +BODY_WIDTH equ (BODY_RIGHT - BODY_LEFT) +BODY_HEIGHT equ (BODY_BOTTOM - BODY_TOP) + +ITEM_SPACING equ 30 +TIGHT_ITEM_SPACING equ 25 + +TEST_BUTTON_LEFT equ 340 +TEST_BUTTON_TOP equ 10 +TEST_BUTTON_WIDTH equ 106 +TEST_BUTTON_HEIGHT equ 20 + +;---------------------------------- PAGE IDS ----------------------------------- + +INTRO_PAGE equ 0 +INSTRUCTION_PAGE equ 1 +PPA_VERSION_PAGE equ 2 +ASPI_VERSION_PAGE equ 3 +SELECT_DRIVE_PAGE equ 4 +PERFORM_TEST_PAGE equ 5 +EXPLAIN_RESULTS equ 6 +QUOTE_PAGE equ 7 +CREDITS_PAGE equ 8 +;------------------------------------------------------------------------------- +FIRST_ACTION_PAGE equ PERFORM_TEST_PAGE +LAST_ACTION_PAGE equ EXPLAIN_RESULTS +LAST_PAGE equ CREDITS_PAGE +INVISIBLE_PAGE equ 0FDh ; never shown page +ACTION_PAGES equ 0FEh +EVERY_PAGE equ 0FFh + +;-------------------------------- Control Names -------------------------------- + +szTEXT CHAR "STATIC",0 +szEDIT CHAR "EDIT",0 +szBUTTON CHAR "BUTTON",0 +szLISTBOX CHAR "LISTBOX",0 +sz3DSink CHAR "3DSINK",0 +szRICHEDIT CHAR "RICHEDIT",0 +szTABCONTROL CHAR "SysTabControl32",0 +szTestMonitor CHAR "TIPTEST",0 + +;-------------------------------- Control Text --------------------------------- + +szBack CHAR "< &Back",0 +szNext CHAR "&Next >",0 +szQuit CHAR "E&xit",0 +szCopy CHAR "&Copy",0 +szWebUrl CHAR "http://grc.com",0 +szHelpMode CHAR "Explanation",0 +szFullScreenMode CHAR "Full Display",0 + +;-------------------------- Global button management --------------------------- + +BackButtonEnabled dd 10000000000000000000000111111110b +NextButtonEnabled dd 00000000000000000000000011111111b + +;=============================================================================== +WindowCreationTable LABEL WORD +;+-----------------------------------------------------------------------------+ +;| Window Creation Data | +;|-----------------------------------------------------------------------------| +;| ClassName, WindowName, Style, x, y, Width, Height, Parent, CtrlID, hWnd | +;+-----------------------------------------------------------------------------+ + DWORD szBUTTON, szBack + DWORD WS_CHILD or WS_VISIBLE + DWORD 185-28, 301, 80, 24 + pagectl EVERY_PAGE, 0, IDB_BACK ; (IBD_BACK == 0FF00) + + DWORD szBUTTON, szNext + DWORD WS_CHILD or WS_VISIBLE + DWORD 264-28, 301, 80, 24 + pagectl EVERY_PAGE, 0, IDB_NEXT + + DWORD szBUTTON, szQuit + DWORD WS_CHILD or WS_VISIBLE + DWORD 367+35, 301, 45, 24 + pagectl EVERY_PAGE, 0, IDB_QUIT, hExitButton + + DWORD szBUTTON, szCopy + DWORD WS_CHILD or WS_VISIBLE + DWORD 367-30, 301, 45, 24 + pagectl EVERY_PAGE, 0, IDB_COPY + +;----------------- These controls are on the two ACTION pages ------------------ + + ; the sound effects button (must go ahead of the 3DSink control + DWORD szBUTTON, NULL + DWORD WS_CHILD or WS_VISIBLE or BS_AUTOCHECKBOX + DWORD 252, 211, 22, 22 + pagectl PERFORM_TEST_PAGE, 0,, hSoundCheckbox + + ; cover up the tab control's contents to inhibit selection within it + DWORD OFFSET sz3DSink, NULL + DWORD WS_CHILD or WS_VISIBLE + DWORD 20, 45, 393, 224 + pagectl ACTION_PAGES, NO_SINK_OUTLINE + + ; tab control for the action window + DWORD szTABCONTROL, NULL + DWORD WS_CHILD or WS_VISIBLE or WS_CLIPSIBLINGS or TCS_FIXEDWIDTH or TCS_FOCUSNEVER + DWORD 14, 16, 433, 260 + pagectl ACTION_PAGES, 0,, hActionTabs + + ; the cartridge eject button + DWORD szBUTTON, szOneMoment + DWORD WS_CHILD or WS_VISIBLE + DWORD TEST_BUTTON_LEFT, TEST_BUTTON_TOP, TEST_BUTTON_WIDTH, TEST_BUTTON_HEIGHT + pagectl ACTION_PAGES, NULL, IDB_TEST, hTestButton + +;+-----------------------------------------------------------------------------+ +;| INTRO | +;+-----------------------------------------------------------------------------+ + DWORD szTEXT, szIntroSubTitle + DWORD WS_CHILD or WS_VISIBLE + DWORD 221, BODY_TOP, 230, 60 + pagectl INTRO_PAGE, LARGE_NORMAL_TEXT + + DWORD szTEXT, szIntroText + DWORD WS_CHILD or WS_VISIBLE + DWORD BODY_LEFT, BODY_TOP+64, BODY_WIDTH, 115 + pagectl INTRO_PAGE, LARGE_NORMAL_TEXT + + DWORD sz3DSink, NULL + DWORD WS_CHILD or WS_VISIBLE + DWORD 15, 17, 122, 260 + pagectl INTRO_PAGE, SMALL_NORMAL_TEXT + + +;+-----------------------------------------------------------------------------+ +;| INSTRUCTIONS | +;+-----------------------------------------------------------------------------+ + ; cover up the edit box so people can't select within it + DWORD OFFSET sz3DSink, NULL + DWORD WS_CHILD or WS_VISIBLE + DWORD 19, 16, 428-16, 260 + pagectl INSTRUCTION_PAGE, NO_SINK_OUTLINE + + ; scrollable instructions edit window + DWORD szRICHEDIT, NULL + DWORD WS_CHILD or WS_VISIBLE or WS_VSCROLL or ES_AUTOVSCROLL or ES_MULTILINE or ES_WANTRETURN + DWORD 19, 16, 428, 260 + pagectl INSTRUCTION_PAGE, LARGE_NORMAL_TEXT, IDE_INSTR, hRichEdit + +;+-----------------------------------------------------------------------------+ +;| PPA_VERSION_PAGE | +;+-----------------------------------------------------------------------------+ + ; cover up the edit box so people can't select within it + DWORD OFFSET sz3DSink, NULL + DWORD WS_CHILD or WS_VISIBLE + DWORD 19, 16, 428-16, 260-30 + pagectl PPA_VERSION_PAGE, NO_SINK_OUTLINE + + ; scrollable instructions edit window + DWORD szRICHEDIT, NULL + DWORD WS_CHILD or WS_VISIBLE or WS_VSCROLL or ES_AUTOVSCROLL or ES_MULTILINE or ES_WANTRETURN + DWORD 19, 16, 428, 260-30 + pagectl PPA_VERSION_PAGE, LARGE_NORMAL_TEXT, IDE_ASPIVER, hPPAVersion + + ; FTP transfer FULL Iomega file set + DWORD szBUTTON, NULL + DWORD WS_CHILD or WS_VISIBLE + DWORD 24, 255, 200, 27 + pagectl PPA_VERSION_PAGE, LARGE_NORMAL_TEXT, IDB_GET_PPA_FULL, hFullURL + + ; FTP transfer Iomega DRIVER file set + DWORD szBUTTON, NULL + DWORD WS_CHILD or WS_VISIBLE + DWORD 238, 255, 200, 27 + pagectl PPA_VERSION_PAGE, LARGE_NORMAL_TEXT, IDB_GET_PPA_DRIVERS, hMinURL + +;+-----------------------------------------------------------------------------+ +;| ASPI_VERSION_PAGE | +;+-----------------------------------------------------------------------------+ + ; cover up the edit box so people can't select within it + DWORD OFFSET sz3DSink, NULL + DWORD WS_CHILD or WS_VISIBLE + DWORD 19, 16, 428-16, 260-30 + pagectl ASPI_VERSION_PAGE, NO_SINK_OUTLINE + + ; scrollable instructions edit window + DWORD szRICHEDIT, NULL + DWORD WS_CHILD or WS_VISIBLE or WS_VSCROLL or ES_AUTOVSCROLL or ES_MULTILINE or ES_WANTRETURN + DWORD 19, 16, 428, 260-30 + pagectl ASPI_VERSION_PAGE, LARGE_NORMAL_TEXT, IDE_PPAVER, hRichVersion + +;+-----------------------------------------------------------------------------+ +;| SELECT_DRIVE_PAGE | +;+-----------------------------------------------------------------------------+ + DWORD szTEXT, szSelectDrive + DWORD WS_CHILD or WS_VISIBLE or SS_CENTER + DWORD 0+80, 10, 462-160, TITLE_HEIGHT + pagectl SELECT_DRIVE_PAGE, HEADLINE_TEXT + + ; lightly sunken rectangle around the text + DWORD sz3DSink, NULL + DWORD WS_CHILD or WS_VISIBLE + DWORD 15, 53, 432, 225 + pagectl SELECT_DRIVE_PAGE, SMALL_NORMAL_TEXT + + ; this is the body text of the credits page + DWORD szTEXT, szSelectionHelp + DWORD WS_CHILD or WS_VISIBLE + DWORD 30, 67, 414-5, 210 + pagectl SELECT_DRIVE_PAGE, LARGE_NORMAL_TEXT + +;+-----------------------------------------------------------------------------+ +;| PERFORM_TEST_PAGE | +;+-----------------------------------------------------------------------------+ + ; the window containing all of the controls ... + DWORD szTestMonitor, NULL + DWORD WS_CHILD or WS_VISIBLE + DWORD 20, 45, 420, 224 + pagectl PERFORM_TEST_PAGE, 0,, hTestMonitor + + +;+-----------------------------------------------------------------------------+ +;| EXPLAIN_RESULTS | +;+-----------------------------------------------------------------------------+ + ; optional text for the perform test page + DWORD szRICHEDIT, NULL + DWORD WS_CHILD or WS_VISIBLE or WS_VSCROLL or ES_AUTOVSCROLL or ES_MULTILINE or ES_WANTRETURN + DWORD 32, 55, 397, 204 + pagectl EXPLAIN_RESULTS, 0, TAB_TEXT, hTabText + +;+-----------------------------------------------------------------------------+ +;| QUOTE | +;+-----------------------------------------------------------------------------+ + ; cover up the edit box so people can't select within it + DWORD OFFSET sz3DSink, NULL + DWORD WS_CHILD or WS_VISIBLE + DWORD 19, 16, 428-16, 260-30 + pagectl QUOTE_PAGE, NO_SINK_OUTLINE + + ; scrollable instructions edit window + DWORD szRICHEDIT, NULL + DWORD WS_CHILD or WS_VISIBLE or WS_VSCROLL or ES_AUTOVSCROLL or ES_MULTILINE or ES_WANTRETURN + DWORD 19, 16, 428, 260-30 + pagectl QUOTE_PAGE, LARGE_NORMAL_TEXT, IDE_QUOTE, hQuoteEdit + + DWORD szBUTTON, szLeftQuote + DWORD WS_CHILD or WS_VISIBLE + DWORD 24, 260, 200, 24 + pagectl QUOTE_PAGE, 0, IDB_LEFT_QUOTE + + DWORD szBUTTON, szRightQuote + DWORD WS_CHILD or WS_VISIBLE + DWORD 238, 260, 200, 24 + pagectl QUOTE_PAGE, 0, IDB_RIGHT_QUOTE + +;+-----------------------------------------------------------------------------+ +;| CREDITS | +;+-----------------------------------------------------------------------------+ + +; DWORD szTEXT, szPage_4_Title +; DWORD WS_CHILD or WS_VISIBLE +; DWORD 20, 38, 375, TITLE_HEIGHT +; pagectl CREDITS_PAGE, HEADLINE_TEXT + + ; lightly sunken rectangle around the text + DWORD sz3DSink, NULL + DWORD WS_CHILD or WS_VISIBLE + DWORD 15, 80, 432, 198 + pagectl CREDITS_PAGE, SMALL_NORMAL_TEXT + + ; this is the body text of the credits page + DWORD szTEXT, szPage_4_Text + DWORD WS_CHILD or WS_VISIBLE + DWORD 25, 90, 414, 186 + pagectl CREDITS_PAGE, LARGE_NORMAL_TEXT + + ; the web launch button on the credits page + DWORD szBUTTON, szWebUrl + DWORD WS_CHILD or WS_VISIBLE + DWORD 17, 301, 100, 24 + pagectl CREDITS_PAGE, SMALL_NORMAL_TEXT, IDB_WEB + + ; the sunked ring around the Web Button + DWORD OFFSET sz3DSink, NULL + DWORD WS_CHILD or WS_VISIBLE + DWORD 15, 299, 104, 28 + pagectl CREDITS_PAGE, SMALL_BOLD_TEXT + +;-/////////////////////////////////////////////////////////////////////////////- + SIZE_OF_CREATE_ENTRY = 40 + WINDOW_CREATION_ENTRIES = ($-WindowCreationTable)/SIZE_OF_CREATE_ENTRY +;=============================================================================== +.ERRNZ ($-WindowCreationTable) - (WINDOW_CREATION_ENTRIES*SIZE_OF_CREATE_ENTRY) + diff --git a/x86-asm-source/TIP.DSP b/x86-asm-source/TIP.DSP new file mode 100644 index 0000000..c9e07a1 --- /dev/null +++ b/x86-asm-source/TIP.DSP @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="TIP" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 5.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) External Target" 0x0106 + +CFG=TIP - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "TIP.MAK". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "TIP.MAK" CFG="TIP - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "TIP - Win32 Release" (based on "Win32 (x86) External Target") +!MESSAGE "TIP - Win32 Debug" (based on "Win32 (x86) External Target") +!MESSAGE + +# Begin Project +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" + +!IF "$(CFG)" == "TIP - Win32 Release" + +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Cmd_Line "NMAKE /f TIP.MAK" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "TIP.EXE" +# PROP BASE Bsc_Name "TIP.BSC" +# PROP BASE Target_Dir "" +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Cmd_Line "NMAKE /f TIP.MAK" +# PROP Rebuild_Opt "/a" +# PROP Target_File "TIP.EXE" +# PROP Bsc_Name "TIP.BSC" +# PROP Target_Dir "" + +!ELSEIF "$(CFG)" == "TIP - Win32 Debug" + +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Cmd_Line "NMAKE /f TIP.MAK" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "TIP.EXE" +# PROP BASE Bsc_Name "TIP.BSC" +# PROP BASE Target_Dir "" +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Cmd_Line "NMAKE /f makefile" +# PROP Rebuild_Opt "/a" +# PROP Target_File "S:\Asm\TIP\tip.exe" +# PROP Bsc_Name "TIP.BSC" +# PROP Target_Dir "" + +!ENDIF + +# Begin Target + +# Name "TIP - Win32 Release" +# Name "TIP - Win32 Debug" + +!IF "$(CFG)" == "TIP - Win32 Release" + +!ELSEIF "$(CFG)" == "TIP - Win32 Debug" + +!ENDIF + +# Begin Source File + +SOURCE=.\ASPI.ASM +# End Source File +# Begin Source File + +SOURCE=..\Include\ASPI.INC +# End Source File +# Begin Source File + +SOURCE=.\font.asm +# End Source File +# Begin Source File + +SOURCE=.\MACROS.INC +# End Source File +# Begin Source File + +SOURCE=.\MAKEFILE +# End Source File +# Begin Source File + +SOURCE=.\New.asm +# End Source File +# Begin Source File + +SOURCE=.\tip.asm +# End Source File +# Begin Source File + +SOURCE=.\tip.cur +# End Source File +# Begin Source File + +SOURCE=.\tip.dat +# End Source File +# Begin Source File + +SOURCE=.\tip.ico +# End Source File +# Begin Source File + +SOURCE=.\tip.rc +# End Source File +# Begin Source File + +SOURCE=.\tip.txt +# End Source File +# End Target +# End Project diff --git a/x86-asm-source/TIP.DSW b/x86-asm-source/TIP.DSW new file mode 100644 index 0000000..010823b --- /dev/null +++ b/x86-asm-source/TIP.DSW @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 5.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "TIP"=.\TIP.DSP - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/x86-asm-source/TIP.ICO b/x86-asm-source/TIP.ICO new file mode 100644 index 0000000000000000000000000000000000000000..5ad8bb5c4f92a779c728d611cccb99b508b53423 GIT binary patch literal 766 zcmcIhI}*Ym5Pfl+Nr{zhQhEzLk{zXV;aD6crDZx(IIeHmOk|w+X|nK^{Q(aas5sho z2bJpv*mFG)EpZ|$Y^j03+_D5FnF+xbYMMkqN{I={6C!F692!!ka`WDw&CGg?F|O(J zVi}72ewl0V>xu{Jdt(uB>X(6B5WAVDv%u>J3*-VL>qJk`4bx}pnIC=rzc2H&Rpxqg z|MQJ}-eLTdNtUVG+V?EVPEsRZG1V^D)ZAN%^tiB}M;Xz`18%4T(HlVj4I|Lp!Fpc* E1bX`Ba{vGU literal 0 HcmV?d00001 diff --git a/x86-asm-source/TIP.PLG b/x86-asm-source/TIP.PLG new file mode 100644 index 0000000..939102d --- /dev/null +++ b/x86-asm-source/TIP.PLG @@ -0,0 +1,6 @@ +--------------------Configuration: TIP - Win32 Debug-------------------- + + + + +TIP.EXE - 0 error(s), 0 warning(s) diff --git a/x86-asm-source/TIP.RC b/x86-asm-source/TIP.RC new file mode 100644 index 0000000..f4e2e32 --- /dev/null +++ b/x86-asm-source/TIP.RC @@ -0,0 +1,139 @@ +#define APPNAME TIP +///////////////////////////////////////////////////////////////////////////// +#define IDB_BACK 0xFF00 +#define IDB_NEXT 0xFF01 +#define IDB_QUIT 0xFF02 +#define IDB_COPY 0xFF03 +#define VK_PRIOR 0x0021 +#define VK_NEXT 0x0022 +#define VK_END 0x0023 +#define VK_HOME 0x0024 +#define VK_LEFT 0x0025 +#define VK_UP 0x0026 +#define VK_RIGHT 0x0027 +#define VK_DOWN 0x0028 + +#define IDB_LINEUP 0x8000 +#define IDB_LINEDN 0x8001 +#define IDB_PAGEUP 0x8002 +#define IDB_PAGEDN 0x8003 +#define IDB_END 0x8004 +#define IDB_HOME 0x8005 + +#define DS_MODALFRAME 0x000000080 + +#define WS_POPUP 0x080000000 +#define WS_VISIBLE 0x010000000 +#define WS_CAPTION 0x000c00000 +#define WS_TABSTOP 0x000010000 + +#define ES_PASSWORD 0x000000020 +#define ES_AUTOHSCROLL 0x000000080 + +#define IDOK 1 +#define IDCANCEL 2 +#define IDC_PASSWORD 3 + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// +APPNAME ICON "tip.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Cursor +// +APPNAME CURSOR "tip.cur" + +///////////////////////////////////////////////////////////////////////////// +// +// Bitmaps +// +REDBITMAP BITMAP "red.bmp" +GRNBITMAP BITMAP "green.bmp" +OFFBITMAP BITMAP "off.bmp" +SOUND BITMAP "sound.bmp" + +////////////////////////////////////////////////////////////////////////////// +// +// Cartridge Password Dialog +// + +APPNAME DIALOG DISCARDABLE 57, 42, 187, 86 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION +CAPTION "Please Enter Cartridge's Password" +FONT 8, "MS Sans Serif" +BEGIN + EDITTEXT IDC_PASSWORD,12,41,162,12,WS_TABSTOP | ES_PASSWORD | ES_AUTOHSCROLL + DEFPUSHBUTTON "OK",IDOK,32,66,50,14 + PUSHBUTTON "Cancel",IDCANCEL,104,66,50,14 + LTEXT "This cartridge has been protected by a password. You must enter the cartridge's password, then press OK, before this cartridge can be used . . .", + 0,12,8,162,27 +END + +///////////////////////////////////////////////////////////////////////////// +// +// Accelerator +// +APPNAME ACCELERATORS MOVEABLE PURE +BEGIN + "b", IDB_BACK, ASCII, ALT, NOINVERT + "B", IDB_BACK, ASCII, ALT, NOINVERT + "b", IDB_BACK, ASCII, NOINVERT + "B", IDB_BACK, ASCII, NOINVERT + "<", IDB_BACK, ASCII, NOINVERT + ",", IDB_BACK, ASCII, NOINVERT + VK_LEFT, IDB_BACK, VIRTKEY, NOINVERT + + "c", IDB_COPY, ASCII, NOINVERT + "C", IDB_COPY, ASCII, NOINVERT + + "n", IDB_NEXT, ASCII, ALT, NOINVERT + "N", IDB_NEXT, ASCII, ALT, NOINVERT + "n", IDB_NEXT, ASCII, NOINVERT + "N", IDB_NEXT, ASCII, NOINVERT + ">", IDB_NEXT, ASCII, NOINVERT + ".", IDB_NEXT, ASCII, NOINVERT + VK_RIGHT, IDB_NEXT, VIRTKEY, NOINVERT + + "x", IDB_QUIT, ASCII, ALT, NOINVERT + "X", IDB_QUIT, ASCII, ALT, NOINVERT + "x", IDB_QUIT, ASCII, NOINVERT + "X", IDB_QUIT, ASCII, NOINVERT + + VK_UP, IDB_LINEUP, VIRTKEY, NOINVERT + VK_DOWN, IDB_LINEDN, VIRTKEY, NOINVERT + VK_PRIOR, IDB_PAGEUP, VIRTKEY, NOINVERT + VK_NEXT, IDB_PAGEDN, VIRTKEY, NOINVERT + VK_END, IDB_END, VIRTKEY, NOINVERT + VK_HOME, IDB_HOME, VIRTKEY, NOINVERT +END + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// +1 VERSIONINFO +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "A Web Site for Updates", "http://grc.com\0" + VALUE "CompanyName", "Gibson Research Corp.\0" + VALUE "FileDescription", "Iomega Drive/Media Tester\0" + VALUE "FileVersion", "2.1b\0" + VALUE "InternalName", "tip.exe\0" + VALUE "LegalCopyright", "Copyright \251 2003 Gibson Research Corp.\0" + VALUE "OriginalFilename", "tip.exe\0" + VALUE "ProductName", "TIP (Trouble In Paradise) by Steve Gibson\0" + VALUE "ProductVersion", "2.1b\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + diff --git a/x86-asm-source/TIP.TXT b/x86-asm-source/TIP.TXT new file mode 100644 index 0000000..440a8f7 --- /dev/null +++ b/x86-asm-source/TIP.TXT @@ -0,0 +1,254 @@ + +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Clickable Hyperlink to web site ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + +szCheck_1 db "Check my web site at " +szCheck_2 db "http://grc.com" +szCheck_3 db " from time",0 +szCheck_4 db "to time for newer versions and other free stuff.",0 + +szActionTabOne db "Perform Test",0 +szActionTabTwo db "Explain Results",0 +szCartStatus db "Cartridge Status:",0 + +szLeftQuote db "Listen to David Hellier's Introduction",0 +szRightQuote db "Listen to David Hellier's Statement",0 + +szEstimating db "Estimating ...",0 +szOneMoment db "--- --- ---",0 +szPressToStart db "Press to Begin",0 +szPressToStop db "Press to Stop",0 +szPressToSpin db "Press to Spin Up",0 +szPressToEject db "Press to Eject",0 +szPressToProceed db "Press to Proceed",0 + +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ RTF Sub Files ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + +szInstructions db "instruct",0 +szNoASPI db "noaspi",0 +szASPITrouble db "trouble",0 +szPPAVersion db "ppaver",0 +szDefectList db "defect",0 +szLocked db "locked",0 +szNoSpares db "nospares",0 +szOutOfSpares db "outofspares",0 +szFewSpares db "fewspares",0 +szNotRunning db "notrunning",0 +szRunning db "running",0 +szInterrupted db "interrupted",0 +szPerfectResult db "perfectresult",0 +szExplainResult db "explainresult",0 +szBadResult db "badresult",0 +szIomegaQuote db "iomegaquote",0 +CloseCurly db "}" + +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Cartridge Status Text ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + +CartStatStrings dd szUnknownStat, szAtSpeedStat, szSpinningUp + dd szNotPresent, szSpunDown, szStalledStat + dd szZtrackFailure, szDiskLocked, szLowSpares + dd szTestUnderway, szTestFailure + ;-------------------------------------------------------------------------- +szUnknownStat db "Ejecting Cartridge",0 +szAtSpeedStat db "Ready to Test",0 +szSpinningUp db "Spinning Up",0 +szNotPresent db "Awaiting Cartridge",0 +szSpunDown db "Not Spinning",0 +szStalledStat db "Stalled Error",0 +szZtrackFailure db "Z-Tracks Failure !!",0 +szDiskLocked db "Disk Protected",0 +szLowSpares db "Low Spares Count",0 +szTestUnderway db "Testing Drive " +DriveUnderTest db "X: ...",0 +szTestFailure db "Testing Failed",0 +szNoIomegaDrives db "No Iomega Drives",0 + +;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ +ErrorTypeTest Label Byte +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +errcode 000000, "-- None So Far --" +;-------------------------------------------------------------------------- +errcode 1C0000, "Missing Defect List" + +errcode 0C0101, "Wrote with Realloc" +errcode 0C8001, "Wrote with Retries" +errcode 0C8101, "Wrote with Off Track" +errcode 0C8201, "Wrote w/o SectorMark" +errcode 0C8301, "Wrote with ID skip" +errcode 170101, "Read with Retries" +errcode 170601, "Retried & Realloc" +errcode 180001, "Data Corrected" +errcode 180101, "ECC & Retries" +errcode 180201, "ECC & Realloc'd" +errcode 1C8F01, "Defect List Recvr'd" + +errcode 040002, "Drive Not Ready" +errcode 040102, "Drive Going Ready" +errcode 040202, "Drive Not Ready #2" +errcode 040302, "Drive Needs Help" +errcode 040402, "Not Rdy - Formating" +errcode 300002, "Incompatible Media" +errcode 3A0002, "Media Not Present" + +errcode 010003, "Missing Sector Mark" +errcode 030003, "Off Track Write" +errcode 100003, "Bad ID Checksum" +errcode 110003, "Unrecovered Read" +errcode 118003, "Unrecovered Read" +errcode 120003, "MissingID Sync" +errcode 130003, "Missing Addr Mark" +errcode 140003, "Sector Not Found" +errcode 160003, "Sync Mark Missing" +errcode 1C0003, "Defect List Error" +errcode 310003, "Corrupt Media Format" +errcode 310103, "Format Command Fail" +; errcode31xx03, " -- failures --" +errcode 320003, "No Spare Sectors" ; abort on this +errcode 328F03, "No Spare Tracks" ; abort on this + +errcode 018104, "Missing Sector Pulse" +errcode 090004, "Track Follow Error" +errcode 150004, "Head Seek Failure" +errcode 220004, "Cartridge Sense Fail" +; errcode 40xx04, "Self Test Failed" +errcode 470004, "Data Parity Error" +; errcode xx0004, "Vendor Specific Error" + +errcode 290006, "I/O Bus Reset Error" + +errcode 88010B, "Reassigned Blk Err" +errcode 88020B, "Side Switch Error" +errcode 0FFFFE6, "Buffer Too Big" +;-------------------------------------------------------------------------- +errcode 0FFFFFFFF, "-- Unknown Error --" +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + +szNoXferLenText db "This system's ASPI manager has returned a ZERO",CR,LF + db "LENGTH transfer buffer length. Please let Steve",CR,LF + db "know by sending him eMail at: steve@grc.com",0 +szNoXferLenTitle db "ASPI Manager Problem ...",0 + +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Main Window Controls Text ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +; INTRO_PAGE +;-------------------------------------------------------------------------- +szIntroTitle db "Trouble In Paradise",0 + +szIntroSubTitle db "FREEWARE by Steve Gibson,",CR + db "Gibson Research Corporation",CR + db "http://grc.com ( v 2.1b )",0 + +szIntroText db "This freeware utility determines whether an Iomega Zip " + db "or Jaz drive is prone to developing the dreaded " + db " 'Click Of Death' (COD) syndrome.",CR + db "My research into the maintenance, repair and data " + db "recovery of Iomega's removable " + db "media mass storage products led to this capability.",CR + db "(Please see my web site for more information.)" + db 0 + +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +; SELECT_DRIVE_PAGE +;---------------------------------------------------------------------------- +szSelectDrive db "Drive Selection",0 + +szSelectionHelp db "This system contains more than one Iomega drive " + db "that can be tested with this program, but only " + db "one drive may be tested at a time." + db CR,CR + db "You may change the drive being tested at any time, " + db "whenever drive testing is not underway, but only " + db "ONE drive should have a cartridge inserted at any " + db "time. If a second cartridge is inserted into a " + db "second drive, this program will assume that you " + db "wish to switch to testing that new drive, so the " + db "previous drive's cartridge will be ejected." + db CR,CR + db "To insure that only the proper drive and/or " + db "cartridge are tested, ALL cartridges inserted into " + db "Iomega drives were ejected when this program was " + db "started.",0 + + +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +; PERFORM_TEST_PAGE +;-------------------------------------------------------------------------- +TestBlackText dw 250, 2 + db "Data Read",0 + dw 350, 2 + db "Patt Write",0 + dw 250, 18 + db "Data Write",0 + dw 350, 18 + db "Patt Read",0 + dw 11, 39 + db "0%",0 + dw 377, 39 + db "100%",0 + dw 11, 77 + db "0",0 + dw 377, 77 + db "100%",0 + dw 22, 154 + db "Sectors",0 + dw 10, 171 + db "Last Error",0 + dw 17, 188 + db "Elapsed",0 + dw 13, 205 + db "Time Left",0 + dw 278, 154 + db "Soft Errors",0 + dw 275, 171 + db "Firm Errors",0 + dw 272, 188 + db "Hard Errors",0 + dw 271, 205 + db "Total Errors",0 + dw 0 + +TestGrayText dw 155, 39 + db "Testing Progress",0 + dw 129, 77 + db "Spare Sectors Consumed",0 + dw 61, 135 + db "Testing Location",0 + dw 219, 135 + db "Sound",0 + dw 297, 135 + db "Error Summary",0 + dw 0 + +szQuestionMark db "?",0 + +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +; EXPLAIN_RESULTS_PAGE +;-------------------------------------------------------------------------- +szExplainResults db "Explain Results",0 + +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +; CREDITS_PAGE +;-------------------------------------------------------------------------- +szPage_4_Title db "My Kind of Software ...",0 + +szPage_4_Text db "This program was hand crafted -- byte by byte -- in " + db "100% pure 32-bit Intel assembly language. It " + db "is just one .EXE file that runs under " + db "any 32-bit Microsoft Windows operating environment. " + db " (Win 95/98 and NT) It " + db "requires no messy setup or installation procedure, " + db "and it consumes NOT ONE SINGLE BYTE more memory " + db "than is absolutely necessary.",CR + db CR + db "This is the way I write my programs -- all of my " + db "programs -- whether they are free or for purchase, " + db "because it's the BEST WAY to do it. It's about " + db "creating the best programs possible. And " + db "that matters to me.",CR + db CR + db "I believe it matters to you too. " + db "I welcome your judgment.",0 + +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +;/////////////////////////////////// END //////////////////////////////////// +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ diff --git a/x86-asm-source/TIP.ncb b/x86-asm-source/TIP.ncb new file mode 100644 index 0000000000000000000000000000000000000000..90f9d523d5620761955492dc67459e3d2d6bb53b GIT binary patch literal 33792 zcmeI*F>ljA6u|M9s1&G*Dv}gJF^!oRDo7e6B<6w;AS8s4SaBLRiqyoFlXmV$pb{T| zfe*mI2k5|zGC=1Jz*-OtOfB!lR|sOFh00d{CtY7+%g*`doX@$l-3RT(IO;`9eSe|4 zFgNF~#8E2_I({?g2aTW?`t@tI+L?)&dv`=+Oe80lrKvA#v-NyMBMAWnvMlgve2;_x z0tg_000IagfB*srAbT>w&eKNoL`0hjhs{f?jy+E?xgZK0Kw;G>r%@6C}ii_(S@9Xqu8m*SS&}g;rm5ZA$4qV*USdp_**7|!vrsbT> z$j_q#^2q17kf#Ly|V=)8}KmY**5Xh#0^|;giXLH|C zY6K1|u)DLnW5)m+O_M)I@%6`~RP7w6(r;@wG-9|9_*=juG!P+6ll17r(hU_9dBK(pb=u|MGC` zzbK{Qbv(KN2>}FBC&2Ij)a?=qga85vAb`Ms7qIr9ga87^Q-J$_j^}=7s}V4P{ri9H g|9Stb`+o{D>#qN`{y(n&<(q~80tg_0K-vU;0FDpe$p8QV literal 0 HcmV?d00001 diff --git a/x86-asm-source/Tip.opt b/x86-asm-source/Tip.opt new file mode 100644 index 0000000000000000000000000000000000000000..433c0445f814f27010fe7b5214317325d39a7184 GIT binary patch literal 48640 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 literal 0 HcmV?d00001 diff --git a/x86-asm-source/font.obj b/x86-asm-source/font.obj new file mode 100644 index 0000000000000000000000000000000000000000..68d4de1104ea79c839427e7a27f0a3c389d75619 GIT binary patch literal 1133 zcmeZaWM)WLu(Mvm%)r3K00DX>sTCzqHZDqmAs|67C9xzCmjbA`14F<8y&_bF5Ge1MJ0IZxeDvpjLA|ez3=Xwt4(_l2 z|8&c9_WE6?*qL8*TO7K4c-cYsieEQNrab$XoOQjqq4Jn`iGlxvz)c;KI{PaR^-s#3 z()0K1rfu!rx^r=H7wjT>wpPmvCsC3sXe)IjM|xXZns6L$q~Dl28Xrkv~Ov6Vco zes$)Nbm^H!%9F|&{u}VHGfqsA=cqnr+*SFe@3HwjoXo6{=k6E^8=ZR1X%xFOK;(jadBGI z_EAvCSb$URyRp+TrbUX28ax7)9D2?n>E7(gyHxqd#rQ2fe_c)=@i)nMsT`&Duwlc; znH3#ut7Ki6f>>W1Z;PA1Q8N61r2MY`8ItYH1;^6g=tmu^Ta)57(9LN$jD|Jc0# zq58Z(pE>If9sXA=`mfNRIdC3B@hVRCKQ9$d2^Z8c`N)1qzr_2L)5f0hxXtCZmCgs< zYnRP*t+P6z_gVP;m&#wx?9O1$!Kcv!DCLovo5Xk`7v zibwt5TIScJRX6(=1=cb3e`AsP{$+B)#T)AXRdzmC|D$4<{*>gJbI!J zndSd~nV=9WZ+PCqsH%-m=*MKPt<5a&mewRHeEc%K=GncM!48jRN`*PhTHny3cxeIe z5nIONKlW_jUM#khZlC({r0dvetXbv#>Qw0`-H=_1oa_9q|V zFwlK&|FzUBTD7;v+hyjl_x6IRN{3xOt^7Xeq`H##p_MLLh7(T57fG&PZ=oSLxv(w7 zP%^zhc(SKWMK9~t&I`g1R09ndql8%(H=K$Hm@xZz;|GqNYE50NQnIdMeJS6M7(I{& zW(U2r%$!tce);#GfgznSEkCbBFR?fmk%=6V^K%RIGE@F22r>Kzs$ph8&c%#Ch0GuV y4It-WCZHTvHAuM^lsTChLHQRGut0@Cl1vPuKr-G9=uD@~lH9}s&)mfHR0aS^wwcfX literal 0 HcmV?d00001 diff --git a/x86-asm-source/green.bmp b/x86-asm-source/green.bmp new file mode 100644 index 0000000000000000000000000000000000000000..cf34ee6ef3087025a74fa1b05a689993e6b13cf6 GIT binary patch literal 206 zcmYj}I|{@w3`8do2xKAT7<-QN+vgarR;`bcT8*z@*gj|3&X7hK*)Ae$=ILX5`sbt*l)wBEUq94Rn^sIg`GynlST<;_(qp#EJw!Oj99)s-_2L_WB3r Ubah%~P(FCv6X-Fq7s2HJ-6M!Tm;e9( literal 0 HcmV?d00001 diff --git a/x86-asm-source/instruct.asm b/x86-asm-source/instruct.asm new file mode 100644 index 0000000..c31a2f8 --- /dev/null +++ b/x86-asm-source/instruct.asm @@ -0,0 +1,36 @@ +.586 +.model flat, stdcall +option casemap:none +option expr32 +;------------------------------------------------------------------------------- +; Compressing non-bitmap binary data. + +;------------------------------------------------------------------------------- +EXTERNDEF InstructData:DWORD + + .const +.RADIX 16 +;------------------------------------------------------------------------------- +InstructData LABEL DWORD + +dd 000000655 ; 1621 original size +dd 00000030C ; 780 compressed size +dd 008200401, 093429AC2, 0A863B080, 06DD30816, 02E770D1A, 0E06261C5, 0A6906EE0, 034C28A1B, 0A6946E3F, 0EAAA5BC2, 0FD9ED991, 0CD6C6DE2, 0A02301A2, 0A1D5D6F7, 0D3793A69, 08E2832DB +dd 0CE0ADAA6, 0332380FA, 071BBB375, 0496DC64A, 02436C81A, 036A7335E, 09E6C9762, 095ED9165, 09EF0D9E7, 000FAFF33, 0F5E2223D, 0AEBEAC67, 06825DFDD, 0750197D3, 076D8DB3B, 00B8DB2B3 +dd 08245A68C, 029A91E83, 0AB15EEAE, 0B9634AB8, 0095462B9, 023B2F62E, 0083A612D, 0FDB18C83, 0BAA32CA6, 076B5858B, 01E9B2C20, 09C19858C, 0F7499017, 0AD94ED69, 093455C16, 06FA58A19 +dd 03FDCA111, 098FA53D6, 0888C093E, 083D74B5D, 02DF1CBA6, 06965E90B, 0D911907F, 0BF72F8AC, 06DEC108C, 0BA36CAAE, 0FA1C985F, 0B56D14F6, 0B67F94A9, 0540D476A, 007117863, 0F3102451 +dd 0E5C9173D, 01E025988, 0B78B85D4, 035B4DE7C, 0AEC88B77, 0678F882F, 0FCB49EA9, 086439AA9, 0BCB295BD, 02EA8FB94, 0F0336561, 09938B996, 05B5B2FD9, 00A5EC337, 0258C771B, 05BB778BD +dd 08EB9AA25, 02C5C5E2A, 023A6849C, 031ADE8FC, 07F60B75D, 0187541E1, 0BC1BD408, 0CE45A002, 0A9162205, 00731057D, 059AE9EA4, 0F8394E10, 078A0C445, 06C24B386, 06E64470F, 0970BC106 +dd 0C70F42C8, 021632EAF, 08A18585A, 0F84AAE09, 03C6F309C, 02D281AFC, 036B045F6, 00EB241BB, 09C2E61C1, 0396E8137, 046B3DE78, 0E2820585, 0BE5EB040, 0CBCF8D42, 055935ED1, 057ADAF5C +dd 0CBEA618E, 0C0D6B1E9, 0BCF5C558, 0BAB69346, 02D3C2E31, 01B68D6C9, 0E3AB4F22, 0774366D7, 0E7ADA754, 08F527312, 0801797B3, 0088C578A, 0ECD5EA93, 03C036AA7, 0D1DB057F, 0D083A395 +dd 0B423785E, 091954881, 0CEB253D1, 0605751F7, 01766C3AC, 020D85AF5, 0025909EE, 0E4458224, 0D6E30EAC, 048EA4A8E, 015CE55BD, 04E569F36, 056C38724, 0E0F639F6, 0F507CC69, 0E15A96C6 +dd 05D4AF9C0, 068DC21AF, 0AA561E48, 0365D3EEF, 0E9622A59, 0A194DA45, 02479E793, 00816B3B2, 0939FC25B, 0E61DEE6B, 01968BE42, 085436172, 04EBC1BAF, 0E57F44AB, 0699E30CD, 09F373F81 +dd 0FAFC2BEA, 074A6070F, 0D54AF07B, 0C1AADC07, 0D561EA7E, 0018DE213, 08026D35B, 00B168220, 0DAA072D0, 0824E3AF1, 064841B31, 080A16932, 037A1B760, 05B5EDE13, 04590A875, 08306BA9E +dd 0436ED2E3, 0AE83CE17, 085AE924C, 0FCDCA4F4, 0B6810D8A, 00A2374B2, 0415C0609, 057F188C6, 02D840302, 0B5704B0F, 040FE0EA9, 0C50A7E2D, 06700F36B, 01A32BDBA, 096B26342, 0260AD179 +dd 09110D6ED, 0B6F400D9, 07F80C907 +dd 061696465 + +;------------------------------------------------------------------------------- +.RADIX 10 + +END ; end of the file diff --git a/x86-asm-source/locked.asm b/x86-asm-source/locked.asm new file mode 100644 index 0000000..9c1bd58 --- /dev/null +++ b/x86-asm-source/locked.asm @@ -0,0 +1,29 @@ +.586 +.model flat, stdcall +option casemap:none +option expr32 +;------------------------------------------------------------------------------- +; Compressing non-bitmap binary data. + +;------------------------------------------------------------------------------- +EXTERNDEF LockedRtf:DWORD + + .const +.RADIX 16 +;------------------------------------------------------------------------------- +LockedRtf LABEL DWORD + +dd 000000317 ; 791 original size +dd 0000001A9 ; 425 compressed size +dd 008200401, 093429AC2, 0A863B080, 06DD30816, 02E770D1A, 0E06261C5, 0A6906EE0, 034C28A1B, 0A6946E3F, 0EAAA5BC2, 0FD9ED991, 0CD6C6DE2, 0A02301A2, 0A1D5D6F7, 0D3793A69, 08E2832DB +dd 0CE0ADAA6, 0332380FA, 071BBB375, 0496DC64A, 02436C81A, 036A7335E, 09E6C9762, 095ED9165, 09EF0D9E7, 000FAFF33, 0F5E2223D, 0AEBEAC67, 06825DFDD, 0750197D3, 076D8DB3B, 00B8DB2B3 +dd 08245A68C, 0F4DB1E83, 0B9A7634C, 02E09541A, 02D200AF6, 083083A55, 0A6FDB18C, 0867AA32C, 0CBCEB585, 0BC14B289, 0A5947D68, 0FEDAA742, 020675F33, 03FB3C4AC, 097A98F8B, 0BAD1F0C0 +dd 0816323EE, 0CF37705F, 052655D58, 052FA242F, 0297EC875, 02DCDF43A, 05F87BA1D, 08F42CA01, 0CBAF725F, 0AC986C3A, 0EB167043, 05FD48C56, 09E2AACB2, 0D92A9769, 04F43DB30, 0E93BA05B +dd 089A6A1F2, 0DEA5E2FF, 02E31998E, 040C764E0, 0891AE5D3, 0BC6A8AB1, 0837293CB, 0DEB7011B, 0DF9EB0EB, 0740BCC9F, 036754DB2, 0E5CC7CB0, 03AE36E01, 0F8DF814D, 08ED5EAB3, 05C01D6AD +dd 06F309D7B, 058C76CA2, 0C3F0DD4B, 0352E1A96, 06E7BCF0D, 06051D555, 06EBE9C6F, 07112D3ED, 05CFDE126, 0FE6E48F7, 00BEBCB5D, 0EB2982BF, 00EA4AAF7, 0B2C5FA71, 084030242, 05AAB0F2D +dd 0C441EF84, 06A77E122, 0EA407310, 04815AADB, 042B6B85F, 0490B0E58, 06BA45636, 06C675DA4, 0D92C8BC7, 001920AC9, 00A0D2EFF + +;------------------------------------------------------------------------------- +.RADIX 10 + +END ; end of the file diff --git a/x86-asm-source/nospares.asm b/x86-asm-source/nospares.asm new file mode 100644 index 0000000..c7dbfc1 --- /dev/null +++ b/x86-asm-source/nospares.asm @@ -0,0 +1,43 @@ +.586 +.model flat, stdcall +option casemap:none +option expr32 +;------------------------------------------------------------------------------- +; Compressing non-bitmap binary data. + +;------------------------------------------------------------------------------- +EXTERNDEF NoSparesRtf:DWORD + + .const +.RADIX 16 +;------------------------------------------------------------------------------- +NoSparesRtf LABEL DWORD + +dd 000000B82 ; 2946 original size +dd 0000004F0 ; 1264 compressed size +dd 008200601, 093429AC2, 0A863B080, 06DD30816, 02E770D1A, 081898714, 09A41BB83, 0D30A286E, 06946C8FC, 0AAA5BC2A, 0D9ED991E, 0D6C6DD9F, 002301A2C, 01D5B5F7A, 03793A69A, 0E2832DBD +dd 0E0ADAA68, 032380FAC, 00EFB3753, 04B6F8CA7, 021B640D2, 075399AF1, 07B6CBB0C, 057B64596, 07BC3679E, 00FACFCCE, 05E2223D0, 0EBEAC67F, 0825F7BDA, 050197D36, 06D8DB3B7, 0B8DB2B37 +dd 0249668C0, 0A691E838, 0B87F3EE2, 0D934AB8A, 02A8C5731, 0765EC5C1, 0074C25A4, 0B6319061, 0D46594DF, 0D6B0B0DA, 01652E96E, 08FAD179F, 054E884B2, 07D667FDB, 0CEDDFEBF, 0826F2EA7 +dd 015E418B5, 0B65941B5, 0C0905A62, 05EAED1F0, 079268320, 05F4F2B6B, 02DDB084D, 0B473D251, 051C50A4A, 01926F13E, 06AD863B9, 0C4FD4069, 04336A93A, 0B6BF4759, 06B2EB9BA, 0B3E677F7 +dd 03A191655, 08AD97979, 036F3826D, 0A259F5F8, 0D2F1D25B, 0318327FE, 02D44E045, 047C61B6D, 087546816, 0C67D4081, 0C8B43A0C, 0916220D7, 01E7EB3BC, 0D6901CC4, 0F2652C5C, 0C43F9537 +dd 035725AD5, 0F36E4B43, 00B58ADEB, 0E712F981, 03A3F0962, 0758BF11B, 00B29E0FD, 0508A3BCB, 0846E6C8E, 0FBACFD34, 077E41FA7, 0AF8E6935, 049EC24AA, 0CBC6075F, 0D7EF405E, 0312F2B6B +dd 039F8FA83, 07A98F9F4, 0FAB537E1, 09574E75B, 0386AC10D, 0D84E082B, 01D6F8F7B, 0F530BACE, 0E6AFE18D, 0444B1846, 07B40FE37, 070029FAE, 0ACB3D264, 099E38FCE, 0459D634B, 0E08802E6 +dd 04D682F85, 0A9B41B05, 0AB06F14E, 06D097424, 0D43B21C2, 038CB67C7, 0C211C90F, 096372F1B, 0BEDD3EA3, 08BB0704D, 0FA719467, 05A5770F4, 04D3FEB1C, 06205E4D9, 0DC6F1453, 0C698723C +dd 0B8C4BB04, 0E2B8A2FE, 098AC1572, 0C3CDCFFE, 02EAE9A6F, 01337E30B, 09D477815, 0C08F8D68, 04D0CF2AF, 0D2E99D8B, 093A88BE2, 04B2CC853, 0B2E1FEA5, 03CA339CC, 0AEDAB92D, 04DB579F0 +dd 0C77E3CDA, 0FD60E648, 018415B49, 0D4AB7D13, 01B4F4125, 0E6BB8EEC, 0940D59D7, 024C2E5BE, 080640F57, 06A6D9863, 0A8F1EB8B, 078DEBF9D, 0E1CD4B87, 032A86F56, 065C56139, 0B6928C63 +dd 006C895B4, 0699BB117, 008A3AE32, 07B5CC4B6, 00CFCD265, 07EF53FAD, 05DE384BA, 0AEF358A9, 0507C4F7A, 0D0B7916E, 05672DE8E, 093F19423, 0BC89B65F, 0ED8A6565, 08E5755B4, 0379CCB71 +dd 0EA3648C2, 057689842, 0F44E2EE7, 0D97E1F9E, 02BF42630, 03F0EFEE4, 01B5B2447, 0B4F5790B, 07C64AC0D, 0C9B104E9, 0A272AA8F, 09906CC27, 0A3B5237C, 04DBB1DAB, 051723625, 0BB733162 +dd 0575D6EAB, 076804423, 0C59D505B, 0A636AADD, 029CB806F, 01F8DD349, 049931E29, 090DFA1E5, 015BF523D, 0D248FAB8, 090E6AA74, 0DEB5FEC7, 03A72FAB4, 023DE3A7C, 042FC76BD, 04774B127 +dd 023DDE271, 0F638426A, 02C6CF595, 0B4042A7A, 02DEA1528, 0E0849B86, 05E73B298, 0D7E2ADDD, 0E964FF50, 0A4C25651, 02BE46D4F, 0EF4E4DD3, 061C59522, 09628EF91, 07FAF7C33, 0CFFD588D +dd 0B592DAE7, 01157EFC7, 00BF47F0E, 070BBA165, 0EFFE3386, 0C2020A44, 086A8C9BD, 0119EE315, 0E1684342, 0CB3E78D9, 0CF42FC2A, 0D55ADCA0, 0EDC5B66E, 0A6B6A576, 0937AE224, 078A8409B +dd 0A0246EF1, 00C9B7225, 02CC608F0, 0EE49715B, 0D67593C2, 064013A1A, 0179EC370, 04D38C6A5, 0A2D26CF7, 0DECB58E5, 0EDD4D7CB, 04C7775C1, 0E3DDFABB, 028595571, 0AF11E6B4, 0A2D3B1FB +dd 00C0D4188, 0A4A23573, 0CB914C74, 0211683E3, 06978E365, 081B37AE3, 01A35BE38, 0FD6AC6F2, 04CF5E22F, 0613CF02E, 0A4CA5D7A, 0169D930D, 0FB782B9E, 0AB6F38EA, 01453CD03, 0260D0485 +dd 08582EA4C, 08846DCF7, 05CE9588E, 095A92728, 085F13F6B, 0BD5D9E3D, 0F19B6EDA, 0463B4DE8, 0853933E5, 0EF6DA825, 09CD689CF, 037FFD4B4, 008CA85FA, 05028C137, 0676F954B, 06BE3437E +dd 0BFCD39B1, 054C7411D, 0BAB7A8FF, 0E1C601DE, 0CCCFA534, 0BE32A871, 0E9CE6624, 0DC56911E, 04B185C79, 0362FACF0, 0E829F109, 0D6B2696A, 06B305939, 0FE13D60B, 061BECE85, 039725783 +dd 01222F451, 000C094FE, 0AAC3CB61, 0F90FE125, 0D8C94FC2, 039A2A128, 069F97B74, 013893108, 0E4138B2D, 008823B6E, 0058F4E94, 01FE03241 +dd 075736E6F + +;------------------------------------------------------------------------------- +.RADIX 10 + +END ; end of the file diff --git a/x86-asm-source/outofspares.asm b/x86-asm-source/outofspares.asm new file mode 100644 index 0000000..f8d184a --- /dev/null +++ b/x86-asm-source/outofspares.asm @@ -0,0 +1,43 @@ +.586 +.model flat, stdcall +option casemap:none +option expr32 +;------------------------------------------------------------------------------- +; Compressing non-bitmap binary data. + +;------------------------------------------------------------------------------- +EXTERNDEF OutOfSparesRtf:DWORD + + .const +.RADIX 16 +;------------------------------------------------------------------------------- +OutOfSparesRtf LABEL DWORD + +dd 000000B96 ; 2966 original size +dd 000000507 ; 1287 compressed size +dd 008200601, 093429AC2, 0A863B080, 06DD30816, 02E770D1A, 081898714, 09A41BB83, 0D30A286E, 06946C8FC, 0AAA5BC2A, 0D9ED991E, 0D6C6DD9F, 002301A2C, 01D5B5F7A, 03793A69A, 0E2832DBD +dd 0E0ADAA68, 032380FAC, 00EFB3753, 04B6F8CA7, 021B640D2, 075399AF1, 07B6CBB0C, 057B64596, 07BC3679E, 00FACFCCE, 05E2223D0, 0EBEAC67F, 0825F7BDA, 050197D36, 06D8DB3B7, 0B8DB2B37 +dd 0249668C0, 0A691E838, 0B87F3EE2, 0D934AB8A, 02A8C5731, 0765EC5C1, 0074C25A4, 0B6319061, 0D46594DF, 0D6B0B0DA, 01652E96E, 08FAD179F, 054E884B2, 0F773F61B, 06479FB53, 073634B28 +dd 09B081C50, 047A69B11, 0AEEB777D, 0A2F2802F, 0CDF283A5, 074C7D37D, 0A3E18123, 00656BD5D, 0572EF24D, 0DEFCBE8D, 03D270ACB, 0A1442B73, 0DE27CA38, 07CD1233C, 012ED4069, 0AFC12ED4 +dd 00BAE6EAD, 0BE60EA65, 0D0C8B286, 056CBCBC9, 0B79C136C, 0AC8FAFC1, 04BC7496E, 0C6BC9FFB, 0B5138114, 01F186DB4, 00EA42E61, 0E9AA8103, 0168741B2, 02C441AF9, 0CFD67792, 0D2039883 +dd 04CA58B9A, 087F2A6FE, 0AE4B5AB8, 06DC96866, 06B15BD7E, 0E25F3021, 0FF612C5C, 0D62FDD65, 03CA783F5, 0F8FFF732, 023736472, 0DD67E9A4, 0BFD0FD3F, 07C7349AB, 04F612555, 05E303AFA +dd 00F7A02F6, 089795B58, 0CFC7D419, 0D4C7CFA1, 0D5A9BF0B, 0ABA73ADF, 0C356086C, 0C2704159, 0EB7C7BDE, 0A985D670, 0357F0C6F, 02258C237, 0DA07F1BA, 08014FD73, 0659E9323, 0CF1C7E75 +dd 02CEB1A5C, 004401732, 06B417C2F, 04DA0D82A, 058378A75, 0684BA125, 0A1D90E13, 0C65B3E3E, 0108E4879, 0B1B978DE, 0F6E9F51C, 05D83826D, 0D38CA33C, 0D2BB87A7, 069FF58E2, 0102F26CA +dd 0E378A29B, 034C394A6, 0C625DAE6, 015C517F5, 0C560AB97, 01E6E7FF4, 07574D37E, 099BF1859, 0EA3BC0A8, 0047C6B44, 06867957E, 0974CEC5A, 09D445F16, 05966429C, 0970FF52A, 0E519CE65 +dd 076D5C969, 06DABCF85, 03BF1E6D2, 0EB073246, 0820ADA4F, 05BEACBA5, 07A092EA5, 0DC7760DA, 06ACEBF35, 0172DF4CC, 0207AB926, 06CC31C03, 08F5C5B53, 0F5FCED47, 06A5C3BC6, 0AAFAB70E +dd 0365EF11F, 0ACF4B946, 0432DAAC5, 0B7BDAADA, 0F7FEAF75, 040FCE37E, 0CF93F379, 09AA9D3B5, 0D23F6E43, 0B9747F6F, 0F51DF9C3, 0CBEF397A, 0E35B6DF9, 0B92746B8, 02FCF57FE, 0AB89AFD1 +dd 0592DB55E, 0A3A9A15F, 06EAAD764, 057E1DF55, 0B7328320, 0D9DEF6C5, 01DADACC2, 055FC1C63, 07C6AF9C4, 0FFEAA30E, 0320D95C8, 0436326F9, 0ECC9FC8B, 0861CD1A4, 023B95912, 01FE27446 +dd 0846CD917, 028D67935, 0EDA3447F, 0A947E1B8, 0CD900C60, 0507970E2, 0816DA0F9, 0BBAA1508, 09AB27639, 073D4CCD4, 00906EABB, 054F69815, 06DCCC6CA, 0B79BDD0D, 012E5DB87, 0E3A16518 +dd 0A890D245, 014570889, 00565CB38, 017440D9D, 03E2D0101, 091A893C9, 070424DFC, 03E61D94C, 0CD85F429, 0F89EAFC1, 0732E5C93, 058C2083C, 05EC57EB9, 0D2859598, 096323F22, 07FBD8233 +dd 0CE3F588D, 0BB20F7E7, 0F0E1EEF3, 07451A0C7, 0CE0842ED, 0514BE555, 0D0C10FFC, 0CE6A8DE1, 09F1A3631, 0E1684F1D, 04EF178D9, 0673D6942, 0905F0954, 0F3F5B554, 077162DB9, 0525F1BCF +dd 085E208F1, 05B912D07, 055CCF9C6, 09E3BB277, 02E399594, 0B2785DC9, 0932462CE, 061B83200, 063528B43, 0119E269C, 0B58E5A2C, 0ED7CBDEC, 0775C1ED8, 0E276FC57, 0285CED71, 0D7A8F6B4 +dd 05169D8FD, 08606AF24, 09D511AB9, 083E3CB83, 0C3652116, 0F5C6D2B1, 05AB174E6, 0637D277C, 0F117FEB5, 07817267A, 02EBD309E, 09986D265, 015CF0B4C, 0A5BCCDBC, 0A0756DFE, 090A28A79 +dd 04984C1A0, 09EF0B05D, 011D108DB, 0E50B9D2B, 0E6552924, 0FF024A6C, 0C66DBB6A, 018ED37A3, 014E69055, 04950F966, 015A2C336, 0B2BB4D66, 0735A5B3D, 08F9992A6, 011951E5E, 0680B8216 +dd 0B7D275AB, 0DFAA8C0D, 09DB3633F, 06F67F17F, 0E9EF6805, 0E246525D, 02863FE26, 0CD897879, 0B3AF339C, 02F69ECB6, 05C0AF8F0, 061B256E1, 02153215D, 02D202536, 066F1E74B, 06859EFAC +dd 053E3726C, 0435999DB, 08CB13BAD, 03C0B69DA, 0B0D526A3, 0DAB92BC1, 0091D1228, 080604BBF, 0D561E5B0, 00C87F1CA, 070E4A7E2, 01CD144A4, 081DE7DBA, 0D1769310, 0EF6138B2, 03A55E3B6 +dd 00D2C7A77, 061FF0192 + +;------------------------------------------------------------------------------- +.RADIX 10 + +END ; end of the file diff --git a/x86-asm-source/red.bmp b/x86-asm-source/red.bmp new file mode 100644 index 0000000000000000000000000000000000000000..5bbc4a2c1fd3b6453d986189b135c6d9cae3032d GIT binary patch literal 206 zcmYj}I}U^}3`7SB389q`$JlewZ_hDOt=k-d)>W<&X?xDHT|{NZNeUd#Jb#jGpA#*< z#G86`4H)ZUr~j6wm9?uy1el1ifzA>+XVMo|6J}mfJU*g{SdjpTX)0t;)%4)ZUjM+H Uu1>2A$_I~o0zD@7BAEQY8_NAWuK)l5 literal 0 HcmV?d00001 diff --git a/x86-asm-source/rtf.asm b/x86-asm-source/rtf.asm new file mode 100644 index 0000000..691de60 --- /dev/null +++ b/x86-asm-source/rtf.asm @@ -0,0 +1,359 @@ +.586 +.model flat, stdcall +option casemap:none +option expr32 +;------------------------------------------------------------------------------- +; Compressing non-bitmap binary data. + +;------------------------------------------------------------------------------- +EXTERNDEF RTF_Data:DWORD + + .const +.RADIX 16 +;------------------------------------------------------------------------------- +RTF_Data LABEL DWORD + +dd 00000E74F ; 59215 original size +dd 000005405 ; 21509 compressed size +dd 008200601, 093429AC2, 0A863B080, 048304F56, 0260E0954, 06DD30816, 02E770D1A, 00A6D8DCC, 01D7B1B17, 028A1BA68, 01B23F34C, 096F0A9A0, 0D24B6EAA, 0C5E38640, 0C098E59A, 06C7DE808 +dd 07D646815, 0CFA3344D, 0CBA45E24, 0E7ACDE1B, 087FDF0D9, 0E6586BB3, 0A38A0C36, 086B2B6A9, 0A664706C, 0FBB1DF5E, 02B08E62D, 05AF4CDAE, 07D670302, 021D6FD60, 0DEF7B9DB, 04E442CF0 +dd 096C6638F, 0C6E39E91, 088F40416, 0B186D788, 0D9ED741C, 08408C0F2, 080BE9B35, 0753083A3, 07058DB7B, 0B8DB2937, 0B31B853D, 0A788C3F4, 0CEBCAB79, 098ADB45D, 02206D2AE, 06260E2BC +dd 0FC86A386, 00F1791BA, 0561610C2, 0A0CB0478, 0CCB08163, 00B48B058, 00D86BD3E, 0DA43CB07, 01B68AAA8, 0AF9D4055, 0C81DF6BF, 0AE64EB18, 0D6B117C6, 0035B0C13, 0D26405E7, 0CA18EFB3 +dd 02B6D0656, 0BA58A3B2, 03B6349F1, 0A7339CBB, 0728C0925, 03DD0EEF3, 041ECBA68, 09DDF7198, 022323C6E, 0DC1BF59B, 0DE16BDBC, 0BD8224AF, 02A10F58D, 00E645FBA, 0B68A7B7D, 03FCA5466 +dd 032F4B52C, 088AEAC1D, 088122883, 0E48B9EF9, 0012CC472, 0E552EA0F, 0C83970A1, 0D2F2E17F, 06B69DC53, 027BEF4F1, 0735522AD, 052B7B0C8, 0FDF305EC, 0D954CBA9, 09A65BC0C, 05EEA599E +dd 02965D688, 02E8DDB2C, 0A968CB44, 05419676C, 0BC549D73, 04C4E03C9, 01B8F72B2, 06D904A59, 0B2D7A193, 024D23197, 03C8A7D52, 05A049E0E, 026EEA2A9, 0AD2496C7, 0DDA5B75F, 0C21B54D5 +dd 038187776, 044B191CB, 03650C956, 0E45BC703, 077A10CD7, 059C5345E, 0496B7414, 0F0F6FA19, 0FC4DA72B, 0F2420F1D, 05BDF4CBA, 019CD2841, 0A5BE629B, 0B78D87F7, 0F7CE1100, 04DC0BCF3 +dd 0853A3F3E, 098F811E2, 04E875722, 0748C6757, 0BBAE613F, 0B27B80A5, 042F68994, 02AB9838F, 0882E0BC8, 066BA56BC, 0594E8F2D, 0086F39DF, 005EA8D91, 0D4EA88EF, 0B36F153B, 09754CB2F +dd 09677530B, 0576444C5, 091E3D65E, 0A4D3E78C, 0E59C1749, 0418DAD6D, 0518734F5, 0BDCCEDBB, 0ED5E1D1F, 02FFFB554, 0CF38E299, 0D981631C, 0DAA00172, 0AD6D0ACF, 06E0A9697, 0437936C3 +dd 007B4EDB4, 03BA1BA7F, 0963D63CB, 034DC1300, 0865533AD, 0F21E2ABC, 082DA75ED, 03A13098E, 0EB22BBFA, 01BE61C10, 06B74F458, 0153299C5, 0A957E12F, 005FAC50F, 06AC8BF6E, 034BB87A7 +dd 0B0F92BA9, 059C5FE4A, 0CB05ED98, 0E25F830E, 0EBBCBF66, 0B5F7F72F, 02D61AA71, 09D874662, 0460C54BE, 0FDDB5DFB, 0A69B54FD, 055B4063A, 0B8459B58, 0AA0AEAF2, 0CD6F2F7D, 0BE28A51C +dd 046B4BE39, 08416295B, 0E1EE808E, 00D61CBA8, 003D60EC6, 0BC72874E, 03EAFA2DE, 05AF37B7E, 013BAE09B, 06960E73D, 0BBE2E0AE, 0264373AF, 060B1A269, 06869C3BF, 091FB148D, 05E4D7EAF +dd 0C5369978, 05BD5F959, 051BCA659, 0C8C2FEAA, 0D8B28332, 0D2DBF717, 0B5F6DE26, 07F6EDE0C, 0BA7912FB, 020AE55C8, 01F15D570, 0BD62A9A6, 09B551057, 08DD4A7DE, 02D64CD2C, 02CFA5DD5 +dd 0363573F5, 0AAD959A0, 093DAA0F6, 05C36BB5C, 082E3841B, 00B17C48E, 0B2E39E78, 0362CF911, 0AB96BF1C, 093C0AFE6, 0B12EE733, 04F0CB202, 0EB4EB770, 0A8AB48D2, 01F155CB4, 0623B6C78 +dd 0A593AB59, 0BDFCE3D0, 0C3AA3F78, 0D15EA040, 0A7AC7117, 0E5854B55, 0C122C441, 09881DCEA, 039585203, 0A3DA0BB7, 05B095E3E, 0EFAB5A64, 06854CBB9, 0EC0A2D2F, 0EC4EE13F, 0F74B71AE +dd 02A3CA5D6, 0477A4FF0, 02DAA9F53, 0E19D822D, 0E991CA2D, 0DE9F3B07, 076258BA5, 09F37C73E, 0282D4DAD, 083743DF8, 09C0D1959, 07B157E74, 0D2306F9D, 07DB87B95, 044D38C15, 0E875DD3D +dd 0E3E9275F, 0E248FA63, 0D041AD23, 077CA605F, 0737B3BF0, 0B5D8A77B, 0F3F39F1E, 0016B0CF3, 0A7B4B290, 059549D4F, 0E75BB023, 05E892EB5, 033A77FE3, 0C656A6DB, 0D85B8298, 04A735F38 +dd 09C811F28, 0D87C9AFE, 03B4BC26A, 07B5EB153, 06335FA5D, 04EE5D5E2, 032AB96D0, 0FF26D3CA, 0291ADEA4, 0DBD646F3, 068DA9D09, 0E457BD3D, 06D45AB8C, 085CF85EF, 00B698AF2, 012F7B90E +dd 00ED2BC05, 09FF8B157, 01DC8FDDC, 0642C6530, 00BE6EE75, 0384BEFE6, 00BFFB7E9, 0985DDFEB, 0DC1506CE, 031F374D4, 09E557075, 077C0ED12, 08E0CCA3B, 0DC578D11, 0D7D7C75D, 070D4E186 +dd 091EFDB0E, 082F6743B, 0CE5C1685, 074F88C49, 0D5196B6A, 04862CC25, 01562C6B5, 009DFFC89, 04D3173D6, 015BA6A95, 0CA0B35E7, 02A56FCC9, 060AE1979, 05544B686, 016FFC9D8, 0F2F3EF70 +dd 0D6719E04, 0C1D25936, 08A9F415F, 01EAD42EE, 0AF9124FF, 054E5D39C, 03C65517E, 0BCD2AA9F, 023DD8864, 0932D94CA, 09749952E, 0618744BB, 0274150D2, 0C1294ADB, 053B80E68, 01F7517B3 +dd 0D52B9CBD, 04A48EFB9, 02F6B8BD2, 06D3D9E31, 01E7BCA9C, 083285597, 090FBB6CF, 0AC7CF190, 08416FF1B, 0FB5015E4, 0B744F668, 076E7C426, 055552316, 02760F527, 07995EF9A, 08ABA2746 +dd 0673E0762, 065A9F53E, 013E50610, 074478C18, 0ADBBCF68, 038EAD9AA, 0F6363E9D, 0450AF7E8, 0413F1BB8, 00D96FBCC, 06F8E1ABE, 024917601, 01E35CE91, 0AFD75342, 0CCEAF5B4, 0EB47B0D4 +dd 0A7F095FF, 026C6EAAB, 022E7D5AC, 0761B3504, 0713F1907, 0877EEEDB, 09CA6ABD7, 09B67D9EC, 06BD72CD5, 03CA5B8E1, 0C4BBDA1C, 0C8A20C2F, 0DA261F55, 0D8EBFF87, 0B94125FD, 042C328D5 +dd 0C3398BAB, 0C843C91F, 01F9B56EE, 00487E7C2, 0F565D5B5, 0C0FBEE2F, 0B4CF0599, 0F14ECD3D, 0DC76B545, 07556FB42, 0D329B998, 0FD6C553C, 0035015DF, 0AD0E875A, 0DFB6A7BD, 0832E1CCC +dd 03CB988F2, 055223A6C, 02D694C81, 012B08C69, 066DD9224, 0BDBDA438, 0F7E99557, 0E58F101F, 036E36299, 0119CB4C3, 0D12F2F9F, 0F7FA7635, 03C54FE86, 0A17AAB91, 0094AD134, 043E6D9A7 +dd 099B249D2, 0A588CE3A, 0C9055A54, 0E949C4E0, 0E9BC777D, 0FFB88C5D, 07BFB72AE, 0CAB9D650, 034D9362A, 03A58B6EF, 02DCF8790, 0B343A3D8, 098666F74, 0B6D19372, 043DA5ADB, 0ABD14894 +dd 031EDB82F, 0AA699FA6, 0EAD337CD, 0A431213B, 0CD94F7E9, 0AAB1750D, 0CF833E7D, 0B7DE1A46, 08CA0BCCD, 017152A13, 09442EE90, 05F7AB7A7, 0392A9D2F, 094AB7A85, 05B787E57, 0CC770F23 +dd 06FD974F4, 0A53D3E98, 07CDF567C, 059AA1882, 0D770A3AA, 017E07644, 061C049E3, 05AD4279D, 0653D365E, 050A64B30, 090405181, 08D198EC9, 0EE79C69C, 05FC8EDA8, 0E7B2704D, 0CDAA7CE6 +dd 03E453EC8, 0AB07B79D, 0C40F1C3C, 0ED82A4B0, 0E2E41440, 09D247D9E, 0AB8F91E1, 0EBE43360, 08D6DB52A, 03BC0785C, 0BA74AB68, 043BAB527, 0C6987C6D, 09A2FF365, 040A9BC3A, 00C9AB6F6 +dd 0637D5DB6, 05D3C9665, 0F13A0C3F, 07FDD57B9, 07A4CBDF1, 057BB8591, 04622309C, 008B515B5, 0C1A9D19D, 0D51A4549, 0F6985A77, 04172AEDB, 00308659D, 0A21FC28A, 039AA27B9, 06710A755 +dd 0BB954A45, 0EE1DDF3B, 01CA353CA, 086719429, 0DAEA4536, 02B50DEF8, 08F7CAEDB, 05DAD0F22, 03E1F19E9, 09F858133, 0F127E0BA, 006EF2759, 0BA0D4E5D, 0CD5D6459, 035023B7C, 0DC6CD415 +dd 08F590774, 041A4AB41, 04B5CD322, 01CB63DB8, 0C73BB70E, 0EF189F1F, 0BD558479, 0B851E911, 0D06CD4AC, 02A26D09F, 069A908D3, 0DA5C0BF3, 0E33DBD36, 0C4B360B9, 02398A13C, 0C6DC018C +dd 039C5A4BC, 0E8CDEBF0, 02B1C631F, 0ECB51402, 0F6DDB94D, 0C6F6F6D6, 0BF12DA78, 0DB4FB690, 051847500, 0C9836CA5, 0103F582A, 0414879DA, 0032DC7A6, 0C3D0D516, 0EF316A3B, 02A02CB33 +dd 05E36B78C, 08D1BD23D, 082AF7B48, 087F4BAF4, 012743D8A, 040BFD5A9, 0619233BB, 016535293, 0CFB84D9A, 05BEA0D9F, 01EACD12C, 0761C0D99, 02519C409, 06B17A1EA, 026DC9F14, 0F7FB6C32 +dd 0E3F82167, 086C96DE2, 03821DF0D, 0E8F61BC7, 0155ADB27, 021AFEB44, 03A64946C, 04DFCDB8C, 0F39B13B9, 09BF1803B, 0600D98E9, 0BB60303E, 0470DF0DD, 03AC6BD2B, 074A20966, 024316CF4 +dd 0CF496BB8, 0CF3E3095, 05D36B53A, 0AC3433E2, 0FE96D0C3, 0DCDC8E44, 09D7C9A0D, 03D8764D6, 0FA468902, 08C362A68, 0609BFF3B, 0E84602DC, 03B4EA4E8, 041F381B8, 02C711159, 0FC673B75 +dd 0E14E0E36, 0F1FD4CE6, 0B482EC69, 0439AA8F4, 04602878E, 0ABB84A9F, 09DB11477, 0C75C3670, 0B9C1083E, 0EEB865AF, 06C72D0CE, 04304529A, 0F2075F87, 01DD4A681, 0A79FEC9B, 029806DEB +dd 0031B699C, 049BBF9A8, 090F4F78B, 040F657C2, 07B82DB53, 054C16E08, 0AB8BCF1D, 0D90DACC6, 0EAFB9EAE, 04FC66A0B, 0E10619EB, 0C4C5CA24, 0A7022DC3, 07F44F77A, 09BB24EB2, 0F205C7DB +dd 03DAC796E, 0ED985FB6, 0FFDAF290, 018324DDB, 031773E2B, 07DC96979, 0D3E4AED0, 05AFDBDE7, 009DC6700, 0B8E0EB4E, 0C5A633D8, 09E988860, 046DC2047, 04D178E12, 0DE62DBC5, 08E0CFEA3 +dd 07A7B5D30, 0C0A0C55B, 0AEB1A796, 08B63CFDB, 02ABA0B5F, 079A50CBE, 0E86B34EB, 0702A09D9, 04D59E453, 0DD52CA4B, 07AED3335, 044D5EAA9, 0F1AD16E9, 05DE784EE, 0DC6855A8, 0D2AD1D6A +dd 0D63EAA36, 04A56F958, 0B27E4BC9, 0DF8647C4, 007B0A887, 0B9CAA92B, 0A74B7E1D, 034315AE0, 0630E79B3, 009A3E370, 0E3A94FAF, 06C00A9E4, 0C15F4F32, 061A73B83, 0EA065124, 08F3BAC47 +dd 08A4B5F29, 06A4FD24B, 00E7E7839, 0E7EB9F4E, 0968ACE7D, 01A46088F, 023687E05, 0531778ED, 0AB9492F4, 05AB2F62C, 008CDA18D, 07580AB36, 09CAD6302, 0008B6A41, 0DA3D3676, 087E1B152 +dd 0574C94E1, 02E0D9AEC, 0ADFC3C4B, 0351A3D92, 05E8D383E, 05C7C566B, 0FB8C761E, 076443266, 00ED17886, 0A10D29EB, 0913EAB8F, 0AD96A609, 06D1B9DF6, 01F968996, 05847523E, 09914AB55 +dd 09FADB3E3, 0C36B4F2B, 070EFCE78, 0ADBA1CF7, 08757C824, 07972CB8C, 09F98812C, 0D952D8B2, 045E168A4, 0DE0D94F9, 0E7752039, 052A54C77, 00ECEF83C, 0C10AA56C, 0F1DE5CAF, 0D7587623 +dd 0D7C3DBEE, 06B45A6D5, 0B7446C75, 08B992C86, 0B95B7E05, 0610704A2, 039A2B0C8, 033CE4967, 09E69AB62, 008FEBEEC, 02A80EB04, 007C6655E, 022008F4E, 0093B0D36, 0DC9EC251, 0B18C033F +dd 00225E696, 0754D8FD8, 0B1BBF3F4, 07A9557DA, 062857656, 01EBDD1CA, 08FD7AA27, 0D04B9ECE, 04FE187B3, 0E4FA6806, 08FE14AB2, 0719C13F1, 089C8DAE8, 0213B90D1, 0D2B73EF3, 0C11EBB4A +dd 03A49CFCF, 0EF908D81, 0DCC63145, 06B44D326, 0450FF764, 009231870, 0DCCABA93, 084D605AF, 0522425EF, 029132317, 0F0309FB0, 03803AE6A, 0DC80D842, 081BC94B4, 088531461, 0D359DCED +dd 0CFE8C1EB, 055ADD5AF, 0D658C681, 004E8EA10, 0836C38AB, 00633A791, 0C5A0093D, 0D808F6A9, 05672D749, 0003A18F5, 02BC5C2A7, 02C6BBD2E, 038381A4F, 0B9DA6623, 0391274C4, 01EEA432B +dd 08F3F9782, 0E54E6228, 0AC128324, 0E82A4D06, 02AA01274, 0504F3515, 0895CF2D4, 0A6EC235D, 0CA567093, 02C658F38, 036D57593, 028412D7C, 0811AD26C, 080DA084F, 06040D623, 0D1B36EDD +dd 0775870A9, 0D1CE46CA, 0F26208F1, 0AAFE748B, 0D9EB9F36, 0F3BBB614, 01452B18D, 0260D0485, 0C0C6AA4C, 00168A93B, 06E7786DE, 0978D4293, 053564569, 0EAEB1F56, 07B4B44D3, 0A6D4E985 +dd 05D31F337, 0241A7274, 03A67376A, 05EB5840C, 08CB7BF9A, 07FDA0D8A, 046557A9A, 0AA311276, 0A1B1CAA1, 03F63ADBE, 00DA8E705, 057D84DD3, 0E055820B, 08BD2105A, 01116BEEE, 06ACE3857 +dd 082ADD2B6, 0B1FD65D2, 0F220F07A, 002DF060A, 0291401AC, 0B330F48F, 0049B0C04, 058BC6799, 02E53D54D, 072ECEAAD, 0D4815C62, 0B4C00024, 0D25E9E4B, 0EC643534, 0E9A4AD26, 0ABD38C24 +dd 09E304557, 050CE9032, 08A735607, 036D56576, 06D401569, 00AC890CC, 09F572AFE, 00BEE4059, 0730F82D1, 05D36F16E, 0C67B23FD, 0193E7568, 0E25E2A56, 0DD20F202, 0086F20C9, 0DC63C570 +dd 02E7C541B, 0136DC191, 02D591F8B, 099D0831F, 0ADE17343, 013273981, 06E4C9B0B, 083177581, 06C06DB1D, 0F3E00CEF, 027E489E7, 00DF2E6B4, 09C2B51FC, 010620C53, 0A686ED5D, 0ABD415E9 +dd 0CFC2314A, 0D63996A8, 0F3378E7C, 0F70383E4, 0CA11D804, 021EF1C2E, 002358D49, 060CCD1F8, 0F7AB5810, 0A3F6E3B0, 01C52F849, 0FFC15C09, 0A1556BBA, 026D77C33, 09CD68A0F, 02A6A1EE6 +dd 041D71D23, 0343A3D83, 051260A6C, 0607F6DC0, 03C8E6CE2, 0DAF931B4, 000AA76BE, 0EB54786E, 037A37AA5, 026B0182A, 051C671F4, 043ED44DF, 0AD112AE7, 07094EA20, 09FDD3F37, 043661D4A +dd 04E05765E, 0EF9DE4EE, 0C520B029, 0443996E9, 066AA3ABC, 04EBEF4C4, 0F5ADE30A, 0DB75EC1B, 0321FA1D2, 0C6AC74C8, 02D6800BE, 0F319FA0B, 087DD67C3, 09735F5FA, 06B8E450C, 0A493FD52 +dd 0F9238363, 0FBC3754F, 08B469145, 00F6EF2CF, 0433ECB76, 0A8E10756, 0EDCF6A35, 0E8A248D4, 0650559CB, 07164D08E, 0AE159562, 04C9F36D3, 00E5BA40B, 0D2DF19E3, 0D19C1106, 0A282EB24 +dd 0E37E8FC3, 0BC8654A7, 0E7D83762, 06C4C7F01, 05D1C3F32, 0EE5DCD1D, 0CCC366F4, 0334384E1, 0ECABDA8F, 0FFBF2516, 06762DEAE, 0B5E89856, 05E17938C, 064464F4F, 0E1657FEC, 0EA6BEC3D +dd 00A834FB0, 007A677DB, 05957025C, 06ECBB57F, 0B7CB00A0, 0135BC1DD, 0B0F1C78D, 0C63B068E, 0A0AD5EE3, 046D8EC11, 0D3CEEACA, 0062C01AD, 0C9101CFC, 0D17E2F68, 0CDF15ACC, 0B1F3E07A +dd 05E56CCF3, 0B8D37C84, 0CB9C2E09, 0544E2952, 0B0BA86D9, 0272BA4D8, 0DD928F5B, 0B2270264, 04FB901A4, 001B1577F, 07787BEBE, 09299A610, 083EF38F8, 0367340DC, 0AE85E790, 07227C9DF +dd 0162BB289, 0A4CE951F, 0FE630526, 07C61FC30, 05FD11E5D, 0BBA4D1F5, 0E7E335D6, 0C1A7868D, 0C3589A08, 0AF268933, 0153D80F7, 0A56D8C4F, 05D877B51, 0FC1835B6, 01E9A1B53, 04E20947E +dd 093A411AC, 0027D7820, 0F7642F46, 045AD50B8, 0CA499A25, 0E7AB3142, 0D7BF21A1, 0C135F717, 0B4D586E9, 08A765063, 031783C06, 0B481C293, 0A433115A, 07BB7AFF9, 0C8E9E240, 03262D3A2 +dd 0888555D5, 09CD49C91, 0A3BA425A, 021A381F1, 024A456A3, 0AB2D6470, 0495A5774, 0AAC0A00D, 09E65A9DC, 0369473AB, 00A534E13, 0C24B8260, 0035F6935, 03AA21528, 0469DD2B6, 081F8E0AA +dd 04A9AA0B6, 0FE416FAD, 026ACB44F, 0039B3C23, 0976EA772, 0B47C62AC, 028446D93, 01EED0228, 0290EDCB6, 0A3626B50, 0A199CA42, 0B6047881, 01C6C61FB, 083C1F329, 0B03A8C7C, 055510A45 +dd 0812E0702, 00A7DAA20, 090B3802A, 0D6894D0E, 0096427AB, 027F00890, 01822CE99, 0F3A04D23, 063F8DAB5, 092356D2C, 0F0258319, 01A47E42B, 07E817101, 09CE68D98, 0DA760F82, 04A72D0FC +dd 0C54D46C5, 0E34816B4, 0EC9AC564, 0C60FC5E6, 0E9DD1B9B, 0E89AF45E, 0769BB804, 09B9EA4E5, 0F34C7331, 044149045, 08B7A067E, 0D0F0C46D, 0F8D6CE95, 02732B7A8, 0695DEB3D, 0555B8237 +dd 051B41B70, 06CEF7EBF, 0144D4B74, 0C614C5A6, 08D947F6A, 0EBA7D038, 0AA6CAFC4, 0943DF1AD, 03D18A47C, 0B6181606, 0E012A84B, 0B2BA2A17, 07E0DA553, 0A81E3339, 05FAAF9EB, 046CB1817 +dd 093C263B5, 038D5BD80, 0E9077337, 03F5B855B, 01D5A6FFA, 075901DA7, 0B2CD4D05, 04ADD315A, 048964631, 02A87A627, 09AA52687, 0EAD9B49F, 0350F879D, 07B96D2B9, 049AE6AE4, 05849FE11 +dd 02ADA49BA, 0FBBADB90, 0D0348263, 0366302D3, 00F608780, 0F239B980, 0B1F4DE58, 017ABCDE9, 0ACCE253E, 0C977B80A, 0F478E84F, 0F6EB7E3B, 054AF7578, 0AAB6F1C8, 06BFC7252, 0AE288D20 +dd 04FD46B14, 05249CBCD, 0D9A1D526, 0A5A7C5CD, 09D7551DF, 0ADF4999E, 0D4743D59, 0C6005F72, 04FEAE6A1, 06E5D501A, 0E092915B, 0751B8A49, 0438AF325, 09261F44A, 0CE8B66D3, 0F513B35B +dd 09CCEF45E, 097274D47, 061222B4E, 05208E9A3, 0D5A14D99, 0F3CDA1A8, 03C8787A1, 03EC7D6A1, 064216F4E, 0D85A8B40, 05AD64D21, 0FA6BE7A0, 04A768C81, 08B15E2FC, 0DB0DF37D, 003D80CB4 +dd 052CF55CB, 08820D265, 0DBAA56CA, 0DC0B3976, 0B66F499A, 09706CAE4, 0CC093391, 06298E4CC, 07744B469, 0159E12F6, 0D78B5E0B, 07EEFA418, 06A67E2D9, 001682991, 026DC4B48, 0CF692973 +dd 0AEEB3829, 0D88A98EE, 022D1EFB2, 0EA339FC4, 072D9E679, 05EA6BCB3, 085348B03, 063EDA756, 09D8A705F, 08808EFAA, 000B32486, 000DA7018, 0A8FFF057, 095233269, 0139A0EAD, 0FAD351BC +dd 0565C6D78, 0D6BD65B3, 01F1A0204, 0B5908E1F, 0294FA7E4, 024F187EC, 07F6C5E80, 02319DABC, 0C50F5EBA, 08486899B, 022F1D1BF, 057EAAF1D, 0992EEBF0, 02F9CB724, 08D594FDF, 01279E3CB +dd 034F16556, 00BEE8255, 0CA571BFA, 0E75A16EC, 04864D3A0, 092312CC5, 0A47F02E0, 08409EDFF, 03E9EE0EE, 04F18ED6C, 0E3C1DA6E, 07B2AFAB2, 017CC0157, 0FEB165DE, 09E980BB5, 0BB6F622D +dd 0734A6858, 096BCF181, 0DA66FC5F, 01FEB1EAA, 0509ADF83, 004A31F3D, 075EB36AD, 03C65AC19, 0A704A565, 0B6413F4D, 0EE5BF51E, 0CAFC3138, 01997C653, 00BF11F83, 0CA0E9F8E, 0E7A5E379 +dd 057E7CC4B, 0563C9D5B, 03902B1F8, 05E0C58CE, 065A9A307, 0BD73315C, 039714240, 0C0932B35, 05CFB89F1, 06712999D, 0901CC408, 050738696, 054D24986, 086189C1C, 0186C21F9, 0F8D8F0FE +dd 06C6BE215, 0181856B6, 0371A72B4, 01FC91D8D, 02D68041E, 06FFDC381, 0C5852DD3, 077626361, 089A1541E, 061C36589, 005FFC1A4, 015F4296A, 01201E0F6, 0985F1F53, 0168DBE38, 0CD704CC2 +dd 06A2CD551, 007AB4470, 06EC4CE0E, 0CB9BA7F5, 0BA879E3F, 0069448BC, 0ADA36A1D, 06F4E89DE, 0C7B9164E, 0632A8526, 0F76FAE49, 06397D4F3, 0D8204DC2, 017FBEAB5, 0660EB441, 05A0BBEF6 +dd 081B44B81, 0EDB32BEC, 0B40FAA36, 04EC94CD5, 0802D4BA5, 0E0A57CD3, 0907F267F, 08EBE84D7, 0D0CBD8F7, 0B53F1CBC, 0697757C2, 0B0797AC2, 09312EF67, 055A26D85, 0AED46EFC, 0DE984D8D +dd 04C119C4C, 0DC500DB5, 079BB4D50, 016A710E4, 0FF064A29, 0E397D4CF, 0B271E955, 0749FC2E3, 0F73F6AAC, 0BD160821, 071A1C629, 068FA6103, 05C833A18, 08DFD0DF0, 0EA1E901A, 03B79E2DB +dd 0832228DE, 034C20986, 04A2CA789, 030983412, 0EF031AA9, 0C2D75525, 01C30778D, 062110F1C, 0ED241D08, 086858135, 032B40EBE, 0DFA5E12C, 084FF9E74, 0B12035B4, 05EB11F78, 04C2B694A +dd 06623493D, 0AC81BCFC, 02376C33E, 0E7FF36FF, 03BC1F52E, 02C6B91DE, 03A0B9E65, 0F18C8308, 06257248A, 0D9A292D0, 017FD3DE2, 0D0C2DD82, 0AFBA76DE, 014BB48AD, 074CB4463, 05ABF8E8C +dd 0B8F571D0, 08AC8E2B7, 0ECAB413E, 01BB571F6, 0D9240E1B, 0F4FC3ED6, 02982AFE4, 0A6537357, 0EA06504F, 09AB5433A, 02F133CA3, 00F6BFBB3, 0040C3A61, 0A542D9EA, 0F783B7F5, 05533BC69 +dd 0FE94B75D, 054E7054E, 0E5DA1A8B, 0F93107FE, 088FE898D, 0EDCA11E6, 052A69CEA, 0DF08A488, 086313BC3, 08B30469E, 04408FE13, 016CDC1E6, 0F3C1138C, 030520C8B, 0B1B8D0A7, 0AB20C824 +dd 08C2782C3, 069DA55F7, 053C2CA5C, 07842366C, 0A6ADB101, 056440926, 0711C5068, 03DE0CCCB, 0F052355B, 0FAD2B80E, 07B410AF7, 04F4E07B8, 05381D633, 049B31729, 0215E6B68, 026A3EF42 +dd 0B3185A78, 069E45779, 08396BC8B, 05C82D4F9, 07B7E2EEA, 0048C5662, 087B74F44, 0F59E1F02, 0D463AE15, 0A71C1664, 0AFAD302C, 09F08C78F, 0E4F0DED3, 0125677F1, 071566E5C, 04124A9BD +dd 03D6C24A1, 0985FEB43, 053F5E2AD, 01DD94349, 0964B4CCB, 0A4681549, 081E55055, 0056B979B, 01B1F6835, 0F864AC17, 05EB38B99, 0E8F433EE, 06A353E55, 0C02B06F6, 081B64159, 0F50C9DCA +dd 009BCE8FE, 051A380E1, 053A0F0A8, 008F18EFC, 00B6901B7, 050EB6985, 05EAC772A, 046C99D30, 027E24F9D, 073F0D5CF, 05840B19B, 0D684AB7C, 0293580B1, 0B76D2826, 0EEEDBCBE, 0DF091735 +dd 0B5D13D0C, 0F1AEE6A5, 01545127C, 069F7FD70, 02761155B, 0BB83186A, 09483C957, 016C3900F, 0DC4F2399, 0AF684B85, 0B6760516, 014EE9BB2, 079B538C1, 0C3E1D577, 02AF8F600, 04F900A70 +dd 036675E3F, 0DD418D4D, 09B26AB93, 0886ED32F, 04C997BA0, 04B82A3B5, 090EC9B41, 04E2AF383, 0DAA2DE2B, 0EA1D2585, 0A90DD921, 0CB616A3A, 069D4F155, 01D5B0731, 08BBD3DA8, 0333AF583 +dd 0254C1619, 0460DCE37, 0758EC2E0, 0EB13D826, 018855821, 0AD32C98E, 024EFD20B, 018DD1CA1, 08B846E90, 0308866A9, 001492FC3, 00535FDF8, 0A91C26A7, 01101BAE6, 0DA46A1A3, 09C156D0D +dd 041C9CD0B, 0E495CA4D, 0D05357B9, 042DFCD35, 0DDBFF437, 021DCCDB8, 0FBDE21B7, 04D6D1A2D, 083488E06, 00C7074DD, 03F59C2F7, 0196D1979, 05062FD38, 0F96F5EBD, 0EC579629, 084B5B63A +dd 00729C4FB, 0BAC07EDD, 05F918289, 03C4CAC84, 0C5C6ECD3, 0E7759C52, 0F53F879E, 0983EAF8C, 0D6554B13, 012441B9A, 0DAF138B7, 09A129C8C, 007196654, 03573A8E5, 0B494574E, 06CF9EA66 +dd 0F8376D62, 0AF513F08, 0626ED3AE, 043655FCC, 091554C03, 0FCE433D6, 0BE9834D8, 01B5367D9, 03DC26845, 0EABE06DC, 04DAF5519, 09E1F6A77, 0DC152BB6, 05040D449, 07EC10F4E, 062721A26 +dd 08AEAC3DA, 0B2185910, 07179E233, 00C139EC2, 0F38E7AB1, 0D093E1AE, 0E7479AA0, 01939727F, 0F93B722F, 0DB95AECC, 0B90C1874, 0C9081A18, 078528313, 0505294C2, 0C63FA5A0, 0324022E4 +dd 020177D27, 06C85ABCB, 0301500E5, 0083B089B, 07506A069, 0E8778E37, 07A3C75A9, 0A34E5F55, 082CD959F, 02F85BAB2, 0332AFA0C, 067BD9772, 030B3FAF8, 0DADE0CE6, 0FC539AA4, 06AA94B0D +dd 0BF0C353F, 002B7FCAD, 00DB8CFF7, 0D67AD932, 03FE709E8, 0000BB7ED, 0982FBED6, 0D0F61D00, 07D733146, 0EB1321E4, 027E791BE, 0042ACEA3, 0F8BAED68, 0657B5DC5, 05BECEFDA, 01C0301E4 +dd 0B9E97863, 0B15270EE, 09C15EAA9, 0EC31AFA4, 0F8536046, 03298CBFB, 02AA91221, 008782714, 0D6B04CD4, 0887F146A, 0831774D8, 0F1A2464A, 03D9F640B, 0816CBAAB, 09B674906, 0233BD34D +dd 0276C80CE, 0B5E805A0, 0AAB694B5, 0A316F813, 0EB64A378, 051D97AB1, 088C1D1F9, 04C7DBD04, 0C3BB33D4, 03A62150D, 04AE15936, 0FEEFC71C, 0FDB6469B, 0EAB6D017, 049936356, 0058717F9 +dd 0112ECCB7, 0D0809D86, 090BD5006, 0B49796ED, 0AA899B61, 0E3D5A222, 04AC06B73, 0ED561E18, 020087F14, 00D620A7E, 01C44BBEC, 00ADE4DBA, 0296BC9A1, 0F76BA448, 0C7EC0A8D, 0083564F4 +dd 01921E58E, 0B24382FA, 0D4888D40, 014D2702A, 07DBADD8F, 091B31373, 0B9385E04, 0BAE9D4D4, 01F599F7E, 0A62C3D03, 092DE2CF9, 036450867, 05DF7D318, 0FC632F0B, 0B93DF024, 0B1E30489 +dd 0D0638A6A, 07C417E10, 04AF247F7, 00D29511E, 00BD83C62, 0E5C83A82, 0530EA3F9, 03A8D6085, 0313B70C4, 0090F1B1E, 05B97804F, 0347E8F21, 0D673492C, 046AB92B9, 0AD14D56B, 0D03F059A +dd 0BE34D38E, 0F32D6ECA, 04B1A44EE, 0AED8C82A, 0576DA969, 0E9A8DF1F, 0AF0EDB80, 0C114A421, 046729C76, 0A89BEEB1, 02D02DC29, 0F489F4F6, 090F024AC, 09636C3A8, 0E4195AD7, 08556EAC6 +dd 0D6A86F95, 04E9BA1A1, 076C6C284, 010E8CDC6, 0237F5B9C, 088FCF64D, 0417982D8, 08264979A, 0A59824BE, 0384F2E9C, 0D1282339, 00EAF3E6E, 0E748B593, 0E6BD9BD1, 095AD3CBD, 0F9A490BB +dd 0BC318E95, 0F47211DA, 0905381E2, 0C69FD6DC, 0A58988BA, 01C99B955, 0108A6B65, 0B5290AED, 0A914E4A7, 0DB91CE71, 0F496C06C, 07319BC38, 059B569E0, 0D61F9BC5, 0C7384B4E, 06ABB41DD +dd 07953A4CF, 00A9F5922, 05CAF5162, 0EC64C311, 0E9B63C2D, 063DA95B4, 0D945FF5C, 0FC99CE2A, 06DBCFECE, 006294E10, 0D4BB824E, 05CFBE03C, 03D99B31F, 0030A339C, 011FBA14E, 03578DDB8 +dd 0BA02F394, 0D7C18F45, 00E2D0E20, 028B762CC, 01CED6577, 0226BE971, 07086F93F, 00D34E2C2, 0B59F8D1B, 0D4A0F625, 0213ADFA4, 006B0C534, 082ED23D8, 01EBF0EF4, 024194A8E, 07922E2FA +dd 0E07C7E06, 0258FED46, 04F6F846E, 0D5235526, 06CBEAA99, 0F4B62195, 071E6A8C3, 013584963, 0E92E93FF, 0C357499A, 0EBAB0BB8, 08C9072DE, 0F56F8DE2, 049E730A2, 01CAF5B15, 0EBD15E9C +dd 08A69F1B6, 0D16D9DE2, 0BAE7D855, 0527663A1, 04E57A3A0, 0FCE214EF, 0BC90F6FF, 015C563C9, 0D8026820, 0274895B7, 0569679DB, 00E1A9BAE, 0B04BE6F9, 0A755148F, 05027F7A1, 0090FABBD +dd 03F210EA3, 032FA1BEF, 0A98C3F4E, 09A4B1E53, 02EC73CF1, 02DD31FEE, 0EEEC94F9, 0F7CFBC6E, 0F3C381A6, 0B481B0A5, 0748774C4, 05BACDD44, 04FE0EFD3, 0665B6BC4, 00A7E0534, 0B98BCF9F +dd 06F345D35, 0413F201C, 01930AB02, 08E27BD63, 0F9F0816A, 089EDF356, 09E0E3616, 082DBBA0B, 09F300AAA, 03EA6C610, 0A19E9342, 0A6475CC8, 0687B379B, 02428A29E, 0C2613068, 095E3C3C3 +dd 058C63C3F, 0F06050E2, 0EC216831, 02AB1E6D1, 04092B6EB, 0E8632D69, 047E40566, 068BCE279, 0E7FE9286, 0C357A573, 027ADC850, 0F5B8551C, 0D4C9CC0D, 003A09C57, 0F4F900D5, 091595537 +dd 099B944C2, 001922075, 09A7B858A, 0563A4ED4, 04481F818, 02A69752B, 0209E2F78, 004213FF5, 0825C3C6C, 04A6DDD14, 0BBFC0F6A, 0044D5A7E, 01CF2CB8F, 005114417, 0BE65C4DB, 0EE3874BD +dd 0B45B790A, 00A531081, 08FF0EDBC, 098CDFB71, 0138DF1B4, 08FF91B48, 0A616D0C3, 045A31661, 0C0A57E95, 0E525A08C, 06DB9DA3A, 0B63F0D0C, 09CF0C03A, 0F6B7951D, 0A8FD7F5C, 01F8DA5B4 +dd 0CA0514C4, 0950DDE94, 054FA60BB, 0D61CA818, 042E6417A, 0A85628CE, 0FF287DBF, 096C7B72D, 0F1381750, 02173CE02, 0EAF633B3, 045C68100, 054A66DCC, 00175222B, 042C6D063, 08DABD83A +dd 0ED388063, 05A47B910, 01F17E1A7, 0227D5619, 02251C952, 09A040508, 03015C81A, 070B1E67D, 088F18171, 0CB489BCA, 0146B31E9, 0B575FCFF, 09F2D94A9, 0675D5CE8, 0B21E8638, 0A3D80C2A +dd 02CC4ACA0, 08C1BE456, 046C2B590, 02A5E05AA, 01E6EA4DF, 0B1A164E3, 01C1B084C, 02503233F, 075DC20C1, 08C098A58, 01F7C676F, 0B04AD19B, 0490910D7, 08C878D8C, 070F4CC24, 0B4FB9EA0 +dd 04CECD6AA, 029399FAE, 0C08BE4C8, 02A4B4B7F, 0669506E9, 04E994CBC, 0E7D54643, 0EED03A17, 0CF9DE3D5, 00FC4B191, 099954E25, 04CAFCD58, 0657AB7A2, 099BF75BE, 0D25AC776, 04EE7D2D6 +dd 07B853503, 08F4C716B, 0DCE445C2, 0765D9089, 0D44E74B7, 07BD9C0B0, 06799A0A7, 048896FFB, 04FC7BFC2, 00064F3BB, 0FCAA12A3, 07A215985, 0AE32A5BA, 01BE65A5D, 00F981E03, 06C1B5B6C +dd 0A3CB9556, 067EF8E80, 0F09ED86D, 039F8FC96, 08C2150C3, 076946C5F, 015F05EB3, 08DEBA970, 01BCA2D51, 0ACB5F817, 0D0A632F8, 04F2E6CC2, 0C14DA790, 06F8B7FC0, 0D14A3ED2, 0E065AF39 +dd 07228038F, 0937ACB83, 018C9EBE0, 0E5BF74F1, 07775209B, 0D3572C43, 0388F6950, 0D3842C0C, 09522419B, 07A433A9C, 011EC0A9C, 0BAA8A84E, 0A4269F4E, 09F737FE3, 08741268C, 0EAADD999 +dd 06588D957, 04D09404F, 02BC0A10B, 0F2D563E3, 0506DDB4E, 019487412, 09E1CC98B, 0AFBCBF78, 0A011CDD1, 0D2FC07CB, 04A89C997, 0AE7A1F5F, 07B31AD35, 0357D282B, 064354D89, 0089F193B +dd 0D56FECA5, 0379C95C0, 0C17CFC00, 09BF5C36B, 05DAC64EA, 02EF86621, 0E670F326, 03186117F, 0AFA4E0F4, 059DDB169, 001D40A98, 02AF43AE5, 0A0F14C79, 0610C35B9, 0A4F2F418, 0EABBE7FF +dd 0520D9689, 00D44D13B, 023E6025E, 0841BE365, 09050E71F, 0CF8D21ED, 0C305A33C, 00DC38296, 08CEF0A94, 0A5DD2DBF, 02E6EB74F, 0D854B826, 0EB1E33DF, 0D60548CE, 025DC1386, 032974193 +dd 08349F04E, 04F5AE206, 0E21B1D43, 0FC742038, 0FBDE7057, 03D3A1D6E, 0A0124A5B, 06B274B7F, 0D810136A, 08BEFCCF4, 08F4F6CB3, 08AF18D31, 023DE018A, 07BC3A3E5, 02B50F7AB, 0FB64CFAF +dd 0BB008721, 0A8C79E92, 04D6B4385, 082B75842, 0F20E3281, 0720A754D, 07F65B712, 0D58C6E3B, 09C39B141, 0306A41E8, 01DBD0CE7, 0B9DB77A9, 01BE5CBED, 07ABF8B35, 0846C4C42, 063A1CB4C +dd 0FD3E3CC2, 07D56160B, 06208B1E2, 0F142F430, 0F4B42F40, 08EEAC836, 08627D863, 0AFE1B04D, 001436AB1, 0CE6ACA55, 0A350F85F, 025A8F2E7, 09022AC0B, 085C7A3AA, 0E1DF54AC, 038A08E69 +dd 0BD637608, 055B48854, 01AF1B1DC, 0E02383F4, 00741E58E, 05216270F, 0D8DA70C8, 0818DD6C4, 020A6F396, 0E19B380C, 0AB3E24D8, 0A0F39D15, 00D0690B0, 0A40B9E4C, 0AC07D345, 03911AE9E +dd 06D5EF1FC, 0C59A95D0, 02888262C, 0B1D08249, 08C3E8849, 0014A1EC9, 0E729E0A6, 04EA093E8, 04E40C94C, 01F5F4B15, 0B12DA6B5, 080F1538F, 08D037D04, 067817F4D, 05160EFF5, 009992498 +dd 0B4D4A4F3, 08DCC0A54, 06CF07ED6, 02C0097F0, 04C0C6C7C, 0BEF68204, 035136F82, 024204175, 04CA335AB, 08918B547, 0DC606272, 015642D50, 0D05AD420, 092579225, 0F508DE70, 08F028844 +dd 0268E2D05, 0338725A7, 02102470E, 03E038D1F, 058381A25, 08D16A1B8, 031FA1297, 04C69EA59, 0846363A0, 00BAC2625, 05A4C8B5B, 0DF381A23, 0119A9410, 0361D45FB, 0C2E89A84, 07D78147F +dd 04FD146A4, 0EDF699B6, 0D87F8C73, 07D11B392, 0AD7185A4, 04506555C, 030242BD7, 0CE1A4CBA, 059A709F2, 042B7914D, 0E9A933CC, 056CE66CC, 04364EF25, 0494C49AB, 068C05353, 040378EE6 +dd 0A996C34C, 0DADC8FE2, 07E3E8B0C, 0AED5D07E, 0657C0C30, 01273D9B3, 02499DD3E, 0A9CF954C, 00EFBE2F4, 06D098F81, 08AD14204, 0F81C3844, 02CB47F48, 039D5B5AD, 0782FBA47, 02A1E46EB +dd 0DF1C15A5, 08A53BC02, 0E4D0435F, 036BCDBAF, 0724EFC9F, 0B058C3A7, 0BA72A942, 020659B4E, 0A186DB94, 015296207, 0F24E5335, 0CE16A794, 0F5CB9B90, 03EB18DC5, 086B2D403, 0BDF0C5C4 +dd 08BCDFDDC, 09110B2ED, 0009DB80A, 04C14B377, 08CC81A7C, 0E42980C1, 0C9B4C5E6, 07E30F3E4, 056489930, 0EC10B0D2, 0F9CEC70A, 0AEA07BC4, 07E34D418, 03AED9CBF, 0CF504D13, 0CB14B75F +dd 018CC5248, 0A049A605, 0A82A2488, 0730A4F30, 05B3FE3D8, 0F6DD7D8F, 0894FA0A3, 048841C27, 05D51B26E, 0AF121F43, 09D9ADDCA, 04B8DDA20, 0B3CE5B6E, 0ADAB51A3, 0AFB5FD4D, 0BA44C0CE +dd 056E2B550, 06EDD1E8F, 038297960, 0899DC08D, 0ECE3F5C4, 0B6CF5C7F, 0905551B3, 05939E86B, 035A16EAE, 0FF669760, 0DCA49B3E, 06795A79D, 0D1DC0368, 019A31941, 001F888A9, 02BE90F84 +dd 06D392576, 0D18713A9, 0B0A56FB5, 02CD194E0, 0B13F7D56, 0C974F6A5, 0A8C76DC8, 0EAEC0480, 0A684C671, 07C4E4C42, 028998BA8, 03863FC15, 0A31A66A4, 00D422559, 0BD646684, 0A1019DCD +dd 0BF67612A, 09316A77A, 0EEF301E3, 0D3DB137C, 08DC95A76, 030D9F14A, 0026B073B, 00636E95E, 00AE24C93, 0949EBB30, 07593AEA6, 0B5C15692, 02748BF0E, 05F322B81, 07FC8D5F1, 0E159D802 +dd 0D99C198C, 0B4158C2D, 06B9956AB, 030DC36AA, 04C3151A2, 0ABD4C48B, 049324E5F, 038E350E3, 0887BCAFD, 0C837F536, 0523D6147, 08E5BD5EA, 0ECD30B3A, 0356AD103, 001F7F546, 0C9DF1E3D +dd 0E46D97EB, 0BEBB3653, 060CEE42F, 0EEE13687, 096EACD41, 098EA0F7A, 0E5370BF4, 0F2BD3B51, 00163318F, 09AA7B26C, 089E36723, 04E350A82, 04AB93F58, 012B46926, 0F57088C2, 0586A8B40 +dd 04AC7B087, 079869C63, 05B5255F9, 0A5010929, 0C9E95CE7, 0B51DE2CC, 0C0D13803, 0A2A9383A, 0F580707C, 0BAA75986, 00C6D9452, 0C6C83D7C, 0ACBFFC7A, 03CC3D668, 0D379B4BC, 0C1D77FF3 +dd 0D677406B, 052C10337, 01E77DCAA, 01AA283C8, 0F97E6E3A, 0513EA768, 01BA07F3A, 0F1A77EB4, 03A0BF91A, 0F18C8308, 0B082E0A8, 086154C35, 02CB95587, 08D5C18FE, 020398805, 0B195C6ED +dd 00856F24E, 08A13126A, 0A9ADF396, 060A4A4E1, 099AB115E, 0A487962F, 01A8124D4, 0080963A5, 08588BF33, 07562E055, 0F3B4FD3C, 0155D5200, 01057A3DF, 03E15EB79, 03F786A51, 043B8EFE9 +dd 024E2A7A6, 070869DCD, 0DF123C70, 095DDB315, 0685CB2E7, 0064E4C15, 0A300B0E1, 0BA8CF2FD, 0E3142FAE, 0F8D18FE7, 0D5DAACA2, 0EFE5235D, 0C59100D1, 0C26B9F5A, 0C37220C4, 0DA10EB20 +dd 03C421A9D, 0ABE9BDDB, 043E3B6E7, 072C20C2B, 04C9D1449, 0BA618141, 0ED1E68B8, 082289F09, 0182AECB4, 0C531AE6F, 08F75C8FB, 0D350E538, 09B6B9A6B, 075BFC4D3, 0CD5B1FF8, 05F2E1A5F +dd 0C36E10CE, 0AA7DED53, 015DA4781, 091317CEF, 03647EED4, 0058303AC, 064ED50D0, 0B3C1456F, 085DA3C6E, 02BAD37BC, 0536E0DFA, 0FB75D9ED, 099ACDE8D, 0B6DEAB59, 0D318734C, 0EAF74275 +dd 00B5719C5, 0E7C8F1B1, 0989ACAB1, 0D518248D, 0469E41BD, 0E03B6434, 09BB88349, 032A9CCB2, 071434259, 0E6EB5885, 00097B800, 07E2598A9, 03BA10217, 08AEA557E, 01A4B2300, 01A59A032 +dd 020FA8DB9, 0C2F1959D, 085BE61C7, 099D6A19C, 033EC9C79, 061DD8E12, 002D876AA, 0BF655EC3, 00E4926D1, 0BEB6F169, 0F5D9D615, 053AB7219, 051B06803, 0C3A170F1, 05695CBF6, 01D523CD5 +dd 0749074AB, 0477FAAEC, 0D9BBF19F, 0D3462766, 045D2A1BF, 06A499396, 04FD2EBCD, 040CBD9E1, 024CA0703, 0BAC4ABEB, 0F7E98D72, 054E837B5, 094F3B41C, 0C6DD4C10, 0DF0B4DD8, 03B3DDAE1 +dd 0016ADD78, 008275B3A, 0BB3C843A, 01ABCD2DD, 0549E9E4E, 0961946F2, 0A4D998B3, 0D65CE475, 0FC101A46, 050A160A5, 0D0358DC0, 02931C665, 013A1D028, 09527564C, 078C772E7, 06486E28B +dd 0A61815DA, 0EF41E7DA, 0A422B482, 06C972441, 0CBA4ED7A, 02C11BF58, 037C383F8, 02B1955AB, 01C1D9D35, 0FA25E145, 038EBC9A7, 09CD6AC3A, 0DD6E19DE, 0CF8A02CD, 0F67D590E, 06FFD6DC9 +dd 0ED78BC84, 00E648037, 04C5A6E15, 07B783F5E, 0E76ED5CD, 007C95FD9, 06F360568, 04BDA054A, 0A6A8DC65, 0427FD5FA, 02F7B58CD, 0B6933801, 09276086C, 07ACD6667, 017919561, 0579D3706 +dd 0D9635BEA, 0D4C4C3C7, 0AE954721, 03466758E, 078B3E15F, 096E6D786, 0D111B1A2, 01EF6A5B8, 00BD8BCA6, 00920CDE3, 012CECC74, 0A1FC7474, 09EF97DC1, 053378C87, 011C0804B, 095B738B3 +dd 079DB26A4, 0872E57AA, 0F4F37ED3, 029F27B9A, 0D36E28E0, 006B5D1F8, 02DA05A0F, 0D4E56B61, 0FE3CDA4B, 06582E0F7, 0EF0FE4C4, 003C0BACC, 0A24EDD31, 07DE37C9E, 04381B7BE, 02583614B +dd 0B48774C5, 0D6A68C86, 0F17C7E9A, 05AF50C44, 0983694A8, 0B72F3CF9, 04EE18BA6, 0364B0D56, 0BACD5969, 04E7E0C3D, 05B3A981B, 0E361689B, 08338D814, 08E6C2980, 07AEAC29F, 01D731185 +dd 00FAD7BA9, 01A514F34, 087878328, 0037F2BC7, 034DF4DA4, 090417C0B, 08F61D06D, 0149401F6, 0ACAF6485, 0D4A5DC65, 06D5183C7, 0668BCE27, 03E7FE928, 00D5B0A57, 0C27ADC89, 0616E5701 +dd 0DE61D9EF, 0503A08A8, 0990834A7, 015F46794, 0C9D1A613, 04032440E, 0F81D3971, 0D88ABF12, 0ABF5F2E0, 060C99886, 021087C4A, 012E1E360, 05B0B2024, 0C7A914BA, 01356B68A, 0E38A8231 +dd 060A22882, 07C2B789B, 05A9C065C, 0786B6F21, 0A90185FB, 06120D936, 06FBFC602, 0A31AAB5C, 0866D450D, 06EC29AD1, 019FD7B47, 038AB0D1F, 022DCEC7F, 0F0164718, 0B823AB63, 0E4406CE6 +dd 099F5AE51, 0B64C80FC, 014C4279A, 004A04515, 096B9C239, 0119603B4, 0666CA608, 052220942, 03D003696, 00F2FF3CA, 08D615B28, 009E330CC, 07A347B4B, 0E026FAB3, 0D281EE37, 0329E54D5 +dd 0C3C7AA59, 0FB629F82, 08C79FEBA, 023644681, 01AB2C11B, 015A91ADD, 0DEEB40F3, 0BA6FEB4A, 088D7B3EF, 081CBB0AE, 007501D4E, 00E1A3465, 05DF1C088, 0A3108C75, 0E9C62C77, 047B97063 +dd 01B5526FD, 0632D0FAC, 0448BDEBB, 0C9923A7C, 0E90BE98A, 0E1CDBDC2, 0CF74996A, 04C727D21, 00EDF8638, 0BDA21A0E, 0FAEA6D15, 0D81CFBCB, 07FD25173, 0952AEF7E, 074AC4E57, 0E7EDEDCD +dd 03C556AA5, 0ADD69110, 024B18CA2, 07441E6B3, 01A377CCE, 0133633F8, 0BC801B90, 095FB766D, 0260DA8A4, 095F2BB26, 05D163632, 0470BE402, 0C74410FA, 0D69916C3, 0A6BB9CFD, 00A34E3C2 +dd 075BD5F6C, 0517E0B7C, 027F9CD29, 062DDF865, 06DE12449, 06DF5E2BA, 0A99275C0, 01D1F4EBA, 062F43A65, 02DE1C7A4, 0AC7F097A, 02AFA977E, 07D57C26E, 0DB4307C6, 082A15053, 0C3155661 +dd 000DE2C44, 077F41CDE, 00FF1A9A2, 0171F9F31, 005F121B4, 00BD21BFC, 0A3AED8CA, 033639245, 06362935A, 0B3315A98, 01FFB64FC, 08036A614, 0307AE3C6, 03CF321F7, 0B110BBB2, 0A1630053 +dd 09295C7AC, 0C90A644D, 0C85CE73D, 0539E8EE5, 08369332C, 0738F01F4, 030C7B3E8, 04A6C6CE3, 08F4B48F2, 0ACD490E2, 076880D1D, 0BD224E97, 04E959D03, 0480ABA1E, 0B8ED1698, 0DCE1CA0D +dd 072FF0AA7, 0F5B8F095, 08323EF33, 03D42266F, 022CCEF72, 09520E6AC, 0B6E50B8E, 05BC62D13, 0BF563AFF, 05EFE8AB7, 0A6DAAE80, 0AC5304CD, 0531AC5B8, 003F740CF, 0A5376E32, 02D367A9F +dd 0089A4138, 07AE90E4D, 0C5C279FB, 0A26F0F52, 0A9E92E0E, 0CD28CDDD, 012CE3D3E, 04B49A007, 06713D62E, 0EFD6C2D2, 07BF5BCE9, 0C1C03C5A, 068DF0818, 0713B20C8, 03134A2E9, 0421F8171 +dd 0206D0A3D, 0BCEBE9A4, 0D4F1F6BC, 03AD537F3, 0779C7854, 0B53D497D, 0124692C2, 0D92DF769, 0749452A2, 0B5DD4932, 00F2FC6F1, 030C139E7, 036A45422, 0EEAEEE22, 011F5B597, 0DA97B493 +dd 07037F763, 071244367, 087A9B1BE, 0EE9A41AB, 0227213B5, 0029504B8, 05719C665, 0E84708C1, 0AE8419CB, 049DF0506, 03EBC71EB, 081527450, 04536A63D, 05E372EEE, 034A391F3, 0FA5D49D6 +dd 05A0F8D20, 02393D8EA, 07684968B, 0D815ACD3, 0D7E05E64, 0A199418F, 01E9B5482, 0C966EDB7, 073A444A8, 010F5D45D, 074D173CB, 01462BF11, 09EE53EBA, 034AFC05E, 0A2C0A56C, 08BA7C5C5 +dd 0C1B40047, 0A7E013A9, 0A4642D20, 05582A9C0, 0235892DA, 080F650DD, 02BF643AC, 08E94FBC0, 0943056F8, 0A9FDD499, 081B41E40, 0898E29D0, 0B56968C6, 0697D07EF, 090B3440D, 01138219C +dd 085B0D370, 02D81A353, 0CEAE82E4, 0AB3BAF1D, 0C7E4B673, 0F48D587C, 043AA63C7, 034B8261A, 0AD484D17, 0C19AF604, 0E456C8EB, 05E5345D1, 086D7895C, 07869B792, 0B1A51F42, 052D7C569 +dd 04BA37C98, 0A07C8DAB, 0B0617070, 051139791, 035B2221E, 0147E7BF1, 026748563, 0553D744A, 0B5ACE589, 01E7835D9, 06904E1DB, 0A93AEA34, 030BDA30E, 0824D5BA4, 06D5E7832, 0021D81EA +dd 055AA8ADD, 0159D30F4, 07C1ABAA0, 008C692D2, 0ED886406, 0467FD135, 031E4AD85, 00E44FEBA, 0F228C1D0, 0D81D4E90, 030B9711F, 04CD30DA2, 05138EB5A, 0B732E26C, 0EA383E0E, 04D823B70 +dd 00AA3808F, 011C5622E, 07E7F31E7, 0270D86EF, 04B888555, 0E55D78D9, 02A796D6B, 0EB1E7D7E, 010EBFBB8, 05112725A, 01667F56B, 0B51B2E6C, 069CD36C6, 07A12F2A4, 0C1E164A6, 04D85A0E3 +dd 0A77C625E, 0260BE268, 08FDB4FAD, 0F56D297A, 0A8EDBE6C, 0BAF33DEA, 0E859717E, 0BE0E8097, 02D35ABBD, 0B8271782, 0C38200F1, 09546ABAD, 09BD661FA, 0710CAAB7, 09126AF1C, 0ECDD5B2E +dd 0EF918286, 07A68515B, 0A5C586F1, 0098166FE, 00AB0AF05, 0A05EC53C, 08B65D856, 050038155, 0AD4E1586, 0C0C5A096, 0B23411A9, 05E45776E, 0EA9F027D, 0354DD3B5, 0C0A2F141, 00DF83646 +dd 078E337DF, 011C34862, 0C1950BE4, 096A63E08, 02D0CF452, 0560FCDDB, 09EE73464, 0EE03868B, 00D55E313, 07B3A1516, 086F0FBFF, 048C9561A, 0C96C8B2C, 0F87113E3, 00D2985EA, 0C6E5D11C +dd 0DFB3610B, 07BAB04ED, 0184E0200, 0C23DCC9A, 0FE3200A9, 0C1B1B5DA, 0E1778589, 0192DCF64, 0C5A6ECAF, 097C84624, 08F8DE004, 09A797718, 034F7E152, 039605165, 0769C04FC, 052661E5F +dd 064BF1BE1, 09A6BD3E1, 0B0A20CB6, 00FBE48A3, 0D671C5CA, 00DF9055B, 0F328ACE4, 0E89BF821, 0808139D3, 0382CE55F, 052530A62, 053AFAF37, 0A54B9CCA, 0E6C70567, 0C7A5C415, 064F218D0 +dd 0AD6936DF, 0B206F797, 0F4B0E6A5, 0CC8A825D, 004C9B0CD, 0AD5B7975, 0D3B68932, 057526FDC, 018404B1B, 034D61F0B, 0D9D727B4, 089635785, 06ACC15AC, 057F5F430, 006BAB934, 0ECC31C03 +dd 06A27EF06, 012D3CEC9, 0C2622CC9, 04CBAB037, 090D93D7E, 04594C1BB, 0A81D460F, 01092BF16, 03644A187, 0EB2B78D4, 0C60906FE, 0F03F88F5, 0C87DEBC9, 0524DDF9E, 0157368D7, 0B2A6A9A4 +dd 0EFF5DEAB, 04CF6B797, 02B4349E4, 056F059E2, 06BF36CBF, 05545EDB0, 03424DC26, 0DA4A0EC6, 0DCAAC709, 02D16D741, 0EBFB9619, 0C364D2DB, 068C48868, 075DC32BA, 07EAB1881, 09743B48D +dd 009D2D978, 0A8A00442, 055363D1C, 005B55203, 03D7585AC, 0470F8CEB, 0D8E59D51, 03BA17A5A, 0E10A7030, 07C51B927, 041E68DFE, 0FEFE0783, 0944ACF42, 0B4C6E089, 0E662B3BE, 0CF655ADE +dd 0BAB7ADEB, 0488CAE0C, 0BB0323C2, 03F440882, 0849B4403, 0337298E0, 03F08E9E3, 094AB9901, 0C25FA686, 038E55219, 030728B53, 0B10F7C80, 0F8B2119C, 0B44B6B09, 0BF0FCE56, 055C413DA +dd 01D1FC384, 017245941, 0C24D3841, 0148D1E26, 0F8C725AA, 0D089476F, 0C8023BC2, 0C3C2AF58, 0465BD694, 00861A895, 0D1706A2F, 024C47BA4, 0B404DFCE, 051924E44, 094560C6D, 05D392E31 +dd 042A2B254, 0647326E8, 02FDC0370, 07A718D1E, 02E87D9EB, 02B88C339, 002AE0930, 0600D7684, 07B0DD3C3, 068C76A54, 03C223640, 072D6BF88, 08427AC23, 05683E3CB, 03F33B01C, 0D9B691AE +dd 0ABDE9556, 0E0AC6853, 0AD41394B, 0E4FC2ABE, 0A613CF01, 0191D5C5D, 0D4AA4B6B, 06491A5EF, 03AAB20ED, 0EB4FB22E, 0C95ACD80, 0D1586D0B, 0C3ACFA74, 069DFD7DB, 079A0BD61, 0A090A28A +dd 05D4984C1, 02927BC1D, 00AE2C636, 0393AAD06, 00E16DF01, 052E0C079, 01E31B5DC, 02A412502, 04E322473, 0A16255A3, 0BFEC50C5, 0E72B551D, 0AD1A9BAA, 0814A456C, 0B8FBF1E6, 09DBFA514 +dd 0783CC751, 0DAF24838, 0B38E6CF3, 09BBF1569, 0BC654CE3, 09869F025, 0C6DC0B1E, 051678258, 0CF8809B1, 0619B577F, 07C689880, 01C6FB3A1, 004E5CA32, 09FA23C55, 00342D112, 0D8C9DCBF +dd 022ECAF2D, 01F8650AF, 0D45D1F88, 0C2A207E1, 0F1CC020F, 07A215E97, 078EC1C1B, 0AF5C337C, 092B51190, 02FC410ED, 05F89A178, 0E128445E, 00FC4D089, 008873C89, 040A1F781, 085122338 +dd 0E71F9238, 0CBAA6359, 09DD6BAD8, 00576AE52, 0C7A8B3EB, 08B615249, 06FFE68A9, 00AE33B40, 075360056, 0CBEFEB24, 0355B4DE9, 059520985, 03A04A85D, 02645787B, 09FE2FD64, 0C13D6A9D +dd 0DEB74991, 04C711726, 0DE67C93E, 09569AACB, 0284015C8, 09488C0F5, 0E5F88E28, 0D156DC31, 0D930C5D0, 0AC0A6BFC, 0C688D351, 06FC7C9D2, 038B3647D, 03E541E5C, 042205B68, 08E6EEA85 +dd 060BEEC9D, 0AD0531A1, 03B425278, 0BE429DA6, 0FB79BD0C, 06DD0B76D, 032F954BC, 027E008BD, 004FC0140, 0D1009628, 020D0F86C, 085FA2738, 09F618254, 0899CA20F, 096382189, 0202CF139 +dd 00DA10C5F, 0866A845A, 000BB7B0C, 08011827E, 045C23040, 007FF8731, 06B69C219, 01CFD890F, 08BC9FAC7, 09E5519D7, 086612E83, 0F43FC3A2, 009DAA55A, 0BCC17782, 069700C74, 04847C3AE +dd 0F1CD14DB, 0ACD9702E, 023F909E2, 0C3B8DF7C, 0514DA0BC, 0B51444CF, 0E2D56B99, 09B1CF8E9, 033135FA4, 08C35395A, 0F93FC720, 09346AB65, 0BD52867C, 04E4E59D8, 078F0992C, 03D85307D +dd 05A04777F, 079DDE512, 01B2695DE, 01F55A4C6, 0473F070A, 09A6B19C3, 03A781B69, 0815DF0E3, 0BCB9BE17, 00846231C, 0B216F645, 007ACA545, 0ABCB40FD, 0F83E938C, 08D6A44CB, 0EB35704C +dd 04DEB6953, 00B6E811A, 0F563D9BF, 0980644BF, 0EF9B4676, 0CF878A60, 0CF753538, 06BA46267, 0D49DA7C1, 03A69867C, 004E42C11, 0C3ADE8F1, 0E35BA74E, 0E8998E10, 08602753E, 085ED44D3 +dd 05AC8C0D6, 024AD463B, 0889BD333, 0AD0C1DDA, 0305BC34A, 00CA5B81D, 0A43946FB, 05FA91E2F, 02B2611C9, 08256D3A9, 0594ED0F5, 08EB55523, 0A0D6ACB4, 07A2BD289, 080C06F5B, 0CECED4AD +dd 0A90D2AA3, 0599BA732, 013E45E36, 0DD358B30, 0598F0369, 0DA88C5A2, 0A5F80E18, 094EA5F5B, 0CE9A6726, 02A4DDFB0, 0648A4D96, 0C3498535, 0844BB690, 00E10755A, 019595D52, 09C0CDAA4 +dd 08D66C649, 0E9322D6C, 071B5E6CE, 09DCF3C25, 0FBFBBE6C, 08CD9082D, 0BE38D628, 0A7A7E77D, 05E1271F8, 0C8FB5885, 04F2F50B8, 0E83C119D, 0AA3F5B19, 0E559E47E, 091AAD265, 0F469356F +dd 04B207D62, 057F3B15F, 03B5C5C59, 0C1867AFF, 058AF9815, 09224A59C, 026649CC9, 005EC6ECA, 07A535ACE, 00AE3DC55, 099A70E6D, 0D1D28096, 036557E08, 02783538F, 0903FAA1E, 0E5A2A91E +dd 07B56F011, 0826BC573, 09B41B6F3, 0B3ADDF49, 0C7D49A9D, 0EFC253EB, 08AFA9751, 0E38F7F67, 0E5F1D152, 003F03190, 040DE55AF, 056447272, 09F1A49B8, 0970F5D29, 071BC8FBA, 04AC47525 +dd 04D2A3A12, 01302D37D, 0120755A1, 03E19603F, 088CCCF7C, 09AC9EDF9, 088F17951, 04AF9354F, 006AED256, 0DDF3B8D4, 0655D13EA, 0781D6353, 044E49E54, 052225109, 0673B7E05, 0CFBE009C +dd 055BA2830, 031C64D9B, 0D1717269, 0C51D1E1B, 0095C62DC, 0F923EBB4, 0AE53A038, 0CA6C5BAD, 00D9F5B87, 004CB6436, 0642DDB57, 07B31D92A, 070D3149F, 059497D14, 0937453FF, 00449E1AE +dd 0AD4B7DB6, 0030054BE, 01751C327, 063CE666C, 03C63F2AB, 000BE07B4, 0A407721D, 060C3E8B1, 0E6C6815E, 09D6D5A22, 04E4B510A, 0FEAD5576, 0AD587ED0, 02B284872, 029FAD775, 01AEF3CAA +dd 02EF4B88E, 0B0B80E9B, 056E4075A, 0DE0EE8C5, 0C38F528E, 06D4FA966, 0A5970CDD, 008EB3D06, 034F771C0, 0BC394BDD, 057F4DFEE, 0567E5890, 0042B26CF, 00FEB4A29, 027B1F0B3, 0A4B495BF +dd 0DE2ABDE8, 0937754F3, 0C2303232, 05E75F550, 0632A4D36, 035974285, 090B70F31, 07C58D4A8, 0BEA7013F, 071FCC6B3, 01E6C5B54, 031A9976A, 09A2263B8, 0B8F7E3A4, 07ABA14CD, 05536A304 +dd 05EE668AE, 08A90E19E, 034BB9F24, 07E2DCF92, 0CA8747D2, 09793D918, 015FCF38B, 065ADA990, 0DB775A39, 051032F62, 0254AD0C6, 05648516C, 02C92A69B, 09F0B9D0F, 0694C271B, 0C2F35468 +dd 0BD029FFC, 04D7BE1CC, 05262C249, 01A213CB1, 0368E0BB1, 06ADD6059, 0CDB2E1DC, 051D84147, 0258AF900, 0B3B3577C, 045AA36FC, 0AE283972, 05C5EB588, 012C0509E, 03451976C, 0E76EC328 +dd 0E0D90311, 01B53A29D, 043E9D7AF, 0962D8358, 08AEC120F, 04D400A15, 0F855C133, 09A343CC4, 08D8B0E5B, 0650EB8DE, 02AB78B2A, 06CE32826, 0917F95F5, 09BE43195, 09C6F681A, 08F1A0BA8 +dd 08F20111D, 03410A64E, 0DE216328, 00FBC7283, 03BC6024F, 07CC7CF2E, 0840AF597, 0B401BEFF, 0F70CC431, 015498B40, 0B0CFC54E, 0FEB51899, 07DEF059A, 0E6856DAD, 0C898076E, 0CF055EE0 +dd 062CD1A2C, 0FBB9508C, 0C1633A9A, 0723E78C9, 0A9B9D867, 0CDC8C9B4, 0DAF1766D, 0A7A6C48D, 0AC50E631, 081D20077, 04B35E1EE, 0D6B360A9, 08B60DE4E, 06C852E01, 0A9CB893B, 0B058E5C1 +dd 06DF83C7D, 0D07C7971, 06831643C, 0AAEB55DD, 0018C2B2E, 03B906A7E, 00CFB4CB8, 0CE332DEF, 0ADA24746, 098D568F0, 0E542FBCD, 04F74A0B2, 0459B6F63, 0F3218BE1, 097BB365D, 051736012 +dd 0F84F3C4D, 0CEE0D672, 071E01933, 0E8CB3C6F, 0AB009ABE, 05F838A8D, 0287202FA, 05104941C, 0CE6CF6E1, 05B51B837, 0A22DABE4, 0A362D76A, 06F7D7F98, 059AE9F5B, 0EA0492BA, 075B4776F +dd 073974FB1, 08F9353AA, 00D32C583, 09F4DADBE, 0FF2B9467, 00C93686C, 0464A01C2, 01D775A18, 01DB08682, 0375382AF, 0DB506E49, 02D9FE669, 0DC790A71, 03191E9FD, 0E196D59F, 0A6DA75B0 +dd 03841F1DD, 0153B531B, 01073536A, 0BFA6B11A, 075820BD8, 00556DBA9, 00C43D4C6, 04003A517, 00AB9E4F6, 085966AEC, 0E8D7E246, 0CA81F344, 04ED7CFDF, 0588399A3, 02E5F4347, 06ACBD369 +dd 015DA9255, 088E62034, 07778D7E2, 0FC4D85E9, 0418461B0, 072CDC4FC, 0E6A04852, 0D3AEAA06, 01FF2F897, 06C91E05E, 0582A99ED, 0A916546E, 07825F2A6, 0EA86F1FC, 0FD12E17C, 0653580D7 +dd 0300A54E0, 06B733C44, 0F36A4D8E, 0F1DDD5A7, 0B1431595, 01C4D7234, 0F6FEF194, 0792B3535, 0EECC5D11, 0D5A31633, 0E73C2534, 0A71C5AD6, 0D39ED863, 08787800E, 0575EFD77, 0E053E1BC +dd 0B4CCEB7C, 0550DCCAB, 01023AFC7, 0DD3064D6, 075A413DD, 0CCC990CF, 0326688B3, 01C230963, 0F7EAD61F, 0808D9D9D, 0AD6D537F, 06224E113, 09634753C, 04F19D91C, 0635B16BE, 0EA6B46A7 +dd 0DF01E408, 002DADA4F, 0AF2DBE86, 0D1366FFB, 0A9B5F8D7, 07B46CB37, 0682DDBEF, 0EFA835E7, 0EDD2856C, 0199A9A09, 0ED6EEDF3, 085D513E8, 0F4BBDB78, 096A67BBB, 0255D72F9, 0B2AFE963 +dd 0FAE301B1, 02A9DACB4, 01A6D0EFE, 0F6AB81C8, 0DB085A6E, 03AB30DAC, 06450AAC6, 0069F75B2, 090E84357, 0387BD699, 0F71AA6D5, 0C989C62D, 098ED4D4D, 0A7A46565, 0DC2C6F82, 0568586B6 +dd 0C2CD2FE2, 0AAB99272, 06C9833AA, 09CEAD112, 065CD70D6, 02682D6CA, 0093AC67D, 02DD0BDFF, 0314F6E95, 0CBA88CCE, 0AF260624, 0BE1A66A4, 09D0819CE, 03A1464C8, 0D9F5CE57, 022A49EA8 +dd 0B873A458, 00D1ABC75, 0CDC26E5F, 0DBA30F1E, 080DAE5D4, 00A923CFB, 0667C5EE4, 068637092, 0041356D6, 0797D74AE, 09B71E55E, 01030EA45, 02D768D7A, 0B4382C9E, 06EE7455B, 0A1C2BA3A +dd 00A9D44DE, 04D414E9B, 0BB44D520, 081A61F4D, 07AE56919, 07183E9F0, 0D4FE69D7, 007D1430A, 031BE6659, 094BF00BC, 009BC18C7, 034344EC1, 02A9AD7EC, 0CEBE1B33, 0FF3EF434, 0F4B2AB74 +dd 04F530DA6, 050ED01BB, 093DA8AD5, 0D5FC2AA6, 046626DA7, 0E87FF4ED, 008CC3F1D, 04E2DDDB6, 0580DC00A, 00A5A9784, 092B3C4FC, 0ACE138A6, 0C8686D55, 0E5202D4D, 02FE71333, 0C60C42E2 +dd 0B56BBB2E, 06B1B7788, 0E585AFB3, 0DB9AFA02, 0F51A7531, 01F07859A, 03C079CD5, 08890CE25, 02A776217, 04ED0793D, 0ACE2EB91, 01D303578, 0CF78A742, 0D9B76157, 022F53841, 0A3BF2F0D +dd 0209D8356, 074359FC3, 015B9B39C, 0AE8EDF21, 0ADEFE046, 05A0D76FB, 0FFCD4C4D, 08631FA24, 038487493, 08F7B0415, 0083010C6, 0765DB567, 035DBC94D, 0AB4106E5, 092451E5F, 0B8A73547 +dd 077FDFF3B, 030FA8EB3, 0AED15857, 02E9998A9, 0B8CAB2B6, 018316648, 090622FF1, 073AB408A, 0C474098C, 0BFF0656E, 051FAE6F2, 01A135C4B, 09370E03E, 0019F96CB, 02F832BAA, 07D535ED1 +dd 05F60F56C, 0FCFEE267, 0AE4327D3, 0BA807E0A, 04E3D07BA, 0B9105767, 0434AE19D, 08BB89369, 0708A83AE, 02B42916C, 0331F6D55, 0F738BAFA, 03CE08CE4, 07B794961, 00083E767, 023F0593F +dd 015E9B6F0, 0F4558ECA, 0B269A02A, 0508C7DD6, 0B1989EAD, 0529468E9, 0ACD83E1A, 03A92478F, 00B9EEBC9, 0B771C78A, 028DE4722, 0228CF7F9, 06B20DBCC, 050B449BF, 06600703C, 0AF63CD70 +dd 04E102BA9, 0F0709422, 09B4BC7C3, 0E24DDD74, 0B9BF0C1C, 003986CA7, 0564A5B6E, 08900CA6B, 06276160D, 080CE87EF, 0E4C836FD, 06D14D413, 0C10BA15F, 005DCADDA, 0E0B0064E, 0F6AC1674 +dd 07E11EBB9, 0BE539F77, 0636A926F, 0D78164CB, 0F55548EE, 0C5EAEB9A, 0E4F22C5E, 03B462B77, 0A269D26D, 03E926D3A, 093AD3AC6, 030C29BA1, 08B85383B, 09080A3B4, 0E97D1E7C, 0E286B4B6 +dd 029C23FAA, 0050E3F2E, 08E0A9C67, 0ACB70C6C, 0502B193F, 0ECB1082D, 094184E72, 067CFF9AE, 0A7B90C62, 08A717856, 0BEC8F34A, 0B3E29921, 014FC444B, 0E02901DD, 04A9FF092, 0426BB869 +dd 0B5955C67, 05C348E94, 0C256103A, 02CC2D5F9, 069382832, 03D92C74D, 0FE391DF5, 0CEFABC7D, 05AA89A39, 0F3C016D4, 09D65C831, 035148494, 023E9A163, 0D1D326FC, 0B395B4FC, 0FD08ADFD +dd 02355DF84, 0FEAADB4A, 044512504, 061253FAC, 0DDE5DCBD, 0E09107F5, 0A358F138, 09918D133, 0885FCA6E, 05A4C1BE0, 056FAD14C, 0A143C249, 08A07D3C3, 011706824, 057F82C66, 0974F0FC0 +dd 0037FECB5, 02E58D7A7, 09005707F, 0103DD26B, 0E478D1A9, 023995836, 018D9F469, 0AAE5B977, 03B6EB493, 0BA6575BB, 002E1154B, 02262DC68, 05820CCBC, 0133FE18C, 0523F0196, 023229DDB +dd 05678F369, 0D3379982, 085B7C77E, 087EB7E84, 0A8432A49, 031325050, 0E70F6DD9, 0C703D54F, 00FE3F3B7, 0800CADF8, 03337EDB4, 02A556FA8, 0B41AD775, 0608B916E, 0C55BC95C, 0B94A8EBD +dd 0D5DC5FC5, 0797AC0A1, 0A068206E, 0069E06FC, 04F557A8A, 02752826B, 07CDD2B1C, 01FE63244, 0C6BDD61A, 029CA1DE5, 03F05ADE2, 0B924E286, 061F14B4D, 06D261696, 018E01315, 017129D7B +dd 0942F5570, 04F61A273, 04040935E, 07A2F250C, 036212C55, 0B29BD514, 03C2B3271, 0790F50E2, 0470CAB9C, 0B1F8095B, 0D3B49188, 00745C2D6, 04F815C2C, 0554A5183, 07B78F9A1, 06DF08097 +dd 0841E6C7F, 0DA313361, 08659698E, 0670390FC, 0C0434328, 03EA61F13, 0388C9EE1, 0F8FA7D77, 084B49DB3, 07912F264, 0A79A4BBC, 010AFAABE, 019EAC66D, 0C63C1976, 0C66E3CF4, 02482775F +dd 08B86B66C, 0227D59BB, 023E3ADDE, 0704FB79A, 07637B7B9, 0E3D4F188, 01AE78BD0, 02EBF1B1F, 0E0B456E6, 0C6A6424C, 09854AB94, 07C69C6B2, 0809A03B5, 0A522426E, 07CD45A02, 0AA0AF438 +dd 0909B8C0E, 07E165ACC, 0F987B48A, 055544E4E, 0B09B76CE, 0B6746582, 05F20DC7A, 0CC75C165, 0469E9257, 01A8DBD6E, 0375DE791, 0C22C8687, 06897B995, 083215DB2, 04A941214, 02831A707 +dd 0EF937985, 0497031CE, 02443CCCA, 02A30CFDB, 0ED48AB22, 0B13AF864, 04668EED4, 097D19395, 05B29EC71, 0E02C550C, 01A977925, 0C34DE8A3, 0818F9287, 04D7C3FAC, 0C63FFDEE, 0FD6B0874 +dd 050733693, 08706B76C, 035D43CBC, 0605F8382, 092D46DDC, 0383C9686, 00E9926C9, 05D2A4E1D, 0B6513D2F, 0F15D9192, 05302F196, 07981A7A6, 0BDC1AA3E, 0AE039847, 0B3F36AA4, 0C33510A6 +dd 05F0034FA, 080B9B275, 05B09AE3A, 074875A64, 06F095BB8, 0D1D81408, 03A0BFAA3, 0518C8308, 091B8CFB9, 049D0CE45, 09BAE0E94, 0FE6B3564, 042DA8DC1, 03A7311C5, 019B5635A, 034242FD3 +dd 0A93E8DF2, 0ADD97659, 067D0DA6A, 063EEC81C, 0AF349B80, 099E96AC9, 02111F5AD, 0D0FE5F4F, 09446E2A6, 0A375DB4D, 0A52E3B26, 0F82A4499, 05E852E75, 0912D870E, 07A75C501, 0CC8DC811 +dd 017F5C3D4, 0D4840E72, 0F1B7BA6D, 00C81F848, 036AA6DBC, 062620928, 054C88B51, 0270CEF5B, 0E2FA486A, 041B1E0A8, 0A0677895, 0EAC7349E, 0213509C0, 00D1A9B4D, 098BBEA0C, 0ACCA7C2C +dd 091DB3758, 0E9C09AF5, 039C0C0A5, 04ABDB74E, 0216855ED, 08A911AA3, 039FD90AE, 00AB645A4, 0EBE2355B, 07DEB8FC4, 06EF63662, 05EA3085A, 0ED76FEF1, 0B0CD6C38, 0A4954B93, 0DBFD0D38 +dd 085A2B7B5, 0F0087FAB, 0331DEBC4, 0A6E369F5, 080F516AC, 09BD21BB7, 0312938B0, 0E68887A7, 0D16D880F, 0DFBB841A, 034E54126, 02A50C3CF, 0E7928D1A, 020A99CD1, 062A3A921, 01247ED8D +dd 08469542B, 0FB956129, 04DABC9A4, 013486A24, 03A6EB67A, 065B8948C, 02DA732C8, 02BB9F515, 04E0A3F08, 01CCB170C, 0DCE31236, 0BEB9A18C, 065354442, 01F9B2FC5, 0B72BE3B7, 0EB05395C +dd 03586DBF5, 0BA6932BC, 01A6200C5, 015A89698, 0B3724884, 005420345, 0C007B0FC, 0719F1C9D, 0ADC94ACA, 0A820276C, 0BB699362, 0D54544A9, 0BCDA8CCA, 07D4745A8, 034E2D0BB, 0652FB4FC +dd 0C7B3F60F, 0262A79CC, 06C5F836C, 00726EB0C, 04756ED61, 07CCDEE6E, 08B7853E3, 017181C59, 09961C75B, 0D9DB5EEB, 0C4FD37D0, 068613C7F, 08F7F8153, 003176E54, 046ACD330, 04CB48CCB +dd 049829935, 0A98155BE, 0C2FC0E9C, 02F7FCD92, 03701F59F, 097BCB4B5, 0AAA01A82, 0D63CE348, 0D177B6A1, 0488D33E5, 0AA8175DE, 0AB8193B4, 0A3E77BAE, 07924D51C, 022A2677A, 0B6ADF1FE +dd 001969B05, 07D4529F9, 0B81A5492, 058ADFA49, 0641ADF6D, 01B763720, 08C60B886, 0FF9DA98F, 0B77044B1, 0385C24D8, 01DAD4650, 0A6923AB6, 025AFEBB5, 00AE0E908, 030339458, 07E766F3A +dd 0DDD3B1EE, 09DCA6D82, 0D36325D5, 0FC79CE99, 0392F6BCF, 09F7FD9B3, 00008CC5F, 0C5E790C3, 029DDD0D3, 0533092EB, 0548B7F27, 0C27B21CD, 0B610D67B, 0CF616ED4, 042C559F0, 0988064A4 +dd 01EB633A0, 0EA2BB883, 0AC658B59, 0BE698175, 047C8A936, 02CFD2427, 096195C06, 0F2DBAFC2, 0930BEE30, 054B3FB96, 0AA9E25A7, 03B0D45FD, 036B553AB, 0C7AD0B07, 004315D56, 0D191E0FB +dd 085A0EC94, 05F741AD2, 03ED49E28, 0BBBB4151, 0C9415586, 0D0557898, 0D14FC3FB, 0A6C5D300, 085541DB2, 086495378, 0D6B5A2F1, 0E7E0B4D3, 0941FFCE9, 02ACF1B1D, 076F50E50, 0AAA90CAA +dd 0F5B24FBE, 043EF6A43, 0CD62307F, 0E81FC120, 04CA032E3, 0207D9D83, 0CAEB4753, 061E1812E, 081FC7DD5, 00CDBAAD8, 029453744, 0936E994B, 0318842B7, 03A32D14E, 0C5F0E81D, 0B70B18D1 +dd 04E90F902, 0827DAB0C, 0049A9E3A, 04E6493C2, 0D62C80D2, 0D4DFB1DA, 0F87EF43D, 072E1823C, 090ABAB40, 0D41E5C39, 097FE6B9E, 096014D1B, 0611E9945, 03EE8874F, 0E826EA85, 0365D4CB7 +dd 0B51B9E4E, 07495752C, 01FBABC1F, 033EDEEB2, 001B83883, 070F300CE, 08BAB1E0A, 058BCA070, 0DBAC2938, 053D05BD6, 01A4A518E, 0D2AC5992, 083B1BE2A, 08AA39F53, 0772462ED, 089522AA4 +dd 0DA9AEE7F, 00D75139F, 0979A9539, 0EACE51ED, 05F8B9534, 0CBB21EC2, 05055A2A3, 04C661A3D, 099F18EF2, 052DF92BB, 0A425DBE9, 056A52637, 0CCC018A7, 0DAD99334, 09091B40E, 0C646A065 +dd 02B9F4516, 0FF656E99, 0709E632E, 02E529013, 0FBC84435, 0823A8888, 09D5CA539, 09E6614A2, 04ABC5C4C, 07FDA6FA6, 00525C131, 02E8666C9, 0ECD4AF0F, 06298B29C, 0A24A662A, 08D0F1021 +dd 0D3E7B8EA, 02B2AA92B, 0C95F8E8C, 09D737C79, 005B0FA20, 00EFB1927, 035BD3EDB, 0745D7CCA, 01CF8C570, 0BD1679F2, 04B67F8B3, 032262B51, 07150942A, 0349A7AC3, 0F98C60D9, 0906E764E +dd 085B16135, 0C3BB8147, 0F9AE0283, 04092AA49, 04FDC2929, 0E2328A8E, 02A04E5A0, 08821D729, 08B616272, 0E85E7AF0, 06489BAA1, 03E150CA0, 02289A1E3, 05151EF27, 0E9D438E8, 08CAD1367 +dd 0A84D03A1, 09C2C24B9, 07EFABB28, 07BA50720, 02EB9B142, 0E0A54FAB, 0B5662897, 05E0D7E1B, 04F6A3E59, 008BEB5AB, 04FE04F91, 0AADDB57A, 0990F8D92, 046418393, 03410FCEB, 09B2A70ED +dd 0536346EE, 0A332FC5C, 0C5E04D9E, 094E18E01, 012D831D4, 042DEBA32, 055803E3C, 0C9906C27, 0A73C6916, 048897086, 0D84CAB0B, 07621C344, 03B04723B, 06498E58B, 01A514A8B, 03F23D953 +dd 00A9CD934, 0AF12BF66, 04AC64754, 05C36E31A, 0209F30B0, 0C5A63154, 0DEE3B9F2, 09CFF76A5, 0F03476A0, 086BBFD46, 09722D29A, 01E0462D3, 0CAAD1636, 0D3B7C1CC, 0BFD13980, 076610F14 +dd 0DF75A48C, 0EC1CE249, 06DC67149, 04EE35C3E, 0988CE14F, 001EFE0EE, 02739A29F, 0DC09F8A1, 0DBE4C89D, 0CCD3B04F, 021F802E6, 0086100B0, 052100C2C, 088690A9D, 0D1838ACB, 0210AC7BA +dd 0320CBD5A, 041B06179, 0BE05888D, 090E30D89, 00BE107BE, 0C450C805, 0E62415AC, 088B8D079, 092FDC85E, 0C47DB431, 051A4B404, 0A06FDB09, 07BA27C3C, 0AEE78201, 0A329F0AF, 0A3837880 +dd 0A838CBA5, 004C15254, 0E3971416, 0947B66C2, 0B312CBE5, 0E7910259, 0F8D990B9, 069685375, 0B4D15C95, 0055A59E5, 0DA991765, 014583C73, 01C255107, 0635F218F, 025EA63C9, 086C38B18 +dd 0A2C2DD90, 08EADEF15, 0A1AC7344, 00AAD0E9C, 0565266DC, 07844DA8D, 02053E710, 06A10B705, 042CB8F09, 07AE55C1F, 0357F8323, 0AC420665, 08A222552, 05C74A8FD, 0CAA3E20F, 024C67145 +dd 071E7BED4, 054318559, 06A903E7E, 0E6B40804, 0A6A886B4, 0067D9863, 0ED6263BC, 0C41C8BB9, 0025B87E4, 0025574E3, 0BE3A3A1D, 0891CAC17, 0AF3C4CF4, 0088819CF, 0A13C6059, 007340F95 +dd 021484E56, 0C11D0358, 0B9F21F66, 0769FB383, 06A9D854D, 05B8CF37D, 0E5B2ADFA, 06D1859FB, 05756BD82, 02265858E, 0ECD40A91, 0975E719C, 018DE37F1, 04F017098, 07E6578E9, 099F34394 +dd 085061D51, 0F46ADC7F, 0A6B74840, 0D3D563BB, 0A9C81AD9, 047194496, 02AE5D5FB, 0AA7675F5, 0406699F5, 0CACF585D, 089BC8F4C, 05C26FDF3, 0C7897903, 06CBCC787, 014BA01E5, 097F0B25D +dd 09AD5B9D4, 0F7415942, 05FD62D62, 0E6A521AE, 0405A7A0E, 0A990E12B, 0DBAEAF7C, 03931D282, 0CC7664B5, 06BD59CCC, 0AEB068EA, 0CC450999, 0A934D5B2, 0CC1B5C28, 080353D95, 0FC2B5AA2 +dd 0688BB6DC, 005F1146B, 0173D3022, 062B99965, 08E9E9416, 077835322, 0DA58C923, 009412818, 0EAAF04CA, 08A4D280B, 081D9D0FF, 0C964183D, 03D345329, 075199C06, 0E30470F6, 0BEE1FE50 +dd 0B69BC5C6, 002F7FD93, 0AE9C66C9, 09415C631, 0CB0B2A2A, 075AE74D9, 09F9135F1, 0E4A98AD2, 08750076A, 07AA852FD, 00EFBE0C7, 026B29342, 0D7BE9528, 06BD81704, 0E2E8C1F8, 07D583A42 +dd 0C1E1C1DD, 0448B4919, 0FD8F584A, 0D60CE6BB, 0495926C8, 00BB41551, 06B520AF7, 04E528718, 03432C6C7, 061DC6375, 056AEBEC1, 0A43CC224, 08593EE35, 03BE80973, 0E6839BC4, 0A35CB7FF +dd 010D83EA0, 02092442A, 0C6A5A5EC, 051A213A5, 0B4DE5053, 0C08243C8, 0DCE6602D, 07465A6B6, 049542E31, 00D5D927A, 09A3FA59B, 01777BB74, 065E4BD9F, 053F18D52, 05B6D00D6, 0A8E044D2 +dd 0E907C9B6, 0242AD044, 0A650387C, 0A4EA13B7, 0AFA4A79A, 04A1034B3, 063F9EABB, 0CB831AEA, 0AB8D2329, 0C075FF75, 0E2B81815, 0AFB54D47, 014B1F16B, 02588D2D0, 095248AE0, 02F2EE4AD +dd 04BEF0B5E, 0AB5CCD4A, 0DFE371A1, 0687ACDE4, 095D3C17D, 070363E98, 0BC249610, 06A8FC70A, 0E7DCB87C, 0656C53F7, 068A8DE5C, 012F215BA, 00E4478E5, 0E02AAA5F, 0188DF7DE, 04D453F01 +dd 06AB7AF03, 0CC85EBC3, 04EDC95AA, 056A68747, 0DF4062FF, 009C9B1AC, 0032F2FED, 0C427F2DA, 0B1D08E80, 0102090C6, 0F786A6DC, 07DEE035A, 0A71B53BB, 084D5B0BE, 03D25C4CA, 002C25052 +dd 05852B0C1, 047AA10B6, 0A5794DA9, 00E15D5AB, 06B4E70F6, 08CB6AF0D, 0084F456C, 0E66FC2A5, 00BA6B995, 08291B9FD, 0893DBDD7, 0EC9D4F09, 0A77AB9A5, 039979AB1, 0CB82E17D, 0B6932976 +dd 030687892, 006355261, 0930B03DE, 0C12E7352, 05471177B, 0C4D28E3D, 0EB3DCB98, 02CF66B70, 01B7FD5F8, 0F236556D, 0B48CC919, 06906D097, 00E882FD2, 0532836FB, 05FB58241, 0194A85E5 +dd 08C31C998, 019223875, 044421F15, 0524EA03D, 005A875DB, 015794A48, 0C6F65ECB, 060AF3EB2, 0FC6937AF, 08D73C2AC, 05C556922, 058079E5B, 03B977707, 04AADB105, 07C18ED93, 0ADF3055D +dd 0CED4693D, 0657DAAFF, 01D2C1979, 0B3C40501, 0A09AAA94, 0642774CC, 0E0B0AFBC, 0954E0784, 05BF2F8DA, 0B43DC0BD, 02F2A524E, 02B90BD6C, 0564E2E0A, 07ED13043, 034A72DED, 001CD1567 +dd 01D8F26AB, 007A262CA, 090CAD506, 0A8EB777E, 073288F33, 0EE857348, 05B054C52, 02802114D, 08132613D, 0C8B15BCB, 051E37809, 0BDD496DF, 0FFA52793, 0E2E2E090, 08E96E2EF, 01A750232 +dd 0B336FB22, 0CED574A1, 011E2A6B2, 03D8BDBC4, 09E71E846, 013B6E8A8, 03EC646C1, 0046C9148, 0446D0427, 0FD96F05D, 018B82616, 09929525B, 08D278C01, 03FFE9E78, 0A13D3692, 0EDCA5606 +dd 04964E023, 08358BDC5, 06B741BCC, 01B33BD08, 04B830F2B, 0FFFB534F, 013D6ED31, 04F09D332, 01C5E3A28, 0FAA04DBD, 0F2871638, 00571AD48, 003D16F60, 019E98CB2, 0C2A31CF4, 0FB22C21F +dd 0F477EDF0, 0AC8D1B46, 035A26C06, 0FB536680, 0C5470870, 062208414, 0E9D268D1, 02B348C65, 030184138, 046FA8548, 05E2C7600, 06383E96E, 0CE30762F, 04BE1F402, 0EF236AA4, 09C970C72 +dd 0FEC92620, 0AE6E6D0B, 0EEF37C3B, 04E5C9B4C, 0A97064D1, 03386D6CA, 0EAFE596F, 0A80DA1F2, 0531174ED, 074802943, 0ABBC582C, 01A318955, 0CECFE77E, 00E2AE838, 0A00E214B, 05FBB2CA9 +dd 0F3AF279A, 029899B18, 0A7D3420F, 0F2E9435B, 0832838D6, 0468C0F21, 0E840B85B, 0224C7B44, 09413302E, 02409D615, 0ED1E3D0F, 028EE8448, 0DE465C7A, 0BC4EF320, 0C3D42E40, 0B60EAD0E +dd 0BF647B01, 09554A6E1, 0A2C9CD52, 04D4078D1, 0F37D2111, 01247F3C7, 00EDF86D4, 0544654CA, 04192D4D0, 09E1B53B0, 04288C446, 0B5807701, 09C4E524B, 0380963CB, 04271A76E, 00B71303E +dd 0D68B76A5, 01F9DCDF0, 05CB88936, 0E0F7C327, 092E2E746, 0EA4F1704, 09D61D36B, 082211F46, 0870F7F77, 09BB256FE, 0FDF1D1D0, 033513E35, 0BF553726, 09962C03A, 02443E96E, 084E63DC1 +dd 0FC447875, 0DEDEDF8E, 07F289CDE, 054326FCD, 09A81764A, 07ECCF99B, 03D34BA98, 0F92A480E, 0C7878780, 0664E109B, 01844FC08, 01413C6C4, 0D092A470, 07E1BAE91, 021E12E6B, 0C1360828 +dd 0D2C2FFD0, 053A7D926, 0828F77F0, 0C1ED8A87, 0735DA2AE, 043EF9198, 06AEE74E6, 0DF558B68, 0DAAD2C25, 03F380450, 06181FD8D, 06C1D23CB, 095759B53, 07E7CC4DA, 03BE9E26D, 0BC9A50A7 +dd 0ADA6E64E, 0E782A805, 03FAD2385, 008369C09, 00B7FF6F0, 0981F1F39, 084FE207F, 03F8182F6, 031F87B46, 074A40EA7, 0ECA4C205, 09665E3CD, 0D0170317, 0B454E4E3, 0306AABBE, 0DCA9381A +dd 05ACBC338, 0F9A37C41, 0023D6A9C, 0E87547B6, 0FE549AA9, 01CC1BB92, 05732E6A7, 074756CEE, 06999D2A6, 0CC8C22AC, 0B1C1A319, 0134A04A7, 0E3A4DB6C, 0D8FF1CA7, 0A03E89EB, 08531267C +dd 01AD6858C, 0EA212597, 01ED34EA1, 06F7960E8, 0B0ACCC92, 0CABD3281, 0186ADB0F, 063F98D13, 0A73C288E, 0DDA4DB0D, 03A25C4B4, 0D10A67FA, 0BCB737E3, 0079D2FB3, 08736D9EE, 02183BC28 +dd 0D9880B73, 0C92AC64C, 0EE7962AB, 09CB1ED53, 09467152D, 0C4C56CE8, 038F18823, 0EA5F8EB6, 0CD800F6B, 0F0E5B4AA, 07F5A478D, 0A761EAE7, 07BE9B382, 06F34EF57, 06EF4A86F, 050DE96DE +dd 081CEB351, 0AD0A8D4F, 03DC2CF69, 07F5EA9D5, 0FDC8DDD9, 0A69980B7, 0C15EE6D5, 04FF9C9AF, 08B8E8AD4, 0BDFF579F, 03BAB9A42, 07E155FAA, 07CD0FD72, 03CBF4975, 0065AC8FA, 0DFBC8B90 +dd 00523AE05, 025B11B66, 07899CB83, 04F0806C4, 0803692E5, 0AA2BBC4A, 0F6E80B4D, 0C4EFDA50, 0F448C3F1, 0EF447D07, 06B7EC5E8, 0208734CE, 0316BE92D, 059D34934, 0931EA79D, 0D69A316C +dd 0263E9890, 053D85D6B, 049FD1996, 042FE7189, 0E962705F, 07205660B, 039297192, 0B09FC387, 0709E6E9C, 06463F1C1, 0FC57D0CE, 08B2AE38C, 07BAD0479, 07D9EEFEE, 044E3E372, 090BE5F74 +dd 00BA41ECB, 08AE62CF9, 080CA7EB3, 0B820D624, 00EB6E931, 02353C0DA, 0614F8381, 03808A2C7, 0E8E2A8F1, 0A0A7AD8E, 0B56DB0C4, 0044A8972, 0FD505C2A, 0DAE06CFF, 0CCB6BE37, 08426E821 +dd 003CC4B29, 0348647ED, 0F9EB0ED5, 0CEAE4A7D, 08E534EAA, 0FC454648, 0ACDF8FBC, 08289F220, 0254F1932, 0EB451C95, 0B74ACB5F, 0DA77BF93, 0E649DF61, 0CF21DF0C, 077B72F7A, 031F830C7 +dd 05007C676, 0FC518ADF, 0AF19E676, 057D2056A, 0D6B3E9BA, 0C5924E6D, 01F2E6CA8, 041F2E591, 0B8F0BDAB, 0378AE39E, 008534BCD, 09A5E194F, 017E9237D, 0DDFA94A5, 06DFCAEB1, 031C39AE0 +dd 0988CBA15, 0D5A5FB29, 0F4D9CAEB, 03434DD49, 05AC85EFD, 0846F3543, 0126ACD69, 04B8BD303, 06D9B5D26, 05B15040D, 0B183715B, 0B1C1E661, 06E9B0EE3, 0AE590D39, 0553D12C8, 0FD5F6EAA +dd 00E6B313D, 08E47503B, 01246C4C7, 0B3EC02D4, 063B04804, 0E87ACED6, 011B5E130, 0DF606563, 068871EF7, 059281D47, 0D1AA2CC5, 0AFAB9F4D, 021C190D9, 0DAAA6FDC, 05C6404DE, 0B4692FF6 +dd 0E3DFBBAB, 0D761D472, 05B176544, 08C57639E, 0003AB77B, 00E015E88, 0DB2F40AB, 072E9919C, 0722ACC23, 01A839AED, 0D3D7CAF5, 09FB4DDC8, 0D28DFB79, 078182D2B, 008FA05BC, 0A793CF99 +dd 027E5D8D6, 00557A6F8, 0ABA65C6B, 0D8414AC0, 062541F84, 007A5C1B6, 05A2A5E6E, 0C70DD9A1, 019789067, 0AE4A7AAA, 0252C4947, 00CF48303, 0C0CEA95F, 0A8ED73B6, 00223AAD5, 03796719B +dd 069E7134A, 0F2C94F59, 0987DBC55, 060702876, 0F1295F65, 0D54D7018, 01802D663, 0A1DAD47F, 09D56B629, 09CFE2B2E, 075EF1876, 04828C40F, 03390C3CD, 05D541EC3, 0E8F0D9D0, 02C338B9B +dd 05DA1DA90, 0502F3C3D, 04F91B466, 07151419B, 0F35AE6BF, 08CEE25DE, 094B44F21, 04BB13EFA, 0A03CABFB, 0EA7440C9, 012F5C152, 0F124418B, 0C5665B49, 016F8621A, 0836279B5, 07765C6A2 +dd 08DB95463, 00DABA494, 07ADCA601, 0A43BB661, 039B90C4A, 06E4C66F6, 0ED53000F, 042DEC9B0, 01FFD6B44, 03D5C65B8, 076994105, 0D15FCFC2, 0E3802357, 0AEBD2CC9, 058B8037B, 05644AA69 +dd 0E6F16A30, 004ED2F26, 01DFBA14A, 058C4D4D1, 096C9AC29, 0A5A72B49, 0AD015DF0, 0EE361AAB, 04B1A708D, 0746EEE96, 009A8A199, 0472EA26A, 0A3EB60E9, 0D706A517, 0EF530319, 0F27A3704 +dd 0842A34F2, 0FBCDAE01, 036C43EF9, 0975A37FA, 04559B5B6, 0B5428CD6, 04E7DF3E2, 0B44435DF, 04D2E350E, 0540A5243, 092EA8439, 01FA2B935, 06C91ADAD, 0EFB74B9E, 0C734861C, 018536277 +dd 032691B21, 0FC0C9AD4, 090B26B6E, 0225C6A9D, 0C05C2C1E, 0B9919448, 078B39B7F, 0933073AC, 03DADAD5C, 01EB8A274, 0FA6A03F0, 00E4A0D4A, 0EAC3F03B, 03179FDC1, 0B792379B, 0CA291F49 +dd 010693370, 0D07142F0, 03D4F9478, 041B5FD4B, 07094CCEF, 011A88895, 01246A262, 0D08A8EEA, 0E717C1B5, 02DF69C2F, 038ECE677, 01ACECA9B, 041E2221E, 0ED76322B, 084D76AB9, 08634B5BD +dd 0CA08E764, 015890790, 0D14897B7, 03031F771, 04F87A5D0, 08D2BDB70, 079F46BAE, 06A1075C1, 018E2E318, 05370EC4F, 019D51528, 08A93226C, 09E0657C0, 01B908938, 0329B3A6A, 02A091F4A +dd 0C3B02769, 012E913F0, 03A4EA569, 0640F0A56, 05935A090, 0A546DFEB, 03E982019, 0355735C0, 0CFC92369, 037BE4D29, 01016257C, 0909FC023, 0EC855608, 00D3A8987, 0B5953E73, 0E0F28AB6 +dd 0B3BC5587, 0DC8B6AF6, 02E8D6C0C, 08CCA298A, 03251AD2B, 0C66ACB8F, 0ECA8416E, 066B013B3, 0E0DD166D, 0D590C68F, 063629765, 0AAD4C06B, 0B72F8538, 00AECBFD1, 04ED61D22, 015F3C4BB +dd 034E88F73, 0AF4AE80E, 0B5899537, 06B1E0EA7, 019A93A86, 0AC6E06BE, 042F3A065, 06F9CAF37, 056474AF4, 004C1BA53, 0E2D95637, 07350D357, 013756F1D, 037570AE7, 0CFC15D61, 08B3730EB +dd 006DB324C, 004EF2FEF, 0A2F02459, 0966880C9, 063E816B4, 0BB2FFAB1, 0B523E990, 05D48B0E6, 0E1264B9C, 03C30E852, 05E971DD0, 04F40BF94, 097D4E0BE, 0C2BB8038, 0D7758DF3, 0B05DF217 +dd 0402F9170, 062FA75D5, 07B0987B4, 00D1BB3DE, 028585ED8, 0AF291267, 0AB47DAAB, 0C0585430, 07B4838CF, 0914132F4, 096506132, 0E7DC39B9, 04EC957CE, 0D26A78B7, 01AE36BA4, 0CF4D0484 +dd 01C157EE0, 04852C6C3, 09D7DF4FA, 0ABD766ED, 0833E7574, 03C512EA8, 034FA1AA7, 0C926155B, 039BBF586, 056A74EE3, 08F415C5E, 08DC13981, 039E3778B, 0EEC0431F, 0C310DA04, 0158A4084 +dd 0A0149CD4, 0958C215D, 04A6C7F3F, 0CD27FDDA, 0A285947C, 030682428, 006355261, 099D4B3DE, 0D26F4991, 0ABB30B56, 0B562AC42, 048DAD5D7, 03A98ADBF, 01B468AA9, 0E40ED5AF, 076F49124 +dd 0AE9B9BE2, 0A528191B, 06F56250F, 07B70E663, 0F6F6CDED, 0BF7CEA7B, 0703EA8C9, 0382871A0, 0AD3CC1B3, 07BD43BC3, 0F299C254, 05D03CCBA, 02691CA4F, 0DC153B04, 0FD95E2A9, 00D0F870C +dd 08E7FFE1F, 0E03F8085, 08ADC9372, 0A3FFAE2E, 0638745FE, 058C49DE2, 05265F28B, 0C1137A29, 08601A4D1, 00DD5166F, 085C6331A, 02EAB4046, 0AAA38EA4, 0EA5A8EAD, 07E24D3E6, 0E7E80E8A +dd 071D46338, 0466E1C81, 0A64427A7, 09078F870, 0DF94F613, 044CDB13A, 0742D4F54, 0E4255FF2, 0F857C8CD, 068C60C63, 0553D0A7B, 079C1D17A, 07A84D644, 0789AB183, 02E0C4C0F, 01E50160B +dd 0A0C1FF78, 00DA417B8, 0684F58AA, 0601DDE3E, 09B781D4E, 001A4C726, 0225E19F5, 04B728A72, 0283C612B, 08B5D6BDA, 0AF8671B1, 0107B15B3, 0AC7F016A, 0D5D52E0A, 0BC3024AD, 007130244 +dd 0E874261D, 04AB1EAAD, 0BBE7009C, 0AAC2CF9F, 041EF86FE, 02F5522C4, 0A4073100, 0B8F7412D, 010ADA9B3, 0F78704D4, 094BB5D22, 0A4E38274, 0E58156A6, 0C5ABB921, 0011EB1A5, 0D01EEB50 +dd 080C905DB, 06E69737F + +;------------------------------------------------------------------------------- +.RADIX 10 + +END ; end of the file diff --git a/x86-asm-source/rtf.obj b/x86-asm-source/rtf.obj new file mode 100644 index 0000000000000000000000000000000000000000..f8fb79ff475cfa060336a0efc1d472b188862e6c GIT binary patch literal 22006 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 O%~V@Q(G>WX+4>(P`Wwao literal 0 HcmV?d00001 diff --git a/x86-asm-source/sectors.asm b/x86-asm-source/sectors.asm new file mode 100644 index 0000000..894e215 --- /dev/null +++ b/x86-asm-source/sectors.asm @@ -0,0 +1,44 @@ +.586 +.model flat, stdcall +option casemap:none +option expr32 +;------------------------------------------------------------------------------- +; Compressing non-bitmap binary data. + +;------------------------------------------------------------------------------- +EXTERNDEF SECTOR_Data:DWORD + + .const +.RADIX 16 +;------------------------------------------------------------------------------- +SECTOR_Data LABEL DWORD + +dd 000001000 ; 4096 original size +dd 000000569 ; 1385 compressed size +dd 0B9D60600, 088250248, 0C6202A14, 0065321BC, 039180C04, 09100B440, 0329B4DE4, 01880C267, 0DC0E46F2, 0D27430AE, 094FB71BC, 0C85E3118, 00722F198, 018FC7D0C, 08D047321, 08E3E0017 +dd 0960239B0, 05F80800B, 06EF8FC00, 0E9523CC6, 0BBD7DA5B, 07CFD45B5, 08B900AF9, 03A400000, 03059D100, 0710418C8, 092D516F6, 0145D6015, 03248BFAB, 0EA5BE16E, 0EC0A6FD4, 062F0FCA6 +dd 045049145, 052280272, 09A914022, 0C9ABBB01, 056000157, 0D0100570, 0071CC26C, 0E3B78033, 0F81D49C5, 00EBB4075, 0E5F1782C, 01E204FAF, 031D15455, 0CDDB3CD8, 04065E033, 0FA4874BD +dd 0B000DBA1, 08E87B5D9, 0005A0002, 0D5AC599A, 098E26052, 068043901, 0EF075048, 0F5F8001F, 0C0078AC4, 0968561D2, 0EB075D83, 07597820B, 0712586F0, 09B0C2763, 0C0406434, 0D0B72309 +dd 009D0A676, 0194D8623, 0CCD24400, 00FB20359, 074379B84, 0F3798840, 09114A756, 00280B723, 0184DE6C1, 09CDC6932, 04E06F101, 027E3A4D9, 04399E4E6, 0001B4CA7, 02E6F6B4D, 00A0698EA +dd 0C38194A4, 03298CC26, 02DB8C220, 093924DD7, 0E4566D66, 0DF76D901, 0CB65341D, 095B29C82, 000AEB796, 001DA8400, 001D2060D, 042C01008, 09C011A80, 0EB56A804, 0FD085E58, 0001D5C03 +dd 0F100FC0C, 0C02FE405, 0A00013FD, 03E75AA8A, 061F8A120, 0248C4763, 010008648, 09B7EB040, 01F0003DE, 002F58030, 0AE5F2004, 022021499, 025A1CAF0, 031169409, 00100C060, 01048C7B2 +dd 0FE6C312A, 07D1F5E21, 08A399233, 01EDF8BC6, 0E17A070B, 00ECC5001, 02C560F00, 0A225F954, 0003F2240, 010113912, 079BF016B, 0E87C0CA4, 0B18F8005, 02C1EFE22, 051018232, 070FB7C91 +dd 087C12198, 07209B340, 002322878, 0333DD301, 0E1180616, 0C78AC130, 0884C1C76, 0224A4506, 05912FC23, 0CCBB87F1, 0E113B22C, 05E45B99E, 086180C16, 080BCDEE4, 0C4E0898D, 0BB2C169F +dd 0B4581C00, 07400562F, 039C80094, 09D05A382, 06ACC158C, 06798F9DD, 0251D0BCA, 051D6E84E, 02AC741BE, 0A727D8EC, 02B6BBADC, 0D6C2E192, 01F1190E7, 0C9D5B03C, 01F500BE4, 0C0069856 +dd 018084563, 0FE3C0B9D, 0DE2849D1, 05F3B9D64, 02BACFA83, 01B702BE7, 0166177E0, 044787CBC, 0011111E0, 012F832CD, 09F5167D4, 0340B8307, 01D16C839, 091448243, 0C2F70693, 0C5FE1097 +dd 09BEDFFCF, 03A008B12, 036B6000B, 0268FD028, 00A9CEA5A, 000800BF4, 07CEA4A21, 01C16DF52, 04A244580, 0A4334924, 02183B3DD, 01C840FF2, 0068EDE52, 05914F245, 01D08A121, 00A3DE634 +dd 064F6DB98, 024E49C2D, 080275200, 080858190, 006C36638, 0A2700860, 0B8764281, 090401AEA, 06FFC99DD, 0924D1DAC, 094404F17, 04FF8E38D, 0683A1CB8, 04B11FACA, 0B86FE6BB, 04E470101 +dd 0D9733999, 0927EEF55, 0F7384D3C, 0A532C94C, 04F2214C9, 0400AEAA6, 0495C0001, 093C844E2, 003735427, 0A03FFC60, 012F7FF54, 037510FFA, 02FBA5086, 0F5BDCFFA, 0F1839DCC, 0B9203C7F +dd 08EC3A318, 0843FEB5A, 013DEFFAC, 0804BFFFA, 02028A400, 0E8C98A61, 07135193F, 011FF4FFA, 0E1618F1F, 0003C2EC0, 0B9BB146C, 0CBF29BDE, 00B5C9F07, 05BC75A00, 0C0C039AF, 07C935107 +dd 038088E89, 0FB21B076, 06B7971D7, 009818722, 06C20E87C, 01C893B70, 00A03E080, 0267B9F02, 06019F02C, 0099F0380, 0C1FE3C16, 0D2419F01, 05A828C00, 0F0A4161F, 00DF49519, 049AEF84B +dd 09F022DEB, 0F0161E45, 0B0624D55, 002FF8371, 002801760, 0BA14DF8B, 00249D076, 0AC03A720, 0B758E800, 0FED16165, 05CCBE06B, 0EAA6799F, 007F46828, 0A15B33E4, 0A797C183, 000BEE83E +dd 02C2DE9C4, 043ACB058, 0C688E8B7, 006879475, 0BBFC647C, 0570CBE37, 076778998, 0606B95BD, 09D3A0A74, 0BEFD8095, 063180150, 00040ABB7, 0E0675780, 04E271085, 07C0A8B91, 079205914 +dd 0742D6B59, 00003A92D, 056000E00, 049D1800A, 0DE492AC9, 0D0058B0E, 06CF70C9C, 0184FE3B6, 0F84F0B22, 0686C7DAE, 0C94ADBE0, 01F09A242, 00DF2C37C, 008B025A3, 080CB12B7, 06C0A7334 +dd 06522D7D6, 021A7D286, 043D66C8A, 01AC309B3, 0C6F27028, 084A98B4D, 063B90156, 0526B47F5, 069C6EBAC, 046DBAC42, 07FD19AD6, 0BFEEA445, 04953A03E, 00221713D, 000284040, 06007DB09 +dd 0CC5E3FEA, 09C87804E, 0DFC703FE, 047DCE67A, 0B058FC61, 0FAD77148, 0FFEB240F, 0FFF548F2, 00B7FD797, 04A8AB026, 0CC2011F6, 0EDFF5BF8, 0A31505F8, 007F806FF, 04B3FEA70, 087F02610 +dd 0F7F3FE9A, 05FCFDE43, 053B483D0, 03B999FF4, 0FF5AB86C, 0FF182501, 09007F97A, 002FFAF2F, 012068074, 001FFACD0, 0772079FF + +;------------------------------------------------------------------------------- +.RADIX 10 + +END ; end of the file diff --git a/x86-asm-source/sectors.bin b/x86-asm-source/sectors.bin new file mode 100644 index 0000000000000000000000000000000000000000..bbb5dc917e733b8821e9c1ee3c54d16a982dc254 GIT binary patch literal 4096 zcmeH}e@s(X6vxkd4~n(}!OpkJ6mAy9v5A7rPK1D>RH~sM#SYn0Q>AJZ+vfGPNOtRB zEED=1{>ZYpf3_KoOALR=0t*Bz&4{9gCTOyZf0i(euGmDG%vGe8-Pcl-#6NU@Im2yk z?s@l}d*6NUd_U*Zze-)UvAhE9u~ZvTW@Zk`Kx)e&<30o0WZ|q9&cK^2W-^(TwR%nV z>YU8S!DClj273Uv47GT=fbNAOZouQ`MuDEZ1V@A?Za38x1NH0cd0FF?#F2l5j-M$1 zb{(!9S7b-y??AvZFU%HOx4J0;CNH`rFg^c8Y65r*$yI;4Vf)G+HJ8!CW|=E!l4?A zq1t5Lhb&g3_#KF4tF!UOLr`L}*`9kNURrLn))@8}k-=PzY&>T=D4KQXps^0s?l+nd zXEapT#Y^G8wPeXCP!vn8r8Ly99sPALyGuPqfusQKLS*6a6b(Br`14P^TcFI%QWtLm zI)(z8{NRxX5Nsel;#E(j(@8x!RqC>gtjtVAnrdT3mXeHrIUi?VYq`-A{FIHmbQmr> zAVtUS=zS-)`3N*?=r&n!{G25965uOEp#_3U(Nr`sxo+<=9OIR9c`jAr>A+r=Q7w_{ zQW#Z&{6<-MvntrE3w0t897%yYf?me-6$i#CRWL~ts;caUIAOAl@_h~5mUS8Y;x?I1 zaO97l*YjI7yo{M>>|c~S$=&w<_WrfbA?Hz5e%_G%TX(&)^)xfq`h|yoD{qRQKdlM> zJ$Iwif7{*Q^bZrkvHH~GF~>L4-o@_Eoq}^g;}p$Z75a;dU7Gm7AB-v}*M-RAwQVsz z7Cz>#HWZXp*?(;41-fvn{rkH>TcNCc`^i(;Hv~z~F#% zAS~~lRh8WQ4R)%K(aS~#`WOYZB3>F5XGCA9nrLz=UK*CBdUYu>igF|qQE~D6jbWda zVVRLDGqQ3=7YE5BjX@z(L#Q4wg|3Bg%;3@x2 zzrR8Fe7QEw|2;&O4cEqr@y|Q4YR`JdfiVB`qWs@~%0Ka{hxFKm+BA{>HEU<_|Cl6R zu^6y%-G@PW`9ng#wl^Pl$si1VnEC_-ZYr5*-a_}s<>N^LeqFXFM8M9`9YbCo7m;}YzcnUH__Kl3v3B)lia)`RhDAm`j?~P zhA!oD?3MS$OEngAhBjPv!o(v|mc;B3NeNFgf>>^5rGVMh=K0w`$d|LWEMXZi0LSTQ^kwHGuZ{0|2a@gM#(b-MnqT$x@Q<{w4*2WqDN6EDKQ zOy0VktckX{`v1Dr|1kf#y=BqJ0^y$t&GG+g{{MfL|8ElI!I`MNpb_RjRPdmH`2T$( mcbfmbwKboF`QH%b|2`DJ6zLH!!auci5IysZIsRW4{{IEoC3Qsr literal 0 HcmV?d00001 diff --git a/x86-asm-source/sectors.obj b/x86-asm-source/sectors.obj new file mode 100644 index 0000000000000000000000000000000000000000..fddd0d053f3c6452fbfa23fe19bf034404d66407 GIT binary patch literal 1733 zcmZ{lYdDl?7{{OY9cIjo7@DT3$jsz)6)No3lz59NL*tYtrn$Edy^ajC;&uH&H%on z+8wqyK%LKMxXN6I*U_i5k&7UwpI2xfRfp0?R~tMjUnFk78vikmzBsf=I>I98@6phi z2|9;o0_Q9R8$M1((J-Ju%fNIV)Z-4+lPM6Xusxu)tpq0;WaZS}b zkQxJT}sb_K@d0*D1YE5cqWC|I$PX* z2ye`QdhBKfLD??ce>`O)VThcZzhgMfB0k(oztAxPQ4;4>wkDowCC*FZ%>r)iErGZS z!_>khV&p*5TYeceXI>==*ADRL_R&v@pb@;+qtfSA1N{ZAWozdEUQDc=N{T0y=IyJu zY?0bC>Z)uzdAUb7Z{_zxj}m)K9V71~7gZcPURe%6>SJgcz8%t|C|9Agp(34M`9lGr zdY^D1ra)flPoH z(elI757MaHWK#>T!4BW+D;wv(dT3SlMWlCR6fiwh62Bgr3Cc0|Fy}gyKE05_95qZe z@$1gQb4ICw%o06Q$AJ|jY1jJ*+oFDR;Ae$q@7s?q-CU0s=*6Adw<@tpH5K$Wj|Wl49^mvI2n=Vq^*TyE8D@LF}&$ z@1}XG%eh0gu#7X8HoTs!5t^DM*Y!6@5AIC7b}U99CM_#I zhJL#41JT1P&mjQa5Y@Y%V&#>SNs>?l8A*XLwqo0}H~kRi}t%lKRnUr!5qEmBx2a#{`n7qmvbx)?UWU5Oug-AlA>e zjvH;@Wu8stL)GD9YhwK5Lk-cZT+Y`Q$q8ig+fBAl87`MG&Z5LR-Ah z^dc>;v1j+dlQlw3fWke#bHdPk2pe@D!}2@#k}VY(9`B79E$U$GwOV(^X$-F>#Hn07 zDVD?OC$w+JUAymvwWeHL_fA%@TvQc=K^Amu_Xk4u!t)p`M)Ah2aty+f7(4AYM~fn- zZm|{vAPP!|3>U|4Pp}gvY@PCv@Yt1Ea|rwvOZK@9h`n_Bn$728xZ40{{R3 literal 0 HcmV?d00001 diff --git a/x86-asm-source/sixteen.asm b/x86-asm-source/sixteen.asm new file mode 100644 index 0000000..d6c3b1a --- /dev/null +++ b/x86-asm-source/sixteen.asm @@ -0,0 +1,167 @@ + +; Bitmap Converter Running ... + +; Non-256 color palette does not require sorting. + +; Bitmap Data -- Width: 190 +; Height: 88 +; Bits/Pixel: 4 +; Colors Used: 16 + + +EXTERNDEF ColorTable :DWORD +EXTERNDEF PixelData :DWORD + +;------------------------------------------------------------------------------- +BITMAPSEG SEGMENT BYTE PUBLIC +;------------------------------------------------------------------------------- +.RADIX 16 +;------------------------------------------------------------------------------- +ColorTable LABEL DWORD + +dd 00A10303, 00AD1F20, 00B32E30, 00B93E40, 00BC4649, 00C35559, 00C65E62, 00CB6A6E, 00D27A80, 00DA8D93, 00DF99A0, 00E09DA4, 00E6ABB3, 00EDBCC5, 00FCE1EA, 00FEEAF1 + +;------------------------------------------------------------------------------- +PixelData LABEL DWORD + +dd 079150000, 0DDDDDDCD, 0001085C9, 000000000, 000000000, 000000000, 000000000, 000000000, 000000000, 000000000, 000000000, 000000000, 000000000, 000000000, 000000000, 000000000 +dd 000000000, 000000000, 000000000, 000000000, 000000000, 000000000, 000000000, 000000000, 0EEEE5B01, 0EEEEEEEE, 051ECEEEE, 000000000, 000000000, 000000000, 000000000, 000000000 +dd 000000000, 000000000, 000000000, 000000000, 000000000, 000000000, 000000000, 000000000, 000000000, 000000000, 000000000, 000000000, 000000000, 000000000, 000000000, 000000000 +dd 0EEEEEE8D, 0EEEEEEEE, 0EDEEEEEE, 000000082, 000000000, 000000000, 000000000, 000000000, 000000000, 000000000, 000000000, 000000000, 000000000, 000000000, 000000000, 000000000 +dd 000000000, 089554512, 0DDDDCD99, 08599C9DD, 000104255, 000000000, 000000000, 000000000, 0C9EDEEEE, 0DCDDDD8B, 0EEEEBD89, 0000050ED, 000000000, 000000000, 000000000, 000000000 +dd 000000000, 000000000, 000000000, 000000000, 000000000, 000000000, 000000000, 000000000, 09D260100, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 095ECEEEE, 0DDBD3821, 00030C8DD, 000000000 +dd 05C21B7EE, 0EEEEEEEE, 0CE2751EC, 00010E9EE, 000000000, 000000000, 000000000, 000000000, 000000000, 000000000, 000000000, 000000000, 000000000, 000000000, 000000000, 000000000 +dd 0EEEEAD04, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 050ECEEEE, 000000000, 0EE0900C3, 0EEEEEEEE, 00500E5EE, 000B0EEDE, 000000000, 000000000, 000000000, 000000000 +dd 022010000, 099996945, 0DDDDDD9C, 0DDDDDDDD, 09999DCDD, 021427599, 000000000, 000000000, 0ECEEEE1C, 077777797, 022527777, 077777747, 0EE9C7877, 0EEEEEEEE, 0ECEEEEEE, 000000030 +dd 0EE7E0000, 09D25A6ED, 00030EDEE, 000E3EE18, 000000000, 000000000, 000000000, 024120000, 0EEDEAD79, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 02274A9DD, 000000010 +dd 0EEEEBE02, 0DDDDDDED, 0DDDDDDDD, 0DDDDDDDD, 0EEEEDEDD, 052A7EDEE, 0EEEEAD46, 0000000E5, 0EDEE0500, 000000051, 000D1EE5D, 000E8AE00, 000000000, 000000000, 014000000, 0EEDE9D69 +dd 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 01064A9DD, 0DE9C0500, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0000051EC, 0EE4A0100, 0000030ED +dd 0D2EE0C00, 000000000, 000E9EE05, 000ED5E00, 000000000, 000000000, 0EEBD5812, 0EEEEEEEE, 0EDEEEEEE, 09799D9DD, 032666666, 025222222, 099566566, 0EEDDCD99, 0EEEEEEEE, 0EDEEEEEE +dd 0121052B8, 0EECD8945, 0EEEEEEEE, 0EDEEEEEE, 0ECEE89C9, 0DD8C0230, 04E0083DD, 00000D1EE, 060EE1E00, 000000000, 010ED8E00, 000EAAE00, 000000000, 09C140000, 0EEEEEEDE, 0EDEEEEEE +dd 0457596C9, 099999967, 0DDDDDDCD, 0DDDDDDDD, 09999C9DD, 043236597, 0EECD9966, 0EEEEEEEE, 094DCEEEE, 012000021, 022222222, 010222222, 0D2EE1D00, 0EEEE8E02, 006A2EEEE, 00000EAEE +dd 020EE2E00, 000000000, 010EE3E00, 000E4EE05, 000000000, 0EEEE9D25, 0EDEEEEEE, 0687597DA, 0EEEEDD9A, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EDEEEEEE, 0334297DA, 0EEDD9A56 +dd 0EEEEEEEE, 00021A6ED, 000000000, 000000000, 040EE7E00, 0EEEEEE3D, 010EDEEEE, 00020EE8E, 050EE1D81, 000000000, 002EC8E00, 000B0EEAE, 09D150000, 0EEEEEEEE, 07786DBEE, 0EEEEDD99 +dd 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EDEEEEEE, 0255296DA, 0EEEEDE8B, 0A6EDEEEE, 000000020, 000000000, 001E9CE00, 042D7EECE, 090EEDE47, 00080EE0C +dd 0B0EE7CED, 000000000, 08EE9DE01, 00010E9EE, 0EEEE7C02, 0A8EDEEEE, 0EEDE8B77, 0EEEEEEEE, 0DDEEEEEE, 0759999DD, 022525555, 055222222, 099695555, 0EEDEDD9C, 0EEEEEEEE, 0DBEEEEEE +dd 0AD473385, 0EEEEEEEE, 0000072EC, 000000000, 008E5EE02, 00010E7EE, 0E4EE1900, 000D1EE07, 0ECEEEEEE, 013001072, 0EEEEEE8D, 0270050ED, 0EEEEEECE, 0CD79A8ED, 0EEEEEEEE, 0DCEEEEEE +dd 010226599, 000000000, 000000000, 000000000, 000000000, 025120000, 0EEDE9C69, 0EEEEEEEE, 042C9EDEE, 0EEEE9D25, 020C7EEEE, 000000000, 01DE2EE02, 0000070EE, 0EC9E0000, 000E1EE03 +dd 0EEEEEEDE, 0EEDDDDEE, 0EEEEEEEE, 0EE7C02D2, 0B9EDEEEE, 0EEEEDE9C, 0DDEEEEEE, 0002165A9, 000000000, 000000000, 000000000, 000000000, 000000000, 000000000, 025010000, 0EEDEAD69 +dd 0EEEEEEEE, 09D3575DB, 0ECEEEEEE, 000000072, 02EE5DE01, 0000020EE, 0EE3E0000, 000D0EE17, 0EEEE9D15, 0EEEEEEEE, 094EDEEEE, 0EEEECE25, 0EEBDD9EE, 0EEEEEEEE, 0105297DD, 000000000 +dd 000000000, 000000000, 000000000, 000001019, 000000000, 000000000, 000000000, 046120000, 0EEEEDE9C, 095EDEEEE, 0EEEECE47, 00010B5EE, 01DE9DE00, 0000060EE, 0EC8E0000, 00090EE1C +dd 0CE370100, 0EEEEEEEE, 04921C6EE, 0EDEEEEDE, 0EEEEEEAC, 052A7EDEE, 000000010, 000000000, 000000000, 000000000, 000000000, 00000708E, 000000000, 000000000, 000000000, 000000000 +dd 09D461200, 0EEEEEEEE, 0EE7C64EB, 030D9EEEE, 01AED8E00, 00000D3EE, 0E7EE0500, 00040EE4E, 001000000, 0DCEEDE7C, 0EE8D0271, 0CEDAEEEE, 0EDEEEEEE, 0000021A6, 000000000, 000000000 +dd 000000000, 000000000, 004000000, 00000D1EE, 000000000, 000000000, 000000000, 000000000, 000000000, 0EEEE9D25, 047B6EEEE, 0EDEEEECE, 0B5EE2E71, 000A2EEEE, 0D5EEAE03, 00000ECDE +dd 000000000, 000210100, 0EEEE8E02, 0EEEEBCED, 021A6EDEE, 000000000, 000000000, 000000000, 012000000, 099794522, 0DEDDCD99, 0DDDDEDEE, 09999C9DD, 010224285, 000000000, 000000000 +dd 000000000, 09D250000, 0EBEEEEEE, 0EEEE8D53, 0E9EE78ED, 0DDEEEE8E, 07CEEEEDE, 00000E3EE, 000000000, 002000000, 0ECEEEE8E, 0EEEEEECD, 0000031D8, 000000000, 000000000, 023010000 +dd 0DEDD8A55, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EDEEEEEE, 0215485DA, 000000000, 000000000, 000000000, 0EEEEDE38, 0EE5B95ED, 0EEDEEDEE, 0EEEEDEDB, 0DEDAEEEE, 0000080EE +dd 000000000, 08E010000, 0DEECEEEE, 083EDEEEE, 000000000, 000000000, 012000000, 0EEDD8B55, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0105285DC +dd 000000000, 000000000, 0EE8D0300, 038C6EEEE, 0EEEEEEEE, 0EEDDDBEE, 0EEDEDBED, 0000000E9, 000000000, 0EE7D0100, 0EEDEECEE, 00030D8EE, 000000000, 000000000, 0DEAD4812, 0EEEEEEEE +dd 0EEEEEEEE, 099C9DDED, 06E555585, 03522EDE9, 099795555, 0EEDEDDBD, 0EEEEEEEE, 0EDEEEEEE, 0001042A8, 000000000, 038000000, 0D7EEEEDE, 0EEEEEE38, 0DDEEEEEE, 0EDEEEEDE, 000000070 +dd 000000000, 0EEEE7D01, 0ECEEDEEC, 000000073, 000000000, 07B140000, 0EEEEEEDE, 0DCEEEEEE, 022425598, 000000010, 04E000000, 00010EEE5, 000000000, 022120000, 0DD9B5735, 0EEEEEEEE +dd 084DBEEEE, 000000010, 000000000, 0EEEE8D03, 0EEEE38D7, 0EEEEEEEE, 081EEEEEE, 000000000, 000000000, 0ECEEEE5D, 050ECEEDE, 000000000, 000000000, 0EEEE8D15, 0EDEEEEEE, 0002164C9 +dd 000000000, 000000000, 06E000000, 00020EED3, 000000000, 000000000, 001000000, 0EEBD6923, 0EEEEEEEE, 0001085ED, 000000000, 0EE7D0100, 0EE38D7EE, 0EEDEEEEE, 00072DAEE, 000000000 +dd 019000000, 0DEECEEEE, 00050ECEE, 000000000, 07C130000, 0EEEEEEEE, 02185DAEE, 000000000, 022220100, 099995724, 0EEDDDD9C, 0DDDDEEED, 0989999DC, 021222254, 000000000, 025010000 +dd 0EEEEDE7A, 083ECEEEE, 000000010, 07D010000, 038D7EEEE, 022E8EEEE, 000000021, 000000000, 0CE020000, 0EEDEECEE, 0000050EB, 000000000, 0EEDE5A01, 0C8EDEEEE, 000000052, 079351200 +dd 0EEEEDD9C, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0428599DC, 000000010, 0BD580200, 0EEEEEEEE, 0000051DA, 001000000, 0D7EEEE7C, 0A1EEEE38, 000000000, 000000000 +dd 0EE5D0000, 0EAEEDEED, 000000030, 015000000, 0EEEEEEBE, 00021A6ED, 069230100, 0EEEEDE9C, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0216499EC +dd 001000000, 0EEEEAD26, 010A4EEEE, 000000000, 0EEEE5C00, 0EDEE3DD5, 000000040, 000000000, 0EEEE1900, 030EAEEDE, 000000000, 0DE390000, 0C7EEEEEE, 012000031, 0EEEECD58, 0EEEEEEEE +dd 0DDEEEEEE, 0559899A9, 0EE565555, 055C3BE82, 099575555, 0EEDDAD99, 0EEEEEEEE, 0EDEEEEEE, 0001052C8, 0BE370100, 0D8EEEEEE, 000000020, 0EE5C0000, 0EE9E82EE, 0000000E7, 000000000 +dd 0DDEECE02, 00030EBEE, 000000000, 0EEEE5B00, 00041D9EE, 0DE8B2500, 0EEEEEEEE, 0C9EDEEEE, 000215285, 000000000, 0EE020000, 000D09E50, 000000000, 022010000, 0DEBD7955, 0EEEEEEEE +dd 085DCEEEE, 001000020, 0EEEEDE49, 0000030E9, 05C000000, 0EE27EBEE, 00000A1EE, 000000000, 0EEEDEE5D, 0000060EE, 001000000, 0ECEEEE5C, 025000073, 0EEEEEE9C, 0C9EDEEEE, 000104285 +dd 000000000, 000000000, 0EE050000, 000D1AE60, 000000000, 000000000, 012000000, 0DEBD7935, 0EEEEEEEE, 0002196EC, 0EE8D0300, 00040EAEE, 000000000, 04DD5EE8E, 00030EDEE, 000000000 +dd 0EEDEEEEE, 0000000D3, 07D010000, 040EAEEEE, 0EE9D2500, 0EDEEEEEE, 000104296, 000000000, 035220100, 099998955, 0EEDDCD99, 0DDEDEEDD, 09999C9DD, 042558599, 000000021, 012000000 +dd 0EEEE9D36, 0A6EDEEEE, 05C010020, 051ECEEEE, 000000000, 082EEDE05, 000D2EEBE, 000000000, 0E9EEEDEE, 000000010, 0EE8D0200, 00330D8EE, 0EEEEEE8C, 01074DAEE, 000000000, 079551200 +dd 0EEEECD99, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 08599C9ED, 000001052, 07A130000, 0EEEEEEDE, 0000072EC, 0EDEEEE4A, 000000071, 0EBEE2B00, 010ECEE28, 000000000 +dd 060EEEEEE, 000000000, 0EEEE8E01, 0CE1710D7, 0DAEEEEEE, 000001062, 09B571300, 0EEEEEEDD, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 098DCEDEE +dd 000001054, 0EEDE6A12, 000B5EEEE, 0EEDE2800, 0000060ED, 0EE8E0000, 0B0EE7ED3, 000000000, 000D3EEEE, 000000000, 0C5EEEE2C, 0EEDE3800, 01062DAEE, 059120000, 0EEEEEEBD, 0EEEEEEEE +dd 0DDEDEEEE, 0859999C9, 0EE5C5555, 035E77E42, 079555555, 0DDBD9999, 0EEEEEEDE, 0EEEEEEEE, 052C9EDEE, 06A120010, 0D7EEEEDE, 0DE170020, 00010E9EE, 0DE050000, 0E9EE29ED, 000000000 +dd 00010E9EE, 007000000, 001A3EEEE, 0EDEEEE5C, 000001093, 0EEDE8D25, 0EEEEEEEE, 08599DDEE, 000102252, 000000000, 0EE090000, 000E55E20, 000000000, 000000000, 079552212, 0EEEEDD9D +dd 0EEEEEEEE, 0002085ED, 0EEEEBE15, 0050040EA, 000D5EECE, 02C000000, 0EE9EB1EE, 000000080, 00000C1EE, 0CE020000, 08D02D5EE, 051EBEEEE, 09D250000, 0EEEEEEEE, 05498DCEE, 000000021 +dd 000000000, 000000000, 0EE0C0000, 000E75E20, 000000000, 000000000, 000000000, 057230100, 0EEEEDE9B, 095EDEEEE, 0EE7C0120, 00071ECEE, 091EEEE07, 002000000, 0EE1CE9DE, 0000000E6 +dd 0000020ED, 0EE6D0000, 0EEAE22EA, 00010C7EE, 0EEEE8C03, 096EDEEEE, 000000041, 000000000, 000000000, 000000000, 0EE0D0000, 000E95E20, 000000000, 000000000, 000000000, 000000000 +dd 09D360100, 0EEEEEEDE, 0280072EB, 081EDEEDE, 0EDEE3C00, 000000030, 0DE71EE5E, 0000020EE, 0000000E4, 0EDEE0900, 0EDEE6E61, 038000082, 0EEEEEEDE, 0001052C9, 000000000, 000000000 +dd 000000000, 000000000, 0EE1D0000, 000EA6E20, 000000000, 000000000, 000000000, 000000000, 000000000, 0EEDE5912, 020C7EEEE, 0EDEE9E03, 0EE8E0140, 0000000E6, 03DE5EE08, 0000080EE +dd 000000070, 0B2EE8E00, 071EEEE2A, 0EE7C0200, 031C7EEEE, 000000000, 000000000, 000000000, 055552412, 099998955, 0EEDEDD9C, 0DCEEDEDD, 085999999, 022545555, 000000021, 000000000 +dd 000000000, 048010000, 0EBEEEEDE, 0EE9E0251, 0DE0410E8, 0000040EE, 017EDAE00, 00000E2EE, 000000000, 016E7EE06, 000A2EEDE, 0EEEECE27, 0000052EB, 000000000, 012000000, 0DD8B5525 +dd 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 05585DBED, 000001022, 000000000, 000000000, 0EEEE7C02, 0CE13B5EE, 01900C3EE, 00000D3EE, 081EE1D00, 00000EADE +dd 000000000, 09E81EE6E, 03A00C3EE, 095EDEEEE, 000000010, 001000000, 0DE9C6925, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 06599DCEE +dd 000000021, 000000000, 0BE260000, 026D8EEEE, 00170EEDE, 00020EDCE, 0D1EE0300, 00030EE7E, 003000000, 0EE3DEBEE, 0EE1800D7, 00041D9EE, 000000000, 0CE994612, 0EEEEEEEE, 0EEEEEEEE +dd 0DADDDDEE, 065999999, 0EE7E5555, 065ED7E42, 099996955, 0DEDDDD99, 0EEEEEEEE, 0EEEEEEEE, 03196C9EE, 000000000, 001000000, 0D7EEDE5A, 010EBEE28, 000C1EE2D, 0E5DE0000, 000A0EE2E +dd 01D000000, 0EDCED2EE, 0EEDE1730, 0000000A3, 07A020000, 0EEEEEEDE, 0EDEEEEEE, 0325597DA, 000000021, 000000000, 0EE2E0000, 000ED5E20, 000000000, 001000000, 099572522, 0EEEEEEDD +dd 0EEEEEEEE, 0000051D9, 000000000, 0EECE1500, 080EE7EC5, 000EAEE04, 0EC8E0000, 000D1EE08, 07E000000, 0E3EE38EE, 0C4EECE05, 000000000, 0EEDE3801, 0DCEEEEEE, 010326599, 000000000 +dd 000000000, 000000000, 0EE2E0000, 010ED6E20, 000000000, 000000000, 000000000, 069351200, 0EEEEDE9C, 020C7EEEE, 000000000, 0DE070000, 0E5EEB9EE, 030EE7E00, 0EE4E0000, 000E2EE32 +dd 0DE010000, 060EE4EE7, 010D7EE8E, 015000000, 0EEEEEEAD, 0003196DB, 000000000, 012000000, 055552422, 099998955, 0EEDEDD9C, 0DCEEDEDD, 085999999, 022545555, 000001022, 000000000 +dd 09C360100, 0EDEEEEEE, 000001094, 018000000, 0EDCEEEEE, 090EE0B10, 0EE1D0000, 000E5DE90, 0EE050000, 006E7DEE3, 00010E9EE, 0EE7C0200, 073DBEEEE, 000000010, 035010000, 0EECD9969 +dd 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 099C9EDEE, 000003165, 000000000, 0EEEE8C14, 00052DBEE, 000000000, 0EEDCEE3C, 0E2EE0690, 0EE0A0000, 000E79EC0 +dd 0EE0C0000, 04ED1EED8, 0000040EE, 0EEEECE03, 0001073DB, 012000000, 0EEDE9D58, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 097DDEEEE +dd 000000052, 08C140000, 0A2EEEEEE, 000000000, 0EEED8E00, 0E8EE02E4, 0EE060000, 000E97ED1, 0EE2E0000, 0DEA2EE9D, 0000000EA, 073ECEE7E, 000000010, 0DE8C1400, 0EEEEEEEE, 0DDEEEEEE +dd 0969999DD, 055555555, 0EE8E6655, 065EE8E52, 055555555, 09C999956, 0EEEEDEDD, 0EEEEEEEE, 01073DBEE, 000000000, 0EDEE8D14, 000000050, 0EEEE1D00, 0EDDE01E9, 0EE030000, 000ED5EE2 +dd 0EE2E0000, 0EE69EE6D, 02C0000E2, 00050ECEE, 025000000, 0EEEEEE9C, 097B9DDEE, 011225255, 089555522, 099999999, 0EEDECD99, 0C9EEDEDD, 099999999, 053558599, 045221221, 0DEBD9956 +dd 0DBEEEEEE, 000001084, 0EE7D0100, 0000010E9, 0EEEE0600, 0EEAE00ED, 0EE060010, 000EE2ED1, 0EE2E0000, 0EE4DEE4E, 0DE060080, 0000050EC, 0EE9D1500, 0A7EDEEEE, 001001042, 0DDDD8925 +dd 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 085DADDED, 012000021, 0EEEEBD58, 01084ECEE, 07D010000, 00000D3EE, 0EECE0000, 0EE5E10EE, 0EE0A0010, 000ED5EB0 +dd 0EE1D0000, 0EE7EEE6D, 0EE6E0030, 000000050, 0EEEEDE07, 0001074DB, 0DE7A2501, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 01064D9EE +dd 08C250100, 0D5EEEEDE, 001000000, 00030EE8E, 0EE6E0000, 0ED7E00EC, 0EE1D0000, 000EC8E70, 0EE0B0000, 0EE9CEE98, 0E8CE0080, 002000000, 052B8EDCE, 038000010, 0EEEEEEBD, 099DDDDEE +dd 055559899, 055555555, 0EE8E5555, 065ED7E42, 055555555, 099575555, 0DEDD9D99, 0EDEEEEEE, 0000020A7, 0EECD5912, 000000091, 000A0EE0C, 0EEAE0000, 0E9BE00E7, 0EE2E0000, 000E9CE40 +dd 0EE080000, 0EED8EED4, 0E4DE01D1, 07E000000, 0000041ED, 0EE180000, 065B9DDEE, 000001022, 000000000, 000000000, 0EE2E0000, 010EE5E20, 000000000, 000000000, 012000000, 0EECD7935 +dd 00010E8EE, 07E010000, 0000040ED, 000D1EE06, 0EEEE0300, 0E5EE01E1, 0EE6E0000, 000E6DE11, 0EE050000, 0EEE7DEE3, 0EC8E00E7, 0DE010010, 0000010E9, 0EDAE0000, 000001084, 000000000 +dd 000000000, 000000000, 0EE2E0000, 020EE2E20, 000000000, 000000000, 000000000, 024000000, 000A0EE9D, 019000000, 00000D1EE, 00070EE1D, 0EEEE0A00, 0E2EE05B0, 0ECBE0000, 000E4EE02 +dd 0DE010000, 0DEED8EE7, 0EE1C30ED, 03E000090, 00010D7EE, 0EE1A0000, 00041C8EE, 000000000, 000000000, 000000000, 0EE2E0000, 020EE2E20, 000000000, 000000000, 000000000, 0DE590100 +dd 00010E9EE, 0DE170000, 0010030ED, 00000EACE, 0EEEE5E00, 0C0EE0B40, 0E3EE0500, 000D1EE07, 07E000000, 0DCEE39ED, 0EE14E8EE, 0060020E8, 010D7EEEE, 06C000000, 0DDEDEEDE, 0555596DC +dd 021222252, 000000000, 0EE2E0000, 020EE2E20, 000000000, 023222201, 09D575555, 0EEEEDEDD, 0000040DB, 0EEDE2800, 0390000D3, 00000D2EE, 0E6EEEE2A, 030EE6E00, 090EE1D00, 00080EE1D +dd 00C000060, 0ED9EC1EE, 08EC4EEAE, 00040EAEE, 0D7EEEE5D, 000001053, 0EEBD5912, 0EEEEEEEE, 0EDEEEEEE, 0DDDDDDDD, 0EEDEDDDD, 0DDEEDEDD, 0DDDDDDDD, 0EEEEEEDD, 0EEEEEEEE, 052A8EDEE +dd 024010010, 0ECEEEE58, 0EE5C0130, 0060050ED, 060EEEEDE, 000E8EE03, 010ED9E00, 00020EE7E, 0030000D2, 0EE1CE9EE, 083EEEED9, 071EDEE8D, 0EEBE2700, 052B8EDEE, 025010010, 0EEEEDD89 +dd 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0D9EDEEEE, 000001074, 0EEBD6913, 010A5EDEE, 0EDEE8D02, 0BE020071, 000E8EEEE, 000D1EE1D, 001E6EE05, 00000E8DE +dd 0000000EA, 0CE51EE8E, 0EDEECDEE, 0EDEE7D64, 049012185, 0EEEEEEDE, 0529699EB, 055221110, 099999956, 0EEDDDDDD, 0EEEEEEEE, 0EEEEEEEE, 0DDDDEDEE, 0969999D9, 010215255, 09C995613 +dd 0EEEEEEEE, 0360131C8, 050ECEEAE, 0EE8E0300, 00090EEEE, 00050EE9E, 008B0EE1D, 00000E2EE, 0000070EE, 01BD5EE1C, 0EEBDEEEE, 0EE8CC8EE, 031A7EDEE, 0EEDE7B13, 0EEEEEEEE, 097DCDDDD +dd 032555555, 022212222, 0EE5E2222, 032ED8E52, 022222222, 055554522, 0DDDD9C58, 0EEEEEEEE, 062DAEEEE, 0EEBD4701, 00040EAEE, 0EEEEDE38, 00700E8EE, 00100E8EE, 02E20ED9E, 0000080EE +dd 00010E9EE, 091EE9E01, 09BEDEE5C, 0BCECEEEE, 0EDEEEEDE, 0462222B7, 0EEEEDE9B, 0EEEEEEEE, 0EEEEEEEE, 0DDEDEEEE, 0EEDEDDDD, 0DDEEDEDD, 0EEEEDEDD, 0EEEEEEEE, 0EEEEEEEE, 0DAEDEEEE +dd 038223296, 0EEEEEECE, 09D1430D9, 0EEEEEEEE, 0BE0230EB, 02C0070EE, 09E00D3EE, 0000010ED, 000C2EE6E, 0ECEE0700, 0ECEE7D31, 0EEEEEE8B, 0EEEEADDB, 0B9EDEEEE, 069252362, 0EEEEDD9B +dd 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0DBEDEEEE, 023235498, 0EEEECD79, 073ECEEEE, 0EEDE4911, 0ECEEEEEE, 0EE6D0050, 0DE0400D5, 0EE0930ED, 0000000E5 +dd 040EDDE66, 0EE5D0000, 0EE8E11E8, 0EEDEBCED, 0BD98EDEE, 0EEEEEEEE, 096DBEEEE, 035432322, 09B998955, 0DEDDDDDD, 0EEEEEEEE, 0EEEEEEEE, 0DDDDDDEE, 0859999DB, 022423355, 0EEDE9C37 +dd 0EEEEEEEE, 0141095ED, 0EEEEEE8D, 070EDEEEE, 0EDEE2A00, 0EE7E0030, 0EE9E00D3, 000000070, 0E7EE3DE4, 0DE030000, 0AE02C2EE, 09DD9EEEE, 0DCEEEEEE, 0EEDEACA9, 0EEEEEEEE, 0DAEDEEEE +dd 022759999, 012212222, 0EE5E2222, 032ED8E52, 022221122, 099793522, 0EEEEDD9B, 0EEEEEEEE, 085DBEEEE, 0DE9C2521, 0EEEDEEEE, 00081EEEE, 0C1EEDE05, 0ECEE1900, 0E9EE0810, 000000000 +dd 0EEDE33ED, 01B000091, 00382EEEE, 0EBEEEEAE, 0EEEECE88, 078A8EDEE, 0EEEEDEAC, 0EEEEEEEE, 0EEEEEEEE, 0DDEDEEEE, 0EEDEDDDD, 0DDEEDEDD, 0EEEEDDDD, 0EEEEEEEE, 0EEEEEEEE, 0DAEDEEEE +dd 027224296, 0EEEEEEBD, 0EEEEDDEE, 0030082ED, 010E9EE9E, 0C1EECE02, 0B0EE6E00, 000000000, 0EE3DD3EE, 0000030EC, 093EEEE5C, 0EEEE8D02, 0DE8997ED, 0EEEEEEEE, 08AA9DBED, 0EEEEDDBC +dd 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0DBEDEEEE, 036436598, 0EEEEDD99, 0DCEEEEEE, 0ECEEEECE, 0BE050071, 00030EBEE, 010EBEE5D, 010EDEE06, 000000000 +dd 08E51EDEE, 00030EAEE, 0EEEE7D01, 0EE4A01B5, 0A8EDEEEE, 0EEEEDE89, 0EEEEEEEE, 057A7DAED, 09B998A77, 0DEDDDDDD, 0EEEEEEEE, 0EEEEEEEE, 0DDDDDDEE, 0859999DB, 036423466, 0EEEEDD99 +dd 0EEEEEEEE, 0EECDDCEE, 030D8EEEE, 0EECE1700, 05C0050EC, 00060EDEE, 000D3EE7E, 000000000, 013E9EE4D, 030EAEECE, 0EE8E0100, 02710C7EE, 0EEEEEEDE, 09B8897ED, 0EEEEEEDE, 0EEEEEEEE +dd 066B9DDEE, 034656666, 0EE5D4444, 034EC8E52, 036223244, 069555566, 0EEEEDECD, 0EEEEEEEE, 0B9DCEEEE, 0EEEEEEBD, 00010C5EE, 0EDEEDE28, 0EE5C0070, 02C0091EE, 00020EBEE, 000000000 +dd 0D3EEBE01, 0E9EEDE06, 0AE020020, 020D8EEEE, 0EEDE7B02, 0DAEEEEEE, 0DD8A5687, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0DEEEDEDD, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0DAEDEEEE +dd 0EEDE9C99, 0DAEEEEEE, 039000052, 081EEEEEE, 0EEEE3C00, 0DE0600C3, 0000080EE, 000000000, 0EEEE0800, 0EEEE1981, 0030020E8, 0E8EEEEAE, 08D140021, 0EEEEEEEE, 086D9EDEE, 0DDAD7956 +dd 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0DDEDEEEE, 0DD9B98AA, 0EEEEEEEE, 01073ECEE, 0EE3A0100, 00082EEEE, 0E7EEEE3A, 0EEAE0210, 0000000D5, 000000000 +dd 0EE5D0000, 0EE3C30EC, 00020E8EE, 0EEEE8E03, 0001094ED, 0EEDE7A25, 0EEEEEEEE, 06598C9EE, 099575544, 0DDDDDD9B, 0EEEEEEEE, 0EEEEEEEE, 0DDEDEEEE, 09799DBDD, 0AA896667, 0EEEEEEDE +dd 0D9EEEEEE, 000001074, 0EEEEAD15, 03A0072ED, 020EAEEEE, 0ECEE5D00, 000000020, 000000000, 0CE030000, 07D01E7EE, 020E8EEEE, 0EE7D0200, 051DAEEEE, 036010000, 0EEEEDE9D, 0EEEEEEEE +dd 09999C9EE, 023225286, 0EE2B4244, 022E88E52, 022434444, 099998956, 0EEEEEEDE, 0EEEEEEEE, 0003196DC, 06B020000, 0ECEEEEEE, 0EE390051, 00050ECEE, 091EEEE19, 000000000, 000000000 +dd 0DE8C0300, 001C4EEEE, 0E8EEEE7D, 049010020, 0EDEEEEDE, 0001052A8, 0BD591200, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEDEEDEE, 0DDEDDEDD, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 052B8EDEE +dd 000000010, 0EEBE5912, 030D8EEEE, 0EEEE3A01, 0050050EC, 002E6EEDE, 083DDDD8C, 000000000, 0EEEECE05, 0C5EEEEEE, 0EEEE5C01, 0000083ED, 0EEEE8D03, 073DAEEEE, 001000010, 09D795522 +dd 0EEEEEEDD, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 07599DCED, 000001052, 08B140000, 0EEEEEEDE, 0140072EC, 0EAEEEE9D, 0CE050040, 08E22E8EE, 0EEEEEEEE, 0000000A2 +dd 0EEEEEECE, 0EEEEEEEE, 0EE5C00C5, 030D8EEEE, 0BD270000, 0EEEEEEEE, 01042A7DD, 000000000, 069352201, 0DEDDBD99, 0EEEEEEEE, 0EEEEEEEE, 0DDDDEEEE, 0325598B9, 000000010, 012000000 +dd 0EEDEAD58, 0B5EDEEEE, 0DE490120, 030EAEEEE, 0EECE0500, 0EE6E30EA, 0EEEEEEEE, 0000020ED, 052B7EEEE, 0EEEEBE46, 02800C5EE, 0EDEEEEDE, 001001082, 0EEEEBD37, 0DBEEEEEE, 000103265 +dd 000000000, 012000000, 0EE272222, 022E4BE72, 000102222, 000000000, 000000000, 0DE7C4512, 0EEEEEEEE, 00031B7ED, 0EEEE9D13, 00010C7EE, 0ECEECE05, 0EEEE0340, 0EEDE79DA, 00000C1EE +dd 00000A3EE, 0EEBE0300, 000C5EEEE, 0EEEE8D03, 01084ECEE, 0BD370100, 0EEEEEEEE, 096DCEEEE, 000102222, 000000000, 0EE050000, 000E29E50, 000000000, 000000000, 09D372212, 0EEEEEEDE +dd 0A7EDEEEE, 08C140031, 0EDEEEEEE, 005000082, 070EDEECE, 0D7EE1D00, 0EEEE9E10, 00000E9EE, 0000000E7, 0EE0A0000, 0C7EEEEEE, 0EE4A0110, 0ECEEEEEE, 000001084, 0EEDE7914, 0EEEEEEEE +dd 0C9DDEEEE, 022555565, 0EE060010, 000E2AE60, 025120000, 0DD795555, 0EEEEEEDE, 0EDEEEEEE, 0001063D9, 0EEEE8C14, 030D8EEEE, 0CE280000, 00081EEEE, 050EE8E00, 0EEEEEE05, 00030EEEE +dd 000000090, 0DE010000, 0EEEECEEA, 0150051EB, 0EEEEEE9D, 02195DCEE, 025010000, 0EEEEDD89, 0EEEEEEEE, 0EEEEEEEE, 0EEDDDDDD, 0DDEDEEDD, 0EEDEDDDD, 0EEEEEEEE, 0EEEEEEEE, 02175D9ED +dd 09D260100, 0EEEEEEDE, 0001084ED, 0EEEE7C01, 0000092EE, 000E9DE00, 0DEC5EE0C, 00080EEED, 000000040, 06E000000, 0EECE05EA, 00094EDEE, 0EEBD2700, 0EDEEEEEE, 0000031A7, 069250100 +dd 0EEEEDE9D, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 06499DDEE, 001000021, 0EEEEBD48, 0A5EDEEEE, 015000020, 0EEEEEEBE, 0000000A3, 000E4DE01, 08E30EE1D, 000A0EEED +dd 000000020, 03E000000, 08D0310ED, 0D7EEEEEE, 048010031, 0EEEEEECE, 098DCEDEE, 000002153, 056250100, 0DDDD9999, 0EEEEEEDD, 0EEEEEEEE, 0DDDDEDEE, 0559699D9, 001000021, 0DD9D5824 +dd 0EEEEEEEE, 00031B7ED, 0DE480100, 072ECEEEE, 000000000, 000E2EE02, 03E20EE2E, 000D1EEEE, 000000030, 06E000000, 0000000ED, 0EEEEDE39, 0001095ED, 0EEAD3701, 0EEEEEEEE, 097A9EDEE +dd 000002154, 000000000, 0CE221200, 02282DEB2, 000001022, 012000000, 0BD995825, 0EEEEEEEE, 096EDEEEE, 000000021, 0EEEEBE25, 00030D8EE, 000000000, 000E3DE01, 05E20EE1E, 000D0EEED +dd 000000080, 0BE000000, 0000000E9, 0EEBE1500, 062EBEEEE, 025010000, 0EEEEDE9B, 0EEEEEEEE, 099DAEEEE, 022659999, 0AE222222, 02272DEC1, 069352222, 0DE9B9999, 0EEEEEEEE, 0EEEEEEEE +dd 0001084DB, 07C030000, 0EDEEEEEE, 000000093, 000000000, 000E7DE00, 0BE83EE0D, 00090EEED, 0000000E4, 0EE080000, 0000000E4, 059010000, 0EEEEEEDE, 0001052B9, 09B360100, 0EEEEEEDE +dd 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEED, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 03196DBEE, 000000000, 0EECE6913, 041D8EEEE, 000000000, 000000000, 020ED8E00, 0EEEEEE07, 00040EEEE +dd 0000061ED, 0EE8E0200, 000000080, 000000000, 0EEEE8D13, 074DBEEEE, 000000010, 09C692501, 0EEEEEEDD, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 0EEEEEEEE, 05598DBED, 000000021 +dd 08C250000, 0EEEEEEDE, 0000073EC, 000000000, 000000000, 0C4EE1D00, 0EEEEBE01, 00000E9EE, 02282EDEE, 0E9EEAE23, 000000000, 000000000, 0BD270000, 0EEEEEEEE, 0105298EB, 000000000 +dd 058452201, 0DDDDCD99, 0EEEEEEEE, 0EEEEEEEE, 0DDDDEDEE, 0425598C9, 000000021, 012000000, 0EEEE9C58, 0B5EDEEEE, 000000020, 000000000, 000000000, 0EEEE0300, 0EEDE18C4, 00000C1EE +dd 0EEEEEEDE, 0D1EEEEEE, 000000000, 000000000, 001000000, 0EEEEBD37, 0EDEEEEEE, 0001032A8, 000000000, 000000000, 02D222212, 02222EAEA, 000001022, 000000000, 001000000, 0EEAD4822 +dd 0EEEEEEEE, 00031B7ED, 000000000, 000000000, 000000000, 0EE7E0000, 0EEDEDDEE, 0000030EE, 0EEEEEE28, 010E8EEEE, 000000000, 000000000, 000000000, 0BD370100, 0EEEEEEEE, 0D9EDEEEE +dd 000003185, 000000000, 009000000, 00000E5EC, 000000000, 000000000, 0DD994601, 0EEEEEEEE, 0B7EDEEEE, 000000031, 000000000, 000000000, 000000000, 0CE050000, 0EEEEEEEE, 0000000C3 +dd 002DD0000 + +;------------------------------------------------------------------------------- +.RADIX 10 + +BITMAPSEG ENDS +END ; end of the file + +; Bitmap Converter Finished. diff --git a/x86-asm-source/sound.bmp b/x86-asm-source/sound.bmp new file mode 100644 index 0000000000000000000000000000000000000000..7eaf9c79adaa4583209446d4158bea096e9ea7e3 GIT binary patch literal 246 zcmXv{F%Ci@46VV0Klwd|qoWCfiMw|pA+aV7utDNwya6QM$%O%5i?+P?N?)Ou>xX9C zAO~Ro!-lqMB=CDT@%PjqIAW$W1&oqfYfv$U9vVX`04XgHGkXg{m_@}OIV0JWk?(Mw w9XYc%6^ib&lc;~J^%m! literal 0 HcmV?d00001 diff --git a/x86-asm-source/tip-asm.sav b/x86-asm-source/tip-asm.sav new file mode 100644 index 0000000..8d4ccc6 --- /dev/null +++ b/x86-asm-source/tip-asm.sav @@ -0,0 +1,3061 @@ +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ TIP.ASM TROUBLE IN PARADISE 05/22/98 ³ +;ÔÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ; +; +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ TO DO ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +; +; o verify that disk status is being read correctly with External Zip drives +; +; o spell-check all rtf files and tip.txt +; +; o dynamically adapt to maximum adpater transfer length +; +; o handle completion debriefing +; +;-//////////////////////////////////////////////////////////////////////////- +; +; o determine TRUE maximum number of available JAZ relocations +; This still needs to be done, but for now I've clipped the test so if +; we are told there are more than the maximum we'll be okay. +; +; o lock drives for use under Win95/98 and NT ?????? +; o perhaps LOCKING the drive for exclusive use? +; Can't Lock drive for exclusive use, since the locking semantics are for +; LOGICAL (drive letter) devices, and there's no clear and simple API for +; determining the LOGICAL drive letter from the PHYSICAL SCSI device. +; +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + +include standard.inc +include aspi.inc +include richedit.inc +include commctrl.inc +include macros.inc + +DEVELOPMENT = 1 +INITIAL_PAGE = PERFORM_TEST_PAGE +FORCE_TROUBLE = 0 +MINIMUM_VERSION = 0 ; set it to zero for NO minimum version checking + +EXTERNDEF FontBitmapImage :DWORD ; our floating "?" bitmap image +EXTERNDEF RTF_Data :DWORD + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ F U N C T I O N P R O T O T Y P E S ³ +;ÔÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ; +WndProc PROTO :HWND, :UINT, :WPARAM, :LPARAM +CenterWindow PROTO :HWND +DecompressBinary PROTO :LPVOID +AllocateSixteenColorDib PROTO Hwidth:DWORD, Vheight:DWORD +SplashTheBitmap PROTO hDC:HDC +PrepForFastBlitting PROTO :HGLOBAL +ApplicationTimerProc PROTO :HWND, :UINT, :UINT, :DWORD +EjectIomegaCartridge PROTO Adapter:DWORD, Device:DWORD +SpinUpIomegaCartridge PROTO Adapter:DWORD, Device:DWORD +SetRichEditText PROTO phRichEditControl:LPHWND, pText:LPSTR +PostToScreen PROTO PostVal:DWORD +PasswordWndProc PROTO :HWND, :UINT, :WPARAM, :LPARAM + +SetTabErrorMode PROTO DisplayMode:BOOL +EjectAllMedia PROTO ; unlock and eject all drives + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ E Q U A T E S ³ +;ÔÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ; +WIZARD_WINDOW_HEIGHT equ 337 ; 358 - 19 +WIZARD_WINDOW_WIDTH equ 467 ; 480 + +NUMBER_OF_FLOATERS equ 6 +VELOCITY_MULTIPLIER equ 1000 + +SMALLER_FONT_SIZE equ 8 +LARGER_FONT_SIZE equ 10 +HEADLINE_FONT_SIZE equ 21 + +SPLASH_WIDTH equ 120 +SPLASH_HEIGHT equ 258 + +FONT_WIDTH equ 151 +FONT_HEIGHT equ 251 + +LOGO_1_LEFT equ 157 +LOGO_1_TOP equ 57 + +LOGO_2_LEFT equ 400 +LOGO_2_TOP equ 17 + +HYPERLINK_HEIGHT equ 248 + +FILE_TIME_TICKS_PER_SECOND equ 10000000 + +SOURCE_BITMAP_BYTE_WIDTH equ ((FONT_WIDTH+31)/32)*4 +DEST_BITMAP_BYTE_WIDTH equ (SPLASH_WIDTH / 2) +FONT_TOP_OFFSET equ SIZEOF BITMAPFILEHEADER + SIZEOF BITMAPINFOHEADER + 2*4 + ((FONT_HEIGHT-1) * SOURCE_BITMAP_BYTE_WIDTH) + +RANDOMULT equ 0B6CAEB15h + +PALETTE_SIZE equ 16 ; Splash is a 16-color bitmap + +IDB_LINEUP equ WM_APP +IDB_LINEDN equ WM_APP+1 +IDB_PAGEUP equ WM_APP+2 +IDB_PAGEDN equ WM_APP+3 +IDB_END equ WM_APP+4 +IDB_HOME equ WM_APP+5 + +FLASH_COUNT equ 16 +RANDOMULT equ 0B6CAEB15h + +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Password Dialog Defines ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + +IDC_PASSWORD equ 3 + +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Drive Array Status Flags ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + +; +---- Device +; | +--- Adapter +; v v +JAZ_DRIVE equ 00010000h +MEDIA_CHANGED equ 00020000h +DISK_EJECTING equ 00040000h ; we've asked for eject and waiting ... +MAX_DRIVE_COUNT equ 16 ; we can handle up to 16 Zip/Jaz drives + +FORMAT_STATUS_PAGE equ 1 +DISK_STATUS_PAGE equ 2 + NEW_DISK_STATUS_OFFSET equ 3 ; newer offset of the Disk Status Byte + OLD_DISK_STATUS_OFFSET equ 1 ; older " " " " + +JAZ_SPARES_COUNT_OFFSET equ 68 ; offsets into DiskStat tbl +NEW_ZIP_SIDE_0_SPARES_COUNT_OFFSET equ 13 +NEW_ZIP_SIDE_1_SPARES_COUNT_OFFSET equ 17 +OLD_ZIP_SIDE_0_SPARES_COUNT_OFFSET equ 11 +OLD_ZIP_SIDE_1_SPARES_COUNT_OFFSET equ 15 +JAZ_PROTECT_MODE_OFFSET equ 21 +NEW_ZIP_PROTECT_MODE_OFFSET equ 21 +OLD_ZIP_PROTECT_MODE_OFFSET equ 19 +JAZ_LAST_LBA_OFFSET equ 5 +NEW_ZIP_LAST_LBA_OFFSET equ 5 +OLD_ZIP_LAST_LBA_OFFSET equ 3 + +MINIMUM_JAZ_SPARES equ 500 +MAXIMUM_JAZ_SPARES equ 2557 +MINIMUM_ZIP_SPARES equ 50 +MAXIMUM_ZIP_SPARES equ 126 + +BYTES_PER_SECTOR equ 512 + +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Cartridge Status ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + +DISK_STATUS_UNKNOWN equ 1 +DISK_AT_SPEED equ 2 +DISK_SPINNING_UP equ 3 +DISK_NOT_PRESENT equ 4 +DISK_SPUN_DOWN equ 5 +DISK_STALLED equ 6 +DISK_Z_TRACK_FAILURE equ 7 +DISK_PROTECTED equ 8 +DISK_LOW_SPARES equ 9 +DISK_TEST_UNDERWAY equ 10 +DISK_TEST_FAILURE equ 11 +;-------------------------------------------------------------------------- +LAST_CART_STATUS equ 11 + +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Testing Phase Status ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + +UNTESTED equ 0 +READY_TO_TEST equ 1 +TESTING_STARTUP equ 2 +READING_DATA equ 3 +WRITING_PATT equ 4 +READING_PATT equ 5 +WRITING_DATA equ 6 + +;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +;³ NON-COMPRESSED GLOBAL DATA ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ + .data + ALIGN 4 + +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ANIMATION MOTION CONSTANTS ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + +xleft DWORD NUMBER_OF_FLOATERS dup (0) +ytop DWORD NUMBER_OF_FLOATERS dup (FONT_TOP_OFFSET) +xwidth DWORD NUMBER_OF_FLOATERS dup (FONT_WIDTH) +yheight DWORD NUMBER_OF_FLOATERS dup (FONT_HEIGHT) +transform DWORD NUMBER_OF_FLOATERS dup (Xform1) +Xform1 DWORD 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15 +ObjectTypes DWORD 0,1*4,2*4,3*4,4*4,5*4 +; this gives same-width objects different velocities, otherwise they +; would all be running at exactly the same speed with boring overlaps +velocities DWORD FONT_WIDTH, FONT_WIDTH+20, FONT_WIDTH+40 + DWORD FONT_WIDTH+60, FONT_WIDTH+80, FONT_WIDTH+100 + +LogoPalette WORD 0300h ; LOGPALETTE HEADER WORDS + WORD PALETTE_SIZE +SplashPalette DWORD 00A10303h, 00AD1F20h, 00B32E30h, 00B93E40h + DWORD 00BC4649h, 00C35559h, 00C65E62h, 00CB6A6Eh + DWORD 00D27A80h, 00DA8D93h, 00DF99A0h, 00E09DA4h + DWORD 00E6ABB3h, 00EDBCC5h, 00FCE1EAh, 00FEEAF1h + +FourBitMasks DWORD 0000000Fh, 000000F0h, 00000F00h, 0000F000h + DWORD 000F0000h, 00F00000h, 0F000000h, 0F0000000h + +;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ +CommandDetailsTable LABEL BYTE ; Command +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +db SCSI_Cmd_RequestSense , SRB_DIR_IN ; 03 IN == get from drive +db SCSI_Cmd_FormatUnit , 0 ; 04 OUT == send to drive +db SCSI_Cmd_NonSenseData , SRB_DIR_IN ; 06 +db SCSI_Cmd_Read , SRB_DIR_IN ; 08 +db SCSI_Cmd_Write , SRB_DIR_OUT ; 0A +db SCSI_Cmd_CartProtect , SRB_DIR_OUT ; 0C +db SCSI_Cmd_Inquiry , SRB_DIR_IN ; 12 +db SCSI_Cmd_ModeSelect , SRB_DIR_OUT ; 15 +db SCSI_Cmd_ModeSense , SRB_DIR_IN ; 1A +db SCSI_Cmd_StartStopUnit , 0 ; 1B +db SCSI_Cmd_SendDiagnostic , 0 ; 1D +db SCSI_Cmd_PreventAllow , 0 ; 1E +db SCSI_Cmd_TranslateLBA , SRB_DIR_IN ; 22 +db SCSI_Cmd_FormatTest , 0 ; 24 +db SCSI_Cmd_ReadMany , SRB_DIR_IN ; 28 +db SCSI_Cmd_WriteMany , SRB_DIR_OUT ; 2A +db SCSI_Cmd_Verify , 0 ; 2F +db SCSI_Cmd_ReadDefectData , SRB_DIR_IN ; 37 +;-------------------------------------------------------------------------- +LENGTH_OF_DETAILS_TABLE = $ - CommandDetailsTable + +RichEditStreamIn EDITSTREAM + +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Test Monitor Panel Definitions ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + +CS_Stat RECT <114, 8, 242, 28> +TP_Perc RECT < 12, 56, 409, 72> +SS_Jaz RECT < 12, 94, 409,126> +SS_Sid0 RECT < 12, 94, 409,110> +TL_Sect RECT < 65,154, 193,170> +ES_Read RECT <346,154, 409,170> + +;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +;³ COMPRESSED GLOBAL DATA ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ + ALIGN 4 +StartEncryption CHAR "SOE!" +;-------------------------------------------------------------------------- +include tip.dat +include tip.txt +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +szAppName CHAR "TIP" +szNullString CHAR 0 +szWindowTitle CHAR " TIP -- Zip & Jaz Drive Tester",0 + +szRedBitmap CHAR "REDBITMAP",0 +szGreenBitmap CHAR "GRNBITMAP",0 +szOffBitmap CHAR "OFFBITMAP",0 + +ChildRegionRect RECT <0,0, 460,285> +TabWindowRegionRect RECT <20,45, 440,270> +SplashRect RECT <14,16,138,278> +WebButton RECT <12,295,140,330> + +szCopyright_1 CHAR "Copyright (c) 1998 by",0 +szCopyright_2 CHAR "Gibson Research Corp.",0 +szCrLf CHAR CR,LF + +szASPI32DLLName CHAR "wnaspi32.dll",0 +szASPI32SupportInfo CHAR "GetASPI32SupportInfo",0 +szASPI32Command CHAR "SendASPI32Command",0 +szCloseCmd CHAR "Close",0 +szRichEditLibrary CHAR "RichEd32.Dll",0 +szIomega CHAR "Iomega",0 +szZip CHAR "Zip",0 +szJaz CHAR "Jaz",0 + +; szInstructionText CHAR "instructions",0 +; szZtrackFailure CHAR "ztrackfailure",0 +; szVeryFewSpares CHAR "veryfewspares",0 +; szNoSpares CHAR "nospares",0 +; szOutOfSpares CHAR "outofspares",0 +; szLockedRtf + +szShellOpenOp CHAR "open",0 +szShellOpenFile CHAR "http://grc.com",0 +szWebFailedTitle CHAR "Unable to Launch a Web Browser",0 +szWebFailedText CHAR "TIP was unable to successfully launch",CR,LF + CHAR "this system's Internet web Browser.",CR,LF + CHAR CR,LF + CHAR "Please check out the http://grc.com website",CR,LF + CHAR "to find out what's new !",0 +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +IF MINIMUM_VERSION +szVersionErrorTitle CHAR "Windows Version Trouble",0 +szVersionErrorText CHAR "This 32-bit Windows client program requires",CR,LF + CHAR "Windows 95/98 or later, or Windows NT 4.0 or",CR,LF + CHAR "later, These operating environments natively ",CR,LF + CHAR "support the ",34,"ASPI for Win32",34," subsystem which",CR,LF + CHAR "this program requires for operation.",0 +ENDIF +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +szArialFontName CHAR "Arial",0 +szCourierNew CHAR "Courier New",0 + +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +TypeTable CHAR " Disk:"," Tape:","Printer:"," CPU:"," WORM:" + CHAR " CD-ROM:","Scanner:","Optical:","JukeBox:","unknown!" + +DividingLine CHAR "--------------------------------------------------",CR,LF + +Removable CHAR "Remov" +Fixed CHAR "Fixed" + +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ FONT CREATION CONSTANTS ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + +CurrentPage DWORD INITIAL_PAGE ; 0 -to- MAX ... the page we're seeing +PreviousPage DWORD -1 ; forces a first draw of every control +ActionsSubPage DWORD FIRST_ACTION_PAGE +;-------------------------------------------------------------------------- +OurTypeFaceSpec DWORD -9, 0, 0, 0 ; both fonts are 9 pixels high +OurFontWeight DWORD FW_NORMAL ; either bold or normal weight + BYTE 0 +OurUnderline BYTE 0, 0 +OurCharSet BYTE DEFAULT_CHARSET +OurFontPrecise BYTE OUT_RASTER_PRECIS, 0, PROOF_QUALITY +PitchAndFamily BYTE 0 +OurFontName CHAR "MS Sans Serif", 0 + +szSide0 CHAR "Side 0",0 +szSide1 CHAR "Side 1",0 +szSpaceDashSpace CHAR " - ",0 + +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + ALIGN 4 +EndEncryption CHAR "EOE!" +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + +RandomSeed DWORD 100 + +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Development Only Data ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +IF DEVELOPMENT +POSTING_SPACE equ 5 +szLongHexFormat CHAR " %08lX ",0 ; a wsprintf format spec. +szBarChartPercent CHAR " %ld%% ",0 +szCenteredDecimal CHAR "%ld",0 +szHoursMinsSecs CHAR "%ld:%02ld:%02ld",0 +LastPostedValue DWORD -1 ; posting to the screen +LastPostedTop DWORD 0 ; the height of the posting +LastPostedLeft DWORD 0 +ENDIF + +;-------------------------------------------------------------------------- + .data? +;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +;³ Uninitialized Static Global Data ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +hMainWnd HWND ? ; +MainWndMsg MSG <> +hInst HINSTANCE ? ; and handle to our main instance +hRichEditLibrary HANDLE ? +hAccel HACCEL ? +hCompletionEvent HANDLE ? +hApplicationTimer DWORD ? +hSplashPalette HPALETTE ? +CPUis386 BOOL ? +WinNT BOOL ? + +HyperlinkRect RECT +HyperlinkPoint POINT +hHyperlinkCursor HCURSOR ? +hStandardCursor HCURSOR ? + +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Pointers to all of the richtext blocks ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + +pFontBitmap LPVOID ? +pSplashDIB LPVOID ? +pRTF_Data LPVOID ?, ? ; pointer followed by stream length + +StreamPointer LPBYTE ? ; pointer to richedit stream +StreamEnd LPBYTE ? ; pointer to past the end of stream + +hASPIDLL HANDLE ? +lpGetASPI32SupportInfo LPVOID ? +lpSendASPI32Command LPVOID ? + +ASPI_CmdBlock ScsiRequestBlock <> + +ErrorMode BOOL ? +hErrorMessage HWND ? +hRichEdit HWND ?, ? ; handle and pTextLastSet +hTabText HWND ?, ? ; text appearing on the perform test +hActionTabs HWND ? +hTestMonitor HWND ? +hTestButton HWND ? +hExitButton HWND ? + +hNullPen HPEN ? +hWhitePen HPEN ? +hGrayPen HPEN ? +hDkGrayPen HPEN ? +hBlackPen HPEN ? + +hNullBrush HBRUSH ? +hWhiteBrush HBRUSH ? +hGrayBrush HBRUSH ? +hDkGrayBrush HBRUSH ? +hBlackBrush HBRUSH ? + +hNormalFont HFONT ? ; 00 - small / normal +hBoldFont HFONT ? ; 01 - small / bold +hDialogTextFont HFONT ? ; 10 - large / normal +hTitleFont HFONT ? ; 11 - large / bold +hHeadlineFont HFONT ? ; way big font +hFixedWidthFont HFONT ? +hDialogTextUnderlined HFONT ? + +hRedBitmap HBITMAP ? +hGreenBitmap HBITMAP ? +hOffBitmap HBITMAP ? + +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ FastTransparentBlt Parameters ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + +PixelsPerLine DWORD ? +PixelsToBlt DWORD ? ; copied from PixelsPerLine per line +LineCount DWORD ? +SourceLineStart DWORD ? +SourceBitStart DWORD ? +DestLineStart DWORD ? +DestBitStart DWORD ? + +xform DWORD 16 dup(?) + +HorzVelocity DWORD NUMBER_OF_FLOATERS dup (?) ; 16ù16 format +VertVelocity DWORD NUMBER_OF_FLOATERS dup (?) ; " " +HorzPosition DWORD NUMBER_OF_FLOATERS dup (?) ; " " +VertPosition DWORD NUMBER_OF_FLOATERS dup (?) ; " " + +ActionButtonFlasher DWORD ? + +pUserDataBuffer LPVOID ? ; pointer to user's data +pPatternBuffer LPVOID ? ; pointer to test pattern + +DriveCount DWORD ? +DriveArray DWORD MAX_DRIVE_COUNT dup (?) +CurrentAdapter DWORD ? ; the adapter that's been recognized +CurrentDevice DWORD ? ; the device that's been recognized +JazDrive DWORD BOOL ; true if the current drive is JAZ + +LastLBAOnCartridge DWORD ? +StartingInstant FILETIME +NumberOfLBAs DWORD ? + +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Run Time Variables ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + +CartridgeStatus DWORD DISK_NOT_PRESENT +Side_0_SparesCount DWORD ? ; JAZ has only one count +Side_1_SparesCount DWORD ? ; ZIP has counts for both sides +CartridgePassword CHAR 32+1 dup(?) +TransferLength DWORD ? +SectorsPerTest DWORD ? + + +FirstTestingVariable LABEL DWORD +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +TestingPhase DWORD ? ; 0 = not testing, no data ... +PercentComplete DWORD ? +FirstLBASector DWORD ? +LastLBASector DWORD ? +SecondsElapsed DWORD ? +ReadDataRecovery DWORD ? +WriteDataRecovery DWORD ? +UnrecoverableData DWORD ? +SectorsNotFound DWORD ? +TracksNotFound DWORD ? +ElapsedTimeOfLastEstimate DWORD ? +CurrentTotalTimeEstimate DWORD ? +UserInterrupt DWORD ? +LastError DWORD ? +SingleTransferLBA DWORD ? +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +TESTING_VARIABLE_COUNT equ ($ - FirstTestingVariable)/SIZEOF DWORD + + + .code +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ WinMain ³ +;³ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄij +;³ ³ +;³ Startup the Windows program. If no previous instances are running then ³ +;³ define and register a new window class, perform various initialization ³ +;³ chores, then setup the main message loop. ³ +;³ ³ +;ÔÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ; +Start: call DecryptOurselves + call Detect386Processor + invoke GetVersion ; find out what platform we're running ... +IF MINIMUM_VERSION + .IF (al < MINIMUM_VERSION) + invoke MessageBox, NULL, ADDR szVersionErrorText, ADDR szVersionErrorTitle, MB_OK + invoke ExitProcess, 1 + .ENDIF +ENDIF + .IF !(eax & 80000000h) + set WinNT + .ENDIF + ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + invoke GetModuleHandle, NULL ; get our module's handle + mov hInst, eax + call CheckPriorInstances + jc Close + call RegisterWindowClasses + jc Close + call CreateStaticResources + jc Close + call CreateAppWindows + jc Close + + ;-------------------------------------------------------------------------- + ; so far so good. now see if we have aspi services ... + call CheckForASPI ; returns the adapter count + .IF (eax) + ; aspi is available, so count the Iomega devices + call EnumerateIomegaDevices + .IF (eax == 1) + ; we have only one, so select it for the user + movmov byte ptr CurrentAdapter, al, byte ptr DriveArray[0] + movmov byte ptr CurrentDevice, al, byte ptr DriveArray[1] + .ELSEIF (eax > 1) + ; we have more than one, so eject'em all ... + call EjectAllMedia + .ENDIF + .ENDIF + call InitializeWizardControls + call InitializeTheFloaterSystem + ; now startup the timer for real-time features + invoke SetTimer, NULL, NULL, 50, ADDR ApplicationTimerProc + mov hApplicationTimer, eax + +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Our application's message loop ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + invoke ShowWindow, hMainWnd, SW_NORMAL + invoke UpdateWindow, hMainWnd + .WHILE TRUE + invoke GetMessage, ADDR MainWndMsg, NULL, 0, 0 + .BREAK .IF (!eax) + invoke TranslateAccelerator, hMainWnd, hAccel, ADDR MainWndMsg + .CONTINUE .IF (eax) ; skip if we handled + invoke TranslateMessage, ADDR MainWndMsg + invoke DispatchMessage, ADDR MainWndMsg + .ENDW + + call UnlockAllMedia +Close: call DeleteStaticResources + invoke ExitProcess, MainWndMsg.wParam +;-//////////////////////////////////////////////////////////////////////////- + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ DECRYPT OURSELVES ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +DecryptOurselves PROC +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + mov esi, OFFSET StartEncryption + .IF (dword ptr [esi] != "!EOS") + mov ecx, OFFSET EndEncryption + sub ecx, esi + shr ecx, 2 + mov edi, esi + .REPEAT + lodsd + xor eax, 0AAAAAAAAh + stosd + .UNTILCXZ + .ENDIF + ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +DecryptOurselves ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ DETECT 386 PROCESSOR ³ +;³ Returns NON-ZERO if we have a 386 processor! ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +Detect386Processor PROC +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + mov ebx, esp ; save current stack pointer to align it + and esp, not 3 ; align stack to avoid AC fault + pushfd ; push original EFLAGS + pop eax ; get original EFLAGS into EAX + mov ecx, eax ; also hold them in ECX + xor eax, 40000h ; invert the AC bit in EFLAGS + push eax ; save for movement into EFLAGS + popfd ; copy into EFLAGS + pushfd ; push EFLAGS + pop eax ; get new EFLAGS value + xor eax, ecx ; see if it was settable + .IF !(eax & 40000h) ; if the bit could not be set ... CPU == 386 + set CPUis386 + .ENDIF + mov esp, ebx + ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +Detect386Processor ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ CHECK PRIOR INSTANCES ³ +;³ Check to see if we're already running and if so, un-minimize it ³ +;³ and bring it back to the top of the screen ... and terminate us ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +CheckPriorInstances PROC +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + invoke FindWindow, NULL, ADDR szWindowTitle + check eax ; clears CY + .IF (!zero?) + push eax ; save the window's hWnd + invoke ShowWindow, eax, SW_SHOWNORMAL + pop eax ; recover the window's hWnd + invoke SetWindowPos, eax, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE OR SWP_NOSIZE + stc ; return carry to abort OUR instance + .ENDIF + ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +CheckPriorInstances ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ REGISTER WINDOW CLASSES ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +RegisterWindowClasses PROC + LOCAL wndclass:WNDCLASS +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + varzero wndclass + movmov wndclass.hInstance, eax, hInst + mov wndclass.hbrBackground, COLOR_BTNFACE + 1 + mov wndclass.lpszClassName, OFFSET szAppName + invoke LoadIcon, hInst, OFFSET szAppName + mov wndclass.hIcon, eax + mov wndclass.lpfnWndProc, OFFSET WndProc + invoke RegisterClass, ADDR wndclass + sub eax, 1 + jc Exit + +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Register the TestMonitor Window Style ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + zero eax + mov wndclass.hbrBackground, eax + mov wndclass.lpszClassName, OFFSET szTestMonitor + mov wndclass.lpfnWndProc, OFFSET TestMonitorWndProc + invoke RegisterClass, ADDR wndclass + sub eax, 1 + jc Exit + +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Register the 3D Sink Window Style ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + mov wndclass.lpszClassName, OFFSET sz3DSink + mov wndclass.lpfnWndProc, OFFSET SinkWndProc + invoke RegisterClass, ADDR wndclass + sub eax, 1 + jc Exit + +Exit: ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +RegisterWindowClasses ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ CREATE DIB PALETTE ³ +;³ Create a 16-color palette. This is used only when the target ³ +;³ system is running in 256-color mode. It contains the image's ³ +;³ custom color set and is realized whenever our window is painted. ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +CreateDIBPalette PROC USES esi edi +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + mov esi, OFFSET SplashPalette ; get the palette data + mov edi, esi + mov ecx, PALETTE_SIZE ; the palette entry count + .REPEAT + lodsd ; .RGB + swap ah, al ; .RBG + ror eax, 8 ; G.RB + swap ah, al ; G.BR + rol eax, 8 ; .BRG + swap ah, al ; .BGR + stosd + .UNTILCXZ + invoke CreatePalette, ADDR LogoPalette + mov hSplashPalette, eax + ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +CreateDIBPalette ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ CONVERT BRACKETS TO NULLS ³ +;³ This scans the block of text converting all closing brackets ']' into ³ +;³ NULLs so that a string compare can be used to find section blocks. ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +ConvertBracketsToNulls PROC USES edi, pBuffer:DWORD, nLength:DWORD +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + mov al, ']' ; we'll be scanning for a closing ']' + mov ecx, nLength ; for this many characters + mov edi, pBuffer ; and at this point in the buffer + .WHILE (ecx) + repne scasb ; scan to a ']' + .BREAK .IF (!zero?) ; if we didn't find one, quit + mov byte ptr [edi-1], 0 ; found one!, so nuke it + .ENDW ; and look for another + ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +ConvertBracketsToNulls ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ CREATE STATIC RESOURCES ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +CreateStaticResources PROC +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + invoke DecompressBinary, ADDR FontBitmapImage + mov pFontBitmap, eax + invoke PrepForFastBlitting, eax + + invoke DecompressBinary, ADDR RTF_Data + mov pRTF_Data, eax + mov pRTF_Data[4], ebx + invoke ConvertBracketsToNulls, eax, ebx + + invoke GetStockObject, NULL_PEN + mov hNullPen, eax + invoke GetStockObject, BLACK_PEN + mov hBlackPen, eax + invoke GetStockObject, WHITE_PEN + mov hWhitePen, eax + invoke CreatePen, PS_SOLID, 1, LTGRAY_COLOR + mov hGrayPen, eax + invoke CreatePen, PS_SOLID, 1, GRAY_COLOR + mov hDkGrayPen, eax + +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Create System Brushes ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + invoke GetStockObject, NULL_BRUSH + mov hNullBrush, eax + invoke GetStockObject, WHITE_BRUSH + mov hWhiteBrush, eax + invoke GetStockObject, LTGRAY_BRUSH + mov hGrayBrush, eax + invoke GetStockObject, DKGRAY_BRUSH + mov hDkGrayBrush, eax + invoke GetStockObject, BLACK_BRUSH + mov hBlackBrush, eax + + call CreateAppFonts + + invoke LoadLibrary, ADDR szRichEditLibrary + mov hRichEditLibrary, eax + sub eax, 1 ; make sure the library loaded + jc Exit + + invoke LoadAccelerators, hInst, ADDR szAppName + mov hAccel, eax + + invoke LoadCursor, NULL, IDC_ARROW + mov hStandardCursor, eax + + invoke LoadCursor, hInst, ADDR szAppName + mov hHyperlinkCursor, eax + + invoke CreateEvent, NULL, FALSE, FALSE, NULL + mov hCompletionEvent, eax + + invoke LoadBitmap, hInst, ADDR szRedBitmap + mov hRedBitmap, eax + + invoke LoadBitmap, hInst, ADDR szGreenBitmap + mov hGreenBitmap, eax + + invoke LoadBitmap, hInst, ADDR szOffBitmap + mov hOffBitmap, eax + +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Allocate the Splash Animation DIB ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + invoke AllocateSixteenColorDib, SPLASH_WIDTH, SPLASH_HEIGHT + mov pSplashDIB, eax + add eax, SIZEOF BITMAPINFOHEADER ; point to the palette + invoke MoveMemory, eax, ADDR SplashPalette, 16*4 + ; now invert the SplashPalette and Create a GDI palette in case + ; we're running on a 256-color system ... + invoke CreateDIBPalette + clc +Exit: ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +CreateStaticResources ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ SET FONT POINT SIZE ³ +;³ nHeight = -MulDiv (PointSize, GetDeviceCaps(hDC, LOGPIXELSY), 72) ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +SetPointSize PROC USES edi, PointSize:DWORD +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +; invoke GetDC, 0 ; get a display DC +; mov edi, eax +; invoke GetDeviceCaps, eax, LOGPIXELSY ; 96 or 120 +; invoke MulDiv, PointSize, eax, 72 +; neg eax +; mov OurTypeFaceSpec, eax +; invoke ReleaseDC, 0, edi + + invoke MulDiv, PointSize, 96, 72 + neg eax + mov OurTypeFaceSpec, eax + + ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +SetPointSize ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ CREATE APP FONTS ³ +;³ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄij +;³ This creates the four fonts we use throughout ChromaZone ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +CreateAppFonts PROC USES edi +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + ; if we're NOT running with standard "small fonts" then switch + ; us over to ARIAL for our main font displays for pixel sizing + invoke GetDC, 0 + mov edi, eax + invoke GetDeviceCaps, eax, LOGPIXELSY ; 96 or 120 + .IF (eax != 96) + invoke lstrcpy, ADDR OurFontName, ADDR szArialFontName + .ENDIF + invoke ReleaseDC, 0, edi + + ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + mov OurFontWeight, FW_NORMAL + invoke SetPointSize, SMALLER_FONT_SIZE + invoke CreateFontIndirect, ADDR OurTypeFaceSpec + mov hNormalFont, eax + + invoke SetPointSize, LARGER_FONT_SIZE + invoke CreateFontIndirect, ADDR OurTypeFaceSpec + mov hDialogTextFont, eax + + set OurUnderline + invoke CreateFontIndirect, ADDR OurTypeFaceSpec + mov hDialogTextUnderlined, eax + reset OurUnderline + + mov OurFontWeight, FW_BOLD + invoke SetPointSize, SMALLER_FONT_SIZE + invoke CreateFontIndirect, ADDR OurTypeFaceSpec + mov hBoldFont, eax + + invoke SetPointSize, LARGER_FONT_SIZE + invoke CreateFontIndirect, ADDR OurTypeFaceSpec + mov hTitleFont, eax + + ; make the larger Headline font + invoke SetPointSize, HEADLINE_FONT_SIZE + invoke lstrcpy, ADDR OurFontName, ADDR szArialFontName + invoke CreateFontIndirect, ADDR OurTypeFaceSpec + mov hHeadlineFont, eax + + ; now we work to create a fixed-width font ... + invoke SetPointSize, LARGER_FONT_SIZE + mov OurFontWeight, FW_NORMAL + mov PitchAndFamily, FIXED_PITCH + invoke lstrcpy, ADDR OurFontName, ADDR szCourierNew + invoke CreateFontIndirect, ADDR OurTypeFaceSpec + mov hFixedWidthFont, eax + + ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +CreateAppFonts ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ CREATE APP WINDOWS ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +CreateAppWindows PROC +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + invoke GetSystemMetrics, SM_CYCAPTION ; includes Y border + add eax, WIZARD_WINDOW_HEIGHT + invoke CreateWindowEx, WS_EX_APPWINDOW or WS_EX_DLGMODALFRAME, + ADDR szAppName, ADDR szWindowTitle, DS_NOIDLEMSG or WS_POPUP or WS_CAPTION or WS_SYSMENU or WS_MINIMIZEBOX, + 0,0, WIZARD_WINDOW_WIDTH, eax, NULL, NULL, hInst, NULL + mov hMainWnd, eax + check eax + jz Exit +;-------------------------------------------------------------------------- + call CreateChildControls + jz Exit +;-------------------------------------------------------------------------- + call SetCurrentWindow + mov eax, 1 + +;-------------------------------------------------------------------------- +Exit: sub eax, 1 ; set carry if we're returning a zero + ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +CreateAppWindows ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ DELETE STATIC RESOURCES ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +DeleteStaticResources PROC +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + invoke KillTimer, NULL, hApplicationTimer + + invoke DeleteObject, hGrayPen + invoke DeleteObject, hDkGrayPen + invoke DeleteObject, hNormalFont + invoke DeleteObject, hDialogTextFont + invoke DeleteObject, hBoldFont + invoke DeleteObject, hTitleFont + invoke DeleteObject, hFixedWidthFont + invoke DeleteObject, hHeadlineFont + invoke DeleteObject, hDialogTextUnderlined + invoke DeleteObject, hSplashPalette + invoke DeleteObject, hRedBitmap + invoke DeleteObject, hGreenBitmap + invoke DeleteObject, hOffBitmap + invoke GlobalFree, pFontBitmap + invoke GlobalFree, pSplashDIB + invoke GlobalFree, pRTF_Data + + invoke CloseHandle, hCompletionEvent ; ASPI completion notification + invoke FreeLibrary, hRichEditLibrary + + mov eax, hASPIDLL + .IF (esi) + invoke FreeLibrary, eax + .ENDIF + ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +DeleteStaticResources ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ BINARY TO DECIMAL ³ +;³ Convert a 32-bit doubleword into its decimal equivalent ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +BinaryToDecimal PROC dest:PTR, val:DWORD, digits:DWORD, reorder:BOOL +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + mov ebx, dest ; determine where to store + mov ecx, digits ; and how many digits to blank + .REPEAT + mov byte ptr [ebx], SPACE + inc ebx + .UNTILCXZ + mov eax, val ; pick up the conversion value + .IF (reorder) ; abcd + ror eax, 8 ; dabc + swap ah, al ; dacb + ror eax, 16 ; cbda + swap ah, al ; cbad + ror eax, 8 ; dcba + .ENDIF + mov ecx, 10 ; convert to base 10 + .REPEAT + dec ebx ; move back to next digit + zero edx ; clear the high end for division + div ecx + add dl, '0' + mov [ebx], dl ; store the character + .UNTIL (!eax) + ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +BinaryToDecimal ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ ASCII IZE ³ +;³ Converts non-printing characters into SPACES, stops at the first CR. ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +AsciiIze PROC dest:LPSTR +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + mov ebx, dest + .WHILE (byte ptr [ebx] != CR) + .IF (byte ptr [ebx] < SPACE) || (byte ptr [ebx] > '~') + mov byte ptr [ebx], SPACE + .ENDIF + inc ebx + .ENDW + ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +AsciiIze ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ PAINT BITMAP ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +PaintBitmap PROC hDC:HDC, xpos:DWORD, ypos:DWORD, image:PTR +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + mov eax, image ; point to the top of the file + mov ebx, eax ; point ebx to the bits + add ebx, [eax + BITMAPFILEHEADER.bfOffBits] + add eax, SIZEOF BITMAPFILEHEADER + zero ecx + invoke SetDIBitsToDevice, hDC, xpos, ypos, [eax + BITMAPINFOHEADER.biWidth], [eax + BITMAPINFOHEADER.biHeight], + 0, 0, 0, [eax + BITMAPINFOHEADER.biHeight], ebx, eax, DIB_RGB_COLORS + ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +PaintBitmap ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ SET CONTROL TEXT ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +SetControlText PROC hDC:WPARAM, hWnd:LPARAM +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + invoke GetWindowLong, hWnd, GWL_ID + shr eax, TREATMENT_STYLE_SHIFT + .IF (eax == SMALL_NORMAL_TEXT) + mov eax, hNormalFont ; 00 - small / normal + .ELSEIF (eax == SMALL_BOLD_TEXT) + mov eax, hBoldFont ; 01 - small / bold + .ELSEIF (eax == LARGE_NORMAL_TEXT) + mov eax, hDialogTextFont ; 10 - large / normal + .ELSEIF (eax == LARGE_BOLD_TEXT) + mov eax, hTitleFont ; 11 - large / bold + .ELSEIF (eax == HEADLINE_TEXT) + mov eax, hHeadlineFont + .ELSEIF (eax == TERMINAL_TEXT) + mov eax, hFixedWidthFont + .ENDIF + invoke SelectObject, hDC, eax + ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +SetControlText ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ DRAW HYPERLINK ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +DrawHyperlink PROC color:DWORD +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + invoke GetDC, hMainWnd + mov edi, eax + invoke SetBkMode, edi, TRANSPARENT + invoke SelectObject, edi, hDialogTextUnderlined + invoke SetTextColor, edi, color + invoke TextOut, edi, HyperlinkPoint.x, HyperlinkPoint.y, ADDR szCheck_2, (szCheck_3 - szCheck_2) + invoke ReleaseDC, hMainWnd, edi + ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +DrawHyperlink ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ LAUNCH GRC WEBSITE ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +LaunchGRCWebsite: +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + invoke ShellExecute, NULL, ADDR szShellOpenOp, + ADDR szShellOpenFile, NULL, NULL, SW_NORMAL + .IF (eax <= 32) + call SetToStandardCursor + invoke MessageBox, hMainWnd, ADDR szWebFailedText, ADDR szWebFailedTitle, MB_OK + .ENDIF +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + ret + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ SET TO STANDARD CURSOR ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +SetToStandardCursor PROC +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + invoke SetCursor, hStandardCursor + .IF (eax == hHyperlinkCursor) + invoke DrawHyperlink, BLUE_COLOR + .ENDIF + ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +SetToStandardCursor ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ WndProc ³ +;³ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄij +;³ This is the system's main window procedure ³ +;ÔÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ; +WndProc PROC USES esi edi, hWnd:HWND, iMessage:UINT, wParam:WPARAM, lParam:LPARAM + LOCAL ps:PAINTSTRUCT, Rect:RECT, MousePos:POINT +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +mov eax, iMessage +;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +;³ WM_CREATE : center the windoow ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +.IF (eax == WM_CREATE) + invoke CenterWindow, hWnd ; ... then return(0) + invoke GetSystemMenu, hWnd, FALSE ; get sysmenu handle + invoke DeleteMenu, eax, SC_MAXIMIZE, 0 ; remove CLOSE + +;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +;³ WM_PAINT ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +.ELSEIF (eax == WM_PAINT) + invoke BeginPaint, hWnd, ADDR ps ; setup our paintstruct + mov edi, eax ; save our painting handle + +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Draw the Lower Horz Button Divider ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + invoke SelectObject, edi, hDkGrayPen + invoke MoveToEx, edi, 15, 289, NULL + invoke LineTo, edi, 446, 289 + invoke SelectObject, edi, hWhitePen + invoke LineTo, edi, 446, 290 + invoke LineTo, edi, 14, 290 + +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Draw the Gibson 'G' Logo ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + .IF (CurrentPage == INTRO_PAGE) + + invoke SelectObject, edi, hDkGrayPen + invoke MoveToEx, edi, LOGO_1_LEFT+1, LOGO_1_TOP+29, NULL + invoke LineTo, edi, LOGO_1_LEFT+14, LOGO_1_TOP+29 + invoke LineTo, edi, LOGO_1_LEFT+14, LOGO_1_TOP+0 + invoke SelectObject, edi, hWhitePen + invoke LineTo, edi, LOGO_1_LEFT+12, LOGO_1_TOP+0 + invoke LineTo, edi, LOGO_1_LEFT+0, LOGO_1_TOP+12 + invoke LineTo, edi, LOGO_1_LEFT+0, LOGO_1_TOP+30 + + invoke SelectObject, edi, hDkGrayPen + invoke MoveToEx, edi, LOGO_1_LEFT+18, LOGO_1_TOP+14, NULL + invoke LineTo, edi, LOGO_1_LEFT+46, LOGO_1_TOP+14 + invoke LineTo, edi, LOGO_1_LEFT+46, LOGO_1_TOP+12 + invoke LineTo, edi, LOGO_1_LEFT+34, LOGO_1_TOP+0 + invoke SelectObject, edi, hWhitePen + invoke LineTo, edi, LOGO_1_LEFT+17, LOGO_1_TOP+0 + invoke LineTo, edi, LOGO_1_LEFT+17, LOGO_1_TOP+15 + + invoke SelectObject, edi, hDkGrayPen + invoke MoveToEx, edi, LOGO_1_LEFT+33, LOGO_1_TOP+46, NULL + invoke LineTo, edi, LOGO_1_LEFT+46, LOGO_1_TOP+46 + invoke LineTo, edi, LOGO_1_LEFT+46, LOGO_1_TOP+29 + invoke LineTo, edi, LOGO_1_LEFT+34, LOGO_1_TOP+17 + invoke SelectObject, edi, hWhitePen + invoke LineTo, edi, LOGO_1_LEFT+32, LOGO_1_TOP+17 + invoke LineTo, edi, LOGO_1_LEFT+32, LOGO_1_TOP+47 + + invoke SelectObject, edi, hDkGrayPen + invoke MoveToEx, edi, LOGO_1_LEFT+1, LOGO_1_TOP+35, NULL + invoke LineTo, edi, LOGO_1_LEFT+12, LOGO_1_TOP+46 + invoke LineTo, edi, LOGO_1_LEFT+29, LOGO_1_TOP+46 + invoke LineTo, edi, LOGO_1_LEFT+29, LOGO_1_TOP+32 + invoke SelectObject, edi, hWhitePen + invoke LineTo, edi, LOGO_1_LEFT+0, LOGO_1_TOP+32 + invoke LineTo, edi, LOGO_1_LEFT+0, LOGO_1_TOP+35 + +;ÄÄÄÄÄÄÄÄÄÄÄ Paint the Splash Image Bitmap and the Web Hyperlink ÄÄÄÄÄÄÄÄÄÄÄÄ + + ; show the current logo bitmap + invoke SplashTheBitmap, edi + + invoke SetBkMode, edi, TRANSPARENT + invoke SelectObject, edi, hDialogTextFont + invoke lstrlen, ADDR szCheck_1 + invoke TextOut, edi, BODY_LEFT, HYPERLINK_HEIGHT, ADDR szCheck_1, eax + invoke GetTextExtentPoint, edi, ADDR szCheck_1, (szCheck_2 - szCheck_1), ADDR Rect + add Rect.top, HYPERLINK_HEIGHT + invoke lstrlen, ADDR szCheck_4 + invoke TextOut, edi, BODY_LEFT, Rect.top, ADDR szCheck_4, eax + + invoke SelectObject, edi, hDialogTextUnderlined + add Rect.left, BODY_LEFT + movmov HyperlinkRect.left, eax, Rect.left + mov HyperlinkRect.top, HYPERLINK_HEIGHT + + ; draw the hyperlink text over the existing text + invoke SetTextColor, edi, BLUE_COLOR + invoke TextOut, edi, Rect.left, HYPERLINK_HEIGHT, ADDR szCheck_2, (szCheck_3 - szCheck_2) + ; save the location for dynamic recoloring + movmov HyperlinkPoint.x, eax, Rect.left + mov HyperlinkPoint.y, HYPERLINK_HEIGHT + + ; save the enclosing rectangle for hot-spot sensing + invoke GetTextExtentPoint, edi, ADDR szCheck_2, (szCheck_3 - szCheck_2), ADDR HyperlinkRect.right + mov eax, HyperlinkRect.left + add HyperlinkRect.right, eax + mov eax, HyperlinkRect.top + add HyperlinkRect.bottom, eax + .ENDIF + +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Paint the Copyright Notice ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + .IF (CurrentPage < CREDITS_PAGE) + invoke SetTextColor, edi, GRAY_COLOR + invoke SetBkMode, edi, TRANSPARENT + invoke SelectObject, edi, hNormalFont + invoke lstrlen, ADDR szCopyright_1 + invoke TextOut, edi, 15, 298, ADDR szCopyright_1, eax + invoke lstrlen, ADDR szCopyright_2 + invoke TextOut, edi, 15, 311, ADDR szCopyright_2, eax + .ENDIF + +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Draw the Gibson 'G' Logo ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + .IF (CurrentPage == CREDITS_PAGE) + + invoke SelectObject, edi, hDkGrayPen + invoke MoveToEx, edi, LOGO_2_LEFT+1, LOGO_2_TOP+29, NULL + invoke LineTo, edi, LOGO_2_LEFT+14, LOGO_2_TOP+29 + invoke LineTo, edi, LOGO_2_LEFT+14, LOGO_2_TOP+0 + invoke SelectObject, edi, hWhitePen + invoke LineTo, edi, LOGO_2_LEFT+12, LOGO_2_TOP+0 + invoke LineTo, edi, LOGO_2_LEFT+0, LOGO_2_TOP+12 + invoke LineTo, edi, LOGO_2_LEFT+0, LOGO_2_TOP+30 + + invoke SelectObject, edi, hDkGrayPen + invoke MoveToEx, edi, LOGO_2_LEFT+18, LOGO_2_TOP+14, NULL + invoke LineTo, edi, LOGO_2_LEFT+46, LOGO_2_TOP+14 + invoke LineTo, edi, LOGO_2_LEFT+46, LOGO_2_TOP+12 + invoke LineTo, edi, LOGO_2_LEFT+34, LOGO_2_TOP+0 + invoke SelectObject, edi, hWhitePen + invoke LineTo, edi, LOGO_2_LEFT+17, LOGO_2_TOP+0 + invoke LineTo, edi, LOGO_2_LEFT+17, LOGO_2_TOP+15 + + invoke SelectObject, edi, hDkGrayPen + invoke MoveToEx, edi, LOGO_2_LEFT+33, LOGO_2_TOP+46, NULL + invoke LineTo, edi, LOGO_2_LEFT+46, LOGO_2_TOP+46 + invoke LineTo, edi, LOGO_2_LEFT+46, LOGO_2_TOP+29 + invoke LineTo, edi, LOGO_2_LEFT+34, LOGO_2_TOP+17 + invoke SelectObject, edi, hWhitePen + invoke LineTo, edi, LOGO_2_LEFT+32, LOGO_2_TOP+17 + invoke LineTo, edi, LOGO_2_LEFT+32, LOGO_2_TOP+47 + + invoke SelectObject, edi, hDkGrayPen + invoke MoveToEx, edi, LOGO_2_LEFT+1, LOGO_2_TOP+35, NULL + invoke LineTo, edi, LOGO_2_LEFT+12, LOGO_2_TOP+46 + invoke LineTo, edi, LOGO_2_LEFT+29, LOGO_2_TOP+46 + invoke LineTo, edi, LOGO_2_LEFT+29, LOGO_2_TOP+32 + invoke SelectObject, edi, hWhitePen + invoke LineTo, edi, LOGO_2_LEFT+0, LOGO_2_TOP+32 + invoke LineTo, edi, LOGO_2_LEFT+0, LOGO_2_TOP+35 + .ENDIF + +;-------------------------------------------------------------------------- + invoke EndPaint, hWnd, ADDR ps ; returns zero if we process + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ WM_MOUSEMOVE : change the mouse cursor when we're over the hyperlink ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +.ELSEIF (eax == WM_MOUSEMOVE) && (CurrentPage == INTRO_PAGE) + movsx eax, word ptr lParam + mov MousePos.x, eax + movsx eax, word ptr lParam[2] + mov MousePos.y, eax + invoke PtInRect, ADDR HyperlinkRect, MousePos + .IF (eax) + invoke SetCursor, hHyperlinkCursor + .IF (eax != hHyperlinkCursor) + invoke DrawHyperlink, RED_COLOR + .ENDIF + .ELSE + call SetToStandardCursor + .ENDIF + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ WM_LBUTTONDOWN : Launch the web browser ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +.ELSEIF (eax == WM_LBUTTONDOWN) || (eax == WM_LBUTTONDBLCLK) + invoke GetCursor + .IF (eax == hHyperlinkCursor) + call LaunchGRCWebsite + .ENDIF + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ WM_CTLCOLORBTN ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +.ELSEIF (eax == WM_CTLCOLORBTN) + invoke SetControlText, wParam, lParam + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ WM_CTLCOLOREDIT ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +.ELSEIF (eax == WM_CTLCOLOREDIT) + invoke SetControlText, wParam, lParam + invoke GetWindowLong, lParam, GWL_ID + .IF (ax == IDE_INSTR) || (ax == TAB_TEXT) + invoke SetBkMode, wParam, TRANSPARENT + mov eax, hNullBrush + jmp Return + .ENDIF + +;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +;³ WM_CTLCOLORSTATIC : Static text ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +.ELSEIF (eax == WM_CTLCOLORSTATIC) + invoke SetControlText, wParam, lParam + +;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +;³ WM_DESTROY : we've been asked to leave, so drop out of the message loop ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +.ELSEIF (eax == WM_DESTROY) + invoke PostQuitMessage, 0 ; ... then return(0) + +;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +;³ WM_NOTIFY : the current tab has changed ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +.ELSEIF (eax == WM_NOTIFY) + ASSUME ebx:PTR NMHDR + mov ebx, lParam ; get the pointer to the NMHDR structure + .IF ([ebx].code == TCN_SELCHANGE) + ; save our PreviousPage since we're about to change it + movmov PreviousPage, eax, CurrentPage + ; it's a selection change event, so get the NEW tab + invoke SendMessage, [ebx].hwndFrom, TCM_GETCURSEL, 0, 0 + add eax, FIRST_ACTION_PAGE + mov CurrentPage, eax + mov ActionsSubPage, eax + call SetCurrentWindow + .ENDIF + ASSUME ebx:NOTHING +;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +;³ WM_COMMAND : a button was pressed ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +.ELSEIF (eax == WM_COMMAND) + movmov PreviousPage, eax, CurrentPage + movzx eax, word ptr wParam ; get the button control ID + .IF (eax == IDB_BACK) && (CurrentPage > 0) + dec CurrentPage + ; handle dropping into the proper of the ACTION pages + .IF (CurrentPage == LAST_ACTION_PAGE) + movmov CurrentPage, eax, ActionsSubPage + .ELSEIF (CurrentPage < LAST_ACTION_PAGE) && (CurrentPage >= FIRST_ACTION_PAGE) + mov CurrentPage, FIRST_ACTION_PAGE-1 + .ENDIF + ; handle skipping over the trouble page if everything is fine + .IF ((!ErrorMode) && (CurrentPage == TROUBLE_PAGE)) + dec CurrentPage + .ENDIF + call SetCurrentWindow + + .ELSEIF (eax == IDB_NEXT) && (CurrentPage < LAST_PAGE) + inc CurrentPage + ; handle skipping over the trouble page if everything is fine + .IF ((!ErrorMode) && (CurrentPage == TROUBLE_PAGE)) + inc CurrentPage + .ENDIF + ; handle dropping into the proper of the ACTION pages + .IF (CurrentPage == FIRST_ACTION_PAGE) + movmov CurrentPage, eax, ActionsSubPage + .ELSEIF (CurrentPage > FIRST_ACTION_PAGE) && (CurrentPage <= LAST_ACTION_PAGE) + mov CurrentPage, LAST_ACTION_PAGE+1 + .ENDIF + call SetCurrentWindow + + .ELSEIF (eax == IDB_WEB) + call LaunchGRCWebsite + + .ELSEIF (eax == IDB_QUIT) && (TestingPhase < TESTING_STARTUP) + invoke PostQuitMessage, 0 ; ... then return(0) + + .ELSEIF (eax == IDB_TEST) + .IF (CartridgeStatus == DISK_SPUN_DOWN) + invoke SpinUpIomegaCartridge, CurrentAdapter, CurrentDevice + + .ELSEIF (CartridgeStatus == DISK_AT_SPEED) + .IF (TestingPhase != READY_TO_TEST) + call PrepareToBeginTesting + .ENDIF + call TestTheDisk + + .ELSEIF (CartridgeStatus == DISK_TEST_UNDERWAY) + set UserInterrupt + + .ELSEIF (CartridgeStatus == DISK_Z_TRACK_FAILURE) \ + || (CartridgeStatus == DISK_TEST_FAILURE) \ + || (CartridgeStatus == DISK_PROTECTED) + invoke EjectIomegaCartridge, CurrentAdapter, CurrentDevice + + .ELSEIF (CartridgeStatus == DISK_LOW_SPARES) + mov CartridgeStatus, DISK_AT_SPEED + invoke SetRichEditText, ADDR hTabText, ADDR szNullString + invoke SetTabErrorMode, NULL + invoke SetWindowText, hTestButton, ADDR szPressToStart + + .ENDIF + + .ELSEIF (CurrentPage == INSTRUCTION_PAGE) + mov ebx, hRichEdit + call ScrollRichEdit + + .ELSEIF (CurrentPage == PERFORM_TEST_PAGE) || (CurrentPage == EXPLAIN_RESULTS) + mov ebx, hTabText + call ScrollRichEdit + + .ELSE + jmp DefaultProc + .ENDIF + jmp ReturnZero + +;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +;³ WM_SYSCOMMAND : a system command was received ... ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +.ELSEIF (eax == WM_SYSCOMMAND) + mov eax, wParam ; get the specific command + ; abort any close attempt while we're running ... + .IF ((eax == SC_CLOSE) || (eax == SC_DEFAULT)) && (TestingPhase >= TESTING_STARTUP) + jmp ReturnZero + .ENDIF + jmp DefaultProc + +;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ +.ELSE +DefaultProc: invoke DefWindowProc, hWnd, iMessage, wParam, lParam + jmp Return ; and return the DefWindowProc's return status ... +.ENDIF +ReturnZero: zero eax ; return that we haven't handled. + jmp Return +ReturnTrue: zero eax ; show that WE'VE handled this message + not eax +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +Return: ret + +;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +;³ Local Subroutines ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +ScrollRichEdit: .IF (eax == IDB_LINEUP) + invoke SendMessage, ebx, EM_SCROLL, SB_LINEUP, 0 + .ELSEIF (eax == IDB_LINEDN) + invoke SendMessage, ebx, EM_SCROLL, SB_LINEDOWN, 0 + .ELSEIF (eax == IDB_PAGEUP) + invoke SendMessage, ebx, EM_SCROLL, SB_PAGEUP, 0 + .ELSEIF (eax == IDB_PAGEDN) + invoke SendMessage, ebx, EM_SCROLL, SB_PAGEDOWN, 0 + .ELSEIF (eax == IDB_END) + invoke SendMessage, ebx, WM_VSCROLL, SB_BOTTOM, NULL + .ELSEIF (eax == IDB_HOME) + invoke SendMessage, ebx, WM_VSCROLL, SB_TOP, NULL + .ENDIF + LocalReturn +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +WndProc ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ PASSWORD WND PROC ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +PasswordWndProc PROC USES esi, hWnd:HWND, iMessage:UINT, wParam:WPARAM, lParam:LPARAM +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +mov eax, iMessage +;---------------------------------------------------------------------------- +; WM_INITDIALOG : set the focus to the edit field +;---------------------------------------------------------------------------- +.IF (eax == WM_INITDIALOG) + invoke GetDlgItem, hWnd, IDC_PASSWORD + invoke SetFocus, eax + jmp ReturnZero + +;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +;³ WM_COMMAND : a button was pressed ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +.ELSEIF (eax == WM_COMMAND) + movzx eax, word ptr wParam ; get the button control ID + .IF (eax == IDOK) + mov esi, 1 + jmp CloseDlg + .ELSEIF (eax == IDCANCEL) + zero esi +CloseDlg: invoke GetDlgItemText, hWnd, IDC_PASSWORD, ADDR CartridgePassword, 32 + invoke EndDialog, hWnd, esi + .ENDIF +.ELSE +ReturnZero: zero eax ; return that we haven't handled. + jmp Return +.ENDIF +ReturnNonZero: zero eax + dec eax +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +Return: ret +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +PasswordWndProc ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ CenterWindow ³ +;³ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄij +;³ This centers the HWND window on the screen ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +CenterWindow PROC USES ebx, hWnd:HWND ; handle of the window to center + LOCAL WndPos:RECT ; local temp structure defining wnd +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + invoke GetWindowRect, hWnd, ADDR WndPos ; get window dimens + + invoke GetSystemMetrics, SM_CXSCREEN ; return screen width + sub eax, WndPos.right ; now compute the + add eax, WndPos.left ; horizontal margin + halve eax ; cut it in half + push eax ; save new left + + invoke GetSystemMetrics, SM_CYSCREEN ; return screen height + pop edx ; recover the new left + sub eax, WndPos.bottom ; now compute the + add eax, WndPos.top ; vertical margin + halve eax ; cut it in half + mov ecx, eax ; save new right + + mov ebx, WndPos.right ; since we're FORCED to provide + sub ebx, WndPos.left ; a new width, let's recompute + inc ebx ; it from the existing width + + mov eax, WndPos.bottom ; and we'll do the same for + sub eax, WndPos.top ; the old and new heights + inc eax + + invoke MoveWindow, hWnd, edx, ecx, ebx, eax, TRUE ; and move it! + ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +CenterWindow ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ CREATE CHILD CONTROLS ³ +;³ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄij +;³ This creates all static windows for our program ³ +;³ Now create the block of standard windows from our array ... ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +CreateChildControls PROC +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + mov esi, OFFSET WindowCreationTable + mov edi, WINDOW_CREATION_ENTRIES + .REPEAT + push dword ptr NULL ; no window creation data + push hInst ; our local hInstance + push dword ptr [esi+32] ; Ctrl ID + mov ebx, [esi+28] ; get the parent's offset + .IF (ebx) ; if parent's offset non-null + mov ebx, [ebx] ; then load its value + .ENDIF + push ebx ; hWndParent + push dword ptr [esi+24] ; nHeight + push dword ptr [esi+20] ; nWidth + push dword ptr [esi+16] ; y + push dword ptr [esi+12] ; x + push dword ptr [esi+ 8] ; the Style + push dword ptr [esi+ 4] ; stack the window's name + push dword ptr [esi ] ; stack the ClassName + push dword ptr 0 ; NULL extended style + call CreateWindowEx + check eax ; if create failed + jz AbortedCreation ; then take us out! + ;------------------------------------------------------------ + mov ebx, [esi+36] ; get the destination offset + .IF (ebx) ; if we have a place to store + mov [ebx], eax ; the resulting hWnd, do so + .ENDIF + add esi, SIZE_OF_CREATE_ENTRY ; bump up to the next entry + dec edi + .UNTIL (zero?) + dec edi ; dec DI again to clear the ZERO flag ... +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +AbortedCreation: ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +CreateChildControls ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ SET CHILD VISIBILITY ³ +;³ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄij +;³ Sets the CurrentPage based window visibility state for the window whose ³ +;³ handle we're being handed. This is an enumeration of all hMainWnd. ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +SetChildVisibility PROC hWnd:HWND, lParam:LPARAM +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + invoke GetWindowLong, hWnd, GWL_ID ; pickup the child's ID + and eax, PAGE_MASK + shr eax, PAGE_SHIFT ; convert ID to control's page number + .IF (eax == ACTION_PAGES) ; if it's on all three pages + .IF (CurrentPage >= FIRST_ACTION_PAGE) && (CurrentPage <= LAST_ACTION_PAGE) + jmp ShowTheControl + .ENDIF + jmp HideTheControl + + .ELSEIF (eax != EVERY_PAGE); munge only if it's NOT on every page + .IF (eax == CurrentPage) +ShowTheControl: invoke GetWindowLong, hWnd, GWL_STYLE + or eax, WS_VISIBLE + .ELSE +HideTheControl: invoke GetWindowLong, hWnd, GWL_STYLE + and eax, NOT WS_VISIBLE + .ENDIF + invoke SetWindowLong, hWnd, GWL_STYLE, eax + .ENDIF + mov eax, TRUE ; return non-zero to continue enumerating ... + ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +SetChildVisibility ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ SET NAV BUTTON ENABLE ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +SetNavButtonEnable PROC USES edi, id:DWORD, enabled:DWORD +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + invoke GetDlgItem, hMainWnd, id ; get the handle + mov edi, eax ; save hWnd in EDI + mov ebx, enabled ; get the presence bitarray + mov cl, byte ptr PreviousPage ; get the PREVIOUS Page + shr ebx, cl ; "1" bit has PREVIOUS status + mov eax, enabled ; get the presence bitarray + mov cl, byte ptr CurrentPage ; get the CURRENT Page + shr eax, cl ; "1" bit has CURRNET status + xor ebx, eax ; one bit has "delta" + .IF (ebx & 1) + shr eax, 1 ; place new status into CARRY + .IF (carry?) + invoke GetWindowLong, edi, GWL_STYLE + and eax, NOT WS_DISABLED + .ELSE + invoke GetWindowLong, edi, GWL_STYLE + or eax, WS_DISABLED + .ENDIF + invoke SetWindowLong, edi, GWL_STYLE, eax + invoke InvalidateRect, edi, NULL, TRUE + .ENDIF + ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +SetNavButtonEnable ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ This sets the visibility of windows for a given page ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +SetCurrentWindow PROC +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + invoke ValidateRect, hMainWnd, NULL + invoke LockWindowUpdate, hMainWnd + invoke EnumChildWindows, hMainWnd, ADDR SetChildVisibility, NULL + invoke LockWindowUpdate, NULL + .IF (PreviousPage >= FIRST_ACTION_PAGE) && (PreviousPage <= LAST_ACTION_PAGE)\ + && (CurrentPage >= FIRST_ACTION_PAGE) && (CurrentPage <= LAST_ACTION_PAGE) + invoke InvalidateRect, hMainWnd, ADDR TabWindowRegionRect, TRUE + .ELSE + invoke InvalidateRect, hMainWnd, ADDR ChildRegionRect, TRUE + .ENDIF + + .IF (PreviousPage >= FIRST_ACTION_PAGE) || (CurrentPage >= FIRST_ACTION_PAGE) + invoke InvalidateRect, hMainWnd, ADDR WebButton, TRUE + .ENDIF + invoke SetNavButtonEnable, IDB_BACK, BackButtonEnabled + invoke SetNavButtonEnable, IDB_NEXT, NextButtonEnabled + invoke UpdateWindow, hMainWnd + ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +SetCurrentWindow ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ 3D SINK WndProc ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +SinkWndProc PROC USES esi edi, hWnd:HWND, msg:DWORD, wParam:WPARAM, lParam:LPARAM + LOCAL ps:PAINTSTRUCT, Rect:RECT +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + mov eax, msg +;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +;³ WM_PAINT : Simply pass this onto the Dialog's Frame painter ... ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +.IF (eax == WM_PAINT) + invoke BeginPaint, hWnd, ADDR ps ; setup our paintstruct + mov edi, eax + invoke GetClientRect, hWnd, ADDR Rect + invoke GetWindowLong, hWnd, GWL_ID + shr eax, TREATMENT_STYLE_SHIFT + .IF (ax == THREE_DEE_BOX) + invoke DrawEdge, edi, ADDR Rect, EDGE_SUNKEN, BF_RECT + .ELSEIF (ax != NO_SINK_OUTLINE) + dec Rect.right + dec Rect.bottom + invoke MoveToEx, edi, 0, Rect.bottom, NULL + invoke SelectObject, edi, hDkGrayPen + invoke LineTo, edi, 0, 0 + invoke LineTo, edi, Rect.right, 0 + invoke SelectObject, edi, hWhitePen + invoke LineTo, edi, Rect.right, Rect.bottom + invoke LineTo, edi, -1, Rect.bottom + .ENDIF + invoke EndPaint, hWnd, ADDR ps ; returns zero if we process +.ELSE + invoke DefWindowProc, hWnd, msg, wParam,lParam +.ENDIF + ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +SinkWndProc ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ SUNKEN FIELDS ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +SunkenFields PROC USES esi edi, hDC:HDC, pFirstRect:LPRECT, count:DWORD, yspacing:DWORD + LOCAL DrawRect:RECT +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + invoke CopyRect, ADDR DrawRect, pFirstRect ; make a local copy + mov edi, hDC + mov esi, count + .REPEAT + invoke DrawEdge, edi, ADDR DrawRect, BDR_SUNKENOUTER, BF_RECT + mov eax, yspacing + add DrawRect.top, eax + add DrawRect.bottom, eax + dec esi + .UNTIL (zero?) + ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +SunkenFields ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ PAINT TEXT ARRAY ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +PaintTextArray PROC USES esi edi, hdc:HDC, pArray:LPVOID, color:DWORD +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + mov edi, hdc + invoke SetTextColor, edi, color + mov esi, pArray + .REPEAT + add esi, SIZEOF DWORD ; skip past the coords + invoke lstrlen, esi + movzx ebx, word ptr [esi-4] + movzx ecx, word ptr [esi-2] + invoke TextOut, edi, ebx, ecx, esi, eax + invoke lstrlen, esi + inc eax ; account for the last zero + add esi, eax ; point to the next set of coords + .UNTIL !(word ptr [esi]) + ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +PaintTextArray ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ PAINT TEST PHASE ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +PaintTestPhase PROC USES esi edi, hdc:HDC +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + mov edi, hdc + invoke CreateCompatibleDC, NULL ; and a DC for our bitmap source + mov esi, eax + invoke SelectObject, esi, hOffBitmap + push eax + ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + .IF (TestingPhase == READING_DATA) + invoke SelectObject, esi, hGreenBitmap + push eax + .ENDIF + invoke BitBlt, edi, 252, 5, 11, 11, esi, 0, 0, SRCCOPY + .IF (TestingPhase == READING_DATA) + pop eax + invoke SelectObject, esi, eax + .ENDIF + ;-------------------------------------------------------------------------- + .IF (TestingPhase == WRITING_PATT) + invoke SelectObject, esi, hRedBitmap + push eax + .ENDIF + invoke BitBlt, edi, 337, 5, 11, 11, esi, 0, 0, SRCCOPY + .IF (TestingPhase == WRITING_PATT) + pop eax + invoke SelectObject, esi, eax + .ENDIF + ;-------------------------------------------------------------------------- + .IF (TestingPhase == READING_PATT) + invoke SelectObject, esi, hGreenBitmap + push eax + .ENDIF + invoke BitBlt, edi, 337,21, 11, 11, esi, 0, 0, SRCCOPY + .IF (TestingPhase == READING_PATT) + pop eax + invoke SelectObject, esi, eax + .ENDIF + ;-------------------------------------------------------------------------- + .IF (TestingPhase == WRITING_DATA) + invoke SelectObject, esi, hRedBitmap + push eax + .ENDIF + invoke BitBlt, edi, 252,21, 11, 11, esi, 0, 0, SRCCOPY + .IF (TestingPhase == WRITING_DATA) + pop eax + invoke SelectObject, esi, eax + .ENDIF + ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + pop eax + invoke SelectObject, esi, eax + invoke DeleteDC, esi + ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +PaintTestPhase ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ PAINT CART STATUS ³ +;³ Paints the textual cartridge status window ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +PaintCartStatus PROC USES esi edi, hDC:HDC + LOCAL TextSize:_SIZE +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + mov edi, hDC + ; set DC's default text modes + invoke SetTextColor, edi, BLACK_COLOR + invoke SelectObject, edi, hDialogTextFont + invoke SetBkMode, edi, TRANSPARENT + ; blank out any previous status display + invoke SelectObject, edi, hNullPen + invoke SelectObject, edi, hGrayBrush + invoke Rectangle, edi, 115, 9, 241, 27 + ; display the new cartridge status + mov eax, CartridgeStatus + dec eax + .IF (sign?) || (eax > (LAST_CART_STATUS-1)) + zero eax + .ENDIF + ; pickup the pointer to the string + mov esi, CartStatStrings[eax*4] + invoke lstrlen, esi + lea ebx, TextSize + invoke GetTextExtentPoint32, edi, esi, eax, ebx + mov ebx, (241+115)/2 ; get the center X + halve TextSize._cx + sub ebx, TextSize._cx + invoke lstrlen, esi + invoke TextOut, edi, ebx, 9, esi, eax + ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +PaintCartStatus ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ PAINT BAR GRAPH ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +PaintBarGraph PROC USES esi edi, hDC:HDC, Xleft:DWORD, Ytop:DWORD, Xwidth:DWORD, Yheight:DWORD, BarColor:DWORD, BarValue:DWORD, pRightText:DWORD, Active:BOOL + LOCAL AbsoluteBarWidth:DWORD, Extent:_SIZE, PercentString[8]:CHAR +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + ; create a temporary drawing bitmap for double-buffererd rendering + invoke GetDC, hTestMonitor + mov esi, eax ; hold the creation DC in esi + invoke CreateCompatibleBitmap, esi, Xwidth, Yheight + swap esi, eax ; eax gets DC, esi gets bitmap + invoke ReleaseDC, hTestMonitor, eax + + ; create a context for drawing onto the double buffer bitmap + invoke CreateCompatibleDC, NULL + swap esi, eax ; eax gets bitmap, esi gets new DC + invoke SelectObject, esi, eax + push eax ; save the old bitmap to remove bitmap + invoke SetBkMode, esi, TRANSPARENT + + ; fill the entire rectangle with background gray + invoke SelectObject, esi, hNullPen + invoke SelectObject, esi, hGrayBrush + mov eax, Xwidth + inc eax + mov ebx, Yheight + inc ebx + invoke Rectangle, esi, 0, 0, eax, ebx + +.IF (Active) ; now fleshout the bitmap ONLY IF we're active + + ; if RightText string is non-null, paint it in darker gray + mov edi, pRightText + .IF (edi) + invoke SelectObject, esi, hDialogTextFont + invoke SetTextColor, esi, GRAY_COLOR + invoke lstrlen, edi + lea ebx, Extent + invoke GetTextExtentPoint32, esi, edi, eax, ebx + invoke lstrlen, edi + mov ebx, Xwidth ; get the total width + sub ebx, Extent._cx + halve ebx + mov ecx, Yheight + sub ecx, Extent._cy + halve ecx + invoke TextOut, esi, ebx, ecx, edi, eax + .ENDIF + + ; now paint the active portion + invoke CreateSolidBrush, BarColor + invoke SelectObject, esi, eax + push eax ; save prior brush + mov eax, Xwidth + inc eax + mul BarValue ; edx will have the new width + add eax, 80000000h ; now round it up! + adc edx, 0 + mov AbsoluteBarWidth, edx + mov eax, Yheight + inc eax + invoke Rectangle, esi, 0, 0, edx, eax + pop eax ; recover prior brush + invoke SelectObject, esi, eax ; recover newly created brush + invoke DeleteObject, eax ; delete the brush + + ; now place the floating percentage into the middle (if it fits there) + invoke SelectObject, esi, hTitleFont + invoke SetTextColor, esi, WHITE_COLOR + mov eax, 100 ; calculate the percentage + mul BarValue ; edx will have the new width + add eax, 80000000h ; now round it up! + adc edx, 0 + invoke wsprintf, ADDR PercentString, ADDR szBarChartPercent, edx + mov edi, eax + lea ebx, Extent + invoke GetTextExtentPoint32, esi, ADDR PercentString, eax, ebx + mov ebx, AbsoluteBarWidth ; get the active bar's width + sub ebx, Extent._cx + sar ebx, 1 ; scale back but keep sign + .IF (sign?) + invoke SelectObject, esi, hDialogTextFont + mov ebx, AbsoluteBarWidth + .ENDIF + mov ecx, Yheight + sub ecx, Extent._cy + halve ecx + invoke TextOut, esi, ebx, ecx, ADDR PercentString, edi + +.ENDIF + ; now blit the final result out to the screen + invoke BitBlt, hDC, Xleft, Ytop, Xwidth, Yheight, esi, 0, 0, SRCCOPY + + ; and clean up after all the work + pop eax ; recover prior bitmap + invoke SelectObject, esi, eax ; recover newly created bitmap + invoke DeleteObject, eax ; delete the bitmap + invoke DeleteDC, esi ; delete created container DC +Exit: ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +PaintBarGraph ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ PAINT THE BAR GRAPHS ³ +;³ This paints the two or three bar graphs on the test monitor window. ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +PaintTheBarGraphs PROC hDC:HDC, Active:BOOL +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + invoke PaintBarGraph, hDC, 13, 57, 395, 14, BLUE_COLOR, PercentComplete, NULL, Active + .IF (JazDrive) + mov ebx, Side_0_SparesCount + mov ecx, MAXIMUM_JAZ_SPARES + .IF (ebx > ecx) ; if Spares > MAXIMUM + mov ebx, ecx ; clip Spares down to MAX + .ENDIF + call CvrtIntoPrcnt + mov ebx, eax + invoke PaintBarGraph, hDC, 13, 95, 395, 30, RED_COLOR, ebx, NULL, Active + .ELSE + mov ebx, Side_0_SparesCount + mov ecx, MAXIMUM_ZIP_SPARES + call CvrtIntoPrcnt + invoke PaintBarGraph, hDC, 13, 95, 395, 14, RED_COLOR, eax, ADDR szSide0, Active + mov ebx, Side_1_SparesCount + mov ecx, MAXIMUM_ZIP_SPARES + call CvrtIntoPrcnt + invoke PaintBarGraph, hDC, 13, 111, 395, 14, RED_COLOR, eax, ADDR szSide1, Active + .ENDIF +;-------------------------------------------------------------------------- + ret + +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +CvrtIntoPrcnt: zero edx + zero eax + dec eax ; set edx:eax to [0:FFFFFFFF] + div ecx ; divide by the maximum possible + neg ebx + add ebx, ecx + mul ebx +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + LocalReturn + +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +PaintTheBarGraphs ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ PAINT CENTERED STRING ³ +;³ Paints a Double-Buffered string into a rectangular region ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +PaintCenteredString PROC USES esi edi, hDC:HDC, Xleft:DWORD, Ytop:DWORD, Xwidth:DWORD, Yheight:DWORD, pText:DWORD, Active:BOOL + LOCAL Extent:_SIZE +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + ; create a temporary drawing bitmap for double-buffererd rendering + invoke GetDC, hTestMonitor + mov esi, eax ; hold the creation DC in esi + invoke CreateCompatibleBitmap, esi, Xwidth, Yheight + swap esi, eax ; eax gets DC, esi gets bitmap + invoke ReleaseDC, hTestMonitor, eax + + ; create a context for drawing onto the double buffer bitmap + invoke CreateCompatibleDC, NULL + swap esi, eax ; eax gets bitmap, esi gets new DC + invoke SelectObject, esi, eax + push eax ; save the old bitmap to remove bitmap + invoke SetBkMode, esi, TRANSPARENT + + ; fill the entire rectangle with background gray + invoke SelectObject, esi, hNullPen + invoke SelectObject, esi, hGrayBrush + mov eax, Xwidth + inc eax + mov ebx, Yheight + inc ebx + invoke Rectangle, esi, 0, 0, eax, ebx + +.IF (Active) ; now fleshout the bitmap ONLY IF we're active + + ; now place the floating string into the middle + invoke SelectObject, esi, hDialogTextFont + invoke lstrlen, pText + mov edi, eax + lea ebx, Extent + invoke GetTextExtentPoint32, esi, pText, eax, ebx + mov ebx, Xwidth ; get the region's width + sub ebx, Extent._cx + halve ebx + mov ecx, Yheight + sub ecx, Extent._cy + halve ecx + invoke TextOut, esi, ebx, ecx, pText, edi + +.ENDIF + ; now blit the final result out to the screen + invoke BitBlt, hDC, Xleft, Ytop, Xwidth, Yheight, esi, 0, 0, SRCCOPY + + ; and clean up after all the work + pop eax ; recover prior bitmap + invoke SelectObject, esi, eax ; recover newly created bitmap + invoke DeleteObject, eax ; delete the bitmap + invoke DeleteDC, esi ; delete created container DC +Exit: ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +PaintCenteredString ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ PAINT CENTERED VALUE ³ +;³ Paints a Double-Buffered decimal value into a rectangular region ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +PaintCenteredValue PROC USES esi edi, hDC:HDC, Xleft:DWORD, Ytop:DWORD, Xwidth:DWORD, Yheight:DWORD, value:DWORD, Active:BOOL + LOCAL szString[40]:CHAR +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + ; convert our value into a string + invoke wsprintf, ADDR szString, ADDR szCenteredDecimal, value + ; and paint it's value + invoke PaintCenteredString, hDC, Xleft, Ytop, Xwidth, Yheight, ADDR szString, Active + ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +PaintCenteredValue ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ PAINT TEST STATISTICS ³ +;³ This paints the two columns of testing statistics ³ +;³ on the test monitor window. ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +PaintTestStatistics PROC USES esi edi, hDC:HDC, Active:BOOL + LOCAL szString[40]:CHAR +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + mov edi, hDC + ; assemble and paint the sector testing range + mov eax, SingleTransferLBA ; are we testing a single sector? + .IF (eax) + invoke wsprintf, ADDR szString, ADDR szCenteredDecimal, eax + .ELSE + invoke wsprintf, ADDR szString, ADDR szCenteredDecimal, FirstLBASector + invoke lstrcat, ADDR szString, ADDR szSpaceDashSpace + invoke lstrlen, ADDR szString + lea esi, szString + add esi, eax + invoke wsprintf, esi, ADDR szCenteredDecimal, LastLBASector + .ENDIF + invoke PaintCenteredString, edi, 66, 155, 126, 14, ADDR szString, Active + + ; show the LastError + push edi ; save our display context + mov edi, OFFSET ErrorTypeTest ; point to the top of the list +TryIt: mov eax, [edi] ; get a candidate error # + add edi, 4 + .IF (eax) ; if we haven't hit the end + cmp eax, LastError + je ShowIt + mov al, 0 + repne scasb + jmp TryIt + .ELSE + .IF (LastError) + invoke PostToScreen, LastError + mov edi, OFFSET szUnknownError + .ENDIF + .ENDIF +ShowIt: mov eax, edi + pop edi + invoke PaintCenteredString, edi, 66, 172, 126, 14, eax, Active + + ; show the elapsed time + mov eax, SecondsElapsed + call CvrtSecondsToHMSstring + invoke PaintCenteredString, edi, 66, 189, 126, 14, ADDR szString, Active + + ; see if it's time for us to estimate ... + mov edx, SecondsElapsed + mov eax, edx + sub eax, ElapsedTimeOfLastEstimate + .IF (eax > 15) + ; assemble the remaining time + mov ElapsedTimeOfLastEstimate, edx ; note this estimate time + zero eax + mov ebx, PercentComplete + .IF (ebx > edx) ; if it's safe to divide, show remaining time + roundiv ebx ; eax will have estimated completion + .ENDIF + mov CurrentTotalTimeEstimate, eax + .ELSE + mov eax, CurrentTotalTimeEstimate + .ENDIF + + ; given the current estimate time, show the remaining time! + .IF (eax) + sub eax, SecondsElapsed + .IF (carry?) ; if it went negative + zero eax ; clamp it to zero + .ENDIF + call CvrtSecondsToHMSstring + .ELSE + invoke lstrcpy, ADDR szString, ADDR szEstimating + .ENDIF + .IF (TestingPhase <= READY_TO_TEST) + invoke lstrcpy, ADDR szString, ADDR szOneMoment + .ENDIF + invoke PaintCenteredString, edi, 66, 206, 126, 14, ADDR szString, Active + + ; now show the error accumulations ... + mov esi, ReadDataRecovery + invoke PaintCenteredValue, edi, 347, 155, 61, 14, esi, Active + mov eax, WriteDataRecovery + add esi, eax + invoke PaintCenteredValue, edi, 347, 172, 61, 14, eax, Active + mov eax, UnrecoverableData + add esi, eax + invoke PaintCenteredValue, edi, 347, 189, 61, 14, eax, Active + invoke PaintCenteredValue, edi, 347, 206, 61, 14, esi, Active + +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + ret + +CvrtSecondsToHMSstring: +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + mov ebx, 60 + zero edx + div ebx ; edx = seconds / eax = minutes + mov ecx, edx ; ecx = seconds + zero edx + div ebx ; edx = minutes / eax = hours + invoke wsprintf, ADDR szString, ADDR szHoursMinsSecs, eax, edx, ecx +;-------------------------------------------------------------------------- + LocalReturn + +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +PaintTestStatistics ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ TEST MONITOR WND PROC ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +TestMonitorWndProc PROC USES esi edi, hWnd:HWND, msg:DWORD, wParam:WPARAM, lParam:LPARAM + LOCAL ps:PAINTSTRUCT, Rect:RECT +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + mov eax, msg +;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +;³ WM_PAINT : Paint our entire test monitor window ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +.IF (eax == WM_PAINT) + invoke BeginPaint, hWnd, ADDR ps ; setup our paintstruct + mov edi, eax + ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + invoke SelectObject, edi, hDialogTextFont + invoke SetBkMode, edi, TRANSPARENT + invoke lstrlen, ADDR szCartStatus + invoke TextOut, edi, 12, 9, ADDR szCartStatus, eax + invoke DrawEdge, edi, ADDR CS_Stat, BDR_SUNKENOUTER, BF_RECT + invoke PaintCartStatus, edi + + ; draw the sunken rectangles + invoke DrawEdge, edi, ADDR TP_Perc, BDR_SUNKENOUTER, BF_RECT + invoke SunkenFields, edi, ADDR TL_Sect, 4, 17 + invoke SunkenFields, edi, ADDR ES_Read, 4, 17 + .IF (JazDrive) ; draw a single LARGE rectangle + invoke DrawEdge, edi, ADDR SS_Jaz, BDR_SUNKENOUTER, BF_RECT + .ELSE ; draw a pair of smaller rectangles + invoke SunkenFields, edi, ADDR SS_Sid0, 2, 16 + .ENDIF + + .IF (CartridgeStatus == DISK_AT_SPEED) || (CartridgeStatus >= DISK_LOW_SPARES) + invoke PaintTheBarGraphs, edi, TRUE + invoke PaintTestStatistics, edi, TRUE + mov eax, BLACK_COLOR + .ELSE + invoke PaintTheBarGraphs, edi, FALSE + invoke PaintTestStatistics, edi, FALSE + mov eax, GRAY_COLOR + .ENDIF + invoke PaintTextArray, edi, ADDR TestBlackText, eax + invoke PaintTextArray, edi, ADDR TestGrayText, GRAY_COLOR + + invoke PaintTestPhase, edi + ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + invoke EndPaint, hWnd, ADDR ps ; returns zero if we process +.ELSE + invoke DefWindowProc, hWnd, msg, wParam,lParam +.ENDIF + ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +TestMonitorWndProc ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ DATA SOURCE ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +DataSource PROC USES ebx ecx edx, pDest:PTR SBYTE, pCount:PTR DWORD, pCompData:PTR COMP_DATA +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + ASSUME ebx:PTR COMP_DATA +;-------------------------------------------------------------------------- + mov ebx, pCompData + mov eax, [ebx].EndOfBuffer ; get the end of the buffer + mov edx, [ebx].SourcePointer ; get the current start + sub eax, edx ; calc the remaining amount + mov ecx, pCount ; get the pointer to the count + mov ecx, [ecx] ; and get the actual count + .IF (eax > ecx) ; if it's more than we can take + mov eax, ecx ; diminish it to the limit + .ENDIF + add [ebx].SourcePointer, eax ; bump the offset forward for next + push eax ; save the amount transferred + invoke MoveMemory, pDest, edx, eax ; move the data + pop eax ; recover the amount we moved + ret ; and return the Count that we placed into the buffer +;-------------------------------------------------------------------------- + ASSUME ebx:NOTHING +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +DataSource ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ DATA SINK ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +DataSink PROC USES ebx ecx edx, pSource:PTR SBYTE, pCount:PTR DWORD, pCompData:PTR COMP_DATA +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + ASSUME ebx:PTR COMP_DATA +;-------------------------------------------------------------------------- + mov ebx, pCompData + mov eax, pCount ; get the pointer to the count + mov eax, [eax] ; and the count itself + mov edx, [ebx].SinkPointer + add [ebx].SinkPointer, eax + push eax + invoke MoveMemory, edx, pSource, eax + pop eax + ret +;-------------------------------------------------------------------------- + ASSUME ebx:NOTHING +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +DataSink ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ DECOMPRESS BINARY ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +DecompressBinary PROC USES esi, pBitmapImage:LPVOID + LOCAL pWorkingBuffer:LPSTR, CompData:COMP_DATA +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + invoke GlobalAlloc, GPTR, EXP_BUFFER_SIZE + mov pWorkingBuffer, eax + mov esi, pBitmapImage ; get the original size + mov eax, [esi] ; eax has uncompressed size + push eax ; save for function return + invoke GlobalAlloc, GPTR, eax + push eax ; save pointer to return + mov CompData.SinkPointer, eax + add esi, 8 ; point to the data's start + mov CompData.SourcePointer, esi ; set the starting point + add esi, [esi-4] + mov CompData.EndOfBuffer, esi + invoke explode, ADDR DataSource, ADDR DataSink, pWorkingBuffer, ADDR CompData + invoke GlobalFree, pWorkingBuffer + pop eax ; return the saved decompressed pointer + pop ebx ; return the original file size + ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +DecompressBinary ENDP + + +GetRandomNumber: +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ Simply returns a 32-bit random number ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ + mov eax, RandomSeed + imul eax, RANDOMULT + inc eax + mov RandomSeed, eax + swap ah, al + ror eax, 8 +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + ret + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ APPLICATION TIMER PROC ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +ApplicationTimerProc PROC hWnd:HWND, Msg:UINT, id:UINT, time:DWORD +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + pushad ; save ALL the regs so we return things as we found them! + ; see whether we need to animate the titlepage + .IF (CurrentPage == INTRO_PAGE) + call FloatTheFloaters + .ENDIF + + call HandleDriveChanging + + ; to flash the ring around the "Start Testing" button + .IF (ActionButtonFlasher) && (CurrentPage >= FIRST_ACTION_PAGE) && (CurrentPage <= LAST_ACTION_PAGE) + invoke GetDC, hMainWnd + mov edi, eax + mov eax, hBlackPen + .IF (ActionButtonFlasher & 1) + mov eax, hGrayPen + .ENDIF + invoke SelectObject, edi, eax + invoke SelectObject, edi, hNullBrush + invoke Rectangle, edi, TEST_BUTTON_LEFT-1, TEST_BUTTON_TOP-1, TEST_BUTTON_LEFT+TEST_BUTTON_WIDTH+1, TEST_BUTTON_TOP+TEST_BUTTON_HEIGHT+1 + invoke Rectangle, edi, TEST_BUTTON_LEFT-2, TEST_BUTTON_TOP-2, TEST_BUTTON_LEFT+TEST_BUTTON_WIDTH+2, TEST_BUTTON_TOP+TEST_BUTTON_HEIGHT+2 + invoke ReleaseDC, hMainWnd, edi + dec ActionButtonFlasher + .ENDIF + popad + ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +ApplicationTimerProc ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ INITIALIZE THE FLOATER SYSTEM ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +InitializeTheFloaterSystem PROC USES esi edi +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + test CPUis386, TRUE + iftrue Exit + ;-------------------------------------------------------------------------- + zero esi ; ESI will be the OBJECT INSTANCE index + .REPEAT ; EDI will be the OBJECT CLASS index + mov edi, ObjectTypes[esi] + Call InitPositionAndVelocity + call GetValidObjectHorzPos + mov HorzPosition[esi], eax + call GetValidObjectVertPos + mov VertPosition[esi], eax + add esi, SIZEOF DWORD + .UNTIL (esi >= NUMBER_OF_FLOATERS * SIZEOF DWORD) + ; place the objects into their initial positions + call BlitTheObjects +;-------------------------------------------------------------------------- +Exit: ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +InitializeTheFloaterSystem ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ GET VALID OBJECT HORZ POS ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +GetValidObjectHorzPos PROC USES ebx edx +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + call GetRandomNumber ; returns EAX + mov ebx, SPLASH_WIDTH + mov ecx, xwidth[edi] + dec ecx + add ebx, ecx + mul ebx + sub edx, ecx + shl edx, 16 ; convert into 16ù16 + mov eax, edx + ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +GetValidObjectHorzPos ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ GET VALID OBJECT VERT POS ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +GetValidObjectVertPos PROC USES ebx edx +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + call GetRandomNumber ; returns EAX + mov ebx, SPLASH_HEIGHT + mov ecx, yheight[edi] + dec ecx + add ebx, ecx + mul ebx + sub edx, ecx + shl edx, 16 ; convert into 16ù16 + mov eax, edx + ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +GetValidObjectVertPos ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ MIX EDX BY THREE ³ +;³ With 1/3rd probability, this negates EDX, leaves it alone, of zeroes it. ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +MixEDXbyThree PROC +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + push edx + call GetRandomNumber ; eax + mov edx, 3 + mul edx + mov eax, edx + pop edx + .IF (!eax) + zero edx + .ELSEIF (eax == 1) + neg edx + .ENDIF + ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +MixEDXbyThree ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ PREP FOR FAST BLITTING ³ +;³ This BSWAPS every DWORD of the bitmap's data placing the first bitmap ³ +;³ bits up at the high end of the DWORD and linearizing them all along. ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +PrepForFastBlitting PROC USES esi edi, pBitmapFile:HGLOBAL +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + test CPUis386, TRUE + iftrue Exit + ;-------------------------------------------------------------------------- + mov eax, pBitmapFile ; get the data block + mov ecx, [eax].BITMAPFILEHEADER.bfSize ; pickup the file's size + mov esi, [eax].BITMAPFILEHEADER.bfOffBits + sub ecx, esi ; calc the total size to bswap + shr ecx, 2 ; divide by 4 for dwords + add esi, eax ; cvrt offset into actual pointer + mov edi, esi ; setup our source and destination + .REPEAT + lodsd + bswap eax + stosd + .UNTILCXZ +Exit: ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +PrepForFastBlitting ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ ALLOCATE SIXTEEN COLOR DIB ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +AllocateSixteenColorDib PROC Hwidth:DWORD, Vheight:DWORD +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + mov eax, Hwidth ; get the width + add eax, 7 ; round up to dword boundary + and eax, 0FFFFFFF8h ; (8 pixels per dword) + mul Vheight ; multiply by the number of lines + add eax, 16*4 + SIZEOF BITMAPINFOHEADER + invoke GlobalAlloc, GPTR, eax + ASSUME EAX:PTR BITMAPINFOHEADER + mov [eax].biSize, SIZEOF BITMAPINFOHEADER + movmov [eax].biWidth, ebx, Hwidth + movmov [eax].biHeight, ebx, Vheight + mov [eax].biPlanes, 1 + mov [eax].biBitCount, 4 + ASSUME EAX:NOTHING + ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +AllocateSixteenColorDib ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ SPLASH THE BITMAP ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +SplashTheBitmap PROC USES esi edi, hDC:HDC +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + mov edi, hDC + invoke SelectPalette, edi, hSplashPalette, FALSE + invoke RealizePalette, edi + mov eax, pSplashDIB + mov ebx, eax ; point ebx to the bits + add ebx, 16*4 + SIZEOF BITMAPINFOHEADER + zero ecx + zero edx + zero esi + invoke SetDIBitsToDevice, edi, 16, 18, [eax + BITMAPINFOHEADER.biWidth], [eax + BITMAPINFOHEADER.biHeight],0, 0, 0, [eax + BITMAPINFOHEADER.biHeight], ebx, eax, DIB_RGB_COLORS + ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +SplashTheBitmap ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ FLOAT THE FLOATERS ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +FloatTheFloaters PROC +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + zero esi ; ESI is the OBJECT INSTANCE index + .REPEAT ; EDI is the OBJECT CLASS index + mov edi, ObjectTypes[esi] +;-------------------------------------------------------------------------- +DoHorz: mov eax, HorzPosition[esi] ; get the 16ù16 format + add eax, HorzVelocity[esi] ; compute new location + mov HorzPosition[esi], eax ; and save it, presuming okay + shr eax, 16 ; discard the fractional part + movsx eax, ax + cmp eax, SPLASH_WIDTH + jge ReFloat + check eax + jns DoVert + neg eax ; make the offset positive + cmp eax, xwidth[edi] ; see if we're too negative + jge ReFloat + +DoVert: mov eax, VertPosition[esi] ; get the 16ù16 format + add eax, VertVelocity[esi] ; compute new location + mov VertPosition[esi], eax ; and save it, presuming okay + shr eax, 16 + movsx eax, ax + cmp eax, SPLASH_HEIGHT + jge ReFloat + check eax + jns NextObject + neg eax ; make the offset positive + cmp eax, yheight[edi] ; see if we're too negative + jl NextObject + +ReFloat: Call InitPositionAndVelocity +;-------------------------------------------------------------------------- +NextObject: add esi, SIZEOF DWORD + .UNTIL (esi >= NUMBER_OF_FLOATERS * SIZEOF DWORD) + ; place the objects into their initial positions + call BlitTheObjects + ; and update the image in the window + mov esi, hMainWnd + .IF (esi) ; make sure the window exists! + invoke GetDC, esi + mov edi, eax + invoke SplashTheBitmap, eax + invoke ReleaseDC, esi, edi + .ENDIF + ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +FloatTheFloaters ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ INIT POSITION AND VELOCITY ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +InitPositionAndVelocity PROC +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + ; get a size-based vbelocity + mov eax, VELOCITY_MULTIPLIER + mul velocities[edi] +; mul xwidth[edi] ; EDX has the size-based velocity + mov edx, eax + ; choose a border from which to emerge + call GetRandomNumber ; returns EAX + mov ebx, eax + .IF (ebx & 1) + call GetValidObjectHorzPos + mov HorzPosition[esi], eax + .IF (ebx & 2) ; TOP EDGE + mov eax, yheight[edi] + dec eax + shl eax, 16 + neg eax + .ELSE ; BOTTOM EDGE + mov eax, (SPLASH_HEIGHT-1) SHL 16 + neg edx + .ENDIF + mov VertPosition[esi], eax + mov VertVelocity[esi], edx + Call MixEDXbyThree + mov HorzVelocity[esi], edx + .ELSE + call GetValidObjectVertPos + mov VertPosition[esi], eax + .IF (ebx & 2) ; LEFT EDGE + mov eax, xwidth[edi] + dec eax + shl eax, 16 + neg eax + .ELSE ; RIGHT EDGE + mov eax, (SPLASH_WIDTH-1) SHL 16 + neg edx + .ENDIF + mov HorzPosition[esi], eax + mov HorzVelocity[esi], edx + Call MixEDXbyThree + mov VertVelocity[esi], edx + .ENDIF + ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +InitPositionAndVelocity ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ BLIT THE OBJECTS ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +BlitTheObjects PROC USES esi edi +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + ; Zero the entire destination bitmap before summing into it ... + mov eax, pSplashDIB + add eax, SIZEOF BITMAPINFOHEADER + 16*4 + invoke ZeroMemory, eax, (SPLASH_HEIGHT * DEST_BITMAP_BYTE_WIDTH) + + ; Now BLIT the entire set of Objects into the bitmap + zero esi + .REPEAT ; ESI will be the OBJECT INSTANCE index + ; EDI will be the OBJECT CLASS index + mov edi, ObjectTypes[esi] ; EDI is the pointer to the OBJECT CLASS + + ; establish the object's translucency transformation table + invoke MoveMemory, ADDR xform, transform[edi], 16*4 + + ; let's figure out the horizontal + mov eax, HorzPosition[esi] ; get the current Horz + shr eax, 16 ; discard the fractional + movsx eax, ax ; and sign-extend it + .IF (sdword ptr eax >= 0) + ; our X coord is positive, so no left clipping + mov ebx, SPLASH_WIDTH + sub ebx, eax + mov edx, xwidth[edi] + .IF (ebx > edx) + mov ebx, edx + .ENDIF + mov edx, eax + zero eax + .ELSE + ; we have a negative X, so some of our left is clipped + mov ebx, xwidth[edi] + add ebx, eax ; EBX has the pixel count + neg eax ; EAX has the left SRC pixel + zero edx ; EDX has the left DEST pixel + .ENDIF + .IF (ebx > SPLASH_WIDTH) ; trim our blit to window width + mov ebx, SPLASH_WIDTH + .ENDIF + mov PixelsPerLine, ebx + + ; EAX has the starting pixel in the SOURCE bitmap + add eax, xleft[edi] ; add-in the source offset + mov ecx, eax ; first setup the bit mask + and cl, 1Fh ; get the lower FIVE bits + mov ebx, 80000000h ; setup the source mask + shr ebx, cl + mov SourceBitStart, ebx + + and eax, 0FFFFFFE0h ; mask off the lower five bits + shr eax, 3 ; now the byte offset + add eax, pFontBitmap + add eax, ytop[edi] ; !!! This is pre-computed !!! + mov SourceLineStart, eax + + ; EDX has the starting pixel in the DEST bitmap + mov ecx, edx + and ecx, 00000007h ; get 0-7 + shl ecx, 2 ; * 4 == 0-28 + neg ecx + add ecx, 28 ; 28 .... 0 + mov DestBitStart, ecx ; (28 for the 0th bit!) + + mov eax, pSplashDIB + add eax, SIZEOF BITMAPINFOHEADER + 16*4 + ((SPLASH_HEIGHT-1) * DEST_BITMAP_BYTE_WIDTH) + and edx, 0FFFFFFF8h + shr edx, 1 ; get the byte offset + add eax, edx + mov DestLineStart, eax + + ; let's figure out the vertical + mov eax, VertPosition[esi] ; get the current Horz + shr eax, 16 ; discard the fractional + movsx eax, ax ; and sign-extend it + .IF (sdword ptr eax >= 0) + ; our X coord is positive, so no top clipping + mov ebx, eax + imul ebx, DEST_BITMAP_BYTE_WIDTH + sub DestLineStart, ebx + mov ebx, SPLASH_HEIGHT + sub ebx, eax + mov edx, yheight[edi] + .IF (ebx > edx) + mov ebx, edx + .ENDIF + .ELSE + ; we have a negative Y, so some of our top is clipped + mov ebx, yheight[edi] + add ebx, eax ; EBX has the new line count + imul eax, SOURCE_BITMAP_BYTE_WIDTH + add SourceLineStart, eax + .ENDIF + mov LineCount, ebx + call FastTransparentBlt + add esi, SIZEOF DWORD + .UNTIL (esi >= NUMBER_OF_FLOATERS * SIZEOF DWORD) + ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +BlitTheObjects ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ FAST TRANSPARENT BLT ³ +;³ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄij +;³ This performs an ULTRA FAST transparent BitBlt of one DIB into another. ³ +;³ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄij +;³ EAX is the working scratch register ³ +;³ EBX contains the destination bitmap data for 8 pixels ³ +;³ ECX has the shift over count ³ +;³ EDX has the 4-bit pixel mask ³ +;³ EBP has the 1-bit pixel mask ³ +;³ ESI has the source bitmap dword pointer ³ +;³ EDI has the dest bitmap dword pointer ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +FastTransparentBlt PROC USES esi edi ebp +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +LinePrep:movmov PixelsToBlt, eax, PixelsPerLine + mov esi, SourceLineStart + mov edi, DestLineStart + mov ebp, SourceBitStart + mov ecx, DestBitStart + mov edx, FourBitMasks[ecx] + mov ebx, [edi] ; get a dword set of bitmaps from the dest + bswap ebx ; de-scramble the nibbles! +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +TstPixel:.IF ([esi] & ebp) ; see if this source-bit is set + mov eax, ebx ; get the destination bitmap dword + and eax, edx ; mask out the 4-bit pixel we want + not edx ; invert the mask to zero the dest pixel + and ebx, edx ; zero the dest for eventual or-ing + not edx ; return the mask to it's positive state + shr eax, cl ; bring the pixel down to bit 0 + mov eax, xform[eax*4] ; perform the transparent transformation + shl eax, cl ; move the new pixel back up where it goes + or ebx, eax ; and OR it back into the DIB + .ENDIF + rcr ebp, 1 ; setup for the next source pixel + .IF (carry?) ; if we're done, get the next word + rcr ebp, 1 ; set the low-order bit + add esi, 4 ; bump to the next source dword + .ENDIF + ror edx, 4 ; move the mask around four bits + sub ecx, 4 ; decrease the shift-over amount by 4 + .IF (carry?) ; if we're done with this pixel + bswap ebx ; re-scramble the nibbles + mov [edi], ebx ; replace the modified dest bitmap dword + add edi, 4 ; bump up to the next dest dword + mov ebx, [edi] ; get the next dest bitmap dword + bswap ebx ; de-scramble the nibbles + mov ecx, 28 ; and reset the shift-over amount + .ENDIF + dec PixelsToBlt + jnz TstPixel + ;-------------------------------------------------------------------------- + bswap ebx ; re-scramble the nibbles + mov [edi], ebx ; replace the modified dest bitmap dword + ;-------------------------------------------------------------------------- + sub SourceLineStart, SOURCE_BITMAP_BYTE_WIDTH + sub DestLineStart, DEST_BITMAP_BYTE_WIDTH + dec LineCount ; see if we're all done or not + jnz LinePrep + ;-------------------------------------------------------------------------- + ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +FastTransparentBlt ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ SET RICH EDIT TEXT ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +SetRichEditText PROC USES esi edi, phRichEditControl:LPHWND, pszSection:LPSTR + LOCAL HeaderLength:DWORD, BodyStart:DWORD, BodyLength:DWORD +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + ; see whether we've already set THIS text into THIS control ... + mov eax, pszSection ; get the section we're setting + mov ebx, phRichEditControl ; and address of the control's handle + cmp eax, [ebx+4] ; see if we've already set it + je Exit ; YEP! so we're all done! + ;-------------------------------------------------------------------------- + mov [ebx+4], eax ; nope, so show it set now! + + ; now check to see if we're pointing to a NULL string ?? + .IF (!byte ptr [eax]) + mov esi, eax ; setup the stream to NULL + mov edi, 1 ; set the length to 1 + jmp SetIt + .ENDIF + + ; now search to the first '[' to size the first (header) section + mov al, '[' ; search for the first '[' bracket + mov edi, pRTF_Data + mov ecx, pRTF_Data+4 + repne scasb ; and scan past the rtf header + mov eax, edi + sub eax, pRTF_Data + dec eax + mov HeaderLength, eax ; establish the header's length + + ; now scan down to the opening of the proper section + mov edi, pRTF_Data ; restart at the top of the file + mov ecx, pRTF_Data+4 +NextOne:.REPEAT + mov al, '[' ; we're looking for a new section + repne scasb ; look for the next '[' + jne Exit ; if we didn't find one ... abort + mov esi, ecx ; save our counter around the call + invoke lstrcmp, edi, pszSection + mov ecx, esi ; restore our counter after the call + .UNTIL (!eax) ; keep looking 'till we find it + + ; now find the start of the NEXT line after the section header + mov al, LF ; look for line feeds + repne scasb ; scan for next line start + jne Exit ; abort if we didn't have one! + mov BodyStart, edi ; mark the start of the body text + + ; now find the start of the NEXT section (and the end of this one) + mov al, '[' ; we're looking for a new section + repne scasb ; look for the next '[' + jne Exit ; if we didn't find one ... abort + + ; now scan BACK to the end of the PRIOR line + mov al, LF ; scan backward past line start + mov ecx, -1 ; set the scan lenght to infinity + std ; set direction to backwards + repne scasb ; and land on the CR above + cld ; restore standard forward direction + sub edi, BodyStart ; compute the Body's length + mov BodyLength, edi + add edi, HeaderLength ; get the total allocation needed + inc edi ; and add ONE more byte for '}' + + ; allocate a block of mem for stream assembly + invoke GlobalAlloc, GPTR, edi + mov esi, eax ; esi will be our stream pointer + + ; fill the allocation with the header and the section's body + invoke MoveMemory, esi, pRTF_Data, HeaderLength + mov eax, esi + add eax, HeaderLength + invoke MoveMemory, eax, BodyStart, BodyLength + mov eax, esi + add eax, HeaderLength + add eax, BodyLength + invoke MoveMemory, eax, ADDR CloseCurly, 1 + + ; setup the stream parameters and initiate the stream +SetIt: mov StreamPointer, esi ; setup the start of the stream + add edi, esi ; add the length to the start + mov StreamEnd, edi ; and set the stream's end point + mov eax, phRichEditControl + invoke SendMessage, dword ptr [eax], EM_STREAMIN, SF_RTF or SFF_PLAINRTF, ADDR RichEditStreamIn + + ; release the temporary stream assembly allocation + .IF (byte ptr [esi]) ; if we were not pointing to a NULL + invoke GlobalFree, esi + .ENDIF +Exit: ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +SetRichEditText ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ INITIALIZE WIZARD CONTROLS ³ +;³ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄij +;³ This presets and preloads the Wizard's Child Controls ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +InitializeWizardControls PROC + LOCAL TabItem:TC_ITEM +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + ; prep the RichEdit controls background colors ... + invoke SendMessage, hRichEdit, EM_SETBKGNDCOLOR, FALSE, LTGRAY_COLOR + invoke SendMessage, hTabText, EM_SETBKGNDCOLOR, FALSE, LTGRAY_COLOR + + ; set the static text for the main RichEdit control + invoke SetRichEditText, ADDR hRichEdit, ADDR szInstructions + + ; setup the tabs for the ACTION page + invoke InitCommonControls ; initialize the common controls + + ; loadup the tab text + varzero TabItem + mov TabItem._mask, TCIF_TEXT + mov TabItem.iImage, -1 + mov TabItem.pszText, OFFSET szActionTabOne + invoke SendMessage, hActionTabs, TCM_INSERTITEM, 0, ADDR TabItem + mov TabItem.pszText, OFFSET szActionTabTwo + invoke SendMessage, hActionTabs, TCM_INSERTITEM, 1, ADDR TabItem + ; set the tab width + invoke SendMessage, hActionTabs, TCM_SETITEMSIZE, 0, 143 + ; set the tab font + invoke SendMessage, hActionTabs, WM_SETFONT, hDialogTextFont, NULL + + + ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +InitializeWizardControls ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ STREAM SOURCE ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +StreamSource PROC dwCookie:DWORD, pBuff:LPBYTE, cb:DWORD, pcb:LPDWORD +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + mov eax, StreamEnd ; get the end of the buffer + mov edx, StreamPointer ; get the current start + sub eax, edx ; calc the remaining amount + mov ecx, cb ; get the count to read + .IF (eax > ecx) ; if it's more than we have left + mov eax, ecx ; diminish it to the limit + .ENDIF + add StreamPointer, eax ; bump the offset forward for next + push eax ; save the amount transferred + invoke MoveMemory, pBuff, edx, eax ; move the data + mov eax, pcb + pop dword ptr [eax] + zero eax ; return zero to continue streaming + ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +StreamSource ENDP + +IF DEVELOPMENT +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ POST TO SCREEN ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +PostToScreen PROC USES eax esi edi, PostVal:DWORD + LOCAL PostString[20]:CHAR, Extent:_SIZE +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + mov eax, PostVal + .IF (eax != LastPostedValue) + mov LastPostedValue, eax + invoke GetDC, HWND_DESKTOP + mov edi, eax + invoke SelectObject, edi, hHeadlineFont + invoke SelectObject, edi, hBlackPen + invoke SelectObject, edi, hBlackBrush + invoke wsprintf, ADDR PostString, ADDR szLongHexFormat, LastPostedValue + mov esi, eax + invoke TextOut, edi, 0, LastPostedTop, ADDR PostString, eax + invoke GetTextExtentPoint32, edi, ADDR PostString, esi, ADDR Extent + mov esi, Extent._cy + add esi, POSTING_SPACE + add LastPostedTop, esi + mov eax, Extent._cx + mov ebx, Extent._cy + add ebx, LastPostedTop + invoke Rectangle, edi, 0, LastPostedTop, eax, ebx + invoke ReleaseDC, HWND_DESKTOP, edi + .ENDIF + ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +PostToScreen ENDP +ENDIF + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ PROCESS PENDING MESSAGES ³ +;³ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄij +;³ This allows all windows to receive and process any and all pending ³ +;³ messages ... such as old WM_PAINT's that they may be holding ... ³ +;³ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄij +;³ Note also that this loop DELIBERATELY AVOIDS the removal of WM_QUIT ³ +;³ messages, since they should only be removed by the GetMessage call ³ +;³ which returns FALSE when it encounters the WM_QUIT ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +ProcessPendingMessages PROC USES esi + LOCAL msg:MSG +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + push esi + .REPEAT + invoke PeekMessage, ADDR msg, NULL, 0, 0, PM_REMOVE + .IF (eax) + mov esi, eax + invoke TranslateMessage, ADDR msg + invoke DispatchMessage, ADDR msg + mov eax, esi + .ENDIF + .UNTIL (!eax) + pop esi + ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +ProcessPendingMessages ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ UPDATE RUN TIME DISPLAY ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +UpdateRunTimeDisplay PROC USES edi +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + invoke GetDC, hTestMonitor + mov edi, eax + invoke PaintTestPhase, edi + invoke PaintTheBarGraphs, edi, TRUE + invoke PaintTestStatistics, edi, TRUE + invoke ReleaseDC, hTestMonitor, edi + call ProcessPendingMessages ; paint all current status + ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +UpdateRunTimeDisplay ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ UPDATE RUN TIME DISPLAY ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +UpdateRunPhaseDisplay PROC USES edi +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + invoke GetDC, hTestMonitor + mov edi, eax + invoke PaintTestPhase, edi + invoke ReleaseDC, hTestMonitor, edi + call ProcessPendingMessages ; paint all current status + ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +UpdateRunPhaseDisplay ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ PREVENT PROGRAM EXIT ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +PreventProgramExit PROC +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + invoke GetSystemMenu, hMainWnd, FALSE ; get sysmenu handle + invoke DeleteMenu, eax, SC_CLOSE, MF_BYCOMMAND + invoke SendMessage, hMainWnd, WM_NCPAINT, NULL, NULL + invoke SetWindowPos, hMainWnd, 0, 0,0,0,0, + SWP_DRAWFRAME or SWP_NOMOVE or SWP_NOSIZE or SWP_NOZORDER + invoke EnableWindow, hExitButton, FALSE + ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +PreventProgramExit ENDP + + +;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ +;³ ALLOW PROGRAM EXIT ³ +;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +AllowProgramExit PROC +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + invoke GetSystemMenu, hMainWnd, FALSE ; get sysmenu handle + invoke AppendMenu, eax, MF_STRING, SC_CLOSE, ADDR szCloseCmd + invoke SendMessage, hMainWnd, WM_NCPAINT, NULL, NULL + invoke SetWindowPos, hMainWnd, 0, 0,0,0,0, + SWP_DRAWFRAME or SWP_NOMOVE or SWP_NOSIZE or SWP_NOZORDER + invoke EnableWindow, hExitButton, TRUE + ret +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +AllowProgramExit ENDP + + + +;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +include aspi.asm +;-//////////////////////////////////////////////////////////////////////////- +END Start +;-//////////////////////////////////////////////////////////////////////////- + diff --git a/x86-asm-source/tip-rc.sav b/x86-asm-source/tip-rc.sav new file mode 100644 index 0000000..00d3deb --- /dev/null +++ b/x86-asm-source/tip-rc.sav @@ -0,0 +1,47 @@ +#define APPNAME TIP +///////////////////////////////////////////////////////////////////////////// +#define IDB_BACK 0xFF00 +#define IDB_NEXT 0xFF01 +#define IDB_QUIT 0xFF02 +#define VK_LEFT 0x0025 +#define VK_RIGHT 0x0027 + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// +APPNAME ICON DISCARDABLE "tip.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Cursor +// +APPNAME CURSOR DISCARDABLE "tip.cur" + +///////////////////////////////////////////////////////////////////////////// +// +// Accelerator +// +APPNAME ACCELERATORS MOVEABLE PURE +BEGIN + "b", IDB_BACK, ASCII, ALT, NOINVERT + "B", IDB_BACK, ASCII, ALT, NOINVERT + "b", IDB_BACK, ASCII, NOINVERT + "B", IDB_BACK, ASCII, NOINVERT + "<", IDB_BACK, ASCII, NOINVERT + ",", IDB_BACK, ASCII, NOINVERT + VK_LEFT, IDB_BACK, VIRTKEY, NOINVERT + + "n", IDB_NEXT, ASCII, ALT, NOINVERT + "N", IDB_NEXT, ASCII, ALT, NOINVERT + "n", IDB_NEXT, ASCII, NOINVERT + "N", IDB_NEXT, ASCII, NOINVERT + ">", IDB_NEXT, ASCII, NOINVERT + ".", IDB_NEXT, ASCII, NOINVERT + VK_RIGHT, IDB_NEXT, VIRTKEY, NOINVERT + + "x", IDB_QUIT, ASCII, ALT, NOINVERT + "X", IDB_QUIT, ASCII, ALT, NOINVERT + "x", IDB_QUIT, ASCII, NOINVERT + "X", IDB_QUIT, ASCII, NOINVERT +END diff --git a/x86-asm-source/tip-test.BAK b/x86-asm-source/tip-test.BAK new file mode 100644 index 0000000000000000000000000000000000000000..cbc4b1d199ef8be35be39ad735760d7d2df33938 GIT binary patch literal 61952 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 PMR!pi@-Nf>eGdF5q4Ezj literal 0 HcmV?d00001 diff --git a/x86-asm-source/tip.RES b/x86-asm-source/tip.RES new file mode 100644 index 0000000000000000000000000000000000000000..32f4c11fed30661ed4f8636568d231071dfecbae GIT binary patch literal 4000 zcmd6p&2Lmy6u{5C8Jrdg)1Wa%7JVuz7y=`90oDjefe?`rS}P_d*iHx9q?E}_@j+b7 zpd>Si8@988xN|nJH_9ab1O5rb6+60X73BIm=f3H@=?7pU3Aa7>+7-iU~V zfO8&L_Kf>Mho43!WxRob{!B+`CyNj`1f;~1Yn)ks)I|7~TFoP7mOxF~?KTWGLXq=` z+1sT=#!?hTCBL+JxzT7m&%I+TChmLM@_E=-PdKRlHWGxK?vn%)Xw+Bi%y~jrg(sMR zH#X-~gC2;3sX8~@6aOg5XRTvJ-fy36?~S(;-afU&Mx1SO?}u9F+Jo+i&=Fo&F3Z`J zbN8f5J`cKO8FY^&x0tN~_dE#uRj@2F_(+iF`d6`GhuYz`%D9}6(`pnWpLh%U0#Xu& z1NIX1<)mbYCley4Z^t?RFp}@*C3wAW$iFe!;0@s>C!T$zAB!ktIhF$kU2O%n|5KCg z7rXGv9J1d4s9z5t+vtS)X?PirJFrOTHT-SDxiM7T{WNC=f$Ca#!b1t$xIKGq|-VvibJkF?NPaE!QI#N$b`|{*KBq z{$8N`QqPf#s!P?XE73)(E7-ZLwpCYMh21K-s*5BlWmS*nm-F|@t@aMh@0g6r7i4&Z zy^j2;J!wu}^)8qI933Qa-Bl7o{7neuZ!MaMso9Q7L^F4E4u{qIkG^ zw=Y+3G={%>n9Z?2SiNiX%J4&zk18t9`DnONHGP#krap@H`+NMouhTPk;FoioHtY*+ zY2QFZGIBuPmtSN;H@yBiDaxc&m_s_lyezOPvpxc~%&si6GA$RNzK2xE36-u$B$wb# zqoa>LG6rW1&b-NtnT}aG5BHW_JFPcukzMi=v;La8rUV8Z%6K95x=*&UcXa7d`OLFb z!uT^WKQO*pHZKM4pl!z^i0|m*j_uH#`<_V5V7uB}SmR3wPyGmG3Oz;ig;K(wOXh#U z=4s!kHOX3(!82z5HFE#tUS>z&#hu z+LQ7cI*-_1>v3ML;^8FRqVbP&!xS}m2~LOwT9Mi@RL=|)Jy}No9;CmPH_+AbXT)R+ zaA)B!Fslw7C+xN&*67O`F^O-H-b*LZ8l5%zxSjWJN$6Rd61pegm9eC&a~~FbpmoW} z)00vbPk(wIeRBz~)E2e4NFAw{Wvw$g$yzO%GoMPtK`p;v5tMakq5O>X`?xJHAF}!{ zkrLT&Hjc)3%n}*Bxf46x`3$VKb%98v=)&5org_!ctCIQhztKZp!nny?CMH^4p~b`Z z?=spo%9_btaHjB8Ye}P}dFb^;h?K^@_s-QBNXCDJn5K9+S|uHiy49`yCWD09=f4

PX+-K&_y?5^1xzi^G4Oq&F zIF7SIFqt?m319m2XYhXq*OBeyaomYZw7pU*$)d-VT7A@GCVNf{|9y1$(D9zbhfbLA zyVi5qNY8NH1kW)OJOg@$c#i*l#K@+Oj&@$)jqzSTGU!QovTdaM^0J_amoB$w=^D%b zz<2CM>2fE0HJe*A{HIM$=6rXC?>%O?nt01JRmeH6hlLgAo%_6V87_yDTG(4ybKDSM zNNM_WHiwCn@Gno39q6y@%lTWdJn29S&XVPTk$4HPZ~2GiuDHr^Qz_j32mH+9lsdnU4EizL>07$PP<}W^Ff1bcL4IeR7JCx(PsDXvd@=!*EuRs28Dv)s- zTLO`T(A@mRr|i$46{j|VO3;eXePYe9Cz)uVO zw7^db{ItMN3;eXePYe9Nv;cpnDaWakrJXoFwl~K~kBTWiHrZj6NSun8tZf*_g}ZAw zb-@#VPF>}xKWFlFA@U8qI4<`wbmzmtxD$~`on3~w2l7n#({Owj;Nx2nZ6R`{a}E-5 zRqPF=bGB3TEsL(BXhkt$mr-&l!xF^%4hC*YZ z;4grtpGG9;N>IV?0_vZ%zJ@pYv)RBjh?Qq6_@O8=jtm$h=QHF5&JdU(FPRL9Y62!- zW?Wma#>n4f$RAi$_2(F4J)rcwMYzl-IYwRpp7YQB!TR7#3p0V(OyG{Z9YWst2Ijn6 zs7lP-g*2t=^qU-i&QN-c%HA8DlX6}HkPNWRpj3o9 zO&nr=48_wa&heoXzesTlz8A%>Qe4E#DV|AjE50qoZ&O^#_YX#V2CIS{q3;3Bx3xfJ z7Jr7q;V@x*8)Ui3(K))ktZ#g$lm45Rf+7WAhLZq zRz%p>gmvZX5%!y!i=m#N%_FM%JAu^#MBkK77k`8z7V0yALgo6EbL}9mkKh`d2B$0O z&T-;iR8MnvXTya$i(xP-a~2mP*%-rIM{R+FOTHU;;$2{Jj7b&vNM{UXcKqQAINSvn zwQCyR^$YazrM|%{QJ%?{`UKydMah1=KZ}ylcwZJJ6Yz~#lCVPIbG!0`RQka+(AFn zh0{6;W7~OWHp(5dgQ>dvWEOphOl`iP5+;j}123dHb7pR%Q>33~xH!^pR)mPeMEW`E z-h#kNAdtHlvPJ#u^vO;>7cjbqm?lbuUW|xoqLoSKY|=SUFQ|nYl*!c;0LfSA#&IdU zGYYhcqn0qX(-&JHPWCr8)fZbLPR(MhtuGcKPK{x#tS`1goSMLBr!N-k#BtOz3Myg` zDoukgG&j$FbGx!`W})KOF;h`Jf%Q2Wsk*QlG|z*4{_}5G z_4K!=+DWDJ{IP6_l_xVhry|EtEc7H5-k(VKuR* zyxKsU^PVA(r8Q0}{x%YN*(Hn`%Q?y< z2zE>pGEOo64U|x;g~T#OMMIp5Ur!mFW{}x#GblM)y^}GG5faB)Vh|29&*;*0t)GW6~6{}VxkV8A*RmHm_{J-jamR%~oGbpL|HpAECOJkafuY$O`-e**0WFT3AqUuKG&f-Ry?J2Vh%cQ9K z7jxzppv)ym=j|tCU5$e}r;zM)h0SV0J0Aue+PSHE8E91e3Q9IrZ(xZiN>nf>v`CaS zZKRN~j!_MyL=819GE{spC7PKNofwNyP7q~q8V~hmM%S2<9_F50l@c|~2?t74P#2YJ#IcN*$k2GIg~VM(C6x1mGB`~~^#MkAmXaOKq7P7_sX4KQ61C0c{Eb9e zIq^b90^^@W34gVan8c`ra%NHnr)g!j+aOAIR0|gADkSzY3GFG-LMk8|5ps8&ej|!qkC1|K=UA{>n%MacZrejz^8JIe2+6x)ZG%mO87ZDb-U$djLqlFfYc zmJnYexms(YjwEVdRF5WTnn?H&#XyfCv=5;J%;+GXX})&hheFyYnT3Vcd6bN^*4iO% zBc1mPIIvlTfVKhXC+TqdTyNlVYm%ro-bGrlP&f$=lTZm1kzBpLd$q?!i zHC=KSBZzd~6CmSgE{MMdfL7wv_LX3GAO1J+=#$0qEHew4{5cy)NdSYa0!ow4ix7R! zD?KWAmSGq`#!6VNY=()BLBixnQUsK>&LNJ(F~LT6GjehzAtDaPhM$O0jG4hoC)LX` zu?(}AVqGTaPt=|xJduiY<#+{Ju^ew%hUe``^HY}4+~NlXB~m?8kd>*I{Rh7p{~zU< z@l4b2_4^Jl{%;i(N0=*WJ;hv6sD^zdyf)XJ6tt931q28BRET!8Caef*>+JZ&?jZXF z-<88DR1qt?ATOlI(p(Kyy5F{^W zu$9guKg|%cVxgaUj}hbWFjC5~3fvnjZPZp>5m=M&X0$PH>TTygLAkqx6$#iEggr>uG)4=_x|&J#zxboxJ;+bA;-qUxDfn0-qD7C; zpQ|VR@h>8`5+YKA$T&mrI18Plp+-AWn?^h1s4_nUwi{vB5LO{zEs6G5!pISSUln`(SxbkUbCm@Q4RAZ#*Ml8shA$wk)(4i2Nmxs1f=DzL%sFxW%*fijRq$Vec=Tc`zm zXTpccEX(kgX1q7y17)HzyvU5NMEIsMt1`Te+7%5I!haz(D$B%#m!e#2GyWOyY)7J> zDdDuX8FI;24wN>CVD#oN9S9!Z6LfWHY)#=MesYOc26_xHNgSxoa2Pv`c1avq&v5Aa zigLEiU{g_w`PT}hc$&A^;RyC_N^DMK&g4lh8WC+!&ia9y9|AgK2cth5<#oO^uG1FA zmbMw3(bia>W|i7Lg;-N`z@Q+oE&(fcN)ldy2wB@G@=5N(%#D)tXY)d0<#}vV69WQt z^ay;s<;5a--VGinnEWWD2YAa%MDl_gyy3hdwAec|ud_j3;w>-m#|dXhuihj+3S?|k z9CF(Ig+F)36FR98FgCP;yO<(84Pox~_qCRW>LI2GH&cX*DZ<$l;b4l8m?Er9tr;yp zy&aqOoeg1LL>nX0r#I-SJKB?-C($G<;U9pc%;YjymGu?!cyYLWnfqEAD;aAW+sV){ zoYu#Wjs5VSJmOymen;S)jZy(&Ab}V_-z$W)7&T$1C+3~BDgDcVb`_{xY4WQV3S zlDfcJ{BEGkQFo%_)Tipv(91IaY|9!-gbclm)DVX^6C&1A>Xmin8fCU{(O9Sp|0!qQ z31(wO;9h>i{RNy^(q!}KCk`i?${4B5g-!wuqG(z*`8)rtl=eApl%}bh&thq&9}iOM zJo>Wf4YNY3D-?atkS;X)VBr^N>;G)y^8J#*RpES^)xMD6p1V zl_@C66m*i#9{^PRPG%=zHM^e~imRhAwNE0G=zE>$Rdg{XLI{+=rzE3068Lp?SFk@i!f+{}&0aYC*#4atUHV!n<+= z=H4CYAmO+XH^4mo9;^r?u`mURZh z9Yn=d{0J7OgGm+NkMgUlF;#OKTg_w@-wB8~S}1jyD%Ka8tF-MXrw-qi|Jcpkh}RS zdJDR|0wp!y3*z8+0-Aj3%u~r{A@)XTi!K%BOXp+-}X9s6pFmEGM4 zOT%40230d;GZ`Ulo2#iQun!j4A7FcE9A@U51!7(W0D83rY@iTW%q5yxc7nxFqa_u@ z80wiBB>%ziyHLhdFkmv5a6Xw>EEIhxx-Yt0^h_AjsT-O7uRgXT-(2$=E>O!|a~-na znkfvYjdPU~ORWS5BpF6BIxFl9q;icXf5i;!2akUchI~v>U?9Sfj{nVSRZ#ZE{bn*F1KWIj6>o^BU2bmIURx%18+UFj@%Qa1LV8IB907*P`t;Jyd*isHr;h z4x^O8MxSA&FE(ji{lv?`tZkma9cuuxkNb?zjCJ&~wLo&(Y9?RGReO|a;wT7@otbUO z7>ptW`FqUrufv7neg^|jFU7yt;FOtSA9_*y}JIa%YUq>eurx1>lW;` z=t4p`cixIh(v-FnU-c?jgf~Klf<-ZhIjHzJqQIg>9r?r`^{Wkb+&|Dk7a^B2q$7|l znZuH$O_8jiu~H|qT{xpFP16TxiUh|2x-vE(pmQs%`r1WB>Rs2;z zj6fYxb6P3Ug`<);FguhF?$FDb-7ctk6oa)FvS~CJfv=LU4OnJiH>$_K7lyZ*e77*f zF31q-Z0KxdsN|hWk0NaSQZSsSScnt~wm+HbL3b&Z(+ z+l5l;Fd|k8b6~8pea5u1ea1xdMxi3iVknMF#k^f4CI-mCiB8;cAh1BTMFma1bV#aV zHNpY<8Bl0!)gkz(_-9ZP8`xyRNz}a=?iz4qH<6to-sDJfhtiROQsq-~%TwG(O7zJ#`kdmTkq-J~HMOq;s+z&kNQ^t|n0{8+cE+*c1F9Yr(z_>>jP+AW=4&_>F5wh zQ`e({CnHBNY?(2+8C97ldS@H{rcyEGSsLycuH&f2!LX4qqU@qYv!8Jh3dgt50!{ zajXp#Q(C+Q8tb1H-*_!bjju_BtS!H3=V{0ud%u0d8kEO+1Sv`_2}NBE_ly+`8!08q z9-Hi9A*P~YYE%T|oy(h9I_CpS4EKVm`i8`j_VG>t24AL`j1}92ls7QN49gm0vM_k0 zT#`h8Nx9@qKr*kXwu&LGPHItRoqI)@S-in&9$7Ri$3FYU!^z?s57Et2E?VhxttQv| z7h{YE7C1i$JLV4MOpc_4ZrhL4O-L&jeG^ivy~&X(Bb^rre;gPpJbcriEub!k(K}S) z*V#%s*A8wT)7dJr4X1N3n^HN_U}w{JWflfgkrt z=bZ(I;RBWmD!xHOM6Y64d68g8Sv!#xGqYHrTSt=ZjzJ;Q*N^*3yk{22%q$SiEcs1^ zQR6lS3|f?zn0%=uC2v8Z(nazTlMV-H=vjG0K?oe_;gIJm)9 zPFq1ehVV>&XW)%ESZ8-ecy2baJf|UY)Ke+RO07o8Z#N+Jl>9)sth5sJe0~(FiR!z@ z%AYIvttdZ3&VI6)A;%&L&%fk((_hn)^EtNJYMV+_?Uk7G_=T8_k-4BO)8hNg@yJv! zLF0m_;Wr*7(6phX#hs?PSx_e+%dSftP9OY&BiFA0M!VBC6dwejH2LnLGW|h{>2n{& zTOp1~hbE{v*2u2ZFwq{|=9R!rmZhu6Y;*+)7D@0T?}KM2K@F(2hSYjU$YK>=^{ue zV5aE`3H&q|cd)P&&MwQ?#F$OKw8i?iyP5!U?9wzA|FQM){qRj_0eA<0)1$9hk7aMZ zk=y`|r#F3gq*qq8?!cju=vGI;XVzi9z^Uh<>CAQCOa$L|65;4}KjSm`Zlg*kf$y8h zVx-gyKEumMD!mg{{ujC3{<~Ziq48jv$sIy+L(uPP(6PAwi&*Dce)F&ac`~|@&{=dg zxIb)(PKJZ_mS|E7bw?|@65**-ten*cP@53`ZkZAmB1&FFGS~2}o=cI&PHcuDn}1fj zy!KAO8uDoW54{Y4W=NU){SF%SCH%^<#bLO zM|G|x>bDP>#$KZ`#EsEXo+3n=B4WpV=5b8Sjf!uM)TlVh9Mw=v33_GCjq+yk$)Zt3 z**G^JF*%p7NobQJaqF&rNlUPL+1bcF_cvngFTk|tLyeqQX)DW@_+p+`bCD?jHpHO; z`@k>x1r*Oy@u~P?t@dk-Zz4LodMNUgd=QZFNtBLYX&I$Y(qQ09*vJwKZH>s1=Q@WB zF^#`8NE&g`PNOu%eUha|l7-1toeEXe*O9^ZhLChIMY)A?$>vN%Scb`!Bs;u&F?V23s?J95S<;X9S))+(!w<&P?1kd4oQ zYB&vze}Heg_&MO5ba56w{&D_*@jQS*=e!V)TgSs(sk+6zhtwztyS!R(G`0nXS4zXx%L80-aeB%3NC<|UO`WBZ|V#fpRu zE+3*7L`gWj;W4HdZ83t2ldRBGw1;sK=7vQf=x=R7hJwh_kuqu>lt#q4^wJ zsSOJCTJrZ@9<0!j>GGYxZd0f?6Ltl|YO65JHp0vi=wwNxSD}2BjZW-{!G<%`pc=+l zt-nn^C11LrEVc--JHU00VHEl=&Xe6u@76Y}lxw>Di}Qk@(q1?M|4v2?$S6C@zzJ!H@GBOYg1&pt zG8i?94SgUzBEK)nj;u2~Aw@sa0T0v@&g*A7b6U%U%L_VNCR8pvH?m9^LD%g%%a+Lt zI*THwTUbYk7Ic=dL)P!b20*M#%+=#`6aQbxxDRNRQN%9tmcTt;th+h44Ee1A81( zP>Jp-4sw2Mdk;a6n(6XVGZ$L?d%KMx9e(7>#YPCtTpi79@h?unSA3b??2ti!wnQ27 zoto9nYFbN=gjwJ>JeTY-j|u9%E>~{{)fD%*sOfB0QsFP@@?z4_N@GP=rmPo!uVosJ z`CtTlnI--m66w5W7&J6pV&yv&8q0sxCPL`5n_9jt^B*U?hO?kN`~(H~PTIunrCz152JuRUX2=^#D& zY&_l1L_dyU*C&d&)<}7a2`3V_V{y7xiKnySei%WT2v4YB2`(uXI|lQiJ{~l!L`osN zs5*i5XRbHuRhVKUom&dp!W4;g-X}!J|D|({h(-Qmsq@4_p<^k=z)=9^)kLLgXfH9n z@8FDek-x2OS=RSID3VvDp-Vb98j}8HwW@gfh((dPN#2k!d7(qPyhy^{jPR+zERcU5 zSR|qmOl!LXZ_grwik$rwEdM`Ri=JTOaiNLRRfRGoB~Z53*D{UxQBVVKr2fHRAs7a; z2d9pvtrXkK9l$c*=!N;SwM@jh;}w`dWkXc6%c-!N#rmL&u>xG89bVfBL^Sn$n`!Au zf03BhBN!Y^(z$hE-VAvHXt-}KE1l~EG;`Z1{F3J@rYWJ1!M_sWU+80=I9x8Wra4ac zAaZ6RUMgbrI%>p118yWx`_-VwdOC@pBMo(0C1%lX`k4uw4o@f8tG{q51f4=vqnzj; z7c!0`fmWPuL=5AMVSE{4qNP8mNjm5D0WkWLVqZ+gHtnr+RWrm?5@lwH*|3TjuKnu7pw~oL)v?bmM;%?2{1Euq-gH|tN{5rf{W9+($km@8bS%F>*dfKa}Wr*2z zB$A}61%_w=Lq#i;8FISoz;s51#f0vNr>`JItg}1a3=Ne_h80kDK-D7D7x0+N(pCL# zJALvUDtj53>`|aVVJV$=92h(|O2>f1+F5%UPl8YTLlXMc)Hv#L@znd`Scjv&mm#KZ zM}OrbK$MK=3ZP85i?OYqrCNrgVTh^a7Yc-hSFyGsqi9xCa= zd@krQI%)B1q#a_dHK1*{Wzh|@Ey^BkGMxPdEqf4W-UPpfc%z3ou^kE8HP?9jZMRwn z#f9}VkMelih4Y>ypbYY2L*Ei_aW&YXx@%3q6Ok)daei5o9ll+!8O2Ft1S~6jlG(37 z&ybJi@BZJ7FL*LcZvMTMTq1i(0|I=g>}{$cJL;JUH{nrVtT+A*P1DH3eh5@Vrj^h4xv>t=%%AKQgM#ad# z(t_3&Yac8mu;BZCs_9oilQO%H!HHhE(AzL8gf{v=6Ds;96z;qdvheCb;vc^SW0RHt zW)rUUHaoHo)B_lfZ5dJDP2cvW$?7j4;?LpA#Yn%#{xR1Q-28Ur#&3cI-Umg*Q4Dvu zbbCy@50-|Fu~!HOq2LZVcvmQik>^F01n6vpM}rL_OX?zSi6V^dktOvI$H31Sog+&o zBaXp9cr!Q%wuq5GhfVS8V{BINBV}w=n3dgyUma8X(~(e)LO2u?AUXll(S*}1sN;;s zp7IhR)!G^4d1imZ{=rSyKP**~W%y^H#)yW+FDUWTH|hM_6fr*zo=U}(&?LtGQ*&LK zp!2a}R;lNc?`Xj4Wv5p)K5vcA|}H=F2|D>QY>>8$+A>AEnw))VNn6zWkw&}$gI zmNt(TUCgVp5={S?yXfGBEtK)>K*A@|cE((F&mXGp#@UutX?;aB)gNY)bo-&OuaE)r z3xyf`{7>TCzljSbab9L|njgf`&3(Bz1-}Hze&${B_x)%wWKidfBXj)NJ+T6msOev? zGx@GU_J8!vlbH0)X2~nlw-x*seVMdEM`kVF9%W!L=aBLYXj)I=v8J;*&ywmO_o(O9uMGJvh|iVEnoMEe7N2H}YtKhejMiQU(p#6-xy z6w37H;{^Bm#pFw58hQhmBY2P(uf>=RwQYH8P#bF+@dBJIP74w-MLdnkyb;o{ahSH1 z9qUl_NDbZ=1(#z;GGBxy!QE*oyy$%U{6ZH!a#|wG+$dr*BSvPXKs;&6Kjv{eO2c(tTs@>QVDm9X zW(q;;BCJZyS`+<`TC+_c+d%T3P*;tmFto+#{tuI9b+fj+U>T;Z5ASeTEfrW3NXMJa0KlyWA zCzJ3v$d^_k26@i66^)3ifaemdWCi~Pk4~1bHd(^fF2V|icSRB3{D|H*kr=;FUTe{X z{FthI2rk$UYaH`lJC9#>0;)Un3D`{D$f4t|wcvrOCVmtApWc07zPC!~Xbhx(XXFGn zVpu5qE|eEob=v%o$)DTYio;03sc#^zE&(v_Aa6h*yOMvbxqZqx)1>xF*v{ZF_Wph<-t5Va^D4t<12Zp?x4v^m@+=@pvUh#wWOo}sl# zIz#EoBIexGo=JBJAx^r4kNJ4xK@Kai%pKa;l6T zBCQn7R&i9+iBkAf-(6b#ln1jV?u+={L@h5VJ4`JI!L>Bs5oTll=5ya@(YdYFdVeg* zCyVu8MByJ|TRrT7l)*Ya+Jb#937_F&mRe`SJ}>AKXcfPZGV#4;{*ERpq&J!KbMeLH z+Zbf4R|A-PsW+;n=Pjjk<6(l7XLh0*E6|06I`u%EP@Db+Jw4LGdd4I#iAtjmM8C)3 zn+VzMk|M$CEib`PAwAl;vhV@`3ny}A{t#|fAp>XococxQ0t}hYkXky*=>av>a{>u?jMxps)HAfH`9hGUyjYu;1l>{}}?jtU?Suyd0DUt(S|+(8tR?c9whWhE}zq zbYO#+;KngZuM8WUGjRr`S8qHkRyK$U^u(|}#XgC;9+F;4b77&#Co?9{YT;sE z;th6KxUw}xlr9;8ZXo0`Y>3{VbkKjclFqqV3*7KHk6V~NjOg&uWX3j*Bpfz0=;5^S7ZcuxlrM~ z`kIuD4S|x_;O0#zt?1i}?*r>ZO<=m^jzE_KtuxgOWQJfbM%F8KB}s$6Zm|e>G6^Xl z!+V>7`m+-3XyIC{vJNWz!l5wG1q+Qe(4Ma%=xv`Q*lHk14S_Co(dIZoKiQnx$tOA1 zy~Dz}9jF;m(-$xgYWh9LLIbtj+zZ&5y)L*tvqCO%JnZs zpX5=7xwEKsW81q$Wsv3Z7#ePif0}2e!1#SR`dK&z^fb(J(MY0Rk%~%QB~V@XUjJYh zLkg>bb|mUx-KsI{M_$b7W)!A$)Hc-MheIC!Dg9sd#v40hum%ruXl3<7bwQ}lna#}8 z6lC=^5+#4_zmk>PF%g75$uJ^y5m;ptBgcU%+VeZr|1|(8eJ-HmOH}{T3$DI!Q3vWA zy_Ea_p->y2VNIa}&#ro6Ib8j3WQ_V}5MuRv7KOk@alFa$c+33Ta|^@_4_ z0z~yIlM(xy1(Ws7Ukro1TnvG3ere$q7hdvC8ypkpmNmh}CmF3I;TE39kc6Zm(6g3vM00WfvJd=uke7q1Z}+KL7Tr5=HCfCS;G!wK?=zJ{#R!A_V}W_Y>8?x{j8v@i%42$Ctam@K&Si%|ya z1uJaGlgfnU<Bf*_8GU;;*^@KypHB*DMR zB^mof=34(qYF$nW*8yoHN(;|3HjK=b{75P(BPA~@m#Tkf*)6J6;ee|!JqS#!=4>D^ zTM<)>Bm|a|C^1xEe#uLDXF0D>>u6}JPqB(=r%$yC*5&JSL|WU0RXZ)H_G=ei5gE^c zyKJgEViK0Gb#F3wox#fto@ekZgUJk@WH5=rL+1``>a$ly2z6ByJoxP!qh3~pj@9fPYFT*2T{1{X27 zfWf&8Mlv{q!Kn;3W^f3DgBa|`U>^n*4EA8K3xfd+`ZL&`!8Q!GVz4=b5(XPE=*6HX zgYFEvG3dgeGlLEcat!7H{`~uCfu9!mX@Q>>_-TQk7Wip_pBDIOfu9!mX@UQL7N~$% zg+#d+=cAHrjw{CZIYKtVd4wc{JqT+MR^i3PTztnNC=mh>S|NBLxFJ{}6oZCG$V51a zuo;2=cHBh#7RRkXIE|nMeiVWdApoHjf)|1df)zqBXx)a1tQ_VH3h)ggFQk5C$OxBeX|ogisT~0ihJ-r9#dT zgdhLzRl>h?g>zO;Jh#=2))ri{dvS@y3+dmpvrV0orTORnIa8tOC)}mYyqt1ow&_LU zE1TKJFWQKV_H9zL(zd1iHudve?TVMB!!>vGk<-$vXq)%U>2+|ypD|0Or7rn%{E9_i zuPmRvWlL=@v%fr-4v2oI}z!~j!TuX|q-9dJ9^q`yy8#}!AxjMhr=Yo)plbYIZ z>7ZZmrE~I0r__&&vKB`rw12judapGV&eiDKy!J;`z@tUyA6B?qr}kL+h^q@0$*N}5 zzqR`8=<2Im*7SoQD?KZ8NBd_xJGftKkT_}B z;^IXCb(U@Hb$;~u_EsBuxxcQzX8z28{J16RsNZG;o(+-qQXJaY%QD-o4%{#);h&E1}8518gS`s&sOT(Is@uG ziA?ygdg=n}T{QwMdyDyu=&+3ks;ZK!dK@>YtIiiqOdtKG*?{y}n@2wAu&5}0$*Qv@ zDLp?gon2TV`Rt+7B`Z>I)$u(r$m^dTz60!Y`=4R)SK(hQ$I`3)i1sEl;)0i3TJGPT z^ta1Omovl9N}4x$)$xdjdw zu2w@{dGUy%vn_KxzUw4CU!iOC!G*N7rzCaFugfD7hVM}JY~H1hty8_qlC1I79H%tB z96R2wO7-bA)W_o*^vJJMebdgomAfW%&-9Oec5cm!Rml>5<~UdNh?zmH;;(syZMjta z(Vka#^S;hMG`8Q%)(#8fcOE$yJ#ONNZDEfOd};Dh;=S)m!2nCq=$S*l-mZ23Ska@r z#sR@ghNrJww&7WNWvhY(3+_Z8aM!-Q`!QKE*LUsd$asBo-SqqYCjQd!ev)in^+N?| z3${<&ee!B(;@(yJGOcT$d^%)UbbNHl@nuz{sm_&^Q>`v-8XlE!xnDvT`wpj~9c?ak zzPDqSx_V##_505h);RBG9I-FG%7NRJ90rPBiAQ7}dhd2oX+7TiV0^#hAG!|rJF(7Z zdtKW_;rZ{b%hbo;bXqm(@%jnvTh?CtsrrMHrz$_%?=|OC>?h|&#|MvanmK*pkx_jv zc5HmOpk<9c`xfXMR9x`S2E+64vyCmJuY13Uo7ndJ>?a>HLmrG7`=Q`;{k^sOPClP- zwD%iv{@0zC`rLImIdaX0{;$Ip+#cDm@%`AQ0hiP}$BnMqXY%?!CohPCdmId3QoVn- zrQ?^!-8uMoi%hTHGZ(gZ+F&(c=jM0yGFE!+9ei}_!&`l-r$$V1YjbJYfdJ(NMQc&U zz~^@y;--YPI@jMtJGN`p&xLv3+k;AKNPqo!yvO5#of=%Jx^~#_oKzkk)nrL<|Ho~A zmn@5YEq=e?^-Vw5-w!pr)aP&ekSQzA1&mOI-F~)g(W|U2U8}5nF@A4sr%$cs_d42!HZ@!Qw9Pg5;Zb+PEjHb|W;cHC-z)7Vq_v*bIq_{GM&3BTOT%R=xk?XO z?e*y!eX>!_k8gGN<}9|Y)b8_%+D2#hm(}|fXvdyg-O{z$6V*=XxzFMWXU=Q3&p**> zr}sYz-Ad2(U-ede$w@!>>8LX&jm?UR4o})Ow8^l*`Rh;jaR~epdjIR!K5MtNvrg>W zZ>>D(<7>NJGn@T>#eHjo(``>D1`cdkdG6xKcTaX)8tRztbXycWKm6pQ&HFpdnw~#k zZO-vZvR6aK?8|w2V*ljM^~P*IFyu_y7p|7$KAW@nY!&;d8=f7k@K58`?q^o+ez`w+xzDSn2P_Xd z^qhD!*qGU6_m0Ftt{zjz`3>v8d->Mu&q_{B?YJw=e^c0vDwFnX@7sOei%w^2r@Vd; zwMx{xU)!Vh_u@N**$x~rVE6lDm-?uiHL-is@k#KTeUrKu-QL>1QC`nKehb;St4WhN z>z_2axGdMkZ{wq_hPn|QGJe^(H>gR2VwqOozpCRp?JU>n>wj;a`PcNMnXZen0%Q+$ z{NVbz&xU{Q^0dz0PS*zyxi}@yZ~Elv+p`bX+?b!A?=aS4>A}S9J=gc?UngPUtHVuW z!k*3E?sI>eGJVyYf!S>aPwv*hBWhjgni<)e)b4&E2g0U@e)b*y^wx{u>nnG+yqHzb zwB=E?hWUZF@7u1wrkJzun2KK}i@Yx6!X9Aocvtf->+WTunqK=H;0U(eTQKClY7);Z+slO>Z-NtgPYp?7P^UjH&lF^JjL&#!{Q3Dst2JNckV<#xjE74 z{`+Nq+QK>WDi6Baby2ZaGq&ojx|fG_Ih;PsHKydT?d{1eg8tGRcYWn+fAKzu&E4irOhDZZzbpSvo)s0#y*);s$uqH>+Sed~W3Qh&|+zorG&KfZ97 zO^4APKJ6UoZ2h8=+oIpJ>T4(V?z;QB&H4_l3;7~Dc~bR`oi2Y_>3F)@;@>SImU%6^ z>Ra>IkURSmKfS(uGvPO*>94%)yI-f*+jHwxZ7bjE5jIsjPP+eY*8DrWx2=0~cl6p@ zjqi+olC-tG`@Iuqn>lPg-`Atwz4<0%_Sd?dj@@dI_Ump#+cb|0ozK5huJuTLHQ(y+ zt&yLaz59~9T6`^0b|v_O{BXpBU%x1ItBy6yYTtL<*T=33(SZ3*drxgY^7yiQQ~k#U z$J&o;SG#Xik18_2kQ@N8FSor_1_gg@lHTQPL*d}lZURae{(=sYuU)=-M1;CdigKCu()dM zy7X!9cDy}5IB4R*S1)Jmx^ljQyuN5TED9 zMu*484w{@2Lv8y^{9a z9Cv-=^?Hr6Bs<6C+Yh?e`jqV1u_1@fwvSs?XOYE&^pji8waqhL;XQ`Cdt163eiL-; zVd3qKd0b$!Tg0XZN;6p&iJ43`E%&<-XWFO1SMVD==geI;~RTwu6A^fusvI~ z?(4WJV_h~rsMm7bm!i?Nil03le<9lOajiBP)eHIh_XoHJ828s2w_-%QMfXdBj#XNl z?-%)DZSE?^Asw0zIq@*h@i*^N>Fq|@Zq^ozYvGkNw(GUOns>O??r`hSr#`Lrq+MTG z8nF1m1IINp*54j6UuGE-_*vbk^&&sh+93}t19^T+uwPPCey9EwCND|@q;p5iyw(2~8u+7J) zZ8vMIeY0`9aeQRMbz`cFcKmaqtD&f1X{xHwKji+L>5>U4eQI1Y>`vd~cz551FR$%2 z={=2At)F;ZJa;y&iRJb`iUMXI3_iH_eunttglT(ZM+UEYyY%Bd)BT{9Zr&ZHw3s&L z!p!UYo@c!}^>qL@`hjh*F()b8XWO|U3s!CT&GSKE#l=;E&fOpOD8AHTar4mWe+)dg zDS74g1N-h@8*UhEf4tFYhpp3$t;X_qZ5vGtdEP&$`^DZ5eSO~kvGets&8-C>#Swv~Ge*H<6EGG?Vm zhu**S>$}@!^|M2JH+uIRn>O|8`-w&F$M<@jSIu8^DSTSvs8t&eX7|3kMg2tn&kDy! zZ9R3bru5j_yM6Ihr*T{DQuYse^r22fzdP^lr`@@=O+HpPF5qZ%@=&o0NhV34+;mzq%iIp+3QP{|Io8To}?beQdw!Km}Jm@G|bYSJnx|Z2Xf^-G> zCl1_G{q=`3V&1TeH%`^8zw6GDs~fssKQ#YIPiyt(=LfqzS@NOMx=H-K^D#G;`qj$s za5S^qiJB?bu61n}6}$AkyhZwhdRYNuM-)lr6W!|AEMrtsJH-`d+ZD!t!r=hwW|?l$A}%eMPi%WOBD z+gT{d?s_L&`N^#vw>|Zochgg28~3c%rcIqu_l}*_R&49t`E|`Xe|KEcU|8@AFMY*5 z)oW3~&oHGsYPFJp=YI9X{By;ba%#mLY{E_GR(a!p@ zXAF^^-Yqfgx$$mk%LYnS<{U&_aps1T(TykRf4PlwBd`G;gw|7gf*P^W5 zDtYq_Etg(Z*eEA2j2L;V^%z(G@t2pLw<~R=+SuR!o&AkD(#aD(v=04RXL`C?*P*Ji zQP@+XS#cy9QE>V0N3U6wMwlEI^Y6A%6M)tx6l*&EfiekJ?0Jtjoys_1Ln zw;uQ2At(P;%=7w*FF!h#^zvR8;xNoP^lkLET-TesyR}HYwqs@6+cOsblK)&UDzeJ1 zaIvZT`&wONeJzV`Tpr@wZ+B6`v%>hU#l78a2c?*fkL?@hGviJ@>B8IVUe?q!s#D`m zC%vp)t8sSqdL@saJ>==Q#qASY{B!Sg#4c{a)IP?of5iXN$St8>!KCzFj|1Lze$}YL zUeDJnCjQd#;l^$?Ms*I05C^||zW#l~1kZE1E87N~Y`1IF*@Dx-cF*>Hs{TfIKQqpw z<$3L%^wXTWiT&rQ`Dvpc&j0+$_iqRJ;<3HIF5fa-U+15my0kCyWr2okA16p7E_LXv zw0W|_S99&{%`ThyOZ~+o7hfMSY1m(``?6YZ>|wuUpwqLek29?+th?c5oU=J?$*gDF z`$V4{_Dl9Fi`hNKwe08~TH{LSyMj?^m!Hh-?6c(F?l+a|o-yrvG;FkT6@Pfq@+x6H zdj^hpGkfF{*_*Mi6ME|H?oZifGssfafA--^6E<;|jy_BoSSdE+L&9Qfzw~EedpA{h zlO1^R_0_Ds7LBb-+?_9|o6Wj$dBBG&f8^vJ$iJ)%n>!;b$+qdbOT8Ng_qiK=JRy6F zcm07&{(LyXvi`v>7RP$dRvoZ7eR}>B=WVP1EN=5&|G!q*e?R$Koet675@5&y3 zUENYoJiN4d$s ztt6!Snwqm#cn0sOuw}XD)R~rn%|;X@DfY_iuIYO5*A}~9#nn13M>ehLw)gi= zr9Bh()T`5ettfo^gunL;n~}JDd_aQ+mTzkwdEnGgF?Lw|uNPOxMNPFj@@42a_lEf? z`WcJbCCKf1^|iEV8s)ibrd^}RLra~4Vs7uQKf-pYB(MJJtF_(g1Z~Pce6M(TAA+?qEp&q>qQR)3fqRwjInUA*IH%la~7=$K#T4D36xdSb6Lv)+%> zb`NsdcFrYTGkZmBo9o++XZMfWwfBQ;#f&X(GV982N4oE*m{XBg?*Uy*w9?M)g{kdje*9xUw`yKCkuhG)`$G;4p)9QMbJ zZV%Y>YV7BzMG@Ufp1K-l<~!a`bjTK6>U*vC$V|@#7nQs2N3^wnu%_$pN1k7_{(G5^ z?d8kQR}CAJ7%-)<;s#gyFvA_UE$?UDeL7mRtfAVXOZNx$CN~^&tzjGEzIUq@W*>Zi zqxRX2KCh>}yc>S#1400&r`<_QXU$4>b8|-H4l%)OAkNa-m~GG`5(L@!^X`%d9P}n<6+WsYh$A4p1JX% zc8&e7Re8pytG$k{YxcNj|JX~Eby8bj@8!uKV!jMozq;aR$yxWM zE2AeXqPu4HabM>a{ZFlNZl!tI#ja1sjys}sb4v`b_DgJy3m!GC)J>w&zW$!oWZt=< z!-q|&*(WY0W@OsXEh#3kreT3=VU9(`5RbvD+MJH9oZ4gJm0q_RYbFNlwsE?8cEYFa zYcF-&F#q_;E-S2SXyW%iiV6Nbxbm@#dh;3$@4D~zqWqhG4^Iv9%s%}3OO;NEPNND> z+YgB9o*4DU`_S9gyQGP?dRz$J+Pz6+){Lz=v+K=XdS~wG#YNeduAg-8csNxxWlZWH z(-KC%uef~P_|1JwCfwW?8?@?Ck98G#9ClPZPz0Tr_S|`U<%Zp?P1kPz{j6{9q=U~= zH){82Iu_NER6f-(J#La{=x4QCJN=+M$FH%~mezcI|LHWpM-6K0qis`L#cXfftzxTH z&39H4y|3H%PHOCw=I-v&3d1Bdyx#go&5J(ml-RQIldX@n8%%Q(eLW9M^*9jLZH#vh zS=TzFN=`=Y>5vvt$JE;Ns_CZ`zemf)HXgabzMVwB=)*!U)v)V-Zod0e_O;5KhpE>e zMI7J1x628a;Q^Plix!_5aDCFJq@z#&KL9^Kz`w|fK0&MO_Hnfv8xADd);|37e)i2^|yofX}mL4UAL6}P6g*wiyGSH{s%Gn zjfwt<<`K&6>YS!hh@=SL!#gpCo<=Z>6aEN9=E2Ptj1$50iwsgQr_i{uB*-AE!-6M_ z_f^_yT*|^zY&Jr80kN&7CJ97VXiyw+%go?CTQySf4!F|#_XMnkJVpfaX1lNkiEk%S=m_Nfl_MRZ!)Do0n?^ zHE16j7p!FXnTxYt?lbi0RX#Op_694!SwXge%AE}L{^-03;eex2sPLdu{EqPmw*hGj zg=y;vYYM{!8o;fch%v;0QUGQ za0-x5KVD}xO^rd_ldC41FVk*_pnI82wWESdL7VK5gYzm*E8e2og(V&8A=wS7I%;9d zRq@nmF$Y^6s6D-lgY`Ny85T?>H_i=4;KGh|CfF0}Ay|bNj>$5u3)1f-p&Z>9kZy#F zsb+{U!!Jnz`295nrzRY!=DGn9qoGFH4Q&;i3(d(vP0E$zxmQ!rHO=2bH}t>VxXs)l zw;|s9EgEf2298LB-E?pa_rh5}c^PdPIQ?Q!ya_IjGPjhRAw0m<*0KtPFIw)X6pHD zVr@702tQG;uG4N}%wJ_g158zs)-&Y%*ff~F*=JK5MQFl3+y=ht8C9=McWNJ=wks9f zNz_14P7lF;CK_^L+QaIK5Lp?XzjZA#a(-4+VAXJ7Esp=J+q^~jTMqpF;`^%UzArh%76eoBH)J(9}Y7~En*mM_zN=Bmb3uK=?tGaA~ z21#d|P18Fg&VXzupatl)wUoB16ZjURc%x+Nv3l82`O(3M1igJs)HA!o4HaTKHd*0H z9LMken?|<%7tprqR%4S%`4@);x6CdPhMj=W22j0_?Ut9cVVjAnBBIsfb8Em#7#>#b z6n_XHehOj@?7Ku9x=r2+p~-70NTh4`jSB3?^kg*%j^!a4`hr8UK#hphDsa*ikKMX` za}%?X1YS6~)YR#^exF$%13fIJ`7GX&X9z_$7}NJ%3om2*B=9}Ci3H=ZYKmjf5Pm^? z_eb(d9#JU`Vm#Ojf;!0M`J)a~gITRk@iQ zWowEM?FuQir{ol=an6z3Y`~WEIJ_Bi;Ayp4#hV}2PD?n)-9fu*&!kg%B3YjbVo|SL z5yNEcEj+gAw3XUpT>nMcD$bew&i=e@5KbuuPJ+ACJmC9WAG4V~oHGgoPNDk|xZQX) zl=A|*MUTPPAPy}K%wo4FcV+Dyap`L!Klz4m!s0Xy8;zf}CHA1yq~AIrG{vw6*dy(N z^bWrsj!GFM`r;ya27Y|tM(vL!ZiH`7CRHQVnX0~Ql_9qD!>HzQV@X&O|C281nn_o~ zxC^W6-g1zP;*D?hqA=%46q4y_Hy{iuiqYfcI?;H9uPCtyPQyxp2 z@jS;a?jO@F`IPMLZoJR;rh&urrLcjt#B_&rMBS`g)9>I<#A{n-GzESNpU;cAHC;4s z93VeI0;@0?W4$MiYJu?iR`czN7B&u^3%c8astPcl5XPoHLX)1M$XrLJn>TxCo}wru zXfR>I!^7j1KRm`*;!t4lF=!#|(dMx#>$Z|WX)R;uW(DL&dE&fihLZm0bEQ|qP{^$( z996jW4a~{ZSDc^&)d2bQH&t1Y!bG{5bs&-fiiLZc)J{5982EuiD|KlqcrTtH^*vM43VB7Lp9hJBCTz~zjw55$7#1sX}l->=M zyI}fM7^oc9dO_ww&L~!>zkMkGEw{&(P!~Ay0?u;}Lo8R*P-%}i3@n7xn?WL#oH|2# zoC@p_PN=B5PM;>E<9~CXj3z;cnc1!CSJ{YVPe2Jx3!%U(<73tGPTOrz5_Cuzi^&|G zc)z@_(ajN{%Ln|@m&u7rUmtp|HLWpwD=2+6iA^SU~4A!hh4Ci8ISe-VZ;^x&kgX|df|mRzb)ORPq%I^Cb(4C-!mTT&PWB; zh7;T+lR=j&=;;{%~F!Vz4KrgiP zHpuFZW7sE#O|apwv1&sBRmy74U-(d?=kll}3#=lLs-wq+tW@9OX^x;c2zFz=REV@y z+_CW*^n)Ydj^#lI4<{B<$Z*=&#MX_0mh+|{3^<$N*d#uy6`k{-u#g4~Or8s*MbihY zo~{u&{PA9G(3P6SEGCF3NrKR^Nr*m-$sS4prr;^(=#!vMOvyk_6-!?qwWckxk5lo0 z1bqXIO@D!B_3vO&m?W7A^Q6?YR0_@M2G^91uc#yrzM9o4o3nZAB_V(B^o$bxSFuBN{m05R{q``$Zi#gqrBWe-wCqq(;$CwwdqZ_br4=0C0=!d-UqjI3uiLyfpZrd8r^8sVLaB1PPMc*Ql-q`(2VyA| zHB(OVl&2QXkekc(#f`B(1JtsH#KrKv-2Kgq?XnP&3b>sBce4~sd>Y7%!GI~`=Ebzh z z75rm3q-GkUStUXZgl1&D&7A?EDq&~8dZ!kX;{o&Td=uN#c3R1eO7Yn+I|pk5Ug