Merge pull request #3 from JimmyStones/version-2

New release - updated UI, second analog stick support
This commit is contained in:
Jim Gregory
2021-10-17 21:38:23 +01:00
committed by GitHub
24 changed files with 3208 additions and 1079 deletions

2
.gitignore vendored
View File

@@ -42,7 +42,6 @@ verilator/obj_dir/*
verilator/x64/*
verilator/roms/*
verilator/*.hex
rtl/*.hex
src/os.asm
src/os.bin
src/os.lk
@@ -53,3 +52,4 @@ src/os.sym
.vscode/settings.json
verilator/imgui.ini
verilator/imgui.ini
docs/*

View File

@@ -1,9 +1,9 @@
/*============================================================================
MiSTer test harness - emu module
Input Test - emu module
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0
Date: 2021-07-03
Date: 2021-07-12
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
@@ -181,16 +181,13 @@ assign {UART_RTS, UART_TXD, UART_DTR} = 0;
assign {SD_SCK, SD_MOSI, SD_CS} = 'Z;
assign {SDRAM_DQ, SDRAM_A, SDRAM_BA, SDRAM_CLK, SDRAM_CKE, SDRAM_DQML, SDRAM_DQMH, SDRAM_nWE, SDRAM_nCAS, SDRAM_nRAS, SDRAM_nCS} = 'Z;
assign {DDRAM_CLK, DDRAM_BURSTCNT, DDRAM_ADDR, DDRAM_DIN, DDRAM_BE, DDRAM_RD, DDRAM_WE} = '0;
assign VGA_F1 = 0;
assign VGA_SCALER = 0;
assign HDMI_FREEZE = 0;
assign AUDIO_S = 0;
assign AUDIO_L = 0;
assign AUDIO_R = 0;
assign AUDIO_MIX = 0;
assign LED_DISK = 0;
assign LED_POWER = 0;
assign BUTTONS = 0;
@@ -209,9 +206,8 @@ localparam CONF_STR = {
"O89,Aspect ratio,Original,Full Screen,[ARC1],[ARC2];",
"-;",
"F0,BIN,Load BIOS;",
"F1,PF,Load Font;",
"-;",
"J1,A,B,X,Y,L,R,Select,Start,C,Z;",
"J1,A,B,X,Y,L,R,Select,Start;",
"V,v",`BUILD_DATE
};
@@ -233,12 +229,18 @@ wire [31:0] joystick_2;
wire [31:0] joystick_3;
wire [31:0] joystick_4;
wire [31:0] joystick_5;
wire [15:0] joystick_analog_0;
wire [15:0] joystick_analog_1;
wire [15:0] joystick_analog_2;
wire [15:0] joystick_analog_3;
wire [15:0] joystick_analog_4;
wire [15:0] joystick_analog_5;
wire [15:0] joystick_l_analog_0;
wire [15:0] joystick_l_analog_1;
wire [15:0] joystick_l_analog_2;
wire [15:0] joystick_l_analog_3;
wire [15:0] joystick_l_analog_4;
wire [15:0] joystick_l_analog_5;
wire [15:0] joystick_r_analog_0;
wire [15:0] joystick_r_analog_1;
wire [15:0] joystick_r_analog_2;
wire [15:0] joystick_r_analog_3;
wire [15:0] joystick_r_analog_4;
wire [15:0] joystick_r_analog_5;
wire [7:0] paddle_0;
wire [7:0] paddle_1;
wire [7:0] paddle_2;
@@ -254,6 +256,7 @@ wire [8:0] spinner_5;
wire [10:0] ps2_key;
wire [24:0] ps2_mouse;
wire [15:0] ps2_mouse_ext;
wire [32:0] timestamp;
hps_io #(.CONF_STR(CONF_STR)) hps_io
(
@@ -278,12 +281,18 @@ hps_io #(.CONF_STR(CONF_STR)) hps_io
.joystick_4(joystick_4),
.joystick_5(joystick_5),
.joystick_analog_0(joystick_analog_0),
.joystick_analog_1(joystick_analog_1),
.joystick_analog_2(joystick_analog_2),
.joystick_analog_3(joystick_analog_3),
.joystick_analog_4(joystick_analog_4),
.joystick_analog_5(joystick_analog_5),
.joystick_l_analog_0(joystick_l_analog_0),
.joystick_l_analog_1(joystick_l_analog_1),
.joystick_l_analog_2(joystick_l_analog_2),
.joystick_l_analog_3(joystick_l_analog_3),
.joystick_l_analog_4(joystick_l_analog_4),
.joystick_l_analog_5(joystick_l_analog_5),
.joystick_r_analog_0(joystick_r_analog_0),
.joystick_r_analog_1(joystick_r_analog_1),
.joystick_r_analog_2(joystick_r_analog_2),
.joystick_r_analog_3(joystick_r_analog_3),
.joystick_r_analog_4(joystick_r_analog_4),
.joystick_r_analog_5(joystick_r_analog_5),
.paddle_0(paddle_0),
.paddle_1(paddle_1),
@@ -301,7 +310,9 @@ hps_io #(.CONF_STR(CONF_STR)) hps_io
.ps2_key(ps2_key),
.ps2_mouse(ps2_mouse),
.ps2_mouse_ext(ps2_mouse_ext)
.ps2_mouse_ext(ps2_mouse_ext),
.TIMESTAMP(timestamp)
);
@@ -359,11 +370,13 @@ system system(
.dn_wr(ioctl_wr),
.dn_index(ioctl_index),
.joystick({joystick_5,joystick_4,joystick_3,joystick_2,joystick_1,joystick_0}),
.analog({joystick_analog_5,joystick_analog_4,joystick_analog_3,joystick_analog_2,joystick_analog_1,joystick_analog_0}),
.analog_l({joystick_l_analog_5,joystick_l_analog_4,joystick_l_analog_3,joystick_l_analog_2,joystick_l_analog_1,joystick_l_analog_0}),
.analog_r({joystick_r_analog_5,joystick_r_analog_4,joystick_r_analog_3,joystick_r_analog_2,joystick_r_analog_1,joystick_r_analog_0}),
.paddle({paddle_5,paddle_4,paddle_3,paddle_2,paddle_1,paddle_0}),
.spinner({7'b0,spinner_5,7'b0,spinner_4,7'b0,spinner_3,7'b0,spinner_2,7'b0,spinner_1,7'b0,spinner_0}),
.ps2_key(ps2_key),
.ps2_mouse({ps2_mouse_ext,7'b0,ps2_mouse})
.ps2_mouse({ps2_mouse_ext,7'b0,ps2_mouse}),
.timestamp(timestamp)
);
endmodule

BIN
PETSCII.pf Normal file

Binary file not shown.

View File

@@ -2,12 +2,13 @@
## Overview
A custom mini-system running an input test utility. 3 test screens available:
A custom mini-system running an input test utility. There are 4 test screens available:
- Digital - shows joypad buttons for first two input devices
- Analog - shows analog axes for first two input devices
- Analog - shows analog axes for selected input device (cycle with a/b)
- Advanced - shows all standard HPS sourced inputs (joystick, analog, paddle, spinner) simultaneously as well as a ps2 keyboard console
Mode switching instructions are shown at the bottom of the screen.
- Button test - guided button test to help detect bounce / missed inputs and test man+machine lag
Hold (select) on the first joypad to enter the menu
## Acknowledgements
@@ -16,9 +17,14 @@ Created by JimmyStones (http://github.com/jimmystones), with thanks to:
- Jotego (https://github.com/jotego) for his very tidy JTFRAME modules
- Porkchop Express (https://misteraddons.com/) for testing a bunch of devices I couldn't
## History
- v1.0 - 2021-07-03 - First release with digital, analog and advanced tests
- v1.1 - 2021-07-18 - PETSCII UI update, add button test mode (unreleased!)
- v1.2 - 2021-10-17 - Add support for 2nd analog stick
## Hardware
A simple bespoke (i.e. I made it up with no real plan) 8-bit system with a 40x30 character display, each character can be set to one of 256 colours. No sound capabilities. All relevant MiSTer inputs are mapped into memory regions.
A simple bespoke (i.e. I made it up with no real plan) 8-bit system with a 40x30 character display, each character foreground and background colour can be set independently to one of 256 colours. No sound capabilities whatsoever. All relevant MiSTer inputs are mapped into memory regions for the CPU to access directly. There is also a dedicated millisecond timer (runs 0-32677, resettable by writing to any bit of the address).
### Components
- Z80 CPU (tv80 by Guy Hutchison, based on VHDL T80 core by Daniel Wallner)
@@ -29,14 +35,17 @@ A simple bespoke (i.e. I made it up with no real plan) 8-bit system with a 40x30
- 2Kb character ROM (port 1 cpu, port 2 download)
- 2Kb character RAM (port 1 cpu, port 2 graphics)
- 2Kb colour RAM (port 1 cpu, port 2 graphics)
- 7 Memory-mapped IO regions (all read-only). _Yes I know about MREQ but SFRs turned out to be annoying in sdcc so :)_
- Hardware state (H/V Sync, H/V Blank etc) (8 bytes)
- joystick_5->0 from HPS (192 bytes)
- joystick_analog_5->0 from HPS (96 bytes)
- paddle_5->0 from HPS (48 bytes)
- spinner_5->0 from HPS (96 bytes)
- ps2_key from HPS (11 bytes)
- 9 Memory-mapped IO regions. _Yes I know about MREQ but SFRs turned out to be annoying in sdcc so :)_
- Hardware state (H/V Sync, H/V Blank etc) (8 bytes, read-only)
- joystick_5->0 from HPS (192 bytes, read-only)
- joystick_l_analog_5->0 from HPS (96 bytes, read-only)
- joystick_r_analog_5->0 from HPS (96 bytes, read-only)
- paddle_5->0 from HPS (48 bytes, read-only)
- spinner_5->0 from HPS (96 bytes, read-only)
- ps2_key from HPS (11 bytes, read-only)
- ps2_mouse from HPS (48 bytes, combination of ps2_mouse and ps2_mouseext with some padding to align bytes) - currently unused
- timestamp from HPS (33 bytes, read-only)
- Hardware millisecond resolution timer (16 bytes read/write)
### Memory Map
Start|End|Length|Name
@@ -45,11 +54,14 @@ Start|End|Length|Name
0x4000|0x47FF|0x0800|Char ROM
0x6000|0x6000|0x0001|System inputs (video signals)
0x7000|0x70BF|0x00C0|Joystick inputs
0x7100|0x715F|0x0060|Analog inputs
0x7200|0x722F|0x0030|Paddle inputs
0x7300|0x735F|0x0060|Spinner inputs
0x7400|0x740B|0x000C|PS2 keyboard input
0x7500|0x752F|0x0030|PS2 mouse input
0x7100|0x715F|0x0060|Analog left inputs
0x7200|0x725F|0x0060|Analog right inputs
0x7300|0x732F|0x0030|Paddle inputs
0x7400|0x745F|0x0060|Spinner inputs
0x7500|0x750B|0x000C|PS2 keyboard input
0x7600|0x762F|0x0030|PS2 mouse input
0x7700|0x7720|0x0021|Timestamp
0x7800|0x7810|0x0011|Timer
0x8000|0x87FF|0x0800|Char RAM
0x8800|0x8FFF|0x0800|Colour RAM
0xC000|0xFFFF|0x4000|Work RAM

View File

@@ -12,6 +12,6 @@ cd ..
# Hexify roms
od -An -t x1 -v src/os.bin > verilator/rom.hex
od -An -t x1 -v src/os.bin > rtl/rom.hex
od -An -t x1 -v MiSTer.pf > verilator/font.hex
od -An -t x1 -v MiSTer.pf > rtl/font.hex
od -An -t x1 -v PETSCII.pf > verilator/font.hex
od -An -t x1 -v PETSCII.pf > rtl/font.hex

Binary file not shown.

96
rtl/font.hex Normal file
View File

@@ -0,0 +1,96 @@
00 00 00 00 00 00 00 00 ff 00 ff 00 ff 00 ff 00
00 ff 00 ff 00 ff 00 00 00 00 ff 00 ff 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
3c 66 60 60 60 66 3c 00 00 00 fc 00 fc 00 00 00
03 0f 3f ff 3f 0f 03 00 c0 f0 fc ff fc f0 c0 00
00 00 18 3c 7e 18 18 00 00 00 18 18 7e 3c 18 00
00 00 fc fc fc 00 00 00 00 00 3f 3f 3f 00 00 00
00 00 60 78 7e 78 60 00 00 38 44 44 fe fe fe 00
00 06 09 09 fc fc fc 00 00 fe c6 c6 c6 fe 00 00
00 fe fe fe fe fe 00 00 00 00 18 18 00 00 00 00
18 18 66 66 18 18 3c 00 36 7f 7f 7f 3e 1c 08 00
06 0c 18 3e 7c 18 30 60 38 fe 82 82 fe fe fe 00
00 00 00 00 00 00 00 00 18 18 18 18 00 00 18 00
66 66 66 00 00 00 00 00 66 66 ff 66 ff 66 66 00
18 3e 60 3c 06 7c 18 00 62 66 0c 18 30 66 46 00
3c 66 3c 38 67 66 3f 00 06 0c 18 00 00 00 00 00
0c 18 30 30 30 18 0c 00 30 18 0c 0c 0c 18 30 00
00 66 3c ff 3c 66 00 00 00 18 18 7e 18 18 00 00
00 00 00 00 00 18 18 30 00 00 00 7e 00 00 00 00
00 00 00 00 00 18 18 00 00 03 06 0c 18 30 60 00
3c 66 6e 76 66 66 3c 00 18 18 38 18 18 18 7e 00
3c 66 06 0c 30 60 7e 00 3c 66 06 1c 06 66 3c 00
06 0e 1e 66 7f 06 06 00 7e 60 7c 06 06 66 3c 00
3c 66 60 7c 66 66 3c 00 7e 66 0c 18 18 18 18 00
3c 66 66 3c 66 66 3c 00 3c 66 66 3e 06 66 3c 00
00 00 18 00 00 18 00 00 00 00 18 00 00 18 18 30
0e 18 30 60 30 18 0e 00 00 00 7e 00 7e 00 00 00
70 18 0c 06 0c 18 70 00 3c 66 06 0c 18 00 18 00
3c 66 6e 6e 60 62 3c 00 18 3c 66 7e 66 66 66 00
7c 66 66 7c 66 66 7c 00 3c 66 60 60 60 66 3c 00
78 6c 66 66 66 6c 78 00 7e 60 60 78 60 60 7e 00
7e 60 60 78 60 60 60 00 3c 66 60 6e 66 66 3c 00
66 66 66 7e 66 66 66 00 3c 18 18 18 18 18 3c 00
1e 0c 0c 0c 0c 6c 38 00 66 6c 78 70 78 6c 66 00
60 60 60 60 60 60 7e 00 63 77 7f 6b 63 63 63 00
66 76 7e 7e 6e 66 66 00 3c 66 66 66 66 66 3c 00
7c 66 66 7c 60 60 60 00 3c 66 66 66 66 3c 0e 00
7c 66 66 7c 78 6c 66 00 3c 66 60 3c 06 66 3c 00
7e 18 18 18 18 18 18 00 66 66 66 66 66 66 3c 00
66 66 66 66 66 3c 18 00 63 63 63 6b 7f 77 63 00
66 66 3c 18 3c 66 66 00 66 66 66 3c 18 18 18 00
7e 06 0c 18 30 60 7e 00 3c 30 30 30 30 30 3c 00
c0 e0 70 38 1c 0e 07 03 3c 0c 0c 0c 0c 0c 3c 00
00 18 3c 7e 18 18 18 18 00 00 00 00 00 ff ff 00
00 00 03 3e 76 36 36 00 00 00 3c 06 3e 66 3e 00
00 60 60 7c 66 66 7c 00 00 00 3c 60 60 60 3c 00
00 06 06 3e 66 66 3e 00 00 00 3c 66 7e 60 3c 00
00 0e 18 3e 18 18 18 00 00 00 3e 66 66 3e 06 7c
00 60 60 7c 66 66 66 00 00 18 00 38 18 18 3c 00
00 06 00 06 06 06 06 3c 00 60 60 6c 78 6c 66 00
00 38 18 18 18 18 3c 00 00 00 66 7f 7f 6b 63 00
00 00 7c 66 66 66 66 00 00 00 3c 66 66 66 3c 00
00 00 7c 66 66 7c 60 60 00 00 3e 66 66 3e 06 06
00 00 7c 66 60 60 60 00 00 00 3e 60 3c 06 7c 00
00 18 7e 18 18 18 0e 00 00 00 66 66 66 66 3e 00
00 00 66 66 66 3c 18 00 00 00 63 6b 7f 3e 36 00
00 00 66 3c 18 3c 66 00 00 00 66 66 66 3e 0c 78
00 00 7e 0c 18 30 7e 00 18 18 18 f8 f8 18 18 18
18 18 18 18 18 18 18 18 18 18 18 1f 1f 18 18 18
08 1c 3e 7f 7f 1c 3e 00 fe fe fe fe fe fe fe 00
00 00 00 ff ff 00 00 00 08 1c 3e 7f 7f 1c 3e 00
18 18 18 18 18 18 18 18 00 00 00 ff ff 00 00 00
00 00 ff ff 00 00 00 00 00 ff ff 00 00 00 00 00
00 00 00 00 ff ff 00 00 30 30 30 30 30 30 30 30
0c 0c 0c 0c 0c 0c 0c 0c 00 00 00 e0 f0 38 18 18
18 18 1c 0f 07 00 00 00 18 18 38 f0 e0 00 00 00
c0 c0 c0 c0 c0 c0 ff ff c0 e0 70 38 1c 0e 07 03
03 07 0e 1c 38 70 e0 c0 ff ff c0 c0 c0 c0 c0 c0
ff ff 03 03 03 03 03 03 00 3c 7e 7e 7e 7e 3c 00
00 00 00 00 00 ff ff 00 36 7f 7f 7f 3e 1c 08 00
60 60 60 60 60 60 60 60 00 00 00 07 0f 1c 18 18
c3 e7 7e 3c 3c 7e e7 c3 00 3c 7e 66 66 7e 3c 00
18 18 66 66 18 18 3c 00 06 06 06 06 06 06 06 06
08 1c 3e 7f 3e 1c 08 00 18 18 18 ff ff 18 18 18
c0 c0 30 30 c0 c0 30 30 18 18 18 18 18 18 18 18
00 00 03 3e 76 36 36 00 ff 7f 3f 1f 0f 07 03 01
00 00 00 00 00 00 00 00 f0 f0 f0 f0 f0 f0 f0 f0
00 00 00 00 ff ff ff ff ff 00 00 00 00 00 00 00
00 00 00 00 00 00 00 ff c0 c0 c0 c0 c0 c0 c0 c0
cc cc 33 33 cc cc 33 33 03 03 03 03 03 03 03 03
00 00 00 00 cc cc 33 33 ff fe fc f8 f0 e0 c0 80
03 03 03 03 03 03 03 03 18 18 18 1f 1f 18 18 18
00 00 00 00 0f 0f 0f 0f 18 18 18 1f 1f 00 00 00
00 00 00 f8 f8 18 18 18 00 00 00 00 00 00 ff ff
00 00 00 1f 1f 18 18 18 18 18 18 ff ff 00 00 00
00 00 00 ff ff 18 18 18 18 18 18 f8 f8 18 18 18
c0 c0 c0 c0 c0 c0 c0 c0 e0 e0 e0 e0 e0 e0 e0 e0
07 07 07 07 07 07 07 07 ff ff 00 00 00 00 00 00
ff ff ff 00 00 00 00 00 00 00 00 00 00 ff ff ff
03 03 03 03 03 03 ff ff 00 00 00 00 f0 f0 f0 f0
0f 0f 0f 0f 00 00 00 00 18 18 18 f8 f8 00 00 00
f0 f0 f0 f0 00 00 00 00 f0 f0 f0 f0 0f 0f 0f 0f

965
rtl/rom.hex Normal file
View File

@@ -0,0 +1,965 @@
c3 00 01 00 00 00 00 00 fb ed 4d fb 00 00 00 00
fb ed 4d 00 00 00 00 00 fb ed 4d 00 00 00 00 00
fb ed 4d 00 00 00 00 00 fb ed 4d 00 00 00 00 00
fb ed 4d 00 00 00 00 00 fb ed 4d 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
31 00 00 cd 38 3c cd cf 2b c3 04 02 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
3e 02 cf c9 3e 00 cf 76 18 fd 3a fd c2 32 fe c2
3a ff c2 32 00 c3 3a f9 c2 32 fa c2 3a fb c2 32
fc c2 3a 0a c0 32 01 c3 3a 0b c0 32 02 c3 3a 0c
c0 32 03 c3 3a 0d c0 32 04 c3 3a 00 70 e6 08 4f
af b9 17 32 fd c2 3a 00 70 e6 04 4f af b9 17 32
ff c2 3a 00 70 e6 02 4f af b9 17 32 f9 c2 3a 00
70 e6 01 32 fb c2 3a 08 70 e6 08 4f af b9 17 32
0a c0 3a 08 70 e6 04 4f af b9 17 32 0b c0 3a 00
70 e6 10 4f af b9 17 32 0c c0 3a 00 70 e6 20 4f
af b9 17 32 0d c0 c9 40 20 21 02 00 39 7e fd 21
09 c4 fd 77 00 fd 7e 00 87 5f 3a 06 c4 b7 20 07
3a 07 c4 b7 20 01 1c 21 05 c3 16 00 19 7e fd 21
0a c4 fd 77 00 fd 7e 00 b7 c8 01 12 c0 2a 0b c4
26 00 09 fd 7e 00 77 21 0b c4 34 c9 0d 58 5a 66
76 12 59 11 63 75 6b 74 72 01 00 75 2a 0c c4 26
00 09 7e e6 01 4f 41 3a 05 c4 90 ca 90 03 06 00
78 d6 02 30 1a 3e 0e 80 5f 3e c0 ce 00 57 68 26
00 29 29 29 d5 11 00 75 19 d1 7e 12 04 18 e1 21
0f c0 46 78 e6 01 32 11 c0 78 e6 02 32 10 c0 3a
0e c0 32 08 c4 21 e1 02 46 21 e2 02 5e 3a 08 c4
90 20 03 3e 01 20 af 47 3a 08 c4 93 20 03 3e 01
20 af 5f 3a 10 c0 b7 28 16 78 b7 28 07 21 06 c4
36 01 18 2c 7b b7 28 28 21 07 c4 36 01 18 21 78
b7 28 07 21 06 c4 36 00 18 16 7b b7 28 07 21 07
c4 36 00 18 0b c5 3a 08 c4 f5 33 cd 99 02 33 c1
21 05 c4 71 c9 dd e5 dd 21 00 00 dd 39 01 00 00
21 00 c0 79 96 78 23 9e 30 1b 21 00 80 09 dd 7e
04 77 21 00 88 09 dd 7e 04 77 21 00 90 09 dd 7e
04 77 03 18 db dd e1 c9 dd e5 dd 21 00 00 dd 39
01 00 00 21 00 c0 79 96 78 23 9e 30 0b 21 00 90
09 dd 7e 04 77 03 18 eb dd e1 c9 dd e5 dd 21 00
00 dd 39 f5 21 97 02 5e dd 66 08 2e 00 55 06 08
29 30 01 19 10 fa dd 4e 07 06 00 09 eb dd 6e 04
dd 66 05 e5 cd c6 2d f1 4d 06 00 78 91 30 20 21
00 80 19 e3 dd 7e 04 80 6f dd 7e 05 ce 00 67 7e
e1 e5 77 21 00 88 19 dd 7e 06 77 13 04 18 dc dd
f9 dd e1 c9 dd e5 dd 21 00 00 dd 39 21 df ff 39
f9 21 97 02 5e dd 66 08 2e 00 55 06 08 29 30 01
19 10 fa dd 4e 07 06 00 09 eb dd 7e 09 4f 17 9f
47 21 00 00 39 dd 75 fd dd 74 fe d5 c5 dd 4e 04
dd 46 05 c5 e5 cd 92 2d 21 06 00 39 f9 d1 dd 4e
fd dd 46 fe c5 cd c6 2d f1 dd 75 ff 0e 00 79 dd
96 ff 30 1f dd 6e fd dd 66 fe 06 00 09 46 78 b7
28 11 21 00 80 19 70 21 00 88 19 dd 7e 06 77 13
0c 18 db dd f9 dd e1 c9 dd e5 dd 21 00 00 dd 39
21 df ff 39 f9 21 97 02 5e dd 66 08 2e 00 55 06
08 29 30 01 19 10 fa dd 4e 07 06 00 09 eb dd 4e
09 06 00 21 00 00 39 dd 75 fd dd 74 fe d5 c5 dd
4e 04 dd 46 05 c5 e5 cd 92 2d 21 06 00 39 f9 d1
dd 4e fd dd 46 fe c5 cd c6 2d f1 dd 75 ff 0e 00
79 dd 96 ff 30 1f dd 6e fd dd 66 fe 06 00 09 46
78 b7 28 11 21 00 80 19 70 21 00 88 19 dd 7e 06
77 13 0c 18 db dd f9 dd e1 c9 dd e5 dd 21 00 00
dd 39 21 d5 ff 39 f9 21 97 02 5e dd 66 08 2e 00
55 06 08 29 30 01 19 10 fa dd 4e 07 06 00 09 eb
21 00 00 39 dd 75 fd dd 74 fe 4d 44 d5 dd 6e 09
dd 66 0a e5 dd 6e 04 dd 66 05 e5 c5 cd 92 2d 21
06 00 39 f9 d1 dd 4e fd dd 46 fe c5 cd c6 2d f1
dd 75 ff 0e 00 79 dd 96 ff 30 1f dd 6e fd dd 66
fe 06 00 09 46 78 b7 28 11 21 00 80 19 70 21 00
88 19 dd 7e 06 77 13 0c 18 db dd f9 dd e1 c9 dd
e5 dd 21 00 00 dd 39 21 d5 ff 39 f9 21 97 02 5e
dd 66 08 2e 00 55 06 08 29 30 01 19 10 fa dd 4e
07 06 00 09 eb 21 00 00 39 dd 75 fe dd 74 ff 4d
44 d5 dd 6e 09 dd 66 0a e5 dd 6e 04 dd 66 05 e5
c5 cd 92 2d 21 06 00 39 f9 d1 dd 4e fe dd 46 ff
c5 cd c6 2d f1 dd 75 fd 0e 00 79 dd 96 fd 30 1f
dd 6e fe dd 66 ff 06 00 09 46 78 b7 28 11 21 00
80 19 70 21 00 88 19 dd 7e 06 77 13 0c 18 db dd
f9 dd e1 c9 dd e5 dd 21 00 00 dd 39 21 d5 ff 39
f9 21 97 02 5e dd 66 08 2e 00 55 06 08 29 30 01
19 10 fa dd 4e 07 06 00 09 eb 21 00 00 39 dd 75
fe dd 74 ff 4d 44 d5 dd 6e 0b dd 66 0c e5 dd 6e
09 dd 66 0a e5 dd 6e 04 dd 66 05 e5 c5 cd 92 2d
21 08 00 39 f9 d1 dd 4e fe dd 46 ff c5 cd c6 2d
f1 dd 75 fd 0e 00 79 dd 96 fd 30 1f dd 6e fe dd
66 ff 06 00 09 46 78 b7 28 11 21 00 80 19 70 21
00 88 19 dd 7e 06 77 13 0c 18 db dd f9 dd e1 c9
dd e5 dd 21 00 00 dd 39 21 97 02 5e dd 66 07 2e
00 55 06 08 29 30 01 19 10 fa dd 4e 06 06 00 09
eb 21 00 80 19 dd 7e 04 77 21 00 88 19 dd 7e 05
77 dd e1 c9 dd e5 dd 21 00 00 dd 39 21 97 02 5e
dd 66 07 2e 00 55 06 08 29 30 01 19 10 fa dd 4e
06 06 00 09 eb 0e 00 79 dd 96 08 30 14 21 00 80
19 dd 7e 04 77 21 00 88 19 dd 7e 05 77 13 0c 18
e6 dd e1 c9 dd e5 dd 21 00 00 dd 39 21 97 02 5e
dd 66 06 2e 00 55 06 08 29 30 01 19 10 fa dd 4e
05 06 00 09 11 00 88 19 dd 7e 04 77 dd e1 c9 dd
e5 dd 21 00 00 dd 39 21 97 02 5e dd 66 06 2e 00
55 06 08 29 30 01 19 10 fa dd 4e 05 06 00 09 11
00 90 19 dd 7e 04 77 dd e1 c9 dd e5 dd 21 00 00
dd 39 21 97 02 5e dd 66 06 2e 00 55 06 08 29 30
01 19 10 fa dd 4e 05 06 00 09 eb 0e 00 79 dd 96
07 30 0c 21 00 90 19 dd 7e 04 77 13 0c 18 ee dd
e1 c9 dd e5 dd 21 00 00 dd 39 f5 f5 3b dd 4e 07
dd 5e 07 16 00 dd 6e 08 26 00 19 79 1e 00 95 7b
9c e2 06 08 ee 80 f2 a4 08 dd 56 0b 15 79 b7 28
06 21 0e c4 46 18 04 21 0d c4 46 c5 d5 33 dd 66
0a dd 6e 09 e5 c5 33 cd e0 06 f1 f1 c1 dd 36 ff
01 dd 5e 06 61 2e 00 55 06 08 29 30 01 19 10 fa
eb dd 7e 04 83 dd 77 fc dd 7e 05 8a dd 77 fd dd
5e 0a dd 36 fe 00 7b 3c dd 77 fb dd 7e fe d6 08
30 38 dd 6e fc dd 66 fd 7e dd a6 ff b7 28 06 21
0e c4 46 18 04 21 0d c4 46 c5 dd 56 0b d5 dd 7e
09 f5 33 c5 33 cd e0 06 f1 f1 c1 dd 5e fb dd 7e
ff 87 dd 77 ff dd 34 fe 18 bc dd 7e fb dd 77 0a
0c c3 f0 07 dd f9 dd e1 c9 dd e5 dd 21 00 00 dd
39 dd 46 04 dd 7e 06 90 38 2d c5 dd 7e 05 f5 33
c5 33 dd 66 09 dd 6e 08 e5 cd e0 06 f1 f1 c1 c5
dd 7e 07 f5 33 c5 33 dd 66 09 dd 6e 08 e5 cd e0
06 f1 f1 c1 04 18 cd dd 46 05 04 78 dd 96 07 30
2d c5 c5 33 dd 66 04 dd 6e 09 e5 dd 7e 08 f5 33
cd e0 06 f1 f1 c1 c5 c5 33 dd 66 06 dd 6e 09 e5
dd 7e 08 f5 33 cd e0 06 f1 f1 c1 04 18 cd dd e1
c9 dd e5 dd 21 00 00 dd 39 dd 66 05 dd 6e 04 e5
dd 56 08 1e 95 d5 cd e0 06 f1 f1 dd 66 05 dd 6e
06 e5 dd 56 08 1e 89 d5 cd e0 06 f1 f1 dd 66 07
dd 6e 04 e5 dd 56 08 1e 8a d5 cd e0 06 f1 f1 dd
66 07 dd 6e 06 e5 dd 56 08 1e 8b d5 cd e0 06 f1
f1 dd 46 04 04 78 dd 96 06 30 2b c5 dd 7e 05 f5
33 c5 33 dd 56 08 1e 83 d5 cd e0 06 f1 f1 c1 c5
dd 7e 07 f5 33 c5 33 dd 56 08 1e 83 d5 cd e0 06
f1 f1 c1 04 18 cf dd 46 05 04 78 dd 96 07 30 2b
c5 c5 33 dd 7e 04 f5 33 dd 56 08 1e 82 d5 cd e0
06 f1 f1 c1 c5 c5 33 dd 7e 06 f5 33 dd 56 08 1e
82 d5 cd e0 06 f1 f1 c1 04 18 cf dd e1 c9 dd e5
dd 21 00 00 dd 39 dd 66 05 dd 6e 04 e5 dd 56 08
1e 95 d5 cd e0 06 f1 f1 dd 66 05 dd 6e 06 e5 dd
56 09 1e 89 d5 cd e0 06 f1 f1 dd 66 07 dd 6e 04
e5 dd 56 09 1e 8a d5 cd e0 06 f1 f1 dd 66 07 dd
6e 06 e5 dd 56 0a 1e 8b d5 cd e0 06 f1 f1 dd 46
04 04 78 dd 96 06 30 2b c5 dd 7e 05 f5 33 c5 33
dd 56 09 1e 83 d5 cd e0 06 f1 f1 c1 c5 dd 7e 07
f5 33 c5 33 dd 56 0a 1e 83 d5 cd e0 06 f1 f1 c1
04 18 cf dd 46 05 04 78 dd 96 07 30 2b c5 c5 33
dd 7e 04 f5 33 dd 56 09 1e 82 d5 cd e0 06 f1 f1
c1 c5 c5 33 dd 7e 06 f5 33 dd 56 0a 1e 82 d5 cd
e0 06 f1 f1 c1 04 18 cf dd e1 c9 dd e5 dd 21 00
00 dd 39 dd 46 05 dd 7e 06 dd 96 04 4f dd 7e 07
90 38 1b 51 14 c5 58 d5 dd 66 04 dd 6e 09 e5 dd
7e 08 f5 33 cd 14 07 f1 f1 33 c1 04 18 df dd e1
c9 dd e5 dd 21 00 00 dd 39 dd 46 05 dd 7e 06 dd
96 04 4f dd 7e 07 90 38 15 51 14 c5 58 d5 dd 66
04 dd 6e 08 e5 cd aa 07 f1 f1 c1 04 18 e5 dd e1
c9 dd e5 dd 21 00 00 dd 39 dd 4e 05 dd 7e 06 dd
96 04 47 dd 7e 07 91 38 16 c5 c5 33 79 f5 33 dd
66 04 dd 6e 08 e5 cd aa 07 f1 f1 c1 0c 18 e4 dd
e1 c9 21 02 00 39 56 1e 1d d5 3e 27 f5 33 af f5
33 af f5 33 cd 21 09 f1 f1 33 c9 01 5e 00 78 d6
1d d0 16 00 58 7a d6 27 30 30 c5 d5 79 f5 33 4a
c5 3e ff f5 33 21 8f 0b e5 cd c8 04 21 06 00 39
f9 d1 c1 63 24 c5 d5 6a e5 af 47 c5 cd e0 06 f1
f1 d1 c1 0c 14 14 14 14 18 ca 43 04 04 18 bf 25
64 00 dd e5 dd 21 00 00 dd 39 dd cb 04 46 20 09
dd cb 05 46 20 03 af 18 02 3e 01 4f c5 af f5 33
cd 95 03 33 11 0b 01 d5 3e ff f5 33 21 c6 0c e5
cd eb 03 f1 f1 33 11 06 04 d5 11 02 07 d5 3e 27
f5 33 af f5 33 af f5 33 cd de 09 21 07 00 39 f9
c1 cb 41 28 05 11 1a 00 18 03 11 1d 00 43 c5 11
a4 52 d5 3e a4 f5 33 c5 33 11 03 27 d5 af f5 33
cd de 09 21 07 00 39 f9 c1 cb 41 ca c3 0c dd cb
04 46 28 0b dd cb 05 46 28 05 21 02 00 18 03 21
01 00 7d 3d 20 03 3e 01 20 af 4f b7 28 05 11 27
00 18 03 11 13 00 79 b7 28 05 01 14 00 18 03 01
0a 00 e5 c5 d5 01 80 40 c5 3e c0 f5 33 16 1d d5
3e 1b f5 33 af f5 33 cd de 09 21 07 00 39 f9 d1
c1 e1 7d d6 02 20 1a 43 04 c5 11 80 40 d5 11 1d
c0 d5 11 1b 27 d5 c5 33 cd de 09 21 07 00 39 f9
c1 dd cb 04 46 28 1e 79 c6 f7 47 c5 3e 1c f5 33
c5 33 3e db f5 33 21 da 0c e5 cd eb 03 f1 f1 33
c1 79 c6 14 4f dd cb 05 46 28 18 79 c6 f8 47 3e
1c f5 33 c5 33 3e db f5 33 21 ec 0c e5 cd eb 03
f1 f1 33 dd e1 c9 4d 69 53 54 65 72 20 49 6e 70
75 74 20 54 65 73 74 65 72 00 48 6f 6c 64 20 53
65 6c 65 63 74 3a 20 4d 65 6e 75 00 53 74 61 72
74 3a 20 43 6f 6e 74 69 6e 75 65 00 dd e5 dd 21
00 00 dd 39 f5 f5 dd 7e 05 dd 77 fd c6 02 dd 77
fc f5 33 dd 56 04 1e fe d5 3e 95 f5 33 cd e0 06
f1 f1 dd 4e 04 79 3c dd 77 ff c5 3e 19 f5 33 dd
7e fc f5 33 dd 56 ff 1e fe d5 3e 83 f5 33 cd 14
07 f1 f1 33 c1 79 c6 1a 5f c5 d5 dd 56 fc d5 11
89 fe d5 cd e0 06 f1 f1 d1 c1 06 03 78 d6 08 30
2e dd 7e 05 80 57 c5 d5 d5 33 dd 56 04 1e fe d5
3e 82 f5 33 cd e0 06 f1 f1 d1 d5 d5 33 53 1e fe
d5 3e 82 f5 33 cd e0 06 f1 f1 d1 c1 04 18 cd dd
7e fd c6 08 47 c5 d5 c5 33 dd 56 04 1e fe d5 3e
8a f5 33 cd e0 06 f1 f1 d1 c1 c5 c5 33 53 1e fe
d5 3e 8b f5 33 cd e0 06 f1 f1 c1 79 c6 08 dd 77
fe c5 c5 33 dd 56 fe 1e fe d5 3e 8b f5 33 cd e0
06 f1 f1 c1 79 c6 12 5f c5 d5 c5 33 53 1e fe d5
3e 8a f5 33 cd e0 06 f1 f1 d1 c1 dd 7e fd c6 07
57 c5 d5 d5 33 dd 56 fe 1e fe d5 3e 95 f5 33 cd
e0 06 f1 f1 d1 d5 d5 33 53 1e fe d5 3e 89 f5 33
cd e0 06 f1 f1 d1 c1 c5 d5 3e 07 f5 33 c5 33 dd
56 ff 1e fe d5 3e 83 f5 33 cd 14 07 f1 f1 33 d1
c1 79 c6 09 5f c5 3e 09 f5 33 d5 33 53 1e fe d5
3e 83 f5 33 cd 14 07 f1 f1 33 c1 79 c6 13 57 c5
3e 07 f5 33 4a c5 11 83 fe d5 cd 14 07 f1 f1 33
c1 dd 46 fd 04 c5 c5 33 dd 56 ff 1e fe d5 3e 82
f5 33 cd e0 06 f1 f1 dd 7e fc f5 33 dd 56 ff 1e
fe d5 3e b1 f5 33 cd e0 06 f1 f1 dd 7e 05 f5 33
dd 56 ff 1e fe d5 3e 95 f5 33 cd e0 06 f1 f1 c1
51 14 14 c5 3e 03 f5 33 dd 7e 05 f5 33 d5 33 11
83 fe d5 cd 14 07 f1 f1 33 c1 79 c6 05 57 c5 d5
4a c5 11 82 fe d5 cd e0 06 f1 f1 d1 d5 dd 7e fc
f5 33 d5 33 11 b1 fe d5 cd e0 06 f1 f1 d1 dd 7e
05 f5 33 d5 33 11 89 fe d5 cd e0 06 f1 f1 c1 79
c6 15 57 c5 d5 4a c5 11 82 fe d5 cd e0 06 f1 f1
d1 d5 dd 7e fc f5 33 d5 33 11 b1 fe d5 cd e0 06
f1 f1 d1 dd 7e 05 f5 33 d5 33 11 95 fe d5 cd e0
06 f1 f1 c1 79 c6 16 57 c5 3e 03 f5 33 dd 7e 05
f5 33 d5 33 11 83 fe d5 cd 14 07 f1 f1 33 c1 79
c6 19 57 d5 4a c5 11 82 fe d5 cd e0 06 f1 f1 d1
d5 dd 7e fc f5 33 d5 33 11 b1 fe d5 cd e0 06 f1
f1 d1 dd 7e 05 f5 33 d5 33 11 89 fe d5 cd e0 06
dd f9 dd e1 c9 dd e5 dd 21 00 00 dd 39 21 fa ff
39 f9 dd 7e 05 dd 86 07 47 dd 7e 04 dd 86 06 4f
c5 3e ff f5 33 c5 33 79 f5 33 dd 66 05 dd 6e 04
e5 cd 21 09 f1 f1 33 c1 58 1d 0d dd 7e 05 dd 77
fe 3c dd 77 fd dd 7e 04 dd 77 fc 47 04 c5 3e 23
f5 33 16 1b d5 79 f5 33 dd 7e fd f5 33 c5 33 cd
9b 0a 21 06 00 39 f9 c1 dd 6e 06 26 00 5d 54 cb
7c 28 02 eb 13 cb 2a cb 1b 7b dd 86 fc 4f dd 5e
07 16 00 6b 62 cb 7a 28 03 6b 62 23 cb 2c cb 1d
7d dd 86 fe dd 77 ff dd 66 06 25 c5 d5 e5 33 dd
7e ff f5 33 c5 33 11 83 23 d5 cd 14 07 f1 f1 33
d1 c1 dd 46 fd dd 6e 05 26 00 19 dd 70 fa dd 36
fb 00 dd 7e fa 95 dd 7e fb 9c e2 3f 10 ee 80 f2
58 10 c5 d5 c5 33 51 1e 23 d5 3e 82 f5 33 cd e0
06 f1 f1 d1 c1 04 18 cd dd 7e ff f5 33 51 1e 23
d5 3e 9b f5 33 cd e0 06 dd f9 dd e1 c9 21 f7 c2
36 0a 21 0f c4 36 00 21 11 c4 36 00 c9 dd e5 dd
21 00 00 dd 39 f5 f5 3b 21 06 c0 cb 46 ca 2d 11
21 07 c0 cb 46 c2 2d 11 cd 0a 02 21 fd c2 cb 46
28 1e 21 fe c2 cb 46 20 17 fd 21 92 c0 fd 35 00
3e 80 fd 96 00 30 04 fd 36 00 03 21 10 c4 36 01
21 ff c2 cb 46 28 1e 21 00 c3 cb 46 20 17 fd 21
92 c0 fd 34 00 fd 7e 00 d6 04 20 04 fd 36 00 00
21 10 c4 36 01 21 0a c0 cb 46 28 41 21 01 c3 cb
46 28 3a fd 21 92 c0 fd 7e 00 b7 28 16 fd 7e 00
3d 28 17 fd 7e 00 d6 02 28 17 fd 7e 00 d6 03 28
17 18 1a 21 f7 c2 36 01 18 13 21 f7 c2 36 05 18
0c 21 f7 c2 36 03 18 05 21 f7 c2 36 07 21 08 c0
cb 46 ca 9e 12 21 09 c0 cb 46 c2 9e 12 fd 21 0f
c4 fd 7e 00 d6 0d d2 dd 11 fd 5e 00 16 00 6b 4a
cb 7a 28 03 13 6b 4a cb 29 cb 1d 4d 41 04 78 c6
0f 5f 3e 0f 95 67 e5 c5 01 36 24 c5 16 ff d5 3e
1c f5 33 e5 33 3e 0c f5 33 cd de 09 21 07 00 39
f9 c1 e1 3e 01 95 30 3e 78 3d c6 0f 57 0d 3e 0f
91 47 c5 d5 af f5 33 af f5 33 d5 33 3e 1b f5 33
c5 33 3e 0d f5 33 cd 9b 0a 21 06 00 39 f9 d1 c1
3e 09 f5 33 d5 33 3e 1b f5 33 c5 33 3e 0d f5 33
cd d1 0a f1 f1 33 fd 21 0f c4 fd 34 00 fd 7e 00
d6 0d c2 9e 12 21 10 c4 36 01 c3 9e 12 21 10 c4
cb 46 ca 9e 12 0e 0a 1e 00 7b d6 04 d2 94 12 dd
71 fd 6b 26 00 dd 7e fd c6 02 dd 77 fe dd 7e fd
3c dd 77 ff 29 e3 3a 92 c0 93 20 40 d5 11 bf b6
d5 3e ff f5 33 dd 56 fe 1e 1b d5 51 1e 0d d5 cd
de 09 21 07 00 39 f9 d1 3e 12 dd 86 fb 6f 3e c4
dd 8e fc 67 4e 23 46 d5 dd 56 ff 1e 0e d5 3e ff
f5 33 c5 cd eb 03 f1 f1 33 d1 18 3e d5 11 b6 64
d5 3e bf f5 33 dd 56 fe 1e 1b d5 51 1e 0d d5 cd
de 09 21 07 00 39 f9 d1 3e 12 dd 86 fb 6f 3e c4
dd 8e fc 67 4e 23 46 d5 dd 56 ff 1e 0e d5 3e b6
f5 33 c5 cd eb 03 f1 f1 33 d1 dd 4e fd 0c 0c 0c
1c c3 e9 11 21 10 c4 36 00 21 11 c4 36 01 dd f9
dd e1 c9 21 f7 c2 36 14 21 1b c4 36 04 21 1a c4
36 00 c9 21 f7 c2 36 16 21 1b c4 36 04 21 1a c4
36 0f c9 21 08 c0 cb 46 c8 21 09 c0 cb 46 c0 fd
21 1b c4 fd 35 00 fd 7e 00 b7 c0 21 1a c4 4e 3e
1d 91 57 3e 27 91 47 3e 07 f5 33 3e 7f f5 33 58
d5 3a 1a c4 f5 33 3a 1a c4 f5 33 cd a9 08 21 06
00 39 f9 21 1b c4 36 04 fd 21 1a c4 fd 34 00 fd
7e 00 d6 10 c0 c3 b3 12 21 08 c0 cb 46 c8 21 09
c0 cb 46 c0 fd 21 1b c4 fd 35 00 fd 7e 00 b7 c0
21 1a c4 4e 3e 1d 91 57 3e 27 91 47 af f5 33 af
f5 33 58 d5 3a 1a c4 f5 33 3a 1a c4 f5 33 cd a9
08 21 06 00 39 f9 21 1b c4 36 04 fd 21 1a c4 fd
35 00 fd 7e 00 b7 c0 3a f8 c2 32 f7 c2 c9 dd e5
dd 21 00 00 dd 39 f5 f5 af 57 1e 01 d5 cd 92 0b
f1 0e 00 79 d6 02 30 5c 41 04 3e 25 81 dd 77 fd
3e c4 ce 00 dd 77 fe dd 6e fd dd 66 fe 7e c6 05
dd 77 ff 3e 23 81 5f 3e c4 ce 00 57 1a c6 fb dd
77 fc c5 d5 c5 33 dd 7e ff f5 33 dd 56 fc 1e ff
d5 21 e9 13 e5 cd c8 04 21 06 00 39 f9 d1 c1 dd
6e fd dd 66 fe 46 1a c5 c5 33 f5 33 cd fc 0c f1
c1 0c 18 9f dd f9 dd e1 c9 4a 4f 59 20 25 64 00
af 57 1e 01 d5 cd 92 0b f1 3a 19 c5 47 05 21 17
c5 4e c5 33 51 1e ff d5 21 02 15 e5 cd eb 03 f1
f1 33 21 19 c5 56 21 17 c5 46 3e 12 f5 33 3e 12
f5 33 58 d5 cd 75 0f f1 f1 3a 19 c5 c6 13 5f 3a
17 c5 4f 0c 7b f5 33 51 1e ff d5 21 0e 15 e5 cd
eb 03 f1 f1 33 3a 19 c5 c6 13 47 3a 17 c5 c6 0a
4f c5 33 51 1e ff d5 21 11 15 e5 cd eb 03 f1 f1
33 21 1c c5 46 04 3a 19 c5 4f 0d c5 33 51 1e 12
d5 3e ff f5 33 21 14 15 e5 cd c8 04 21 06 00 39
f9 3a 1a c5 5f 1d 3a 18 c5 c6 07 4f 7b f5 33 51
1e ff d5 21 1b 15 e5 cd eb 03 f1 f1 33 21 1a c5
56 21 18 c5 46 3e 12 f5 33 3e 12 f5 33 58 d5 cd
75 0f f1 f1 3a 1a c5 c6 13 47 3a 18 c5 4f 0c c5
33 51 1e ff d5 21 0e 15 e5 cd eb 03 f1 f1 33 3a
1a c5 c6 13 47 3a 18 c5 c6 0a 4f c5 33 51 1e ff
d5 21 11 15 e5 cd eb 03 f1 f1 33 3a 1a c5 c6 14
47 c5 33 11 3f 05 d5 21 28 15 e5 cd eb 03 f1 f1
33 c9 41 4e 41 4c 4f 47 20 4c 45 46 54 00 58 3a
00 59 3a 00 50 41 44 20 25 64 00 41 4e 41 4c 4f
47 20 52 49 47 48 54 00 43 79 63 6c 65 20 73 65
6c 65 63 74 65 64 20 70 61 64 20 77 69 74 68 20
41 20 2f 20 42 00 dd e5 dd 21 00 00 dd 39 21 ec
ff 39 f9 af 57 1e 01 d5 cd 92 0b f1 11 07 05 d5
3e ff f5 33 21 e9 16 e5 cd eb 03 f1 f1 33 11 15
05 d5 3e ff f5 33 21 f6 16 e5 cd eb 03 f1 f1 33
11 19 05 d5 3e ff f5 33 21 fa 16 e5 cd eb 03 f1
f1 33 11 1e 05 d5 3e ff f5 33 21 fe 16 e5 cd eb
03 f1 f1 33 11 22 05 d5 3e ff f5 33 21 02 17 e5
cd eb 03 f1 f1 33 11 07 0d d5 3e ff f5 33 21 06
17 e5 cd eb 03 f1 f1 33 11 12 0d d5 3e ff f5 33
21 0a 17 e5 cd eb 03 f1 f1 33 21 00 00 39 eb dd
73 fd dd 72 fe dd 73 fb dd 72 fc dd 73 f9 dd 72
fa dd 73 f7 dd 72 f8 dd 73 f5 dd 72 f6 dd 36 ff
00 dd 7e ff d6 06 d2 d5 16 dd 4e ff 06 00 03 dd
71 f3 dd 70 f4 4b 42 d5 dd 6e f3 dd 66 f4 e5 21
13 17 e5 c5 cd 92 2d 21 06 00 39 f9 d1 dd 7e ff
dd 77 f2 c6 06 67 dd 7e ff 87 4f 3e ff 91 dd 77
f1 dd 4e fd dd 46 fe d5 e5 33 3e 02 f5 33 dd 7e
f1 f5 33 c5 cd eb 03 f1 f1 33 d1 dd 4e fb dd 46
fc d5 dd 6e f3 dd 66 f4 e5 21 19 17 e5 c5 cd 92
2d 21 06 00 39 f9 d1 dd 7e f2 c6 0e dd 77 f2 dd
4e f9 dd 46 fa d5 dd 56 f2 1e 02 d5 dd 7e f1 f5
33 c5 cd eb 03 f1 f1 33 d1 dd 4e f7 dd 46 f8 d5
dd 6e f3 dd 66 f4 e5 21 1f 17 e5 c5 cd 92 2d 21
06 00 39 f9 d1 dd 4e f5 dd 46 f6 d5 dd 56 f2 1e
0e d5 dd 7e f1 f5 33 c5 cd eb 03 f1 f1 33 d1 dd
34 ff c3 01 16 11 02 15 d5 3e ff f5 33 21 25 17
e5 cd eb 03 dd f9 dd e1 c9 52 4c 44 55 41 42 58
59 4c 52 73 53 00 41 4c 58 00 41 4c 59 00 41 52
58 00 41 52 59 00 50 4f 53 00 53 50 44 20 20 50
4f 53 00 4a 4f 59 25 64 00 50 41 44 25 64 00 53
50 4e 25 64 00 43 4f 4e 00 21 03 00 39 7e f5 33
21 03 00 39 7e f5 33 cd 92 0b f1 11 0f 04 d5 3e
aa f5 33 21 4e 17 e5 cd eb 03 f1 f1 33 c9 42 55
54 54 4f 4e 20 54 45 53 54 00 21 21 c4 36 00 21
22 c4 36 00 01 93 c0 1e 00 7b d6 0c 30 09 6b 26
00 09 36 01 1c 18 f2 0e 00 79 d6 06 d0 21 9f c0
06 00 09 36 01 21 a5 c0 06 00 09 36 ff 21 ab c0
06 00 09 36 01 21 b1 c0 06 00 09 36 ff 21 b7 c0
06 00 09 36 01 21 bd c0 06 00 09 36 01 21 c3 c0
06 00 09 36 01 69 26 00 29 29 11 c9 c0 19 af 77
23 77 23 77 23 36 00 0c 18 af 21 f7 c2 36 02 cd
6e 13 c3 5a 17 21 f7 c2 36 06 cd f0 13 c3 5a 17
21 f7 c2 36 04 cd 46 15 3a 1c c4 32 e1 c0 3a 1d
c4 32 e2 c0 c3 5a 17 21 f7 c2 36 08 21 1d c5 36
00 21 1e c5 36 00 21 1f c5 36 00 21 20 c5 36 01
21 21 c5 36 00 21 22 c5 36 00 21 23 c5 36 00 af
57 1e 01 d5 cd 29 17 f1 11 03 0e d5 3e ff f5 33
21 4d 18 e5 cd eb 03 f1 f1 33 11 02 19 d5 3e ee
f5 33 21 6f 18 e5 cd eb 03 f1 f1 33 c9 50 72 65
73 73 20 74 68 65 20 62 75 74 74 6f 6e 20 79 6f
75 20 77 61 6e 74 20 74 6f 20 74 65 73 74 00 52
65 6d 65 6d 62 65 72 20 74 6f 20 65 6e 61 62 6c
65 20 66 61 73 74 20 55 53 42 20 70 6f 6c 6c 69
6e 67 21 00 dd e5 dd 21 00 00 dd 39 0e 01 79 fe
07 30 15 3d 5f 17 9f 57 21 e4 c0 19 eb 21 e4 c0
06 00 09 7e 12 0c 18 e6 21 ea c0 dd 7e 04 77 dd
e1 c9 21 fd c2 cb 46 20 0f 21 fe c2 cb 46 28 08
3e 01 f5 33 cd 94 18 33 21 ff c2 cb 46 20 0f 21
00 c3 cb 46 28 08 3e 02 f5 33 cd 94 18 33 21 f9
c2 cb 46 20 0f 21 fa c2 cb 46 28 08 3e 03 f5 33
cd 94 18 33 21 fb c2 cb 46 20 0f 21 fc c2 cb 46
28 08 3e 04 f5 33 cd 94 18 33 21 0c c0 cb 46 20
0f 21 03 c3 cb 46 28 08 3e 05 f5 33 cd 94 18 33
3a e4 c0 3d c0 3a e5 c0 3d c0 3a e6 c0 d6 02 c0
3a e7 c0 d6 02 c0 3a e8 c0 d6 03 c0 3a e9 c0 d6
04 c0 3a ea c0 d6 05 c0 21 f8 c2 36 1e af f5 33
cd 94 18 33 c3 a3 12 21 0b c0 cb 46 28 18 fd 21
21 c4 fd 34 00 fd 7e 00 d6 3c 20 0f fd 36 00 00
cd 6d 10 2e 01 c9 21 21 c4 36 00 2e 00 c9 dd e5
dd 21 00 00 dd 39 21 f7 ff 39 f9 cd e9 02 21 06
c0 cb 46 28 0d 21 07 c0 cb 46 20 06 cd 0a 02 cd
c2 18 21 08 c0 cb 46 ca c3 1a 21 09 c0 cb 46 c2
c3 1a cd 67 19 cb 45 c2 c3 1a dd 36 ff 00 dd 7e
ff d6 02 d2 c3 1a dd 7e ff 0f 0f 0f e6 e0 dd 77
fe 3e 25 dd 86 ff dd 77 fb 3e c4 ce 00 dd 77 fc
3e 23 dd 86 ff dd 77 f7 3e c4 ce 00 dd 77 f8 dd
36 fd 00 dd 7e fd d6 0c d2 bd 1a dd 7e fd d6 08
30 1f 01 00 70 dd 6e fe 26 00 09 4e dd 46 fd 21
01 00 04 18 01 29 10 fd 06 00 7d a1 4f 7c a0 18
24 01 00 70 dd 7e fe c6 08 6f 17 9f 67 09 4e dd
7e fd c6 f8 47 21 01 00 04 18 01 29 10 fd 06 00
7d a1 4f 7c a0 79 b7 28 0a dd 36 f9 ff dd 36 fa
00 18 08 dd 36 f9 a4 dd 36 fa 00 dd 4e f9 dd 6e
fb dd 66 fc 5e 3e 0b dd 86 fd 6f 3e c5 ce 00 67
7e 83 dd 77 f9 e1 e5 5e 3e ff dd 86 fd 6f 3e c4
ce 00 67 7e 83 47 dd 5e fd 16 00 6b 62 29 19 29
eb 21 27 c4 19 eb dd 7e f9 f5 33 c5 33 79 f5 33
d5 cd eb 03 f1 f1 33 dd 34 fd c3 03 1a dd 34 ff
c3 ce 19 dd f9 dd e1 c9 dd e5 dd 21 00 00 dd 39
21 fa ff 39 f9 cd e9 02 21 06 c0 cb 46 28 5d 21
07 c0 cb 46 20 56 cd 0a 02 cd c2 18 21 0c c0 cb
46 20 1f 21 03 c3 cb 46 28 18 fd 21 1c c5 fd 7e
00 d6 05 20 06 fd 36 00 00 18 04 21 1c c5 34 cd
f0 13 21 0d c0 cb 46 20 23 21 04 c3 cb 46 28 1c
fd 21 1c c5 fd 7e 00 b7 20 06 fd 36 00 05 18 09
3a 1c c5 21 1c c5 c6 ff 77 cd f0 13 21 08 c0 cb
46 ca 37 1d 21 09 c0 cb 46 c2 37 1d cd 67 19 cb
45 c2 37 1d 3a 17 c5 c6 09 5f 3a 19 c5 c6 09 4f
3a ed c0 81 47 21 eb c0 6e dd 73 fd 7d dd 86 fd
c5 c5 33 57 1e 23 d5 cd 54 07 f1 33 c1 11 00 71
fd 21 1c c5 fd 6e 00 26 00 29 29 29 29 19 7e dd
77 fa 11 00 71 fd 7e 00 07 07 07 07 e6 f0 c6 08
6f 17 9f 67 19 46 3e eb 21 1c c5 86 dd 77 fb 3e
c0 ce 00 dd 77 fc dd 7e fa 5f 17 9f 57 c5 21 0f
00 e5 d5 cd ee 2d f1 f1 c1 7d dd 6e fb dd 66 fc
77 3e ed 21 1c c5 86 dd 77 fb 3e c0 ce 00 dd 77
fc 78 5f 17 9f 57 c5 21 0f 00 e5 d5 cd ee 2d f1
f1 c1 7d dd 6e fb dd 66 fc 77 3a ed c0 81 57 3a
eb c0 dd 86 fd c5 5f d5 3e ff f5 33 cd 54 07 f1
33 c1 3a 19 c5 c6 13 5f 3a 17 c5 4f 0c 0c 0c c5
dd 56 fa d5 51 1e ff d5 21 3c 1d e5 cd 44 04 21
06 00 39 f9 c1 3a 19 c5 c6 13 5f 3a 17 c5 c6 0c
4f c5 33 7b f5 33 51 1e ff d5 21 3c 1d e5 cd 44
04 21 06 00 39 f9 3a 18 c5 c6 09 5f 3a 1a c5 c6
09 4f 21 ee c0 6e dd 71 fb 7d dd 86 fb 4f 3a ec
c0 83 47 d5 79 f5 33 c5 33 3e 23 f5 33 cd 54 07
f1 33 d1 01 00 72 fd 21 1c c5 fd 6e 00 26 00 29
29 29 29 09 7e dd 77 ff 01 00 72 fd 7e 00 07 07
07 07 e6 f0 c6 08 6f 17 9f 67 09 7e dd 77 fe dd
7e ff 4f 17 9f 47 d5 21 0f 00 e5 c5 cd ee 2d f1
f1 d1 55 21 ec c0 72 dd 7e fe 4f 17 9f 47 d5 21
0f 00 e5 c5 cd ee 2d f1 f1 d1 7d 32 ee c0 dd 86
fb 4f 7a 83 47 79 f5 33 c5 33 3e ff f5 33 cd 54
07 f1 33 3a 1a c5 c6 13 5f 3a 18 c5 4f 0c 0c 0c
dd 56 ff d5 51 1e ff d5 21 3c 1d e5 cd 44 04 21
06 00 39 f9 3a 1a c5 c6 13 47 3a 18 c5 c6 0c 4f
dd 7e fe f5 33 c5 33 51 1e ff d5 21 3c 1d e5 cd
44 04 21 06 00 39 f9 dd f9 dd e1 c9 25 34 64 00
dd e5 dd 21 00 00 dd 39 21 c8 ff 39 f9 cd e9 02
21 06 c0 cb 46 28 0d 21 07 c0 cb 46 20 06 cd 0a
02 cd c2 18 21 08 c0 cb 46 ca cb 22 21 09 c0 cb
46 c2 cb 22 cd 67 19 cb 45 c2 cb 22 21 05 00 39
dd 75 db dd 74 dc dd 7e db dd 77 df dd 7e dc dd
77 e0 dd 7e db dd 77 e3 dd 7e dc dd 77 e4 dd 7e
db dd 77 eb dd 7e dc dd 77 ec 21 00 00 39 dd 75
f1 dd 74 f2 dd 7e f1 dd 77 d7 dd 7e f2 dd 77 d8
dd 36 f6 00 dd 7e f6 d6 06 d2 b5 21 dd 36 fc 06
dd 7e f6 c6 06 dd 77 f9 dd 7e f6 0f 0f 0f e6 e0
dd 77 f8 dd 7e f6 87 dd 77 f3 0e 00 79 fe 02 d2
9c 1e 87 87 87 47 dd 7e f8 80 5f 79 dd 86 f3 47
21 00 70 16 00 19 7e dd 77 f7 3e 93 80 5f 3e c0
ce 00 57 1a 47 dd 7e f7 90 28 6c dd 36 fb 01 79
b7 20 0a dd 36 d9 08 dd 36 da 00 18 08 dd 36 d9
04 dd 36 da 00 dd 7e d9 dd 77 ff dd 46 fc dd 36
fe 00 dd 7e fe dd 96 ff 30 47 04 dd 7e f7 dd a6
fb b7 28 08 3a 0e c4 dd 77 d9 18 06 3a 0d c4 dd
77 d9 c5 d5 dd 7e f9 f5 33 c5 33 3e ff f5 33 dd
7e d9 f5 33 cd e0 06 f1 f1 d1 c1 dd 7e fb 87 dd
77 fb dd 34 fe 18 bb dd 7e fc c6 08 dd 77 fc 18
03 dd 70 fc dd 7e f7 12 0c c3 ec 1d dd 6e f6 26
00 29 29 29 29 11 00 71 19 7e dd 77 fa dd 7e f6
07 07 07 07 e6 f0 c6 08 4f 17 9f 47 21 00 71 09
46 3e 9f dd 86 f6 5f 3e c0 ce 00 57 1a 4f dd 7e
fa 91 20 0f 3e a5 dd 86 f6 6f 3e c0 ce 00 67 7e
90 28 53 78 6f 17 9f 67 dd 7e fa dd 77 d9 17 9f
dd 77 da e5 dd 6e db dd 66 dc e5 fd e1 e1 c5 d5
e5 dd 6e d9 dd 66 da e5 21 d0 22 e5 fd e5 cd 92
2d 21 08 00 39 f9 d1 c1 dd 7e f6 c6 06 67 dd 6e
df dd 4e e0 c5 d5 e5 33 11 ff 14 d5 61 e5 cd eb
03 f1 f1 33 d1 c1 dd 7e fa 12 3e a5 dd 86 f6 6f
3e c0 ce 00 67 70 dd 6e f6 26 00 29 29 29 29 11
00 72 19 7e dd 77 f5 dd 7e f6 07 07 07 07 e6 f0
c6 08 4f 17 9f 47 21 00 72 09 46 3e ab dd 86 f6
5f 3e c0 ce 00 57 1a 4f dd 7e f5 91 20 0f 3e b1
dd 86 f6 6f 3e c0 ce 00 67 7e 90 28 53 78 6f 17
9f 67 dd 7e f5 dd 77 d9 17 9f dd 77 da e5 dd 6e
e3 dd 66 e4 e5 fd e1 e1 c5 d5 e5 dd 6e d9 dd 66
da e5 21 d0 22 e5 fd e5 cd 92 2d 21 08 00 39 f9
d1 c1 dd 7e f6 c6 06 67 dd 6e eb dd 4e ec c5 d5
e5 33 11 ff 1d d5 61 e5 cd eb 03 f1 f1 33 d1 c1
dd 7e f5 12 3e b1 dd 86 f6 6f 3e c0 ce 00 67 70
dd 6e f6 26 00 29 29 29 11 00 73 19 7e dd 77 f4
3e b7 dd 86 f6 5f 3e c0 ce 00 57 1a 4f dd 7e f4
91 28 38 dd 6e f4 26 00 dd 4e f1 dd 46 f2 d5 e5
21 d7 22 e5 c5 cd 92 2d 21 06 00 39 f9 d1 dd 7e
f6 c6 0e 4f dd 6e d7 dd 66 d8 d5 51 1e 06 d5 3e
ff f5 33 e5 cd eb 03 f1 f1 33 d1 dd 7e f4 12 dd
7e f6 07 07 07 07 e6 f0 c6 08 4f 17 9f 47 21 00
74 09 7e e6 01 4f dd 7e f6 dd 77 d9 dd 36 da 00
6f 26 00 29 29 29 29 11 00 74 19 7e dd 77 fd 3e
bd dd 86 f6 dd 77 dd 3e c0 ce 00 dd 77 de dd 6e
dd dd 66 de 46 dd 71 e1 dd 7e f6 c6 0e dd 77 e2
dd 7e e1 90 ca 55 21 3e 03 18 08 dd cb d9 26 dd
cb da 16 3d 20 f5 3e c9 dd 86 d9 dd 77 d9 3e c0
dd 8e da dd 77 da dd 5e d9 dd 56 da 21 1d 00 39
eb 01 04 00 ed b0 dd 7e fd dd 77 e9 17 9f dd 77
ea dd 7e e9 dd 77 ed dd 7e ea dd 77 ee 17 9f dd
77 ef dd 77 f0 dd 7e e5 dd 86 ed dd 77 ed dd 7e
e6 dd 8e ee dd 77 ee dd 7e e7 dd 8e ef dd 77 ef
dd 7e e8 dd 8e f0 dd 77 f0 dd 5e d9 dd 56 da 21
25 00 39 01 04 00 ed b0 dd 4e ed dd 46 ee cb 38
cb 19 cb 38 cb 19 cb 38 cb 19 41 c5 33 dd 56 e2
1e 16 d5 3e ff f5 33 21 d7 22 e5 cd c8 04 21 06
00 39 f9 18 10 dd 7e fd 3d 28 06 dd 7e fd 3c 20
04 dd 36 fd 00 3e c3 dd 86 f6 dd 77 ed 3e c0 ce
00 dd 77 ee dd 6e ed dd 66 ee dd 7e fd 96 28 1b
dd 7e fd f5 33 dd 56 e2 1e 11 d5 3e ff f5 33 21
d7 22 e5 cd 44 04 21 06 00 39 f9 dd 6e ed dd 66
ee dd 7e fd 77 dd 6e dd dd 66 de dd 7e e1 77 dd
34 f6 c3 c4 1d 3a 0b c4 b7 ca 8a 22 21 e3 c0 cb
46 28 15 3a e2 c0 f5 33 3a e1 c0 57 1e ff d5 3e
20 f5 33 cd e0 06 f1 f1 0e 00 21 0b c4 79 96 d2
7b 22 21 12 c0 06 00 09 46 78 d6 0a 20 1d 3a 1c
c4 32 e1 c0 fd 21 e2 c0 fd 34 00 3a 1f c4 fd 96
00 30 74 3a 1d c4 32 e2 c0 18 6c 78 d6 08 20 28
3a 1c c4 fd 21 e1 c0 fd 96 00 30 5b fd 35 00 c5
3a e2 c0 f5 33 3a e1 c0 57 1e ff d5 3e 20 f5 33
cd e0 06 f1 f1 c1 18 3f c5 3a e2 c0 f5 33 3a e1
c0 57 1e ff d5 c5 33 cd e0 06 f1 f1 c1 fd 21 e1
c0 fd 34 00 3a 1e c4 fd 96 00 30 1b 3a 1c c4 32
e1 c0 fd 21 e2 c0 fd 34 00 3a 1f c4 fd 96 00 30
06 3a 1d c4 32 e2 c0 0c c3 da 21 21 0b c4 36 00
21 e3 c0 36 00 21 20 c4 36 01 fd 21 20 c4 fd 35
00 fd 7e 00 b7 20 34 fd 21 e3 c0 fd 7e 00 ee 01
fd 77 00 21 20 c4 36 1e 21 e3 c0 cb 46 28 05 01
7c 00 18 03 01 20 00 41 3a e2 c0 f5 33 3a e1 c0
57 1e ff d5 c5 33 cd e0 06 f1 f1 dd f9 dd e1 c9
25 34 64 25 34 64 00 25 34 64 00 21 1d c5 36 02
af f5 33 af f5 33 cd 29 17 f1 21 21 c5 36 3c 21
00 78 36 00 11 0e 0e d5 3e dd f5 33 21 26 23 e5
cd eb 03 f1 f1 33 11 13 0f d5 11 13 dd d5 cd e0
06 f1 f1 11 03 10 d5 3e dd f5 33 21 31 23 e5 cd
eb 03 f1 f1 33 c9 50 72 65 73 73 20 68 65 72 65
00 2d 2d 2d 03 03 03 02 02 02 01 01 01 a6 a6 a6
7f 7f 7f a6 a6 a6 01 01 01 02 02 02 03 03 03 2d
2d 2d 00 dd e5 dd 21 00 00 dd 39 3b 21 06 c0 cb
46 ca 0f 24 21 07 c0 cb 46 c2 0f 24 3a 00 70 b7
ca 0f 24 dd 36 ff 00 0e 00 79 d6 08 30 26 21 00
70 5e 41 21 01 00 04 18 01 29 10 fd 06 00 7d a3
5f 7c a0 b3 28 08 dd 7e ff 32 1f c5 18 06 0c dd
71 ff 18 d5 21 1d c5 36 01 af f5 33 af f5 33 cd
29 17 f1 11 05 0e d5 3e f8 f5 33 21 27 24 e5 cd
eb 03 f1 f1 33 11 06 10 d5 3e ff f5 33 21 45 24
e5 cd eb 03 f1 f1 33 21 1f c5 4e 06 00 69 60 29
09 29 29 11 6f c4 19 11 1a 10 d5 3e 07 f5 33 e5
cd eb 03 f1 f1 33 11 07 12 d5 3e 38 f5 33 21 5a
24 e5 cd eb 03 f1 f1 33 21 21 c5 36 0a 18 14 21
08 c0 cb 46 28 0d 21 09 c0 cb 46 20 06 cd 0a 02
cd 67 19 33 dd e1 c9 48 69 74 20 74 68 65 20 62
75 74 74 6f 6e 20 61 74 20 65 61 63 68 20 70 72
6f 6d 70 74 00 53 65 6c 65 63 74 65 64 20 62 75
74 74 6f 6e 20 69 73 3a 20 00 50 72 65 73 73 20
61 67 61 69 6e 20 74 6f 20 73 74 61 72 74 20 74
65 73 74 00 21 06 c0 cb 46 c8 21 07 c0 cb 46 c0
21 00 70 5e 21 1f c5 46 0e 01 04 18 02 cb 21 10
fc 7b a1 4f fd 21 21 c5 fd 7e 00 b7 28 0b 3a 00
70 b7 20 14 fd 35 00 18 0f 79 b7 20 0b 3a 20 c5
b7 28 05 c5 cd db 22 c1 21 20 c5 71 c9 dd e5 dd
21 00 00 dd 39 3b 21 00 70 4e 21 1f c5 46 21 01
00 04 18 01 29 10 fd 06 00 7d a1 4f 7c a0 b1 c6
ff 3e 00 17 4f dd 71 ff cb 41 28 2f 3a 24 c5 b7
20 29 01 ef c0 fd 21 23 c5 fd 6e 00 26 00 29 09
eb 3a 08 78 47 0e 00 3a 00 78 6f 26 00 79 b5 4f
78 b4 47 79 12 13 78 12 fd 34 00 dd 7e ff 32 24
c5 21 08 c0 cb 46 ca 16 26 21 09 c0 cb 46 c2 16
26 21 21 c5 35 3e 10 f5 33 3a 27 c5 f5 33 af f5
33 cd 7f 07 f1 33 3a 21 c5 d6 1e 20 05 21 27 c5
36 02 3a 27 c5 b7 28 26 21 21 c5 4e 06 00 21 02
00 e5 c5 cd e2 2d f1 f1 7c b5 20 12 fd 21 27 c5
fd 34 00 3e 23 fd 96 00 30 04 fd 36 00 00 3a 27
c5 b7 28 10 3e 10 f5 33 3a 27 c5 57 1e ff d5 cd
7f 07 f1 33 fd 21 28 c5 fd 7e 00 b7 28 24 fd 35
00 fd 7e 00 b7 20 1b 3a 22 c5 d6 05 20 14 21 1d
c5 36 03 21 25 c5 36 01 11 01 01 d5 cd 29 17 f1
18 54 3a 21 c5 b7 20 4e 01 ed c2 fd 21 22 c5 fd
6e 00 26 00 29 09 eb 3a 08 78 47 0e 00 3a 00 78
6f 26 00 79 b5 4f 78 b4 47 79 12 13 78 12 fd 46
00 04 c5 33 11 12 06 d5 3e ff f5 33 21 1a 26 e5
cd c8 04 21 06 00 39 f9 21 21 c5 36 5a 21 28 c5
36 21 21 22 c5 34 33 dd e1 c9 25 32 64 00 21 03
00 39 cb 7e 28 0c 21 02 00 39 af 96 77 3e 00 23
9e 77 c1 e1 e5 c5 c9 dd e5 dd 21 00 00 dd 39 21
ea ff 39 f9 21 25 c5 cb 46 ca 6d 28 11 02 06 d5
3e ff f5 33 21 97 28 e5 cd eb 03 f1 f1 33 11 0b
06 d5 3e ff f5 33 21 9f 28 e5 cd eb 03 f1 f1 33
dd 36 f1 07 dd 36 ee 00 dd 36 ec 00 dd 36 ed 00
dd 36 ef 00 dd 36 f0 00 dd 7e ee b7 c2 68 28 dd
7e ef dd 77 f4 dd 36 f5 00 dd 7e f4 dd 77 f6 dd
7e f5 dd 77 f7 dd cb f6 26 dd cb f7 16 dd 7e ef
d6 05 30 11 3e ed dd 86 f6 6f 3e c2 dd 8e f7 67
4e 23 46 18 03 01 ff ff dd 6e f0 26 00 29 dd 75
f2 dd 74 f3 21 23 c5 dd 7e f0 96 30 1f 3e ef dd
86 f2 6f 3e c0 dd 8e f3 67 5e 23 56 dd 73 f8 dd
72 f9 dd 36 fa 00 dd 36 fb 00 18 10 dd 36 f8 ff
dd 36 f9 ff dd 36 fa 00 dd 36 fb 00 dd 7e f8 dd
77 fe dd 7e f9 dd 77 ff dd 7e f1 3c dd 77 f8 79
dd 96 fe 78 dd 9e ff 30 3a dd 7e f6 c6 ed 6f dd
7e f7 ce c2 67 5e 23 56 c5 d5 dd 56 f1 1e 02 d5
3e ff f5 33 21 a7 28 e5 cd 4a 05 21 07 00 39 f9
c1 dd 7e f8 dd 77 f1 dd 34 ef dd 71 ec dd 70 ed
c3 88 26 dd 7e fe 91 dd 7e ff 98 d2 61 28 dd 7e
f2 c6 ef 6f dd 7e f3 ce c0 67 4e 23 46 c5 dd 56
f1 1e 0b d5 3e ff f5 33 21 a7 28 e5 cd 4a 05 21
07 00 39 f9 dd 4e f4 dd 46 f5 03 3e 05 b9 3e 00
98 e2 a6 27 ee 80 fa ba 27 dd 7e f6 c6 ed 6f dd
7e f7 ce c2 67 4e 23 46 18 03 01 ff ff dd 7e fe
dd 96 ec 5f dd 7e ff dd 9e ed 57 c5 d5 cd 1e 26
f1 c1 dd 75 fc dd 74 fd 79 dd 96 fe 4f 78 dd 9e
ff 47 c5 cd 1e 26 f1 33 33 e5 dd 7e ea d6 f4 dd
7e eb de 01 30 1b e1 e5 e5 dd 56 f1 1e 14 d5 3e
f8 f5 33 21 ad 28 e5 cd cf 05 21 07 00 39 f9 18
44 3e f4 dd be fc 3e 01 dd 9e fd 38 1f dd 6e fc
dd 66 fd e5 dd 56 f1 1e 14 d5 3e 3f f5 33 21 ba
28 e5 cd cf 05 21 07 00 39 f9 18 19 e1 e5 e5 dd
56 f1 1e 14 d5 3e 07 f5 33 21 c6 28 e5 cd cf 05
21 07 00 39 f9 dd 7e f8 dd 77 f1 dd 34 f0 c3 88
26 dd 36 ee 01 c3 88 26 21 25 c5 36 00 21 08 c0
cb 46 28 1e 21 09 c0 cb 46 20 17 cd 0a 02 cd 67
19 21 0a c0 cb 46 28 0a 21 01 c3 cb 46 20 03 cd
f7 17 dd f9 dd e1 c9 50 72 6f 6d 70 74 73 00 50
72 65 73 73 65 73 00 25 36 64 6d 73 00 25 33 64
6d 73 20 62 65 66 6f 72 65 00 25 33 64 6d 73 20
61 66 74 65 72 00 3f 3f 3f 3f 00 fd 21 1d c5 fd
7e 00 b7 ca 53 23 fd 7e 00 3d ca 74 24 fd 7e 00
d6 02 ca bd 24 fd 7e 00 d6 03 ca 37 26 c9 c3 53
23 c3 74 24 c3 bd 24 c3 37 26 21 f7 c2 36 1f 21
36 c5 36 00 af f5 33 cd 95 03 33 3e 07 f5 33 cd
32 0b 33 af 57 1e 12 d5 3e 07 f5 33 21 31 29 e5
cd eb 03 f1 f1 33 21 2a c5 36 05 21 2b c5 36 01
c9 53 4e 45 4b 00 21 f7 c2 36 29 21 00 00 22 34
c5 2e 14 22 2c c5 2e 0f 22 2e c5 21 30 c5 36 00
21 31 c5 36 01 21 32 c5 36 00 21 33 c5 36 01 af
f5 33 cd 95 03 33 3e 07 f5 33 cd 32 0b 33 af 57
1e 12 d5 3e 07 f5 33 21 a3 29 e5 cd eb 03 f1 f1
33 21 2e c5 46 21 2c c5 4e c5 11 53 ff d5 cd e0
06 f1 f1 21 2a c5 36 0e 21 29 c5 36 c8 21 2b c5
36 0e c9 53 4e 45 4b 00 dd e5 dd 21 00 00 dd 39
f5 f5 3b 21 06 c0 cb 46 28 71 21 07 c0 cb 46 20
6a 3a 31 c5 3d 28 11 3a 00 70 cb 5f 28 0a 21 33
c5 36 ff 21 32 c5 36 00 3a 31 c5 3c 28 11 3a 00
70 cb 57 28 0a 21 33 c5 36 01 21 32 c5 36 00 3a
30 c5 3d 28 11 3a 00 70 cb 4f 28 0a 21 32 c5 36
ff 21 33 c5 36 00 3a 30 c5 3c 28 10 3a 00 70 0f
30 0a 21 32 c5 36 01 21 33 c5 36 00 3a 08 70 cb
57 28 08 21 f7 c2 36 00 c3 4a 2b 21 08 c0 cb 46
ca 4a 2b 21 09 c0 cb 46 c2 4a 2b fd 21 2b c5 fd
35 00 fd 7e 00 b7 c2 00 2b 21 2e c5 46 21 2c c5
4e c5 11 7f 66 d5 cd e0 06 f1 f1 3a 32 c5 32 30
c5 3a 33 c5 32 31 c5 3a 30 c5 4f 17 9f 47 21 2c
c5 7e 81 77 23 7e 88 77 3a 31 c5 4f 17 9f 47 21
2e c5 7e 81 77 23 7e 88 77 21 97 02 4e 06 00 c5
2a 2e c5 e5 cd 23 2d f1 f1 4d 44 2a 2c c5 09 01
00 80 09 7e b7 28 0b 21 f8 c2 36 1e cd a3 12 c3
4a 2b fd 21 34 c5 fd 34 00 20 03 fd 34 01 21 2e
c5 46 21 2c c5 4e c5 11 53 ff d5 cd e0 06 f1 f1
3a 2a c5 32 2b c5 21 00 00 39 eb 4b 42 d5 2a 34
c5 e5 21 4f 2b e5 c5 cd 92 2d 21 06 00 39 f9 d1
af 47 0e 23 c5 3e ff f5 33 d5 cd eb 03 f1 f1 33
fd 21 29 c5 fd 35 00 fd 7e 00 b7 20 3d fd 36 00
c8 3e 03 fd 21 2a c5 fd 96 00 30 03 fd 35 00 21
2a c5 4e 06 00 21 02 00 39 5d 54 e5 c5 01 4f 2b
c5 d5 cd 92 2d 21 06 00 39 f9 e1 11 23 1d d5 3e
ff f5 33 e5 cd eb 03 f1 f1 33 dd f9 dd e1 c9 25
34 64 00 21 06 c0 cb 46 28 1c 21 07 c0 cb 46 20
15 3a 08 70 cb 5f c2 36 29 3a 08 70 cb 57 28 06
21 f7 c2 36 00 c9 21 08 c0 cb 46 c8 21 09 c0 cb
46 c0 fd 21 2b c5 fd 35 00 fd 7e 00 b7 c0 fd 21
36 c5 fd 7e 00 d6 01 3e 00 17 fd 77 00 fd 7e 00
b7 20 05 01 00 00 18 03 01 ff 00 41 11 10 0f d5
c5 33 21 c3 2b e5 cd eb 03 f1 f1 33 3a 2a c5 32
2b c5 c9 50 52 45 53 53 20 53 54 41 52 54 00 21
98 02 5e 21 97 02 66 2e 00 55 06 08 29 30 01 19
10 fa 22 00 c0 3a 00 60 cb 07 e6 01 32 02 c0 3a
00 60 e6 40 f6 00 c6 ff 3e 00 17 32 04 c0 3a 00
60 e6 20 f6 00 c6 ff 3e 00 17 32 06 c0 3a 00 60
e6 10 f6 00 c6 ff 3e 00 17 32 08 c0 fd 21 f7 c2
fd 7e 00 3d 28 6b fd 7e 00 d6 02 28 69 fd 7e 00
d6 03 28 67 fd 7e 00 d6 04 28 65 fd 7e 00 d6 05
28 63 fd 7e 00 d6 06 28 61 fd 7e 00 d6 07 28 5f
fd 7e 00 d6 08 28 5d fd 7e 00 d6 09 28 5b fd 7e
00 d6 0a 28 59 fd 7e 00 d6 14 28 57 fd 7e 00 d6
16 28 55 fd 7e 00 d6 1e 28 53 fd 7e 00 d6 1f 28
51 fd 7e 00 d6 28 28 4f fd 7e 00 d6 29 28 4d 18
50 cd ca 17 18 4e cd 8e 19 18 49 cd e0 17 18 44
cd 40 1d 18 3f cd d5 17 18 3a cd c8 1a 18 35 cd
f7 17 18 30 cd cb 28 18 2b cd 6d 10 18 26 cd 7d
10 18 21 cd c3 12 18 1c cd 18 13 18 17 cd fa 28
18 12 cd 53 2b 18 0d cd 36 29 18 08 cd a8 29 18
03 cd ca 17 3a 02 c0 32 03 c0 3a 04 c0 32 05 c0
3a 06 c0 32 07 c0 3a 08 c0 32 09 c0 c3 e5 2b 44
69 67 69 74 61 6c 00 41 6e 61 6c 6f 67 00 41 64
76 61 6e 63 65 64 00 42 75 74 74 6f 6e 20 74 65
73 74 00 f1 c1 d1 d5 c5 f5 af 6f b0 06 10 20 04
06 08 79 29 cb 11 17 30 01 19 10 f7 c9 dd e5 dd
21 00 00 dd 39 dd 6e 05 dd 66 06 e5 4e 23 46 e1
59 50 13 73 23 72 dd 7e 04 02 dd e1 c9 21 02 00
39 fd 21 06 00 fd 39 fd 4e 00 fd 46 01 c5 fd 21
06 00 fd 39 fd 4e 00 fd 46 01 c5 e5 21 3d 2d e5
cd 51 2f f1 f1 f1 f1 4d 44 d1 e1 e5 d5 36 00 69
60 c9 dd e5 dd 21 00 00 dd 39 21 08 00 39 eb 21
04 00 39 d5 dd 4e 06 dd 46 07 c5 e5 21 3d 2d e5
cd 51 2f f1 f1 f1 f1 4d 44 dd 5e 04 dd 56 05 af
12 69 60 dd e1 c9 c1 e1 e5 c5 af 47 4f ed b1 21
ff ff ed 42 c9 21 03 00 39 5e 2b 6e cd fe 2d c3
2c 2e f1 e1 d1 d5 e5 f5 cd 06 2e c3 2c 2e f1 e1
d1 d5 e5 f5 c3 06 2e 21 03 00 39 5e 2b 6e 7d 07
9f 67 7b 07 9f 57 7c aa 17 7c f5 17 30 06 97 95
6f 9f 94 67 cb 7a 28 06 97 93 5f 9f 92 57 cd c8
39 f1 d0 47 97 95 6f 9f 94 67 78 c9 17 eb d0 97
95 6f 9f 94 67 c9 21 02 00 39 7e c6 30 47 3e 39
90 30 10 78 c6 07 47 21 03 00 39 cb 46 28 04 78
c6 20 47 21 06 00 39 7e 23 66 6f e5 c5 33 21 07
00 39 7e 23 66 6f cd f7 39 f1 33 c9 dd e5 dd 21
00 00 dd 39 dd 7e 04 07 07 07 07 e6 0f 47 dd 6e
08 dd 66 09 e5 dd 6e 06 dd 66 07 e5 dd 7e 05 f5
33 c5 33 cd 36 2e 21 06 00 39 f9 dd 7e 04 e6 0f
47 dd 6e 08 dd 66 09 e5 dd 6e 06 dd 66 07 e5 dd
7e 05 f5 33 c5 33 cd 36 2e 21 06 00 39 f9 dd e1
c9 dd e5 dd 21 00 00 dd 39 21 f9 ff 39 f9 dd 5e
04 dd 56 05 d5 21 04 00 39 eb 01 04 00 ed b0 d1
21 04 00 19 4d 44 dd 36 ff 20 0a 87 dd 77 fa dd
7e fe cb 07 e6 01 dd 77 f9 dd 7e fa dd b6 f9 dd
77 f9 02 dd cb fb 26 dd cb fc 16 dd cb fd 16 dd
cb fe 16 dd 7e f9 dd 96 06 38 1f 0a dd 96 06 02
dd 7e fb f6 01 dd 77 fb dd 7e fc dd 77 fc dd 7e
fd dd 77 fd dd 7e fe dd 77 fe dd 35 ff dd 7e ff
b7 20 a7 21 02 00 39 01 04 00 ed b0 dd f9 dd e1
c9 dd e5 dd 21 00 00 dd 39 21 c5 ff 39 f9 dd 36
e6 00 dd 36 e7 00 21 06 00 39 dd 75 e8 dd 74 e9
21 05 00 39 dd 75 e4 dd 74 e5 21 06 00 39 dd 75
d0 dd 74 d1 dd 7e d0 c6 04 dd 77 d4 dd 7e d1 ce
00 dd 77 d5 dd 7e d4 dd 77 d2 dd 7e d5 dd 77 d3
dd 7e d4 dd 77 d7 dd 7e d5 dd 77 d8 dd 6e 08 dd
66 09 5e 23 dd 75 08 dd 74 09 dd 73 d6 7b b7 ca
a0 39 dd 7e d6 d6 25 c2 7d 39 dd 36 fc 00 dd 36
f9 00 dd 36 f8 00 dd 36 f7 00 dd 36 ff 00 dd 36
fe 00 dd 36 fd 00 dd 36 fb 00 dd 36 f3 00 dd 36
db 00 dd 36 f2 ff dd 7e 08 dd 77 d9 dd 7e 09 dd
77 da dd 6e d9 dd 66 da 7e dd 77 dd dd 34 d9 20
03 dd 34 da dd 7e d9 dd 77 08 dd 7e da dd 77 09
dd 7e dd d6 25 20 23 dd 6e 06 dd 66 07 e5 dd 7e
dd f5 33 dd 6e 04 dd 66 05 cd f7 39 f1 33 dd 34
e6 c2 ac 2f dd 34 e7 c3 ac 2f dd 7e dd d6 30 38
40 3e 39 dd 96 dd 38 39 dd 7e f2 3c 20 1f dd 7e
db dd 77 dc 6f 4d 29 29 09 29 dd 7e dd 85 c6 d0
dd 77 db b7 20 8c dd 36 f9 01 c3 02 30 dd 6e f2
4d 29 29 09 29 dd 7e dd 85 c6 d0 dd 77 f2 c3 02
30 dd 7e dd d6 2e 20 0e dd 7e f2 3c c2 02 30 dd
36 f2 00 c3 02 30 dd 7e dd d6 61 38 15 3e 7a dd
96 dd 38 0e dd 7e dd e6 df dd 77 dd dd 36 fa 01
18 04 dd 36 fa 00 dd 7e dd d6 20 ca 65 31 dd 7e
dd d6 2b ca 5e 31 dd 7e dd d6 2d 28 7a dd 7e dd
d6 42 ca 6c 31 dd 7e dd d6 43 ca 7a 31 dd 7e dd
d6 44 ca 82 33 dd 7e dd d6 46 ca 9e 33 dd 7e dd
d6 48 ca 02 30 dd 7e dd d6 49 ca 82 33 dd 7e dd
d6 4a ca 02 30 dd 7e dd d6 4c 28 57 dd 7e dd d6
4f ca 8c 33 dd 7e dd d6 50 ca d9 32 dd 7e dd d6
53 ca c2 31 dd 7e dd d6 54 ca 02 30 dd 7e dd d6
55 ca 92 33 dd 7e dd d6 58 ca 98 33 dd 7e dd d6
5a ca 02 30 c3 a4 33 dd 36 fc 01 c3 02 30 dd 36
f8 01 c3 02 30 dd 36 f7 01 c3 02 30 dd 36 fe 01
c3 02 30 dd 36 fd 01 c3 02 30 dd cb fe 46 28 11
dd 6e 0a dd 66 0b 23 dd 75 0a dd 74 0b 2b 46 18
11 dd 6e 0a dd 66 0b 23 23 dd 75 0a dd 74 0b 2b
2b 46 dd 6e 06 dd 66 07 e5 c5 33 dd 6e 04 dd 66
05 cd f7 39 f1 33 dd 34 e6 c2 ce 33 dd 34 e7 c3
ce 33 21 06 00 39 dd 75 d9 dd 74 da dd 6e 0a dd
66 0b 23 23 dd 75 0a dd 74 0b 2b 2b 4e 23 46 dd
6e d9 dd 66 da 71 23 70 c5 cd c6 2d f1 4d dd 7e
f2 3c 20 03 dd 71 f2 dd cb fc 46 20 3c 79 dd 96
db 30 36 dd 7e db 91 47 dd 5e e6 dd 56 e7 78 05
b7 28 1d c5 d5 dd 6e 06 dd 66 07 e5 3e 20 f5 33
dd 6e 04 dd 66 05 cd f7 39 f1 33 d1 c1 13 18 de
dd 73 e6 dd 72 e7 dd 70 db dd 46 f2 dd 5e e6 dd
56 e7 dd 6e d9 dd 66 da 7e 23 66 6f 7e dd 77 dc
b7 28 4a 68 05 af 95 e2 5c 32 ee 80 f2 9d 32 c5
d5 dd 6e 06 dd 66 07 e5 dd 7e dc f5 33 dd 6e 04
dd 66 05 cd f7 39 f1 33 d1 c1 13 dd 6e d9 dd 66
da 7e 23 66 6f 23 dd 75 de dd 74 df dd 6e d9 dd
66 da dd 7e de 77 23 dd 7e df 77 18 a5 dd 73 e6
dd 72 e7 dd cb fc 46 ca ce 33 79 dd 96 db d2 ce
33 dd 7e db 91 4f 79 0d b7 ca c5 33 c5 d5 dd 6e
06 dd 66 07 e5 3e 20 f5 33 dd 6e 04 dd 66 05 cd
f7 39 f1 33 d1 c1 13 18 dd 21 06 00 39 eb dd 6e
0a dd 66 0b 23 23 dd 75 0a dd 74 0b 2b 2b 4e 23
46 79 12 13 78 12 dd 6e 06 dd 66 07 e5 3e 30 f5
33 dd 6e 04 dd 66 05 cd f7 39 f1 33 dd 4e e6 dd
46 e7 03 c5 dd 6e 06 dd 66 07 e5 3e 78 f5 33 dd
6e 04 dd 66 05 cd f7 39 f1 33 c1 03 21 07 00 39
56 c5 dd 6e 06 dd 66 07 e5 dd 6e 04 dd 66 05 e5
dd 7e fa f5 33 d5 33 cd 6c 2e 21 06 00 39 f9 c1
03 03 dd 6e e8 dd 66 e9 56 c5 dd 6e 06 dd 66 07
e5 dd 6e 04 dd 66 05 e5 dd 7e fa f5 33 d5 33 cd
6c 2e 21 06 00 39 f9 c1 03 03 dd 71 e6 dd 70 e7
18 4c dd 36 ff 01 dd 36 f3 0a 18 42 dd 36 f3 08
18 3c dd 36 f3 0a 18 36 dd 36 f3 10 18 30 dd 36
fb 01 18 2a dd 6e 06 dd 66 07 e5 dd 7e dd f5 33
dd 6e 04 dd 66 05 cd f7 39 f1 33 dd 34 e6 20 0e
dd 34 e7 18 09 dd 73 e6 dd 72 e7 dd 71 db dd cb
fb 46 ca 8a 34 21 06 00 39 dd 75 de dd 74 df dd
7e 0a c6 04 dd 77 d9 dd 7e 0b ce 00 dd 77 da dd
7e d9 dd 77 0a dd 7e da dd 77 0b dd 7e d9 c6 fc
dd 77 d9 dd 7e da ce ff dd 77 da dd 5e d9 dd 56
da 21 1b 00 39 eb 01 04 00 ed b0 dd 5e de dd 56
df 21 1b 00 39 01 04 00 ed b0 21 06 00 39 dd 75
e0 dd 74 e1 36 ab 23 36 39 dd 7e e6 dd 77 de dd
7e e7 dd 77 df dd 6e e0 dd 66 e1 4e 23 46 59 50
13 dd 6e e0 dd 66 e1 73 23 72 0a 47 b7 ca ac 2f
dd 6e 06 dd 66 07 e5 c5 33 dd 6e 04 dd 66 05 cd
f7 39 f1 33 dd 34 de 20 03 dd 34 df dd 7e de dd
77 e6 dd 7e df dd 77 e7 18 bb dd 7e f3 b7 ca ac
2f dd 7e e4 dd 77 e0 dd 7e e5 dd 77 e1 dd cb fe
46 ca 2e 35 21 06 00 39 dd 75 de dd 74 df dd 7e
0a c6 01 dd 77 d9 dd 7e 0b ce 00 dd 77 da dd 7e
d9 dd 77 0a dd 7e da dd 77 0b dd 6e d9 dd 66 da
2b 7e dd 77 dc dd 77 ea dd 36 eb 00 dd 36 ec 00
dd 36 ed 00 dd 5e de dd 56 df 21 25 00 39 01 04
00 ed b0 dd cb ff 46 c2 39 36 dd 5e de dd 56 df
21 25 00 39 eb 01 04 00 ed b0 dd 7e ea dd 77 ea
dd 36 eb 00 dd 36 ec 00 dd 36 ed 00 dd 5e de dd
56 df 21 25 00 39 01 04 00 ed b0 c3 39 36 dd cb
fd 46 28 58 21 06 00 39 dd 75 ea dd 74 eb dd 7e
0a c6 04 dd 77 de dd 7e 0b ce 00 dd 77 df dd 7e
de dd 77 0a dd 7e df dd 77 0b dd 7e de c6 fc dd
77 de dd 7e df ce ff dd 77 df dd 5e de dd 56 df
21 29 00 39 eb 01 04 00 ed b0 dd 5e ea dd 56 eb
21 29 00 39 01 04 00 ed b0 c3 39 36 21 06 00 39
dd 75 ee dd 74 ef dd 7e 0a c6 02 dd 77 ea dd 7e
0b ce 00 dd 77 eb dd 7e ea dd 77 0a dd 7e eb dd
77 0b dd 7e ea c6 fe dd 77 ea dd 7e eb ce ff dd
77 eb dd 7e ea dd 77 ea dd 7e eb dd 77 eb dd 6e
ea dd 66 eb 7e dd 77 ea 23 7e dd 77 eb dd 7e ea
dd 77 ea dd 7e eb dd 77 eb 17 9f dd 77 ec dd 77
ed dd 5e ee dd 56 ef 21 25 00 39 01 04 00 ed b0
dd cb ff 46 20 33 dd 5e ee dd 56 ef 21 25 00 39
eb 01 04 00 ed b0 dd 7e ea dd 77 ea dd 7e eb dd
77 eb dd 36 ec 00 dd 36 ed 00 dd 5e ee dd 56 ef
21 25 00 39 01 04 00 ed b0 dd cb ff 46 28 5f 21
06 00 39 dd 75 ee dd 74 ef eb 21 25 00 39 eb 01
04 00 ed b0 dd cb ed 7e 28 40 dd 5e ee dd 56 ef
21 25 00 39 eb 01 04 00 ed b0 af dd 96 ea dd 77
ea 3e 00 dd 9e eb dd 77 eb 3e 00 dd 9e ec dd 77
ec 3e 00 dd 9e ed dd 77 ed dd 5e ee dd 56 ef 21
25 00 39 01 04 00 ed b0 18 04 dd 36 ff 00 dd 36
f4 01 dd 4e e0 dd 46 e1 dd 36 ee 00 21 0a 00 39
36 00 dd 5e d0 dd 56 d1 c5 dd 7e f3 f5 33 d5 cd
c1 2e f1 33 c1 dd cb f4 46 20 23 dd 6e d2 dd 66
d3 7e 07 07 07 07 e6 f0 5f dd 6e d2 dd 66 d3 7e
07 07 07 07 e6 0f b3 5f 0a b3 02 0b 18 08 dd 6e
d4 dd 66 d5 7e 02 dd 34 ee dd 7e f4 ee 01 dd 77
f4 dd 6e d0 dd 66 d1 5e 23 56 23 23 7e 2b 6e b5
b2 b3 20 98 dd 71 ea dd 70 eb dd 7e ee dd 77 ee
dd 7e db b7 20 04 dd 36 db 01 dd cb f9 46 20 5e
dd cb fc 46 20 58 dd 7e e6 dd 77 e0 dd 7e e7 dd
77 e1 dd 7e db dd 77 de dd 7e ee dd 77 dc dd 34
dc dd 7e dc dd 96 de 30 23 dd 6e 06 dd 66 07 e5
3e 20 f5 33 dd 6e 04 dd 66 05 cd f7 39 f1 33 dd
34 e0 20 03 dd 34 e1 dd 35 de 18 cc dd 7e e0 dd
77 e6 dd 7e e1 dd 77 e7 dd 7e de dd 77 db dd cb
ff 46 28 23 dd 6e 06 dd 66 07 e5 3e 2d f5 33 dd
6e 04 dd 66 05 cd f7 39 f1 33 dd 34 e6 20 03 dd
34 e7 dd 35 db 18 56 dd 7e ee b7 28 50 dd cb f8
46 28 23 dd 6e 06 dd 66 07 e5 3e 2b f5 33 dd 6e
04 dd 66 05 cd f7 39 f1 33 dd 34 e6 20 03 dd 34
e7 dd 35 db 18 27 dd cb f7 46 28 21 dd 6e 06 dd
66 07 e5 3e 20 f5 33 dd 6e 04 dd 66 05 cd f7 39
f1 33 dd 34 e6 20 03 dd 34 e7 dd 35 db dd cb fc
46 20 57 dd 7e e6 dd 77 e0 dd 7e e7 dd 77 e1 dd
7e db dd 77 de dd 4e de dd 35 de dd 7e ee 91 30
52 dd cb f9 46 28 0a dd 36 d9 30 dd 36 da 00 18
08 dd 36 d9 20 dd 36 da 00 dd 46 d9 dd 6e 06 dd
66 07 e5 c5 33 dd 6e 04 dd 66 05 cd f7 39 f1 33
dd 34 e0 20 c0 dd 34 e1 18 bb dd 7e ee dd 96 db
30 0b dd 7e db dd 96 ee dd 77 dc 18 18 dd 36 dc
00 18 12 dd 7e e0 dd 77 e6 dd 7e e1 dd 77 e7 dd
7e de dd 77 dc dd 7e ea dd 77 ea dd 7e eb dd 77
eb dd 7e e6 dd 77 e0 dd 7e e7 dd 77 e1 dd 7e ee
dd 77 ee dd 4e ee dd 35 ee 79 b7 28 6a dd 7e f4
ee 01 dd 77 f4 dd cb f4 46 20 1e dd 34 ea 20 03
dd 34 eb dd 6e ea dd 66 eb 7e 07 07 07 07 e6 0f
dd 6e d4 dd 66 d5 77 18 10 dd 6e ea dd 66 eb 7e
e6 0f dd 6e d4 dd 66 d5 77 dd 6e d7 dd 66 d8 46
dd 6e 06 dd 66 07 e5 dd 6e 04 dd 66 05 e5 dd 7e
fa f5 33 c5 33 cd 36 2e 21 06 00 39 f9 dd 34 e0
20 91 dd 34 e1 18 8c dd 7e e0 dd 77 e6 dd 7e e1
dd 77 e7 dd cb fc 46 ca ac 2f dd 7e e0 dd 77 f5
dd 7e e1 dd 77 f6 dd 4e dc 79 0d b7 ca ac 2f c5
dd 6e 06 dd 66 07 e5 3e 20 f5 33 dd 6e 04 dd 66
05 cd f7 39 f1 33 c1 dd 34 f5 20 03 dd 34 f6 dd
7e f5 dd 77 e6 dd 7e f6 dd 77 e7 18 cc dd 6e 06
dd 66 07 e5 dd 7e d6 f5 33 dd 6e 04 dd 66 05 cd
f7 39 f1 33 dd 34 e6 c2 ac 2f dd 34 e7 c3 ac 2f
dd 6e e6 dd 66 e7 dd f9 dd e1 c9 3c 4e 4f 20 46
4c 4f 41 54 3e 00 f1 e1 d1 d5 e5 f5 18 0a 21 03
00 39 5e 2b 6e 26 00 54 7b e6 80 b2 20 10 06 10
ed 6a 17 93 30 01 83 3f ed 6a 10 f6 5f c9 06 09
7d 6c 26 00 cb 1d ed 6a ed 52 30 01 19 3f 17 10
f5 cb 10 50 5f eb c9 e9 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 c2 60 00 00 00 00 00 00 00 00 00 00 00 00
51 71 21 31 00 00 00 00 00 00 5a 7a 53 73 41 61
57 77 22 32 00 00 00 00 43 63 58 78 44 64 45 65
24 34 c2 33 00 00 00 00 20 20 56 76 46 66 54 74
52 72 25 35 00 00 00 00 4e 6e 42 62 48 68 47 67
59 79 5e 36 00 00 00 00 00 00 4d 6d 4a 6a 55 75
26 37 2a 38 00 00 00 00 3c 2c 4b 6b 49 69 4f 6f
29 30 28 39 00 00 00 00 3e 2e 3f 2f 4c 6c 3a 3b
50 70 5f 2d 00 00 00 00 00 00 40 27 00 00 7b 5b
2b 3d 00 00 00 00 2b 3d 00 00 0a 0a 7d 5d 00 00
7c 5c 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 08 08 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 0a 30 31
00 00 00 ff 2c 07 2d 0e 2d 17 2d 00 00 02 16 25
24 01 00 00 07 07 05 10 52 00 00 00 00 00 4c 00
00 00 00 00 44 00 00 00 00 00 55 00 00 00 00 00
41 00 00 00 00 00 42 00 00 00 00 00 58 00 00 00
00 00 59 00 00 00 00 00 4c 00 00 00 00 00 52 00
00 00 00 00 53 65 6c 00 00 00 53 74 61 72 74 00
44 50 41 44 20 52 69 67 68 74 00 00 44 50 41 44
20 4c 65 66 74 00 00 00 44 50 41 44 20 44 6f 77
6e 00 00 00 44 50 41 44 20 55 70 00 00 00 00 00
41 00 00 00 00 00 00 00 00 00 00 00 42 00 00 00
00 00 00 00 00 00 00 00 58 00 00 00 00 00 00 00
00 00 00 00 59 00 00 00 00 00 00 00 00 00 00 00
4c 00 00 00 00 00 00 00 00 00 00 00 52 00 00 00
00 00 00 00 00 00 00 00 53 65 6c 65 63 74 00 00
00 00 00 00 53 74 61 72 74 00 00 00 00 00 00 00
06 02 04 04 18 16 16 14 03 17 09 0d 05 05 06 04
05 06 04 05 01 01 05 05 01 14 05 05 00 00 00 00
00 01 00 00 00 00 00 00 00 00 00 00 00 14 00 0f
00 00 01 00 01 00 00 00 01 40 02 78 b1 28 08 11
f7 c2 21 f8 39 ed b0 c9

View File

@@ -1,6 +1,6 @@
`timescale 1ns / 1ps
/*============================================================================
MiSTer test harness - System module
Aznable (custom 8-bit computer system) - System module
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0
@@ -33,7 +33,10 @@ module system (
input [191:0] joystick,
// 6 devices, 16 bits each - -127..+127, Y: [15:8], X: [7:0]
input [95:0] analog,
input [95:0] analog_l,
// 6 devices, 16 bits each - -127..+127, Y: [15:8], X: [7:0]
input [95:0] analog_r,
// 6 devices, 8 bits each - paddle 0..255
input [47:0] paddle,
@@ -48,6 +51,9 @@ module system (
// [0-23] mouse data, [24] - toggles with every event, [25-31] - padding,
// [32-39] - wheel movements, [40-47] - reserved(additional buttons)
input [47:0] ps2_mouse,
// [31:0] - seconds since 1970-01-01 00:00:00, [32] - toggle with every change
input [32:0] timestamp,
output VGA_HS,
output VGA_VS,
@@ -87,20 +93,49 @@ jtframe_vtimer #(
.VS(VGA_VS)
);
// Millisecond timer
reg [15:0] timer;
reg [14:0] timer_divider = 15'd0;
always @(posedge clk_sys)
begin
if(timer_cs == 1'b1 && cpu_wr_n == 1'b0)
begin
timer <= 16'd0;
timer_divider <= 15'd0;
end
else
begin
if(timer_divider==15'd24000)
begin
timer <= timer + 16'd1;
timer_divider <= 15'd0;
end
else
begin
timer_divider <= timer_divider + 15'd1;
end
end
end
// Character map
wire [3:0] chpos_x = 4'd7 - hcnt[2:0];
wire [2:0] chpos_y = vcnt[2:0];
wire [5:0] chram_x = hcnt[8:3];
wire [5:0] chram_y = vcnt[8:3];
wire [11:0] chram_addr = {chram_y, chram_x};
wire [11:0] colram_addr = chram_addr;
wire [11:0] chrom_addr = {1'b0, chmap_data_out[7:0], chpos_y};
wire chpixel = chrom_data_out[chpos_x[2:0]];
// RGB output
assign VGA_R = chpixel ? {{2{colram_data_out[2:0]}},2'b0} : 8'b0;
assign VGA_G = chpixel ? {{2{colram_data_out[5:3]}},2'b0} : 8'b0;
assign VGA_B = chpixel ? {{3{colram_data_out[7:6]}},2'b0} : 8'b0;
// RGB mixer
wire [2:0] r_temp = chpixel ? fgcolram_data_out[2:0] : bgcolram_data_out[2:0];
wire [2:0] g_temp = chpixel ? fgcolram_data_out[5:3] : bgcolram_data_out[5:3];
wire [1:0] b_temp = chpixel ? fgcolram_data_out[7:6] : bgcolram_data_out[7:6];
// Convert RGb to 24bpp
assign VGA_R = {{2{r_temp}},2'b0};
assign VGA_G = {{2{g_temp}},2'b0};
assign VGA_B = {{3{b_temp}},2'b0};
// CPU control signals
wire [15:0] cpu_addr;
@@ -136,59 +171,75 @@ wire [7:0] pgrom_data_out;
wire [7:0] chrom_data_out;
wire [7:0] wkram_data_out;
wire [7:0] chram_data_out;
wire [7:0] colram_data_out;
wire [7:0] fgcolram_data_out;
wire [7:0] bgcolram_data_out;
// RAM data to GFX
wire [7:0] chmap_data_out;
// Hardware inputs
wire [7:0] in0_data_out = {VGA_HS, VGA_VS, 6'b101000};
wire [7:0] in0_data_out = {VGA_HS, VGA_VS,VGA_HB, VGA_VB, 4'b1000};
wire [7:0] joystick_data_out = joystick[cpu_addr[7:0] +: 8];
wire [7:0] analog_data_out = analog[cpu_addr[6:0] +: 8];
wire [7:0] analog_l_data_out = analog_l[cpu_addr[6:0] +: 8];
wire [7:0] analog_r_data_out = analog_r[cpu_addr[6:0] +: 8];
wire [7:0] paddle_data_out = paddle[cpu_addr[5:0] +: 8];
wire [7:0] spinner_data_out = spinner[cpu_addr[6:0] +: 8];
wire [7:0] ps2_key_data_out = ps2_key[cpu_addr[3:0] +: 8];
wire [7:0] ps2_mouse_data_out = ps2_mouse[cpu_addr[5:0] +: 8];
wire [7:0] timestamp_data_out = timestamp[cpu_addr[5:0] +: 8];
wire [7:0] timer_data_out = timer[cpu_addr[3:0] +: 8];
// CPU address decodes
wire pgrom_cs = cpu_addr[15:14] == 2'b00;
//wire chrom_cs = cpu_addr[15:12] == 4'b0100; // CPU never accesses the character ROM data directly
wire chram_cs = cpu_addr[15:11] == 5'b10000;
wire colram_cs = cpu_addr[15:11] == 5'b10001;
wire fgcolram_cs = cpu_addr[15:11] == 5'b10001;
wire bgcolram_cs = cpu_addr[15:11] == 5'b10010;
wire wkram_cs = cpu_addr[15:14] == 2'b11;
wire in0_cs = cpu_addr == 16'h6000;
wire joystick_cs = cpu_addr[15:8] == 8'b01110000;
wire analog_cs = cpu_addr[15:8] == 8'b01110001;
wire paddle_cs = cpu_addr[15:8] == 8'b01110010;
wire spinner_cs = cpu_addr[15:8] == 8'b01110011;
wire ps2_key_cs = cpu_addr[15:8] == 8'b01110100;
wire ps2_mouse_cs = cpu_addr[15:8] == 8'b01110101;
wire analog_l_cs = cpu_addr[15:8] == 8'b01110001;
wire analog_r_cs = cpu_addr[15:8] == 8'b01110010;
wire paddle_cs = cpu_addr[15:8] == 8'b01110011;
wire spinner_cs = cpu_addr[15:8] == 8'b01110100;
wire ps2_key_cs = cpu_addr[15:8] == 8'b01110101;
wire ps2_mouse_cs = cpu_addr[15:8] == 8'b01110110;
wire timestamp_cs = cpu_addr[15:8] == 8'b01110111;
wire timer_cs = cpu_addr[15:8] == 8'b01111000;
// always @(posedge clk_sys) begin
// always @(posedge timestamp[32]) begin
// $display("%b", timestamp);
// end
//always @(posedge clk_sys) begin
// if(pgrom_cs) $display("%x pgrom o %x", cpu_addr, pgrom_data_out);
// if(wkram_cs) $display("%x wkram i %x o %x w %b", cpu_addr, cpu_dout, wkram_data_out, wkram_wr);
// if(chram_cs) $display("%x chram i %x o %x w %b", cpu_addr, cpu_dout, chram_data_out, chram_wr);
// if(colram_cs) $display("%x colram i %x o %x w %b", cpu_addr, cpu_dout, colram_data_out, colram_wr);
// if(fgcolram_cs) $display("%x fgcolram i %x o %x w %b", cpu_addr, cpu_dout, fgcolram_data_out, fgcolram_wr);
// if(in0_cs) $display("%x in0 i %x o %x", cpu_addr, cpu_dout, in0_data_out);
// if(joystick_cs) $display("joystick %b %b", joystick_bit, joystick_data_out);
// if(analog_cs) $display("analog %b %b", analog_bit, analog_data_out);
// if(analog_l_cs) $display("analog_l %b %b", analog_l_bit, analog_l_data_out);
// if(analog_r_cs) $display("analog_r %b %b", analog_r_bit, analog_r_data_out);
// if(paddle_cs) $display("paddle %b", paddle_data_out);
// if(ps2_key_cs) $display("ps2_key %b %x", ps2_key_data_out, cpu_addr[3:0]);
// $display("%x", cpu_addr);
// end
//end
// CPU data mux
assign cpu_din = pgrom_cs ? pgrom_data_out :
wkram_cs ? wkram_data_out :
chram_cs ? chram_data_out :
colram_cs ? colram_data_out :
fgcolram_cs ? fgcolram_data_out :
bgcolram_cs ? bgcolram_data_out :
in0_cs ? in0_data_out :
joystick_cs ? joystick_data_out :
analog_cs ? analog_data_out :
analog_l_cs ? analog_l_data_out :
analog_r_cs ? analog_r_data_out :
paddle_cs ? paddle_data_out :
spinner_cs ? spinner_data_out :
ps2_key_cs ? ps2_key_data_out :
ps2_mouse_cs ? ps2_mouse_data_out :
timestamp_cs ? timestamp_data_out :
timer_cs ? timer_data_out :
8'b00000000;
// Rom upload write enables
@@ -198,7 +249,8 @@ wire chrom_wr = dn_wr && dn_index == 8'b1;
// Ram write enables
wire wkram_wr = !cpu_wr_n && wkram_cs;
wire chram_wr = !cpu_wr_n && chram_cs;
wire colram_wr = !cpu_wr_n && colram_cs;
wire fgcolram_wr = !cpu_wr_n && fgcolram_cs;
wire bgcolram_wr = !cpu_wr_n && bgcolram_cs;
// MEMORY
@@ -253,20 +305,36 @@ dpram #(11,8) chram
.q_b(chmap_data_out)
);
// Char color RAM - 0x8800 - 0x8FFF (0x0800 / 2048 bytes)
dpram #(11,8) colram
// Char foreground color RAM - 0x8800 - 0x8FFF (0x0800 / 2048 bytes)
dpram #(11,8) fgcolram
(
.clock_a(clk_sys),
.address_a(cpu_addr[10:0]),
.wren_a(colram_wr),
.wren_a(fgcolram_wr),
.data_a(cpu_dout),
.q_a(),
.clock_b(clk_sys),
.address_b(colram_addr[10:0]),
.address_b(chram_addr[10:0]),
.wren_b(1'b0),
.data_b(),
.q_b(colram_data_out)
.q_b(fgcolram_data_out)
);
// Char background color RAM - 0x9000 - 0x97FF (0x0800 / 2048 bytes)
dpram #(11,8) bgcolram
(
.clock_a(clk_sys),
.address_a(cpu_addr[10:0]),
.wren_a(bgcolram_wr),
.data_a(cpu_dout),
.q_a(),
.clock_b(clk_sys),
.address_b(chram_addr[10:0]),
.wren_b(1'b0),
.data_b(),
.q_b(bgcolram_data_out)
);
// Work RAM - 0xC000 - 0xFFFF (0x4000 / 16384 bytes)

84
src/fader.c Normal file
View File

@@ -0,0 +1,84 @@
/*============================================================================
Input Test - Fader
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0
Date: 2021-07-12
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program. If not, see <http://www.gnu.org/licenses/>.
===========================================================================*/
#pragma once
#include "sys.c"
// Fade in/out constants
#define fadefreq 4
// Fade in/out variables
unsigned char fade = 0;
unsigned char fadetimer = 0;
// Initialise fadeout state
void start_fadeout()
{
state = STATE_FADEOUT;
fadetimer = fadefreq;
fade = 0;
}
// Initialise fadein state
void start_fadein()
{
state = STATE_FADEIN;
fadetimer = fadefreq;
fade = 15;
}
// Fade out state
void fadeout()
{
if (VBLANK_RISING)
{
fadetimer--;
if (fadetimer == 0)
{
box(fade, fade, 39 - fade, 29 - fade, 127, 0b0000111);
fadetimer = fadefreq;
fade++;
if (fade == 16)
{
start_fadein();
}
}
}
}
// Fade in state
void fadein()
{
if (VBLANK_RISING)
{
fadetimer--;
if (fadetimer == 0)
{
box(fade, fade, 39 - fade, 29 - fade, 0, 0b0000000);
fadetimer = fadefreq;
fade--;
if (fade == 0)
{
state = nextstate;
}
}
}
}

