MSIZE	EQU	48			;SYSTEM SIZE IN KILOBYTES
BIOSSZ	EQU	512			; BIOS SIZE IN BYTES
;
;
;	PINIT FIRST READS IN AND SCANS THE DIRECTORY FOR THE 8080/
;	Z80 INTERPRETER (SYSTEM.MICRO).  THEN THE INTERPRETER IS
;	LOADED INTO MEMORY, THE BIOS PAGE POINTER SET, AND EXECUTION
;	IS STARTED AT THE SYSTEM.PASCAL BOOT VECTOR.
;
;	THIS PROGRAM PROVIDED COURTESY OF NORTHWEST MICROCOMPUTER SYSTEMS, INC.
;
;MODIFIED
;   10/11/78 BY WINK SAVILLE OF SVA TO READ ANY SIZE INTERPETER
;
;
BOOT		EQU	0H		;LOCATION OF CP/M BOOT VECTOR
BIOS$PAGE	EQU	2H		;BIOS PAGE POINTER LOCATION
BIOS	EQU	MSIZE*1024-BIOSSZ	; LOCATION OF BIOS VECTOR TABLE
IBASE	EQU	BIOS-1024		; LOCATION OF THIS INIT ROUTINE
INTERP$BASE	EQU	100H		;FIRST LOC USED BY THE INTERPRETER
PBEGIN		EQU	INTERP$BASE+100H;ENTRY TO THE PASCAL BOOTER
FIRSTSP	EQU	INTERP$BASE+103H
DENTSZ		EQU	1AH		;DIR ENTRY SIZE IN BYTES
DTITLE		EQU	06H		;OFFSET TO ENTRY TITLE
DIRTOP		EQU	IBASE-1000H	;TOP OF TEMP RAM DISK DIRECTORY
HOME		EQU	BIOS+18H	;DISK HOME TO TRACK 00
SELDSK		EQU	BIOS+1BH	;DISK SELECT
SETTRK		EQU	BIOS+1EH	;SET TRACK
SETSEC		EQU	BIOS+21H	;SET SECTOR
SETDMA		EQU	BIOS+24H	;SET DATA TRANSFER AREA
READ		EQU	BIOS+27H	;READ SECTOR TO DATA AREA
;
;
;
	ORG	IBASE
;
;
	LXI	SP,100H
MAIN:				;LET'S BOOT SYSTEM.MICRO
	CALL	INIT$IO		;RESET I/O SYSTEM
;
	LXI	B,DIRTOP	;READ THE DIRECTORY INTO DIRTOP
	CALL	READ$DIR
;
	LXI	H,DIRTOP	;SET THE DIRECTORY ENTRY POINTER
	LXI	D,DENTSZ	;  TO FIRST ENTRY AFTER THE VOLUME NAME
	DAD	D
	SHLD	DENTP
;
	CALL	FIND$INTERP	;THEN FIND THE INTERPRETER
	CALL	READ$INTERP	;  AND READ IT IN
;
	MVI	A,JMP		;SET VECTOR TO BIOS ENTRY FOR THE PASCAL
	STA	BOOT		;  SYSTEM 'H(ALT' COMMAND
	LXI	H,BIOS+03H	;NOTE: LOC 2 MUST HAVE CURRENT BIOS PAGE
	SHLD	BOOT+1		;      FOR PROPER SYSTEM OPERATION
	MVI	L,0
	SHLD	FIRSTSP
;
	JMP	PBEGIN		;START BOOTING SYSTEM.PASCAL
;
;
;
INIT$IO:			;INITIALIZE SYSTEM
	MVI	C,1
	CALL	SELDSK
	CALL	HOME
	MVI	C,0
	CALL	SELDSK
	CALL	HOME
	RET			;THAT'S IT
;
;
READ$DIR:			;READ DIRECTORY'S 4 BLOCKS TO BUFFER
				;BUFFER ADDRESS IS ALREADY IN BC-REG
	MVI	E,4		;DIR IS 4 BLOCKS LONG
	LXI	H,2		;AND STARTS AT BLOCK #2
	CALL	SYSRD		;GO GET IT
	RET
;
;
FIND$INTERP:			;FIND 'SYSTEM.MICRO'
	MVI	C,77		;STOP AFTER THE 77'TH ENTRY
	LHLD	DENTP		;GET STARTING ENTRY
FI$SCH$LP:
	LXI	D,DTITLE	;ADVANCE TO TITLE STRING
	DAD	D
	LXI	D,SYSTLE	;SET DE-REG TO COMPARISON STRING
	MVI	B,LENGTH+1	;COMPARISON LENGTH
FI$CMP$LP:			;START COMPARING
	LDAX	D
	CMP	M
	JNZ	FI$CONT		;IT'S NOT THIS ONE
	INX	D		;HEY, WE'VE STILL GOT A CHANCE
	INX	H
	DCR	B		;IS THIS THE END OF THE STRING
	JNZ	FI$CMP$LP
	JMP	FI$FOUND	;I THINK WE FOUND IT
