From 4bbe531d08ce3d2b4126d7710d40bf2c2f7d940b Mon Sep 17 00:00:00 2001 From: Carl Vargklint Date: Thu, 18 Jun 2026 11:44:07 +0200 Subject: [PATCH] First code, works well, but very fast timeline --- Makefile | 9 + __pycache__/sprites_gen.cpython-313.pyc | Bin 0 -> 14413 bytes flash.sh | 41 + funconfig.h | 7 + pinout.md | 77 + sprites.h | 443 +++ sprites_gen.py | 312 ++ tama.bin | Bin 0 -> 9488 bytes tama.c | 413 +++ tama.elf | Bin 0 -> 86052 bytes tama.hex | 595 ++++ tama.lst | 3458 +++++++++++++++++++++++ tama.map | 586 ++++ tama_ext.bin | 0 14 files changed, 5941 insertions(+) create mode 100644 Makefile create mode 100644 __pycache__/sprites_gen.cpython-313.pyc create mode 100755 flash.sh create mode 100644 funconfig.h create mode 100644 pinout.md create mode 100644 sprites.h create mode 100644 sprites_gen.py create mode 100755 tama.bin create mode 100644 tama.c create mode 100755 tama.elf create mode 100644 tama.hex create mode 100644 tama.lst create mode 100644 tama.map create mode 100755 tama_ext.bin diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..8ea7cd6 --- /dev/null +++ b/Makefile @@ -0,0 +1,9 @@ +all : flash + +TARGET:=tama + +TARGET_MCU?=CH32V003 +include ../ch32v003fun/ch32fun/ch32fun.mk + +flash : cv_flash +clean : cv_clean diff --git a/__pycache__/sprites_gen.cpython-313.pyc b/__pycache__/sprites_gen.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dc2c9720a1c62acd7e63291e61735c3e2afd18ca GIT binary patch literal 14413 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 HY!Ckn?vG)o literal 0 HcmV?d00001 diff --git a/flash.sh b/flash.sh new file mode 100755 index 0000000..8224744 --- /dev/null +++ b/flash.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +# Build the Panagotchi firmware and flash it to the CH32V003 over single-wire +# debug (WCH-LinkE on DIO/PD1). +set -e + +DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$DIR" + +TARGET=tama + +# Regenerate sprites.h from the editable art generator (if python3 is present). +if command -v python3 >/dev/null 2>&1; then + echo ">> Generating sprites.h..." + python3 sprites_gen.py > sprites.h +fi + +# --- Toolchain (xpack riscv-none-elf-gcc, bundles a ch32fun-compatible newlib) --- +XROOT="/home/superminaren/CH32V003/xpack-riscv-none-elf-gcc-14.2.0-3" +export PATH="$XROOT/bin:$PATH" +MAKEFLAGS_TC=(PREFIX=riscv-none-elf NEWLIB="$XROOT/riscv-none-elf/include") + +MINICHLINK="$DIR/../ch32v003fun/minichlink/minichlink" + +echo ">> Building..." +make clean >/dev/null 2>&1 || true +make "$TARGET.bin" "${MAKEFLAGS_TC[@]}" + +echo ">> Flashing $TARGET.bin to CH32V003..." +# minichlink auto-switches the WCH-LinkE from ARM to RISC-V mode on first run; +# if that happens it asks for a re-attempt, so retry a few times. +for i in 1 2 3; do + if "$MINICHLINK" -w "$TARGET.bin" flash -b; then + echo ">> Done. The Panagotchi should now be running on the OLED." + exit 0 + fi + echo ">> retry $i..." + sleep 1 +done + +echo ">> Flash failed after retries." >&2 +exit 1 diff --git a/funconfig.h b/funconfig.h new file mode 100644 index 0000000..1abd059 --- /dev/null +++ b/funconfig.h @@ -0,0 +1,7 @@ +#ifndef _FUNCONFIG_H +#define _FUNCONFIG_H + +// Configuration overrides go here. Defaults in ch32fun/ch32fun.h are fine for blink. +#define FUNCONF_USE_HSI 1 // internal 24 MHz RC oscillator (no external crystal needed) + +#endif diff --git a/pinout.md b/pinout.md new file mode 100644 index 0000000..d27d42a --- /dev/null +++ b/pinout.md @@ -0,0 +1,77 @@ +# CH32V003F4P6 — IR Remote / Badge Project Pinout + +Last updated: 2026-06-18 + +## MCU + +- **Part:** CH32V003F4P6 +- **Package:** TSSOP20 +- **Core:** QingKe RISC-V2A, 48 MHz +- **VDD:** 3.3V nominal (2.7–3.6V tolerance), supplied via TLV61070A boost from CR2032 +- **Ports available:** PA1–PA2, PC0–PC7, PD0–PD7 (18 GPIOs total; PD7 shared with NRST) + +## Pin Assignment + +| Pin | Function | Notes | +|------|------------------------|------------------------------------------------------------------------| +| PA1 | Indicator LED | Activity/status LED. No documented alternate-function conflicts. | +| PC0 | OK Button | Input, pull-up, active-low. Also TIM1 CH3 (default remap) — not used as PWM here, fine as plain GPIO. | +| PC1 | OLED SDA | I2C1 | +| PC2 | OLED SCL | I2C1 | +| PC4 | IR Receiver VCC (switched) | GPIO output, drives power gate (high-side) for IR receiver module. Switch off when IR not in use to save current (~200–500 µA continuous draw when powered). | +| PD1 | SWDIO | Reserved — debug/programming. Do not repurpose. | +| PD2 | Buzzer (PWM tone) | TIM2-driven PWM, passive piezo. Confirmed working pattern on this chip; caution that heavy use can interfere with programming since PD1 (SWDIO) is adjacent/shared in function. | +| PD3 | IR Receiver DATA | Input, pull-up. EXTI-capable — use falling-edge interrupt to catch IR bursts rather than polling. Note: TIM1 default-remap CH2 also lives here, unused as PWM in this design. | +| PD4 | IR TX (PWM, 38 kHz carrier) | TIM1 CH1 (default remap). Drives transistor stage → IR333C-A LED, current-limited per design. | +| PD5 | Right Button | Input, pull-up. Also candidate wake-from-sleep EXTI source. | +| PD6 | Left Button | Input, pull-up. | +| PD7 | NRST | Reserved (shared reset pad). Reconfigure deliberately only if using as deep-sleep wake source — confirm wake mode requirements before repurposing. | + +### Free / unused pins + +PA2, PC3, PC5, PC6, PC7, PD0 + +- PC3 was earlier considered for TLV61070A EN, but EN is wired per the power architecture below (see note). +- PC5/PC7 carry TIM1 full-remap alternate functions (CH1/ETR, CH2) — keep in mind if a second PWM channel is needed later. +- PA2 has no documented alternate-function entanglement found so far — good candidate for future expansion, similar to PA1. + +## Power Architecture + +- **Cell:** CR2032 coin cell +- **Boost converter:** TLV61070A (synchronous boost, SOT-23-6, DBV) + - VIN: direct from CR2032 + - VOUT: 3.3V, set via FB divider **R1 = 560 kΩ, R2 = 100 kΩ** (Vref ≈ 0.5V typical — confirm tolerance in datasheet if accuracy-critical) + - EN: tie to VIN for always-on main MCU rail (no GPIO needed), OR to a GPIO if this specific converter instance needs to be software-gateable. **Confirm which role this converter instance plays in the final design** — if it's the main MCU supply, EN→VIN is correct; if it's a switchable secondary rail, EN needs a GPIO instead. + - True load disconnect on EN-low (no body-diode leakage path), unlike most boost converters — useful if this rail ever needs clean shutdown. + - Light-load power-save mode, ~20 µA Iq from VOUT. + +- **OLED power gating:** No dedicated pin assigned in this pinout. The module has no always-on indicator LED, so the software `0xAE` display-off command may be sufficient on its own. Hardware gating was discussed as an option but not assigned a pin — confirm before layout freeze if hardware gating is still wanted for the OLED, separate from the IR receiver gating on PC4. + +- **IR Receiver power gating:** PC4 drives the IR receiver module's VCC, switched off when not listening for IR, to avoid the ~200–500 µA continuous draw typical of TSOP-style demodulating receivers (exact figure for XL-IRM0038D not independently confirmed — estimated from sibling parts in the same family). + +## Display + +- **Module:** SSD1306, 128×64 (or 128×32 — confirm) +- **Interface:** I2C1, SDA = PC1, SCL = PC2 +- **Power:** confirm whether gated or tied to main 3.3V rail (see Power Architecture note above) + +## IR Subsystem + +- **TX LED:** Everlight IR333C-A, 940 nm, 5mm through-hole (LCSC C5130) + - Driven via PD4 (TIM1 CH1 PWM, 38 kHz carrier) through a transistor stage (reservoir capacitor topology / AC-coupled gate protection, per existing design pattern) + - Current heavily limited per design intent — confirm final resistor/transistor values against IR333C-A datasheet forward voltage/current specs +- **RX Module:** Xinglight XL-IRM0038D, 38 kHz, SIP-3 through-hole + - VCC: PC4 (switched) + - DATA (OUT): PD3, input pull-up, EXTI falling-edge + - GND: common ground + - **Pin order not independently verified in this conversation — confirm against XL-IRM0038D datasheet/silkscreen before finalizing layout (SIP-3 IR receiver modules vary in pin order between manufacturers).** + +## Audio + +- **Buzzer:** Passive piezo, PWM tone generation via PD2 (TIM2) + +## Inputs + +- 3x tactile buttons: PC0 (OK), PD5 (Right), PD6 (Left) — all input, internal or external pull-up, active-low, software debounce +- One of these (suggest PD5) intended as deep-sleep wake-from-EXTI source — confirm in firmware before relying on it for wake behavior, and confirm sleep mode (standby vs. lighter retained-state sleep) since wake mechanism differs between modes on this chip. + diff --git a/sprites.h b/sprites.h new file mode 100644 index 0000000..9a92810 --- /dev/null +++ b/sprites.h @@ -0,0 +1,443 @@ +// Auto-generated by sprites_gen.py -- do not edit by hand. +#ifndef _SPRITES_H +#define _SPRITES_H + +#define PANA_W 32 +#define PANA_H 32 +#define ICON_W 16 +#define ICON_H 16 + +// pana_idle: 32x32 +static const unsigned char pana_idle[] = { + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x80, + 0x0f, 0xe0, 0x07, 0xf0, + 0x1f, 0xf0, 0x0f, 0xf8, + 0x1f, 0xf0, 0x0f, 0xf8, + 0x1f, 0xf0, 0x0f, 0xf8, + 0x3f, 0xf8, 0x9f, 0xfc, + 0x1f, 0xff, 0xff, 0xf8, + 0x1f, 0xff, 0xff, 0xf8, + 0x1f, 0xff, 0xff, 0xf8, + 0x0f, 0xff, 0xff, 0xf0, + 0x03, 0xff, 0xff, 0xe0, + 0x07, 0xff, 0xff, 0xf0, + 0x07, 0xef, 0xfb, 0xf0, + 0x0f, 0x83, 0xe0, 0xf8, + 0x0f, 0x93, 0xe4, 0xf8, + 0x0f, 0x11, 0xc4, 0x78, + 0x0f, 0x83, 0xe0, 0xf8, + 0x1f, 0x83, 0xe0, 0xfc, + 0x0f, 0xef, 0x7b, 0xf8, + 0x0f, 0xfc, 0x1f, 0xf8, + 0x0f, 0xff, 0x7f, 0xf8, + 0x0f, 0xff, 0xff, 0xf8, + 0x07, 0xf8, 0x0f, 0xf0, + 0x07, 0xff, 0xff, 0xf0, + 0x03, 0xff, 0xff, 0xe0, + 0x01, 0xff, 0xff, 0xc0, + 0x00, 0xff, 0xff, 0x80, + 0x00, 0x7f, 0xff, 0x00, + 0x00, 0x1f, 0xfc, 0x00, + 0x00, 0x00, 0x80, 0x00, +}; + +// pana_blink: 32x32 +static const unsigned char pana_blink[] = { + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x80, + 0x0f, 0xe0, 0x07, 0xf0, + 0x1f, 0xf0, 0x0f, 0xf8, + 0x1f, 0xf0, 0x0f, 0xf8, + 0x1f, 0xf0, 0x0f, 0xf8, + 0x3f, 0xf8, 0x9f, 0xfc, + 0x1f, 0xff, 0xff, 0xf8, + 0x1f, 0xff, 0xff, 0xf8, + 0x1f, 0xff, 0xff, 0xf8, + 0x0f, 0xff, 0xff, 0xf0, + 0x03, 0xff, 0xff, 0xe0, + 0x07, 0xff, 0xff, 0xf0, + 0x07, 0xff, 0xff, 0xf0, + 0x0f, 0xff, 0xff, 0xf8, + 0x0f, 0xff, 0xff, 0xf8, + 0x0f, 0x01, 0xc0, 0x78, + 0x0f, 0xff, 0xff, 0xf8, + 0x1f, 0xff, 0xff, 0xfc, + 0x0f, 0xff, 0x7f, 0xf8, + 0x0f, 0xfc, 0x1f, 0xf8, + 0x0f, 0xff, 0x7f, 0xf8, + 0x0f, 0xff, 0xff, 0xf8, + 0x07, 0xf8, 0x0f, 0xf0, + 0x07, 0xff, 0xff, 0xf0, + 0x03, 0xff, 0xff, 0xe0, + 0x01, 0xff, 0xff, 0xc0, + 0x00, 0xff, 0xff, 0x80, + 0x00, 0x7f, 0xff, 0x00, + 0x00, 0x1f, 0xfc, 0x00, + 0x00, 0x00, 0x80, 0x00, +}; + +// pana_happy: 32x32 +static const unsigned char pana_happy[] = { + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x80, + 0x0f, 0xe0, 0x07, 0xf0, + 0x1f, 0xf0, 0x0f, 0xf8, + 0x1f, 0xf0, 0x0f, 0xf8, + 0x1f, 0xf0, 0x0f, 0xf8, + 0x3f, 0xf8, 0x9f, 0xfc, + 0x1f, 0xff, 0xff, 0xf8, + 0x1f, 0xff, 0xff, 0xf8, + 0x1f, 0xff, 0xff, 0xf8, + 0x0f, 0xff, 0xff, 0xf0, + 0x03, 0xff, 0xff, 0xe0, + 0x07, 0xff, 0xff, 0xf0, + 0x07, 0xff, 0xff, 0xf0, + 0x0f, 0xff, 0xff, 0xf8, + 0x0f, 0xef, 0xfb, 0xf8, + 0x0f, 0xd7, 0xf5, 0xf8, + 0x0f, 0xff, 0xff, 0xf8, + 0x1f, 0xff, 0xff, 0xfc, + 0x0f, 0xff, 0xff, 0xf8, + 0x0f, 0xf8, 0x0f, 0xf8, + 0x0f, 0xfb, 0xef, 0xf8, + 0x0f, 0xf7, 0xf7, 0xf8, + 0x07, 0xfc, 0x1f, 0xf0, + 0x07, 0xff, 0xff, 0xf0, + 0x03, 0xff, 0xff, 0xe0, + 0x01, 0xff, 0xff, 0xc0, + 0x00, 0xff, 0xff, 0x80, + 0x00, 0x7f, 0xff, 0x00, + 0x00, 0x1f, 0xfc, 0x00, + 0x00, 0x00, 0x80, 0x00, +}; + +// pana_sad: 32x32 +static const unsigned char pana_sad[] = { + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x80, + 0x0f, 0xe0, 0x07, 0xf0, + 0x1f, 0xf0, 0x0f, 0xf8, + 0x1f, 0xf0, 0x0f, 0xf8, + 0x1f, 0xf0, 0x0f, 0xf8, + 0x3f, 0xf8, 0x9f, 0xfc, + 0x1f, 0xff, 0xff, 0xf8, + 0x1f, 0xff, 0xff, 0xf8, + 0x1f, 0xff, 0xff, 0xf8, + 0x0f, 0xff, 0xff, 0xf0, + 0x03, 0xff, 0xff, 0xe0, + 0x07, 0xff, 0xff, 0xf0, + 0x07, 0xff, 0xff, 0xf0, + 0x0f, 0xef, 0xfb, 0xf8, + 0x0f, 0x83, 0xe0, 0xf8, + 0x0f, 0x93, 0xe4, 0xf8, + 0x0f, 0x11, 0xc4, 0x78, + 0x1f, 0x83, 0xe0, 0xfc, + 0x0f, 0x83, 0x60, 0xf8, + 0x0f, 0xec, 0x1b, 0xf8, + 0x0f, 0xff, 0x7f, 0xf8, + 0x0f, 0xfc, 0x1f, 0xf8, + 0x07, 0xf7, 0xf7, 0xf0, + 0x07, 0xfb, 0xef, 0xf0, + 0x03, 0xff, 0xff, 0xe0, + 0x01, 0xff, 0xff, 0xc0, + 0x00, 0xff, 0xff, 0x80, + 0x00, 0x7f, 0xff, 0x00, + 0x00, 0x1f, 0xfc, 0x00, + 0x00, 0x00, 0x80, 0x00, +}; + +// pana_eat: 32x32 +static const unsigned char pana_eat[] = { + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x80, + 0x0f, 0xe0, 0x07, 0xf0, + 0x1f, 0xf0, 0x0f, 0xf8, + 0x1f, 0xf0, 0x0f, 0xf8, + 0x1f, 0xf0, 0x0f, 0xf8, + 0x3f, 0xf8, 0x9f, 0xfc, + 0x1f, 0xff, 0xff, 0xf8, + 0x1f, 0xff, 0xff, 0xf8, + 0x1f, 0xff, 0xff, 0xf8, + 0x0f, 0xff, 0xff, 0xf0, + 0x03, 0xff, 0xff, 0xe0, + 0x07, 0xef, 0xfb, 0xf0, + 0x07, 0x83, 0xe0, 0xf0, + 0x0f, 0x93, 0xe4, 0xf8, + 0x0f, 0x11, 0xc4, 0x78, + 0x0f, 0x83, 0xe0, 0xf8, + 0x0f, 0x83, 0xe0, 0xf8, + 0x1f, 0xef, 0xfb, 0xfc, + 0x0f, 0xff, 0x7f, 0xf8, + 0x0f, 0xfc, 0x1f, 0xf8, + 0x0f, 0xfc, 0x1f, 0xf8, + 0x0f, 0xf8, 0x0f, 0xf8, + 0x07, 0xfc, 0x1f, 0xf0, + 0x07, 0xfc, 0x1f, 0xf0, + 0x03, 0xff, 0x7f, 0xe0, + 0x01, 0xff, 0xff, 0xc0, + 0x00, 0xff, 0xff, 0x80, + 0x00, 0x7f, 0xff, 0x00, + 0x00, 0x1f, 0xfc, 0x00, + 0x00, 0x00, 0x80, 0x00, +}; + +// pana_sleep: 32x32 +static const unsigned char pana_sleep[] = { + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x80, + 0x0f, 0xe0, 0x07, 0xf0, + 0x1f, 0xf0, 0x0f, 0xf8, + 0x1f, 0xf0, 0x0f, 0xf8, + 0x1f, 0xf0, 0x0f, 0xf8, + 0x3f, 0xf8, 0x9f, 0xfc, + 0x1f, 0xff, 0xff, 0xf8, + 0x1f, 0xff, 0xff, 0xf8, + 0x1f, 0xff, 0xff, 0xf8, + 0x0f, 0xff, 0xff, 0xf0, + 0x03, 0xff, 0xff, 0xe0, + 0x07, 0xff, 0xff, 0xf0, + 0x07, 0xff, 0xff, 0xf0, + 0x0f, 0xff, 0xff, 0xf8, + 0x0f, 0xff, 0xff, 0xf8, + 0x0f, 0xff, 0xff, 0xf8, + 0x0f, 0x01, 0xc0, 0x78, + 0x1f, 0xff, 0xff, 0xfc, + 0x0f, 0xff, 0xff, 0xf8, + 0x0f, 0xff, 0x7f, 0xf8, + 0x0f, 0xfc, 0x1f, 0xf8, + 0x0f, 0xff, 0x7f, 0xf8, + 0x07, 0xff, 0xff, 0xf0, + 0x07, 0xff, 0xff, 0xf0, + 0x03, 0xff, 0xff, 0xe0, + 0x01, 0xff, 0xff, 0xc0, + 0x00, 0xff, 0xff, 0x80, + 0x00, 0x7f, 0xff, 0x00, + 0x00, 0x1f, 0xfc, 0x00, + 0x00, 0x00, 0x80, 0x00, +}; + +// pana_dead: 32x32 +static const unsigned char pana_dead[] = { + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x80, + 0x0f, 0xe0, 0x07, 0xf0, + 0x1f, 0xf0, 0x0f, 0xf8, + 0x1f, 0xf0, 0x0f, 0xf8, + 0x1f, 0xf0, 0x0f, 0xf8, + 0x3f, 0xf8, 0x9f, 0xfc, + 0x1f, 0xff, 0xff, 0xf8, + 0x1f, 0xff, 0xff, 0xf8, + 0x1f, 0xff, 0xff, 0xf8, + 0x0f, 0xff, 0xff, 0xf0, + 0x03, 0xff, 0xff, 0xe0, + 0x07, 0xff, 0xff, 0xf0, + 0x07, 0xff, 0xff, 0xf0, + 0x0f, 0xbb, 0xee, 0xf8, + 0x0f, 0xd7, 0xf5, 0xf8, + 0x0f, 0xef, 0xfb, 0xf8, + 0x0f, 0xd7, 0xf5, 0xf8, + 0x1f, 0xbb, 0xee, 0xfc, + 0x0f, 0xff, 0xff, 0xf8, + 0x0f, 0xff, 0xff, 0xf8, + 0x0f, 0xff, 0xff, 0xf8, + 0x0f, 0xf0, 0x07, 0xf8, + 0x07, 0xff, 0xff, 0xf0, + 0x07, 0xff, 0xff, 0xf0, + 0x03, 0xff, 0xff, 0xe0, + 0x01, 0xff, 0xff, 0xc0, + 0x00, 0xff, 0xff, 0x80, + 0x00, 0x7f, 0xff, 0x00, + 0x00, 0x1f, 0xfc, 0x00, + 0x00, 0x00, 0x80, 0x00, +}; + +enum { EXP_IDLE, EXP_BLINK, EXP_HAPPY, EXP_SAD, EXP_EAT, EXP_SLEEP, EXP_DEAD, EXP_COUNT }; +static const unsigned char *const pana_frames[EXP_COUNT] = { + pana_idle, pana_blink, pana_happy, pana_sad, pana_eat, pana_sleep, pana_dead, +}; + +// spr_grave: 32x32 +static const unsigned char spr_grave[] = { + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xfc, 0x00, + 0x03, 0xff, 0xff, 0x00, + 0x07, 0xff, 0xff, 0x80, + 0x06, 0x1f, 0xe1, 0x80, + 0x06, 0x30, 0x31, 0x80, + 0x06, 0x30, 0x31, 0x80, + 0x06, 0x3f, 0xc3, 0x00, + 0x06, 0x33, 0x03, 0x00, + 0x06, 0x31, 0x83, 0x00, + 0x06, 0x30, 0xc3, 0x00, + 0x06, 0x00, 0x06, 0x00, + 0x06, 0x0f, 0x06, 0x00, + 0x07, 0xff, 0xff, 0x80, + 0x0f, 0xff, 0xff, 0xc0, + 0x1f, 0xff, 0xff, 0xe0, + 0x3f, 0xff, 0xff, 0xf0, + 0x7f, 0xff, 0xff, 0xf8, + 0xff, 0xff, 0xff, 0xfc, + 0xff, 0xff, 0xff, 0xfc, + 0x00, 0xf0, 0xf0, 0x00, + 0x03, 0xff, 0xf0, 0x00, + 0x0f, 0xff, 0xfc, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, +}; + +// spr_poop: 8x8 +static const unsigned char spr_poop[] = { + 0x00, + 0x18, + 0x3c, + 0x6c, + 0x7e, + 0xff, + 0xff, + 0x00, +}; + +// icon_feed: 16x16 +static const unsigned char icon_feed[] = { + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0xa0, + 0x01, 0x90, + 0x0f, 0xe0, + 0x1b, 0xf0, + 0x3b, 0xf8, + 0x31, 0xf8, + 0x3b, 0xf8, + 0x7b, 0xfc, + 0x3f, 0xf8, + 0x3f, 0xf8, + 0x3f, 0xf8, + 0x1f, 0xf0, + 0x0f, 0xe0, + 0x01, 0x00, +}; + +// icon_play: 16x16 +static const unsigned char icon_play[] = { + 0x00, 0x00, + 0x00, 0x00, + 0x07, 0x70, + 0x00, 0x00, + 0x1f, 0x7c, + 0x3f, 0x7e, + 0x3f, 0x7e, + 0x3f, 0x7e, + 0x00, 0x00, + 0x3f, 0x7e, + 0x3f, 0x7e, + 0x3f, 0x7e, + 0x1f, 0x7c, + 0x00, 0x00, + 0x07, 0x70, + 0x00, 0x00, +}; + +// icon_sleep: 16x16 +static const unsigned char icon_sleep[] = { + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x04, 0x00, + 0x0c, 0x00, + 0x1c, 0x00, + 0x18, 0x00, + 0x1c, 0x00, + 0x3c, 0x00, + 0x1c, 0x00, + 0x1e, 0x00, + 0x1f, 0x00, + 0x0f, 0xe8, + 0x07, 0xf0, + 0x00, 0x80, + 0x00, 0x00, +}; + +// icon_clean: 16x16 +static const unsigned char icon_clean[] = { + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x80, + 0x00, 0x80, + 0x01, 0xc0, + 0x01, 0xc0, + 0x07, 0xf0, + 0x0d, 0xf8, + 0x0d, 0xf8, + 0x08, 0xf8, + 0x1d, 0xfc, + 0x0d, 0xf8, + 0x0f, 0xf8, + 0x0f, 0xf8, + 0x07, 0xf0, + 0x00, 0x80, +}; + +// icon_heal: 16x16 +static const unsigned char icon_heal[] = { + 0x00, 0x00, + 0x00, 0x80, + 0x07, 0xf0, + 0x0f, 0xf8, + 0x1c, 0x3c, + 0x3c, 0x3e, + 0x30, 0x0e, + 0x30, 0x0e, + 0x70, 0x0f, + 0x30, 0x0e, + 0x3c, 0x3e, + 0x3c, 0x3e, + 0x1f, 0xfc, + 0x0f, 0xf8, + 0x07, 0xf0, + 0x00, 0x80, +}; + +// icon_stats: 16x16 +static const unsigned char icon_stats[] = { + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0xc0, + 0x00, 0xc0, + 0x00, 0xc0, + 0x06, 0xc0, + 0x06, 0xc0, + 0x06, 0xd8, + 0x06, 0xd8, + 0x36, 0xd8, + 0x36, 0xd8, + 0x36, 0xd8, + 0x36, 0xd8, + 0x00, 0x00, + 0x00, 0x00, +}; + +#define ICON_COUNT 6 +static const unsigned char *const menu_icons[ICON_COUNT] = { + icon_feed, icon_play, icon_sleep, icon_clean, icon_heal, icon_stats, +}; +static const char *const menu_labels[ICON_COUNT] = { + "FEED", "PLAY", "SLEEP", "CLEAN", "HEAL", "STATS", +}; + +#endif // _SPRITES_H diff --git a/sprites_gen.py b/sprites_gen.py new file mode 100644 index 0000000..f0a896f --- /dev/null +++ b/sprites_gen.py @@ -0,0 +1,312 @@ +#!/usr/bin/env python3 +""" +sprites_gen.py -> generates sprites.h for the Panagotchi firmware. + +All artwork is defined here as math/ASCII so it stays human-editable. +Output is packed 1-bpp, row-major, MSB-first -- exactly the format +ch32fun's ssd1306_drawImage() expects (width must be a multiple of 8). + +Run: python3 sprites_gen.py > sprites.h +""" + +# ---------------------------------------------------------------- grid helpers +def grid(w, h): + return [[0] * w for _ in range(h)] + +def px(g, x, y, v=1): + if 0 <= y < len(g) and 0 <= x < len(g[0]): + g[y][x] = v + +def fill_ellipse(g, cx, cy, rx, ry, v=1): + for y in range(len(g)): + for x in range(len(g[0])): + dx = (x - cx) / rx + dy = (y - cy) / ry + if dx * dx + dy * dy <= 1.0: + g[y][x] = v + +def hline(g, x0, x1, y, v=1): + if x0 > x1: + x0, x1 = x1, x0 + for x in range(x0, x1 + 1): + px(g, x, y, v) + +def vline(g, x, y0, y1, v=1): + if y0 > y1: + y0, y1 = y1, y0 + for y in range(y0, y1 + 1): + px(g, x, y, v) + +def from_art(art): + """art = list of strings, '#'/'X'/'1' -> 1, anything else -> 0. + Rows are padded to a common width (rounded up to a multiple of 8).""" + w = max(len(r) for r in art) + w = (w + 7) // 8 * 8 + g = [] + for row in art: + g.append([1 if c in "#X1" else 0 for c in row.ljust(w)]) + return g + +def pack(g): + """Pack to bytes, MSB first, width padded to multiple of 8.""" + h = len(g) + w = len(g[0]) + wbytes = (w + 7) // 8 + out = [] + for y in range(h): + for b in range(wbytes): + byte = 0 + for bit in range(8): + x = b * 8 + bit + if x < w and g[y][x]: + byte |= 0x80 >> bit + out.append(byte) + return out + +def emit(name, g): + data = pack(g) + w = len(g[0]) + wbytes = (w + 7) // 8 + print(f"// {name}: {w}x{len(g)}") + print(f"static const unsigned char {name}[] = {{") + for i in range(0, len(data), wbytes): + row = data[i:i + wbytes] + print(" " + ", ".join(f"0x{v:02x}" for v in row) + ",") + print("};") + print() + +# ---------------------------------------------------------------- the panda +# 32x32 base body: round head/body + two ears. Features carved per expression. +def base_panda(): + g = grid(32, 32) + fill_ellipse(g, 16, 19, 13, 12) # head/body + fill_ellipse(g, 7, 7, 5, 5) # left ear + fill_ellipse(g, 24, 7, 5, 5) # right ear + return g + +def carve_eye(g, cx, cy): # dark socket + lit pupil + fill_ellipse(g, cx, cy, 3, 3, 0) + px(g, cx, cy, 1) + px(g, cx, cy - 1, 1) + +def panda_idle(): + g = base_panda() + carve_eye(g, 11, 17) + carve_eye(g, 21, 17) + fill_ellipse(g, 16, 21, 2, 1, 0) # nose + hline(g, 13, 19, 24, 0) # gentle mouth + return g + +def panda_blink(): + g = base_panda() + hline(g, 8, 14, 17, 0) # closed eyes + hline(g, 18, 24, 17, 0) + fill_ellipse(g, 16, 21, 2, 1, 0) + hline(g, 13, 19, 24, 0) + return g + +def panda_happy(): + g = base_panda() + # ^ ^ eyes + px(g, 10, 17, 0); px(g, 11, 16, 0); px(g, 12, 17, 0) + px(g, 20, 17, 0); px(g, 21, 16, 0); px(g, 22, 17, 0) + # big smile + for x in range(12, 21): + y = 22 + (1 if x in (12, 20) else (2 if 14 <= x <= 18 else 0)) + px(g, x, y, 0) + hline(g, 13, 19, 21, 0) + return g + +def panda_sad(): + g = base_panda() + carve_eye(g, 11, 18) + carve_eye(g, 21, 18) + fill_ellipse(g, 16, 21, 2, 1, 0) + # frown + for x in range(12, 21): + y = 25 - (1 if x in (12, 20) else (2 if 14 <= x <= 18 else 0)) + px(g, x, y, 0) + px(g, 8, 22, 1) # tear (lit dot below eye) + px(g, 8, 23, 1) + return g + +def panda_eat(): + g = base_panda() + carve_eye(g, 11, 16) + carve_eye(g, 21, 16) + fill_ellipse(g, 16, 23, 3, 3, 0) # wide open mouth + return g + +def panda_sleep(): + g = base_panda() + hline(g, 8, 14, 18, 0) # closed, relaxed + hline(g, 18, 24, 18, 0) + fill_ellipse(g, 16, 22, 2, 1, 0) + return g + +def panda_dead(): + g = base_panda() + # X X eyes + for d in range(-2, 3): + px(g, 11 + d, 17 + d, 0); px(g, 11 + d, 17 - d, 0) + px(g, 21 + d, 17 + d, 0); px(g, 21 + d, 17 - d, 0) + hline(g, 12, 20, 23, 0) # flat mouth + return g + +# ---------------------------------------------------------------- props +def grave(): + art = [ + " ", + " ", + " ############## ", + " ################## ", + " #################### ", + " ## ######## ## ", + " ## ## ## ## ", + " ## ## ## ## ", + " ## ######## ## ", + " ## ## ## ## ", + " ## ## ## ## ", + " ## ## ## ## ", + " ## ## ", + " ## #### ## ", + " #################### ", + " ###################### ", + " ######################## ", + " ########################## ", + " ############################ ", + "############################## ", + "############################## ", + " #### #### ", + " ############## ", + " ################## ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + ] + return from_art(art) + +def poop(): + art = [ + " ", + " ## ", + " #### ", + " ## ## ", + " ###### ", + "########", + "########", + " ", + ] + return from_art(art) + +# ---------------------------------------------------------------- 16x16 icons +def icon_feed(): # apple + g = grid(16, 16) + fill_ellipse(g, 7, 9, 6, 6) + vline(g, 8, 2, 4) # stem + px(g, 10, 2); px(g, 11, 3) # leaf + fill_ellipse(g, 5, 7, 1, 2, 0) # shine + return g + +def icon_play(): # ball + g = grid(16, 16) + fill_ellipse(g, 8, 8, 7, 7) + hline(g, 1, 15, 8, 0) + vline(g, 8, 1, 15, 0) + for d in range(-5, 6): + px(g, 8 + d, 3, 0); px(g, 8 + d, 13, 0) + return g + +def icon_sleep(): # moon + g = grid(16, 16) + fill_ellipse(g, 8, 8, 6, 6) + fill_ellipse(g, 11, 6, 6, 6, 0) # crescent cut + return g + +def icon_clean(): # water drop + g = grid(16, 16) + fill_ellipse(g, 8, 10, 5, 5) + for y in range(2, 10): + half = (y - 2) // 2 + hline(g, 8 - half, 8 + half, y) + fill_ellipse(g, 6, 9, 1, 2, 0) + return g + +def icon_heal(): # plus / cross + g = grid(16, 16) + fill_ellipse(g, 8, 8, 7, 7) + for t in range(4, 12): + hline(g, 6, 9, t, 0) + vline(g, t, 6, 9, 0) + return g + +def icon_stats(): # bar chart + g = grid(16, 16) + for i, h in enumerate((4, 8, 11, 6)): + x = 2 + i * 3 + for yy in range(14 - h, 14): + hline(g, x, x + 1, yy) + return g + +# ---------------------------------------------------------------- main +def main(): + print("// Auto-generated by sprites_gen.py -- do not edit by hand.") + print("#ifndef _SPRITES_H") + print("#define _SPRITES_H") + print() + print("#define PANA_W 32") + print("#define PANA_H 32") + print("#define ICON_W 16") + print("#define ICON_H 16") + print() + + frames = [ + ("pana_idle", panda_idle()), + ("pana_blink", panda_blink()), + ("pana_happy", panda_happy()), + ("pana_sad", panda_sad()), + ("pana_eat", panda_eat()), + ("pana_sleep", panda_sleep()), + ("pana_dead", panda_dead()), + ] + for n, g in frames: + emit(n, g) + + # expression index enum (matches frames[] order) + print("enum { EXP_IDLE, EXP_BLINK, EXP_HAPPY, EXP_SAD, EXP_EAT, EXP_SLEEP, EXP_DEAD, EXP_COUNT };") + print("static const unsigned char *const pana_frames[EXP_COUNT] = {") + print(" pana_idle, pana_blink, pana_happy, pana_sad, pana_eat, pana_sleep, pana_dead,") + print("};") + print() + + emit("spr_grave", grave()) + emit("spr_poop", poop()) + + icons = [ + ("icon_feed", icon_feed()), + ("icon_play", icon_play()), + ("icon_sleep", icon_sleep()), + ("icon_clean", icon_clean()), + ("icon_heal", icon_heal()), + ("icon_stats", icon_stats()), + ] + for n, g in icons: + emit(n, g) + + print("#define ICON_COUNT 6") + print("static const unsigned char *const menu_icons[ICON_COUNT] = {") + print(" icon_feed, icon_play, icon_sleep, icon_clean, icon_heal, icon_stats,") + print("};") + print('static const char *const menu_labels[ICON_COUNT] = {') + print(' "FEED", "PLAY", "SLEEP", "CLEAN", "HEAL", "STATS",') + print("};") + print() + print("#endif // _SPRITES_H") + +if __name__ == "__main__": + main() diff --git a/tama.bin b/tama.bin new file mode 100755 index 0000000000000000000000000000000000000000..ce467ea065f941d60a55432b85e7974c214d1b91 GIT binary patch literal 9488 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 literal 0 HcmV?d00001 diff --git a/tama.c b/tama.c new file mode 100644 index 0000000..3f50256 --- /dev/null +++ b/tama.c @@ -0,0 +1,413 @@ +/* + * PANAGOTCHI -- a Tamagotchi-style virtual pet for the CH32V003F4P6 badge. + * + * Hardware (see pinout.md): + * PA1 indicator LED (active-high) + * PC0 OK button (active-low, internal pull-up) + * PD5 Right button (active-low, internal pull-up) + * PD6 Left button (active-low, internal pull-up) + * PC1/PC2 SSD1306 128x64 OLED over I2C1 (driven by ssd1306_i2c.h) + * PD2 passive piezo buzzer (square-wave bit-bang tone) + * + * Controls: Left / Right move the menu cursor, OK activates the selected + * action. On the stats / dead screens any button returns / restarts. + */ + +#include "ch32fun.h" +#include + +#define SSD1306_128X64 // 128x64 panel (see pinout.md / OLED size) +#include "ssd1306_i2c.h" +#include "ssd1306.h" +#include "sprites.h" + +// ----------------------------------------------------------------- pins +#define LED_PIN PA1 +#define BTN_OK PC0 +#define BTN_RIGHT PD5 +#define BTN_LEFT PD6 +#define BUZZER PD2 + +// ----------------------------------------------------------------- tuning +#define FRAME_MS 60 // main loop period +#define TICK_FRAMES 50 // stat update every ~3 s (50 * 60 ms) +#define ANIM_FRAMES 12 // how long an action reaction is shown + +// ----------------------------------------------------------------- state +enum { SCR_MAIN, SCR_STATS, SCR_DEAD }; + +typedef struct { + int8_t satiety; // 0..100 (fullness) + int8_t happy; // 0..100 + int8_t energy; // 0..100 + int8_t hygiene; // 0..100 + int8_t health; // 0..100 + uint16_t age_min; // age in game-minutes (one per tick) + uint8_t poop; // 0..3 piles on the floor + uint8_t sleeping; // 1 while napping + uint8_t alive; +} Pet; + +static Pet pet; +static uint8_t screen; +static uint8_t cursor; // selected menu icon 0..ICON_COUNT-1 +static uint8_t anim_exp; // expression forced during a reaction +static uint8_t anim_timer; // frames remaining for the reaction +static uint32_t frame; // free-running frame counter +static uint16_t tick_acc; // frames since last stat tick + +// menu icon order must match sprites.h menu_icons[] / menu_labels[] +enum { ACT_FEED, ACT_PLAY, ACT_SLEEP, ACT_CLEAN, ACT_HEAL, ACT_STATS }; + +// ----------------------------------------------------------------- helpers +static int8_t clamp100(int v) { return v < 0 ? 0 : (v > 100 ? 100 : v); } + +// short square-wave beep on the passive piezo (blocking, ms-scale only) +static void beep(uint16_t freq, uint16_t ms) +{ + if (freq == 0) { Delay_Ms(ms); return; } + uint32_t half = 500000u / freq; // half-period in us + uint32_t cycles = ((uint32_t)ms * 1000u) / (half * 2u); + for (uint32_t i = 0; i < cycles; i++) { + funDigitalWrite(BUZZER, FUN_HIGH); + Delay_Us(half); + funDigitalWrite(BUZZER, FUN_LOW); + Delay_Us(half); + } +} + +static void led_blink(void) +{ + funDigitalWrite(LED_PIN, FUN_HIGH); + Delay_Ms(30); + funDigitalWrite(LED_PIN, FUN_LOW); +} + +static void pet_reset(void) +{ + pet.satiety = 80; + pet.happy = 80; + pet.energy = 90; + pet.hygiene = 100; + pet.health = 100; + pet.age_min = 0; + pet.poop = 0; + pet.sleeping = 0; + pet.alive = 1; + screen = SCR_MAIN; + cursor = 0; +} + +// pick the expression frame to draw this instant +static uint8_t current_expression(void) +{ + if (!pet.alive) return EXP_DEAD; + if (anim_timer) return anim_exp; + if (pet.sleeping) return EXP_SLEEP; + if (pet.health < 30 || pet.happy < 25 || pet.satiety < 20) + return EXP_SAD; + // idle, with an occasional blink + if ((frame % 50) < 4) return EXP_BLINK; + return EXP_IDLE; +} + +// ----------------------------------------------------------------- actions +static void react(uint8_t exp) { anim_exp = exp; anim_timer = ANIM_FRAMES; } + +static void do_action(uint8_t act) +{ + switch (act) { + case ACT_FEED: + pet.satiety = clamp100(pet.satiety + 30); + pet.hygiene = clamp100(pet.hygiene - 5); + react(EXP_EAT); + beep(880, 60); beep(1175, 80); + led_blink(); + break; + + case ACT_PLAY: + if (pet.energy < 15) { beep(220, 120); break; } // too tired + pet.happy = clamp100(pet.happy + 25); + pet.energy = clamp100(pet.energy - 12); + react(EXP_HAPPY); + beep(988, 60); beep(1319, 60); beep(1568, 90); + led_blink(); + break; + + case ACT_SLEEP: + pet.sleeping = !pet.sleeping; + beep(pet.sleeping ? 440 : 660, 120); + break; + + case ACT_CLEAN: + pet.poop = 0; + pet.hygiene = 100; + pet.happy = clamp100(pet.happy + 5); + beep(1319, 50); beep(1047, 50); + break; + + case ACT_HEAL: + pet.health = clamp100(pet.health + 35); + beep(784, 60); beep(1047, 60); beep(1319, 90); + led_blink(); + break; + + case ACT_STATS: + screen = SCR_STATS; + beep(659, 40); + break; + } +} + +// ----------------------------------------------------------------- game tick +static void game_tick(void) +{ + pet.age_min++; + + if (pet.sleeping) { + pet.energy = clamp100(pet.energy + 10); + // drift down slowly even while asleep + pet.satiety = clamp100(pet.satiety - 1); + if (pet.energy >= 100) pet.sleeping = 0; // wakes when rested + } else { + pet.satiety = clamp100(pet.satiety - 3); + pet.energy = clamp100(pet.energy - 2); + pet.happy = clamp100(pet.happy - 2); + } + + pet.hygiene = clamp100(pet.hygiene - 1); + + // random-ish bowel movements (LFSR-free: derive from counters) + if (!pet.sleeping && pet.poop < 3 && + ((pet.age_min * 7u + frame) & 0x0F) == 0) + pet.poop++; + + // being dirty / full of poop saps happiness + if (pet.poop) pet.happy = clamp100(pet.happy - pet.poop); + if (pet.hygiene < 20) pet.happy = clamp100(pet.happy - 1); + + // health responds to overall wellbeing + int8_t lo = pet.satiety; + if (pet.happy < lo) lo = pet.happy; + if (pet.energy < lo) lo = pet.energy; + if (pet.hygiene < lo) lo = pet.hygiene; + if (lo < 15) pet.health = clamp100(pet.health - 5); + else if (lo > 50) pet.health = clamp100(pet.health + 2); + + if (pet.health <= 0) { + pet.alive = 0; + screen = SCR_DEAD; + beep(330, 200); beep(247, 200); beep(165, 400); + } +} + +// ----------------------------------------------------------------- drawing +static void draw_center_str(int y, const char *s) +{ + int len = 0; + while (s[len]) len++; + int x = (SSD1306_W - len * 8) / 2; + if (x < 0) x = 0; + ssd1306_drawstr(x, y, s, 1); +} + +static void draw_menu_bar(void) +{ + // 6 icons across the bottom, selected one boxed + for (uint8_t i = 0; i < ICON_COUNT; i++) { + int x = i * 21 + 3; + ssd1306_drawImage(x, 48, menu_icons[i], ICON_W, ICON_H, 0); + if (i == cursor) + ssd1306_drawRect(x - 2, 46, ICON_W + 3, ICON_H + 2, 1); + } +} + +static void draw_main(void) +{ + ssd1306_setbuf(0); + + // top bar: action label, with a tiny low-health warning + draw_center_str(0, menu_labels[cursor]); + if (pet.alive && pet.health < 30 && (frame & 8)) + ssd1306_drawstr(0, 0, "!", 1); + ssd1306_drawFastHLine(0, 10, SSD1306_W, 1); + + // pet: gentle horizontal stroll + vertical bob (still while asleep) + int px, py; + if (pet.sleeping) { + px = 48; py = 16; + ssd1306_drawstr(px + PANA_W - 2, 14, "z", 1); + ssd1306_drawstr(px + PANA_W + 4, 12, "Z", 1); + } else { + uint32_t t = frame % 80; + px = (t < 40) ? 30 + t : 30 + (80 - t); // 30..70..30 + py = 14 + ((frame % 16) < 8 ? 0 : 1); + } + ssd1306_drawImage(px, py, pana_frames[current_expression()], + PANA_W, PANA_H, 0); + + // floor + poop piles + ssd1306_drawFastHLine(0, 46, SSD1306_W, 1); + for (uint8_t i = 0; i < pet.poop; i++) + ssd1306_drawImage(8 + i * 12, 38, spr_poop, 8, 8, 0); + + draw_menu_bar(); + ssd1306_refresh(); +} + +static void draw_bar(int y, const char *label, int8_t val) +{ + ssd1306_drawstr(0, y, label, 1); + int bx = 48, bw = 76; + ssd1306_drawRect(bx, y, bw, 7, 1); + int fill = (val * (bw - 2)) / 100; + if (fill > 0) ssd1306_fillRect(bx + 1, y + 1, fill, 5, 1); +} + +static void draw_stats(void) +{ + ssd1306_setbuf(0); + draw_center_str(0, "-- STATUS --"); + draw_bar(10, "FOOD", pet.satiety); + draw_bar(19, "FUN ", pet.happy); + draw_bar(28, "ENGY", pet.energy); + draw_bar(37, "WASH", pet.hygiene); + draw_bar(46, "HLTH", pet.health); + + char line[17]; + snprintf(line, sizeof(line), "Age %u %s", pet.age_min, + pet.sleeping ? "Zzz" : ""); + ssd1306_drawstr(0, 56, line, 1); + ssd1306_refresh(); +} + +static void draw_dead(void) +{ + ssd1306_setbuf(0); + ssd1306_drawImage(48, 8, spr_grave, 32, 32, 0); + draw_center_str(44, "R.I.P."); + char line[17]; + snprintf(line, sizeof(line), "lived %u min", pet.age_min); + draw_center_str(52, line); + ssd1306_refresh(); +} + +// ----------------------------------------------------------------- input +typedef struct { uint8_t ok, left, right; } Buttons; + +static Buttons read_buttons(void) +{ + // active-low: pressed reads 0 + Buttons b; + b.ok = !funDigitalRead(BTN_OK); + b.left = !funDigitalRead(BTN_LEFT); + b.right = !funDigitalRead(BTN_RIGHT); + return b; +} + +// ----------------------------------------------------------------- setup +static void gpio_setup(void) +{ + funGpioInitAll(); + + funPinMode(LED_PIN, GPIO_Speed_10MHz | GPIO_CNF_OUT_PP); + funDigitalWrite(LED_PIN, FUN_LOW); + + funPinMode(BUZZER, GPIO_Speed_10MHz | GPIO_CNF_OUT_PP); + funDigitalWrite(BUZZER, FUN_LOW); + + // buttons: input with internal pull-up (ODR high selects pull-up) + funPinMode(BTN_OK, GPIO_CNF_IN_PUPD); + funPinMode(BTN_LEFT, GPIO_CNF_IN_PUPD); + funPinMode(BTN_RIGHT, GPIO_CNF_IN_PUPD); + funDigitalWrite(BTN_OK, FUN_HIGH); + funDigitalWrite(BTN_LEFT, FUN_HIGH); + funDigitalWrite(BTN_RIGHT, FUN_HIGH); +} + +static void splash(void) +{ + ssd1306_setbuf(0); + draw_center_str(4, "PANAGOTCHI"); + ssd1306_drawImage(48, 16, pana_idle, PANA_W, PANA_H, 0); + draw_center_str(52, "press any key"); + ssd1306_refresh(); + + beep(659, 80); beep(784, 80); beep(988, 120); + + // wait until a button is pressed (or ~4 s timeout) + for (int i = 0; i < 200; i++) { + Buttons b = read_buttons(); + if (b.ok || b.left || b.right) break; + Delay_Ms(20); + } +} + +// ----------------------------------------------------------------- main +int main(void) +{ + SystemInit(); + gpio_setup(); + + Delay_Ms(120); // let the OLED rail settle + if (ssd1306_i2c_init()) { // non-zero == failure + // no display: fall back to a heartbeat blink so the board still shows life + while (1) { led_blink(); Delay_Ms(700); } + } + ssd1306_init(); + + pet_reset(); + splash(); + + Buttons prev = {0, 0, 0}; + + while (1) { + Buttons b = read_buttons(); + uint8_t ok_edge = b.ok && !prev.ok; + uint8_t left_edge = b.left && !prev.left; + uint8_t right_edge = b.right && !prev.right; + prev = b; + + switch (screen) { + case SCR_MAIN: + if (left_edge) { + cursor = (cursor + ICON_COUNT - 1) % ICON_COUNT; + beep(1047, 25); + } + if (right_edge) { + cursor = (cursor + 1) % ICON_COUNT; + beep(1047, 25); + } + if (ok_edge) do_action(cursor); + draw_main(); + break; + + case SCR_STATS: + if (ok_edge || left_edge || right_edge) { + screen = SCR_MAIN; + beep(880, 30); + } + draw_stats(); + break; + + case SCR_DEAD: + if (ok_edge) { // start a new pet + pet_reset(); + beep(659, 80); beep(988, 120); + } + draw_dead(); + break; + } + + if (anim_timer) anim_timer--; + + // advance game time independent of which screen is showing + if (pet.alive && ++tick_acc >= TICK_FRAMES) { + tick_acc = 0; + game_tick(); + } + + frame++; + Delay_Ms(FRAME_MS); + } +} diff --git a/tama.elf b/tama.elf new file mode 100755 index 0000000000000000000000000000000000000000..8e32faaea6ddf18eb9e6b0f9cbd796de96c74e8c GIT binary patch literal 86052 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 O3wtxcQ$~cV(fvQXJ#0Gw literal 0 HcmV?d00001 diff --git a/tama.hex b/tama.hex new file mode 100644 index 0000000..c826178 --- /dev/null +++ b/tama.hex @@ -0,0 +1,595 @@ +:100000006F00100400000000FE080000B2080000AD +:1000100000000000000000000000000000000000E0 +:1000200000000000000000000000000000000000D0 +:10003000B208000000000000B2080000000000004C +:10004000B2080000B2080000B2080000B2080000C8 +:10005000B2080000B2080000B2080000B2080000B8 +:10006000B2080000B2080000B2080000B2080000A8 +:10007000B2080000B2080000B2080000B208000098 +:10008000B2080000B2080000B2080000B208000088 +:10009000B2080000B2080000B20800000000000032 +:1000A000634E050263C305042E86AA857D5515C2DD +:1000B00085466378B6006356C00006068606E36C84 +:1000C000B6FE014563E4C500918D558D858205829C +:1000D000F5FA82808682C93F2E8582823305A04050 +:1000E0006347B000B305B040C1B7B305B0408682E6 +:1000F000653F3305A0408282868263C7050063495D +:1001000005005D372E858282B305B040E35B05FEB6 +:100110003305A040513F3305B0408282000099C6AC +:10012000014363D7B600B685054319A00143AE86E7 +:100130008D8EBA87B383E600B382F340634A5004DE +:1001400093C7F6FFFD87FD8EBA9681473386F5404B +:10015000B382F6006342C00493C7F5FFFD87FD8DAF +:10016000B6953385E540630403026372B7029307D3 +:10017000A002A38FF5FE9386F5FF637AD700238F45 +:10018000F5FE9386E5FF6374D700A38EF5FE8280AB +:100190008507A38FC7FE4DB73306F500034606005B +:1001A00085072380C2005DB72A832E8501CE832276 +:1001B000060001475C426348A700238007004842CD +:1001C0003305554082800C461442FD15AE96E386F9 +:1001D000D7FE9386170054C2B306E30083C6060019 +:1001E00005072380D700F9B7B70700E09387470FCB +:1001F0009843137707086DFF372730781307870870 +:10020000B70600E098C39386460F7147A54571561F +:100210009C4293F70708EDFF3353E5001373F30097 +:10022000B3B76500B307F04093F7770293870703EE +:100230009A97A20793E757089CC27117E31AC7FC65 +:10024000828037F700E01C473E951C47898FE3CE3C +:1002500007FE8280011106CE22CC26CA02C02A8364 +:100260006357050089E685473303A0403EC0058AF1 +:100270001304100619C213041004BA8459141A8501 +:100280003AC81AC22EC61AC4B135A5472243B24590 +:1002900042479376F50F63E1A7069386060393F62C +:1002A000F60F938714002380D4001A853AC83EC6FF +:1002B0002EC4DD3B9246A245B24742472A8363FBE8 +:1002C000B602824699C69306D0022380D700938750 +:1002D00024003385E7409356F501AA962380070052 +:1002E00085860146FD17634BD600F2406244D24436 +:1002F00005618280BE8461B7A29655B7B305C70079 +:1003000083C2070003C30500050623805500238030 +:100310006700C9BFB7170240984BB7062000558F3A +:1003200098CB984BB706E0FFFD16758F98CBB75763 +:10033000004003D74740C166938606FC758F13675C +:1003400087012392E74071770507239EE74003D793 +:100350000740136717002390E74003D70740136750 +:1003600007402390E74082809307F00763E7A702E6 +:100370009307F00363E3B70293D735009E07AA976C +:10038000138581C23E959D89054783470500B315B6 +:10039000B70009C6CD8F2300F500828093C5F5FF15 +:1003A000ED8FD5BF311122C62E84AA8537A507004F +:1003B0001305051206C826C4C53993175400818F4A +:1003C0008A07A29713141500AA84A28513953700F3 +:1003D000E1392694931714002A873EC00144024550 +:1003E000B71401403AC291469384044094C8913DA9 +:1003F0000245B706040094C8A93512470504E31066 +:1004000087FEC2403244A24451018280611122C061 +:100410003714014006C213040480894737C502001F +:100420001CC8130505F2313DB707020092401CC8F5 +:1004300002442101828037575A641307070523AE0F +:10044000E1C09387C1C1130740062382E700054737 +:1004500023930700239407002385E700238C01C022 +:10046000A38B01C08280B71701408847938707405C +:1004700098479C471345F5FF19831347F7FF95836A +:1004800093C7F7FF058B05892207858B7111C2077A +:10049000598D5D8D11018280011122CC26CA06CEB4 +:1004A0002A842E83B28483C204008504638D0204EF +:1004B0000147939732008966938606BABA97B69732 +:1004C00083C60700814713D67600B305E3003305E2 +:1004D000F40016C836C63AC41AC23EC07135B246D8 +:1004E000824721468606850712432247C24293F679 +:1004F000F60FE39AC7FC0507E31DF7FA329493075A +:100500008007E3D287FAF2406244D24405618280D8 +:100510002E860147B307E60083C7070099EBC14762 +:10052000998F8A0713C7F7FF7D87AA8533F5E70000 +:10053000A5B70507C5B71307F0076362A7049307BC +:10054000F00363EEB70241119307F6FF22C406C61B +:1005500026C2AA972A846375F70013060008098E3D +:10056000B304C400228505462EC00504F53B824530 +:10057000E39A84FEB2402244924441018280828008 +:100580009307F00763CFA702411122C406C626C213 +:10059000B387C500130700042E846354F7003306A5 +:1005A000B740B304860063179400B24022449244DB +:1005B00041018280A28505462AC07D33024505049B +:1005C000DDB78280311126C4B284368606C822C6C1 +:1005D00036C22A842EC06D37124682451385F4FF39 +:1005E0002295793F824526862285B137824722852A +:1005F00032449385F7FF9247C2402686A244BE95B7 +:10060000510115BF211122C826C62A84B2842E8624 +:10061000AA85014506CA4935130500039D46130600 +:10062000C004A28545371395340026950A05269502 +:1006300006059307300663DFA702930714009305AE +:1006400040063EC0B13C82472A871904930617032F +:10065000930410032685BE85054636C43AC23EC0C3 +:100660002133A246850482471247E395D4FE8507CD +:10067000E39E87FCD2404244B24461018280130170 +:1006800081FDB387E50022D226D02AC832CA13D40E +:1006900036003EC6814393F775000547B317F70050 +:1006A0003EC0D24781469E973ECC93D735009E07E9 +:1006B0003ECEE247939236000147B69783C70700C4 +:1006C0003EC2C247BE92F247B3845700B387E200EE +:1006D0001306F0076364F604124593070008B3D7C6 +:1006E000E740E98F3386E400138581C232950343E6 +:1006F00001003EC4834705001346F3FF05077D8EC6 +:10070000A247B337F000B307F0403373F30033660A +:1007100066002300C500A147E31AF7FA8506E31A2D +:10072000D4F8B2478505A2936386B7009307000407 +:10073000E393F5F612548254130181028280B707C5 +:1007400000E083A7470F8280B70700E09387470F39 +:100750009843211106CA22C826C61377070C9306B0 +:10076000000C630BD70002C42E84DDED9C4389C7C7 +:1007700093F7070891E3E1370144D24022854244D0 +:10078000B24461018280B30794401D476353F70070 +:10079000BA87B7061000370700E085061307470F32 +:1007A000104393750608A5E111C62AC23EC0413F19 +:1007B0001245824734000D47B685634DF704A246C3 +:1007C000370700E00D46232CD70EB30695000147EE +:1007D00083C2060005073383E500230053006385C9 +:1007E000E7008506E316C7FE13874700136707F87F +:1007F0002304E100A246370700E0BE94232AD70E67 +:10080000E3C384F89DBFFD16C1FE1C4393E7070CAC +:100810001CC39DB73386E4002A96034606000507ED +:100820008506A38FC6FE51BF8144D9BF611122C086 +:1008300006C22E84113F924022850244210182800B +:10084000970100209381C1BB1381414009651305C5 +:1008500005887310053097F6FFFF9386A67A93E616 +:100860003600739056301385C1C0938581020146CE +:100870006356B50010C11105E34EB5FE1725000003 +:100880001305C5C8938541C01386C1C06388C500E0 +:10089000144194C111059105E39AC5FEB7F700E034 +:1008A000054798C385679387A7D97390173473005A +:1008B0002030732510340D3A7325003035327325FE +:1008C00030341D32732520340532B70700E093879A +:1008D000470F9843137707086DFF0567130757A85D +:1008E00098C3B70700E09387470F9843137707082B +:1008F0006DFF37B7AAAA130737A898C301A0371707 +:1009000002401C47B7068000D58F1CC7AA8703C7C3 +:10091000070001E73385A74082808507CDBF13011B +:1009200041FAA2CAA6C886CC2AC02EC23284B68496 +:1009300009E59307801A02C23EC002CA8347040039 +:1009400013071400A30FF10081EBE6405644524513 +:10095000C6441301C10582803AC6930650026380E3 +:10096000D7021246824785451305F1018297324727 +:1009700026C43A84D247A244AA973ECAC1B7834745 +:1009800014009306000313072400A30FF1003EC6D2 +:100990006393D7083A8481460147A54519A8931760 +:1009A0002700BA97860705043307F6008347F4FF4C +:1009B0008546138607FD1375F60FE3F2A5FE99C26F +:1009C000A30FF1003AC8E14663D3E60036C8130628 +:1009D000C00681466398C700834704008546050426 +:1009E000A30FF1000346F101930740066305F606E5 +:1009F00063E7C702930780056302F60A9307300690 +:100A00006300F60C39D21246824785451305F10181 +:100A1000829726C485B79306000236C6A5BF930702 +:100A20005007630AF602930780076309F6069307E7 +:100A30003007E31AF6FC9387440084403ACC3EC466 +:100A40002685E9356247AA856359E008C2463246E1 +:100A50003818268525A0938744003EC485CA13060E +:100A6000B6F818109336160088400146A945EFF0F5 +:100A70006FFEC24632463818AA850810EFF02FEAFA +:100A80001246AA85281882478297EDB5930750072A +:100A900018108546E30AF6FC8146F9B7884013062C +:100AA00086FA938744001810854613361600C14510 +:100AB0003EC4EFF02FFAC2463246AA85381875BFF9 +:100AC000938744003EC49C40C2463246A30FF100C7 +:100AD000381885451305F10155B71246268565B7C7 +:100AE000111132C62A8605652EC436C881453400E8 +:100AF0001305C58206C23ACA3ECC36C00D359240B7 +:100B00007101828089670A059387C7B8AA978C43C9 +:100B1000056571111305456806C0D937824011017A +:100B20006FF04FFF71116167B757004006C01307A0 +:100B3000076A938707407D5683D68701898AE1C675 +:100B40007D17E31BC7FE014521A8E1679387176A5C +:100B50008356470193F6060899E6FD17F5FB0D4508 +:100B60005537054589A88347050005052318F70073 +:100B7000E39DA5FCE16637570040370607009386E2 +:100B8000066A1307074013064608FD55035547013B +:100B900083578701C207C98FF18F6387C700FD168E +:100BA000E396B6FE11456DBF83570700014593E7F5 +:100BB00007202310F7008240110182803757004040 +:100BC000AA95130707406DB7930780072318F7000E +:100BD0006166B7560040370707001306066A93861A +:100BE0000640130727087D5383D2460183D7860129 +:100BF000C207B3E75700F98FE382E7FC7D16E315E0 +:100C000066FE0945B1BF03D70700E166370603005A +:100C1000136707102390E700375700409386066A52 +:100C20001307074005067D53835247018357870109 +:100C3000C207B3E75700F18FE388C7F8FD16E395C5 +:100C400066FE054531BF130181FDA300A100894562 +:100C50000A8506D223000100F1359250130181026A +:100C60008280311106C822C62AC02AC22EC49DC164 +:100C7000B337A000B307F0402A84B375F100130521 +:100C8000801A713901C4124582471D8DC240324419 +:100C90005101828001448145DDB7311136C43400F1 +:100CA00006C23AC63EC836C06D3F924051018280AE +:100CB0002A96AA876393C70082802380B70085079E +:100CC000D5BF130600408145138581C2D5B7814742 +:100CD0006313F60082803387F500834607003307ED +:100CE000F50085072300D700E5B7797113051002D9 +:100CF00006D622D426D2813F0145B1371305F0072D +:100D000099371305200281370145353F1D4513846E +:100D100081C2153F9304044093070004A285130683 +:100D20000002130511002300F1005537930510024E +:100D30000A8513040402FD33E31094FEB2502254DA +:100D4000925445618280B7270240054798C3B71780 +:100D500002403707080123A207001307170898C3AA +:100D600037079F0098C7984393166700E3DD06FE98 +:100D7000D843B7160240719B13672700D8C3214799 +:100D8000DC42B18BE39EE7FEB70700E023AC070E21 +:100D90001307000823AAE70E8280397106DE22DCE1 +:100DA00026DA5537B71402409C4C37140140FD76C3 +:100DB00093E757039CCC9307048098439386F60FE0 +:100DC000370600F11377F7F01367070198C3370769 +:100DD000020098CB9307044098437D1637050B001B +:100DE000758F1367071098C33707040098CB184016 +:100DF000130505C8419B1367870018C09843718F7E +:100E000037060008518F98C39843370610FF7D16A8 +:100E1000718F37068000518F98C3054718C8130794 +:100E2000000498CB1307000298CBEFF08FC1DC4C85 +:100E300037072000D98FDCCC9C4C7D779306F70FC9 +:100E400093E717019CCC1C400567130707D093F765 +:100E5000F7F01CC01C4093E7070D1CC01C40F58F29 +:100E60001CC01C40D98F1CC00964EFF0AFCA13042A +:100E7000043A813D034504009307F00F6314F50025 +:100E8000AD3521A00504C13375D5EFF0CFDA153D9E +:100E900085659385856B1145EFF08FE71307000299 +:100EA0000966BA861306C63BC14513050003EFF079 +:100EB0000FFD85659385456C13054003EFF04FE505 +:100EC0002D359305000513053029EFF0AFCD9305BF +:100ED000000513050031EFF0EFCC930580071305F3 +:100EE000C03DEFF02FCC1304800CEFF0CFD7135799 +:100EF000850093570501A300E102498F2301F10208 +:100F0000D98F2300A10293F7F70F81EB75651305C5 +:100F1000054C7D14EFF0EFB269F8014781440144BC +:100F20003AC0EFF04FD4935705011377F50F3AC24B +:100F3000230FF10093F7F70F935685003EC69247B3 +:100F400013F7F60FA30ED1003AC4230EA1000247F7 +:100F5000814699C3933614002246814719C293B73C +:100F60001400B245014699C11336170083C581C1EB +:100F70009384C1C12EC0024585456301B5408945B2 +:100F80006304B54A631D051C95C303C571C199452A +:100F900032CA150536C8EFF02F96A38BA1C0E545E0 +:100FA00013057041EFF00FC05246C24605C203C59B +:100FB00071C1994536C80505EFF00F94A38BA1C008 +:100FC000E54513057041EFF0EFBDC246ADC683C7DE +:100FD00071C1954663E1F60685668A079386467B6E +:100FE000B6979C4382878387040013074006F9075E +:100FF000635AF71ABA872380F400838734001307F3 +:101000004006ED176355F71ABA87A381F40011471C +:101010002386E1C09305C003314713050037238BB6 +:10102000E1C0EFF02FB89305000513057049EFF00C +:101030006FB7EFF0AFBD713183C771C101453EC8D5 +:1010400042478967938707470A07BA978C43EFF0AF +:101050002FCC83C7A4003ECA8DC303874400F54745 +:1010600063CDE70083A701C1A18B81CB0566130681 +:10107000466D81450145EFF02FC2014422850546AA +:10108000A945EFF06FAE050493070008E318F4FEDE +:1010900003C494006307042405661306866DB945EE +:1010A0001305E004EFF04FBF05661306C66DB145AA +:1010B00013054005EFF04FBE13030003C142524732 +:1010C000994719C783C761C16386072483C7C1C015 +:1010D0000967130747458A07BA9790431307000229 +:1010E000BA8696851A85EFF08FD901442285054688 +:1010F0009305E002EFF04FA7050493070008E317FC +:10110000F4FE83C7840002476366F7240144931703 +:101110002400338787000A07330387000967130712 +:10112000C743BA9790434147BA86130533009305E6 +:1011300000031AC0EFF0AFD442479377F40F024395 +:10114000631AF700C9464D469305E00213051300E4 +:10115000EFF04FC705049947E31BF4FA793683C7CC +:1011600061C181C7FD17238BF1C083C7A40081CF64 +:1011700083D741C1930610038507C207C18363E784 +:10118000F630239AF1C083A701C137850500130506 +:1011900005E4850723A8F1C0EFF0AF8A3247A244E7 +:1011A0001244BDBB13C7F7FF7D87F98FA9B513C7DD +:1011B000F7FF7D87F98F91BD03872400B94763C985 +:1011C000E700930580071305C00DEFF0AF9DA5B5AF +:1011D0008387140093064006E50763D5F604B687B7 +:1011E000A380F400930747FF130740066353F700FB +:1011F000BA872381F40009472386E1C09305C00321 +:1012000031471305C03D238BE1C0EFF0AF99930543 +:10121000C00313057052EFF0EF989305A005130576 +:10122000006231B593C6F7FFFD86F58F55BF03C544 +:10123000940093058007933715003335A0003305DC +:10124000A0401375C50DA384F4001305851BB5BF1D +:101250009386C1C1838714001307400623840400CA +:10126000A381E40095076350F702BA879305200332 +:1012700013057052A380F600EFF0CF929305200380 +:101280001305704199B713C7F7FF7D87F98FF9BF31 +:101290008387440013074006938737026356F7029B +:1012A000BA879305C003130500312382F400EFF0E1 +:1012B0006F8F9305C00313057041EFF0AF8E930558 +:1012C000A00513057052A5B313C7F7FF7D87F98FEB +:1012D000C9BF8547238CF1C09305800213053029CF +:1012E000EDB583A201C193050005168516CCEFE08C +:1012F0007FDE93077002E2421303E50163F6A70065 +:101300009307E0063383A74093F28200B332500084 +:10131000B90275B39547E31D04DA83864400754727 +:101320008D47E357D7DA838614006147E352D7DA53 +:10133000838604004D47E35DD7D803A501C193051B +:10134000200316CC1ACAEFE0FFD8E242524393378B +:101350004500BDBB82472147139517003E950A05FE +:10136000BA86138641C0930560023A95EFF02FB11B +:101370008247850793F7F70F3EC061B3D58FD18FB2 +:1013800081CBF94513050037238C01C0EFF08F8125 +:10139000EFF03F9385659385056E0145EFF04F971C +:1013A0000386040085659385056F2945EFF08FA5B9 +:1013B0000386140085659385856F4D45EFF08FA4F6 +:1013C000038624008565938505707145EFF08FA332 +:1013D0000386340085659385857013055002EFF010 +:1013E0006FA2038644008565938505711305E002AD +:1013F000EFF04FA183C7940083D6640095C30567BF +:101400001307476B056613068671C5450810EFF094 +:10141000DF881010930580030145EFF0EF873DBB97 +:1014200005671307076BF9BF99CEEFF0CF809305DF +:10143000000513053029EFE0FFF69305800713053B +:10144000C03DEFE03FF6EFF0DF87130700020966CB +:10145000BA8613068648A14513050003EFF02FA2B4 +:101460008565938545721305C002EFF06F8A83D6B8 +:10147000640005661306C672C5450810EFF0FF81CB +:101480000C1013054003EFF0AF88C9B903D3640013 +:1014900003C59400239A01C00503420313530301BB +:1014A0002393640003870400838724009305400688 +:1014B000630105149386A70063D3D512AE86E206B6 +:1014C000E1862381D4007D1713064006635EE61093 +:1014D0003287620761872380E40013069005635713 +:1014E000F600A3840400930640060145838534007A +:1014F000930740061386F5FF63DCC7143E86620639 +:101500006186A381C40015E103C58400894763EEA9 +:10151000A70093173300B387674003A301C19A97CD +:10152000BD8B81E705052384A40003C5840019C988 +:1015300083871400898F130540066350F512AA872C +:10154000A380F400D14763CCB700838714009305D0 +:101550004006FD1763D8F510AE87A380F40083C55D +:101560001400AE87E205E1856353B600B287139697 +:10157000870161866353C700BA8713978701618724 +:1015800063D3E600B687139787016187B9468387DF +:10159000440063CEE60CED1713074006635FF70CBB +:1015A000BA872382F40083874400E34EF0BC0947E6 +:1015B0009305800C1305A014238CE1C0238504003F +:1015C000EFE05FDE9305800C1305700FEFE09FDD09 +:1015D000930500191305500AEFE0DFDC6DB613C662 +:1015E000F6FF7D86F18EE1BD1346F7FF7D86718F94 +:1015F000CDB575170386140063DDE5022E876207FB +:1016000061872380E400F9179306400663D8F60249 +:10161000B68793968701E1862381D40079169307D4 +:10162000400663D2C7023E869387C1C1A380C7002C +:1016300075BD9346F7FFFD86758FD1B793C6F7FF4B +:10164000FD86F58FF9B79347F6FFFD877D8EE9BFDD +:101650009347F6FFFD877D8E5DB513C5F7FF7D854A +:10166000E98FF9BD93C5F7FFFD85ED8FFDB59306B5 +:101670002003E3DAE6F2890705B713C7F7FF7D8792 +:10168000F98F05B7737364313330365F6932635F46 +:101690006572726F72202D2074696D656F7574208C +:1016A00077616974696E6720666F722025730A0D11 +:1016B000000000005A7A7A0050414E41474F54438F +:1016C00048490000707265737320616E79206B6504 +:1016D00079000000210000007A0000005A0000009C +:1016E0002D2D20535441545553202D2D0000000022 +:1016F000464F4F440000000046554E2000000000B9 +:10170000454E475900000000574153480000000073 +:10171000484C544800000000416765202575202092 +:1017200025730000522E492E502E00006C697665FC +:1017300064202575206D696E000000006E6F7420B6 +:1017400062757379000000006D6173746572206DBD +:101750006F6465007472616E736D6974206D6F647F +:1017600065000000747820656D70747900000000D9 +:101770007472616E736D697420636F6D706C6574E3 +:10178000650000004645454400000000504C4159AA +:1017900000000000534C454550000000434C4541BB +:1017A0004E0000004845414C000000005354415495 +:1017B00053000000E60F0000B81100002E120000D8 +:1017C0005012000090120000D21200000000000031 +:1017D000000000C000C000C006C006C006D806D881 +:1017E00036D836D836D836D8000000000000008041 +:1017F00007F00FF81C3C3C3E300E300E700F300EE0 +:101800003C3E3C3E1FFC0FF807F00080000000004B +:101810000080008001C001C007F00DF80DF808F845 +:101820001DFC0DF80FF80FF807F000800000000015 +:10183000000004000C001C0018001C003C001C00F0 +:101840001E001F000FE807F00080000000000000ED +:10185000077000001F7C3F7E3F7E3F7E00003F7E82 +:101860003F7E3F7E1F7C00000770000000000000EC +:1018700000A001900FE01BF03BF831F83BF87BFC37 +:101880003FF83FF83FF81FF00FE0010000000000B4 +:1018900000000000010000800FE007F01FF00FF8CB +:1018A0001FF00FF81FF00FF83FF89FFC1FFFFFF825 +:1018B0001FFFFFF81FFFFFF80FFFFFF003FFFFE020 +:1018C00007FFFFF007FFFFF00FBBEEF80FD7F5F8AB +:1018D0000FEFFBF80FD7F5F81FBBEEFC0FFFFFF87B +:1018E0000FFFFFF80FFFFFF80FF007F807FFFFF0FB +:1018F00007FFFFF003FFFFE001FFFFC000FFFF80D5 +:10190000007FFF00001FFC000000800000000000BE +:1019100000000000010000800FE007F01FF00FF84A +:101920001FF00FF81FF00FF83FF89FFC1FFFFFF8A4 +:101930001FFFFFF81FFFFFF80FFFFFF003FFFFE09F +:1019400007FFFFF007FFFFF00FFFFFF80FFFFFF8A3 +:101950000FFFFFF80F01C0781FFFFFFC0FFFFFF81C +:101960000FFF7FF80FFC1FF80FFF7FF807FFFFF056 +:1019700007FFFFF003FFFFE001FFFFC000FFFF8054 +:10198000007FFF00001FFC0000008000000000003E +:1019900000000000010000800FE007F01FF00FF8CA +:1019A0001FF00FF81FF00FF83FF89FFC1FFFFFF824 +:1019B0001FFFFFF81FFFFFF80FFFFFF003FFFFE01F +:1019C00007EFFBF00783E0F00F93E4F80F11C47802 +:1019D0000F83E0F80F83E0F81FEFFBFC0FFF7FF8A9 +:1019E0000FFC1FF80FFC1FF80FF80FF807FC1FF093 +:1019F00007FC1FF003FF7FE001FFFFC000FFFF8037 +:101A0000007FFF00001FFC000000800000000000BD +:101A100000000000010000800FE007F01FF00FF849 +:101A20001FF00FF81FF00FF83FF89FFC1FFFFFF8A3 +:101A30001FFFFFF81FFFFFF80FFFFFF003FFFFE09E +:101A400007FFFFF007FFFFF00FEFFBF80F83E0F851 +:101A50000F93E4F80F11C4781F83E0FC0F8360F844 +:101A60000FEC1BF80FFF7FF80FFC1FF807F7F7F0DC +:101A700007FBEFF003FFFFE001FFFFC000FFFF8067 +:101A8000007FFF00001FFC0000008000000000003D +:101A900000000000010000800FE007F01FF00FF8C9 +:101AA0001FF00FF81FF00FF83FF89FFC1FFFFFF823 +:101AB0001FFFFFF81FFFFFF80FFFFFF003FFFFE01E +:101AC00007FFFFF007FFFFF00FFFFFF80FEFFBF836 +:101AD0000FD7F5F80FFFFFF81FFFFFFC0FFFFFF810 +:101AE0000FF80FF80FFBEFF80FF7F7F807FC1FF0F0 +:101AF00007FFFFF003FFFFE001FFFFC000FFFF80D3 +:101B0000007FFF00001FFC000000800000000000BC +:101B100000000000010000800FE007F01FF00FF848 +:101B20001FF00FF81FF00FF83FF89FFC1FFFFFF8A2 +:101B30001FFFFFF81FFFFFF80FFFFFF003FFFFE09D +:101B400007FFFFF007FFFFF00FFFFFF80FFFFFF8A1 +:101B50000F01C0780FFFFFF81FFFFFFC0FFF7FF89A +:101B60000FFC1FF80FFF7FF80FFFFFF807F80FF0CB +:101B700007FFFFF003FFFFE001FFFFC000FFFF8052 +:101B8000007FFF00001FFC00000080003C170000E9 +:101B90004817000054170000641700007017000079 +:101BA00000000000000000007E81A581BD99817EBB +:101BB0007EFFDBFFC3E7FF7E6CFEFEFE7C3810007D +:101BC00010387CFE7C381000387C38FEFED6103889 +:101BD00010387CFEFE7C10380000183C3C180000D9 +:101BE000FFFFE7C3C3E7FFFF003C664242663C00DD +:101BF000FFC399BDBD99C3FF0F070F7DCCCCCC7837 +:101C00003C6666663C187E183F333F303070F0E02B +:101C10007F637F636367E6C018DB3CE7E73CDB1864 +:101C200080E0F8FEF8E08000020E3EFE3E0E02006C +:101C3000183C7E18187E3C1866666666660066006C +:101C40007FDBDB7B1B1B1B003E613C66663C867CAE +:101C5000000000007E7E7E00183C7E187E3C18FF4F +:101C6000183C7E1818181800181818187E3C180010 +:101C700000180CFE0C180000003060FE6030000000 +:101C80000000C0C0C0FE0000002466FF6624000003 +:101C900000183C7EFFFF000000FFFF7E3C180000A4 +:101CA0000000000000000000183C3C18180018005C +:101CB00066662400000000006C6CFE6CFE6C6C001C +:101CC000183E603C067C180000C6CC183066C60082 +:101CD000386C3876DCCC7600181830000000000034 +:101CE0000C18303030180C0030180C0C0C18300068 +:101CF00000663CFF3C6600000018187E18180000C3 +:101D000000000000001818300000007E00000000F5 +:101D10000000000000181800060C183060C0800099 +:101D2000386CC6D6C66C38001838181818187E00DB +:101D30007CC6061C3066FE007CC6063C06C67C00DF +:101D40001C3C6CCCFE0C1E00FEC0C0FC06C67C0019 +:101D50003860C0FCC6C67C00FEC60C1830303000AF +:101D60007CC6C67CC6C67C007CC6C67E060C7800D7 +:101D70000018180000181800001818000018183073 +:101D8000060C1830180C060000007E00007E0000D3 +:101D90006030180C183060007CC60C181800180051 +:101DA0007CC6DEDEDEC07800386CC6FEC6C6C60065 +:101DB000FC66667C6666FC003C66C0C0C0663C0093 +:101DC000F86C6666666CF800FE6268786862FE0011 +:101DD000FE6268786860F0003C66C0C0CE663A007B +:101DE000C6C6C6FEC6C6C6003C18181818183C0061 +:101DF0001E0C0C0CCCCC7800E6666C786C66E600A9 +:101E0000F06060606266FE00C6EEFEFED6C6C600EA +:101E1000C6E6F6DECEC6C6007CC6C6C6C6C67C0012 +:101E2000FC66667C6060F0007CC6C6C6C6CE7C0ED2 +:101E3000FC66667C6C66E6003C6630180C663C000E +:101E40007E7E5A1818183C00C6C6C6C6C6C67C0098 +:101E5000C6C6C6C6C66C3800C6C6C6D6D6FE6C0098 +:101E6000C6C66C386CC6C6006666663C18183C0070 +:101E7000FEC68C183266FE003C30303030303C00FC +:101E8000C06030180C0602003C0C0C0C0C0C3C0022 +:101E900010386CC60000000000000000000000FFC9 +:101EA00030180C00000000000000780C7CCC76009C +:101EB000E0607C666666DC0000007CC6C0C67C0014 +:101EC0001C0C7CCCCCCC760000007CC6FEC07C0018 +:101ED0003C6660F86060F000000076CCCC7C0CF8CA +:101EE000E0606C766666E6001800381818183C004A +:101EF000060006060666663CE060666C786CE600E6 +:101F00003818181818183C000000ECFED6D6D60079 +:101F10000000DC666666660000007CC6C6C67C0003 +:101F20000000DC66667C60F0000076CCCC7C0C1E89 +:101F30000000DC766060F00000007EC07C06FC00E3 +:101F40003030FC3030361C000000CCCCCCCC7600DD +:101F50000000C6C6C66C38000000C6D6D6FE6C00AF +:101F60000000C66C386CC6000000C6C6C67E06FC03 +:101F700000007E4C18327E000E18187018180E00E3 +:101F800018181818181818007018180E181870005B +:101F900076DC0000000000000010386CC6C6FE00B1 +:101FA0007CC6C0C0C67C0C78CC00CCCCCCCC760037 +:101FB0000C187CC6FEC07C007C82780C7CCC760041 +:101FC000C600780C7CCC76003018780C7CCC76007F +:101FD0003030780C7CCC760000007EC0C07E0C389F +:101FE0007C827CC6FEC07C00C6007CC6FEC07C0035 +:101FF00030187CC6FEC07C006600381818183C00FB +:102000007C82381818183C003018003818183C002A +:10201000C6386CC6FEC6C600386C7CC6FEC6C60096 +:102020001830FEC0F8C0FE0000007E187ED87E008A +:102030003E6CCCFECCCCCE007C827CC6C6C67C007E +:10204000C6007CC6C6C67C0030187CC6C6C67C00EE +:10205000788400CCCCCC76006030CCCCCCCC760074 +:10206000C600C6C6C67E06FCC6386CC6C66C38003E +:10207000C600C6C6C6C67C0018187EC0C07E18182A +:10208000386C64F06066FC0066663C7E187E18184A +:10209000F8CCCCFAC6CFC6C70E1B183C18D87000B7 +:1020A0001830780C7CCC76000C18003818183C00DE +:1020B0000C187CC6C6C67C001830CCCCCCCC7600C4 +:1020C00076DC00DC6666660076DC00E6F6DECE00D6 +:1020D0003C6C6C3E007E0000386C6C38007C00006C +:1020E0001800181830633E00000000FEC0C0000059 +:1020F000000000FE0606000063E66C7E3366CC0F2F +:1021000063E66C7A366ADF06180018183C3C180043 +:10211000003366CC6633000000CC663366CC00002A +:10212000228822882288228855AA55AA55AA55AA0B +:1021300077DD77DD77DD77DD18181818181818188F +:1021400018181818F81818181818F818F81818186F +:1021500036363636F636363600000000FE3636366F +:102160000000F818F81818183636F606F63636361F +:1021700036363636363636360000FE06F636363613 +:102180003636F606FE00000036363636FE00000013 +:102190001818F818F800000000000000F8181818C7 +:1021A000181818181F00000018181818FF00000051 +:1021B00000000000FF181818181818181F18181811 +:1021C00000000000FF00000018181818FF18181869 +:1021D00018181F181F181818363636363736363680 +:1021E000363637303F00000000003F303736363695 +:1021F0003636F700FF0000000000FF00F7363636E5 +:1022000036363730373636360000FF00FF00000024 +:102210003636F700F73636361818FF00FF00000094 +:1022200036363636FF0000000000FF00FF18181891 +:1022300000000000FF363636363636363F000000E6 +:1022400018181F181F00000000001F181F1818186A +:10225000000000003F36363636363636FF36363624 +:102260001818FF18FF18181818181818F800000088 +:10227000000000001F181818FFFFFFFFFFFFFFFFFF +:1022800000000000FFFFFFFFF0F0F0F0F0F0F0F0D2 +:102290000F0F0F0F0F0F0F0FFFFFFFFF00000000CA +:1022A000000076DCC8DC760078CCCCD8CCC6CC007C +:1022B000FEC6C0C0C0C0C0000000FE6C6C6C6C00EC +:1022C000FEC6603060C6FE0000007ED8D8D8700020 +:1022D0000000666666667CC00076DC181818180078 +:1022E0007E183C66663C187E386CC6FEC66C3800AC +:1022F000386CC6C66C6CEE000E180C3E66663C0070 +:1023000000007EDBDB7E0000060C7EDBDB7E60C037 +:102310001E30607E60301E00007CC6C6C6C6C60089 +:1023200000FE00FE00FE000018187E1818007E0057 +:1023300030180C1830007E000C1830180C007E008D +:102340000E1B1B18181818181818181818D8D87039 +:102350000018007E001800000076DC0076DC00002B +:10236000386C6C38000000000000001818000000F5 +:1023700000000018000000000F0C0C0CEC6C3C1C62 +:102380006C36363636000000780C18307C000000C1 +:1023900000003C3C3C3C000000000000000000004D +:1023A000AED580A83FD300408D142000A1C8DA121A +:1023B000818FD9F1DB40A4A6AFFF00000000000030 +:1023C00000000000010000800FE007F01FF00FF890 +:1023D0001FF00FF81FF00FF83FF89FFC1FFFFFF8EA +:1023E0001FFFFFF81FFFFFF80FFFFFF003FFFFE0E5 +:1023F00007FFFFF007EFFBF00F83E0F80F93E4F81F +:102400000F11C4780F83E0F81F83E0FC0FEF7BF817 +:102410000FFC1FF80FFF7FF80FFFFFF807F80FF012 +:1024200007FFFFF003FFFFE001FFFFC000FFFF8099 +:10243000007FFF00001FFC00000080006C180000FF +:102440004C1800002C1800000C180000EC170000BD +:10245000CC170000BC2300000C1B00008C1A0000ED +:102460000C1A00008C1900000C1900008C180000D8 +:10247000841700008C170000941700009C170000C0 +:10248000A4170000AC1700000000000000000000CE +:1024900000FFFC0003FFFF0007FFFF80061FE18035 +:1024A0000630318006303180063FC300063303001A +:1024B000063183000630C30006000600060F060042 +:1024C00007FFFF800FFFFFC01FFFFFE03FFFFFF090 +:1024D0007FFFFFF8FFFFFFFCFFFFFFFC00F0F000B5 +:1024E00003FFF0000FFFFC000000000000000000F0 +:1024F00000000000000000000000000000000000DC +:082500000000000000000000D3 +:0825080000183C6C7EFFFF008F +:00000001FF diff --git a/tama.lst b/tama.lst new file mode 100644 index 0000000..520153c --- /dev/null +++ b/tama.lst @@ -0,0 +1,3458 @@ + +tama.elf: file format elf32-littleriscv + + +Disassembly of section .init: + +00000000 : + void InterruptVectorDefault() __attribute__((naked)) __attribute((section(".init"))) __attribute((naked)); + + void InterruptVectorDefault( void ) + { + #if !defined(FUNCONF_TINYVECTOR) || !FUNCONF_TINYVECTOR + asm volatile( DEFAULT_INTERRUPT_VECTOR_CONTENTS ); + 0: 0410006f j 840 + 4: 00000000 .word 0x00000000 + 8: 000008fe .word 0x000008fe + c: 000008b2 .word 0x000008b2 + ... + 30: 000008b2 .word 0x000008b2 + 34: 00000000 .word 0x00000000 + 38: 000008b2 .word 0x000008b2 + 3c: 00000000 .word 0x00000000 + 40: 000008b2 .word 0x000008b2 + 44: 000008b2 .word 0x000008b2 + 48: 000008b2 .word 0x000008b2 + 4c: 000008b2 .word 0x000008b2 + 50: 000008b2 .word 0x000008b2 + 54: 000008b2 .word 0x000008b2 + 58: 000008b2 .word 0x000008b2 + 5c: 000008b2 .word 0x000008b2 + 60: 000008b2 .word 0x000008b2 + 64: 000008b2 .word 0x000008b2 + 68: 000008b2 .word 0x000008b2 + 6c: 000008b2 .word 0x000008b2 + 70: 000008b2 .word 0x000008b2 + 74: 000008b2 .word 0x000008b2 + 78: 000008b2 .word 0x000008b2 + 7c: 000008b2 .word 0x000008b2 + 80: 000008b2 .word 0x000008b2 + 84: 000008b2 .word 0x000008b2 + 88: 000008b2 .word 0x000008b2 + 8c: 000008b2 .word 0x000008b2 + 90: 000008b2 .word 0x000008b2 + 94: 000008b2 .word 0x000008b2 + 98: 000008b2 .word 0x000008b2 + 9c: 0000 unimp + ... + +Disassembly of section .text: + +000000a0 <__divsi3>: + a0: 02054e63 bltz a0,dc <__umodsi3+0x8> + a4: 0405c363 bltz a1,ea <__umodsi3+0x16> + +000000a8 <__hidden___udivsi3>: + a8: 862e mv a2,a1 + aa: 85aa mv a1,a0 + ac: 557d li a0,-1 + ae: c215 beqz a2,d2 <__hidden___udivsi3+0x2a> + b0: 4685 li a3,1 + b2: 00b67863 bgeu a2,a1,c2 <__hidden___udivsi3+0x1a> + b6: 00c05663 blez a2,c2 <__hidden___udivsi3+0x1a> + ba: 0606 slli a2,a2,0x1 + bc: 0686 slli a3,a3,0x1 + be: feb66ce3 bltu a2,a1,b6 <__hidden___udivsi3+0xe> + c2: 4501 li a0,0 + c4: 00c5e463 bltu a1,a2,cc <__hidden___udivsi3+0x24> + c8: 8d91 sub a1,a1,a2 + ca: 8d55 or a0,a0,a3 + cc: 8285 srli a3,a3,0x1 + ce: 8205 srli a2,a2,0x1 + d0: faf5 bnez a3,c4 <__hidden___udivsi3+0x1c> + d2: 8082 ret + +000000d4 <__umodsi3>: + d4: 8286 mv t0,ra + d6: 3fc9 jal a8 <__hidden___udivsi3> + d8: 852e mv a0,a1 + da: 8282 jr t0 + dc: 40a00533 neg a0,a0 + e0: 00b04763 bgtz a1,ee <__umodsi3+0x1a> + e4: 40b005b3 neg a1,a1 + e8: b7c1 j a8 <__hidden___udivsi3> + ea: 40b005b3 neg a1,a1 + ee: 8286 mv t0,ra + f0: 3f65 jal a8 <__hidden___udivsi3> + f2: 40a00533 neg a0,a0 + f6: 8282 jr t0 + +000000f8 <__modsi3>: + f8: 8286 mv t0,ra + fa: 0005c763 bltz a1,108 <__modsi3+0x10> + fe: 00054963 bltz a0,110 <__modsi3+0x18> + 102: 375d jal a8 <__hidden___udivsi3> + 104: 852e mv a0,a1 + 106: 8282 jr t0 + 108: 40b005b3 neg a1,a1 + 10c: fe055be3 bgez a0,102 <__modsi3+0xa> + 110: 40a00533 neg a0,a0 + 114: 3f51 jal a8 <__hidden___udivsi3> + 116: 40b00533 neg a0,a1 + 11a: 8282 jr t0 + ... + +0000011e : + if(pad_to == 0) pad_to = len; + 11e: c699 beqz a3,12c + int overflow = 0; + 120: 4301 li t1,0 + if(len > pad_to) { + 122: 00b6d763 bge a3,a1,130 + len = pad_to; + 126: 85b6 mv a1,a3 + overflow = 1; + 128: 4305 li t1,1 + 12a: a019 j 130 + int overflow = 0; + 12c: 4301 li t1,0 + if(pad_to == 0) pad_to = len; + 12e: 86ae mv a3,a1 + for(i = pad_to - len; i > 0; i --) { + 130: 8e8d sub a3,a3,a1 + char * pbuffer = buffer; + 132: 87ba mv a5,a4 + 134: 00e683b3 add t2,a3,a4 + for(i = pad_to - len; i > 0; i --) { + 138: 40f382b3 sub t0,t2,a5 + 13c: 04504a63 bgtz t0,190 + 140: fff6c793 not a5,a3 + 144: 87fd srai a5,a5,0x1f + 146: 8efd and a3,a3,a5 + 148: 96ba add a3,a3,a4 + 14a: 4781 li a5,0 + for(i = len; i > 0; i --) { + 14c: 40f58633 sub a2,a1,a5 + 150: 00f682b3 add t0,a3,a5 + 154: 04c04263 bgtz a2,198 + 158: fff5c793 not a5,a1 + 15c: 87fd srai a5,a5,0x1f + 15e: 8dfd and a1,a1,a5 + 160: 95b6 add a1,a1,a3 + len = pbuffer - buffer; + 162: 40e58533 sub a0,a1,a4 + if(overflow) { + 166: 02030463 beqz t1,18e + for (i = 0; i < 3 && pbuffer > buffer; i ++) { + 16a: 02b77263 bgeu a4,a1,18e + *(pbuffer-- - 1) = '*'; + 16e: 02a00793 li a5,42 + 172: fef58fa3 sb a5,-1(a1) + 176: fff58693 addi a3,a1,-1 + for (i = 0; i < 3 && pbuffer > buffer; i ++) { + 17a: 00d77a63 bgeu a4,a3,18e + *(pbuffer-- - 1) = '*'; + 17e: fef58f23 sb a5,-2(a1) + 182: ffe58693 addi a3,a1,-2 + for (i = 0; i < 3 && pbuffer > buffer; i ++) { + 186: 00d77463 bgeu a4,a3,18e + *(pbuffer-- - 1) = '*'; + 18a: fef58ea3 sb a5,-3(a1) +} + 18e: 8082 ret + *(pbuffer++) = pad_char; + 190: 0785 addi a5,a5,1 + 192: fec78fa3 sb a2,-1(a5) + for(i = pad_to - len; i > 0; i --) { + 196: b74d j 138 + *(pbuffer++) = *(ptr++); + 198: 00f50633 add a2,a0,a5 + 19c: 00064603 lbu a2,0(a2) + 1a0: 0785 addi a5,a5,1 + 1a2: 00c28023 sb a2,0(t0) + for(i = len; i > 0; i --) { + 1a6: b75d j 14c + +000001a8 <_puts>: +{ + 1a8: 832a mv t1,a0 + 1aa: 852e mv a0,a1 + if(!buf) return len; + 1ac: ce01 beqz a2,1c4 <_puts+0x1c> + char * p0 = b->buffer; + 1ae: 00062283 lw t0,0(a2) + for (i = 0; i < len; i++) { + 1b2: 4701 li a4,0 + if(b->pbuffer == b->buffer + b->buffer_len - 1) { + 1b4: 425c lw a5,4(a2) + for (i = 0; i < len; i++) { + 1b6: 00a74863 blt a4,a0,1c6 <_puts+0x1e> + *(b->pbuffer) = 0; + 1ba: 00078023 sb zero,0(a5) + return b->pbuffer - p0; + 1be: 4248 lw a0,4(a2) + 1c0: 40550533 sub a0,a0,t0 +} + 1c4: 8082 ret + if(b->pbuffer == b->buffer + b->buffer_len - 1) { + 1c6: 460c lw a1,8(a2) + 1c8: 4214 lw a3,0(a2) + 1ca: 15fd addi a1,a1,-1 + 1cc: 96ae add a3,a3,a1 + 1ce: fed786e3 beq a5,a3,1ba <_puts+0x12> + *(b->pbuffer ++) = s[i]; + 1d2: 00178693 addi a3,a5,1 + 1d6: c254 sw a3,4(a2) + 1d8: 00e306b3 add a3,t1,a4 + 1dc: 0006c683 lbu a3,0(a3) + for (i = 0; i < len; i++) { + 1e0: 0705 addi a4,a4,1 + *(b->pbuffer ++) = s[i]; + 1e2: 00d78023 sb a3,0(a5) + for (i = 0; i < len; i++) { + 1e6: b7f9 j 1b4 <_puts+0xc> + +000001e8 : + while( (*DMDATA0) & 0x80 ); + 1e8: e00007b7 lui a5,0xe0000 + 1ec: 0f478793 addi a5,a5,244 # e00000f4 <_eusrstack+0xbffff8f4> + 1f0: 4398 lw a4,0(a5) + 1f2: 08077713 andi a4,a4,128 + 1f6: ff6d bnez a4,1f0 + *DMDATA0 = 0x78302088; //" 0x" + 1f8: 78302737 lui a4,0x78302 + 1fc: 08870713 addi a4,a4,136 # 78302088 <_eusrstack+0x58301888> + while( (*DMDATA0) & 0x80 ); + 200: e00006b7 lui a3,0xe0000 + *DMDATA0 = 0x78302088; //" 0x" + 204: c398 sw a4,0(a5) + while( (*DMDATA0) & 0x80 ); + 206: 0f468693 addi a3,a3,244 # e00000f4 <_eusrstack+0xbffff8f4> + for( shift = 28; shift >= 0; shift -= 4 ) + 20a: 4771 li a4,28 + s += ( s < 10 ) ? '0' : ('a' - 10); + 20c: 45a5 li a1,9 + for( shift = 28; shift >= 0; shift -= 4 ) + 20e: 5671 li a2,-4 + while( (*DMDATA0) & 0x80 ); + 210: 429c lw a5,0(a3) + 212: 0807f793 andi a5,a5,128 + 216: ffed bnez a5,210 + int s = (n>>shift) & 0xf; + 218: 00e55333 srl t1,a0,a4 + 21c: 00f37313 andi t1,t1,15 + s += ( s < 10 ) ? '0' : ('a' - 10); + 220: 0065b7b3 sltu a5,a1,t1 + 224: 40f007b3 neg a5,a5 + 228: 0277f793 andi a5,a5,39 + 22c: 03078793 addi a5,a5,48 + 230: 979a add a5,a5,t1 + *DMDATA0 = 0x85 | (s<<8); //" 0x" + 232: 07a2 slli a5,a5,0x8 + 234: 0857e793 ori a5,a5,133 + 238: c29c sw a5,0(a3) + for( shift = 28; shift >= 0; shift -= 4 ) + 23a: 1771 addi a4,a4,-4 + 23c: fcc71ae3 bne a4,a2,210 +} + 240: 8082 ret + +00000242 : +#endif + +void DelaySysTick( uint32_t n ) +{ +#if defined(CH32V003) || defined(CH32V00x) + uint32_t targend = SysTick->CNT + n; + 242: e000f737 lui a4,0xe000f + 246: 471c lw a5,8(a4) + 248: 953e add a0,a0,a5 + while( ((int32_t)( SysTick->CNT - targend )) < 0 ); + 24a: 471c lw a5,8(a4) + 24c: 8f89 sub a5,a5,a0 + 24e: fe07cee3 bltz a5,24a + uint64_t targend = SysTick->CNT - n; + while( ((int64_t)( SysTick->CNT - targend )) > 0 ); +#else + #error DelaySysTick not defined. +#endif +} + 252: 8082 ret + +00000254 : +int mini_itoa(long value, unsigned int radix, int uppercase, int unsig, char *buffer) + 254: 1101 addi sp,sp,-32 + 256: ce06 sw ra,28(sp) + 258: cc22 sw s0,24(sp) + 25a: ca26 sw s1,20(sp) + int negative = 0; + 25c: c002 sw zero,0(sp) +int mini_itoa(long value, unsigned int radix, int uppercase, int unsig, char *buffer) + 25e: 832a mv t1,a0 + if (value < 0 && !unsig) { + 260: 00055763 bgez a0,26e + 264: e689 bnez a3,26e + negative = 1; + 266: 4785 li a5,1 + value = -value; + 268: 40a00333 neg t1,a0 + negative = 1; + 26c: c03e sw a5,0(sp) + 26e: 8a05 andi a2,a2,1 + 270: 06100413 li s0,97 + 274: c219 beqz a2,27a + 276: 04100413 li s0,65 + int negative = 0; + 27a: 84ba mv s1,a4 + *(pbuffer++) = (digit < 10 ? '0' + digit : (uppercase ? 'A' : 'a') + digit - 10); + 27c: 1459 addi s0,s0,-10 + int digit = value % radix; + 27e: 851a mv a0,t1 + 280: c83a sw a4,16(sp) + 282: c21a sw t1,4(sp) + 284: c62e sw a1,12(sp) + 286: c41a sw t1,8(sp) + 288: 35b1 jal d4 <__umodsi3> + *(pbuffer++) = (digit < 10 ? '0' + digit : (uppercase ? 'A' : 'a') + digit - 10); + 28a: 47a5 li a5,9 + 28c: 4322 lw t1,8(sp) + 28e: 45b2 lw a1,12(sp) + 290: 4742 lw a4,16(sp) + 292: 0ff57693 zext.b a3,a0 + 296: 06a7e163 bltu a5,a0,2f8 + 29a: 03068693 addi a3,a3,48 + 29e: 0ff6f693 zext.b a3,a3 + 2a2: 00148793 addi a5,s1,1 + 2a6: 00d48023 sb a3,0(s1) + value /= radix; + 2aa: 851a mv a0,t1 + 2ac: c83a sw a4,16(sp) + *(pbuffer++) = (digit < 10 ? '0' + digit : (uppercase ? 'A' : 'a') + digit - 10); + 2ae: c63e sw a5,12(sp) + value /= radix; + 2b0: c42e sw a1,8(sp) + 2b2: 3bdd jal a8 <__hidden___udivsi3> + } while (value > 0); + 2b4: 4692 lw a3,4(sp) + 2b6: 45a2 lw a1,8(sp) + 2b8: 47b2 lw a5,12(sp) + 2ba: 4742 lw a4,16(sp) + value /= radix; + 2bc: 832a mv t1,a0 + } while (value > 0); + 2be: 02b6fb63 bgeu a3,a1,2f4 + if (negative) + 2c2: 4682 lw a3,0(sp) + 2c4: c699 beqz a3,2d2 + *(pbuffer++) = '-'; + 2c6: 02d00693 li a3,45 + 2ca: 00d78023 sb a3,0(a5) + 2ce: 00248793 addi a5,s1,2 + len = (pbuffer - buffer); + 2d2: 40e78533 sub a0,a5,a4 + for (i = 0; i < len / 2; i++) { + 2d6: 01f55693 srli a3,a0,0x1f + 2da: 96aa add a3,a3,a0 + *(pbuffer) = '\0'; + 2dc: 00078023 sb zero,0(a5) + for (i = 0; i < len / 2; i++) { + 2e0: 8685 srai a3,a3,0x1 + 2e2: 4601 li a2,0 + 2e4: 17fd addi a5,a5,-1 + 2e6: 00d64b63 blt a2,a3,2fc +} + 2ea: 40f2 lw ra,28(sp) + 2ec: 4462 lw s0,24(sp) + 2ee: 44d2 lw s1,20(sp) + 2f0: 6105 addi sp,sp,32 + 2f2: 8082 ret + *(pbuffer++) = (digit < 10 ? '0' + digit : (uppercase ? 'A' : 'a') + digit - 10); + 2f4: 84be mv s1,a5 + 2f6: b761 j 27e + 2f8: 96a2 add a3,a3,s0 + 2fa: b755 j 29e + char j = buffer[i]; + 2fc: 00c705b3 add a1,a4,a2 + buffer[i] = buffer[len-i-1]; + 300: 0007c283 lbu t0,0(a5) + char j = buffer[i]; + 304: 0005c303 lbu t1,0(a1) + for (i = 0; i < len / 2; i++) { + 308: 0605 addi a2,a2,1 + buffer[i] = buffer[len-i-1]; + 30a: 00558023 sb t0,0(a1) + buffer[len-i-1] = j; + 30e: 00678023 sb t1,0(a5) + for (i = 0; i < len / 2; i++) { + 312: bfc9 j 2e4 + +00000314 : +void ssd1306_i2c_setup(void) +{ + uint16_t tempreg; + + // Reset I2C1 to init all regs + RCC->APB1PRSTR |= RCC_APB1Periph_I2C1; + 314: 400217b7 lui a5,0x40021 + 318: 4b98 lw a4,16(a5) + 31a: 002006b7 lui a3,0x200 + 31e: 8f55 or a4,a4,a3 + 320: cb98 sw a4,16(a5) + RCC->APB1PRSTR &= ~RCC_APB1Periph_I2C1; + 322: 4b98 lw a4,16(a5) + 324: ffe006b7 lui a3,0xffe00 + 328: 16fd addi a3,a3,-1 # ffdfffff <_eusrstack+0xdfdff7ff> + 32a: 8f75 and a4,a4,a3 + 32c: cb98 sw a4,16(a5) + + // set freq + tempreg = I2C1->CTLR2; + 32e: 400057b7 lui a5,0x40005 + 332: 4047d703 lhu a4,1028(a5) # 40005404 <_eusrstack+0x20004c04> + tempreg &= ~I2C_CTLR2_FREQ; + 336: 66c1 lui a3,0x10 + 338: fc068693 addi a3,a3,-64 # ffc0 + 33c: 8f75 and a4,a4,a3 + tempreg |= (FUNCONF_SYSTEM_CORE_CLOCK/SSD1306_I2C_PRERATE)&I2C_CTLR2_FREQ; + 33e: 01876713 ori a4,a4,24 + I2C1->CTLR2 = tempreg; + 342: 40e79223 sh a4,1028(a5) + tempreg = (FUNCONF_SYSTEM_CORE_CLOCK/(25*SSD1306_I2C_CLKRATE))&I2C_CKCFGR_CCR; + tempreg |= I2C_CKCFGR_DUTY; +#endif + tempreg |= I2C_CKCFGR_FS; +#endif + I2C1->CKCFGR = tempreg; + 346: 7771 lui a4,0xffffc + 348: 0705 addi a4,a4,1 # ffffc001 <_eusrstack+0xdfffb801> + 34a: 40e79e23 sh a4,1052(a5) + // initialize the state + ssd1306_i2c_irq_state = 0; +#endif + + // Enable I2C + I2C1->CTLR1 |= I2C_CTLR1_PE; + 34e: 4007d703 lhu a4,1024(a5) + 352: 00176713 ori a4,a4,1 + 356: 40e79023 sh a4,1024(a5) + + // set ACK mode + I2C1->CTLR1 |= I2C_CTLR1_ACK; + 35a: 4007d703 lhu a4,1024(a5) + 35e: 40076713 ori a4,a4,1024 + 362: 40e79023 sh a4,1024(a5) +} + 366: 8082 ret + +00000368 : +void ssd1306_drawPixel(uint32_t x, uint32_t y, int color) +{ + uint32_t addr; + + /* clip */ + if(x >= SSD1306_W) + 368: 07f00793 li a5,127 + 36c: 02a7e763 bltu a5,a0,39a + return; + if(y >= SSD1306_H) + 370: 03f00793 li a5,63 + 374: 02b7e363 bltu a5,a1,39a + return; + + /* compute buffer address */ + addr = x + SSD1306_W*(y/8); + 378: 0035d793 srli a5,a1,0x3 + 37c: 079e slli a5,a5,0x7 + 37e: 97aa add a5,a5,a0 + + /* set/clear bit in buffer */ + if(color) + ssd1306_buffer[addr] |= (1<<(y&7)); + 380: c2818513 addi a0,gp,-984 # 20000024 + 384: 953e add a0,a0,a5 + 386: 899d andi a1,a1,7 + 388: 4705 li a4,1 + 38a: 00054783 lbu a5,0(a0) + 38e: 00b715b3 sll a1,a4,a1 + if(color) + 392: c609 beqz a2,39c + ssd1306_buffer[addr] |= (1<<(y&7)); + 394: 8fcd or a5,a5,a1 + else + ssd1306_buffer[addr] &= ~(1<<(y&7)); + 396: 00f50023 sb a5,0(a0) +} + 39a: 8082 ret + ssd1306_buffer[addr] &= ~(1<<(y&7)); + 39c: fff5c593 not a1,a1 + 3a0: 8fed and a5,a5,a1 + 3a2: bfd5 j 396 + +000003a4 : +// ----------------------------------------------------------------- helpers +static int8_t clamp100(int v) { return v < 0 ? 0 : (v > 100 ? 100 : v); } + +// short square-wave beep on the passive piezo (blocking, ms-scale only) +static void beep(uint16_t freq, uint16_t ms) +{ + 3a4: 1131 addi sp,sp,-20 + 3a6: c622 sw s0,12(sp) + 3a8: 842e mv s0,a1 + if (freq == 0) { Delay_Ms(ms); return; } + uint32_t half = 500000u / freq; // half-period in us + 3aa: 85aa mv a1,a0 + 3ac: 0007a537 lui a0,0x7a + 3b0: 12050513 addi a0,a0,288 # 7a120 +{ + 3b4: c806 sw ra,16(sp) + 3b6: c426 sw s1,8(sp) + uint32_t half = 500000u / freq; // half-period in us + 3b8: 39c5 jal a8 <__hidden___udivsi3> + uint32_t cycles = ((uint32_t)ms * 1000u) / (half * 2u); + 3ba: 00541793 slli a5,s0,0x5 + 3be: 8f81 sub a5,a5,s0 + 3c0: 078a slli a5,a5,0x2 + 3c2: 97a2 add a5,a5,s0 + 3c4: 00151413 slli s0,a0,0x1 + uint32_t half = 500000u / freq; // half-period in us + 3c8: 84aa mv s1,a0 + uint32_t cycles = ((uint32_t)ms * 1000u) / (half * 2u); + 3ca: 85a2 mv a1,s0 + 3cc: 00379513 slli a0,a5,0x3 + 3d0: 39e1 jal a8 <__hidden___udivsi3> + for (uint32_t i = 0; i < cycles; i++) { + funDigitalWrite(BUZZER, FUN_HIGH); + Delay_Us(half); + 3d2: 9426 add s0,s0,s1 + 3d4: 00141793 slli a5,s0,0x1 + uint32_t cycles = ((uint32_t)ms * 1000u) / (half * 2u); + 3d8: 872a mv a4,a0 + Delay_Us(half); + 3da: c03e sw a5,0(sp) + for (uint32_t i = 0; i < cycles; i++) { + 3dc: 4401 li s0,0 + Delay_Us(half); + 3de: 4502 lw a0,0(sp) + funDigitalWrite(BUZZER, FUN_HIGH); + 3e0: 400114b7 lui s1,0x40011 + 3e4: c23a sw a4,4(sp) + 3e6: 4691 li a3,4 + 3e8: 40048493 addi s1,s1,1024 # 40011400 <_eusrstack+0x20010c00> + 3ec: c894 sw a3,16(s1) + Delay_Us(half); + 3ee: 3d91 jal 242 + funDigitalWrite(BUZZER, FUN_LOW); + Delay_Us(half); + 3f0: 4502 lw a0,0(sp) + funDigitalWrite(BUZZER, FUN_LOW); + 3f2: 000406b7 lui a3,0x40 + 3f6: c894 sw a3,16(s1) + Delay_Us(half); + 3f8: 35a9 jal 242 + for (uint32_t i = 0; i < cycles; i++) { + 3fa: 4712 lw a4,4(sp) + 3fc: 0405 addi s0,s0,1 + 3fe: fe8710e3 bne a4,s0,3de + } +} + 402: 40c2 lw ra,16(sp) + 404: 4432 lw s0,12(sp) + 406: 44a2 lw s1,8(sp) + 408: 0151 addi sp,sp,20 + 40a: 8082 ret + +0000040c : + +static void led_blink(void) +{ + 40c: 1161 addi sp,sp,-8 + 40e: c022 sw s0,0(sp) + funDigitalWrite(LED_PIN, FUN_HIGH); + 410: 40011437 lui s0,0x40011 +{ + 414: c206 sw ra,4(sp) + funDigitalWrite(LED_PIN, FUN_HIGH); + 416: 80040413 addi s0,s0,-2048 # 40010800 <_eusrstack+0x20010000> + 41a: 4789 li a5,2 + Delay_Ms(30); + 41c: 0002c537 lui a0,0x2c + funDigitalWrite(LED_PIN, FUN_HIGH); + 420: c81c sw a5,16(s0) + Delay_Ms(30); + 422: f2050513 addi a0,a0,-224 # 2bf20 + 426: 3d31 jal 242 + funDigitalWrite(LED_PIN, FUN_LOW); + 428: 000207b7 lui a5,0x20 +} + 42c: 4092 lw ra,4(sp) + funDigitalWrite(LED_PIN, FUN_LOW); + 42e: c81c sw a5,16(s0) +} + 430: 4402 lw s0,0(sp) + 432: 0121 addi sp,sp,8 + 434: 8082 ret + +00000436 : + +static void pet_reset(void) +{ + pet.satiety = 80; + 436: 645a5737 lui a4,0x645a5 + 43a: 05070713 addi a4,a4,80 # 645a5050 <_eusrstack+0x445a4850> + 43e: c0e1ae23 sw a4,-996(gp) # 20000018 + pet.happy = 80; + pet.energy = 90; + pet.hygiene = 100; + pet.health = 100; + 442: c1c18793 addi a5,gp,-996 # 20000018 + 446: 06400713 li a4,100 + 44a: 00e78223 sb a4,4(a5) # 20004 + pet.age_min = 0; + pet.poop = 0; + pet.sleeping = 0; + pet.alive = 1; + 44e: 4705 li a4,1 + pet.age_min = 0; + 450: 00079323 sh zero,6(a5) + pet.poop = 0; + 454: 00079423 sh zero,8(a5) + pet.alive = 1; + 458: 00e78523 sb a4,10(a5) + screen = SCR_MAIN; + 45c: c0018c23 sb zero,-1000(gp) # 20000014 + cursor = 0; + 460: c0018ba3 sb zero,-1001(gp) # 20000013 +} + 464: 8082 ret + +00000466 : + +static Buttons read_buttons(void) +{ + // active-low: pressed reads 0 + Buttons b; + b.ok = !funDigitalRead(BTN_OK); + 466: 400117b7 lui a5,0x40011 + 46a: 4788 lw a0,8(a5) + b.left = !funDigitalRead(BTN_LEFT); + 46c: 40078793 addi a5,a5,1024 # 40011400 <_eusrstack+0x20010c00> + 470: 4798 lw a4,8(a5) + b.right = !funDigitalRead(BTN_RIGHT); + 472: 479c lw a5,8(a5) + b.ok = !funDigitalRead(BTN_OK); + 474: fff54513 not a0,a0 + b.left = !funDigitalRead(BTN_LEFT); + 478: 8319 srli a4,a4,0x6 + 47a: fff74713 not a4,a4 + b.right = !funDigitalRead(BTN_RIGHT); + 47e: 8395 srli a5,a5,0x5 + 480: fff7c793 not a5,a5 + return b; + 484: 8b05 andi a4,a4,1 + 486: 8905 andi a0,a0,1 + 488: 0722 slli a4,a4,0x8 + 48a: 8b85 andi a5,a5,1 +{ + 48c: 1171 addi sp,sp,-4 + return b; + 48e: 07c2 slli a5,a5,0x10 + 490: 8d59 or a0,a0,a4 +} + 492: 8d5d or a0,a0,a5 + 494: 0111 addi sp,sp,4 + 496: 8082 ret + +00000498 : +} + +/* + * draw a string to the display + */ +void ssd1306_drawstr(int x, int y, const char *str, uint8_t color) + 498: 1101 addi sp,sp,-32 + 49a: cc22 sw s0,24(sp) + 49c: ca26 sw s1,20(sp) + 49e: ce06 sw ra,28(sp) + 4a0: 842a mv s0,a0 + 4a2: 832e mv t1,a1 + 4a4: 84b2 mv s1,a2 +{ + uint8_t c; + + while((c=*str++)) + 4a6: 0004c283 lbu t0,0(s1) + 4aa: 0485 addi s1,s1,1 + 4ac: 04028d63 beqz t0,506 + 4b0: 4701 li a4,0 + d = fontdata[(chr<<3)+i]; + 4b2: 00329793 slli a5,t0,0x3 + 4b6: 6689 lui a3,0x2 + 4b8: ba068693 addi a3,a3,-1120 # 1ba0 + 4bc: 97ba add a5,a5,a4 + 4be: 97b6 add a5,a5,a3 + 4c0: 0007c683 lbu a3,0(a5) + 4c4: 4781 li a5,0 + ssd1306_drawPixel(x+j, y+i, col); + 4c6: 0076d613 srli a2,a3,0x7 + 4ca: 00e305b3 add a1,t1,a4 + 4ce: 00f40533 add a0,s0,a5 + 4d2: c816 sw t0,16(sp) + 4d4: c636 sw a3,12(sp) + 4d6: c43a sw a4,8(sp) + 4d8: c21a sw t1,4(sp) + 4da: c03e sw a5,0(sp) + 4dc: 3571 jal 368 + d <<= 1; + 4de: 46b2 lw a3,12(sp) + for(j=0;j<8;j++) + 4e0: 4782 lw a5,0(sp) + 4e2: 4621 li a2,8 + d <<= 1; + 4e4: 0686 slli a3,a3,0x1 + for(j=0;j<8;j++) + 4e6: 0785 addi a5,a5,1 + 4e8: 4312 lw t1,4(sp) + 4ea: 4722 lw a4,8(sp) + 4ec: 42c2 lw t0,16(sp) + d <<= 1; + 4ee: 0ff6f693 zext.b a3,a3 + for(j=0;j<8;j++) + 4f2: fcc79ae3 bne a5,a2,4c6 + for(i=0;i<8;i++) + 4f6: 0705 addi a4,a4,1 + 4f8: faf71de3 bne a4,a5,4b2 + { + ssd1306_drawchar(x, y, c, color); + x += 8; + 4fc: 9432 add s0,s0,a2 + if(x>120) + 4fe: 07800793 li a5,120 + 502: fa87d2e3 bge a5,s0,4a6 + break; + } +} + 506: 40f2 lw ra,28(sp) + 508: 4462 lw s0,24(sp) + 50a: 44d2 lw s1,20(sp) + 50c: 6105 addi sp,sp,32 + 50e: 8082 ret + +00000510 : +{ + 510: 862e mv a2,a1 + int len = 0; + 512: 4701 li a4,0 + while (s[len]) len++; + 514: 00e607b3 add a5,a2,a4 + 518: 0007c783 lbu a5,0(a5) + 51c: eb99 bnez a5,532 + int x = (SSD1306_W - len * 8) / 2; + 51e: 47c1 li a5,16 + 520: 8f99 sub a5,a5,a4 + 522: 078a slli a5,a5,0x2 + if (x < 0) x = 0; + 524: fff7c713 not a4,a5 + 528: 877d srai a4,a4,0x1f + ssd1306_drawstr(x, y, s, 1); + 52a: 85aa mv a1,a0 + 52c: 00e7f533 and a0,a5,a4 + 530: b7a5 j 498 + while (s[len]) len++; + 532: 0705 addi a4,a4,1 + 534: b7c5 j 514 + +00000536 : + if((x >= SSD1306_W) || (y >= SSD1306_H)) return; + 536: 07f00713 li a4,127 + 53a: 04a76263 bltu a4,a0,57e + 53e: 03f00793 li a5,63 + 542: 02b7ee63 bltu a5,a1,57e +void ssd1306_drawFastHLine(uint32_t x, uint32_t y, uint32_t w, uint32_t color) + 546: 1141 addi sp,sp,-16 + if((x+w-1) >= SSD1306_W) w = SSD1306_W-x; + 548: fff60793 addi a5,a2,-1 +void ssd1306_drawFastHLine(uint32_t x, uint32_t y, uint32_t w, uint32_t color) + 54c: c422 sw s0,8(sp) + 54e: c606 sw ra,12(sp) + 550: c226 sw s1,4(sp) + if((x+w-1) >= SSD1306_W) w = SSD1306_W-x; + 552: 97aa add a5,a5,a0 + 554: 842a mv s0,a0 + 556: 00f77563 bgeu a4,a5,560 + 55a: 08000613 li a2,128 + 55e: 8e09 sub a2,a2,a0 + 560: 00c404b3 add s1,s0,a2 + 564: 8522 mv a0,s0 + ssd1306_drawPixel(x++, y, color); + 566: 4605 li a2,1 + 568: c02e sw a1,0(sp) + 56a: 0405 addi s0,s0,1 + 56c: 3bf5 jal 368 + while (w--) + 56e: 4582 lw a1,0(sp) + 570: fe849ae3 bne s1,s0,564 +} + 574: 40b2 lw ra,12(sp) + 576: 4422 lw s0,8(sp) + 578: 4492 lw s1,4(sp) + 57a: 0141 addi sp,sp,16 + 57c: 8082 ret + 57e: 8082 ret + +00000580 : + if((x >= SSD1306_W) || (y >= SSD1306_H)) return; + 580: 07f00793 li a5,127 + 584: 02a7cf63 blt a5,a0,5c2 +void ssd1306_drawFastVLine(int32_t x, int32_t y, int32_t h, uint32_t color) + 588: 1141 addi sp,sp,-16 + 58a: c422 sw s0,8(sp) + 58c: c606 sw ra,12(sp) + 58e: c226 sw s1,4(sp) + if((y+h-1) >= SSD1306_H) h = SSD1306_H-y; + 590: 00c587b3 add a5,a1,a2 + 594: 04000713 li a4,64 + 598: 842e mv s0,a1 + 59a: 00f75463 bge a4,a5,5a2 + 59e: 40b70633 sub a2,a4,a1 + 5a2: 008604b3 add s1,a2,s0 + while(h--) + 5a6: 00941763 bne s0,s1,5b4 +} + 5aa: 40b2 lw ra,12(sp) + 5ac: 4422 lw s0,8(sp) + 5ae: 4492 lw s1,4(sp) + 5b0: 0141 addi sp,sp,16 + 5b2: 8082 ret + ssd1306_drawPixel(x, y++, color); + 5b4: 85a2 mv a1,s0 + 5b6: 4605 li a2,1 + 5b8: c02a sw a0,0(sp) + 5ba: 337d jal 368 + 5bc: 4502 lw a0,0(sp) + 5be: 0405 addi s0,s0,1 + 5c0: b7dd j 5a6 + 5c2: 8082 ret + +000005c4 : +void ssd1306_drawRect(int32_t x, int32_t y, uint32_t w, uint32_t h, uint32_t color) + 5c4: 1131 addi sp,sp,-20 + 5c6: c426 sw s1,8(sp) + 5c8: 84b2 mv s1,a2 + ssd1306_drawFastVLine(x, y, h, color); + 5ca: 8636 mv a2,a3 +void ssd1306_drawRect(int32_t x, int32_t y, uint32_t w, uint32_t h, uint32_t color) + 5cc: c806 sw ra,16(sp) + 5ce: c622 sw s0,12(sp) + 5d0: c236 sw a3,4(sp) + 5d2: 842a mv s0,a0 + 5d4: c02e sw a1,0(sp) + ssd1306_drawFastVLine(x, y, h, color); + 5d6: 376d jal 580 + ssd1306_drawFastVLine(x+w-1, y, h, color); + 5d8: 4612 lw a2,4(sp) + 5da: 4582 lw a1,0(sp) + 5dc: fff48513 addi a0,s1,-1 + 5e0: 9522 add a0,a0,s0 + 5e2: 3f79 jal 580 + ssd1306_drawFastHLine(x, y, w, color); + 5e4: 4582 lw a1,0(sp) + 5e6: 8626 mv a2,s1 + 5e8: 8522 mv a0,s0 + 5ea: 37b1 jal 536 + ssd1306_drawFastHLine(x, y+h-1, w, color); + 5ec: 4782 lw a5,0(sp) + 5ee: 8522 mv a0,s0 +} + 5f0: 4432 lw s0,12(sp) + ssd1306_drawFastHLine(x, y+h-1, w, color); + 5f2: fff78593 addi a1,a5,-1 + 5f6: 4792 lw a5,4(sp) +} + 5f8: 40c2 lw ra,16(sp) + ssd1306_drawFastHLine(x, y+h-1, w, color); + 5fa: 8626 mv a2,s1 +} + 5fc: 44a2 lw s1,8(sp) + ssd1306_drawFastHLine(x, y+h-1, w, color); + 5fe: 95be add a1,a1,a5 +} + 600: 0151 addi sp,sp,20 + ssd1306_drawFastHLine(x, y+h-1, w, color); + 602: bf15 j 536 + +00000604 : +{ + 604: 1121 addi sp,sp,-24 + 606: c822 sw s0,16(sp) + 608: c626 sw s1,12(sp) + 60a: 842a mv s0,a0 + 60c: 84b2 mv s1,a2 + ssd1306_drawstr(0, y, label, 1); + 60e: 862e mv a2,a1 + 610: 85aa mv a1,a0 + 612: 4501 li a0,0 +{ + 614: ca06 sw ra,20(sp) + ssd1306_drawstr(0, y, label, 1); + 616: 3549 jal 498 + ssd1306_drawRect(bx, y, bw, 7, 1); + 618: 03000513 li a0,48 + 61c: 469d li a3,7 + 61e: 04c00613 li a2,76 + 622: 85a2 mv a1,s0 + 624: 3745 jal 5c4 + int fill = (val * (bw - 2)) / 100; + 626: 00349513 slli a0,s1,0x3 + 62a: 9526 add a0,a0,s1 + 62c: 050a slli a0,a0,0x2 + 62e: 9526 add a0,a0,s1 + 630: 0506 slli a0,a0,0x1 + if (fill > 0) ssd1306_fillRect(bx + 1, y + 1, fill, 5, 1); + 632: 06300793 li a5,99 + 636: 02a7df63 bge a5,a0,674 + 63a: 00140793 addi a5,s0,1 + int fill = (val * (bw - 2)) / 100; + 63e: 06400593 li a1,100 + if (fill > 0) ssd1306_fillRect(bx + 1, y + 1, fill, 5, 1); + 642: c03e sw a5,0(sp) + int fill = (val * (bw - 2)) / 100; + 644: 3cb1 jal a0 <__divsi3> + 646: 4782 lw a5,0(sp) + 648: 872a mv a4,a0 + 64a: 0419 addi s0,s0,6 + 64c: 03170693 addi a3,a4,49 + m=x; + 650: 03100493 li s1,49 + 654: 8526 mv a0,s1 + ssd1306_drawPixel(m++, n, color); + 656: 85be mv a1,a5 + 658: 4605 li a2,1 + 65a: c436 sw a3,8(sp) + 65c: c23a sw a4,4(sp) + 65e: c03e sw a5,0(sp) + 660: 3321 jal 368 + while(w--) + 662: 46a2 lw a3,8(sp) + ssd1306_drawPixel(m++, n, color); + 664: 0485 addi s1,s1,1 + while(w--) + 666: 4782 lw a5,0(sp) + 668: 4712 lw a4,4(sp) + 66a: fed495e3 bne s1,a3,654 + n++; + 66e: 0785 addi a5,a5,1 + while(h--) + 670: fc879ee3 bne a5,s0,64c +} + 674: 40d2 lw ra,20(sp) + 676: 4442 lw s0,16(sp) + 678: 44b2 lw s1,12(sp) + 67a: 0161 addi sp,sp,24 + 67c: 8082 ret + +0000067e : +void ssd1306_drawImage(uint32_t x, uint32_t y, const unsigned char* input, uint32_t width, uint32_t height, uint32_t color_mode) { + 67e: fd810113 addi sp,sp,-40 + 682: 00e587b3 add a5,a1,a4 + 686: d222 sw s0,36(sp) + 688: d026 sw s1,32(sp) + 68a: c82a sw a0,16(sp) + 68c: ca32 sw a2,20(sp) + uint32_t bytes_to_draw = width / 8; + 68e: 0036d413 srli s0,a3,0x3 + 692: c63e sw a5,12(sp) + 694: 4381 li t2,0 + uint32_t v_mask = 1 << (y_absolute & 7); + 696: 0075f793 andi a5,a1,7 + 69a: 4705 li a4,1 + 69c: 00f717b3 sll a5,a4,a5 + 6a0: c03e sw a5,0(sp) + uint32_t input_byte = input[byte + line * bytes_to_draw]; + 6a2: 47d2 lw a5,20(sp) + for (uint32_t byte = 0; byte < bytes_to_draw; byte++) { + 6a4: 4681 li a3,0 + uint32_t input_byte = input[byte + line * bytes_to_draw]; + 6a6: 979e add a5,a5,t2 + 6a8: cc3e sw a5,24(sp) + buffer_addr = x_absolute + SSD1306_W * (y_absolute / 8); + 6aa: 0035d793 srli a5,a1,0x3 + 6ae: 079e slli a5,a5,0x7 + 6b0: ce3e sw a5,28(sp) + uint32_t input_byte = input[byte + line * bytes_to_draw]; + 6b2: 47e2 lw a5,24(sp) + x_absolute = x + 8 * byte + pixel; + 6b4: 00369293 slli t0,a3,0x3 + for (pixel = 0; pixel < 8; pixel++) { + 6b8: 4701 li a4,0 + uint32_t input_byte = input[byte + line * bytes_to_draw]; + 6ba: 97b6 add a5,a5,a3 + 6bc: 0007c783 lbu a5,0(a5) + 6c0: c23e sw a5,4(sp) + x_absolute = x + 8 * byte + pixel; + 6c2: 47c2 lw a5,16(sp) + 6c4: 92be add t0,t0,a5 + buffer_addr = x_absolute + SSD1306_W * (y_absolute / 8); + 6c6: 47f2 lw a5,28(sp) + 6c8: 005784b3 add s1,a5,t0 + if (x_absolute >= SSD1306_W) { + 6cc: 00e287b3 add a5,t0,a4 + 6d0: 07f00613 li a2,127 + 6d4: 04f66463 bltu a2,a5,71c + uint8_t input_pixel = input_byte & (0x80 >> pixel); // MSB first (default) + 6d8: 4512 lw a0,4(sp) + 6da: 08000793 li a5,128 + 6de: 40e7d7b3 sra a5,a5,a4 + 6e2: 8fe9 and a5,a5,a0 + buffer_addr = x_absolute + SSD1306_W * (y_absolute / 8); + 6e4: 00e48633 add a2,s1,a4 + ssd1306_buffer[buffer_addr] = (ssd1306_buffer[buffer_addr] & ~v_mask) | (input_pixel ? v_mask : 0); + 6e8: c2818513 addi a0,gp,-984 # 20000024 + 6ec: 9532 add a0,a0,a2 + 6ee: 00014303 lbu t1,0(sp) + uint8_t input_pixel = input_byte & (0x80 >> pixel); // MSB first (default) + 6f2: c43e sw a5,8(sp) + ssd1306_buffer[buffer_addr] = (ssd1306_buffer[buffer_addr] & ~v_mask) | (input_pixel ? v_mask : 0); + 6f4: 00054783 lbu a5,0(a0) + 6f8: fff34613 not a2,t1 + for (pixel = 0; pixel < 8; pixel++) { + 6fc: 0705 addi a4,a4,1 + ssd1306_buffer[buffer_addr] = (ssd1306_buffer[buffer_addr] & ~v_mask) | (input_pixel ? v_mask : 0); + 6fe: 8e7d and a2,a2,a5 + 700: 47a2 lw a5,8(sp) + 702: 00f037b3 snez a5,a5 + 706: 40f007b3 neg a5,a5 + 70a: 00f37333 and t1,t1,a5 + 70e: 00666633 or a2,a2,t1 + 712: 00c50023 sb a2,0(a0) + for (pixel = 0; pixel < 8; pixel++) { + 716: 47a1 li a5,8 + 718: faf71ae3 bne a4,a5,6cc + for (uint32_t byte = 0; byte < bytes_to_draw; byte++) { + 71c: 0685 addi a3,a3,1 + 71e: f8d41ae3 bne s0,a3,6b2 + for (uint32_t line = 0; line < height; line++) { + 722: 47b2 lw a5,12(sp) + 724: 0585 addi a1,a1,1 + 726: 93a2 add t2,t2,s0 + 728: 00b78663 beq a5,a1,734 + if (y_absolute >= SSD1306_H) { + 72c: 04000793 li a5,64 + 730: f6f593e3 bne a1,a5,696 +} + 734: 5412 lw s0,36(sp) + 736: 5482 lw s1,32(sp) + 738: 02810113 addi sp,sp,40 + 73c: 8082 ret + +0000073e : + uint32_t dmd0 = *dmdata0; + 73e: e00007b7 lui a5,0xe0000 + 742: 0f47a783 lw a5,244(a5) # e00000f4 <_eusrstack+0xbffff8f4> +} + 746: 8082 ret + +00000748 <_write.constprop.0>: + if( ( *DMDATA0 & 0xc0 ) == 0xc0 ) return 0; + 748: e00007b7 lui a5,0xe0000 + 74c: 0f478793 addi a5,a5,244 # e00000f4 <_eusrstack+0xbffff8f4> + 750: 4398 lw a4,0(a5) +WEAK int _write(int fd, const char *buf, int size) + 752: 1121 addi sp,sp,-24 + 754: ca06 sw ra,20(sp) + 756: c822 sw s0,16(sp) + 758: c626 sw s1,12(sp) + if( ( *DMDATA0 & 0xc0 ) == 0xc0 ) return 0; + 75a: 0c077713 andi a4,a4,192 + 75e: 0c000693 li a3,192 + 762: 00d70b63 beq a4,a3,778 <_write.constprop.0+0x30> + char buffer[4] = { 0 }; + 766: c402 sw zero,8(sp) + 768: 842e mv s0,a1 + if( size == 0 ) + 76a: eddd bnez a1,828 <_write.constprop.0+0xe0> + lastdmd = (*DMDATA0); + 76c: 439c lw a5,0(a5) + if( lastdmd && !(lastdmd&0x80) ) internal_handle_input( (uint32_t*)DMDATA0 ); + 76e: c789 beqz a5,778 <_write.constprop.0+0x30> + 770: 0807f793 andi a5,a5,128 + 774: e391 bnez a5,778 <_write.constprop.0+0x30> + 776: 37e1 jal 73e + if( ( *DMDATA0 & 0xc0 ) == 0xc0 ) return 0; + 778: 4401 li s0,0 +} + 77a: 40d2 lw ra,20(sp) + 77c: 8522 mv a0,s0 + 77e: 4442 lw s0,16(sp) + 780: 44b2 lw s1,12(sp) + 782: 0161 addi sp,sp,24 + 784: 8082 ret + int tosend = size - place; + 786: 409407b3 sub a5,s0,s1 + if( tosend > 7 ) tosend = 7; + 78a: 471d li a4,7 + 78c: 00f75363 bge a4,a5,792 <_write.constprop.0+0x4a> + 790: 87ba mv a5,a4 + 792: 001006b7 lui a3,0x100 + while( ( lastdmd = (*DMDATA0) ) & 0x80 ) + 796: e0000737 lui a4,0xe0000 + if( tosend > 7 ) tosend = 7; + 79a: 0685 addi a3,a3,1 # 100001 + while( ( lastdmd = (*DMDATA0) ) & 0x80 ) + 79c: 0f470713 addi a4,a4,244 # e00000f4 <_eusrstack+0xbffff8f4> + 7a0: 4310 lw a2,0(a4) + 7a2: 08067593 andi a1,a2,128 + 7a6: e1a5 bnez a1,806 <_write.constprop.0+0xbe> + if( lastdmd ) internal_handle_input( (uint32_t*)DMDATA0 ); + 7a8: c611 beqz a2,7b4 <_write.constprop.0+0x6c> + 7aa: c22a sw a0,4(sp) + 7ac: c03e sw a5,0(sp) + 7ae: 3f41 jal 73e + 7b0: 4512 lw a0,4(sp) + 7b2: 4782 lw a5,0(sp) + 7b4: 0034 addi a3,sp,8 + if( tosend > 7 ) tosend = 7; + 7b6: 470d li a4,3 + 7b8: 85b6 mv a1,a3 + while( t < tosend ) + 7ba: 04f74d63 blt a4,a5,814 <_write.constprop.0+0xcc> + *DMDATA1 = *(uint32_t*)&(buffer[0]); + 7be: 46a2 lw a3,8(sp) + 7c0: e0000737 lui a4,0xe0000 + while( t < tosend && t < 3 ) + 7c4: 460d li a2,3 + *DMDATA1 = *(uint32_t*)&(buffer[0]); + 7c6: 0ed72c23 sw a3,248(a4) # e00000f8 <_eusrstack+0xbffff8f8> + 7ca: 009506b3 add a3,a0,s1 + t = 0; + 7ce: 4701 li a4,0 + buffer[t+1] = buf[t+place]; + 7d0: 0006c283 lbu t0,0(a3) + 7d4: 0705 addi a4,a4,1 + 7d6: 00e58333 add t1,a1,a4 + 7da: 00530023 sb t0,0(t1) + while( t < tosend && t < 3 ) + 7de: 00e78563 beq a5,a4,7e8 <_write.constprop.0+0xa0> + 7e2: 0685 addi a3,a3,1 + 7e4: fec716e3 bne a4,a2,7d0 <_write.constprop.0+0x88> + buffer[0] = 0x80 | (tosend + 4); + 7e8: 00478713 addi a4,a5,4 + 7ec: f8076713 ori a4,a4,-128 + 7f0: 00e10423 sb a4,8(sp) + *DMDATA0 = *(uint32_t*)&(buffer[0]); + 7f4: 46a2 lw a3,8(sp) + 7f6: e0000737 lui a4,0xe0000 + place += tosend; + 7fa: 94be add s1,s1,a5 + *DMDATA0 = *(uint32_t*)&(buffer[0]); + 7fc: 0ed72a23 sw a3,244(a4) # e00000f4 <_eusrstack+0xbffff8f4> + while( place < size ) + 800: f884c3e3 blt s1,s0,786 <_write.constprop.0+0x3e> + 804: bf9d j 77a <_write.constprop.0+0x32> + if( timeout-- == 0 ) + 806: 16fd addi a3,a3,-1 + 808: fec1 bnez a3,7a0 <_write.constprop.0+0x58> + *DMDATA0 |= 0xc0; + 80a: 431c lw a5,0(a4) + 80c: 0c07e793 ori a5,a5,192 + 810: c31c sw a5,0(a4) + return 0; + 812: b79d j 778 <_write.constprop.0+0x30> + buffer[t-3] = buf[t+place]; + 814: 00e48633 add a2,s1,a4 + 818: 962a add a2,a2,a0 + 81a: 00064603 lbu a2,0(a2) + t++; + 81e: 0705 addi a4,a4,1 + 820: 0685 addi a3,a3,1 + buffer[t-3] = buf[t+place]; + 822: fec68fa3 sb a2,-1(a3) + 826: bf51 j 7ba <_write.constprop.0+0x72> + 828: 4481 li s1,0 + 82a: bfd9 j 800 <_write.constprop.0+0xb8> + +0000082c <__puts_uart>: +{ + 82c: 1161 addi sp,sp,-8 + 82e: c022 sw s0,0(sp) + 830: c206 sw ra,4(sp) + 832: 842e mv s0,a1 + _write( 0, s, len ); + 834: 3f11 jal 748 <_write.constprop.0> +} + 836: 4092 lw ra,4(sp) + 838: 8522 mv a0,s0 + 83a: 4402 lw s0,0(sp) + 83c: 0121 addi sp,sp,8 + 83e: 8082 ret + +00000840 : + asm volatile( "\n\ + 840: 20000197 auipc gp,0x20000 + 844: bbc18193 addi gp,gp,-1092 # 200003fc <__global_pointer$> + 848: 40418113 addi sp,gp,1028 # 20000800 <_eusrstack> + 84c: 6509 lui a0,0x2 + 84e: 88050513 addi a0,a0,-1920 # 1880 + 852: 30051073 csrw mstatus,a0 + 856: fffff697 auipc a3,0xfffff + 85a: 7aa68693 addi a3,a3,1962 # 0 + 85e: 0036e693 ori a3,a3,3 + 862: 30569073 csrw mtvec,a3 +asm volatile( + 866: c0c18513 addi a0,gp,-1012 # 20000008 + 86a: 02818593 addi a1,gp,40 # 20000424 <_ebss> + 86e: 4601 li a2,0 + 870: 00b55663 bge a0,a1,87c + 874: c110 sw a2,0(a0) + 876: 0511 addi a0,a0,4 + 878: feb54ee3 blt a0,a1,874 + 87c: 00002517 auipc a0,0x2 + 880: c8c50513 addi a0,a0,-884 # 2508 <_data_lma> + 884: c0418593 addi a1,gp,-1020 # 20000000 + 888: c0c18613 addi a2,gp,-1012 # 20000008 + 88c: 00c58863 beq a1,a2,89c + 890: 4114 lw a3,0(a0) + 892: c194 sw a3,0(a1) + 894: 0511 addi a0,a0,4 + 896: 0591 addi a1,a1,4 + 898: fec59ae3 bne a1,a2,88c + SysTick->CTLR = 1; + 89c: e000f7b7 lui a5,0xe000f + 8a0: 4705 li a4,1 + 8a2: c398 sw a4,0(a5) +asm volatile( + 8a4: 6785 lui a5,0x1 + 8a6: d9a78793 addi a5,a5,-614 # d9a
+ 8aa: 34179073 csrw mepc,a5 + 8ae: 30200073 mret + +000008b2 : + +// Return the Machine Exception Program Register (MEPC) +static inline uint32_t __get_MEPC(void) +{ + uint32_t result; + __ASM volatile( ADD_ARCH_ZICSR "csrr %0," "mepc" : "=r"(result)); + 8b2: 34102573 csrr a0,mepc + PrintHex( __get_MEPC() ); // "addr2line -e debugprintfdemo.elf 0x000007e6" ---> debugprintfdemo.c:45 + 8b6: 3a0d jal 1e8 + __ASM volatile( ADD_ARCH_ZICSR "csrr %0, mstatus": "=r"(result) ); + 8b8: 30002573 csrr a0,mstatus + PrintHex( __get_MSTATUS() ); + 8bc: 3235 jal 1e8 + +// Return the Machine Trap Value Register (MTVAL) +static inline uint32_t __get_MTVAL(void) +{ + uint32_t result; + __ASM volatile( ADD_ARCH_ZICSR "csrr %0," "mtval" : "=r" (result) ); + 8be: 34302573 csrr a0,mtval + PrintHex( __get_MTVAL() ); + 8c2: 321d jal 1e8 + __ASM volatile( ADD_ARCH_ZICSR "csrr %0," "mcause": "=r"(result)); + 8c4: 34202573 csrr a0,mcause + PrintHex( __get_MCAUSE() ); + 8c8: 3205 jal 1e8 + while( (*DMDATA0) & 0x80 ); + 8ca: e00007b7 lui a5,0xe0000 + 8ce: 0f478793 addi a5,a5,244 # e00000f4 <_eusrstack+0xbffff8f4> + 8d2: 4398 lw a4,0(a5) + 8d4: 08077713 andi a4,a4,128 + 8d8: ff6d bnez a4,8d2 + *DMDATA0 = 0x0a85; + 8da: 6705 lui a4,0x1 + 8dc: a8570713 addi a4,a4,-1403 # a85 + 8e0: c398 sw a4,0(a5) + while( (*DMDATA0) & 0x80 ); + 8e2: e00007b7 lui a5,0xe0000 + 8e6: 0f478793 addi a5,a5,244 # e00000f4 <_eusrstack+0xbffff8f4> + 8ea: 4398 lw a4,0(a5) + 8ec: 08077713 andi a4,a4,128 + 8f0: ff6d bnez a4,8ea + *DMDATA0 = 0xaaaaaa83; + 8f2: aaaab737 lui a4,0xaaaab + 8f6: a8370713 addi a4,a4,-1405 # aaaaaa83 <_eusrstack+0x8aaaa283> + 8fa: c398 sw a4,0(a5) + asm volatile( "1: j 1b" ); + 8fc: a001 j 8fc + +000008fe : + RCC->INTR |= RCC_CSSC; // clear the clock security int flag + 8fe: 40021737 lui a4,0x40021 + 902: 471c lw a5,8(a4) + 904: 008006b7 lui a3,0x800 + 908: 8fd5 or a5,a5,a3 + 90a: c71c sw a5,8(a4) + +0000090c : + for (; *s; s++); + 90c: 87aa mv a5,a0 + 90e: 0007c703 lbu a4,0(a5) + 912: e701 bnez a4,91a +} + 914: 40a78533 sub a0,a5,a0 + 918: 8082 ret + for (; *s; s++); + 91a: 0785 addi a5,a5,1 + 91c: bfcd j 90e + +0000091e : +{ + 91e: fa410113 addi sp,sp,-92 + 922: caa2 sw s0,84(sp) + 924: c8a6 sw s1,80(sp) + 926: cc86 sw ra,88(sp) + 928: c02a sw a0,0(sp) + 92a: c22e sw a1,4(sp) + 92c: 8432 mv s0,a2 + 92e: 84b6 mv s1,a3 + if(puts == (void*)0) { + 930: e509 bnez a0,93a + puts = _puts; buf = (void*)0; + 932: 1a800793 li a5,424 + 936: c202 sw zero,4(sp) + 938: c03e sw a5,0(sp) + int n = 0; + 93a: ca02 sw zero,20(sp) + while ((ch=*(fmt++))) { + 93c: 00044783 lbu a5,0(s0) + 940: 00140713 addi a4,s0,1 + 944: 00f10fa3 sb a5,31(sp) + 948: eb81 bnez a5,958 +} + 94a: 40e6 lw ra,88(sp) + 94c: 4456 lw s0,84(sp) + 94e: 4552 lw a0,20(sp) + 950: 44c6 lw s1,80(sp) + 952: 05c10113 addi sp,sp,92 + 956: 8082 ret + 958: c63a sw a4,12(sp) + if (ch!='%') { + 95a: 02500693 li a3,37 + 95e: 02d78063 beq a5,a3,97e + len = puts(&ch, len, buf); + 962: 4612 lw a2,4(sp) + 964: 4782 lw a5,0(sp) + 966: 4585 li a1,1 + 968: 01f10513 addi a0,sp,31 + 96c: 9782 jalr a5 + while ((ch=*(fmt++))) { + 96e: 4732 lw a4,12(sp) + 970: c426 sw s1,8(sp) + 972: 843a mv s0,a4 + n = n + len; + 974: 47d2 lw a5,20(sp) + 976: 44a2 lw s1,8(sp) + 978: 97aa add a5,a5,a0 + 97a: ca3e sw a5,20(sp) + 97c: b7c1 j 93c + ch=*(fmt++); + 97e: 00144783 lbu a5,1(s0) + if (ch == '0') pad_char = '0'; + 982: 03000693 li a3,48 + ch=*(fmt++); + 986: 00240713 addi a4,s0,2 + 98a: 00f10fa3 sb a5,31(sp) + if (ch == '0') pad_char = '0'; + 98e: c63e sw a5,12(sp) + 990: 08d79363 bne a5,a3,a16 + ch=*(fmt++); + 994: 843a mv s0,a4 + 996: 4681 li a3,0 + 998: 4701 li a4,0 + while (ch >= '0' && ch <= '9') { + 99a: 45a5 li a1,9 + 99c: a819 j 9b2 + pad_to = pad_to * 10 + (ch - '0'); + 99e: 00271793 slli a5,a4,0x2 + 9a2: 97ba add a5,a5,a4 + 9a4: 0786 slli a5,a5,0x1 + ch=*(fmt++); + 9a6: 0405 addi s0,s0,1 + pad_to = pad_to * 10 + (ch - '0'); + 9a8: 00f60733 add a4,a2,a5 + ch=*(fmt++); + 9ac: fff44783 lbu a5,-1(s0) + 9b0: 4685 li a3,1 + while (ch >= '0' && ch <= '9') { + 9b2: fd078613 addi a2,a5,-48 + 9b6: 0ff67513 zext.b a0,a2 + 9ba: fea5f2e3 bgeu a1,a0,99e + 9be: c299 beqz a3,9c4 + 9c0: 00f10fa3 sb a5,31(sp) + if(pad_to > (signed int) sizeof(bf)) { + 9c4: c83a sw a4,16(sp) + 9c6: 46e1 li a3,24 + 9c8: 00e6d363 bge a3,a4,9ce + 9cc: c836 sw a3,16(sp) + if (ch == 'l') { + 9ce: 06c00613 li a2,108 + char l = 0; + 9d2: 4681 li a3,0 + if (ch == 'l') { + 9d4: 00c79863 bne a5,a2,9e4 + ch=*(fmt++); + 9d8: 00044783 lbu a5,0(s0) + l = 1; + 9dc: 4685 li a3,1 + ch=*(fmt++); + 9de: 0405 addi s0,s0,1 + 9e0: 00f10fa3 sb a5,31(sp) + switch (ch) { + 9e4: 01f14603 lbu a2,31(sp) + 9e8: 06400793 li a5,100 + 9ec: 06f60563 beq a2,a5,a56 + 9f0: 02c7e763 bltu a5,a2,a1e + 9f4: 05800793 li a5,88 + 9f8: 0af60263 beq a2,a5,a9c + 9fc: 06300793 li a5,99 + a00: 0cf60063 beq a2,a5,ac0 + a04: d239 beqz a2,94a + len = puts(&ch, len, buf); + a06: 4612 lw a2,4(sp) + a08: 4782 lw a5,0(sp) + a0a: 4585 li a1,1 + a0c: 01f10513 addi a0,sp,31 + a10: 9782 jalr a5 + break; + a12: c426 sw s1,8(sp) + a14: b785 j 974 + char pad_char = ' '; + a16: 02000693 li a3,32 + a1a: c636 sw a3,12(sp) + a1c: bfa5 j 994 + switch (ch) { + a1e: 07500793 li a5,117 + a22: 02f60a63 beq a2,a5,a56 + a26: 07800793 li a5,120 + a2a: 06f60963 beq a2,a5,a9c + a2e: 07300793 li a5,115 + a32: fcf61ae3 bne a2,a5,a06 + ptr = va_arg(va, char*); + a36: 00448793 addi a5,s1,4 + a3a: 4084 lw s1,0(s1) + a3c: cc3a sw a4,24(sp) + a3e: c43e sw a5,8(sp) + len = mini_strlen(ptr); + a40: 8526 mv a0,s1 + a42: 35e9 jal 90c + if (pad_to > 0) { + a44: 4762 lw a4,24(sp) + len = mini_strlen(ptr); + a46: 85aa mv a1,a0 + if (pad_to > 0) { + a48: 08e05963 blez a4,ada + len = mini_pad(ptr, len, pad_char, pad_to, bf); + a4c: 46c2 lw a3,16(sp) + a4e: 4632 lw a2,12(sp) + a50: 1838 addi a4,sp,56 + a52: 8526 mv a0,s1 + a54: a025 j a7c + len = mini_itoa(va_arg(va, unsigned long), 10, 0, (ch=='u'), bf2); + a56: 00448793 addi a5,s1,4 + a5a: c43e sw a5,8(sp) + if(l) { + a5c: ca85 beqz a3,a8c + len = mini_itoa(va_arg(va, unsigned long), 10, 0, (ch=='u'), bf2); + a5e: f8b60613 addi a2,a2,-117 + a62: 1018 addi a4,sp,32 + a64: 00163693 seqz a3,a2 + a68: 4088 lw a0,0(s1) + a6a: 4601 li a2,0 + a6c: 45a9 li a1,10 + a6e: fe6ff0ef jal 254 + len = mini_pad(bf2, len, pad_char, pad_to, bf); + a72: 46c2 lw a3,16(sp) + a74: 4632 lw a2,12(sp) + a76: 1838 addi a4,sp,56 + a78: 85aa mv a1,a0 + len = mini_pad(bf2, len, pad_char, pad_to, bf); + a7a: 1008 addi a0,sp,32 + a7c: ea2ff0ef jal 11e + len = puts(bf, len, buf); + a80: 4612 lw a2,4(sp) + len = mini_pad(bf2, len, pad_char, pad_to, bf); + a82: 85aa mv a1,a0 + len = puts(bf, len, buf); + a84: 1828 addi a0,sp,56 + a86: 4782 lw a5,0(sp) + a88: 9782 jalr a5 + break; + a8a: b5ed j 974 + if(ch == 'u') { + a8c: 07500793 li a5,117 + a90: 1018 addi a4,sp,32 + a92: 4685 li a3,1 + a94: fcf60ae3 beq a2,a5,a68 + if (radix > 16) + a98: 4681 li a3,0 + a9a: b7f9 j a68 + if(l) { + a9c: 4088 lw a0,0(s1) + len = mini_itoa(va_arg(va, unsigned long), 16, (ch=='X'), 1, bf2); + a9e: fa860613 addi a2,a2,-88 + len = mini_itoa(va_arg(va, unsigned long), 10, 0, (ch=='u'), bf2); + aa2: 00448793 addi a5,s1,4 + aa6: 1018 addi a4,sp,32 + aa8: 4685 li a3,1 + aaa: 00163613 seqz a2,a2 + aae: 45c1 li a1,16 + ab0: c43e sw a5,8(sp) + if (radix > 16) + ab2: fa2ff0ef jal 254 + len = mini_pad(bf2, len, pad_char, pad_to, bf); + ab6: 46c2 lw a3,16(sp) + ab8: 4632 lw a2,12(sp) + aba: 85aa mv a1,a0 + abc: 1838 addi a4,sp,56 + abe: bf75 j a7a + ch = (char)(va_arg(va, int)); + ac0: 00448793 addi a5,s1,4 + ac4: c43e sw a5,8(sp) + ac6: 409c lw a5,0(s1) + len = mini_pad(&ch, 1, pad_char, pad_to, bf); + ac8: 46c2 lw a3,16(sp) + aca: 4632 lw a2,12(sp) + ch = (char)(va_arg(va, int)); + acc: 00f10fa3 sb a5,31(sp) + len = mini_pad(&ch, 1, pad_char, pad_to, bf); + ad0: 1838 addi a4,sp,56 + ad2: 4585 li a1,1 + ad4: 01f10513 addi a0,sp,31 + ad8: b755 j a7c + len = puts(ptr, len, buf); + ada: 4612 lw a2,4(sp) + adc: 8526 mv a0,s1 + ade: b765 j a86 + +00000ae0 : +{ + ae0: 1111 addi sp,sp,-28 + ae2: c632 sw a2,12(sp) + int ret_status = mini_vpprintf(__puts_uart, 0, format, args); + ae4: 862a mv a2,a0 + ae6: 6505 lui a0,0x1 +{ + ae8: c42e sw a1,8(sp) + aea: c836 sw a3,16(sp) + int ret_status = mini_vpprintf(__puts_uart, 0, format, args); + aec: 4581 li a1,0 + va_start( args, format ); + aee: 0034 addi a3,sp,8 + int ret_status = mini_vpprintf(__puts_uart, 0, format, args); + af0: 82c50513 addi a0,a0,-2004 # 82c <__puts_uart> +{ + af4: c206 sw ra,4(sp) + af6: ca3a sw a4,20(sp) + af8: cc3e sw a5,24(sp) + va_start( args, format ); + afa: c036 sw a3,0(sp) + int ret_status = mini_vpprintf(__puts_uart, 0, format, args); + afc: 350d jal 91e +} + afe: 4092 lw ra,4(sp) + b00: 0171 addi sp,sp,28 + b02: 8082 ret + +00000b04 : + * error handler + */ +uint8_t ssd1306_i2c_error(uint8_t err) +{ + // report error + printf("ssd1306_i2c_error - timeout waiting for %s\n\r", errstr[err]); + b04: 6789 lui a5,0x2 + b06: 050a slli a0,a0,0x2 + b08: b8c78793 addi a5,a5,-1140 # 1b8c + b0c: 97aa add a5,a5,a0 + b0e: 438c lw a1,0(a5) + b10: 6505 lui a0,0x1 +uint8_t ssd1306_i2c_error(uint8_t err) + b12: 1171 addi sp,sp,-4 + printf("ssd1306_i2c_error - timeout waiting for %s\n\r", errstr[err]); + b14: 68450513 addi a0,a0,1668 # 1684 +uint8_t ssd1306_i2c_error(uint8_t err) + b18: c006 sw ra,0(sp) + printf("ssd1306_i2c_error - timeout waiting for %s\n\r", errstr[err]); + b1a: 37d9 jal ae0 + + // reset & initialize I2C + ssd1306_i2c_setup(); + + return 1; +} + b1c: 4082 lw ra,0(sp) + b1e: 0111 addi sp,sp,4 + ssd1306_i2c_setup(); + b20: ff4ff06f j 314 + +00000b24 : +} +#else +/* + * low-level packet send for blocking polled operation via i2c + */ +uint8_t ssd1306_i2c_send(uint8_t addr, const uint8_t *data, int sz) + b24: 1171 addi sp,sp,-4 +{ + int32_t timeout; + + // wait for not busy + timeout = TIMEOUT_MAX; + b26: 6761 lui a4,0x18 + while((I2C1->STAR2 & I2C_STAR2_BUSY) && (timeout--)); + b28: 400057b7 lui a5,0x40005 +uint8_t ssd1306_i2c_send(uint8_t addr, const uint8_t *data, int sz) + b2c: c006 sw ra,0(sp) + timeout = TIMEOUT_MAX; + b2e: 6a070713 addi a4,a4,1696 # 186a0 + while((I2C1->STAR2 & I2C_STAR2_BUSY) && (timeout--)); + b32: 40078793 addi a5,a5,1024 # 40005400 <_eusrstack+0x20004c00> + b36: 567d li a2,-1 + b38: 0187d683 lhu a3,24(a5) + b3c: 8a89 andi a3,a3,2 + b3e: c6e1 beqz a3,c06 + b40: 177d addi a4,a4,-1 + b42: fec71be3 bne a4,a2,b38 + if(timeout==-1) + return ssd1306_i2c_error(0); + b46: 4501 li a0,0 + b48: a821 j b60 + b4a: 67e1 lui a5,0x18 + b4c: 6a178793 addi a5,a5,1697 # 186a1 + // send data one byte at a time + while(sz--) + { + // wait for TX Empty + timeout = TIMEOUT_MAX; + while(!(I2C1->STAR1 & I2C_STAR1_TXE) && (timeout--)); + b50: 01475683 lhu a3,20(a4) + b54: 0806f693 andi a3,a3,128 + b58: e699 bnez a3,b66 + b5a: 17fd addi a5,a5,-1 + b5c: fbf5 bnez a5,b50 + if(timeout==-1) + return ssd1306_i2c_error(3); + b5e: 450d li a0,3 + return ssd1306_i2c_error(1); + b60: 3755 jal b04 + return ssd1306_i2c_error(0); + b62: 4505 li a0,1 + b64: a889 j bb6 + + // send command + I2C1->DATAR = *data++; + b66: 00054783 lbu a5,0(a0) + b6a: 0505 addi a0,a0,1 + b6c: 00f71823 sh a5,16(a4) + while(sz--) + b70: fca59de3 bne a1,a0,b4a + } + + // wait for tx complete + timeout = TIMEOUT_MAX; + b74: 66e1 lui a3,0x18 + uint32_t status = I2C1->STAR1 | (I2C1->STAR2<<16); + b76: 40005737 lui a4,0x40005 + while((!ssd1306_i2c_chk_evt(SSD1306_I2C_EVENT_MASTER_BYTE_TRANSMITTED)) && (timeout--)); + b7a: 00070637 lui a2,0x70 + timeout = TIMEOUT_MAX; + b7e: 6a068693 addi a3,a3,1696 # 186a0 + uint32_t status = I2C1->STAR1 | (I2C1->STAR2<<16); + b82: 40070713 addi a4,a4,1024 # 40005400 <_eusrstack+0x20004c00> + while((!ssd1306_i2c_chk_evt(SSD1306_I2C_EVENT_MASTER_BYTE_TRANSMITTED)) && (timeout--)); + b86: 08460613 addi a2,a2,132 # 70084 + b8a: 55fd li a1,-1 + uint32_t status = I2C1->STAR1 | (I2C1->STAR2<<16); + b8c: 01475503 lhu a0,20(a4) + b90: 01875783 lhu a5,24(a4) + b94: 07c2 slli a5,a5,0x10 + b96: 8fc9 or a5,a5,a0 + while((!ssd1306_i2c_chk_evt(SSD1306_I2C_EVENT_MASTER_BYTE_TRANSMITTED)) && (timeout--)); + b98: 8ff1 and a5,a5,a2 + b9a: 00c78763 beq a5,a2,ba8 + b9e: 16fd addi a3,a3,-1 + ba0: feb696e3 bne a3,a1,b8c + if(timeout==-1) + return ssd1306_i2c_error(4); + ba4: 4511 li a0,4 + ba6: bf6d j b60 + + // set STOP condition + I2C1->CTLR1 |= I2C_CTLR1_STOP; + ba8: 00075783 lhu a5,0(a4) + + // we're happy + return 0; + bac: 4501 li a0,0 + I2C1->CTLR1 |= I2C_CTLR1_STOP; + bae: 2007e793 ori a5,a5,512 + bb2: 00f71023 sh a5,0(a4) +} + bb6: 4082 lw ra,0(sp) + bb8: 0111 addi sp,sp,4 + bba: 8082 ret + while(!(I2C1->STAR1 & I2C_STAR1_TXE) && (timeout--)); + bbc: 40005737 lui a4,0x40005 + bc0: 95aa add a1,a1,a0 + bc2: 40070713 addi a4,a4,1024 # 40005400 <_eusrstack+0x20004c00> + bc6: b76d j b70 + I2C1->DATAR = addr<<1; + bc8: 07800793 li a5,120 + bcc: 00f71823 sh a5,16(a4) + timeout = TIMEOUT_MAX; + bd0: 6661 lui a2,0x18 + uint32_t status = I2C1->STAR1 | (I2C1->STAR2<<16); + bd2: 400056b7 lui a3,0x40005 + while((!ssd1306_i2c_chk_evt(SSD1306_I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) && (timeout--)); + bd6: 00070737 lui a4,0x70 + timeout = TIMEOUT_MAX; + bda: 6a060613 addi a2,a2,1696 # 186a0 + uint32_t status = I2C1->STAR1 | (I2C1->STAR2<<16); + bde: 40068693 addi a3,a3,1024 # 40005400 <_eusrstack+0x20004c00> + while((!ssd1306_i2c_chk_evt(SSD1306_I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) && (timeout--)); + be2: 08270713 addi a4,a4,130 # 70082 + be6: 537d li t1,-1 + uint32_t status = I2C1->STAR1 | (I2C1->STAR2<<16); + be8: 0146d283 lhu t0,20(a3) + bec: 0186d783 lhu a5,24(a3) + bf0: 07c2 slli a5,a5,0x10 + bf2: 0057e7b3 or a5,a5,t0 + while((!ssd1306_i2c_chk_evt(SSD1306_I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) && (timeout--)); + bf6: 8ff9 and a5,a5,a4 + bf8: fce782e3 beq a5,a4,bbc + bfc: 167d addi a2,a2,-1 + bfe: fe6615e3 bne a2,t1,be8 + return ssd1306_i2c_error(2); + c02: 4509 li a0,2 + c04: bfb1 j b60 + I2C1->CTLR1 |= I2C_CTLR1_START; + c06: 0007d703 lhu a4,0(a5) + timeout = TIMEOUT_MAX; + c0a: 66e1 lui a3,0x18 + while((!ssd1306_i2c_chk_evt(SSD1306_I2C_EVENT_MASTER_MODE_SELECT)) && (timeout--)); + c0c: 00030637 lui a2,0x30 + I2C1->CTLR1 |= I2C_CTLR1_START; + c10: 10076713 ori a4,a4,256 + c14: 00e79023 sh a4,0(a5) + uint32_t status = I2C1->STAR1 | (I2C1->STAR2<<16); + c18: 40005737 lui a4,0x40005 + timeout = TIMEOUT_MAX; + c1c: 6a068693 addi a3,a3,1696 # 186a0 + uint32_t status = I2C1->STAR1 | (I2C1->STAR2<<16); + c20: 40070713 addi a4,a4,1024 # 40005400 <_eusrstack+0x20004c00> + while((!ssd1306_i2c_chk_evt(SSD1306_I2C_EVENT_MASTER_MODE_SELECT)) && (timeout--)); + c24: 0605 addi a2,a2,1 # 30001 + c26: 537d li t1,-1 + uint32_t status = I2C1->STAR1 | (I2C1->STAR2<<16); + c28: 01475283 lhu t0,20(a4) + c2c: 01875783 lhu a5,24(a4) + c30: 07c2 slli a5,a5,0x10 + c32: 0057e7b3 or a5,a5,t0 + while((!ssd1306_i2c_chk_evt(SSD1306_I2C_EVENT_MASTER_MODE_SELECT)) && (timeout--)); + c36: 8ff1 and a5,a5,a2 + c38: f8c788e3 beq a5,a2,bc8 + c3c: 16fd addi a3,a3,-1 + c3e: fe6695e3 bne a3,t1,c28 + return ssd1306_i2c_error(1); + c42: 4505 li a0,1 + c44: bf31 j b60 + +00000c46 : +{ + c46: fd810113 addi sp,sp,-40 + + /* build command or data packets */ + if(cmd) + { + pkt[0] = 0; + pkt[1] = *data; + c4a: 00a100a3 sb a0,1(sp) + else + { + pkt[0] = 0x40; + memcpy(&pkt[1], data, sz); + } + return ssd1306_i2c_send(SSD1306_I2C_ADDR, pkt, sz+1); + c4e: 4589 li a1,2 + c50: 850a mv a0,sp + c52: d206 sw ra,36(sp) + pkt[0] = 0; + c54: 00010023 sb zero,0(sp) + return ssd1306_i2c_send(SSD1306_I2C_ADDR, pkt, sz+1); + c58: 35f1 jal b24 +} + c5a: 5092 lw ra,36(sp) + c5c: 02810113 addi sp,sp,40 + c60: 8082 ret + +00000c62 : +{ + c62: 1131 addi sp,sp,-20 + c64: c806 sw ra,16(sp) + c66: c622 sw s0,12(sp) + b.buffer = buffer; + c68: c02a sw a0,0(sp) + b.pbuffer = buffer; + c6a: c22a sw a0,4(sp) + b.buffer_len = buffer_len; + c6c: c42e sw a1,8(sp) + if(buffer_len == 0) buffer = (void*) 0; + c6e: c19d beqz a1,c94 + int n = mini_vpprintf(_puts, (buffer != (void*)0)?&b:(void*)0, fmt, va); + c70: 00a037b3 snez a5,a0 + c74: 40f007b3 neg a5,a5 + c78: 842a mv s0,a0 + c7a: 00f175b3 and a1,sp,a5 + c7e: 1a800513 li a0,424 + c82: 3971 jal 91e + if(buffer == (void*) 0) { + c84: c401 beqz s0,c8c + return b.pbuffer - b.buffer; + c86: 4512 lw a0,4(sp) + c88: 4782 lw a5,0(sp) + c8a: 8d1d sub a0,a0,a5 +} + c8c: 40c2 lw ra,16(sp) + c8e: 4432 lw s0,12(sp) + c90: 0151 addi sp,sp,20 + c92: 8082 ret + c94: 4401 li s0,0 + int n = mini_vpprintf(_puts, (buffer != (void*)0)?&b:(void*)0, fmt, va); + c96: 4581 li a1,0 + c98: b7dd j c7e + +00000c9a : +{ + c9a: 1131 addi sp,sp,-20 + c9c: c436 sw a3,8(sp) + va_start( args, format ); + c9e: 0034 addi a3,sp,8 +{ + ca0: c206 sw ra,4(sp) + ca2: c63a sw a4,12(sp) + ca4: c83e sw a5,16(sp) + va_start( args, format ); + ca6: c036 sw a3,0(sp) + int ret = mini_vsnprintf( buffer, buffer_len, format, args ); + ca8: 3f6d jal c62 +} + caa: 4092 lw ra,4(sp) + cac: 0151 addi sp,sp,20 + cae: 8082 ret + +00000cb0 : +WEAK void *memset(void *dest, int c, size_t n) { unsigned char *s = dest; for (; n; n--, s++) *s = c; return dest; } + cb0: 962a add a2,a2,a0 + cb2: 87aa mv a5,a0 + cb4: 00c79363 bne a5,a2,cba + cb8: 8082 ret + cba: 00b78023 sb a1,0(a5) + cbe: 0785 addi a5,a5,1 + cc0: bfd5 j cb4 + +00000cc2 : + memset(ssd1306_buffer, color ? 0xFF : 0x00, sizeof(ssd1306_buffer)); + cc2: 40000613 li a2,1024 + cc6: 4581 li a1,0 + cc8: c2818513 addi a0,gp,-984 # 20000024 + ccc: b7d5 j cb0 + +00000cce : + for (; n; n--) *d++ = *s++; + cce: 4781 li a5,0 + cd0: 00f61363 bne a2,a5,cd6 +} + cd4: 8082 ret + for (; n; n--) *d++ = *s++; + cd6: 00f58733 add a4,a1,a5 + cda: 00074683 lbu a3,0(a4) + cde: 00f50733 add a4,a0,a5 + ce2: 0785 addi a5,a5,1 + ce4: 00d70023 sb a3,0(a4) + ce8: b7e5 j cd0 + +00000cea : +{ + cea: 7179 addi sp,sp,-48 + ssd1306_cmd(SSD1306_COLUMNADDR); + cec: 02100513 li a0,33 +{ + cf0: d606 sw ra,44(sp) + cf2: d422 sw s0,40(sp) + cf4: d226 sw s1,36(sp) + ssd1306_cmd(SSD1306_COLUMNADDR); + cf6: 3f81 jal c46 + ssd1306_cmd(SSD1306_OFFSET); // Column start address (0 = reset) + cf8: 4501 li a0,0 + cfa: 37b1 jal c46 + ssd1306_cmd(SSD1306_OFFSET+SSD1306_W-1); // Column end address (127 = reset) + cfc: 07f00513 li a0,127 + d00: 3799 jal c46 + ssd1306_cmd(SSD1306_PAGEADDR); + d02: 02200513 li a0,34 + d06: 3781 jal c46 + ssd1306_cmd(0); // Page start address (0 = reset) + d08: 4501 li a0,0 + d0a: 3f35 jal c46 + ssd1306_cmd(7); // Page end address + d0c: 451d li a0,7 + d0e: c2818413 addi s0,gp,-984 # 20000024 + d12: 3f15 jal c46 + for(i=0;i + return ssd1306_i2c_send(SSD1306_I2C_ADDR, pkt, sz+1); + d2c: 02100593 li a1,33 + d30: 850a mv a0,sp + d32: 02040413 addi s0,s0,32 + d36: 33fd jal b24 + d38: fe9410e3 bne s0,s1,d18 +} + d3c: 50b2 lw ra,44(sp) + d3e: 5422 lw s0,40(sp) + d40: 5492 lw s1,36(sp) + d42: 6145 addi sp,sp,48 + d44: 8082 ret + +00000d46 : +//#define BASE_CTLR (((FUNCONF_HSITRIM) << 3) | HSEBYP | RCC_CSS) // disable HSI in HSE modes + + // Flash latency settings. +#if defined(CH32V003) + #if FUNCONF_SYSTEM_CORE_CLOCK > 25000000 + FLASH->ACTLR = FLASH_ACTLR_LATENCY_1; // +1 Cycle Latency + d46: 400227b7 lui a5,0x40022 + d4a: 4705 li a4,1 + d4c: c398 sw a4,0(a5) +#elif defined(FUNCONF_USE_HSI) && FUNCONF_USE_HSI + #if defined(CH32V30x) || defined(CH32V20x) || defined(CH32L103) || defined(CH32V10x) + EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE; + #endif + #if defined(FUNCONF_USE_PLL) && FUNCONF_USE_PLL + RCC->CFGR0 = BASE_CFGR0; + d4e: 400217b7 lui a5,0x40021 + RCC->CTLR = BASE_CTLR | RCC_HSION | RCC_PLLON; // Use HSI, enable PLL. + d52: 01080737 lui a4,0x1080 + RCC->CFGR0 = BASE_CFGR0; + d56: 0007a223 sw zero,4(a5) # 40021004 <_eusrstack+0x20020804> + RCC->CTLR = BASE_CTLR | RCC_HSION | RCC_PLLON; // Use HSI, enable PLL. + d5a: 08170713 addi a4,a4,129 # 1080081 + d5e: c398 sw a4,0(a5) + FLASH->ACTLR = FLASH_ACTLR_LATENCY_0; + #endif +#endif + +#ifndef CH5xx + RCC->INTR = 0x009F0000; // Clear PLL, CSSC, HSE, HSI and LSI ready flags. + d60: 009f0737 lui a4,0x9f0 + d64: c798 sw a4,8(a5) +#endif + +#if defined(FUNCONF_USE_PLL) && FUNCONF_USE_PLL && !defined(CH5xx) + while((RCC->CTLR & RCC_PLLRDY) == 0) {}; // Wait till PLL is ready + d66: 4398 lw a4,0(a5) + d68: 00671693 slli a3,a4,0x6 + d6c: fe06dde3 bgez a3,d66 + #if defined(CH32H41x) + RCC->PLLCFGR |= RCC_SYSPLL_GATE; + #endif + uint32_t tmp32 = RCC->CFGR0 & ~(0x03); // clr the SW + d70: 43d8 lw a4,4(a5) + RCC->CFGR0 = tmp32 | RCC_SW_PLL; // Select PLL as system clock source + while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08); // Wait till PLL is used as system clock source + d72: 400216b7 lui a3,0x40021 + uint32_t tmp32 = RCC->CFGR0 & ~(0x03); // clr the SW + d76: 9b71 andi a4,a4,-4 + RCC->CFGR0 = tmp32 | RCC_SW_PLL; // Select PLL as system clock source + d78: 00276713 ori a4,a4,2 + d7c: c3d8 sw a4,4(a5) + while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08); // Wait till PLL is used as system clock source + d7e: 4721 li a4,8 + d80: 42dc lw a5,4(a3) + d82: 8bb1 andi a5,a5,12 + d84: fee79ee3 bne a5,a4,d80 + *DMDATA1 = 0x00; + d88: e00007b7 lui a5,0xe0000 + d8c: 0e07ac23 sw zero,248(a5) # e00000f8 <_eusrstack+0xbffff8f8> + *DMDATA0 = 0x80; + d90: 08000713 li a4,128 + d94: 0ee7aa23 sw a4,244(a5) + SetupDebugPrintf(); +#endif +#if defined(FUNCONF_SUPPORT_CONSTRUCTORS) && FUNCONF_SUPPORT_CONSTRUCTORS + CallConstructors(); +#endif +} + d98: 8082 ret + +00000d9a
: + } +} + +// ----------------------------------------------------------------- main +int main(void) +{ + d9a: 7139 addi sp,sp,-64 + d9c: de06 sw ra,60(sp) + d9e: dc22 sw s0,56(sp) + da0: da26 sw s1,52(sp) + SystemInit(); + da2: 3755 jal d46 + funGpioInitAll(); + da4: 400214b7 lui s1,0x40021 + da8: 4c9c lw a5,24(s1) + funPinMode(LED_PIN, GPIO_Speed_10MHz | GPIO_CNF_OUT_PP); + daa: 40011437 lui s0,0x40011 + funPinMode(BUZZER, GPIO_Speed_10MHz | GPIO_CNF_OUT_PP); + dae: 76fd lui a3,0xfffff + funGpioInitAll(); + db0: 0357e793 ori a5,a5,53 + db4: cc9c sw a5,24(s1) + funPinMode(LED_PIN, GPIO_Speed_10MHz | GPIO_CNF_OUT_PP); + db6: 80040793 addi a5,s0,-2048 # 40010800 <_eusrstack+0x20010000> + dba: 4398 lw a4,0(a5) + funPinMode(BUZZER, GPIO_Speed_10MHz | GPIO_CNF_OUT_PP); + dbc: 0ff68693 addi a3,a3,255 # fffff0ff <_eusrstack+0xdfffe8ff> + funPinMode(BTN_LEFT, GPIO_CNF_IN_PUPD); + dc0: f1000637 lui a2,0xf1000 + funPinMode(LED_PIN, GPIO_Speed_10MHz | GPIO_CNF_OUT_PP); + dc4: f0f77713 andi a4,a4,-241 + dc8: 01076713 ori a4,a4,16 + dcc: c398 sw a4,0(a5) + funDigitalWrite(LED_PIN, FUN_LOW); + dce: 00020737 lui a4,0x20 + dd2: cb98 sw a4,16(a5) + funPinMode(BUZZER, GPIO_Speed_10MHz | GPIO_CNF_OUT_PP); + dd4: 40040793 addi a5,s0,1024 + dd8: 4398 lw a4,0(a5) + funPinMode(BTN_LEFT, GPIO_CNF_IN_PUPD); + dda: 167d addi a2,a2,-1 # f0ffffff <_eusrstack+0xd0fff7ff> + gpio_setup(); + + Delay_Ms(120); // let the OLED rail settle + ddc: 000b0537 lui a0,0xb0 + funPinMode(BUZZER, GPIO_Speed_10MHz | GPIO_CNF_OUT_PP); + de0: 8f75 and a4,a4,a3 + de2: 10076713 ori a4,a4,256 + de6: c398 sw a4,0(a5) + funDigitalWrite(BUZZER, FUN_LOW); + de8: 00040737 lui a4,0x40 + dec: cb98 sw a4,16(a5) + funPinMode(BTN_OK, GPIO_CNF_IN_PUPD); + dee: 4018 lw a4,0(s0) + Delay_Ms(120); // let the OLED rail settle + df0: c8050513 addi a0,a0,-896 # afc80 + funPinMode(BTN_OK, GPIO_CNF_IN_PUPD); + df4: 9b41 andi a4,a4,-16 + df6: 00876713 ori a4,a4,8 + dfa: c018 sw a4,0(s0) + funPinMode(BTN_LEFT, GPIO_CNF_IN_PUPD); + dfc: 4398 lw a4,0(a5) + dfe: 8f71 and a4,a4,a2 + e00: 08000637 lui a2,0x8000 + e04: 8f51 or a4,a4,a2 + e06: c398 sw a4,0(a5) + funPinMode(BTN_RIGHT, GPIO_CNF_IN_PUPD); + e08: 4398 lw a4,0(a5) + e0a: ff100637 lui a2,0xff100 + e0e: 167d addi a2,a2,-1 # ff0fffff <_eusrstack+0xdf0ff7ff> + e10: 8f71 and a4,a4,a2 + e12: 00800637 lui a2,0x800 + e16: 8f51 or a4,a4,a2 + e18: c398 sw a4,0(a5) + funDigitalWrite(BTN_OK, FUN_HIGH); + e1a: 4705 li a4,1 + e1c: c818 sw a4,16(s0) + funDigitalWrite(BTN_LEFT, FUN_HIGH); + e1e: 04000713 li a4,64 + e22: cb98 sw a4,16(a5) + funDigitalWrite(BTN_RIGHT, FUN_HIGH); + e24: 02000713 li a4,32 + e28: cb98 sw a4,16(a5) + Delay_Ms(120); // let the OLED rail settle + e2a: c18ff0ef jal 242 + * init I2C and GPIO + */ +uint8_t ssd1306_i2c_init(void) +{ + // Enable GPIOC and I2C + RCC->APB1PCENR |= RCC_APB1Periph_I2C1; + e2e: 4cdc lw a5,28(s1) + e30: 00200737 lui a4,0x200 + e34: 8fd9 or a5,a5,a4 + e36: ccdc sw a5,28(s1) + funPinMode( PB6, GPIO_CFGLR_OUT_10Mhz_AF_OD ); + funPinMode( PB7, GPIO_CFGLR_OUT_10Mhz_AF_OD ); +#endif + +#else + RCC->APB2PCENR |= RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO; + e38: 4c9c lw a5,24(s1) + // PC1 is SDA, 10MHz Output, alt func, open-drain + GPIOC->CFGLR &= ~(0xf<<(4*1)); + GPIOC->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_OD_AF)<<(4*1); + + // PC2 is SCL, 10MHz Output, alt func, open-drain + GPIOC->CFGLR &= ~(0xf<<(4*2)); + e3a: 777d lui a4,0xfffff + e3c: 0ff70693 addi a3,a4,255 # fffff0ff <_eusrstack+0xdfffe8ff> + RCC->APB2PCENR |= RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO; + e40: 0117e793 ori a5,a5,17 + e44: cc9c sw a5,24(s1) + GPIOC->CFGLR &= ~(0xf<<(4*1)); + e46: 401c lw a5,0(s0) + GPIOC->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_OD_AF)<<(4*2); + e48: 6705 lui a4,0x1 + e4a: d0070713 addi a4,a4,-768 # d00 + GPIOC->CFGLR &= ~(0xf<<(4*1)); + e4e: f0f7f793 andi a5,a5,-241 + e52: c01c sw a5,0(s0) + GPIOC->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_OD_AF)<<(4*1); + e54: 401c lw a5,0(s0) + e56: 0d07e793 ori a5,a5,208 + e5a: c01c sw a5,0(s0) + GPIOC->CFGLR &= ~(0xf<<(4*2)); + e5c: 401c lw a5,0(s0) + e5e: 8ff5 and a5,a5,a3 + e60: c01c sw a5,0(s0) + GPIOC->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_OD_AF)<<(4*2); + e62: 401c lw a5,0(s0) + e64: 8fd9 or a5,a5,a4 + e66: c01c sw a5,0(s0) + + ssd1306_setbuf(0); + + // initialize OLED +#if !defined(SSD1306_CUSTOM_INIT_ARRAY) || !SSD1306_CUSTOM_INIT_ARRAY + uint8_t *cmd_list = (uint8_t *)ssd1306_init_array; + e68: 6409 lui s0,0x2 + GPIOC->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*4); + GPIOC->BSHR = (1<<(16+4)); +#endif + + // load I2C regs + ssd1306_i2c_setup(); + e6a: caaff0ef jal 314 + e6e: 3a040413 addi s0,s0,928 # 23a0 + ssd1306_setbuf(0); + e72: 3d81 jal cc2 + while(*cmd_list != SSD1306_TERMINATE_CMDS) + e74: 00044503 lbu a0,0(s0) + e78: 0ff00793 li a5,255 + e7c: 00f51463 bne a0,a5,e84 + { + if(ssd1306_cmd(*cmd_list++)) + return 1; + } + + ssd1306_refresh(); + e80: 35ad jal cea +#endif + + return 0; + e82: a021 j e8a + if(ssd1306_cmd(*cmd_list++)) + e84: 0405 addi s0,s0,1 + e86: 33c1 jal c46 + e88: d575 beqz a0,e74 + // no display: fall back to a heartbeat blink so the board still shows life + while (1) { led_blink(); Delay_Ms(700); } + } + ssd1306_init(); + + pet_reset(); + e8a: dacff0ef jal 436 + ssd1306_setbuf(0); + e8e: 3d15 jal cc2 + draw_center_str(4, "PANAGOTCHI"); + e90: 6585 lui a1,0x1 + e92: 6b858593 addi a1,a1,1720 # 16b8 + e96: 4511 li a0,4 + e98: e78ff0ef jal 510 + ssd1306_drawImage(48, 16, pana_idle, PANA_W, PANA_H, 0); + e9c: 02000713 li a4,32 + ea0: 6609 lui a2,0x2 + ea2: 86ba mv a3,a4 + ea4: 3bc60613 addi a2,a2,956 # 23bc + ea8: 45c1 li a1,16 + eaa: 03000513 li a0,48 + eae: fd0ff0ef jal 67e + draw_center_str(52, "press any key"); + eb2: 6585 lui a1,0x1 + eb4: 6c458593 addi a1,a1,1732 # 16c4 + eb8: 03400513 li a0,52 + ebc: e54ff0ef jal 510 + ssd1306_refresh(); + ec0: 352d jal cea + beep(659, 80); beep(784, 80); beep(988, 120); + ec2: 05000593 li a1,80 + ec6: 29300513 li a0,659 + eca: cdaff0ef jal 3a4 + ece: 05000593 li a1,80 + ed2: 31000513 li a0,784 + ed6: cceff0ef jal 3a4 + eda: 07800593 li a1,120 + ede: 3dc00513 li a0,988 + ee2: cc2ff0ef jal 3a4 + ee6: 0c800413 li s0,200 + Buttons b = read_buttons(); + eea: d7cff0ef jal 466 + eee: 00855713 srli a4,a0,0x8 + ef2: 01055793 srli a5,a0,0x10 + ef6: 02e100a3 sb a4,33(sp) + if (b.ok || b.left || b.right) break; + efa: 8f49 or a4,a4,a0 + Buttons b = read_buttons(); + efc: 02f10123 sb a5,34(sp) + if (b.ok || b.left || b.right) break; + f00: 8fd9 or a5,a5,a4 + Buttons b = read_buttons(); + f02: 02a10023 sb a0,32(sp) + if (b.ok || b.left || b.right) break; + f06: 0ff7f793 zext.b a5,a5 + f0a: eb81 bnez a5,f1a + Delay_Ms(20); + f0c: 6575 lui a0,0x1d + f0e: 4c050513 addi a0,a0,1216 # 1d4c0 + for (int i = 0; i < 200; i++) { + f12: 147d addi s0,s0,-1 + Delay_Ms(20); + f14: b2eff0ef jal 242 + for (int i = 0; i < 200; i++) { + f18: f869 bnez s0,eea + beep(659, 80); beep(784, 80); beep(988, 120); + f1a: 4701 li a4,0 + f1c: 4481 li s1,0 + f1e: 4401 li s0,0 + f20: c03a sw a4,0(sp) + splash(); + + Buttons prev = {0, 0, 0}; + + while (1) { + Buttons b = read_buttons(); + f22: d44ff0ef jal 466 + f26: 01055793 srli a5,a0,0x10 + f2a: 0ff57713 zext.b a4,a0 + f2e: c23a sw a4,4(sp) + f30: 00f10f23 sb a5,30(sp) + f34: 0ff7f793 zext.b a5,a5 + f38: 00855693 srli a3,a0,0x8 + f3c: c63e sw a5,12(sp) + uint8_t ok_edge = b.ok && !prev.ok; + f3e: 4792 lw a5,4(sp) + Buttons b = read_buttons(); + f40: 0ff6f713 zext.b a4,a3 + f44: 00d10ea3 sb a3,29(sp) + f48: c43a sw a4,8(sp) + f4a: 00a10e23 sb a0,28(sp) + uint8_t ok_edge = b.ok && !prev.ok; + f4e: 4702 lw a4,0(sp) + f50: 4681 li a3,0 + f52: c399 beqz a5,f58 + f54: 00143693 seqz a3,s0 + uint8_t left_edge = b.left && !prev.left; + f58: 4622 lw a2,8(sp) + f5a: 4781 li a5,0 + f5c: c219 beqz a2,f62 + f5e: 0014b793 seqz a5,s1 + uint8_t right_edge = b.right && !prev.right; + f62: 45b2 lw a1,12(sp) + f64: 4601 li a2,0 + f66: c199 beqz a1,f6c + f68: 00173613 seqz a2,a4 + prev = b; + + switch (screen) { + f6c: c181c583 lbu a1,-1000(gp) # 20000014 + f70: c1c18493 addi s1,gp,-996 # 20000018 + f74: c02e sw a1,0(sp) + f76: 4502 lw a0,0(sp) + f78: 4585 li a1,1 + f7a: 40b50163 beq a0,a1,137c + f7e: 4589 li a1,2 + f80: 4ab50463 beq a0,a1,1428 + f84: 1c051d63 bnez a0,115e + case SCR_MAIN: + if (left_edge) { + f88: c395 beqz a5,fac + cursor = (cursor + ICON_COUNT - 1) % ICON_COUNT; + f8a: c171c503 lbu a0,-1001(gp) # 20000013 + f8e: 4599 li a1,6 + f90: ca32 sw a2,20(sp) + f92: 0515 addi a0,a0,5 + f94: c836 sw a3,16(sp) + f96: 962ff0ef jal f8 <__modsi3> + f9a: c0a18ba3 sb a0,-1001(gp) # 20000013 + beep(1047, 25); + f9e: 45e5 li a1,25 + fa0: 41700513 li a0,1047 + fa4: c00ff0ef jal 3a4 + fa8: 4652 lw a2,20(sp) + faa: 46c2 lw a3,16(sp) + } + if (right_edge) { + fac: c205 beqz a2,fcc + cursor = (cursor + 1) % ICON_COUNT; + fae: c171c503 lbu a0,-1001(gp) # 20000013 + fb2: 4599 li a1,6 + fb4: c836 sw a3,16(sp) + fb6: 0505 addi a0,a0,1 + fb8: 940ff0ef jal f8 <__modsi3> + fbc: c0a18ba3 sb a0,-1001(gp) # 20000013 + beep(1047, 25); + fc0: 45e5 li a1,25 + fc2: 41700513 li a0,1047 + fc6: bdeff0ef jal 3a4 + fca: 46c2 lw a3,16(sp) + } + if (ok_edge) do_action(cursor); + fcc: c6ad beqz a3,1036 + switch (act) { + fce: c171c783 lbu a5,-1001(gp) # 20000013 + fd2: 4695 li a3,5 + fd4: 06f6e163 bltu a3,a5,1036 + fd8: 6685 lui a3,0x1 + fda: 078a slli a5,a5,0x2 + fdc: 7b468693 addi a3,a3,1972 # 17b4 + fe0: 97b6 add a5,a5,a3 + fe2: 439c lw a5,0(a5) + fe4: 8782 jr a5 + pet.satiety = clamp100(pet.satiety + 30); + fe6: 00048783 lb a5,0(s1) # 40021000 <_eusrstack+0x20020800> +static int8_t clamp100(int v) { return v < 0 ? 0 : (v > 100 ? 100 : v); } + fea: 06400713 li a4,100 + pet.satiety = clamp100(pet.satiety + 30); + fee: 07f9 addi a5,a5,30 +static int8_t clamp100(int v) { return v < 0 ? 0 : (v > 100 ? 100 : v); } + ff0: 1af75a63 bge a4,a5,11a4 + ff4: 87ba mv a5,a4 + ff6: 00f48023 sb a5,0(s1) + pet.hygiene = clamp100(pet.hygiene - 5); + ffa: 00348783 lb a5,3(s1) +static int8_t clamp100(int v) { return v < 0 ? 0 : (v > 100 ? 100 : v); } + ffe: 06400713 li a4,100 + pet.hygiene = clamp100(pet.hygiene - 5); + 1002: 17ed addi a5,a5,-5 +static int8_t clamp100(int v) { return v < 0 ? 0 : (v > 100 ? 100 : v); } + 1004: 1af75563 bge a4,a5,11ae + 1008: 87ba mv a5,a4 + 100a: 00f481a3 sb a5,3(s1) +static void react(uint8_t exp) { anim_exp = exp; anim_timer = ANIM_FRAMES; } + 100e: 4711 li a4,4 + 1010: c0e18623 sb a4,-1012(gp) # 20000008 + beep(880, 60); beep(1175, 80); + 1014: 03c00593 li a1,60 +static void react(uint8_t exp) { anim_exp = exp; anim_timer = ANIM_FRAMES; } + 1018: 4731 li a4,12 + beep(880, 60); beep(1175, 80); + 101a: 37000513 li a0,880 +static void react(uint8_t exp) { anim_exp = exp; anim_timer = ANIM_FRAMES; } + 101e: c0e18b23 sb a4,-1002(gp) # 20000012 + beep(880, 60); beep(1175, 80); + 1022: b82ff0ef jal 3a4 + 1026: 05000593 li a1,80 + 102a: 49700513 li a0,1175 + beep(988, 60); beep(1319, 60); beep(1568, 90); + 102e: b76ff0ef jal 3a4 + led_blink(); + 1032: bdaff0ef jal 40c + ssd1306_setbuf(0); + 1036: 3171 jal cc2 + draw_center_str(0, menu_labels[cursor]); + 1038: c171c783 lbu a5,-1001(gp) # 20000013 + 103c: 4501 li a0,0 + 103e: c83e sw a5,16(sp) + 1040: 4742 lw a4,16(sp) + 1042: 6789 lui a5,0x2 + 1044: 47078793 addi a5,a5,1136 # 2470 + 1048: 070a slli a4,a4,0x2 + 104a: 97ba add a5,a5,a4 + 104c: 438c lw a1,0(a5) + 104e: cc2ff0ef jal 510 + if (pet.alive && pet.health < 30 && (frame & 8)) + 1052: 00a4c783 lbu a5,10(s1) + 1056: ca3e sw a5,20(sp) + 1058: c38d beqz a5,107a + 105a: 00448703 lb a4,4(s1) + 105e: 47f5 li a5,29 + 1060: 00e7cd63 blt a5,a4,107a + 1064: c101a783 lw a5,-1008(gp) # 2000000c + 1068: 8ba1 andi a5,a5,8 + 106a: cb81 beqz a5,107a + ssd1306_drawstr(0, 0, "!", 1); + 106c: 6605 lui a2,0x1 + 106e: 6d460613 addi a2,a2,1748 # 16d4 + 1072: 4581 li a1,0 + 1074: 4501 li a0,0 + 1076: c22ff0ef jal 498 + beep(pet.sleeping ? 440 : 660, 120); + 107a: 4401 li s0,0 + 107c: 8522 mv a0,s0 + ssd1306_drawPixel(x++, y, color); + 107e: 4605 li a2,1 + 1080: 45a9 li a1,10 + 1082: ae6ff0ef jal 368 + 1086: 0405 addi s0,s0,1 + while (w--) + 1088: 08000793 li a5,128 + 108c: fef418e3 bne s0,a5,107c + if (pet.sleeping) { + 1090: 0094c403 lbu s0,9(s1) + 1094: 24040763 beqz s0,12e2 + ssd1306_drawstr(px + PANA_W - 2, 14, "z", 1); + 1098: 6605 lui a2,0x1 + 109a: 6d860613 addi a2,a2,1752 # 16d8 + 109e: 45b9 li a1,14 + 10a0: 04e00513 li a0,78 + 10a4: bf4ff0ef jal 498 + ssd1306_drawstr(px + PANA_W + 4, 12, "Z", 1); + 10a8: 6605 lui a2,0x1 + 10aa: 6dc60613 addi a2,a2,1756 # 16dc + 10ae: 45b1 li a1,12 + 10b0: 05400513 li a0,84 + 10b4: be4ff0ef jal 498 + 10b8: 03000313 li t1,48 + px = 48; py = 16; + 10bc: 42c1 li t0,16 + if (!pet.alive) return EXP_DEAD; + 10be: 4752 lw a4,20(sp) + 10c0: 4799 li a5,6 + 10c2: c719 beqz a4,10d0 + if (anim_timer) return anim_exp; + 10c4: c161c783 lbu a5,-1002(gp) # 20000012 + 10c8: 24078663 beqz a5,1314 + 10cc: c0c1c783 lbu a5,-1012(gp) # 20000008 + ssd1306_drawImage(px, py, pana_frames[current_expression()], + 10d0: 6709 lui a4,0x2 + 10d2: 45470713 addi a4,a4,1108 # 2454 + 10d6: 078a slli a5,a5,0x2 + 10d8: 97ba add a5,a5,a4 + 10da: 4390 lw a2,0(a5) + 10dc: 02000713 li a4,32 + 10e0: 86ba mv a3,a4 + 10e2: 8596 mv a1,t0 + 10e4: 851a mv a0,t1 + 10e6: d98ff0ef jal 67e + 10ea: 4401 li s0,0 + 10ec: 8522 mv a0,s0 + ssd1306_drawPixel(x++, y, color); + 10ee: 4605 li a2,1 + 10f0: 02e00593 li a1,46 + 10f4: a74ff0ef jal 368 + 10f8: 0405 addi s0,s0,1 + while (w--) + 10fa: 08000793 li a5,128 + 10fe: fef417e3 bne s0,a5,10ec + for (uint8_t i = 0; i < pet.poop; i++) + 1102: 0084c783 lbu a5,8(s1) + 1106: 4702 lw a4,0(sp) + 1108: 24f76663 bltu a4,a5,1354 + 110c: 4401 li s0,0 + ssd1306_drawImage(x, 48, menu_icons[i], ICON_W, ICON_H, 0); + 110e: 00241793 slli a5,s0,0x2 + 1112: 00878733 add a4,a5,s0 + 1116: 070a slli a4,a4,0x2 + 1118: 00870333 add t1,a4,s0 + 111c: 6709 lui a4,0x2 + 111e: 43c70713 addi a4,a4,1084 # 243c + 1122: 97ba add a5,a5,a4 + 1124: 4390 lw a2,0(a5) + 1126: 4741 li a4,16 + 1128: 86ba mv a3,a4 + 112a: 00330513 addi a0,t1,3 + 112e: 03000593 li a1,48 + 1132: c01a sw t1,0(sp) + 1134: d4aff0ef jal 67e + if (i == cursor) + 1138: 4742 lw a4,16(sp) + 113a: 0ff47793 zext.b a5,s0 + 113e: 4302 lw t1,0(sp) + 1140: 00f71a63 bne a4,a5,1154 + ssd1306_drawRect(x - 2, 46, ICON_W + 3, ICON_H + 2, 1); + 1144: 46c9 li a3,18 + 1146: 464d li a2,19 + 1148: 02e00593 li a1,46 + 114c: 00130513 addi a0,t1,1 + 1150: c74ff0ef jal 5c4 + for (uint8_t i = 0; i < ICON_COUNT; i++) { + 1154: 0405 addi s0,s0,1 + 1156: 4799 li a5,6 + 1158: faf41be3 bne s0,a5,110e + ssd1306_refresh(); + 115c: 3679 jal cea + } + draw_dead(); + break; + } + + if (anim_timer) anim_timer--; + 115e: c161c783 lbu a5,-1002(gp) # 20000012 + 1162: c781 beqz a5,116a + 1164: 17fd addi a5,a5,-1 + 1166: c0f18b23 sb a5,-1002(gp) # 20000012 + + // advance game time independent of which screen is showing + if (pet.alive && ++tick_acc >= TICK_FRAMES) { + 116a: 00a4c783 lbu a5,10(s1) + 116e: cf81 beqz a5,1186 + 1170: c141d783 lhu a5,-1004(gp) # 20000010 + 1174: 03100693 li a3,49 + 1178: 0785 addi a5,a5,1 + 117a: 07c2 slli a5,a5,0x10 + 117c: 83c1 srli a5,a5,0x10 + 117e: 30f6e763 bltu a3,a5,148c + 1182: c0f19a23 sh a5,-1004(gp) # 20000010 + tick_acc = 0; + game_tick(); + } + + frame++; + 1186: c101a783 lw a5,-1008(gp) # 2000000c + Delay_Ms(FRAME_MS); + 118a: 00058537 lui a0,0x58 + 118e: e4050513 addi a0,a0,-448 # 57e40 + frame++; + 1192: 0785 addi a5,a5,1 + 1194: c0f1a823 sw a5,-1008(gp) # 2000000c + Delay_Ms(FRAME_MS); + 1198: 8aaff0ef jal 242 + prev = b; + 119c: 4732 lw a4,12(sp) + 119e: 44a2 lw s1,8(sp) + 11a0: 4412 lw s0,4(sp) + while (1) { + 11a2: bbbd j f20 +static int8_t clamp100(int v) { return v < 0 ? 0 : (v > 100 ? 100 : v); } + 11a4: fff7c713 not a4,a5 + 11a8: 877d srai a4,a4,0x1f + 11aa: 8ff9 and a5,a5,a4 + 11ac: b5a9 j ff6 + 11ae: fff7c713 not a4,a5 + 11b2: 877d srai a4,a4,0x1f + 11b4: 8ff9 and a5,a5,a4 + 11b6: bd91 j 100a + if (pet.energy < 15) { beep(220, 120); break; } // too tired + 11b8: 00248703 lb a4,2(s1) + 11bc: 47b9 li a5,14 + 11be: 00e7c963 blt a5,a4,11d0 + 11c2: 07800593 li a1,120 + 11c6: 0dc00513 li a0,220 + beep(659, 40); + 11ca: 9daff0ef jal 3a4 + break; + 11ce: b5a5 j 1036 + pet.happy = clamp100(pet.happy + 25); + 11d0: 00148783 lb a5,1(s1) +static int8_t clamp100(int v) { return v < 0 ? 0 : (v > 100 ? 100 : v); } + 11d4: 06400693 li a3,100 + pet.happy = clamp100(pet.happy + 25); + 11d8: 07e5 addi a5,a5,25 +static int8_t clamp100(int v) { return v < 0 ? 0 : (v > 100 ? 100 : v); } + 11da: 04f6d563 bge a3,a5,1224 + 11de: 87b6 mv a5,a3 + 11e0: 00f480a3 sb a5,1(s1) + pet.energy = clamp100(pet.energy - 12); + 11e4: ff470793 addi a5,a4,-12 +static int8_t clamp100(int v) { return v < 0 ? 0 : (v > 100 ? 100 : v); } + 11e8: 06400713 li a4,100 + 11ec: 00f75363 bge a4,a5,11f2 + 11f0: 87ba mv a5,a4 + 11f2: 00f48123 sb a5,2(s1) +static void react(uint8_t exp) { anim_exp = exp; anim_timer = ANIM_FRAMES; } + 11f6: 4709 li a4,2 + 11f8: c0e18623 sb a4,-1012(gp) # 20000008 + beep(988, 60); beep(1319, 60); beep(1568, 90); + 11fc: 03c00593 li a1,60 +static void react(uint8_t exp) { anim_exp = exp; anim_timer = ANIM_FRAMES; } + 1200: 4731 li a4,12 + beep(988, 60); beep(1319, 60); beep(1568, 90); + 1202: 3dc00513 li a0,988 +static void react(uint8_t exp) { anim_exp = exp; anim_timer = ANIM_FRAMES; } + 1206: c0e18b23 sb a4,-1002(gp) # 20000012 + beep(988, 60); beep(1319, 60); beep(1568, 90); + 120a: 99aff0ef jal 3a4 + 120e: 03c00593 li a1,60 + 1212: 52700513 li a0,1319 + 1216: 98eff0ef jal 3a4 + 121a: 05a00593 li a1,90 + 121e: 62000513 li a0,1568 + 1222: b531 j 102e +static int8_t clamp100(int v) { return v < 0 ? 0 : (v > 100 ? 100 : v); } + 1224: fff7c693 not a3,a5 + 1228: 86fd srai a3,a3,0x1f + 122a: 8ff5 and a5,a5,a3 + 122c: bf55 j 11e0 + pet.sleeping = !pet.sleeping; + 122e: 0094c503 lbu a0,9(s1) + beep(pet.sleeping ? 440 : 660, 120); + 1232: 07800593 li a1,120 + pet.sleeping = !pet.sleeping; + 1236: 00153793 seqz a5,a0 + beep(pet.sleeping ? 440 : 660, 120); + 123a: 00a03533 snez a0,a0 + 123e: 40a00533 neg a0,a0 + 1242: 0dc57513 andi a0,a0,220 + pet.sleeping = !pet.sleeping; + 1246: 00f484a3 sb a5,9(s1) + beep(pet.sleeping ? 440 : 660, 120); + 124a: 1b850513 addi a0,a0,440 + 124e: bfb5 j 11ca + pet.happy = clamp100(pet.happy + 5); + 1250: c1c18693 addi a3,gp,-996 # 20000018 + 1254: 00148783 lb a5,1(s1) + pet.hygiene = 100; + 1258: 06400713 li a4,100 + pet.poop = 0; + 125c: 00048423 sb zero,8(s1) + pet.hygiene = 100; + 1260: 00e481a3 sb a4,3(s1) + pet.happy = clamp100(pet.happy + 5); + 1264: 0795 addi a5,a5,5 +static int8_t clamp100(int v) { return v < 0 ? 0 : (v > 100 ? 100 : v); } + 1266: 02f75063 bge a4,a5,1286 + 126a: 87ba mv a5,a4 + beep(1319, 50); beep(1047, 50); + 126c: 03200593 li a1,50 + 1270: 52700513 li a0,1319 +static int8_t clamp100(int v) { return v < 0 ? 0 : (v > 100 ? 100 : v); } + 1274: 00f680a3 sb a5,1(a3) + beep(1319, 50); beep(1047, 50); + 1278: 92cff0ef jal 3a4 + 127c: 03200593 li a1,50 + 1280: 41700513 li a0,1047 + 1284: b799 j 11ca +static int8_t clamp100(int v) { return v < 0 ? 0 : (v > 100 ? 100 : v); } + 1286: fff7c713 not a4,a5 + 128a: 877d srai a4,a4,0x1f + 128c: 8ff9 and a5,a5,a4 + 128e: bff9 j 126c + pet.health = clamp100(pet.health + 35); + 1290: 00448783 lb a5,4(s1) +static int8_t clamp100(int v) { return v < 0 ? 0 : (v > 100 ? 100 : v); } + 1294: 06400713 li a4,100 + pet.health = clamp100(pet.health + 35); + 1298: 02378793 addi a5,a5,35 +static int8_t clamp100(int v) { return v < 0 ? 0 : (v > 100 ? 100 : v); } + 129c: 02f75663 bge a4,a5,12c8 + 12a0: 87ba mv a5,a4 + beep(784, 60); beep(1047, 60); beep(1319, 90); + 12a2: 03c00593 li a1,60 + 12a6: 31000513 li a0,784 +static int8_t clamp100(int v) { return v < 0 ? 0 : (v > 100 ? 100 : v); } + 12aa: 00f48223 sb a5,4(s1) + beep(784, 60); beep(1047, 60); beep(1319, 90); + 12ae: 8f6ff0ef jal 3a4 + 12b2: 03c00593 li a1,60 + 12b6: 41700513 li a0,1047 + 12ba: 8eaff0ef jal 3a4 + 12be: 05a00593 li a1,90 + 12c2: 52700513 li a0,1319 + 12c6: b3a5 j 102e +static int8_t clamp100(int v) { return v < 0 ? 0 : (v > 100 ? 100 : v); } + 12c8: fff7c713 not a4,a5 + 12cc: 877d srai a4,a4,0x1f + 12ce: 8ff9 and a5,a5,a4 + 12d0: bfc9 j 12a2 + screen = SCR_STATS; + 12d2: 4785 li a5,1 + 12d4: c0f18c23 sb a5,-1000(gp) # 20000014 + beep(659, 40); + 12d8: 02800593 li a1,40 + 12dc: 29300513 li a0,659 + 12e0: b5ed j 11ca + uint32_t t = frame % 80; + 12e2: c101a283 lw t0,-1008(gp) # 2000000c + 12e6: 05000593 li a1,80 + 12ea: 8516 mv a0,t0 + 12ec: cc16 sw t0,24(sp) + 12ee: de7fe0ef jal d4 <__umodsi3> + px = (t < 40) ? 30 + t : 30 + (80 - t); // 30..70..30 + 12f2: 02700793 li a5,39 + 12f6: 42e2 lw t0,24(sp) + 12f8: 01e50313 addi t1,a0,30 + 12fc: 00a7f663 bgeu a5,a0,1308 + 1300: 06e00793 li a5,110 + 1304: 40a78333 sub t1,a5,a0 + py = 14 + ((frame % 16) < 8 ? 0 : 1); + 1308: 0082f293 andi t0,t0,8 + 130c: 005032b3 snez t0,t0 + 1310: 02b9 addi t0,t0,14 + 1312: b375 j 10be + if (pet.sleeping) return EXP_SLEEP; + 1314: 4795 li a5,5 + 1316: da041de3 bnez s0,10d0 + if (pet.health < 30 || pet.happy < 25 || pet.satiety < 20) + 131a: 00448683 lb a3,4(s1) + 131e: 4775 li a4,29 + return EXP_SAD; + 1320: 478d li a5,3 + if (pet.health < 30 || pet.happy < 25 || pet.satiety < 20) + 1322: dad757e3 bge a4,a3,10d0 + 1326: 00148683 lb a3,1(s1) + 132a: 4761 li a4,24 + 132c: dad752e3 bge a4,a3,10d0 + 1330: 00048683 lb a3,0(s1) + 1334: 474d li a4,19 + 1336: d8d75de3 bge a4,a3,10d0 + if ((frame % 50) < 4) return EXP_BLINK; + 133a: c101a503 lw a0,-1008(gp) # 2000000c + 133e: 03200593 li a1,50 + 1342: cc16 sw t0,24(sp) + 1344: ca1a sw t1,20(sp) + 1346: d8ffe0ef jal d4 <__umodsi3> + 134a: 42e2 lw t0,24(sp) + 134c: 4352 lw t1,20(sp) + 134e: 00453793 sltiu a5,a0,4 + 1352: bbbd j 10d0 + ssd1306_drawImage(8 + i * 12, 38, spr_poop, 8, 8, 0); + 1354: 4782 lw a5,0(sp) + 1356: 4721 li a4,8 + 1358: 00179513 slli a0,a5,0x1 + 135c: 953e add a0,a0,a5 + 135e: 050a slli a0,a0,0x2 + 1360: 86ba mv a3,a4 + 1362: c0418613 addi a2,gp,-1020 # 20000000 + 1366: 02600593 li a1,38 + 136a: 953a add a0,a0,a4 + 136c: b12ff0ef jal 67e + for (uint8_t i = 0; i < pet.poop; i++) + 1370: 4782 lw a5,0(sp) + 1372: 0785 addi a5,a5,1 + 1374: 0ff7f793 zext.b a5,a5 + 1378: c03e sw a5,0(sp) + 137a: b361 j 1102 + if (ok_edge || left_edge || right_edge) { + 137c: 8fd5 or a5,a5,a3 + 137e: 8fd1 or a5,a5,a2 + 1380: cb81 beqz a5,1390 + beep(880, 30); + 1382: 45f9 li a1,30 + 1384: 37000513 li a0,880 + screen = SCR_MAIN; + 1388: c0018c23 sb zero,-1000(gp) # 20000014 + beep(880, 30); + 138c: 818ff0ef jal 3a4 + ssd1306_setbuf(0); + 1390: 933ff0ef jal cc2 + draw_center_str(0, "-- STATUS --"); + 1394: 6585 lui a1,0x1 + 1396: 6e058593 addi a1,a1,1760 # 16e0 + 139a: 4501 li a0,0 + 139c: 974ff0ef jal 510 + draw_bar(10, "FOOD", pet.satiety); + 13a0: 00048603 lb a2,0(s1) + 13a4: 6585 lui a1,0x1 + 13a6: 6f058593 addi a1,a1,1776 # 16f0 + 13aa: 4529 li a0,10 + 13ac: a58ff0ef jal 604 + draw_bar(19, "FUN ", pet.happy); + 13b0: 00148603 lb a2,1(s1) + 13b4: 6585 lui a1,0x1 + 13b6: 6f858593 addi a1,a1,1784 # 16f8 + 13ba: 454d li a0,19 + 13bc: a48ff0ef jal 604 + draw_bar(28, "ENGY", pet.energy); + 13c0: 00248603 lb a2,2(s1) + 13c4: 6585 lui a1,0x1 + 13c6: 70058593 addi a1,a1,1792 # 1700 + 13ca: 4571 li a0,28 + 13cc: a38ff0ef jal 604 + draw_bar(37, "WASH", pet.hygiene); + 13d0: 00348603 lb a2,3(s1) + 13d4: 6585 lui a1,0x1 + 13d6: 70858593 addi a1,a1,1800 # 1708 + 13da: 02500513 li a0,37 + 13de: a26ff0ef jal 604 + draw_bar(46, "HLTH", pet.health); + 13e2: 00448603 lb a2,4(s1) + 13e6: 6585 lui a1,0x1 + 13e8: 71058593 addi a1,a1,1808 # 1710 + 13ec: 02e00513 li a0,46 + 13f0: a14ff0ef jal 604 + snprintf(line, sizeof(line), "Age %u %s", pet.age_min, + 13f4: 0094c783 lbu a5,9(s1) + 13f8: 0064d683 lhu a3,6(s1) + 13fc: c395 beqz a5,1420 + 13fe: 6705 lui a4,0x1 + 1400: 6b470713 addi a4,a4,1716 # 16b4 + 1404: 6605 lui a2,0x1 + 1406: 71860613 addi a2,a2,1816 # 1718 + 140a: 45c5 li a1,17 + 140c: 1008 addi a0,sp,32 + 140e: 88dff0ef jal c9a + ssd1306_drawstr(0, 56, line, 1); + 1412: 1010 addi a2,sp,32 + 1414: 03800593 li a1,56 + 1418: 4501 li a0,0 + 141a: 87eff0ef jal 498 + ssd1306_refresh(); + 141e: bb3d j 115c + snprintf(line, sizeof(line), "Age %u %s", pet.age_min, + 1420: 6705 lui a4,0x1 + 1422: 6b070713 addi a4,a4,1712 # 16b0 + 1426: bff9 j 1404 + if (ok_edge) { // start a new pet + 1428: ce99 beqz a3,1446 + pet_reset(); + 142a: 80cff0ef jal 436 + beep(659, 80); beep(988, 120); + 142e: 05000593 li a1,80 + 1432: 29300513 li a0,659 + 1436: f6ffe0ef jal 3a4 + 143a: 07800593 li a1,120 + 143e: 3dc00513 li a0,988 + 1442: f63fe0ef jal 3a4 + ssd1306_setbuf(0); + 1446: 87dff0ef jal cc2 + ssd1306_drawImage(48, 8, spr_grave, 32, 32, 0); + 144a: 02000713 li a4,32 + 144e: 6609 lui a2,0x2 + 1450: 86ba mv a3,a4 + 1452: 48860613 addi a2,a2,1160 # 2488 + 1456: 45a1 li a1,8 + 1458: 03000513 li a0,48 + 145c: a22ff0ef jal 67e + draw_center_str(44, "R.I.P."); + 1460: 6585 lui a1,0x1 + 1462: 72458593 addi a1,a1,1828 # 1724 + 1466: 02c00513 li a0,44 + 146a: 8a6ff0ef jal 510 + snprintf(line, sizeof(line), "lived %u min", pet.age_min); + 146e: 0064d683 lhu a3,6(s1) + 1472: 6605 lui a2,0x1 + 1474: 72c60613 addi a2,a2,1836 # 172c + 1478: 45c5 li a1,17 + 147a: 1008 addi a0,sp,32 + 147c: 81fff0ef jal c9a + draw_center_str(52, line); + 1480: 100c addi a1,sp,32 + 1482: 03400513 li a0,52 + 1486: 88aff0ef jal 510 + 148a: b9c9 j 115c + pet.age_min++; + 148c: 0064d303 lhu t1,6(s1) + if (pet.sleeping) { + 1490: 0094c503 lbu a0,9(s1) + tick_acc = 0; + 1494: c0019a23 sh zero,-1004(gp) # 20000010 + pet.age_min++; + 1498: 0305 addi t1,t1,1 + 149a: 0342 slli t1,t1,0x10 + 149c: 01035313 srli t1,t1,0x10 + 14a0: 00649323 sh t1,6(s1) + pet.satiety = clamp100(pet.satiety - 1); + 14a4: 00048703 lb a4,0(s1) + pet.energy = clamp100(pet.energy + 10); + 14a8: 00248783 lb a5,2(s1) + 14ac: 06400593 li a1,100 + if (pet.sleeping) { + 14b0: 14050163 beqz a0,15f2 + pet.energy = clamp100(pet.energy + 10); + 14b4: 00a78693 addi a3,a5,10 +static int8_t clamp100(int v) { return v < 0 ? 0 : (v > 100 ? 100 : v); } + 14b8: 12d5d363 bge a1,a3,15de + 14bc: 86ae mv a3,a1 + 14be: 06e2 slli a3,a3,0x18 + 14c0: 86e1 srai a3,a3,0x18 + pet.energy = clamp100(pet.energy + 10); + 14c2: 00d48123 sb a3,2(s1) + pet.satiety = clamp100(pet.satiety - 1); + 14c6: 177d addi a4,a4,-1 +static int8_t clamp100(int v) { return v < 0 ? 0 : (v > 100 ? 100 : v); } + 14c8: 06400613 li a2,100 + 14cc: 10e65e63 bge a2,a4,15e8 + 14d0: 8732 mv a4,a2 + 14d2: 0762 slli a4,a4,0x18 + 14d4: 8761 srai a4,a4,0x18 + pet.satiety = clamp100(pet.satiety - 1); + 14d6: 00e48023 sb a4,0(s1) + if (pet.energy >= 100) pet.sleeping = 0; // wakes when rested + 14da: 05900613 li a2,89 + 14de: 00f65763 bge a2,a5,14ec + 14e2: 000484a3 sb zero,9(s1) + 14e6: 06400693 li a3,100 + 14ea: 4501 li a0,0 + pet.hygiene = clamp100(pet.hygiene - 1); + 14ec: 00348583 lb a1,3(s1) +static int8_t clamp100(int v) { return v < 0 ? 0 : (v > 100 ? 100 : v); } + 14f0: 06400793 li a5,100 + pet.hygiene = clamp100(pet.hygiene - 1); + 14f4: fff58613 addi a2,a1,-1 +static int8_t clamp100(int v) { return v < 0 ? 0 : (v > 100 ? 100 : v); } + 14f8: 14c7dc63 bge a5,a2,1650 + 14fc: 863e mv a2,a5 + 14fe: 0662 slli a2,a2,0x18 + 1500: 8661 srai a2,a2,0x18 + pet.hygiene = clamp100(pet.hygiene - 1); + 1502: 00c481a3 sb a2,3(s1) + if (!pet.sleeping && pet.poop < 3 && + 1506: e115 bnez a0,152a + 1508: 0084c503 lbu a0,8(s1) + 150c: 4789 li a5,2 + 150e: 00a7ee63 bltu a5,a0,152a + ((pet.age_min * 7u + frame) & 0x0F) == 0) + 1512: 00331793 slli a5,t1,0x3 + 1516: 406787b3 sub a5,a5,t1 + 151a: c101a303 lw t1,-1008(gp) # 2000000c + 151e: 979a add a5,a5,t1 + 1520: 8bbd andi a5,a5,15 + if (!pet.sleeping && pet.poop < 3 && + 1522: e781 bnez a5,152a + pet.poop++; + 1524: 0505 addi a0,a0,1 + 1526: 00a48423 sb a0,8(s1) + if (pet.poop) pet.happy = clamp100(pet.happy - pet.poop); + 152a: 0084c503 lbu a0,8(s1) + 152e: c919 beqz a0,1544 + 1530: 00148783 lb a5,1(s1) + 1534: 8f89 sub a5,a5,a0 +static int8_t clamp100(int v) { return v < 0 ? 0 : (v > 100 ? 100 : v); } + 1536: 06400513 li a0,100 + 153a: 12f55063 bge a0,a5,165a + 153e: 87aa mv a5,a0 + 1540: 00f480a3 sb a5,1(s1) + if (pet.hygiene < 20) pet.happy = clamp100(pet.happy - 1); + 1544: 47d1 li a5,20 + 1546: 00b7cc63 blt a5,a1,155e + 154a: 00148783 lb a5,1(s1) +static int8_t clamp100(int v) { return v < 0 ? 0 : (v > 100 ? 100 : v); } + 154e: 06400593 li a1,100 + if (pet.hygiene < 20) pet.happy = clamp100(pet.happy - 1); + 1552: 17fd addi a5,a5,-1 +static int8_t clamp100(int v) { return v < 0 ? 0 : (v > 100 ? 100 : v); } + 1554: 10f5d863 bge a1,a5,1664 + 1558: 87ae mv a5,a1 + 155a: 00f480a3 sb a5,1(s1) + if (pet.hygiene < lo) lo = pet.hygiene; + 155e: 0014c583 lbu a1,1(s1) + 1562: 87ae mv a5,a1 + 1564: 05e2 slli a1,a1,0x18 + 1566: 85e1 srai a1,a1,0x18 + 1568: 00b65363 bge a2,a1,156e + 156c: 87b2 mv a5,a2 + 156e: 01879613 slli a2,a5,0x18 + 1572: 8661 srai a2,a2,0x18 + 1574: 00c75363 bge a4,a2,157a + 1578: 87ba mv a5,a4 + 157a: 01879713 slli a4,a5,0x18 + 157e: 8761 srai a4,a4,0x18 + 1580: 00e6d363 bge a3,a4,1586 + 1584: 87b6 mv a5,a3 + 1586: 01879713 slli a4,a5,0x18 + 158a: 8761 srai a4,a4,0x18 + if (lo < 15) pet.health = clamp100(pet.health - 5); + 158c: 46b9 li a3,14 + 158e: 00448783 lb a5,4(s1) + 1592: 0ce6ce63 blt a3,a4,166e + 1596: 17ed addi a5,a5,-5 +static int8_t clamp100(int v) { return v < 0 ? 0 : (v > 100 ? 100 : v); } + 1598: 06400713 li a4,100 + 159c: 0cf75f63 bge a4,a5,167a + 15a0: 87ba mv a5,a4 + 15a2: 00f48223 sb a5,4(s1) + if (pet.health <= 0) { + 15a6: 00448783 lb a5,4(s1) + 15aa: bcf04ee3 bgtz a5,1186 + screen = SCR_DEAD; + 15ae: 4709 li a4,2 + beep(330, 200); beep(247, 200); beep(165, 400); + 15b0: 0c800593 li a1,200 + 15b4: 14a00513 li a0,330 + screen = SCR_DEAD; + 15b8: c0e18c23 sb a4,-1000(gp) # 20000014 + pet.alive = 0; + 15bc: 00048523 sb zero,10(s1) + beep(330, 200); beep(247, 200); beep(165, 400); + 15c0: de5fe0ef jal 3a4 + 15c4: 0c800593 li a1,200 + 15c8: 0f700513 li a0,247 + 15cc: dd9fe0ef jal 3a4 + 15d0: 19000593 li a1,400 + 15d4: 0a500513 li a0,165 + 15d8: dcdfe0ef jal 3a4 + 15dc: b66d j 1186 +static int8_t clamp100(int v) { return v < 0 ? 0 : (v > 100 ? 100 : v); } + 15de: fff6c613 not a2,a3 + 15e2: 867d srai a2,a2,0x1f + 15e4: 8ef1 and a3,a3,a2 + 15e6: bde1 j 14be + 15e8: fff74613 not a2,a4 + 15ec: 867d srai a2,a2,0x1f + 15ee: 8f71 and a4,a4,a2 + 15f0: b5cd j 14d2 + pet.satiety = clamp100(pet.satiety - 3); + 15f2: 1775 addi a4,a4,-3 + pet.happy = clamp100(pet.happy - 2); + 15f4: 00148603 lb a2,1(s1) +static int8_t clamp100(int v) { return v < 0 ? 0 : (v > 100 ? 100 : v); } + 15f8: 02e5dd63 bge a1,a4,1632 + 15fc: 872e mv a4,a1 + 15fe: 0762 slli a4,a4,0x18 + 1600: 8761 srai a4,a4,0x18 + pet.satiety = clamp100(pet.satiety - 3); + 1602: 00e48023 sb a4,0(s1) + pet.energy = clamp100(pet.energy - 2); + 1606: 17f9 addi a5,a5,-2 +static int8_t clamp100(int v) { return v < 0 ? 0 : (v > 100 ? 100 : v); } + 1608: 06400693 li a3,100 + 160c: 02f6d863 bge a3,a5,163c + 1610: 87b6 mv a5,a3 + 1612: 01879693 slli a3,a5,0x18 + 1616: 86e1 srai a3,a3,0x18 + pet.energy = clamp100(pet.energy - 2); + 1618: 00d48123 sb a3,2(s1) + pet.happy = clamp100(pet.happy - 2); + 161c: 1679 addi a2,a2,-2 +static int8_t clamp100(int v) { return v < 0 ? 0 : (v > 100 ? 100 : v); } + 161e: 06400793 li a5,100 + 1622: 02c7d263 bge a5,a2,1646 + 1626: 863e mv a2,a5 + 1628: c1c18793 addi a5,gp,-996 # 20000018 + 162c: 00c780a3 sb a2,1(a5) + 1630: bd75 j 14ec + 1632: fff74693 not a3,a4 + 1636: 86fd srai a3,a3,0x1f + 1638: 8f75 and a4,a4,a3 + 163a: b7d1 j 15fe + 163c: fff7c693 not a3,a5 + 1640: 86fd srai a3,a3,0x1f + 1642: 8ff5 and a5,a5,a3 + 1644: b7f9 j 1612 + 1646: fff64793 not a5,a2 + 164a: 87fd srai a5,a5,0x1f + 164c: 8e7d and a2,a2,a5 + 164e: bfe9 j 1628 + 1650: fff64793 not a5,a2 + 1654: 87fd srai a5,a5,0x1f + 1656: 8e7d and a2,a2,a5 + 1658: b55d j 14fe + 165a: fff7c513 not a0,a5 + 165e: 857d srai a0,a0,0x1f + 1660: 8fe9 and a5,a5,a0 + 1662: bdf9 j 1540 + 1664: fff7c593 not a1,a5 + 1668: 85fd srai a1,a1,0x1f + 166a: 8fed and a5,a5,a1 + 166c: b5fd j 155a + else if (lo > 50) pet.health = clamp100(pet.health + 2); + 166e: 03200693 li a3,50 + 1672: f2e6dae3 bge a3,a4,15a6 + 1676: 0789 addi a5,a5,2 + 1678: b705 j 1598 +static int8_t clamp100(int v) { return v < 0 ? 0 : (v > 100 ? 100 : v); } + 167a: fff7c713 not a4,a5 + 167e: 877d srai a4,a4,0x1f + 1680: 8ff9 and a5,a5,a4 + 1682: b705 j 15a2 + 1684: 31647373 .insn 4, 0x31647373 + 1688: 5f363033 .insn 4, 0x5f363033 + 168c: 3269 jal 1016 + 168e: 72655f63 bge a0,t1,1dcc + 1692: 6f72 .insn 2, 0x6f72 + 1694: 2072 .insn 2, 0x2072 + 1696: 202d jal 16c0 + 1698: 6974 .insn 2, 0x6974 + 169a: 656d lui a0,0x1b + 169c: 2074756f jal a0,490a2 + 16a0: 74696177 .insn 4, 0x74696177 + 16a4: 6e69 lui t3,0x1a + 16a6: 6f662067 .insn 4, 0x6f662067 + 16aa: 2072 .insn 2, 0x2072 + 16ac: 7325 lui t1,0xfffe9 + 16ae: 0d0a slli s10,s10,0x2 + 16b0: 0000 unimp + 16b2: 0000 unimp + 16b4: 7a5a .insn 2, 0x7a5a + 16b6: 007a c.slli zero,0x1e + 16b8: 4150 lw a2,4(a0) + 16ba: 414e lw sp,208(sp) + 16bc: 43544f47 .insn 4, 0x43544f47 + 16c0: 4948 lw a0,20(a0) + 16c2: 0000 unimp + 16c4: 7270 .insn 2, 0x7270 + 16c6: 7365 lui t1,0xffff9 + 16c8: 6e612073 .insn 4, 0x6e612073 + 16cc: 2079 jal 175a + 16ce: 0079656b .insn 4, 0x0079656b + 16d2: 0000 unimp + 16d4: 0021 c.nop 8 + 16d6: 0000 unimp + 16d8: 007a c.slli zero,0x1e + 16da: 0000 unimp + 16dc: 005a c.slli zero,0x16 + 16de: 0000 unimp + 16e0: 2d2d jal 1d1a + 16e2: 5320 lw s0,96(a4) + 16e4: 4154 lw a3,4(a0) + 16e6: 5554 lw a3,44(a0) + 16e8: 2d2d2053 .insn 4, 0x2d2d2053 + 16ec: 0000 unimp + 16ee: 0000 unimp + 16f0: 4f46 lw t5,80(sp) + 16f2: 0000444f .insn 4, 0x444f + 16f6: 0000 unimp + 16f8: 5546 lw a0,112(sp) + 16fa: 204e .insn 2, 0x204e + 16fc: 0000 unimp + 16fe: 0000 unimp + 1700: 4e45 li t3,17 + 1702: 00005947 .insn 4, 0x5947 + 1706: 0000 unimp + 1708: 48534157 .insn 4, 0x48534157 + 170c: 0000 unimp + 170e: 0000 unimp + 1710: 4c48 lw a0,28(s0) + 1712: 4854 lw a3,20(s0) + 1714: 0000 unimp + 1716: 0000 unimp + 1718: 6741 lui a4,0x10 + 171a: 2065 jal 17c2 + 171c: 7525 lui a0,0xfffe9 + 171e: 2020 .insn 2, 0x2020 + 1720: 7325 lui t1,0xfffe9 + 1722: 0000 unimp + 1724: 2e52 .insn 2, 0x2e52 + 1726: 2e49 jal 1ab8 + 1728: 2e50 .insn 2, 0x2e50 + 172a: 0000 unimp + 172c: 696c .insn 2, 0x696c + 172e: 6576 .insn 2, 0x6576 + 1730: 2064 .insn 2, 0x2064 + 1732: 7525 lui a0,0xfffe9 + 1734: 6d20 .insn 2, 0x6d20 + 1736: 6e69 lui t3,0x1a + 1738: 0000 unimp + 173a: 0000 unimp + 173c: 6f6e .insn 2, 0x6f6e + 173e: 2074 .insn 2, 0x2074 + 1740: 7562 .insn 2, 0x7562 + 1742: 00007973 .insn 4, 0x7973 + 1746: 0000 unimp + 1748: 616d addi sp,sp,240 + 174a: 72657473 .insn 4, 0x72657473 + 174e: 6d20 .insn 2, 0x6d20 + 1750: 0065646f jal s0,57756 + 1754: 7274 .insn 2, 0x7274 + 1756: 6e61 lui t3,0x18 + 1758: 74696d73 .insn 4, 0x74696d73 + 175c: 6d20 .insn 2, 0x6d20 + 175e: 0065646f jal s0,57764 + 1762: 0000 unimp + 1764: 7874 .insn 2, 0x7874 + 1766: 6520 .insn 2, 0x6520 + 1768: 706d c.lui zero,0xffffb + 176a: 7974 .insn 2, 0x7974 + 176c: 0000 unimp + 176e: 0000 unimp + 1770: 7274 .insn 2, 0x7274 + 1772: 6e61 lui t3,0x18 + 1774: 74696d73 .insn 4, 0x74696d73 + 1778: 6320 .insn 2, 0x6320 + 177a: 6c706d6f jal s10,8640 + 177e: 7465 lui s0,0xffff9 + 1780: 0065 c.nop 25 + 1782: 0000 unimp + 1784: 4546 lw a0,80(sp) + 1786: 4445 li s0,17 + 1788: 0000 unimp + 178a: 0000 unimp + 178c: 4c50 lw a2,28(s0) + 178e: 5941 li s2,-16 + 1790: 0000 unimp + 1792: 0000 unimp + 1794: 45454c53 .insn 4, 0x45454c53 + 1798: 0050 addi a2,sp,4 + 179a: 0000 unimp + 179c: 41454c43 .insn 4, 0x41454c43 + 17a0: 004e c.slli zero,0x13 + 17a2: 0000 unimp + 17a4: 4548 lw a0,12(a0) + 17a6: 4c41 li s8,16 + 17a8: 0000 unimp + 17aa: 0000 unimp + 17ac: 54415453 .insn 4, 0x54415453 + 17b0: 00000053 .insn 4, 0x0053 + 17b4: 0fe6 slli t6,t6,0x19 + 17b6: 0000 unimp + 17b8: 11b8 addi a4,sp,232 + 17ba: 0000 unimp + 17bc: 122e slli tp,tp,0x2b + 17be: 0000 unimp + 17c0: 1250 addi a2,sp,292 + 17c2: 0000 unimp + 17c4: 1290 addi a2,sp,352 + 17c6: 0000 unimp + 17c8: 12d2 slli t0,t0,0x34 + ... + +000017cc : + 17cc: 0000 0000 0000 c000 c000 c000 c006 c006 ................ + 17dc: d806 d806 d836 d836 d836 d836 0000 0000 ....6.6.6.6..... + +000017ec : + 17ec: 0000 8000 f007 f80f 3c1c 3e3c 0e30 0e30 .........<<>0.0. + 17fc: 0f70 0e30 3e3c 3e3c fc1f f80f f007 8000 p.0.<><>........ + +0000180c : + 180c: 0000 0000 8000 8000 c001 c001 f007 f80d ................ + 181c: f80d f808 fc1d f80d f80f f80f f007 8000 ................ + +0000182c : + 182c: 0000 0000 0000 0004 000c 001c 0018 001c ................ + 183c: 003c 001c 001e 001f e80f f007 8000 0000 <............... + +0000184c : + 184c: 0000 0000 7007 0000 7c1f 7e3f 7e3f 7e3f .....p...|?~?~?~ + 185c: 0000 7e3f 7e3f 7e3f 7c1f 0000 7007 0000 ..?~?~?~.|...p.. + +0000186c : + 186c: 0000 0000 a000 9001 e00f f01b f83b f831 ............;.1. + 187c: f83b fc7b f83f f83f f83f f01f e00f 0001 ;.{.?.?.?....... + +0000188c : + ... + 1894: 0001 8000 e00f f007 f01f f80f f01f f80f ................ + 18a4: f01f f80f f83f fc9f ff1f f8ff ff1f f8ff ....?........... + 18b4: ff1f f8ff ff0f f0ff ff03 e0ff ff07 f0ff ................ + 18c4: ff07 f0ff bb0f f8ee d70f f8f5 ef0f f8fb ................ + 18d4: d70f f8f5 bb1f fcee ff0f f8ff ff0f f8ff ................ + 18e4: ff0f f8ff f00f f807 ff07 f0ff ff07 f0ff ................ + 18f4: ff03 e0ff ff01 c0ff ff00 80ff 7f00 00ff ................ + 1904: 1f00 00fc 0000 0080 ........ + +0000190c : + ... + 1914: 0001 8000 e00f f007 f01f f80f f01f f80f ................ + 1924: f01f f80f f83f fc9f ff1f f8ff ff1f f8ff ....?........... + 1934: ff1f f8ff ff0f f0ff ff03 e0ff ff07 f0ff ................ + 1944: ff07 f0ff ff0f f8ff ff0f f8ff ff0f f8ff ................ + 1954: 010f 78c0 ff1f fcff ff0f f8ff ff0f f87f ...x............ + 1964: fc0f f81f ff0f f87f ff07 f0ff ff07 f0ff ................ + 1974: ff03 e0ff ff01 c0ff ff00 80ff 7f00 00ff ................ + 1984: 1f00 00fc 0000 0080 ........ + +0000198c : + ... + 1994: 0001 8000 e00f f007 f01f f80f f01f f80f ................ + 19a4: f01f f80f f83f fc9f ff1f f8ff ff1f f8ff ....?........... + 19b4: ff1f f8ff ff0f f0ff ff03 e0ff ef07 f0fb ................ + 19c4: 8307 f0e0 930f f8e4 110f 78c4 830f f8e0 ...........x.... + 19d4: 830f f8e0 ef1f fcfb ff0f f87f fc0f f81f ................ + 19e4: fc0f f81f f80f f80f fc07 f01f fc07 f01f ................ + 19f4: ff03 e07f ff01 c0ff ff00 80ff 7f00 00ff ................ + 1a04: 1f00 00fc 0000 0080 ........ + +00001a0c : + ... + 1a14: 0001 8000 e00f f007 f01f f80f f01f f80f ................ + 1a24: f01f f80f f83f fc9f ff1f f8ff ff1f f8ff ....?........... + 1a34: ff1f f8ff ff0f f0ff ff03 e0ff ff07 f0ff ................ + 1a44: ff07 f0ff ef0f f8fb 830f f8e0 930f f8e4 ................ + 1a54: 110f 78c4 831f fce0 830f f860 ec0f f81b ...x......`..... + 1a64: ff0f f87f fc0f f81f f707 f0f7 fb07 f0ef ................ + 1a74: ff03 e0ff ff01 c0ff ff00 80ff 7f00 00ff ................ + 1a84: 1f00 00fc 0000 0080 ........ + +00001a8c : + ... + 1a94: 0001 8000 e00f f007 f01f f80f f01f f80f ................ + 1aa4: f01f f80f f83f fc9f ff1f f8ff ff1f f8ff ....?........... + 1ab4: ff1f f8ff ff0f f0ff ff03 e0ff ff07 f0ff ................ + 1ac4: ff07 f0ff ff0f f8ff ef0f f8fb d70f f8f5 ................ + 1ad4: ff0f f8ff ff1f fcff ff0f f8ff f80f f80f ................ + 1ae4: fb0f f8ef f70f f8f7 fc07 f01f ff07 f0ff ................ + 1af4: ff03 e0ff ff01 c0ff ff00 80ff 7f00 00ff ................ + 1b04: 1f00 00fc 0000 0080 ........ + +00001b0c : + ... + 1b14: 0001 8000 e00f f007 f01f f80f f01f f80f ................ + 1b24: f01f f80f f83f fc9f ff1f f8ff ff1f f8ff ....?........... + 1b34: ff1f f8ff ff0f f0ff ff03 e0ff ff07 f0ff ................ + 1b44: ff07 f0ff ff0f f8ff ff0f f8ff 010f 78c0 ...............x + 1b54: ff0f f8ff ff1f fcff ff0f f87f fc0f f81f ................ + 1b64: ff0f f87f ff0f f8ff f807 f00f ff07 f0ff ................ + 1b74: ff03 e0ff ff01 c0ff ff00 80ff 7f00 00ff ................ + 1b84: 1f00 00fc 0000 0080 ........ + +00001b8c : + 1b8c: 173c 0000 1748 0000 1754 0000 1764 0000 <...H...T...d... + 1b9c: 1770 0000 p... + +00001ba0 : + ... + 1ba8: 817e 81a5 99bd 7e81 ff7e ffdb e7c3 7eff ~......~~......~ + 1bb8: fe6c fefe 387c 0010 3810 fe7c 387c 0010 l...|8...8|.|8.. + 1bc8: 7c38 fe38 d6fe 3810 3810 fe7c 7cfe 3810 8|8....8.8|..|.8 + 1bd8: 0000 3c18 183c 0000 ffff c3e7 e7c3 ffff ...<<........... + 1be8: 3c00 4266 6642 003c c3ff bd99 99bd ffc3 ..>....<~..~<. + 1c38: 6666 6666 0066 0066 db7f 7bdb 1b1b 001b fffff.f....{.... + 1c48: 613e 663c 3c66 7c86 0000 0000 7e7e 007e >a`<.|.. + 1cc8: c600 18cc 6630 00c6 6c38 7638 ccdc 0076 ....0f..8l8v..v. + 1cd8: 1818 0030 0000 0000 180c 3030 1830 000c ..0.......000... + 1ce8: 1830 0c0c 180c 0030 6600 ff3c 663c 0000 0.....0..f<.l...... + 2038: 827c c67c c6c6 007c 00c6 c67c c6c6 007c |.|...|...|...|. + 2048: 1830 c67c c6c6 007c 8478 cc00 cccc 0076 0.|...|.x.....v. + 2058: 3060 cccc cccc 0076 00c6 c6c6 7ec6 fc06 `0....v......~.. + 2068: 38c6 c66c 6cc6 0038 00c6 c6c6 c6c6 007c .8l..l8.......|. + 2078: 1818 c07e 7ec0 1818 6c38 f064 6660 00fc ..~..~..8ld.`f.. + 2088: 6666 7e3c 7e18 1818 ccf8 facc cfc6 c7c6 ff<~.~.......... + 2098: 1b0e 3c18 d818 0070 3018 0c78 cc7c 0076 ...<..p..0x.|.v. + 20a8: 180c 3800 1818 003c 180c c67c c6c6 007c ...8..<...|...|. + 20b8: 3018 cccc cccc 0076 dc76 dc00 6666 0066 .0....v.v...fff. + 20c8: dc76 e600 def6 00ce 6c3c 3e6c 7e00 0000 v........~.. + 20d8: 6c38 386c 7c00 0000 0018 1818 6330 003e 8ll8.|......0c>. + 20e8: 0000 fe00 c0c0 0000 0000 fe00 0606 0000 ................ + 20f8: e663 7e6c 6633 0fcc e663 7a6c 6a36 06df c.l~3f..c.lz6j.. + 2108: 0018 1818 3c3c 0018 3300 cc66 3366 0000 ....<<...3f.f3.. + 2118: cc00 3366 cc66 0000 8822 8822 8822 8822 ..f3f...".".".". + 2128: aa55 aa55 aa55 aa55 dd77 dd77 dd77 dd77 U.U.U.U.w.w.w.w. + 2138: 1818 1818 1818 1818 1818 1818 18f8 1818 ................ + 2148: 1818 18f8 18f8 1818 3636 3636 36f6 3636 ........6666.666 + 2158: 0000 0000 36fe 3636 0000 18f8 18f8 1818 .....666........ + 2168: 3636 06f6 36f6 3636 3636 3636 3636 3636 66...66666666666 + 2178: 0000 06fe 36f6 3636 3636 06f6 00fe 0000 .....66666...... + 2188: 3636 3636 00fe 0000 1818 18f8 00f8 0000 6666............ + 2198: 0000 0000 18f8 1818 1818 1818 001f 0000 ................ + 21a8: 1818 1818 00ff 0000 0000 0000 18ff 1818 ................ + 21b8: 1818 1818 181f 1818 0000 0000 00ff 0000 ................ + 21c8: 1818 1818 18ff 1818 1818 181f 181f 1818 ................ + 21d8: 3636 3636 3637 3636 3636 3037 003f 0000 666676666670?... + 21e8: 0000 303f 3637 3636 3636 00f7 00ff 0000 ..?0766666...... + 21f8: 0000 00ff 36f7 3636 3636 3037 3637 3636 .....66666707666 + 2208: 0000 00ff 00ff 0000 3636 00f7 36f7 3636 ........66...666 + 2218: 1818 00ff 00ff 0000 3636 3636 00ff 0000 ........6666.... + 2228: 0000 00ff 18ff 1818 0000 0000 36ff 3636 .............666 + 2238: 3636 3636 003f 0000 1818 181f 001f 0000 6666?........... + 2248: 0000 181f 181f 1818 0000 0000 363f 3636 ............?666 + 2258: 3636 3636 36ff 3636 1818 18ff 18ff 1818 6666.666........ + 2268: 1818 1818 00f8 0000 0000 0000 181f 1818 ................ + 2278: ffff ffff ffff ffff 0000 0000 ffff ffff ................ + 2288: f0f0 f0f0 f0f0 f0f0 0f0f 0f0f 0f0f 0f0f ................ + 2298: ffff ffff 0000 0000 0000 dc76 dcc8 0076 ..........v...v. + 22a8: cc78 d8cc c6cc 00cc c6fe c0c0 c0c0 00c0 x............... + 22b8: 0000 6cfe 6c6c 006c c6fe 3060 c660 00fe ...llll...`0`... + 22c8: 0000 d87e d8d8 0070 0000 6666 6666 c07c ..~...p...ffff|. + 22d8: 7600 18dc 1818 0018 187e 663c 3c66 7e18 .v......~.ff<...~..~.. + 2308: 0c06 db7e 7edb c060 301e 7e60 3060 001e ..~..~`..0`~`0.. + 2318: 7c00 c6c6 c6c6 00c6 fe00 fe00 fe00 0000 .|.............. + 2328: 1818 187e 0018 007e 1830 180c 0030 007e ..~...~.0...0.~. + 2338: 180c 1830 000c 007e 1b0e 181b 1818 1818 ..0...~......... + 2348: 1818 1818 d818 70d8 1800 7e00 1800 0000 .......p...~.... + 2358: 7600 00dc dc76 0000 6c38 386c 0000 0000 .v..v...8ll8.... + 2368: 0000 1800 0018 0000 0000 1800 0000 0000 ................ + 2378: 0c0f 0c0c 6cec 1c3c 366c 3636 0036 0000 .....l<.l6666... + 2388: 0c78 3018 007c 0000 0000 3c3c 3c3c 0000 x..0|.....<<<<.. + ... + +000023a0 : + 23a0: d5ae a880 d33f 4000 148d 0020 c8a1 12da ....?..@.. ..... + 23b0: 8f81 f1d9 40db a6a4 ffaf 0000 .....@...... + +000023bc : + ... + 23c4: 0001 8000 e00f f007 f01f f80f f01f f80f ................ + 23d4: f01f f80f f83f fc9f ff1f f8ff ff1f f8ff ....?........... + 23e4: ff1f f8ff ff0f f0ff ff03 e0ff ff07 f0ff ................ + 23f4: ef07 f0fb 830f f8e0 930f f8e4 110f 78c4 ...............x + 2404: 830f f8e0 831f fce0 ef0f f87b fc0f f81f ..........{..... + 2414: ff0f f87f ff0f f8ff f807 f00f ff07 f0ff ................ + 2424: ff03 e0ff ff01 c0ff ff00 80ff 7f00 00ff ................ + 2434: 1f00 00fc 0000 0080 ........ + +0000243c : + 243c: 186c 0000 184c 0000 182c 0000 180c 0000 l...L...,....... + 244c: 17ec 0000 17cc 0000 ........ + +00002454 : + 2454: 23bc 0000 1b0c 0000 1a8c 0000 1a0c 0000 .#.............. + 2464: 198c 0000 190c 0000 188c 0000 ............ + +00002470 : + 2470: 1784 0000 178c 0000 1794 0000 179c 0000 ................ + 2480: 17a4 0000 17ac 0000 ........ + +00002488 : + ... + 2490: ff00 00fc ff03 00ff ff07 80ff 1f06 80e1 ................ + 24a0: 3006 8031 3006 8031 3f06 00c3 3306 0003 .01..01..?...3.. + 24b0: 3106 0083 3006 00c3 0006 0006 0f06 0006 .1...0.......... + 24c0: ff07 80ff ff0f c0ff ff1f e0ff ff3f f0ff ............?... + 24d0: ff7f f8ff ffff fcff ffff fcff f000 00f0 ................ + 24e0: ff03 00f0 ff0f 00fc 0000 0000 0000 0000 ................ + ... diff --git a/tama.map b/tama.map new file mode 100644 index 0000000..4941c20 --- /dev/null +++ b/tama.map @@ -0,0 +1,586 @@ +Archive member included to satisfy reference by file (symbol) + +../ch32v003fun/ch32fun//../misc/libgcc.a(div.o) + /tmp/ccuFqAhq.ltrans0.ltrans.o (__divsi3) + +Discarded input sections + + .text 0x00000000 0x0 /tmp/ccuFqAhq.ltrans0.ltrans.o + .data 0x00000000 0x0 /tmp/ccuFqAhq.ltrans0.ltrans.o + .bss 0x00000000 0x0 /tmp/ccuFqAhq.ltrans0.ltrans.o + .text.vprintf 0x00000000 0x16 /tmp/ccuFqAhq.ltrans0.ltrans.o + .text.sprintf 0x00000000 0x26 /tmp/ccuFqAhq.ltrans0.ltrans.o + .text.strcpy 0x00000000 0x14 /tmp/ccuFqAhq.ltrans0.ltrans.o + .text.strncpy 0x00000000 0x1c /tmp/ccuFqAhq.ltrans0.ltrans.o + .text.strcmp 0x00000000 0x1a /tmp/ccuFqAhq.ltrans0.ltrans.o + .text.strncmp 0x00000000 0x2e /tmp/ccuFqAhq.ltrans0.ltrans.o + .text.strchr 0x00000000 0x16 /tmp/ccuFqAhq.ltrans0.ltrans.o + .text.strrchr 0x00000000 0x3c /tmp/ccuFqAhq.ltrans0.ltrans.o + .text.memcmp 0x00000000 0x20 /tmp/ccuFqAhq.ltrans0.ltrans.o + .text.memmove 0x00000000 0x5e /tmp/ccuFqAhq.ltrans0.ltrans.o + .text.memchr 0x00000000 0x1a /tmp/ccuFqAhq.ltrans0.ltrans.o + .text.strnlen 0x00000000 0x2a /tmp/ccuFqAhq.ltrans0.ltrans.o + .text.twoway_strstr + 0x00000000 0x232 /tmp/ccuFqAhq.ltrans0.ltrans.o + .text.strstr 0x00000000 0x11c /tmp/ccuFqAhq.ltrans0.ltrans.o + .rodata.puts.str1.4 + 0x00000000 0x2 /tmp/ccuFqAhq.ltrans0.ltrans.o + .text.puts 0x00000000 0x40 /tmp/ccuFqAhq.ltrans0.ltrans.o + .text.setjmp 0x00000000 0x10 /tmp/ccuFqAhq.ltrans0.ltrans.o + .text.longjmp 0x00000000 0x14 /tmp/ccuFqAhq.ltrans0.ltrans.o + .text.putchar 0x00000000 0x68 /tmp/ccuFqAhq.ltrans0.ltrans.o + .rodata.APBAHBPrescTable.lto_priv.0 + 0x00000000 0x10 /tmp/ccuFqAhq.ltrans0.ltrans.o + .rodata.ADCPrescTable.lto_priv.0 + 0x00000000 0x14 /tmp/ccuFqAhq.ltrans0.ltrans.o + .rodata.APBAHBPrescTable.lto_priv.1 + 0x00000000 0x10 /tmp/ccuFqAhq.ltrans0.ltrans.o + .rodata.ADCPrescTable.lto_priv.1 + 0x00000000 0x14 /tmp/ccuFqAhq.ltrans0.ltrans.o + .comment 0x00000000 0x35 /tmp/ccuFqAhq.ltrans0.ltrans.o + .note.GNU-stack + 0x00000000 0x0 /tmp/ccuFqAhq.ltrans0.ltrans.o + .comment 0x00000000 0x35 /tmp/cc6O5Yfp.debug.temp.o + .note.GNU-stack + 0x00000000 0x0 /tmp/cc6O5Yfp.debug.temp.o + .comment 0x00000000 0x35 /tmp/ccQWTvKu.debug.temp.o + .note.GNU-stack + 0x00000000 0x0 /tmp/ccQWTvKu.debug.temp.o + .data 0x00000000 0x0 ../ch32v003fun/ch32fun//../misc/libgcc.a(div.o) + .bss 0x00000000 0x0 ../ch32v003fun/ch32fun//../misc/libgcc.a(div.o) + +Memory Configuration + +Name Origin Length Attributes +FLASH 0x00000000 0x00004000 xr +RAM 0x20000000 0x00000800 xrw +*default* 0x00000000 0xffffffff + +Linker script and memory map + +LOAD /tmp/ccc3BNuu.o +LOAD /tmp/ccuFqAhq.ltrans0.ltrans.o +LOAD /tmp/cc6O5Yfp.debug.temp.o +LOAD /tmp/ccQWTvKu.debug.temp.o +LOAD /tmp/ccZbRLFZ.o +LOAD ../ch32v003fun/ch32fun//../misc/libgcc.a +LOAD ../ch32v003fun/ch32fun//../misc/libgcc.a + +.init 0x00000000 0xa0 + 0x00000000 _sinit = . + 0x00000000 . = ALIGN (0x4) + *(SORT_NONE(.init)) + .init 0x00000000 0x9e /tmp/ccuFqAhq.ltrans0.ltrans.o + 0x00000000 InterruptVectorDefault + 0x00000000 InterruptVector + 0x000000a0 . = ALIGN (0x4) + *fill* 0x0000009e 0x2 + 0x000000a0 _einit = . + +.text 0x000000a0 0x2468 + 0x000000a0 . = ALIGN (0x4) + *(.text) + .text 0x000000a0 0x7e ../ch32v003fun/ch32fun//../misc/libgcc.a(div.o) + 0x000000a0 __divsi3 + 0x000000a8 __hidden___udivsi3 + 0x000000a8 __udivsi3 + 0x000000d4 __umodsi3 + 0x000000f8 __modsi3 + *(.text.*) + .text.mini_pad + 0x0000011e 0x8a /tmp/ccuFqAhq.ltrans0.ltrans.o + .text._puts 0x000001a8 0x40 /tmp/ccuFqAhq.ltrans0.ltrans.o + .text.PrintHex + 0x000001e8 0x5a /tmp/ccuFqAhq.ltrans0.ltrans.o + .text.DelaySysTick + 0x00000242 0x12 /tmp/ccuFqAhq.ltrans0.ltrans.o + .text.mini_itoa.part.0 + 0x00000254 0xc0 /tmp/ccuFqAhq.ltrans0.ltrans.o + .text.ssd1306_i2c_setup + 0x00000314 0x54 /tmp/ccuFqAhq.ltrans0.ltrans.o + .text.ssd1306_drawPixel + 0x00000368 0x3c /tmp/ccuFqAhq.ltrans0.ltrans.o + .text.beep 0x000003a4 0x68 /tmp/ccuFqAhq.ltrans0.ltrans.o + .text.led_blink + 0x0000040c 0x2a /tmp/ccuFqAhq.ltrans0.ltrans.o + .text.pet_reset + 0x00000436 0x30 /tmp/ccuFqAhq.ltrans0.ltrans.o + .text.read_buttons + 0x00000466 0x32 /tmp/ccuFqAhq.ltrans0.ltrans.o + .text.ssd1306_drawstr.constprop.0 + 0x00000498 0x78 /tmp/ccuFqAhq.ltrans0.ltrans.o + .text.draw_center_str + 0x00000510 0x26 /tmp/ccuFqAhq.ltrans0.ltrans.o + .text.ssd1306_drawFastHLine.constprop.0 + 0x00000536 0x4a /tmp/ccuFqAhq.ltrans0.ltrans.o + .text.ssd1306_drawFastVLine.constprop.0 + 0x00000580 0x44 /tmp/ccuFqAhq.ltrans0.ltrans.o + .text.ssd1306_drawRect.constprop.0 + 0x000005c4 0x40 /tmp/ccuFqAhq.ltrans0.ltrans.o + .text.draw_bar + 0x00000604 0x7a /tmp/ccuFqAhq.ltrans0.ltrans.o + .text.ssd1306_drawImage.constprop.0 + 0x0000067e 0xc0 /tmp/ccuFqAhq.ltrans0.ltrans.o + .text.internal_handle_input.constprop.0 + 0x0000073e 0xa /tmp/ccuFqAhq.ltrans0.ltrans.o + .text._write.constprop.0 + 0x00000748 0xe4 /tmp/ccuFqAhq.ltrans0.ltrans.o + .text.__puts_uart + 0x0000082c 0x14 /tmp/ccuFqAhq.ltrans0.ltrans.o + .text.handle_reset + 0x00000840 0x72 /tmp/ccuFqAhq.ltrans0.ltrans.o + 0x00000840 handle_reset + .text.vector_handler + 0x000008b2 0x5a /tmp/ccuFqAhq.ltrans0.ltrans.o + 0x000008b2 OPCM_IRQHandler + 0x000008b2 EXTI2_IRQHandler + 0x000008b2 TIM8_TRG_COM_IRQHandler + 0x000008b2 TIM8_CC_IRQHandler + 0x000008b2 USART_WKUP_IRQHandler + 0x000008b2 UART8_IRQHandler + 0x000008b2 SPI4_IRQHandler + 0x000008b2 NFC_IRQHandler + 0x000008b2 DFSDM0_IRQHandler + 0x000008b2 TIM1_CC_IRQHandler + 0x000008b2 HardFault_Handler + 0x000008b2 TIM10_IRQHandler + 0x000008b2 GPIOB_IRQHandler + 0x000008b2 IPC_CH2_Handler + 0x000008b2 USBPD_IRQHandler + 0x000008b2 TIM6_IRQHandler + 0x000008b2 GPIOA_IRQHandler + 0x000008b2 SysTick_Handler + 0x000008b2 CAN3_RX1_IRQHandler + 0x000008b2 I3C_ER_IRQHandler + 0x000008b2 PVD_IRQHandler + 0x000008b2 SDIO_IRQHandler + 0x000008b2 TIM9_BRK_IRQHandler + 0x000008b2 DMA2_Channel8_IRQHandler + 0x000008b2 CAN2_RX1_IRQHandler + 0x000008b2 EXTI3_IRQHandler + 0x000008b2 HSEM_Handler + 0x000008b2 UART1_IRQHandler + 0x000008b2 USBHS_IRQHandler + 0x000008b2 LPTIM2_IRQHandler + 0x000008b2 DMA2_Channel9_IRQHandler + 0x000008b2 TIM10_CC_IRQHandler + 0x000008b2 EXTI25_16_IRQHandler + 0x000008b2 I2C3_ER_IRQHandler + 0x000008b2 USBFS_IRQHandler + 0x000008b2 UART0_IRQHandler + 0x000008b2 USART8_IRQHandler + 0x000008b2 EXTI0_IRQHandler + 0x000008b2 I2C2_EV_IRQHandler + 0x000008b2 TIM10_TRG_COM_IRQHandler + 0x000008b2 LPTIM_IRQHandler + 0x000008b2 CAN1_RX0_IRQHandler + 0x000008b2 CAN3_SCE_IRQHandler + 0x000008b2 CAN2_SCE_IRQHandler + 0x000008b2 ADC1_2_IRQHandler + 0x000008b2 BB_IRQHandler + 0x000008b2 Break_Point_Handler + 0x000008b2 IPC_CH0_Handler + 0x000008b2 TIM2_CC_IRQHandler + 0x000008b2 SPI1_IRQHandler + 0x000008b2 USART5_IRQHandler + 0x000008b2 TAMPER_IRQHandler + 0x000008b2 TMR0_IRQHandler + 0x000008b2 AWU_IRQHandler + 0x000008b2 EXTI7_0_IRQHandler + 0x000008b2 CAN2_RX0_IRQHandler + 0x000008b2 OSCWakeUp_IRQHandler + 0x000008b2 TIM8_UP_IRQHandler + 0x000008b2 Ecall_M_Mode_Handler + 0x000008b2 ECDC_IRQHandler + 0x000008b2 SDMMC_IRQHandler + 0x000008b2 USART7_IRQHandler + 0x000008b2 DMA2_Channel2_IRQHandler + 0x000008b2 DMA1_Channel4_IRQHandler + 0x000008b2 ADC1_IRQHandler + 0x000008b2 TIM2_BRK_IRQHandler + 0x000008b2 USART6_IRQHandler + 0x000008b2 CAN3_RX0_IRQHandler + 0x000008b2 HSADC_IRQHandler + 0x000008b2 TIM9_UP_IRQHandler + 0x000008b2 USART3_IRQHandler + 0x000008b2 RTC_IRQHandler + 0x000008b2 DMA1_Channel7_IRQHandler + 0x000008b2 LED_IRQHandler + 0x000008b2 CAN1_RX1_IRQHandler + 0x000008b2 DVP_IRQHandler + 0x000008b2 UART5_IRQHandler + 0x000008b2 USBSS_IRQHandler + 0x000008b2 SWPMI_IRQHandler + 0x000008b2 USBPDWakeUp_IRQHandler + 0x000008b2 EXTI15_8_IRQHandler + 0x000008b2 TIM4_IRQHandler + 0x000008b2 DMA2_Channel1_IRQHandler + 0x000008b2 SWPMI_WKUP_IRQHandler + 0x000008b2 USBPD_WKUP_IRQHandler + 0x000008b2 I2C1_EV_IRQHandler + 0x000008b2 USBSSWakeup_IRQHandler + 0x000008b2 UART2_IRQHandler + 0x000008b2 USART4_IRQHandler + 0x000008b2 PWMX_IRQHandler + 0x000008b2 DMA1_Channel6_IRQHandler + 0x000008b2 UART4_IRQHandler + 0x000008b2 DMA2_Channel4_IRQHandler + 0x000008b2 TIM3_IRQHandler + 0x000008b2 RCC_IRQHandler + 0x000008b2 TIM1_TRG_COM_IRQHandler + 0x000008b2 DMA1_Channel1_IRQHandler + 0x000008b2 DMA2_Channel7_IRQHandler + 0x000008b2 QSPI1_IRQHandler + 0x000008b2 EXTI15_10_IRQHandler + 0x000008b2 ADC_IRQHandler + 0x000008b2 IPC_CH3_Handler + 0x000008b2 DMA1_Channel8_IRQHandler + 0x000008b2 I3C_EV_IRQHandler + 0x000008b2 TMR2_IRQHandler + 0x000008b2 I3C_WKUP_IRQHandler + 0x000008b2 DefaultIRQHandler + 0x000008b2 TIM12_IRQHandler + 0x000008b2 TIM7_IRQHandler + 0x000008b2 CAN2_TX_IRQHandler + 0x000008b2 TIM5_IRQHandler + 0x000008b2 I2C3_EV_IRQHandler + 0x000008b2 USB_IRQHandler + 0x000008b2 EXTI9_5_IRQHandler + 0x000008b2 PIOC_IRQHandler + 0x000008b2 TIM9_IRQHandler + 0x000008b2 LTDC_IRQHandler + 0x000008b2 SAI_IRQHandler + 0x000008b2 SPI2_IRQHandler + 0x000008b2 OSC32KCal_IRQHandler + 0x000008b2 IPC_CH1_Handler + 0x000008b2 I2C_IRQHandler + 0x000008b2 LPTIM1_WKUP_IRQHandler + 0x000008b2 TIM10_BRK_IRQHandler + 0x000008b2 TIM9_CC_IRQHandler + 0x000008b2 CAN1_TX_IRQHandler + 0x000008b2 DMA2_Channel5_IRQHandler + 0x000008b2 USB2_IRQHandler + 0x000008b2 USBHSWakeUp_IRQHandler + 0x000008b2 DMA1_Channel5_IRQHandler + 0x000008b2 EXTI4_IRQHandler + 0x000008b2 USB_LP_CAN1_RX0_IRQHandler + 0x000008b2 QSPI2_IRQHandler + 0x000008b2 RNG_IRQHandler + 0x000008b2 USB_HP_CAN1_TX_IRQHandler + 0x000008b2 LLE_IRQHandler + 0x000008b2 CMPWakeUp_IRQHandler + 0x000008b2 DMA1_Channel3_IRQHandler + 0x000008b2 FSMC_IRQHandler + 0x000008b2 ETH_IRQHandler + 0x000008b2 TIM1_UP_IRQHandler + 0x000008b2 LPTIMWakeUp_IRQHandler + 0x000008b2 WWDG_IRQHandler + 0x000008b2 USBHSWakeup_IRQHandler + 0x000008b2 DMA2_Channel11_IRQHandler + 0x000008b2 WDOG_BAT_IRQHandler + 0x000008b2 Ecall_U_Mode_Handler + 0x000008b2 I2C4_EV_IRQHandler + 0x000008b2 CAN3_TX_IRQHandler + 0x000008b2 TMR3_IRQHandler + 0x000008b2 DMA2_Channel6_IRQHandler + 0x000008b2 TIM2_IRQHandler + 0x000008b2 SW_Handler + 0x000008b2 TIM1_BRK_IRQHandler + 0x000008b2 GPHA_IRQHandler + 0x000008b2 OPA_IRQHandler + 0x000008b2 DMA2_Channel10_IRQHandler + 0x000008b2 EXTI1_IRQHandler + 0x000008b2 SPI0_IRQHandler + 0x000008b2 USB2_HOST_IRQHandler + 0x000008b2 LPTIM2_WKUP_IRQHandler + 0x000008b2 RTCAlarm_IRQHandler + 0x000008b2 TIM11_IRQHandler + 0x000008b2 TIM10_UP_IRQHandler + 0x000008b2 TIM9_TRG_COM_IRQHandler + 0x000008b2 UART7_IRQHandler + 0x000008b2 USART2_IRQHandler + 0x000008b2 UART6_IRQHandler + 0x000008b2 UHSIF_IRQHandler + 0x000008b2 ETHWakeUp_IRQHandler + 0x000008b2 I2C2_ER_IRQHandler + 0x000008b2 DMA1_Channel2_IRQHandler + 0x000008b2 TIM8_BRK_IRQHandler + 0x000008b2 TIM2_TRG_IRQHandler + 0x000008b2 CAN1_SCE_IRQHandler + 0x000008b2 FLASH_IRQHandler + 0x000008b2 USBFSWakeUp_IRQHandler + 0x000008b2 USART1_IRQHandler + 0x000008b2 OTG_FS_IRQHandler + 0x000008b2 SPI3_IRQHandler + 0x000008b2 USBFS_WakeUp_IRQHandler + 0x000008b2 UART3_IRQHandler + 0x000008b2 I2C1_ER_IRQHandler + 0x000008b2 FMC_IRQHandler + 0x000008b2 USB2_DEVICE_IRQHandler + 0x000008b2 LPTIM1_IRQHandler + 0x000008b2 DFSDM1_IRQHandler + 0x000008b2 TMR1_IRQHandler + 0x000008b2 I2C4_ER_IRQHandler + 0x000008b2 SERDES_IRQHandler + 0x000008b2 USBSS_LINK_IRQHandler + 0x000008b2 USBWakeUp_IRQHandler + 0x000008b2 DMA2_Channel3_IRQHandler + 0x000008fe NMI_Handler + 0x000008fe NMI_RCC_CSS_IRQHandler + .text.strlen 0x0000090c 0x12 /tmp/ccuFqAhq.ltrans0.ltrans.o + 0x0000090c strlen + .text.mini_vpprintf + 0x0000091e 0x1c2 /tmp/ccuFqAhq.ltrans0.ltrans.o + .text.printf 0x00000ae0 0x24 /tmp/ccuFqAhq.ltrans0.ltrans.o + 0x00000ae0 printf + .text.ssd1306_i2c_error.isra.0 + 0x00000b04 0x20 /tmp/ccuFqAhq.ltrans0.ltrans.o + .text.ssd1306_i2c_send.constprop.0 + 0x00000b24 0x122 /tmp/ccuFqAhq.ltrans0.ltrans.o + .text.ssd1306_cmd + 0x00000c46 0x1c /tmp/ccuFqAhq.ltrans0.ltrans.o + .text.mini_vsnprintf + 0x00000c62 0x38 /tmp/ccuFqAhq.ltrans0.ltrans.o + .text.snprintf + 0x00000c9a 0x16 /tmp/ccuFqAhq.ltrans0.ltrans.o + 0x00000c9a snprintf + .text.memset 0x00000cb0 0x12 /tmp/ccuFqAhq.ltrans0.ltrans.o + 0x00000cb0 memset + .text.ssd1306_setbuf.constprop.0 + 0x00000cc2 0xc /tmp/ccuFqAhq.ltrans0.ltrans.o + .text.memcpy 0x00000cce 0x1c /tmp/ccuFqAhq.ltrans0.ltrans.o + 0x00000cce memcpy + .text.ssd1306_refresh + 0x00000cea 0x5c /tmp/ccuFqAhq.ltrans0.ltrans.o + .text.SystemInit + 0x00000d46 0x54 /tmp/ccuFqAhq.ltrans0.ltrans.o + 0x00000d46 SystemInit + .text.startup.main + 0x00000d9a 0x8ea /tmp/ccuFqAhq.ltrans0.ltrans.o + 0x00000d9a main + *(.rodata) + *(.rodata*) + *fill* 0x00001684 0x0 + .rodata.ssd1306_i2c_error.isra.0.str1.4 + 0x00001684 0x12e /tmp/ccuFqAhq.ltrans0.ltrans.o + 0x2d (size before relaxing) + .rodata.main.str1.4 + 0x000017b2 0x89 /tmp/ccuFqAhq.ltrans0.ltrans.o + *fill* 0x000017b2 0x2 + .rodata.main 0x000017b4 0x18 /tmp/ccuFqAhq.ltrans0.ltrans.o + .rodata.icon_stats + 0x000017cc 0x20 /tmp/ccuFqAhq.ltrans0.ltrans.o + .rodata.icon_heal + 0x000017ec 0x20 /tmp/ccuFqAhq.ltrans0.ltrans.o + .rodata.icon_clean + 0x0000180c 0x20 /tmp/ccuFqAhq.ltrans0.ltrans.o + .rodata.icon_sleep + 0x0000182c 0x20 /tmp/ccuFqAhq.ltrans0.ltrans.o + .rodata.icon_play + 0x0000184c 0x20 /tmp/ccuFqAhq.ltrans0.ltrans.o + .rodata.icon_feed + 0x0000186c 0x20 /tmp/ccuFqAhq.ltrans0.ltrans.o + .rodata.pana_dead + 0x0000188c 0x80 /tmp/ccuFqAhq.ltrans0.ltrans.o + .rodata.pana_sleep + 0x0000190c 0x80 /tmp/ccuFqAhq.ltrans0.ltrans.o + .rodata.pana_eat + 0x0000198c 0x80 /tmp/ccuFqAhq.ltrans0.ltrans.o + .rodata.pana_sad + 0x00001a0c 0x80 /tmp/ccuFqAhq.ltrans0.ltrans.o + .rodata.pana_happy + 0x00001a8c 0x80 /tmp/ccuFqAhq.ltrans0.ltrans.o + .rodata.pana_blink + 0x00001b0c 0x80 /tmp/ccuFqAhq.ltrans0.ltrans.o + .rodata.str1.4 + 0x00001b8c 0x76 /tmp/ccuFqAhq.ltrans0.ltrans.o + .rodata.errstr + 0x00001b8c 0x14 /tmp/ccuFqAhq.ltrans0.ltrans.o + .rodata.fontdata + 0x00001ba0 0x800 /tmp/ccuFqAhq.ltrans0.ltrans.o + .rodata.ssd1306_init_array + 0x000023a0 0x1a /tmp/ccuFqAhq.ltrans0.ltrans.o + *fill* 0x000023ba 0x2 + .rodata.pana_idle + 0x000023bc 0x80 /tmp/ccuFqAhq.ltrans0.ltrans.o + .rodata.menu_icons + 0x0000243c 0x18 /tmp/ccuFqAhq.ltrans0.ltrans.o + .rodata.pana_frames + 0x00002454 0x1c /tmp/ccuFqAhq.ltrans0.ltrans.o + .rodata.menu_labels + 0x00002470 0x18 /tmp/ccuFqAhq.ltrans0.ltrans.o + .rodata.spr_grave + 0x00002488 0x80 /tmp/ccuFqAhq.ltrans0.ltrans.o + *(.gnu.linkonce.t.*) + 0x00002508 . = ALIGN (0x4) + +.fini 0x00002508 0x0 + *(SORT_NONE(.fini)) + 0x00002508 . = ALIGN (0x4) + [!provide] PROVIDE (_etext = .) + [!provide] PROVIDE (_eitcm = .) + +.preinit_array 0x00002508 0x0 + [!provide] PROVIDE (__preinit_array_start = .) + *(.preinit_array) + [!provide] PROVIDE (__preinit_array_end = .) + +.init_array 0x00002508 0x0 + 0x00002508 PROVIDE (__init_array_start = .) + *(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)) + *(.init_array EXCLUDE_FILE(*crtend?.o *crtend.o *crtbegin?.o *crtbegin.o) .ctors) + 0x00002508 PROVIDE (__init_array_end = .) + +.fini_array 0x00002508 0x0 + [!provide] PROVIDE (__fini_array_start = .) + *(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)) + *(.fini_array EXCLUDE_FILE(*crtend?.o *crtend.o *crtbegin?.o *crtbegin.o) .dtors) + [!provide] PROVIDE (__fini_array_end = .) + +.ctors + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT_BY_NAME(.ctors.*)) + *(.ctors) + +.dtors + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT_BY_NAME(.dtors.*)) + *(.dtors) + +.dalign 0x20000000 0x0 load address 0x00002508 + 0x20000000 . = ALIGN (0x4) + 0x20000000 PROVIDE (_data_vma = .) + +.dlalign 0x00002508 0x0 + 0x00002508 . = ALIGN (0x4) + 0x00002508 PROVIDE (_data_lma = .) + +.data 0x20000000 0x8 load address 0x00002508 + 0x20000000 . = ALIGN (0x4) + 0x200003fc __global_pointer$ = (. + 0x3fc) + *(.gnu.linkonce.r.*) + *(.data .data.*) + *(.gnu.linkonce.d.*) + 0x20000000 . = ALIGN (0x8) + *(.sdata .sdata.*) + *(.sdata2*) + *(.gnu.linkonce.s.*) + 0x20000000 . = ALIGN (0x8) + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + .srodata.spr_poop + 0x20000000 0x8 /tmp/ccuFqAhq.ltrans0.ltrans.o + 0x20000008 . = ALIGN (0x4) + 0x20000008 PROVIDE (_edata = .) + +.rela.dyn 0x20000008 0x0 load address 0x00002510 + .rela.text.handle_reset + 0x20000008 0x0 /tmp/ccuFqAhq.ltrans0.ltrans.o + +.bss 0x20000008 0x41c load address 0x00002510 + 0x20000008 . = ALIGN (0x4) + 0x20000008 PROVIDE (_sbss = .) + *(.sbss*) + .sbss.anim_exp + 0x20000008 0x1 /tmp/ccuFqAhq.ltrans0.ltrans.o + *fill* 0x20000009 0x3 + .sbss.frame 0x2000000c 0x4 /tmp/ccuFqAhq.ltrans0.ltrans.o + .sbss.tick_acc + 0x20000010 0x2 /tmp/ccuFqAhq.ltrans0.ltrans.o + .sbss.anim_timer + 0x20000012 0x1 /tmp/ccuFqAhq.ltrans0.ltrans.o + .sbss.cursor 0x20000013 0x1 /tmp/ccuFqAhq.ltrans0.ltrans.o + .sbss.screen 0x20000014 0x1 /tmp/ccuFqAhq.ltrans0.ltrans.o + *(.gnu.linkonce.sb.*) + *(.bss*) + *fill* 0x20000015 0x3 + .bss.pet 0x20000018 0xc /tmp/ccuFqAhq.ltrans0.ltrans.o + .bss.ssd1306_buffer + 0x20000024 0x400 /tmp/ccuFqAhq.ltrans0.ltrans.o + *(.gnu.linkonce.b.*) + *(COMMON*) + 0x20000424 . = ALIGN (0x4) + 0x20000424 PROVIDE (_ebss = .) + [!provide] PROVIDE (_end = _ebss) + [!provide] PROVIDE (end = .) + 0x20000800 PROVIDE (_eusrstack = (ORIGIN (RAM) + LENGTH (RAM))) + +/DISCARD/ + *(.note .note.*) + *(.eh_frame .eh_frame.*) + *(.comment .comment.*) + *(.ARM.extab* .gnu.linkonce.armextab.*) + *(.ARM.exidx*) +OUTPUT(tama.elf elf32-littleriscv) + +.riscv.attributes + 0x00000000 0x25 + .riscv.attributes + 0x00000000 0x25 /tmp/ccuFqAhq.ltrans0.ltrans.o + .riscv.attributes + 0x00000025 0x1f ../ch32v003fun/ch32fun//../misc/libgcc.a(div.o) + +.debug_info 0x00000000 0x49c5 + .debug_info 0x00000000 0x25b8 /tmp/ccuFqAhq.ltrans0.ltrans.o + .debug_info 0x000025b8 0x1159 /tmp/cc6O5Yfp.debug.temp.o + 0x000025b8 ch32fun.c.3da016ab + .debug_info 0x00003711 0x1257 /tmp/ccQWTvKu.debug.temp.o + 0x00003711 tama.c.f19bf6d4 + .debug_info 0x00004968 0x5d ../ch32v003fun/ch32fun//../misc/libgcc.a(div.o) + +.debug_abbrev 0x00000000 0x7c5 + .debug_abbrev 0x00000000 0x20c /tmp/ccuFqAhq.ltrans0.ltrans.o + .debug_abbrev 0x0000020c 0x278 /tmp/cc6O5Yfp.debug.temp.o + .debug_abbrev 0x00000484 0x319 /tmp/ccQWTvKu.debug.temp.o + .debug_abbrev 0x0000079d 0x28 ../ch32v003fun/ch32fun//../misc/libgcc.a(div.o) + +.debug_loclists + 0x00000000 0x20c5 + .debug_loclists + 0x00000000 0x20c5 /tmp/ccuFqAhq.ltrans0.ltrans.o + +.debug_aranges 0x00000000 0x200 + .debug_aranges + 0x00000000 0x1e0 /tmp/ccuFqAhq.ltrans0.ltrans.o + .debug_aranges + 0x000001e0 0x20 ../ch32v003fun/ch32fun//../misc/libgcc.a(div.o) + +.debug_rnglists + 0x00000000 0x4a6 + .debug_rnglists + 0x00000000 0x4a6 /tmp/ccuFqAhq.ltrans0.ltrans.o + +.debug_line 0x00000000 0x4835 + .debug_line 0x00000000 0x45f0 /tmp/ccuFqAhq.ltrans0.ltrans.o + .debug_line 0x000045f0 0x76 /tmp/cc6O5Yfp.debug.temp.o + .debug_line 0x00004666 0x7c /tmp/ccQWTvKu.debug.temp.o + .debug_line 0x000046e2 0x153 ../ch32v003fun/ch32fun//../misc/libgcc.a(div.o) + +.debug_str 0x00000000 0xf6f + .debug_str 0x00000000 0xf6f /tmp/ccuFqAhq.ltrans0.ltrans.o + 0x1c2 (size before relaxing) + .debug_str 0x00000f6f 0x751 /tmp/cc6O5Yfp.debug.temp.o + .debug_str 0x00000f6f 0x994 /tmp/ccQWTvKu.debug.temp.o + .debug_str 0x00000f6f 0xd9 ../ch32v003fun/ch32fun//../misc/libgcc.a(div.o) + +.debug_line_str + 0x00000000 0x33f + .debug_line_str + 0x00000000 0x33f /tmp/ccuFqAhq.ltrans0.ltrans.o + 0x157 (size before relaxing) + .debug_line_str + 0x0000033f 0x246 /tmp/cc6O5Yfp.debug.temp.o + .debug_line_str + 0x0000033f 0x1e5 /tmp/ccQWTvKu.debug.temp.o + .debug_line_str + 0x0000033f 0x92 ../ch32v003fun/ch32fun//../misc/libgcc.a(div.o) + +.debug_frame 0x00000000 0x5b0 + .debug_frame 0x00000000 0x5b0 /tmp/ccuFqAhq.ltrans0.ltrans.o diff --git a/tama_ext.bin b/tama_ext.bin new file mode 100755 index 0000000..e69de29