Remove Rust emulator

This commit is contained in:
Ry 2022-10-26 18:02:30 -07:00
parent 675a39e813
commit fb9f8ccf93
20 changed files with 0 additions and 7817 deletions

3222
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,21 +0,0 @@
[package]
name = "fox32"
version = "0.5.0"
authors = ["ry"]
edition = "2021"
build = "build.rs"
[dependencies]
chrono = "0.4"
image = "0.24"
log = "0.4"
pixels = "0.9.0"
rfd = "0.7.0"
ringbuf = "0.2"
rodio = "0.15.0"
winit = "0.26"
winit_input_helper = "0.11"
[build-dependencies]
anyhow = "1.0"
vergen = { version = "7", default-features = false, features = ["build", "git"] }

21
LICENSE
View File

@ -1,21 +0,0 @@
MIT License
Copyright (c) 2022 ryfox/ry755
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1,9 +0,0 @@
use anyhow::Result;
use vergen::{Config, ShaKind, vergen};
fn main() -> Result<()> {
let mut config = Config::default();
*config.git_mut().sha_kind_mut() = ShaKind::Short;
*config.git_mut().skip_if_error_mut() = true;
vergen(config)
}

View File

@ -1,51 +0,0 @@
# Encoding
```
size instr . cond dest src <src> <dest>
xx xxxxxx 0 xxx xx xx <8,16,32 bits> <8,16,32 bits>
```
# Size table
If the instruction doesn't allow variable sizes or a size was not specified, set the size bits to Word (0b10)
| | |
| :--: | -------------- |
| 0b00 | byte (8 bits) |
| 0b01 | half (16 bits) |
| 0b10 | word (32 bits) |
# Instruction table
| 0x | -0 | -1 | -2 | -3 | -4 | -5 | -6 | -7 | -8 | -9 | -A | -B | -C | -D | -E | -F |
| :-: | ---- | ------------- | ------------- | ------------- | ------------- | ------------- | ------------- | -------------- | ---- | ----- | -------------- | --- | --- | --- | --- | --- |
| 0- | NOP | ADD[.8,16,32] | MUL[.8,16,32] | AND[.8,16,32] | SLA[.8,16,32] | SRA[.8,16,32] | BSE[.8,16,32] | CMP[.8,16,32] | JMP | RJMP | PUSH[.8,16,32] | IN | ISE | MSE | | |
| 1- | HALT | INC[.8,16,32] | | OR[.8,16,32] | | SRL[.8,16,32] | BCL[.8,16,32] | MOV[.8,16,32] | CALL | RCALL | POP[.8,16,32] | OUT | ICL | MCL | | |
| 2- | BRK | SUB[.8,16,32] | DIV[.8,16,32] | XOR[.8,16,32] | ROL[.8,16,32] | ROR[.8,16,32] | BTS[.8,16,32] | MOVZ[.8,16,32] | LOOP | RLOOP | RET | | INT | TLB | | |
| 3- | | DEC[.8,16,32] | REM[.8,16,32] | NOT[.8,16,32] | | | | | | RTA | RETI | | | FLP | | |
# Condition table
| | | |
| :---: | ------ | --------------------------------------------- |
| 0b000 | --- | always |
| 0b001 | IFZ | zero |
| 0b010 | IFNZ | not zero |
| 0b011 | IFC | carry |
| 0b011 | IFLT | less than (equivalent to IFC) |
| 0b100 | IFNC | not carry |
| 0b100 | IFGTEQ | greater than or equal to (equivalent to IFNC) |
| 0b101 | IFGT | greater than |
| 0b110 | IFLTEQ | less than or equal to |
# Destination table
| | |
| :--: | ------------------- |
| 0b00 | register |
| 0b01 | register (pointer) |
| 0b10 | (invalid) |
| 0b11 | immediate (pointer) |
# Source table
| | |
| :--: | ------------------- |
| 0b00 | register |
| 0b01 | register (pointer) |
| 0b10 | immediate |
| 0b11 | immediate (pointer) |

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

View File

