" ***********************************************************
" *                                                         *
" * Copyright, (C) Honeywell Information Systems Inc., 1982 *
" *                                                         *
" ***********************************************************
" SAVE - Program to Write Secondary Storage onto Tape.
" Modified 2/80 by R.J.C. Kissel for 6250 bpi operation.
"
" args are:
"	device address range
"	ALL to ignore fsdct
"	TAPE n1 ... nx to set tape numbers


	name	save


"  ******************************************************
"  *                                                    *
"  *                                                    *
"  * Copyright (c) 1972 by Massachusetts Institute of   *
"  * Technology and Honeywell Information Systems, Inc. *
"  *                                                    *
"  *                                                    *
"  ******************************************************



	include	bosequ


" 

	include	ntape_equ

	include	sav_util

" 

go:	tsx2	set_vol_info	copy volume information

startape:	tsx2	resetq		reset all entries except header

	lda	svh_length,dl	copy the header
	mlr	(pr,rl),(pr,rl)	so that it can be written out
	desc9a	bf|svh,al
	desc9a	bf|svhc,al

	tsx2	opentapew		open for writing
	zero	qh
	zero	tapen

	tra	wpre		now write out preamble


setpre:	tsx2	set_vol_info	set info for next volume

wpre:	lda	bf|svh.curvol	get current volume number
	als	24		place in position for ID
	sta	qp+1		set in ID for preamble record

	tsx2	pprint		print tape contents

	lxl7	0,dl		set preamble queue entry to go
	sxl7	qp		..

	eax3	qp		wait until preamble written
	tsx2	savwait		and check for EOT and errors
	arg	saverr
	tra	eot


	tsx2	savloop		loop through volume
	arg	dosave		..

drain:	tsx2	savwait		wait for I/O to quiesce
	arg	saverr
	tra	eot

	tsx2	nextq		step to next queue entry
	cmpx3	ql,du		until we lap queue
	tnz	drain		..

	lda	bf|svh.curvol	get current volume index
	cmpa	bf|svh.nvol	any more volumes?
	tpl	done		if not, all finished

	tsx2	copy_from_preamble	place preamble info back in header

	aos	bf|svh.curvol	bump volume index
	tra	setpre		and write preamble for next

" 

" The following subroutine is called to process each 32K block
" of secondary storage on a volume.

dosave:	stx2	dosvx2		save X2

more:	stz	base		clear base of block
	stx3	qtemp		save current queue pointer

wait:	tsx2	savwait		wait for tape I/O
	arg	saverr		..
	tra	eot

	eax7	tpdone		get done flag
	tsx2	setq		and set queue entry with done flag ON
	tsx2	comp_base		compute base and top
	tsx2	nextq		step to next queue entry
	tze	wait		and loop until queue stopper

	tsx2	disk_io		read in block from disk
	arg	rdev		..

	ldx3	qtemp		restore queue pointer
	lca	tpdone+1,dl	all bits ON except tpdone
undone:	ansa	0,3		turn off done bit in queue entry
	tsx2	nextq		step to next entry
	tze	undone		and loop until stopper

	tsx2	runtape		now, allow tape to run

	cmpx3	ql,du		have we lapped the queue?
	tnz	more		if not, continue through 32K block

dosvx2:	eax2	*		restore X2
	tra	0,2		return to caller

" 

eot:	lda	1,3		get last ID
	ana	-1,dl		mask it
	sta	bf|svp.sva+sva.done	remember where we left off

	tsx2	copy_from_preamble	copy preamble info back into header

	tra	startape		now start new tape

" 

set_vol_info:
	stx2	svix2		save X2

	tsx2	copy_to_preamble	copy volume info into preamble

	eax0	0		prepare to read volume label
	eax1	svl		into label area