910
src/inputtester.c Normal file
View File

@@ -0,0 +1,910 @@
/*============================================================================
Input Test - Input test state handlers
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0
Date: 2021-07-13
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program. If not, see <http://www.gnu.org/licenses/>.
===========================================================================*/
#pragma once
#include "sys.c"
#include "fader.c"
#include "menu.c"
// Input tester variables
unsigned char joystick_last[12];
signed char ax_l_last[6];
signed char ay_l_last[6];
signed char ax_r_last[6];
signed char ay_r_last[6];
unsigned char px_last[6];
signed char sx_toggle_last[6];
signed char sx_last[6];
unsigned long sx_pos[6];
// Console constants
#define con_cursorfreq 30
// Console variables
unsigned char con_x; // Console cursor X position
unsigned char con_y; // Console cursor X position
unsigned char con_l = 2; // Console left edge X
unsigned char con_t = 22; // Console top edge Y
unsigned char con_r = 37; // Console right edge X
unsigned char con_b = 36; // Console bottom edge Y
bool con_cursor;
unsigned char con_cursortimer = 1;
// Mode switcher variables
char modeswitchtimer_select = 0;
char modeswitchtimer_start = 0;
#define HISTORY_LENGTH 7
char history[HISTORY_LENGTH];
#define PAD_COUNT 2
#define BUTTON_COUNT 12
char pad_offset_x[PAD_COUNT] = {7, 7};
char pad_offset_y[PAD_COUNT] = {5, 16};
char button_symbol[BUTTON_COUNT][6] = {
"R",
"L",
"D",
"U",
"A",
"B",
"X",
"Y",
"L",
"R",
"Sel",
"Start"};
char button_name[BUTTON_COUNT][12] = {
"DPAD Right",
"DPAD Left",
"DPAD Down",
"DPAD Up",
"A",
"B",
"X",
"Y",
"L",
"R",
"Select",
"Start"};
char button_x[BUTTON_COUNT] = {6, 2, 4, 4, 24, 22, 22, 20, 3, 23, 9, 13};
char button_y[BUTTON_COUNT] = {5, 5, 6, 4, 5, 6, 4, 5, 1, 1, 5, 5};
#define color_button_active 0xFF
#define color_button_inactive 0b10100100
char analog_offset_x[PAD_COUNT] = {1, 20};
char analog_offset_y[PAD_COUNT] = {5, 5};
signed char analog_x[PAD_COUNT];
signed char analog_y[PAD_COUNT];
#define analog_size 18
#define analog_ratio 15 // 256 / 17;
#define timestamp_clock_index 32
#define timestamp_index_1 8
#define timestamp_index_2 16
#define timestamp_index_3 24
bool last_timestamp_clock = 0;
// Button test constants
#define btntest_mode_select 0
#define btntest_mode_ready 1
#define btntest_mode_test 2
#define btntest_mode_results 3
#define btntest_timer_start 60 // vblanks to wait before first prompt
#define btntest_timer_interval 90 // vblanks to wait between prompts
#define btntest_timer_visible 30 // vblanks to wait between prompts
#define btntest_counter_max 5 // Number of button presses required
#define btntest_max 255
#define btntest_highlight_start 2
#define btntest_highlight_end 35
// Analog tester variables
char analog_pad = 0;
// Button test variables
char btntest_mode = 0;
char btntest_buttonbank = 0;
char btntest_buttonindex = 0;
char btntest_buttonlast = 1;
char btntest_timer = 0;
char btntest_counter = 0;
unsigned short btntest_presses[btntest_max];
unsigned short btntest_prompts[btntest_counter_max];
char btntest_pos = 0;
char btntest_buttondownlast = 0;
bool btntest_results_refresh = 0;
char btntest_results_offset = 0;
char btntest_highlight = 0;
char btntest_aftertimer = 0;
// Draw static elements for digital input test page
void page_inputtester_digital()
{
page_frame(true, false);
// Draw pads
for (char j = 0; j < PAD_COUNT; j++)
{
write_stringf("JOY %d", 0xFF, pad_offset_x[j] - 5, pad_offset_y[j] + 5, j + 1);
draw_pad(pad_offset_x[j], pad_offset_y[j]);
}
}
// Draw static elements for analog input test page
void page_inputtester_analog()
{
page_frame(true, false);
// Draw analog grids
char j = 0;
write_string("ANALOG LEFT", 0xFF, analog_offset_x[j], analog_offset_y[j] - 1);
draw_analog(analog_offset_x[j], analog_offset_y[j], analog_size, analog_size);
write_string("X:", 0xFF, analog_offset_x[j] + 1, analog_offset_y[j] + analog_size + 1);
write_string("Y:", 0xFF, analog_offset_x[j] + 10, analog_offset_y[j] + analog_size + 1);
write_stringf("PAD %d", 0xFF, 18, analog_offset_y[j] - 1, analog_pad + 1);
j = 1;
write_string("ANALOG RIGHT", 0xFF, analog_offset_x[j] + analog_size - 11, analog_offset_y[j] - 1);
draw_analog(analog_offset_x[j], analog_offset_y[j], analog_size, analog_size);
write_string("X:", 0xFF, analog_offset_x[j] + 1, analog_offset_y[j] + analog_size + 1);
write_string("Y:", 0xFF, analog_offset_x[j] + 10, analog_offset_y[j] + analog_size + 1);
write_string("Cycle selected pad with A / B", 0x3F, 5, analog_offset_y[j] + analog_size + 2);
}
// Draw static elements for advanced input test page
void page_inputtester_advanced()
{
page_frame(true, false);
write_string("RLDUABXYLRsS", 0xFF, 7, 5);
write_string("ALX", 0xFF, 21, 5);
write_string("ALY", 0xFF, 25, 5);
write_string("ARX", 0xFF, 30, 5);
write_string("ARY", 0xFF, 34, 5);
write_string("POS", 0xFF, 7, 13);
write_string("SPD POS", 0xFF, 18, 13);
char label[5];
for (unsigned char j = 0; j < 6; j++)
{
sprintf(label, "JOY%d", j + 1);
write_string(label, 0xFF - (j * 2), 2, 6 + j);
sprintf(label, "PAD%d", j + 1);
write_string(label, 0xFF - (j * 2), 2, 14 + j);
sprintf(label, "SPN%d", j + 1);
write_string(label, 0xFF - (j * 2), 14, 14 + j);
}
write_string("CON", 0xFF, 2, 21);
}
// Draw static elements for button test page
void page_btntest(bool showMenuButton, bool showContinueButton)
{
page_frame(showMenuButton, showContinueButton);
write_string("BUTTON TEST", 0xAA, 15, 4);
}
void reset_inputstates()
{
modeswitchtimer_select = 0;
modeswitchtimer_start = 0;
for (char i = 0; i < 12; i++)
{
joystick_last[i] = 1;
}
for (char i = 0; i < 6; i++)
{
ax_l_last[i] = 1;
ay_l_last[i] = -1;
ax_r_last[i] = 1;
ay_r_last[i] = -1;
px_last[i] = 1;
sx_toggle_last[i] = 1;
sx_last[i] = 1;
sx_pos[i] = 0;
}
}
// Initialise digital inputtester state and draw static elements
void start_inputtester_digital()
{
state = STATE_INPUTTESTER;
// Draw page
page_inputtester_digital();
// Reset last states for inputs
reset_inputstates();
}
// Initialise analog inputtester state and draw static elements
void start_inputtester_analog()
{
state = STATE_INPUTTESTERANALOG;
// Draw page
page_inputtester_analog();
// Reset last states for inputs
reset_inputstates();
}
// Initialise advanced inputtester state and draw static elements
void start_inputtester_advanced()
{
state = STATE_INPUTTESTERADVANCED;
// Draw page
page_inputtester_advanced();
// Reset console cursor
con_x = con_l;
con_y = con_t;
// Reset last states for inputs
reset_inputstates();
}
// Initialise button test state and draw static elements
void start_btntest()
{
state = STATE_BTNTEST;
btntest_mode = btntest_mode_select;
btntest_buttonbank = 0;
btntest_buttonindex = 0;
btntest_buttonlast = 1;
btntest_timer = 0;
btntest_counter = 0;
btntest_pos = 0;
// Draw page
page_btntest(true, false);
write_string("Press the button you want to test", 0xFF, 3, 14);
write_string("Remember to enable fast USB polling!", 0xEE, 2, 25);
}
// Rotate DPAD direction history and push new entry
void pushhistory(char new)
{
for (char h = 1; h < HISTORY_LENGTH; h++)
{
history[h - 1] = history[h];
}
history[HISTORY_LENGTH - 1] = new;
}
// Track input history of P1 DPAD for secret codes!
void handle_codes()
{
if (!input_up && input_up_last)
{
pushhistory(1);
}
if (!input_down && input_down_last)
{
pushhistory(2);
}
if (!input_left && input_left_last)
{
pushhistory(3);
}
if (!input_right && input_right_last)
{
pushhistory(4);
}
if (!input_a && input_a_last)
{
pushhistory(5);
}
// Check for SNEK code
if (history[0] == 1 && history[1] == 1 && history[2] == 2 && history[3] == 2 && history[4] == 3 && history[5] == 4 && history[6] == 5)
{
nextstate = STATE_START_ATTRACT;
pushhistory(0);
start_fadeout();
return;
}
}
// Menu opening handler
bool modeswitcher()
{
// Open menu if select is held
if (input_select)
{
modeswitchtimer_select++;
if (modeswitchtimer_select == menu_openholdtime)
{
modeswitchtimer_select = 0;
start_menu();
return 1;
}
}
else
{
modeswitchtimer_select = 0;
}
return 0;
}
// Digital input tester state
void inputtester_digital()
{
// Handle PS/2 inputs whenever possible to improve latency
handle_ps2();
// Handle secret code detection (joypad 1 directions)
if (HBLANK_RISING)
{
basic_input();
handle_codes();
}
// As soon as vsync is detected start drawing screen updates
if (VBLANK_RISING)
{
// Handle test mode switch
if (modeswitcher())
{
return;
}
// Draw control pad buttons
for (char joy = 0; joy < PAD_COUNT; joy++)
{
char index = joy * 32;
for (char button = 0; button < BUTTON_COUNT; button++)
{
char color = (button < 8 ? CHECK_BIT(joystick[index], button) : CHECK_BIT(joystick[index + 8], button - 8)) ? color_button_active : color_button_inactive;
write_string(button_symbol[button], color, pad_offset_x[joy] + button_x[button], pad_offset_y[joy] + button_y[button]);
}
}
}
}
// Analog input tester state
void inputtester_analog()
{
// Handle PS/2 inputs whenever possible to improve latency
handle_ps2();
if (HBLANK_RISING)
{
basic_input();
handle_codes();
// Pad selection
if (!input_a && input_a_last)
{
if (analog_pad == 5)
{
analog_pad = 0;
}
else
{
analog_pad += 1;
}
page_inputtester_analog();
}
if (!input_b && input_b_last)
{
if (analog_pad == 0)
{
analog_pad = 5;
}
else
{
analog_pad -= 1;
}
page_inputtester_analog();
}
}
// As soon as vsync is detected start drawing screen updates
if (VBLANK_RISING)
{
// Handle test mode switch
if (modeswitcher())
{
return;
}
// Draw analog left point
char side = 0;
char mx = analog_offset_x[side] + (analog_size / 2);
char my = analog_offset_y[side] + (analog_size / 2);
// Reset previous color
set_fgcolour(color_analog_grid, analog_x[side] + mx, analog_y[side] + my);
signed char ax = analog_l[(analog_pad * 16)];
signed char ay = analog_l[(analog_pad * 16) + 8];
analog_x[analog_pad] = ax / analog_ratio;
analog_y[analog_pad] = ay / analog_ratio;
// Set new color
set_fgcolour(0xFF, analog_x[side] + mx, analog_y[side] + my);
write_stringfs("%4d", 0xFF, analog_offset_x[side] + 3, analog_offset_y[side] + analog_size + 1, ax);
write_stringfs("%4d", 0xFF, analog_offset_x[side] + 12, analog_offset_y[side] + analog_size + 1, ay);
// Draw analog right point
side = 1;
mx = analog_offset_x[side] + (analog_size / 2);
my = analog_offset_y[side] + (analog_size / 2);
// Reset previous color
set_fgcolour(color_analog_grid, analog_x[side] + mx, analog_y[side] + my);
ax = analog_r[(analog_pad * 16)];
ay = analog_r[(analog_pad * 16) + 8];
analog_x[side] = ax / analog_ratio;
analog_y[side] = ay / analog_ratio;
// Set new color
set_fgcolour(0xFF, analog_x[side] + mx, analog_y[side] + my);
write_stringfs("%4d", 0xFF, analog_offset_x[side] + 3, analog_offset_y[side] + analog_size + 1, ax);
write_stringfs("%4d", 0xFF, analog_offset_x[side] + 12, analog_offset_y[side] + analog_size + 1, ay);
}
}
// Advanced input tester state
void inputtester_advanced()
{
// Handle PS/2 inputs whenever possible to improve latency
handle_ps2();
// Handle secret code detection (joypad 1 directions)
if (HBLANK_RISING)
{
basic_input();
handle_codes();
}
// As soon as vsync is detected start drawing screen updates
if (VBLANK_RISING)
{
// Handle test mode switch
if (modeswitcher())
{
return;
}
// Draw joystick inputs (only update each byte if value has changed)
for (char inputindex = 0; inputindex < 6; inputindex++)
{
char m = 0b00000001;
char x = 6;
char y = 6 + inputindex;
char inputoffset = (inputindex * 32);
char lastoffset = (inputindex * 2);
for (char b = 0; b < 2; b++)
{
char index = (b * 8) + inputoffset;
char lastindex = b + lastoffset;
char joy = joystick[index];
if (joy != joystick_last[lastindex])
{
m = 0b00000001;
char bytes = (b == 0 ? 8 : 4);
for (char i = 0; i < bytes; i++)
{
x++;
write_char((joy & m) ? asc_1 : asc_0, 0xFF, x, y);
m <<= 1;
}
}
else
{
x += 8;
}
joystick_last[lastindex] = joy;
}
char stra[10];
// Draw analog left inputs (only update if value has changed)
signed char ax_l = analog_l[(inputindex * 16)];
signed char ay_l = analog_l[(inputindex * 16) + 8];
if (ax_l != ax_l_last[inputindex] || ay_l != ay_l_last[inputindex])
{
sprintf(stra, "%4d%4d", ax_l, ay_l);
write_string(stra, 0xFF, 20, 6 + inputindex);
}
ax_l_last[inputindex] = ax_l;
ay_l_last[inputindex] = ay_l;
// Draw analog right inputs (only update if value has changed)
signed char ax_r = analog_r[(inputindex * 16)];
signed char ay_r = analog_r[(inputindex * 16) + 8];
if (ax_r != ax_r_last[inputindex] || ay_r != ay_r_last[inputindex])
{
sprintf(stra, "%4d%4d", ax_r, ay_r);
write_string(stra, 0xFF, 29, 6 + inputindex);
}
ax_r_last[inputindex] = ax_r;
ay_r_last[inputindex] = ay_r;
// Draw paddle inputs (only update if value has changed)
unsigned char px = paddle[(inputindex * 8)];
if (px != px_last[inputindex])
{
char strp[5];
sprintf(strp, "%4d", px);
write_string(strp, 0xFF, 6, 14 + inputindex);
}
px_last[inputindex] = px;
// Draw spinner inputs (only update when update clock changes)
bool sx_toggle = CHECK_BIT(spinner[(inputindex * 16) + 8], 0);
signed char sx = spinner[(inputindex * 16)];
if (sx_toggle != sx_toggle_last[inputindex])
{
sx_pos[inputindex] += sx;
write_stringf("%4d", 0xFF, 22, 14 + inputindex, sx_pos[inputindex] / 8);
}
else
{
if (sx == 1 || sx == -1)
{
sx = 0;
}
}
if (sx_last[inputindex] != sx)
{
write_stringfs("%4d", 0xFF, 17, 14 + inputindex, sx);
}
sx_last[inputindex] = sx;
sx_toggle_last[inputindex] = sx_toggle;
}
// Keyboard test console
if (kbd_buffer_len > 0)
{
// Clear existing cursor if visible
if (con_cursor)
{
write_char(' ', 0xFF, con_x, con_y);
}
// Write characters in buffer
for (char k = 0; k < kbd_buffer_len; k++)
{
if (kbd_buffer[k] == '\n')
{
// New line
con_x = con_l;
con_y++;
if (con_y > con_b)
{
// Wrap to top
con_y = con_t;
}
}
else if (kbd_buffer[k] == '\b')
{
// Backspace - only if not at beginning of line
if (con_x > con_l)
{
con_x--;
// Clear existing character
write_char(' ', 0xFF, con_x, con_y);
}
}
else
{
// Write character
write_char(kbd_buffer[k], 0xFF, con_x, con_y);
// Move cursor right
con_x++;
if (con_x > con_r)
{
// New line
con_x = con_l;
con_y++;
if (con_y > con_b)
{
// Wrap to top
con_y = con_t;
}
}
}
}
// Clear buffer and enable cursor
kbd_buffer_len = 0;
con_cursor = 0;
con_cursortimer = 1;
}
// Cursor blink timer
con_cursortimer--;
if (con_cursortimer <= 0)
{
con_cursor = !con_cursor;
con_cursortimer = con_cursorfreq;
write_char(con_cursor ? '|' : ' ', 0xFF, con_x, con_y);
}
}
}
void btntest_starttest()
{
btntest_mode = btntest_mode_test;
page_btntest(false, false); // reset screen
// Prepare variables
btntest_timer = btntest_timer_start;
// Reset hardware timer
timer[0] = 0;
write_string("Press here", 0xDD, 14, 14);
write_char(19, 0xDD, 19, 15);
write_string("---\x3\x3\x3\x2\x2\x2\x1\x1\x1\xA6\xA6\xA6\x7f\x7f\x7f\xA6\xA6\xA6\x1\x1\x1\x2\x2\x2\x3\x3\x3---", 0xDD, 3, 16);
}
// Button test - button select state
void btntest_select()
{
if (HBLANK_RISING)
{
// If any of 1st 8 buttons is pressed
if (joystick[0] != 0)
{
// Find which button
for (char b = 0; b < 8; b++)
{
if (CHECK_BIT(joystick[0], b))
{
btntest_buttonindex = b;
break;
}
}
btntest_mode = btntest_mode_ready;
page_btntest(false, false); // reset screen
write_string("Hit the button at each prompt", 0b11111000, 5, 14);
write_string("Selected button is: ", 0xFF, 6, 16);
char i = btntest_buttonindex;
write_string(button_name[i], 0b00000111, 26, 16);
write_string("Press again to start test", 0b00111000, 7, 18);
btntest_timer = 10;
return;
}
}
if (VBLANK_RISING)
{
// Check inputs for select hold to enter menu
basic_input();
modeswitcher();
}
}
// Button test - ready state
void btntest_ready()
{
if (HBLANK_RISING)
{
char button = CHECK_BIT(joystick[0], btntest_buttonindex);
if (btntest_timer > 0)
{
if (joystick[0] == 0)
{
btntest_timer--;
}
}
else
{
// Check for selected button to be pressed again
if (!button && btntest_buttonlast)
{
btntest_starttest();
}
}
btntest_buttonlast = button;
}
}
// Button test - begin test state
void btntest_test()
{
// Track button presses
bool down = CHECK_BIT(joystick[0], btntest_buttonindex);
if (down && !btntest_buttondownlast)
{
btntest_presses[btntest_pos] = GET_TIMER;
btntest_pos++;
}
btntest_buttondownlast = down;
if (VBLANK_RISING)
{
// Count down to next prompt on vblanks
btntest_timer--;
set_bgcolour(0x0, btntest_highlight, 16);
if (btntest_timer == 30)
{
btntest_highlight = btntest_highlight_start;
}
if (btntest_highlight > 0)
{
if ((btntest_timer % 2) == 0)
{
btntest_highlight++;
if (btntest_highlight > btntest_highlight_end)
{
btntest_highlight = 0;
}
}
}
if (btntest_highlight > 0)
{
set_bgcolour(0xFF, btntest_highlight, 16);
}
if (btntest_aftertimer > 0)
{
btntest_aftertimer--;
if (btntest_aftertimer == 0)
{
// End test here
if (btntest_counter == btntest_counter_max)
{
btntest_mode = btntest_mode_results;
btntest_results_refresh = true;
page_btntest(true, true); // reset screen
return;
}
}
}
if (btntest_timer == 0)
{
// Capture timer
btntest_prompts[btntest_counter] = GET_TIMER;
// Display test counter
write_stringf("%2d", 0xFF, 18, 6, btntest_counter + 1);
btntest_timer = btntest_timer_interval;
btntest_aftertimer = 33;
btntest_counter++;
}
}
}
unsigned short abs(signed short value)
{
if (value < 0)
{
value = value * -1;
}
return value;
}
// Button test - results view
void btntest_results()
{
if (btntest_results_refresh)
{
write_string("Prompts", 0xFF, 2, 6);
// write_string("-------", 0xFF, 2, 7);
write_string("Presses", 0xFF, 11, 6);
// write_string("-------", 0xFF, 11, 7);
char y = 7;
char press = 0;
char prompt = 0;
char done = false;
unsigned short prompt_last = 0;
unsigned short press_last = 0;
while (!done)
{
unsigned short prompt_time = prompt < btntest_counter_max ? btntest_prompts[prompt] : 65535;
unsigned short press_time = press < btntest_pos ? btntest_presses[press] : 65535;
if (prompt_time < press_time)
{
write_stringf_ushort("%6dms", 0xFF, 2, y, btntest_prompts[prompt]);
y++;
prompt++;
prompt_last = prompt_time;
}
else if (press_time < prompt_time)
{
write_stringf_ushort("%6dms", 0xFF, 11, y, btntest_presses[press]);
// Is this early or late or just nowhere near?!
unsigned short prompt_next = prompt + 1 <= btntest_counter_max ? btntest_prompts[prompt] : 65535;
unsigned short diff_last = abs(press_time - prompt_last);
unsigned short diff_next = abs(prompt_next - press_time);
if (diff_next < 500)
{
write_stringf_short("%3dms before", 0b11111000, 20, y, diff_next);
}
else if (diff_last <= 500)
{
write_stringf_short("%3dms after", 0b00111111, 20, y, diff_last);
}
else
{
write_stringf_short("????", 0b00000111, 20, y, diff_next);
}
y++;
press++;
}
else
{
done = true;
}
}
btntest_results_refresh = 0;
}
if (VBLANK_RISING)
{
// Check inputs for select hold to enter menu
basic_input();
modeswitcher();
if (input_start && !input_start_last)
{
start_btntest();
}
}
}
// Button test - mode handler
void btntest()
{
switch (btntest_mode)
{
case btntest_mode_select:
btntest_select();
break;
case btntest_mode_ready:
btntest_ready();
break;
case btntest_mode_test:
btntest_test();
break;
case btntest_mode_results:
btntest_results();
break;
}
}

