CSCOLD	EQU	(Offset $)
   CSEG 0	
  iflist
;REUSE	EQU	$
	ORG	CSCOLD
;****************************************************************
;*								*
;* INIT - Called once from MP/M kernel at an early stage of 	*
;* 	  system initialization.  Its function is to do XIOS	*
;*	  setup such at interrupt vectors, PIC's, clocks and	*
;*	  so forth.						*
;*								*
;****************************************************************

INIT:	PUSH	DS
	MOV  Word Ptr SYSDAT,DS	;Save system data segment for later use
	MOV  Word Ptr BUFSEG,DS	;Set system data segment as default 
	MOV  Word Ptr DMASEG,DS	;  dma segment
	MOV  BX,Offset SUPMOD	;Pick up address from system on SUP entry

	MOV	AX,CS		;8080 model: code seg = data seg
	MOV	DS,AX

	MOV  Word Ptr INTSS,SS	;Switch to local XIOS stack
	MOV  Word Ptr INTSP,SP	
	mov	SS,AX		;Stack, code, data all the same
	MOV	SP,Offset INT_STACK	;Temporary stack for intialization
				
	MOV	SI,SUPERVISOR	;Place copy of SUPMOD in data seg in code seg
	MOV  AX,Word                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 ,AL
	MOV	AL,maskmstr
	OUT	PICMP1,AL

	MOV	AL,00011101b	;Level, cascade, icw4
	OUT	PICSP0,AL
	MOV	AL,INTBASE/4+8
	OUT	PICSP1,AL		
	MOV	AL,00000111b	;Slave # 7
	OUT	PICSP1,AL
	MOV	AL,00000001B	;8088 mode
	OUT	PICSP1,AL
	MOV	AL,maskslv
	OUT	PICSP1,AL

	CALL	RTCINIT		;Initialize system time
;	CALL	DMAINIT		;Initilialize DMA queue
	CALL	FDCINIT		;Initilialize Disk 1 controller
	if	hard
	CALL	HDINIT		;Initilialize HD process
	endif
	CALL	BINIT		;Initilialize character I/O buffer pool
	CALL	Z80INIT		;Set up and intialize the Zslaves

	MOV	ax,100h		;Major/Minor -> (ax)
	MOV	BX,Offset DD_TBL+D_SIZE  ;Call all device initialzation routines
INIT1:	MOV	DX,D_INIT[BX]
	CMP	DX,0		;Check for end of the table
	JE	INIT2
	PUSH	AX
	PUSH	BX
	CALL	DX
	POP	BX
	POP	AX
	INC	AH		;Next major device number
	ADD	BX,d_size	;Next entry
	JMP	INIT1
;
INIT2:	CALL	MALLOC		;Set up MP/M memory allocation

	MOV	BX,Offset SIGNON  ;Print sign on message
	CALL	PCON		;To system console (no interrupts

	PUSHF
	POP	AX
	CLI
	MOV  SS,Word Ptr INTSS	;Recover registers and return
	MOV  SP,Word Ptr INTSP		 
	PUSH	AX
	POPF
	POP	DS
	RETF

;
;****************************************************************
;*								*
;* MALLOC - Called from init to set up MP/M memory allocation	*
;*	    tables.  This is the dynamic memory allocation of	*
;*	    MP/M 8-16 where it goes out and finds out how much	*
;*	    memory there is in the system and builds segments	*
;*	    in 16K chunks.  User memory is considered from the	*
;*	    end of MP/M to the end of memory.  The disk cache	*
;*	    and other reserved memory should be below the	*
;*          operating system.					*
;*								*
;****************************************************************

MALLOC:
	MOV	BX,Offset MEM	;Address of new memory table
	MOV  Word Ptr MFL,BX		;Set into SYSDAT
	MOV  AX,Word Ptr ENDSEG	;Start memory allocation at end of MP/M system
	MOV  Word Ptr MD_LINK[BX],Offset MEM+MD_LEN ;Hand carve first entry
	MOV  Word Ptr MD_BEG[BX],AX	;Starting segment of first segment
	ADD	AX,400h
	AND	AX,0fc00h	;Find next 16K boundry
	SUB	AX,0Ah		;Start all segments A0 bytes below 16K boundry
	MOV  Word Ptr PREV,AX
	MOV  CX,Word Ptr ENDSEG
	SUB	AX,CX
	MOV  Word Ptr MD_SIZE[BX],AX
	MOV  Word Ptr MD_RES0[BX],0
	MOV  Word Ptr MD_RES1[BX],0
	ADD	BX,MD_LEN	;Next memory descriptor

MAL1:	MOV  AX,Word Ptr PREV	;Pick up last addess
	MOV  Word Ptr MD_BEG[BX],AX	;Base of memory descriptor
	MOV  Word Ptr MD_SIZE[BX],400h  ;Length
	MOV  Word Ptr MD_RES0[BX],0	;Zero out RFU entries
	MOV  Word Ptr MD_RES1[BX],0
	ADD	AX,400h		;Point to next 16K block
	PUSH	AX
	ADD	AX,400h		;Check if end of block is past end of memory
	JC	mstop2
	CMP  AX,Word Ptr ENDMEM ;Check against end of memory
	POP	AX
	JA	MSTOP
	MOV  Word Ptr PREV,AX	;Save new address as last address
	PUSH	BX
	ADD	BX,MD_LEN	;Length of each memory entry
	MOV	CX,BX
	POP	BX
	MOV  Word Ptr MD_LINK[BX],CX	;Address of next entry for chain
	MOV	BX,CX		;Next memory entry
	JMP	MAL1

M                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                