Skip to content

Commit

Permalink
Commit the RDP demo before I mess it up.
Browse files Browse the repository at this point in the history
Signed-off-by: Tyler J. Stachecki <stachecki.tyler@gmail.com>
  • Loading branch information
tj90241 committed Dec 31, 2017
1 parent f5208d4 commit 1454d17
Show file tree
Hide file tree
Showing 8 changed files with 1,987 additions and 3 deletions.
1 change: 0 additions & 1 deletion libgfx/include/libgfx/init.h
Expand Up @@ -21,7 +21,6 @@ void libgfx_init(void);
static inline void libgfx_run(void) {
libn64_rsp_set_pc(0x04001000);
libn64_rsp_set_status(RSP_STATUS_CLEAR_HALT | RSP_STATUS_CLEAR_BROKE);
while ((libn64_rsp_get_status() & 0x3) != 0x3);
}

#endif
Expand Down
166 changes: 166 additions & 0 deletions libgfx/include/libgfx/rdp.h
@@ -0,0 +1,166 @@
//
// libgfx/include/libgfx/rdpcmd.h: RDP commands.
//
// n64chain: A (free) open-source N64 development toolchain.
// Copyright 2014-16 Tyler J. Stachecki <stachecki.tyler@gmail.com>
//
// This file is subject to the terms and conditions defined in
// 'LICENSE', which is part of this source code package.
//

#ifndef LIBGFX_INCLUDE_LIBGFX_RDPCMD_H
#define LIBGFX_INCLUDE_LIBGFX_RDPCMD_H

#include <libgfx/rspbuf.h>
#include <stdint.h>

// This file provides a bunch of functions which pack RAW RDP fields.
// An interface that is a bit more intelligent about cramming values
// should come later...
#define COLOR_ELEMENT_4B 0
#define COLOR_ELEMENT_8B 1
#define COLOR_ELEMENT_16B 2
#define COLOR_ELEMENT_32B 3

#define CYCLE_TYPE_1CYCLE (0ULL << 52)
#define CYCLE_TYPE_2CYCLE (1ULL << 52)
#define CYCLE_TYPE_COP (2ULL << 52)
#define CYCLE_TYPE_FILL (3ULL << 52)

#define FORMAT_RGBA 0
#define FORMAT_YUV 1
#define FORMAT_COLOR_INDEX 2
#define FORMAT_IA 3
#define FORMAT_I 4

#define SCISSOR_NO_INTERLACED 0
#define SCISSOR_INTERLACED 1
#define SCISSOR_DONTCARE 0
#define SCISSOR_KEEPEVEN 0
#define SCISSOR_KEEPODD 1

static inline uint32_t rdp_rgba16(
uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
uint16_t rgba16 = (r << 8) | ((g & 0xF8) << 3) | ((b & 0xF8) >> 2) | (a >> 7);
return (rgba16 << 16) | rgba16;
}

static inline uint32_t rdp_rgba32(
uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
return (r << 24) | (g << 16) | (b << 8) | a;
}

static inline void rsp_finalize(struct libgfx_rspbuf *rspbuf) {
libgfx_rspbuf_append(rspbuf, 0x00000000);
}

// The commands that follow are uCode commands. uCode commands can
// be quickly identified because they are always signed number (i.e.,
// bit 31 is signed).

// RSP Draw Triangle (given three vertex cache indexes)
static inline void rsp_draw_triangle(struct libgfx_rspbuf *rspbuf,
unsigned vert1, unsigned vert2, unsigned vert3) {

libgfx_rspbuf_append(rspbuf, 0xF000000F |
(vert1 << 20) | (vert2 << 12) | (vert3 << 4));
}

// The commands that follow are RDP commands. An interface which is
// a bit more intelligent about packing them should come in the future...

// RDP Fill Rectangle
static inline void rdp_fill_rectangle(struct libgfx_rspbuf *rspbuf,
float xh, float yh, float xl, float yl) {

uint16_t xhsc = xh * 4;
uint16_t yhsc = yh * 4;
uint16_t xlsc = xl * 4;
uint16_t ylsc = yl * 4;

libgfx_rspbuf_append(rspbuf, 0x36000000 |
((xlsc & 0xFFF) << 12) | (ylsc & 0xFFF));

libgfx_rspbuf_append(rspbuf,
((xhsc & 0xFFF) << 12) | (yhsc & 0xFFF));
}

// RDP Set Blend Color
static inline void rdp_set_blend_color(struct libgfx_rspbuf *rspbuf,
uint32_t rgba32) {

libgfx_rspbuf_append(rspbuf, 0x39000000);
libgfx_rspbuf_append(rspbuf, rgba32);
}

