AUSAM/source/mdec/rk60boot.s

Compare this file to the similar file:
Show the results in this format:

/ Optimised RK11 file system bootstrap
/
/ Knows about ...
/		 Indirect blocks,
/		 Optimised RK11 mapping,
/		 Boots any pathname,
/		 Recovers better from errors,
/		 Files up to 60Kw can be loaded !!
/

/ some useful defines

blkoff	=	2435.			/ block offset for start of optimised file system
maxblk	=	4872.			/ maximum blocks on drive
retrycnt =	10.			/ retrys to be attempted after read errors
core	=	60. * 32.		/ location of loader in physical memory
					/ ie twixt 60Kw & 64Kw
					/ ie the top 4k of a 32k segment so that
					/ virtual address == real address (16bits)
loadloc =	begin - end		/ put loader at top of virtual address space
stcklo	=	loadloc - 100		/ allow 100 bytes for loader stack
ibno	=	stcklo - 2		/ indirect block number
ibuf	=	ibno - 512.		/ indirect block
inod	=	ibuf - 512.		/ inode ( need this much for algorithm used)
addr	=	inod + 8.		/ address begin here
mode	=	inod + 0.		/ flag field
buf	=	inod - 512.		/ block
bno	=	buf - 2.		/ block number
names	=	bno - [20.*14.]		/ 20 file names in path name

LRG	=	10000			/ inode flag for large file algorithm
SWR	=	37570			/ switch register address
reset	=	5			/ reset instruction
	.globl	dskb			/ block offset for patching porpoise

start:
	reset				/ initialize the system

/ enable memory management

	clr	*$172340		/ KIA0 to address physical 0
	mov	$177600,*$172342	/ KIA1 to address i/o page
	mov	$core,*$172356		/ KIA7 to address loader
	mov	$77406,r4		/ r/w 8Kb
	mov	r4,*$172300		/ KID0 r/w 8Kb
	mov	r4,*$172302		/ KID1 r/w 8Kb
	mov	r4,*$172316		/ KID7 r/w 8Kb
	inc	*$177572		/ enable memory management (MMR0 <- 1)
					/ 18 bit mode - no I&D space


/ relocate loader to high core

	mov	$loadloc,sp		/ sp,r1 now address final
	mov	sp,r1			/ resting place of code
	mov	$begin,r0		/ get loading @ 'begin'
1:	mov	(r0)+,(r1)+		/ copy
	tst	r1			/ what is
	bne	1b			/ necessary
	jmp	(sp)			/ begin execution of relocated code

/ clear core from names thru loadloc

begin:
	mov	pc,sp			/ reset stack pointer
	tst	-(sp)			/ get below first instruction
	mov	sp,r2			/ first location to clear
2:
	clr	-(r2)			/ clear
	cmp	$names,r2		/ desired
	bne	2b			/ locations
	inc	-(sp)			/ always start search with inode 1 == "/"

/ set up default file name

	tst	*$SWR			/ are defaults to be used ??
	beq	ask			/ --> no.
	mov	$"un,(r2)+		/ default: boot /unix
	mov	$"ix,(r2)
	br	decode

/ prompt for filename to be used
/ read in path name
/ breaking on '/' into 14 ch names

ask:
	mov	$'?,r0
	jsr	pc,putc
1:
	mov	r2,r1
2:
	jsr	pc,getc
	cmp	r0,$'\n
	beq	decode
	cmp	r0,$'/
	beq	3f
	movb	r0,(r1)+
	br	2b
3:
	cmp	r2,r1
	beq	2b			/ ignore null names
	add	$14.,r2
	br	1b

decode:

/ initialize controller i/o

	mov	$rkread32,r4		/ read into 32Kw -> 64Kw

/ start of path name decoding
/ start with first name  and root ino

	mov	$names,r2
	cmp	r2,r1
	beq	begin			/ no name !

/ get next inode    (sp) is inode number

1:
	mov	$inod,r5		/ address of inode area
	clr	*$bno			/ start at block 0
	mov	(sp),r0			/ pick up desired inode number
	add	$31.,r0			/ step over blocks 0 & 1
	mov	r0,r3
	bic	$!17,r3			/ clear all but displacement
	ash	$5.,r3			/ r3 is displacement in block
	sub	r3,r5			/ put inode where desired
	ash	$-4.,r0			/ r0 block number of inode
	jsr	pc,rblk			/ get the block containing inode
	tst	(r2)			/ last inode ??
	beq	load			/ --> yes.

/ read next directory looking for next name

	mov	$buf,r5			/ input block to here
2:
	jsr	pc,rmblk
	beq	begin			/ --> end of file ??
	mov	r5,r1			/ first directory entry
3:
	mov	r2,r3			/ address of name to be looked for
	mov	r1,r0			/ r0 become current dir-entry ptr
	add	$16.,r1			/ r1 become next dir-entry
	mov	(r0)+,(sp)		/ pick up next inode number
	beq	5f			/ --> dir entry not allocated
