summaryrefslogblamecommitdiffstatshomepage
path: root/src/devices/cpu/i86/i286.h
blob: 0012cd6369936a07ac3822afffa76fa7531cf4b9 (plain) (tree)
1
2
3
4
5
6
7
8
9
10

                         



                           
 
                

                             
                                              

    
                                    
                              
 
                    
                

                
                
                
                

                
                   
 
                
                



                    
                  



                      


                      


                      


                      
 












                        
                       

  



                                                        
                                                                                                           
 
                                            
                                                                         
 
                                                 

                                                                                                                                                     

          


                                             

                                           
                                                                            
                                                                                                           
 
                                                                           
                                                                         
                                                                                     
 




                                                                                                                                                            

                                 

                                                                                                              

        




                                                                                                                    
                                                                    
                                                 
                              



                                                                                 
                                                                 

                         



                            
                        
                         

                

                               

                         



                               

                       
                                                                                                                

                                              
                                              
                                         
                                                  



















                              
                                             

  
                                         
                                                                                                                   

                                     
                                                                                     
 
                             
// license:BSD-3-Clause
// copyright-holders:Carl
#ifndef MAME_CPU_I86_I286_H
#define MAME_CPU_I86_I286_H

#pragma once

#include "i86.h"
#define INPUT_LINE_A20      1

DECLARE_DEVICE_TYPE(I80286, i80286_cpu_device)

enum
{   // same order as I8086 registers
	I286_PC = STATE_GENPC,

	I286_IP = 1,
	I286_AX,
	I286_CX,
	I286_DX,
	I286_BX,
	I286_SP,
	I286_BP,
	I286_SI,
	I286_DI,
	I286_FLAGS,

	I286_ES,
	I286_CS,
	I286_SS,
	I286_DS,

	I286_VECTOR,
	I286_HALT,

	I286_ES_BASE,
	I286_ES_LIMIT,
	I286_ES_FLAGS,
	I286_CS_BASE,
	I286_CS_LIMIT,
	I286_CS_FLAGS,
	I286_SS_BASE,
	I286_SS_LIMIT,
	I286_SS_FLAGS,
	I286_DS_BASE,
	I286_DS_LIMIT,
	I286_DS_FLAGS,

	I286_MSW,

	I286_GDTR_BASE,
	I286_GDTR_LIMIT,
	I286_IDTR_BASE,
	I286_IDTR_LIMIT,
	I286_TR,
	I286_TR_BASE,
	I286_TR_LIMIT,
	I286_TR_FLAGS,
	I286_LDTR,
	I286_LDTR_BASE,
	I286_LDTR_LIMIT,
	I286_LDTR_FLAGS
};

class i80286_cpu_device : public i8086_common_cpu_device
{
public:
	// construction/destruction
	i80286_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);

	// device_memory_interface overrides
	virtual space_config_vector memory_space_config() const override;

	typedef delegate<uint32_t (bool)> a20_cb;
	template <typename Object> void set_a20_callback(Object &&cb) { m_a20_callback = std::forward<Object>(cb); }
	template <class Object> devcb_base &set_shutdown_callback(Object &&cb) { return m_out_shutdown_func.set_callback(std::forward<Object>(cb)); }

protected:
	virtual void execute_run() override;
	virtual void device_reset() override;
	virtual void device_start() override;

	// device_state_interface overrides
	virtual void state_import(const device_state_entry &entry) override;
	virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;

	virtual uint32_t execute_input_lines() const override { return 1; }
	virtual void execute_set_input(int inputnum, int state) override;
	bool memory_translate(int spacenum, int intention, offs_t &address) override;

	virtual void interrupt(int int_num, int trap = 1) override { if(trap) throw TRAP(int_num, (uint16_t)-1); else interrupt_descriptor(int_num, 0, 0); }
	virtual uint8_t read_port_byte(uint16_t port) override;
	virtual uint16_t read_port_word(uint16_t port) override;
	virtual void write_port_byte(uint16_t port, uint8_t data) override;
	virtual void write_port_word(uint16_t port, uint16_t data) override;

	// Executing instructions
	virtual uint8_t fetch() override;
	virtual uint32_t calc_addr(int seg, uint16_t offset, int size, int op, bool override = true) override;

private:
	void check_permission(uint8_t check_seg, uint32_t offset, uint16_t size, int operation);
	void code_descriptor(uint16_t selector, uint16_t offset, int gate);
	void data_descriptor(int reg, uint16_t selector);
	void data_descriptor(int reg, uint16_t selector, int cpl, uint32_t trap, uint16_t offset = 0, int size = 0);
	uint16_t far_return(int iret, int bytes);
	void interrupt_descriptor(int number, int hwint, int error);
	void load_flags(uint16_t flags, int cpl);
	void pop_seg(int reg);
	uint32_t selector_address(uint16_t sel);
	void switch_task(uint16_t ntask, int type);
	void trap(uint32_t error);
	int verify(uint16_t selector, int operation, uint8_t rights, bool valid);
	uint32_t update_pc() { return m_pc = m_base[CS] + m_ip; }

	int m_trap_level;
	uint16_t m_msw;
	uint32_t m_base[4];
	uint16_t m_limit[4];
	uint8_t m_rights[4];
	bool m_valid[4];
	uint32_t m_amask;

	struct {
		uint32_t base;
		uint16_t limit;
	} m_gdtr, m_idtr;
	struct {
		uint16_t sel;
		uint32_t base;
		uint16_t limit;
		uint8_t rights;
	} m_ldtr, m_tr;

	uint32_t TRAP(uint16_t fault, uint16_t code)  { return ((((uint32_t)fault&0xffff)<<16)|(code&0xffff)); }

	address_space_config m_program_config;
	address_space_config m_opcodes_config;
	address_space_config m_io_config;
	static const uint8_t m_i80286_timing[200];

	enum {
		FAULT_DE = 0,
		FAULT_DB,
		NMI,
		FAULT_BP,
		FAULT_OF,
		FAULT_BR,
		FAULT_UD,
		FAULT_NM,
		FAULT_DF,
		FAULT_MP,
		FAULT_TS,
		FAULT_NP,
		FAULT_SS,
		FAULT_GP
	};

	a20_cb m_a20_callback;
	bool m_shutdown;
	devcb_write_line m_out_shutdown_func;
};

#define MCFG_80286_A20(_class, _a20_cb) \
	downcast<i80286_cpu_device &>(*device).set_a20_callback(i80286_cpu_device::a20_cb(&_class::_a20_cb, this));

#define MCFG_80286_SHUTDOWN(_devcb) \
	downcast<i80286_cpu_device &>(*device).set_shutdown_callback(DEVCB_##_devcb);

#endif // MAME_CPU_I86_I286_H