@ -1,150 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 36 36"
version="1.1"
id="svg16"
sodipodi:docname="32.svg"
inkscape:export-filename="/home/ry/Documents/fox32/docs/logos/32.png"
inkscape:export-xdpi="341.33334"
inkscape:export-ydpi="341.33334"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04, custom)"
width="36"
height="36"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs20">
<inkscape:path-effect
effect="powerclip"
id="path-effect51605"
is_visible="true"
lpeversion="1"
inverse="true"
flatten="false"
hide_clip="false"
message="Use fill-rule evenodd on &lt;b&gt;fill and stroke&lt;/b&gt; dialog if no flatten result after convert clip to paths." />
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath51601">
<path
style="display:none;fill:#f18f26;fill-opacity:1;stroke-width:0.0502793"
d="M 14.587831,27.863504 C 14.382965,27.727479 13.734884,26.908543 13.457514,26.435201 13.074891,25.782241 12.802463,25.12596 12.2477,23.520759 11.54419,21.485155 11.532784,21.464321 11.049545,21.332324 10.678257,21.230906 9.0747412,21.190197 8.3212291,21.263058 7.5503856,21.337595 6.4089614,21.570204 5.6761529,21.802094 4.1005881,22.300666 3.0721423,22.860948 2.1641077,23.715406 1.7440613,24.110668 1.696405,24.142717 1.7284655,24.00838 1.7908089,23.747154 2.5898195,22.17273 2.964067,21.573668 3.3024942,21.031943 4.10012,19.944034 4.5066782,19.469646 4.6078844,19.351555 4.6742061,19.238427 4.6540598,19.21825 4.6339135,19.198073 4.172433,19.1738 3.6285475,19.164311 c -0.5438855,-0.0095 -0.9971402,-0.02529 -1.0072326,-0.03511 -0.051212,-0.04983 1.4590175,-2.760125 2.0373689,-3.656307 0.7207834,-1.116888 1.8379204,-2.499044 2.7887559,-3.450332 1.1558488,-1.1564 2.2171525,-1.919729 3.7145713,-2.6716564 1.167618,-0.5863179 2.814287,-0.8933047 5.434415,-1.0131321 2.787996,-0.1275046 5.8009,0.134319 7.311395,0.6353659 1.064281,0.3530328 2.407592,1.1206046 3.519475,2.0110386 1.248433,0.999788 2.838308,2.82234 3.90961,4.48178 0.566992,0.878269 2.048569,3.523133 2.048569,3.657043 0,0.01838 -0.345042,0.03566 -0.76676,0.0384 -0.421718,0.0027 -0.889733,0.0197 -1.040035,0.03771 l -0.273275,0.03274 0.340993,0.418558 c 0.563124,0.691217 1.176336,1.55625 1.545759,2.18054 0.377875,0.638571 1.019097,1.934392 1.077479,2.177438 0.03251,0.135328 -0.0072,0.109342 -0.386254,-0.25271 -1.055819,-1.008484 -2.340669,-1.658309 -4.22344,-2.136041 -1.067335,-0.270825 -1.740108,-0.360359 -2.911339,-0.387453 -1.113448,-0.02576 -1.922155,0.05148 -2.104624,0.201 -0.172488,0.141344 -0.558337,1.078132 -1.216006,2.952299 -0.549422,1.565695 -1.162101,2.673918 -1.842111,3.332038 l -0.247837,0.239859 -0.159143,-0.07939 c -0.269958,-0.134674 -0.960666,-0.172303 -3.153742,-0.171816 -2.179025,5.03e-4 -2.9376,0.03891 -3.182763,0.16121 -0.123158,0.06144 -0.156957,0.06093 -0.254546,-0.0039 z"
id="path51603" />
<path
id="lpe_path-effect51605"
style="fill:#f18f26;fill-opacity:1;stroke-width:0.0502793"
class="powerclip"
d="M 6,10.5 H 30 V 36.776 H 6 Z m 8.587831,17.363504 v -2.1e-5 c 0.09759,0.06483 0.131388,0.06534 0.254546,0.0039 0.245163,-0.1223 1.003738,-0.160707 3.182763,-0.16121 2.193076,-4.87e-4 2.883784,0.03714 3.153742,0.171816 l 0.159143,0.07939 0.247837,-0.239859 c 0.68001,-0.65812 1.292689,-1.766343 1.842111,-3.332038 0.657669,-1.874167 1.043518,-2.810955 1.216006,-2.952299 0.182469,-0.14952 0.991176,-0.22676 2.104624,-0.201 1.171231,0.02709 1.844004,0.116628 2.911339,0.387453 1.882771,0.477732 3.167621,1.127557 4.22344,2.136041 0.379054,0.362052 0.418764,0.388038 0.386254,0.25271 -0.05838,-0.243046 -0.699604,-1.538867 -1.077479,-2.177438 -0.369423,-0.62429 -0.982635,-1.489323 -1.545759,-2.18054 l -0.340993,-0.418558 0.273275,-0.03274 c 0.150302,-0.01801 0.618317,-0.03501 1.040035,-0.03771 0.421718,-0.0027 0.76676,-0.02002 0.76676,-0.0384 0,-0.13391 -1.481577,-2.778774 -2.048569,-3.657043 -1.071302,-1.65944 -2.661177,-3.481992 -3.90961,-4.48178 C 26.315413,10.093744 24.972102,9.3261722 23.907821,8.9731394 22.397326,8.4720925 19.384422,8.2102689 16.596426,8.3377735 13.976298,8.4576009 12.329629,8.7645877 11.162011,9.3509056 9.6645922,10.102833 8.6032885,10.866162 7.4474397,12.022562 6.4966042,12.97385 5.3794672,14.356006 4.6586838,15.472894 c -0.5783514,0.896182 -2.0885809,3.606477 -2.0373689,3.656307 0.010092,0.0098 0.4633471,0.02561 1.0072326,0.03511 0.5438855,0.0095 1.005366,0.03376 1.0255123,0.05394 0.020146,0.02018 -0.046175,0.133305 -0.1473816,0.251396 -0.4065582,0.474388 -1.204184,1.562297 -1.5426112,2.104022 -0.3742475,0.599062 -1.1732581,2.173486 -1.2356015,2.434712 -0.032061,0.134337 0.015596,0.102288 0.4356422,-0.292974 0.9080346,-0.854458 1.9364804,-1.41474 3.5120452,-1.913312 0.7328085,-0.23189 1.8742327,-0.464499 2.6450762,-0.539036 0.7535121,-0.07286 2.3570279,-0.03215 2.7283159,0.06927 0.483239,0.131997 0.494645,0.152831 1.198155,2.188435 0.554763,1.605201 0.827191,2.261482 1.209814,2.914442 0.27737,0.473342 0.925451,1.292278 1.130317,1.428303 z" />
</clipPath>
</defs>
<sodipodi:namedview
id="namedview18"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="19.888889"
inkscape:cx="14.606145"
inkscape:cy="16.240223"
inkscape:window-width="1920"
inkscape:window-height="1132"
inkscape:window-x="0"
inkscape:window-y="32"
inkscape:window-maximized="1"
inkscape:current-layer="svg16"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
width="36px" />
<path
fill="#f4900c"
d="M 13.436985,9.7783459 C 14.094985,12.416346 4.7639847,20.267346 2.1929847,13.876346 0.70198476,10.173346 -0.60001524,2.4103459 0.87998476,2.0413459 c 1.47999994,-0.368 11.90000024,5.098 12.55700024,7.737 z"
id="path2" />
<path
fill="#a0041e"
d="m 11.442985,10.331346 c 0.96,1.538 -1.8310003,4.561 -3.3680003,5.522 -1.538,0.961 -2.899,-0.552 -4.414,-4.414 -0.662,-1.6890001 -1.666,-6.2700001 -1.103,-6.6220001 0.562,-0.351 7.9240003,3.976 8.8850003,5.5140001 z"
id="path4" />
<path
fill="#f4900c"
d="m 22.562985,9.7783459 c -0.657,2.6390001 8.673,10.4890001 11.245,4.0980001 1.49,-3.703 2.792,-11.4660001 1.312,-11.8350001 -1.48,-0.368 -11.899,5.098 -12.557,7.737 z"
id="path6" />
<path
fill="#a0041e"
d="m 24.557985,10.331346 c -0.96,1.538 1.831,4.561 3.368,5.522 1.537,0.961 2.898,-0.552 4.413,-4.414 0.662,-1.6880001 1.666,-6.2690001 1.104,-6.6210001 -0.563,-0.352 -7.924,3.975 -8.885,5.5130001 z"
id="path8" />
<path
fill="#f18f26"
d="m 32.352985,26.888346 c 0,-0.454 -0.188,-1.091 -0.407,-1.687 0.585,0.028 1.519,0.191 2.77,0.817 -0.008,-0.536 -0.118,-0.984 -0.273,-1.393 0.041,0.02 0.075,0.034 0.116,0.055 -1.103,-3.31 -3.309,-5.517 -3.309,-5.517 h 2.206 c -2.331,-4.663 -4.965,-8.015 -8.075,-9.5590001 -1.39,-0.873 -3.688,-1.338 -7.373,-1.339 h -0.003 c -3.695,0 -5.996,0.468 -7.385,1.346 C 7.5159847,11.158346 4.8859847,14.507346 2.5589847,19.163346 h 2.207 c 0,0 -2.207,2.206 -3.311,5.517 0.03,-0.015 0.055,-0.025 0.084,-0.04 -0.201,0.392 -0.307,0.847 -0.282,1.377 1.263,-0.632 2.217,-0.792 2.813,-0.818 -0.189,0.513 -0.343,1.044 -0.386,1.475 -0.123,0.371 -0.191,0.812 -0.135,1.343 3.207,-1.457 4.707,-1.249 6.4570003,-0.374 1.213,3.623 4.206,6.333 8.001,6.333 3.793,0 6.746,-2.794 7.958,-6.416 1.458,-1.25 3.708,-0.875 6.416,0.416 0.066,-0.414 0.036,-0.773 -0.036,-1.093 z"
id="path10" />
<path
fill="#ffd983"
d="m 31.248985,23.577346 c 0.006,0 1.108,0.003 3.309,1.103 -1.249,-2.839 -7.525,-4.07 -9.931,-3.291 -1.171,1.954 -1.281,5.003 -3.383,6.622 -1.741,1.431 -4.713,1.458 -6.479,0 -2.345,-1.924 -2.559,-5.813 -3.382,-6.622 -2.4070003,-0.781 -8.6810003,0.454 -9.9310003,3.291 2.201,-1.101 3.304,-1.103 3.309,-1.103 0,0.001 -1.103,2.208 -1.103,3.311 l 10e-4,-10e-4 v 10e-4 c 2.398,-1.573 5.116,-2.271 7.4290003,-0.452 1.666,7.921 12.293,7.545 13.833,0 2.314,-1.818 5.03,-1.122 7.429,0.452 v -10e-4 l 0.001,10e-4 c 0.002,-1.103 -1.101,-3.311 -1.102,-3.311 z"
id="path12" />
<path
fill="#272b2b"
d="m 11,17 c 0,0 0,-1.5 1.5,-1.5 1.5,0 1.5,1.5 1.5,1.5 v 1.5 c 0,0 0,1.5 -1.5,1.5 C 11,20 11,18.5 11,18.5 Z m 11,0 c 0,0 0,-1.5 1.5,-1.5 1.5,0 1.5,1.5 1.5,1.5 v 1.5 c 0,0 0,1.5 -1.5,1.5 C 22,20 22,18.5 22,18.5 Z m -7.061,10.808 c -1.021,0.208 2.041,3.968 3.062,3.968 1.02,0 4.082,-3.76 3.062,-3.968 -1.021,-0.208 -5.103,-0.208 -6.124,0 z"
id="path14"
clip-path="url(#clipPath51601)"
inkscape:path-effect="#path-effect51605"
inkscape:original-d="m 11,17 c 0,0 0,-1.5 1.5,-1.5 1.5,0 1.5,1.5 1.5,1.5 v 1.5 c 0,0 0,1.5 -1.5,1.5 C 11,20 11,18.5 11,18.5 Z m 11,0 c 0,0 0,-1.5 1.5,-1.5 1.5,0 1.5,1.5 1.5,1.5 v 1.5 c 0,0 0,1.5 -1.5,1.5 C 22,20 22,18.5 22,18.5 Z m -7.061,10.808 c -1.021,0.208 2.041,3.968 3.062,3.968 1.02,0 4.082,-3.76 3.062,-3.968 -1.021,-0.208 -5.103,-0.208 -6.124,0 z"
transform="translate(0.00598476,-0.0236541)" />
<rect
id="rect20344"
width="14.987617"
height="5.4221425"
x="10.660814"
y="15.06275" />
<path
style="fill:#f18f26;fill-opacity:1;stroke-width:0.0502793"
d="m 10.665203,17.775229 v -2.664805 h 7.49162 7.49162 v 2.664805 2.664804 h -7.49162 -7.49162 z"
id="path43623" />
<path
style="fill:#f18f26;fill-opacity:1;stroke-width:0.0502793"
d="M 14.315606,27.528379 C 13.46489,26.637945 12.88055,25.459451 12.197043,23.255676 11.923358,22.373255 11.743921,21.90606 11.554649,21.583091 c -0.126701,-0.216198 -0.142027,-0.225105 -0.547607,-0.318215 -0.576266,-0.132297 -2.3143337,-0.134641 -3.1574819,-0.0043 -1.9761923,0.305592 -3.8463816,0.979038 -4.9946162,1.798537 -0.2443852,0.174418 -0.60074,0.4846 -0.7918994,0.689291 -0.1911594,0.204691 -0.3475626,0.348334 -0.3475626,0.319207 0,-0.09995 0.5829805,-1.340028 0.870599,-1.851886 0.5399921,-0.960992 1.3195062,-2.062849 1.937075,-2.73809 0.1426508,-0.155972 0.2593651,-0.297382 0.2593651,-0.314246 0,-0.01686 -0.4864525,-0.03066 -1.0810056,-0.03066 -0.594553,0 -1.0810056,-0.0066 -1.0810056,-0.01461 0,-0.008 0.1833343,-0.364389 0.4074094,-0.7919 1.3941728,-2.659922 2.6984315,-4.540018 4.2674621,-6.151569 1.2172475,-1.250235 2.0634416,-1.874141 3.7971957,-2.7997066 1.47896,-0.7895434 4.73153,-1.2087858 8.205581,-1.0576642 1.542956,0.067119 2.444202,0.1617141 3.459224,0.3630819 1.241039,0.2462071 1.689399,0.4193972 3.041899,1.1750086 2.206292,1.2326053 4.353351,3.5582893 6.223065,6.7407943 0.468591,0.797605 1.369114,2.447936 1.369114,2.509089 0,0.01511 -0.486453,0.02747 -1.081006,0.02747 -0.594553,0 -1.081005,0.01868 -1.081005,0.04152 0,0.02283 0.05931,0.09637 0.131808,0.163408 0.463289,0.428437 1.593185,2.012135 2.124307,2.977497 0.261765,0.47578 0.810924,1.656856 0.810924,1.744054 0,0.02366 -0.197975,-0.154148 -0.439944,-0.395139 -0.24197,-0.240991 -0.633862,-0.566615 -0.870873,-0.723611 -1.169171,-0.774457 -2.937534,-1.390064 -4.823261,-1.679088 -0.843788,-0.129326 -2.585209,-0.127933 -3.1531,0.0025 l -0.412876,0.09485 -0.199056,0.407949 c -0.263912,0.540865 -0.354247,0.774214 -0.771053,1.991746 -0.764143,2.232138 -1.188289,3.06167 -1.961072,3.835402 l -0.340569,0.340988 -0.1384,-0.100049 c -0.229821,-0.166136 -1.295001,-0.220591 -3.692872,-0.188789 -2.082095,0.02761 -2.542915,0.06325 -2.70411,0.209133 -0.07997,0.07237 -0.116314,0.04729 -0.473696,-0.326774 z m 3.853787,-7.075775 -7.50419,-0.0129 v -2.664475 -2.664476 l 7.50419,-0.0129 7.50419,-0.0129 -7.52933,-0.01241 -7.529329,-0.0124 v 2.715084 2.715083 l 7.529329,-0.0124 7.52933,-0.0124 z"
id="path43662" />
<path
style="fill:#f18f26;fill-opacity:1;stroke-width:0.0502793"
d="m 14.315606,27.528379 c -0.858133,-0.898197 -1.294443,-1.768132 -2.082541,-4.152256 -0.453391,-1.371583 -0.623116,-1.783587 -0.800933,-1.944255 -0.05428,-0.04904 -0.266012,-0.127112 -0.470518,-0.173485 -0.537398,-0.121859 -2.3187637,-0.120056 -3.1120539,0.0031 -2.5177159,0.391026 -4.52037,1.236284 -5.6941341,2.403317 -0.2419692,0.240582 -0.4399441,0.41806 -0.4399441,0.394396 0,-0.09303 0.5649821,-1.300197 0.8328803,-1.779577 0.5548107,-0.992785 1.4670937,-2.282752 2.0134029,-2.846949 0.1214158,-0.125391 0.2207559,-0.244176 0.2207559,-0.263966 0,-0.01979 -0.4864525,-0.03598 -1.0810056,-0.03598 -0.594553,0 -1.0810056,-0.0086 -1.0810056,-0.01908 0,-0.01049 0.1893241,-0.378161 0.4207201,-0.817039 1.4213479,-2.695802 2.675331,-4.500353 4.2541514,-6.121959 1.0008,-1.027921 1.9509803,-1.778947 2.9731667,-2.3500022 1.288882,-0.720047 1.747815,-0.8957786 2.98604,-1.1433947 2.603668,-0.5206727 6.897439,-0.5235156 9.481668,-0.00628 0.810558,0.1622346 1.418164,0.3402647 1.892064,0.5543799 0.416508,0.1881844 1.509162,0.808149 1.964242,1.114496 1.814892,1.221739 3.72945,3.392111 5.252648,5.954483 0.654748,1.101437 1.54625,2.717627 1.54625,2.803172 0,0.01609 -0.491382,0.03536 -1.09196,0.04281 l -1.091961,0.01355 0.250247,0.276537 c 0.953898,1.054113 1.937825,2.571956 2.554235,3.940261 0.156457,0.347302 0.284147,0.660573 0.283756,0.696157 -4.02e-4,0.03559 -0.11605,-0.06615 -0.257019,-0.226068 -0.301615,-0.342166 -0.928812,-0.83947 -1.433824,-1.136878 -2.088393,-1.229881 -5.635517,-1.874161 -7.74358,-1.406501 l -0.259156,0.05749 -0.27716,0.583858 c -0.152438,0.321121 -0.451215,1.092936 -0.663951,1.715142 -0.806048,2.357523 -1.176235,3.091227 -1.983372,3.931008 -0.335728,0.349305 -0.352068,0.35943 -0.444753,0.275552 -0.198119,-0.179244 -0.645408,-0.207911 -3.226977,-0.206772 -2.544916,0.0011 -3.032833,0.03113 -3.217026,0.197818 -0.07951,0.07196 -0.116595,0.04633 -0.473353,-0.327085 z m 3.753665,-7.075775 -7.403195,-0.0129 -0.01345,-2.702347 -0.01345,-2.702348 -0.01212,2.727654 -0.01212,2.727653 7.42877,-0.0124 7.428771,-0.0124 z m -6.234117,-5.37516 c -0.03404,-0.01377 -0.101918,-0.01461 -0.150838,-0.0019 -0.04892,0.01275 -0.02107,0.02402 0.06189,0.02504 0.08296,0.001 0.122987,-0.0094 0.08895,-0.02318 z m 10.683401,-0.0047 c -1.624651,-0.0074 -4.283171,-0.0074 -5.907821,0 -1.624651,0.0074 -0.295391,0.01338 2.95391,0.01338 3.249302,0 4.578562,-0.006 2.953911,-0.01338 z"
id="path43701" />
<path
style="fill:#f18f26;fill-opacity:1;stroke-width:0.0502793"
d="M 14.315606,27.528379 C 13.457727,26.630447 13.020865,25.759248 12.224592,23.358434 11.766106,21.976069 11.607421,21.590252 11.432253,21.431977 11.188211,21.211471 9.7687669,21.089992 8.6105901,21.190491 5.9196975,21.423992 3.466552,22.369886 2.1336025,23.687914 c -0.2299663,0.227393 -0.4181206,0.392023 -0.4181206,0.365847 0,-0.02618 0.1280101,-0.331751 0.2844669,-0.679053 C 2.6122967,22.01542 3.6074184,20.48026 4.5541051,19.434447 L 4.8044301,19.15791 3.7124699,19.14436 c -0.600578,-0.0075 -1.0919601,-0.02371 -1.0919601,-0.03612 0,-0.05096 0.8842852,-1.682765 1.2576431,-2.320774 0.2208661,-0.377426 0.4015748,-0.693185 0.4015748,-0.701687 0,-0.0085 0.1505915,-0.248405 0.3346478,-0.533115 1.364098,-2.110082 3.1972851,-4.1069 4.7403577,-5.163486 0.6436101,-0.4407007 1.9177378,-1.1351211 2.4099198,-1.3134489 1.642493,-0.5951092 4.542093,-0.886847 7.536025,-0.7582232 2.958097,0.1270843 4.523179,0.4525661 5.97067,1.2416886 2.070491,1.1287605 3.468266,2.3767155 5.119518,4.5707825 0.511814,0.680063 1.341376,1.890066 1.341376,1.956538 0,0.0109 0.166289,0.299165 0.369532,0.640582 0.381881,0.641502 1.289686,2.309489 1.289686,2.369648 0,0.01874 -0.487165,0.04016 -1.082589,0.04762 l -1.082588,0.01355 0.409348,0.477654 c 0.728605,0.850182 1.459337,1.935402 2.008279,2.982522 0.2891,0.551465 0.652578,1.356755 0.652578,1.445796 0,0.02481 -0.18708,-0.141233 -0.415732,-0.368981 -0.459366,-0.457548 -0.947507,-0.811573 -1.595441,-1.157098 -1.84659,-0.984732 -4.765843,-1.563688 -6.762132,-1.341089 -0.760641,0.08482 -0.882011,0.134495 -1.042574,0.426732 -0.22706,0.413268 -0.466509,1.018831 -0.899239,2.274161 -0.226234,0.656295 -0.488581,1.37427 -0.582994,1.595499 -0.404249,0.947246 -0.903675,1.72207 -1.423247,2.208069 -0.241042,0.225466 -0.262615,0.235288 -0.347687,0.158299 -0.190116,-0.172053 -0.65957,-0.201352 -3.196317,-0.199487 -2.513635,0.0018 -3.064686,0.03486 -3.240687,0.194139 -0.08147,0.07373 -0.115416,0.05045 -0.474832,-0.325747 z m 2.873847,-7.075775 -6.523236,-0.01295 -0.0136,-2.300091 -0.0136,-2.300092 -0.01205,2.325419 -0.01205,2.325419 6.548882,-0.01238 6.548883,-0.01238 z m -5.354299,-5.37516 c -0.03404,-0.01377 -0.101918,-0.01461 -0.150838,-0.0019 -0.04892,0.01275 -0.02107,0.02402 0.06189,0.02504 0.08296,0.001 0.122987,-0.0094 0.08895,-0.02318 z m 9.555821,-0.0047 c -1.000406,-0.0076 -2.652082,-0.0076 -3.670391,-8e-6 -1.018309,0.0076 -0.199795,0.01384 1.818921,0.01384 2.018715,5e-6 2.851876,-0.0062 1.85147,-0.01383 z"
id="path43740" />
<path
style="fill:#f18f26;fill-opacity:1;stroke-width:0.0502793"
d="m 14.325997,27.541936 c -0.844775,-0.868685 -1.348283,-1.873086 -2.122513,-4.234001 -0.424452,-1.294313 -0.628837,-1.773879 -0.805273,-1.889486 -0.381442,-0.24993 -2.3063045,-0.33559 -3.4983716,-0.155684 -1.5140705,0.228503 -2.8859632,0.641115 -4.0167581,1.208083 -0.7854121,0.393797 -1.2734414,0.741269 -1.8282139,1.30167 -0.186662,0.188555 -0.3393855,0.32011 -0.3393855,0.292343 0,-0.09043 0.4018864,-0.971524 0.7130925,-1.563375 C 2.9541431,21.50196 3.89147,20.152277 4.5760284,19.409307 L 4.8076607,19.15791 3.7140853,19.14436 c -0.6014665,-0.0075 -1.0935755,-0.02547 -1.0935755,-0.04004 0,-0.03944 0.8013273,-1.530374 1.133204,-2.108417 0.1587701,-0.276536 0.3461605,-0.604609 0.4164232,-0.72905 0.4732593,-0.838184 1.5628449,-2.34916 2.3693132,-3.285629 0.6277435,-0.728939 1.7527867,-1.804517 2.3804372,-2.27578 0.9717958,-0.7296601 2.3086426,-1.4682698 3.1279966,-1.7282229 1.481794,-0.4701224 3.269439,-0.6716382 5.958101,-0.6716382 2.195716,0 3.257411,0.083729 4.767801,0.3760062 1.256669,0.2431792 1.907448,0.5040377 3.242609,1.2997688 1.835364,1.0938421 3.585621,2.8803621 5.247666,5.3563911 0.471778,0.702831 2.127399,3.63113 2.127399,3.762734 0,0.01776 -0.47514,0.03229 -1.055866,0.03229 -0.580726,0 -1.055773,0.01697 -1.055659,0.03771 1.01e-4,0.02074 0.217628,0.297905 0.483363,0.615922 0.602682,0.721254 1.454692,1.997159 1.863518,2.790662 0.366886,0.712099 0.679684,1.427905 0.655578,1.500223 -0.0094,0.02827 -0.08364,-0.03598 -0.164928,-0.142785 -0.382107,-0.502058 -1.481398,-1.265062 -2.410364,-1.673001 -2.141741,-0.94051 -5.182137,-1.364547 -6.837989,-0.953679 l -0.251396,0.06238 -0.232691,0.466103 c -0.223298,0.44729 -0.411953,0.943731 -1.026605,2.701495 -0.51683,1.478012 -1.113194,2.536577 -1.780879,3.161118 -0.238327,0.222928 -0.266421,0.236286 -0.345819,0.164431 -0.189387,-0.171397 -0.75719,-0.207396 -3.225738,-0.204519 -2.436274,0.0028 -3.04453,0.04052 -3.22021,0.199512 -0.07233,0.06546 -0.120963,0.032 -0.459778,-0.316409 z m -3.673466,-9.377043 c -0.0084,-0.421717 -0.01529,-0.07667 -0.01529,0.76676 0,0.843436 0.0069,1.188478 0.01529,0.76676 0.0084,-0.421718 0.0084,-1.111802 0,-1.53352 z m 1.181666,-3.087768 c -0.03457,-0.01395 -0.09113,-0.01395 -0.125698,0 -0.03457,0.01395 -0.0063,0.02536 0.06285,0.02536 0.06913,0 0.09742,-0.01141 0.06285,-0.02536 z m 8.726849,-0.0043 c -0.571952,-0.0081 -1.522231,-0.0081 -2.111732,-2.3e-5 -0.589502,0.008 -0.121541,0.01464 1.039911,0.01466 1.161453,1.2e-5 1.643772,-0.0066 1.071821,-0.01464 z"
id="path43779" />
<path
style="fill:#f18f26;fill-opacity:1;stroke-width:0.0502793"
d="M 14.297924,27.510248 C 13.853145,27.045673 13.544349,26.59754 13.209282,25.930381 12.892377,25.299386 12.734493,24.892448 12.24958,23.456793 11.589984,21.503964 11.557413,21.440224 11.158635,21.321799 10.719198,21.1913 9.5994975,21.131802 8.7288234,21.192685 c -2.6588492,0.185921 -5.2324127,1.16491 -6.6000538,2.510674 -0.2273082,0.223672 -0.4132877,0.386143 -0.4132877,0.361047 0,-0.09381 0.3688001,-0.905326 0.6855013,-1.508386 0.5331622,-1.015244 1.3849081,-2.266627 2.0489722,-3.010346 0.1552575,-0.17388 0.2822863,-0.337916 0.2822863,-0.364525 0,-0.02945 -0.413128,-0.04838 -1.0558659,-0.04838 -0.5807263,0 -1.055866,-0.01369 -1.055866,-0.03043 0,-0.137871 1.6653086,-3.075618 2.1692035,-3.826661 1.1979585,-1.785524 2.8371426,-3.599712 4.1279648,-4.568674 0.9368462,-0.703248 2.2900469,-1.4587652 3.0860919,-1.7230229 2.826214,-0.9381997 9.2758,-0.9273473 12.071338,0.020312 0.713002,0.2417002 2.069755,0.9989949 2.943357,1.6428839 1.39549,1.028547 2.899712,2.684807 4.204254,4.629195 0.521966,0.777977 2.168741,3.680774 2.168741,3.822874 0,0.01844 -0.47514,0.03352 -1.055866,0.03352 -0.580726,0 -1.055211,0.01697 -1.05441,0.03771 8e-4,0.02074 0.1821,0.252654 0.402886,0.515363 0.74682,0.888627 1.482659,1.99088 1.986074,2.97505 0.28875,0.564501 0.626344,1.32273 0.626344,1.406755 0,0.02688 -0.17751,-0.12864 -0.394467,-0.345596 -1.412345,-1.412345 -4.121534,-2.401571 -6.996595,-2.554719 -0.69945,-0.03726 -1.646374,0.03398 -2.051724,0.154357 l -0.261309,0.0776 -0.221468,0.463109 c -0.19834,0.414745 -0.423098,1.012699 -1.090673,2.901655 -0.444479,1.257688 -1.075762,2.348426 -1.693751,2.926482 l -0.250441,0.234259 -0.208933,-0.103372 c -0.306587,-0.151687 -2.26663,-0.219912 -4.419227,-0.153825 -1.451778,0.04457 -1.632438,0.05951 -1.815679,0.150175 l -0.203488,0.100677 z m -3.645933,-8.591165 c -0.01016,-0.145181 -0.01847,-0.0264 -0.01847,0.263967 0,0.290363 0.0083,0.409148 0.01847,0.263966 0.01016,-0.145181 0.01016,-0.382751 0,-0.527933 z m 1.156019,-3.839036 c -0.01671,-0.01671 -0.06007,-0.01849 -0.09637,-0.004 -0.04011,0.01605 -0.0282,0.02796 0.03038,0.03038 0.053,0.0022 0.0827,-0.0097 0.06599,-0.02641 z m 7.997431,-0.0067 c -0.157924,-0.0099 -0.429433,-0.01003 -0.603351,-2.01e-4 -0.17392,0.0098 -0.04471,0.01798 0.287135,0.01808 0.331844,1.01e-4 0.474141,-0.008 0.316216,-0.0179 z"
id="path43818" />
<path
style="fill:#f18f26;fill-opacity:1;stroke-width:0.0502793"
d="m 14.359921,27.586146 c -0.449118,-0.46165 -0.774129,-0.921958 -1.097682,-1.554631 -0.357124,-0.698319 -0.501736,-1.067487 -1.04548,-2.668928 -0.529824,-1.56044 -0.683673,-1.895886 -0.913053,-1.990778 -0.433149,-0.179189 -2.1903377,-0.250274 -3.1776096,-0.128545 -1.5393556,0.189799 -3.2368706,0.697742 -4.3994413,1.316434 -0.6531412,0.347585 -1.0528936,0.638018 -1.5712291,1.141547 -0.2419692,0.235057 -0.4399441,0.404558 -0.4399441,0.376667 0,-0.104533 0.2723938,-0.719479 0.6177788,-1.394674 0.5418102,-1.059186 1.3855229,-2.307419 2.150618,-3.181736 0.1353957,-0.154724 0.2340183,-0.300986 0.2191615,-0.325024 -0.014857,-0.02404 -0.489504,-0.04371 -1.0547714,-0.04371 -0.5652675,0 -1.027759,-0.01453 -1.027759,-0.03229 0,-0.13601 1.6603023,-3.067457 2.1602058,-3.814081 1.5348801,-2.2924 3.3386499,-4.149172 5.0728368,-5.221896 0.6873586,-0.4251822 1.6391386,-0.9096447 2.0820556,-1.0597805 0.810768,-0.2748262 2.129365,-0.5100076 3.58155,-0.638796 0.903836,-0.080157 4.05342,-0.079476 4.977654,0.00108 1.543209,0.1345005 3.004547,0.4073241 3.772959,0.7043904 0.494496,0.1911708 1.647102,0.8170272 2.256994,1.2255301 1.617327,1.08328 3.256759,2.818797 4.689489,4.964335 0.549829,0.823379 2.177206,3.692152 2.177206,3.838024 0,0.01842 -0.446858,0.03383 -0.993017,0.03425 -0.546159,4.03e-4 -1.01874,0.01739 -1.050179,0.03771 -0.03719,0.02403 0.08213,0.203835 0.341489,0.514593 0.467784,0.560485 0.947496,1.226338 1.392085,1.93225 0.344109,0.546372 1.138107,2.120417 1.193805,2.366633 0.03066,0.135554 -0.0063,0.111054 -0.364842,-0.241791 -0.550334,-0.541597 -1.132137,-0.944948 -1.902023,-1.318634 -1.412288,-0.685492 -3.031636,-1.10039 -4.81663,-1.234084 -0.860028,-0.06442 -1.872246,-0.007 -2.343561,0.132992 -0.251044,0.07455 -0.257802,0.08188 -0.453253,0.491388 -0.237949,0.498551 -0.355853,0.804095 -0.816878,2.116898 -0.193656,0.551449 -0.419991,1.173656 -0.502966,1.382682 -0.379566,0.956182 -0.938898,1.852392 -1.487633,2.383612 -0.244267,0.236471 -0.255468,0.241404 -0.373107,0.164323 -0.0667,-0.0437 -0.289916,-0.100907 -0.496028,-0.127113 -0.62273,-0.07918 -2.496509,-0.106834 -4.10597,-0.0606 -1.367916,0.03929 -1.539255,0.05369 -1.723341,0.144766 l -0.204409,0.101133 z"
id="path43857" />
<path
style="fill:#f18f26;fill-opacity:1;stroke-width:0.0502793"
d="m 14.403969,27.642829 c -0.427383,-0.432058 -0.826131,-0.994183 -1.138203,-1.604554 -0.354369,-0.6931 -0.577208,-1.261284 -1.070533,-2.729591 -0.217837,-0.64836 -0.47586,-1.338444 -0.573384,-1.53352 -0.199017,-0.398091 -0.269341,-0.439497 -0.901874,-0.531014 -0.519927,-0.07523 -2.0883058,-0.0595 -2.752725,0.02759 -1.1152026,0.14619 -2.2770199,0.44766 -3.2862076,0.852708 -1.0888276,0.437013 -1.7838744,0.868696 -2.5029605,1.55455 -0.5888592,0.561646 -0.5881332,0.521868 0.012773,-0.699864 0.606453,-1.233008 1.3020399,-2.306209 2.1363972,-3.296187 0.3300835,-0.391649 0.3851535,-0.480745 0.3145717,-0.508938 -0.047058,-0.0188 -0.521105,-0.03577 -1.0534374,-0.03771 -0.5323324,-0.0019 -0.9678771,-0.01862 -0.9678771,-0.03706 0,-0.124898 1.6059164,-2.980203 2.0872048,-3.711033 C 6.1018147,13.271287 7.894097,11.364917 9.4992903,10.291624 9.9649538,9.9802629 10.609756,9.6091278 11.20764,9.3083303 c 1.271804,-0.6398471 3.355514,-0.9712565 6.34583,-1.0092898 3.181374,-0.040463 5.6787,0.2818303 7.033277,0.9076827 1.495578,0.6910001 2.777111,1.5889428 3.976731,2.7864108 1.615843,1.612944 2.990855,3.580493 4.478694,6.408707 0.192108,0.365175 0.349287,0.677703 0.349287,0.694508 0,0.0168 -0.450681,0.03753 -1.001513,0.04605 -0.550831,0.0085 -1.017787,0.03183 -1.037679,0.05178 -0.01989,0.01996 0.08238,0.178336 0.227266,0.351956 0.916457,1.098194 1.635258,2.19891 2.24185,3.43299 0.600022,1.220717 0.600959,1.261037 0.01635,0.703911 -0.26116,-0.248883 -0.655072,-0.572872 -0.875359,-0.719976 -1.940371,-1.295749 -5.363968,-2.055624 -7.716166,-1.712621 -0.59776,0.08717 -0.627462,0.10635 -0.83244,0.53764 -0.252864,0.532044 -0.417325,0.954211 -0.821666,2.109194 -0.191096,0.545857 -0.419453,1.173472 -0.507461,1.394701 -0.390215,0.980902 -0.943457,1.870135 -1.496784,2.405801 -0.245376,0.237545 -0.254975,0.241726 -0.374723,0.163265 -0.225302,-0.147624 -0.879789,-0.185601 -3.182009,-0.184635 -2.300094,9.66e-4 -3.012214,0.04044 -3.223155,0.17865 -0.113682,0.07449 -0.127616,0.06717 -0.404001,-0.21224 z"
id="path43896" />
<path
style="fill:#f18f26;fill-opacity:1;stroke-width:0.0502793"
d="m 14.402815,27.645005 c -0.914169,-0.94931 -1.324158,-1.742554 -2.138694,-4.137933 -0.514997,-1.514499 -0.667383,-1.879371 -0.848583,-2.031841 -0.251243,-0.211407 -0.605124,-0.256092 -2.0073187,-0.253472 -1.3984275,0.0026 -1.8778887,0.06065 -3.0832261,0.373225 -1.8362553,0.476185 -3.1519523,1.140892 -4.1677735,2.105612 -0.5567972,0.528788 -0.5580281,0.490824 -0.020131,-0.620898 0.591698,-1.222918 1.335546,-2.380104 2.1729246,-3.380366 0.20299,-0.242475 0.3697199,-0.455004 0.370511,-0.472288 0.00305,-0.06659 -0.3452735,-0.09427 -1.1864109,-0.09427 -0.4804819,0 -0.8736034,-0.01509 -0.8736034,-0.03352 0,-0.126809 1.510769,-2.823522 2.0490637,-3.657565 0.7109995,-1.101635 1.7502949,-2.389306 2.7167692,-3.366037 1.2149256,-1.22782 2.247209,-1.975378 3.8212981,-2.7673067 1.084716,-0.545723 2.805538,-0.8702497 5.253707,-0.990787 2.841031,-0.1398801 5.918483,0.1234604 7.477598,0.6398651 0.860348,0.2849616 2.198054,1.0215625 3.142458,1.7303796 1.465297,1.099769 3.204842,3.063773 4.384783,4.950562 0.585857,0.936818 1.925273,3.344592 1.925273,3.460929 0,0.01842 -0.401606,0.03616 -0.892458,0.03943 -0.490852,0.0033 -0.95769,0.02024 -1.037418,0.03771 l -0.14496,0.03176 0.432232,0.541124 c 0.572343,0.716534 1.056151,1.402831 1.443931,2.048261 0.348187,0.579531 1.02598,1.948309 1.083035,2.187151 0.0323,0.135225 -0.008,0.108727 -0.389552,-0.256004 -0.726692,-0.69469 -1.495458,-1.178794 -2.531123,-1.593889 -1.035404,-0.414991 -2.231442,-0.718368 -3.423787,-0.868447 -1.19753,-0.150732 -3.016979,-0.07553 -3.270888,0.135199 -0.195888,0.162573 -0.518918,0.935502 -1.174128,2.809398 -0.599601,1.714853 -1.192001,2.80287 -1.898487,3.486806 -0.242337,0.234602 -0.256309,0.240868 -0.37076,0.166265 -0.218777,-0.142607 -0.936215,-0.183811 -3.184654,-0.182904 -2.308691,9.3e-4 -3.019274,0.03947 -3.22605,0.174952 -0.120415,0.0789 -0.128275,0.07479 -0.403578,-0.211097 z"
id="path43935" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:1.25;font-family:Overpass;-inkscape-font-specification:Overpass;letter-spacing:-1px;fill:#272b2b;fill-opacity:1;stroke:none"
x="8.9459906"
y="23.576347"
id="text48393"><tspan
sodipodi:role="line"
id="tspan48391"
x="8.9459906"
y="23.576347"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;font-family:Overpass;-inkscape-font-specification:Overpass;fill:#272b2b;fill-opacity:1">32</tspan></text>
</svg>

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

