"70320" 
******************************************************************************* 
* 
*  Foreground monitor code for the 70335(v35+) emulator
*  
*  This is the standard foreground monitor for the 70335 emulator.
*  The monitor occupies 2K of emulation memory( separate from the normal
*  user space).
*  The desired 2K bytes boundary should be specified in
*   
*       	MONSEGMENT	EQU 	0XX00H
*
*  statement at the start of the monitor. The start address of monitor must
*  be also defined in the emulator configuration below.
*
*		cf mon=fg..0xx000 ( terminal mode )
*	or 
*		Foreground monitor location? 0xx000H ( 300 series USER I/F )
*
*  And the address of user stack pointer should be specified in this 
*  foreground monitor below.
*
*  		USERSS		EQU	0XXXXH		;stack segment
*  		USERSP		EQU	0XXXXH		;stack pointer
*
*  In this manner, communication between the foreground monitor and
*  the emulator operating software can be established.
*
*  The first few sections of the foreground monitor can't be modified 
*  and their location with respect to the start of the foreground
*  monitor can't be altered.  These include the following:
*
*  		monitor vector table 
*		monitor variables
*		key monitor entry routines
*
*  The monitor vector table is used by the emulator to make transition
*  into the foreground monitor from break state.
*
*  The monitor variables section consists of four parts.
*  The first part is a group of variables that act as the communications
*  path between the foreground monitor and the emulator controller.
*  The second part holds a copy of the 70335 registers which are stored
*  when entering the foreground monitor.
*  The third part is the transfer buffer which is used to transfer block
*  of data from the emulation controller to target system.
*  The other is the variables used by the monitor.
*
*  The key monitor entry routines involve a brief background state.
*  Therefore,these routines can't be modified or moved
*  with respect to the start of the monitor.
*  
*********************************************************************** 

******************************
*   set up monitor segment   *
******************************

MONSEGMENT      EQU    0F000H
*
PARAG	        EQU    MONSEGMENT*10000H
*
***********************************************
* set up user stack segment and stack pointer *
***********************************************
*
USERSS          EQU    00000H		;user stack segment
USERSP          EQU    0FFFFH		;user stack pointer
*
* monitor use * 
USERSP_M        EQU    USERSP-6
*
***********************************
*      monitor vector table       *
***********************************

		ORG    PARAG+0000H
		DW     0
		DW     0

		DW     00240H			
		DW     MONSEGMENT		

         	DW     00220H                   
         	DW     MONSEGMENT	        

         	DW     0			
         	DW     0			
  
************************************
*      monitor vector table end    *
************************************
* 
************************************
*      monitor variables   	   *
************************************
* monitor control variables

		ORG    PARAG+00C0H
EXIT_TYPE	DW     0			
ENT_TYPE	DW     0			
CMD_CONTROL     DW     3		
CMD_RESULT      DW     0	
CMD_TYPE        DW     0
TARG_START      DW     0			
		DW     0			
TARG_BYTES      DW     0			
IOB_VAL         DW     0			
LAST_ENTRY      DW     0			

*************************************
* register buffer 

		ORG    PARAG+00D4H
REG_SEG		DW     0
REG_OFF		DW     0
REG_PSW		DW     002F0H
REG_AW		DW     0
REG_BW		DW     0
REG_CW		DW     0
REG_DW		DW     0
REG_SP		DW     0
REG_BP		DW     0
REG_IX		DW     0
REG_IY		DW     0
REG_DS0		DW     0
REG_DS1		DW     0
REG_SS		DW     0

*************************************
* transfer buffer 

		ORG    PARAG+120H
XFR_BUF		DW     0

*************************************
* Other variables

                ORG    PARAG+000F6H 
ROMFLAG         DW     0			

OKTORUN		DB     0			
		DB     0			

IDBTEMP		DB     0FFH			
		DB     0			

LAST_PS_PC	DW     0			

BRKTYPE		DB     0			

ACCESSTYPE	DB     0			

