diff options
-rw-r--r-- | basys3/basys3.srcs/spi_tb.vhd | 1 | ||||
-rw-r--r-- | basys3/basys3.xpr | 4 | ||||
-rw-r--r-- | src/demo.c | 183 | ||||
-rw-r--r-- | src/demo.h | 35 | ||||
-rw-r--r-- | src/ds.c | 2 | ||||
-rw-r--r-- | src/main.c | 13 | ||||
-rw-r--r-- | src/makefile | 3 | ||||
-rw-r--r-- | src/ppu/consts.h | 4 | ||||
-rw-r--r-- | src/ppu/stm.c | 2 | ||||
-rw-r--r-- | src/ppusim/mem.c | 2 | ||||
-rw-r--r-- | src/stm32/main.c | 3 | ||||
-rw-r--r-- | src/stm32/setup.c | 3 | ||||
-rw-r--r-- | test/ppu-stm-integration-demo/test-image-sprites.txt | 104 |
13 files changed, 169 insertions, 190 deletions
diff --git a/basys3/basys3.srcs/spi_tb.vhd b/basys3/basys3.srcs/spi_tb.vhd index 255f38b..fea96b9 100644 --- a/basys3/basys3.srcs/spi_tb.vhd +++ b/basys3/basys3.srcs/spi_tb.vhd @@ -21,6 +21,7 @@ begin RESET => RESET, DO => open, DI => SPI_DATA, + SR => '0', DCK => SPI_CLK, WEN => open); diff --git a/basys3/basys3.xpr b/basys3/basys3.xpr index f90ecdb..852d6c3 100644 --- a/basys3/basys3.xpr +++ b/basys3/basys3.xpr @@ -60,7 +60,7 @@ <Option Name="IPStaticSourceDir" Val="$PIPUSERFILESDIR/ipstatic"/> <Option Name="EnableBDX" Val="FALSE"/> <Option Name="DSABoardId" Val="basys3"/> - <Option Name="WTXSimLaunchSim" Val="118"/> + <Option Name="WTXSimLaunchSim" Val="124"/> <Option Name="WTModelSimLaunchSim" Val="0"/> <Option Name="WTQuestaLaunchSim" Val="0"/> <Option Name="WTIesLaunchSim" Val="0"/> @@ -243,7 +243,7 @@ </File> <Config> <Option Name="DesignMode" Val="RTL"/> - <Option Name="TopModule" Val="spi_tb"/> + <Option Name="TopModule" Val="ppu_tb"/> <Option Name="TopLib" Val="xil_defaultlib"/> <Option Name="TransportPathDelay" Val="0"/> <Option Name="TransportIntDelay" Val="0"/> @@ -1,154 +1,59 @@ #include <math.h> #include "demo.h" -#include "input.h" -#include "entity.h" #include "ppu/ppu.h" -#include "engine/maths.h" -#include "engine/camera.h" -#include "engine/entity.h" -#include "engine/draw_screen.h" -#include "engine/player_controller.h" -#include "engine/sprite_controller.h" +#include "ppu/internals.h" +#include "../test/ppu-stm-integration-demo/test-image-sprites.h" +#define HH_DEMO_BALL_COUNT 5 +hh_s_ppu_loc_fam_entry g_hh_demo_balls[HH_DEMO_BALL_COUNT]; -hh_s_entity_player g_hh_player_1 = { - .pos_x = 31000, // 0b0000 0001 0011 0110 - .pos_y = 21000, - .radius = 8, - .speed = 100, - .direction_x = 1, - .rotation = 8, - .in_air = false, -}; - -void hh_player_movement(); - -uint16_t g_hh_pos_x; // 0b0000 0001 0011 0110 -uint16_t g_hh_pos_y; -uint8_t g_hh_left = 0; -uint8_t g_hh_right = 0; -uint8_t g_hh_up = 0; -uint8_t g_hh_down = 0; -uint8_t g_hh_pos_x_bit[2]; -uint8_t g_hh_pos_y_bit[2]; -uint8_t g_hh_data_send[3]; -int g_hh_tile_x; -int g_hh_tile_y; - -typedef struct { - vec2 pos; - uint8_t idx; -}hh_s_tiles; - - -hh_entity hh_g_player, hh_g_player_new; void hh_demo_setup() { - - hh_setup_palettes(); - hh_setup_screen(); - -} - -void hh_demo_loop(unsigned long frame) { - - // hh_player_movement(); - - hh_player_actions(); - -} - -// void sendData(uint8_t address, uint16_t data) { -// uint8_t bitData[3]; -// bitData[2] = data & 0xff; -// bitData[1] = (data >> 8); -// bitData[0] = address; // first byte is address -// -// HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_RESET); -// HAL_SPI_Transmit(&hspi1, bitData, 3, 100); //2*8 bit data -// HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_SET); -// } - -void hh_player_movement() { - int8_t directionX = (-1 * g_hh_controller_p1.dpad_left) + (1 * g_hh_controller_p1.dpad_right); // -1 = L || 1 == R - int8_t directionY = (-1 * g_hh_controller_p1.dpad_up) + (1 * g_hh_controller_p1.dpad_down); // -1 = D || 1 == U - - uint8_t i, j; - uint8_t rotation = 0; // 0-7 - - // rotation calc - for (i = -1; i < 2; i++) { - for (j = -1; j < 2; j++) { - if (directionX == i) { - if (directionY == j) { - if (i != 0 && j != 0) // dont update when player idle - { - g_hh_player_1.rotation = rotation; - } - } - } - rotation++; - } - } - // direction calc - if (directionX != 0) // update direction if player is not idle - { - g_hh_player_1.direction_x = directionX; + // load sprites + hh_ppu_update_sprite(0, HH_DBG_SPRITE_BALL); + hh_ppu_update_sprite(1, HH_DBG_SPRITE_CHECKERBOARD); + + // background pattern + hh_ppu_update_color(0, 1, (hh_ppu_rgb_color_t) {0x4, 0x4, 0x4}); + for (unsigned i = 0; i < HH_PPU_BG_CANVAS_TILES_H * HH_PPU_BG_CANVAS_TILES_V; i++) { + hh_ppu_update_background(i, (hh_s_ppu_loc_bam_entry) { + .horizontal_flip = false, + .vertical_flip = false, + .palette_index = 0, + .tilemap_index = 1, + }); } - // collision map x-axis - - // tile calc including radius and direction for background coliision - - uint16_t tileColX; - uint16_t tileColY = (g_hh_player_1.pos_y / 100) / 16; - ; - - // remaining space between grid and exact - uint8_t modTileX; - uint8_t modTileY; - if (g_hh_player_1.in_air == false && directionX != 0) { - if (directionX == 1) { - tileColX = ((g_hh_player_1.pos_x / 100) + g_hh_player_1.radius) / 16; - modTileX = (g_hh_player_1.pos_x + (100 * g_hh_player_1.radius)) % 1600; - } else if (directionX == -1) { - tileColX = ((g_hh_player_1.pos_x / 100) - g_hh_player_1.radius) / 16; - modTileX = (g_hh_player_1.pos_x - (100 * g_hh_player_1.radius)) % 1600; - } - - if (HH_DEMO_HITBOX_TILEMAP[tileColY][tileColX + directionX] != 1) { - g_hh_player_1.pos_x = g_hh_player_1.pos_x + (directionX * g_hh_player_1.speed); // NEW x set - } - - else if (HH_DEMO_HITBOX_TILEMAP[tileColY][tileColX + directionX] == 1) { - if (modTileX < g_hh_player_1.speed) { - g_hh_player_1.pos_x = g_hh_player_1.pos_x + (directionX * modTileX); // NEW x set - } else { - g_hh_player_1.pos_x = g_hh_player_1.pos_x + (directionX * g_hh_player_1.speed); // NEW x set - } - } - - } else // if in air different all borders have to be checked - { + // cool colors + hh_ppu_update_color(1, 1, (hh_ppu_rgb_color_t) {0xf, 0x0, 0xf}); + hh_ppu_update_color(2, 1, (hh_ppu_rgb_color_t) {0xf, 0xf, 0xf}); + hh_ppu_update_color(3, 1, (hh_ppu_rgb_color_t) {0xf, 0x0, 0x0}); + hh_ppu_update_color(4, 1, (hh_ppu_rgb_color_t) {0x0, 0xf, 0xf}); + hh_ppu_update_color(5, 1, (hh_ppu_rgb_color_t) {0x0, 0x0, 0xf}); + + // balls + for (unsigned i = 0; i < HH_DEMO_BALL_COUNT; i++) { + g_hh_demo_balls[i].horizontal_flip = false; + g_hh_demo_balls[i].vertical_flip = false; + g_hh_demo_balls[i].palette_index = i+1; + g_hh_demo_balls[i].tilemap_index = 0; } +} - - if(directionY != 0) - { - // g_hh_player_1.pos_y = g_hh_player_1.pos_y + (directionY * g_hh_player_1.speed * 2); // NEW x set - } - // collision map floor (y-axis) (falling) - // if falling no jump press (implement) - /* - tileColY = (( g_hh_player_1.pos_y / 100) + g_hh_player_1.radius) / 16; //bottom of player box - modTileY = 1; - if(HH_DEMO_HITBOX_TILEMAP[tileColY+1][tileColX] != 1) //rework after jumping - { - g_hh_player_1.pos_y = g_hh_player_1.pos_y + 5 ;// NEW y set //makew var gravity - //playerStat = falling; //for later use of graphics/sound +void hh_demo_loop(unsigned long frame) { + // set background pattern position + hh_ppu_update_aux((hh_s_ppu_loc_aux) { + .bg_shift_x = (frame / 2) % HH_PPU_SPRITE_WIDTH, + .bg_shift_y = (frame / 8) % HH_PPU_SPRITE_HEIGHT, + .fg_fetch = 0, + .sysreset = 0, + }); + + for (unsigned i = 0; i < HH_DEMO_BALL_COUNT; i++) { + g_hh_demo_balls[i].position_x = HH_PPU_SCREEN_WIDTH/2 - HH_PPU_SPRITE_WIDTH/2 + (int)(60 * (double)sin((1*(double)frame / 10) + (double)i * 12)); + g_hh_demo_balls[i].position_y = HH_PPU_SCREEN_HEIGHT/2 - HH_PPU_SPRITE_HEIGHT/2 + (int)(30 * (double)sin((2*(double)frame / 10) + (double)i * 12)); + hh_ppu_update_foreground(i+16, g_hh_demo_balls[i]); } - */ - // else if(HH_DEMO_HITBOX_TILEMAP[]) } @@ -42,38 +42,3 @@ static const hh_s_ppu_loc_sprite HH_DBG_SPRITE_CHECKERBOARD = { 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0 }; - -static const uint8_t HH_DEMO_HITBOX_TILEMAP[30][40] = - { - {1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 }, - {1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 }, - {1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 }, - {1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 }, - {1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 }, - {1,1,1,1,1,1,1,1,1,1 ,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0 ,1,1,1,1,1,1,1,1,1,1 }, - {1,1,1,1,1,1,1,1,1,1 ,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0 ,1,1,1,1,1,1,1,1,1,1 }, - {1,1,1,1,1,1,1,1,1,1 ,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0 ,1,1,1,1,1,1,1,1,1,1 }, - {1,1,1,1,1,1,1,1,1,1 ,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0 ,1,1,1,1,1,1,1,1,1,1 }, - {1,1,1,1,1,1,1,1,1,1 ,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0 ,1,1,1,1,1,1,1,1,1,1 }, - {1,1,1,1,1,1,1,1,1,1 ,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0 ,1,1,1,1,1,1,1,1,1,1 }, - {1,1,1,1,1,1,1,1,1,1 ,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0 ,1,1,1,1,1,1,1,1,1,1 }, - {1,1,1,1,1,1,1,1,1,1 ,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0 ,1,1,1,1,1,1,1,1,1,1 }, - {1,1,1,1,1,1,1,1,1,1 ,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0 ,1,1,1,1,1,1,1,1,1,1 }, - {1,1,1,1,1,1,1,1,1,1 ,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0 ,1,1,1,1,1,1,1,1,1,1 }, - {1,1,1,1,1,1,1,1,1,1 ,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0 ,1,1,1,1,1,1,1,1,1,1 }, - {1,1,1,1,1,1,1,1,1,1 ,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0 ,1,1,1,1,1,1,1,1,1,1 }, - {1,1,1,1,1,1,1,1,1,1 ,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0 ,1,1,1,1,1,1,1,1,1,1 }, - {1,1,1,1,1,1,1,1,1,1 ,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0 ,1,1,1,1,1,1,1,1,1,1 }, - {1,1,1,1,1,1,1,1,1,1 ,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0 ,1,1,1,1,1,1,1,1,1,1 }, - {1,1,1,1,1,1,1,1,1,1 ,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0 ,1,1,1,1,1,1,1,1,1,1 }, - {1,1,1,1,1,1,1,1,1,1 ,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0 ,1,1,1,1,1,1,1,1,1,1 }, - {1,1,1,1,1,1,1,1,1,1 ,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0 ,1,1,1,1,1,1,1,1,1,1 }, - {1,1,1,1,1,1,1,1,1,1 ,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0 ,1,1,1,1,1,1,1,1,1,1 }, - {1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 }, - {1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 }, - {1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 }, - {1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 }, - {1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 }, - {1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 } - }; - @@ -1,8 +1,10 @@ #include "main.h" #include "ppu/ppu.h" +#include "demo.h" void hh_setup() { hh_ppu_init(); + hh_demo_setup(); } void hh_exit() { @@ -1,19 +1,16 @@ #include <stdlib.h> #include "main.h" -#include "../test/ppu-stm-integration-demo/data.h" +#include "demo.h" +#include "ppu/ppu.h" #include "ppu/internals.h" bool g_hh_run = true; -bool g_hh_test_complete = false; - void hh_ppu_vblank_interrupt() { -#ifdef HH_TARGET_DESKTOP - if (g_hh_test_complete) return; -#endif - hh_ppu_vram_dwrite((uint8_t*) HH_PPUINTDEMO_ARR, HH_PPUINTDEMO_LENGTH); - g_hh_test_complete = true; + static unsigned long frame = 0; + hh_demo_loop(frame++); + hh_ppu_vram_flush(); } int main() { diff --git a/src/makefile b/src/makefile index bbd859e..8ef67b0 100644 --- a/src/makefile +++ b/src/makefile @@ -29,7 +29,8 @@ CFLAGS += $(if $(DESKTOP), -DHH_TARGET_DESKTOP, ) LOCAL_SRCS += ppu/internals.c \ ppu/ppu.c \ - main.c + main.c \ + demo.c CFLAGS += $(SHARED_FLAGS) LFLAGS += $(SHARED_FLAGS) diff --git a/src/ppu/consts.h b/src/ppu/consts.h index 917510f..4cdd428 100644 --- a/src/ppu/consts.h +++ b/src/ppu/consts.h @@ -25,9 +25,9 @@ /** @brief amount of bytes in command (16 + 16 bits) */ #define HH_PPU_COMMAND_BYTES 4 -/** @brief command buffer size (large enough to update entire screen + all fg sprites + aux + all palettes) */ +/** @brief command buffer size (large enough to update entire screen + all fg sprites + aux + all palettes + 16 for safety) */ #define HH_PPU_COMMAND_BUFFER_SIZE (HH_PPU_COMMAND_BYTES * \ - (HH_PPU_VRAM_FAM_SIZE + HH_PPU_VRAM_BAM_SIZE + HH_PPU_VRAM_AUX_SIZE + HH_PPU_VRAM_PAL_SIZE)) + (HH_PPU_VRAM_FAM_SIZE + HH_PPU_VRAM_BAM_SIZE + HH_PPU_VRAM_AUX_SIZE + HH_PPU_VRAM_PAL_SIZE + 16)) #include "ppu/types.h" diff --git a/src/ppu/stm.c b/src/ppu/stm.c index 8334090..72e46ae 100644 --- a/src/ppu/stm.c +++ b/src/ppu/stm.c @@ -15,7 +15,7 @@ void hh_ppu_vram_dwrite(uint8_t* data, size_t size) { HAL_SPI_Transmit(&hspi1, test, 4, HAL_MAX_DELAY); // HAL_Delay(100); } - HAL_SPI_Transmit(&hspi1, (uint8_t[4]){ 0xff }, size, HAL_MAX_DELAY); + HAL_SPI_Transmit(&hspi1, (uint8_t[4]){ 0xff }, 4, HAL_MAX_DELAY); // reset SPI HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_RESET); diff --git a/src/ppusim/mem.c b/src/ppusim/mem.c index f536727..06eba4b 100644 --- a/src/ppusim/mem.c +++ b/src/ppusim/mem.c @@ -11,7 +11,7 @@ void hh_ppu_vram_dwrite(uint8_t* data, size_t size) { if (i+4 > size) break; hh_ppu_addr_t ppu_addr = (data[i+0] << 8) | (data[i+1] << 0); hh_ppu_data_t ppu_data = (data[i+2] << 8) | (data[i+3] << 0); - // printf("%04x: %04x\n", ppu_addr, ppu_data); + printf("%04x: %04x\n", ppu_addr, ppu_data); if (!hh_ppu_vram_valid_address(ppu_addr)) continue; g_hh_ppusim_vram[ppu_addr] = ppu_data; } diff --git a/src/stm32/main.c b/src/stm32/main.c index d815154..fb548d8 100644 --- a/src/stm32/main.c +++ b/src/stm32/main.c @@ -6,8 +6,9 @@ void hh_ppu_load_tilemap() {} void hh_loop() { + // TODO: call hh_ppu_vblank_interrupt on interrupt instead of manually while (1) { hh_ppu_vblank_interrupt(); - HAL_Delay(1e3); + HAL_Delay(16); } } diff --git a/src/stm32/setup.c b/src/stm32/setup.c index 4f56535..9de1f48 100644 --- a/src/stm32/setup.c +++ b/src/stm32/setup.c @@ -7,6 +7,7 @@ #include "main.h" #include "setup.h" +#include "demo.h" #include "ppu/ppu.h" UART_HandleTypeDef huart2 = { @@ -73,6 +74,7 @@ void hh_setup() { hh_io_tim_setup(); hh_ppu_init(); + hh_demo_setup(); } void hh_exit() { @@ -150,6 +152,7 @@ void hh_io_gpio_setup() { void HAL_MspInit() { __HAL_RCC_SYSCFG_CLK_ENABLE(); __HAL_RCC_PWR_CLK_ENABLE(); + HAL_NVIC_SetPriority(PendSV_IRQn, 3, 0); } void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi) { diff --git a/test/ppu-stm-integration-demo/test-image-sprites.txt b/test/ppu-stm-integration-demo/test-image-sprites.txt new file mode 100644 index 0000000..82131e0 --- /dev/null +++ b/test/ppu-stm-integration-demo/test-image-sprites.txt @@ -0,0 +1,104 @@ +0000: 0000 +0001: 1249 +0002: 0001 +0003: 1000 +0004: 1249 +0005: 0249 +0006: 1000 +0007: 1249 +0008: 1249 +0009: 1001 +000a: 1249 +000b: 1249 +000c: 0049 +000d: 1249 +000e: 1249 +000f: 0249 +0010: 1249 +0011: 1249 +0012: 1249 +0013: 1249 +0014: 1249 +0015: 1249 +0016: 1249 +0017: 1249 +0018: 1249 +0019: 1249 +001a: 1249 +001b: 1249 +001c: 1249 +001d: 1249 +001e: 0249 +001f: 1249 +0020: 1249 +0021: 1249 +0022: 1241 +0023: 1241 +0024: 0049 +0025: 1000 +0026: 1201 +0027: 1249 +0028: 1049 +0029: 0009 +002a: 1249 +002b: 1049 +002c: 0009 +002d: 1240 +002e: 1249 +002f: 0009 +0030: 0000 +0031: 1249 +0032: 0001 +0033: 0000 +0034: 0001 +0035: 0208 +0036: 1000 +0037: 0000 +0038: 0200 +0039: 0000 +003a: 0048 +003b: 0200 +003c: 0001 +003d: 1008 +003e: 0200 +003f: 0040 +0040: 0008 +0041: 0208 +0042: 1000 +0043: 0008 +0044: 0200 +0045: 0000 +0046: 0008 +0047: 0200 +0048: 0001 +0049: 0208 +004a: 0200 +004b: 0040 +004c: 0008 +004d: 0201 +004e: 1000 +004f: 0008 +0050: 0040 +0051: 0000 +0052: 0008 +0053: 1000 +0054: 0001 +0055: 0208 +0056: 1000 +0057: 0040 +0058: 0008 +0059: 1001 +005a: 1000 +005b: 0008 +005c: 1040 +005d: 0000 +005e: 0008 +005f: 1000 +0060: 0000 +0061: 0208 +0062: 1000 +0063: 0008 +0064: 0008 +0065: 1001 +0066: 0200 +0067: 0000 |