diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/devices/cpu/sparc/mb86901.cpp | 8 | ||||
-rw-r--r-- | src/devices/cpu/sparc/sparc.h | 33 | ||||
-rw-r--r-- | src/devices/machine/timekpr.cpp | 16 | ||||
-rw-r--r-- | src/devices/machine/timekpr.h | 11 | ||||
-rw-r--r-- | src/mame/drivers/sun4.cpp | 779 | ||||
-rw-r--r-- | src/osd/modules/render/bgfx/shaders/chains/crt/fs_crt-caligari.sc | 123 | ||||
-rw-r--r-- | src/osd/modules/render/bgfx/shaders/chains/crt/varying.def.sc | 7 | ||||
-rw-r--r-- | src/osd/modules/render/bgfx/shaders/chains/crt/vs_crt-caligari.sc | 45 |
8 files changed, 792 insertions, 230 deletions
diff --git a/src/devices/cpu/sparc/mb86901.cpp b/src/devices/cpu/sparc/mb86901.cpp index ee08106e260..8ed13db2778 100644 --- a/src/devices/cpu/sparc/mb86901.cpp +++ b/src/devices/cpu/sparc/mb86901.cpp @@ -641,6 +641,10 @@ void mb86901_device::execute_set_input(int inputnum, int state) case SPARC_MAE: m_mae = (state != 0) ? 1 : 0; break; + + case SPARC_RESET: + m_bp_reset_in = (state != 0) ? 1 : 0; + break; } } @@ -2558,7 +2562,6 @@ void mb86901_device::select_trap() if (m_reset_trap) { - m_reset_trap = 0; m_trap = 0; return; } @@ -2958,7 +2961,9 @@ void mb86901_device::execute_step() if (m_bp_reset_in) { m_execute_mode = 0; + m_error_mode = 0; m_reset_mode = 1; + printf("Entering reset mode\n"); return; } else if ((PSR & PSR_ET_MASK) && (m_bp_irl == 15 || m_bp_irl > ((PSR & PSR_PIL_MASK) >> PSR_PIL_SHIFT))) @@ -3045,6 +3050,7 @@ void mb86901_device::reset_step() m_execute_mode = 1; m_trap = 1; m_reset_trap = 1; + printf("m_bp_reset_in is false, resetting\n"); } } diff --git a/src/devices/cpu/sparc/sparc.h b/src/devices/cpu/sparc/sparc.h index d23f032fe9a..fa8b9dd234b 100644 --- a/src/devices/cpu/sparc/sparc.h +++ b/src/devices/cpu/sparc/sparc.h @@ -18,36 +18,6 @@ #include <map> #endif -#define SPARC_NO_TRAP 256 -#define SPARC_RESET 0 -#define SPARC_INSTRUCTION_ACCESS_EXCEPTION 1 -#define SPARC_ILLEGAL_INSTRUCTION 2 -#define SPARC_PRIVILEGED_INSTRUCTION 3 -#define SPARC_FP_DISABLED 4 -#define SPARC_WINDOW_OVERFLOW 5 -#define SPARC_WINDOW_UNDERFLOW 6 -#define SPARC_MEM_ADDRESS_NOT_ALIGNED 7 -#define SPARC_FLOATING_POINT_EXCEPTION 8 -#define SPARC_DATA_ACCESS_EXCEPTION 9 -#define SPARC_TAG_OVERFLOW 10 -#define SPARC_INT1 17 -#define SPARC_INT2 18 -#define SPARC_INT3 19 -#define SPARC_INT4 20 -#define SPARC_INT5 21 -#define SPARC_INT6 22 -#define SPARC_INT7 23 -#define SPARC_INT8 24 -#define SPARC_INT9 25 -#define SPARC_INT10 26 -#define SPARC_INT11 27 -#define SPARC_INT12 28 -#define SPARC_INT13 29 -#define SPARC_INT14 30 -#define SPARC_INT15 31 -#define SPARC_TRAP_INSTRUCTION 128 - -#define SPARC_FPU_SEQUENCE_ERROR // TODO: when there are more SPARC CPUs, move setter to a base class #define MCFG_SPARC_ADD_ASI_DESC(desc) \ mb86901_device::add_asi_desc(*device, desc); @@ -316,7 +286,8 @@ enum SPARC_IRQ13, SPARC_IRQ14, SPARC_NMI, - SPARC_MAE + SPARC_MAE, + SPARC_RESET }; #endif /* __SPARC_H__ */ diff --git a/src/devices/machine/timekpr.cpp b/src/devices/machine/timekpr.cpp index 06aba0b7221..4b87d43ff69 100644 --- a/src/devices/machine/timekpr.cpp +++ b/src/devices/machine/timekpr.cpp @@ -10,6 +10,7 @@ - M48T37 - M48T58 - MK48T08 + - MK48T12 ***************************************************************************/ @@ -23,6 +24,7 @@ const device_type M48T35 = &device_creator<m48t35_device>; const device_type M48T37 = &device_creator<m48t37_device>; const device_type M48T58 = &device_creator<m48t58_device>; const device_type MK48T08 = &device_creator<mk48t08_device>; +const device_type MK48T12 = &device_creator<mk48t12_device>; /*************************************************************************** @@ -202,6 +204,20 @@ mk48t08_device::mk48t08_device(const machine_config &mconfig, const char *tag, d m_offset_flags = 0x1ff0; } +mk48t12_device::mk48t12_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : timekeeper_device(mconfig, MK48T12, "MK48T12 Timekeeper", tag, owner, clock, "m48t12", __FILE__, 0x2000) +{ + m_offset_control = 0x7f8; + m_offset_seconds = 0x7f9; + m_offset_minutes = 0x7fa; + m_offset_hours = 0x7fb; + m_offset_day = 0x7fc; + m_offset_date = 0x7fd; + m_offset_month = 0x7fe; + m_offset_year = 0x7ff; + m_offset_century = -1; +} + //------------------------------------------------- // device_start - device-specific startup diff --git a/src/devices/machine/timekpr.h b/src/devices/machine/timekpr.h index 3d96d2f394a..f6ecb8dcbfc 100644 --- a/src/devices/machine/timekpr.h +++ b/src/devices/machine/timekpr.h @@ -10,6 +10,7 @@ - M48T37 - M48T58 - MK48T08 + - MK48T12 ***************************************************************************/ @@ -41,6 +42,9 @@ #define MCFG_MK48T08_ADD(_tag) \ MCFG_DEVICE_ADD(_tag, MK48T08, 0) +#define MCFG_MK48T12_ADD(_tag) \ + MCFG_DEVICE_ADD(_tag, MK48T12, 0) + //************************************************************************** @@ -134,11 +138,18 @@ public: mk48t08_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); }; +class mk48t12_device : public timekeeper_device +{ +public: + mk48t12_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); +}; + // device type definition extern const device_type M48T02; extern const device_type M48T35; extern const device_type M48T37; extern const device_type M48T58; extern const device_type MK48T08; +extern const device_type MK48T12; #endif // __TIMEKPR_H__ diff --git a/src/mame/drivers/sun4.cpp b/src/mame/drivers/sun4.cpp index 406b8e36681..086a28bae6c 100644 --- a/src/mame/drivers/sun4.cpp +++ b/src/mame/drivers/sun4.cpp @@ -419,6 +419,10 @@ #include "bus/rs232/rs232.h" #include "bus/sunkbd/sunkbd.h" #include "machine/timekpr.h" +#include "machine/nscsi_bus.h" +#include "machine/nscsi_cd.h" +#include "machine/nscsi_hd.h" +#include "machine/ncr5390.h" #include "machine/upd765.h" #include "formats/pc_dsk.h" #include "formats/mfi_dsk.h" @@ -436,7 +440,6 @@ #define RS232A_TAG "rs232a" #define RS232B_TAG "rs232b" #define FDC_TAG "fdc" -#define SCSI_TAG "ncr5390" #define ENA_NOTBOOT (0x80) #define ENA_SDVMA (0x20) @@ -445,13 +448,41 @@ #define ENA_DIAG (0x01) // page table entry constants -#define PM_VALID (0x80000000) // page is valid -#define PM_WRITEMASK (0x40000000) // writable? -#define PM_SYSMASK (0x20000000) // system use only? -#define PM_CACHE (0x10000000) // cachable? -#define PM_TYPEMASK (0x0c000000) // type mask -#define PM_ACCESSED (0x02000000) // accessed flag -#define PM_MODIFIED (0x01000000) // modified flag +#define PM_VALID (0x80000000) // page is valid +#define PM_WRITEMASK (0x40000000) // writable? +#define PM_SYSMASK (0x20000000) // system use only? +#define PM_CACHE (0x10000000) // cachable? +#define PM_TYPEMASK (0x0c000000) // type mask +#define PM_ACCESSED (0x02000000) // accessed flag +#define PM_MODIFIED (0x01000000) // modified flag + +#define PAGE_SIZE (0x00000400) + +// DMA controller constants +#define DMA_DEV_ID (0x80000000) +#define DMA_L (0x00008000) // use ILACC +#define DMA_TC (0x00004000) // terminal count +#define DMA_EN_CNT (0x00002000) // enable count +#define DMA_BYTE_ADDR (0x00001800) // next byte number to be accessed +#define DMA_BYTE_ADDR_SHIFT (11) +#define DMA_REQ_PEND (0x00000400) // request pending +#define DMA_EN_DMA (0x00000200) // enable DMA +#define DMA_WRITE (0x00000100) // DMA device->mem if 1, otherwise mem->device +#define DMA_RESET (0x00000080) // DMA hardware reset +#define DMA_DRAIN (0x00000040) // force remaining pack bytes to memory +#define DMA_FLUSH (0x00000020) // force PACK_CNT and ERR_PEND to 0 +#define DMA_INT_EN (0x00000010) // interrupt enable +#define DMA_PACK_CNT (0x0000000c) // number of bytes in pack register +#define DMA_PACK_CNT_SHIFT (2) +#define DMA_ERR_PEND (0x00000002) // error pending, set when memory exception occurs +#define DMA_INT_PEND (0x00000001) // interrupt pending, set when TC=1 +#define DMA_READ_ONLY (DMA_TC | DMA_BYTE_ADDR | DMA_REQ_PEND | DMA_PACK_CNT | DMA_ERR_PEND | DMA_INT_PEND) +#define DMA_WRITE_ONLY (DMA_FLUSH) +#define DMA_READ_WRITE (DMA_EN_CNT | DMA_EN_DMA | DMA_WRITE | DMA_RESET | DMA_INT_EN) +#define DMA_CTRL (0) +#define DMA_ADDR (1) +#define DMA_BYTE_COUNT (2) +#define DMA_XTAL (XTAL_25MHz) namespace { @@ -501,9 +532,12 @@ public: sun4_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) , m_maincpu(*this, "maincpu") + , m_timekpr(*this, TIMEKEEPER_TAG) , m_scc1(*this, SCC1_TAG) , m_scc2(*this, SCC2_TAG) , m_fdc(*this, FDC_TAG) + , m_scsibus(*this, "scsibus") + , m_scsi(*this, "scsibus:7:ncr5390") , m_type0space(*this, "type0") , m_type1space(*this, "type1") , m_ram(*this, RAM_TAG) @@ -520,6 +554,8 @@ public: static const device_timer_id TIMER_0 = 0; static const device_timer_id TIMER_1 = 1; + static const device_timer_id TIMER_DMA = 2; + static const device_timer_id TIMER_RESET = 3; DECLARE_READ32_MEMBER( sun4_mmu_r ); DECLARE_WRITE32_MEMBER( sun4_mmu_w ); @@ -535,6 +571,11 @@ public: DECLARE_WRITE8_MEMBER( irq_w ); DECLARE_READ8_MEMBER( fdc_r ); DECLARE_WRITE8_MEMBER( fdc_w ); + DECLARE_READ32_MEMBER( dma_r ); + DECLARE_WRITE32_MEMBER( dma_w ); + + DECLARE_WRITE_LINE_MEMBER( scsi_irq ); + DECLARE_WRITE_LINE_MEMBER( scsi_drq ); DECLARE_WRITE_LINE_MEMBER( scc1_int ); DECLARE_WRITE_LINE_MEMBER( scc2_int ); @@ -549,9 +590,16 @@ public: protected: required_device<mb86901_device> m_maincpu; + + required_device<mk48t12_device> m_timekpr; + required_device<z80scc_device> m_scc1; required_device<z80scc_device> m_scc2; + required_device<n82077aa_device> m_fdc; + required_device<nscsi_bus_device> m_scsibus; + required_device<ncr5390_device> m_scsi; + optional_device<address_map_bank_device> m_type0space, m_type1space; required_device<ram_device> m_ram; required_memory_region m_rom; @@ -562,6 +610,9 @@ protected: UINT8 m_system_enable; UINT32 m_buserr[4]; UINT32 m_counter[4]; + UINT32 m_dma[4]; + int m_scsi_irq; + int m_scsi_drq; private: UINT32 *m_ram_ptr; @@ -578,8 +629,21 @@ private: int m_arch; emu_timer *m_c0_timer, *m_c1_timer; + emu_timer *m_dma_timer; + emu_timer *m_reset_timer; + + UINT32 read_insn_data(UINT8 asi, address_space &space, UINT32 offset, UINT32 mem_mask); + void write_insn_data(UINT8 asi, address_space &space, UINT32 offset, UINT32 data, UINT32 mem_mask); + UINT32 read_insn_data_4c(UINT8 asi, address_space &space, UINT32 offset, UINT32 mem_mask); + void write_insn_data_4c(UINT8 asi, address_space &space, UINT32 offset, UINT32 data, UINT32 mem_mask); + + void dma_set_int_pend(int state); + void dma_update_irq(); + void dma_tick(); + void dma_setup_timer(bool continuing); void start_timer(int num); + void l2p_command(int ref, int params, const char **param); void fcodes_command(int ref, int params, const char **param); }; @@ -613,6 +677,102 @@ UINT32 sun4_state::bw2_update(screen_device &screen, bitmap_rgb32 &bitmap, const return 0; } +UINT32 sun4_state::read_insn_data_4c(UINT8 asi, address_space &space, UINT32 offset, UINT32 mem_mask) +{ + // it's translation time + UINT8 pmeg = m_segmap[m_context & m_ctx_mask][(offset >> 16) & 0xfff] & m_pmeg_mask; + UINT32 entry = (pmeg << 6) + ((offset >> 10) & 0x3f); + + if (m_pagemap[entry] & PM_VALID) + { + m_pagemap[entry] |= PM_ACCESSED; + + UINT32 tmp = (m_pagemap[entry] & 0xffff) << 10; + tmp |= (offset & 0x3ff); + + //printf("sun4: read translated vaddr %08x to phys %08x type %d, PTE %08x, PC=%x\n", offset<<2, tmp<<2, (m_pagemap[entry]>>26) & 3, m_pagemap[entry], m_maincpu->pc()); + + switch ((m_pagemap[entry] >> 26) & 3) + { + case 0: // type 0 space + return m_type0space->read32(space, tmp, mem_mask); + + case 1: // type 1 space + // magic EPROM bypass + if ((tmp >= (0x6000000>>2)) && (tmp <= (0x6ffffff>>2))) + { + return m_rom_ptr[offset & 0x1ffff]; + } + //printf("Read type 1 @ VA %08x, phys %08x\n", offset<<2, tmp<<2); + return m_type1space->read32(space, tmp, mem_mask); + + default: + printf("sun4c: access to memory type not defined in sun4c\n"); + return 0; + } + } + else + { + if (!space.debugger_access()) + { + printf("sun4c: INVALID PTE entry %d %08x accessed! vaddr=%x PC=%x\n", entry, m_pagemap[entry], offset <<2, m_maincpu->pc()); + //m_maincpu->trap(SPARC_DATA_ACCESS_EXCEPTION); + //m_buserr[0] = 0x88; // read, invalid PTE + //m_buserr[1] = offset<<2; + } + return 0; + } +} + +void sun4_state::write_insn_data_4c(UINT8 asi, address_space &space, UINT32 offset, UINT32 data, UINT32 mem_mask) +{ + // it's translation time + UINT8 pmeg = m_segmap[m_context & m_ctx_mask][(offset >> 16) & 0xfff] & m_pmeg_mask; + UINT32 entry = (pmeg << 6) + ((offset >> 10) & 0x3f); + + if (m_pagemap[entry] & PM_VALID) + { + if ((!(m_pagemap[entry] & PM_WRITEMASK)) || ((m_pagemap[entry] & PM_SYSMASK) && !(asi & 1))) + { + printf("sun4c: write protect MMU error (PC=%x)\n", m_maincpu->pc()); + m_buserr[0] = 0x8040; // write, protection error + m_buserr[1] = offset<<2; + m_maincpu->set_input_line(SPARC_MAE, ASSERT_LINE); + return; + } + + m_pagemap[entry] |= (PM_ACCESSED | PM_MODIFIED); + + UINT32 tmp = (m_pagemap[entry] & 0xffff) << 10; + tmp |= (offset & 0x3ff); + + //printf("sun4: write translated vaddr %08x to phys %08x type %d, PTE %08x, ASI %d, PC=%x\n", offset<<2, tmp<<2, (m_pagemap[entry]>>26) & 3, m_pagemap[entry], asi, m_maincpu->pc()); + + switch ((m_pagemap[entry] >> 26) & 3) + { + case 0: // type 0 + m_type0space->write32(space, tmp, data, mem_mask); + return; + + case 1: // type 1 + //printf("write device space @ %x\n", tmp<<1); + m_type1space->write32(space, tmp, data, mem_mask); + return; + default: + printf("sun4c: access to memory type not defined\n"); + return; + } + } + else + { + printf("sun4c: INVALID PTE entry %d %08x accessed! vaddr=%x PC=%x\n", entry, m_pagemap[entry], offset <<2, m_maincpu->pc()); + //m_maincpu->trap(SPARC_DATA_ACCESS_EXCEPTION); + //m_buserr[0] = 0x8; // invalid PTE + //m_buserr[1] = offset<<2; + } +} + + READ32_MEMBER( sun4_state::sun4c_mmu_r ) { UINT8 asi = m_maincpu->get_asi(); @@ -691,58 +851,12 @@ READ32_MEMBER( sun4_state::sun4c_mmu_r ) page += (offset >> 10) & 0x3f; //printf("sun4: read page map @ %x (entry %d, seg %d, PMEG %d, mem_mask %08x, PC=%x)\n", offset << 2, page, (offset >> 16) & 0xfff, m_segmap[m_context & m_ctx_mask][(offset >> 16) & 0xfff] & m_pmeg_mask, mem_mask, m_maincpu->pc()); return m_pagemap[page]; - break; case 8: case 9: case 10: case 11: - { - // it's translation time - UINT8 pmeg = m_segmap[m_context & m_ctx_mask][(offset >> 16) & 0xfff] & m_pmeg_mask; - UINT32 entry = (pmeg << 6) + ((offset >> 10) & 0x3f); - - if (m_pagemap[entry] & PM_VALID) - { - m_pagemap[entry] |= PM_ACCESSED; - - UINT32 tmp = (m_pagemap[entry] & 0xffff) << 10; - tmp |= (offset & 0x3ff); - - //printf("sun4: read translated vaddr %08x to phys %08x type %d, PTE %08x, PC=%x\n", offset<<2, tmp<<2, (m_pagemap[entry]>>26) & 3, m_pagemap[entry], m_maincpu->pc()); - - switch ((m_pagemap[entry] >> 26) & 3) - { - case 0: // type 0 space - return m_type0space->read32(space, tmp, mem_mask); - - case 1: // type 1 space - // magic EPROM bypass - if ((tmp >= (0x6000000>>2)) && (tmp <= (0x6ffffff>>2))) - { - return m_rom_ptr[offset & 0x1ffff]; - } - //printf("Read type 1 @ VA %08x, phys %08x\n", offset<<2, tmp<<2); - return m_type1space->read32(space, tmp, mem_mask); - - default: - printf("sun4c: access to memory type not defined in sun4c\n"); - return 0; - } - } - else - { - if (!space.debugger_access()) - { - printf("sun4c: INVALID PTE entry %d %08x accessed! vaddr=%x PC=%x\n", entry, m_pagemap[entry], offset <<2, m_maincpu->pc()); - //m_maincpu->trap(SPARC_DATA_ACCESS_EXCEPTION); - //m_buserr[0] = 0x88; // read, invalid PTE - //m_buserr[1] = offset<<2; - } - return 0; - } - } - break; + return read_insn_data_4c(asi, space, offset, mem_mask); default: if (!space.debugger_access()) printf("sun4c: ASI %d unhandled read @ %x (PC=%x)\n", asi, offset<<2, m_maincpu->pc()); @@ -773,6 +887,13 @@ WRITE32_MEMBER( sun4_state::sun4c_mmu_w ) case 4: // system enable reg m_system_enable = data>>24; + + if (m_system_enable & ENA_RESET) + { + m_reset_timer->adjust(attotime::from_usec(1)); + m_maincpu->set_input_line(SPARC_RESET, ASSERT_LINE); + printf("Asserting reset line\n"); + } //printf("%08x to system enable, mask %08x\n", data, mem_mask); if (m_system_enable & ENA_RESET) { @@ -781,7 +902,7 @@ WRITE32_MEMBER( sun4_state::sun4c_mmu_w ) m_maincpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE); } return; - + case 6: // bus error printf("%08x to bus error @ %x, mask %08x\n", data, offset, mem_mask); m_buserr[offset & 0xf] = data; @@ -832,64 +953,107 @@ WRITE32_MEMBER( sun4_state::sun4c_mmu_w ) COMBINE_DATA(&m_pagemap[page]); m_pagemap[page] &= 0xff00ffff; // these 8 bits are cleared when written and tested as such return; + case 8: case 9: case 10: case 11: - // it's translation time - UINT8 pmeg = m_segmap[m_context & m_ctx_mask][(offset >> 16) & 0xfff] & m_pmeg_mask; - UINT32 entry = (pmeg << 6) + ((offset >> 10) & 0x3f); + write_insn_data_4c(asi, space, offset, data, mem_mask); + return; - if (m_pagemap[entry] & PM_VALID) - { - if ((!(m_pagemap[entry] & PM_WRITEMASK)) || - ((m_pagemap[entry] & PM_SYSMASK) && !(asi & 1))) - { - printf("sun4c: write protect MMU error (PC=%x)\n", m_maincpu->pc()); - m_buserr[0] = 0x8040; // write, protection error - m_buserr[1] = offset<<2; - m_maincpu->set_input_line(SPARC_MAE, ASSERT_LINE); - return; - } + } - m_pagemap[entry] |= (PM_ACCESSED | PM_MODIFIED); + printf("sun4c: %08x to asi %d byte offset %x, PC = %x, mask = %08x\n", data, asi, offset << 2, m_maincpu->pc(), mem_mask); +} - UINT32 tmp = (m_pagemap[entry] & 0xffff) << 10; - tmp |= (offset & 0x3ff); +// ----------------------------------------------------------------- - //printf("sun4: write translated vaddr %08x to phys %08x type %d, PTE %08x, ASI %d, PC=%x\n", offset<<2, tmp<<2, (m_pagemap[entry]>>26) & 3, m_pagemap[entry], asi, m_maincpu->pc()); +UINT32 sun4_state::read_insn_data(UINT8 asi, address_space &space, UINT32 offset, UINT32 mem_mask) +{ + // it's translation time + UINT8 pmeg = m_segmap[m_context][(offset >> 16) & 0xfff]; + UINT32 entry = (pmeg << 5) + ((offset >> 11) & 0x1f); - switch ((m_pagemap[entry] >> 26) & 3) - { - case 0: // type 0 - m_type0space->write32(space, tmp, data, mem_mask); - return; + if (m_pagemap[entry] & PM_VALID) + { + m_pagemap[entry] |= PM_ACCESSED; - case 1: // type 1 - //printf("write device space @ %x\n", tmp<<1); - m_type1space->write32(space, tmp, data, mem_mask); - return; - default: - printf("sun4c: access to memory type not defined\n"); - return; + UINT32 tmp = (m_pagemap[entry] & 0x7ffff) << 11; + tmp |= (offset & 0x7ff); + + //printf("sun4: read translated vaddr %08x to phys %08x type %d, PTE %08x, PC=%x\n", offset<<2, tmp<<2, (m_pagemap[entry]>>26) & 3, m_pagemap[entry], m_maincpu->pc()); + + switch ((m_pagemap[entry] >> 26) & 3) + { + case 0: // type 0 space + return m_type0space->read32(space, tmp, mem_mask); + + case 1: // type 1 space + // magic EPROM bypass + if ((tmp >= (0x6000000>>2)) && (tmp <= (0x6ffffff>>2))) + { + return m_rom_ptr[offset & 0x1ffff]; } + //printf("Read type 1 @ VA %08x, phys %08x\n", offset<<2, tmp<<2); + return m_type1space->read32(space, tmp, mem_mask); + + default: + printf("sun4: access to unhandled memory type\n"); + return 0; } - else + } + else + { + if (!space.debugger_access()) { - printf("sun4c: INVALID PTE entry %d %08x accessed! vaddr=%x PC=%x\n", entry, m_pagemap[entry], offset <<2, m_maincpu->pc()); + printf("sun4: INVALID PTE entry %d %08x accessed! vaddr=%x PC=%x\n", entry, m_pagemap[entry], offset <<2, m_maincpu->pc()); //m_maincpu->trap(SPARC_DATA_ACCESS_EXCEPTION); - //m_buserr[0] = 0x8; // invalid PTE + //m_buserr[0] = 0x88; // read, invalid PTE //m_buserr[1] = offset<<2; - return; } - break; - + return 0; } - - printf("sun4c: %08x to asi %d byte offset %x, PC = %x, mask = %08x\n", data, asi, offset << 2, m_maincpu->pc(), mem_mask); } -// ----------------------------------------------------------------- +void sun4_state::write_insn_data(UINT8 asi, address_space &space, UINT32 offset, UINT32 data, UINT32 mem_mask) +{ + // it's translation time + UINT8 pmeg = m_segmap[m_context][(offset >> 16) & 0xfff]; + UINT32 entry = (pmeg << 5) + ((offset >> 11) & 0x1f); + + if (m_pagemap[entry] & PM_VALID) + { + m_pagemap[entry] |= PM_ACCESSED; + + UINT32 tmp = (m_pagemap[entry] & 0x7ffff) << 11; + tmp |= (offset & 0x7ff); + + //printf("sun4: write translated vaddr %08x to phys %08x type %d, PTE %08x, PC=%x\n", offset<<2, tmp<<2, (m_pagemap[entry]>>26) & 3, m_pagemap[entry], m_maincpu->pc()); + + switch ((m_pagemap[entry] >> 26) & 3) + { + case 0: // type 0 + m_type0space->write32(space, tmp, data, mem_mask); + return; + + case 1: // type 1 + //printf("write device space @ %x\n", tmp<<1); + m_type1space->write32(space, tmp, data, mem_mask); + return; + + default: + printf("sun4: access to memory type not defined in sun4c\n"); + return; + } + } + else + { + printf("sun4: INVALID PTE entry %d %08x accessed! vaddr=%x PC=%x\n", entry, m_pagemap[entry], offset <<2, m_maincpu->pc()); + //m_maincpu->trap(SPARC_DATA_ACCESS_EXCEPTION); + //m_buserr[0] = 0x8; // invalid PTE + //m_buserr[1] = offset<<2; + } +} READ32_MEMBER( sun4_state::sun4_mmu_r ) { @@ -973,52 +1137,7 @@ READ32_MEMBER( sun4_state::sun4_mmu_r ) case 9: case 10: case 11: - { - // it's translation time - UINT8 pmeg = m_segmap[m_context][(offset >> 16) & 0xfff]; - UINT32 entry = (pmeg << 5) + ((offset >> 11) & 0x1f); - - if (m_pagemap[entry] & PM_VALID) - { - m_pagemap[entry] |= PM_ACCESSED; - - UINT32 tmp = (m_pagemap[entry] & 0x7ffff) << 11; - tmp |= (offset & 0x7ff); - - //printf("sun4: read translated vaddr %08x to phys %08x type %d, PTE %08x, PC=%x\n", offset<<2, tmp<<2, (m_pagemap[entry]>>26) & 3, m_pagemap[entry], m_maincpu->pc()); - - switch ((m_pagemap[entry] >> 26) & 3) - { - case 0: // type 0 space - return m_type0space->read32(space, tmp, mem_mask); - - case 1: // type 1 space - // magic EPROM bypass - if ((tmp >= (0x6000000>>2)) && (tmp <= (0x6ffffff>>2))) - { - return m_rom_ptr[offset & 0x1ffff]; - } - //printf("Read type 1 @ VA %08x, phys %08x\n", offset<<2, tmp<<2); - return m_type1space->read32(space, tmp, mem_mask); - - default: - printf("sun4: access to unhandled memory type\n"); - return 0; - } - } - else - { - if (!space.debugger_access()) - { - printf("sun4: INVALID PTE entry %d %08x accessed! vaddr=%x PC=%x\n", entry, m_pagemap[entry], offset <<2, m_maincpu->pc()); - //m_maincpu->trap(SPARC_DATA_ACCESS_EXCEPTION); - //m_buserr2qor[0] = 0x88; // read, invalid PTE - //m_buserr[1] = offset<<2; - } - return 0; - } - } - break; + return read_insn_data(asi, space, offset, mem_mask); default: if (!space.debugger_access()) printf("sun4: ASI %d unhandled read @ %x (PC=%x)\n", asi, offset<<2, m_maincpu->pc()); @@ -1049,6 +1168,12 @@ WRITE32_MEMBER( sun4_state::sun4_mmu_w ) case 4: // system enable reg m_system_enable = data>>24; + + if (m_system_enable & ENA_RESET) + { + m_reset_timer->adjust(attotime::from_usec(1)); + m_maincpu->set_input_line(SPARC_RESET, ASSERT_LINE); + } //printf("%08x to system enable, mask %08x\n", data, mem_mask); if (m_system_enable & ENA_RESET) { @@ -1129,42 +1254,7 @@ WRITE32_MEMBER( sun4_state::sun4_mmu_w ) case 9: case 10: case 11: - // it's translation time - UINT8 pmeg = m_segmap[m_context][(offset >> 16) & 0xfff]; - UINT32 entry = (pmeg << 5) + ((offset >> 11) & 0x1f); - - if (m_pagemap[entry] & PM_VALID) - { - m_pagemap[entry] |= PM_ACCESSED; - - UINT32 tmp = (m_pagemap[entry] & 0x7ffff) << 11; - tmp |= (offset & 0x7ff); - - //printf("sun4: write translated vaddr %08x to phys %08x type %d, PTE %08x, PC=%x\n", offset<<2, tmp<<2, (m_pagemap[entry]>>26) & 3, m_pagemap[entry], m_maincpu->pc()); - - switch ((m_pagemap[entry] >> 26) & 3) - { - case 0: // type 0 - m_type0space->write32(space, tmp, data, mem_mask); - return; - - case 1: // type 1 - //printf("write device space @ %x\n", tmp<<1); - m_type1space->write32(space, tmp, data, mem_mask); - return; - default: - printf("sun4: access to memory type not defined in sun4c\n"); - return; - } - } - else - { - printf("sun4: INVALID PTE entry %d %08x accessed! vaddr=%x PC=%x\n", entry, m_pagemap[entry], offset <<2, m_maincpu->pc()); - //m_maincpu->trap(SPARC_DATA_ACCESS_EXCEPTION); - //m_buserror[0] = 0x8; // invalid PTE - //m_buserror[1] = offset<<2; - return; - } + write_insn_data(asi, space, offset, data, mem_mask); break; } @@ -1249,7 +1339,28 @@ void sun4_state::machine_reset() m_system_enable = 0; m_irq_reg = 0; m_scc1_int = m_scc2_int = 0; + m_scsi_irq = 0; + m_scsi_drq = 0; + + for (UINT32 i = 0; i < (0x7f8 - 0x7d7); i++) + { + m_timekpr->write(m_maincpu->space(AS_PROGRAM), 0x7d7 + i, 0); + } + + m_timekpr->write(m_maincpu->space(AS_PROGRAM), 0x7d9, 0x12); + m_timekpr->write(m_maincpu->space(AS_PROGRAM), 0x7e4, 0x34); + m_timekpr->write(m_maincpu->space(AS_PROGRAM), 0x7e5, 0x56); + m_timekpr->write(m_maincpu->space(AS_PROGRAM), 0x7e6, 0x78); + + m_timekpr->write(m_maincpu->space(AS_PROGRAM), 0x7da, 0x11); + m_timekpr->write(m_maincpu->space(AS_PROGRAM), 0x7db, 0x22); + m_timekpr->write(m_maincpu->space(AS_PROGRAM), 0x7dc, 0x33); + m_timekpr->write(m_maincpu->space(AS_PROGRAM), 0x7dd, 0x44); + m_timekpr->write(m_maincpu->space(AS_PROGRAM), 0x7de, 0x55); + m_timekpr->write(m_maincpu->space(AS_PROGRAM), 0x7df, 0x66); + memset(m_counter, 0, sizeof(m_counter)); + memset(m_dma, 0, sizeof(m_dma)); } void sun4_state::machine_start() @@ -1273,6 +1384,14 @@ void sun4_state::machine_start() m_c1_timer = timer_alloc(TIMER_1); m_c0_timer->adjust(attotime::never); m_c1_timer->adjust(attotime::never); + + // allocate timer for system reset + m_reset_timer = timer_alloc(TIMER_RESET); + m_reset_timer->adjust(attotime::never); + + // allocate timer for DMA controller + m_dma_timer = timer_alloc(TIMER_DMA); + m_dma_timer->adjust(attotime::never); } READ32_MEMBER( sun4_state::ram_r ) @@ -1363,6 +1482,8 @@ static ADDRESS_MAP_START(type1space_map, AS_PROGRAM, 32, sun4_state) AM_RANGE(0x06000000, 0x0607ffff) AM_ROM AM_REGION("user1", 0) AM_RANGE(0x07200000, 0x07200003) AM_READWRITE8(fdc_r, fdc_w, 0xffffffff) AM_RANGE(0x08000000, 0x08000003) AM_READ(ss1_sl0_id) // slot 0 contains SCSI/DMA/Ethernet + AM_RANGE(0x08400000, 0x0840000f) AM_READWRITE(dma_r, dma_w) + AM_RANGE(0x08800000, 0x0880001f) AM_DEVICE8("scsibus:7:ncr5390", ncr5390_device, map, 0xff0000) AM_RANGE(0x0e000000, 0x0e000003) AM_READ(ss1_sl3_id) // slot 3 contains video board AM_RANGE(0x0e800000, 0x0e8fffff) AM_RAM AM_SHARE("bw2_vram") ADDRESS_MAP_END @@ -1470,6 +1591,16 @@ void sun4_state::device_timer(emu_timer &timer, device_timer_id id, int param, v //printf("Taking INT14\n"); } break; + + case TIMER_DMA: + dma_tick(); + break; + + case TIMER_RESET: + m_reset_timer->adjust(attotime::never); + m_maincpu->set_input_line(SPARC_RESET, CLEAR_LINE); + printf("Clearing reset line\n"); + break; } } @@ -1551,6 +1682,246 @@ WRITE32_MEMBER( sun4_state::timer_w ) } } +void sun4_state::dma_set_int_pend(int state) +{ + if (!state) + { + m_dma[DMA_CTRL] &= ~DMA_INT_PEND; + } + else + { + m_dma[DMA_CTRL] |= DMA_INT_PEND; + } + + dma_update_irq(); +} + +void sun4_state:: dma_update_irq() +{ + int irq_or_err_pending = (m_dma[DMA_CTRL] & (DMA_INT_PEND | DMA_ERR_PEND)) ? 1 : 0; + int irq_enabled = (m_dma[DMA_CTRL] & DMA_INT_EN) ? 1 : 0; + if (irq_or_err_pending && irq_enabled) + { + m_maincpu->set_input_line(SPARC_IRQ3, ASSERT_LINE); + } + else + { + m_maincpu->set_input_line(SPARC_IRQ3, CLEAR_LINE); + } +} + +void sun4_state::dma_tick() +{ + UINT32 transfer_size = (m_dma[DMA_BYTE_COUNT] > PAGE_SIZE ? PAGE_SIZE : m_dma[DMA_BYTE_COUNT]); + address_space &space = m_maincpu->space(AS_PROGRAM); + + if (m_dma[DMA_CTRL] & DMA_WRITE) + { + UINT32 data = 0; + UINT32 byte_cnt = 3; + UINT32 mem_mask = 0; + while (transfer_size > 0) + { + UINT8 value = m_scsi->dma_r(); + data |= value << (byte_cnt * 8); + mem_mask |= 0xff << (byte_cnt * 8); + transfer_size--; + + if (byte_cnt == 0) + { + if (m_arch == ARCH_SUN4C) + { + write_insn_data_4c(11, space, m_dma[DMA_ADDR] >> 2, data, mem_mask); + } + else + { + write_insn_data(11, space, m_dma[DMA_ADDR] >> 2, data, mem_mask); + } + m_dma[DMA_ADDR] += 4; + m_dma[DMA_BYTE_COUNT] -= 4; + + byte_cnt = 3; + data = 0; + mem_mask = 0; + } + else + { + byte_cnt--; + } + } + + if (byte_cnt != 0) + { + if (m_arch == ARCH_SUN4C) + { + write_insn_data_4c(11, space, m_dma[DMA_ADDR] >> 2, data, mem_mask); + } + else + { + write_insn_data(11, space, m_dma[DMA_ADDR] >> 2, data, mem_mask); + } + + m_dma[DMA_ADDR] += byte_cnt; + m_dma[DMA_BYTE_COUNT] -= byte_cnt; + } + } + else + { + UINT32 byte_cnt = 3; + UINT32 mem_mask = 0; + while (transfer_size > 0) + { + mem_mask |= 0xff << (byte_cnt * 8); + transfer_size--; + + if (byte_cnt == 0) + { + UINT32 data = 0; + if (m_arch == ARCH_SUN4C) + { + data = read_insn_data_4c(11, space, m_dma[DMA_ADDR] >> 2, mem_mask); + } + else + { + data = read_insn_data(11, space, m_dma[DMA_ADDR] >> 2, mem_mask); + } + + for (int i = 24; i >= 0; i -= 8) + { + m_scsi->dma_w((data >> i) & 0xff); + m_dma[DMA_BYTE_COUNT]--; + } + + byte_cnt = 3; + mem_mask = 0; + } + else + { + byte_cnt--; + } + } + + if (byte_cnt != 0) + { + byte_cnt++; + UINT32 data = 0; + if (m_arch == ARCH_SUN4C) + { + data = read_insn_data_4c(11, space, m_dma[DMA_ADDR] >> 2, mem_mask); + } + else + { + data = read_insn_data(11, space, m_dma[DMA_ADDR] >> 2, mem_mask); + } + + UINT32 initial_cnt = byte_cnt; + for (int i = 0; i < 4 - initial_cnt; i++) + { + UINT8 byte_val = (data >> (byte_cnt * 8)) & 0xff; + m_scsi->dma_w(byte_val); + + m_dma[DMA_BYTE_COUNT]--; + byte_cnt--; + } + } + } + + if (m_dma[DMA_BYTE_COUNT] == 0) + { + m_dma[DMA_CTRL] |= DMA_TC; + dma_set_int_pend(1); + m_dma_timer->adjust(attotime::never); + } + else + { + dma_setup_timer(true); + } +} + +void sun4_state::dma_setup_timer(bool continuing) +{ + const UINT32 remaining_bytes = m_dma[DMA_BYTE_COUNT]; + const UINT64 latency = (continuing ? 0 : 40); + const UINT64 transfer_size = (remaining_bytes < PAGE_SIZE ? remaining_bytes : PAGE_SIZE); + const UINT64 transfer_duration = ((transfer_size + 15) / 16) * 8; // 16 byte groupings, 8 clock cycles per group + const UINT64 total_ticks = latency + transfer_duration; + + m_dma_timer->adjust(attotime::from_ticks(total_ticks, DMA_XTAL)); + + if (!continuing) + { + m_dma[DMA_CTRL] &= DMA_TC; + } +} + +READ32_MEMBER( sun4_state::dma_r ) +{ + return m_dma[offset]; +} + +WRITE32_MEMBER( sun4_state::dma_w ) +{ + switch (offset) + { + case DMA_CTRL: + { + // clear write-only bits + UINT32 old_ctrl = m_dma[DMA_CTRL]; + + m_dma[DMA_CTRL] &= (DMA_READ_ONLY | DMA_READ_WRITE); + + m_dma[DMA_CTRL] |= (data & (DMA_WRITE_ONLY | DMA_READ_WRITE)); + + if (data & DMA_FLUSH) + { + m_dma[DMA_CTRL] &= ~DMA_PACK_CNT; + m_dma[DMA_CTRL] &= ~DMA_ERR_PEND; + m_dma[DMA_CTRL] &= ~DMA_TC; + + if (!m_scsi_irq) + { + dma_set_int_pend(0); + } + } + + if (data & DMA_EN_DMA && !(old_ctrl & DMA_EN_DMA)) + { + dma_setup_timer(false); + } + break; + } + + case DMA_ADDR: + case DMA_BYTE_COUNT: + m_dma[offset] = data; + break; + + default: + break; + } +} + +WRITE_LINE_MEMBER( sun4_state::scsi_irq ) +{ + if (!(m_dma[DMA_CTRL] & DMA_TC)) + { + dma_set_int_pend(state); + } + m_scsi_irq = state; +} + +WRITE_LINE_MEMBER( sun4_state::scsi_drq ) +{ + if (state) + { + if (m_dma[DMA_CTRL] & DMA_EN_DMA) + { + dma_setup_timer(false); + } + } + m_scsi_drq = state; +} + // indicate 4/60 SCSI/DMA/Ethernet card exists READ32_MEMBER( sun4_state::ss1_sl0_id ) { @@ -1571,17 +1942,17 @@ static SLOT_INTERFACE_START( sun_floppies ) SLOT_INTERFACE( "35hd", FLOPPY_35_HD ) SLOT_INTERFACE_END -//static SLOT_INTERFACE_START( sun_scsi_devices ) - //SLOT_INTERFACE("cdrom", NSCSI_CDROM) - //SLOT_INTERFACE("harddisk", NSCSI_HARDDISK) - //SLOT_INTERFACE_INTERNAL("ncr5390", NCR5390) -//SLOT_INTERFACE_END +static SLOT_INTERFACE_START( sun_scsi_devices ) + SLOT_INTERFACE("cdrom", NSCSI_CDROM) + SLOT_INTERFACE("harddisk", NSCSI_HARDDISK) + SLOT_INTERFACE_INTERNAL("ncr5390", NCR5390) +SLOT_INTERFACE_END -//static MACHINE_CONFIG_FRAGMENT( ncr5390 ) - //MCFG_DEVICE_CLOCK(10000000) - //MCFG_NCR5390_IRQ_HANDLER(DEVWRITELINE(":", next_state, scsi_irq)) - //MCFG_NCR5390_DRQ_HANDLER(DEVWRITELINE(":", next_state, scsi_drq)) -//MACHINE_CONFIG_END +static MACHINE_CONFIG_FRAGMENT( ncr5390 ) + MCFG_DEVICE_CLOCK(10000000) + MCFG_NCR5390_IRQ_HANDLER(DEVWRITELINE(":", sun4_state, scsi_irq)) + MCFG_NCR5390_DRQ_HANDLER(DEVWRITELINE(":", sun4_state, scsi_drq)) +MACHINE_CONFIG_END static MACHINE_CONFIG_START( sun4, sun4_state ) /* basic machine hardware */ @@ -1593,7 +1964,7 @@ static MACHINE_CONFIG_START( sun4, sun4_state ) MCFG_RAM_DEFAULT_SIZE("16M") MCFG_RAM_DEFAULT_VALUE(0x00) - MCFG_M48T02_ADD(TIMEKEEPER_TAG) + MCFG_MK48T12_ADD(TIMEKEEPER_TAG) MCFG_N82077AA_ADD(FDC_TAG, n82077aa_device::MODE_PS2) MCFG_FLOPPY_DRIVE_ADD("fdc:0", sun_floppies, "35hd", sun4_state::floppy_formats) @@ -1636,15 +2007,16 @@ static MACHINE_CONFIG_START( sun4, sun4_state ) MCFG_RS232_DCD_HANDLER(DEVWRITELINE(SCC2_TAG, z80scc_device, dcdb_w)) MCFG_RS232_CTS_HANDLER(DEVWRITELINE(SCC2_TAG, z80scc_device, ctsb_w)) - //MCFG_NSCSI_ADD("scsibus:0", next_scsi_devices, "harddisk", false) - //MCFG_NSCSI_ADD("scsibus:1", next_scsi_devices, "cdrom", false) - //MCFG_NSCSI_ADD("scsibus:2", next_scsi_devices, nullptr, false) - //MCFG_NSCSI_ADD("scsibus:3", next_scsi_devices, nullptr, false) - //MCFG_NSCSI_ADD("scsibus:4", next_scsi_devices, nullptr, false) - //MCFG_NSCSI_ADD("scsibus:5", next_scsi_devices, nullptr, false) - //MCFG_NSCSI_ADD("scsibus:6", next_scsi_devices, nullptr, false) - //MCFG_NSCSI_ADD("scsibus:7", next_scsi_devices, SCSI_TAG, true) - //MCFG_DEVICE_CARD_MACHINE_CONFIG(SCSI_TAG, ncr5390) + MCFG_NSCSI_BUS_ADD("scsibus") + MCFG_NSCSI_ADD("scsibus:0", sun_scsi_devices, "harddisk", false) + MCFG_NSCSI_ADD("scsibus:1", sun_scsi_devices, "cdrom", false) + MCFG_NSCSI_ADD("scsibus:2", sun_scsi_devices, nullptr, false) + MCFG_NSCSI_ADD("scsibus:3", sun_scsi_devices, nullptr, false) + MCFG_NSCSI_ADD("scsibus:4", sun_scsi_devices, nullptr, false) + MCFG_NSCSI_ADD("scsibus:5", sun_scsi_devices, nullptr, false) + MCFG_NSCSI_ADD("scsibus:6", sun_scsi_devices, nullptr, false) + MCFG_NSCSI_ADD("scsibus:7", sun_scsi_devices, "ncr5390", true) + MCFG_DEVICE_CARD_MACHINE_CONFIG("ncr5390", ncr5390) MACHINE_CONFIG_END static MACHINE_CONFIG_START( sun4c, sun4_state ) @@ -1657,7 +2029,7 @@ static MACHINE_CONFIG_START( sun4c, sun4_state ) MCFG_RAM_DEFAULT_SIZE("16M") MCFG_RAM_DEFAULT_VALUE(0x00) - MCFG_M48T02_ADD(TIMEKEEPER_TAG) + MCFG_MK48T12_ADD(TIMEKEEPER_TAG) MCFG_N82077AA_ADD(FDC_TAG, n82077aa_device::MODE_PS2) MCFG_FLOPPY_DRIVE_ADD("fdc:0", sun_floppies, "35hd", sun4_state::floppy_formats) @@ -1700,6 +2072,17 @@ static MACHINE_CONFIG_START( sun4c, sun4_state ) MCFG_RS232_DCD_HANDLER(DEVWRITELINE(SCC2_TAG, z80scc_device, dcdb_w)) MCFG_RS232_CTS_HANDLER(DEVWRITELINE(SCC2_TAG, z80scc_device, ctsb_w)) + MCFG_NSCSI_BUS_ADD("scsibus") + MCFG_NSCSI_ADD("scsibus:0", sun_scsi_devices, "harddisk", false) + MCFG_NSCSI_ADD("scsibus:1", sun_scsi_devices, "cdrom", false) + MCFG_NSCSI_ADD("scsibus:2", sun_scsi_devices, nullptr, false) + MCFG_NSCSI_ADD("scsibus:3", sun_scsi_devices, nullptr, false) + MCFG_NSCSI_ADD("scsibus:4", sun_scsi_devices, nullptr, false) + MCFG_NSCSI_ADD("scsibus:5", sun_scsi_devices, nullptr, false) + MCFG_NSCSI_ADD("scsibus:6", sun_scsi_devices, nullptr, false) + MCFG_NSCSI_ADD("scsibus:7", sun_scsi_devices, "ncr5390", true) + MCFG_DEVICE_CARD_MACHINE_CONFIG("ncr5390", ncr5390) + MCFG_SCREEN_ADD("bwtwo", RASTER) MCFG_SCREEN_UPDATE_DRIVER(sun4_state, bw2_update) MCFG_SCREEN_SIZE(1152,900) diff --git a/src/osd/modules/render/bgfx/shaders/chains/crt/fs_crt-caligari.sc b/src/osd/modules/render/bgfx/shaders/chains/crt/fs_crt-caligari.sc new file mode 100644 index 00000000000..68d9908983f --- /dev/null +++ b/src/osd/modules/render/bgfx/shaders/chains/crt/fs_crt-caligari.sc @@ -0,0 +1,123 @@ +$input v_color0, v_texcoord0, v_texcoord1 + +// license:BSD-3-Clause +// copyright-holders:caligari + +/* + Phosphor shader - Copyright (C) 2011 caligari. + + Ported by Hyllian. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#define onex v_texcoord1.xy +#define oney v_texcoord1.zw + +#include "common.sh" + +// Autos +uniform vec4 u_source_size; + +// User-supplied +uniform vec4 SPOT_WIDTH; +uniform vec4 SPOT_HEIGHT; +uniform vec4 COLOR_BOOST; +uniform vec4 InputGamma; +uniform vec4 OutputGamma; + +// Samplers +SAMPLER2D(s_p, 0); + +#define GAMMA_IN(color) pow(color, InputGamma.xxxx) +#define GAMMA_OUT(color) pow(color, 1.0 / OutputGamma.xxxx) + +#define TEX2D(coords) GAMMA_IN( texture2D(s_p, coords) ) + +// Macro for weights computing +#define WEIGHT(w) \ + if(w > 1.0) w = 1.0; \ + w = 1.0 - w * w; \ + w = w * w; + +void main() +{ + vec2 coords = v_texcoord0 * u_source_size.xy; + vec2 pixel_center = floor(coords) + vec2(0.5, 0.5); + vec2 texture_coords = pixel_center / u_source_size.xy; + + vec4 color = TEX2D(texture_coords); + + float dx = coords.x - pixel_center.x; + + float h_weight_00 = dx / SPOT_WIDTH.x; + WEIGHT(h_weight_00); + + color *= vec4(h_weight_00, h_weight_00, h_weight_00, h_weight_00 ); + + // get closest horizontal neighbour to blend + vec2 coords01; + if (dx > 0.0) + { + coords01 = onex; + dx = 1.0 - dx; + } + else + { + coords01 = -onex; + dx = 1.0 + dx; + } + vec4 colorNB = TEX2D(texture_coords + coords01); + + float h_weight_01 = dx / SPOT_WIDTH.x; + WEIGHT(h_weight_01); + + color = color + colorNB * vec4(h_weight_01, h_weight_01, h_weight_01, h_weight_01); + + ////////////////////////////////////////////////////// + // Vertical Blending + float dy = coords.y - pixel_center.y; + float v_weight_00 = dy / SPOT_HEIGHT.x; + WEIGHT(v_weight_00); + color *= vec4(v_weight_00, v_weight_00, v_weight_00, v_weight_00); + + // get closest vertical neighbour to blend + vec2 coords10; + if (dy > 0.0) + { + coords10 = oney; + dy = 1.0 - dy; + } + else + { + coords10 = -oney; + dy = 1.0 + dy; + } + colorNB = TEX2D(texture_coords + coords10); + + float v_weight_10 = dy / SPOT_HEIGHT.x; + WEIGHT(v_weight_10); + + color = color + colorNB * vec4(v_weight_10 * h_weight_00, v_weight_10 * h_weight_00, v_weight_10 * h_weight_00, v_weight_10 * h_weight_00); + + colorNB = TEX2D(texture_coords + coords01 + coords10); + + color = color + colorNB * vec4(v_weight_10 * h_weight_01, v_weight_10 * h_weight_01, v_weight_10 * h_weight_01, v_weight_10 * h_weight_01); + + color *= COLOR_BOOST.xxxx; + + gl_FragColor = clamp(GAMMA_OUT(color), 0.0, 1.0); +} diff --git a/src/osd/modules/render/bgfx/shaders/chains/crt/varying.def.sc b/src/osd/modules/render/bgfx/shaders/chains/crt/varying.def.sc new file mode 100644 index 00000000000..8404fc635e1 --- /dev/null +++ b/src/osd/modules/render/bgfx/shaders/chains/crt/varying.def.sc @@ -0,0 +1,7 @@ +vec4 v_color0 : COLOR0 = vec4(1.0, 0.0, 0.0, 1.0); +vec2 v_texcoord0 : TEXCOORD0 = vec2(0.0, 0.0); +vec4 v_texcoord1 : TEXCOORD1 = vec4(0.0, 0.0, 0.0, 0.0); + +vec3 a_position : POSITION; +vec4 a_color0 : COLOR0; +vec2 a_texcoord0 : TEXCOORD0; diff --git a/src/osd/modules/render/bgfx/shaders/chains/crt/vs_crt-caligari.sc b/src/osd/modules/render/bgfx/shaders/chains/crt/vs_crt-caligari.sc new file mode 100644 index 00000000000..37a119ec7d4 --- /dev/null +++ b/src/osd/modules/render/bgfx/shaders/chains/crt/vs_crt-caligari.sc @@ -0,0 +1,45 @@ +$input a_position, a_texcoord0, a_color0 +$output v_texcoord0, v_texcoord1, v_color0 + +// license:BSD-3-Clause +// copyright-holders:caligari + +/* + Phosphor shader - Copyright (C) 2011 caligari. + + Ported by Hyllian. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#define onex v_texcoord1.xy +#define oney v_texcoord1.zw + +#include "common.sh" + +// Autos +uniform vec4 u_source_size; + +void main() +{ + gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0)); + v_texcoord0 = a_texcoord0; + + onex = vec2(1.0 / u_source_size.x, 0.0); + oney = vec2(0.0, 1.0 / u_source_size.y); + + v_color0 = a_color0; +} |