************************************
*      monitor variables end  	   *
************************************
*
*****************************************
*      key monitor entry routines       *
*****************************************

 	        ASSUME PS:ORG,DS0:ORG 
                ORG    PARAG+0220H 

		MOV    PS:REG_AW,AW
		MOV    AL,PS:OKTORUN		
		OR     AL,#2			
 		MOV    PS:BRKTYPE,AL		
        	TEST1  AL,#7			
		BZ     MONITOR			
		PUSH   PSW
		PUSH   PS
		PUSH   OFFSET MONITOR
EXIT_TO_USER    RETI
*****************************************
*      key monitor entry routines end   *
*****************************************
*
**************************************************
*               monitor entry routines           *
**************************************************
*
 	        ASSUME PS:ORG,DS0:ORG 
                ORG    PARAG+0240H 
**************************************************
* store processor registers in register buffer

FGMON_STEP_ENT 	MOV    PS:REG_AW,AW
		EI
MONITOR	
		MOV    PS:REG_BW,BW
		MOV    PS:REG_CW,CW
		MOV    PS:REG_DW,DW
		MOV    PS:REG_IX,IX
		MOV    PS:REG_IY,IY
		MOV    PS:REG_BP,BP
		MOV    PS:REG_DS0,DS0
		MOV    PS:REG_DS1,DS1

		CMP    PS:ENT_TYPE+1,#0
		BZ     NO_RST_MON
		MOV    AW,USERSS
		MOV    PS:REG_SS,AW
		MOV    PS:REG_SP,USERSP_M
		MOV    PS:ENT_TYPE+1,#0
		BR     RD_IDB

NO_RST_MON	MOV    PS:REG_SS,SS
		MOV    PS:REG_SP,SP

**************************************************
* make a copy of idb 

RD_IDB		MOV    AW,#0FF00H		
		MOV    DS1,AW			
		MOV    AL,DS1:BYTE PTR [0FFFH]	
		MOV    PS:IDBTEMP,AL		
**************************************************
* create background stack pointer in "bw" register 
  
		MOV    BW,SS			
		SHL    BW,#4			
		ADD    BW,SP			
		AND    BW,#3FFH			
		OR     BW,#800H			
		MOV    DW,BW			
**************************************************
* check last PS/PC value

 		MOV    PS:LAST_PS_PC,#1		
 		INC    BW
 		AND    BW,#0BFFH
 		CMP    PS:BYTE PTR [BW],#0	
 		BNZ    MON_ENTRY_TYPE 		
 		INC    BW
 		AND    BW,#0BFFH
 		CMP    PS:BYTE PTR [BW],#0	
 		BNZ    MON_ENTRY_TYPE 		
 		INC    BW
 		AND    BW,#0BFFH
 		CMP    PS:BYTE PTR [BW],#0	
 		BNZ    MON_ENTRY_TYPE 		
 		MOV    PS:LAST_PS_PC,#0		
**************************************************
* check monitor entry type
MON_ENTRY_TYPE 
		MOV    PS:ENT_TYPE,#0H		
		CMP    PS:EXIT_TYPE,100H	
		BNE    NOT_STEP 		
		MOV    AL,PS:BRKTYPE
		TEST1  AL,#4
		BZ     NOT_STEP
		TEST1  AL,#1
		BZ     FGMON_ADJUST 		
		AND    PS:BRKTYPE,#0FDH

     		MOV    BW,DW		
		ADD    BW,#5			
		AND    BW,#0BFFH		
 		TEST1  PS:BYTE PTR [BW],#0      
 		BNZ    NOT_STEP

               	ADD    SP,#6			
               	ADD    PS:REG_SP,#6	
		BR     FGMON_ADJUST 		

NOT_STEP	MOV    AL,PS:BRKTYPE
        	TEST1  AL,#1
		BZ     FGMON_ADJUST 		
        	TEST1  PS:BRKTYPE,#4		
		BNZ    BKGMON_ADJUST		

                CMP    PS:LAST_PS_PC,#0		
		BNZ    ADJUST_SP12		
						

ADJUST_SP6     	ADD    PS:REG_SP,#6	
		ADD    DW,#6	
		AND    DW,#0BFFH	
                BR     BKGMON_ADJUST