View File

@ -1,162 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 54 36"
version="1.1"
id="svg16"
sodipodi:docname="fox32.svg"
inkscape:export-filename="/home/ry/Documents/fox32/docs/logos/fox32.png"
inkscape:export-xdpi="682.66669"
inkscape:export-ydpi="682.66669"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04, custom)"
width="54"
height="36"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs20">
<inkscape:path-effect
effect="powerclip"
id="path-effect51605"
is_visible="true"
lpeversion="1"
inverse="true"
flatten="false"
hide_clip="false"
message="-0.21577385" />
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath51601">
<path
style="display:none;fill:#f18f26;fill-opacity:1;stroke-width:0.0502793"
d="M 14.587831,27.863504 C 14.382965,27.727479 13.734884,26.908543 13.457514,26.435201 13.074891,25.782241 12.802463,25.12596 12.2477,23.520759 11.54419,21.485155 11.532784,21.464321 11.049545,21.332324 10.678257,21.230906 9.0747412,21.190197 8.3212291,21.263058 7.5503856,21.337595 6.4089614,21.570204 5.6761529,21.802094 4.1005881,22.300666 3.0721423,22.860948 2.1641077,23.715406 1.7440613,24.110668 1.696405,24.142717 1.7284655,24.00838 1.7908089,23.747154 2.5898195,22.17273 2.964067,21.573668 3.3024942,21.031943 4.10012,19.944034 4.5066782,19.469646 4.6078844,19.351555 4.6742061,19.238427 4.6540598,19.21825 4.6339135,19.198073 4.172433,19.1738 3.6285475,19.164311 c -0.5438855,-0.0095 -0.9971402,-0.02529 -1.0072326,-0.03511 -0.051212,-0.04983 1.4590175,-2.760125 2.0373689,-3.656307 0.7207834,-1.116888 1.8379204,-2.499044 2.7887559,-3.450332 1.1558488,-1.1564 2.2171525,-1.919729 3.7145713,-2.6716564 1.167618,-0.5863179 2.814287,-0.8933047 5.434415,-1.0131321 2.787996,-0.1275046 5.8009,0.134319 7.311395,0.6353659 1.064281,0.3530328 2.407592,1.1206046 3.519475,2.0110386 1.248433,0.999788 2.838308,2.82234 3.90961,4.48178 0.566992,0.878269 2.048569,3.523133 2.048569,3.657043 0,0.01838 -0.345042,0.03566 -0.76676,0.0384 -0.421718,0.0027 -0.889733,0.0197 -1.040035,0.03771 l -0.273275,0.03274 0.340993,0.418558 c 0.563124,0.691217 1.176336,1.55625 1.545759,2.18054 0.377875,0.638571 1.019097,1.934392 1.077479,2.177438 0.03251,0.135328 -0.0072,0.109342 -0.386254,-0.25271 -1.055819,-1.008484 -2.340669,-1.658309 -4.22344,-2.136041 -1.067335,-0.270825 -1.740108,-0.360359 -2.911339,-0.387453 -1.113448,-0.02576 -1.922155,0.05148 -2.104624,0.201 -0.172488,0.141344 -0.558337,1.078132 -1.216006,2.952299 -0.549422,1.565695 -1.162101,2.673918 -1.842111,3.332038 l -0.247837,0.239859 -0.159143,-0.07939 c -0.269958,-0.134674 -0.960666,-0.172303 -3.153742,-0.171816 -2.179025,5.03e-4 -2.9376,0.03891 -3.182763,0.16121 -0.123158,0.06144 -0.156957,0.06093 -0.254546,-0.0039 z"
id="path51603" />
<path
id="lpe_path-effect51605"
style="fill:#f18f26;fill-opacity:1;stroke-width:0.0502793"
class="powerclip"
d="M 6,10.5 H 30 V 36.776 H 6 Z m 8.587831,17.363504 v -2.1e-5 c 0.09759,0.06483 0.131388,0.06534 0.254546,0.0039 0.245163,-0.1223 1.003738,-0.160707 3.182763,-0.16121 2.193076,-4.87e-4 2.883784,0.03714 3.153742,0.171816 l 0.159143,0.07939 0.247837,-0.239859 c 0.68001,-0.65812 1.292689,-1.766343 1.842111,-3.332038 0.657669,-1.874167 1.043518,-2.810955 1.216006,-2.952299 0.182469,-0.14952 0.991176,-0.22676 2.104624,-0.201 1.171231,0.02709 1.844004,0.116628 2.911339,0.387453 1.882771,0.477732 3.167621,1.127557 4.22344,2.136041 0.379054,0.362052 0.418764,0.388038 0.386254,0.25271 -0.05838,-0.243046 -0.699604,-1.538867 -1.077479,-2.177438 -0.369423,-0.62429 -0.982635,-1.489323 -1.545759,-2.18054 l -0.340993,-0.418558 0.273275,-0.03274 c 0.150302,-0.01801 0.618317,-0.03501 1.040035,-0.03771 0.421718,-0.0027 0.76676,-0.02002 0.76676,-0.0384 0,-0.13391 -1.481577,-2.778774 -2.048569,-3.657043 -1.071302,-1.65944 -2.661177,-3.481992 -3.90961,-4.48178 C 26.315413,10.093744 24.972102,9.3261722 23.907821,8.9731394 22.397326,8.4720925 19.384422,8.2102689 16.596426,8.3377735 13.976298,8.4576009 12.329629,8.7645877 11.162011,9.3509056 9.6645922,10.102833 8.6032885,10.866162 7.4474397,12.022562 6.4966042,12.97385 5.3794672,14.356006 4.6586838,15.472894 c -0.5783514,0.896182 -2.0885809,3.606477 -2.0373689,3.656307 0.010092,0.0098 0.4633471,0.02561 1.0072326,0.03511 0.5438855,0.0095 1.005366,0.03376 1.0255123,0.05394 0.020146,0.02018 -0.046175,0.133305 -0.1473816,0.251396 -0.4065582,0.474388 -1.204184,1.562297 -1.5426112,2.104022 -0.3742475,0.599062 -1.1732581,2.173486 -1.2356015,2.434712 -0.032061,0.134337 0.015596,0.102288 0.4356422,-0.292974 0.9080346,-0.854458 1.9364804,-1.41474 3.5120452,-1.913312 0.7328085,-0.23189 1.8742327,-0.464499 2.6450762,-0.539036 0.7535121,-0.07286 2.3570279,-0.03215 2.7283159,0.06927 0.483239,0.131997 0.494645,0.152831 1.198155,2.188435 0.554763,1.605201 0.827191,2.261482 1.209814,2.914442 0.27737,0.473342 0.925451,1.292278 1.130317,1.428303 z" />
</clipPath>
</defs>
<sodipodi:namedview
id="namedview18"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="19.888889"
inkscape:cx="27.427374"
inkscape:cy="16.240223"
inkscape:window-width="1920"
inkscape:window-height="1132"
inkscape:window-x="0"
inkscape:window-y="32"
inkscape:window-maximized="1"
inkscape:current-layer="svg16"
width="56px"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
height="32px" />
<path
fill="#f4900c"
d="m 31.323892,9.7783459 c 0.658,2.6380001 -8.673005,10.4890001 -11.244005,4.0980001 -1.491,-3.703 -2.793,-11.4660001 -1.313,-11.8350001 1.48,-0.368 11.900005,5.098 12.557005,7.737 z"
id="path2" />
<path
fill="#a0041e"
d="m 29.329892,10.331346 c 0.96,1.538 -1.83101,4.561 -3.36801,5.522 -1.537995,0.961 -2.898995,-0.552 -4.413995,-4.414 -0.662,-1.6890001 -1.666,-6.2700001 -1.103,-6.6220001 0.562,-0.351 7.924005,3.976 8.885005,5.5140001 z"
id="path4" />
<path
fill="#f4900c"
d="m 40.449892,9.7783459 c -0.657,2.6390001 8.673,10.4890001 11.245,4.0980001 1.49,-3.703 2.792,-11.4660001 1.312,-11.8350001 -1.48,-0.368 -11.899,5.098 -12.557,7.737 z"
id="path6" />
<path
fill="#a0041e"
d="m 42.444892,10.331346 c -0.96,1.538 1.831,4.561 3.368,5.522 1.537,0.961 2.898,-0.552 4.413,-4.414 0.662,-1.6880001 1.666,-6.2690001 1.104,-6.6210001 -0.563,-0.352 -7.924,3.975 -8.885,5.5130001 z"
id="path8" />
<path
fill="#f18f26"
d="m 50.239892,26.888346 c 0,-0.454 -0.188,-1.091 -0.407,-1.687 0.585,0.028 1.519,0.191 2.77,0.817 -0.008,-0.536 -0.118,-0.984 -0.273,-1.393 0.041,0.02 0.075,0.034 0.116,0.055 -1.103,-3.31 -3.309,-5.517 -3.309,-5.517 h 2.206 c -2.331,-4.663 -4.965,-8.015 -8.075,-9.5590001 -1.39,-0.873 -3.688,-1.338 -7.373,-1.339 h -0.003 c -3.695,0 -5.996,0.468 -7.385,1.346 -3.104005,1.5470001 -5.734005,4.8960001 -8.061005,9.5520001 h 2.207 c 0,0 -2.207,2.206 -3.311,5.517 0.03,-0.015 0.055,-0.025 0.084,-0.04 -0.201,0.392 -0.307,0.847 -0.282,1.377 1.263,-0.632 2.217,-0.792 2.813,-0.818 -0.189,0.513 -0.343,1.044 -0.386,1.475 -0.123,0.371 -0.191,0.812 -0.135,1.343 3.207,-1.457 4.706995,-1.249 6.456995,-0.374 1.21301,3.623 4.20601,6.333 8.00101,6.333 3.793,0 6.746,-2.794 7.958,-6.416 1.458,-1.25 3.708,-0.875 6.416,0.416 0.066,-0.414 0.036,-0.773 -0.036,-1.093 z"
id="path10" />
<path
fill="#ffd983"
d="m 49.135892,23.577346 c 0.006,0 1.108,0.003 3.309,1.103 -1.249,-2.839 -7.525,-4.07 -9.931,-3.291 -1.171,1.954 -1.281,5.003 -3.383,6.622 -1.741,1.431 -4.713,1.458 -6.479,0 -2.345,-1.924 -2.559,-5.813 -3.382,-6.622 -2.40701,-0.781 -8.681005,0.454 -9.931005,3.291 2.201,-1.101 3.304,-1.103 3.309,-1.103 0,0.001 -1.103,2.208 -1.103,3.311 l 0.001,-10e-4 v 10e-4 c 2.398,-1.573 5.115995,-2.271 7.429005,-0.452 1.666,7.921 12.293,7.545 13.833,0 2.314,-1.818 5.03,-1.122 7.429,0.452 v -10e-4 l 0.001,10e-4 c 0.002,-1.103 -1.101,-3.311 -1.102,-3.311 z"
id="path12" />
<path
fill="#272b2b"
d="m 11,17 c 0,0 0,-1.5 1.5,-1.5 1.5,0 1.5,1.5 1.5,1.5 v 1.5 c 0,0 0,1.5 -1.5,1.5 C 11,20 11,18.5 11,18.5 Z m 11,0 c 0,0 0,-1.5 1.5,-1.5 1.5,0 1.5,1.5 1.5,1.5 v 1.5 c 0,0 0,1.5 -1.5,1.5 C 22,20 22,18.5 22,18.5 Z m -7.061,10.808 c -1.021,0.208 2.041,3.968 3.062,3.968 1.02,0 4.082,-3.76 3.062,-3.968 -1.021,-0.208 -5.103,-0.208 -6.124,0 z"
id="path14"
clip-path="url(#clipPath51601)"
inkscape:path-effect="#path-effect51605"
inkscape:original-d="m 11,17 c 0,0 0,-1.5 1.5,-1.5 1.5,0 1.5,1.5 1.5,1.5 v 1.5 c 0,0 0,1.5 -1.5,1.5 C 11,20 11,18.5 11,18.5 Z m 11,0 c 0,0 0,-1.5 1.5,-1.5 1.5,0 1.5,1.5 1.5,1.5 v 1.5 c 0,0 0,1.5 -1.5,1.5 C 22,20 22,18.5 22,18.5 Z m -7.061,10.808 c -1.021,0.208 2.041,3.968 3.062,3.968 1.02,0 4.082,-3.76 3.062,-3.968 -1.021,-0.208 -5.103,-0.208 -6.124,0 z"
transform="translate(17.892887,-0.0236541)" />
<rect
id="rect20344"
width="14.987617"
height="5.4221425"
x="28.54771"
y="15.06275" />
<path
style="fill:#f18f26;fill-opacity:1;stroke-width:0.0502793"
d="m 28.552102,17.775229 v -2.664805 h 7.49162 7.49162 v 2.664805 2.664804 h -7.49162 -7.49162 z"
id="path43623" />
<path
style="fill:#f18f26;fill-opacity:1;stroke-width:0.0502793"
d="m 32.202512,27.528379 c -0.85072,-0.890434 -1.43506,-2.068928 -2.11857,-4.272703 -0.27368,-0.882421 -0.45312,-1.349616 -0.64239,-1.672585 -0.1267,-0.216198 -0.14203,-0.225105 -0.54761,-0.318215 -0.57626,-0.132297 -2.31433,-0.134641 -3.15748,-0.0043 -1.976192,0.305592 -3.846381,0.979038 -4.994616,1.798537 -0.244385,0.174418 -0.60074,0.4846 -0.791899,0.689291 -0.191159,0.204691 -0.347563,0.348334 -0.347563,0.319207 0,-0.09995 0.582981,-1.340028 0.870599,-1.851886 0.539993,-0.960992 1.319507,-2.062849 1.937075,-2.73809 0.142651,-0.155972 0.259366,-0.297382 0.259366,-0.314246 0,-0.01686 -0.486453,-0.03066 -1.081006,-0.03066 -0.594553,0 -1.081006,-0.0066 -1.081006,-0.01461 0,-0.008 0.183335,-0.364389 0.40741,-0.7919 1.394173,-2.659922 2.698431,-4.540018 4.267462,-6.151569 1.217248,-1.250235 2.063438,-1.874141 3.797198,-2.7997066 1.47896,-0.7895434 4.73153,-1.2087858 8.20558,-1.0576642 1.54295,0.067119 2.4442,0.1617141 3.45922,0.3630819 1.24104,0.2462071 1.6894,0.4193972 3.0419,1.1750086 2.20629,1.2326053 4.35335,3.5582893 6.22307,6.7407943 0.46859,0.797605 1.36911,2.447936 1.36911,2.509089 0,0.01511 -0.48645,0.02747 -1.08101,0.02747 -0.59455,0 -1.081,0.01868 -1.081,0.04152 0,0.02283 0.0593,0.09637 0.13181,0.163408 0.46329,0.428437 1.59318,2.012135 2.1243,2.977497 0.26177,0.47578 0.81093,1.656856 0.81093,1.744054 0,0.02366 -0.19798,-0.154148 -0.43995,-0.395139 -0.24197,-0.240991 -0.63386,-0.566615 -0.87087,-0.723611 -1.16917,-0.774457 -2.93753,-1.390064 -4.82326,-1.679088 -0.84379,-0.129326 -2.58521,-0.127933 -3.1531,0.0025 l -0.41288,0.09485 -0.19905,0.407949 c -0.26391,0.540865 -0.35425,0.774214 -0.77105,1.991746 -0.76415,2.232138 -1.18829,3.06167 -1.96108,3.835402 l -0.34057,0.340988 -0.1384,-0.100049 c -0.22982,-0.166136 -1.295,-0.220591 -3.69287,-0.188789 -2.08209,0.02761 -2.54291,0.06325 -2.70411,0.209133 -0.08,0.07237 -0.11631,0.04729 -0.47369,-0.326774 z m 3.85378,-7.075775 -7.50419,-0.0129 v -2.664475 -2.664476 l 7.50419,-0.0129 7.50419,-0.0129 -7.52933,-0.01241 -7.52933,-0.0124 v 2.715084 2.715083 l 7.52933,-0.0124 7.52933,-0.0124 z"
id="path43662" />
<path
style="fill:#f18f26;fill-opacity:1;stroke-width:0.0502793"
d="m 32.202512,27.528379 c -0.85814,-0.898197 -1.29445,-1.768132 -2.08254,-4.152256 -0.4534,-1.371583 -0.62312,-1.783587 -0.80094,-1.944255 -0.0543,-0.04904 -0.26601,-0.127112 -0.47052,-0.173485 -0.53739,-0.121859 -2.31876,-0.120056 -3.11205,0.0031 -2.517715,0.391026 -4.520369,1.236284 -5.694133,2.403317 -0.24197,0.240582 -0.439945,0.41806 -0.439945,0.394396 0,-0.09303 0.564983,-1.300197 0.832881,-1.779577 0.55481,-0.992785 1.467093,-2.282752 2.013403,-2.846949 0.121415,-0.125391 0.220756,-0.244176 0.220756,-0.263966 0,-0.01979 -0.486453,-0.03598 -1.081006,-0.03598 -0.594553,0 -1.081006,-0.0086 -1.081006,-0.01908 0,-0.01049 0.189324,-0.378161 0.42072,-0.817039 1.421348,-2.695802 2.675331,-4.500353 4.254152,-6.121959 1.000798,-1.027921 1.950978,-1.778947 2.973168,-2.3500022 1.28888,-0.720047 1.74781,-0.8957786 2.98604,-1.1433947 2.60367,-0.5206727 6.89744,-0.5235156 9.48167,-0.00628 0.81055,0.1622346 1.41816,0.3402647 1.89206,0.5543799 0.41651,0.1881844 1.50916,0.808149 1.96424,1.114496 1.81489,1.221739 3.72945,3.392111 5.25265,5.954483 0.65475,1.101437 1.54625,2.717627 1.54625,2.803172 0,0.01609 -0.49138,0.03536 -1.09196,0.04281 l -1.09196,0.01355 0.25025,0.276537 c 0.95389,1.054113 1.93782,2.571956 2.55423,3.940261 0.15646,0.347302 0.28415,0.660573 0.28376,0.696157 -4e-4,0.03559 -0.11605,-0.06615 -0.25702,-0.226068 -0.30162,-0.342166 -0.92881,-0.83947 -1.43383,-1.136878 -2.08839,-1.229881 -5.63551,-1.874161 -7.74358,-1.406501 l -0.25915,0.05749 -0.27716,0.583858 c -0.15244,0.321121 -0.45122,1.092936 -0.66395,1.715142 -0.80605,2.357523 -1.17624,3.091227 -1.98337,3.931008 -0.33573,0.349305 -0.35207,0.35943 -0.44476,0.275552 -0.19812,-0.179244 -0.64541,-0.207911 -3.22697,-0.206772 -2.54492,0.0011 -3.03284,0.03113 -3.21703,0.197818 -0.0795,0.07196 -0.1166,0.04633 -0.47335,-0.327085 z m 3.75366,-7.075775 -7.40319,-0.0129 -0.0134,-2.702347 -0.0135,-2.702348 -0.0121,2.727654 -0.0121,2.727653 7.42877,-0.0124 7.42877,-0.0124 z m -6.23412,-5.37516 c -0.034,-0.01377 -0.10191,-0.01461 -0.15083,-0.0019 -0.0489,0.01275 -0.0211,0.02402 0.0619,0.02504 0.083,0.001 0.12298,-0.0094 0.0889,-0.02318 z m 10.68341,-0.0047 c -1.62466,-0.0074 -4.28318,-0.0074 -5.90783,0 -1.62465,0.0074 -0.29539,0.01338 2.95391,0.01338 3.24931,0 4.57857,-0.006 2.95392,-0.01338 z"
id="path43701" />
<path
style="fill:#f18f26;fill-opacity:1;stroke-width:0.0502793"
d="m 32.202512,27.528379 c -0.85788,-0.897932 -1.29474,-1.769131 -2.09102,-4.169945 -0.45848,-1.382365 -0.61717,-1.768182 -0.79234,-1.926457 -0.24404,-0.220506 -1.66348,-0.341985 -2.82166,-0.241486 -2.690892,0.233501 -5.144037,1.179395 -6.476987,2.497423 -0.229966,0.227393 -0.418121,0.392023 -0.418121,0.365847 0,-0.02618 0.128011,-0.331751 0.284467,-0.679053 0.612348,-1.359288 1.60747,-2.894448 2.554157,-3.940261 l 0.250325,-0.276537 -1.091961,-0.01355 c -0.600578,-0.0075 -1.09196,-0.02371 -1.09196,-0.03612 0,-0.05096 0.884286,-1.682765 1.257643,-2.320774 0.220867,-0.377426 0.401575,-0.693185 0.401575,-0.701687 0,-0.0085 0.150592,-0.248405 0.334648,-0.533115 1.364098,-2.110082 3.197284,-4.1069 4.740354,-5.163486 0.64361,-0.4407007 1.91774,-1.1351211 2.40992,-1.3134489 1.6425,-0.5951092 4.5421,-0.886847 7.53603,-0.7582232 2.9581,0.1270843 4.52318,0.4525661 5.97067,1.2416886 2.07049,1.1287605 3.46826,2.3767155 5.11952,4.5707825 0.51181,0.680063 1.34137,1.890066 1.34137,1.956538 0,0.0109 0.16629,0.299165 0.36953,0.640582 0.38189,0.641502 1.28969,2.309489 1.28969,2.369648 0,0.01874 -0.48716,0.04016 -1.08259,0.04762 l -1.08259,0.01355 0.40935,0.477654 c 0.72861,0.850182 1.45934,1.935402 2.00828,2.982522 0.2891,0.551465 0.65258,1.356755 0.65258,1.445796 0,0.02481 -0.18708,-0.141233 -0.41573,-0.368981 -0.45937,-0.457548 -0.94751,-0.811573 -1.59544,-1.157098 -1.84659,-0.984732 -4.76585,-1.563688 -6.76214,-1.341089 -0.76064,0.08482 -0.88201,0.134495 -1.04257,0.426732 -0.22706,0.413268 -0.46651,1.018831 -0.89924,2.274161 -0.22623,0.656295 -0.48858,1.37427 -0.58299,1.595499 -0.40425,0.947246 -0.90368,1.72207 -1.42325,2.208069 -0.24104,0.225466 -0.26262,0.235288 -0.34769,0.158299 -0.19011,-0.172053 -0.65957,-0.201352 -3.19631,-0.199487 -2.51364,0.0018 -3.06469,0.03486 -3.24069,0.194139 -0.0815,0.07373 -0.11542,0.05045 -0.47483,-0.325747 z m 2.87384,-7.075775 -6.52323,-0.01295 -0.0136,-2.300091 -0.0136,-2.300092 -0.0121,2.325419 -0.0121,2.325419 6.54888,-0.01238 6.54888,-0.01238 z m -5.3543,-5.37516 c -0.034,-0.01377 -0.10191,-0.01461 -0.15083,-0.0019 -0.0489,0.01275 -0.0211,0.02402 0.0619,0.02504 0.083,0.001 0.12298,-0.0094 0.0889,-0.02318 z m 9.55583,-0.0047 c -1.00041,-0.0076 -2.65209,-0.0076 -3.6704,-8e-6 -1.0183,0.0076 -0.19979,0.01384 1.81893,0.01384 2.01871,5e-6 2.85187,-0.0062 1.85147,-0.01383 z"
id="path43740" />
<path
style="fill:#f18f26;fill-opacity:1;stroke-width:0.0502793"
d="m 32.212902,27.541936 c -0.84478,-0.868685 -1.34829,-1.873086 -2.12252,-4.234001 -0.42445,-1.294313 -0.62883,-1.773879 -0.80527,-1.889486 -0.38144,-0.24993 -2.3063,-0.33559 -3.49837,-0.155684 -1.514071,0.228503 -2.885963,0.641115 -4.016758,1.208083 -0.785412,0.393797 -1.273442,0.741269 -1.828214,1.30167 -0.186662,0.188555 -0.339386,0.32011 -0.339386,0.292343 0,-0.09043 0.401887,-0.971524 0.713093,-1.563375 0.525569,-0.999526 1.462896,-2.349209 2.147454,-3.092179 l 0.231632,-0.251397 -1.093575,-0.01355 c -0.601467,-0.0075 -1.093576,-0.02547 -1.093576,-0.04004 0,-0.03944 0.801328,-1.530374 1.133204,-2.108417 0.15877,-0.276536 0.346161,-0.604609 0.416424,-0.72905 0.473259,-0.838184 1.562844,-2.34916 2.369313,-3.285629 0.627743,-0.728939 1.752789,-1.804517 2.380439,-2.27578 0.97179,-0.7296601 2.30864,-1.4682698 3.12799,-1.7282229 1.4818,-0.4701224 3.26944,-0.6716382 5.95811,-0.6716382 2.19571,0 3.25741,0.083729 4.7678,0.3760062 1.25667,0.2431792 1.90744,0.5040377 3.24261,1.2997688 1.83536,1.0938421 3.58562,2.8803621 5.24766,5.3563911 0.47178,0.702831 2.1274,3.63113 2.1274,3.762734 0,0.01776 -0.47514,0.03229 -1.05587,0.03229 -0.58072,0 -1.05577,0.01697 -1.05565,0.03771 10e-5,0.02074 0.21762,0.297905 0.48336,0.615922 0.60268,0.721254 1.45469,1.997159 1.86352,2.790662 0.36688,0.712099 0.67968,1.427905 0.65557,1.500223 -0.009,0.02827 -0.0836,-0.03598 -0.16492,-0.142785 -0.38211,-0.502058 -1.4814,-1.265062 -2.41037,-1.673001 -2.14174,-0.94051 -5.18213,-1.364547 -6.83799,-0.953679 l -0.25139,0.06238 -0.23269,0.466103 c -0.2233,0.44729 -0.41196,0.943731 -1.02661,2.701495 -0.51683,1.478012 -1.11319,2.536577 -1.78088,3.161118 -0.23832,0.222928 -0.26642,0.236286 -0.34582,0.164431 -0.18938,-0.171397 -0.75719,-0.207396 -3.22573,-0.204519 -2.43628,0.0028 -3.04453,0.04052 -3.22021,0.199512 -0.0723,0.06546 -0.12097,0.032 -0.45978,-0.316409 z m -3.67347,-9.377043 c -0.008,-0.421717 -0.0153,-0.07667 -0.0153,0.76676 0,0.843436 0.007,1.188478 0.0153,0.76676 0.008,-0.421718 0.008,-1.111802 0,-1.53352 z m 1.18167,-3.087768 c -0.0346,-0.01395 -0.0911,-0.01395 -0.1257,0 -0.0346,0.01395 -0.006,0.02536 0.0628,0.02536 0.0691,0 0.0974,-0.01141 0.0628,-0.02536 z m 8.72685,-0.0043 c -0.57196,-0.0081 -1.52223,-0.0081 -2.11174,-2.3e-5 -0.5895,0.008 -0.12154,0.01464 1.03992,0.01466 1.16145,1.2e-5 1.64377,-0.0066 1.07182,-0.01464 z"
id="path43779" />
<path
style="fill:#f18f26;fill-opacity:1;stroke-width:0.0502793"
d="m 32.184822,27.510248 c -0.44477,-0.464575 -0.75357,-0.912708 -1.08864,-1.579867 -0.3169,-0.630995 -0.47479,-1.037933 -0.9597,-2.473588 -0.6596,-1.952829 -0.69217,-2.016569 -1.09094,-2.134994 -0.43944,-0.130499 -1.55914,-0.189997 -2.42982,-0.129114 -2.658845,0.185921 -5.232409,1.16491 -6.60005,2.510674 -0.227308,0.223672 -0.413288,0.386143 -0.413288,0.361047 0,-0.09381 0.368801,-0.905326 0.685502,-1.508386 0.533162,-1.015244 1.384908,-2.266627 2.048972,-3.010346 0.155257,-0.17388 0.282286,-0.337916 0.282286,-0.364525 0,-0.02945 -0.413128,-0.04838 -1.055866,-0.04838 -0.580726,0 -1.055866,-0.01369 -1.055866,-0.03043 0,-0.137871 1.665309,-3.075618 2.169204,-3.826661 1.197958,-1.785524 2.837142,-3.599712 4.127966,-4.568674 0.93684,-0.703248 2.29005,-1.4587652 3.08609,-1.7230229 2.82621,-0.9381997 9.2758,-0.9273473 12.07134,0.020312 0.713,0.2417002 2.06975,0.9989949 2.94336,1.6428839 1.39549,1.028547 2.89971,2.684807 4.20425,4.629195 0.52197,0.777977 2.16874,3.680774 2.16874,3.822874 0,0.01844 -0.47514,0.03352 -1.05587,0.03352 -0.58072,0 -1.05521,0.01697 -1.05441,0.03771 8e-4,0.02074 0.1821,0.252654 0.40289,0.515363 0.74682,0.888627 1.48266,1.99088 1.98607,2.97505 0.28875,0.564501 0.62635,1.32273 0.62635,1.406755 0,0.02688 -0.17751,-0.12864 -0.39447,-0.345596 -1.41234,-1.412345 -4.12153,-2.401571 -6.99659,-2.554719 -0.69945,-0.03726 -1.64638,0.03398 -2.05173,0.154357 l -0.26131,0.0776 -0.22146,0.463109 c -0.19834,0.414745 -0.4231,1.012699 -1.09068,2.901655 -0.44448,1.257688 -1.07576,2.348426 -1.69375,2.926482 l -0.25044,0.234259 -0.20893,-0.103372 c -0.30659,-0.151687 -2.26663,-0.219912 -4.41923,-0.153825 -1.45178,0.04457 -1.63244,0.05951 -1.81568,0.150175 l -0.20349,0.100677 z m -3.64593,-8.591165 c -0.0102,-0.145181 -0.0185,-0.0264 -0.0185,0.263967 0,0.290363 0.008,0.409148 0.0185,0.263966 0.0102,-0.145181 0.0102,-0.382751 0,-0.527933 z m 1.15602,-3.839036 c -0.0167,-0.01671 -0.0601,-0.01849 -0.0964,-0.004 -0.0401,0.01605 -0.0282,0.02796 0.0304,0.03038 0.053,0.0022 0.0827,-0.0097 0.066,-0.02641 z m 7.99743,-0.0067 c -0.15792,-0.0099 -0.42943,-0.01003 -0.60335,-2.01e-4 -0.17392,0.0098 -0.0447,0.01798 0.28714,0.01808 0.33184,1.01e-4 0.47414,-0.008 0.31621,-0.0179 z"
id="path43818" />
<path
style="fill:#f18f26;fill-opacity:1;stroke-width:0.0502793"
d="m 32.246822,27.586146 c -0.44912,-0.46165 -0.77413,-0.921958 -1.09768,-1.554631 -0.35712,-0.698319 -0.50174,-1.067487 -1.04548,-2.668928 -0.52982,-1.56044 -0.68367,-1.895886 -0.91305,-1.990778 -0.43315,-0.179189 -2.19034,-0.250274 -3.17761,-0.128545 -1.539359,0.189799 -3.236874,0.697742 -4.399444,1.316434 -0.653142,0.347585 -1.052894,0.638018 -1.571229,1.141547 -0.24197,0.235057 -0.439945,0.404558 -0.439945,0.376667 0,-0.104533 0.272394,-0.719479 0.617779,-1.394674 0.54181,-1.059186 1.385523,-2.307419 2.150618,-3.181736 0.135396,-0.154724 0.234019,-0.300986 0.219162,-0.325024 -0.01486,-0.02404 -0.489504,-0.04371 -1.054772,-0.04371 -0.565267,0 -1.027759,-0.01453 -1.027759,-0.03229 0,-0.13601 1.660303,-3.067457 2.160206,-3.814081 1.53488,-2.2924 3.338654,-4.149172 5.072834,-5.221896 0.68736,-0.4251822 1.63914,-0.9096447 2.08206,-1.0597805 0.81077,-0.2748262 2.12936,-0.5100076 3.58155,-0.638796 0.90383,-0.080157 4.05342,-0.079476 4.97765,0.00108 1.54321,0.1345005 3.00455,0.4073241 3.77296,0.7043904 0.4945,0.1911708 1.6471,0.8170272 2.257,1.2255301 1.61732,1.08328 3.25675,2.818797 4.68948,4.964335 0.54983,0.823379 2.17721,3.692152 2.17721,3.838024 0,0.01842 -0.44686,0.03383 -0.99302,0.03425 -0.54616,4.03e-4 -1.01874,0.01739 -1.05018,0.03771 -0.0372,0.02403 0.0821,0.203835 0.34149,0.514593 0.46779,0.560485 0.9475,1.226338 1.39209,1.93225 0.34411,0.546372 1.13811,2.120417 1.1938,2.366633 0.0307,0.135554 -0.006,0.111054 -0.36484,-0.241791 -0.55033,-0.541597 -1.13214,-0.944948 -1.90202,-1.318634 -1.41229,-0.685492 -3.03164,-1.10039 -4.81663,-1.234084 -0.86003,-0.06442 -1.87225,-0.007 -2.34356,0.132992 -0.25105,0.07455 -0.2578,0.08188 -0.45326,0.491388 -0.23794,0.498551 -0.35585,0.804095 -0.81687,2.116898 -0.19366,0.551449 -0.41999,1.173656 -0.50297,1.382682 -0.37957,0.956182 -0.9389,1.852392 -1.48763,2.383612 -0.24427,0.236471 -0.25547,0.241404 -0.37311,0.164323 -0.0667,-0.0437 -0.28992,-0.100907 -0.49603,-0.127113 -0.62273,-0.07918 -2.49651,-0.106834 -4.10597,-0.0606 -1.36791,0.03929 -1.53925,0.05369 -1.72334,0.144766 l -0.20441,0.101133 z"
id="path43857" />
<path
style="fill:#f18f26;fill-opacity:1;stroke-width:0.0502793"
d="m 32.290872,27.642829 c -0.42738,-0.432058 -0.82613,-0.994183 -1.1382,-1.604554 -0.35437,-0.6931 -0.57721,-1.261284 -1.07054,-2.729591 -0.21783,-0.64836 -0.47586,-1.338444 -0.57338,-1.53352 -0.19902,-0.398091 -0.26934,-0.439497 -0.90187,-0.531014 -0.51993,-0.07523 -2.08831,-0.0595 -2.75273,0.02759 -1.115202,0.14619 -2.277019,0.44766 -3.286207,0.852708 -1.088828,0.437013 -1.783874,0.868696 -2.502961,1.55455 -0.588859,0.561646 -0.588133,0.521868 0.01277,-0.699864 0.606453,-1.233008 1.30204,-2.306209 2.136398,-3.296187 0.330083,-0.391649 0.385153,-0.480745 0.314571,-0.508938 -0.04706,-0.0188 -0.521105,-0.03577 -1.053437,-0.03771 -0.532332,-0.0019 -0.967877,-0.01862 -0.967877,-0.03706 0,-0.124898 1.605916,-2.980203 2.087205,-3.711033 1.3941,-2.116919 3.186378,-4.023289 4.791578,-5.096582 0.46566,-0.3113611 1.11046,-0.6824962 1.70835,-0.9832937 1.2718,-0.6398471 3.35551,-0.9712565 6.34583,-1.0092898 3.18137,-0.040463 5.6787,0.2818303 7.03327,0.9076827 1.49558,0.6910001 2.77712,1.5889428 3.97674,2.7864108 1.61584,1.612944 2.99085,3.580493 4.47869,6.408707 0.19211,0.365175 0.34929,0.677703 0.34929,0.694508 0,0.0168 -0.45068,0.03753 -1.00152,0.04605 -0.55083,0.0085 -1.01778,0.03183 -1.03768,0.05178 -0.0199,0.01996 0.0824,0.178336 0.22727,0.351956 0.91646,1.098194 1.63526,2.19891 2.24185,3.43299 0.60002,1.220717 0.60096,1.261037 0.0163,0.703911 -0.26116,-0.248883 -0.65507,-0.572872 -0.87536,-0.719976 -1.94037,-1.295749 -5.36397,-2.055624 -7.71616,-1.712621 -0.59776,0.08717 -0.62747,0.10635 -0.83244,0.53764 -0.25287,0.532044 -0.41733,0.954211 -0.82167,2.109194 -0.1911,0.545857 -0.41945,1.173472 -0.50746,1.394701 -0.39022,0.980902 -0.94346,1.870135 -1.49679,2.405801 -0.24537,0.237545 -0.25497,0.241726 -0.37472,0.163265 -0.2253,-0.147624 -0.87979,-0.185601 -3.18201,-0.184635 -2.30009,9.66e-4 -3.01221,0.04044 -3.22315,0.17865 -0.11368,0.07449 -0.12762,0.06717 -0.404,-0.21224 z"
id="path43896" />
<path
style="fill:#f18f26;fill-opacity:1;stroke-width:0.0502793"
d="m 32.289722,27.645005 c -0.91417,-0.94931 -1.32416,-1.742554 -2.1387,-4.137933 -0.515,-1.514499 -0.66738,-1.879371 -0.84858,-2.031841 -0.25124,-0.211407 -0.60513,-0.256092 -2.00732,-0.253472 -1.39843,0.0026 -1.877889,0.06065 -3.083226,0.373225 -1.836256,0.476185 -3.151953,1.140892 -4.167774,2.105612 -0.556797,0.528788 -0.558028,0.490824 -0.02013,-0.620898 0.591698,-1.222918 1.335546,-2.380104 2.172925,-3.380366 0.20299,-0.242475 0.36972,-0.455004 0.370511,-0.472288 0.003,-0.06659 -0.345274,-0.09427 -1.186411,-0.09427 -0.480482,0 -0.873603,-0.01509 -0.873603,-0.03352 0,-0.126809 1.510769,-2.823522 2.049063,-3.657565 0.711,-1.101635 1.750295,-2.389306 2.716769,-3.366037 1.214926,-1.22782 2.247206,-1.975378 3.821296,-2.7673067 1.08472,-0.545723 2.80554,-0.8702497 5.25371,-0.990787 2.84103,-0.1398801 5.91848,0.1234604 7.4776,0.6398651 0.86035,0.2849616 2.19805,1.0215625 3.14246,1.7303796 1.46529,1.099769 3.20484,3.063773 4.38478,4.950562 0.58586,0.936818 1.92527,3.344592 1.92527,3.460929 0,0.01842 -0.4016,0.03616 -0.89246,0.03943 -0.49085,0.0033 -0.95769,0.02024 -1.03741,0.03771 l -0.14496,0.03176 0.43223,0.541124 c 0.57234,0.716534 1.05615,1.402831 1.44393,2.048261 0.34819,0.579531 1.02598,1.948309 1.08303,2.187151 0.0323,0.135225 -0.008,0.108727 -0.38955,-0.256004 -0.72669,-0.69469 -1.49546,-1.178794 -2.53112,-1.593889 -1.03541,-0.414991 -2.23144,-0.718368 -3.42379,-0.868447 -1.19753,-0.150732 -3.01698,-0.07553 -3.27089,0.135199 -0.19588,0.162573 -0.51891,0.935502 -1.17412,2.809398 -0.59961,1.714853 -1.19201,2.80287 -1.89849,3.486806 -0.24234,0.234602 -0.25631,0.240868 -0.37076,0.166265 -0.21878,-0.142607 -0.93622,-0.183811 -3.18466,-0.182904 -2.30869,9.3e-4 -3.01927,0.03947 -3.22605,0.174952 -0.12041,0.0789 -0.12827,0.07479 -0.40357,-0.211097 z"
id="path43935" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:1.25;font-family:Overpass;-inkscape-font-specification:Overpass;letter-spacing:-1px;fill:#272b2b;fill-opacity:1;stroke:none"
x="26.83289"
y="23.576347"
id="text48393"><tspan
sodipodi:role="line"
id="tspan48391"
x="26.83289"
y="23.576347"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;font-family:Overpass;-inkscape-font-specification:Overpass;fill:#272b2b;fill-opacity:1">32</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:1.25;font-family:Overpass;-inkscape-font-specification:Overpass;letter-spacing:-1px;fill:#272b2b;fill-opacity:1;stroke:#f18f26;stroke-width:0.2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
x="-0.086526871"
y="23.6"
id="text48393-3"><tspan
sodipodi:role="line"
id="tspan48391-6"
x="-0.086526871"
y="23.6"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;font-family:Overpass;-inkscape-font-specification:Overpass;fill:#272b2b;fill-opacity:1;stroke:#f18f26;stroke-width:0.2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1">fox</tspan></text>
</svg>

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 586 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

