Google
 

Trailing-Edge - PDP-10 Archives - decuslib10-08 - 43,50512/saver.mac
There are no other files named saver.mac in the archive.
TITLE	SAVER -- Write an .EXE file on TOPS-10

;This code will work with non-contiguous core.

SEARCH	UUOSYM,MACTEN

IFNDEF FTKI10,<FTKI10==-1>	;Assume we must run on old klunkers


T1==1
T2==2
T3==3
T4==4
T5==5
NEWD1==6
D2==7
D1==10
IOW==11
IOW2==12
FPAGE==13
DIR==14
FREPAG==15
PC==16
P==17

SS%CPY==400000
SS%UCA==200000
SS%RD==100000
SS%WR==40000
SS%EXE==20000

DEFINE HISEGB,<-1(DIR)>		;This is where the HISEG bits live


SSAVE::	;routine to create a sharable .EXE file from what's in core
	TLO	T3,200000	;Set the 'Sharable' bit

SAVE::	;routine to create a nonsharable .EXE file from what's in core

	;T1 & T3 should be 0. File should be open on ch 0
	;     1 table entry or address of table in T2
	;Table entries are of the following format:
	;
	;	b0-b17	b18	b19	b20	b21	b22	b27-b35
	; neg #of pages CW &w/current	R	W	E	start page #
	; Table ends on 0 word

	TLO	T3,400000	;Set the 'Hiseg' bit

	PUSH	P,FREPAG
	PUSH	P,PC
	PUSH	P,DIR
	PUSH	P,T4
	PUSH	P,T5
	PUSH	P,IOW
	PUSH	P,IOW2
	PUSH	P,FPAGE
	PUSH	P,NEWD1
	PUSH	P,D2
	PUSH	P,D1
	PUSH	P,T3

	PUSH	P,[1776,,0]	;Header block
	MOVEI	DIR,(P)

	SETZB	D1,D2		;Initialization
	SETZB	IOW,IOW2	;
	SETZB	NEWD1,FREPAG	;
	USETO	0,5		;Start at page 1 of the file
	MOVEI	FPAGE,1		;...

	TLNE	T2,777777	;1 entry, or pointer to lots
	 JRST	[MOVE T1,T2	;Just 1 use it as an entry
		 JSP PC,SAVER1	;do that & return
		 JRST SAVERZ]	;no, close up & return
SAVER0:	SKIPN	T1,(T2)		;Any more entries in table?
	 JRST	SAVERZ		;no, close up & return
	JSP	PC,SAVER1	;Do this part
	AOJA	T2,SAVER0	;And go back for more

SAVER1:	MOVE	T5,T1		;Isolate page #
	TRZ	T5,760000	;Get rid of bits here
SAVER2:	MOVEI	T3,(T5)		;Set up arg for PAGE.
	HRLI	T3,.PAGCA	;First we must check
	PAGE.	T3,		; the access of this page
	 HALT			;Aged & infirm monitor?
	JUMPE	FREPAG,SAVER3	;Did we create a page?
	CAIN	FREPAG,(T5)	;Is this a page we created?
	 JRST	@.+1		;yes, treat it like a nonexistant page
SAVER3:	JUMPL	T3,[SETZ NEWD1,	;This page does not exist
		    JRST SAVER5] ;Clear new directory entry & go

;Start of some code to implement the access bits
;this won't be very useful until TOPS-10 can handle
;.EXE files with other than either private or hiseg pages.

	HRRZS	NEWD1		;Clear bits in left half
	TXNN	T1,SS%UCA	;Limit to current access?
	 JRST	SAVER4		;no
	TXNN	T3,PA.GWR	;Is the process page writable?
	 JRST	.+3		;no, so file page shouldn't be either

SAVER4:	TXNE	T1,SS%CPY!SS%WR	;Should we allow writing?
	 TLOA	NEWD1,100000	;Say it's writable
	 TDO	NEWD1,HISEGB	;Turn on 'Hiseg' and possibly 'sharable' flag
	;note that pages are always readable & executable
	TXNE	T3,PA.GAZ	;Is it zero
	 TRZ	NEWD1,777777	;Yes, remember that

	CAMN	NEWD1,D1		;Same as last time?
	 JRST	[ADD D2,[1000,,0] ;Bump the repeat count
		 JRST SAVER7]	;Go write it, maybe

	;Page does exist, so we should save it

	TXNN	T3,PA.GAZ	;Allocated but 0
	 HRRI	NEWD1,(FPAGE)	;Start at current file page

SAVER5:	;Here to save the current directory entry (if any) on the stack

	JUMPE	D1,.+3		;Don't write nothing there
	 PUSH	P,D1		;Save the previous directory entry
	 PUSH	P,D2		; ...
	MOVEM	NEWD1,D1	;This one is now current
	MOVEI	D2,(T5)		;Starting with this process page
	PUSHJ	P,WRITE		;do it