// RDP Set Color Image
static inline void rdp_set_color_image(struct libgfx_rspbuf *rspbuf,
unsigned format, unsigned size, unsigned width, uint32_t fb_origin) {

libgfx_rspbuf_append(rspbuf, 0x3F000000 |
(format << 21) | (size << 19) | width);

libgfx_rspbuf_append(rspbuf, fb_origin);
}

// RDP Set Fill Color
static inline void rdp_set_fill_color(struct libgfx_rspbuf *rspbuf,
uint32_t rgba) {

libgfx_rspbuf_append(rspbuf, 0x37000000);
libgfx_rspbuf_append(rspbuf, rgba);
}

// RDP Set Other Modes
static inline void rdp_set_other_modes(struct libgfx_rspbuf *rspbuf,
uint64_t bits) {

uint32_t bits_hi = bits >> 32;
uint32_t bits_lo = bits;

libgfx_rspbuf_append(rspbuf, 0x2F000000 | bits_hi);
libgfx_rspbuf_append(rspbuf, bits_lo);
}

// RDP Set Scissor
static inline void rdp_set_scissor(struct libgfx_rspbuf *rspbuf,
float xh, float yh, float xl, float yl, unsigned f, unsigned o) {

uint16_t xhsc = xh * 4;
uint16_t yhsc = yh * 4;
uint16_t xlsc = xl * 4;
uint16_t ylsc = yl * 4;

libgfx_rspbuf_append(rspbuf, 0x2D000000 |
((xhsc & 0xFFF) << 12) | (yhsc & 0xFFF));

libgfx_rspbuf_append(rspbuf, (f << 25) | (o << 24) |
((xlsc & 0xFFF) << 12) | (ylsc & 0xFFF));
}

// RDP Sync Full
static inline void rdp_sync_full(struct libgfx_rspbuf *rspbuf) {
libgfx_rspbuf_append(rspbuf, 0x29000000);
libgfx_rspbuf_append(rspbuf, 0x00000000);
}

// RDP Sync Load
static inline void rdp_sync_load(struct libgfx_rspbuf *rspbuf) {
libgfx_rspbuf_append(rspbuf, 0x26000000);
libgfx_rspbuf_append(rspbuf, 0x00000000);
}

// RDP Sync Pipe
static inline void rdp_sync_pipe(struct libgfx_rspbuf *rspbuf) {
libgfx_rspbuf_append(rspbuf, 0x27000000);
libgfx_rspbuf_append(rspbuf, 0x00000000);
}

// RDP Sync Tile
static inline void rdp_sync_tile(struct libgfx_rspbuf *rspbuf) {
libgfx_rspbuf_append(rspbuf, 0x28000000);
libgfx_rspbuf_append(rspbuf, 0x00000000);
}

#endif

4 changes: 2 additions & 2 deletions libgfx/ucodes/gfx.rsp
Expand Up @@ -8,7 +8,7 @@
.text
addiu $30, $0, VERTEX_CACHE_OFFSET
addiu COMMAND_POINTER, $0, 0x10
addiu OUTPUT_POINTER, $0, 0x100
addiu OUTPUT_POINTER, $0, 0x400

loop:
; Check if command is RSP processing command.
Expand All @@ -30,7 +30,7 @@ loop:

finish:
lui $at, 0x0400
ori $at, $at, 0x100
ori $at, $at, 0x400
mtc0 $at, CMD_START

lui $at, 0x0400
Expand Down
8 changes: 8 additions & 0 deletions libn64/ucodes/init.rsp
@@ -1,5 +1,10 @@
#include "defs.h"

.data
.half 0x0000 ; 0
.half 0x4000 ; 1/4
.half 0x0008 ; 8

.text

; Initialize the RSP (configure CP0, load constants, etc.)
Expand All @@ -12,6 +17,9 @@ init_rdp:
addiu $at, $0, (SET_XBUS_DMEM_DMA | CLEAR_FREEZE | CLEAR_FLUSH)
mtc0 $at, CMD_STATUS

; Load the magical constant vector register.
lqv $v31, 0x0($0)

; Raise an interrupt - we are done.
break
nop
Expand Down
125 changes: 125 additions & 0 deletions rdpdemo/Makefile
@@ -0,0 +1,125 @@
#
# Makefile for n64chain ROMs.
#
# n64chain: A (free) open-source N64 development toolchain.
# Copyright 2014-16 Tyler J. Stachecki <stachecki.tyler@gmail.com>
#
# This file is subject to the terms and conditions defined in
# 'LICENSE', which is part of this source code package.
#

ifdef SystemRoot
FIXPATH = $(subst /,\,$1)
RM = del /Q
else
FIXPATH = $1
RM = rm -f
endif

ROM_NAME = $(notdir $(CURDIR))