139
src/menu.c Normal file
View File

@@ -0,0 +1,139 @@
/*============================================================================
Aznable OS - Popup menu functions
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0
Date: 2021-07-13
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program. If not, see <http://www.gnu.org/licenses/>.
===========================================================================*/
#pragma once
// Menu constants
#define menu_tx 12
#define menu_bx 28
#define menu_my 15
#define menu_openholdtime 60
#define menu_count 4
// Menu variables
char menu_timer = 0;
char menu_index;
bool menu_dirty = 0;
bool menu_ready = 0;
char *menu_string[] = {
"Digital",
"Analog",
"Advanced",
"Button test"};
// Initialise menu state
void start_menu()
{
state = STATE_MENU;
menu_timer = 0;
menu_ready = 0;
}
// Menu state
void menu()
{
// Check inputs at end of each scanline. Is this too much?!
if (HBLANK_RISING)
{
basic_input();
if (input_up && !input_up_last) // up
{
menu_index--;
if (menu_index > 128)
{
menu_index = menu_count - 1;
}
menu_dirty = true;
}
if (input_down && !input_down_last) // down
{
menu_index++;
if (menu_index == menu_count)
{
menu_index = 0;
}
menu_dirty = true;
}
if (input_start && input_start_last)
{
switch (menu_index)
{
case 0:
state = STATE_START_INPUTTESTER;
break;
case 1:
state = STATE_START_INPUTTESTERANALOG;
break;
case 2:
state = STATE_START_INPUTTESTERADVANCED;
break;
case 3:
state = STATE_START_BTNTEST;
break;
}
}
}
// As soon as vsync is detected start drawing screen updates
if (VBLANK_RISING)
{
char maxsize = (menu_count * 3) + 1;
if (menu_timer < maxsize)
{
char oy1 = ((menu_timer) / 2);
char oy2 = oy1 + ((menu_count % 2) ? 0 : 1);
char my = menu_my;
panel_shaded(menu_tx, my - oy1, menu_bx, my + oy2, 0xFF, 0b00110110, 0b00100100);
if (oy1 > 1)
{
fill(menu_tx + 1, my - (oy1 - 1), menu_bx - 1, my + (oy2 - 1), 0, 0);
fill_bgcolor(menu_tx + 1, my - (oy1 - 1), menu_bx - 1, my + (oy2 - 1), 0b00001001);
}
menu_timer++;
if (menu_timer == maxsize)
{
menu_dirty = true;
}
}
else
{
if (menu_dirty)
{
char ty = menu_my - ((menu_count * 3) / 2) + 1;
for (char m = 0; m < menu_count; m++)
{
if (menu_index == m)
{
panel_shaded(menu_tx + 1, ty, menu_bx - 1, ty + 2, 0b11111111, 0b10111111, 0b10110110);
write_string(menu_string[m], 0b11111111, menu_tx + 2, ty + 1);
}
else
{
panel_shaded(menu_tx + 1, ty, menu_bx - 1, ty + 2, 0b10111111, 0b10110110, 0b01100100);
write_string(menu_string[m], 0b10110110, menu_tx + 2, ty + 1);
}
ty += 3;
}
menu_dirty = false;
menu_ready = true;
}
}
}
}

