David Rimer
/
Gigatron_Emulator
A small emulator for the gigatron created for the STM32F746G-DISCO and an NES wii controller
main.cpp@0:72d8735c099e, 2020-03-05 (annotated)
- Committer:
- davidr99
- Date:
- Thu Mar 05 01:07:01 2020 +0000
- Revision:
- 0:72d8735c099e
Code for the gigatron emulator
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
davidr99 | 0:72d8735c099e | 1 | #include "mbed.h" |
davidr99 | 0:72d8735c099e | 2 | #include "stm32746g_discovery_lcd.h" |
davidr99 | 0:72d8735c099e | 3 | //#include "stm32746g_discovery_ts.h" |
davidr99 | 0:72d8735c099e | 4 | #include "GigatronCPU.h" |
davidr99 | 0:72d8735c099e | 5 | #include "I2CConfig.h" |
davidr99 | 0:72d8735c099e | 6 | #include "WiiClassicControllerReader.h" |
davidr99 | 0:72d8735c099e | 7 | |
davidr99 | 0:72d8735c099e | 8 | |
davidr99 | 0:72d8735c099e | 9 | Serial serial(USBTX, USBRX); |
davidr99 | 0:72d8735c099e | 10 | |
davidr99 | 0:72d8735c099e | 11 | #define BUTTON_A 0x80 |
davidr99 | 0:72d8735c099e | 12 | #define BUTTON_B 0x40 |
davidr99 | 0:72d8735c099e | 13 | #define BUTTON_SELECT 0x20 |
davidr99 | 0:72d8735c099e | 14 | #define BUTTON_START 0x10 |
davidr99 | 0:72d8735c099e | 15 | #define BUTTON_UP 0x08 |
davidr99 | 0:72d8735c099e | 16 | #define BUTTON_DOWN 0x04 |
davidr99 | 0:72d8735c099e | 17 | #define BUTTON_LEFT 0x02 |
davidr99 | 0:72d8735c099e | 18 | #define BUTTON_RIGHT 0x01 |
davidr99 | 0:72d8735c099e | 19 | |
davidr99 | 0:72d8735c099e | 20 | #define HZ 6250000 |
davidr99 | 0:72d8735c099e | 21 | |
davidr99 | 0:72d8735c099e | 22 | GigatronCPU * cpu; |
davidr99 | 0:72d8735c099e | 23 | CPUStates cpuState; |
davidr99 | 0:72d8735c099e | 24 | VGA vga; |
davidr99 | 0:72d8735c099e | 25 | bool vSync = false; |
davidr99 | 0:72d8735c099e | 26 | uint32_t cycles = 0; |
davidr99 | 0:72d8735c099e | 27 | bool justStarted = true; |
davidr99 | 0:72d8735c099e | 28 | int ledStatus = 0; |
davidr99 | 0:72d8735c099e | 29 | |
davidr99 | 0:72d8735c099e | 30 | extern const uint8_t rom_map[]; |
davidr99 | 0:72d8735c099e | 31 | |
davidr99 | 0:72d8735c099e | 32 | /* |
davidr99 | 0:72d8735c099e | 33 | void ReadAndReport(WiiClassicControllerReader* const ctrlr, const char* const portname) |
davidr99 | 0:72d8735c099e | 34 | { |
davidr99 | 0:72d8735c099e | 35 | int bufSize = 0; |
davidr99 | 0:72d8735c099e | 36 | char* bufPtr = NULL; |
davidr99 | 0:72d8735c099e | 37 | bool debug = true; |
davidr99 | 0:72d8735c099e | 38 | |
davidr99 | 0:72d8735c099e | 39 | ctrlr->RequestRead(); |
davidr99 | 0:72d8735c099e | 40 | serial.printf("%s: ", portname); |
davidr99 | 0:72d8735c099e | 41 | |
davidr99 | 0:72d8735c099e | 42 | if (debug) |
davidr99 | 0:72d8735c099e | 43 | { |
davidr99 | 0:72d8735c099e | 44 | bufSize = ctrlr->getBufferSize(); |
davidr99 | 0:72d8735c099e | 45 | bufPtr = ctrlr->getReadBuf(); |
davidr99 | 0:72d8735c099e | 46 | if (bufPtr != NULL) |
davidr99 | 0:72d8735c099e | 47 | { |
davidr99 | 0:72d8735c099e | 48 | for (int i = 0; i < bufSize; i++) |
davidr99 | 0:72d8735c099e | 49 | { |
davidr99 | 0:72d8735c099e | 50 | serial.printf("%x ", bufPtr[i]); |
davidr99 | 0:72d8735c099e | 51 | } |
davidr99 | 0:72d8735c099e | 52 | serial.printf("\r\n"); |
davidr99 | 0:72d8735c099e | 53 | } |
davidr99 | 0:72d8735c099e | 54 | } |
davidr99 | 0:72d8735c099e | 55 | serial.printf("\r\nA\tB\tX\tY\tZL\tZR\tDU\tDD\tDL\tDR\tH\r\n"); |
davidr99 | 0:72d8735c099e | 56 | serial.printf("%d\t", ctrlr->getButtonA()); |
davidr99 | 0:72d8735c099e | 57 | serial.printf("%d\t", ctrlr->getButtonB()); |
davidr99 | 0:72d8735c099e | 58 | serial.printf("%d\t", ctrlr->getButtonX()); |
davidr99 | 0:72d8735c099e | 59 | serial.printf("%d\t", ctrlr->getButtonY()); |
davidr99 | 0:72d8735c099e | 60 | serial.printf("%d\t", ctrlr->getButtonZL()); |
davidr99 | 0:72d8735c099e | 61 | serial.printf("%d\t", ctrlr->getButtonZR()); |
davidr99 | 0:72d8735c099e | 62 | serial.printf("%d\t", ctrlr->getButtonDU()); |
davidr99 | 0:72d8735c099e | 63 | serial.printf("%d\t", ctrlr->getButtonDD()); |
davidr99 | 0:72d8735c099e | 64 | serial.printf("%d\t", ctrlr->getButtonDL()); |
davidr99 | 0:72d8735c099e | 65 | serial.printf("%d\t", ctrlr->getButtonDR()); |
davidr99 | 0:72d8735c099e | 66 | serial.printf("%d\t", ctrlr->getButtonHOME()); |
davidr99 | 0:72d8735c099e | 67 | serial.printf("\r\nSEL\tSTART\tLT\tLC\tRT\tRC\tLX\tLY\tRX\tRY\r\n"); |
davidr99 | 0:72d8735c099e | 68 | serial.printf("%d\t", ctrlr->getButtonSELECT()); |
davidr99 | 0:72d8735c099e | 69 | serial.printf("%d\t", ctrlr->getButtonSTART()); |
davidr99 | 0:72d8735c099e | 70 | serial.printf("%d\t", ctrlr->getButtonLT()); |
davidr99 | 0:72d8735c099e | 71 | serial.printf("%d\t", ctrlr->getButtonLC()); |
davidr99 | 0:72d8735c099e | 72 | serial.printf("%d\t", ctrlr->getButtonRT()); |
davidr99 | 0:72d8735c099e | 73 | serial.printf("%d\t", ctrlr->getButtonRC()); |
davidr99 | 0:72d8735c099e | 74 | serial.printf("%d\t", ctrlr->getLJoyX()); |
davidr99 | 0:72d8735c099e | 75 | serial.printf("%d\t", ctrlr->getLJoyY()); |
davidr99 | 0:72d8735c099e | 76 | serial.printf("%d\t", ctrlr->getRJoyX()); |
davidr99 | 0:72d8735c099e | 77 | serial.printf("%d\t", ctrlr->getRJoyY()); |
davidr99 | 0:72d8735c099e | 78 | serial.printf("\r\n\n\n"); |
davidr99 | 0:72d8735c099e | 79 | } |
davidr99 | 0:72d8735c099e | 80 | */ |
davidr99 | 0:72d8735c099e | 81 | |
davidr99 | 0:72d8735c099e | 82 | int main() |
davidr99 | 0:72d8735c099e | 83 | { |
davidr99 | 0:72d8735c099e | 84 | WiiClassicControllerReader ctrlrA(I2CPort_A::SDA, I2CPort_A::SCL); |
davidr99 | 0:72d8735c099e | 85 | //I2C test(PB_9, PB_8); |
davidr99 | 0:72d8735c099e | 86 | |
davidr99 | 0:72d8735c099e | 87 | /* |
davidr99 | 0:72d8735c099e | 88 | while (true) |
davidr99 | 0:72d8735c099e | 89 | { |
davidr99 | 0:72d8735c099e | 90 | ReadAndReport(&ctrlrA, "PORT A"); |
davidr99 | 0:72d8735c099e | 91 | wait(1); |
davidr99 | 0:72d8735c099e | 92 | }*/ |
davidr99 | 0:72d8735c099e | 93 | |
davidr99 | 0:72d8735c099e | 94 | |
davidr99 | 0:72d8735c099e | 95 | ctrlrA.RequestRead(); |
davidr99 | 0:72d8735c099e | 96 | BSP_LCD_Init(); |
davidr99 | 0:72d8735c099e | 97 | BSP_LCD_LayerDefaultInit(LTDC_ACTIVE_LAYER, LCD_FB_START_ADDRESS); |
davidr99 | 0:72d8735c099e | 98 | //BSP_LCD_LayerRgb565Init(1, 0xC0100000); //0xC007F800 - End of Page 1 |
davidr99 | 0:72d8735c099e | 99 | BSP_LCD_SelectLayer(LTDC_ACTIVE_LAYER); |
davidr99 | 0:72d8735c099e | 100 | //BSP_LCD_SelectLayer(1); |
davidr99 | 0:72d8735c099e | 101 | |
davidr99 | 0:72d8735c099e | 102 | BSP_LCD_SetFont(&Font12); |
davidr99 | 0:72d8735c099e | 103 | BSP_LCD_SetBackColor(LCD_COLOR_BLUE); |
davidr99 | 0:72d8735c099e | 104 | BSP_LCD_SetTextColor(LCD_COLOR_WHITE); |
davidr99 | 0:72d8735c099e | 105 | |
davidr99 | 0:72d8735c099e | 106 | BSP_LCD_Clear(LCD_COLOR_BLACK); |
davidr99 | 0:72d8735c099e | 107 | |
davidr99 | 0:72d8735c099e | 108 | cpu = new GigatronCPU(); |
davidr99 | 0:72d8735c099e | 109 | cpuState.Current = new CPUState; |
davidr99 | 0:72d8735c099e | 110 | cpuState.New = new CPUState; |
davidr99 | 0:72d8735c099e | 111 | |
davidr99 | 0:72d8735c099e | 112 | cpu->SetCPURom((uint8_t *) &rom_map); |
davidr99 | 0:72d8735c099e | 113 | |
davidr99 | 0:72d8735c099e | 114 | while(1) { |
davidr99 | 0:72d8735c099e | 115 | cpuState = cpu->CpuCycle(cpuState); |
davidr99 | 0:72d8735c099e | 116 | cycles++; |
davidr99 | 0:72d8735c099e | 117 | |
davidr99 | 0:72d8735c099e | 118 | vga.ClockCycle(cpuState.New->OUT); |
davidr99 | 0:72d8735c099e | 119 | |
davidr99 | 0:72d8735c099e | 120 | |
davidr99 | 0:72d8735c099e | 121 | if ((cycles % ((HZ / 100) + 100)) == 0 && !justStarted) |
davidr99 | 0:72d8735c099e | 122 | { |
davidr99 | 0:72d8735c099e | 123 | int buttons = 0x00; |
davidr99 | 0:72d8735c099e | 124 | |
davidr99 | 0:72d8735c099e | 125 | ctrlrA.ControllerReadCmd(); |
davidr99 | 0:72d8735c099e | 126 | //ctrlrA.RequestRead(); |
davidr99 | 0:72d8735c099e | 127 | ctrlrA.ControllerDecode(); |
davidr99 | 0:72d8735c099e | 128 | |
davidr99 | 0:72d8735c099e | 129 | if (ctrlrA.getButtonA() == 0) |
davidr99 | 0:72d8735c099e | 130 | { |
davidr99 | 0:72d8735c099e | 131 | buttons |= BUTTON_A; |
davidr99 | 0:72d8735c099e | 132 | //serial.printf("A "); |
davidr99 | 0:72d8735c099e | 133 | } |
davidr99 | 0:72d8735c099e | 134 | |
davidr99 | 0:72d8735c099e | 135 | if (ctrlrA.getButtonB() == 0) |
davidr99 | 0:72d8735c099e | 136 | { |
davidr99 | 0:72d8735c099e | 137 | buttons |= BUTTON_B; |
davidr99 | 0:72d8735c099e | 138 | //serial.printf("B "); |
davidr99 | 0:72d8735c099e | 139 | } |
davidr99 | 0:72d8735c099e | 140 | |
davidr99 | 0:72d8735c099e | 141 | if (ctrlrA.getButtonDD() == 0) |
davidr99 | 0:72d8735c099e | 142 | { |
davidr99 | 0:72d8735c099e | 143 | buttons |= BUTTON_DOWN; |
davidr99 | 0:72d8735c099e | 144 | //serial.printf("D "); |
davidr99 | 0:72d8735c099e | 145 | } |
davidr99 | 0:72d8735c099e | 146 | |
davidr99 | 0:72d8735c099e | 147 | if (ctrlrA.getButtonDU() == 0) |
davidr99 | 0:72d8735c099e | 148 | { |
davidr99 | 0:72d8735c099e | 149 | buttons |= BUTTON_UP; |
davidr99 | 0:72d8735c099e | 150 | //serial.printf("U "); |
davidr99 | 0:72d8735c099e | 151 | } |
davidr99 | 0:72d8735c099e | 152 | |
davidr99 | 0:72d8735c099e | 153 | if (ctrlrA.getButtonDL() == 0) |
davidr99 | 0:72d8735c099e | 154 | { |
davidr99 | 0:72d8735c099e | 155 | buttons |= BUTTON_LEFT; |
davidr99 | 0:72d8735c099e | 156 | //serial.printf("U "); |
davidr99 | 0:72d8735c099e | 157 | } |
davidr99 | 0:72d8735c099e | 158 | |
davidr99 | 0:72d8735c099e | 159 | if (ctrlrA.getButtonDR() == 0) |
davidr99 | 0:72d8735c099e | 160 | { |
davidr99 | 0:72d8735c099e | 161 | buttons |= BUTTON_RIGHT; |
davidr99 | 0:72d8735c099e | 162 | //serial.printf("U "); |
davidr99 | 0:72d8735c099e | 163 | } |
davidr99 | 0:72d8735c099e | 164 | |
davidr99 | 0:72d8735c099e | 165 | if (ctrlrA.getButtonSTART() == 0) |
davidr99 | 0:72d8735c099e | 166 | { |
davidr99 | 0:72d8735c099e | 167 | buttons |= BUTTON_START; |
davidr99 | 0:72d8735c099e | 168 | //serial.printf("U "); |
davidr99 | 0:72d8735c099e | 169 | } |
davidr99 | 0:72d8735c099e | 170 | |
davidr99 | 0:72d8735c099e | 171 | if (ctrlrA.getButtonSELECT() == 0) |
davidr99 | 0:72d8735c099e | 172 | { |
davidr99 | 0:72d8735c099e | 173 | buttons |= BUTTON_SELECT; |
davidr99 | 0:72d8735c099e | 174 | //serial.printf("U "); |
davidr99 | 0:72d8735c099e | 175 | } |
davidr99 | 0:72d8735c099e | 176 | |
davidr99 | 0:72d8735c099e | 177 | // Active Low |
davidr99 | 0:72d8735c099e | 178 | cpuState.New->IN = buttons ^ 0xFF; |
davidr99 | 0:72d8735c099e | 179 | } |
davidr99 | 0:72d8735c099e | 180 | else if ((cycles % (HZ / 100)) == 0) |
davidr99 | 0:72d8735c099e | 181 | { |
davidr99 | 0:72d8735c099e | 182 | ctrlrA.ControllerWriteCmd(); |
davidr99 | 0:72d8735c099e | 183 | } |
davidr99 | 0:72d8735c099e | 184 | /* |
davidr99 | 0:72d8735c099e | 185 | else if ((cycles % (HZ / 100)) == 0) |
davidr99 | 0:72d8735c099e | 186 | { |
davidr99 | 0:72d8735c099e | 187 | if (serial.readable() == 1) |
davidr99 | 0:72d8735c099e | 188 | { |
davidr99 | 0:72d8735c099e | 189 | char c = serial.getc(); |
davidr99 | 0:72d8735c099e | 190 | |
davidr99 | 0:72d8735c099e | 191 | serial.printf("%c", c); |
davidr99 | 0:72d8735c099e | 192 | |
davidr99 | 0:72d8735c099e | 193 | switch(c) |
davidr99 | 0:72d8735c099e | 194 | { |
davidr99 | 0:72d8735c099e | 195 | case 13: |
davidr99 | 0:72d8735c099e | 196 | c = 10; |
davidr99 | 0:72d8735c099e | 197 | break; |
davidr99 | 0:72d8735c099e | 198 | } |
davidr99 | 0:72d8735c099e | 199 | |
davidr99 | 0:72d8735c099e | 200 | cpuState.New->IN = c; |
davidr99 | 0:72d8735c099e | 201 | } |
davidr99 | 0:72d8735c099e | 202 | } |
davidr99 | 0:72d8735c099e | 203 | */ |
davidr99 | 0:72d8735c099e | 204 | |
davidr99 | 0:72d8735c099e | 205 | justStarted = false; |
davidr99 | 0:72d8735c099e | 206 | } |
davidr99 | 0:72d8735c099e | 207 | } |