View File

@ -1,70 +0,0 @@
// audio.rs
use crate::Interrupt;
use crate::memory::Memory;
use std::sync::{Arc, Mutex};
use std::sync::mpsc::Sender;
use std::{thread, time};
use rodio::{OutputStream, buffer::SamplesBuffer, Sink};
const AUDIO_BUFFER_0_ADDRESS: usize = 0x0212C000;
const AUDIO_BUFFER_1_ADDRESS: usize = 0x02134000;
const AUDIO_BUFFER_2_ADDRESS: usize = 0x02290000;
const AUDIO_BUFFER_3_ADDRESS: usize = 0x02298000;
const AUDIO_BUFFER_SIZE: usize = 0x8000;
const AUDIO_CHANNEL_0_INTERRUPT: u8 = 0xFE;
const AUDIO_CHANNEL_1_INTERRUPT: u8 = 0xFD;
const AUDIO_CHANNEL_2_INTERRUPT: u8 = 0xFC;
const AUDIO_CHANNEL_3_INTERRUPT: u8 = 0xFB;
pub struct AudioChannel {
pub id: u8,
pub playing: bool,
pub sample_rate: u32,
}
impl AudioChannel {
pub fn new(id: u8) -> Self {
AudioChannel {
id,
playing: false,
sample_rate: 0,
}
}
// this is terrible
pub fn spawn_thread(this: Arc<Mutex<Self>>, interrupt_sender: Sender<Interrupt>, memory: Memory) {
let (audio_buffer_address, audio_channel_interrupt) = match this.lock().unwrap().id {
0 => (AUDIO_BUFFER_0_ADDRESS, AUDIO_CHANNEL_0_INTERRUPT),
1 => (AUDIO_BUFFER_1_ADDRESS, AUDIO_CHANNEL_1_INTERRUPT),
2 => (AUDIO_BUFFER_2_ADDRESS, AUDIO_CHANNEL_2_INTERRUPT),
3 => (AUDIO_BUFFER_3_ADDRESS, AUDIO_CHANNEL_3_INTERRUPT),
_ => unreachable!(),
};
let builder = thread::Builder::new().name("audio".to_string());
builder.spawn({
move || {
let (_stream, stream_handle) = OutputStream::try_default().unwrap();
let channel = Sink::try_new(&stream_handle).unwrap();
loop {
// every `sleep` number of ms, play what is in the audio buffer
let self_lock = this.lock().unwrap();
if self_lock.playing {
let audio_buffer: Vec<i16> = memory.ram()[audio_buffer_address..audio_buffer_address+AUDIO_BUFFER_SIZE]
.to_vec()
.chunks_exact(2)
.map(|x| ((x[1] as i16) << 8) | x[0] as i16)
.collect();
// 1 Hz = 1000 ms
let sleep: f32 = (1000 as f32 / self_lock.sample_rate as f32) * (AUDIO_BUFFER_SIZE as f32 / 2.0);
channel.append(SamplesBuffer::new(1, self_lock.sample_rate, audio_buffer));
interrupt_sender.send(Interrupt::Request(audio_channel_interrupt)).unwrap();
thread::sleep(time::Duration::from_millis(sleep as u64));
}
}
}
}).unwrap();
}
}

View File

@ -1,300 +0,0 @@
// bus.rs
use crate::{Memory, AudioChannel, DiskController, Keyboard, Mouse, Overlay};
use chrono::prelude::*;
use std::sync::{Arc, Mutex};
use std::io::{Write, stdout};
pub struct Bus {
pub memory: Memory,
pub disk_controller: DiskController,
pub audio_channel_0: Arc<Mutex<AudioChannel>>,
pub audio_channel_1: Arc<Mutex<AudioChannel>>,
pub audio_channel_2: Arc<Mutex<AudioChannel>>,
pub audio_channel_3: Arc<Mutex<AudioChannel>>,
pub keyboard: Arc<Mutex<Keyboard>>,
pub mouse: Arc<Mutex<Mouse>>,
pub overlays: Arc<Mutex<Vec<Overlay>>>,
pub startup_time: i64,
}
impl Bus {
pub fn read_io(&mut self, port: u32) -> u32 {
match port {
0x80000000..=0x8000031F => { // overlay port
let overlay_lock = self.overlays.lock().unwrap();
let overlay_number = (port & 0x000000FF) as usize;
let setting = (port & 0x0000FF00) >> 8;
match setting {
0x00 => {
// we're reading the position of this overlay
let x = overlay_lock[overlay_number].x as u32;
let y = overlay_lock[overlay_number].y as u32;
(y << 16) | x
}
0x01 => {
// we're reading the size of this overlay
let width = overlay_lock[overlay_number].width as u32;
let height = overlay_lock[overlay_number].height as u32;
(height << 16) | width
}
0x02 => {
// we're reading the framebuffer pointer of this overlay
overlay_lock[overlay_number].framebuffer_pointer
}
0x03 => {
// we're reading the enable status of this overlay
overlay_lock[overlay_number].enabled as u32
}
_ => panic!("invalid overlay control port"),
}
}
0x80000400..=0x80000401 => { // mouse port
let setting = (port & 0x000000FF) as u8;
match setting {
0x00 => {
// we're reading the button states
let mut byte: u8 = 0x00;
let mouse_lock = self.mouse.lock().expect("failed to lock the mouse mutex");
if mouse_lock.clicked {
byte |= 0b001;
}
if mouse_lock.released {
byte |= 0b010;
}
if mouse_lock.held {
byte |= 0b100;
} else {
byte &= !0b100;
}
byte as u32
}
0x01 => {
// we're reading the position
let mouse_lock = self.mouse.lock().expect("failed to lock the mouse mutex");
let x = mouse_lock.x as u32;
let y = mouse_lock.y as u32;
(y << 16) | x
}
_ => panic!("invalid mouse control port"),
}
}
0x80000500 => { // keyboard port
let mut keyboard_lock = self.keyboard.lock().expect("failed to lock the keyboard mutex");
keyboard_lock.pop() as u32
}
0x80000600..=0x80000603 => { // audio port
let channel = (port & 0x000000FF) as u8;
match channel {
0 => {
let audio_lock = self.audio_channel_0.lock().unwrap();
audio_lock.sample_rate
},
1 => {
let audio_lock = self.audio_channel_1.lock().unwrap();
audio_lock.sample_rate
},
2 => {
let audio_lock = self.audio_channel_2.lock().unwrap();
audio_lock.sample_rate
},
3 => {
let audio_lock = self.audio_channel_3.lock().unwrap();
audio_lock.sample_rate
},
_ => panic!("invalid audio channel"),
}
}
0x80000700..=0x80000706 => { // RTC port
let setting = (port & 0x000000FF) as u8;
match setting {
0 => { // year
Local::now().year() as u32
},
1 => { // month
Local::now().month()
},
2 => { // day
Local::now().day()
},
3 => { // hour
Local::now().hour()
},
4 => { // minute
Local::now().minute()
},
5 => { // second
Local::now().second()
},
6 => { // milliseconds elapsed since startup
(Local::now().timestamp_millis() - self.startup_time) as u32
},
_ => panic!("invalid RTC port"),
}
}
0x80001000..=0x80002003 => { // disk controller port
let id = port as u8;
let operation = (port & 0x0000F000) >> 8;
match operation {
0x10 => {
// we're reading the current insert state of the specified disk id
if id > 3 {
panic!("invalid disk ID");
}
match &self.disk_controller.disk[id as usize] {
Some(_) => self.disk_controller.get_size(id) as u32, // return size if this disk is inserted
None => 0, // return 0 if this disk is not inserted
}
}
0x20 => {
// we're getting the location of the memory sector buffer
self.disk_controller.buffer_pointer as u32
}
_ => panic!("invalid disk controller port"),
}
}
_ => 0,
}
}
pub fn write_io(&mut self, port: u32, word: u32) {
match port {
0x00000000 => { // terminal output port
print!("{}", word as u8 as char);
stdout().flush().expect("could not flush stdout");
}
0x80000000..=0x8000031F => { // overlay port
let mut overlay_lock = self.overlays.lock().unwrap();
let overlay_number = (port & 0x000000FF) as usize;
let setting = (port & 0x0000FF00) >> 8;
match setting {
0x00 => {
// we're setting the position of this overlay
let x = (word & 0x0000FFFF) as usize;
let y = ((word & 0xFFFF0000) >> 16) as usize;
overlay_lock[overlay_number].x = x;
overlay_lock[overlay_number].y = y;
}
0x01 => {
// we're setting the size of this overlay
let width = (word & 0x0000FFFF) as usize;
let height = ((word & 0xFFFF0000) >> 16) as usize;
overlay_lock[overlay_number].width = width;
overlay_lock[overlay_number].height = height;
}
0x02 => {
// we're setting the framebuffer pointer of this overlay
overlay_lock[overlay_number].framebuffer_pointer = word;
}
0x03 => {
// we're setting the enable status of this overlay
overlay_lock[overlay_number].enabled = word != 0;
}
_ => panic!("invalid overlay control port"),
}
}
0x80000400..=0x80000401 => { // mouse port
let setting = (port & 0x000000FF) as u8;
match setting {
0x00 => {
// we're setting the button states
let mut mouse_lock = self.mouse.lock().expect("failed to lock the mouse mutex");
mouse_lock.clicked = word & (1 << 0) != 0;
mouse_lock.released = word & (1 << 1) != 0;
mouse_lock.held = word & (1 << 2) != 0;
}
0x01 => {
// we're setting the position
let mut mouse_lock = self.mouse.lock().expect("failed to lock the mouse mutex");
let x = (word & 0x0000FFFF) as u16;
let y = ((word & 0xFFFF0000) >> 16) as u16;
mouse_lock.x = x;
mouse_lock.y = y;
}
_ => panic!("invalid mouse control port"),
}
}
0x80000600..=0x80000603 => { // audio port
let channel = (port & 0x000000FF) as u8;
match channel {
0 => {
let mut audio_lock = self.audio_channel_0.lock().unwrap();
audio_lock.playing = word != 0;
audio_lock.sample_rate = word;
},
1 => {
let mut audio_lock = self.audio_channel_1.lock().unwrap();
audio_lock.playing = word != 0;
audio_lock.sample_rate = word;
},
2 => {
let mut audio_lock = self.audio_channel_2.lock().unwrap();
audio_lock.playing = word != 0;
audio_lock.sample_rate = word;
},
3 => {
let mut audio_lock = self.audio_channel_3.lock().unwrap();
audio_lock.playing = word != 0;
audio_lock.sample_rate = word;
},
_ => panic!("invalid audio channel"),
};
}
0x80001000..=0x80005003 => { // disk controller port
let id = port as u8;
let operation = (port & 0x0000F000) >> 8;
match operation {
0x10 => {
// we're requesting a disk to be inserted to the specified disk id
if id > 3 {
panic!("invalid disk ID");
}
let file = self.disk_controller.select_file();
match file {
Some(file) => self.disk_controller.insert(file, id),
None => {},
};
}
0x20 => {
// we're setting the location of the memory sector buffer
self.disk_controller.buffer_pointer = word as usize;
}
0x30 => {
// we're reading the specified sector of the specified disk id into the memory sector buffer
if id > 3 {
panic!("invalid disk ID");
}
self.disk_controller.set_current_sector(id, word);
self.disk_controller.read_into_memory(id, self.memory.ram());
}
0x40 => {
// we're writing the specified sector to the specified disk id from the memory sector buffer
if id > 3 {
panic!("invalid disk ID");
}
self.disk_controller.set_current_sector(id, word);
self.disk_controller.write_from_memory(id, self.memory.ram());
}
0x50 => {
// we're requesting a disk to be removed from the specified disk id
if id > 3 {
panic!("invalid disk ID");
}
self.disk_controller.remove(id);
}
_ => panic!("invalid disk controller port"),
}
}
_ => return,
}
}
}