AS = $(call FIXPATH,$(CURDIR)/../tools/bin/mips64-elf-as)
AR = $(call FIXPATH,$(CURDIR)/../tools/bin/mips64-elf-gcc-ar)
CC = $(call FIXPATH,$(CURDIR)/../tools/bin/mips64-elf-gcc)
CPP = $(call FIXPATH,$(CURDIR)/../tools/bin/mips64-elf-cpp)
MAKE = $(call FIXPATH,$(CURDIR)/../tools/bin/make)
MKFS = $(call FIXPATH,$(CURDIR)/../tools/bin/mkfs)
OBJCOPY = $(call FIXPATH,$(CURDIR)/../tools/bin/mips64-elf-objcopy)

CHECKSUM = $(call FIXPATH,$(CURDIR)/../tools/bin/checksum)
RSPASM = $(call FIXPATH,$(CURDIR)/../tools/bin/rspasm)

# priv_include is not "advertised", but this is just a demo...
CFLAGS = -Wall -Wextra -pedantic -std=c99 -Wno-main \
-I../libn64/include -I../libgfx/include -I../libn64/priv_include -I.

OPTFLAGS = -Os -march=vr4300 -mtune=vr4300 -mabi=eabi -mgp32 -mlong32 \
-flto -ffat-lto-objects -ffunction-sections -fdata-sections \
-G4 -mno-extern-sdata -mgpopt -mfix4300 -mbranch-likely \
-mno-check-zero-division

ASMFILES = $(call FIXPATH,\
)

CFILES = $(call FIXPATH,\
src/main.c \
)

UCODES = $(call FIXPATH,\
$(wildcard ucodes/*.rsp) \
)

OBJFILES = \
$(ASMFILES:.S=.o) \
$(CFILES:.c=.o)

UCODETSKS = $(foreach ucode, $(UCODES),\
filesystem/$(basename $(notdir $(ucode))).tsk)

DEPFILES = $(OBJFILES:.o=.d)

#
# Primary targets.
#
all: $(ROM_NAME).z64

$(ROM_NAME).z64: $(ROM_NAME).elf
@echo $(call FIXPATH,"Building: $(ROM_NAME)/$@")
@$(OBJCOPY) -O binary $< $@
@$(CHECKSUM) $(call FIXPATH,../libn64/header.bin) $@

$(ROM_NAME).elf: libn64 libgfx $(OBJFILES) filesystem.obj
@echo $(call FIXPATH,"Building: $(ROM_NAME)/$@")
@$(CC) $(CFLAGS) $(OPTFLAGS) -Wl,-Map=$(ROM_NAME).map -nostdlib \
-T$(call FIXPATH,../libn64/rom.ld) -o $@ $(OBJFILES) filesystem.obj \
-L$(call FIXPATH,../libn64) -ln64 -L$(call FIXPATH,../libgfx) -lgfx

#
# Filesystem build target.
#
filesystem.obj: filesystem.h
@echo $(call FIXPATH,"Building: $(ROM_NAME)/$@")
@$(OBJCOPY) -I binary -O elf32-bigmips -B mips filesystem.bin $@

filesystem.h: $(wildcard filesystem/*) $(UCODETSKS)
@echo $(call FIXPATH,"Generate: $(ROM_NAME)/$@")
@$(MKFS) filesystem.bin filesystem.h filesystem

#
# Generic compilation/assembly targets.
#
%.o: %.S filesystem.h
@echo $(call FIXPATH,"Assembling: $(ROM_NAME)/$<")
@$(CC) $(CFLAGS) $(OPTFLAGS) -MMD -c $< -o $@

%.o: %.c filesystem.h
@echo $(call FIXPATH,"Compiling: $(ROM_NAME)/$<")
@$(CC) $(CFLAGS) $(OPTFLAGS) -MMD -c $< -o $@

filesystem/%.tsk: ucodes/%.rsp
@echo $(call FIXPATH,"Assembling: $(ROM_NAME)/$@")
@$(CPP) -E -I../libn64/ucodes -Iucodes $< | $(RSPASM) -o $@ -

.PHONY: libn64
libn64:
@$(MAKE) -sC $(call FIXPATH,../libn64)

.PHONY: libgfx
libgfx:
@$(MAKE) -sC $(call FIXPATH,../libgfx)

#
# Clean project target.
#
.PHONY: clean
clean:
@echo "Cleaning $(ROM_NAME)..."
@$(RM) $(ROM_NAME).map $(ROM_NAME).elf $(ROM_NAME).z64 \
$(DEPFILES) $(OBJFILES) $(UCODEBINS) filesystem.obj \
filesystem.bin filesystem.h

#
# Use computed dependencies.
#
-include $(DEPFILES)

0 comments on commit 1454d17

Please sign in to comment.