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 "scu.h"
|
||||
#include "smpc.h"
|
||||
#include "sh2.h"
|
||||
|
||||
void fill_32(u32 * buf, u32 v, s32 n)
|
||||
{
|
||||
@ -16,9 +17,13 @@ void timer0_int(void) __attribute__ ((interrupt_handler));
|
||||
void timer0_int(void)
|
||||
{
|
||||
scu.reg.IST &= ~(IST__TIMER0);
|
||||
}
|
||||
|
||||
// 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.
|
||||
void oci_int(void) __attribute__ ((interrupt_handler));
|
||||
void oci_int(void)
|
||||
{
|
||||
// clear OCFA
|
||||
sh2.reg.FTCSR &= ~(FTCSR__OCFA);
|
||||
|
||||
while (smpc.reg.SF != 0) {}
|
||||
|
||||
@ -193,10 +198,53 @@ void start(void)
|
||||
|
||||
vec[SCU_VEC__TIMER0] = (u32)(&timer0_int);
|
||||
vec[SCU_VEC__SMPC] = (u32)(&smpc_int);
|
||||
scu.reg.T0C = 5;
|
||||
scu.reg.T1MD = T1MD__TENB;
|
||||
//scu.reg.T0C = 5;
|
||||
//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.IMS = ~(IMS__TIMER0 | IMS__SMPC);
|
||||
scu.reg.IMS = ~(IMS__SMPC);
|
||||
|
||||
while (1) {
|
||||
vec[0] = scu.reg.IST;
|
||||
|
2
scu.h
2
scu.h
@ -160,5 +160,3 @@ enum scu_vec {
|
||||
};
|
||||
|
||||
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 TIER; // 0x010
|
||||
reg8 FTCSR; // 0x011
|
||||
reg16 FRC; // 0x012
|
||||
reg16 OCRA_B; // 0x014
|
||||
struct {
|
||||
reg8 H; // 0x012
|
||||
reg8 L; // 0x013
|
||||
} FRC;
|
||||
struct {
|
||||
reg8 H; // 0x014
|
||||
reg8 L; // 0x015
|
||||
} OCRAB;
|
||||
reg8 TCR; // 0x016
|
||||
reg8 TOCR; // 0x017
|
||||
reg16 FICR; // 0x018
|
||||
struct {
|
||||
reg8 H; // 0x018
|
||||
reg8 L; // 0x018
|
||||
} FICR;
|
||||
reg8 _res1[70];
|
||||
reg16 IPRB; // 0x060
|
||||
reg16 VCRA; // 0x062
|
||||
@ -87,7 +96,7 @@ typedef struct sh2_reg {
|
||||
} sh2_reg;
|
||||
|
||||
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);
|
||||
|
||||
struct sh2 {
|
||||
@ -95,3 +104,47 @@ struct 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