815
src/os.c
View File

@@ -3,7 +3,7 @@
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0
Date: 2021-07-03
Date: 2021-07-12
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
@@ -22,782 +22,16 @@
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include "sys.c"
#include "ui.c"
#include "sys_custom.c"
#include "ps2.c"
bool hsync;
bool hsync_last;
bool vsync;
bool vsync_last;
// Application state
#define STATE_START_INPUTTESTER 0
#define STATE_INPUTTESTER 1
#define STATE_START_INPUTTESTERADVANCED 2
#define STATE_INPUTTESTERADVANCED 3
#define STATE_START_INPUTTESTERANALOG 4
#define STATE_INPUTTESTERANALOG 5
#define STATE_FADEOUT 8
#define STATE_START_FADEIN 9
#define STATE_FADEIN 10
#define STATE_START_ATTRACT 16
#define STATE_ATTRACT 17
#define STATE_START_GAME 24
#define STATE_GAME 25
char state = STATE_START_INPUTTESTER;
char nextstate = 0;
// SNEK variables
unsigned char movefreqinit = 14;
unsigned char movefreqdecfreq = 200;
unsigned char movefreqdectimer = 0;
unsigned char movefreq = 0;
unsigned char movetimer = 0;
signed int x = 20;
signed int y = 15;
signed char xd = 0;
signed char yd = 1;
signed char nxd = 0;
signed char nyd = 1;
unsigned int length = 0;
unsigned char playerchar = 83;
// Fade in/out variables
unsigned char fade = 0;
unsigned char fadetimer = 0;
unsigned char fadefreq = 4;
// Attract mode variables
unsigned char attractstate = 0;
// Input tester variables
unsigned char joystick_last[12];
signed char ax_last[6];
signed char ay_last[6];
unsigned char px_last[6];
signed char sx_toggle_last[6];
signed char sx_last[6];
unsigned long sx_pos[6];
unsigned char con_x; // Console cursor X position
unsigned char con_y; // Console cursor X position
unsigned char con_l = 2; // Console left edge X
unsigned char con_t = 20; // Console top edge Y
unsigned char con_r = 37; // Console right edge X
unsigned char con_b = 37; // Console bottom edge Y
bool con_cursor;
unsigned char con_cursortimer = 1;
unsigned char con_cursorfreq = 30;
char modeswitchtimer_select = 0;
char modeswitchtimer_start = 0;
// DPAD tracker
bool bdown_left = 0;
bool bdown_left_last = 0;
bool bdown_right = 0;
bool bdown_right_last = 0;
bool bdown_up = 0;
bool bdown_up_last = 0;
bool bdown_down = 0;
bool bdown_down_last = 0;
#define HISTORY_LENGTH 6
char history[HISTORY_LENGTH];
#define PAD_COUNT 2
#define BUTTON_COUNT 12
char pad_offset_x[PAD_COUNT] = {7, 7};
char pad_offset_y[PAD_COUNT] = {7, 16};
char button_name[BUTTON_COUNT][6] = {
"R",
"L",
"D",
"U",
"A",
"B",
"X",
"Y",
"L",
"R",
"Sel",
"Start"};
char button_x[BUTTON_COUNT] = {6, 2, 4, 4, 24, 22, 22, 20, 3, 23, 9, 13};
char button_y[BUTTON_COUNT] = {3, 3, 4, 2, 3, 4, 2, 3, 0, 0, 3, 3};
char analog_offset_x[PAD_COUNT] = {1, 20};
char analog_offset_y[PAD_COUNT] = {5, 5};
char analog_size = 18;
signed char analog_x[PAD_COUNT];
signed char analog_y[PAD_COUNT];
char analog_ratio = 256 / 17;
// Draw static elements for digital input test page
void page_inputtester_digital()
{
clear_chars(0);
page_border(0b00000111);
write_string("- MiSTer Input Tester -", 0b11100011, 8, 1);
write_string("Hold: Select=analog Start=advanced", 0b11100011, 3, 29);
// Draw pads
for (char j = 0; j < PAD_COUNT; j++)
{
write_stringf("JOY %d", 0xFF, pad_offset_x[j] - 5, pad_offset_y[j] + 3, j + 1);
draw_pad(pad_offset_x[j], pad_offset_y[j]);
}
}
// Draw static elements for analog input test page
void page_inputtester_analog()
{
clear_chars(0);
page_border(0b00000111);
write_string("- MiSTer Input Tester -", 0b11100011, 8, 1);
write_string("Hold: Select=digital Start=advanced", 0b11100011, 3, 29);
for (char j = 0; j < PAD_COUNT; j++)
{
write_stringf("ANALOG %d", 0xFF, analog_offset_x[j] + 5, analog_offset_y[j] - 1, j + 1);
draw_analog(analog_offset_x[j], analog_offset_y[j], analog_size, analog_size);
}
}
// Draw static elements for advanced input test page
void page_inputtester_advanced()
{
clear_chars(0);
page_border(0b00000111);
write_string("- MiSTer Input Tester -", 0b11100011, 8, 1);
write_string("Hold: Select=digital Start=analog", 0b11100011, 3, 29);
write_string("RLDUABXYLRsS", 0xFF, 7, 3);
write_string("AX", 0xFF, 22, 3);
write_string("AY", 0xFF, 27, 3);
write_string("POS", 0xFF, 7, 11);
write_string("SPD POS", 0xFF, 18, 11);
char label[5];
for (unsigned char j = 0; j < 6; j++)
{
sprintf(label, "JOY%d", j + 1);
write_string(label, 0xFF - (j * 2), 2, 4 + j);
sprintf(label, "PAD%d", j + 1);
write_string(label, 0xFF - (j * 2), 2, 12 + j);
sprintf(label, "SPN%d", j + 1);
write_string(label, 0xFF - (j * 2), 14, 12 + j);
}
write_string("CON", 0xFF, 2, 19);
}
void reset_inputstates()
{
modeswitchtimer_select = 0;
modeswitchtimer_start = 0;
for (char i = 0; i < 12; i++)
{
joystick_last[i] = 1;
}
for (char i = 0; i < 6; i++)
{
ax_last[i] = 1;
ay_last[i] = 1;
px_last[i] = 1;
sx_toggle_last[i] = 1;
sx_last[i] = 1;
sx_pos[i] = 0;
}
}
// Initialise digital inputtester state and draw static elements
void start_inputtester_digital()
{
state = STATE_INPUTTESTER;
// Draw page
page_inputtester_digital();
// Reset last states for inputs
reset_inputstates();
}
// Initialise analog inputtester state and draw static elements
void start_inputtester_analog()
{
state = STATE_INPUTTESTERANALOG;
// Draw page
page_inputtester_analog();
// Reset last states for inputs
reset_inputstates();
}
// Initialise advanced inputtester state and draw static elements
void start_inputtester_advanced()
{
state = STATE_INPUTTESTERADVANCED;
// Draw page
page_inputtester_advanced();
// Reset console cursor
con_x = con_l;
con_y = con_t;
// Reset last states for inputs
reset_inputstates();
}
// Initialise fadeout state
void start_fadeout()
{
state = STATE_FADEOUT;
fadetimer = fadefreq;
fade = 0;
}
// Initialise fadein state
void start_fadein()
{
state = STATE_FADEIN;
fadetimer = fadefreq;
fade = 15;
}
// Initialise attract state and draw static elements
void start_attract()
{
state = STATE_ATTRACT;
attractstate = 0;
clear_chars(0);
page_border(0b00000111);
write_string("SNEK", 0b00000111, 18, 0);
movefreq = 5;
movetimer = 1;
}
// Initialise attract state and draw static elements
void start_gameplay()
{
state = STATE_GAME;
length = 0;
x = 20;
y = 15;
xd = 0;
yd = 1;
nxd = 0;
nyd = 1;
clear_chars(0);
page_border(0b00000111);
write_string("SNEK", 0b00000111, 18, 0);
write_char(playerchar, 0xFF, x, y);
movefreq = movefreqinit;
movefreqdectimer = movefreqdecfreq;
movetimer = movefreq;
}
// Fade out state
void fadeout()
{
if (vsync && !vsync_last)
{
fadetimer--;
if (fadetimer == 0)
{
box(fade, fade, 39 - fade, 29 - fade, 127, 0b0000111);
fadetimer = fadefreq;
fade++;
if (fade == 16)
{
start_fadein();
}
}
}
}
// Fade in state
void fadein()
{
if (vsync && !vsync_last)
{
fadetimer--;
if (fadetimer == 0)
{
box(fade, fade, 39 - fade, 29 - fade, 0, 0b0000000);
fadetimer = fadefreq;
fade--;
if (fade == 0)
{
state = nextstate;
}
}
}
}
// Rotate DPAD direction history and push new entry
void pushhistory(char new)
{
for (char h = 1; h < HISTORY_LENGTH; h++)
{
history[h - 1] = history[h];
}
history[HISTORY_LENGTH - 1] = new;
}
// Track input history of P1 DPAD for secret codes!
void handle_codes()
{
bdown_up_last = bdown_up;
bdown_down_last = bdown_down;
bdown_left_last = bdown_left;
bdown_right_last = bdown_right;
bdown_up = CHECK_BIT(joystick[0], 3);
bdown_down = CHECK_BIT(joystick[0], 2);
bdown_left = CHECK_BIT(joystick[0], 1);
bdown_right = CHECK_BIT(joystick[0], 0);
if (!bdown_up && bdown_up_last)
{
pushhistory(1);
}
if (!bdown_down && bdown_down_last)
{
pushhistory(2);
}
if (!bdown_left && bdown_left_last)
{
pushhistory(3);
}
if (!bdown_right && bdown_right_last)
{
pushhistory(4);
}
// Check for SNEK code
if (history[0] == 1 && history[1] == 1 && history[2] == 2 && history[3] == 2 && history[4] == 3 && history[5] == 4)
{
nextstate = STATE_START_ATTRACT;
pushhistory(0);
start_fadeout();
return;
}
}
bool modeswitcher()
{
// Switch to advanced mode if start is held for 1 second
if (CHECK_BIT(joystick[8], 3))
{
modeswitchtimer_start++;
if (modeswitchtimer_start == 60)
{
if (state == STATE_INPUTTESTERADVANCED)
{
start_inputtester_analog();
}
else
{
start_inputtester_advanced();
}
return 1;
}
}
else
{
modeswitchtimer_start = 0;
}
// Switch between digital/analog mode if select is held for 1 second
if (CHECK_BIT(joystick[8], 2))
{
modeswitchtimer_select++;
if (modeswitchtimer_select == 60)
{
if (state == STATE_INPUTTESTER)
{
start_inputtester_analog();
}
else
{
start_inputtester_digital();
}
return 1;
}
}
else
{
modeswitchtimer_select = 0;
}
return 0;
}
// Digital input tester state
void inputtester_digital()
{
// Handle PS/2 inputs whenever possible to improve latency
handle_ps2();
// Handle secret code detection (joypad 1 directions)
if (hsync && !hsync_last)
{
handle_codes();
}
// As soon as vsync is detected start drawing screen updates
if (vsync && !vsync_last)
{
// Handle test mode switch
if (modeswitcher())
{
return;
}
// Draw control pad buttons
for (char joy = 0; joy < PAD_COUNT; joy++)
{
char index = joy * 32;
for (char button = 0; button < BUTTON_COUNT; button++)
{
char color = (button < 8 ? CHECK_BIT(joystick[index], button) : CHECK_BIT(joystick[index + 8], button - 8)) ? 0xFF : 0b10010010;
write_string(button_name[button], color, pad_offset_x[joy] + button_x[button], pad_offset_y[joy] + button_y[button]);
}
}
}
}
// Analog input tester state
void inputtester_analog()
{
// Handle PS/2 inputs whenever possible to improve latency
handle_ps2();
// Handle secret code detection (joypad 1 directions)
if (hsync && !hsync_last)
{
handle_codes();
}
// As soon as vsync is detected start drawing screen updates
if (vsync && !vsync_last)
{
// Handle test mode switch
if (modeswitcher())
{
return;
}
// Draw analog point
for (char j = 0; j < PAD_COUNT; j++)
{
char mx = analog_offset_x[j] + (analog_size / 2);
char my = analog_offset_y[j] + (analog_size / 2);
// Reset previous color
set_colour(color_analog_grid, analog_x[j] + mx, analog_y[j] + my);
signed char ax = analog[(j * 16)];
signed char ay = analog[(j * 16) + 8];
analog_x[j] = ax / analog_ratio;
analog_y[j] = ay / analog_ratio;
// Set new color
set_colour(0xFF, analog_x[j] + mx, analog_y[j] + my);
write_stringfs("%4d", 0xFF, analog_offset_x[j], analog_offset_y[j] + analog_size + 1, ax);
write_stringfs("%4d", 0xFF, analog_offset_x[j] + 5, analog_offset_y[j] + analog_size + 1, ay);
}
}
}
// Advanced input tester state
void inputtester_advanced()
{
// Handle PS/2 inputs whenever possible to improve latency
handle_ps2();
// Handle secret code detection (joypad 1 directions)
if (hsync && !hsync_last)
{
handle_codes();
}
// As soon as vsync is detected start drawing screen updates
if (vsync && !vsync_last)
{
// Handle test mode switch
if (modeswitcher())
{
return;
}
// Draw joystick inputs (only update each byte if value has changed)
for (char inputindex = 0; inputindex < 6; inputindex++)
{
char m = 0b00000001;
char x = 6;
char y = 4 + inputindex;
char inputoffset = (inputindex * 32);
char lastoffset = (inputindex * 2);
for (char b = 0; b < 2; b++)
{
char index = (b * 8) + inputoffset;
char lastindex = b + lastoffset;
char joy = joystick[index];
if (joy != joystick_last[lastindex])
{
m = 0b00000001;
char bytes = (b == 0 ? 8 : 4);
for (char i = 0; i < bytes; i++)
{
x++;
write_char((joy & m) ? asc_1 : asc_0, 0xFF, x, y);
m <<= 1;
}
}
else
{
x += 8;
}
joystick_last[lastindex] = joy;
}
// Draw analog inputs (only update if value has changed)
signed char ax = analog[(inputindex * 16)];
signed char ay = analog[(inputindex * 16) + 8];
if (ax != ax_last[inputindex] || ay != ay_last[inputindex])
{
char stra[10];
sprintf(stra, "%4d %4d", ax, ay);
write_string(stra, 0xFF, 20, 4 + inputindex);
}
ax_last[inputindex] = ax;
ay_last[inputindex] = ay;
// Draw paddle inputs (only update if value has changed)
unsigned char px = paddle[(inputindex * 8)];
if (px != px_last[inputindex])
{
char strp[5];
sprintf(strp, "%4d", px);
write_string(strp, 0xFF, 6, 12 + inputindex);
}
px_last[inputindex] = px;
// Draw spinner inputs (only update when update clock changes)
bool sx_toggle = CHECK_BIT(spinner[(inputindex * 16) + 8], 0);
signed char sx = spinner[(inputindex * 16)];
if (sx_toggle != sx_toggle_last[inputindex])
{
sx_pos[inputindex] += sx;
write_stringf("%4d", 0xFF, 22, 12 + inputindex, sx_pos[inputindex] / 8);
}
else
{
if (sx == 1 || sx == -1)
{
sx = 0;
}
}
if (sx_last[inputindex] != sx)
{
write_stringfs("%4d", 0xFF, 17, 12 + inputindex, sx);
}
sx_last[inputindex] = sx;
sx_toggle_last[inputindex] = sx_toggle;
}
// Keyboard test console
if (kbd_buffer_len > 0)
{
// Clear existing cursor if visible
if (con_cursor)
{
write_char(' ', 0xFF, con_x, con_y);
}
// Write characters in buffer
for (char k = 0; k < kbd_buffer_len; k++)
{
if (kbd_buffer[k] == '\n')
{
// New line
con_x = con_l;
con_y++;
if (con_y > con_b)
{
// Wrap to top
con_y = con_t;
}
}
else if (kbd_buffer[k] == '\b')
{
// Backspace - only if not at beginning of line
if (con_x > con_l)
{
con_x--;
// Clear existing character
write_char(' ', 0xFF, con_x, con_y);
}
}
else
{
// Write character
write_char(kbd_buffer[k], 0xFF, con_x, con_y);
// Move cursor right
con_x++;
if (con_x > con_r)
{
// New line
con_x = con_l;
con_y++;
if (con_y > con_b)
{
// Wrap to top
con_y = con_t;
}
}
}
}
// Clear buffer and enable cursor
kbd_buffer_len = 0;
con_cursor = 0;
con_cursortimer = 1;
}
// Cursor blink timer
con_cursortimer--;
if (con_cursortimer <= 0)
{
con_cursor = !con_cursor;
con_cursortimer = con_cursorfreq;
write_char(con_cursor ? '|' : ' ', 0xFF, con_x, con_y);
}
}
}
// SNEK - gameplay state
void gameplay()
{
if (hsync && !hsync_last)
{
if (yd != 1 && joystick[0] & 0b00001000) // up
{
nyd = -1;
nxd = 0;
}
if (yd != -1 && joystick[0] & 0b00000100) // down
{
nyd = 1;
nxd = 0;
}
if (xd != 1 && joystick[0] & 0b00000010) // left
{
nxd = -1;
nyd = 0;
}
if (xd != -1 && joystick[0] & 0b00000001) //right
{
nxd = 1;
nyd = 0;
}
if (CHECK_BIT(joystick[8], 2)) // select to quit
{
start_inputtester_advanced();
return;
}
}
if (vsync && !vsync_last)
{
movetimer--;
if (movetimer == 0)
{
write_char(127, 0x66, x, y);
xd = nxd;
yd = nyd;
x += xd;
y += yd;
unsigned int p = (y * chram_cols) + x;
if (chram[p] > 0)
{
nextstate = STATE_START_ATTRACT;
start_fadeout();
return;
}
length++;
write_char(playerchar, 0xFF, x, y);
movetimer = movefreq;
char score[5];
sprintf(score, "%4d", length);
write_string(score, 0xFF, 35, 0);
}
movefreqdectimer--;
if (movefreqdectimer == 0)
{
movefreqdectimer = movefreqdecfreq;
if (movefreq > 3)
{
movefreq--;
}
char str_movefreq[3];
sprintf(str_movefreq, "%4d", movefreq);
write_string(str_movefreq, 0xFF, 35, 29);
}
}
}
// SNEK - attract state
void attract()
{
if (hsync && !hsync_last)
{
if (CHECK_BIT(joystick[8], 3)) // start to start
{
start_gameplay();
return;
}
if (CHECK_BIT(joystick[8], 2)) // select to quit
{
start_inputtester_advanced();
return;
}
}
if (vsync && !vsync_last)
{
movetimer--;
if (movetimer == 0)
{
attractstate = !attractstate;
write_string("PRESS START", attractstate == 0 ? 0x00 : 0xFF, 16, 15);
movetimer = movefreq;
}
}
}
#include "ui.c"
#include "ui_custom.c"
#include "menu.c"
#include "inputtester.c"
#include "snek.c"
#include "fader.c"
// Main entry and state machine
void main()
@@ -807,6 +41,8 @@ void main()
{
hsync = input0 & 0x80;
vsync = input0 & 0x40;
hblank = input0 & 0x20;
vblank = input0 & 0x10;
switch (state)
{
case STATE_START_INPUTTESTER:
@@ -830,6 +66,20 @@ void main()
inputtester_analog();
break;
case STATE_START_BTNTEST:
start_btntest();
break;
case STATE_BTNTEST:
btntest();
break;
case STATE_START_MENU:
start_menu();
break;
case STATE_MENU:
menu();
break;
case STATE_FADEOUT:
fadeout();
break;
@@ -841,20 +91,27 @@ void main()
start_attract();
break;
case STATE_ATTRACT:
attract();
snek_attract();
break;
case STATE_START_GAME:
case STATE_START_GAME_SNEK:
start_gameplay();
break;
case STATE_GAME:
gameplay();
case STATE_GAME_SNEK:
snek_gameplay();
break;
default:
// Start default state
start_inputtester_digital();
//start_inputtester_advanced();
//start_inputtester_analog();
//start_btntest();
break;
}
hsync_last = hsync;
vsync_last = vsync;
hblank_last = hblank;
vblank_last = vblank;
}
}