FI$CONT:
	LHLD	DENTP		;ON TO THE NEXT ENTRY
	LXI	D,DENTSZ
	DAD	D
	SHLD	DENTP
	DCR	C		;WAIT, IS THERE ANY DIR LEFT?
	JNZ	FI$SCH$LP
FI$HANG:			;INTERPRETER NOT THERE, GO DUMB
	JMP	FI$HANG		;ADD CODE TO SEND A MESSAGE TO CONOUT

FI$FOUND:			;WE'VE GOT IT
	RET
;
LENGTH	EQU	12		;TITLE LENGTH
SYSTLE	DB	LENGTH,'SYSTEM.MICRO'
;
;
READ$INTERP:			;PUT INTERP IN ITS PLACE
	LHLD	DENTP		;GET STARTING BLOCK
	MOV	E,M		;  INTO HL-REG
	INX	H
	MOV	D,M
;
;  COMPUTE LENGTH OF INTERPETER
	PUSH	D	;SAVE FIRST BLOCK ON STACK
			;TAKE 2'S COMPLIMENT OF FIRST BLOCK
	MOV	A,E
	CMA
	MOV	E,A
	MOV	A,D
	CMA
	MOV	D,A
	INX	D	;DE=2'S COMP OF FIRST BLOCK

	PUSH	D	;SAVE ON THE STACK

;GET NEXT AVAIL BLOCK
	INX	H
	MOV	E,M
	INX	H
	MOV	D,M
	XCHG
;
	POP	D	;HL=NXT BLOCK,DE=-(FIRST BLOCK)
			;SO HL+DE=LENGTH OF SYSTEM.MICRO
	DAD	D	;HL=LENGTH
	XCHG		;DE=LENGTH
	POP	H	;HL=FIRST BLOCK , DE=LENGTH
	LXI	B,INTERP$BASE	;AND SET IT LOAD POINT
	CALL	SYSRD		;THEN READ IT
	RET
;
;
;
SYSRD:				;READ BLOCKS FROM PASCAL DISKETTE
	PUSH	D		;SAVE BLOCK COUNT
	PUSH	H		;AND BLOCK NUMBER
	CALL	READ$RX		;BUFFER IS ADVANCED BY 512 BYTES
	POP	H
	POP	D
	INX	H		;ADVANCE TO NEXT BLOCK
	DCR	E		;BUT, BEFORE WE GO ON
	JNZ	SYSRD		;  SEE IF WE'RE DONE
	RET
;
;
READ$RX:			;READ A PASCAL BLOCK
	DAD	H		;THERE ARE 4 IBM SECTORS TO A PASCAL BLOCK
	DAD	H		;  SO MULT LOGICAL BLOCK BY 4 TO GET 1ST SEC
	MVI	E,4
RR$LP:				;THIS GETS CONFUSING
	PUSH	B		;SET BUFFER ADDRESS
	PUSH	D
	PUSH	H
	CALL	SETDMA
	POP	H		;NOW COMPUTE PHYSICAL TRACK-SECTOR
	PUSH	H
	CALL	MAP		;MAP CONVERTS LOGICAL SECTOR IN HL-REG
	MOV	C,H		;  INTO PHYSICAL TRACK, H-REG, SECTOR, L-REG
	PUSH	H
	CALL	SETTRK
	POP	H
	MOV	C,L
	CALL	SETSEC
	CALL	READ		;AND READ THE DATA
	POP	H
	POP	D
	POP	B
	PUSH	H		;ADVANCE THE BUFFER ADDRESS
	LXI	H,128
	DAD	B
	MOV	B,H
	MOV	C,L
	POP	H
	INX	H		;ADVANCE BLOCK COUNT
	DCR	E		;THEN SEE IF WE CONTINUE
	JNZ	RR$LP
	RET			;LEAVE, WHEN DONE
;
;
DENTP	DS	2
;
;
MAP:			;TURN LSN INTO IBM TRACK-SECTOR
;
;	NOTE:	TRACK 00 IS NOT USED SO BLOCK 0
;		IS AT TRACK 01 SECTOR 1
;
;	ON ENTRY:	HL-REG HAS LOGICAL SECTOR NO.
;	ON EXIT:	H-REG HAS PHYSICAL TRACK
;			L-REG HAS PHYSICAL SECTOR
;
;
	PUSH	B
	PUSH	D
;
	CALL	DIV26
	MOV	A,L
	ADD	A
	MOV	B,A
	MVI	A,12
	CMP	L
	JNC	MAPC
	INR	B
MAPC:
	MOV	C,E
	XRA	A
	MOV	D,A
	MOV	H,A
	MOV	L,B
	MVI	A,6
MAP$LOOP:
	DAD	D
	DCR	A
	JNZ	MAP$LOOP
	PUSH	B
	CALL	DIV26
	POP	B
	INR	L
	MOV	H,C
	INR	H
	POP	D
	POP	B
	RET
;
;
DIV26:
	LXI	B,-26
	MVI	E,0FFH
DIVL:
	INR	E
	DAD	B
	MOV	A,H
	ORA	A
	JP	DIVL
	LXI	B,26
	DAD	B
	RET
;
;
	END	IBASE