2935
src/cpu.rs

File diff suppressed because it is too large Load Diff

View File

@ -1,84 +0,0 @@
// disk.rs
use crate::memory::MemoryRam;
use std::io::{Seek, SeekFrom, Read, Write};
use std::fs::File;
use rfd::FileDialog;
pub struct Disk {
file: File,
size: u64,
current_sector: u32,
}
impl Disk {
pub fn new(file: File) -> Self {
Disk {
size: file.metadata().unwrap().len(),
file,
current_sector: 0,
}
}
}
pub struct DiskController {
pub disk: [Option<Disk>; 4],
pub buffer_pointer: usize,
}
impl DiskController {
pub fn new() -> Self {
DiskController {
disk: [None, None, None, None],
buffer_pointer: 0x00000000
}
}
pub fn select_file(&self) -> Option<File> {
let path = FileDialog::new()
.add_filter("Disk Image", &["img", "dsk"])
.add_filter("Raw Binary", &["bin"])
.add_filter("All Files", &["*"])
.set_title(&format!("Select a file to insert"))
.pick_file();
match path {
Some(path) => Some(File::options().read(true).write(true).open(path).expect("failed to open disk image")),
None => None,
}
}
pub fn insert(&mut self, file: File, disk_id: u8) {
self.disk[disk_id as usize] = Some(Disk::new(file));
}
pub fn remove(&mut self, disk_id: u8) {
self.disk[disk_id as usize] = None;
}
pub fn get_size(&self, disk_id: u8) -> u64 {
self.disk[disk_id as usize].as_ref().expect("attempted to access unmounted disk").size
}
pub fn get_current_sector(&self, disk_id: u8) -> u32 {
self.disk[disk_id as usize].as_ref().expect("attempted to access unmounted disk").current_sector
}
pub fn set_current_sector(&mut self, disk_id: u8, sector: u32) {
let mut disk = self.disk[disk_id as usize].as_mut().expect("attempted to access unmounted disk");
disk.current_sector = sector;
disk.file.seek(SeekFrom::Start(sector as u64 * 512)).expect("attempted to seek to sector beyond edge of disk");
}
pub fn read_into_memory(&mut self, disk_id: u8, ram: &mut MemoryRam) -> usize {
let disk = self.disk[disk_id as usize].as_mut().expect("attempted to access unmounted disk");
let mut temp_buffer = [0u8; 512];
let number_of_bytes_read = disk.file.read(&mut temp_buffer).unwrap();
ram[self.buffer_pointer..self.buffer_pointer+512].copy_from_slice(&temp_buffer);
number_of_bytes_read
}
pub fn write_from_memory(&mut self, disk_id: u8, ram: &MemoryRam) -> usize {
let disk = self.disk[disk_id as usize].as_mut().expect("attempted to access unmounted disk");
let number_of_bytes_written = disk.file.write(ram.get(self.buffer_pointer..self.buffer_pointer+512).unwrap()).unwrap();
number_of_bytes_written
}
}