View File

@@ -1,5 +1,5 @@
/*============================================================================
MiSTer test harness OS - PS/2 interface functions
Aznable OS - PS/2 interface functions
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0

181
src/snek.c Normal file
View File

@@ -0,0 +1,181 @@
/*============================================================================
Input Test - Snek mini-game
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0
Date: 2021-07-12
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program. If not, see <http://www.gnu.org/licenses/>.
===========================================================================*/
#pragma once
#include "sys.c"
#include "fader.c"
// SNEK constants
#define movefreqinit 14
#define movefreqdecfreq 200
#define playerchar 83
// SNEK variables
unsigned char movefreqdectimer = 0;
unsigned char movefreq = 0;
unsigned char movetimer = 0;
signed int x = 20;
signed int y = 15;
signed char xd = 0;
signed char yd = 1;
signed char nxd = 0;
signed char nyd = 1;
unsigned int length = 0;
// Attract mode variables
unsigned char attractstate = 0;
// Initialise attract state and draw static elements
void start_attract()
{
state = STATE_ATTRACT;
attractstate = 0;
clear_chars(0);
page_border(0b00000111);
write_string("SNEK", 0b00000111, 18, 0);
movefreq = 5;
movetimer = 1;
}
// Initialise attract state and draw static elements
void start_gameplay()
{
state = STATE_GAME_SNEK;
length = 0;
x = 20;
y = 15;
xd = 0;
yd = 1;
nxd = 0;
nyd = 1;
clear_chars(0);
page_border(0b00000111);
write_string("SNEK", 0b00000111, 18, 0);
write_char(playerchar, 0xFF, x, y);
movefreq = movefreqinit;
movefreqdectimer = movefreqdecfreq;
movetimer = movefreq;
}
// SNEK - gameplay state
void snek_gameplay()
{
if (HBLANK_RISING)
{
if (yd != 1 && joystick[0] & 0b00001000) // up
{
nyd = -1;
nxd = 0;
}
if (yd != -1 && joystick[0] & 0b00000100) // down
{
nyd = 1;
nxd = 0;
}
if (xd != 1 && joystick[0] & 0b00000010) // left
{
nxd = -1;
nyd = 0;
}
if (xd != -1 && joystick[0] & 0b00000001) //right
{
nxd = 1;
nyd = 0;
}
if (CHECK_BIT(joystick[8], 2)) // select to quit
{
state = 0;
return;
}
}
if (VBLANK_RISING)
{
movetimer--;
if (movetimer == 0)
{
write_char(127, 0x66, x, y);
xd = nxd;
yd = nyd;
x += xd;
y += yd;
unsigned int p = (y * chram_cols) + x;
if (chram[p] > 0)
{
nextstate = STATE_START_ATTRACT;
start_fadeout();
return;
}
length++;
write_char(playerchar, 0xFF, x, y);
movetimer = movefreq;
char score[5];
sprintf(score, "%4d", length);
write_string(score, 0xFF, 35, 0);
}
movefreqdectimer--;
if (movefreqdectimer == 0)
{
movefreqdectimer = movefreqdecfreq;
if (movefreq > 3)
{
movefreq--;
}
char str_movefreq[3];
sprintf(str_movefreq, "%4d", movefreq);
write_string(str_movefreq, 0xFF, 35, 29);
}
}
}
// SNEK - attract state
void snek_attract()
{
if (HBLANK_RISING)
{
if (CHECK_BIT(joystick[8], 3)) // start to start
{
start_gameplay();
return;
}
if (CHECK_BIT(joystick[8], 2)) // select to quit
{
state = 0;
return;
}
}
if (VBLANK_RISING)
{
movetimer--;
if (movetimer == 0)
{
attractstate = !attractstate;
write_string("PRESS START", attractstate == 0 ? 0x00 : 0xFF, 16, 15);
movetimer = movefreq;
}
}
}

