Skip to content

Instantly share code, notes, and snippets.

@lovyan03
Last active July 25, 2024 10:48
Show Gist options
  • Save lovyan03/b50333fa917371bd92b4b5f2e7a67e89 to your computer and use it in GitHub Desktop.
Save lovyan03/b50333fa917371bd92b4b5f2e7a67e89 to your computer and use it in GitHub Desktop.
RP2040 RaspberryPi Pico のPWM出力機能を使ってNTSC信号を出力してみるテスト
/*
MIT License
Copyright (c) 2023 lovyan03
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
// フレームワークは earlephilhower版のArduinoCoreを使用。
// ※ mbed公式版では動作しない
// #pragma GCC optimize ("O3")
#include <Arduino.h>
#include <stdio.h>
#include <stdint.h>
#include <math.h>
#include <string.h>
#include <pico/stdlib.h>
#include <hardware/dma.h>
#include <hardware/pwm.h>
#include <hardware/clocks.h>
extern const uint16_t sushi[];
// NTSC信号をPWM出力するピン
#define PIN_OUTPUT 19
// デバッグ用、割込み処理中HIGHになるピン
// #define PIN_DEBUG_BUSY 15
// フレームバッファ (RGB332形式。1ピクセルあたり1Byte)
#define FRAME_WIDTH 192
#define FRAME_HEIGHT 128
uint8_t framebuffer[FRAME_WIDTH * FRAME_HEIGHT];
// NTSC出力 1ラインあたりのサンプル数
#define NUM_LINE_SAMPLES 910 // 227.5 * 4
// NTSC出力 走査線数
#define NUM_LINES 525 // 走査線525本
// DMAピンポンバッファ
uint16_t dma_buffer[2][(NUM_LINE_SAMPLES+3)&~3u];
// RGB332 カラーパレット
uint32_t color_tbl[256];
static int pwm_dma_chan;
static void makeDmaBuffer(uint16_t* buf, size_t line_num)
{
static uint_fast8_t odd_burst = 0;
odd_burst = 2 ^ odd_burst;
size_t y = line_num * 2;
bool odd_frame = y > NUM_LINES;
if (odd_frame) {
y = y - NUM_LINES;
}
if (y < 20)
{
for (int i = 0; i < 2; ++i)
{
int sink_index = y + i;
if (sink_index < 2) continue;
bool long_sink = sink_index >= 8 && sink_index <= 13;
auto b = &buf[i * (NUM_LINE_SAMPLES / 2)];
int sink_len = 0;
if (sink_index < 20) {
sink_len = long_sink ? 390 : 32;
memset(b, 0, sink_len * 2);
}
for (int j = sink_len; j < (NUM_LINE_SAMPLES / 2); ++j)
{
b[j] = 2;
}
}
}
else
{
y = (y-20);
int sink_len = 68;
int active_start = 148;
int burst_start = 76;
memset(buf, 0, sink_len * 2);
for (int i = burst_start; i < burst_start + 4 * 9; ++i)
{
buf[i] = 1 + (((1 + i + odd_burst) & 2));
}
if (y < 18) { active_start = NUM_LINE_SAMPLES; }
for (int i = burst_start + 4*10; i < active_start; ++i)
{
buf[i] = 2;
}
auto f = &framebuffer[(y>>2) * FRAME_WIDTH];
auto b = &buf[active_start];
for (int i = active_start; i < NUM_LINE_SAMPLES - 16; i+=4)
{
auto c = (const uint8_t*)(&color_tbl[*f++]);
b[0] = c[(odd_burst + 0) ];
b[1] = c[(odd_burst + 1) ];
b[2] = c[(odd_burst + 2) & 3];
b[3] = c[(odd_burst + 3) & 3];
b += 4;
}
}
}
static uint32_t setup_palette_ntsc_inner(uint32_t rgb, uint32_t diff_level, uint32_t base_level, float satuation_base, float chroma_scale)
{
static constexpr float BASE_RAD = (M_PI * 192) / 180; // 2.932153;
uint8_t buf[4];
uint32_t r = rgb >> 16;
uint32_t g = (rgb >> 8) & 0xFF;
uint32_t b = rgb & 0xFF;
float y = r * 0.299f + g * 0.587f + b * 0.114f;
float i = (b - y) * -0.2680f + (r - y) * 0.7358f;
float q = (b - y) * 0.4127f + (r - y) * 0.4778f;
y = y * diff_level / 256 + base_level;
float phase_offset = atan2f(i, q) + BASE_RAD;
float saturation = sqrtf(i * i + q * q) * chroma_scale;
saturation = saturation * satuation_base;
for (int j = 0; j < 4; j++)
{
int tmp = ((int)(128.5f + y + sinf(phase_offset + (float)M_PI / 2 * j) * saturation)) >> 8;
buf[j] = tmp < 0 ? 0 : (tmp > 255 ? 255 : tmp);
}
return buf[3] << 24
| buf[2] << 16
| buf[1] << 8
| buf[0] << 0
;
}
static void setup_palette_ntsc_332(uint32_t* palette, uint_fast16_t white_level, uint_fast16_t black_level, uint_fast8_t chroma_level)
{
float chroma_scale = chroma_level / 7168.0f;
float satuation_base = black_level / 2;
uint32_t diff_level = white_level - black_level;
for (int rgb332 = 0; rgb332 < 256; ++rgb332)
{
int r = (( rgb332 >> 5) * 0x49) >> 1;
int g = (((rgb332 >> 2) & 0x07) * 0x49) >> 1;
int b = (( rgb332 & 0x03) * 0x55);
palette[rgb332] = setup_palette_ntsc_inner(r<<16|g<<8|b, diff_level, black_level, satuation_base, chroma_scale);
}
}
static void irq_handler(void) {
static bool flip = false;
static size_t scanline = 0;
dma_channel_set_read_addr(pwm_dma_chan, dma_buffer[flip], true);
dma_hw->ints0 = 1u << pwm_dma_chan;
#if defined ( PIN_DEBUG_BUSY )
digitalWrite(PIN_DEBUG_BUSY, HIGH);
#endif
flip = !flip;
makeDmaBuffer(dma_buffer[flip], scanline);
if (++scanline >= NUM_LINES) {
scanline = 0;
}
#if defined ( PIN_DEBUG_BUSY )
digitalWrite(PIN_DEBUG_BUSY, LOW);
#endif
}
void setup(void)
{
#if defined ( PIN_DEBUG_BUSY )
pinMode(PIN_DEBUG_BUSY, OUTPUT);
#endif
setup_palette_ntsc_332(color_tbl, 960*2, 286*2, 128);
// CPUを157.5MHzで動作させる
uint32_t freq_khz = 157500;
// PWM周期を11サイクルとする (157.5 [MHz] / 11 = 14318181 [Hz])
uint32_t pwm_div = 11;
// ※ NTSCのカラー信号を1周期4サンプルで出力する。
// 出力されるカラーバースト信号は 14318181 [Hz] / 4 = 3579545 [Hz] となる。
set_sys_clock_khz(freq_khz, true);
gpio_set_function(PIN_OUTPUT, GPIO_FUNC_PWM);
auto pwm_slice_num = pwm_gpio_to_slice_num(PIN_OUTPUT);
pwm_config config = pwm_get_default_config();
pwm_config_set_clkdiv(&config, 1);
pwm_init(pwm_slice_num, &config, true);
pwm_set_wrap(pwm_slice_num, pwm_div - 1);
pwm_dma_chan = dma_claim_unused_channel(true);
auto pwm_dma_chan_config = dma_channel_get_default_config(pwm_dma_chan);
channel_config_set_transfer_data_size(&pwm_dma_chan_config, DMA_SIZE_16);
channel_config_set_read_increment(&pwm_dma_chan_config, true);
channel_config_set_write_increment(&pwm_dma_chan_config, false);
channel_config_set_dreq(&pwm_dma_chan_config, DREQ_PWM_WRAP0 + pwm_slice_num);
volatile void* wr_addr = &pwm_hw->slice[pwm_slice_num].cc;
wr_addr = (volatile void*)(((uintptr_t)wr_addr) + 2);
makeDmaBuffer(dma_buffer[0], 0);
dma_channel_configure(
pwm_dma_chan,
&pwm_dma_chan_config,
wr_addr,
dma_buffer[0],
NUM_LINE_SAMPLES,
true
);
dma_channel_set_irq0_enabled(pwm_dma_chan, true);
irq_set_exclusive_handler(DMA_IRQ_0, irq_handler);
irq_set_enabled(DMA_IRQ_0, true);
// カラーバー描画
for (size_t y = 0; y < FRAME_HEIGHT; ++y) {
size_t x = 100;
static constexpr const uint8_t colbar[] = {
0xFFu, 0xFCu, 0x1Fu, 0x1Cu, 0xE3u, 0xE0u, 0x03u, 0x00u
};
int baridx = 0;
uint8_t c = colbar[baridx];
for (int i = 0; i < FRAME_WIDTH; ++i)
{
if (++x >= 25) {
x = 0;
c = colbar[baridx&7];
++baridx;
}
framebuffer[i + y * FRAME_WIDTH] = c;
}
}
}
void loop(void)
{
static uint32_t counter = 0;
++counter;
for (size_t y = 24; y < 72; ++y)
{
for (size_t x = 0; x < FRAME_WIDTH; ++x)
{
size_t idx = ((x+counter) % 48) + ((y+counter) % 48) * 48;
uint_fast16_t rgb565 = (sushi[idx]);
uint8_t r = (rgb565 >> 8) & 0xE0u;
uint8_t g = (rgb565 >> 6) & 0x1Cu;
uint8_t b = (rgb565 >> 3) & 0x03u;
framebuffer[x + y * FRAME_WIDTH] = r + g + b;
}
}
for (size_t y = 72; y < FRAME_HEIGHT; ++y)
{
for (size_t x = 0; x < FRAME_WIDTH; ++x)
{
uint8_t r = (x-counter)<<1;
uint8_t g = (y+counter)<<1;
uint8_t b = (((x+counter) & 0x80) + ((y-counter) & 0x100)) >> 1;
framebuffer[x + y * FRAME_WIDTH] = (r & 0xE0) + ((g >> 3) & 0x1C) + (b >> 6);
}
}
}
constexpr const uint16_t sushi[2304] = {
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x1860, 0x69C5, 0x7A46, 0x82C8, 0x7B2B, 0x838C, 0x7BAE, 0x83AE, 0x7B2C, 0x5A07, 0x0821, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5143, 0xAB88,
0xFD2E, 0xFDD0, 0xFDF0, 0xFDF1, 0xFE32, 0xFEB5, 0xFF16, 0xFEF7, 0xFEF6, 0xFEF6, 0xFED5, 0xFED5, 0xFF17, 0xFED6, 0xE551, 0x934A,
0x5165, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7A65, 0xFDB0, 0xFE52, 0xFDD2,
0xFD92, 0xFD71, 0xFD30, 0xF590, 0xFDB1, 0xFD4E, 0xF52D, 0xFD6D, 0xFD8E, 0xF5AE, 0xFDCF, 0xF5F0, 0xF5F0, 0xF5D1, 0xFDF1, 0xFDF1,
0xFE12, 0xFE32, 0xCC2C, 0x5143, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFD6F, 0xFE74, 0xFD91, 0xFC8D, 0xFC2B,
0xFC4A, 0xF429, 0xFD0C, 0xF4CA, 0xFC88, 0xF4A9, 0xFCC9, 0xF4E9, 0xFD08, 0xFD09, 0xF509, 0xFD09, 0xF509, 0xFD2B, 0xF5AE, 0xF5AE,
0xF5B0, 0xF5D1, 0xFDF2, 0xFE12, 0xFCEE, 0x5143, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1840, 0xFEB3, 0xFE54, 0xFC8D, 0xFC4A, 0xFC89, 0xFC88,
0xFC86, 0xFDAD, 0xF528, 0xFD07, 0xFD27, 0xFD27, 0xFD47, 0xFD27, 0xF507, 0xFD07, 0xFCC6, 0xF54B, 0xFDAC, 0xF52A, 0xF4A7, 0xFCA8,
0xF4A8, 0xF4AA, 0xF50C, 0xF54E, 0xFDB1, 0xFDB0, 0xE40A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFE72, 0xFDF3, 0xFCA9, 0xFD08, 0xFD48, 0xFD66, 0xFE2B,
0xF60C, 0xFD46, 0xFD05, 0xFCE5, 0xFD05, 0xFCE5, 0xF4C5, 0xFD87, 0xFE4B, 0xF6B0, 0xFEAF, 0xFDC8, 0xFD26, 0xFCE7, 0xFCC7, 0xF4A8,
0xFC87, 0xF487, 0xFC68, 0xF489, 0xF4CB, 0xF56F, 0xFD70, 0xFD8E, 0x28C2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9B48, 0xFEB4, 0xFD68, 0xFDA8, 0xFD86, 0xFCA5, 0xFD09, 0xFB43,
0xFAE3, 0xFAA3, 0xFA62, 0xFA42, 0xFA62, 0xFB24, 0xFB86, 0xFAE3, 0xFAC1, 0xFAA0, 0xFB61, 0xFC85, 0xF5A8, 0xFE09, 0xFD87, 0xFD07,
0xF4C6, 0xFC87, 0xF467, 0xFC67, 0xFC48, 0xFC6A, 0xF4EC, 0xFD4F, 0xFDAF, 0x69A3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFF17, 0xFD46, 0xFCC5, 0xFB84, 0xFAC3, 0xFBC7, 0xF9C1, 0xF9A1,
0xF960, 0xF100, 0xE8E0, 0xF9E2, 0xE9A2, 0xF100, 0xF120, 0xE961, 0xF1A1, 0xFA02, 0xFA01, 0xFA01, 0xFA60, 0xFB41, 0xFCE5, 0xFE0B,
0xFDEB, 0xFD69, 0xFD29, 0xF50A, 0xF50B, 0xFD0C, 0xF56E, 0xFD2F, 0xF54F, 0xFDCF, 0x30C2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1841, 0xFD09, 0xFB23, 0xFA42, 0xF940, 0xFA42, 0xD101, 0xBA05, 0xAAE9,
0xABED, 0x93ED, 0x9C6F, 0x9CD1, 0xAD53, 0x9CF2, 0xACB1, 0xA40E, 0xB36D, 0xB288, 0xC902, 0xD8A0, 0xF161, 0xF263, 0xFB06, 0xFB22,
0xFCE4, 0xF608, 0xFD88, 0xFD06, 0xFCC8, 0xFCA9, 0xFC89, 0xF48B, 0xFCED, 0xFD6F, 0xFDAF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xDA85, 0xE9C3, 0xC3AC, 0xB533, 0xBE57, 0xDFBD, 0xE77D, 0xC677,
0xDEFA, 0xD698, 0xE71B, 0xE6F9, 0xF77D, 0xE73B, 0xEF3B, 0xEF7D, 0xE71A, 0xD71A, 0xDF3B, 0xB594, 0xCCAF, 0xC102, 0xE060, 0xE940,
0xF9E2, 0xFB42, 0xFD86, 0xFE2A, 0xFD68, 0xFD29, 0xFD0A, 0xFCCB, 0xFCCC, 0xFD0E, 0xFE52, 0x3103, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3A8A, 0xD79B, 0xBE36, 0xEF9D, 0xE71A, 0xEF3C, 0xE71A, 0xEF3C,
0xE71A, 0xD6B9, 0xD678, 0xE73B, 0xDED9, 0xE71B, 0xE71A, 0xE6FA, 0xDEDA, 0xE71B, 0xE6FA, 0xE71B, 0xE73B, 0xCED9, 0xB553, 0xBA87,
0xE0A0, 0xF181, 0xF9C1, 0xFBE3, 0xFEAC, 0xFE4E, 0xFDEC, 0xFDAD, 0xFD6D, 0xFD4E, 0xFED4, 0x2924, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xAD54, 0xD6D8, 0xCE36, 0xE73B, 0xBE36, 0xD6D9, 0xD71A,
0xCED9, 0xDF3B, 0xD6D9, 0xDED9, 0xCE97, 0xD6D9, 0xD6D9, 0xD6B8, 0xDF3A, 0xDEFA, 0xDED9, 0xE6FA, 0xE6FA, 0xEF3B, 0xEF5B, 0xDF1B,
0x9511, 0xB1C5, 0xF1C2, 0xF223, 0xFA61, 0xFCE4, 0xFDE7, 0xFD8A, 0xFD6B, 0xFDAE, 0xFE90, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4227, 0x9D53, 0xADB4, 0xE699, 0xF679, 0xFDD6,
0xFD96, 0xFD55, 0xFD34, 0xFD34, 0xFD14, 0xFD14, 0xF514, 0xFDB6, 0xF618, 0xF658, 0xE698, 0xDEB9, 0xCEF9, 0xD6DA, 0xDEFA, 0xDEB9,
0xEF3B, 0xC698, 0x9C4E, 0xC880, 0xF141, 0xF161, 0xFB23, 0xFD65, 0xFDA8, 0xFD27, 0xAB08, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x41C7, 0xD514, 0xFDF7, 0xFD14, 0xFCB2, 0xF472,
0xF430, 0xF3CF, 0xF38E, 0xF30C, 0xEB6E, 0xF411, 0xEBAE, 0xF34E, 0xEB4D, 0xEB8E, 0xF410, 0xF4B3, 0xFD75, 0xFE38, 0xE6B9, 0xD6F9,
0xD6B9, 0xCE57, 0xF79D, 0xBE77, 0x9A47, 0xC8A0, 0xE8A0, 0xF120, 0xEA60, 0xD369, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xF5D7, 0xFE38, 0xFD34, 0xF451, 0xF451, 0xEC31, 0xEC11,
0xF3CF, 0xEC11, 0xF4B3, 0xF493, 0xF3CF, 0xF2AB, 0xF2CC, 0xEACC, 0xF2AB, 0xF2AC, 0xEA8B, 0xEB2D, 0xF430, 0xEC72, 0xFD55, 0xFDF7,
0xEE57, 0xD697, 0xCED9, 0xE71B, 0xDF3A, 0xCEFA, 0xB552, 0xC5D5, 0xCEFB, 0xA5B5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2945, 0xFE9A, 0xFCD3, 0xF471, 0xF3D0, 0xEBAF, 0xEBF0, 0xEC51, 0xEC52,
0xF431, 0xEB6E, 0xEA6A, 0xEAAB, 0xEAAC, 0xEACC, 0xF2CB, 0xEACC, 0xF2AB, 0xF3AF, 0xF411, 0xF3AF, 0xEAAB, 0xF2EC, 0xEB2D, 0xF3CF,
0xF4D3, 0xFD96, 0xEDF6, 0xD697, 0xCEB8, 0xDEB9, 0xE73B, 0xD698, 0xFFFD, 0x62C9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2945, 0xFD55, 0xFC71, 0xF3CF, 0xEAEC, 0xF410, 0xF411, 0xF36E, 0xEB2D, 0xF32D,
0xEACC, 0xF2EC, 0xF34E, 0xF36E, 0xEB0D, 0xF30C, 0xF32E, 0xEB2D, 0xF3AF, 0xEA8B, 0xEA8A, 0xF2AC, 0xEB0C, 0xF30D, 0xEB2D, 0xF34D,
0xEB6E, 0xF3CF, 0xF4D3, 0xFD76, 0xEDF6, 0xC656, 0xD6B8, 0xF77B, 0x632B, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFE18, 0xFB6E, 0xF2EC, 0xF2AB, 0xF493, 0xF30C, 0xEAEC, 0xEB4E, 0xEB4E, 0xEC32,
0xF4F4, 0xEBAF, 0xEA8B, 0xF24A, 0xEA4A, 0xEA4A, 0xEA4A, 0xF24A, 0xEA6A, 0xF26B, 0xEA6A, 0xEA6A, 0xEA4A, 0xEAAB, 0xF38F, 0xEBCF,
0xF431, 0xF431, 0xF431, 0xF472, 0xF534, 0xFE39, 0x83CD, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xA451, 0xFACB, 0xF2EC, 0xF28B, 0xF472, 0xF28B, 0xF30D, 0xF30D, 0xF2ED, 0xF515, 0xF493,
0xEBB0, 0xF36F, 0xF32E, 0xEACC, 0xEA4A, 0xF22A, 0xEA29, 0xEA2A, 0xEA09, 0xEA29, 0xF2CC, 0xF411, 0xF3F0, 0xF34E, 0xEA8B, 0xF28B,
0xEAEC, 0xEB2D, 0xF3AE, 0xEBF0, 0xF410, 0xF492, 0xFDF8, 0xE5F6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFD96, 0xFAAB, 0xF34D, 0xFC31, 0xFA8A, 0xF1E9, 0xF26A, 0xF4B3, 0xF492, 0xE9E8, 0xE9E8,
0xEA08, 0xEA08, 0xF1C8, 0xE9E8, 0xF2AB, 0xF2EC, 0xF2ED, 0xF32E, 0xF34E, 0xF32E, 0xEAEC, 0xEA09, 0xEA4A, 0xF2AB, 0xEAAB, 0xEA8B,
0xF28B, 0xEACC, 0xEB0D, 0xF36E, 0xF3EF, 0xF430, 0xF471, 0xFD34, 0xFE59, 0x1082, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x3186, 0xFBCF, 0xFC73, 0xF36E, 0xE166, 0xD1E8, 0xD36E, 0xCB2C, 0xC945, 0xC125, 0xC186, 0xC166,
0xC966, 0xC104, 0xCA6A, 0xD229, 0xD125, 0xD905, 0xE145, 0xE9A7, 0xF1C8, 0xF208, 0xF209, 0xEA0A, 0xEA4A, 0xEAAC, 0xF32E, 0xF30D,
0xEACC, 0xF2AB, 0xF2AB, 0xEAAB, 0xF34E, 0xEC11, 0xF492, 0xF4F4, 0xFD54, 0xFEBB, 0x10A2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x728A, 0xFB8E, 0xD0C3, 0xC125, 0xB905, 0xC1C7, 0xB842, 0xB822, 0xB042, 0xB082, 0xB041, 0xB882,
0xB862, 0xD2EB, 0xB8A2, 0xC0C3, 0xB0E4, 0xC124, 0xB925, 0xC145, 0xC945, 0xD125, 0xD905, 0xF249, 0xFBD0, 0xFBD0, 0xFCB3, 0xF515,
0xFCB3, 0xF431, 0xF3F0, 0xF3AF, 0xF32D, 0xF2CC, 0xF34D, 0xF3CF, 0xF472, 0xFCD2, 0xFDF8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x6B0B, 0xF946, 0xC8A4, 0xB082, 0xA186, 0xAB6C, 0x9CB0, 0xADF5, 0xB676, 0xAE15, 0xCEFA, 0xB615,
0xBDB5, 0xB532, 0xB450, 0xAB0A, 0xAA69, 0xA145, 0xA062, 0xB082, 0xC0C3, 0xC104, 0xCA8A, 0xC186, 0xC904, 0xD125, 0xD986, 0xEA8B,
0xF38F, 0xFC32, 0xF3D0, 0xF34E, 0xF30C, 0xF2CC, 0xF2EC, 0xF32D, 0xF3CF, 0xFC92, 0xFCF3, 0x5208, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xA470, 0xBDB4, 0xD79C, 0xDF9C, 0xEF9D, 0xEF7D, 0xF7BD, 0xEF5D, 0xEF7C, 0xEF7D, 0xEF7D,
0xE73B, 0xE75C, 0xDEFA, 0xE79D, 0xDF9C, 0xDFBD, 0xC719, 0xADD5, 0x9C0E, 0xA2CA, 0xA0A2, 0xB862, 0xC104, 0xC125, 0xC945, 0xC966,
0xD166, 0xE229, 0xFB4E, 0xFBF1, 0xFBD0, 0xF34D, 0xF2EC, 0xFAEC, 0xF32D, 0xF3CF, 0xFC71, 0x9B8E, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x634C, 0xEF7C, 0xF7BE, 0xEF9D, 0xF79D, 0xE75C, 0xDEFA, 0xE73B, 0xE71B, 0xEF5C, 0xE73B,
0xE71B, 0xEF9D, 0xF79D, 0xEF7D, 0xEF7D, 0xE6FA, 0xEF9D, 0xEF5B, 0xE75C, 0xDF3B, 0xE7FE, 0xAD94, 0xA32B, 0x9861, 0xC0A3, 0xC104,
0xC965, 0xD167, 0xD145, 0xE1A7, 0xFAEC, 0xFB8F, 0xFB0D, 0xF2CC, 0xFAEC, 0xF34D, 0xFC51, 0x9BCF, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x10A2, 0xFFFF, 0xDEFA, 0xDEFA, 0xEF5C, 0xE75B, 0xE73B, 0xE73B, 0xDEFA, 0xD6B9, 0xD6D9,
0xEF5C, 0xE71A, 0xDF1B, 0xE73B, 0xE73B, 0xE73B, 0xE73C, 0xEF5C, 0xEF7D, 0xEF7D, 0xEF7D, 0xEF9C, 0xEFBD, 0xDFBD, 0xA4F2, 0xA185,
0xB862, 0xC0E3, 0xCA29, 0xD2AB, 0xD1A7, 0xEA29, 0xFB4D, 0xFBAF, 0xFBAF, 0xFC72, 0xFB8E, 0x7B6D, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x630A, 0xE719, 0xD6D9, 0xDEDA, 0xC657, 0xD698, 0xD6B9, 0xD698, 0xD6B9, 0xE71B,
0xCE77, 0xDEFA, 0xDEDA, 0xD6B9, 0xE71B, 0xDF1B, 0xDEFA, 0xDF1A, 0xE73C, 0xEF7C, 0xEF7C, 0xF7BE, 0xEF7D, 0xEF9D, 0xE75B, 0xD75B,
0xA5B4, 0x91A6, 0xC125, 0xC0C3, 0xC925, 0xC8E5, 0xE105, 0xFA29, 0xFB4D, 0xFB8E, 0xFB6E, 0x4249, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x39C6, 0xBE15, 0xD677, 0xE73B, 0xDEFA, 0xDEDA, 0xD6D9, 0xD6D9, 0xCE78,
0xC657, 0xDEFA, 0xCE78, 0xCE77, 0xE71B, 0xCE98, 0xE71B, 0xDEFA, 0xDF1A, 0xDEFA, 0xEF5C, 0xE71B, 0xE73B, 0xE73C, 0xE71B, 0xF7BE,
0xEF7D, 0xE7DD, 0xA552, 0xA145, 0xB882, 0xC145, 0xC105, 0xD105, 0xE905, 0xF966, 0xFD35, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x18C2, 0x632B, 0xAD93, 0xF79C, 0xDED9, 0xCE57, 0xDED9,
0xD6B9, 0xCE57, 0xCE78, 0xDEFA, 0xDED9, 0xBDF5, 0xE71B, 0xDEFA, 0xD698, 0xE71A, 0xDF1A, 0xCE98, 0xDF1B, 0xDED9, 0xE73B, 0xE75C,
0xF79D, 0xE73B, 0xF7BE, 0xDFDD, 0xACD1, 0xA0C3, 0xA8A3, 0xA8E3, 0xB0E4, 0xE0C4, 0xA451, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3A07, 0x7BEE, 0xC616,
0xDEF9, 0xCE77, 0xD6B8, 0xCE98, 0xDEB9, 0xE73B, 0xDED9, 0xCE98, 0xEF3C, 0xCE98, 0xD6B9, 0xD6B9, 0xDED9, 0xDEDA, 0xCE77, 0xDEFB,
0xDEFA, 0xDF1A, 0xEF5C, 0xE71B, 0xEF9D, 0xD79C, 0xACB0, 0x9A28, 0xBA8A, 0xDD13, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x4227, 0x632B, 0x8C4F, 0xC636, 0xDEF9, 0xD698, 0xDEF9, 0xBE16, 0xD6B9, 0xD6B8, 0xC616, 0xBDD5, 0xCE77, 0xDEFA, 0xD698,
0xD6B9, 0xD698, 0xDF1B, 0xE71B, 0xDF1B, 0xEF7C, 0xD6FA, 0xEF9D, 0xADF5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2123, 0x7BCE, 0xDEF9, 0xCE97, 0xDED9, 0xE73A, 0xDF3B, 0xD6B9, 0xCE98, 0xD698,
0xD698, 0xD6B9, 0xC636, 0xE71B, 0xCE77, 0xD6B9, 0xF79D, 0xFFFE, 0x0040, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x39C6, 0x52A9, 0x5AA9, 0x8C4F, 0xD6B9,
0xD6D8, 0xDED9, 0xD6F9, 0xD6B8, 0xC616, 0xDED9, 0x9D11, 0x0861, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0840, 0x4A48, 0x52CA, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment