Compare commits
3 Commits
b133879f7e
...
c3bfbb7b90
Author | SHA1 | Date | |
---|---|---|---|
c3bfbb7b90 | |||
07e3c9eb06 | |||
3bf80b521a |
1
.gitignore
vendored
1
.gitignore
vendored
@ -14,6 +14,7 @@ scramble
|
|||||||
cdi4dc
|
cdi4dc
|
||||||
tools/ttf_outline
|
tools/ttf_outline
|
||||||
tools/ttf_bitmap
|
tools/ttf_bitmap
|
||||||
|
tools/ftdi_transfer
|
||||||
k_means_vq
|
k_means_vq
|
||||||
*.blend1
|
*.blend1
|
||||||
*.scramble
|
*.scramble
|
||||||
|
2
burn.sh
Normal file
2
burn.sh
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
cdrecord -speed=8 -v dev=/dev/sr0 -dao -multi taudio01.wav
|
||||||
|
cdrecord -eject -overburn -speed=8 -v dev=/dev/sr0 -tao -xa tdata02.iso
|
@ -34,7 +34,7 @@ SECTIONS
|
|||||||
KEEP(*(.ctors.*))
|
KEEP(*(.ctors.*))
|
||||||
} > p1ram
|
} > p1ram
|
||||||
|
|
||||||
.bss ALIGN(4) (NOLOAD) : SUBALIGN(4)
|
.bss ALIGN(4) (NOLOAD) :
|
||||||
{
|
{
|
||||||
*(.bss)
|
*(.bss)
|
||||||
*(.bss.*)
|
*(.bss.*)
|
||||||
|
36
common.mk
36
common.mk
@ -2,7 +2,7 @@ MAKEFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST)))
|
|||||||
DIR := $(dir $(MAKEFILE_PATH))
|
DIR := $(dir $(MAKEFILE_PATH))
|
||||||
|
|
||||||
LIB ?= .
|
LIB ?= .
|
||||||
OPT ?= -O2
|
OPT ?= -Og
|
||||||
GENERATED ?=
|
GENERATED ?=
|
||||||
|
|
||||||
AARCH = --isa=sh4 --little
|
AARCH = --isa=sh4 --little
|
||||||
@ -21,16 +21,16 @@ IP_OBJ = \
|
|||||||
systemid.o \
|
systemid.o \
|
||||||
toc.o \
|
toc.o \
|
||||||
sg/sg_sec.o \
|
sg/sg_sec.o \
|
||||||
sg/sg_arejp.o \
|
sg_arejp.o \
|
||||||
sg/sg_areus.o \
|
sg_areus.o \
|
||||||
sg/sg_areec.o \
|
sg_areec.o \
|
||||||
sg/sg_are00.o \
|
sg_are00.o \
|
||||||
sg/sg_are01.o \
|
sg_are01.o \
|
||||||
sg/sg_are02.o \
|
sg_are02.o \
|
||||||
sg/sg_are03.o \
|
sg_are03.o \
|
||||||
sg/sg_are04.o \
|
sg_are04.o \
|
||||||
sg/sg_ini.o \
|
sg_ini.o \
|
||||||
sg/aip.o
|
aip.o
|
||||||
|
|
||||||
%.o: %.obj
|
%.o: %.obj
|
||||||
$(OBJCOPY) -g \
|
$(OBJCOPY) -g \
|
||||||
@ -80,13 +80,13 @@ sine.pcm: common.mk
|
|||||||
/=./COPYRIGH.TXT \
|
/=./COPYRIGH.TXT \
|
||||||
/=./ABSTRACT.TXT \
|
/=./ABSTRACT.TXT \
|
||||||
/=./BIBLIOGR.TXT \
|
/=./BIBLIOGR.TXT \
|
||||||
/=./REIGN.PCM \
|
/=./pcm/REIGN.PCM \
|
||||||
/=./PILLAR.PCM \
|
/=./pcm/PILLAR.PCM \
|
||||||
/=./RIDDLE.PCM \
|
/=./pcm/RIDDLE.PCM \
|
||||||
/=./PRELUDE.PCM \
|
/=./pcm/PRELUDE.PCM \
|
||||||
/=./CLOCKTOW.PCM \
|
/=./pcm/CLOCKTOW.PCM \
|
||||||
/=./ELEC.PCM \
|
/=./pcm/ELEC.PCM \
|
||||||
/=./ECCLESIA.PCM
|
/=./pcm/ECCLESIA.PCM
|
||||||
|
|
||||||
%.cdi: %.iso
|
%.cdi: %.iso
|
||||||
./cdi4dc $< $@ >/dev/null
|
./cdi4dc $< $@ >/dev/null
|
||||||
|
@ -206,14 +206,17 @@ void * memset(void * dest, int c, size_t n)
|
|||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
static fft::complex comp[samples_per_line * 2];
|
static fft::complex comp[samples_per_line * 8];
|
||||||
|
|
||||||
void render_column(int col, int x, const uint32_t * buf)
|
int render_column(int col, int x, const uint32_t * buf)
|
||||||
{
|
{
|
||||||
uint32_t offset = texture_memory_alloc::texture.start + 0;
|
uint32_t offset = texture_memory_alloc::texture.start + 0;
|
||||||
auto texture = reinterpret_cast<volatile uint32_t *>(&texture_memory64[offset / 4]);
|
auto texture = reinterpret_cast<volatile uint32_t *>(&texture_memory64[offset / 4]);
|
||||||
|
|
||||||
const int16_t * src = &((int16_t *)(buf))[col * samples_per_line * 2];
|
const int16_t * src = &((int16_t *)(buf))[col * samples_per_line / 2];
|
||||||
|
if ((src) >= (int16_t*)&buf[(chunk_size - samples_per_line * 2)/4])
|
||||||
|
return 0; // FIXME: this is a hack
|
||||||
|
|
||||||
fft::int16_to_complex(src, samples_per_line * 2, comp);
|
fft::int16_to_complex(src, samples_per_line * 2, comp);
|
||||||
fft::fft(comp, samples_per_line * 2);
|
fft::fft(comp, samples_per_line * 2);
|
||||||
for (int32_t y = 0; y < samples_per_line; y++) {
|
for (int32_t y = 0; y < samples_per_line; y++) {
|
||||||
@ -229,24 +232,27 @@ void render_column(int col, int x, const uint32_t * buf)
|
|||||||
value |= v << shift;
|
value |= v << shift;
|
||||||
texture[ix / 4] = value;
|
texture[ix / 4] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void render();
|
void render();
|
||||||
void texture_init();
|
void texture_init();
|
||||||
|
|
||||||
void aica_step(uint32_t& chunk_index, const uint32_t gdrom_buf[2][chunk_size / 4])
|
void aica_step(uint32_t& chunk_index, const uint32_t gdrom_buf[2][chunk_size / 4 * 2])
|
||||||
{
|
{
|
||||||
{ // wait for interrupt from arm
|
{ // wait for interrupt from arm
|
||||||
int col = 0;
|
int col = 0;
|
||||||
while ((system.ISTEXT & (1 << 1)) == 0) {
|
while ((system.ISTEXT & (1 << 1)) == 0) {
|
||||||
if (step_time >= 0) {
|
if (step_time >= 0) {
|
||||||
int32_t dt = step_start - (int32_t)sh7091.TMU.TCNT0;
|
int32_t dt = step_start - (int32_t)sh7091.TMU.TCNT0;
|
||||||
if (step_time * col / lines_per_chunk < dt) {
|
if (step_time * col / (lines_per_chunk * 4) < dt) {
|
||||||
render_column(col, __x, gdrom_buf[!chunk_index]);
|
int inc = render_column(col, __x, gdrom_buf[!chunk_index]);
|
||||||
render();
|
col += inc;
|
||||||
col += 1;
|
__x += inc;
|
||||||
__x += 1;
|
|
||||||
__x %= samples_per_line;
|
__x %= samples_per_line;
|
||||||
|
if (col % 2)
|
||||||
|
render();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -362,14 +368,9 @@ uint32_t gdrom_cd_read2(uint16_t * buf,
|
|||||||
length += byte_count;
|
length += byte_count;
|
||||||
gdrom_read_data(buf, byte_count);
|
gdrom_read_data(buf, byte_count);
|
||||||
|
|
||||||
serial::string("status: ");
|
|
||||||
serial::integer<uint8_t>(gdrom_if.status);
|
|
||||||
|
|
||||||
while ((gdrom::status::bsy(gdrom_if.status)) != 0); // wait for drive to become not-busy
|
while ((gdrom::status::bsy(gdrom_if.status)) != 0); // wait for drive to become not-busy
|
||||||
}
|
}
|
||||||
|
|
||||||
serial::string("length: ");
|
|
||||||
serial::integer<uint32_t>(length);
|
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -466,7 +467,7 @@ struct extent gdrom_find_file()
|
|||||||
serial::string(dr->file_identifier, dr->length_of_file_identifier);
|
serial::string(dr->file_identifier, dr->length_of_file_identifier);
|
||||||
serial::character('\n');
|
serial::character('\n');
|
||||||
|
|
||||||
const char filename[] = "ELEC.PCM;1";
|
const char filename[] = "RIDDLE.PCM;1";
|
||||||
bool equal = str_equal(dr->file_identifier, dr->length_of_file_identifier,
|
bool equal = str_equal(dr->file_identifier, dr->length_of_file_identifier,
|
||||||
filename, (sizeof (filename)) - 1);
|
filename, (sizeof (filename)) - 1);
|
||||||
|
|
||||||
@ -603,7 +604,9 @@ void render()
|
|||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
serial::init(4);
|
memset(&comp, 0, (sizeof (comp)));
|
||||||
|
|
||||||
|
serial::init(0);
|
||||||
|
|
||||||
holly.SOFTRESET = softreset::pipeline_soft_reset
|
holly.SOFTRESET = softreset::pipeline_soft_reset
|
||||||
| softreset::ta_soft_reset;
|
| softreset::ta_soft_reset;
|
||||||
@ -646,7 +649,7 @@ void main()
|
|||||||
|
|
||||||
gdrom_unlock();
|
gdrom_unlock();
|
||||||
const auto extent = gdrom_find_file();
|
const auto extent = gdrom_find_file();
|
||||||
uint32_t gdrom_buf[2][chunk_size / 4];
|
uint32_t gdrom_buf[2][(chunk_size / 4) * 2] = {0};
|
||||||
gdrom_read_chunk(gdrom_buf[chunk_index], extent.location + segment_index, sectors_per_chunk);
|
gdrom_read_chunk(gdrom_buf[chunk_index], extent.location + segment_index, sectors_per_chunk);
|
||||||
next_segment(extent, segment_index);
|
next_segment(extent, segment_index);
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
#include "holly/video_output.hpp"
|
#include "holly/video_output.hpp"
|
||||||
#include "memorymap.hpp"
|
#include "memorymap.hpp"
|
||||||
|
|
||||||
#include "macaw.hpp"
|
#include "texture/macaw/macaw.data.h"
|
||||||
|
|
||||||
struct vertex {
|
struct vertex {
|
||||||
float x;
|
float x;
|
||||||
@ -110,13 +110,13 @@ void init_texture_memory(const struct opb_size& opb_size)
|
|||||||
480 / 32, // height
|
480 / 32, // height
|
||||||
opb_size
|
opb_size
|
||||||
);
|
);
|
||||||
background_parameter(0xff00ff00);
|
background_parameter(0xff004400);
|
||||||
}
|
}
|
||||||
|
|
||||||
void copy_macaw_texture()
|
void copy_macaw_texture()
|
||||||
{
|
{
|
||||||
auto src = reinterpret_cast<const uint8_t *>(&_binary_macaw_data_start);
|
auto src = reinterpret_cast<const uint8_t *>(&_binary_texture_macaw_macaw_data_start);
|
||||||
auto size = reinterpret_cast<const uint32_t>(&_binary_macaw_data_size);
|
auto size = reinterpret_cast<const uint32_t>(&_binary_texture_macaw_macaw_data_size);
|
||||||
auto texture = reinterpret_cast<volatile uint16_t *>(&texture_memory64[texture_memory_alloc::texture.start / 4]);
|
auto texture = reinterpret_cast<volatile uint16_t *>(&texture_memory64[texture_memory_alloc::texture.start / 4]);
|
||||||
for (uint32_t px = 0; px < size / 3; px++) {
|
for (uint32_t px = 0; px < size / 3; px++) {
|
||||||
uint8_t r = src[px * 3 + 0];
|
uint8_t r = src[px * 3 + 0];
|
||||||
|
4
ip.lds
4
ip.lds
@ -42,11 +42,13 @@ SECTIONS
|
|||||||
.text.sg_ini :
|
.text.sg_ini :
|
||||||
{
|
{
|
||||||
KEEP(*(.text.*sg_ini))
|
KEEP(*(.text.*sg_ini))
|
||||||
|
. = ORIGIN(sg_ini) + LENGTH(sg_ini);
|
||||||
} > sg_ini
|
} > sg_ini
|
||||||
|
|
||||||
.text.aip :
|
.text.aip :
|
||||||
{
|
{
|
||||||
KEEP(*(.text.*aip))
|
KEEP(*(.text.*aip))
|
||||||
|
. = ORIGIN(aip) + LENGTH(aip);
|
||||||
} > aip
|
} > aip
|
||||||
|
|
||||||
/DISCARD/ :
|
/DISCARD/ :
|
||||||
@ -56,4 +58,6 @@ SECTIONS
|
|||||||
*(.bss)
|
*(.bss)
|
||||||
*(.comment)
|
*(.comment)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INCLUDE "debug.lds"
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include <functional>
|
#include <tuple>
|
||||||
|
|
||||||
#include "vec.hpp"
|
#include "vec.hpp"
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include "vec2.hpp"
|
||||||
|
|
||||||
template <int R, int C, typename T>
|
template <int R, int C, typename T>
|
||||||
struct mat;
|
struct mat;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include "vec4.hpp"
|
||||||
|
|
||||||
template <int R, int C, typename T>
|
template <int R, int C, typename T>
|
||||||
struct mat;
|
struct mat;
|
||||||
|
5
sg_are00.s
Normal file
5
sg_are00.s
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
.section .text.sg_are00
|
||||||
|
bra _sg_are00_next
|
||||||
|
nop
|
||||||
|
.ascii " "
|
||||||
|
_sg_are00_next:
|
5
sg_are01.s
Normal file
5
sg_are01.s
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
.section .text.sg_are01
|
||||||
|
bra _sg_are01_next
|
||||||
|
nop
|
||||||
|
.ascii " "
|
||||||
|
_sg_are01_next:
|
5
sg_are02.s
Normal file
5
sg_are02.s
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
.section .text.sg_are02
|
||||||
|
bra _sg_are02_next
|
||||||
|
nop
|
||||||
|
.ascii " "
|
||||||
|
_sg_are02_next:
|
5
sg_are03.s
Normal file
5
sg_are03.s
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
.section .text.sg_are03
|
||||||
|
bra _sg_are03_next
|
||||||
|
nop
|
||||||
|
.ascii " "
|
||||||
|
_sg_are03_next:
|
5
sg_are04.s
Normal file
5
sg_are04.s
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
.section .text.sg_are04
|
||||||
|
bra _sg_are04_next
|
||||||
|
nop
|
||||||
|
.ascii " "
|
||||||
|
_sg_are04_next:
|
5
sg_areec.s
Normal file
5
sg_areec.s
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
.section .text.sg_areec
|
||||||
|
bra _sg_areec_next
|
||||||
|
nop
|
||||||
|
.ascii "For EUROPE. "
|
||||||
|
_sg_areec_next:
|
5
sg_arejp.s
Normal file
5
sg_arejp.s
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
.section .text.sg_arejp
|
||||||
|
bra _sg_arejp_next
|
||||||
|
nop
|
||||||
|
.ascii "For JAPAN,TAIWAN,PHILIPINES."
|
||||||
|
_sg_arejp_next:
|
5
sg_areus.s
Normal file
5
sg_areus.s
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
.section .text.sg_areus
|
||||||
|
bra _sg_areus_next
|
||||||
|
nop
|
||||||
|
.ascii "For USA and CANADA. "
|
||||||
|
_sg_areus_next:
|
250
sg_ini.s
250
sg_ini.s
@ -2,7 +2,7 @@
|
|||||||
.global _text_sg_ini_start
|
.global _text_sg_ini_start
|
||||||
|
|
||||||
_text_sg_ini_start:
|
_text_sg_ini_start:
|
||||||
mov.l label_18,r0 /* 8d000000 → beginning of system ram, image area */
|
mov.l label_18,r0 /* 8d000000 → end of system ram */
|
||||||
mov r0,r15
|
mov r0,r15
|
||||||
nop
|
nop
|
||||||
nop
|
nop
|
||||||
@ -23,26 +23,36 @@ label_20:
|
|||||||
.fill 0x2000,1,0x00
|
.fill 0x2000,1,0x00
|
||||||
|
|
||||||
label_2020:
|
label_2020:
|
||||||
|
/* function that processes the list of addresses/values at label_2284 */
|
||||||
mov.l label_204c,r0 /* 8c00d940 → label_2140 */
|
mov.l label_204c,r0 /* 8c00d940 → label_2140 */
|
||||||
mov #0,r1
|
mov #0,r1
|
||||||
jsr @r0
|
jsr @r0
|
||||||
nop
|
nop
|
||||||
|
|
||||||
|
/* ???? possibly jump to boot menu? */
|
||||||
mov.l label_2050,r0 /* 8c00d900 → label_2100 */
|
mov.l label_2050,r0 /* 8c00d900 → label_2100 */
|
||||||
jsr @r0
|
jsr @r0
|
||||||
nop
|
nop
|
||||||
|
|
||||||
|
/* possibly jump to boot menu? */
|
||||||
mov.l label_2054,r0 /* 8c00d888 → label_2088 */
|
mov.l label_2054,r0 /* 8c00d888 → label_2088 */
|
||||||
jsr @r0
|
jsr @r0
|
||||||
nop
|
nop
|
||||||
|
|
||||||
|
/* check for Windows CE? */
|
||||||
mov.l label_2058,r0 /* 8c00dae0 → label_22e0 */
|
mov.l label_2058,r0 /* 8c00dae0 → label_22e0 */
|
||||||
jsr @r0
|
jsr @r0
|
||||||
nop
|
nop
|
||||||
|
|
||||||
mov.l label_205c,r0 /* 8c00db40 → label_2340 */
|
mov.l label_205c,r0 /* 8c00db40 → label_2340 */
|
||||||
jsr @r0
|
jsr @r0
|
||||||
nop
|
nop
|
||||||
|
|
||||||
nop
|
nop
|
||||||
mov.l label_2060,r0 /* 8c00d86c → label_206c */
|
mov.l label_2060,r0 /* 8c00d86c → label_206c */
|
||||||
jmp @r0
|
jmp @r0
|
||||||
nop
|
nop
|
||||||
|
|
||||||
nop
|
nop
|
||||||
nop
|
nop
|
||||||
|
|
||||||
@ -80,7 +90,7 @@ label_2084:
|
|||||||
label_2088:
|
label_2088:
|
||||||
sts.l pr,@-r15
|
sts.l pr,@-r15
|
||||||
mov.l label_20a4,r0 /* 8c000048 */
|
mov.l label_20a4,r0 /* 8c000048 */
|
||||||
mov.l @r0,r0
|
mov.l @r0,r0 /* r0 ← 1 */
|
||||||
cmp/eq #6,r0
|
cmp/eq #6,r0
|
||||||
bt label_209e
|
bt label_209e
|
||||||
cmp/eq #7,r0
|
cmp/eq #7,r0
|
||||||
@ -98,6 +108,7 @@ label_20a4:
|
|||||||
label_20a8:
|
label_20a8:
|
||||||
.long 0x8c00d8ac
|
.long 0x8c00d8ac
|
||||||
|
|
||||||
|
/* jump back to boot menu? */
|
||||||
label_20ac:
|
label_20ac:
|
||||||
mov.l label_20b4,r0 /* 8c0000e0 */
|
mov.l label_20b4,r0 /* 8c0000e0 */
|
||||||
mov.l @r0,r0
|
mov.l @r0,r0
|
||||||
@ -108,61 +119,68 @@ label_20b4:
|
|||||||
|
|
||||||
label_20b8:
|
label_20b8:
|
||||||
exts.b r4,r0
|
exts.b r4,r0
|
||||||
mov #57,r1
|
mov #57,r1 /* ascii '9' */
|
||||||
cmp/gt r1,r0
|
cmp/gt r1,r0
|
||||||
bf label_20c2
|
bf label_20c2
|
||||||
add #-7,r0
|
add #-7,r0
|
||||||
label_20c2:
|
label_20c2:
|
||||||
rts
|
rts
|
||||||
add #-48,r0
|
add #-48,r0
|
||||||
|
|
||||||
|
/* called from label_2100 and label_22e0 */
|
||||||
label_20c6:
|
label_20c6:
|
||||||
xor r2,r2
|
xor r2,r2
|
||||||
sts.l pr,@-r15
|
sts.l pr,@-r15
|
||||||
mov.b @r4,r4
|
mov.b @r4,r4 /* r4 ← (0x8c00803e) = 0x30 */
|
||||||
mov r4,r0
|
mov r4,r0 /* r0 ← 0x30 */
|
||||||
cmp/eq #32,r0
|
cmp/eq #0x20,r0 /* check for ascii space in 'Compatible peripherals' of systemid */
|
||||||
bt label_20e0
|
bt label_20e0 /* if it is space, return 0 */
|
||||||
bsr label_20b8
|
bsr label_20b8 /* ascii 0-9 to integer */
|
||||||
nop
|
nop
|
||||||
mov #1,r1
|
mov #1,r1
|
||||||
tst r1,r0
|
tst r1,r0 /* check for ascii '1' / "uses Windows CE" */
|
||||||
bt.s label_20e0
|
bt.s label_20e0 /* if not "uses Windows CE", take branch to label_20e0 */
|
||||||
xor r2,r2
|
xor r2,r2
|
||||||
mov #1,r2
|
mov #1,r2
|
||||||
label_20e0:
|
label_20e0:
|
||||||
lds.l @r15+,pr
|
lds.l @r15+,pr
|
||||||
rts
|
rts
|
||||||
mov r2,r0
|
mov r2,r0 /* return 1 if Windows CE, 0 if not */
|
||||||
.word 0xffff
|
.word 0xffff
|
||||||
label_20e8:
|
label_20e8:
|
||||||
mov.l label_20fc,r1 ! 8c008024
|
mov.l label_20fc,r1 ! 8c008024
|
||||||
mov.l label_20f8,r3 ! 4c494d20
|
mov.l label_20f8,r3 /* ascii ' MIL' ; 0x4c494d20 */
|
||||||
mov.l @r1,r2
|
mov.l @r1,r2 /* r2 ← 0x2d444720 ' GD-' */
|
||||||
cmp/eq r3,r2
|
cmp/eq r3,r2
|
||||||
movt r0
|
movt r0
|
||||||
rts
|
rts
|
||||||
nop
|
nop
|
||||||
nop
|
nop
|
||||||
label_20f8:
|
label_20f8:
|
||||||
.long 0x4c494d20
|
.ascii " MIL" /* 4c494d20 */
|
||||||
label_20fc:
|
label_20fc:
|
||||||
.long 0x8c008024
|
.long 0x8c008024
|
||||||
|
|
||||||
|
/* called from label_2020 */
|
||||||
label_2100:
|
label_2100:
|
||||||
sts.l pr,@-r15
|
sts.l pr,@-r15
|
||||||
mov.l label_212c,r3 /* 8c00d8c6 → label_20c6 */
|
mov.l label_212c,r3 /* 8c00d8c6 → label_20c6 */
|
||||||
mov.l label_213c,r4 ! 8c008000
|
mov.l label_213c,r4 /* 8c008000 */
|
||||||
jsr @r3
|
jsr @r3
|
||||||
add #62,r4
|
add #0x3e,r4 /* r4 ← 0x8c00803e */
|
||||||
tst r0,r0
|
tst r0,r0 /* check return value != 0 */
|
||||||
bf label_2126
|
bf label_2126
|
||||||
|
|
||||||
|
/* check for ' MIL' CD */
|
||||||
mov.l label_2130,r3 /* 8c00d8e8 → label_20e8 */
|
mov.l label_2130,r3 /* 8c00d8e8 → label_20e8 */
|
||||||
jsr @r3
|
jsr @r3
|
||||||
nop
|
nop
|
||||||
tst r0,r0
|
tst r0,r0 /* check return value != 0 */
|
||||||
bf label_2126
|
bf label_2126
|
||||||
|
|
||||||
mov.l label_2138,r3 ! 8c010000
|
mov.l label_2138,r3 ! 8c010000
|
||||||
mov.w @r3,r0
|
mov.w @r3,r0
|
||||||
cmp/eq #34,r0
|
cmp/eq #34,r0 /* check for 'stc vbr,r0' ?? */
|
||||||
bf label_2126
|
bf label_2126
|
||||||
mov.l label_2134,r1 /* 8c00d8ac → label_20ac */
|
mov.l label_2134,r1 /* 8c00d8ac → label_20ac */
|
||||||
jmp @r1
|
jmp @r1
|
||||||
@ -182,22 +200,25 @@ label_2138:
|
|||||||
label_213c:
|
label_213c:
|
||||||
.long 0x8c008000
|
.long 0x8c008000
|
||||||
|
|
||||||
|
/* function that processes the list of addresses/values at label_2284 */
|
||||||
label_2140:
|
label_2140:
|
||||||
mov.l r2,@-r15
|
mov.l r2,@-r15
|
||||||
mov.l r3,@-r15
|
mov.l r3,@-r15
|
||||||
mov.l r4,@-r15
|
mov.l r4,@-r15
|
||||||
mov.l r5,@-r15
|
mov.l r5,@-r15
|
||||||
sts.l pr,@-r15
|
sts.l pr,@-r15
|
||||||
mova label_2284,r0
|
mova label_2284,r0 /* 0x8c00da84 */
|
||||||
mov.w @(r0,r1),r1
|
mov.w @(r0,r1),r1 /* 0x2 */
|
||||||
add r1,r0
|
add r1,r0 /* 0x8c00da86 */
|
||||||
label_2150:
|
label_2150:
|
||||||
add #3,r0
|
add #3,r0
|
||||||
shlr2 r0
|
shlr2 r0
|
||||||
shll2 r0
|
shll2 r0 /* #1 r0 ← 0x8c00da88
|
||||||
mov.w @r0+,r4
|
#2 r0 ← 0x8c00da90 */
|
||||||
tst r4,r4
|
mov.w @r0+,r4 /* #1 r0 ← 0x8c00da8a ; r4 ← 2
|
||||||
bf label_2172
|
#2 r4 ← 1 */
|
||||||
|
tst r4,r4 /* r4 & r4 != 0 → T unset */
|
||||||
|
bf label_2172 /* branch taken */
|
||||||
mov.w @r0+,r4
|
mov.w @r0+,r4
|
||||||
tst r4,r4
|
tst r4,r4
|
||||||
bf.s label_2150
|
bf.s label_2150
|
||||||
@ -210,20 +231,22 @@ label_2150:
|
|||||||
rts
|
rts
|
||||||
sett
|
sett
|
||||||
label_2172:
|
label_2172:
|
||||||
mov.w @r0+,r3
|
mov.w @r0+,r3 /* #1 0x8c00da8a ; r0 ← 0x8c00da8c ; r3 ← 0x6
|
||||||
mov.l label_2278,r1 ! ffff8000
|
#2 0x8c00da92 ; r0 ← 0x8c00da94 ; r3 ← 0x18
|
||||||
and r3,r1
|
*/
|
||||||
tst r1,r1
|
mov.l label_2278,r1 /* ffff8000 */
|
||||||
bt label_2180
|
and r3,r1 /* r1 ← 0 */
|
||||||
|
tst r1,r1 /* r1 & r1 == 0 → T set */
|
||||||
|
bt label_2180 /* branch taken */
|
||||||
xor r1,r3
|
xor r1,r3
|
||||||
bf label_2182
|
bf label_2182
|
||||||
label_2180:
|
label_2180:
|
||||||
mov.l @r0+,r2
|
mov.l @r0+,r2 /* 0x8c00da8c ; r2 ← 0xff000038 */
|
||||||
label_2182:
|
label_2182:
|
||||||
mov.l label_227c,r1 ! 6000
|
mov.l label_227c,r1 /* r1 ← 6000 */
|
||||||
and r3,r1
|
and r3,r1 /* r1 ← 0 */
|
||||||
tst r1,r1
|
tst r1,r1 /* T set */
|
||||||
bt label_21a0
|
bt label_21a0 /* branch taken */
|
||||||
xor r1,r3
|
xor r1,r3
|
||||||
add #12,r3
|
add #12,r3
|
||||||
mov.l @r0+,r1
|
mov.l @r0+,r1
|
||||||
@ -236,27 +259,43 @@ label_2194:
|
|||||||
add #4,r2
|
add #4,r2
|
||||||
bra label_2150
|
bra label_2150
|
||||||
mov r5,r0
|
mov r5,r0
|
||||||
|
/* branch from label_2182 */
|
||||||
label_21a0:
|
label_21a0:
|
||||||
bsrf r3
|
bsrf r3 /* #1 0x06 ; PC ← 0x8c00d9aa (label_21aa)
|
||||||
dt r4
|
#2 0x18 ; PC ← 0x8c00d9bc (label_2abc)
|
||||||
bf.s label_21a0
|
#3 0x0c ; PC ← 0x8c00d9b0 (label_21b0)
|
||||||
add #4,r2
|
*/
|
||||||
bt label_2150
|
dt r4 /* #1 r4 ← 1 ; T unset
|
||||||
|
#2 r4 ← 0 ; T set
|
||||||
|
#3 r4 ← 3 ; T unset
|
||||||
|
*/
|
||||||
|
bf.s label_21a0 /* #1 branch taken ; #2 branch not taken */
|
||||||
|
add #4,r2 /* 0xff000038 ; r2 ← 0xff00003c */
|
||||||
|
bt label_2150 /* branch taken */
|
||||||
|
label_21aa:
|
||||||
mov #0,r1
|
mov #0,r1
|
||||||
rts
|
rts
|
||||||
mov.l r1,@r2
|
mov.l r1,@r2
|
||||||
|
label_21b0:
|
||||||
mov #0,r1
|
mov #0,r1
|
||||||
rts
|
rts
|
||||||
mov.w r1,@r2
|
mov.w r1,@r2
|
||||||
mov #0,r1
|
mov #0,r1
|
||||||
rts
|
rts
|
||||||
mov.b r1,@r2
|
mov.b r1,@r2
|
||||||
mov.l @r0+,r1
|
label_21bc:
|
||||||
|
mov.l @r0+,r1 /* 0x8c00da98 ; r1 ← 0x12c0 */
|
||||||
rts
|
rts
|
||||||
mov.l r1,@r2
|
mov.l r1,@r2 /* 0xffa0002c ; CHCR2 ← 0x000012c0
|
||||||
|
DM: fixed
|
||||||
|
SM: incremented
|
||||||
|
RS: external request, single address mode
|
||||||
|
*/
|
||||||
|
label_21c2:
|
||||||
mov.w @r0+,r1
|
mov.w @r0+,r1
|
||||||
rts
|
rts
|
||||||
mov.l r1,@r2
|
mov.l r1,@r2
|
||||||
|
|
||||||
mov.l @r0+,r1
|
mov.l @r0+,r1
|
||||||
rts
|
rts
|
||||||
mov.b r1,@r2
|
mov.b r1,@r2
|
||||||
@ -357,50 +396,90 @@ label_2278:
|
|||||||
label_227c:
|
label_227c:
|
||||||
.long 0x00006000
|
.long 0x00006000
|
||||||
|
|
||||||
/* unreachable? */
|
.long 0xa05f8040 /* unused; VO_BORDER_COL */
|
||||||
.word 0x8040
|
|
||||||
.word 0xa05f
|
|
||||||
label_2284:
|
label_2284:
|
||||||
.word 0x0002
|
.word 0x0002
|
||||||
.word 0x0009
|
label_2286:
|
||||||
|
.word 0x0009 /* unused garbage data? */
|
||||||
|
|
||||||
|
label_2288:
|
||||||
.word 0x0002
|
.word 0x0002
|
||||||
.word 0x0006
|
label_228a:
|
||||||
.word 0x0038
|
.word 0x0006 /* r3 */
|
||||||
.word 0xff00
|
label_228c:
|
||||||
|
.long 0xff000038
|
||||||
|
|
||||||
|
label_2290:
|
||||||
.word 0x0001
|
.word 0x0001
|
||||||
.word 0x0018
|
label_2292:
|
||||||
.word 0x002c
|
.word 0x0018 /* r3 */
|
||||||
.word 0xffa0
|
label_2294:
|
||||||
.word 0x12c0
|
.long 0xffa0002c /* CHCR2 ← 0x000012c0 */
|
||||||
.word 0x0000
|
label_2298:
|
||||||
|
.long 0x000012c0
|
||||||
|
|
||||||
|
label_229c:
|
||||||
.word 0x0004
|
.word 0x0004
|
||||||
|
label_229e:
|
||||||
.word 0x000c
|
.word 0x000c
|
||||||
.word 0x0000
|
label_22a0:
|
||||||
.word 0xffd0
|
.long 0xffd00000 /* ICR ← 0
|
||||||
.word 0x0001
|
IPRA ← 0
|
||||||
.word 0x0018
|
IPRB ← 0
|
||||||
.word 0x0024
|
IPRC ← 0
|
||||||
.word 0xff00
|
*/
|
||||||
.word 0x0020
|
label_22a4:
|
||||||
.word 0x0000
|
.word 0x0001 /* r4 */
|
||||||
.word 0x0002
|
label_22a6:
|
||||||
.word 0x001e
|
.word 0x0018 /* r3 → bsrf label_21bc */
|
||||||
.word 0x7490
|
label_22a8:
|
||||||
.word 0xa05f
|
.long 0xff000024 /* r2
|
||||||
|
?? ← 0x00000020 */
|
||||||
|
label_22ac:
|
||||||
|
.long 0x00000020 /* r1 */
|
||||||
|
|
||||||
|
label_22b0:
|
||||||
|
.word 0x0002 /* r4 */
|
||||||
|
label_22b2:
|
||||||
|
.word 0x001e /* r3 → bsrf label_21c2 */
|
||||||
|
label_22b4:
|
||||||
|
.long 0xa05f7490 /* r2
|
||||||
|
SB_G1CRC ← 0x0222
|
||||||
|
SB_G1CWC ← 0x0222
|
||||||
|
*/
|
||||||
|
label_22b8:
|
||||||
.word 0x0222
|
.word 0x0222
|
||||||
|
label_22ba:
|
||||||
.word 0x0222
|
.word 0x0222
|
||||||
.word 0x0002
|
|
||||||
.word 0x001e
|
label_22bc:
|
||||||
.word 0x74a0
|
.word 0x0002 /* r4 */
|
||||||
.word 0xa05f
|
label_22be:
|
||||||
|
.word 0x001e /* r3 → bsrf label_21c2 */
|
||||||
|
label_22c0:
|
||||||
|
.long 0xa05f74a0 /* r2
|
||||||
|
SB_G1GDRC ← 0x2001
|
||||||
|
SB_G1GDWC ← 0x2001
|
||||||
|
*/
|
||||||
|
label_22c4:
|
||||||
.word 0x2001
|
.word 0x2001
|
||||||
|
label_22c6:
|
||||||
.word 0x2001
|
.word 0x2001
|
||||||
.word 0x0002
|
|
||||||
.word 0x001e
|
label_22c8:
|
||||||
.word 0x7890
|
.word 0x0002 /* r4 */
|
||||||
.word 0xa05f
|
label_22ca:
|
||||||
|
.word 0x001e /* r3 → bsrf label_21c2 */
|
||||||
|
label_22cc:
|
||||||
|
.long 0xa05f7890 /* SB_G2DSTO ← 0x001b
|
||||||
|
SB_G2TRTO ← 0x0271
|
||||||
|
*/
|
||||||
|
label_22d0:
|
||||||
.word 0x001b
|
.word 0x001b
|
||||||
|
label_22d2:
|
||||||
.word 0x0271
|
.word 0x0271
|
||||||
|
|
||||||
|
label_22d4:
|
||||||
.word 0x0000
|
.word 0x0000
|
||||||
.word 0x0000
|
.word 0x0000
|
||||||
nop
|
nop
|
||||||
@ -408,14 +487,16 @@ label_2284:
|
|||||||
nop
|
nop
|
||||||
nop
|
nop
|
||||||
|
|
||||||
|
/* called from label_2020 */
|
||||||
label_22e0:
|
label_22e0:
|
||||||
sts.l pr,@-r15
|
sts.l pr,@-r15
|
||||||
mov.l label_2330,r4 ! 8c008000
|
/* check systemid for "uses Windows CE" */
|
||||||
mov.l label_2328,r3 ! 8c00d8c6
|
mov.l label_2330,r4 /* 8c008000 systemid */
|
||||||
|
mov.l label_2328,r3 /* 8c00d8c6 label_20c6 */
|
||||||
jsr @r3
|
jsr @r3
|
||||||
add #62,r4
|
add #0x3e,r4
|
||||||
tst r0,r0
|
tst r0,r0 /* r0 (1 if Windows CE) */
|
||||||
bt label_2320
|
bt label_2320 /* if not Windows CE, return */
|
||||||
mov.l label_2334,r1 ! 8ce01010
|
mov.l label_2334,r1 ! 8ce01010
|
||||||
mov.l @r1,r0
|
mov.l @r1,r0
|
||||||
tst r0,r0
|
tst r0,r0
|
||||||
@ -467,10 +548,11 @@ label_2340:
|
|||||||
add #-20,r15
|
add #-20,r15
|
||||||
mov r15,r3
|
mov r15,r3
|
||||||
mov r15,r5
|
mov r15,r5
|
||||||
mov.l r3,@(16,r15)
|
mov.l r3,@(16,r15) /* copy stack pointer to stack */
|
||||||
add #16,r5
|
add #16,r5
|
||||||
bsr label_23e0
|
bsr label_23e0
|
||||||
mov #30,r4
|
mov #30,r4
|
||||||
|
|
||||||
mov r0,r4
|
mov r0,r4
|
||||||
tst r4,r4
|
tst r4,r4
|
||||||
bt label_2384
|
bt label_2384
|
||||||
@ -554,7 +636,7 @@ label_23e0:
|
|||||||
mov #0,r6
|
mov #0,r6
|
||||||
mov #0,r7
|
mov #0,r7
|
||||||
mov.l label_2404,r0 ! 8c0000bc
|
mov.l label_2404,r0 ! 8c0000bc
|
||||||
mov.l @r0,r0
|
mov.l @r0,r0 /* r0 ← 0x8c001000 */
|
||||||
label_23e8:
|
label_23e8:
|
||||||
jmp @r0
|
jmp @r0
|
||||||
nop
|
nop
|
||||||
@ -562,14 +644,14 @@ label_23ec:
|
|||||||
mov #0,r6
|
mov #0,r6
|
||||||
mov #1,r7
|
mov #1,r7
|
||||||
mov.l label_2404,r0 ! 8c0000bc
|
mov.l label_2404,r0 ! 8c0000bc
|
||||||
mov.l @r0,r0
|
mov.l @r0,r0 /* r0 ← 0x8c001000 */
|
||||||
jmp @r0
|
jmp @r0
|
||||||
nop
|
nop
|
||||||
label_23f8:
|
label_23f8:
|
||||||
mov #0,r6
|
mov #0,r6
|
||||||
mov #2,r7
|
mov #2,r7
|
||||||
mov.l label_2404,r0 ! 8c0000bc
|
mov.l label_2404,r0 ! 8c0000bc
|
||||||
mov.l @r0,r0
|
mov.l @r0,r0 /* r0 ← 0x8c001000 */
|
||||||
jmp @r0
|
jmp @r0
|
||||||
nop
|
nop
|
||||||
label_2404:
|
label_2404:
|
||||||
|
10
systemid.s
10
systemid.s
@ -34,12 +34,12 @@
|
|||||||
|
|
||||||
.section .text.systemid
|
.section .text.systemid
|
||||||
|
|
||||||
.ascii "SEGA SEGAKATANA " /* H/W identifier */
|
.ascii "SEGA SEGAKATANA " /* 0x00 H/W identifier */
|
||||||
.ascii "SEGA ENTERPRISES" /* H/W Vendor ID */
|
.ascii "SEGA ENTERPRISES" /* 0x10 H/W Vendor ID */
|
||||||
.ascii "39F1 " /* Media ID */
|
.ascii "39F1 " /* 0x20 Media ID */
|
||||||
.ascii "GD-ROM1/1 " /* Media information */
|
.ascii "GD-ROM1/1 " /* Media information */
|
||||||
.ascii "JUE " /* Compatible Area Symbol */
|
.ascii "JUE " /* 0x30 Compatible Area Symbol */
|
||||||
.ascii "C000810 " /* Compatible peripherals */
|
.ascii "C000810 " /* Compatible peripherals */
|
||||||
.ascii "HDR-0900 " /* Product number */
|
.ascii "HDR-0900 " /* Product number */
|
||||||
.ascii "V0.000" /* Version number */
|
.ascii "V0.000" /* Version number */
|
||||||
.ascii "19980901" /* Release date */
|
.ascii "19980901" /* Release date */
|
||||||
|
5
texture/macaw/macaw.data.h
Normal file
5
texture/macaw/macaw.data.h
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <cstdint>
|
||||||
|
extern uint32_t _binary_texture_macaw_macaw_data_start __asm("_binary_texture_macaw_macaw_data_start");
|
||||||
|
extern uint32_t _binary_texture_macaw_macaw_data_end __asm("_binary_texture_macaw_macaw_data_end");
|
||||||
|
extern uint32_t _binary_texture_macaw_macaw_data_size __asm("_binary_texture_macaw_macaw_data_size");
|
@ -1,5 +0,0 @@
|
|||||||
#include <cstdint>
|
|
||||||
|
|
||||||
extern uint32_t _binary_macaw_data_start __asm("_binary_macaw_data_start");
|
|
||||||
extern uint32_t _binary_macaw_data_end __asm("_binary_macaw_data_end");
|
|
||||||
extern uint32_t _binary_macaw_data_size __asm("_binary_macaw_data_size");
|
|
@ -1,16 +1,25 @@
|
|||||||
CFLAGS = -Og -g -gdwarf-4 -Wall -Wextra -Werror -Wfatal-errors -ggdb -Wno-error=unused-parameter -Wno-error=unused-variable -fstack-protector-strong
|
CFLAGS = -Og -g -gdwarf-4 -Wall -Wextra -Werror -Wfatal-errors -ggdb -Wno-error=unused-parameter -Wno-error=unused-variable -fstack-protector-strong
|
||||||
CXXFLAGS = -std=c++23
|
CXXFLAGS = -std=c++23
|
||||||
|
|
||||||
CFLAGS += $(shell pkg-config --cflags freetype2)
|
FREETYPE_CFLAGS = $(shell pkg-config --cflags freetype2)
|
||||||
LDFLAGS = $(shell pkg-config --libs freetype2)
|
FREETYPE_LDFLAGS = $(shell pkg-config --libs freetype2)
|
||||||
|
|
||||||
|
FTDI_CFLAGS = $(shell pkg-config --cflags libftdi1)
|
||||||
|
FTDI_LDFLAGS = $(shell pkg-config --libs libftdi1)
|
||||||
|
|
||||||
all: ttf_outline
|
all: ttf_outline
|
||||||
|
|
||||||
%.o: %.cpp
|
ttf_%.o: ttf_%.cpp
|
||||||
$(CXX) $(CFLAGS) $(CXXFLAGS) -c $< -o $@
|
$(CXX) $(CFLAGS) $(FREETYPE_CFLAGS) $(CXXFLAGS) -c $< -o $@
|
||||||
|
|
||||||
%: %.o
|
ttf_%: ttf_%.o
|
||||||
$(CXX) $(LDFLAGS) $^ -o $@
|
$(CXX) $(LDFLAGS) $(FREETYPE_LDFLAGS) $^ -o $@
|
||||||
|
|
||||||
|
ftdi_%.o: ftdi_%.c
|
||||||
|
$(CC) -std=gnu2x $(CFLAGS) $(FTDI_CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
ftdi_%: ftdi_%.o
|
||||||
|
$(CXX) $(LDFLAGS) $(FTDI_LDFLAGS) $^ -o $@
|
||||||
|
|
||||||
ttf_outline: ttf_outline.o 2d_pack.o
|
ttf_outline: ttf_outline.o 2d_pack.o
|
||||||
|
|
||||||
@ -21,3 +30,9 @@ clean:
|
|||||||
.INTERMEDIATE:
|
.INTERMEDIATE:
|
||||||
.SECONDARY:
|
.SECONDARY:
|
||||||
.PHONY: all clean
|
.PHONY: all clean
|
||||||
|
|
||||||
|
%: RCS/%,v
|
||||||
|
%: RCS/%
|
||||||
|
%: %,v
|
||||||
|
%: s.%
|
||||||
|
%: SCCS/s.%
|
||||||
|
312
tools/ftdi_transfer.c
Normal file
312
tools/ftdi_transfer.c
Normal file
@ -0,0 +1,312 @@
|
|||||||
|
#include <assert.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <ftdi.h>
|
||||||
|
#include <libusb.h>
|
||||||
|
|
||||||
|
extern int convert_baudrate_UT_export(int baudrate, struct ftdi_context *ftdi,
|
||||||
|
unsigned short *value, unsigned short *index);
|
||||||
|
|
||||||
|
int dreamcast_rates[] = {
|
||||||
|
1562500,
|
||||||
|
781250,
|
||||||
|
520833,
|
||||||
|
390625,
|
||||||
|
312500,
|
||||||
|
260416,
|
||||||
|
223214,
|
||||||
|
195312,
|
||||||
|
173611,
|
||||||
|
156250,
|
||||||
|
142045,
|
||||||
|
130208,
|
||||||
|
120192
|
||||||
|
};
|
||||||
|
|
||||||
|
int init_ftdi_context(struct ftdi_context * ftdi)
|
||||||
|
{
|
||||||
|
ftdi_set_interface(ftdi, INTERFACE_ANY);
|
||||||
|
struct ftdi_device_list * devlist;
|
||||||
|
int res;
|
||||||
|
if ((res = ftdi_usb_find_all(ftdi, &devlist, 0, 0)) < 0) {
|
||||||
|
fprintf(stderr, "ftdi_usb_find_all\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res == 0) {
|
||||||
|
fprintf(stderr, "no device\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct libusb_device_descriptor desc;
|
||||||
|
struct ftdi_device_list * devlist_item = devlist;
|
||||||
|
for (int i = 0; i < res; i++) {
|
||||||
|
res = libusb_get_device_descriptor(devlist_item->dev, &desc);
|
||||||
|
if (res < 0) {
|
||||||
|
fprintf(stderr, "libusb_get_device_descriptor\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
fprintf(stdout, "idVendor: %04x; idProduct: %04x;\n", desc.idVendor, desc.idProduct);
|
||||||
|
fprintf(stdout, "bNumConfigurations: %d;\n", desc.bNumConfigurations);
|
||||||
|
devlist_item = devlist_item->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = ftdi_usb_open_dev(ftdi, devlist->dev);
|
||||||
|
if (res < 0) {
|
||||||
|
fprintf(stderr, "ftdi_usb_open_dev\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ftdi_list_free(&devlist);
|
||||||
|
|
||||||
|
unsigned short value;
|
||||||
|
unsigned short index;
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < (sizeof (dreamcast_rates)) / (sizeof (dreamcast_rates[0])); i++) {
|
||||||
|
int baud = convert_baudrate_UT_export(dreamcast_rates[i], ftdi, &value, &index);
|
||||||
|
float baudf = baud;
|
||||||
|
float ratef = dreamcast_rates[i];
|
||||||
|
float error = (baudf > ratef) ? ratef / baudf : baudf / ratef;
|
||||||
|
fprintf(stdout, "%d: best: %d, error: %f\n", dreamcast_rates[i], baud, (1.f - error) * 100.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
res = ftdi_set_baudrate(ftdi, 1562500);
|
||||||
|
//res = ftdi_set_baudrate(ftdi, 312500);
|
||||||
|
if (res < 0) {
|
||||||
|
fprintf(stderr, "ftdi_set_baudrate\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = ftdi_set_line_property(ftdi, 8, STOP_BIT_1, NONE);
|
||||||
|
if (res < 0) {
|
||||||
|
fprintf(stderr, "ftdi_set_line_property\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = ftdi_set_latency_timer(ftdi, 1);
|
||||||
|
if (res < 0) {
|
||||||
|
fprintf(stderr, "ftdi_set_latency_timer\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = ftdi_tciflush(ftdi);
|
||||||
|
if (res < 0) {
|
||||||
|
fprintf(stderr, "ftdi_tciflush\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = ftdi_tcoflush(ftdi);
|
||||||
|
if (res < 0) {
|
||||||
|
fprintf(stderr, "ftdi_tcoflush\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
union data_command {
|
||||||
|
struct {
|
||||||
|
uint8_t command[4];
|
||||||
|
uint32_t size;
|
||||||
|
uint32_t dest;
|
||||||
|
};
|
||||||
|
uint8_t data[4 * 3];
|
||||||
|
};
|
||||||
|
static_assert((sizeof (union data_command)) == 4 * 3);
|
||||||
|
|
||||||
|
uint32_t bswap(const uint32_t n)
|
||||||
|
{
|
||||||
|
if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
|
||||||
|
return n;
|
||||||
|
else
|
||||||
|
return __builtin_bswap32(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
long read_with_timeout(struct ftdi_context * ftdi, uint8_t * read_buf, const long expect_length)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
struct timespec tp0;
|
||||||
|
res = clock_gettime(CLOCK_MONOTONIC, &tp0);
|
||||||
|
assert(res >= 0);
|
||||||
|
|
||||||
|
long read_length = 0;
|
||||||
|
while (true) {
|
||||||
|
res = ftdi_read_data(ftdi, read_buf, expect_length - read_length);
|
||||||
|
assert(res >= 0);
|
||||||
|
|
||||||
|
read_length += res;
|
||||||
|
if (read_length >= expect_length)
|
||||||
|
break;
|
||||||
|
|
||||||
|
struct timespec tp1;
|
||||||
|
res = clock_gettime(CLOCK_MONOTONIC, &tp1);
|
||||||
|
assert(res >= 0);
|
||||||
|
|
||||||
|
if (tp1.tv_sec - tp0.tv_sec > 1) {
|
||||||
|
fprintf(stderr, "read timeout: %ld expect: %ld\n", read_length, expect_length);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return read_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int chunk_size = 1024;
|
||||||
|
|
||||||
|
long min(long a, long b)
|
||||||
|
{
|
||||||
|
return a > b ? b : a;
|
||||||
|
}
|
||||||
|
|
||||||
|
long max(long a, long b)
|
||||||
|
{
|
||||||
|
return a > b ? a : b;
|
||||||
|
}
|
||||||
|
|
||||||
|
void symmetric(struct ftdi_context * ftdi, const uint8_t * tx_buf, const long size)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
uint8_t rx_buf[size];
|
||||||
|
long tx_offset = 0;
|
||||||
|
long rx_offset = 0;
|
||||||
|
|
||||||
|
while (tx_offset < size) {
|
||||||
|
long txrx_diff = tx_offset - rx_offset;
|
||||||
|
long tx_length = max(min(min(chunk_size, size - tx_offset), chunk_size - txrx_diff), 0);
|
||||||
|
|
||||||
|
if (tx_length > 0) {
|
||||||
|
res = ftdi_write_data(ftdi, &tx_buf[tx_offset], tx_length);
|
||||||
|
assert(res >= 0);
|
||||||
|
tx_offset += res;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = ftdi_read_data(ftdi, &rx_buf[rx_offset], size - rx_offset);
|
||||||
|
assert(res >= 0);
|
||||||
|
rx_offset += res;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
if (tx_buf[i] != rx_buf[i]) {
|
||||||
|
fprintf(stderr, "mismatch at %d\n", i);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fprintf(stderr, "equal\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
double timespec_difference(struct timespec const * const a, struct timespec const * const b)
|
||||||
|
{
|
||||||
|
return (double)(a->tv_sec - b->tv_sec) + (double)(a->tv_nsec - b->tv_nsec) / 1'000'000'000.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int transfer(struct ftdi_context * ftdi, const uint8_t * buf, const long size)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
|
||||||
|
union data_command command = {
|
||||||
|
.command = {'D', 'A', 'T', 'A'},
|
||||||
|
.size = bswap(size),
|
||||||
|
.dest = bswap(0xac010000),
|
||||||
|
};
|
||||||
|
|
||||||
|
res = ftdi_write_data(ftdi, command.data, (sizeof (union data_command)));
|
||||||
|
assert(res >= 0);
|
||||||
|
|
||||||
|
const char * expect = "data\n";
|
||||||
|
const long expect_length = 5;
|
||||||
|
uint8_t read_buf[expect_length + 1];
|
||||||
|
read_buf[expect_length] = 0;
|
||||||
|
long read_length = read_with_timeout(ftdi, read_buf, expect_length);
|
||||||
|
if (read_length != expect_length) {
|
||||||
|
fprintf(stderr, "want %ld bytes; received: %ld\n", expect_length, read_length);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
res = memcmp(read_buf, expect, expect_length);
|
||||||
|
if (res != 0) {
|
||||||
|
fprintf(stderr, "expect `%s`; received: `%s`\n", expect, read_buf);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "OK\n");
|
||||||
|
|
||||||
|
struct timespec start;
|
||||||
|
struct timespec end;
|
||||||
|
res = clock_gettime(CLOCK_MONOTONIC, &start);
|
||||||
|
symmetric(ftdi, buf, size);
|
||||||
|
res = clock_gettime(CLOCK_MONOTONIC, &end);
|
||||||
|
fprintf(stderr, "symmetric time: %.03f\n", timespec_difference(&end, &start));
|
||||||
|
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char * argv[])
|
||||||
|
{
|
||||||
|
if (argc < 2) {
|
||||||
|
fprintf(stderr, "argc\n");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE * file = fopen(argv[1], "r");
|
||||||
|
if (file == NULL) {
|
||||||
|
fprintf(stderr, "fopen\n");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ret;
|
||||||
|
ret = fseek(file, 0L, SEEK_END);
|
||||||
|
if (ret < 0) {
|
||||||
|
fprintf(stderr, "seek(SEEK_END)");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
long off = ftell(file);
|
||||||
|
|
||||||
|
ret = fseek(file, 0L, SEEK_SET);
|
||||||
|
if (ret < 0) {
|
||||||
|
fprintf(stderr, "seek(SEEK_SET)");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "%s off %ld\n", argv[1], off);
|
||||||
|
uint8_t buf[off];
|
||||||
|
ssize_t size = fread(buf, 1, off, file);
|
||||||
|
if (size < 0) {
|
||||||
|
fprintf(stderr, "read");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = fclose(file);
|
||||||
|
if (ret < 0) {
|
||||||
|
fprintf(stderr, "close");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ftdi_context * ftdi;
|
||||||
|
|
||||||
|
ftdi = ftdi_new();
|
||||||
|
if (ftdi == 0) {
|
||||||
|
fprintf(stderr, "ftdi_new\n");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int res;
|
||||||
|
res = init_ftdi_context(ftdi);
|
||||||
|
if (res < 0) {
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct timespec start;
|
||||||
|
struct timespec end;
|
||||||
|
res = clock_gettime(CLOCK_MONOTONIC, &start);
|
||||||
|
int transfer_ret = transfer(ftdi, buf, off);
|
||||||
|
res = clock_gettime(CLOCK_MONOTONIC, &end);
|
||||||
|
|
||||||
|
fprintf(stderr, "time: %.03f\n", timespec_difference(&end, &start));
|
||||||
|
|
||||||
|
return transfer_ret;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user