View File

@@ -1,9 +1,9 @@
/*============================================================================
MiSTer test harness OS - System interface functions
Aznable OS - System interface functions
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0
Date: 2021-07-03
Date: 2021-07-12
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
@@ -25,21 +25,47 @@
#include <stdbool.h>
#include <string.h>
// Memory maps
// Memory mapped IO
// - Inputs
unsigned char __at(0x6000) input0;
unsigned char __at(0x7000) joystick[24];
unsigned char __at(0x7100) analog[12];
unsigned char __at(0x7200) paddle[6];
unsigned char __at(0x7300) spinner[12];
unsigned char __at(0x7400) ps2_key[2];
unsigned char __at(0x7500) ps2_mouse[6];
unsigned char __at(0x7100) analog_l[12];
unsigned char __at(0x7200) analog_r[12];
unsigned char __at(0x7300) paddle[6];
unsigned char __at(0x7400) spinner[12];
unsigned char __at(0x7500) ps2_key[2];
unsigned char __at(0x7600) ps2_mouse[6];
unsigned char __at(0x7700) timestamp[5];
unsigned char __at(0x7800) timer[2];
// - Graphics RAM
unsigned char __at(0x8000) chram[2048];
unsigned char __at(0x8800) colram[2048];
unsigned char __at(0x8800) fgcolram[2048];
unsigned char __at(0x9000) bgcolram[2048];
// Character map
const unsigned char chram_cols = 64;
const unsigned char chram_rows = 32;
unsigned int chram_size;
// Hardware inputs
bool hsync;
bool hsync_last;
bool vsync;
bool vsync_last;
bool hblank;
bool hblank_last;
bool vblank;
bool vblank_last;
// Macros
#define CHECK_BIT(var, pos) ((var) & (1 << (pos)))
#define CHECK_BIT(var, pos) ((var) & (1 << (pos)))
#define SET_BIT(var,pos) ((var) |= (1 << (pos)))
#define CLEAR_BIT(var,pos) ((var) &= ~(1 << (pos)))
#define VBLANK_RISING (vblank && !vblank_last)
#define VSYNC_RISING (vsync && !vsync_last)
#define HBLANK_RISING (hblank && !hblank_last)
#define HSYNC_RISING (hsync && !hsync_last)
// Application state
char state = 0;
char nextstate = 0;

91
src/sys_custom.c Normal file
View File

@@ -0,0 +1,91 @@
/*============================================================================
Input Test - Custom system functions
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0
Date: 2021-07-12
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program. If not, see <http://www.gnu.org/licenses/>.
===========================================================================*/
#pragma once
#include "sys.c"
// Application states
#define STATE_START_INPUTTESTER 1
#define STATE_INPUTTESTER 2
#define STATE_START_INPUTTESTERADVANCED 3
#define STATE_INPUTTESTERADVANCED 4
#define STATE_START_INPUTTESTERANALOG 5
#define STATE_INPUTTESTERANALOG 6
#define STATE_START_BTNTEST 7
#define STATE_BTNTEST 8
#define STATE_START_MENU 9
#define STATE_MENU 10
#define STATE_FADEOUT 20
#define STATE_START_FADEIN 21
#define STATE_FADEIN 22
#define STATE_START_ATTRACT 30
#define STATE_ATTRACT 31
#define STATE_START_GAME_SNEK 40
#define STATE_GAME_SNEK 41
#define GET_TIMER ((unsigned short)timer[8] << 8) | (unsigned char)timer[0]
// DPAD tracker
bool input_left = 0;
bool input_left_last = 0;
bool input_right = 0;
bool input_right_last = 0;
bool input_up = 0;
bool input_up_last = 0;
bool input_down = 0;
bool input_down_last = 0;
bool input_start;
bool input_start_last = 0;
bool input_select;
bool input_select_last = 0;
bool input_a;
bool input_a_last = 0;
bool input_b;
bool input_b_last = 0;
// Track joypad 1 directions and start for menu control
void basic_input()
{
input_up_last = input_up;
input_down_last = input_down;
input_left_last = input_left;
input_right_last = input_right;
input_start_last = input_start;
input_select_last = input_select;
input_a_last = input_a;
input_b_last = input_b;
input_up = CHECK_BIT(joystick[0], 3);
input_down = CHECK_BIT(joystick[0], 2);
input_left = CHECK_BIT(joystick[0], 1);
input_right = CHECK_BIT(joystick[0], 0);
input_start = CHECK_BIT(joystick[8], 3);
input_select = CHECK_BIT(joystick[8], 2);
input_a = CHECK_BIT(joystick[0], 4);
input_b = CHECK_BIT(joystick[0], 5);
}

265
src/ui.c
View File

@@ -1,9 +1,9 @@
/*============================================================================
MiSTer test harness OS - User interface functions
Aznable OS - User interface functions
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0
Date: 2021-07-03
Version: 1.1
Date: 2021-07-15
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
@@ -25,30 +25,51 @@
char asc_0 = 48;
char asc_1 = 49;
#define char_corner_round_tl 149
#define char_corner_round_tr 137
#define char_corner_round_bl 138
#define char_corner_round_br 139
#define char_line_h 131
#define char_line_v 130
#define char_t_up 177
#define char_dot 27
#define char_cross 155
// Set all character RAM to specified character
void clear_chars(char c)
{
for (unsigned int p = 0; p < chram_size; p++)
{
chram[p] = c;
fgcolram[p] = c;
bgcolram[p] = c;
}
}
// Set all character background colours to specified
void clear_bgcolor(char color)
{
for (unsigned int p = 0; p < chram_size; p++)
{
bgcolram[p] = color;
}
}
// Write string to character RAM
void write_string(const char *string, char color, unsigned int x, unsigned int y)
void write_string(const char *string, char color, unsigned char x, unsigned char y)
{
unsigned int p = (y * chram_cols) + x;
unsigned char l = strlen(string);
for (char c = 0; c < l; c++)
{
chram[p] = string[c];
colram[p] = color;
fgcolram[p] = color;
p++;
}
}
// Write formatted string to character RAM (signed char data)
void write_stringfs(const char *format, char color, unsigned int x, unsigned int y, signed char data)
void write_stringfs(const char *format, char color, unsigned char x, unsigned char y, signed char data)
{
unsigned int p = (y * chram_cols) + x;
char temp[30];
@@ -61,13 +82,13 @@ void write_stringfs(const char *format, char color, unsigned int x, unsigned int
return;
}
chram[p] = temp[c];
colram[p] = color;
fgcolram[p] = color;
p++;
}
}
// Write formatted string to character RAM (unsigned char data)
void write_stringf(const char *format, char color, unsigned int x, unsigned int y, char data)
void write_stringf(const char *format, char color, unsigned char x, unsigned char y, char data)
{
unsigned int p = (y * chram_cols) + x;
char temp[30];
@@ -80,28 +101,115 @@ void write_stringf(const char *format, char color, unsigned int x, unsigned int
return;
}
chram[p] = temp[c];
colram[p] = color;
fgcolram[p] = color;
p++;
}
}
// Write formatted string to character RAM (unsigned short data)
void write_stringf_ushort(const char *format, char color, unsigned char x, unsigned char y, unsigned short data)
{
unsigned int p = (y * chram_cols) + x;
char temp[40];
sprintf(temp, format, data);
unsigned char l = strlen(temp);
for (char c = 0; c < l; c++)
{
if (temp[c] == 0)
{
return;
}
chram[p] = temp[c];
fgcolram[p] = color;
p++;
}
}
// Write formatted string to character RAM (signed short data)
void write_stringf_short(const char *format, char color, unsigned char x, unsigned char y, short data)
{
unsigned int p = (y * chram_cols) + x;
char temp[40];
sprintf(temp, format, data);
unsigned char l = strlen(temp);
for (char c = 0; c < l; c++)
{
if (temp[c] == 0)
{
return;
}
chram[p] = temp[c];
fgcolram[p] = color;
p++;
}
}
// Write formatted string to character RAM (unsigned long data)
void write_stringf_ulong(const char *format, char color, unsigned char x, unsigned char y, unsigned long data)
{
unsigned int p = (y * chram_cols) + x;
char temp[40];
sprintf(temp, format, data);
unsigned char l = strlen(temp);
for (char c = 0; c < l; c++)
{
if (temp[c] == 0)
{
return;
}
chram[p] = temp[c];
fgcolram[p] = color;
p++;
}
}
// Write single char to character RAM and colour RAM
void write_char(unsigned char c, char color, unsigned int x, unsigned int y)
void write_char(unsigned char c, char color, unsigned char x, unsigned char y)
{
unsigned int p = (y * chram_cols) + x;
chram[p] = c;
colram[p] = color;
fgcolram[p] = color;
}
// Write row of consecutive chars to character RAM and colour RAM
void write_char_row(unsigned char c, char color, unsigned char x, unsigned char y, unsigned char count)
{
unsigned int p = (y * chram_cols) + x;
for (char b = 0; b < count; b++)
{
chram[p] = c;
fgcolram[p] = color;
p++;
}
}
// Set colour of single char
void set_colour(char color, unsigned int x, unsigned int y)
void set_fgcolour(char color, char x, char y)
{
unsigned int p = (y * chram_cols) + x;
colram[p] = color;
fgcolram[p] = color;
}
// Set background colour of single char
void set_bgcolour(char color, char x, char y)
{
unsigned int p = (y * chram_cols) + x;
bgcolram[p] = color;
}
// Write row of consecutive chars to character RAM and colour RAM
void write_bgcol_row(char color, unsigned char x, unsigned char y, unsigned char count)
{
unsigned int p = (y * chram_cols) + x;
for (char b = 0; b < count; b++)
{
bgcolram[p] = color;
p++;
}
}
// Write grouped bits to character RAM
void write_bits(char bits[], char multi, unsigned char first, unsigned char length, char color, unsigned int x, unsigned int y)
void write_bits(char bits[], char multi, unsigned char first, unsigned char length, char color, unsigned char x, unsigned char y)
{
for (char b = first; b < first + length; b++)
{
@@ -118,14 +226,14 @@ void write_bits(char bits[], char multi, unsigned char first, unsigned char leng
}
// Draw box outline with specified character
void box(unsigned int tx, unsigned int ty, unsigned int bx, unsigned int by, char c, char color)
void box(unsigned char tx, unsigned char ty, unsigned char bx, unsigned char by, char c, char color)
{
for (unsigned int x = tx; x <= bx; x++)
for (unsigned char x = tx; x <= bx; x++)
{
write_char(c, color, x, ty);
write_char(c, color, x, by);
}
for (unsigned int y = ty + 1; y < by; y++)
for (unsigned char y = ty + 1; y < by; y++)
{
write_char(c, color, tx, y);
write_char(c, color, bx, y);
@@ -135,30 +243,60 @@ void box(unsigned int tx, unsigned int ty, unsigned int bx, unsigned int by, cha
// Draw UI panel
void panel(char tx, char ty, char bx, char by, char color)
{
write_char(128, color, tx, ty);
write_char(130, color, bx, ty);
write_char(133, color, tx, by);
write_char(132, color, bx, by);
write_char(char_corner_round_tl, color, tx, ty);
write_char(char_corner_round_tr, color, bx, ty);
write_char(char_corner_round_bl, color, tx, by);
write_char(char_corner_round_br, color, bx, by);
for (char x = tx + 1; x < bx; x++)
{
write_char(129, color, x, ty);
write_char(129, color, x, by);
write_char(char_line_h, color, x, ty);
write_char(char_line_h, color, x, by);
}
for (char y = ty + 1; y < by; y++)
{
write_char(131, color, tx, y);
write_char(131, color, bx, y);
write_char(char_line_v, color, tx, y);
write_char(char_line_v, color, bx, y);
}
}
// Shaded panel
void panel_shaded(char tx, char ty, char bx, char by, char color_high, char color1, char color2)
{
write_char(char_corner_round_tl, color_high, tx, ty);
write_char(char_corner_round_tr, color1, bx, ty);
write_char(char_corner_round_bl, color1, tx, by);
write_char(char_corner_round_br, color2, bx, by);
for (char x = tx + 1; x < bx; x++)
{
write_char(char_line_h, color1, x, ty);
write_char(char_line_h, color2, x, by);
}
for (char y = ty + 1; y < by; y++)
{
write_char(char_line_v, color1, tx, y);
write_char(char_line_v, color2, bx, y);
}
}
void fill(char tx, char ty, char bx, char by, char c, char color)
{
for (char x = tx; x <= bx; x++)
for (char y = ty; y <= by; y++)
{
for (char y = ty; y <= by; y++)
{
write_char(c, color, x, y);
}
write_char_row(c, color, tx, y, (bx - tx) + 1);
}
}
void fill_bgcolor(char tx, char ty, char bx, char by, char bgcolor)
{
for (char y = ty; y <= by; y++)
{
write_bgcol_row(bgcolor, tx, y, (bx - tx) + 1);
}
}
void fill_bgcol(char tx, char ty, char bx, char by, char color)
{
for (char y = ty; y <= by; y++)
{
write_bgcol_row(color, tx, y, bx - tx);
}
}
@@ -168,65 +306,16 @@ void page_border(char color)
panel(0, 0, 39, 29, color);
}
char color_pad_outline = 0xFE;
// Draw game pad outline
void draw_pad(char xo, char yo)
void draw_charactermap()
{
// Outline
write_char(134, color_pad_outline, xo, yo + 1);
for (char x = 1; x < 26; x++)
char c = 94;
for (char y = 0; y < 29; y += 2)
{
write_char(135, color_pad_outline, xo + x, yo + 1);
for (char x = 0; x < 39; x += 4)
{
write_stringf("%d", 0xFF, x, y, c);
write_char(c, 0, x, y + 1);
c++;
}
}
write_char(136, color_pad_outline, xo + 26, yo + 1);
for (char y = 2; y < 5; y++)
{
write_char(137, color_pad_outline, xo, yo + y);
write_char(137, color_pad_outline, xo + 26, yo + y);
}
write_char(139, color_pad_outline, xo, yo + 5);
write_char(138, color_pad_outline, xo + 26, yo + 5);
write_char(138, color_pad_outline, xo + 8, yo + 5);
write_char(139, color_pad_outline, xo + 18, yo + 5);
write_char(134, color_pad_outline, xo + 8, yo + 4);
write_char(136, color_pad_outline, xo + 18, yo + 4);
for (char x = 1; x < 8; x++)
{
write_char(135, color_pad_outline, xo + x, yo + 5);
}
for (char x = 9; x < 18; x++)
{
write_char(135, color_pad_outline, xo + x, yo + 4);
}
for (char x = 19; x < 26; x++)
{
write_char(135, color_pad_outline, xo + x, yo + 5);
}
// Shoulders
write_char(134, color_pad_outline, xo + 1, yo);
write_char(136, color_pad_outline, xo + 5, yo);
write_char(134, color_pad_outline, xo + 21, yo);
write_char(136, color_pad_outline, xo + 25, yo);
}
char color_analog_grid = 0x23;
// Draw game pad outline
void draw_analog(char xo, char yo, char xs, char ys)
{
panel(xo, yo, xo + xs, yo + ys, 0xFF);
fill(xo + 1, yo + 1, xo + xs - 1, yo + ys - 1, 27, color_analog_grid);
char mx = xo + (xs / 2);
char my = yo + (ys / 2);
for (char x = xo + 1; x < xo + xs; x++)
{
write_char(129, color_analog_grid, x, my);
}
for (char y = yo + 1; y < yo + ys; y++)
{
write_char(131, color_analog_grid, mx, y);
}
write_char('+', color_analog_grid, mx, my);
}

111
src/ui_custom.c Normal file
View File

@@ -0,0 +1,111 @@
/*============================================================================
Input Test - Custom UI functions
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0
Date: 2021-07-12
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program. If not, see <http://www.gnu.org/licenses/>.
===========================================================================*/
#pragma once
#include <stdbool.h>
#define color_pad_outline 0xFE
void page_frame(bool showMenuButton, bool showContinueButton)
{
bool footer = showMenuButton || showContinueButton;
clear_chars(0);
write_string("MiSTer Input Tester", 0b11111111, 11, 1);
panel_shaded(0, 0, 39, 2, 0b00000111, 0b00000110, 0b00000100);
panel_shaded(0, 3, 39, footer ? 26 : 29, 0b10100100, 0b10100100, 0b01010010);
if (footer)
{
char buttons = showMenuButton && showContinueButton ? 2 : 1;
char x1 = buttons == 1 ? 39 : 19;
char m1 = buttons == 1 ? 20 : 10;
panel_shaded(0, 27, x1, 29, 0b11000000, 0b10000000, 0b01000000);
if (buttons == 2)
{
panel_shaded(x1 + 1, 27, 39, 29, 0b11000000, 0b10000000, 0b01000000);
}
if (showMenuButton)
{
write_string("Hold Select: Menu", 0b11011011, m1 - 9, 28);
m1 += 20;
}
if (showContinueButton)
{
write_string("Start: Continue", 0b11011011, m1 - 8, 28);
}
}
}
// Draw game pad outline
void draw_pad(char xo, char yo)
{
// Outline
write_char(char_corner_round_tl, color_pad_outline, xo, yo + 2);
write_char_row(char_line_h, color_pad_outline, xo + 1, yo + 2, 25);
write_char(char_corner_round_tr, color_pad_outline, xo + 26, yo + 2);
for (char y = 3; y < 8; y++)
{
write_char(char_line_v, color_pad_outline, xo, yo + y);
write_char(char_line_v, color_pad_outline, xo + 26, yo + y);
}
write_char(char_corner_round_bl, color_pad_outline, xo, yo + 8);
write_char(char_corner_round_br, color_pad_outline, xo + 26, yo + 8);
write_char(char_corner_round_br, color_pad_outline, xo + 8, yo + 8);
write_char(char_corner_round_bl, color_pad_outline, xo + 18, yo + 8);
write_char(char_corner_round_tl, color_pad_outline, xo + 8, yo + 7);
write_char(char_corner_round_tr, color_pad_outline, xo + 18, yo + 7);
write_char_row(char_line_h, color_pad_outline, xo + 1, yo + 8, 7);
write_char_row(char_line_h, color_pad_outline, xo + 9, yo + 7, 9);
write_char_row(char_line_h, color_pad_outline, xo + 19, yo + 8, 7);
// Shoulders
write_char(char_line_v, color_pad_outline, xo + 1, yo + 1);
write_char(char_t_up, color_pad_outline, xo + 1, yo + 2);
write_char(char_corner_round_tl, color_pad_outline, xo + 1, yo);
write_char_row(char_line_h, color_pad_outline, xo + 2, yo, 3);
write_char(char_line_v, color_pad_outline, xo + 5, yo + 1);
write_char(char_t_up, color_pad_outline, xo + 5, yo + 2);
write_char(char_corner_round_tr, color_pad_outline, xo + 5, yo);
write_char(char_line_v, color_pad_outline, xo + 21, yo + 1);
write_char(char_t_up, color_pad_outline, xo + 21, yo + 2);
write_char(char_corner_round_tl, color_pad_outline, xo + 21, yo);
write_char_row(char_line_h, color_pad_outline, xo + 22, yo, 3);
write_char(char_line_v, color_pad_outline, xo + 25, yo + 1);
write_char(char_t_up, color_pad_outline, xo + 25, yo + 2);
write_char(char_corner_round_tr, color_pad_outline, xo + 25, yo);
}
#define color_analog_grid 0x23
// Draw game pad outline
void draw_analog(char xo, char yo, char xs, char ys)
{
panel(xo, yo, xo + xs, yo + ys, 0xFF);
fill(xo + 1, yo + 1, xo + xs - 1, yo + ys - 1, char_dot, color_analog_grid);
char mx = xo + (xs / 2);
char my = yo + (ys / 2);
write_char_row(char_line_h, color_analog_grid, xo + 1, my, xs - 1);
for (char y = yo + 1; y < yo + ys; y++)
{
write_char(char_line_v, color_analog_grid, mx, y);
}
write_char(char_cross, color_analog_grid, mx, my);
}

View File

@@ -1732,7 +1732,7 @@ BEGIN
-- Triple buffering.
-- For intelaced video, half frames are updated independently
-- Input : Toggle buffer at end of input frame
o_freeze <= freeze;
o_freeze <= freeze;
o_inter <=i_inter; -- <ASYNC>
o_iendframe0<=i_endframe0; -- <ASYNC>
o_iendframe02<=o_iendframe0;
@@ -1746,7 +1746,12 @@ BEGIN
o_ibuf1<=buf_next(o_ibuf1,o_obuf1,o_freeze);
o_bufup1<='1';
END IF;
-- Output : Change framebuffer, and image properties, at VS falling edge
IF o_vsv(1)='1' AND o_vsv(0)='0' AND o_bufup0='1' THEN
o_obuf0<=buf_next(o_obuf0,o_ibuf0,o_freeze);
o_bufup0<='0';
END IF;
IF o_vsv(1)='1' AND o_vsv(0)='0' AND o_bufup1='1' THEN
o_obuf1<=buf_next(o_obuf1,o_ibuf1,o_freeze);
o_bufup1<='0';
@@ -1755,6 +1760,33 @@ BEGIN
o_hdown<=i_hdown; -- <ASYNC>
o_vdown<=i_vdown; -- <ASYNC>
END IF;
-- Simultaneous change of input and output framebuffers
IF o_vsv(1)='1' AND o_vsv(0)='0' AND
o_iendframe0='1' AND o_iendframe02='0' THEN
o_bufup0<='0';
o_obuf0<=o_ibuf0;
END IF;
IF o_vsv(1)='1' AND o_vsv(0)='0' AND
o_iendframe1='1' AND o_iendframe12='0' THEN
o_bufup1<='0';
o_obuf1<=o_ibuf1;
END IF;
-- Non-interlaced, use same buffer for even and odd lines
IF o_inter='0' THEN
o_ibuf1<=o_ibuf0;
o_obuf1<=o_obuf0;
END IF;
-- Triple buffer disabled
IF o_mode(3)='0' THEN
o_obuf0<=0;
o_obuf1<=0;
o_ibuf0<=0;
o_ibuf1<=0;
END IF;
-- Framebuffer mode.
IF o_fb_ena='1' THEN
o_ihsize<=o_fb_hsize;
@@ -1774,25 +1806,6 @@ BEGIN
o_stride<=to_unsigned(o_ihsize_temp2,14);
o_stride(NB_BURST-1 DOWNTO 0)<=(OTHERS =>'0');
END IF;
IF o_vsv(1)='1' AND o_vsv(0)='0' AND o_bufup0='1' THEN
o_obuf0<=buf_next(o_obuf0,o_ibuf0,o_freeze);
o_bufup0<='0';
END IF;
IF o_inter='0' THEN
o_ibuf1<=o_ibuf0;
o_obuf1<=o_obuf0;
END IF;
-- Triple buffer disabled
IF o_mode(3)='0' THEN
o_obuf0<=0;
o_obuf1<=0;
o_ibuf0<=0;
o_ibuf1<=0;
END IF;
------------------------------------------------------
o_hmode<=o_mode;
IF o_hdown='1' AND DOWNSCALE THEN

View File

@@ -24,8 +24,10 @@
// Use buffer to access SD card. It's time-critical part.
//
// WIDE=1 for 16 bit file I/O
// VDNUM 1-4
module hps_io #(parameter CONF_STR, CONF_STR_BRAM=1, PS2DIV=0, WIDE=0, VDNUM=1, PS2WE=0)
// VDNUM 1..4
// BLKSZ 0..7: 0 = 128, 1 = 256, 2 = 512(default), .. 7 = 16384
//
module hps_io #(parameter CONF_STR, CONF_STR_BRAM=1, PS2DIV=0, WIDE=0, VDNUM=1, BLKSZ=2, PS2WE=0)
(
input clk_sys,
inout [45:0] HPS_BUS,
@@ -39,12 +41,19 @@ module hps_io #(parameter CONF_STR, CONF_STR_BRAM=1, PS2DIV=0, WIDE=0, VDNUM=1,
output reg [31:0] joystick_5,
// analog -127..+127, Y: [15:8], X: [7:0]
output reg [15:0] joystick_analog_0,
output reg [15:0] joystick_analog_1,
output reg [15:0] joystick_analog_2,
output reg [15:0] joystick_analog_3,
output reg [15:0] joystick_analog_4,
output reg [15:0] joystick_analog_5,
output reg [15:0] joystick_l_analog_0,
output reg [15:0] joystick_l_analog_1,
output reg [15:0] joystick_l_analog_2,
output reg [15:0] joystick_l_analog_3,
output reg [15:0] joystick_l_analog_4,
output reg [15:0] joystick_l_analog_5,
output reg [15:0] joystick_r_analog_0,
output reg [15:0] joystick_r_analog_1,
output reg [15:0] joystick_r_analog_2,
output reg [15:0] joystick_r_analog_3,
output reg [15:0] joystick_r_analog_4,
output reg [15:0] joystick_r_analog_5,
// paddle 0..255
output reg [7:0] paddle_0,
@@ -83,7 +92,8 @@ module hps_io #(parameter CONF_STR, CONF_STR_BRAM=1, PS2DIV=0, WIDE=0, VDNUM=1,
output reg [63:0] img_size, // size of image in bytes. valid only for active bit in img_mounted
// SD block level access
input [31:0] sd_lba,
input [31:0] sd_lba[VDNUM],
input [5:0] sd_blk_cnt[VDNUM], // number of blocks-1, total size ((sd_blk_cnt+1)*(1<<(BLKSZ+7))) must be <= 16384!
input [VD:0] sd_rd,
input [VD:0] sd_wr,
output reg [VD:0] sd_ack,
@@ -91,9 +101,8 @@ module hps_io #(parameter CONF_STR, CONF_STR_BRAM=1, PS2DIV=0, WIDE=0, VDNUM=1,
// SD byte level access. Signals for 2-PORT altsyncram.
output reg [AW:0] sd_buff_addr,
output reg [DW:0] sd_buff_dout,
input [DW:0] sd_buff_din,
input [DW:0] sd_buff_din[VDNUM],
output reg sd_buff_wr,
input [15:0] sd_req_type,
// ARM -> FPGA download
output reg ioctl_download = 0, // signal indicating an active download
@@ -102,6 +111,7 @@ module hps_io #(parameter CONF_STR, CONF_STR_BRAM=1, PS2DIV=0, WIDE=0, VDNUM=1,
output reg [26:0] ioctl_addr, // in WIDE mode address will be incremented by 2
output reg [DW:0] ioctl_dout,
output reg ioctl_upload = 0, // signal indicating an active upload
input ioctl_upload_req,
input [DW:0] ioctl_din,
output reg ioctl_rd,
output reg [31:0] ioctl_file_ext,
@@ -154,7 +164,7 @@ assign EXT_BUS[31:16] = HPS_BUS[31:16];
assign EXT_BUS[35:33] = HPS_BUS[35:33];
localparam DW = (WIDE) ? 15 : 7;
localparam AW = (WIDE) ? 7 : 8;
localparam AW = (WIDE) ? 12 : 13;
localparam VD = VDNUM-1;
wire io_strobe= HPS_BUS[33];
@@ -177,22 +187,18 @@ assign forced_scandoubler = cfg[4];
//cfg[5] - ypbpr handled in sys_top
assign direct_video = cfg[10];
// command byte read by the io controller
wire [15:0] sd_cmd =
{
2'b00,
(VDNUM>=4) ? sd_wr[3] : 1'b0,
(VDNUM>=3) ? sd_wr[2] : 1'b0,
(VDNUM>=2) ? sd_wr[1] : 1'b0,
reg [3:0] sdn;
reg [3:0] sd_rrb = 0;
always_comb begin
int n, i;
(VDNUM>=4) ? sd_rd[3] : 1'b0,
(VDNUM>=3) ? sd_rd[2] : 1'b0,
(VDNUM>=2) ? sd_rd[1] : 1'b0,
4'h5, 1'b0, 1'b0,
sd_wr[0],
sd_rd[0]
};
sdn = 0;
for(i = VDNUM - 1; i >= 0; i = i - 1) begin
n = i + sd_rrb;
if(n >= VDNUM) n = n - VDNUM;
if(sd_wr[n] | sd_rd[n]) sdn = n[3:0];
end
end
/////////////////////////////////////////////////////////
@@ -240,7 +246,8 @@ wire pressed = (ps2_key_raw[15:8] != 8'hf0);
wire extended = (~pressed ? (ps2_key_raw[23:16] == 8'he0) : (ps2_key_raw[15:8] == 8'he0));
reg [MAX_W:0] byte_cnt;
wire [7:0] disk = 4'd1 << (io_din[10:8]-1'd1);
reg [3:0] sdn_ack;
wire [15:0] disk = 16'd1 << io_din[11:8];
always@(posedge clk_sys) begin : uio_block
reg [15:0] cmd;
@@ -251,16 +258,22 @@ always@(posedge clk_sys) begin : uio_block
reg [3:0] stflg = 0;
reg [63:0] status_req;
reg old_status_set = 0;
reg old_upload_req = 0;
reg upload_req = 0;
reg old_info = 0;
reg [7:0] info_n = 0;
reg [15:0] tmp1;
reg [7:0] tmp2;
reg [3:0] sdn_r;
old_status_set <= status_set;
if(~old_status_set & status_set) begin
stflg <= stflg + 1'd1;
status_req <= status_in;
end
old_upload_req <= ioctl_upload_req;
if(~old_upload_req & ioctl_upload_req) upload_req <= 1;
old_info <= info_req;
if(~old_info & info_req) info_n <= info;
@@ -299,14 +312,16 @@ always@(posedge clk_sys) begin : uio_block
cmd <= io_din;
casex(io_din)
'hX17,
'hX18: sd_ack <= VD ? disk[VD:0] : 1'd1;
'h29: io_dout <= {4'hA, stflg};
'h2B: io_dout <= 1;
'h2F: io_dout <= 1;
'h32: io_dout <= gamma_bus[21];
'h36: begin io_dout <= info_n; info_n <= 0; end
'h39: io_dout <= 1;
'h16: begin io_dout <= {1'b1, sd_blk_cnt[sdn], BLKSZ[2:0], sdn, sd_wr[sdn], sd_rd[sdn]}; sdn_r <= sdn; end
'h0X17,
'h0X18: begin sd_ack <= disk[VD:0]; sdn_ack <= io_din[11:8]; end
'h29: io_dout <= {4'hA, stflg};
'h2B: io_dout <= 1;
'h2F: io_dout <= 1;
'h32: io_dout <= gamma_bus[21];
'h36: begin io_dout <= info_n; info_n <= 0; end
'h39: io_dout <= 1;
'h3C: if(upload_req) begin io_dout <= 1; upload_req <= 0; end
endcase
sd_buff_addr <= 0;
@@ -358,39 +373,38 @@ always@(posedge clk_sys) begin : uio_block
'h14: if(byte_cnt <= STRLEN) io_dout[7:0] <= conf_byte;
// reading sd card status
'h16: if(!byte_cnt[MAX_W:3]) begin
case(byte_cnt[2:0])
1: io_dout <= sd_cmd;
2: io_dout <= sd_lba[15:0];
3: io_dout <= sd_lba[31:16];
4: io_dout <= sd_req_type;
'h16: if(!byte_cnt[MAX_W:2]) begin
case(byte_cnt[1:0])
1: sd_rrb <= (sd_rrb == VD) ? 4'd0 : (sd_rrb + 1'd1);
2: io_dout <= sd_lba[sdn_r][15:0];
3: io_dout <= sd_lba[sdn_r][31:16];
endcase
end
// send sector IO -> FPGA
// flag that download begins
'hX17: begin
'h0X17: begin
sd_buff_dout <= io_din[DW:0];
b_wr <= 1;
end
// reading sd card write data
'hX18: begin
'h0X18: begin
if(~&sd_buff_addr) sd_buff_addr <= sd_buff_addr + 1'b1;
io_dout <= sd_buff_din;
io_dout <= sd_buff_din[sdn_ack];
end
// joystick analog
// joystick left analog
'h1a: if(!byte_cnt[MAX_W:2]) begin
case(byte_cnt[1:0])
1: {pdsp_idx,stick_idx} <= io_din[7:0]; // first byte is joystick index
2: case(stick_idx)
0: joystick_analog_0 <= io_din;
1: joystick_analog_1 <= io_din;
2: joystick_analog_2 <= io_din;
3: joystick_analog_3 <= io_din;
4: joystick_analog_4 <= io_din;
5: joystick_analog_5 <= io_din;
0: joystick_l_analog_0 <= io_din;
1: joystick_l_analog_1 <= io_din;
2: joystick_l_analog_2 <= io_din;
3: joystick_l_analog_3 <= io_din;
4: joystick_l_analog_4 <= io_din;
5: joystick_l_analog_5 <= io_din;
15: case(pdsp_idx)
0: paddle_0 <= io_din[7:0];
1: paddle_1 <= io_din[7:0];
@@ -409,6 +423,21 @@ always@(posedge clk_sys) begin : uio_block
endcase
end
// joystick right analog
'h3d: if(!byte_cnt[MAX_W:2]) begin
case(byte_cnt[1:0])
1: stick_idx <= io_din[3:0]; // first byte is joystick index
2: case(stick_idx)
0: joystick_r_analog_0 <= io_din;
1: joystick_r_analog_1 <= io_din;
2: joystick_r_analog_2 <= io_din;
3: joystick_r_analog_3 <= io_din;
4: joystick_r_analog_4 <= io_din;
5: joystick_r_analog_5 <= io_din;
endcase
endcase
end
// notify image selection
'h1c: begin
img_mounted <= io_din[VD:0] ? io_din[VD:0] : 1'b1;

View File

@@ -1,10 +1,10 @@
`timescale 1ns / 1ps
/*============================================================================
MiSTer test harness - Verilator emu module
Input Test - Verilator emu module
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 0.1
Date: 2021-06-29
Version: 1.0
Date: 2021-07-12
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
@@ -32,12 +32,19 @@ module emu (
input [31:0] joystick_4,
input [31:0] joystick_5,
input [15:0] joystick_analog_0,
input [15:0] joystick_analog_1,
input [15:0] joystick_analog_2,
input [15:0] joystick_analog_3,
input [15:0] joystick_analog_4,
input [15:0] joystick_analog_5,
input [15:0] joystick_l_analog_0,
input [15:0] joystick_l_analog_1,
input [15:0] joystick_l_analog_2,
input [15:0] joystick_l_analog_3,
input [15:0] joystick_l_analog_4,
input [15:0] joystick_l_analog_5,
input [15:0] joystick_r_analog_0,
input [15:0] joystick_r_analog_1,
input [15:0] joystick_r_analog_2,
input [15:0] joystick_r_analog_3,
input [15:0] joystick_r_analog_4,
input [15:0] joystick_r_analog_5,
input [7:0] paddle_0,
input [7:0] paddle_1,
@@ -61,6 +68,9 @@ module emu (
input [24:0] ps2_mouse,
input [15:0] ps2_mouse_ext, // 15:8 - reserved(additional buttons), 7:0 - wheel movements
// [31:0] - seconds since 1970-01-01 00:00:00, [32] - toggle with every change
input [32:0] timestamp,
output [7:0] VGA_R,
output [7:0] VGA_G,
output [7:0] VGA_B,
@@ -84,8 +94,8 @@ wire ce_pix;
jtframe_cen24 divider
(
.clk(clk_sys),
//.cen12(ce_pix), // <-- dodgy video speed for faster simulation, will cause bearable char map corruption
.cen4(ce_pix) // <-- correct video speed
.cen12(ce_pix), // <-- dodgy video speed for faster simulation, will cause bearable char map corruption
//.cen4(ce_pix) // <-- correct video speed
);
/* verilator lint_on PINMISSING */
@@ -106,11 +116,13 @@ system system(
.dn_index(ioctl_index),
.joystick({joystick_5,joystick_4,joystick_3,joystick_2,joystick_1,joystick_0}),
.analog({joystick_analog_5,joystick_analog_4,joystick_analog_3,joystick_analog_2,joystick_analog_1,joystick_analog_0}),
.analog_l({joystick_l_analog_5,joystick_l_analog_4,joystick_l_analog_3,joystick_l_analog_2,joystick_l_analog_1,joystick_l_analog_0}),
.analog_r({joystick_r_analog_5,joystick_r_analog_4,joystick_r_analog_3,joystick_r_analog_2,joystick_r_analog_1,joystick_r_analog_0}),
.paddle({paddle_5,paddle_4,paddle_3,paddle_2,paddle_1,paddle_0}),
.spinner({7'b0,spinner_5,7'b0,spinner_4,7'b0,spinner_3,7'b0,spinner_2,7'b0,spinner_1,7'b0,spinner_0}),
.ps2_key(ps2_key),
.ps2_mouse({ps2_mouse_ext,7'b0,ps2_mouse})
.ps2_mouse({ps2_mouse_ext,7'b0,ps2_mouse}),
.timestamp(timestamp)
);
endmodule

View File

@@ -10,6 +10,7 @@
#define WIN32
#include <dinput.h>
#endif
#include <chrono>
#include "sim_console.h"
#include "sim_bus.h"
@@ -45,7 +46,7 @@ const int input_b = 5;
const int input_x = 6;
const int input_y = 7;
const int input_l = 8;
const int input_r= 9;
const int input_r = 9;
const int input_select = 10;
const int input_start = 11;
@@ -69,15 +70,30 @@ int multi_step_amount = 1024;
// --------------
Vemu* top = NULL;
vluint64_t main_time = 0; // Current simulation time.
double sc_time_stamp() { // Called by $time in Verilog.
vluint64_t main_time = 0; // Current simulation time.
vluint32_t timestamp = 0; // Simulated Unix timestamp.
vluint16_t timestamp_ticksperms = 24000; // Number of simulation ticks per simulated millisecond
vluint16_t timestamp_ticks = 0; // Ticks left until next ms
unsigned short timestamp_updatefreq = 5000; // Only update sim every 5 seconds
unsigned short timestamp_update = 0; // Ms to next update.
bool timestamp_clock = 1; // Timestamp update clock
double sc_time_stamp() { // Called by $time in Verilog.
return main_time;
}
SimClock clk_sys(1);
long GetTime() {
return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
}
void resetSim() {
main_time = 0;
timestamp = GetTime();
top->reset = 1;
clk_sys.Reset();
}
@@ -94,6 +110,24 @@ int verilate() {
// Clock dividers
clk_sys.Tick();
// Increment timestamp
timestamp_ticks ++;
if (timestamp_ticks >= timestamp_ticksperms) {
timestamp_ticks -= timestamp_ticksperms;
timestamp++;
top->timestamp = timestamp;
timestamp_clock = !timestamp_clock;
if (timestamp_clock) {
timestamp_update--;
if (timestamp_update <= 0) {
top->timestamp |= ((uint64_t)1) << 32;
timestamp_update = timestamp_updatefreq;
}
}
}
// Set system clock in core
top->clk_sys = clk_sys.clk;
@@ -167,7 +201,7 @@ int main(int argc, char** argv, char** env) {
input.SetMapping(input_r, DIK_W); // R
input.SetMapping(input_select, DIK_1); // Select
input.SetMapping(input_start, DIK_2); // Start
#else
input.SetMapping(input_up, SDL_SCANCODE_UP);
input.SetMapping(input_right, SDL_SCANCODE_RIGHT);
@@ -185,6 +219,9 @@ int main(int argc, char** argv, char** env) {
// Setup video output
if (video.Initialise(windowTitle) == 1) { return 1; }
// Initial reset
resetSim();
#ifdef WIN32
MSG msg;
ZeroMemory(&msg, sizeof(msg));
@@ -243,6 +280,7 @@ int main(int argc, char** argv, char** env) {
ImGui::Checkbox("Flip V", &video.output_vflip);
ImGui::Text("main_time: %d frame_count: %d sim FPS: %f", main_time, video.count_frame, video.stats_fps);
ImGui::Text("timestamp: %d actual ms: %d frame_ms: %d ", timestamp, timestamp/1000, video.count_frame * 1000);
ImGui::Text("minx: %d maxx: %d miny: %d maxy: %d", video.stats_xMin, video.stats_xMax, video.stats_yMin, video.stats_yMax);
// Draw VGA output
@@ -297,30 +335,38 @@ int main(int argc, char** argv, char** env) {
if (input.inputs[i]) { top->joystick_0 |= (1 << i); }
}
top->joystick_1 = top->joystick_0;
//top->joystick_2 = top->joystick_0;
//top->joystick_3 = top->joystick_0;
//top->joystick_4 = top->joystick_0;
//top->joystick_5 = top->joystick_0;
top->joystick_analog_0 += 1;
top->joystick_analog_0 -= 256;
//top->joystick_analog_1 -= 1;
//top->joystick_analog_1 += 256;
//top->joystick_analog_2 += 1;
//top->joystick_analog_2 -= 256;
//top->joystick_analog_3 -= 1;
//top->joystick_analog_3 += 256;
//top->joystick_analog_4 += 1;
//top->joystick_analog_4 -= 256;
//top->joystick_analog_5 -= 1;
//top->joystick_analog_5 += 256;
top->joystick_l_analog_0 += 1;
top->joystick_l_analog_0 -= 256;
top->joystick_r_analog_0 += 1;
top->joystick_r_analog_0 -= 256;
top->joystick_l_analog_1 -= 0;
top->joystick_l_analog_1 += 512;
top->joystick_r_analog_1 = 30;
top->joystick_r_analog_1 += 512;
top->joystick_l_analog_2 = 40;
top->joystick_l_analog_2 += 1024;
top->joystick_r_analog_2 = 50;
top->joystick_r_analog_2 += 1024;
top->joystick_l_analog_3 = 60;
top->joystick_l_analog_3 += 2048;
top->joystick_r_analog_3 = 70;
top->joystick_r_analog_3 += 2048;
top->joystick_l_analog_4 = 80;
top->joystick_l_analog_4 += 4096;
top->joystick_r_analog_4 = 90;
top->joystick_r_analog_4 += 4096;
top->joystick_l_analog_5 = 100;
top->joystick_l_analog_5 += 8192;
top->joystick_r_analog_5 = 110;
top->joystick_r_analog_5 += 8192;
top->paddle_0 += 1;
//top->paddle_1 -= 1;
//top->paddle_2 += 1;
//top->paddle_3 -= 1;
//top->paddle_4 += 1;
//top->paddle_5 -= 1;
if (input.inputs[0] || input.inputs[1]) {
spinner_toggle = !spinner_toggle;
@@ -328,12 +374,8 @@ int main(int argc, char** argv, char** env) {
for (char b = 8; b < 16; b++) {
top->spinner_0 &= ~(1UL << b);
}
if (spinner_toggle) { top->spinner_0 |= 1UL << 8; } }
//top->spinner_1 -= 1;
//top->spinner_2 += 1;
//top->spinner_3 -= 1;
//top->spinner_4 += 1;
//top->spinner_5 -= 1;
if (spinner_toggle) { top->spinner_0 |= 1UL << 8; }
}
top->ps2_mouse += 1;
top->ps2_mouse_ext -= 1;

View File

@@ -1,25 +1,16 @@
set -e
if grep -qEi "(Microsoft|WSL)" /proc/version &> /dev/null ; then
$VERILATOR_ROOT/bin/verilator \
-cc \
-exe \
--public \
verilator \
--cc \
--compiler msvc +define+SIMULATION=1 \
-O3 --x-assign fast --x-initial fast --noassert \
-Wno-TIMESCALEMOD \
--converge-limit 6000 \
--top-module emu sim.v \
../rtl/dpram.v \
../rtl/spram.v \
../rtl/JTFRAME/jtframe_vtimer.v \
../rtl/JTFRAME/jtframe_cen24.v \
../rtl/system.v \
../rtl/tv80/tv80_core.v \
../rtl/tv80/tv80_alu.v \
../rtl/tv80/tv80_mcode.v \
../rtl/tv80/tv80_reg.v \
../rtl/tv80/tv80n.v \
../rtl/tv80/tv80s.v
-I../rtl \
-I../rtl/JTFRAME \
-I../rtl/tv80
else
echo "not running on windows"
fi