Metropoli BBS
VIEWER: save.asm MODE: TEXT (ASCII)
; SAVE.ASM for E32 - Copyright (C) 1994 Douglas Herr
;  all rights reserved

; this prompts for a file name then writes the file.
; The original file is renamed to filename.BAK.  If an
; invalid filename is entered, the speaker is beeped.

include	model.inc

public	save
extrn	edit_filename:near
extrn	working:near
extrn	msave:near
extrn	error:near
extrn	yesno_message:near
extrn	mark:near

extrn	dotbak:near
extrn	qfname:near
extrn	fexist:near
extrn	disksize:near

temp_filename	equ	[ebp-64]
save_start	equ	[ebp-68]
save_bytes	equ	[ebp-72]
cleanup		equ	dword ptr [ebp-76]

include	dataseg.inc
save_mess	db 'Save as: ',0
save_block_mess	db 'Save block as: ',0
not_enough	db 'Not enough disk space'
delete		db 0
		db ' delete backup file (Y/N)?',0
extrn	filename:dword		; pointer to filename
extrn	filesiz:dword
extrn	dirty_bits:byte
extrn	warning:byte
extrn	mark_mode:byte, mark_start:dword, mark_end:dword
@curseg	ends

include	codeseg.inc
save	proc	near
	enter	76,0

	xor	eax,eax
	mov	save_start,eax
	mov	delete,al
	mov	eax,filesiz
	mov	save_bytes,eax
	mov	cleanup,offset save_new_filename

prompt_for_filename:
	mov	esi,filename	; pointer to filename

; copy filename to temporary buffer
s0:
	lea	edi,temp_filename
	push	ss
	pop	es
	mov	ecx,64/4
	rep	movsd

	mov	esi,offset save_mess
	cmp	mark_mode,0
	je	short s2
	mov	eax,mark_start
	mov	ebx,mark_end
	cmp	eax,ebx
	je	short s2
	jb	short s1
	xchg	eax,ebx
s1:
	sub	ebx,eax
	mov	save_start,eax
	mov	save_bytes,ebx
	mov	esi,offset save_block_mess
	mov	cleanup,offset mark
	mov	byte ptr temp_filename,0
s2:
	mov	ecx,63
	call	edit_filename
	cmp	ax,27
	je	bad_exit

got_name:
	mov	edx,esi		; point EDX to the filename
	mov	ax,4300h	; get the file attributes
	int	21h
	jnc	short name_ok	; if no error, filename ok
	cmp	ax,3		; was path not found error?
	jne	short name_ok

	mov	ax,0E07h	; write a bell character
	int	10h		; BIOS tty service
	jmp	s0		; try again

name_ok:
	call	working		; print 'Working' message
	mov	ebx,esi
	call	qfname
	mov	edi,ebx
	push	ds
	pop	es
	cld
	rep	movsb		; copy qualified filename to buffer

check_disk_space:
	mov	dl,[ebx]	; get drivespec
	and	dl,0FFh-32	; make it upper case
	sub	dl,'A'		; normalize
	call	disksize
	cmp	edx,save_bytes
	jae	short s4

; insufficient disk space
; see if an old file w/ same name is on the disk
; & prompt for deletion if so
	mov	delete,':'	; default: existing file w/same name
	mov	edx,ebx		; DS:[EDX] -> filename
	call	fexist
	cmc			; CF = 1 if existing file
	sbb	eax,eax		; AX = 0FFFFh if file exists
	and	delete,al	; 'delete' = 0 if no existing file
	lea	edx,not_enough
	jz	short print_msg
	mov	ah,warning
	mov	esi,edx
	call	yesno_message
	cmp	al,'Y'		; delete original file?
	je	short s3
	jmp	prompt_for_filename
s3:	mov	edx,filename
	mov	ah,41h
	int	21h
	call	working
	mov	ebx,filename	; DS:[EBX] -> filename
	jmp	check_disk_space

print_msg:
	call	error
	jmp	prompt_for_filename

s4:	lea	edx,temp_filename
	mov	esi,ebx
	call	dotbak		; rename original to .BAK
	mov	eax,save_bytes
	push	fs
	pop	es
	mov	ebx,save_start
	call	msave
	jc	short bad_exit	; don't save new filename if error

; clean up & return to ready mode
	call	cleanup		; save filename if not marked block
				;  else unmark
bad_exit:
	clc
	leave
	ret

save	endp

save_new_filename:
	push	ds
	pop	es
	lea	esi,temp_filename
	mov	edi,filename
	mov	ecx,64/4
	rep	movsd
	and	dirty_bits,00111111b
	or	dirty_bits,00100000b
	ret

@curseg	ends
	end
[ RETURN TO DIRECTORY ]