ADJUST_SP12    	ADD    PS:REG_SP,#12
		ADD    DW,#12	
		AND    DW,#0BFFH
                BR     BKGMON_ADJUST

**************************************************
* store segment, offset and psw
FGMON_ADJUST	
            	POP    PS:WORD PTR REG_OFF
 		POP    PS:WORD PTR REG_SEG
 		POP    PS:WORD PTR REG_PSW
 		AND    PS:WORD PTR REG_PSW,#0FEFFH
 		OR     PS:BRKTYPE,#030H			
							
 		SUB    SP,#6H				
 		BR     OKRUN_BREAK 

BKGMON_ADJUST	AND    PS:BRKTYPE,#0FDH		
              	MOV    BW,DW			
						
		AND    BW,#0BFFH
		MOV    AL,PS:BYTE PTR [BW]	
		MOV    PS:BYTE PTR REG_OFF,AL		
		INC    BW
		AND    BW,#0BFFH
		MOV    AL,PS:BYTE PTR [BW]	
		MOV    PS:BYTE PTR REG_OFF+1,AL		
		INC    BW
		AND    BW,#0BFFH
		MOV    AL,PS:BYTE PTR [BW]	
		MOV    PS:BYTE PTR REG_SEG,AL		
		INC    BW
		AND    BW,#0BFFH
		MOV    AL,PS:BYTE PTR [BW]
		MOV    PS:BYTE PTR REG_SEG+1,AL		
        	INC    BW
		AND    BW,#0BFFH
		MOV    AL,PS:BYTE PTR [BW]	
		MOV    PS:BYTE PTR REG_PSW,AL		
		INC    BW
		AND    BW,#0BFFH
		MOV    AL,PS:BYTE PTR [BW]	
		OR     AL,#80H			
		AND    AL,#0FEH			
		MOV    PS:BYTE PTR REG_PSW+1,AL		

 		OR     PS:BRKTYPE,#030H		
						
**************************************************
* entry point of break from ok-to-run wait

OKRUN_BREAK	MOV    PS:IOB_VAL,#0		
**************************************************
* swap lsb and msb of register values

		ADD    PS:REG_SP,#6H		
		MOV    IX,OFFSET REG_SEG	
                MOV    CW,14			  
REGSWAP_1	MOV    AW,PS:WORD PTR[IX]
		XCH    AH,AL
		MOV    PS:WORD PTR[IX],AW 
	        ADD    IX,#2
		DEC    CW
                BNE    REGSWAP_1
**************************************************
* initialize last_entry and cmd_control

                MOV    PS:CMD_CONTROL,0400H
                BR     MON_LOOP
**************************************************
* entry point of monitor command completion

MON_COMPLETE	MOV    AW,#0FF00H		
		MOV    DS1,AW			
		MOV    AH,PS:IDBTEMP 		
		MOV    DS1:BYTE PTR [0FFFH],AH	
		MOV    AL,#0                    
		MOV    DS1,AW                   

		MOV    PS:CMD_CONTROL,0300H
**************************************************
* monitor command waiting loop

MON_LOOP        CMP    PS:CMD_CONTROL,0100H	
                BE     PS:CMD_REQUEST		
                BR     MON_LOOP			
**************************************************
* monitor command interpreter

CMD_REQUEST 	MOV    PS:CMD_CONTROL,0200H
                CMP    PS:CMD_TYPE,0100H
                BE     SW_IN_MON
                CMP    PS:CMD_TYPE,0400H
                BE     TARG_MEM_WR
                CMP    PS:CMD_TYPE,0800H
                BE     TARG_MEM_RD
                CMP    PS:CMD_TYPE,1000H
		BNE    CMD_REQ_1
                BR     TARG_IO_WR
CMD_REQ_1       CMP    PS:CMD_TYPE,2000H
		BNE    CMD_REQ_2
                BR     TARG_IO_RD
CMD_REQ_2       CMP    PS:CMD_TYPE,0200H
                BNE    MON_COMPLETE		
                BR     EXIT_START

SW_IN_MON       MOV    PS:CMD_RESULT,00H
                BR     MON_COMPLETE

**************************************************
* target memory write routine

