

                ;  THIS 'PASCAL' MODIFIED BY SORRENTO VALLEY ASSOCIATES 6/15/81
                ;     TO AUTOMATICALLY READ IN THE INTERPRETER FROM THE HARD DISK
                ;     SET UP AS UCSD PASCAL SYSTEM VOLUME 9 
                ;
                ;	'PASCAL' FIRST READS IN AND SCANS THE DIRECTORY FOR THE 8080/
                ;	Z80 INTERPRETER (SYSTEM.MICRO).  THEN THE INTERPRETER IS
                ;	LOADED INTO MEMORY AND STARTED AT THE SYSTEM.PASCAL BOOT VECTOR.
                ;
                ;	THIS PROGRAM PROVIDED COURTESY OF NORTHWEST MICROCOMPUTER SYSTEMS, INC.
                ;
                ;
                ;MODIFIED
                ;   10/11/78 BY WINK SAVILLE TO READ IN ANY SIZE INTERPETER
                ;
 0000 =         BOOT		EQU	0H		;LOCATION OF CP/M BOOT VECTOR
 0005 =         BDOS		EQU	5H		;CP/M ENTRY VECTOR
 0100 =         TPA		EQU	100H		;START OF USER AREA
                ;
 0001 =         RDCON		EQU	1
 0009 =         WRBUF		EQU	9
                ;
 0020 =         NBLOCKS		EQU	32		;MAXIMUM # OF BLOCKS FOR THE
                					;INTERPETER. USED TO COMPUTE START
 4100 =         START		EQU	TPA+NBLOCKS*512	;LOCATION OF THIS PROGRAM
 0100 =         INTERP$BASE	EQU	TPA		;FIRST LOC USED BY THE INTERPRETER
 0200 =         PBEGIN		EQU	INTERP$BASE+100H;ENTRY TO THE PASCAL BOOTER
 0203 =         FIRSTSP		EQU	INTERP$BASE+103H;PASCAL INITIAL STACK POINTER
 001A =         DENTSZ		EQU	1AH		;DIR ENTRY SIZE IN BYTES
 0006 =         DTITLE		EQU	06H		;OFFSET TO ENTRY TITLE
 0200 =         DIRTOP		EQU	PBEGIN		;TOP OF TEMP RAM DISK DIRECTORY
                ;
 000D =         CR	EQU	0DH
 000A =         LF	EQU	0AH
 0024 =         EOM	EQU	'$'
                ;
                ;
                ;
 0100           	ORG	TPA
                ;
                ;
 0100 C30041    	JMP	START
                ;
                ;
                ;
 4100           	ORG	START
                ;
                ;
 4100 310001    	LXI	SP,100H
                MAIN:				;LET'S BOOT SYSTEM.MICRO
 4103 CD2E41    	CALL	INIT$IO		;RESET I/O SYSTEM
                ;
                ;	CALL	REQUEST$DISK	;GET PASCAL DISK ON DRIVE E
 4106 0600      	MVI	B,0
 4108 0E04      	MVI	C,4		;  THEN SELECT THE DRIVE
 410A CDF942    	CALL	SELDSK
                ;
 410D 010002    	LXI	B,DIRTOP	;READ THE DIRECTORY INTO DIRTOP
 4110 CD7341    	CALL	READ$DIR
                ;
 4113 210002    	LXI	H,DIRTOP	;SET THE DIRECTORY ENTRY POINTER
 4116 111A00    	LXI	D,DENTSZ	;  TO FIRST ENTRY AFTER THE VOLUME NAME
 4119 19        	DAD	D
 411A 22F142    	SHLD	DENTP
                ;
 411D CD7C41    	CALL	FIND$INTERP	;THEN FIND THE INTERPRETER
                ;	CALL	SAY$LOADING	;GOT IT SAY WHAT WE'RE UP TO
 4120 CD0D42    	CALL	READ$INTERP	;  AND READ IT IN
                ;
 4123 2A0100    	LHLD	BOOT+1		;NOTE: LOC 2 MUST HAVE CURRENT BIOS PAGE
 4126 2E00      	MVI	L,0		;      FOR PROPER SYSTEM OPERATION
 4128 220302    	SHLD	FIRSTSP
                ;
 412B C30002    	JMP	PBEGIN		;START BOOTING SYSTEM.PASCAL
                ;
                ;
                ;
                INIT$IO:			;INITIALIZE SYSTEM
 412E C9        	RET			;THAT'S IT
                ;
                ;
                REQUEST$DISK:			;ASK FOR PASCAL
 412F 0E09      	MVI	C,WRBUF
 4131 114241    	LXI	D,DSKMSG
 4134 CD0500    	CALL	BDOS
                RD$LOOP:			;THEN WAIT FOR A CR
 4137 0E01      	MVI	C,RDCON
 4139 CD0500    	CALL	BDOS
 413C FE0D      	CPI	CR
 413E C23741    	JNZ	RD$LOOP
 4141 C9        	RET
                ;
 4142 0D0A494E53DSKMSG:	DB	CR,LF,'INSERT PASAL DISK IN DRIVE A, THEN TYPE RETURN',EOM
                ;
                ;
                READ$DIR:			;READ DIRECTORY'S 4 BLOCKS TO BUFFER
                				;BUFFER ADDRESS IS ALREADY IN BC-REG
 4173 1E04      	MVI	E,4		;DIR IS 4 BLOCKS LONG
 4175 210200    	LXI	H,2		;AND STARTS AT BLOCK #2
 4178 CDB342    	CALL	SYSRD		;GO GET IT
 417B C9        	RET
                ;
                ;
                FIND$INTERP:			;FIND 'SYSTEM.MICRO'
 417C 0E4D      	MVI	C,77		;STOP AFTER THE 77'TH ENTRY
 417E 2AF142    	LHLD	DENTP		;GET STARTING ENTRY
                FI$SCH$LP:
 4181 110600    	LXI	D,DTITLE	;ADVANCE TO TITLE STRING
 4184 19        	DAD	D
 4185 11EA41    	LXI	D,SYSTLE	;SET DE-REG TO COMPARISON STRING
 4188 060D      	MVI	B,LENGTH+1	;COMPARISON LENGTH
                FI$CMP$LP:			;START COMPARING
 418A 1A        	LDAX	D
 418B BE        	CMP	M
 418C C29841    	JNZ	FI$CONT		;IT'S NOT THIS ONE
 418F 13        	INX	D		;HEY, WE'VE STILL GOT A CHANCE
 4190 23        	INX	H
 4191 05        	DCR	B		;IS THIS THE END OF THE STRING
 4192 C28A41    	JNZ	FI$CMP$LP
 4195 C3BE41    	JMP	FI$FOUND	;I THINK WE FOUND IT
                FI$CONT:
 4198 2AF142    	LHLD	DENTP		;ON TO THE NEXT ENTRY
 419B 111A00    	LXI	D,DENTSZ
 419E 19        	DAD	D
 419F 22F142    	SHLD	DENTP
 41A2 0D        	DCR	C		;WAIT, IS THERE ANY DIR LEFT?
 41A3 C28141    	JNZ	FI$SCH$LP
                ;
 41A6 0E09      	MVI	C,WRBUF		;NO INTERP THERE
 41A8 11BF41    	LXI	D,NOTFNDMSG
 41AB CD0500    	CALL	BDOS
                ;
                ;
                REBOOT:
 41AE 0E09      	MVI	C,WRBUF		;TRY TO REBOOT CP/M
 41B0 11D941    	LXI	D,REBOOTMSG
 41B3 CD0500    	CALL	BDOS
 41B6 0E01      	MVI	C,RDCON
 41B8 CD0500    	CALL	BDOS		;WAIT FOR ANY CHAR
 41BB C30000    	JMP	BOOT
                ;
                FI$FOUND:			;WE'VE GOT IT
 41BE C9        	RET
                ;
 41BF 0D0A494E54NOTFNDMSG:	DB	CR,LF,'INTERPRETER NOT FOUND',CR,LF,EOM
 41D9 0D0A524542REBOOTMSG:	DB	CR,LF,'REBOOTING CP/M',EOM
                ;
 000C =         LENGTH	EQU	12		;TITLE LENGTH
 41EA 0C53595354SYSTLE	DB	LENGTH,'SYSTEM.MICRO'
                ;
                ;
                SAY$LOADING:			;WE'RE GOING TO LOAD THE INTERPRETER
 41F7 0E09      	MVI	C,WRBUF
 41F9 110042    	LXI	D,LOADINGMSG
 41FC CD0500    	CALL	BDOS
 41FF C9        	RET
                ;
 4200 0D0A4C4F41LOADINGMSG:	DB	CR,LF,'LOADING...',EOM
                ;
                ;
                READ$INTERP:			;PUT INTERP IN ITS PLACE
 420D 2AF142    	LHLD	DENTP		;GET STARTING BLOCK
 4210 5E        	MOV	E,M		;  INTO HL-REG
 4211 23        	INX	H
 4212 56        	MOV	D,M
                ;
                ;COMPUTE THE LENGTH OF THE INTERPETER
 4213 D5        	PUSH	D	;SAVE FIRST BLOCK ON STACK
                			;TAKE 2'S COMPLIMENT OF FIRST BLOCK
 4214 7B        	MOV	A,E
 4215 2F        	CMA
 4216 5F        	MOV	E,A
 4217 7A        	MOV	A,D
 4218 2F        	CMA
 4219 57        	MOV	D,A
 421A 13        	INX	D	;DE=2'S COMP OF FIRST BLOCK
                
 421B D5        	PUSH	D	;SAVE ON THE STACK
                
                ;GET NEXT AVAIL BLOCK
 421C 23        	INX	H
 421D 5E        	MOV	E,M
 421E 23        	INX	H
 421F 56        	MOV	D,M
 4220 EB        	XCHG
                ;
 4221 D1        	POP	D	;HL=NXT BLOCK,DE=-(FIRST BLOCK)
                			;SO HL+DE=LENGTH OF SYSTEM.MICRO
 4222 19        	DAD	D	;HL=LENGTH
 4223 EB        	XCHG		;DE=LENGTH
 4224 E1        	POP	H	;HL=FIRST BLOCK , DE=LENGTH
                ;
                ;CHECK THAT WE WON'T OVERWRITE OURSELVES
 4225 012000    	LXI	B,NBLOCKS
 4228 79        	MOV	A,C
 4229 93        	SUB	E
 422A 78        	MOV	A,B
 422B 9A        	SBB	D
 422C D2AC42    	JNC	OK	;JIF OK
                			;ELSE TELL OPERATOR AND REBOOT
 422F 113A42    	LXI	D,INTERP$TO$LARGE
 4232 0E09      	MVI	C,WRBUF
 4234 CD0500    	CALL	BDOS	;PRINT THE MESSAGE
 4237 C3AE41    	JMP	REBOOT	;REBOOT CPM
                
                INTERP$TO$LARGE:
 423A 0D0A494E54	DB	CR,LF,'INTERPETER TO LARGE IT WILL OVER WRITE'
 4262 0D0A544849	DB	CR,LF,'THIS PROGRAM. REASSEMBLE THIS PROGRAM'
 4289 0D0A574954	DB	CR,LF,'WITH A HIGHER STARTING ADDRESS',CR,LF,EOM
                
                ;
                OK:
 42AC 010001    	LXI	B,INTERP$BASE	;AND SET IT LOAD POINT
 42AF CDB342    	CALL	SYSRD		;THEN READ IT
 42B2 C9        	RET
                ;
                ;
                SYSRD:				;READ BLOCKS FROM PASCAL DISKETTE
 42B3 D5        	PUSH	D		;SAVE BLOCK COUNT
 42B4 E5        	PUSH	H		;AND BLOCK NUMBER
 42B5 CDC042    	CALL	READ$RX		;BUFFER IS ADVANCED BY 512 BYTES
 42B8 E1        	POP	H
 42B9 D1        	POP	D
 42BA 23        	INX	H		;ADVANCE TO NEXT BLOCK
 42BB 1D        	DCR	E		;BUT, BEFORE WE GO ON
 42BC C2B342    	JNZ	SYSRD		;  SEE IF WE'RE DONE
 42BF C9        	RET
                ;
                ;
                READ$RX:			;READ A PASCAL BLOCK
 42C0 29        	DAD	H		;THERE ARE 4 IBM SECTORS TO A PASCAL BLOCK
 42C1 29        	DAD	H		;  SO MULT LOGICAL BLOCK BY 4 TO GET 1ST SEC
 42C2 1E04      	MVI	E,4
                RR$LP:				;THIS GETS CONFUSING
 42C4 C5        	PUSH	B		;SET BUFFER ADDRESS
 42C5 D5        	PUSH	D
 42C6 E5        	PUSH	H
 42C7 CD0B43    	CALL	SETDMA
 42CA E1        	POP	H		;NOW COMPUTE PHYSICAL TRACK-SECTOR
 42CB E5        	PUSH	H
 42CC CD1743    	CALL	MAP		;MAP CONVERTS LOGICAL SECTOR IN HL-REG
 42CF 0600      	MVI	B,00H		;ZERO B FOR 2.24 BIOS CALL
 42D1 4C        	MOV	C,H		;  INTO PHYSICAL TRACK, H-REG, SECTOR, L-REG
 42D2 E5        	PUSH	H
 42D3 CDFF42    	CALL	SETTRK
 42D6 E1        	POP	H
 42D7 0600      	MVI	B,00H		;ZERO B FOR 2.24 BIOS CALL
 42D9 4D        	MOV	C,L
 42DA CD0543    	CALL	SETSEC
 42DD CD1143    	CALL	READ		;AND READ THE DATA
 42E0 E1        	POP	H
 42E1 D1        	POP	D
 42E2 C1        	POP	B
 42E3 E5        	PUSH	H		;ADVANCE THE BUFFER ADDRESS
 42E4 218000    	LXI	H,128
 42E7 09        	DAD	B
 42E8 44        	MOV	B,H
 42E9 4D        	MOV	C,L
 42EA E1        	POP	H
 42EB 23        	INX	H		;ADVANCE BLOCK COUNT
 42EC 1D        	DCR	E		;THEN SEE IF WE CONTINUE
 42ED C2C442    	JNZ	RR$LP
 42F0 C9        	RET			;LEAVE, WHEN DONE
                ;
                ;
 42F1           DENTP	DS	2
                ;
                ;
                HOME:				;HOME SELECTED DISK TO TRACK 00
 42F3 2A0100    	LHLD	BOOT+1
 42F6 2E18      	MVI	L,18H
 42F8 E9        	PCHL
                ;
                SELDSK:				;SELECT DISK (C-REG)
 42F9 2A0100    	LHLD	BOOT+1
 42FC 2E1B      	MVI	L,1BH
 42FE E9        	PCHL
                ;
                SETTRK:				;SET TRACK (C-REG)
 42FF 2A0100    	LHLD	BOOT+1
 4302 2E1E      	MVI	L,1EH
 4304 E9        	PCHL
                ;
                SETSEC:				;SET SECTOR (C-REG)
 4305 2A0100    	LHLD	BOOT+1
 4308 2E21      	MVI	L,21H
 430A E9        	PCHL
                ;
                SETDMA:				;SET DATA TRANSFER ADDRESS (BC-REG)
 430B 2A0100    	LHLD	BOOT+1
 430E 2E24      	MVI	L,24H
 4310 E9        	PCHL
                ;
                READ:				;READ A SECTOR TO THE DATA AREA
 4311 2A0100    	LHLD	BOOT+1
 4314 2E27      	MVI	L,27H
 4316 E9        	PCHL
                ;
                ;
                MAP:			;TURN LSN INTO IBM TRACK-SECTOR
                ;
                ;	NOTE:	BLOCK 0 
                ;		IS AT TRACK 00 SECTOR 0
                ;
                ;	ON ENTRY:	HL-REG HAS LOGICAL SECTOR NO.
                ;	ON EXIT:	H-REG HAS PHYSICAL TRACK
                ;			L-REG HAS PHYSICAL SECTOR
                ;
 4317 C5        	PUSH	B
 4318 D5        	PUSH	D
 4319 CD2043    	CALL	DIV26
 431C 63        	MOV	H,E
 431D D1        	POP	D
 431E C1        	POP	B
 431F C9        	RET
                ;
                ;
                DIV26:
 4320 01BCFF    	LXI	B,-68
 4323 1EFF      	MVI	E,0FFH
                DIVL:
 4325 1C        	INR	E
 4326 09        	DAD	B
 4327 7C        	MOV	A,H
 4328 B7        	ORA	A
 4329 F22543    	JP	DIVL
 432C 014400    	LXI	B,68
 432F 09        	DAD	B
 4330 C9        	RET
                ;
                ;
 4331           	END	START