rdlbl:	stx1	lblp+1		set ITS pointer offset
	lda	lbltbl,0		get record number in A
	tsx2	mulbos		convert to BOS address
	arg	=itp(bf,svp.sva+sva.devt),*
	tra	lblioerr

	tsx2	rdev		read one record from label
	arg	=itp(bf,svp.sva+sva.devt),*
	arg	lblp,*
	tra	lblioerr

	eax1	1024,1		step to next record
	eax0	1,0		..
	cmpx0	lbltblen,du	check for completion
	tmi	rdlbl		..

	lda	1,dl		set preamble version number
	sta	bf|svp.version

	lxl7	bf|svp.sva+sva.devt	get device type word
	anx7	=o17,du		mask to get device type
	lda	rec_per_dev_list,*7	get number of records on this device
	sta	bf|svp.recs	and save in preamble info

	csl	(),(pr,rl),bool(17)	mark all bits in bit map
	descb	*,0
	descb	bf|svp.bits,al

	lda	bf|MAP+vol_map.bit_map_n_words  get number of words in volume map
	als	5		multiply by 32
	sba	bf|MAP+vol_map.n_rec  subtract number of records in map
	neg	0		-number of unused bits in last word of map
	eax5	32,al		number of bits in last word in X5

	lxl7	bf|MAP+vol_map.bit_map_n_words  get number of words in volume map
	lda	bf|MAP+vol_map.base_add  get first record in volume map
	ldq	0,dl		keep offset in Q
	ldx6	32,du		copy 32 bits until last word

mapl:	cmpx7	1,du		last word of map?
	tpnz	*+2		tra if not
	eax6	0,5		use bit count for last word

	csl	(ql,pr),(al,pr,rl),bool(03)  copy 32 bits at a time
	descb	bf|MAP+vol_map.bit_map(1),32
	descb	bf|svp.bits,x6

	adq	36,dl		step to next word of volume map
	ada	32,dl		step to next 32 bits of preamble map
	eax7	-1,7		count another map word
	tpnz	mapl		and loop until finished

	lda	bf|svp.sva+sva.vtoc_size  get records in VTOC
	csl	(),(pr,rl),bool(00)	clear bits for label, volume map, and VTOC
	descb	*,0
	descb	bf|svp.bits,al

svix2:	eax2	*		restore X2
	tra	0,2		return to caller


	even
lblp:	its	bf,svl		pointer for reading volume label

lbltbl:	vfd	36/LABEL_ADDR	table of label record numbers
	vfd	36/VOLMAP_ADDR+0
	vfd	36/VOLMAP_ADDR+1
	vfd	36/VOLMAP_ADDR+2

	equ	lbltblen,*-lbltbl


" 

saverr:	stx2	sverx2		save X2

	lda	1,3		get ID
	ana	=o777777,dl	mask record address
	sta	rtemp		and save

	tsx2	erpt		print error message
	acc	'unrecoverable error writing record ^d.'
	arg	rtemp

sverx2:	eax2	*		restore X2
	tra	0,2		return to caller

" 

	include	bos_sdw
	include	bos_tv
	include	bos_common

	end
"
"
"                                          -----------------------------------------------------------
"
"
"
" Historical Background
"
" This edition of the Multics software materials and documentation is provided and donated
" to Massachusetts Institute of Technology by Group Bull including Bull HN Information Systems Inc. 
" as a contribution to computer science knowledge.  
" This donation is made also to give evidence of the common contributions of Massachusetts Institute of Technology,
" Bell Laboratories, General Electric, Honeywell Information Systems Inc., Honeywell Bull Inc., Groupe Bull
" and Bull HN Information Systems Inc. to the development of this operating system. 
" Multics development was initiated by Massachusetts Institute of Technology Project MAC (1963-1970),
" renamed the MIT Laboratory for Computer Science and Artificial Intelligence in the mid 1970s, under the leadership
" of Professor Fernando Jose Corbato. Users consider that Multics provided the best software architecture for
" managing computer hardware properly and for executing programs. Many subsequent operating systems
" incorporated Multics principles.
" Multics was distributed in 1975 to 2000 by Group Bull in Europe , and in the U.S. by Bull HN Information Systems Inc., 
" as successor in interest by change in name only to Honeywell Bull Inc. and Honeywell Information Systems Inc. .
"
"                                          -----------------------------------------------------------
"
" Permission to use, copy, modify, and distribute these programs and their documentation for any purpose and without
" fee is hereby granted,provided that the below copyright notice and historical background appear in all copies
" and that both the copyright notice and historical background and this permission notice appear in supporting
" documentation, and that the names of MIT, HIS, Bull or Bull HN not be used in advertising or publicity pertaining
" to distribution of the programs without specific prior written permission.
"    Copyright 1972 by Massachusetts Institute of Technology and Honeywell Information Systems Inc.
"    Copyright 2006 by Bull HN Information Systems Inc.
"    Copyright 2006 by Bull SAS
"    All Rights Reserved
"
"