TARG_MEM_WR	MOV	PS:CMD_RESULT,00H
		MOV 	AW,PS:TARG_START+2
                XCH     AH,AL
                MOV     IY,AW
		MOV 	AW,PS:TARG_START
                XCH     AH,AL
                MOV     DS0,AW
		MOV	IX,OFFSET XFR_BUF
		MOV	CW,PS:TARG_BYTES
		XCH     CH,CL
		TEST1	CW,#11    		
		BZ	TARG_IRAM_WR		
		MOV	DS1:BYTE PTR [0FFFH],#0	
TARG_IRAM_WR 	AND     CW,7FFH
		BR      TARG_MOP_WR

**************************************************
* target memory read routine

TARG_MEM_RD	MOV	PS:CMD_RESULT,00H
		MOV 	AW,PS:TARG_START+2
                XCH     AH,AL
                MOV     IX,AW
		MOV 	AW,PS:TARG_START
                XCH     AH,AL
                MOV     DS0,AW
		MOV	IY,OFFSET XFR_BUF
		MOV	CW,PS:TARG_BYTES
		XCH     CH,CL
		TEST1	CW,#11    		
		BZ	TARG_IRAM_RD		
		MOV	DS1:BYTE PTR [0FFFH],#0	
                AND     CW,7FFH
		BR      TARG_MOP_RD

TARG_IRAM_RD	AND     CW,7FFH
		BR      TARG_MOP_RD

**************************************************
* target io write routine

TARG_IO_WR	MOV	PS:CMD_RESULT,00H
		MOV 	DW,PS:TARG_START+2
                XCH     DH,DL
		MOV	IX,OFFSET XFR_BUF
		MOV	CW,PS:TARG_BYTES
		XCH     CH,CL
                AND     CW,7FFH
		BR      TARG_IOP_WR

**************************************************
* target io read routine

TARG_IO_RD	MOV	PS:CMD_RESULT,00H
		MOV 	DW,PS:TARG_START+2
                XCH     DH,DL
		MOV	IY,OFFSET XFR_BUF
		MOV	CW,PS:TARG_BYTES
		XCH     CH,CL
                AND     CW,7FFH 
		BR      TARG_IOP_RD

**************************************************
*exit routine
 
EXIT_START
		MOV    PS:CMD_RESULT,00H
                MOV    PS:CMD_CONTROL,0300H

		CMP    PS:EXIT_TYPE,#100H	
		BNE    EXIT_RUN			
		OR     PS:REG_PSW,#1		
			
EXIT_RUN	

**************************************************
* swap lsb and msb of register values

		MOV    IX,OFFSET REG_SEG
                MOV    CW,14
REGSWAP_2	MOV    AW,PS:WORD PTR[IX]
		XCH    AH,AL
		MOV    PS:WORD PTR[IX],AW 
	        ADD    IX,#2
		DEC    CW
                BNE    REGSWAP_2

**************************************************
*restore processor registers from register buffer

         	MOV    SS,PS:REG_SS
		MOV    SP,PS:REG_SP
		PUSH   PS:WORD PTR REG_PSW
		PUSH   PS:WORD PTR REG_SEG
		PUSH   PS:WORD PTR REG_OFF

**************************************************
* restore processor registers from register buffer

		MOV    AW,PS:REG_AW
		MOV    BW,PS:REG_BW
		MOV    CW,PS:REG_CW
		MOV    DW,PS:REG_DW
		MOV    IX,PS:REG_IX
		MOV    IY,PS:REG_IY
		MOV    BP,PS:REG_BP
		MOV    DS0,PS:REG_DS0
		MOV    DS1,PS:REG_DS1

       		BR     EXIT_TO_USER

******************************************************************************* 
*   This table defines monitor entry points other than by breaking. To use    *
*   these entry points, the processors vector table must be loaded with       *
*   pointers to these locations.					      *
******************************************************************************* 

		ORG     PARAG+700H
DIV0_ENTRY     	MOV	PS:LAST_ENTRY,#0400H
 		BR	FGMON_STEP_ENT

STEP_ENTRY      MOV	PS:LAST_ENTRY,#0500H
 		BR	FGMON_STEP_ENT