4:
	cmpb	(r3)+,(r0)+		/ same file name ?
	bne	5f			/ --> no
	cmp	r0,r1
	blo	4b
	add	$14.,r2			/ step to next in pathname
	br	1b			/ go next file associated this inode
5:
	cmp	r1,$buf+512.
	blo	3b
	br	2b

/ last entry was found
/ read into 0.

load:
	clr	r5			/ set up buffer address
	mov	$rkread,r4		/ read into 0Kw -> 32Kw
	jsr	pc,rmblk		/ read first block
	beq	begin			/ --> zero length file ??
	cmp	(r5),$407
	bne	4f			/ --> not suitable a.out.
2:
	mov	20(r5),(r5)+		/ shuffle first block
	cmp	r5,$760
	blo	2b
3:
	jsr	pc,rmblk		/ read successive blocks
	beq	callout			/ --> go enter prog just loaded
4:
	add	$1000,r5		/ step buffer pointer
	bne	3b			/ --> no wrap to next 32k
	add	$rkxmem,r4		/ fixup A17,A16
	br	3b

/ routine to read in block number specified by bno
/ after applying file system mapping algorithm in inode.
/ bno is incremented.
/ success is Z-bit clear
/ failure is Z-bit set

rmblk:
	mov	*$bno,r0
	inc	*$bno
	bit	$LRG,*$mode		/ large file ?
	bne	1f			/ --> yes
	asl	r0
	mov	addr(r0),r0
	bne	rblk
2:
	rts	pc			/ nothing read

/ large algorithm
1:
	clr	-(sp)
	movb	r0,(sp)
	clrb	r0
	swab	r0
	asl	r0
	mov	addr(r0),r0
	beq	2b
	cmp	r0,*$ibno		/ same indirect block ??
	beq	9f			/ --> yes
	mov	r5,-(sp)
	mov	r4,-(sp)
	mov	$rkread32,r4		/ read into 32Kw -> 64Kw
	mov	$ibuf,r5		/ get indirect block this buffer
	mov	r0,*$ibno
	jsr	pc,rblk
	mov	(sp)+,r4
	mov	(sp)+,r5
9:
	mov	(sp)+,r0
	asl	r0
	mov	ibuf(r0),r0
	beq	2b


/ Optimised RK11 Disk Driver

rblk:

rkread	 =	5			/ read command
rkxmem	 =	20			/ 1st xmem bit for controller
rkread32 =	rkxmem+rkread		/ read into 32 -> 64K
rkda	 =	37412			/ controller bus address register
rkcreset =	1			/ controller reset command
rkdreset =	15			/ drive reset command
rkds	 =	37400			/ controller drive status register
rkrws	 =	100			/ read/write/seek ready bit in rkds

	mov	r0,-(sp)		/ save disk address for retry
	mov	$retrycnt+1,r3		/ retrys after errors
0:
	mov	(sp),r1			/ load disk address
dskb = .+2
	add	$blkoff,r1		/ map block onto optimised disk
	cmp	r1,$maxblk
	blt	1f
	sub	$maxblk-1,r1
1:
	clr	r0
	div	$12.,r0			/ r0 = track, r1 = sector
	ash	$4,r0
	bis	r1,r0
	mov	$rkda,r1
	mov	r0,(r1)
	mov	r5,-(r1)		/ buffer address
	mov	$-256.,-(r1)
	mov	r4,-(r1)		/ read
1:
	tstb	(r1)			/ io complete ??
	bpl	1b			/ --> no
	tst	(r1)			/ error ?
	bmi	1f			/ --> yes
	mov	(sp)+,r0		/ disk address always non-zero - clear Z
	rts	pc

1:
	mov	$rkcreset,(r1)		/ clear controller
1:
	tstb	(r1)
	bpl	1b
	mov	$rkdreset,(r1)		/ reset drive
	mov	$'e,r0
	jsr	pc,putc			/ type 'e'
1:
	bit	$rkrws,*$rkds
	beq	1b	 		/ wait for drive to reset
	sob	r3,0b			/ retry
	jmp	begin			/ too many errors - give up

/ read and echo character from tty.
/ perform normal cr/lf mapping.
tks = 37560
tkb = 37562
getc:
	tstb	*$tks
	bpl	getc
	mov	*$tkb,r0
	bic	$!177,r0
	cmp	r0,$'\r
	bne	putc
	jsr	pc,putc
	mov	$'\n,r0

/ put a character on the tty.
/ also performs delay.
tps = 37564
tpb = 37566
putc:
	tstb	*$tps
	bpl	putc
	mov	r0,*$tpb
	rts	pc


/ transfer control to prog just loaded
/ callout == 177776 in virtual address space so that
/ when mem managment disabled by the reset below the pc
/ will equal zero and hence commence executing from
/ physical location zero - the prog just loaded !!

callout:
	reset				/ disable memory management
					/ and commence exec at physical
					/ location 0

end:					/ end of useable code