diff options
| author | Lameguy64 <lameguy64@gmail.com> | 2021-10-25 10:51:50 +0800 |
|---|---|---|
| committer | Lameguy64 <lameguy64@gmail.com> | 2021-10-25 10:51:50 +0800 |
| commit | 538f28cfbbbb8163ab8a96de77d6887123856c81 (patch) | |
| tree | a3108f05c038d0f43f2e96ae4d2d34ce4da225b4 | |
| parent | 7718b576b7aba725455ce510ee9632067a65f0d7 (diff) | |
| download | psn00bsdk-538f28cfbbbb8163ab8a96de77d6887123856c81.tar.gz | |
Added indev directory
| -rw-r--r-- | changelog.txt | 6 | ||||
| -rw-r--r-- | indev/README.md | 28 | ||||
| -rw-r--r-- | indev/psxmdec/data.s | 6 | ||||
| -rw-r--r-- | indev/psxmdec/main.c | 191 | ||||
| -rw-r--r-- | indev/psxmdec/makefile | 41 | ||||
| -rw-r--r-- | indev/psxmdec/mdec.s | 185 | ||||
| -rw-r--r-- | indev/psxmdec/output.bullschit | bin | 0 -> 43200 bytes | |||
| -rw-r--r-- | indev/psxmdec/table.h | 102 | ||||
| -rw-r--r-- | indev/psxmdec/vlc.c | 305 | ||||
| -rw-r--r-- | indev/psxpad/card.s | 377 | ||||
| -rw-r--r-- | indev/psxpad/main.c | 399 | ||||
| -rw-r--r-- | indev/psxpad/makefile | 39 | ||||
| -rw-r--r-- | indev/psxpad/pad.s | 264 |
13 files changed, 1943 insertions, 0 deletions
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 <sys/types.h>
+#include <stdio.h>
+#include <string.h>
+#include <malloc.h>
+#include <psxgte.h>
+#include <psxgpu.h>
+
+/* 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 Binary files differnew file mode 100644 index 0000000..4229da0 --- /dev/null +++ b/indev/psxmdec/output.bullschit 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 <sys/types.h>
+
+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()<<incnt;incnt-=16;}}
+
+#define Init_Buffer() {bitbuf = (mdec_bs[0]<<16)|(mdec_bs[1]);mdec_bs+=2;incnt = -16;}
+
+#define Get_Word() (*mdec_bs++)
+#define Printf printf
+
+int DecDCTvlc(Uint16 *mdec_bs,Uint16 *mdec_rl)
+{
+/* Uint16 *mdec_bs = mdecbs,*mdec_rl = mdecrl */
+ Uint16 *rl_end;
+ Uint32 bitbuf;
+ int incnt; /* 16-有効bit数 x86=char risc = long */
+ int q_code;
+ int type,n;
+ int last_dc[3];
+
+/* BS_HDR Uint16 rlsize,magic,ver,q_scale */
+
+ /* printf("%04x,%04x,",mdec_bs[0],mdec_bs[1]); */
+ *(long*)mdec_rl=*(long*)mdec_bs;
+ mdec_rl+=2;
+ rl_end = mdec_rl+(int)mdec_bs[0]*2;
+ q_code = (mdec_bs[2]<<10); /* code = q */
+ type = mdec_bs[3];
+ mdec_bs+=4;
+
+ Init_Buffer();
+
+ n = 0;
+ last_dc[0]=last_dc[1]=last_dc[2] = 0;
+ while(mdec_rl<rl_end) {
+ Uint32 code2;
+ /* DC */
+ if (type==2) {
+ code2 = Show_Bits(10)|(10<<16); /* DC code */
+ } else {
+ code2 = Show_Bits(6);
+ if (n>=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<<bit)-1);
+ if ((val&(1<<(bit-1)))==0)
+ val -= (1<<bit)-1;
+ val = (last_dc[2]+=val*4);
+ code2 = (nbit<<16) | (val&0x3ff);
+ }
+ /* printf("%d ",last_dc[2]); */
+ } else {
+ /* U,V */
+ if (code2<56) {
+ code2 = DC_UVtab0[code2];
+ code2 = (code2&0xffff0000)|((last_dc[n]+=VALOF(code2)*4)&0x3ff);
+ } else {
+ int nbit,val;
+ int bit = 4;
+ while(Show_Bits(bit)&1) { bit++;}
+ nbit = bit*2;
+ val = Show_Bits(nbit)&((1<<bit)-1);
+ if ((val&(1<<(bit-1)))==0)
+ val -= (1<<bit)-1;
+ val = (last_dc[n]+=val*4);
+ code2 = (nbit<<16) | (val&0x3ff);
+ }
+ /* printf("%d ",last_dc[n]); */
+ }
+ if (++n==6) n=0;
+ }
+ /* printf("%d ",VALOF(code2)); */
+ code2 |= q_code;
+
+ /* AC */
+ while(mdec_rl<rl_end){
+/* Uint32 code; */
+#define code code2
+#define SBIT 17
+ *mdec_rl++=code2;
+ Flush_Buffer(BITOF(code2));
+ code = Show_Bits(SBIT);
+ if (code>=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<rl_end);
+ return 0;
+ }
+ }
+ *mdec_rl++=code2; /* EOB code */
+ Flush_Buffer(2); /* EOB bitlen */
+ }
+ return 0;
+}
\ No newline at end of file diff --git a/indev/psxpad/card.s b/indev/psxpad/card.s new file mode 100644 index 0000000..2732194 --- /dev/null +++ b/indev/psxpad/card.s @@ -0,0 +1,377 @@ +.set noreorder + +.include "hwregs_a.h" + +.section .text + +_CardCSum: + + # a0 - base csum + # a1 - data pointer + # a2 - length + + lbu $v0, 0($a1) + addi $a2, -1 + xor $a0, $v0 + bgtz $a2, _CardCSum + addiu $a1, 1 + + jr $ra + move $v0, $a0 + + +.global _CardWrite +.type _CardWrite, @function +_CardWrite: + + # a0 - port number + # a1 - pointer to 128 byte buffer + # a2 - sector number + + # return values: + # 0 - ok + # 1 - no device + # 2 - timeout + # 3 - bad checksum + # 4 - bad sector + + # note: you must wait at least two vsyncs between each sector write + + 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 + li $v0, 310 # (needs optimization testing) + +# May cause issues with third party adapters such as Brook wireless +#.Lread_empty_fifo_write: # 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_write +# nop + + lhu $v1, JOY_CTRL($t0) + nop + or $v1, 0x10 + sh $v1, JOY_CTRL($t0) + + jal _CardExchng # Send device check byte + li $a0, 0x81 + andi $v1, $v0, 0x100 # No card if exchange timed out + bnez $v1, .Lno_device_write + addiu $v0, $0 , 1 + + jal _wait # 1st exchange needs 27microsec after ACK + li $v0, 190 # (e.g. 7 as usual + an extra 20) + + jal _CardExchng # Send write command + li $a0, 0x57 + andi $v1, $v0, 0x100 # No card if exchange timed out + bnez $v1, .Lno_device_write + addiu $v0, $0 , 1 + + jal _CardExchng # Receive card ID bytes + move $a0, $0 + andi $v1, $v0, 0x100 + bnez $v1, .Lwrite_timeout + addiu $v0, $0 , 2 + jal _CardExchng + move $a0, $0 + andi $v1, $v0, 0x100 + bnez $v1, .Lwrite_timeout + addiu $v0, $0 , 2 + + jal _CardExchng # Send address bytes + srl $a0, $a2, 8 + andi $v1, $v0, 0x100 + bnez $v1, .Lwrite_timeout + addiu $v0, $0 , 2 + jal _CardExchng + andi $a0, $a2, 0xFF + andi $v1, $v0, 0x100 + bnez $v1, .Lwrite_timeout + addiu $v0, $0 , 2 + + srl $t1, $a2, 8 # Checksum address by MSB xor LSB + andi $v0, $a2, 0xFF + xor $t1, $v0 + + move $a2, $0 # Send data and compute checksum +.Lwrite_loop: + lbu $a0, 0($a1) + addiu $a1, 1 + jal _CardExchng + xor $t1, $a0 + addiu $a2, 1 + blt $a2, 128, .Lwrite_loop + nop + + jal _CardExchng # Send checksum byte + move $a0, $t1 + andi $v1, $v0, 0x100 + bnez $v1, .Lwrite_timeout + addiu $v0, $0 , 2 + + jal _CardExchng # Receive card acknowledge bytes + move $a0, $0 + andi $v1, $v0, 0x100 + bnez $v1, .Lwrite_timeout + addiu $v0, $0 , 2 + jal _CardExchng + move $a0, $0 + andi $v1, $v0, 0x100 + bnez $v1, .Lwrite_timeout + addiu $v0, $0 , 2 + + sb $0 , JOY_TXRX($t0) # Gets end byte + nop +.Lsend_wait_end_write: + lhu $v0, JOY_STAT($t0) + nop + andi $v0, 0x6 + bne $v0, 0x6, .Lsend_wait_end_write + nop + lbu $v0, JOY_TXRX($t0) + nop + + beq $v0, 0x4e, .Lwrite_timeout # Bad checksum + addiu $v0, $0 , 3 + beq $v0, 0xff, .Lwrite_timeout # Bad sector + addiu $v0, $0 , 4 + + move $v0, $0 + +.Lwrite_timeout: +.Lno_device_write: + + sh $0 , JOY_CTRL($t0) # Apparently required + + lw $ra, 0($sp) + addiu $sp, 4 + jr $ra + nop + + +.global _CardRead +.type _CardRead, @function +_CardRead: + + # a0 - port number + # a1 - pointer to 128 byte buffer + # a2 - sector number + + addiu $sp, -12 + sw $ra, 0($sp) + sw $a1, 4($sp) + sw $a2, 8($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 + + lhu $v1, JOY_CTRL($t0) + nop + or $v1, 0x10 + sh $v1, JOY_CTRL($t0) + + jal _CardExchng # Send device check byte + li $a0, 0x81 + andi $v1, $v0, 0x100 # No card if exchange timed out + bnez $v1, .Lno_device + addiu $v0, $0 , 1 + + jal _wait # 1st exchange needs 27microsec after ACK + li $v0, 190 # (e.g. 7 as usual + an extra 20) + + jal _CardExchng # Send read command + li $a0, 0x52 + andi $v1, $v0, 0x100 # No card if exchange timed out + bnez $v1, .Lno_device + addiu $v0, $0 , 2 + + jal _CardExchng # Receive card ID bytes + move $a0, $0 + andi $v1, $v0, 0x100 + bnez $v1, .Lno_device + addiu $v0, $0 , 3 + jal _CardExchng + move $a0, $0 + andi $v1, $v0, 0x100 + bnez $v1, .Lno_device + addiu $v0, $0 , 4 + + jal _CardExchng # Send address + srl $a0, $a2, 8 + andi $v1, $v0, 0x100 + bnez $v1, .Lno_device + addiu $v0, $0 , 5 + jal _CardExchng + andi $a0, $a2, 0xFF + andi $v1, $v0, 0x100 + bnez $v1, .Lno_device + addiu $v0, $0 , 6 + + sb $0 , JOY_TXRX($t0) # Receive command acknowledge 1 + nop +.Lsend_wait: + lhu $v0, JOY_STAT($t0) + nop + andi $v0, 0x4 + beqz $v0, .Lsend_wait + nop + move $v1, $0 + lui $a0, 0xBFC0 +.Lwait_ack: + bgt $v1, 30000, .Lread_timeout + addiu $v0, $0, 10 + lhu $v0, JOY_STAT($t0) + lw $0 , 4($a0) + lw $0 , 0($a0) + andi $v0, 0x202 + bne $v0, 0x202, .Lwait_ack + addiu $v1, 1 + lhu $v1, JOY_CTRL($t0) + lbu $v0, JOY_TXRX($t0) + or $v1, 0x10 + sh $v1, JOY_CTRL($t0) + + jal _CardExchng # Receive command acknowledge 2 + move $a0, $0 + andi $v1, $v0, 0x100 + bnez $v1, .Lno_device + addiu $v0, $0 , 7 + + jal _CardExchng # Receive confirmed address MSB + move $a0, $0 + andi $v1, $v0, 0x100 + bnez $v1, .Lno_device + addiu $v0, $0 , 8 + + jal _CardExchng # Receive confirmed address LSB + move $a0, $0 + andi $v1, $v0, 0x100 + bnez $v1, .Lno_device + addiu $v0, $0 , 9 + + move $a2, $0 +.Ltransfer_loop: + jal _CardExchng + move $a0, $0 + sb $v0, 0($a1) + addiu $a2, 1 + blt $a2, 128, .Ltransfer_loop + addiu $a1, 1 + + jal _CardExchng # Gets checksum byte + move $a0, $0 + move $a3, $v0 + + sb $0 , JOY_TXRX($t0) # Gets end byte + nop +.Lsend_wait_end: + lhu $v1, JOY_STAT($t0) + nop + andi $v1, 0x6 + bne $v1, 0x6, .Lsend_wait_end + nop + lbu $v1, JOY_TXRX($t0) + nop + + lw $a2, 8($sp) + lw $a1, 4($sp) + andi $v1, $a2, 0xff + srl $a2, 8 + xor $a0, $a2, $v1 + jal _CardCSum + li $a2, 128 + + bne $v0, $a3, .Lno_device + addiu $v0, $0 , -1 + + move $v0, $0 +.Lread_timeout: +.Lno_device: + + sh $0 , JOY_CTRL($t0) # Apparently required + + lw $ra, 0($sp) + addiu $sp, 12 + jr $ra + nop + + +.global _CardExchng +.type _CardExchng, @function +_CardExchng: + + lui $t0, IOBASE + + sb $a0, JOY_TXRX($t0) + nop +.Lsend_wait_exchg: + lhu $v0, JOY_STAT($t0) + nop + andi $v0, 0x4 + beqz $v0, .Lsend_wait_exchg + nop + + lui $a0, 0xBFC0 + move $v1, $0 +.Lwait_ack_exchg: + bgt $v1, 500, .Ltimeout + lhu $v0, JOY_STAT($t0) + lw $0 , 4($a0) + lw $0 , 0($a0) + andi $v0, 0x202 + bne $v0, 0x202, .Lwait_ack_exchg + 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 diff --git a/indev/psxpad/main.c b/indev/psxpad/main.c new file mode 100644 index 0000000..e8a6181 --- /dev/null +++ b/indev/psxpad/main.c @@ -0,0 +1,399 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <malloc.h> +#include <psxetc.h> +#include <psxgte.h> +#include <psxgpu.h> +#include <psxapi.h> +#include <siofs.h> + +#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<bytes; i++ ) + { + *out = hex_tbl[in[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
+
+
|