NMI_ENTRY 	MOV	PS:LAST_ENTRY,#0600H
 		BR	FGMON_STEP_ENT

BRKV_ENTRY     	MOV	PS:LAST_ENTRY,#0700H
 		BR	FGMON_STEP_ENT

CHKIND_ENTRY   	MOV	PS:LAST_ENTRY,#0800H
 		BR	FGMON_STEP_ENT

FPO_ENTRY     	MOV	PS:LAST_ENTRY,#0900H
 		BR	FGMON_STEP_ENT

**************************************************
* target mop write routine in byte size

		ORG     PARAG+770H
TARG_MOP_WR	MOV	AL,PS:BYTE PTR[IX]
 		MOV	DS0:BYTE PTR [IY],AL
 		INC	IX
 		INC	IY
 		DBNZ	TARG_MOP_WR
 		BR	MON_COMPLETE

**************************************************
* target mop read routine in byte size

		ORG	PARAG+790H
TARG_MOP_RD	MOV	AL,DS0:BYTE PTR[IX]
 		MOV	PS:BYTE PTR [IY],AL
 		INC	IX
 		INC	IY
 		DBNZ	TARG_MOP_RD
 		BR	MON_COMPLETE

**************************************************
* target iop write routine byte size

		ORG     PARAG+7B0H
TARG_IOP_WR	MOV	AL,PS:BYTE PTR[IX]
 		OUT	DW,AL
 		INC	IX
 		INC	DW
 		DBNZ	TARG_IOP_WR
 		BR	MON_COMPLETE

**************************************************
* target iop read routine in byte size

		ORG	PARAG+7D0H
TARG_IOP_RD	IN	AL,DW
 		MOV	PS:BYTE PTR [IY],AL
 		INC	DW
 		INC	IY
 		DBNZ	TARG_IOP_RD
 		BR	MON_COMPLETE

**************************************************
*     Target memory / IO word access routines    *
**************************************************
*
**************************************************
* target mop write routine in word size
*
*		ORG     PARAG+770H
*TARG_MOP_WR	SHR	CW
*TARG_MOP_WRLP	MOV	AW,PS:WORD PTR[IX]
*		MOV	DS0:WORD PTR [IY],AW
*            	INC	IX
*            	INC	IX
* 		INC	IY
* 		INC	IY
*		BCWZ	TARGWR_COMP
* 		DBNZ	TARG_MOP_WRLP
*TARGWR_COMP	BR	MON_COMPLETE
*
**************************************************
* target mop read routine in word size
*
*		ORG	PARAG+790H
*TARG_MOP_RD	SHR	CW
*TARG_MOP_RDLP	MOV	AW,DS0:WORD PTR[IX]
*		MOV	PS:WORD PTR [IY],AW
*		INC	IX
*		INC	IX
*		INC	IY
*		INC	IY
*		BCWZ	TARGRD_COMP
*		DBNZ	TARG_MOP_RDLP
*TARGRD_COMP	BR	MON_COMPLETE
*
**************************************************
* target iop write routine word size

*		ORG     PARAG+7B0H
*TARG_IOP_WR	SHR	CW
*TARG_IOP_WRLP	MOV	AW,PS:WORD PTR[IX]
*		OUT	DW,AW
*		INC	IX
*		INC	IX
*		INC	DW
*		INC	DW
*		BCWZ	IOWR_COMP
*		DBNZ	TARG_IOP_WRLP
*IOWR_COMP	BR	MON_COMPLETE
*
**************************************************
* target iop read routine in word size
*
*		ORG	PARAG+7D0H
*TARG_IOP_RD	SHR	CW,1
*TARG_IOP_RDLP	IN	AW,DW
*		MOV	PS:WORD PTR [IY],AW
*		INC	DW
*		INC	DW
*		INC	IY
*		INC	IY
*		BCWZ	IORD_COMP
*		DBNZ	TARG_IOP_RDLP
*IORD_COMP	BR	MON_COMPLETE
*
**************************************************
*
**************************************************
*  Target memory / IO word access routines end   *
**************************************************
