home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Arcade Explosion
/
ae.mdf
/
arcexp
/
descent
/
levels
/
utils
/
dthogexe
/
splithog.asm
< prev
next >
Wrap
Assembly Source File
|
1995-04-06
|
14KB
|
530 lines
;=============================================================================
;FILE: SPLITHOG.ASM
;
;DESC: Splits a Descent .HOG file into separate files
;
;NOTES: Uses Spontaneous Assembly 3.0. Can be modified to not use it
; at all....
;
; Built with MASM 6.1 and Spontaneous Assembly 3.0.
; Use the /cp:1 link option for automatic memory footprint reduction
; at load time:
;
; ml /c splithog.asm
; link /cp:1 starts splithog,splithog,,sas;
;
; This source code is placed into the public domain.
;
; Version 1.0, 03/25/95: Initial release
; 1.1, 04/06/95: Added ESC checking
;=============================================================================
_model equ <small>
include MODEL.INC
include CONSOLE.INC
include FILECNTL.INC
include FILEIO.INC
include IMATH.INC
READWRITEBUFR equ 63 * 1024
NAMELENGTH equ 13
.codeseg lib
.extrn start:auto, exit:auto, exit_ok:auto
.extrn console_init:auto
.extrn get_version:auto
.extrn clr_region:auto
.extrn goto_xy:auto
.extrn openex_h:auto
.extrn cput_str:auto
.extrn lseekb_h:auto
.extrn read_h:auto
.extrn create_h:auto
.extrn write_h:auto
.extrn word_to_asc:auto
.extrn dword_to_dec:auto
.extrn arg_count:auto
.extrn arg_next:auto
.extrn str_len:auto
.ends
.dataseg
.extrn e_code:word
SizeOfCreate dword 0 ; bytes in file to be created
MemSeg word 0 ; read/write buffer segment
HogHandle word 0 ; handle of HOG file
NewHandle word 0 ; handle of FileToCreate file
LogHandle word 0 ; handle of results log file
BigHogFile byte "DESCENT.HOG",0,0,0
FileToCreate byte 13 dup(0),0
CrLf byte 13,10,0
ScratchBuffer byte 130 dup(0) ; oversized buffer in case user
; really screws up command line
Spaces1 byte 6 dup(" "),0
Spaces2 byte 17 dup(" ")
LogFile byte 13 dup(0) ; name of results log file
ModulesOf byte 13,10,"Modules of file ",0
ColonAndEnd byte ":",13,10,"(file name, size in bytes)",13,10,10,0
ResultsAlsoIn byte 13,10,"Results logged to file ",0
PressESC byte "SPLITHOG.EXE 1.1 by Bob Clarke",13,10
byte "Splits Registered Descent HOG file into components"
byte 13,10,10
byte "You may press ESC to interrupt program run."
byte 13,10,"Press a key to begin.",13,10,10,0
Interrupted byte 13,10,"*** Processing interrupted by user ***",13,10,0
; Error messages
MemAllocError byte "Error allocating read/write buffer.",13,10,0
NoHogOpen byte "Can't open .HOG file.", 13,10,0
ErrorCodeMsg byte "Error code: ",0
Overflow byte "Overflow subtracting word from dword!",13,10,0
HogReadError byte "Error reading HOG file.",13,10,0
HogWriteError byte "Error writing to new file.",13,10,0
CreateError byte "Error creating ",0
LogWriteError byte "Error writing to log file.",13,10,0
LogCreateError byte "Error creating log results file.",0
.ends
IF NOT __TINY__
.stackseg
.public stack_start
.label stack_start word
db 1024 dup(?) ;define a 1024 byte stack
.ends
ENDIF
;=============================================================================
;FUNC: MAIN
;
;DESC: Main body of program.
;
;IN: DX segment address of PSP
;
;ASUMS: DS,ES @DATASEG (same as @CODESEG in TINY model)
; SS @STACKSEG (same as @CODESEG in TINY model)
;=============================================================================
.codeseg
IF __TINY__
assume cs:@codeseg, ds:@dataseg, es:@dataseg, ss:@dataseg
ELSE
assume cs:@codeseg, ds:@dataseg, es:@dataseg, ss:@stackseg
ENDIF
.public main
.proc main auto
cld
.call console_init
.call get_version ;; init for use of file sharing flags
; read the command line, looking for a .HOG file name
.call arg_count
or cx,cx
jz UseDescentHog
mov si,offset ScratchBuffer
.call arg_next
mov di,offset BigHogFile
mov cx,13
rep movsb
; clear the screen and home the cursor
UseDescentHog:
.call clr_region
xor ax,ax
.call goto_xy
mov si,offset PressESC
.call cput_str
xor ah,ah
int 16h
; allocate read/write buffer
mov ah,48h
mov bx,READWRITEBUFR shr 4
int 21h
jnc GotMem
mov [e_code],ax
mov si,offset MemAllocError
.call cput_str
call ErrorOut
jmp NoRelease
GotMem: mov [MemSeg],ax
; open .HOG file
mov si,offset BigHogFile
mov al,O_RDONLY+O_DENYNO
.call openex_h
jnc @F
mov si,offset NoHogOpen
.call cput_str
jmp AllDone
Oops: call ErrorOut
jmp AllDone
; create the log file
@@: mov [HogHandle],bx
mov si,offset BigHogFile
mov di,offset LogFile
LogLoop: lodsb
stosb
cmp al,"."
je LoopOut
or al,al ; shouldn't happen...
jnz LogLoop
LoopOut: mov ax,"OL"
stosw
mov al,"G"
stosb
xor al,al
stosb
mov si,offset LogFile
mov ax,FA_NORM
.call create_h
jnc @F
mov si,offset LogCreateError
.call cput_str
jmp short Oops
@@: mov [LogHandle],bx
; write header to log file
mov si,offset ModulesOf
.call str_len
.call write_h
jnc @F
LogWErr: mov si,offset LogWriteError
.call cput_str
jmp short Oops
@@: mov si,offset BigHogFile
.call str_len
.call write_h
jc LogWErr
mov si,offset ColonAndEnd
.call str_len
.call write_h
jc LogWErr
; move past 3-byte header in .HOG file
mov dx,0
mov ax,3
mov bx,[HogHandle]
.call lseekb_h
jc Oops
; start loop that reads file name, creates file, transfers bytes, closes file
; get the name of the file
BigLoop: mov ah,1
int 16h ; check for key waiting
jz NoKey
cmp al,27 ; ESC?
jne NoKey
mov si,offset Interrupted
.call cput_str
jmp AllDone
NoKey: mov si,offset FileToCreate
mov cx,NAMELENGTH
mov bx,[HogHandle]
.call read_h
ja AllDone ; all done
je @F ; read was okay...
mov si,offset HogReadError ;read failed
.call cput_str
jmp Oops
; create the new file
@@: mov ax,FA_NORM ; normal file attributes
.call create_h ; destroys earlier BX
jnc @F
mov si,offset CreateError
.call cput_str
mov si,offset FileToCreate
.call cput_str
mov si,offset CrLf
.call cput_str
jmp Oops
@@: mov [NewHandle],bx
; display the file being written
mov si,offset FileToCreate
.call cput_str
mov si,offset Spaces1
.call cput_str
; read the length of the file
mov si,offset SizeOfCreate
mov cx,4
mov bx,[HogHandle]
.call read_h
ja AllDone ; shouldn't happen...
je SizeToCRT
mov si,offset HogReadError
.call cput_str
jmp Oops
; dislay the number of bytes in the file
SizeToCRT:
lodsw ; low-order
mov dx,ax
lodsw ; high-order
xchg dx,ax
mov si,offset ScratchBuffer
.call dword_to_dec
.call cput_str
mov si,offset CrLf
.call cput_str
; write file info to log file
call LogWrite
jc AllDone
; read as many bytes as told by the file length just read, and place into
; the newly created file
; compare what has been read to what we need to read
HogCompare:
mov dx,word ptr [SizeOfCreate+2]
mov ax,word ptr [SizeOfCreate]
mov bx,ax
or bx,dx ; if 0, all done with this new file
jnz @F
; close the output file, get the next one
mov ah,3eh
mov bx,[NewHandle]
int 21h
mov [NewHandle],0
jmp BigLoop
@@: mov cx,READWRITEBUFR
.cmp_dw dx,ax,cx
; JB if dword (DX:AX) < word (CX)
; JBE if dword <= word
; JE if dword = word
; JAE if dword >= word
; JA if dword > word
; If what we need to read is >= READWRITEBUFR, read a full buffer, else
; read what's left.
; Since DX = 0 if DX:AX <= READWRITEBUFR, AX is amount for the read operation
ja FullRead
mov word ptr [SizeOfCreate],0
mov word ptr [SizeOfCreate+2],0
mov cx,ax
jmp short DoTheRead
; subtract the amount we're about to read from what is left to read
FullRead: .sub_dw dx,ax,cx
jnc NoOverflow ; there should be no overflow...
; error, close all and exit
mov si,offset Overflow
.call cput_str
jmp short AllDone
NoOverflow:
mov word ptr [SizeOfCreate+2],dx
mov word ptr [SizeOfCreate],ax
; read from the source file, write it to the target file
DoTheRead:
mov bx,[HogHandle]
xor si,si
push ds
mov ds,[MemSeg]
.call read_h
pop ds
ja AllDone ; already at EOF (shouldn't happen...)
je ReadOkay
mov si,offset HogReadError
.call cput_str
jmp Oops
ReadOkay: mov bx,[NewHandle]
push ds
mov ds,[MemSeg]
.call write_h
pop ds
jae HogCompare ; okay, get more
mov si,offset HogWriteError
.call cput_str
jmp Oops
; release any allocated memory
AllDone: mov ax,[MemSeg]
or ax,ax
jz NoRelease
mov es,ax
mov ah,49h
int 21h
NoRelease:
mov bx,[NewHandle]
or bx,bx
jz @F
mov ah,3eh
int 21h
@@: mov bx,[HogHandle]
or bx,bx
jz @F
mov ah,3eh
int 21h
@@: mov bx,[LogHandle]
or bx,bx
jz @F
mov ah,3eh
int 21h
mov si,offset ResultsAlsoIn
.call cput_str
mov si,offset LogFile
.call cput_str
mov si,offset CrLf
.call cput_str
@@: ret
.endp main
;=============================================================================
;FUNC: ErrorOut
;
;DESC: Displays DOS error code message
;
;IN: nothing
;
;OUT: nothing
;
;=============================================================================
.public ErrorOut
.proc ErrorOut auto uses ax bx si
mov ax,[e_code]
mov bl,10
mov si,offset ErrorCodeMsg+12
.call word_to_asc
mov si,offset ErrorCodeMsg
.call cput_str
ret
.endp ErrorOut
;=============================================================================
;FUNC: LogWrite
;
;DESC: Write HOG module info to log file
;
;IN: nothing
;
;OUT: CF set if error, else CF clear
;
;=============================================================================
.public LogWrite
.proc LogWrite auto uses ax bx cx dx si
mov bx,[LogHandle]
mov si,offset FileToCreate
.call str_len
.call write_h
jc LWError
mov dx,17
sub dx,cx
xchg dx,cx
mov si,offset Spaces2
.call write_h
jc LWError
mov si,offset ScratchBuffer
.call str_len
.call write_h
jc LWError
mov si,offset CrLf
mov cx,2
.call write_h
jc LWError
ret
LWError: mov si,offset LogWriteError
.call cput_str
call ErrorOut
stc
ret
.endp LogWrite
.ends
;=============================================================================
; Stack normalization and memory management initialization labels
;
; NOTE: These declarations must remain after the declaration of the stack
; and anything in the stack segment. These labels define the end of the
; stack and the program, which is where the near and far heaps are placed
; by default. These declarations do not affect the size of the program and
; may be left here even if the stack is not normalized and the heaps are
; not used.
;=============================================================================
.public nheap_default, fheap_default
IF NOT __TINY__
.stackseg
IF __SMALL__ OR __MEDIUM__
.public stack_end ;used by START to normalize stack
.label stack_end word ;must be defined past entire stack
ENDIF
.label nheap_default word ;used by the near heap
.label fheap_default word ;used by the far heap
.ends
ELSE
_BSSEND segment byte public 'STACK'
.label nheap_default word ;used by the near heap
.label fheap_default word ;used by the far heap
_BSSEND ends
% @codeseg group _BSSEND
ENDIF
end start ;specify START as starting address