View File

@ -1,122 +0,0 @@
// keyboard.rs
use crate::warn;
use ringbuf::{Consumer, Producer, RingBuffer};
use std::sync::mpsc::Sender;
use winit::event::{ElementState, VirtualKeyCode};
pub struct Keyboard {
consumer: Consumer<u8>,
producer: Producer<u8>,
debug_toggle_sender: Sender<()>,
}
impl Keyboard {
pub fn new(debug_toggle_sender: Sender<()>) -> Self {
let buffer = RingBuffer::<u8>::new(32);
let (producer, consumer) = buffer.split();
Keyboard { consumer, producer, debug_toggle_sender }
}
fn keycode_to_scancode(&self, keycode: VirtualKeyCode) -> u8 {
match keycode {
VirtualKeyCode::Escape => 0x01,
VirtualKeyCode::Key1 => 0x02,
VirtualKeyCode::Key2 => 0x03,
VirtualKeyCode::Key3 => 0x04,
VirtualKeyCode::Key4 => 0x05,
VirtualKeyCode::Key5 => 0x06,
VirtualKeyCode::Key6 => 0x07,
VirtualKeyCode::Key7 => 0x08,
VirtualKeyCode::Key8 => 0x09,
VirtualKeyCode::Asterisk => 0x09,
VirtualKeyCode::Key9 => 0x0A,
VirtualKeyCode::Key0 => 0x0B,
VirtualKeyCode::Minus => 0x0C,
VirtualKeyCode::Equals => 0x0D,
VirtualKeyCode::Back => 0x0E,
VirtualKeyCode::Tab => 0x0F,
VirtualKeyCode::Q => 0x10,
VirtualKeyCode::W => 0x11,
VirtualKeyCode::E => 0x12,
VirtualKeyCode::R => 0x13,
VirtualKeyCode::T => 0x14,
VirtualKeyCode::Y => 0x15,
VirtualKeyCode::U => 0x16,
VirtualKeyCode::I => 0x17,
VirtualKeyCode::O => 0x18,
VirtualKeyCode::P => 0x19,
VirtualKeyCode::LBracket => 0x1A,
VirtualKeyCode::RBracket => 0x1B,
VirtualKeyCode::Return => 0x1C,
VirtualKeyCode::LControl => 0x1D,
VirtualKeyCode::A => 0x1E,
VirtualKeyCode::S => 0x1F,
VirtualKeyCode::D => 0x20,
VirtualKeyCode::F => 0x21,
VirtualKeyCode::G => 0x22,
VirtualKeyCode::H => 0x23,
VirtualKeyCode::J => 0x24,
VirtualKeyCode::K => 0x25,
VirtualKeyCode::L => 0x26,
VirtualKeyCode::Semicolon => 0x27,
VirtualKeyCode::Apostrophe => 0x28,
VirtualKeyCode::Grave => 0x29,
VirtualKeyCode::LShift => 0x2A,
VirtualKeyCode::Backslash => 0x2B,
VirtualKeyCode::Z => 0x2C,
VirtualKeyCode::X => 0x2D,
VirtualKeyCode::C => 0x2E,
VirtualKeyCode::V => 0x2F,
VirtualKeyCode::B => 0x30,
VirtualKeyCode::N => 0x31,
VirtualKeyCode::M => 0x32,
VirtualKeyCode::Comma => 0x33,
VirtualKeyCode::Period => 0x34,
VirtualKeyCode::Slash => 0x35,
VirtualKeyCode::RShift => 0x36,
VirtualKeyCode::LAlt => 0x38,
VirtualKeyCode::Space => 0x39,
VirtualKeyCode::Capital => 0x3A,
VirtualKeyCode::F1 => 0x3B,
VirtualKeyCode::F2 => 0x3C,
VirtualKeyCode::F3 => 0x3D,
VirtualKeyCode::F4 => 0x3E,
VirtualKeyCode::F5 => 0x3F,
VirtualKeyCode::F6 => 0x40,
VirtualKeyCode::F7 => 0x41,
VirtualKeyCode::F8 => 0x42,
VirtualKeyCode::F9 => 0x43,
VirtualKeyCode::F10 => 0x44,
VirtualKeyCode::F11 => 0x57,
VirtualKeyCode::F12 => 0x58,
VirtualKeyCode::Up => 0x67,
VirtualKeyCode::Down => 0x6C,
VirtualKeyCode::Left => 0x69,
VirtualKeyCode::Right => 0x6A,
_ => 0x00,
}
}
pub fn push(&mut self, keycode: Option<VirtualKeyCode>, state: ElementState) {
let mut scancode = if let Some(keycode) = keycode {
self.keycode_to_scancode(keycode)
} else {
0x00
};
if state == ElementState::Released && scancode != 0x00 {
scancode |= 0x80; // "break" scancode
}
if scancode == 0x57 {
self.debug_toggle_sender.send(()).unwrap();
return;
}
self.producer.push(scancode).unwrap_or_else(|_| warn("keyboard buffer full!"));
}
pub fn pop(&mut self) -> u8 {
self.consumer.pop().unwrap_or_default()
}
}

View File

@ -1,352 +0,0 @@
// main.rs
pub mod memory;
pub mod audio;
pub mod bus;
pub mod cpu;
pub mod keyboard;
pub mod mouse;
pub mod disk;
use audio::AudioChannel;
use bus::Bus;
use cpu::{Cpu, Exception, Interrupt};
use keyboard::Keyboard;
use mouse::Mouse;
use disk::DiskController;
use memory::{MEMORY_RAM_START, MEMORY_ROM_START, MemoryRam, Memory};
use std::sync::{Arc, mpsc, Mutex};
use std::thread;
use std::process::exit;
use std::env;
use std::fs::{File, read};
use chrono::prelude::*;
use image;
use log::error;
use pixels::{Pixels, SurfaceTexture};
use winit::dpi::LogicalSize;
use winit::event::{Event, WindowEvent};
use winit::event_loop::{ControlFlow, EventLoop};
use winit::window::{WindowBuilder, Icon};
use winit_input_helper::WinitInputHelper;
const WIDTH: usize = 640;
const HEIGHT: usize = 480;
const FRAMEBUFFER_ADDRESS: usize = 0x02000000;
pub struct Display {
background: Vec<u8>,
overlays: Arc<Mutex<Vec<Overlay>>>,
}
#[derive(Copy, Clone, Debug, Default)]
pub struct Overlay {
enabled: bool,
width: usize,
height: usize,
x: usize,
y: usize,
framebuffer_pointer: u32,
}
fn read_rom() -> Vec<u8> {
read("fox32.rom").unwrap_or_else(|_| {
read("../fox32rom/fox32.rom").unwrap_or_else(|_| {
println!("fox32.rom file not found, using embedded ROM");
include_bytes!("fox32.rom").to_vec()
})
})
}
pub fn error(message: &str) -> ! {
println!("Error: {}", message);
exit(1);
}
pub fn warn(message: &str) {
println!("Warning: {}", message);
}
fn main() {
let version_string = format!("fox32 {} ({})", env!("VERGEN_BUILD_SEMVER"), option_env!("VERGEN_GIT_SHA_SHORT").unwrap_or("unknown"));
println!("{}", version_string);
let args: Vec<String> = env::args().collect();
let (debug_toggle_sender, debug_toggle_receiver) = mpsc::channel::<()>();
let mut display = Display::new();
let keyboard = Arc::new(Mutex::new(Keyboard::new(debug_toggle_sender)));
let mouse = Arc::new(Mutex::new(Mouse::new()));
let audio_channel_0 = Arc::new(Mutex::new(AudioChannel::new(0)));
let audio_channel_1 = Arc::new(Mutex::new(AudioChannel::new(1)));
let audio_channel_2 = Arc::new(Mutex::new(AudioChannel::new(2)));
let audio_channel_3 = Arc::new(Mutex::new(AudioChannel::new(3)));
let (exception_sender, exception_receiver) = mpsc::channel::<Exception>();
let memory = Memory::new(read_rom().as_slice(), exception_sender);
let mut bus = Bus {
memory: memory.clone(),
audio_channel_0: audio_channel_0.clone(),
audio_channel_1: audio_channel_1.clone(),
audio_channel_2: audio_channel_2.clone(),
audio_channel_3: audio_channel_3.clone(),
disk_controller: DiskController::new(),
keyboard: keyboard.clone(),
mouse: mouse.clone(),
overlays: display.overlays.clone(),
startup_time: Local::now().timestamp_millis(),
};
if args.len() > 1 {
let mut args_iter = args.iter();
args_iter.next();
for (i, arg) in args_iter.enumerate() {
bus.disk_controller.insert(File::options().read(true).write(true).open(&arg).expect("failed to load provided disk image"), i as u8);
}
}
let memory_cpu = memory.clone();
let memory_eventloop = memory.clone();
let ram_size = memory_cpu.ram().len();
let ram_bottom_address = MEMORY_RAM_START;
let ram_top_address = ram_bottom_address + ram_size - 1;
println!("RAM: {:.2} MiB mapped at physical {:#010X}-{:#010X}", ram_size / 1048576, ram_bottom_address, ram_top_address);
let rom_size = memory_cpu.rom().len();
let rom_bottom_address = MEMORY_ROM_START;
let rom_top_address = rom_bottom_address + rom_size - 1;
println!("ROM: {:.2} KiB mapped at physical {:#010X}-{:#010X}", rom_size / 1024, rom_bottom_address, rom_top_address);
let mut cpu = Cpu::new(bus, debug_toggle_receiver);
let event_loop = EventLoop::new();
let mut input = WinitInputHelper::new();
let icon = image::load_from_memory(include_bytes!("32.png")).unwrap();
let window = {
let size = LogicalSize::new(WIDTH as f64, HEIGHT as f64);
WindowBuilder::new()
.with_title(version_string)
.with_inner_size(size)
.with_min_inner_size(size)
.with_window_icon(Some(Icon::from_rgba(icon.as_bytes().to_vec(), 128, 128).unwrap()))
.build(&event_loop)
.unwrap()
};
window.set_cursor_visible(false);
let mut pixels = {
let window_size = window.inner_size();
let surface_texture = SurfaceTexture::new(window_size.width, window_size.height, &window);
Pixels::new(WIDTH as u32, HEIGHT as u32, surface_texture).unwrap()
};
let (interrupt_sender, interrupt_receiver) = mpsc::channel::<Interrupt>();
let (exit_sender, exit_receiver) = mpsc::channel::<bool>();
AudioChannel::spawn_thread(audio_channel_0, interrupt_sender.clone(), memory.clone());
AudioChannel::spawn_thread(audio_channel_1, interrupt_sender.clone(), memory.clone());
AudioChannel::spawn_thread(audio_channel_2, interrupt_sender.clone(), memory.clone());
AudioChannel::spawn_thread(audio_channel_3, interrupt_sender.clone(), memory.clone());
let builder = thread::Builder::new().name("cpu".to_string());
builder.spawn({
move || {
loop {
while !cpu.halted {
if let Ok(exception) = exception_receiver.try_recv() {
(cpu.next_exception, cpu.next_exception_operand) = cpu.exception_to_vector(exception);
} else {
if let Ok(interrupt) = interrupt_receiver.try_recv() {
if let Interrupt::Request(vector) = interrupt {
cpu.next_interrupt = Some(vector);
}
}
}
cpu.execute_memory_instruction();
if let Ok(_) = exit_receiver.try_recv() {
// the rest of the VM has exited, stop the CPU thread
break;
}
}
if let Ok(_) = exit_receiver.try_recv() {
// the rest of the VM has exited, stop the CPU thread
break;
}
if !cpu.flag.interrupt {
// the cpu was halted and interrupts are disabled
// at this point, the cpu is dead and cannot resume, break out of the loop
break;
}
if let Ok(interrupt) = interrupt_receiver.recv() {
if let Interrupt::Request(vector) = interrupt {
cpu.next_interrupt = Some(vector);
cpu.halted = false;
}
} else {
// sender is closed, break
break;
}
}
println!("CPU halted");
}
}).unwrap();
event_loop.run(move |event, _, control_flow| {
*control_flow = ControlFlow::Poll;
// draw the current frame
if let Event::MainEventsCleared = event {
// update internal state and request a redraw
match interrupt_sender.send(Interrupt::Request(0xFF)) { // vsync interrupt
Ok(_) => {},
Err(_) => {
*control_flow = ControlFlow::Exit;
return;
}
};
display.update(memory_eventloop.clone().ram());
window.request_redraw();
display.draw(pixels.get_frame());
if pixels
.render()
.map_err(|e| error!("pixels.render() failed: {}", e))
.is_err()
{
*control_flow = ControlFlow::Exit;
return;
}
}
// handle input events
if let Event::WindowEvent { ref event, .. } = event {
if let WindowEvent::KeyboardInput { input, .. } = event {
let mut keyboard_lock = keyboard.lock().unwrap();
let keycode = input.virtual_keycode;
keyboard_lock.push(keycode, input.state);
}
}
if input.update(&event) {
// close events
if input.quit() {
exit_sender.send(true).unwrap();
*control_flow = ControlFlow::Exit;
return;
}
// resize the window
if let Some(size) = input.window_resized() {
pixels.resize_surface(size.width, size.height);
}
let mouse_pixel = input.mouse().map(|(mx, my)| {
let (x, y) = pixels.window_pos_to_pixel((mx, my)).unwrap_or_else(|pos| pixels.clamp_pixel_pos(pos));
(x as u16, y as u16)
}).unwrap_or_default();
// TODO: allow right click
let mut mouse_lock = mouse.lock().expect("failed to lock the mouse mutex");
mouse_lock.x = mouse_pixel.0;
mouse_lock.y = mouse_pixel.1;
if mouse_lock.held && !input.mouse_held(0) {
// mouse button was released this frame
mouse_lock.released = true;
}
mouse_lock.held = input.mouse_held(0);
if input.mouse_pressed(0) {
mouse_lock.clicked = true;
}
}
});
}
impl Display {
fn new() -> Self {
Self {
background: vec![0; (HEIGHT*WIDTH*4) as usize],
overlays: Arc::new(Mutex::new(vec![Overlay { enabled: false, width: 16, height: 16, x: 0, y: 0, framebuffer_pointer: 0 }; 32])),
}
}
fn update(&mut self, ram: &MemoryRam) {
let overlay_lock = self.overlays.lock().unwrap();
for i in 0..(HEIGHT*WIDTH*4) as usize {
self.background[i] = ram[FRAMEBUFFER_ADDRESS + i];
}
for index in 0..=31 {
if overlay_lock[index].enabled {
blit_overlay(&mut self.background, &overlay_lock[index], ram);
}
}
}
fn draw(&self, frame: &mut [u8]) {
for (i, pixel) in frame.chunks_exact_mut(4).enumerate() {
//let x = (i % WIDTH as usize) as i16;
//let y = (i / WIDTH as usize) as i16;
let i = i * 4;
let slice = &self.background[i..i+4];
pixel.copy_from_slice(slice);
}
}
}
// modified from https://github.com/parasyte/pixels/blob/main/examples/invaders/simple-invaders/src/sprites.rs
fn blit_overlay(framebuffer: &mut [u8], overlay: &Overlay, ram: &[u8]) {
//assert!(overlay.x + overlay.width <= WIDTH);
//assert!(overlay.y + overlay.height <= HEIGHT);
let mut width = overlay.width * 4;
let mut height = overlay.height;
// FIXME: this is a hack, and it only allows overlays to go off-screen on the bottom and right sides
// it also completely fucks up the image on the right side :p
if overlay.x + overlay.width > WIDTH {
let difference = (overlay.x + overlay.width) - WIDTH;
width = width - (difference * 4);
//println!("width: {}, difference: {}", width, difference);
}
if overlay.y + overlay.height > HEIGHT {
let difference = (overlay.y + overlay.height) - HEIGHT;
height = height - difference;
//println!("height: {}, difference: {}", height, difference);
}
let overlay_framebuffer = &ram[(overlay.framebuffer_pointer as usize)..((overlay.framebuffer_pointer+((width as u32)*(height as u32))) as usize)];
let mut overlay_framebuffer_index = 0;
for y in 0..height {
let index = overlay.x * 4 + overlay.y * WIDTH * 4 + y * WIDTH * 4;
// merge overlay onto screen
// this is such a dumb hack
let mut zipped = framebuffer[index..index + width].iter_mut().zip(&overlay_framebuffer[overlay_framebuffer_index..overlay_framebuffer_index + width]);
while let Some((left, &right)) = zipped.next() {
let (left_0, &right_0) = (left, &right);
let (left_1, &right_1) = zipped.next().unwrap();
let (left_2, &right_2) = zipped.next().unwrap();
let (left_3, &right_3) = zipped.next().unwrap();
// ensure that the alpha byte is greater than zero, meaning that this pixel shouldn't be transparent
if right_3 > 0 {
*left_0 = right_0;
*left_1 = right_1;
*left_2 = right_2;
*left_3 = right_3;
}
}
overlay_framebuffer_index += width;
}
}

