mac-tip/x86-asm-source/TIP.ASM
2021-11-19 21:28:52 -07:00

3941 lines
142 KiB
NASM
Raw Blame History

;+-----------------------------------------------------------------------------+
;| 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" <George.Earl@ssa.gov>
; "James Wynn" <jwynn@mail.mcg.edu>
; Ron Charlton <charltoncr@mindspring.com>
;
; o TIP lockups under NT4/SP3 after using ASPI_ME with an Adaptec 1542
; controller. Several reports of this configuration problem.
; Des Gordon <Des.Gordon@digital.com>
;
; o NT Startup delay ?????
; "Keating, Dan (Miami)" <DKeating@herald.com>
;
; 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 <bodine_j@FORTLEWIS.EDU>
;
; o She's getting the "buffer too big" error on a SCSI Jaz drive!
; Tip-test reports "00FFFFE6"
; Dorothy Nyberg <dnyberg@premier1.net>
;
; 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 <jstrick@oz.net>
;
;------------------------------------ 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 <tcarter@piedmontpublishing.com>
;
; 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 <imagenex@sentry.npsnet.com>
; "Vince D. Kimball" <vkimball@shore.net>
; Franz <starhan@kapsch.net>
; Harold Annen <jhha@execpc.com>
;
; Fixed weird window background colors being used for background of
; the RichEdit controls! let "Jonathan Tham" <jtham@snet.net> know.
;
; Fixed 2 Gb drive troubles: "Tom D. Bruce" <tdb@iname.com>
;
; 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 <NULL,NULL,OFFSET StreamSource>
;----------------------- 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
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; 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
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
.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
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; 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
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; 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]
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; 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]
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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]
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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
;-/////////////////////////////////////////////////////////////////////////////-