>= 1;
74 | srcShift++;
75 | }
76 |
77 | *dstL++= dstBuf;
78 | }
79 | }
80 |
81 | // EOF
82 |
--------------------------------------------------------------------------------
/rom-db-ui/app/page.tsx:
--------------------------------------------------------------------------------
1 | import fs from 'fs';
2 | import path from 'path';
3 | import SearchComponent from './SearchComponent';
4 |
5 | function getScreenshotFolders() {
6 | try {
7 | const screenshotsPath = path.resolve(process.cwd(), 'public/screenshots/');
8 |
9 | if (!fs.existsSync(screenshotsPath)) {
10 | console.error('Screenshots directory not found');
11 | return [];
12 | }
13 |
14 | const entries = fs.readdirSync(screenshotsPath, { withFileTypes: true });
15 |
16 | return entries
17 | .filter(entry => entry.isDirectory())
18 | .map(dir => dir.name);
19 |
20 | } catch (error) {
21 | console.error('Error fetching screenshot folders:', error);
22 | return [];
23 | }
24 | }
25 |
26 | function getImagesInFolder(folderName: string) {
27 | try {
28 | const folderPath = path.resolve(process.cwd(), 'public/screenshots/', folderName);
29 | const entries = fs.readdirSync(folderPath);
30 |
31 | // only include .png files
32 | const filteredEntries = entries.filter(file => file.toLowerCase().endsWith('.png'));
33 |
34 | // sort by filename (number)
35 | filteredEntries.sort((a, b) => parseInt(a) - parseInt(b));
36 |
37 | return filteredEntries;
38 | } catch (error) {
39 | console.error(`Error reading images from folder ${folderName}:`, error);
40 | return [];
41 | }
42 | }
43 |
44 | export default function ScreenshotsPage() {
45 | const folders = getScreenshotFolders();
46 |
47 | const folderImages = folders.map(folder => {
48 | const images = getImagesInFolder(folder);
49 | return { folder, images };
50 | });
51 |
52 | return (
53 |
54 |
55 |
56 | );
57 | }
58 |
--------------------------------------------------------------------------------
/external/tonc/code/basic/hello/Makefile:
--------------------------------------------------------------------------------
1 | #
2 | # hello.mak
3 | #
4 | # tilemap text via tonclib
5 | #
6 | # NOTE: for educational purposes only. For real work, use
7 | # devkitPro's templates ( $(DEVKITPRO)/examples/gba/template )
8 | # or tonclib's templates ( $(TONCCODE)/lab/template )
9 |
10 | PATH := $(DEVKITARM)/bin:$(PATH)
11 |
12 | # --- Project details -------------------------------------------------
13 |
14 | PROJ := hello
15 | TITLE := $(PROJ)
16 |
17 | LIBTONC := ../../tonclib
18 |
19 | INCLUDE := -I$(LIBTONC)/include
20 | LIBPATHS := -L$(LIBTONC)/lib
21 |
22 | LIBS := -ltonc
23 |
24 | COBJS := $(PROJ).o
25 |
26 | OBJS := $(COBJS)
27 |
28 | # --- boot type (MB=0 : normal. MB=1 : multiboot) ---
29 |
30 | MB = 0
31 |
32 | ifeq ($(MB),1)
33 |
34 | TARGET := $(PROJ).mb
35 | SPECS := -specs=gba_mb.specs
36 |
37 | else
38 |
39 | TARGET := $(PROJ)
40 | SPECS := -specs=gba.specs
41 |
42 | endif
43 |
44 | # --- Compiling -------------------------------------------------------
45 |
46 | CROSS ?= arm-none-eabi-
47 | AS := $(CROSS)as
48 | CC := $(CROSS)gcc
49 | LD := $(CROSS)gcc
50 | OBJCOPY := $(CROSS)objcopy
51 |
52 |
53 | ARCH := -mthumb-interwork -mthumb
54 |
55 | ASFLAGS := -mthumb-interwork
56 | CFLAGS := $(ARCH) $(INCLUDE) -O2 -Wall -fno-strict-aliasing
57 | LDFLAGS := $(ARCH) $(SPECS) $(LIBPATHS) $(LIBS) -Wl,-Map,$(PROJ).map
58 |
59 | .PHONY : build clean
60 |
61 | # --- Build -----------------------------------------------------------
62 |
63 | build : $(TARGET).gba
64 |
65 |
66 | $(TARGET).gba : $(TARGET).elf
67 | $(OBJCOPY) -v -O binary $< $@
68 | -@gbafix $@ -t$(TITLE)
69 |
70 | $(TARGET).elf : $(OBJS)
71 | $(LD) $^ $(LDFLAGS) -o $@
72 |
73 | $(COBJS) : %.o : %.c
74 | $(CC) $(CFLAGS) -c $< -o $@
75 |
76 | # --- Clean -----------------------------------------------------------
77 |
78 | clean :
79 | @rm -fv *.gba
80 | @rm -fv *.elf
81 | @rm -fv *.o
82 |
83 | #EOF
84 |
--------------------------------------------------------------------------------
/external/tonc/code/tonclib/include/tonc.h:
--------------------------------------------------------------------------------
1 | //
2 | // Main tonc header
3 | //
4 | //! \file tonc.h
5 | //! \author J Vijn
6 | //! \date 20060508 - 20080825
7 | //
8 | // === NOTES ===
9 |
10 |
11 | #ifndef TONC_MAIN
12 | #define TONC_MAIN
13 |
14 | #ifdef __cplusplus
15 | extern "C" {
16 | #endif
17 |
18 | #include "tonc_types.h"
19 | #include "tonc_memmap.h"
20 | #include "tonc_memdef.h"
21 |
22 | #include "tonc_bios.h"
23 | #include "tonc_core.h"
24 | #include "tonc_input.h"
25 | #include "tonc_irq.h"
26 | #include "tonc_math.h"
27 | #include "tonc_oam.h"
28 | #include "tonc_tte.h"
29 | #include "tonc_video.h"
30 | #include "tonc_surface.h"
31 |
32 | #include "tonc_nocash.h"
33 |
34 | // For old times' sake
35 | #include "tonc_text.h"
36 |
37 | #ifdef __cplusplus
38 | };
39 | #endif
40 |
41 | // --- Doxygen modules: ---
42 |
43 | /*! \defgroup grpBios Bios Calls */
44 | /*! \defgroup grpCore Core */
45 | /*! \defgroup grpDma DMA */
46 | /*! \defgroup grpInput Input */
47 | /*! \defgroup grpIrq Interrupt */
48 | /*! \defgroup grpMath Math */
49 | /*! \defgroup grpMemmap Memory Map */
50 | /*! \defgroup grpAudio Sound */
51 | /*! \defgroup grpTTE Tonc Text Engine */
52 | /*! \defgroup grpText Old Text */
53 | /*! \defgroup grpTimer Timer */
54 | /*! \defgroup grpVideo Video */
55 |
56 |
57 |
58 | /*! \mainpage Tonclib 1.4 (20080825)
59 |
60 | Tonclib is the library accompanying the set of GBA tutorials known
61 | as Tonc Initially, it
62 | was just a handful of macros and functions for dealing with the
63 | GBA hardware: the memory map and its bits, affine transformation
64 | code and things like that. More recently, more general items
65 | have been added like tonccpy() and toncset(), the TSurface system
66 | and TTE. All these items should provide a firm basis on which to
67 | build GBA software.
68 |
69 | */
70 |
71 | #endif // TONC_MAIN
72 |
73 |
--------------------------------------------------------------------------------
/external/tonc/code/lab/template/gba-tonc-fix.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # Converts names from template to project-specific stuff, based on the
4 | # directory name. Changes minor things in Makefile and PN2 project files.
5 | #
6 | # Usage :
7 | # - Copy template folder.
8 | # - Rename folder.
9 | # - Run script. This file will also remove itself once you're done.
10 | #
11 | # 'Pre-usage' considerations:
12 | # - Set the library paths to point to the right folders on your system.
13 |
14 | # ---------------------------------------------------------------------
15 | # Variables
16 | # ---------------------------------------------------------------------
17 |
18 | files="template.pnproj template.ppg Makefile"
19 | projdir=$(dirname $0)
20 | proj=$(basename $projdir)
21 |
22 |
23 | # Full path of the library itself, in platform-specific format.
24 | # Yeah, it's ugly, but apparently the only way to get it right.
25 | libtonc=e:/dev/gba/proj/tonc/code/tonclib
26 |
27 | # Replacement list, space separated.
28 | sedlist="PROJNAME=$proj LIBTONC=$libtonc"
29 |
30 | # ---------------------------------------------------------------------
31 | # Actual script
32 | # ---------------------------------------------------------------------
33 |
34 | # Construct sed-script for conversions.
35 | for item in $sedlist ; do
36 | sedcmd="$sedcmd -e s#\[\[${item/=/\]\]#}#g"
37 | done
38 |
39 | # Apply conversions for appropriate files.
40 | # NOTE: if I don't do this by using an intermediate file, things go squirrily.
41 | for file in $files
42 | do
43 | if [ -e $file ] ; then
44 | echo Converting: $file
45 | dst=${file/template/$proj} # Filename conversion.
46 | sed $sedcmd $file > $dst.t # File content conversion.
47 | rm -f $file
48 | mv $dst.t $dst
49 | fi
50 | done
51 |
52 | # Remove this script if not in the template directory.
53 | if [ "$proj" != "template" ] && [ "$proj" != "nds-forge" ] ; then
54 | echo "This file will self-destruct in 3 ... 2 ... 1 ..."
55 | rm -f $0
56 | fi
57 |
--------------------------------------------------------------------------------
/external/tonc/code/basic/second/toolbox.h:
--------------------------------------------------------------------------------
1 | // toolbox.h:
2 | //
3 | // Tools header for second.c
4 | //
5 | // (20060211-20060922, cearn)
6 | //
7 | // === NOTES ===
8 | // * This is a _small_ set of typedefs, #defines and inlines that can
9 | // be found in tonclib, and might not represent the
10 | // final forms.
11 |
12 |
13 | #ifndef TOOLBOX_H
14 | #define TOOLBOX_H
15 |
16 | // === (from tonc_types.h) ============================================
17 |
18 | typedef unsigned char u8;
19 | typedef unsigned short u16;
20 | typedef unsigned int u32;
21 |
22 | typedef u16 COLOR;
23 |
24 | #define INLINE static inline
25 |
26 | // === (from tonc_memmap.h) ===========================================
27 |
28 | #define MEM_IO 0x04000000
29 | #define MEM_VRAM 0x06000000
30 |
31 | #define REG_DISPCNT *((u32*)(MEM_IO+0x0000))
32 |
33 | // === (from tonc_memdef.h) =======================================----
34 |
35 | // --- REG_DISPCNT defines ---
36 | #define DCNT_MODE0 0x0000
37 | #define DCNT_MODE1 0x0001
38 | #define DCNT_MODE2 0x0002
39 | #define DCNT_MODE3 0x0003
40 | #define DCNT_MODE4 0x0004
41 | #define DCNT_MODE5 0x0005
42 | // layers
43 | #define DCNT_BG0 0x0100
44 | #define DCNT_BG1 0x0200
45 | #define DCNT_BG2 0x0400
46 | #define DCNT_BG3 0x0800
47 | #define DCNT_OBJ 0x1000
48 |
49 |
50 | // === (from tonc_video.h) ============================================
51 |
52 | #define SCREEN_WIDTH 240
53 | #define SCREEN_HEIGHT 160
54 |
55 | #define vid_mem ((u16*)MEM_VRAM)
56 |
57 | INLINE void m3_plot(int x, int y, COLOR clr)
58 | { vid_mem[y*SCREEN_WIDTH+x]= clr; }
59 |
60 | #define CLR_BLACK 0x0000
61 | #define CLR_RED 0x001F
62 | #define CLR_LIME 0x03E0
63 | #define CLR_YELLOW 0x03FF
64 | #define CLR_BLUE 0x7C00
65 | #define CLR_MAG 0x7C1F
66 | #define CLR_CYAN 0x7FE0
67 | #define CLR_WHITE 0x7FFF
68 |
69 |
70 | INLINE COLOR RGB15(u32 red, u32 green, u32 blue)
71 | { return red | (green<<5) | (blue<<10); }
72 |
73 | #endif // TOOLBOX_H
74 |
75 | // EOF
76 |
--------------------------------------------------------------------------------
/gba-core/src/arm7tdmi/pipeline.rs:
--------------------------------------------------------------------------------
1 | use super::decoder::Instruction;
2 | use crate::memory::mmio::Mmio;
3 | use std::fmt::Display;
4 | use tracing::*;
5 |
6 | pub struct State {
7 | pub pc: u32,
8 | pub opcode: u32,
9 | pub is_thumb: bool,
10 | }
11 |
12 | pub struct Pipeline {
13 | states: Vec,
14 | }
15 |
16 | impl Pipeline {
17 | pub fn new() -> Pipeline {
18 | Pipeline {
19 | states: Vec::with_capacity(3),
20 | }
21 | }
22 |
23 | pub fn advance(&mut self, pc: u32, is_thumb: bool, mmio: &mut Mmio) {
24 | let opcode = mmio.read_u32(pc);
25 | self.states.push(State { pc, opcode, is_thumb });
26 | }
27 |
28 | pub fn pop(&mut self) -> Option<(Instruction, State)> {
29 | if self.states.len() < 3 {
30 | return None;
31 | }
32 |
33 | let state = self.states.remove(0);
34 | let instr = Instruction::decode(state.opcode, state.is_thumb).unwrap_or_else(|e| {
35 | error!(target: "pipeline", "Failed to decode instruction: {:?} at {:08X}", e, state.pc);
36 | Instruction::nop()
37 | });
38 |
39 | Some((instr, state))
40 | }
41 |
42 | pub fn flush(&mut self) {
43 | self.states.clear();
44 | }
45 |
46 | pub fn peek_fetch(&self) -> Option<&State> {
47 | self.states.last()
48 | }
49 |
50 | pub fn is_full(&self) -> bool {
51 | self.states.len() >= 3
52 | }
53 |
54 | pub fn is_empty(&self) -> bool {
55 | self.states.is_empty()
56 | }
57 | }
58 |
59 | impl Display for Pipeline {
60 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
61 | write!(f, "Pipeline: [")?;
62 | for (i, state) in self.states.iter().enumerate() {
63 | if i > 0 {
64 | write!(f, ", ")?;
65 | }
66 | write!(f, "{:08X} @ {:08X}", state.opcode, state.pc)?;
67 | }
68 | write!(f, "]")
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/external/tonc/code/adv/m7_ex/source/id_sort_shell.s:
--------------------------------------------------------------------------------
1 | @
2 | @ id_sort_shell2: general shellsort unsing an index table
3 | @ MAXCOUNT: 256
4 | @ === NOTES: ===
5 | @ * changed from oe->fill keys to int keys after completion;
6 | @ not fully optimised for that yet.
7 |
8 | .section .iwram,"ax",%progbits
9 | .align 2
10 | @ DECL: CODE_IN_IWRAM void id_sort_shell(int keys[], u8 ids[], int count)
11 | @ r0: sort key (oe.fill)
12 | @ r1: sort indices
13 | @ r2: array length
14 | @ r3: inc
15 | @ r4, r5, r6: inc, ii, jj, jj-inc
16 | @ r7: id= ids[jj-inc]
17 | @ r8, r9: id0=ids[ii], key0=fill[ids[ii]]
18 | @ r10: fill[id]
19 | @ r12: (1<<32)/3
20 | .global id_sort_shell
21 | id_sort_shell:
22 | stmfd sp!, {r4-r10}
23 | @ TODO: special for count==1
24 | @ setup inc: inc= 3*inc+1
25 | mov r3, #0
26 | .Lshell_inc_setup:
27 | rsb r3, r3, r3, lsl #2
28 | add r3, r3, #1
29 | cmp r3, r2
30 | ble .Lshell_inc_setup
31 | ldr r12, .Lshell_pool
32 | @ inc loop
33 | .Lshell_inc_loop:
34 | umull r5, r4, r12, r3 @ ii= inc/3
35 | mov r3, r4 @ inc= ii
36 | cmp r3, r2 @ ii>count
37 | bgt .Lshell_up_loop_end
38 | @ ii=inc to nn loop
39 | .Lshell_up_loop:
40 | ldrb r8, [r1, r4] @ id0= ids[ii]
41 | ldr r9, [r0, r8, lsl #2] @ key0= fill[ids[ii]]
42 | mov r5, r4 @ jj= ii
43 | sub r6, r5, r3 @ jnext= jj-inc
44 | @ jj=ii to 0 loop
45 | .Lshell_down_loop:
46 | ldrb r7, [r1, r6]
47 | ldr r10, [r0, r7, lsl #2]
48 | cmp r10, r9 @ fill[id] > key0
49 | ble .Lshell_down_loop_end
50 | strb r7, [r1, r5] @ PONDER: xxxgt?
51 | mov r5, r6
52 | subs r6, r5, r3
53 | bge .Lshell_down_loop
54 | .Lshell_down_loop_end:
55 | strb r8, [r1, r5] @ TODO: clean
56 | add r4, r4, #1 @ TODO: combine with ldrb
57 | cmp r4, r2
58 | blt .Lshell_up_loop
59 | .Lshell_up_loop_end:
60 | cmp r3, #1
61 | bgt .Lshell_inc_loop
62 | ldmfd sp!, {r4-r10}
63 | bx lr
64 | .align 2
65 | .Lshell_pool:
66 | .word 1431655766
67 |
68 |
--------------------------------------------------------------------------------
/external/tonc/code/lab/prio_demo/id_sort_shell2.s:
--------------------------------------------------------------------------------
1 | @
2 | @ id_sort_shell2: general shellsort unsing an index table
3 | @ MAXCOUNT: 256
4 | @ === NOTES: ===
5 | @ * changed from oe->fill keys to int keys after completion;
6 | @ not fully optimised for that yet.
7 |
8 | .section .iwram,"ax",%progbits
9 | .align 2
10 | @ DECL: CODE_IN_IWRAM void id_sort_shell2(int keys[], u8 ids[], int count)
11 | @ r0: sort key (oe.fill)
12 | @ r1: sort indices
13 | @ r2: array length
14 | @ r3: inc
15 | @ r4, r5, r6: inc, ii, jj, jj-inc
16 | @ r7: id= ids[jj-inc]
17 | @ r8, r9: id0=ids[ii], key0=fill[ids[ii]]
18 | @ r10: fill[id]
19 | @ r12: (1<<32)/3
20 | .global id_sort_shell2
21 | id_sort_shell2:
22 | stmfd sp!, {r4-r10}
23 | @ TODO: special for count==1
24 | @ setup inc: inc= 3*inc+1
25 | mov r3, #0
26 | .Lshell_inc_setup:
27 | rsb r3, r3, r3, lsl #2
28 | add r3, r3, #1
29 | cmp r3, r2
30 | ble .Lshell_inc_setup
31 | ldr r12, .Lshell_pool
32 | @ inc loop
33 | .Lshell_inc_loop:
34 | umull r5, r4, r12, r3 @ ii= inc/3
35 | mov r3, r4 @ inc= ii
36 | cmp r3, r2 @ ii>count
37 | bgt .Lshell_up_loop_end
38 | @ ii=inc to nn loop
39 | .Lshell_up_loop:
40 | ldrb r8, [r1, r4] @ id0= ids[ii]
41 | ldr r9, [r0, r8, lsl #2] @ key0= fill[ids[ii]]
42 | mov r5, r4 @ jj= ii
43 | sub r6, r5, r3 @ jnext= jj-inc
44 | @ jj=ii to 0 loop
45 | .Lshell_down_loop:
46 | ldrb r7, [r1, r6]
47 | ldr r10, [r0, r7, lsl #2]
48 | cmp r10, r9 @ fill[id] > key0
49 | ble .Lshell_down_loop_end
50 | strb r7, [r1, r5] @ PONDER: xxxgt?
51 | mov r5, r6
52 | subs r6, r5, r3
53 | bge .Lshell_down_loop
54 | .Lshell_down_loop_end:
55 | strb r8, [r1, r5] @ TODO: clean
56 | add r4, r4, #1 @ TODO: combine with ldrb
57 | cmp r4, r2
58 | blt .Lshell_up_loop
59 | .Lshell_up_loop_end:
60 | cmp r3, #1
61 | bgt .Lshell_inc_loop
62 | ldmfd sp!, {r4-r10}
63 | bx lr
64 | .align 2
65 | .Lshell_pool:
66 | .word 1431655766
67 |
68 |
--------------------------------------------------------------------------------
/external/tonc/code/tonclib/src/tte/chr4c_drawg_b1cts.c:
--------------------------------------------------------------------------------
1 | //
2 | // Tile renderer, var width/height, 1->4bpp tiles,
3 | // recolored with transparency
4 | //
5 | //! \file chr4c_drawg_b1cts.c
6 | //! \author J Vijn
7 | //! \date 20070621 - 20080427
8 | //
9 | /* === NOTES ===
10 | * 20070725: Skipping rendering if raw == 0 helps. A lot. Also, there
11 | is more than one way to bitunpack and split between tiles. Which
12 | method is faster is very platform dependent.
13 | * 20070723: Prepping dst stuff inside the drawg and passing along to
14 | renc does NOT help (prolly due to Thumb). Try combining in
15 | asm manually.
16 | */
17 |
18 | #include "tonc_memdef.h"
19 | #include "tonc_tte.h"
20 |
21 |
22 | // --------------------------------------------------------------------
23 | // FUNCTIONS
24 | // --------------------------------------------------------------------
25 |
26 | //! Render 1bpp fonts to 4bpp tiles
27 | void chr4c_drawg_b1cts(uint gid)
28 | {
29 | TTE_BASE_VARS(tc, font);
30 | TTE_CHAR_VARS(font, gid, u8, srcD, srcL, charW, charH);
31 | uint x= tc->cursorX, y= tc->cursorY;
32 | uint srcP= font->cellH, dstP= tc->dst.pitch/4;
33 |
34 | u32 *dstD= (u32*)(tc->dst.data + y*4 + x/8*dstP*4), *dstL;
35 | x %= 8;
36 | u32 lsl= 4*x, lsr= 32-4*x, right= x+charW;
37 |
38 | // Inner loop vars
39 | u32 px, pxmask, raw;
40 | u32 ink= tc->cattr[TTE_INK];
41 | const u32 mask= 0x01010101;
42 |
43 | uint iy, iw;
44 | for(iw=0; iw 8)
69 | dstL[dstP]= (dstL[dstP] &~ (pxmask>>lsr) ) | (px>>lsr);
70 | }
71 | dstL++;
72 | }
73 | }
74 | }
75 |
76 | // EOF
77 |
--------------------------------------------------------------------------------
/gba-core/src/cartridge/sram.rs:
--------------------------------------------------------------------------------
1 | use tracing::debug;
2 |
3 | use crate::cartridge::StorageChip;
4 | use crate::cartridge::storage::BackupType;
5 | use crate::memory::device::{Addressable, Saveable};
6 |
7 | const SRAM_SIZE: u32 = 0x8000; // 32 KiB
8 |
9 | pub struct Sram {
10 | sram: Vec,
11 | backup_type: BackupType,
12 | }
13 |
14 | impl Sram {
15 | pub fn new() -> Self {
16 | Sram {
17 | sram: vec![0; SRAM_SIZE as usize],
18 | backup_type: BackupType::Sram,
19 | }
20 | }
21 | }
22 |
23 | impl Addressable for Sram {
24 | fn read(&self, addr: u32) -> u8 {
25 | match addr {
26 | 0x0E000000..=0x0FFFFFFF => {
27 | // GamePak SRAM – mirrors every 32 KiB in 0x0E000000‑0x0FFFFFFF
28 | let addr = (addr - 0x0E000000) % SRAM_SIZE;
29 | self.sram[addr as usize]
30 | }
31 | _ => unreachable!(),
32 | }
33 | }
34 |
35 | fn write(&mut self, addr: u32, value: u8) {
36 | match addr {
37 | 0x0E000000..=0x0FFFFFFF => {
38 | // GamePak SRAM – mirrors every 32 KiB in 0x0E000000‑0x0FFFFFFF
39 | let addr = (addr - 0x0E000000) % SRAM_SIZE;
40 | self.sram[addr as usize] = value;
41 | }
42 | _ => unreachable!(),
43 | }
44 | }
45 | }
46 |
47 | impl StorageChip for Sram {
48 | fn size(&self) -> usize {
49 | SRAM_SIZE as usize
50 | }
51 |
52 | fn backup_type(&self) -> BackupType {
53 | self.backup_type
54 | }
55 |
56 | fn backing_storage(&self) -> Vec {
57 | self.sram.clone()
58 | }
59 | }
60 |
61 | impl Saveable for Sram {
62 | fn aggregate_storage(&self) -> Vec {
63 | self.sram.clone()
64 | }
65 |
66 | fn load_storage(&mut self, data: &[u8]) {
67 | if data.len() != SRAM_SIZE as usize {
68 | panic!("Invalid SRAM data size: expected {}, got {}", SRAM_SIZE, data.len());
69 | }
70 |
71 | debug!(target: "storage", "Loading SRAM with {} bytes", data.len());
72 | self.sram.copy_from_slice(data);
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/scripts/dump_swi.rhai:
--------------------------------------------------------------------------------
1 | fn dump_bios_function() {
2 | let BIOS_FUNC_LUT = #{
3 | "0x00": "SoftReset",
4 | "0x01": "RegisterRamReset",
5 | "0x02": "Halt",
6 | "0x03": "Stop/Sleep",
7 | "0x04": "IntrWait",
8 | "0x05": "VBlankIntrWait",
9 | "0x06": "Div",
10 | "0x07": "DivArm",
11 | "0x08": "Sqrt",
12 | "0x09": "ArcTan",
13 | "0x0a": "ArcTan2",
14 | "0x0b": "CpuSet",
15 | "0x0c": "CpuFastSet",
16 | "0x0d": "GetBiosChecksum",
17 | "0x0e": "BgAffineSet",
18 | "0x0f": "ObjAffineSet",
19 | "0x10": "BitUnPack",
20 | "0x11": "LZ77UnCompWram",
21 | "0x12": "LZ77UnCompVram",
22 | "0x13": "HuffUnComp",
23 | "0x14": "RLUnCompWram",
24 | "0x15": "RLUnCompVram",
25 | "0x16": "Diff8bitUnFilterWram",
26 | "0x17": "Diff8bitUnFilterVram",
27 | "0x18": "Diff16bitUnFilter",
28 | "0x19": "SoundBias",
29 | "0x1a": "SoundDriverInit",
30 | "0x1b": "SoundDriverMode",
31 | "0x1c": "SoundDriverMain",
32 | "0x1d": "SoundDriverVSync",
33 | "0x1e": "SoundChannelClear",
34 | "0x1f": "MidiKey2Freq",
35 | "0x20": "SoundWhatever0",
36 | "0x21": "SoundWhatever1",
37 | "0x22": "SoundWhatever2",
38 | "0x23": "SoundWhatever3",
39 | "0x24": "SoundWhatever4",
40 | "0x25": "MultiBoot",
41 | "0x26": "HardReset",
42 | "0x27": "CustomHalt",
43 | "0x28": "SoundDriverVSyncOff",
44 | "0x29": "SoundDriverVSyncOn",
45 | "0x2a": "SoundGetJumpList",
46 | };
47 |
48 | let r12 = emu.read_register("r12"); // LDRB R12, [LR, -#$0002]
49 | let bios_func = `0x${hex8(emu.read_u8(r12))}`;
50 | let bios_func_name = BIOS_FUNC_LUT.get(bios_func);
51 |
52 | if bios_func_name == () {
53 | println(`Unknown BIOS function: ${bios_func}`);
54 | return;
55 | }
56 |
57 | println(`BIOS: ${bios_func_name} (${bios_func})`);
58 | }
59 |
60 | fn setup() {
61 | let breakpoints = #{
62 | "0x144": "dump_bios_function"
63 | };
64 | breakpoints
65 | }
66 |
--------------------------------------------------------------------------------
/external/tonc/code/basic/obj_demo/obj_demo.c:
--------------------------------------------------------------------------------
1 | //
2 | // obj_demo.c
3 | // testing various sprite related things
4 | //
5 | // (20031003 - 20060924, Cearn)
6 |
7 | #include
8 | #include "toolbox.h"
9 | #include "metr.h"
10 |
11 | OBJ_ATTR obj_buffer[128];
12 | OBJ_AFFINE *obj_aff_buffer= (OBJ_AFFINE*)obj_buffer;
13 |
14 | // testing a few sprite things
15 | // D-pad: move
16 | // SELECT: switch palette
17 | // START: toggle mapping mode
18 | // A: horizontal flip
19 | // B: vertical flip
20 | // L & R shift starting tile
21 | void obj_test()
22 | {
23 | int x= 96, y= 32;
24 | u32 tid= 0, pb= 0; // tile id, pal-bank
25 |
26 | OBJ_ATTR *metr= &obj_buffer[0];
27 | obj_set_attr(metr,
28 | ATTR0_SQUARE, // Square, regular sprite
29 | ATTR1_SIZE_64, // 64x64p,
30 | ATTR2_PALBANK(pb) | tid); // palbank 0, tile 0
31 |
32 | // position sprite (redundant here; the _real_ position
33 | // is set further down
34 | obj_set_pos(metr, x, y);
35 |
36 | while(1)
37 | {
38 | vid_vsync();
39 | key_poll();
40 |
41 | // move left/right
42 | x += 2*key_tri_horz();
43 |
44 | // move up/down
45 | y += 2*key_tri_vert();
46 |
47 | // increment/decrement starting tile with R/L
48 | tid += bit_tribool(key_hit(-1), KI_R, KI_L);
49 |
50 | // flip
51 | if(key_hit(KEY_A)) // horizontally
52 | metr->attr1 ^= ATTR1_HFLIP;
53 | if(key_hit(KEY_B)) // vertically
54 | metr->attr1 ^= ATTR1_VFLIP;
55 |
56 | // make it glow (via palette swapping)
57 | pb= key_is_down(KEY_SELECT) ? 1 : 0;
58 |
59 | // toggle mapping mode
60 | if(key_hit(KEY_START))
61 | REG_DISPCNT ^= DCNT_OBJ_1D;
62 |
63 | // Hey look, it's one of them build macros!
64 | metr->attr2= ATTR2_BUILD(tid, pb, 0);
65 | obj_set_pos(metr, x, y);
66 |
67 | oam_copy(oam_mem, obj_buffer, 1); // only need to update one
68 | }
69 | }
70 |
71 | int main()
72 | {
73 | // Places the glyphs of a 4bpp boxed metroid sprite
74 | // into LOW obj memory (cbb == 4)
75 | memcpy(&tile_mem[4][0], metrTiles, metrTilesLen);
76 | memcpy(pal_obj_mem, metrPal, metrPalLen);
77 |
78 | oam_init(obj_buffer, 128);
79 | REG_DISPCNT= DCNT_OBJ | DCNT_OBJ_1D;
80 |
81 | obj_test();
82 |
83 | while(1);
84 |
85 | return 0;
86 | }
87 |
--------------------------------------------------------------------------------
/debugger/src/dbg/debugger.rs:
--------------------------------------------------------------------------------
1 | use super::widgets::cpu::CpuWidget;
2 | use super::widgets::disasm::DisassemblyWidget;
3 | use super::widgets::memory::MemoryWidget;
4 | use super::widgets::ppu::PpuWidget;
5 | use crate::event::{RequestEvent, ResponseEvent};
6 | use crossbeam_channel::{Receiver, Sender};
7 | use egui::Context;
8 |
9 | pub struct Debugger {
10 | pub open: bool,
11 | rx: Receiver,
12 | memory_widget: MemoryWidget,
13 | cpu_widget: CpuWidget,
14 | disasm_widget: DisassemblyWidget,
15 | ppu_widget: PpuWidget,
16 | }
17 |
18 | impl Debugger {
19 | pub fn new(
20 | cpu_tx: Sender, memory_tx: Sender, disasm_tx: Sender,
21 | ppu_tx: Sender, rx: Receiver,
22 | ) -> Debugger {
23 | Debugger {
24 | open: false,
25 | rx,
26 | memory_widget: MemoryWidget::new(memory_tx),
27 | cpu_widget: CpuWidget::new(cpu_tx),
28 | disasm_widget: DisassemblyWidget::new(disasm_tx),
29 | ppu_widget: PpuWidget::new(ppu_tx),
30 | }
31 | }
32 |
33 | pub fn update(&mut self, ctx: &Context) {
34 | if !self.open {
35 | return;
36 | }
37 |
38 | match self.rx.try_recv() {
39 | Ok(ResponseEvent::Cpu(cpu)) => self.cpu_widget.update(cpu),
40 | Ok(ResponseEvent::Memory(memory)) => self.memory_widget.update(memory),
41 | Ok(ResponseEvent::Disassembly(pc, r15, disassembly)) => self.disasm_widget.update(disassembly, pc, r15),
42 | Ok(ResponseEvent::Ppu(frames, _tileset, tilemaps, palette, registers, sprites)) => {
43 | // TODO: we ignore tileset cause its been causing issues
44 | self.ppu_widget
45 | .update(ctx, frames, tilemaps, palette, registers, sprites)
46 | }
47 | _ => (),
48 | }
49 |
50 | self.cpu_widget.render(ctx);
51 | self.memory_widget.render(ctx);
52 | self.disasm_widget.render(ctx);
53 | self.ppu_widget.render(ctx);
54 | }
55 |
56 | pub fn toggle_window(&mut self) {
57 | self.open = !self.open;
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/gba-core/src/cartridge/storage.rs:
--------------------------------------------------------------------------------
1 | const SANYO_MANUFACTURER_ID: u8 = 0x62;
2 | const SANYO_DEVICE_ID: u8 = 0x13;
3 | const PANASONIC_MANUFACTURER_ID: u8 = 0x32;
4 | const PANASONIC_DEVICE_ID: u8 = 0x1B;
5 |
6 | // TODO: Switch to https://docs.google.com/spreadsheets/d/16-a3qDDkJJNpaYOEXi-xgTv-j1QznXHt9rTUJNFshjo/edit?pli=1&gid=0#gid=0 maybe?
7 |
8 | #[derive(Clone, Copy, PartialEq, Eq)]
9 | pub enum BackupType {
10 | Eeprom4k,
11 | Eeprom64k,
12 | Flash512k,
13 | Flash1m,
14 | Sram,
15 | None,
16 | }
17 |
18 | impl BackupType {
19 | pub fn has_rtc(&self) -> bool {
20 | matches!(self, BackupType::Flash512k | BackupType::Flash1m)
21 | }
22 |
23 | pub fn manufacturer_id(&self) -> u8 {
24 | match self {
25 | BackupType::Flash512k => PANASONIC_MANUFACTURER_ID,
26 | BackupType::Flash1m => SANYO_MANUFACTURER_ID,
27 | _ => unreachable!(),
28 | }
29 | }
30 |
31 | pub fn device_id(&self) -> u8 {
32 | match self {
33 | BackupType::Flash512k => PANASONIC_DEVICE_ID,
34 | BackupType::Flash1m => SANYO_DEVICE_ID,
35 | _ => unreachable!(),
36 | }
37 | }
38 | }
39 |
40 | impl From for BackupType {
41 | fn from(value: u8) -> Self {
42 | match value {
43 | 0 => BackupType::None,
44 | 1 => BackupType::Eeprom4k,
45 | 2 => BackupType::Eeprom64k,
46 | 3 => BackupType::Sram,
47 | 4 => BackupType::Flash512k,
48 | 5 => BackupType::Flash1m,
49 | _ => unreachable!(),
50 | }
51 | }
52 | }
53 |
54 | impl std::fmt::Display for BackupType {
55 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
56 | match self {
57 | BackupType::Eeprom4k => write!(f, "EEPROM 4K"),
58 | BackupType::Eeprom64k => write!(f, "EEPROM 64K"),
59 | BackupType::Flash512k => write!(f, "Flash 512K"),
60 | BackupType::Flash1m => write!(f, "Flash 1M"),
61 | BackupType::Sram => write!(f, "SRAM"),
62 | BackupType::None => write!(f, "None"),
63 | }?;
64 | write!(f, " (has RTC: {})", self.has_rtc())
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/external/tonc/code/tonclib/src/tte/chr4r_drawg_b1cts.c:
--------------------------------------------------------------------------------
1 | //
2 | // Tile renderer, var width/height, 1->4bpp tiles,
3 | // recolored with transparency
4 | //
5 | //! \file chr4r_drawg_b1cts.c
6 | //! \author J Vijn
7 | //! \date 20070621 - 20070725
8 | //
9 | /* === NOTES ===
10 | * 20070725: Skipping rendering if raw == 0 helps. A lot. Also, there
11 | is more than one way to bitunpack and split between tiles. Which
12 | method is faster is very platform dependent.
13 | * 20070723: Prepping dst stuff inside the drawg and passing along to
14 | renc does NOT help (prolly due to Thumb). Try combining in
15 | asm manually.
16 | */
17 |
18 | #include "tonc_memdef.h"
19 | #include "tonc_tte.h"
20 |
21 |
22 | // --------------------------------------------------------------------
23 | // FUNCTIONS
24 | // --------------------------------------------------------------------
25 |
26 | //! Render 1bpp fonts to 4bpp tiles
27 | void chr4r_drawg_b1cts(uint gid)
28 | {
29 | TTE_BASE_VARS(tc, font);
30 | TTE_CHAR_VARS(font, gid, u8, srcD, srcL, charW, charH);
31 | uint x= tc->cursorX, y= tc->cursorY;
32 | uint srcP= font->cellH, dstP= tc->dst.pitch/4;
33 |
34 | u32 *dstD= (u32*)(tc->dst.data + y/8*dstP + (y%8)*4 + x/8*32), *dstL;
35 | dstP= dstP/4 - 8;
36 | x %= 8;
37 | u32 lsl= 4*x, lsr= 32-4*x, right= x+charW;
38 |
39 | // Inner loop vars
40 | u32 px, pxmask, raw;
41 | u32 ink= tc->cattr[TTE_INK];
42 | const u32 mask= 0x01010101;
43 |
44 | uint iy, iw;
45 | for(iw=0; iw 8)
70 | dstL[8]= (dstL[8] &~ (pxmask>>lsr) ) | (px>>lsr);
71 | }
72 | dstL++;
73 |
74 | if( ((u32)dstL)%32 == 0 )
75 | dstL += dstP;
76 | }
77 | }
78 | }
79 |
80 | // EOF
81 |
--------------------------------------------------------------------------------
/gba-core/src/input/joypad.rs:
--------------------------------------------------------------------------------
1 | use super::registers::{KeyControl, KeyInput};
2 | use crate::memory::device::Addressable;
3 |
4 | pub struct Joypad {
5 | status: KeyInput,
6 | irq_control: KeyControl,
7 | }
8 |
9 | impl Joypad {
10 | pub fn new() -> Joypad {
11 | Joypad {
12 | status: KeyInput::all(),
13 | irq_control: KeyControl::empty(),
14 | }
15 | }
16 |
17 | pub fn set_key_state(&mut self, key: KeyInput, pressed: bool) {
18 | if pressed {
19 | self.status.remove(key);
20 | } else {
21 | self.status.insert(key);
22 | }
23 | }
24 |
25 | pub fn is_key_pressed(&self, key: KeyInput) -> bool {
26 | !self.status.contains(key)
27 | }
28 | }
29 |
30 | impl Addressable for Joypad {
31 | fn read(&self, addr: u32) -> u8 {
32 | match addr {
33 | 0x04000130 => self.status.bits() as u8,
34 | 0x04000131 => ((self.status.bits() & 0xff00) >> 8) as u8,
35 | 0x04000132 => self.irq_control.bits() as u8,
36 | 0x04000133 => ((self.irq_control.bits() & 0xff00) >> 8) as u8,
37 | _ => unreachable!(),
38 | }
39 | }
40 |
41 | fn write(&mut self, addr: u32, value: u8) {
42 | match addr {
43 | 0x04000130 => {
44 | self.status = KeyInput::from_bits_truncate(u16::from_le_bytes([value, self.status.bits() as u8]));
45 | }
46 | 0x04000131 => {
47 | self.status = KeyInput::from_bits_truncate(u16::from_le_bytes([
48 | ((self.status.bits() & 0xff00) >> 8) as u8,
49 | value,
50 | ]));
51 | }
52 | 0x04000132 => {
53 | self.irq_control =
54 | KeyControl::from_bits_truncate(u16::from_le_bytes([value, self.irq_control.bits() as u8]));
55 | }
56 | 0x04000133 => {
57 | self.irq_control = KeyControl::from_bits_truncate(u16::from_le_bytes([
58 | ((self.irq_control.bits() & 0xff00) >> 8) as u8,
59 | value,
60 | ]));
61 | }
62 | _ => unreachable!(),
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/external/tonc/code/tonc.mak:
--------------------------------------------------------------------------------
1 | #
2 | # Hub makefile for Tonc's demos
3 | #
4 |
5 | # === Variables =======================================================
6 |
7 | export CROSS := arm-none-eabi-
8 |
9 | LIBTONC := tonclib
10 | GRPDIRS := basic ext adv lab
11 | BINDIR := ../bin
12 |
13 | # List all directories in the group dirs
14 | # Yeah, there's probably a better way :/
15 | PROJALL := $(foreach dir, $(GRPDIRS), $(shell ls -d $(dir)/*/))
16 | EXCLUDE :=
17 | PROJDIRS := $(filter-out $(foreach proj, $(EXCLUDE), %/$(proj)/), $(PROJALL))
18 |
19 | DEMO := bigmap
20 | DEMODIR := $(filter %/$(DEMO)/, $(PROJDIRS))
21 |
22 | # Convert GCC lines to conform to the right IDE, feel free to add more
23 | # GCC : {filename}:{line}: ...
24 | # MSVS: {dir}\{filename}({line}): ...
25 | ifeq ($(IDE),msvc)
26 |
27 | # And switch is DEMO is not in 'basic' or 'ext',
28 | # as the rest behaves differently :/
29 | ifeq ($(filter basic/% ext/%, lab/%, $(DEMODIR)),)
30 | ERRFIX := 2>&1 | sed -e 's|\(.\+\):\([0-9]\+\):|\1(\2):|'
31 | else
32 | ERRFIX := 2>&1 | sed -e 's|\(.\+\):\([0-9]\+\):|../$(DEMODIR)\1(\2):|'
33 | endif
34 |
35 | endif # /$(IDE)
36 |
37 | .PHONY : build clean build_all clean_all
38 |
39 | # === Build Single ====================================================
40 |
41 | build:
42 | $(MAKE) -C $(DEMODIR) $(ERRFIX)
43 |
44 |
45 | # === Clean Single ====================================================
46 |
47 | clean:
48 | @$(MAKE) -C $(DEMODIR) clean
49 |
50 |
51 | # === Build Single ====================================================
52 |
53 | build_all: libtonc
54 | @echo === Building all projects \(this could take a while\) ===
55 | @for proj in $(PROJDIRS) ; \
56 | do $(MAKE) -s -C $$proj ; done;
57 | @[ -d $(BINDIR) ] || mkdir -p $(BINDIR)
58 | @for proj in $(PROJDIRS); do cp $$proj*.gba $(BINDIR) ; done;
59 |
60 | # === Clean Single ====================================================
61 |
62 | clean_all:
63 | @echo === Cleaning all projects \(this could take a while\) ===
64 | # @$(MAKE) clean -C $(LIBTONC)
65 | @for proj in $(PROJDIRS); \
66 | do $(MAKE) clean -s -C $$proj ; done;
67 |
68 |
69 | # === Build libtonc ===================================================
70 |
71 | libtonc:
72 | @$(MAKE) -C $(LIBTONC)
73 |
74 |
--------------------------------------------------------------------------------
/external/tonc/code/basic/cbb_demo/cbb_demo.c:
--------------------------------------------------------------------------------
1 | //
2 | // cbb_demo.c
3 | // showing char-block boundaries for 4 and 8-bit tile-maps
4 | //
5 | // (20031114 - 20060924, cearn)
6 |
7 | #include "toolbox.h"
8 |
9 | #include "cbb_ids.h"
10 |
11 | #define CBB_4 0
12 | #define SBB_4 2
13 |
14 | #define CBB_8 2
15 | #define SBB_8 4
16 |
17 | void load_tiles()
18 | {
19 | int ii;
20 | TILE *tl= (TILE*)ids4Tiles;
21 | TILE8 *tl8= (TILE8*)ids8Tiles;
22 |
23 | // Loading tiles. don't get freaked out on how it looks
24 | // 4-bit tiles to blocks 0 and 1
25 | tile_mem[0][1]= tl[1]; tile_mem[0][2]= tl[2];
26 | tile_mem[1][0]= tl[3]; tile_mem[1][1]= tl[4];
27 | // and the 8-bit tiles to blocks 2 though 5
28 | tile8_mem[2][1]= tl8[1]; tile8_mem[2][2]= tl8[2];
29 | tile8_mem[3][0]= tl8[3]; tile8_mem[3][1]= tl8[4];
30 | tile8_mem[4][0]= tl8[5]; tile8_mem[4][1]= tl8[6];
31 | tile8_mem[5][0]= tl8[7]; tile8_mem[5][1]= tl8[8];
32 |
33 | // And let's not forget the palette (yes, obj pal too)
34 | u16 *src= (u16*)ids4Pal;
35 | for(ii=0; ii<16; ii++)
36 | pal_bg_mem[ii]= pal_obj_mem[ii]= *src++;
37 | }
38 |
39 | void init_maps()
40 | {
41 | // se4 and se8 map coords: (0,2) and (0,8)
42 | SCR_ENTRY *se4= &se_mem[SBB_4][2*32], *se8= &se_mem[SBB_8][8*32];
43 | // show first tiles of char-blocks available to bg0
44 | // tiles 1, 2 of char-block CBB_4
45 | se4[0x01]= 0x0001; se4[0x02]= 0x0002;
46 |
47 | // tiles 0, 1 of char-block CBB_4+1
48 | se4[0x20]= 0x0200; se4[0x21]= 0x0201;
49 |
50 | // show first tiles of char-blocks available to bg1
51 | // tiles 1, 2 of char-block CBB_8 (== 2)
52 | se8[0x01]= 0x0001; se8[0x02]= 0x0002;
53 |
54 | // tiles 1, 2 of char-block CBB_8+1
55 | se8[0x20]= 0x0100; se8[0x21]= 0x0101;
56 |
57 | // tiles 1, 2 of char-block CBB_8+2 (== CBB_OBJ_LO)
58 | se8[0x40]= 0x0200; se8[0x41]= 0x0201;
59 |
60 | // tiles 1, 2 of char-block CBB_8+3 (== CBB_OBJ_HI)
61 | se8[0x60]= 0x0300; se8[0x61]= 0x0301;
62 | }
63 |
64 | int main()
65 | {
66 | load_tiles();
67 | init_maps();
68 |
69 | // init backgrounds
70 | REG_BG0CNT= BG_CBB(CBB_4) | BG_SBB(SBB_4) | BG_4BPP;
71 | REG_BG1CNT= BG_CBB(CBB_8) | BG_SBB(SBB_8) | BG_8BPP;
72 | // enable backgrounds
73 | REG_DISPCNT= DCNT_MODE0 | DCNT_BG0 | DCNT_BG1 | DCNT_OBJ;
74 |
75 | while(1);
76 |
77 | return 0;
78 | }
79 |
--------------------------------------------------------------------------------
/external/tonc/code/tonclib/asm/tonc_isr_master.s:
--------------------------------------------------------------------------------
1 | //
2 | // Default ISR for interrupts. No automatic nestings.
3 | //
4 | //! \file tonc_isr_master.s
5 | //! \author J Vijn
6 | //! \date 20080320 - 20090801
7 | //
8 | // === NOTES ===
9 |
10 | #include "tonc_asminc.h"
11 |
12 | .file "tonc_isr_master.s"
13 | .extern __isr_table;
14 |
15 | /*! \fn IWRAM_CODE void isr_master()
16 | \brief Default irq dispatcher (no automatic nesting)
17 | */
18 | @ Register list
19 | @ r0 : ®_IE
20 | @ r1 : __isr_table / isr
21 | @ r2 : IF & IE
22 | @ r3 : tmp
23 | @ ip : (IF,IE)
24 | BEGIN_FUNC_ARM(isr_master, CSEC_IWRAM)
25 | @ Read IF/IE
26 | mov r0, #0x04000000
27 | ldr ip, [r0, #0x200]!
28 | and r2, ip, ip, lsr #16 @ irq= IE & IF
29 |
30 | @ Acknowledge irq in IF and for BIOS
31 | strh r2, [r0, #2]
32 | ldr r3, [r0, #-0x208]
33 | orr r3, r3, r2
34 | str r3, [r0, #-0x208]
35 |
36 | @ Search for irq.
37 | ldr r1, =__isr_table
38 |
39 | .Lirq_search:
40 | ldr r3, [r1], #8
41 | tst r3, r2
42 | bne .Lpost_search @ Found one, break off search
43 | cmp r3, #0
44 | bne .Lirq_search @ Not here; try next irq
45 |
46 | @ Search over : return if no isr, otherwise continue.
47 | .Lpost_search:
48 | ldrne r1, [r1, #-4] @ isr= __isr_table[ii-1].isr
49 | cmpne r1, #0
50 | bxeq lr @ If no isr: quit
51 |
52 | @ --- If we're here, we have an isr ---
53 |
54 | ldr r3, [r0, #8] @ Read IME
55 | strb r0, [r0, #8] @ Clear IME
56 | bic r2, ip, r2
57 | strh r2, [r0] @ Clear current irq in IE
58 |
59 | mrs r2, spsr
60 | stmfd sp!, {r2-r3, ip, lr} @ sprs, IME, (IE,IF), lr_irq
61 |
62 | @ Set mode to usr
63 | mrs r3, cpsr
64 | bic r3, r3, #0xDF
65 | orr r3, r3, #0x1F
66 | msr cpsr, r3
67 |
68 | @ Call isr
69 | stmfd sp!, {r0,lr} @ ®_IE, lr_sys
70 | mov lr, pc
71 | bx r1
72 | ldmfd sp!, {r0,lr} @ ®_IE, lr_sys
73 |
74 | @ --- Unwind ---
75 | strb r0, [r0, #8] @ Clear IME again (safety)
76 |
77 | @ Reset mode to irq
78 | mrs r3, cpsr
79 | bic r3, r3, #0xDF
80 | orr r3, r3, #0x92
81 | msr cpsr, r3
82 |
83 | ldmfd sp!, {r2-r3, ip, lr} @ sprs, IME, (IE,IF), lr_irq
84 | msr spsr, r2 @ Restore spsr
85 | strh ip, [r0] @ Restore IE
86 | str r3, [r0, #8] @ Restore IME
87 |
88 | bx lr
89 | END_FUNC(isr_master)
90 |
91 | @ EOF
92 |
93 |
--------------------------------------------------------------------------------
/external/tonc/code/tonclib/asm/clr_fade_fast.s:
--------------------------------------------------------------------------------
1 | //
2 | // Color fade with 33 alpha levels
3 | //
4 | //! \file tonc_memcpy.s
5 | //! \author J Vijn
6 | //! \date 20071130 - 20071130
7 |
8 | #include "tonc_asminc.h"
9 |
10 | #ifndef CLR_ROUND
11 | #define CLR_ROUND 1
12 | #endif
13 |
14 | /*
15 | void clr_fade_fast(COLOR *src, COLOR clr, COLOR *dst,
16 | int nclrs, u32 alpha) IWRAM_CODE;
17 | */
18 | //! Fades color arrays \a srca to \a clr into \a dst.
19 | /*! \param src Source array.
20 | * \param clr Final color (at alpha=32).
21 | * \param dst Destination array.
22 | * \param nclrs Number of colors.
23 | * \param alpha Blend weight (range: 0-32).
24 | * \note u32 version, 2 clrs/loop. Loop: 18i/32c, Barrel shifter FTW.
25 | */
26 | .section .iwram,"ax", %progbits
27 | .align 2
28 | .arm
29 | .global clr_fade_fast
30 | clr_fade_fast:
31 | movs r3, r3, lsr #1 @ adjust nclrs for u32 run
32 | bxeq lr @ quit on nclrs=0
33 | ldr r12, [sp] @ get alpha from stack
34 | stmfd sp!, {r4-r10, lr}
35 | #if(CLR_ROUND==1)
36 | ldr lr, =0x00200401 @ -1-|1-1
37 | rsb r7, lr, lr, lsl #5 @ MASKLO: -g-|b-r
38 | #else
39 | ldr r7, =0x03E07C1F @ MASKLO: -g-|b-r
40 | #endif
41 | mov r6, r7, lsl #5 @ MASKHI: g-|b-r-
42 |
43 | @ Precalc y1 and y2
44 | orr r1, r1, r1, lsl #16
45 | and r9, r7, r1, ror #16 @ precalc: y2= -g-|b-r (ror16)
46 | and r1, r7, r1 @ precalc: y1= -g-|b-r
47 | .Lfade_fast_loop:
48 | ldr r8, [r0], #4 @ a= *pa++
49 | @ --- -g-|b-r
50 | and r4, r6, r8, lsl #5 @ x/32: (-g-|b-r)
51 | sub r5, r1, r4, lsr #5 @ z: y1-x
52 | mla r4, r5, r12, r4 @ z: (y1-x)*w + x*32
53 | #if(CLR_ROUND==1)
54 | add r4, r4, lr, lsl #4 @ round
55 | #endif
56 | and r10, r7, r4, lsr #5 @ blend(-g-|b-r)
57 | @ --- b-r|-g- (rotated by 16 for great awesome)
58 | and r4, r6, r8, ror #11 @ x/32: -g-|b-r (ror16)
59 | sub r5, r9, r4, lsr #5 @ z: y2-x
60 | mla r4, r5, r12, r4 @ z: (y2-x)*w + x*32
61 | #if(CLR_ROUND==1)
62 | add r4, r4, lr, lsl #4 @ round
63 | #endif
64 | and r4, r7, r4, lsr #5 @ blend(-g-|b-r (ror16))
65 | @ --- mix -g-|b-r and b-r|-g-
66 | orr r10, r10, r4, ror #16
67 | @ --- write faded, loop
68 | str r10, [r2], #4 @ *dst++= c
69 | subs r3, r3, #1
70 | bgt .Lfade_fast_loop
71 | ldmfd sp!, {r4-r10, lr}
72 | bx lr
73 |
74 | @ EOF
75 |
--------------------------------------------------------------------------------
/external/tonc/code/tonclib/src/tte/bmp16_drawg_b1cs.c:
--------------------------------------------------------------------------------
1 | //
2 | // Bitmap 16bpp render
3 | // * vwf and fwf
4 | // * any width, height
5 | // * 1->16bpp
6 | // * recolored
7 | // * transparency
8 | //
9 | //! \file bmp16_drawg_b1cs.c
10 | //! \author J Vijn
11 | //! \date 20070605 - 20070704
12 | //
13 | // === NOTES ===
14 |
15 | #include "tonc_memdef.h"
16 |
17 | #include "tonc_tte.h"
18 |
19 | // --------------------------------------------------------------------
20 | // FUNCTIONS
21 | // --------------------------------------------------------------------
22 |
23 |
24 | //! Linear bitmap, 16bpp transparent character plotter.
25 | /* Works on a 16 bpp bitmap (mode 3 or 5).
26 | \param gid Character to plot.
27 | \note Font req: Any width/height. 1bpp font, 8px stips.
28 | */
29 | void bmp16_drawg_b1cts(uint gid)
30 | {
31 | TTE_BASE_VARS(tc, font);
32 | TTE_CHAR_VARS(font, gid, u8, srcD, srcL, charW, charH);
33 | TTE_DST_VARS(tc, u16, dstD, dstL, dstP, x0, y0);
34 | uint srcP= font->cellH;
35 | dstD += x0;
36 |
37 | u32 ink= tc->cattr[TTE_INK], raw;
38 |
39 | //# Fixme (src, dst, nx)
40 | uint ix, iy, iw;
41 | for(iw=0; iw0; raw>>=1, ix++)
48 | if(raw&1)
49 | dstL[ix]= ink;
50 |
51 | dstL += dstP/2;
52 | }
53 | srcL += srcP;
54 | }
55 | }
56 |
57 | //! Linear bitmap, 16bpp opaque character plotter.
58 | /* Works on a 16 bpp bitmap (mode 3 or 5).
59 | \param gid Character to plot.
60 | \note Font req: Any width/height. 1bpp font, 8px stips.
61 | */
62 | void bmp16_drawg_b1cos(uint gid)
63 | {
64 | TTE_BASE_VARS(tc, font);
65 | TTE_CHAR_VARS(font, gid, u8, srcD, srcL, charW, charH);
66 | TTE_DST_VARS(tc, u16, dstD, dstL, dstP, x0, y0);
67 | uint srcP= font->cellH;
68 |
69 | dstD += x0;
70 |
71 | u32 ink= tc->cattr[TTE_INK];
72 | u32 paper= tc->cattr[TTE_PAPER];
73 | u32 raw;
74 |
75 | uint ix, iy, iw;
76 | for(iw=0; iw>=1)&1) ? ink : paper;
85 |
86 | dstL += dstP;
87 | }
88 | srcL += srcP;
89 | }
90 | }
91 |
92 | // EOF
93 |
--------------------------------------------------------------------------------
/external/tonc/code/tonclib/asm/clr_blend_fast.s:
--------------------------------------------------------------------------------
1 | //
2 | // Color blend with 33 alpha levels
3 | //
4 | //! \file tonc_memcpy.s
5 | //! \author J Vijn
6 | //! \date 20071130 - 20090801
7 |
8 | #include "tonc_asminc.h"
9 |
10 | #ifndef CLR_ROUND
11 | #define CLR_ROUND 1
12 | #endif
13 |
14 | /*
15 | void clr_blend_fast(COLOR *srca, COLOR *srcb, COLOR *dst,
16 | int nclrs, u32 alpha) IWRAM_CODE;
17 | */
18 | //! Blends color arrays \a srca and \a srcb into \a dst.
19 | /*! \param srca Source array A.
20 | \param srcb Source array B
21 | \param dst Destination array.
22 | \param nclrs Number of colors.
23 | \param alpha Blend weight (range: 0-32).
24 | \note u32 version, 2 clrs/loop. Loop: 18i/32c, Barrel shifter FTW.
25 | \note Properly rounds the blending. If you don't want that, remove
26 | the references to lr.
27 | */
28 | BEGIN_FUNC_ARM(clr_blend_fast, CSEC_IWRAM)
29 | movs r3, r3, lsr #1 @ adjust nclrs for u32 run
30 | bxeq lr @ quit on nclrs=0
31 | ldr r12, [sp] @ get alpha from stack
32 | stmfd sp!, {r4-r10, lr}
33 | #if(CLR_ROUND==1)
34 | ldr lr, =0x00200401 @ -1-|1-1
35 | rsb r7, lr, lr, lsl #5 @ MASKLO: -g-|b-r
36 | #else
37 | ldr r7, =0x03E07C1F @ MASKLO: -g-|b-r
38 | #endif
39 | mov r6, r7, lsl #5 @ MASKHI: g-|b-r-
40 | .Lbld_fast_loop:
41 | ldr r8, [r0], #4 @ a= *pa++
42 | ldr r9, [r1], #4 @ b= *pb++
43 | @ --- -g-|b-r
44 | and r4, r6, r8, lsl #5 @ x/32: (-g-|b-r)
45 | and r5, r7, r9 @ y: -g-|b-r
46 | sub r5, r5, r4, lsr #5 @ z: y-x
47 | mla r4, r5, r12, r4 @ z: (y-x)*w + x*32
48 | #if(CLR_ROUND==1)
49 | add r4, r4, lr, lsl #4 @ round
50 | #endif
51 | and r10, r7, r4, lsr #5 @ blend(-g-|b-r)
52 | @ --- b-r|-g- (rotated by 16 for great awesome)
53 | and r4, r6, r8, ror #11 @ x/32: -g-|b-r (ror16)
54 | and r5, r7, r9, ror #16 @ y: -g-|b-r (ror16)
55 | sub r5, r5, r4, lsr #5 @ z: y-x
56 | mla r4, r5, r12, r4 @ z: (y-x)*w + x*32
57 | #if(CLR_ROUND==1)
58 | add r4, r4, lr, lsl #4 @ round
59 | #endif
60 | and r4, r7, r4, lsr #5 @ blend(-g-|b-r (ror16))
61 | @ --- mix -g-|b-r and b-r|-g-
62 | orr r10, r10, r4, ror #16
63 | @ --- write blended, loop
64 | str r10, [r2], #4 @ *dst++= c
65 | subs r3, r3, #1
66 | bgt .Lbld_fast_loop
67 | ldmfd sp!, {r4-r10, lr}
68 | bx lr
69 | END_FUNC(clr_blend_fast)
70 |
71 |
72 | @ EOF
73 |
--------------------------------------------------------------------------------
/external/tonc/code/ext/mos_demo/mos_demo.c:
--------------------------------------------------------------------------------
1 | //
2 | // mos_demo.c
3 | // testing a mosaic sprite and background
4 | //
5 | // (20031013 - 20071203, cearn)
6 | // === NOTES ===
7 | // * bg/oam use:
8 | // bg 0, cbb 0, sbb 31, pb 0: text
9 | // bg 1, cbb 1, sbb 30, pb 1: bg metroid
10 | // oam 0: tile 0-63: obj metroid
11 |
12 | #include
13 | #include
14 | #include "metr.h"
15 |
16 | void test_mosaic()
17 | {
18 | tte_printf("#{P:48,8}obj#{P:168,8}bg");
19 | tte_set_margins(4, SCR_H-30, SCR_W-4, SCR_H-4);
20 |
21 | POINT pt_obj={0,0}, pt_bg={0,0};
22 | POINT *ppt= &pt_obj;
23 |
24 | while(1)
25 | {
26 | vid_vsync();
27 |
28 | // control the mosaic
29 | key_poll();
30 |
31 | // switch between bg or obj mosaic
32 | ppt= key_is_down(KEY_A) ? &pt_bg : &pt_obj;
33 |
34 | ppt->x += key_tri_horz(); // inc/dec h-mosaic
35 | ppt->y -= key_tri_vert(); // inc/dec v-mosaic
36 |
37 | ppt->x= clamp(ppt->x, 0, 0x80);
38 | ppt->y= clamp(ppt->y, 0, 0x80);
39 |
40 | REG_MOSAIC= MOS_BUILD(pt_bg.x>>3, pt_bg.y>>3,
41 | pt_obj.x>>3, pt_obj.y>>3);
42 |
43 | tte_printf("#{es;P}obj h,v: %2d,%2d\n bg h,v: %2d,%2d",
44 | pt_obj.x>>3, pt_obj.y>>3, pt_bg.x>>3, pt_bg.y>>3);
45 | }
46 | }
47 |
48 | void load_metr()
49 | {
50 | int ix, iy;
51 |
52 | memcpy32(&tile_mem[1][0], metrTiles, metrTilesLen/4);
53 | memcpy32(&tile_mem[4][0], metrTiles, metrTilesLen/4);
54 | memcpy32(pal_obj_mem, metrPal, metrPalLen/4);
55 |
56 | // create object: oe0
57 | OBJ_ATTR *metr= &oam_mem[0];
58 | obj_set_attr(metr, ATTR0_SQUARE | ATTR0_MOSAIC, ATTR1_SIZE_64, 0);
59 | obj_set_pos(metr, 32, 24); // left-center
60 |
61 | // create bg map: bg1, cbb1, sbb 31
62 | for(ix=1; ix<16; ix++)
63 | pal_bg_mem[ix+16]= pal_obj_mem[ix] ^ CLR_WHITE;
64 |
65 | SCR_ENTRY *pse= &se_mem[30][3*32+18]; // right-center
66 | for(iy=0; iy<8; iy++)
67 | for(ix=0; ix<8; ix++)
68 | pse[iy*32+ix]= (iy*8+ix) | SE_PALBANK(1);
69 |
70 | REG_BG1CNT= BG_CBB(1) | BG_SBB(30) | BG_MOSAIC;
71 | }
72 |
73 | int main()
74 | {
75 | // setup sprite
76 | oam_init(oam_mem, 128);
77 |
78 | load_metr();
79 |
80 | // set-up text: bg0, cbb0, sbb31
81 | tte_init_chr4c_b4_default(0, BG_CBB(2)|BG_SBB(31));
82 | tte_init_con();
83 |
84 | REG_DISPCNT= DCNT_BG0 | DCNT_BG1 | DCNT_OBJ | DCNT_OBJ_1D;
85 |
86 | test_mosaic();
87 |
88 | return 0;
89 | }
90 |
--------------------------------------------------------------------------------