mirror of
https://github.com/kalymos/PsNee.git
synced 2026-03-06 11:23:28 +00:00
removal of the TIMER
removal of the ISR(CTC_TIMER_VECTOR) function, and all its dependencies. - Timer_Start - Timer_Stop modification - Board detection - inject_SCEX - BIOS_PATCH - MCU - Setting
This commit is contained in:
@@ -1,84 +1,141 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
void Timer_Start(void);
|
||||
void Timer_Stop(void);
|
||||
#ifdef BIOS_PATCH
|
||||
|
||||
extern volatile uint8_t count_isr;
|
||||
extern volatile uint32_t microsec;
|
||||
extern volatile uint32_t millisec;
|
||||
volatile uint8_t impulse = 0;
|
||||
volatile uint8_t patch = 0;
|
||||
|
||||
volatile uint8_t impulse = 0;
|
||||
volatile uint8_t patch = 0;
|
||||
#ifdef INTERRUPT_RISING
|
||||
|
||||
#if defined(SCPH_102) || defined(SCPH_100) || defined(SCPH_7000_9000) || defined(SCPH_5500) || defined(SCPH_3500_5000) || defined(SCPH_3000) || defined(SCPH_1000)
|
||||
ISR(PIN_AX_INTERRUPT_VECTOR) {
|
||||
impulse++;
|
||||
if (impulse == TRIGGER){ // If impulse reaches the value defined by TRIGGER, the following actions are performed:
|
||||
_delay_us(HOLD);
|
||||
PIN_DX_OUTPUT;
|
||||
_delay_us(PATCHING);
|
||||
PIN_DX_INPUT;
|
||||
PIN_AX_INTERRUPT_DISABLE;
|
||||
|
||||
ISR(PIN_AX_INTERRUPT_VECTOR) {
|
||||
impulse++;
|
||||
if (impulse == TRIGGER){ // If impulse reaches the value defined by TRIGGER, the following actions are performed:
|
||||
HOLD;
|
||||
#ifdef HIGH_PATCH
|
||||
PIN_DX_SET;
|
||||
#endif
|
||||
PIN_DX_OUTPUT;
|
||||
PATCHING;
|
||||
#ifdef HIGH_PATCH
|
||||
PIN_DX_CLEAR;
|
||||
#endif
|
||||
PIN_DX_INPUT;
|
||||
PIN_AX_INTERRUPT_DISABLE;
|
||||
|
||||
impulse = 0;
|
||||
patch = 1; // patch is set to 1, indicating that the first patch is completed.
|
||||
impulse = 0;
|
||||
patch = 1; // patch is set to 1, indicating that the first patch is completed.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Bios_Patching(){
|
||||
|
||||
#ifdef HIGH_PATCH
|
||||
PIN_AX_INTERRUPT_RISING;
|
||||
|
||||
if (PIN_AX_READ != 0) // If the AX pin is high
|
||||
{
|
||||
while (PIN_AX_READ != 0); // Wait for it to go low
|
||||
while (PIN_AX_READ == 0); // Then wait for it to go high again.
|
||||
}
|
||||
else // If the AX pin is low
|
||||
{
|
||||
while (PIN_AX_READ == 0); // Wait for it to go high.
|
||||
}
|
||||
|
||||
// Wait until the number of microseconds elapsed reaches a value defined by CHECKPOINT.
|
||||
_delay_ms(CHECKPOINT);
|
||||
PIN_AX_INTERRUPT_ENABLE;
|
||||
|
||||
while (patch != 1); // Wait for the first stage of the patch to complete:
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef INTERRUPT_FALLING
|
||||
|
||||
ISR(PIN_AX_INTERRUPT_VECTOR) {
|
||||
impulse++;
|
||||
if (impulse == TRIGGER){ // If impulse reaches the value defined by TRIGGER, the following actions are performed:
|
||||
_delay_us (HOLD);
|
||||
PIN_DX_OUTPUT;
|
||||
_delay_us (PATCHING);
|
||||
PIN_DX_INPUT;
|
||||
PIN_AX_INTERRUPT_DISABLE;
|
||||
|
||||
impulse = 0;
|
||||
patch = 1; // patch is set to 1, indicating that the first patch is completed.
|
||||
}
|
||||
}
|
||||
|
||||
void Bios_Patching(){
|
||||
|
||||
PIN_AX_INTERRUPT_FALLING;
|
||||
|
||||
if (PIN_AX_READ != 0) // If the AX pin is high
|
||||
{
|
||||
while (PIN_AX_READ != 0); // Wait for it to go low
|
||||
while (PIN_AX_READ == 0); // Then wait for it to go high again.
|
||||
}
|
||||
else // If the AX pin is low
|
||||
{
|
||||
while (PIN_AX_READ == 0); // Wait for it to go high.
|
||||
}
|
||||
|
||||
_delay_ms(CHECKPOINT); // Wait until the number of microseconds elapsed reaches a value defined by CHECKPOINT.
|
||||
PIN_AX_INTERRUPT_ENABLE;
|
||||
|
||||
while (patch != 1); // Wait for the first stage of the patch to complete:
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef INTERRUPT_RISING_HIGH_PATCH
|
||||
|
||||
ISR(PIN_AX_INTERRUPT_VECTOR) {
|
||||
impulse++;
|
||||
if (impulse == TRIGGER){ // If impulse reaches the value defined by TRIGGER, the following actions are performed:
|
||||
_delay_us (HOLD);
|
||||
PIN_DX_SET;
|
||||
PIN_DX_OUTPUT;
|
||||
_delay_us (PATCHING);
|
||||
PIN_DX_CLEAR;
|
||||
PIN_DX_INPUT;
|
||||
PIN_AX_INTERRUPT_DISABLE;
|
||||
|
||||
impulse = 0;
|
||||
patch = 1; // patch is set to 1, indicating that the first patch is completed.
|
||||
}
|
||||
}
|
||||
|
||||
ISR(PIN_AY_INTERRUPT_VECTOR){
|
||||
|
||||
impulse++;
|
||||
if (impulse == TRIGGER2) // If impulse reaches the value defined by TRIGGER2, the following actions are performed:
|
||||
{
|
||||
HOLD2;
|
||||
_delay_us (HOLD2);
|
||||
PIN_DX_OUTPUT;
|
||||
PATCHING2;
|
||||
_delay_us (PATCHING2);
|
||||
PIN_DX_INPUT;
|
||||
PIN_AY_INTERRUPT_DISABLE;
|
||||
|
||||
patch = 2; // patch is set to 2, indicating that the second patch is completed.
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void Bios_Patching(){
|
||||
|
||||
void Bios_Patching(){
|
||||
PIN_AX_INTERRUPT_RISING;
|
||||
|
||||
// If LOW_TRIGGER is defined
|
||||
#ifdef LOW_TRIGGER
|
||||
PIN_AX_INTERRUPT_FALLING;
|
||||
#else
|
||||
PIN_AX_INTERRUPT_RISING;
|
||||
#endif
|
||||
if (PIN_AX_READ != 0) // If the AX pin is high
|
||||
{
|
||||
while (PIN_AX_READ != 0); // Wait for it to go low
|
||||
while (PIN_AX_READ == 0); // Then wait for it to go high again.
|
||||
}
|
||||
else // If the AX pin is low
|
||||
{
|
||||
while (PIN_AX_READ == 0); // Wait for it to go high.
|
||||
}
|
||||
|
||||
_delay_ms(CHECKPOINT); // Wait until the number of microseconds elapsed reaches a value defined by CHECKPOINT.
|
||||
PIN_AX_INTERRUPT_ENABLE;
|
||||
|
||||
while (patch != 1); // Wait for the first stage of the patch to complete:
|
||||
|
||||
if (PIN_AX_READ != 0) // If the AX pin is high
|
||||
{
|
||||
while (PIN_AX_READ != 0); // Wait for it to go low
|
||||
while (PIN_AX_READ == 0); // Then wait for it to go high again.
|
||||
}
|
||||
else // If the AX pin is low
|
||||
{
|
||||
while (PIN_AX_READ == 0); // Wait for it to go high.
|
||||
}
|
||||
|
||||
Timer_Start();
|
||||
while (microsec < CHECKPOINT); // Wait until the number of microseconds elapsed reaches a value defined by CHECKPOINT.
|
||||
Timer_Stop();
|
||||
PIN_AX_INTERRUPT_ENABLE;
|
||||
|
||||
while (patch != 1); // Wait for the first stage of the patch to complete:
|
||||
|
||||
#ifdef HIGH_PATCH
|
||||
|
||||
#ifdef HIGH_PATCH
|
||||
PIN_AY_INTERRUPT_FALLING;
|
||||
@@ -86,105 +143,17 @@ volatile uint8_t patch = 0;
|
||||
PIN_AY_INTERRUPT_RISING;
|
||||
#endif
|
||||
|
||||
while (PIN_AY_READ != 0); // Wait for it to go low
|
||||
Timer_Start();
|
||||
while (microsec < CHECKPOINT2); // Wait until the number of microseconds elapsed reaches a value defined by CHECKPOINT2.
|
||||
Timer_Stop();
|
||||
while (PIN_AY_READ != 0); // Wait for it to go low
|
||||
|
||||
_delay_ms(CHECKPOINT2); // Wait until the number of microseconds elapsed reaches a value defined by CHECKPOINT2.
|
||||
PIN_AY_INTERRUPT_ENABLE;
|
||||
while (patch != 2); // Wait for the second stage of the patch to complete:
|
||||
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef SCPH_102_legacy
|
||||
//void Bios_Patching_SCPH_102_legacy() {
|
||||
|
||||
// PIN_AX_INPUT; //A18
|
||||
// PIN_DX_INPUT; //D2
|
||||
|
||||
// Timer_Start();
|
||||
// while (millisec < SATBILIZATIONPOINT); // this is right after SQCK appeared. wait a little to avoid noise
|
||||
// while (PIN_AX_READ != 0);
|
||||
// Timer_Stop();
|
||||
|
||||
// // //wait for stage 1 A18 pulse
|
||||
#endif
|
||||
|
||||
|
||||
// Timer_Start();
|
||||
// while (millisec < DELAYPOINT); //wait through stage 1 of A18 activity delay(1350)
|
||||
// Timer_Stop();
|
||||
|
||||
// //noInterrupts(); // start critical section
|
||||
// GLOBAL_INTERRUPT_DISABLE;
|
||||
// Timer_Start();
|
||||
// while (PIN_AX_READ != 0);
|
||||
// {
|
||||
// ; //wait for priming A18 pulse
|
||||
// }
|
||||
// //while (microsec < HOLD ); // delayMicroseconds(17) min 13us max 17us for 16Mhz ATmega (maximize this when tuning!)
|
||||
// HOLD;
|
||||
// PIN_DX_CLEAR; // store a low
|
||||
// PIN_DX_OUTPUT; // D2 = output. drags line low now
|
||||
// PATCHING;
|
||||
// //while (microsec < PATCHING ); // delayMicroseconds(4) min 2us for 16Mhz ATmega, 8Mhz requires 3us (minimize this when tuning, after maximizing first us delay!)
|
||||
// PIN_DX_INPUT; // D2 = input / high-z
|
||||
// GLOBAL_INTERRUPT_ENABLE;
|
||||
// //interrupts(); // end critical section
|
||||
// Timer_Stop();
|
||||
// // not necessary but I want to make sure these pins are now high-z again
|
||||
// PIN_AX_INPUT;
|
||||
// PIN_DX_INPUT;
|
||||
// }
|
||||
|
||||
// Original function equivalent to NTSC_fix(), using macros
|
||||
void Bios_Patching_SCPH_102_legacy(void) {
|
||||
|
||||
// configure A18 and D2 as inputs
|
||||
PIN_AX_INPUT;
|
||||
PIN_DX_INPUT;
|
||||
|
||||
// arm A18 interrupt for noise immunity (optional)
|
||||
PIN_AX_INTERRUPT_RISING;
|
||||
PIN_AX_INTERRUPT_ENABLE;
|
||||
|
||||
// initial stabilization delay
|
||||
Timer_Start();
|
||||
SATBILIZATIONPOINT; // _delay_ms(100)
|
||||
Timer_Stop();
|
||||
|
||||
// wait for stage 1 A18 pulse
|
||||
while (!PIN_AX_READ) ;
|
||||
|
||||
// wait through stage 1 of A18 activity
|
||||
Timer_Start();
|
||||
DELAYPOINT; // _delay_ms(1350)
|
||||
Timer_Stop();
|
||||
|
||||
// critical section
|
||||
noInterrupts();
|
||||
// wait for priming A18 pulse
|
||||
while (!PIN_AX_READ) ;
|
||||
Timer_Start();
|
||||
HOLD; // _delay_us(17)
|
||||
Timer_Stop();
|
||||
|
||||
// drive D2 low for patch
|
||||
PIN_DX_CLEAR; // clear D2
|
||||
PIN_DX_OUTPUT; // set D2 as output
|
||||
Timer_Start();
|
||||
PATCH; // _delay_us(4)
|
||||
Timer_Stop();
|
||||
PIN_DX_INPUT; // release D2 (input/high-Z)
|
||||
interrupts();
|
||||
|
||||
// restore pins to input
|
||||
PIN_AX_INPUT;
|
||||
PIN_DX_INPUT;
|
||||
|
||||
// disable A18 interrupt now that patch is done
|
||||
PIN_AX_INTERRUPT_DISABLE;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
133
PSNee/MCU.h
133
PSNee/MCU.h
@@ -96,21 +96,45 @@
|
||||
|
||||
#ifdef ATmega328_168
|
||||
|
||||
|
||||
// Configuring Port C (A0-A5) as Digital Inputs
|
||||
// DDRC at 0 = Input. Ensure that the first 6 bits are 0.
|
||||
#define A DDRC &= ~0x3F;
|
||||
|
||||
// Disable the ADC (Analog-to-Digital Converter)
|
||||
// ADEN at 0 disables the module. PRADC at 1 disables the module's clock.
|
||||
#define B ADCSRA &= ~(1 << ADEN);
|
||||
#define C PRR |= (1 << PRADC);
|
||||
|
||||
// Configure DIDR0 (Digital Input Disable Register)
|
||||
// To read digitally via PINC, the bits of DIDR0 MUST be set to 0.
|
||||
// (0 = Digital Buffer enabled)
|
||||
#define D DIDR0 &= ~0x3F;
|
||||
|
||||
// Stop Timer 0 (Stops Arduino millis/micros)
|
||||
// Setting TCCR0B to 0 stops the clock source. Setting TIMSK0 to 0 disables interrupts.
|
||||
#define E TCCR0B = 0;
|
||||
#define F TIMSK0 = 0;
|
||||
|
||||
// Disable the Analog Comparator (Frees up resources on PD6/PD7)
|
||||
// ACD at 1 = Comparator off.
|
||||
#define G ACSR |= (1 << ACD);
|
||||
|
||||
// Define the clock speed for the microcontroller
|
||||
#define F_CPU 16000000L
|
||||
|
||||
// Clear the timer count register (TCNT0)
|
||||
#define TIMER_TCNT_CLEAR TCNT0 = 0x00 // TCNT0 - Timer/Counter Register, clears the timer count
|
||||
//#define TIMER_TCNT_CLEAR TCNT0 = 0x00 // TCNT0 - Timer/Counter Register, clears the timer count
|
||||
|
||||
// Set OCR0A to achieve a 100KHz clock frequency
|
||||
#define SET_OCROA_DIV OCR0A = 159; // OCR0A – Output Compare Register A, 100KHz clock generation, 0x10011111
|
||||
//#define SET_OCROA_DIV OCR0A = 159; // OCR0A – Output Compare Register A, 100KHz clock generation, 0x10011111
|
||||
|
||||
// Configure Timer/Counter 0 for CTC mode and enable the clock source
|
||||
#define SET_TIMER_TCCROA TCCR0A |= (1 << WGM01); // TCCR0A – Timer/Counter Control Register A, enable CTC mode (WGM01)
|
||||
#define SET_TIMER_TCCROB TCCR0B |= (1 << CS00); // TCCR0B – Timer/Counter Control Register B, set clock source to I/O clock
|
||||
//#define SET_TIMER_TCCROA TCCR0A |= (1 << WGM01); // TCCR0A – Timer/Counter Control Register A, enable CTC mode (WGM01)
|
||||
//#define SET_TIMER_TCCROB TCCR0B |= (1 << CS00); // TCCR0B – Timer/Counter Control Register B, set clock source to I/O clock
|
||||
//Waveform Generation Mode, Mode 2 CTC
|
||||
// Interrupt vector for timer compare match event
|
||||
#define CTC_TIMER_VECTOR TIMER0_COMPA_vect //interrupt vector for match event, OCR0A comparison and Timer/Counter 0
|
||||
//#define CTC_TIMER_VECTOR TIMER0_COMPA_vect //interrupt vector for match event, OCR0A comparison and Timer/Counter 0
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
@@ -124,8 +148,8 @@
|
||||
#define GLOBAL_INTERRUPT_DISABLE SREG &= ~(1 << 7) // Clear the I-bit (bit 7) in the Status Register to disable global interrupts
|
||||
|
||||
// Enable/Disable timer interrupts
|
||||
#define TIMER_INTERRUPT_ENABLE TIMSK0 |= (1 << OCIE0A) // Enable interrupt on Timer0 Compare Match A
|
||||
#define TIMER_INTERRUPT_DISABLE TIMSK0 &= ~(1 << OCIE0A) // Disable interrupt on Timer0 Compare Match A
|
||||
//#define TIMER_INTERRUPT_ENABLE TIMSK0 |= (1 << OCIE0A) // Enable interrupt on Timer0 Compare Match A
|
||||
//#define TIMER_INTERRUPT_DISABLE TIMSK0 &= ~(1 << OCIE0A) // Disable interrupt on Timer0 Compare Match A
|
||||
|
||||
// Main pin configuration for input and output
|
||||
|
||||
@@ -159,10 +183,10 @@
|
||||
#endif
|
||||
|
||||
// Handling the BIOS patch
|
||||
#if defined(SCPH_102) || defined(SCPH_102_legacy) || defined(SCPH_100) || defined(SCPH_7000_9000) || defined(SCPH_5500) || defined(SCPH_3500_5000) || defined(SCPH_3000) || defined(SCPH_1000)
|
||||
#if defined(SCPH_102) || defined(SCPH_102_legacy) || defined(SCPH_100) || defined(SCPH_7500_9000) || defined(SCPH_7000) || defined(SCPH_5500) || defined(SCPH_3500_5000) || defined(SCPH_3000) || defined(SCPH_1000)
|
||||
|
||||
// Clear the timer interrupt flag
|
||||
#define TIMER_TIFR_CLEAR TIFR0 |= (1 << OCF0A) // Clear the Timer0 Compare Match A interrupt flag
|
||||
//#define TIMER_TIFR_CLEAR TIFR0 |= (1 << OCF0A) // Clear the Timer0 Compare Match A interrupt flag
|
||||
|
||||
// Define input pins for the BIOS patch
|
||||
#define PIN_AX_INPUT DDRD &= ~(1 << DDD2) // Set DDRD register to configure PIND2 as input
|
||||
@@ -604,11 +628,6 @@
|
||||
#ifdef LGT8F328P
|
||||
|
||||
#define F_CPU 32000000L
|
||||
#define TIMER_TCNT_CLEAR TCNT0 = 0x00
|
||||
#define SET_OCROA_DIV OCR0A = 319;
|
||||
#define SET_TIMER_TCCROA TCCR0A |= (1 << WGM01);
|
||||
#define SET_TIMER_TCCROB TCCR0B |= (1 << CS00);
|
||||
#define CTC_TIMER_VECTOR TIMER0_COMPA_vect
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
@@ -699,89 +718,3 @@
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CH32V003
|
||||
|
||||
#include "ch32v003.h" // Inclure le fichier d'en-tête spécifique au microcontrôleur
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
// Fréquence d'horloge
|
||||
#define F_CPU 8000000L
|
||||
|
||||
// Configuration du timer pour une fréquence de 100 kHz
|
||||
#define TIMER_TCNT_CLEAR TIM2_CNT = 0x00 // ok Effacer le compteur du Timer 2
|
||||
#define SET_OCROA_DIV TIM2_ARR = 79 // not Définir la valeur de comparaison pour générer une interruption à 100 kHz
|
||||
#define SET_TIMER_TCCROA TIM2_CR1 |= TIM_CR1_OPM // notMettre le Timer en mode One Pulse (à adapter selon le mode souhaité)
|
||||
#define SET_TIMER_TCCROB TIM2_PSC = 0 // ok Définir le prescaler à 0 pour une fréquence maximale
|
||||
|
||||
// Vecteur d'interruption pour le Timer 2
|
||||
#define CTC_TIMER_VECTOR TIM2_UP_IRQHandler // Remplacer par le vecteur d'interruption approprié
|
||||
|
||||
// Interruption globale
|
||||
#define GLOBAL_INTERRUPT_ENABLE __enable_irq()
|
||||
#define GLOBAL_INTERRUPT_DISABLE __disable_irq()
|
||||
|
||||
// Configuration des broches GPIO
|
||||
#define PIN_DATA_INPUT GPIOA->INDR &= ~(GPIO_MODER_MODER0)
|
||||
#define PIN_WFCK_INPUT GPIOA->INDR &= ~(GPIO_MODER_MODER1)
|
||||
#define PIN_SQCK_INPUT GPIOA->INDR &= ~(GPIO_MODER_MODER6)
|
||||
#define PIN_SUBQ_INPUT GPIOA->INDR &= ~(GPIO_MODER_MODER7)
|
||||
|
||||
#define PIN_DATA_OUTPUT GPIOA->OUTDR |= (GPIO_MODER_MODER0_0)
|
||||
#define PIN_WFCK_OUTPUT GPIOA->OUTDR |= (GPIO_MODER_MODER1_0)
|
||||
|
||||
#define PIN_DATA_SET GPIOA->BSHR |= (GPIO_ODR_ODR_0)
|
||||
|
||||
#define PIN_DATA_CLEAR GPIOA->BRC &= ~(GPIO_ODR_ODR_0)
|
||||
#define PIN_WFCK_CLEAR GPIOA->BRC &= ~(GPIO_ODR_ODR_1)
|
||||
|
||||
#define PIN_SQCK_READ (GPIOA->IDR & (GPIO_IDR_IDR_6))
|
||||
#define PIN_SUBQ_READ (GPIOA->IDR & (GPIO_IDR_IDR_7))
|
||||
#define PIN_WFCK_READ (GPIOA->IDR & (GPIO_IDR_IDR_1))
|
||||
|
||||
// Gestion de la broche LED
|
||||
#define PIN_LED_OUTPUT GPIOA->MODER |= (GPIO_MODER_MODER5_0)
|
||||
#define PIN_LED_ON GPIOA->ODR |= (GPIO_ODR_ODR_5)
|
||||
#define PIN_LED_OFF GPIOA->ODR &= ~(GPIO_ODR_ODR_5)
|
||||
|
||||
// Gestion des interruptions du timer
|
||||
#define TIMER_INTERRUPT_ENABLE TIM2_DIER |= (TIM_DIER_UIE)
|
||||
#define TIMER_INTERRUPT_DISABLE TIM2_DIER &= ~(TIM_DIER_UIE)
|
||||
#define TIMER_TIFR_CLEAR TIM2_SR &= ~(TIM_SR_UIF)
|
||||
|
||||
// Configuration des broches pour le BIOS
|
||||
#define PIN_AX_INPUT GPIOA->MODER &= ~(GPIO_MODER_MODER2)AFIO_EXTICR
|
||||
#define PIN_AY_INPUT GPIOA->MODER &= ~(GPIO_MODER_MODER3)
|
||||
#define PIN_DX_INPUT GPIOA->MODER &= ~(GPIO_MODER_MODER4)
|
||||
|
||||
#define PIN_DX_OUTPUT GPIOA->MODER |= (GPIO_MODER_MODER4_0)
|
||||
|
||||
#define PIN_DX_SET GPIOA->ODR |= (GPIO_ODR_ODR_4)
|
||||
|
||||
#define PIN_DX_CLEAR GPIOA->ODR &= ~(GPIO_ODR_ODR_4)
|
||||
|
||||
#define PIN_AX_READ (GPIOA->IDR & (GPIO_IDR_IDR_2))
|
||||
#define PIN_AY_READ (GPIOA->IDR & (GPIO_IDR_IDR_3))
|
||||
|
||||
// Gestion des interruptions externes
|
||||
#define PIN_AX_INTERRUPT_ENABLE EXTI->IMR |= (EXTI_IMR_MR0) //1<<EXTI_INTENR_MR0
|
||||
#define PIN_AY_INTERRUPT_ENABLE EXTI->IMR |= (EXTI_IMR_MR1)
|
||||
|
||||
#define PIN_AX_INTERRUPT_DISABLE EXTI->IMR &= ~(EXTI_IMR_MR0) //EXTI_INTENR
|
||||
#define PIN_AY_INTERRUPT_DISABLE EXTI->IMR &= ~(EXTI_IMR_MR1)
|
||||
|
||||
#define PIN_AX_INTERRUPT_RISING EXTI->RTSR |= (EXTI_RTSR_TR0) //EXTI_RTENR
|
||||
#define PIN_AY_INTERRUPT_RISING EXTI->RTSR |= (EXTI_RTSR_TR1)
|
||||
|
||||
#define PIN_AX_INTERRUPT_FALLING EXTI->FTSR |= (EXTI_FTENR_MR0) //EXTI_FTENR
|
||||
#define PIN_AY_INTERRUPT_FALLING EXTI->FTSR |= (EXTI_FTENR_MR1)
|
||||
|
||||
#define PIN_AX_INTERRUPT_VECTOR EXTI0_IRQHandler
|
||||
#define PIN_AY_INTERRUPT_VECTOR EXTI1_IRQHandler
|
||||
|
||||
// Gestion de la broche de commutation pour le BIOS
|
||||
#define PIN_SWITCH_INPUT GPIOA->MODER &= ~(GPIO_MODER_MODER5)
|
||||
#define PIN_SWITCH_SET GPIOA->ODR |= (GPIO_ODR_ODR_5)
|
||||
#define PIN_SWITCH_READ (GPIOA->IDR & (GPIO_IDR_IDR_5))
|
||||
|
||||
#endif
|
||||
|
||||
185
PSNee/PSNee.ino
185
PSNee/PSNee.ino
@@ -6,7 +6,7 @@
|
||||
|
||||
// MCU // Arduino
|
||||
//------------------------------------------------------------------------------------------------
|
||||
//#define ATmega328_168 // Nano, Pro Mini, Uno
|
||||
#define ATmega328_168 // Nano, Pro Mini, Uno
|
||||
//#define ATmega32U4_16U4 // Micro, Pro Micro
|
||||
//#define ATtiny85_45_25 // ATtiny
|
||||
|
||||
@@ -44,9 +44,9 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
SCPH model number // Data pin | 32-pin BIOS | 40-pin BIOS | BIOS version
|
||||
-------------------------------------------------------------------------------------------------*/
|
||||
//#define SCPH_102 // DX - D0 | AX - A7 | | 4.4e - CRC 0BAD7EA9, 4.5e -CRC 76B880E5
|
||||
//#define SCPH_102_legacy // ! works in progress DX - D2, AX - A18. | 4.4e - CRC 0BAD7EA9, 4.5e -CRC 76B880E5
|
||||
//#define SCPH_100 // DX - D0 | AX - A7 | | 4.3j - CRC F2AF798B
|
||||
//#define SCPH_7000_9000 // DX - D0 | AX - A7 | | 4.0j - CRC EC541CD0
|
||||
//#define SCPH_7500_9000 // DX - D0 | AX - A7 | | 4.0j - CRC EC541CD0
|
||||
//#define SCPH_7000 // DX - D0 | AX - A7 | | 4.0j - CRC EC541CD0 Enables hardware support for disabling BIOS patching.
|
||||
//#define SCPH_5500 // DX - D0 | AX - A5 | | 3.0j - CRC FF3EEB8C
|
||||
//#define SCPH_3500_5000 // DX - D0 | AX - A5 | AX - A4 | 2.2j - CRC 24FC7E17, 2.1j - CRC BC190209
|
||||
//#define SCPH_3000 // DX - D5 | AX - A7, AY - A8 | AX - A6, AY - A7 | 1.1j - CRC 3539DEF6
|
||||
@@ -59,9 +59,6 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
#define LED_RUN // Turns on the LED when injections occur.
|
||||
// D13 for Arduino, ATtiny add a led between PB3 (pin 2) and gnd with a 1k resistor in series, ATmega32U4 (Pro Micro) add a led between PB6 (pin 10) and gnd with a 1k resistor in series.
|
||||
|
||||
//#define PATCH_SWITCH // Enables hardware support for disabling BIOS patching.
|
||||
// With SCPH_7000 - 9000 models, Bios 4.0j, the bios patch prevents reading memory cards in the console interface, and in some cases can cause a crash (No problem in game).
|
||||
// In rare cases where the BIOS patch prevents the playback of original games.
|
||||
|
||||
//#define PSNEE_DEBUG_SERIAL_MONITOR // Enables serial monitor output.
|
||||
/* Requires compilation with Arduino libs!
|
||||
@@ -125,14 +122,6 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
#include "settings.h"
|
||||
#include "BIOS_patching.h"
|
||||
|
||||
//Initializing values for region code injection timing
|
||||
#define DELAY_BETWEEN_BITS 4000 // 250 bits/s (microseconds) (ATtiny 8Mhz works from 3950 to 4100) PU-23 PU-22 MAX 4250 MIN 3850
|
||||
#define DELAY_BETWEEN_INJECTIONS 90 // The sweet spot is around 80~100. For all observed models, the worst minimum time seen is 72, and it works well up to 250.
|
||||
|
||||
//Creation of the different variables for the counter
|
||||
volatile uint8_t count_isr = 0;
|
||||
volatile uint32_t microsec = 0;
|
||||
volatile uint32_t millisec = 0;
|
||||
|
||||
//Flag initializing for automatic console generation selection 0 = old, 1 = pu-22 end ++
|
||||
volatile bool wfck_mode = 0;
|
||||
@@ -143,89 +132,6 @@ volatile bool Flag_Switch = 0;
|
||||
Code section
|
||||
------------------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------------------
|
||||
Interrupt Service Routine: CTC_TIMER_VECTOR
|
||||
Description:
|
||||
This ISR is triggered by the Timer/Counter Compare Match event. It increments time-related
|
||||
counters used for tracking microseconds and milliseconds.
|
||||
|
||||
Functionality:
|
||||
- Increments `microsec` by 10 on each interrupt call.
|
||||
- Increments `count_isr` to keep track of the number of interrupts.
|
||||
- When `count_isr` reaches 100, it means 1 millisecond has elapsed:
|
||||
- `millisec` is incremented.
|
||||
- `count_isr` is reset to 0.
|
||||
|
||||
Notes:
|
||||
- This method provides a simple way to maintain a software-based timekeeping system.
|
||||
------------------------------------------------------------------------------------------------*/
|
||||
ISR(CTC_TIMER_VECTOR) {
|
||||
microsec += 10;
|
||||
count_isr++;
|
||||
if (count_isr == 100)
|
||||
{
|
||||
millisec++;
|
||||
count_isr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// *****************************************************************************************
|
||||
// Function: Timer_Start
|
||||
// Description:
|
||||
// This function initializes and starts the timer by resetting the timer counter register
|
||||
// and enabling timer interrupts. It ensures compatibility across multiple microcontrollers.
|
||||
//
|
||||
// Supported Microcontrollers:
|
||||
// - ATmega328/168
|
||||
// - ATmega32U4/16U4
|
||||
// - ATtiny85/45/25
|
||||
//
|
||||
// Functionality:
|
||||
// - Clears the timer counter to ensure a fresh start.
|
||||
// - Enables the timer interrupt to allow periodic execution of ISR routines.
|
||||
// - If BIOS_PATCH is defined, it also clears the timer interrupt flag to prevent
|
||||
// unwanted immediate interrupts.
|
||||
//
|
||||
// Notes:
|
||||
// - The actual timer configuration is handled in MCU.h.
|
||||
// - This function ensures that all supported MCUs behave consistently.
|
||||
//
|
||||
// *****************************************************************************************
|
||||
void Timer_Start() {
|
||||
#if defined(ATmega328_168) || defined(ATmega32U4_16U4) || defined(ATtiny85_45_25)
|
||||
TIMER_TCNT_CLEAR;
|
||||
TIMER_INTERRUPT_ENABLE;
|
||||
#if defined(BIOS_PATCH)
|
||||
TIMER_TIFR_CLEAR;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
// *****************************************************************************************
|
||||
// Function: Timer_Stop
|
||||
// Description:
|
||||
// Stops the timer by disabling interrupts and resetting the timer counter.
|
||||
// It also clears the time tracking variables (count_isr, microsec, millisec)
|
||||
// to ensure a fresh start when the timer is restarted.
|
||||
//
|
||||
// Supported Microcontrollers:
|
||||
// - ATmega328/168
|
||||
// - ATmega32U4/16U4
|
||||
// - ATtiny85/45/25
|
||||
//
|
||||
// *****************************************************************************************
|
||||
void Timer_Stop() {
|
||||
|
||||
#if defined(ATmega328_168) || defined(ATmega32U4_16U4) || defined(ATtiny85_45_25)
|
||||
TIMER_INTERRUPT_DISABLE; // Disable timer interrupts to stop counting
|
||||
TIMER_TCNT_CLEAR; // Reset the timer counter to ensure proper timing when restarted
|
||||
#endif
|
||||
// Reset time tracking variables
|
||||
count_isr = 0;
|
||||
microsec = 0;
|
||||
millisec = 0;
|
||||
}
|
||||
|
||||
// *****************************************************************************************
|
||||
// Function: readBit
|
||||
// Description:
|
||||
@@ -293,7 +199,10 @@ void inject_SCEX(const char region) {
|
||||
0b00000010
|
||||
};
|
||||
|
||||
// Iterate through 44 bits of SCEX data
|
||||
//Initializing values for region code injection timing
|
||||
#define DELAY_BETWEEN_BITS 4000 // 250 bits/s (microseconds) (ATtiny 8Mhz works from 3950 to 4100) PU-23 PU-22 MAX 4250 MIN 3850
|
||||
#define DELAY_BETWEEN_INJECTIONS 90 // The sweet spot is around 80~100. For all observed models, the worst minimum time seen is 72, and it works well up to 250.
|
||||
|
||||
for (uint8_t bit_counter = 0; bit_counter < 44; bit_counter++) {
|
||||
// Check if the current bit is 0
|
||||
if (readBit(bit_counter, region == 'e' ? SCEEData : region == 'a' ? SCEAData : SCEIData) == 0) {
|
||||
@@ -306,19 +215,29 @@ void inject_SCEX(const char region) {
|
||||
if (wfck_mode) // WFCK mode (pu22mode enabled): synchronize PIN_DATA with WFCK clock signal
|
||||
{
|
||||
PIN_DATA_OUTPUT;
|
||||
Timer_Start();
|
||||
do {
|
||||
// Read the WFCK pin and set or clear DATA accordingly
|
||||
if (PIN_WFCK_READ) {
|
||||
PIN_DATA_SET;
|
||||
}
|
||||
uint8_t count = 30;
|
||||
uint8_t last_wfck = PIN_WFCK_READ;
|
||||
|
||||
else {
|
||||
while (count > 0) {
|
||||
uint8_t current_wfck = PIN_WFCK_READ;
|
||||
|
||||
if (current_wfck) {
|
||||
_delay_us(5);
|
||||
PIN_DATA_SET;
|
||||
_delay_us(55);
|
||||
PIN_DATA_CLEAR;
|
||||
_delay_us(10);
|
||||
} else {
|
||||
PIN_DATA_CLEAR;
|
||||
}
|
||||
}
|
||||
while (microsec < DELAY_BETWEEN_BITS);
|
||||
Timer_Stop(); // Stop the timer after the delay
|
||||
}
|
||||
|
||||
if (current_wfck && !last_wfck) {
|
||||
count--;
|
||||
}
|
||||
|
||||
last_wfck = current_wfck;
|
||||
}
|
||||
|
||||
}
|
||||
// PU-18 or lower mode: simply set PIN_DATA as input with a delay
|
||||
else {
|
||||
@@ -335,21 +254,14 @@ void inject_SCEX(const char region) {
|
||||
|
||||
void Init() {
|
||||
#if defined(ATmega328_168) || defined(ATmega32U4_16U4) || defined(ATtiny85_45_25)
|
||||
TIMER_TCNT_CLEAR;
|
||||
SET_OCROA_DIV;
|
||||
SET_TIMER_TCCROA;
|
||||
SET_TIMER_TCCROB;
|
||||
A;
|
||||
B;
|
||||
D;
|
||||
E;
|
||||
F;
|
||||
G;
|
||||
#endif
|
||||
|
||||
#if defined(ATmega328_168)
|
||||
// Power saving
|
||||
// Disable the ADC by setting the ADEN bit (bit 7) of the ADCSRA register to zero.
|
||||
ADCSRA = ADCSRA & B01111111;
|
||||
// Disable the analog comparator by setting the ACD bit (bit 7) of the ACSR register to one.
|
||||
ACSR = B10000000;
|
||||
// Disable digital input buffers on all analog input pins by setting bits 0-5 of the DIDR0 register to one.
|
||||
DIDR0 = DIDR0 | B00111111;
|
||||
#endif
|
||||
|
||||
#if defined(PATCH_SWITCH) && defined(BIOS_PATCH)
|
||||
PIN_SWITCH_INPUT;
|
||||
@@ -384,6 +296,8 @@ int main() {
|
||||
uint8_t bitpos = 0;
|
||||
uint8_t scpos = 0; // scbuf position
|
||||
uint16_t lows = 0;
|
||||
uint8_t preset = 0;
|
||||
uint32_t totalSamples = 400000;
|
||||
|
||||
Init();
|
||||
|
||||
@@ -394,11 +308,7 @@ int main() {
|
||||
#endif
|
||||
|
||||
if (Flag_Switch == 0) {
|
||||
#ifdef SCPH_102_legacy
|
||||
Bios_Patching_SCPH_102_legacy();
|
||||
#else
|
||||
Bios_Patching();
|
||||
#endif
|
||||
Bios_Patching();
|
||||
}
|
||||
|
||||
#ifdef LED_RUN
|
||||
@@ -407,7 +317,7 @@ int main() {
|
||||
|
||||
#endif
|
||||
|
||||
Timer_Start();
|
||||
//Timer_Start();
|
||||
/*----------------------------------------------------------------------
|
||||
Board detection
|
||||
|
||||
@@ -415,18 +325,21 @@ int main() {
|
||||
|
||||
__-_-_-_-_-_-_-_-_-_-_-_- // this is a PU-22 or newer board!
|
||||
|
||||
typical readouts PU-22: highs: 2449 lows: 2377
|
||||
|
||||
-----------------------------------------------------------------------*/
|
||||
do {
|
||||
if (PIN_WFCK_READ == 0) lows++; // good for ~5000 reads in 1s
|
||||
_delay_us(200);
|
||||
}
|
||||
while (millisec < 1000); // sample 1s
|
||||
|
||||
Timer_Stop();
|
||||
|
||||
if (lows > 100) {
|
||||
while (totalSamples > 0 && lows < 500){
|
||||
if (PIN_WFCK_READ != preset){
|
||||
preset = PIN_WFCK_READ;
|
||||
if (preset == 0){
|
||||
lows++;
|
||||
}
|
||||
}
|
||||
totalSamples--;
|
||||
}
|
||||
|
||||
if (lows > 499) {
|
||||
wfck_mode = 1; //flag pu22mode
|
||||
}
|
||||
|
||||
|
||||
106
PSNee/settings.h
106
PSNee/settings.h
@@ -22,6 +22,7 @@
|
||||
|
||||
#ifdef SCPH_102_legacy
|
||||
#define BIOS_PATCH
|
||||
//#define INTERRUPT_RISING
|
||||
#define SATBILIZATIONPOINT 100
|
||||
#define DELAYPOINT 1350
|
||||
#define HOLD _delay_us(17)
|
||||
@@ -30,74 +31,85 @@
|
||||
|
||||
#ifdef SCPH_102
|
||||
#define BIOS_PATCH
|
||||
#define HOLD _delay_us(2.75)
|
||||
#define PATCHING _delay_us(0.2)
|
||||
#define CHECKPOINT 83900
|
||||
#define INTERRUPT_RISING
|
||||
#define CHECKPOINT 83.9
|
||||
#define TRIGGER 48
|
||||
#define HOLD 2.75
|
||||
#define PATCHING 0.2
|
||||
#endif
|
||||
|
||||
#ifdef SCPH_100
|
||||
#define BIOS_PATCH
|
||||
#define HOLD _delay_us(2.7)
|
||||
#define PATCHING _delay_us(0.2)
|
||||
#define CHECKPOINT 83900
|
||||
#define INTERRUPT_RISING
|
||||
#define CHECKPOINT 83.9
|
||||
#define TRIGGER 48
|
||||
#define HOLD 2.8
|
||||
#define PATCHING 0.2
|
||||
#endif
|
||||
|
||||
#ifdef SCPH_7000_9000
|
||||
#ifdef SCPH_7500_9000
|
||||
#define BIOS_PATCH
|
||||
#define HOLD _delay_us(2.85)
|
||||
#define PATCHING _delay_us(0.1)
|
||||
#define CHECKPOINT 75270
|
||||
#define INTERRUPT_RISING
|
||||
#define CHECKPOINT 75.2 // ms SCPH_9000 74.95-75.55.
|
||||
#define TRIGGER 16
|
||||
#define HOLD 2.8
|
||||
#define PATCHING 0.2
|
||||
#endif
|
||||
|
||||
#ifdef SCPH_7000
|
||||
#define BIOS_PATCH
|
||||
//#define PATCH_SWITCH
|
||||
#define INTERRUPT_RISING
|
||||
#define CHECKPOINT 74.7
|
||||
#define TRIGGER 16
|
||||
#define HOLD 2.75
|
||||
#define PATCHING 0.6
|
||||
#endif
|
||||
|
||||
#ifdef SCPH_5500
|
||||
#define BIOS_PATCH
|
||||
#define HOLD _delay_us(2.85)
|
||||
#define PATCHING _delay_us(0.1)
|
||||
#define CHECKPOINT 76130
|
||||
#define INTERRUPT_FALLING
|
||||
#define CHECKPOINT 76.13
|
||||
#define TRIGGER 21
|
||||
#define LOW_TRIGGER
|
||||
#define HOLD 2.85
|
||||
#define PATCHING 0.1
|
||||
#endif
|
||||
|
||||
#ifdef SCPH_3500_5000
|
||||
#define BIOS_PATCH
|
||||
#define HOLD _delay_us(2.85)
|
||||
#define PATCHING _delay_us(0.1)
|
||||
#define CHECKPOINT 75260
|
||||
#define INTERRUPT_FALLING
|
||||
#define CHECKPOINT 75.26
|
||||
#define TRIGGER 21
|
||||
#define LOW_TRIGGER
|
||||
#define HOLD 2.85
|
||||
#define PATCHING 0.1
|
||||
#endif
|
||||
|
||||
#ifdef SCPH_3000
|
||||
#define BIOS_PATCH
|
||||
#define HOLD _delay_us(2.75)
|
||||
#define PATCHING _delay_us(0.1)
|
||||
#define CHECKPOINT 83000
|
||||
#define BIOS_PATCH
|
||||
#define INTERRUPT_RISING_HIGH_PATCH
|
||||
#define CHECKPOINT 83
|
||||
#define TRIGGER 60
|
||||
//#define DOUBLE_PATCH
|
||||
//#define LOW_TRIGGER2
|
||||
#define HOLD 2.75
|
||||
#define PATCHING 0.1
|
||||
#define HIGH_PATCH
|
||||
#define HOLD2 _delay_us(2.88)
|
||||
#define PATCHING2 _delay_us(0.15)
|
||||
#define CHECKPOINT2 253300
|
||||
#define TRIGGER2 43
|
||||
#define HOLD2 2.88
|
||||
#define PATCHING2 0.15
|
||||
#endif
|
||||
|
||||
#ifdef SCPH_1000
|
||||
#define BIOS_PATCH
|
||||
#define HOLD _delay_us(2.7)
|
||||
#define PATCHING _delay_us(0.1)
|
||||
#define CHECKPOINT 83000
|
||||
#define INTERRUPT_RISING_HIGH_PATCH
|
||||
#define CHECKPOINT 83
|
||||
#define TRIGGER 92
|
||||
//#define DOUBLE_PATCH
|
||||
//#define LOW_TRIGGER2
|
||||
#define HOLD 2.7
|
||||
#define PATCHING 0.1
|
||||
#define HIGH_PATCH
|
||||
#define HOLD2 _delay_us(2.88)
|
||||
#define PATCHING2 _delay_us(0.15)
|
||||
#define CHECKPOINT2 272800
|
||||
#define CHECKPOINT2 27.28
|
||||
#define TRIGGER2 71
|
||||
#define HOLD2 2.88
|
||||
#define PATCHING2 0.15
|
||||
#endif
|
||||
|
||||
/*------------------------------------------------------------------------------------------------
|
||||
@@ -108,11 +120,11 @@
|
||||
const char region[3] = {'a', 'a', 'a'};
|
||||
#endif
|
||||
|
||||
#if defined(SCPH_102) || defined(SCPH_xxx2) // PAL | Europ.
|
||||
#if defined(SCPH_102) || defined(SCPH_xxx2) // PAL | Europ.
|
||||
const char region[3] = {'e', 'e', 'e'};
|
||||
#endif
|
||||
|
||||
#if defined(SCPH_100) || defined(SCPH_7000_9000) || defined(SCPH_5500) || defined(SCPH_3500_5000) || defined(SCPH_3000) || defined(SCPH_1000) || defined(SCPH_xxx3) // NTSC J | Asia.
|
||||
#if defined(SCPH_100) || defined(SCPH_7500_9000) || defined(SCPH_7000) || defined(SCPH_5500) || defined(SCPH_3500_5000) || defined(SCPH_3000) || defined(SCPH_1000) || defined(SCPH_xxx3) // NTSC J | Asia.
|
||||
const char region[3] = {'i', 'i', 'i'};
|
||||
#endif
|
||||
|
||||
@@ -169,7 +181,7 @@ void Debug_Inject(){ // Confirmation of region code injection
|
||||
|
||||
#if defined(ATtiny85_45_25)
|
||||
mySerial.print("!");
|
||||
#elif !defined(ATtiny85_45_25)
|
||||
#elif !defined(ATtiny85_45_25)|| defined(SCPH_102_legacy)
|
||||
Serial.println(" INJECT ! ");
|
||||
#endif
|
||||
}
|
||||
@@ -180,17 +192,17 @@ void Debug_Inject(){ // Confirmation of region code injection
|
||||
Compilation message
|
||||
-----------------------------------------------------------------------------------------------*/
|
||||
|
||||
#if !defined(SCPH_103) && \
|
||||
!defined(SCPH_102) && !defined(SCPH_101) && !defined(SCPH_100) && !defined(SCPH_7000_9000) && \
|
||||
!defined(SCPH_5500) && !defined(SCPH_3500_5000) && !defined(SCPH_3000) && \
|
||||
!defined(SCPH_1000) && !defined(SCPH_xxxx) && !defined(SCPH_102_legacy) && \
|
||||
!defined(SCPH_xxx1) && !defined(SCPH_xxx2) && !defined(SCPH_xxxx3)
|
||||
#if !defined(SCPH_xxx3) && \
|
||||
!defined(SCPH_102) && !defined(SCPH_101) && !defined(SCPH_100) && !defined(SCPH_7500_9000) && \
|
||||
!defined(SCPH_7000) && !defined(SCPH_5500) && !defined(SCPH_3500_5000) && !defined(SCPH_3000) && \
|
||||
!defined(SCPH_1000) && !defined(SCPH_xxxx) && \
|
||||
!defined(SCPH_xxx1) && !defined(SCPH_xxx2)
|
||||
#error "Console not selected! Please uncoment #define with SCPH model number."
|
||||
#elif !defined(SCPH_103) ^ \
|
||||
defined(SCPH_102) ^ defined(SCPH_101) ^ defined(SCPH_100) ^ defined(SCPH_7000_9000) ^ \
|
||||
defined(SCPH_5500) ^ defined(SCPH_3500_5000) ^ defined(SCPH_3000) ^ \
|
||||
defined(SCPH_1000) ^ defined(SCPH_xxxx) ^ defined(SCPH_102_legacy) ^ \
|
||||
defined(SCPH_xxx1) ^ defined(SCPH_xxx2) ^ defined(SCPH_xxx3)
|
||||
#elif !defined(SCPH_xxx3) ^ \
|
||||
defined(SCPH_102) ^ defined(SCPH_101) ^ defined(SCPH_100) ^ defined(SCPH_7500_9000) ^ \
|
||||
defined(SCPH_7000) ^ defined(SCPH_5500) ^ defined(SCPH_3500_5000) ^ defined(SCPH_3000) ^ \
|
||||
defined(SCPH_1000) ^ defined(SCPH_xxxx) ^ \
|
||||
defined(SCPH_xxx1) ^ defined(SCPH_xxx2)
|
||||
#error "May be selected only one console! Please check #define with SCPH model number."
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user