commit ddbf083d1b045a08a008ca44d95743ba3e0d339e Author: xenia Date: Wed Feb 7 19:32:27 2024 +0100 Initial commit diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..3550a30 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use flake diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b15f48a --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.direnv +inc +ultlf +xenrom/data diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..e43ff24 --- /dev/null +++ b/flake.lock @@ -0,0 +1,459 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1694529238, + "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "ff7b65b44d01cf9ba6a71320833626af21126384", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { + "inputs": { + "systems": "systems_2" + }, + "locked": { + "lastModified": 1694529238, + "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "ff7b65b44d01cf9ba6a71320833626af21126384", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_3": { + "inputs": { + "systems": "systems_3" + }, + "locked": { + "lastModified": 1694529238, + "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "ff7b65b44d01cf9ba6a71320833626af21126384", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_4": { + "inputs": { + "systems": "systems_4" + }, + "locked": { + "lastModified": 1694529238, + "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "ff7b65b44d01cf9ba6a71320833626af21126384", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_5": { + "inputs": { + "systems": "systems_5" + }, + "locked": { + "lastModified": 1694529238, + "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "ff7b65b44d01cf9ba6a71320833626af21126384", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_6": { + "inputs": { + "systems": "systems_6" + }, + "locked": { + "lastModified": 1694529238, + "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "ff7b65b44d01cf9ba6a71320833626af21126384", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_7": { + "inputs": { + "systems": "systems_7" + }, + "locked": { + "lastModified": 1694529238, + "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "ff7b65b44d01cf9ba6a71320833626af21126384", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "fox32": { + "inputs": { + "flake-utils": "flake-utils_2", + "fox32rom": "fox32rom", + "nixpkgs": "nixpkgs_3" + }, + "locked": { + "dirtyRev": "7777dfd3ae2dd85b12dcd60335214a78c7774c60-dirty", + "dirtyShortRev": "7777dfd-dirty", + "lastModified": 1690147702, + "narHash": "sha256-Tn99hPzeOzZ2PaU/22HNO7VoZlMbWUAzPuMV/hfYxS8=", + "type": "git", + "url": "file:../fox32" + }, + "original": { + "type": "git", + "url": "file:../fox32" + } + }, + "fox32asm": { + "inputs": { + "flake-utils": "flake-utils_4", + "nixpkgs": "nixpkgs" + }, + "locked": { + "lastModified": 1706813730, + "narHash": "sha256-U1fg1EId3JOl5hKvMMBGKTMBJ/b94TCL7Z0+NLa/m6M=", + "ref": "refs/heads/main", + "rev": "30da72b3c70a1f43b0de4ee8e2e9d190be1d9bb9", + "revCount": 58, + "type": "git", + "url": "file:../fox32asm/" + }, + "original": { + "type": "git", + "url": "file:../fox32asm/" + } + }, + "fox32asm_2": { + "inputs": { + "flake-utils": "flake-utils_5", + "nixpkgs": "nixpkgs_4" + }, + "locked": { + "dirtyRev": "30da72b3c70a1f43b0de4ee8e2e9d190be1d9bb9-dirty", + "dirtyShortRev": "30da72b-dirty", + "lastModified": 1706813730, + "narHash": "sha256-HfMO2G4V3RiGrAPrhlpi5yziTONpyxs/M4RjyuGmMHE=", + "type": "git", + "url": "file:../fox32asm" + }, + "original": { + "type": "git", + "url": "file:../fox32asm" + } + }, + "fox32asm_3": { + "inputs": { + "flake-utils": "flake-utils_7", + "nixpkgs": "nixpkgs_5" + }, + "locked": { + "lastModified": 1706813730, + "narHash": "sha256-U1fg1EId3JOl5hKvMMBGKTMBJ/b94TCL7Z0+NLa/m6M=", + "ref": "refs/heads/main", + "rev": "30da72b3c70a1f43b0de4ee8e2e9d190be1d9bb9", + "revCount": 58, + "type": "git", + "url": "file:../fox32asm/" + }, + "original": { + "type": "git", + "url": "file:../fox32asm/" + } + }, + "fox32rom": { + "inputs": { + "flake-utils": "flake-utils_3", + "fox32asm": "fox32asm", + "nixpkgs": "nixpkgs_2" + }, + "locked": { + "lastModified": 1706819209, + "narHash": "sha256-yOOADll1zrrpuVtLC1SS/bSTzmNTZBUUXhAAiTVz7PU=", + "ref": "refs/heads/main", + "rev": "b53476353d99cadafba216cddcb29e83326685e4", + "revCount": 180, + "type": "git", + "url": "file:../fox32rom/" + }, + "original": { + "type": "git", + "url": "file:../fox32rom/" + } + }, + "fox32rom_2": { + "inputs": { + "flake-utils": "flake-utils_6", + "fox32asm": "fox32asm_3", + "nixpkgs": "nixpkgs_6" + }, + "locked": { + "lastModified": 1706819209, + "narHash": "sha256-yOOADll1zrrpuVtLC1SS/bSTzmNTZBUUXhAAiTVz7PU=", + "ref": "refs/heads/main", + "rev": "b53476353d99cadafba216cddcb29e83326685e4", + "revCount": 180, + "type": "git", + "url": "file:../fox32rom" + }, + "original": { + "type": "git", + "url": "file:../fox32rom" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1697009197, + "narHash": "sha256-viVRhBTFT8fPJTb1N3brQIpFZnttmwo3JVKNuWRVc3s=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "01441e14af5e29c9d27ace398e6dd0b293e25a54", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "type": "indirect" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1697009197, + "narHash": "sha256-viVRhBTFT8fPJTb1N3brQIpFZnttmwo3JVKNuWRVc3s=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "01441e14af5e29c9d27ace398e6dd0b293e25a54", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "type": "indirect" + } + }, + "nixpkgs_3": { + "locked": { + "lastModified": 1697009197, + "narHash": "sha256-viVRhBTFT8fPJTb1N3brQIpFZnttmwo3JVKNuWRVc3s=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "01441e14af5e29c9d27ace398e6dd0b293e25a54", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "type": "indirect" + } + }, + "nixpkgs_4": { + "locked": { + "lastModified": 1697009197, + "narHash": "sha256-viVRhBTFT8fPJTb1N3brQIpFZnttmwo3JVKNuWRVc3s=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "01441e14af5e29c9d27ace398e6dd0b293e25a54", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "type": "indirect" + } + }, + "nixpkgs_5": { + "locked": { + "lastModified": 1697009197, + "narHash": "sha256-viVRhBTFT8fPJTb1N3brQIpFZnttmwo3JVKNuWRVc3s=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "01441e14af5e29c9d27ace398e6dd0b293e25a54", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "type": "indirect" + } + }, + "nixpkgs_6": { + "locked": { + "lastModified": 1697009197, + "narHash": "sha256-viVRhBTFT8fPJTb1N3brQIpFZnttmwo3JVKNuWRVc3s=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "01441e14af5e29c9d27ace398e6dd0b293e25a54", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "type": "indirect" + } + }, + "nixpkgs_7": { + "locked": { + "lastModified": 1697009197, + "narHash": "sha256-viVRhBTFT8fPJTb1N3brQIpFZnttmwo3JVKNuWRVc3s=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "01441e14af5e29c9d27ace398e6dd0b293e25a54", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "type": "indirect" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "fox32": "fox32", + "fox32asm": "fox32asm_2", + "fox32rom": "fox32rom_2", + "nixpkgs": "nixpkgs_7" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_2": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_3": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_4": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_5": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_6": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_7": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..b43230a --- /dev/null +++ b/flake.nix @@ -0,0 +1,80 @@ +{ + description = "test stuff for fox32"; + + inputs = { + fox32asm.url = "git+file:../fox32asm"; + fox32.url = "git+file:../fox32"; + fox32rom.url = "git+file:../fox32rom"; + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = { self, nixpkgs, fox32asm, fox32, fox32rom, flake-utils }: + flake-utils.lib.eachDefaultSystem (sys: + let pkgs = import nixpkgs { system = sys; }; + asm = fox32asm.packages.${sys}.fox32asm; + emulator = fox32.packages.${sys}.fox32; + romdev = fox32rom.packages.${sys}.fox32rom-dev; + py = pkgs.python310; + + ultlf = pkgs.stdenv.mkDerivation { + name = "ultlf"; + src = pkgs.fetchFromGitHub { + owner = "ultlang"; repo = "ultlf"; + rev = "9b867a6cd04a2daf6d44ab9731ecf426d535a8a2"; + hash = "sha256-Y7WrkvC+GNZluqzIuXm/2WIlFj/nvJNWTXU6gCvOf5E="; + }; + dontBuild = true; + installPhase = '' + mkdir -p $out/data + cp ultlf-data/{codepoints.json,trimmed_baselines.json,data.json} $out/data + ''; + }; + + rom = pkgs.stdenv.mkDerivation rec { + pname = "xen32"; + version = "0.0-alpha"; + + src = ./. ; + + buildPhase = '' + mkdir -p inc + mkdir -p xenrom/data + cp ${romdev}/dev/fox32rom.def inc + mkdir -p ultlf + cp ${ultlf}/data/* ultlf + + mkdir -p $out/bin/ + ${py}/bin/python3 ./gen/fontgen.py + ${py}/bin/python3 ./gen/logogen.py + ${py}/bin/python3 ./gen/vergen.py + ${asm}/bin/fox32asm xenrom/main.asm $out/bin/xen32.rom + ''; + + NIX_SEMVER = version; + NIX_GIT_SHA_SHORT = if self ? rev then builtins.substring 0 7 self.rev else "dirty"; + }; + + in rec { + packages.rom = rom; + + packages.run = pkgs.writeScriptBin "xen32-run" '' + ${emulator}/bin/fox32 --rom ${packages.rom}/bin/xen32.rom + ''; + + packages.ultlf = ultlf; + + devShells.default = pkgs.mkShell { + packages = [ asm emulator py ]; + shellHook = '' + mkdir -p inc + mkdir -p xenrom/data + cp ${romdev}/dev/fox32rom.def inc + mkdir -p ultlf + cp ${ultlf}/data/* ultlf + ${py}/bin/python3 ./gen/fontgen.py + ${py}/bin/python3 ./gen/logogen.py + ''; + }; + } + ); +} diff --git a/gen/fontgen.py b/gen/fontgen.py new file mode 100644 index 0000000..237c74d --- /dev/null +++ b/gen/fontgen.py @@ -0,0 +1,66 @@ +import json +import struct + +# generates: +# font_data.dat (binary file, expected to load at location 0xf000_0100) +# font_data.inc (fox32 assembly) +# font_data.inc defines constants +# N_CHARS: number of defined characters (u32) +# CHAR_TABLE: pointer to main char table (&Char) +# UNKNOWN_CHAR: pointer to unknown character (&Char) +# +# struct Char { +# width: u8, height: u8, baseline: u8, +# data_ptr: &[u8], +# } (7 bytes) + +DATA_FILE_ORIGIN = 0xf000_0100 + +BASELINE = 7 +N_CHARS = 127 + +codepoints = json.load(open("ultlf/codepoints.json")) +font_data = json.load(open("ultlf/data.json")) +baselines = json.load(open("ultlf/trimmed_baselines.json")) + +UNKNOWN = [ + "# ### #", + "# # # #", + "# # #", + "# # #", + "# # #", + "# #", + "# # #", +] + +with open("xenrom/data/font_data.inc", "w") as inc, open("xenrom/data/font_data.dat", "wb") as dat: + table = b'' + char_data = b'' + + for ch in [None] + list(range(N_CHARS)): + if ch in codepoints: + i = codepoints.index(ch) + glyph = font_data[i] + baseline = baselines[i] + if '?' in "".join(glyph): + print(f"Font doesn't have char {ch}") + glyph = UNKNOWN + baseline = 6 + else: + glyph = UNKNOWN + baseline = 6 + print(f"Couldn't find char {ch}") + + table += struct.pack("BBBI", len(glyph[0]), len(glyph), baseline, DATA_FILE_ORIGIN + len(char_data)) + + for line in glyph: + for ch in glyph: + char_data += b'\x00' if ch == ' ' else b'\x01' + + dat.write(char_data + table) + + inc.write(f''' +const N_CHARS: {N_CHARS} +const CHAR_TABLE: {hex(DATA_FILE_ORIGIN + len(char_data))} +const UNKNOWN_CHAR: {hex(DATA_FILE_ORIGIN)} + ''') diff --git a/gen/logogen.py b/gen/logogen.py new file mode 100644 index 0000000..d23676a --- /dev/null +++ b/gen/logogen.py @@ -0,0 +1,73 @@ +import struct +import math +import random +random.seed(0) + +LOGO = ''' +BBBB BBBB BB B + B B B + BB BBBB B B + B B B +BBBB BBBB B BB + + + WWWW WWWW + W W + WWWW WWWW + W W + WWWW WWWW +'''[1:-1] + +LOGO = ''' +RRRR RRRR RR R BBBB BBBB + R R R B B + RR RRRR R R BBBB BBBB + R R R B B +RRRR RRRR R RR BBBB BBBB + + + WWWW WWWW + W W W + W W WWWW + W W W + WWWW WWWW +'''[1:-1] +LOGO = LOGO.split("\n") +print(LOGO) + +width = max(len(row) for row in LOGO) +height = len(LOGO) +print("width =", width) +print("height =", height) + +with open("xenrom/data/logo.dat", "wb") as data_out, open("xenrom/data/logo.inc", "w") as inc: + for y in range(height): + row = LOGO[y] + for x in range(width): + c = row[x] if x < len(row) else ' ' + data_out.write(b'\x00' if c == ' ' else b'\x01' if c == 'B' else b'\x02' if c == 'W' else b'\x03') + inc.write(f"const LOGO_WIDTH: {hex(width)}\n") + inc.write(f"const LOGO_HEIGHT: {hex(height)}\n") + +with open("xenrom/data/logo_cycle.dat", "wb") as data, open("xenrom/data/logo_cycle.inc", "w") as inc: + + T = 60 + N = T * 4 + r = 0 + + for i in range(N): + if i < T or i > 3 * T: + f = 0.5 - (1/2 * math.cos((i/T) * math.pi)) + elif i < 180: + f = 0.75 - (1/4 * math.cos((i/T) * math.pi)) + + if i == 3 * T - 10: + r = 1 + if i == 3 * T: + r = 2 + if i == 3 * T + 10: + r = 0 + + data.write(struct.pack("BB", min(255, int(256 * f)), r)) + + inc.write(f"const LOGO_LENGTH: {N}") diff --git a/gen/vergen.py b/gen/vergen.py new file mode 100644 index 0000000..c370f35 --- /dev/null +++ b/gen/vergen.py @@ -0,0 +1,8 @@ +import os + +with open("xenrom/data/version.inc", "w") as f: + version = os.getenv("NIX_SEMVER", "(unknown version)") + git_sha = os.getenv("NIX_GIT_SHA_SHORT", "(unknown git hash)") + + f.write(f'version_str: data.str "{version}" data.8 0\n') + f.write(f'sha_str: data.str "{git_sha}" data.8 0\n') diff --git a/xenrom/logo.asm b/xenrom/logo.asm new file mode 100644 index 0000000..5c377f5 --- /dev/null +++ b/xenrom/logo.asm @@ -0,0 +1,183 @@ +show_logo: + icl ; disable interrupts + + ; Save old interrupt handler + mov r0, [0x3fc] + push r0 + + ; Set vsync interrupt handler to logo display + mov [0x3fc], intr_vsync_logo + + mov [SHOWING_LOGO], 1 + mov [FRAMENR], 0 + + ise ; Enable interrupts + + ; Wait for logo display interrupt to return + show_logo_wait: + cmp [SHOWING_LOGO], 1 + ifz jmp show_logo_wait + + icl ; Restore interrupt handler + pop r0 + mov [0x3fc], r0 + + ; Draw logo in black (clear) + mov r0, 0 + mov r1, 0 + call draw_logo + + ret + +cycle_data: #include_bin "data/logo_cycle.dat" +; defines LOGO_LENGTH +#include "data/logo_cycle.inc" + +intr_vsync_logo: + ; [rsp] = interrupt number + ; [rsp+4] = flags + ; [rsp+8] = previous instuction + + inc [FRAMENR] + + mov r2, [FRAMENR] + cmp r2, LOGO_LENGTH + ifgteq mov [SHOWING_LOGO], 0 + + ; fetch brightness and glitchiness + mul r2, 2 + add r2, cycle_data + movz.8 r0, [r2] + inc r2 + movz.8 r1, [r2] + + call draw_logo + + add rsp, 4 ; pop interrupt number + reti + + +boot_logo: #include_bin "data/logo.dat" +; defines LOGO_WIDTH, LOGO_HEIGHT: +#include "data/logo.inc" + +const LOGO_SCALE: 8 ; pixels per pixel in logo + +; input: r0: 0-255 color multiplier +; input: r1: glitch effect +draw_logo: + mov r31, r0 + mov r30, r1 + + ; r0: x counter + ; r1: y counter + ; r2: pointer to current boot logo index + ; r5: x on screen start + ; r6: y on screen start + + mov r5, SCREEN_WIDTH + mov r6, LOGO_WIDTH + mul r6, LOGO_SCALE + sub r5, r6 + ror r5, 1 + + mov r6, SCREEN_HEIGHT + mov r7, LOGO_HEIGHT + mul r7, LOGO_SCALE + sub r6, r7 + ror r6, 1 + + mov r2, boot_logo + + mov r1, 0 + draw_loop_y: + cmp r1, LOGO_HEIGHT + ifz jmp draw_logo_done + + mov r0, 0 + draw_loop_x: + cmp r0, LOGO_WIDTH + ifz jmp draw_loop_x_done + + ; r3: color to draw + mov r3, 0x00000000 ; black + + xor r2, r30 + cmp.8 [r2], 1 + ifz mov r3, 0x00040401 ; blue + cmp.8 [r2], 2 + ifz mov r3, 0x00040403; white + cmp.8 [r2], 3 + ifz mov r3, 0x00010204; orange + xor r2, r30 + + cmp r30, 0 + ifz jmp no_color_glitch + cmp r3, 0 + ifnz xor r3, r0 + ifnz xor r3, r1 + + no_color_glitch: + + mov r28, r31 + srl r28, 2 + mul r3, r28 ; brightness + + xor r3, r29 + + or r3, 0xff000000 + + ; r4: screen buffer index of top left + mov r4, r6 + mov r7, r1 + mul r7, LOGO_SCALE + add r4, r7 + mul r4, 640 + + add r4, r5 + mov r7, r0 + mul r7, LOGO_SCALE + add r4, r7 + mul r4, 4 + add r4, BG_FRAMEBUFFER + + ; r7: paint x + ; r8: point y + + mov r7, 0 + draw_loop_px: + cmp r7, LOGO_SCALE + ifz jmp draw_loop_px_done + + mov r8, 0 + draw_loop_py: + cmp r8, LOGO_SCALE + ifz jmp draw_loop_py_done + + mov r9, r8 + mul r9, 640 + add r9, r7 + mul r9, 4 + add r9, r4 + + mov [r9], r3 + + inc r8 + jmp draw_loop_py + draw_loop_py_done: + + inc r7 + jmp draw_loop_px + draw_loop_px_done: + + + inc r2 + inc r0 + jmp draw_loop_x + draw_loop_x_done: + inc r1 + jmp draw_loop_y + + draw_logo_done: + ret + diff --git a/xenrom/main.asm b/xenrom/main.asm new file mode 100644 index 0000000..bb77664 --- /dev/null +++ b/xenrom/main.asm @@ -0,0 +1,99 @@ +; Constants + +const SYS_STACK_START: 0x03fffff0 +const BG_FRAMEBUFFER: 0x2000000 + +const SCREEN_WIDTH: 640 +const SCREEN_HEIGHT: 480 + + +; Globals +const FRAMENR: 0x00000000 +const SHOWING_LOGO: 0x00000004 + +org 0xf0000000 + +entry: + mcl ; disable MMU + mov rsp, SYS_STACK_START ; set stack pointer + + mov r0, entry_str + call serial_print + mov r0, version_str_1 + call serial_print + mov r0, version_str + call serial_print + mov r0, version_str_2 + call serial_print + mov r0, sha_str + call serial_print + mov r0, version_str_3 + call serial_print + + call show_logo + + mov r0, booting_str + call serial_print + + halt + +entry_str: data.str "== Welcome to Xen32OS" data.8 0 +; defines version_str, sha_str +#include "data/version.inc" + +version_str_1: data.str " - version " data.8 0 +version_str_2: data.str " (" data.8 0 +version_str_3: data.str ") ==" data.8 10 data.8 0 + +booting_str: data.str "booting..." data.8 10 data.8 0 + +; input: +; str: &str0 @ r0 +; returns: +; nothing +; clobbers: +; r0 +serial_print: + cmp.8 [r0], 0 + ifz ret + out 0x00000000, [r0] + inc r0 + jmp serial_print + +; input: +; n: u64 @ r0 +; returns +; nothing +; clobbers: +; r0 +serial_print_num: + cmp r0, 0 + ifz jmp serial_print_num_zero + call serial_print_num_nonzero + ret + + serial_print_num_nonzero: + cmp r0, 0 + ifz ret + + push r0 + div r0, 10 + call serial_print_num_nonzero + pop r0 + rem r0, 10 + add r0, 48 + out 0x00000000, r0 + ret + + serial_print_num_zero: + mov r0, serial_print_num_str_zero + jmp serial_print ; tail call + + serial_print_num_str_zero: data.str "0" data.8 0 + +serial_print_nl: + out 0x00000000, 10 + ret + +#include "logo.asm" + diff --git a/xenrom/text.asm b/xenrom/text.asm new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/xenrom/text.asm @@ -0,0 +1 @@ +