SAVER7:	;Here to Add a page to the I/O list (if not alloc-but-zero)
	;and to output some pages if the block has gotten big enough

	TRNN	NEWD1,-1	;non-ex,zero or our own page?
	 JRST	SAVER9		;yes, don't write anything
	TRNE	T5,37777	;Is this page 0?
	TXNE	T3,PA.GHI	;or a Hiseg page?
	 AOJA	FPAGE,CPYPAG		;yes, must copy it first
	JUMPN	IOW,SAVER8	;I/O Word is already set up

	;Here to build a new IOWD (or a 0 if zero page)

	MOVEI	IOW,(T5)	;use current process page
	LSH	IOW,9		;Convert to word addr
	SOJ	IOW,		;addr-1
SAVER8:	SUB	IOW,[1000,,0]	;Set up to write out another page
	CAML	IOW,[-10000,,0]	;Is it time to write something?
	 AOJA	FPAGE,SAVER9	;Not yet
	AOJ	FPAGE,		;Remember to bump page counter
	PUSHJ	P,WRITE		;Yes, do it
	MOVEI	IOW,1(5)	;Build new I/O word
	LSH	IOW,9		;Convert to word addr
	SOJ	IOW,		;
SAVER9:	AOBJN	T5,SAVER2	;Try next page
	PUSHJ	P,WRITE		;Write anything that's left
	JRST	(PC)		;and return

SAVERZ:	;Everything from (DIR) to (P) is the .EXE file directory
	JUMPE	D1,.+3		;Don't write null entry
	 PUSH	P,D1		;Generate the last directory entry
	 PUSH	P,D2		;
	PUSH	P,[1777,,1]	;And the closing block
	MOVEI	T1,-1(DIR)	;Build I/O word
	SUBI	T1,(P)		;
	MOVNI	T2,1(T1)	;Stuff length of main part of directory
	HRRM	T2,(DIR)	;into the start of it
	MOVSI	IOW,(T1)	;
	HRRI	IOW,-1(DIR)	;
	USETO	0,1		;Aim at first block of file
	PUSHJ	P,WRITE
IFE FTKI10,<
	ADJSP	P,(T1)		;Clean off the stack
>
IFN FTKI10,<
	HRLI	T1,(T1)		;Will subtract from both halves
	ADD	P,T1		;Adjust stack pointer
>
;; Luser must do this himself if not update mode.
;; If it is update mode, do this only if want to kill old hiseg
;;;;;	RELEAS	0,		;Close & release channel
	JUMPE	FREPAG,SAVEZZ	;Did we create a page of our own
	HRLI	FREPAG,400000	;Yes, we ought to get rid of it
	MOVEI	DIR,1		;Build argument block
	MOVE	T3,[.PAGCD,,DIR];Fun,,addr
	PAGE.	T3,		;destroy!!!
	 JFCL			;oh well, we tried,
SAVEZZ:
	POP	P,T3
	POP	P,D1
	POP	P,D2
	POP	P,NEWD1
	POP	P,FPAGE
	POP	P,IOW2
	POP	P,IOW
	POP	P,T5
	POP	P,T4
	POP	P,DIR
	POP	P,PC
	POP	P,FREPAG

CPOPJ:	POPJ	P,		;and return

CPYPAG:	PUSHJ	P,WRITE		;Write out anything that's waiting
	JUMPN	FREPAG,CPYPA2	;Already got a free page
	MOVE	IOW,.JBREL	;Try to alloc the page above .JBREL
	MOVEM	IOW,FREPAG	;Save addr of free page
	LSH	FREPAG,-9	;as a page addr
	AOJ	FREPAG,		;to the page after .JBREL
	ADDI	IOW,1000	;
	CORE	IOW,		;
	 HALT			;fix this someday
CPYPA2:	MOVSI	IOW,(T5)	;Construct addr of start of source page
	HRRI	IOW,(FREPAG)	;dest page #
	LSH	IOW,9		;word addresses for BLT
	MOVEI	IOW2,777(IOW)	;get end of page
	BLT	IOW,(IOW2)	;copy the page
	SETZ	IOW2,		;Zero this again for the iolist
	HRRI	IOW,(FREPAG)	;Get the page back again
	LSH	IOW,9		;word addr
	SOJ	IOW,		;-1
	HRLI	IOW,-1000	;
	PUSHJ	P,WRITE		;Write it out
	JRST	SAVER9		;Back for more
IOERROR:
	OUTSTR	[Asciz "?
?I/O error while writing .EXE file.
"]
	MONRT.
	JRST	.-1

WRITE:	TLNE	IOW,777777	;Nothing waiting to go out
	 OUT	0,IOW		;There was something, we just wrote it
	  TDZA	IOW,IOW		;Clear the I/O word
	 JRST	IOERROR		;OUCH!!
	POPJ	P,

END