summaryrefslogtreecommitdiff
path: root/Source/main.c
blob: 650f90721e70544fa3a677670925362f4b6568cf (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
/* *************************************
 * 	Includes
 * *************************************/

#include "Global_Inc.h"
#include "System.h"
#include "Serial.h"
#include "LoadMenu.h"
#include "EndAnimation.h"

/* *************************************
 * 	Defines
 * *************************************/

#define PSX_EXE_HEADER_SIZE 2048
#define EXE_DATA_PACKET_SIZE 8

/* *************************************
 * 	Local Prototypes
 * *************************************/

/* *************************************
 * 	Local Variables
 * *************************************/

 /* Untitled1 (10/07/2017 18:57:47)
   StartOffset: 00000000, EndOffset: 0000002F, Length: 00000030 */

/* Untitled2 (10/07/2017 21:10:19)
   StartOffset: 00000000, EndOffset: 000357FF, Length: 00035800 */

extern void _start(void);



int main(void)
{
    uint8_t* inBuffer = SystemGetBufferAddress();
   // int (*exeAddress)(void);

	//System initialization
    dprintf("SystemInit()\n");
	SystemInit();

    dprintf("LoadMenuInit()\n");

    LoadMenuInit();

    if(1)
    {
        uint32_t initPC_Address;
        uint32_t RAMDest_Address;
        uint32_t ExeSize = 0;
        uint32_t i;
        void (*exeAddress)(void);

        GfxSetGlobalLuminance(0);

        SerialInit();

        // Read PSX-EXE header (32 bytes will be enough).

        SerialSetState(SERIAL_STATE_READING_HEADER);

        SerialRead(inBuffer, 32);

        // Get initial program counter address from PSX-EXE header.

        initPC_Address = (inBuffer[0x10] | (inBuffer[0x11] << 8) | (inBuffer[0x12] << 16) | (inBuffer[0x13] << 24) );

        SerialSetPCAddress(initPC_Address);

        //dprintf("initPC_Address = 0x%08X\n", initPC_Address);

        // Get destination address in RAM from PSX-EXE header.

        RAMDest_Address = (inBuffer[0x18] | (inBuffer[0x19] << 8) | (inBuffer[0x1A] << 16) | (inBuffer[0x1B] << 24) );

        SerialSetRAMDestAddress(RAMDest_Address);

        //dprintf("RAMDest_Address = 0x%08X\n", RAMDest_Address);

        // We have received all data correctly. Send ACK.

        memset(inBuffer, 0, SystemGetBufferSize());

        SerialSetState(SERIAL_STATE_WRITING_ACK);

        SerialWrite(ACK_BYTE_STRING, sizeof(uint8_t)); // Write ACK

        // Get PSX-EXE size, without header, in hexadecimal, little-endian format;

        SerialSetState(SERIAL_STATE_READING_EXE_SIZE);

        SerialRead(inBuffer, sizeof(uint32_t) );

        for(i = 0; i < sizeof(uint32_t); i++)
        {
            ExeSize |= inBuffer[i] << (i << 3); // (i << 3) == (i * 8)
        }

        SerialSetExeSize(ExeSize);

        //DEBUG_PRINT_VAR(ExeSize);

        SerialSetState(SERIAL_STATE_CLEANING_MEMORY);

        exeAddress = (void*)initPC_Address;

        // Clean memory where EXE data will be loaded, just in case...

        memset((void*)RAMDest_Address, 0, (uint32_t)((uint32_t)(&_start) - (uint32_t)(RAMDest_Address) ) );

        SerialSetState(SERIAL_STATE_WRITING_ACK);

        // We have received PSX-EXE size (without header) correctly. Send ACK.

        SerialWrite(ACK_BYTE_STRING, sizeof(uint8_t)); // Write ACK

        SerialSetState(SERIAL_STATE_READING_EXE_DATA);

        while(GfxIsGPUBusy() == true);

        for(i = 0; i < ExeSize; i += EXE_DATA_PACKET_SIZE)
        {
            uint32_t bytes_to_read;

            // Read actual EXE data into proper RAM address.

            if( (i + EXE_DATA_PACKET_SIZE) >= ExeSize)
            {
                bytes_to_read = ExeSize - i;
            }
            else
            {
                bytes_to_read = EXE_DATA_PACKET_SIZE;
            }

            SerialRead((uint8_t*)RAMDest_Address + i, bytes_to_read);

            SerialSetExeBytesReceived(bytes_to_read);

            SerialWrite(ACK_BYTE_STRING, sizeof(uint8_t)); // Write ACK
        }

        SetVBlankHandler(&ISR_SystemDefaultVBlank);

        // Make a pretty animation before exeting OpenSend application.

        EndAnimation();

        PSX_DeInit();

        // PSX-EXE has been successfully loaded into RAM. Run executable!

        //dprintf("Entering exe...\n");
        
        exeAddress();
    }
		
	return 0;
}