View File

@ -1,303 +0,0 @@
// memory.rs
use crate::error;
use crate::cpu::Exception;
use std::cell::UnsafeCell;
use std::collections::HashMap;
use std::sync::Arc;
use std::io::Write;
use std::fs::File;
use std::sync::mpsc::Sender;
pub const MEMORY_RAM_SIZE: usize = 0x04000000; // 64 MiB
pub const MEMORY_ROM_SIZE: usize = 0x00080000; // 512 KiB
pub const MEMORY_RAM_START: usize = 0x00000000;
pub const MEMORY_ROM_START: usize = 0xF0000000;
pub type MemoryRam = [u8; MEMORY_RAM_SIZE];
pub type MemoryRom = [u8; MEMORY_ROM_SIZE];
#[derive(Debug)]
pub struct MemoryPage {
physical_address: u32,
present: bool,
rw: bool,
}
struct MemoryInner {
ram: Box<MemoryRam>,
rom: Box<MemoryRom>,
mmu_enabled: Box<bool>,
tlb: Box<HashMap<u32, MemoryPage>>,
paging_directory_address: Box<u32>,
exception_sender: Sender<Exception>,
}
impl MemoryInner {
pub fn new(rom: &[u8], exception_sender: Sender<Exception>) -> Self {
let mut this = Self {
// HACK: allocate directly on the heap to avoid a stack overflow
// at runtime while trying to move around a 64MB array
ram: unsafe { Box::from_raw(Box::into_raw(vec![0u8; MEMORY_RAM_SIZE].into_boxed_slice()) as *mut MemoryRam) },
rom: unsafe { Box::from_raw(Box::into_raw(vec![0u8; MEMORY_ROM_SIZE].into_boxed_slice()) as *mut MemoryRom) },
mmu_enabled: Box::from(false),
tlb: Box::from(HashMap::with_capacity(1024)),
paging_directory_address: Box::from(0x00000000),
exception_sender,
};
this.rom.as_mut_slice().write(rom).expect("failed to copy ROM to memory");
this
}
}
#[derive(Clone)]
pub struct Memory(Arc<UnsafeCell<MemoryInner>>);
// SAFETY: once MemoryInner is initialzed, there is no way to modify the Box
// pointers it contains and it does not matter if contents of the byte
// arrays are corrupted
unsafe impl Send for Memory {}
unsafe impl Sync for Memory {}
impl Memory {
pub fn new(rom: &[u8], exception_sender: Sender<Exception>) -> Self {
Self(Arc::new(UnsafeCell::new(MemoryInner::new(rom, exception_sender))))
}
fn inner(&self) -> &mut MemoryInner {
unsafe { &mut *self.0.get() }
}
pub fn ram(&self) -> &mut MemoryRam { &mut self.inner().ram }
pub fn rom(&self) -> &mut MemoryRom { &mut self.inner().rom }
pub fn mmu_enabled(&self) -> &mut bool { &mut self.inner().mmu_enabled }
pub fn tlb(&self) -> &mut HashMap<u32, MemoryPage> { &mut self.inner().tlb }
pub fn paging_directory_address(&self) -> &mut u32 { &mut self.inner().paging_directory_address }
pub fn exception_sender(&self) -> &mut Sender<Exception> { &mut self.inner().exception_sender }
pub fn dump(&self) {
let mut file = File::create("memory.dump").expect("failed to open memory dump file");
file.write_all(self.ram()).expect("failed to write memory dump file");
}
// each table contains 1024 entries
// the paging directory contains pointers to paging tables with the following format:
// bit 0: present
// remaining bits are ignored, should be zero
// bits 12-31: physical address of paging table
// the paging table contains pointers to physical memory pages with the following format:
// bit 0: present
// bit 1: r/w
// remaining bits are ignored, should be zero
// bits 12-31: physical address
pub fn flush_tlb(&self, paging_directory_address: Option<u32>) {
if let Some(address) = paging_directory_address {
*self.paging_directory_address() = address;
};
self.tlb().clear();
}
pub fn flush_page(&self, virtual_address: u32) {
let virtual_page = virtual_address & 0xFFFFF000;
self.tlb().remove(&virtual_page);
}
pub fn insert_tlb_entry_from_tables(&mut self, page_directory_index: u32, page_table_index: u32) -> bool {
let old_state = *self.mmu_enabled();
*self.mmu_enabled() = false;
let directory_address = *self.paging_directory_address();
let directory = self.read_opt_32(directory_address + (page_directory_index * 4));
match directory {
Some(directory) => {
let dir_present = directory & 0b1 != 0;
let dir_address = directory & 0xFFFFF000;
if dir_present {
let table = self.read_opt_32(dir_address + (page_table_index * 4));
match table {
Some(table) => {
let table_present = table & 0b01 != 0;
let table_rw = table & 0b10 != 0;
let table_address = table & 0xFFFFF000;
if table_present {
let tlb_entry = MemoryPage {
physical_address: table_address,
present: table_present,
rw: table_rw,
};
self.tlb().entry((page_directory_index << 22) | (page_table_index << 12)).or_insert(tlb_entry);
}
},
None => {}
}
}
*self.mmu_enabled() = old_state;
dir_present
},
None => {
*self.mmu_enabled() = old_state;
false
}
}
}
pub fn virtual_to_physical(&mut self, virtual_address: u32) -> Option<(u32, bool)> {
let virtual_page = virtual_address & 0xFFFFF000;
let offset = virtual_address & 0x00000FFF;
let physical_page = self.tlb().get(&virtual_page);
let physical_address = match physical_page {
Some(page) => {
if page.present {
Some((page.physical_address | offset, page.rw))
} else {
None
}
},
None => {
let page_directory_index = virtual_address >> 22;
let page_table_index = (virtual_address >> 12) & 0x03FF;
let dir_present = self.insert_tlb_entry_from_tables(page_directory_index, page_table_index);
if !dir_present {
return None;
}
// try again after inserting the TLB entry
let physical_page = self.tlb().get(&virtual_page);
let physical_address = match physical_page {
Some(page) => {
if page.present {
Some((page.physical_address | offset, page.rw))
} else {
None
}
},
None => None,
};
physical_address
},
};
physical_address
}
pub fn read_opt_8(&mut self, mut address: u32) -> Option<u8> {
if *self.mmu_enabled() {
let address_maybe = self.virtual_to_physical(address as u32);
match address_maybe {
Some(addr) => address = addr.0,
None => return None,
}
}
let address = address as usize;
if address >= MEMORY_ROM_START && address < MEMORY_ROM_START + MEMORY_ROM_SIZE {
self.rom().get(address - MEMORY_ROM_START).map(|value| *value)
} else {
self.ram().get(address - MEMORY_RAM_START).map(|value| *value)
}
}
pub fn read_opt_16(&mut self, address: u32) -> Option<u16> {
Some(self.read_opt_8(address)? as u16 |
(self.read_opt_8(address + 1)? as u16) << 8
)
}
pub fn read_opt_32(&mut self, address: u32) -> Option<u32> {
Some(self.read_opt_8(address)? as u32 |
(self.read_opt_8(address + 1)? as u32) << 8 |
(self.read_opt_8(address + 2)? as u32) << 16 |
(self.read_opt_8(address + 3)? as u32) << 24
)
}
pub fn read_8(&mut self, address: u32) -> Option<u8> {
let mut read_ok = true;
let value = self.read_opt_8(address).unwrap_or_else(|| { read_ok = false; 0 });
if read_ok {
Some(value)
} else {
self.exception_sender().send(Exception::PageFaultRead(address)).unwrap();
None
}
}
pub fn read_16(&mut self, address: u32) -> Option<u16> {
Some(self.read_8(address)? as u16 |
(self.read_8(address + 1)? as u16) << 8
)
}
pub fn read_32(&mut self, address: u32) -> Option<u32> {
Some(self.read_8(address)? as u32 |
(self.read_8(address + 1)? as u32) << 8 |
(self.read_8(address + 2)? as u32) << 16 |
(self.read_8(address + 3)? as u32) << 24
)
}
pub fn write_8(&mut self, mut address: u32, byte: u8) -> Option<()> {
let original_address = address;
let mut writable = true;
if *self.mmu_enabled() {
(address, writable) = self.virtual_to_physical(address as u32).unwrap_or_else(|| {
(0, false)
});
}
if writable {
let address = address as usize;
if address >= MEMORY_ROM_START && address < MEMORY_ROM_START + MEMORY_ROM_SIZE {
error(&format!("attempting to write to ROM address: {:#010X}", address));
}
match self.ram().get_mut(address - MEMORY_RAM_START) {
Some(value) => {
*value = byte;
}
None => {
self.exception_sender().send(Exception::PageFaultWrite(original_address)).unwrap();
}
}
Some(())
} else {
self.exception_sender().send(Exception::PageFaultWrite(original_address)).unwrap();
None
}
}
pub fn write_16(&mut self, address: u32, half: u16) -> Option<()> {
// first check if we can write to all addresses without faulting
if *self.mmu_enabled() {
let (_, writable_0) = self.virtual_to_physical(address).unwrap_or_else(|| (0, false));
let (_, writable_1) = self.virtual_to_physical(address + 1).unwrap_or_else(|| (0, false));
if !writable_0 { self.exception_sender().send(Exception::PageFaultWrite(address)).unwrap(); return None }
if !writable_1 { self.exception_sender().send(Exception::PageFaultWrite(address + 1)).unwrap(); return None }
}
// then do the actual writes
self.write_8(address, (half & 0x00FF) as u8)?;
self.write_8(address + 1, (half >> 8) as u8)?;
Some(())
}
pub fn write_32(&mut self, address: u32, word: u32) -> Option<()> {
// first check if we can write to all addresses without faulting
if *self.mmu_enabled() {
let (_, writable_0) = self.virtual_to_physical(address).unwrap_or_else(|| (0, false));
let (_, writable_1) = self.virtual_to_physical(address + 1).unwrap_or_else(|| (0, false));
let (_, writable_2) = self.virtual_to_physical(address + 2).unwrap_or_else(|| (0, false));
let (_, writable_3) = self.virtual_to_physical(address + 3).unwrap_or_else(|| (0, false));
if !writable_0 { self.exception_sender().send(Exception::PageFaultWrite(address)).unwrap(); return None }
if !writable_1 { self.exception_sender().send(Exception::PageFaultWrite(address + 1)).unwrap(); return None }
if !writable_2 { self.exception_sender().send(Exception::PageFaultWrite(address + 2)).unwrap(); return None }
if !writable_3 { self.exception_sender().send(Exception::PageFaultWrite(address + 3)).unwrap(); return None }
}
// then do the actual writes
self.write_8(address, (word & 0x000000FF) as u8)?;
self.write_8(address + 1, ((word & 0x0000FF00) >> 8) as u8)?;
self.write_8(address + 2, ((word & 0x00FF0000) >> 16) as u8)?;
self.write_8(address + 3, ((word & 0xFF000000) >> 24) as u8)?;
Some(())
}
}

View File

@ -1,15 +0,0 @@
// mouse.rs
pub struct Mouse {
pub x: u16,
pub y: u16,
pub clicked: bool,
pub released: bool,
pub held: bool,
}
impl Mouse {
pub fn new() -> Self {
Mouse { x: 0, y: 0, clicked: false, released: false, held: false }
}
}