From 538f28cfbbbb8163ab8a96de77d6887123856c81 Mon Sep 17 00:00:00 2001 From: Lameguy64 Date: Mon, 25 Oct 2021 10:51:50 +0800 Subject: Added indev directory --- changelog.txt | 6 + indev/README.md | 28 +++ indev/psxmdec/data.s | 6 + indev/psxmdec/main.c | 191 ++++++++++++++++++++ indev/psxmdec/makefile | 41 +++++ indev/psxmdec/mdec.s | 185 +++++++++++++++++++ indev/psxmdec/output.bullschit | Bin 0 -> 43200 bytes indev/psxmdec/table.h | 102 +++++++++++ indev/psxmdec/vlc.c | 305 +++++++++++++++++++++++++++++++ indev/psxpad/card.s | 377 ++++++++++++++++++++++++++++++++++++++ indev/psxpad/main.c | 399 +++++++++++++++++++++++++++++++++++++++++ indev/psxpad/makefile | 39 ++++ indev/psxpad/pad.s | 264 +++++++++++++++++++++++++++ 13 files changed, 1943 insertions(+) create mode 100644 indev/README.md create mode 100644 indev/psxmdec/data.s create mode 100644 indev/psxmdec/main.c create mode 100644 indev/psxmdec/makefile create mode 100644 indev/psxmdec/mdec.s create mode 100644 indev/psxmdec/output.bullschit create mode 100644 indev/psxmdec/table.h create mode 100644 indev/psxmdec/vlc.c create mode 100644 indev/psxpad/card.s create mode 100644 indev/psxpad/main.c create mode 100644 indev/psxpad/makefile create mode 100644 indev/psxpad/pad.s diff --git a/changelog.txt b/changelog.txt index 3d7ee97..a7861b9 100644 --- a/changelog.txt +++ b/changelog.txt @@ -2,6 +2,12 @@ PSn00bSDK changelog Items that are lower in the log are more recently implemented. +10-25-2021 by Lameguy64: + +* Made a very tiny change in the readme file. + +* Included some of the indev directory from the SVN repository. + 10-17-2021 by spicyjpeg: diff --git a/indev/README.md b/indev/README.md new file mode 100644 index 0000000..2064a36 --- /dev/null +++ b/indev/README.md @@ -0,0 +1,28 @@ +# The indev directory + +This directory is intended to contain work-in-progress SDK components +(libraries, tools, etc) that are still in prototype stage. These files are +not to be compiled in a typical SDK installation but is added into the +main repo as the redundant SVN repo on the Lameguy64 website will soon be +retired. Contributed components that are in work-in-progress status may +also go into this directory. + +## Lameguy's indev components + +* psxmdec: Prototype component for performing BS image decoding using the + MDEC. Unfortunately I only got as far as returning garbled pixels from + the MDEC, which was pretty bull. + +* libpad: The early beginnings of a pad/card library using routines that + accesses the pad/card interfaces directly. Ideally PSn00bSDK's pad library + should include the functionality of pad/tap/gun peripherals into one + library as well as include functions for reading and writing memory card + sectors. Routines and callback hooks for directly controlling the pad/card + interface should also be provided to support homebrewn peripherals. + + The Github release of this work-in-progress component includes delay + corrections for PAL consoles. + +Work-in-progress components such as psxcd, interlace-exp, xptest and partest +are not included, as the former was completed while the remaining latter are +merely scrap test programs. \ No newline at end of file diff --git a/indev/psxmdec/data.s b/indev/psxmdec/data.s new file mode 100644 index 0000000..adf825a --- /dev/null +++ b/indev/psxmdec/data.s @@ -0,0 +1,6 @@ +.section .data + +.global bs_data +.type bs_data, @object +bs_data: + .incbin "output.bullschit" diff --git a/indev/psxmdec/main.c b/indev/psxmdec/main.c new file mode 100644 index 0000000..c9fd678 --- /dev/null +++ b/indev/psxmdec/main.c @@ -0,0 +1,191 @@ +#include +#include +#include +#include +#include +#include + +/* mdec.s */ +extern void mdec_reset( void ); +extern void mdec_setscale( void ); +extern void mdec_setquants( void ); +extern void mdec_cmd( unsigned int cmd ); +extern void mdec_in( void *src, int blocks ); +extern void mdec_out( void *dst, int blocks ); + +/* vlc.c */ +int DecDCTvlc( unsigned short *mdec_bs, unsigned short *mdec_rl ); + +/* data.s */ +extern unsigned short bs_data[]; + +DISPENV disp[2]; +DRAWENV draw[2]; +int db; + +void memory_browser(unsigned int addr) +{ + int i,j,key; + unsigned char *ptr,*pptr; + + while(1) + { + /* Set cursor position to top-left */ + printf("\033[1;1H"); + printf("MEMVIEW 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 0123456789ABCDEF"); + + ptr = (unsigned char*)addr; + + /* Print contents from current location of memory */ + for(j=0; j<23; j++) + { + printf("\n%04X: ", (unsigned int)ptr); + pptr = ptr; + for(i=0; i<16; i++) + { + printf("%02X ", *ptr); + ptr++; + } + printf(" "); + for(i=0; i<16; i++) + { + if(( *pptr < 32 ) || ( *pptr > 127 ) ) + { + printf("."); + } + else + { + printf("%c", *pptr); + } + pptr++; + } + } + + /* Parse input */ + while(1) + { + key = getchar(); + if( key == 0x1B ) + { + key = getchar(); + + if( key == 0x5B ) + { + key = getchar(); + if( key == 0x41 ) // Up + { + addr -= 16; + break; + } + else if( key == 0x42 ) // Down + { + addr += 16; + break; + } + if( key == 0x35 ) // Page up + { + addr -= 16*23; + break; + } + else if( key == 0x36 ) // Page down + { + addr += 16*23; + break; + } + } + } + + } + } + +} /* memory_browser */ + +void init( void ) +{ + ResetGraph( 0 ); + + SetDefDispEnv( &disp[0], 0, 0, 320, 240 ); + SetDefDispEnv( &disp[1], 0, 240, 320, 240 ); + + SetDefDrawEnv( &draw[0], 0, 240, 320, 240 ); + SetDefDrawEnv( &draw[1], 0, 0, 320, 240 ); + + draw[0].isbg = draw[1].isbg = 1; + setRGB0( &draw[0], 0, 63, 0 ); + setRGB0( &draw[1], 0, 63, 0 ); + + PutDispEnv( &disp[1] ); + PutDrawEnv( &draw[1] ); + db = 0; + +} /* init */ + +void display( void ) +{ + DrawSync( 0 ); + VSync( 0 ); + + PutDispEnv( &disp[db] ); + PutDrawEnv( &draw[db] ); + SetDispMask( 1 ); + + db = !db; + +} /* display */ + +void decode_test( void ) +{ + unsigned short *out_buff; + unsigned short *dec_buff; + int dec_len; + RECT rect; + int xx; + + out_buff = (unsigned short*)malloc( 131072 ); + dec_buff = (unsigned short*)malloc( 7680 ); + + memset( out_buff, 0, 131072 ); + DecDCTvlc( bs_data, out_buff ); + + dec_len = ((unsigned short*)out_buff)[0]; + + printf( "out_buff=%p len=%d\n", out_buff, dec_len ); + + //memory_browser( (unsigned int)(out_buff+2) ); + mdec_cmd( 0x38000000|dec_len ); + + mdec_in( out_buff+2, 8 ); + + rect.x = 320; rect.y = 0; + rect.w = 16; rect.h = 240; + xx = 0; + //while( xx < 320 ) + { + mdec_out( dec_buff, 120 ); + LoadImage( &rect, (unsigned int*)dec_buff ); + DrawSync( 0 ); + xx += 16; + rect.x += 16; + } + +} /* decode_test */ + +int main( int argc, const char *argv[] ) +{ + init(); + + /* init MDEC */ + mdec_reset(); + mdec_setscale(); + mdec_setquants(); + + decode_test(); + + while( 1 ) + { + display(); + } + + return( 0 ); + +} /* main */ diff --git a/indev/psxmdec/makefile b/indev/psxmdec/makefile new file mode 100644 index 0000000..3b921e0 --- /dev/null +++ b/indev/psxmdec/makefile @@ -0,0 +1,41 @@ +include ../../psn00bsdk-setup.mk + +TARGET = mdectest.elf + +CFILES = $(notdir $(wildcard *.c)) +CPPFILES = $(notdir $(wildcard *.cpp)) +AFILES = $(notdir $(wildcard *.s)) + +OFILES = $(addprefix build/,$(CFILES:.c=.o)) \ + $(addprefix build/,$(CPPFILES:.cpp=.o)) \ + $(addprefix build/,$(AFILES:.s=.o)) + +LIBS = -lpsxgpu -lpsxgte -lpsxspu -lpsxetc -lpsxapi -lc + +CFLAGS = -g -O2 -fno-builtin -fdata-sections -ffunction-sections + +CPPFLAGS = $(CFLAGS) -fno-exceptions + +AFLAGS = -g -msoft-float + +LDFLAGS = -g -Ttext=0x80010000 -gc-sections \ + -T $(GCC_BASE)/mipsel-unknown-elf/lib/ldscripts/elf32elmip.x + +all: $(OFILES) + $(LD) $(LDFLAGS) $(LIBDIRS) $(OFILES) $(LIBS) -o $(TARGET) + elf2x -q $(TARGET) + +build/%.o: %.c + @mkdir -p $(dir $@) + $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@ + +build/%.o: %.cpp + @mkdir -p $(dir $@) + $(CXX) $(AFLAGS) $(INCLUDE) -c $< -o $@ + +build/%.o: %.s + @mkdir -p $(dir $@) + $(CC) $(AFLAGS) $(INCLUDE) -c $< -o $@ + +clean: + rm -rf build $(TARGET) $(TARGET:.elf=.exe) \ No newline at end of file diff --git a/indev/psxmdec/mdec.s b/indev/psxmdec/mdec.s new file mode 100644 index 0000000..a7b5094 --- /dev/null +++ b/indev/psxmdec/mdec.s @@ -0,0 +1,185 @@ +.set noreorder + +.include "hwregs_a.h" + +.section .text + +.global mdec_reset # Resets the MDEC +.type mdec_reset, @function +mdec_reset: + + lui $a0, IOBASE + + lui $v0, 0xE000 # Reset MDEC + sw $v0, MDEC1($a0) + nop + + lui $v1, 0x8004 # Wait until reset completes +.Lreset_wait: + lw $v0, MDEC1($a0) + nop + bne $v0, $v1, .Lreset_wait + nop + + jr $ra + nop + + +.global mdec_cmd # Sends a MDEC command word +.type mdec_cmd, @function +mdec_cmd: + + lui $a1, IOBASE + +.Lcmd_ready: # Wait until command busy is zero + lw $v0, MDEC1($a1) + lui $v1, 0x2000 + and $v0, $v1 + bnez $v0, .Lcmd_ready + nop + + sw $a0, MDEC0($a1) # Write command word + + jr $ra + nop + +.global mdec_in # Transmit data to DMA0 (MDEC in) +.type mdec_in, @function +mdec_in: + + # a0 - data source address + # a1 - blocks to transfer (64 bytes per block) + + lui $a3, IOBASE + +.Lmdec_in_wait: # Wait until MDEC is ready for data + lw $v0, MDEC1($a3) + lui $v1, 0x1000 + and $v0, $v1 + beqz $v0, .Lmdec_in_wait + nop + + sw $a0, D0_MADR($a3) # Set source address + + andi $v0, $a1, 0xFFFF # Set transfer length + sll $v0, 16 + ori $v0, 0x20 # 32 word block size + sw $v0, D0_BCR($a3) + + lui $v0, 0x0100 # Begin transfer + ori $v0, 0x0201 + sw $v0, D0_CHCR($a3) + + jr $ra + nop + +.global mdec_out # Transmit data to DMA0 (MDEC in) +.type mdec_out, @function +mdec_out: + + # a0 - data source address + # a1 - blocks to transfer (64 bytes per block) + + lui $a3, IOBASE + +.Lmdec_out_ready: # Wait until MDEC is ready for data + lw $v0, MDEC1($a3) + lui $v1, 0x1000 + and $v0, $v1 + beqz $v0, .Lmdec_out_ready + nop + + sw $a0, D1_MADR($a3) # Set source address + + andi $v0, $a1, 0xFFFF # Set transfer length + sll $v0, 16 + ori $v0, 0x20 # 32 word block size + sw $v0, D1_BCR($a3) + + lui $v0, 0x0100 # Begin transfer + ori $v0, 0x0200 + sw $v0, D1_CHCR($a3) + +.Lmdec_out_wait: + lw $v0, D1_CHCR($a3) + lui $v1, 0x0200 + and $v0, $v1 + bnez $v0, .Lmdec_out_wait + nop + + jr $ra + nop + +.global mdec_setscale # Uploads the internal scaletable to MDEC +.type mdec_setscale, @function +mdec_setscale: + + addiu $sp, -4 + sw $ra, 0($sp) + + lui $a0, 0x6000 # Set scaletable command + jal mdec_cmd + nop + + la $a0, _mdec_scaletable # Upload scaletable + jal mdec_in + li $a1, 1 # 64 halfwords + + lw $ra, 0($sp) + addiu $sp, 4 + jr $ra + nop + + +.global mdec_setquants # Uploads the internal quant tables +.type mdec_setquants, @function +mdec_setquants: + + addiu $sp, -4 + sw $ra, 0($sp) + + lui $a0, 0x4000 # Set quant tables command + ori $a0, 0x0001 # luma + chroma data + jal mdec_cmd + nop + + la $a0, _mdec_qtables # Upload quant tables + jal mdec_in + li $a1, 2 # 128 halfwords + + lw $ra, 0($sp) + addiu $sp, 4 + jr $ra + nop + + +.section .data + +_mdec_qtables: + # taken from CCITT Rec. T.81 + .hword 16, 11, 10, 16, 24, 40, 51, 61 # Luma table + .hword 12, 12, 14, 19, 26, 58, 60, 55 + .hword 14, 13, 16, 24, 40, 57, 69, 56 + .hword 14, 17, 22, 29, 51, 87, 80, 62 + .hword 18, 22, 37, 56, 68, 109, 103, 77 + .hword 24, 35, 55, 64, 81, 104, 113, 92 + .hword 49, 64, 78, 87, 103, 121, 120, 101 + .hword 72, 92, 95, 98, 112, 100, 103, 99 + .hword 17, 18, 24, 47, 99, 99, 99, 99 # Chroma table + .hword 18, 21, 26, 66, 99, 99, 99, 99 + .hword 24, 26, 56, 99, 99, 99, 99, 99 + .hword 47, 66, 99, 99, 99, 99, 99, 99 + .hword 99, 99, 99, 99, 99, 99, 99, 99 + .hword 99, 99, 99, 99, 99, 99, 99, 99 + .hword 99, 99, 99, 99, 99, 99, 99, 99 + .hword 99, 99, 99, 99, 99, 99, 99, 99 + +_mdec_scaletable: + .hword 0x5A82,0x5A82,0x5A82,0x5A82,0x5A82,0x5A82,0x5A82,0x5A82 + .hword 0x7D8A,0x6A6D,0x471C,0x18F8,0xE707,0xB8E3,0x9592,0x8275 + .hword 0x7641,0x30FB,0xCF04,0x89BE,0x89BE,0xCF04,0x30FB,0x7641 + .hword 0x6A6D,0xE707,0x8275,0xB8E3,0x471C,0x7D8A,0x18F8,0x9592 + .hword 0x5A82,0xA57D,0xA57D,0x5A82,0x5A82,0xA57D,0xA57D,0x5A82 + .hword 0x471C,0x8275,0x18F8,0x6A6D,0x9592,0xE707,0x7D8A,0xB8E3 + .hword 0x30FB,0x89BE,0x7641,0xCF04,0xCF04,0x7641,0x89BE,0x30FB + .hword 0x18F8,0xB8E3,0x6A6D,0x8275,0x7D8A,0x9592,0x471C,0xE707 diff --git a/indev/psxmdec/output.bullschit b/indev/psxmdec/output.bullschit new file mode 100644 index 0000000..4229da0 Binary files /dev/null and b/indev/psxmdec/output.bullschit differ diff --git a/indev/psxmdec/table.h b/indev/psxmdec/table.h new file mode 100644 index 0000000..3e50b18 --- /dev/null +++ b/indev/psxmdec/table.h @@ -0,0 +1,102 @@ +const static huff_t table0[]={ + {6,3},{8,5},{10,6},{12,8},{76,9},{66,9},{20,11},{58,13},{48,13},{38,13},{32,13},{52,14},{50,14},{48,14},{46,14},{62,15},{60,15},{58,15},{56,15},{54,15},{52,15},{50,15},{48,15},{46,15},{44,15},{42,15},{40,15},{38,15},{36,15},{34,15},{32,15},{48,16},{46,16},{44,16},{42,16},{40,16},{38,16},{36,16},{34,16},{32,16}, +}; +const static huff_t table1[]={ + {6,4},{12,7},{74,9},{24,11},{54,13},{44,14},{42,14},{62,16},{60,16},{58,16},{56,16},{54,16},{52,16},{50,16},{38,17},{36,17},{34,17},{32,17}, +}; +const static huff_t table2[]={ + {10,5},{8,8},{22,11},{40,13},{40,14}, +}; +const static huff_t table3[]={ + {14,6},{72,9},{56,13},{38,14}, +}; +const static huff_t table4[]={ + {12,6},{30,11},{36,13}, +}; +const static huff_t table5[]={ + {14,7},{18,11},{36,14}, +}; +const static huff_t table6[]={ + {10,7},{60,13},{40,17}, +}; +const static huff_t table7[]={ + {8,7},{42,13}, +}; +const static huff_t table8[]={ + {14,8},{34,13}, +}; +const static huff_t table9[]={ + {10,8},{34,14}, +}; +const static huff_t table10[]={ + {78,9},{32,14}, +}; +const static huff_t table11[]={ + {70,9},{52,17}, +}; +const static huff_t table12[]={ + {68,9},{50,17}, +}; +const static huff_t table13[]={ + {64,9},{48,17}, +}; +const static huff_t table14[]={ + {28,11},{46,17}, +}; +const static huff_t table15[]={ + {26,11},{44,17}, +}; +const static huff_t table16[]={ + {16,11},{42,17}, +}; +const static huff_t table17[]={ + {62,13}, +}; +const static huff_t table18[]={ + {52,13}, +}; +const static huff_t table19[]={ + {50,13}, +}; +const static huff_t table20[]={ + {46,13}, +}; +const static huff_t table21[]={ + {44,13}, +}; +const static huff_t table22[]={ + {62,14}, +}; +const static huff_t table23[]={ + {60,14}, +}; +const static huff_t table24[]={ + {58,14}, +}; +const static huff_t table25[]={ + {56,14}, +}; +const static huff_t table26[]={ + {54,14}, +}; +const static huff_t table27[]={ + {62,17}, +}; +const static huff_t table28[]={ + {60,17}, +}; +const static huff_t table29[]={ + {58,17}, +}; +const static huff_t table30[]={ + {56,17}, +}; +const static huff_t table31[]={ + {54,17}, +}; +const static huff_t *huff_table[]={ + table0,table1,table2,table3,table4,table5,table6,table7,table8,table9,table10,table11,table12,table13,table14,table15,table16,table17,table18,table19,table20,table21,table22,table23,table24,table25,table26,table27,table28,table29,table30,table31, +}; +const static int maxlevel[]={ + 40,18,5,4,3,3,3,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +}; diff --git a/indev/psxmdec/vlc.c b/indev/psxmdec/vlc.c new file mode 100644 index 0000000..bc64a12 --- /dev/null +++ b/indev/psxmdec/vlc.c @@ -0,0 +1,305 @@ +#include + +typedef unsigned short Uint16; +typedef unsigned int Uint32; + +typedef struct { + unsigned int code,nbits; +} huff_t; + +#include "table.h" + +#define CODE1(a,b,c) (((a)<<10)|((b)&0x3ff)|((c)<<16)) +/* run, level, bit */ +#define CODE(a,b,c) CODE1(a,b,c+1),CODE1(a,-b,c+1) +#define CODE0(a,b,c) CODE1(a,b,c),CODE1(a,b,c) +#define CODE2(a,b,c) CODE1(a,b,c+1),CODE1(a,b,c+1) +#define RUNOF(a) ((a)>>10) +#define VALOF(a) ((short)((a)<<6)>>6) +#define BITOF(a) ((a)>>16) +#define EOB 0xfe00 +#define ESCAPE_CODE CODE1(63,0,6) +#define EOB_CODE CODE1(63,512,2) + +/* + DC code + Y U,V +0 100 00 0 +1 00x 01x -1,1 +2 01xx 10xx -3,-2,2,3 +3 101xxx 110xxx -7..-4,4..7 +4 110xxxx 1110 -15..-8,8..15 +5 1110xxxxx 11110 -31..-16,16..31 +6 11110xxxxxx 111110 -63..-32,32..63 +7 111110 1111110 -127..-64,64..127 +8 1111110 11111110 -255..-128,128..255 + 7+8 8+8 +*/ + +/* + This table based on MPEG2DEC by MPEG Software Simulation Group +*/ + +/* Table B-14, DCT coefficients table zero, +* codes 0100 ... 1xxx (used for all other coefficients) +*/ +static const Uint32 VLCtabnext[12*2] = { + CODE(0,2,4), CODE(2,1,4), CODE2(1,1,3), CODE2(1,-1,3), + CODE0(63,512,2), CODE0(63,512,2), CODE0(63,512,2), CODE0(63,512,2), /*EOB*/ + CODE2(0,1,2), CODE2(0,1,2), CODE2(0,-1,2), CODE2(0,-1,2) +}; + +/* Table B-14, DCT coefficients table zero, +* codes 000001xx ... 00111xxx +*/ +static const Uint32 VLCtab0[60*2] = { + CODE0(63,0,6), CODE0(63,0,6),CODE0(63,0,6), CODE0(63,0,6), /* ESCAPE */ + CODE2(2,2,7), CODE2(2,-2,7), CODE2(9,1,7), CODE2(9,-1,7), + CODE2(0,4,7), CODE2(0,-4,7), CODE2(8,1,7), CODE2(8,-1,7), + CODE2(7,1,6), CODE2(7,1,6), CODE2(7,-1,6), CODE2(7,-1,6), + CODE2(6,1,6), CODE2(6,1,6), CODE2(6,-1,6), CODE2(6,-1,6), + CODE2(1,2,6), CODE2(1,2,6), CODE2(1,-2,6), CODE2(1,-2,6), + CODE2(5,1,6), CODE2(5,1,6), CODE2(5,-1,6), CODE2(5,-1,6), + CODE(13,1,8), CODE(0,6,8), CODE(12,1,8), CODE(11,1,8), + CODE(3,2,8), CODE(1,3,8), CODE(0,5,8), CODE(10,1,8), + CODE2(0,3,5), CODE2(0,3,5), CODE2(0,3,5), CODE2(0,3,5), + CODE2(0,-3,5), CODE2(0,-3,5), CODE2(0,-3,5), CODE2(0,-3,5), + CODE2(4,1,5), CODE2(4,1,5), CODE2(4,1,5), CODE2(4,1,5), + CODE2(4,-1,5), CODE2(4,-1,5), CODE2(4,-1,5), CODE2(4,-1,5), + CODE2(3,1,5), CODE2(3,1,5), CODE2(3,1,5), CODE2(3,1,5), + CODE2(3,-1,5), CODE2(3,-1,5), CODE2(3,-1,5), CODE2(3,-1,5) +}; + +/* Table B-14, DCT coefficients table zero, +* codes 0000001000 ... 0000001111 +*/ +static const Uint32 VLCtab1[8*2] = { + CODE(16,1,10), CODE(5,2,10), CODE(0,7,10), CODE(2,3,10), + CODE(1,4,10), CODE(15,1,10), CODE(14,1,10), CODE(4,2,10) +}; + +/* Table B-14/15, DCT coefficients table zero / one, +* codes 000000010000 ... 000000011111 +*/ +static const Uint32 VLCtab2[16*2] = { + CODE(0,11,12), CODE(8,2,12), CODE(4,3,12), CODE(0,10,12), + CODE(2,4,12), CODE(7,2,12), CODE(21,1,12), CODE(20,1,12), + CODE(0,9,12), CODE(19,1,12), CODE(18,1,12), CODE(1,5,12), + CODE(3,3,12), CODE(0,8,12), CODE(6,2,12), CODE(17,1,12) +}; + +/* Table B-14/15, DCT coefficients table zero / one, +* codes 0000000010000 ... 0000000011111 +*/ +static const Uint32 VLCtab3[16*2] = { + CODE(10,2,13), CODE(9,2,13), CODE(5,3,13), CODE(3,4,13), + CODE(2,5,13), CODE(1,7,13), CODE(1,6,13), CODE(0,15,13), + CODE(0,14,13), CODE(0,13,13), CODE(0,12,13), CODE(26,1,13), + CODE(25,1,13), CODE(24,1,13), CODE(23,1,13), CODE(22,1,13) +}; + +/* Table B-14/15, DCT coefficients table zero / one, +* codes 00000000010000 ... 00000000011111 +*/ +static const Uint32 VLCtab4[16*2] = { + CODE(0,31,14), CODE(0,30,14), CODE(0,29,14), CODE(0,28,14), + CODE(0,27,14), CODE(0,26,14), CODE(0,25,14), CODE(0,24,14), + CODE(0,23,14), CODE(0,22,14), CODE(0,21,14), CODE(0,20,14), + CODE(0,19,14), CODE(0,18,14), CODE(0,17,14), CODE(0,16,14) +}; + +/* Table B-14/15, DCT coefficients table zero / one, +* codes 000000000010000 ... 000000000011111 +*/ +static const Uint32 VLCtab5[16*2] = { + CODE(0,40,15), CODE(0,39,15), CODE(0,38,15), CODE(0,37,15), + CODE(0,36,15), CODE(0,35,15), CODE(0,34,15), CODE(0,33,15), + CODE(0,32,15), CODE(1,14,15), CODE(1,13,15), CODE(1,12,15), + CODE(1,11,15), CODE(1,10,15), CODE(1,9,15), CODE(1,8,15) +}; + +/* Table B-14/15, DCT coefficients table zero / one, +* codes 0000000000010000 ... 0000000000011111 +*/ +static const Uint32 VLCtab6[16*2] = { + CODE(1,18,16), CODE(1,17,16), CODE(1,16,16), CODE(1,15,16), + CODE(6,3,16), CODE(16,2,16), CODE(15,2,16), CODE(14,2,16), + CODE(13,2,16), CODE(12,2,16), CODE(11,2,16), CODE(31,1,16), + CODE(30,1,16), CODE(29,1,16), CODE(28,1,16), CODE(27,1,16) +}; + +/* + DC code + Y U,V +0 100 00 0 +1 00x 01x -1,1 +2 01xx 10xx -3,-2,2,3 +3 101xxx 110xxx -7..-4,4..7 +4 110xxxx 1110xxxx -15..-8,8..15 +5 1110xxxxx 11110xxxxx -31..-16,16..31 +6 11110xxxxxx 111110xxxxxx -63..-32,32..63 +7 111110xxxxxxx 1111110xxxxxxx -127..-64,64..127 +8 1111110xxxxxxxx 11111110xxxxxxxx -255..-128,128..255 +*/ + +static const Uint32 DC_Ytab0[48] = { + CODE1(0,-1,3),CODE1(0,-1,3),CODE1(0,-1,3),CODE1(0,-1,3), + CODE1(0,-1,3),CODE1(0,-1,3),CODE1(0,-1,3),CODE1(0,-1,3), + CODE1(0,1,3),CODE1(0,1,3),CODE1(0,1,3),CODE1(0,1,3), + CODE1(0,1,3),CODE1(0,1,3),CODE1(0,1,3),CODE1(0,1,3), + + CODE1(0,-3,4),CODE1(0,-3,4),CODE1(0,-3,4),CODE1(0,-3,4), + CODE1(0,-2,4),CODE1(0,-2,4),CODE1(0,-2,4),CODE1(0,-2,4), + CODE1(0,2,4),CODE1(0,2,4),CODE1(0,2,4),CODE1(0,2,4), + CODE1(0,3,4),CODE1(0,3,4),CODE1(0,3,4),CODE1(0,3,4), + + CODE1(0,0,3),CODE1(0,0,3),CODE1(0,0,3),CODE1(0,0,3), + CODE1(0,0,3),CODE1(0,0,3),CODE1(0,0,3),CODE1(0,0,3), + CODE1(0,-7,6),CODE1(0,-6,6),CODE1(0,-5,6),CODE1(0,-4,6), + CODE1(0,4,6),CODE1(0,5,6),CODE1(0,6,6),CODE1(0,7,6), + +}; + +static const Uint32 DC_UVtab0[56] = { + CODE1(0,0,2),CODE1(0,0,2),CODE1(0,0,2),CODE1(0,0,2), + CODE1(0,0,2),CODE1(0,0,2),CODE1(0,0,2),CODE1(0,0,2), + CODE1(0,0,2),CODE1(0,0,2),CODE1(0,0,2),CODE1(0,0,2), + CODE1(0,0,2),CODE1(0,0,2),CODE1(0,0,2),CODE1(0,0,2), + + CODE1(0,-1,3),CODE1(0,-1,3),CODE1(0,-1,3),CODE1(0,-1,3), + CODE1(0,-1,3),CODE1(0,-1,3),CODE1(0,-1,3),CODE1(0,-1,3), + CODE1(0,1,3),CODE1(0,1,3),CODE1(0,1,3),CODE1(0,1,3), + CODE1(0,1,3),CODE1(0,1,3),CODE1(0,1,3),CODE1(0,1,3), + + CODE1(0,-3,4),CODE1(0,-3,4),CODE1(0,-3,4),CODE1(0,-3,4), + CODE1(0,-2,4),CODE1(0,-2,4),CODE1(0,-2,4),CODE1(0,-2,4), + CODE1(0,2,4),CODE1(0,2,4),CODE1(0,2,4),CODE1(0,2,4), + CODE1(0,3,4),CODE1(0,3,4),CODE1(0,3,4),CODE1(0,3,4), + + CODE1(0,-7,6),CODE1(0,-6,6),CODE1(0,-5,6),CODE1(0,-4,6), + CODE1(0,4,6),CODE1(0,5,6),CODE1(0,6,6),CODE1(0,7,6), +}; + +#define DCTSIZE2 64 + +/* decode one intra coded MPEG-1 block */ + +#define Show_Bits(N) (bitbuf>>(32-(N))) +/* 最小有効bit 17 bit*/ + +#define Flush_Buffer(N) {bitbuf <<=(N);incnt +=(N);while(incnt>=0) {bitbuf |= Get_Word()<=2) { + /* Y */ + if (code2<48) { + code2 = DC_Ytab0[code2]; + code2 = (code2&0xffff0000)|((last_dc[2]+=VALOF(code2)*4)&0x3ff); + } else { + int nbit,val; + int bit = 3; + while(Show_Bits(bit)&1) { bit++;} + bit++; + nbit = bit*2-1; + val = Show_Bits(nbit)&((1<=1<<(SBIT- 2)) { + code2 = VLCtabnext[(code>>12)-8]; + if (code2==EOB_CODE) break; + } + else if (code>=1<<(SBIT- 6)) { + code2 = VLCtab0[(code>>8)-8]; + if (code2==ESCAPE_CODE) { + Flush_Buffer(6); /* ESCAPE len */ + code2 = Show_Bits(16)| (16<<16); + } + } + else if (code>=1<<(SBIT- 7)) code2 = VLCtab1[(code>>6)-16]; + else if (code>=1<<(SBIT- 8)) code2 = VLCtab2[(code>>4)-32]; + else if (code>=1<<(SBIT- 9)) code2 = VLCtab3[(code>>3)-32]; + else if (code>=1<<(SBIT-10)) code2 = VLCtab4[(code>>2)-32]; + else if (code>=1<<(SBIT-11)) code2 = VLCtab5[(code>>1)-32]; + else if (code>=1<<(SBIT-12)) code2 = VLCtab6[(code>>0)-32]; + else { + do { + *mdec_rl++=EOB; + } while(mdec_rl +#include +#include +#include +#include +#include +#include +#include +#include + +#define OT_LEN 8 + +#define SCREEN_XRES 320 +#define SCREEN_YRES 240 + +#define CENTER_X SCREEN_XRES/2 +#define CENTER_Y SCREEN_YRES/2 + + +/* Display and drawing environments */ +DISPENV disp[2]; +DRAWENV draw[2]; + +char pribuff[2][16384]; /* Primitive packet buffers */ +unsigned int ot[2][OT_LEN]; /* Ordering tables */ +char *nextpri; /* Pointer to next packet buffer offset */ +int db = 0; /* Double buffer index */ + + +void init() { + + int i; + + /* Reset GPU (also installs event handler for VSync) */ + printf("Init GPU... "); + ResetGraph( 0 ); + printf("Done.\n"); + + + printf("Set video mode... "); + + /* Set display and draw environment parameters */ + SetDefDispEnv( &disp[0], 0, 0, SCREEN_XRES, SCREEN_YRES ); + SetDefDrawEnv( &draw[0], 0, SCREEN_YRES, SCREEN_XRES, SCREEN_YRES ); + SetDefDispEnv( &disp[1], 0, SCREEN_YRES, SCREEN_XRES, SCREEN_YRES ); + SetDefDrawEnv( &draw[1], 0, 0, SCREEN_XRES, SCREEN_YRES ); + + //disp[0].isinter = 1; /* Enable interlace (required for hires) */ + //disp[1].isinter = 1; + + /* Set clear color, area clear and dither processing */ + setRGB0( &draw[0], 63, 0, 127 ); + draw[0].isbg = 1; + draw[0].dtd = 1; + + setRGB0( &draw[1], 63, 0, 127 ); + draw[1].isbg = 1; + draw[1].dtd = 1; + + /* Apply the display and drawing environments */ + PutDispEnv( &disp[1] ); + PutDrawEnv( &draw[1] ); + + /* Enable video output */ + SetDispMask( 1 ); + + printf("Done.\n"); + + + FntLoad( 960, 0 ); + FntOpen( 8, 16, 304, 216, 0, 100 ); + +} + +extern void _InitPadDirect(void); +extern int _PadReadDirect(int port, unsigned char *data, int len); +extern int _CardRead(int port, unsigned char *data, int lba); +extern int _CardWrite(int port, unsigned char *data, int lba); +extern int _PadExchng(int byte); +extern void _PadSetPort(int port); + +extern unsigned char _pad_mot_values[]; + +unsigned char padbuff[2][34]; + + +char *hex_tbl = "0123456789ABCDEF"; + +void byte2str(unsigned char *in, int bytes, char *out) +{ + int i; + + for( i=0; i>4]; out++; + *out = hex_tbl[in[i]&0xF]; out++; + } + + *out = 0x0; +} + +unsigned char card_buff[128]; + +void dump_data(unsigned char *buff) +{ + int ix,iy; + + for( iy=0; iy<8; iy++ ) + { + for( ix=0; ix<16; ix++ ) + { + printf( "%02x", *buff ); + buff++; + } + printf( "\n" ); + } +} + +void TurnOnVibrators(void) +{ + _PadSetPort(0); + + if( _PadExchng(0x01) & 0x100 ) + { + ExitCriticalSection(); + return; + } + + if( _PadExchng(0x43) & 0x100 ) + { + ExitCriticalSection(); + return; + } + + _PadExchng(0x00); + _PadExchng(0x01); + + while( !(_PadExchng(0) & 0x100) ); + + _PadSetPort(2); + + ExitCriticalSection(); + VSync(0); + EnterCriticalSection(); + + // Set analog state + _PadSetPort(0); + + _PadExchng(0x01); + _PadExchng(0x4D); + _PadExchng(0x00); + + _PadExchng(0x00); + _PadExchng(0x01); + _PadExchng(0xFF); + _PadExchng(0xFF); + _PadExchng(0xFF); + _PadExchng(0xFF); + + _PadSetPort(2); + + ExitCriticalSection(); + VSync(0); + EnterCriticalSection(); + + // Exit configuration mode + _PadSetPort(0); + + _PadExchng(0x01); + _PadExchng(0x43); + _PadExchng(0x00); + _PadExchng(0x00); + + while( !(_PadExchng(0) & 0x100) ); + + _PadSetPort(2); + + ExitCriticalSection(); + VSync(0); +} + +void TurnOnAnalog(void) +{ + EnterCriticalSection(); + + // Enter configuration mode + _PadSetPort(0); + + if( _PadExchng(0x01) & 0x100 ) + { + ExitCriticalSection(); + return; + } + + if( _PadExchng(0x43) & 0x100 ) + { + ExitCriticalSection(); + return; + } + + _PadExchng(0x00); + _PadExchng(0x01); + + while( !(_PadExchng(0) & 0x100) ); + + _PadSetPort(2); + + ExitCriticalSection(); + VSync(0); + EnterCriticalSection(); + + // Set analog state + _PadSetPort(0); + + _PadExchng(0x01); + _PadExchng(0x44); + _PadExchng(0x00); + _PadExchng(0x01); // 0 - analog off, 1 - analog on + _PadExchng(0x02); + + while( !(_PadExchng(0) & 0x100) ); + + _PadSetPort(2); + + ExitCriticalSection(); + VSync(0); + EnterCriticalSection(); + + // Exit configuration mode + _PadSetPort(0); + + _PadExchng(0x01); + _PadExchng(0x43); + _PadExchng(0x00); + _PadExchng(0x00); + + while( !(_PadExchng(0) & 0x100) ); + + _PadSetPort(2); + + ExitCriticalSection(); + VSync(0); +} + +int main(int argc, const char* argv[]) { + + DR_TPAGE *tpri; + + int i,j,counter=0,fd; + char textbuff[64]; + char *memcard_image,*p; + + /* Init graphics and stuff before doing anything else */ + init(); + + _InitPadDirect(); + + + /* + if( fsInit(115200) >= 0 ) + { + printf("Loading memory card image... "); + + fd = fsOpen("cardimage.bin", FS_READ|FS_BINARY); + + if( fd < 0 ) + { + printf("File not found\n"); + } + else + { + memcard_image = (char*)malloc(131072); + + fsRead(fd, memcard_image, 131072); + + fsClose(fd); + + printf("Done.\n"); + + p = memcard_image; + for( j=0; j<1024; j++ ) + { + i = _CardWrite(0, p, j); + printf("Writing memory card (%d/1024)... \r", j); + if( i ) + printf("\nError %d at sector %d\n", i, j); + p += 128; + // Memory cards need at least 2 vsyncs between each write + // apparently + VSync(2); + } + + } + } + else + { + fd = -1; + memcard_image = NULL; + } + */ + + /* + for( j=0; j<1024; j++ ) + { + memset( card_buff, 0xff, 128 ); + i = _CardRead( 0, card_buff, j ); + + printf("Reading memory card (%d/1024)... \r", j); + + if( i != 0 ) + { + printf("\nPotential read error at sector %d\n", j); + } + + if( fd >= 0 ) + fsWrite(fd, (u_char*)card_buff, 128); + + if( i ) + break; + } + + if( fd >= 0 ) + fsClose(fd); + + printf("\nSuccessfully read entire memory card\n"); + */ + + /* + i = _CardRead( 0, card_buff, j ); + printf("Clearing memory card FAT.\n"); + memset( card_buff, 0xff, 128 ); + for(j=0; j<4; j++) + { + i = _CardWrite( 0, card_buff, 4 ); + printf("_CardWrite returned %d\n", i); + VSync(2); + } + */ + + + TurnOnAnalog(); + TurnOnVibrators(); + + /* Main loop */ + printf("Entering loop...\n"); + + while(1) { + + /* + if((counter>>4)&0x1) + { + _pad_mot_values[0] = 0xff; + } + else + { + _pad_mot_values[0] = 0x0; + } + */ + + i = _PadReadDirect(0, padbuff[0], 34); + //_PadReadDirect(1, padbuff[1], 34); + + FntPrint( -1, "HELLO WORLD %d\n", counter ); + + byte2str( padbuff[0], i, textbuff ); + FntPrint( -1, "P1:%s\n", textbuff ); + //byte2str( padbuff[1], 8, textbuff ); + //FntPrint( -1, "P2:%s\n", textbuff ); + + /* Clear ordering table and set start address of primitive */ + /* buffer for next frame */ + ClearOTagR( ot[db], OT_LEN ); + nextpri = pribuff[db]; + + + + /* Wait for GPU and VSync */ + FntFlush(-1); + DrawSync( 0 ); + VSync( 0 ); + + /* Since draw.isbg is non-zero this clears the screen */ + PutDispEnv( &disp[db] ); + PutDrawEnv( &draw[db] ); + + /* Begin drawing the new frame */ + DrawOTag( ot[db]+(OT_LEN-1) ); + + /* Alternate to the next buffer */ + db = !db; + + /* Increment counter for the snake animation */ + counter++; + + } + + return 0; + +} diff --git a/indev/psxpad/makefile b/indev/psxpad/makefile new file mode 100644 index 0000000..ab6a733 --- /dev/null +++ b/indev/psxpad/makefile @@ -0,0 +1,39 @@ +include ../../examples/sdk-common.mk + +TARGET = libpad.elf + +CFILES = $(notdir $(wildcard *.c)) +CPPFILES = $(notdir $(wildcard *.cpp)) +AFILES = $(notdir $(wildcard *.s)) + +OFILES = $(addprefix build/,$(CFILES:.c=.o) $(CPPFILES:.cpp=.o) $(AFILES:.s=.o)) + +INCLUDE += +LIBDIRS += + +LIBS = -lsiofs -lpsxsio -lpsxetc -lpsxgpu -lpsxgte -lpsxspu -lpsxapi -lc + +CFLAGS = -g -O2 -fno-builtin -fdata-sections -ffunction-sections +CPPFLAGS = $(CFLAGS) -fno-exceptions +AFLAGS = -g -msoft-float +LDFLAGS = -g -Ttext=0x80010000 -gc-sections -T $(GCC_BASE)/mipsel-unknown-elf/lib/ldscripts/elf32elmip.x + +CC = $(PREFIX)gcc +CXX = $(PREFIX)g++ +AS = $(PREFIX)as +LD = $(PREFIX)ld + +all: $(OFILES) + $(LD) $(LDFLAGS) $(LIBDIRS) $(OFILES) $(LIBS) -o $(TARGET) + elf2x -q $(TARGET) + +build/%.o: %.c + @mkdir -p $(dir $@) + $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@ + +build/%.o: %.s + @mkdir -p $(dir $@) + $(CC) $(AFLAGS) $(INCLUDE) -c $< -o $@ + +clean: + rm -rf build $(TARGET) $(TARGET:.elf=.exe) diff --git a/indev/psxpad/pad.s b/indev/psxpad/pad.s new file mode 100644 index 0000000..0fa66aa --- /dev/null +++ b/indev/psxpad/pad.s @@ -0,0 +1,264 @@ +.set noreorder + +.include "hwregs_a.h" + +.section .text + +.global _InitPadDirect +.type _InitPadDirect, @function +_InitPadDirect: + + addiu $sp, -4 + sw $ra, 0($sp) + + lui $t0, IOBASE + + # Interface setup + li $v0, 0x40 # Interface reset + sh $v0, JOY_CTRL($t0) + li $v0, 0x88 # 250kHz clock rate + sh $v0, JOY_BAUD($t0) + li $v0, 0x0d # 8-bit, no parity, x1 multiplier + sh $v0, JOY_MODE($t0) + li $v0, 0x1003 # JOY1, TX enabled + sh $v0, JOY_CTRL($t0) + + jal _wait + li $v0, 1000 + + # Empty RX fifo +.Lempty_fifo: + lbu $v1, JOY_TXRX($t0) + lhu $v0, JOY_STAT($t0) + nop + andi $v0, 0x2 + bnez $v0, .Lempty_fifo + nop + + lw $ra, 0($sp) + addiu $sp, 4 + jr $ra + nop + + +.global _PadSetPort +.type _PadSetPort, @function +_PadSetPort: + addiu $sp, -4 + sw $ra, 0($sp) + + lui $t0, IOBASE + + beq $a0, 2, .Lstop_comms + nop + + li $v0, 0x1003 # TX Enable, Joypad port select + andi $a0, 1 + sll $a0, 13 + or $v0, $a0 # Select port 2 if a0 is 1 + + sh $v0, JOY_CTRL($t0) # Set to Joypad control interface + + jal _wait # Delay for analog pads (needs testing) + li $v0, 500 + +.Lread_empty_fifo_set: # Flush the RX FIFO just in case + lbu $v1, JOY_TXRX($t0) + lhu $v0, JOY_STAT($t0) + nop + andi $v0, 0x2 + bnez $v0, .Lread_empty_fifo_set + nop + + lw $ra, 0($sp) + addiu $sp, 4 + jr $ra + nop + +.Lstop_comms: + + sh $0 , JOY_CTRL($t0) + + lw $ra, 0($sp) + addiu $sp, 4 + jr $ra + nop + + +.global _PadReadDirect +.type _PadReadDirect, @function +_PadReadDirect: + + # a0 - port number + # a1 - device data buffer + # a2 - data max length + + addiu $sp, -4 + sw $ra, 0($sp) + + lui $t0, IOBASE + + li $v0, 0x1003 # TX Enable, Joypad port select + andi $a0, 1 + sll $a0, 13 + or $v0, $a0 # Select port 2 if a0 is 1 + + sh $v0, JOY_CTRL($t0) # Set to Joypad control interface + + jal _wait # Delay for analog pads (needs testing) + li $v0, 310 + +# May cause issues with third party adapters such as Brook wireless +#.Lread_empty_fifo: # Flush the RX FIFO just in case +# lbu $v1, JOY_TXRX($t0) +# lhu $v0, JOY_STAT($t0) +# nop +# andi $v0, 0x2 +# bnez $v0, .Lread_empty_fifo +# nop + + jal _PadExchng # Send device check byte + li $a0, 0x01 + + andi $v1, $v0, 0x100 # No pad if exchange timed out + bnez $v1, .Lno_device + addiu $v0, $0 , 1 + + sb $v0, 0($a1) + addiu $a1, 1 + + jal _wait # 1st exchange needs 27microsec after ACK + li $v0, 190 # (e.g. 7 as usual + an extra 20) + + jal _PadExchng # Send command byte + li $a0, 0x42 + + sb $v0, 0($a1) + addiu $a1, 1 + addiu $a2, -2 + + jal _PadExchng # Send 0 for pads, 1 for multitap + move $a0, $0 # Read is usually 0x5A + + addi $a3, $0 , 1 + + la $t1, _pad_mot_values + +.Lread_loop: # Read until buffer full, or no more data + + lbu $a0, 0($t1) + nop + beqz $a0, .Lskip_mot + nop + + jal _PadExchng + nop + + b .Ldone_exchg + addiu $t1, 1 + +.Lskip_mot: + + jal _PadExchng # when ACK is no longer triggered + move $a0, $0 + +.Ldone_exchg: + + sb $v0, 0($a1) + + andi $v0, 0x100 + bnez $v0, .Lread_end + addi $a3, 1 + + addiu $a2, -1 + bgtz $a2, .Lread_loop + addiu $a1, 1 + +.Lread_end: + + b .Lexit + move $v0, $a3 + +.Lno_device: + + addiu $v0, $0 , -1 + sb $v0, 0($a1) + +.Lexit: + + sh $0 , JOY_CTRL($t0) + + lw $ra, 0($sp) + addiu $sp, 4 + jr $ra + nop + + +.global _PadExchng +.type _PadExchng, @function +_PadExchng: + + lui $t0, IOBASE + + sb $a0, JOY_TXRX($t0) + nop +.Lsend_wait: + lhu $v0, JOY_STAT($t0) + nop + andi $v0, 0x4 + beqz $v0, .Lsend_wait + nop + + move $v1, $0 +.Lwait_ack: + bgt $v1, 100, .Ltimeout + lhu $v0, JOY_STAT($t0) + nop + andi $v0, 0x202 + bne $v0, 0x202, .Lwait_ack + addiu $v1, 1 + + b .Ldone + nop + +.Ltimeout: + + lbu $v0, JOY_TXRX($t0) + nop + b .Lexit_exchg + ori $v0, 0x100 + +.Ldone: + + lhu $v1, JOY_CTRL($t0) + lbu $v0, JOY_TXRX($t0) + or $v1, 0x10 + sh $v1, JOY_CTRL($t0) + +.Lexit_exchg: + + jr $ra + nop + + +.global _wait +.type _wait, @function +_wait: + addiu $v0, -1 + bgtz $v0, _wait + nop + jr $ra + nop + + +.section .data + +.global _pad_mot_values +.type _pad_mot_values, @object +_pad_mot_values: + .byte 0 # Small motor + .byte 0 # Big motor + .byte 0 + .byte 0 + + -- cgit v1.2.3