on-chip FRT experiment
This commit is contained in:
parent
843c7ce297
commit
76c4998664
58
main.c
58
main.c
@ -2,6 +2,7 @@
|
|||||||
#include "vdp1.h"
|
#include "vdp1.h"
|
||||||
#include "scu.h"
|
#include "scu.h"
|
||||||
#include "smpc.h"
|
#include "smpc.h"
|
||||||
|
#include "sh2.h"
|
||||||
|
|
||||||
void fill_32(u32 * buf, u32 v, s32 n)
|
void fill_32(u32 * buf, u32 v, s32 n)
|
||||||
{
|
{
|
||||||
@ -16,9 +17,13 @@ void timer0_int(void) __attribute__ ((interrupt_handler));
|
|||||||
void timer0_int(void)
|
void timer0_int(void)
|
||||||
{
|
{
|
||||||
scu.reg.IST &= ~(IST__TIMER0);
|
scu.reg.IST &= ~(IST__TIMER0);
|
||||||
|
}
|
||||||
|
|
||||||
// The SMPC uses the V-BLANK-IN interrupt to execute internal tasks. At this
|
void oci_int(void) __attribute__ ((interrupt_handler));
|
||||||
// time, issuing commands for 300 µs from V-BLANK-IN is prohibited.
|
void oci_int(void)
|
||||||
|
{
|
||||||
|
// clear OCFA
|
||||||
|
sh2.reg.FTCSR &= ~(FTCSR__OCFA);
|
||||||
|
|
||||||
while (smpc.reg.SF != 0) {}
|
while (smpc.reg.SF != 0) {}
|
||||||
|
|
||||||
@ -193,10 +198,53 @@ void start(void)
|
|||||||
|
|
||||||
vec[SCU_VEC__TIMER0] = (u32)(&timer0_int);
|
vec[SCU_VEC__TIMER0] = (u32)(&timer0_int);
|
||||||
vec[SCU_VEC__SMPC] = (u32)(&smpc_int);
|
vec[SCU_VEC__SMPC] = (u32)(&smpc_int);
|
||||||
scu.reg.T0C = 5;
|
//scu.reg.T0C = 5;
|
||||||
scu.reg.T1MD = T1MD__TENB;
|
//scu.reg.T1MD = T1MD__TENB;
|
||||||
|
|
||||||
|
// From the SMPC manual:
|
||||||
|
// The SMPC uses the V-BLANK-IN interrupt to execute internal tasks. At this
|
||||||
|
// time, issuing commands for 300 µs from V-BLANK-IN is prohibited.
|
||||||
|
|
||||||
|
// CLKCHG320 (power-on default) NTSC, the FRC's internal clock is 26.8741 MHz.
|
||||||
|
// The possible periods are then:
|
||||||
|
//
|
||||||
|
// - 0.29768 µs (/8)
|
||||||
|
// - 1.19074 µs (/32)
|
||||||
|
// - 4.76295 µs (/128)
|
||||||
|
//
|
||||||
|
// (1/(26.8741 MHz)) * 128 * 63 = 300.066 µs
|
||||||
|
|
||||||
|
// FRC, OCRA, OCRB, and FCIR are 16-bit registers, but the FRT bus is an 8-bit
|
||||||
|
// bus.
|
||||||
|
|
||||||
|
// TCR set CKS to /128
|
||||||
|
// TOCR set OCRS to OCRA
|
||||||
|
// TIER set OCIAE
|
||||||
|
// FTCSR set CCLRA (clear FRC on compare match A)
|
||||||
|
// VCRC set FOCV
|
||||||
|
// OCRA set 63
|
||||||
|
// FRC set 0
|
||||||
|
|
||||||
|
vec[0x60] = (u32)&oci_int;
|
||||||
|
sh2.reg.VCRC = VCRC__FOCV(0x60);
|
||||||
|
|
||||||
|
sh2.reg.TCR = TCR__CKS__INTERNAL_DIV128;
|
||||||
|
sh2.reg.TOCR = TOCR__OCRS__OCRA;
|
||||||
|
sh2.reg.FTCSR = FTCSR__CCLRA;
|
||||||
|
sh2.reg.OCRAB.H = 0; // Even though Kronos doesn't emulate this, SH7095 says
|
||||||
|
// we are required to write the upper bit prior to
|
||||||
|
// writing the lower byte
|
||||||
|
sh2.reg.OCRAB.L = 63;
|
||||||
|
sh2.reg.FRC.H = 0;
|
||||||
|
sh2.reg.FRC.L = 0;
|
||||||
|
|
||||||
|
// enable output compare interrupt
|
||||||
|
sh2.reg.TIER = TIER__OCIAE;
|
||||||
|
|
||||||
|
// reset/enable interrupts
|
||||||
|
|
||||||
scu.reg.IST = 0;
|
scu.reg.IST = 0;
|
||||||
scu.reg.IMS = ~(IMS__TIMER0 | IMS__SMPC);
|
scu.reg.IMS = ~(IMS__SMPC);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
vec[0] = scu.reg.IST;
|
vec[0] = scu.reg.IST;
|
||||||
|
2
scu.h
2
scu.h
@ -160,5 +160,3 @@ enum scu_vec {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static_assert(SCU_VEC__EXT15 == 0x5f);
|
static_assert(SCU_VEC__EXT15 == 0x5f);
|
||||||
|
|
||||||
extern reg32 vec[0x60] __asm("vec");
|
|
||||||
|
61
sh2.h
61
sh2.h
@ -10,11 +10,20 @@ typedef struct sh2_reg {
|
|||||||
reg8 _res0[10];
|
reg8 _res0[10];
|
||||||
reg8 TIER; // 0x010
|
reg8 TIER; // 0x010
|
||||||
reg8 FTCSR; // 0x011
|
reg8 FTCSR; // 0x011
|
||||||
reg16 FRC; // 0x012
|
struct {
|
||||||
reg16 OCRA_B; // 0x014
|
reg8 H; // 0x012
|
||||||
|
reg8 L; // 0x013
|
||||||
|
} FRC;
|
||||||
|
struct {
|
||||||
|
reg8 H; // 0x014
|
||||||
|
reg8 L; // 0x015
|
||||||
|
} OCRAB;
|
||||||
reg8 TCR; // 0x016
|
reg8 TCR; // 0x016
|
||||||
reg8 TOCR; // 0x017
|
reg8 TOCR; // 0x017
|
||||||
reg16 FICR; // 0x018
|
struct {
|
||||||
|
reg8 H; // 0x018
|
||||||
|
reg8 L; // 0x018
|
||||||
|
} FICR;
|
||||||
reg8 _res1[70];
|
reg8 _res1[70];
|
||||||
reg16 IPRB; // 0x060
|
reg16 IPRB; // 0x060
|
||||||
reg16 VCRA; // 0x062
|
reg16 VCRA; // 0x062
|
||||||
@ -87,7 +96,7 @@ typedef struct sh2_reg {
|
|||||||
} sh2_reg;
|
} sh2_reg;
|
||||||
|
|
||||||
static_assert((sizeof (struct sh2_reg)) == 0x200);
|
static_assert((sizeof (struct sh2_reg)) == 0x200);
|
||||||
static_assert((offsetof (struct sh2_reg, OCRA_B)) == 0x014);
|
static_assert((offsetof (struct sh2_reg, OCRAB)) == 0x014);
|
||||||
static_assert((offsetof (struct sh2_reg, BCR1)) == 0x1e0);
|
static_assert((offsetof (struct sh2_reg, BCR1)) == 0x1e0);
|
||||||
|
|
||||||
struct sh2 {
|
struct sh2 {
|
||||||
@ -95,3 +104,47 @@ struct sh2 {
|
|||||||
};
|
};
|
||||||
|
|
||||||
extern struct sh2 sh2 __asm("sh2");
|
extern struct sh2 sh2 __asm("sh2");
|
||||||
|
|
||||||
|
extern reg32 vec[0xff] __asm("vec");
|
||||||
|
|
||||||
|
enum tier_bits {
|
||||||
|
TIER__ICIE = (1 << 7),
|
||||||
|
TIER__OCIAE = (1 << 3),
|
||||||
|
TIER__OCIBE = (1 << 2),
|
||||||
|
TIER__OVIE = (1 << 1),
|
||||||
|
};
|
||||||
|
enum ftcsr_bits {
|
||||||
|
FTCSR__ICF = (1 << 7),
|
||||||
|
FTCSR__OCFA = (1 << 3),
|
||||||
|
FTCSR__OCFB = (1 << 2),
|
||||||
|
FTCSR__OVF = (1 << 1),
|
||||||
|
FTCSR__CCLRA = (1 << 0),
|
||||||
|
};
|
||||||
|
enum tcr_bits {
|
||||||
|
TCR__IEDGA__RISING_EDGE = (1 << 7),
|
||||||
|
TCR__CKS__INTERNAL_DIV8 = (0b00),
|
||||||
|
TCR__CKS__INTERNAL_DIV32 = (0b01),
|
||||||
|
TCR__CKS__INTERNAL_DIV128 = (0b10),
|
||||||
|
TCR__CKS__EXTERNAL_RISING = (0b11),
|
||||||
|
};
|
||||||
|
enum tocr_bits {
|
||||||
|
TOCR__OCRS__OCRA = (0 << 4),
|
||||||
|
TOCR__OCRS__OCRB = (1 << 4),
|
||||||
|
TOCR__OLVLA = (1 << 1),
|
||||||
|
TOCR__OLBLB = (1 << 0),
|
||||||
|
};
|
||||||
|
// enum vcra_bits {
|
||||||
|
#define VCRA__SERV(n) (n << 8)
|
||||||
|
#define VCRA__SRXV(n) (n << 0)
|
||||||
|
// };
|
||||||
|
// enum vcrb_bits {
|
||||||
|
#define VCRB__STXV(n) (n << 8)
|
||||||
|
#define VCRB__STEV(n) (n << 0)
|
||||||
|
// };
|
||||||
|
// enum vcrc_bits {
|
||||||
|
#define VCRC__FICV(n) (n << 8) // input-capture interrupt vector number
|
||||||
|
#define VCRC__FOCV(n) (n << 0) // output-compare interrupt vector number
|
||||||
|
// };
|
||||||
|
// enum vcrd_bits {
|
||||||
|
#define VCRD__FOVV(n) (n << 8)
|
||||||
|
// };
|
||||||
|
Loading…
x
Reference in New Issue
Block a user