47 Commits

Author SHA1 Message Date
8be364c990 Merge pull request 'feature/ci-cd-drone-migration' (#3) from feature/ci-cd-drone-migration into develop
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #3
2025-03-10 20:08:38 +00:00
0e2c6b2936 Final commit to merge through develop & master
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone Build is failing
- CI/CD Pipeline now working & tested.
- Commits to all branches will trigger the pipeline in DroneCI.
- Commits to master will trigger the resulting ISO artefact to be uploaded to Gitea as a Package.

# Conflicts:
#	.drone.yml
2025-03-10 12:48:21 +00:00
632c3fa66b DevOps Workflow Improvements
- `VirtualBox-Wrapper.ps1` now takes 'up' or 'down' as opposed to a machine name. This allows start/stop of a virtualmachine.
- `VirtualBox-Wrapper.ps1` now relies on a gitignored `localenv.json` to work.
- `VirtualBox-Wrapper.ps1` can also optionally monitor the log file generated from the serial adapter in VirtualBox.
- `readme.md` updated to provide instructions on how to populate the `localenv.json` file.
- `tasks.json` updated to have a "Clean" task to --remove-orphans, the Build task depends on this.
- `tasks.json` updated to have a "Close VirtualBox" task, this runs the `virtualbox-wrapper.ps1` in 'down' mode. The Build task depends on this.
- `launch.json` updated to run the `VirtualBox-Wrapper.ps1` with the "-Command up" argument, instead of machine name.
- .gitignore updated to ignore any instances of `localenv.json`.
2025-03-09 13:05:39 +00:00
875e3e4765 VirtualBox 7 Compatability Changes
- Created a PowerShell script `virtualbox-wrapper.ps1` to wrap calls to vboxmanage and only exit once the virtual machine has been terminated.
- Updated launch.json to use the PowerShell launch type to launch `virtualbox-wrapper.ps1` with the machine name supplied as an argument.
- Updated `readme.md` to reflect these changes.
2025-03-08 19:29:46 +00:00
e28d68128d Merge branch 'feature/video-refactor' of https://gitlab.spexeah.com/spexeah/asuro into feature/video-refactor 2022-02-07 19:48:15 +00:00
a9969d58f8 Draw texture function added to Video driver. 2022-02-07 19:48:01 +00:00
d7a54d858d TARGA & Texture Units
Added TARGA and Texture units to represent & parse TARGA into and provide a standard texture format for use when drawing.
2022-02-07 19:48:00 +00:00
4e991c3e6f Double Buffer with SSE 128 copy working 2022-02-07 19:48:00 +00:00
a3217de71a SSE MOVUPS/128bit Memcpy + Fixed Doublebuffer 2022-02-07 19:48:00 +00:00
19b433a19f Vesa32 additions + util functions to support 2022-02-07 19:48:00 +00:00
69d1d22a18 Fixed files being weird with case/unit searches 2022-02-07 19:48:00 +00:00
5c15343ed0 Delete files to recommit with lowercase names. 2022-02-07 19:48:00 +00:00
3ae349fbc8 New modular driver set for video
Started outlining how the modular driver set will look for video drawing routines. Currently supports Drawing pixels to the screen & Flushing backbuffer -> frontbuffer.
Still very much test code, tracer is used everywhere for debugging, NOT DEVELOP READY.
Many more draw routines need implementing - such as, but not limited to; drawRect, drawBitmap, drawLine, drawCurve, drawCircle.

TODO: Implement the aforementioned routines in all VESA modes + WindowManager.
2022-02-07 19:48:00 +00:00
78c060c114 Abstracted video driver somewhat
Split out video driver into abstract/standard/implementation.
2022-02-07 19:48:00 +00:00
cd925e96c2 Enabled AVX + Changed flush to flush 2 pixels per iteration. 2022-02-07 19:48:00 +00:00
142dd486dd Double buffering implemented
Double buffering is now enabled with the use of the new large alloc (klalloc).
2022-02-07 19:48:00 +00:00
beeeabd441 Expaneded Video.pas and addec color.pas
Backbuffer will need modification to lmemorymanager to remove the limits to allocation size.
2022-02-07 19:48:00 +00:00
b73c66f6d6 Started work on refactored video. 2022-02-07 19:48:00 +00:00
189526cab8 Merge branch 'feature/kernel-size-awareness' into 'develop'
Kernel Size Awareness

See merge request spexeah/asuro!32
2022-02-07 19:43:45 +00:00
595dd4fbac Merge branch 'feature/compile-script-improvements' into 'develop'
Compile Script Improvements

See merge request spexeah/asuro!31
2022-02-07 19:42:59 +00:00
ba6d8037d2 Compile Script Improvements
Improved the compile script (compile_sources.sh) to show line numbers on error and generally compile faster.
2022-02-06 13:32:57 +00:00
208bda92c8 Kernel Size Awareness
Modified the linker script + Added an init function to System.pas to be called at system boot, this allows tracking of the Kernel start & end addresses, and thus, allows us to calculate the kernel size.
2022-02-06 13:29:29 +00:00
a7111d3cac Draw texture function added to Video driver. 2022-02-06 13:26:12 +00:00
d182fd7f46 TARGA & Texture Units
Added TARGA and Texture units to represent & parse TARGA into and provide a standard texture format for use when drawing.
2022-02-06 13:25:04 +00:00
4c5038b001 Merge branch 'cherry-pick-24c371ca' into 'develop'
Added new String functions

See merge request spexeah/asuro!30
2022-01-31 11:26:25 +00:00
98481ea1ce Added new String functions
(cherry picked from commit 24c371cab1)
2022-01-31 00:36:22 +00:00
b5582b1284 Double Buffer with SSE 128 copy working 2022-01-30 00:17:50 +00:00
346dc4e4c9 Merge branch 'feature/readme-update-1' into 'develop'
Update readme.md

See merge request spexeah/asuro!29
2022-01-29 12:47:56 +00:00
b2eee58df4 Update readme.md 2022-01-29 12:46:35 +00:00
161cea4920 SSE MOVUPS/128bit Memcpy + Fixed Doublebuffer 2022-01-29 01:39:45 +00:00
6b81c4ece0 Vesa32 additions + util functions to support 2022-01-23 16:58:46 +00:00
ee17f69115 Fixed files being weird with case/unit searches 2021-07-07 17:49:04 +01:00
81c19bff16 Delete files to recommit with lowercase names. 2021-07-07 17:49:04 +01:00
e7cda58113 New modular driver set for video
Started outlining how the modular driver set will look for video drawing routines. Currently supports Drawing pixels to the screen & Flushing backbuffer -> frontbuffer.
Still very much test code, tracer is used everywhere for debugging, NOT DEVELOP READY.
Many more draw routines need implementing - such as, but not limited to; drawRect, drawBitmap, drawLine, drawCurve, drawCircle.

TODO: Implement the aforementioned routines in all VESA modes + WindowManager.
2021-07-07 17:49:04 +01:00
44f18554e1 Abstracted video driver somewhat
Split out video driver into abstract/standard/implementation.
2021-07-07 17:49:04 +01:00
52b42ec975 Enabled AVX + Changed flush to flush 2 pixels per iteration. 2021-07-07 17:49:04 +01:00
2815dd9e4d Double buffering implemented
Double buffering is now enabled with the use of the new large alloc (klalloc).
2021-07-07 17:49:04 +01:00
d057bfc3ff Expaneded Video.pas and addec color.pas
Backbuffer will need modification to lmemorymanager to remove the limits to allocation size.
2021-07-07 17:49:04 +01:00
e4621c8aaa Started work on refactored video. 2021-07-07 17:49:04 +01:00
170b93dd69 Merge branch 'feature/pipeline-docs-fix' into 'develop'
Docgen changes

See merge request spexeah/asuro!27
2021-07-06 19:42:57 +00:00
34d6873a6a Docgen changes
Changed docgen job to create doc folder, not public for now.
2021-07-06 20:35:26 +01:00
e69d06ea4f Merge branch 'joe/ci-suggestions' into 'develop'
3 time the charm

See merge request spexeah/asuro!26
2021-07-06 19:18:24 +00:00
2939afa729 3 time the charm 2021-07-06 19:18:23 +00:00
ad8e80913a Merge branch 'feature/documentation' into 'develop'
Changed comments in Asuro.pas when generated

Changed the Asuro.pas comment to be the standard format in terms of Directory->File (no .pas) for PasDoc gen.

See merge request spexeah/asuro!23
2021-07-05 18:23:11 +00:00
33cb042b8c Changed comments in Asuro.pas when generated
Changed the Asuro.pas comment to be the standard format in terms of Directory->File (no .pas) for PasDoc gen.
2021-07-05 19:18:32 +01:00
4d25ceef77 Merge branch 'feature/documentation' into 'develop'
Tidied up comments for docgen.

Added some documentation to Asuro.pas, ProgManager, AHCI, asfs & ATA_ISR to fix some of the pasdoc/docgen issues.

See merge request spexeah/asuro!22
2021-07-05 18:09:51 +00:00
439d4ef8ac Tidied out comments for docgen.
Added some documentation to Asuro.pas & ProgManager.
2021-07-05 19:07:33 +01:00
30 changed files with 1343 additions and 138 deletions

52
.drone.yml Normal file
View File

@ -0,0 +1,52 @@
kind: pipeline
type: docker
name: build
steps:
- name: build-image
image: plugins/docker
settings:
repo: t3hn3rd/asuro-build
tags: latest
dockerfile: Dockerfile
registry: docker.io
username:
from_secret: docker_username
password:
from_secret: docker_password
- name: compile
image: t3hn3rd/asuro-build:latest
depends_on:
- build-image
commands:
- git fetch --tags
- find . -type f -print0 | xargs -0 dos2unix
- chmod +x /drone/src/*.sh
- /drone/src/compile.sh
- name: upload-iso-artifact
image: alpine/git
depends_on:
- compile
when:
branch:
- master
environment:
GITEA_TOKEN:
from_secret: gitea_token
commands:
- apk add --no-cache curl
- chmod +w Asuro.iso
- cp Asuro.iso "Asuro-$(git rev-parse --short HEAD).iso"
- echo "Uploading Asuro-$(git rev-parse --short HEAD).iso to Gitea Packages..."
- |
curl -X PUT "https://gitea.spexeah.com/api/packages/Spexeah/generic/asuro-iso/$(git rev-parse --short HEAD)/Asuro.iso" \
-H "Authorization: token $GITEA_TOKEN" --upload-file "Asuro-$(git rev-parse --short HEAD).iso"
- echo "Updating latest ISO reference..."
- |
curl -X DELETE https://gitea.spexeah.com/api/packages/Spexeah/generic/asuro-iso/latest/Asuro.iso \
-H "Authorization: token $GITEA_TOKEN" || echo "No previous latest version found."
- |
curl -X PUT https://gitea.spexeah.com/api/packages/Spexeah/generic/asuro-iso/latest/Asuro.iso \
-H "Authorization: token $GITEA_TOKEN" --upload-file "Asuro-$(git rev-parse --short HEAD).iso"

3
.gitignore vendored
View File

@ -10,5 +10,4 @@
/*.sh~ /*.sh~
/*.img /*.img
src/include/asuro.pas src/include/asuro.pas
.vscode/launch.json localenv.json
.vscode

View File

@ -1,73 +0,0 @@
stages:
- Compile Versions
- Compile Sources
- Link
- Generate Documentation
- Deploy
cache:
- key: ${CI_COMMIT_REF_SLUG}
paths:
- lib/*.o
- bin/kernel.bin
- doc
before_script:
- chmod +x *.sh
versions:
stage: Compile Versions
script:
- ./compile_vergen.sh
artifacts:
paths:
- release/*.svg
- src/include/asuro.pas
compile_sources:
stage: Compile Sources
script:
- rm -f lib/*.so
- ./compile_sources.sh
needs:
- versions
link:
stage: Link
script:
- ./compile_stub.sh
- ./compile_link.sh
needs:
- versions
- compile_sources
isogen:
stage: Deploy
script:
- ./compile_isogen.sh
- ./compile_sumgen.sh
artifacts:
paths:
- ./Asuro.iso
- ./release/checksum.svg
needs:
- link
docgen:
stage: Generate Documentation
only:
- master
- develop
script:
- ./compile_sourcelist.sh
- ./compile_docs.sh
# Remove comments when we want to use gitlab pages.
#- cp doc public
allow_failure: true
artifacts:
paths:
- doc
#- public/*
#- ./sources.list
needs:
- versions

13
.vscode/launch.json vendored
View File

@ -3,18 +3,11 @@
{ {
"name":"Run", "name":"Run",
"request": "launch", "request": "launch",
"type": "coreclr", "type": "PowerShell",
"preLaunchTask": "Build", "preLaunchTask": "Build",
"program": "VBoxSDL", "script": "${workspaceFolder}/virtualbox-wrapper.ps1",
"args": [ "args": ["-Command", "up"],
"--comment",
"Asuro",
"--startvm",
"7d395c96-891c-4139-b77d-9b6b144b0b93"
],
"cwd": "${workspaceFolder}", "cwd": "${workspaceFolder}",
"console": "internalConsole",
"internalConsoleOptions": "neverOpen"
} }
] ]
} }

26
.vscode/tasks.json vendored
View File

@ -9,14 +9,18 @@
"command": "docker-compose", "command": "docker-compose",
"args": [ "args": [
"run", "run",
"builder" "builder",
], ],
"type": "shell", "type": "shell",
"problemMatcher": [], "problemMatcher": [],
"group": { "group": {
"kind": "build", "kind": "build",
"isDefault": true "isDefault": true
} },
"dependsOn": [
"Close VirtualBox",
"Clean"
]
}, },
{ {
"label": "Build (Builder)", "label": "Build (Builder)",
@ -26,6 +30,24 @@
"builder" "builder"
], ],
"type": "shell" "type": "shell"
},
{
"label": "Clean",
"command": "docker-compose",
"args": [
"down",
"--remove-orphans"
],
"type": "shell"
},
{
"label": "Close VirtualBox",
"command": "./virtualbox-wrapper.ps1",
"args": [
"-Command",
"down"
],
"type": "shell"
} }
] ]
} }

View File

@ -16,7 +16,7 @@ RUN curl -sL https://sourceforge.net/projects/freepascal/files/Linux/$FPC_VERSIO
COPY compile.sh /compile.sh COPY compile.sh /compile.sh
ADD https://raw.githubusercontent.com/fsaintjacques/semver-tool/master/src/semver /usr/bin/semver ADD https://raw.githubusercontent.com/fsaintjacques/semver-tool/master/src/semver /usr/bin/semver
RUN mkdir /code && chmod +x /usr/bin/semver RUN chmod +x /usr/bin/semver
WORKDIR /code WORKDIR /code
RUN find . -type f -print0 | xargs -0 dos2unix RUN find . -type f -print0 | xargs -0 dos2unix
ENTRYPOINT ["/bin/bash", "-c"] ENTRYPOINT ["/bin/bash", "-c"]

View File

@ -20,26 +20,30 @@ runOrFail() {
fi fi
} }
runOrFail $(pwd)/compile_stub.sh "Failed to compile stub!" declare -a run_steps=(
"compile_stub.sh" "Failed to compile stub!"
"compile_vergen.sh" "Versions failed to compile"
"compile_sources.sh" "Failed to compile FPC Sources!"
"compile_link.sh" "Failed linking!"
"compile_isogen.sh" "Failed to create ISO!"
)
#Generate .pas with versioning headers. for ((i=0; i<${#run_steps[@]}; i+=2))
runOrFail $(pwd)/compile_vergen.sh "Versions failed to compile" do
if [ "$ERRCOUNT" -eq "0" ]
#Compile all .pas sources then
runOrFail $(pwd)/compile_sources.sh "Failed to compile FPC Sources!" script=$(pwd)/"${run_steps[$i]}"
message="${run_steps[$i+1]}"
#Link into a binary. runOrFail "$script" "$message"
runOrFail $(pwd)/compile_link.sh "Failed linking!" fi
done
#Generate an ISO with GRUB as the Bootloader.
runOrFail ./compile_isogen.sh "Failed to create ISO!"
#Call generate final artifacts based on failure or success of the above. #Call generate final artifacts based on failure or success of the above.
if [ "$ERRCOUNT" -ne "0" ] if [ "$ERRCOUNT" -ne "0" ]
then then
./compile_finish.sh "failed" . ./compile_finish.sh "failed"
else else
./compile_finish.sh "success" . ./compile_finish.sh "success"
fi fi
cd .. cd ..

View File

@ -4,4 +4,4 @@ echo "======================="
echo " " echo " "
echo "Compiling FPC Sources..." echo "Compiling FPC Sources..."
echo " " echo " "
fpc -Aelf -gw -n -va -O3 -Op3 -Si -Sc -Sg -Xd -CX -XXs -CfSSE -CfSSE2 -Rintel -Pi386 -Tlinux -FElib/ -Fusrc/* -Fusrc/driver/* -Fusrc/driver/net/* src/kernel.pas fpc -Aelf -gw -g -gl -n -vlewn -O3 -Op3 -Si -Sc -Sg -Xd -CX -XXs -CfSSE -CfSSE2 -Rintel -Pi386 -Tlinux -FElib/ -Fusrc/* -Fusrc/driver/* -Fusrc/driver/net/* src/kernel.pas

View File

@ -1,4 +1,3 @@
version: "3.9"
services: services:
builder: builder:
build: . build: .

View File

@ -2,7 +2,7 @@ ENTRY(loader)
SECTIONS SECTIONS
{ {
. = 0xC0100000; . = 0xC0100000;
kernel_start = .;
.text : AT(ADDR(.text) - 0xC0000000) .text : AT(ADDR(.text) - 0xC0000000)
{ {
text = .; _text = .; __text = .; text = .; _text = .; __text = .;
@ -33,4 +33,5 @@ SECTIONS
. = ALIGN(4096); . = ALIGN(4096);
} }
end = .; _end = .; __end = .; end = .; _end = .; __end = .;
kernel_end = .;
} }

View File

@ -13,8 +13,8 @@ We welcome everyone to give building/breaking/fixing/shooting Asuro a go, feel f
I don't think this needs an explaination. I don't think this needs an explaination.
* [VSCode (Optional, but highly recommended)](https://code.visualstudio.com/) * [VSCode (Optional, but highly recommended)](https://code.visualstudio.com/)
Visual Studio code is our IDE of choice, and we have a number of recommended plugins. Visual Studio code is our IDE of choice, and we have a number of recommended plugins.
* [C# Plugin by Microsoft](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csharp) * [PowerShell Plugin by Microsoft](https://marketplace.visualstudio.com/items?itemName=ms-vscode.powershell)
This plugin gives you the ability to use the 'coreclr' task type, allowing the automatic launching of virtualbox with the resulting image generated during compilation of Asuro. This plugin gives you the ability to use the 'PowerShell' task type, allowing the automatic launching of virtualbox with the resulting image generated during compilation of Asuro.
* [VirtualBox](https://www.virtualbox.org/) * [VirtualBox](https://www.virtualbox.org/)
Virtualbox is our Virtualisation environment of choice, don't ask why, it just is. Virtualbox is our Virtualisation environment of choice, don't ask why, it just is.
@ -27,15 +27,15 @@ We welcome everyone to give building/breaking/fixing/shooting Asuro a go, feel f
3. Install Docker for Windows. 3. Install Docker for Windows.
4. Install Git for Windows. 4. Install Git for Windows.
5. Install VSCode & the listed plugins. 5. Install VSCode & the listed plugins.
6. Install VirtualBox. 6. Install VirtualBox (v7+).
7. Clone this repository. 7. Clone this repository.
8. Run the following command in the root of the repo to build the docker image: 8. Run the following command in the root of the repo to build the docker image:
```powershell ```powershell
docker-compose build builder docker compose build builder
``` ```
9. Run the following command to compile Asuro: 9. Run the following command to compile Asuro:
```powershell ```powershell
docker-compose run builder docker compose run builder
``` ```
10. Create a new virtual machine in Virtualbox and mount the `Asuro.iso` generated in step 9 as a boot image. 10. Create a new virtual machine in Virtualbox and mount the `Asuro.iso` generated in step 9 as a boot image.
11. Add the virtualbox installation directory to your `%PATH%` environment variable, usually: 11. Add the virtualbox installation directory to your `%PATH%` environment variable, usually:
@ -50,32 +50,29 @@ We welcome everyone to give building/breaking/fixing/shooting Asuro a go, feel f
```xml ```xml
<Machine uuid="{7d395c96-891c-4139-b77d-9b6b144b0b93}" name="Asuro" OSType="Linux" snapshotFolder="Snapshots" lastStateChange="2021-06-20T20:33:07Z"> <Machine uuid="{7d395c96-891c-4139-b77d-9b6b144b0b93}" name="Asuro" OSType="Linux" snapshotFolder="Snapshots" lastStateChange="2021-06-20T20:33:07Z">
``` ```
Copy the uuid, in our case `7d395c96-891c-4139-b77d-9b6b144b0b93` and replace the uuid found in `.vscode\launch.json` under `args`, so that it looks something like this: Copy the uuid, in our case `7d395c96-891c-4139-b77d-9b6b144b0b93` & create a `localenv.json` file in the project root with the following content:
```json ```json
{ {
"configurations": [ "VirtualBox":{
{ "MachineName":"<YOUR_UUID_OR_MACHINE_NAME>"
"name":"Run", }
"request": "launch",
"type": "coreclr",
"preLaunchTask": "Build",
"program": "VBoxSDL",
"args": [
"--comment",
"Asuro",
"--startvm",
"<YOUR UUID HERE>"
],
"cwd": "${workspaceFolder}",
"console": "internalConsole",
"internalConsoleOptions": "neverOpen"
}
]
} }
``` ```
This will allow VSCode to automatically launch VirtualBox once Asuro has been compiled. This will allow VSCode to automatically launch VirtualBox once Asuro has been compiled.
You can also enable the serial adapter "COM1" in mode "Raw File", give it a path, and provide this path in the `localenv.json` as follows:
```json
{
"VirtualBox" : {
"MachineName": "<YOUR_UUID_OR_MACHINE_NAME>",
"LogLocation": "Fully\\Qualified\\Path\\To\\Your\\Log\\File"
}
}
```
This will allow you to see the console output from Asuro in your host terminal.
13. Open your project folder in VSCode, use CTRL+SHIFT+B to build & F5 to build + run in VBox. 13. Open your project folder in VSCode, use CTRL+SHIFT+B to build & F5 to build + run in VBox.
14. Congratulations! You can now play with Asuro! 14. Congratulations! You can now play with Asuro!
### Gotchas ### Notes & Gotchas
- It was noted that Windows builds above `20H2` seem to have issues installing WSL2. We may have to wait for a patch from Microsoft to fix this. Our devs are currently using build `20H2`. - The above process has been updated to be compatible with VirtualBox 7+, in which VBoxSDL was removed and vboxmanage should be used in its place. A small wrapper powershell script is used to achieve this.
- It was noted that Windows builds above `20H2` seem to have issues installing WSL2. We may have to wait for a patch from Microsoft to fix this. Our devs are currently using build `20H2`.

View File

@ -1776,14 +1776,15 @@ var
fb: puint32; fb: puint32;
Begin Begin
Ready:= False;
fb:= puint32(uint32(multibootinfo^.framebuffer_addr)); fb:= puint32(uint32(multibootinfo^.framebuffer_addr));
Console_Properties.Width:= multibootinfo^.framebuffer_width; Console_Properties.Width:= multibootinfo^.framebuffer_width;
Console_Properties.Height:= multibootinfo^.framebuffer_height; Console_Properties.Height:= multibootinfo^.framebuffer_height;
Console_Properties.BitsPerPixel:= multibootinfo^.framebuffer_bpp; Console_Properties.BitsPerPixel:= multibootinfo^.framebuffer_bpp;
Console_Properties.MAX_CELL_X:= (Console_Properties.Width div 8) - 1; Console_Properties.MAX_CELL_X:= (Console_Properties.Width div 8) - 1;
Console_Properties.MAX_CELL_Y:= (Console_Properties.Height div 16) - 1; Console_Properties.MAX_CELL_Y:= (Console_Properties.Height div 16) - 1;
If Console_Properties.BitsPerPixel <> 16 then while true do begin If Console_Properties.BitsPerPixel <> 16 then begin
exit;
end; end;
kpalloc(uint32(fb)); kpalloc(uint32(fb));
keyboard.hook(@keyhook); keyboard.hook(@keyhook);

View File

@ -291,6 +291,28 @@ begin
end; end;
end; end;
procedure enableAVX();
begin
if CPUID.Capabilities1^.AVX then begin
asm
PUSH EAX
PUSH ECX
PUSH EDX
XOR ECX, ECX
db $0F
db $01
db $D0
OR EAX, 7
db $0F
db $01
db $D1
POP EDX
POP ECX
POP EAX
end;
end;
end;
procedure init(); procedure init();
begin begin
terminal.registerCommand('CPU', @Terminal_Command_CPU, 'CPU Info.'); terminal.registerCommand('CPU', @Terminal_Command_CPU, 'CPU Info.');
@ -300,6 +322,7 @@ begin
getCPUCapabilities; getCPUCapabilities;
getCPUClockSpeed; getCPUClockSpeed;
enableSSE; enableSSE;
enableAVX;
end; end;
end. end.

View File

@ -0,0 +1,100 @@
// Copyright 2021 Kieron Morris
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
{
Driver->Video->Doublebuffer - Implements a very basic double buffer, tested with VESA drivers.
@author(Kieron Morris <kjm@kieronmorris.me>)
}
unit doublebuffer;
interface
uses
lmemorymanager, tracer, videotypes, serial, util;
//Init the driver, and register with the video interface in a state ready for execution.
procedure init(Register : FRegisterDriver);
implementation
function allocateBackBuffer(Width : uint32; Height : uint32; BitsPerPixel : uint8) : uint64;
begin
tracer.push_trace('doublebuffer.allocateBackBuffer.enter');
//This doesn't currently work... Needs a rework of lmemorymanager
allocateBackBuffer:= uint64(klalloc((Width * Height) * BitsPerPixel));
tracer.push_trace('doublebuffer.allocateBackBuffer.exit');
end;
procedure initBackBuffer(VInterface : PVideoInterface; Width : uint32; Height : uint32; BitsPerPixel : uint8);
begin
tracer.push_trace('doublebuffer.initBackBuffer.enter');
if not(VInterface^.BackBuffer.Initialized) then begin
VInterface^.BackBuffer.Location:= allocateBackBuffer(Width, Height, BitsPerPixel);
if (VInterface^.BackBuffer.Location <> 0) then begin
VInterface^.BackBuffer.Width:= Width;
VInterface^.BackBuffer.Height:= Height;
VInterface^.BackBuffer.BitsPerPixel:= BitsPerPixel;
VInterface^.BackBuffer.Initialized:= True;
end;
end;
tracer.push_trace('doublebuffer.initBackBuffer.exit');
end;
procedure Flush(FrontBuffer : PVideoBuffer; BackBuffer : PVideoBuffer);
var
idx : uint32;
Back,Front : uint32;
BufferSize : uint32;
const
//COPY_WIDTH = 64; //Use this for 64bit copies
COPY_WIDTH = 128; //Use this for SSE copies
begin
//tracer.push_trace('doublebuffer.Flush.enter');
if not(BackBuffer^.Initialized) then exit;
if ((FrontBuffer^.Width > BackBuffer^.Width) or (FrontBuffer^.Height > BackBuffer^.Height)) then exit;
Back:= BackBuffer^.Location;
Front:= FrontBuffer^.Location;
BufferSize:= ( ( BackBuffer^.Width * BackBuffer^.Height * BackBuffer^.BitsPerPixel) div COPY_WIDTH ) - 1;
for idx:=0 to BufferSize do begin
//Front[idx]:= Back[idx];
// -- TODO: Get SSE working here for 128bit copies --
__SSE_128_memcpy(Back + (idx * 16), Front + (idx * 16));
end;
//tracer.push_trace('doublebuffer.Flush.exit');
end;
function enable(VideoInterface : PVideoInterface) : boolean;
begin
tracer.push_trace('doublebuffer.enable.enter');
enable:= false;
initBackBuffer(VideoInterface, VideoInterface^.FrontBuffer.Width, VideoInterface^.FrontBuffer.Height, VideoInterface^.FrontBuffer.BitsPerPixel);
if VideoInterface^.BackBuffer.Initialized then begin
VideoInterface^.DefaultBuffer:= @VideoInterface^.BackBuffer;
VideoInterface^.DrawRoutines.Flush:= @Flush;
enable:= true;
end;
tracer.push_trace('doublebuffer.enable.exit');
end;
procedure init(Register : FRegisterDriver);
begin
tracer.push_trace('doublebuffer.init.enter');
Register('BASIC_DOUBLE_BUFFER', @enable);
tracer.push_trace('doublebuffer.init.exit');
end;
end.

87
src/driver/video/vesa.pas Normal file
View File

@ -0,0 +1,87 @@
// Copyright 2021 Kieron Morris
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
{
Driver->Video->VESA - VESA Display Driver.
@author(Kieron Morris <kjm@kieronmorris.me>)
}
unit vesa;
interface
uses
videotypes, tracer, multiboot, lmemorymanager;
//Init the driver, and register with the video interface in a state ready for execution.
procedure init(Register : FRegisterDriver);
implementation
uses
VESA8, VESA16, VESA24, VESA32;
procedure allocateVESAFrameBuffer(Address : uint32; Width : uint32; Height : uint32);
var
LowerAddress, UpperAddress : uint32;
Block : uint32;
begin
tracer.push_trace('VESA.allocateFrameBuffer.enter');
LowerAddress:= ((Address) SHR 22)-1;
UpperAddress:= ((Address + (Width * Height)) SHR 22)+1;
For Block:=LowerAddress to UpperAddress do begin
kpalloc(Block SHL 22);
end;
tracer.push_trace('VESA.allocateFrameBuffer.exit');
end;
procedure initVESAFrameBuffer(VideoBuffer : PVideoBuffer; Location : uint64; Width : uint32; Height : uint32; BitsPerPixel : uint8);
begin
tracer.push_trace('VESA.initVESAFrameBuffer.enter');
if not(VideoBuffer^.Initialized) then begin
VideoBuffer^.Location:= Location;
VideoBuffer^.BitsPerPixel:= BitsPerPixel;
VideoBuffer^.Width:= Width;
VideoBuffer^.Height:= Height;
allocateVESAFrameBuffer(VideoBuffer^.Location, VideoBuffer^.Width, VideoBuffer^.Height);
if VideoBuffer^.Location <> 0 then
VideoBuffer^.Initialized:= True;
end;
tracer.push_trace('VESA.initVESAFrameBuffer.exit');
end;
function enable(VideoInterface : PVideoInterface) : boolean;
begin
tracer.push_trace('VESA.enable.enter');
initVESAFrameBuffer(@VideoInterface^.FrontBuffer, multiboot.multibootinfo^.framebuffer_addr, multiboot.multibootinfo^.framebuffer_width, multiboot.multibootinfo^.framebuffer_height, multiboot.multibootinfo^.framebuffer_bpp);
case (VideoInterface^.FrontBuffer.BitsPerPixel) of
08:VESA8.init(@VideoInterface^.DrawRoutines);
16:VESA16.init(@VideoInterface^.DrawRoutines);
24:VESA24.init(@VideoInterface^.DrawRoutines);
32:VESA32.init(@VideoInterface^.DrawRoutines);
end;
enable:= VideoInterface^.FrontBuffer.Initialized;
tracer.push_trace('VESA.enable.exit');
end;
procedure init(Register : FRegisterDriver);
begin
tracer.push_trace('VESA.init.enter');
if Register <> nil then
Register('VESA', @enable);
tracer.push_trace('VESA.init.exit');
end;
end.

View File

@ -0,0 +1,43 @@
// Copyright 2021 Kieron Morris
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
{
Driver->Video->VESA16 - Implementation of VESA 16bpp draw routines for the VESA Driver.
@author(Kieron Morris <kjm@kieronmorris.me>)
}
unit vesa16;
interface
uses
videotypes, vesa, tracer, color;
//Init the draw routines by providing what we support through the DrawRoutines struct.
procedure init(DrawRoutines : PDrawRoutines);
implementation
procedure DrawPixel(Buffer : PVideoBuffer; X : uint32; Y : uint32; Pixel : TRGB32);
begin
end;
procedure init(DrawRoutines : PDrawRoutines);
begin
tracer.push_trace('vesa16.init.enter');
tracer.push_trace('vesa16.init.exit');
end;
end.

View File

@ -0,0 +1,43 @@
// Copyright 2021 Kieron Morris
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
{
Driver->Video->VESA24 - Implementation of VESA 24bpp draw routines for the VESA Driver.
@author(Kieron Morris <kjm@kieronmorris.me>)
}
unit vesa24;
interface
uses
videotypes, vesa, tracer, color;
//Init the draw routines by providing what we support through the DrawRoutines struct.
procedure init(DrawRoutines : PDrawRoutines);
implementation
procedure DrawPixel(Buffer : PVideoBuffer; X : uint32; Y : uint32; Pixel : TRGB32);
begin
end;
procedure init(DrawRoutines : PDrawRoutines);
begin
tracer.push_trace('vesa24.init.enter');
tracer.push_trace('vesa24.init.exit');
end;
end.

View File

@ -0,0 +1,52 @@
// Copyright 2021 Kieron Morris
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
{
Driver->Video->VESA32 - Implementation of VESA 32bpp draw routines for the VESA Driver.
@author(Kieron Morris <kjm@kieronmorris.me>)
}
unit vesa32;
interface
uses
videotypes, vesa, tracer, color;
//Init the draw routines by providing what we support through the DrawRoutines struct.
procedure init(DrawRoutines : PDrawRoutines);
implementation
procedure DrawPixel(Buffer : PVideoBuffer; X : uint32; Y : uint32; Pixel : TRGB32);
var
Location : PuInt32;
LocationIndex : Uint32;
begin
//tracer.push_trace('vesa32.DrawPixel.enter');
Location:= Puint32(Buffer^.Location);
LocationIndex:= (Y * Buffer^.Width) + X;
Location[LocationIndex]:= uint32(Pixel);
//tracer.push_trace('vesa32.DrawPixel.exit');
end;
procedure init(DrawRoutines : PDrawRoutines);
begin
tracer.push_trace('vesa32.init.enter');
DrawRoutines^.DrawPixel:= @DrawPixel;
tracer.push_trace('vesa32.init.exit');
end;
end.

View File

@ -0,0 +1,43 @@
// Copyright 2021 Kieron Morris
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
{
Driver->Video->VESA8 - Implementation of VESA 8bpp draw routines for the VESA Driver.
@author(Kieron Morris <kjm@kieronmorris.me>)
}
unit vesa8;
interface
uses
videotypes, vesa, tracer, color;
//Init the draw routines by providing what we support through the DrawRoutines struct.
procedure init(DrawRoutines : PDrawRoutines);
implementation
procedure DrawPixel(Buffer : PVideoBuffer; X : uint32; Y : uint32; Pixel : TRGB32);
begin
end;
procedure init(DrawRoutines : PDrawRoutines);
begin
tracer.push_trace('vesa8.init.enter');
tracer.push_trace('vesa8.init.exit');
end;
end.

318
src/driver/video/video.pas Normal file
View File

@ -0,0 +1,318 @@
// Copyright 2021 Kieron Morris
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
{
Driver->Video->Video - Provides an abstract rasterization/drawing interface.
@author(Kieron Morris <kjm@kieronmorris.me>)
}
unit video;
interface
uses
lmemorymanager, tracer, color, videotypes, hashmap, util, texture;
procedure init();
procedure DrawPixel(X : uint32; Y : uint32; Pixel : TRGB32);
procedure DrawLine(x1,y1,x2,y2 : uint32; thickness : uint32; Color : TRGB32);
procedure DrawRect(x1,y1,x2,y2 : uint32; line_thickness : uint32; Color : TRGB32);
procedure FillRect(x1,y1,x2,y2 : uint32; line_thickness : uint32; Line_Color : TRGB32; Fill_Color : TRGB32);
procedure Flush();
function register(DriverIdentifier : pchar; EnableCallback : FEnableDriver) : boolean;
function enable(DriverIdentifier : pchar) : boolean;
function frontBufferWidth : uint32;
function frontBufferHeight : uint32;
function frontBufferBpp : uint8;
function backBufferWidth : uint32;
function backBufferHeight : uint32;
function backBufferBpp : uint8;
Procedure basicFDrawTexture(Buffer : PVideoBuffer; X : uint32; Y : uint32; Texture : PTexture);
implementation
Procedure dummyFDrawPixel(Buffer : PVideoBuffer; X : uint32; Y : uint32; Pixel : TRGB32);
begin
tracer.push_trace('video.dummyFDrawPixel.enter');
//Do nothing, this is the most basic function that must be implemented by a driver.
end;
Procedure basicFFlush(FrontBuffer : PVideoBuffer; BackBuffer : PVideoBuffer);
var
idx : uint32;
Back,Front : puint32;
BufferSize : uint32;
const
COPY_WIDTH = 32;
begin
//tracer.push_trace('video.basicFFlush.enter');
If not(FrontBuffer^.Initialized and BackBuffer^.Initialized) then exit;
if (BackBuffer^.Width > FrontBuffer^.Width) or (BackBuffer^.Height > FrontBuffer^.Height) then exit;
Back:= puint32(BackBuffer^.Location);
Front:= puint32(FrontBuffer^.Location);
BufferSize:= ( (BackBuffer^.Width * BackBuffer^.Height * BackBuffer^.BitsPerPixel ) div COPY_WIDTH ) - 1;
for idx:=0 to BufferSize do begin
Front[idx]:= Back[idx];
end;
end;
Procedure basicFDrawTexture(Buffer : PVideoBuffer; X : uint32; Y : uint32; Texture : PTexture);
var
i, j : uint32;
begin
//Draw texture to Buffer at x and y
for i:=0 to Texture^.Height - 1 do begin
for j:=0 to Texture^.Width - 1 do begin
DrawPixel(X + j, Y + i, Texture^.Pixels[(i * Texture^.Width) + j]);
end;
end;
end;
procedure basicFDrawLine(Buffer : PVideoBuffer; x1,y1,x2,y2 : uint32; thickness : uint32; Color : TRGB32);
var
X, Y, DX, DY, DX1, DY1, PX, PY, XE, YE, I : sint32;
begin
tracer.push_trace('video.basicFDrawLine.enter');
if(x1 = x2) then begin
for Y:=Y1 to Y2 do begin
DrawPixel(X1,Y,Color);
end;
end else if (y1 = y2) then begin
for X:=X1 to X2 do begin
DrawPixel(X,Y1,Color);
end;
end else begin
DX:= X2 - X1;
DY:= Y2 - Y1;
DX1:= util.abs(DX);
DY1:= util.abs(DY);
PX:= 2 * DY1 - DX1;
PY:= 2 * DX1 - DY1;
if (DY1 <= DX1) then begin
if (dx >= 0) then begin
X:= X1; Y:= Y1; XE:= X2;
end else begin
X:= X2; Y:= Y2; XE:= X1;
end;
DrawPixel(X, Y, Color);
I:=0;
while (x < xe) do begin
X:= X + 1;
if (PX < 0) then begin
PX:= PX + 2 + DY1;
end else begin
if(((dx < 0) and (dy < 0)) OR ((dx > 0) and (dy > 0))) then begin
Y:= Y + 1;
end else begin
Y:= Y - 1;
end;
PX:= PX + 2 * (DY1 - DX1);
end;
DrawPixel(X,Y,Color);
I:= I + 1;
end;
end else begin
if (DY >= 0) then begin
X:= X1; Y:= Y1; YE:= Y2;
end else begin
X:= X2; Y:= Y2; YE:= Y1;
end;
DrawPixel(X, Y, Color);
I:=0;
while (Y < YE) do begin
Y:= Y + 1;
if (PY <= 0) then begin
PY:= PY + 2 * DX1;
end else begin
if (((dx < 0) and (dy < 0)) OR ((dx > 0) and (dy > 0))) then begin
X:= X + 1;
end else begin
X:= X - 1;
end;
PY:= PY + 2 * (dx1 - dy1);
end;
DrawPixel(X,Y,Color);
I:= I + 1;
end;
end;
end;
end;
procedure basicFDrawRect(Buffer : PVideoBuffer; x1,y1,x2,y2 : uint32; line_thickness : uint32; Color : TRGB32);
begin
tracer.push_trace('video.basicFDrawRect.enter');
DrawLine(x1,y1,x2,y1,line_thickness,Color);
DrawLine(x1,y2,x2,y2,line_thickness,Color);
DrawLine(x1,y1,x1,y2,line_thickness,Color);
DrawLine(x2,y1,x2,y2,line_thickness,Color);
end;
procedure basicFFillRect(Buffer : PVideoBuffer; x1,y1,x2,y2 : uint32; line_thickness : uint32; Line_Color : TRGB32; Fill_Color : TRGB32);
var
Y : uint32;
begin
tracer.push_trace('video.basicFFillRect.enter');
for Y:=y1 to y2 do begin
DrawLine(x1,y,x2,y,line_thickness,Fill_Color);
end;
DrawRect(x1,y1,x2,y2,line_thickness,Line_Color);
end;
var
VideoInterface : TVideoInterface;
DriverMap : PHashMap;
procedure init();
var
RGB : TRGB32;
x,y : uint32;
begin
tracer.push_trace('video.init.enter');
//Ensure the frontbuffer is empty & nil, ready for initialization by a driver.
VideoInterface.FrontBuffer.Initialized:= false;
VideoInterface.FrontBuffer.Width:= 0;
VideoInterface.FrontBuffer.Height:= 0;
VideoInterface.FrontBuffer.BitsPerPixel:= 0;
VideoInterface.FrontBuffer.Location:= 0;
//Ensure the backbuffer is empty & nil, ready for initialization by a driver.
VideoInterface.BackBuffer.Initialized:= false;
VideoInterface.BackBuffer.Width:= 0;
VideoInterface.BackBuffer.Height:= 0;
VideoInterface.BackBuffer.BitsPerPixel:= 0;
VideoInterface.BackBuffer.Location:= 0;
//Set the default buffer to be the FrontBuffer, assume no double buffering to begin with.
VideoInterface.DefaultBuffer:= @VideoInterface.FrontBuffer;
{ Set the draw routines to point to dummy/empty routines.
Calls will still succeed but do nothing until a driver has registered. }
VideoInterface.DrawRoutines.DrawPixel:= @dummyFDrawPixel;
VideoInterface.DrawRoutines.Flush:= @basicFFlush;
VideoInterface.DrawRoutines.DrawLine:= @basicFDrawLine;
VideoInterface.DrawRoutines.DrawRect:= @basicFDrawRect;
VideoInterface.DrawRoutines.FillRect:= @basicFFillRect;
//Initialize our 'DriverMap', a hashmap of loadable display drivers.
DriverMap:= hashmap.new;
tracer.push_trace('video.init.exit');
end;
function register(DriverIdentifier : pchar; EnableCallback : FEnableDriver) : boolean;
var
Value : Void;
begin
tracer.push_trace('video.register.enter');
register:= false;
Value:= Hashmap.get(DriverMap, DriverIdentifier);
if (Value = nil) then begin
Hashmap.add(DriverMap, DriverIdentifier, void(EnableCallback));
register:= true;
end;
tracer.push_trace('video.register.exit');
end;
function enable(DriverIdentifier : pchar) : boolean;
var
Value : Void;
begin
tracer.push_trace('video.enable.enter');
enable:= false;
Value:= Hashmap.get(DriverMap, DriverIdentifier);
if (Value <> nil) then begin
enable:= FEnableDriver(Value)(@VideoInterface);
end;
tracer.push_trace('video.enable.exit');
end;
procedure DrawPixel(X : uint32; Y : uint32; Pixel : TRGB32);
begin
//tracer.push_trace('video.DrawPixel.enter');
VideoInterface.DrawRoutines.DrawPixel(VideoInterface.DefaultBuffer, X, Y, Pixel);
//tracer.push_trace('video.DrawPixel.exit');
end;
procedure Flush();
begin
//tracer.push_trace('video.Flush.enter');
VideoInterface.DrawRoutines.Flush(@VideoInterface.FrontBuffer, @VideoInterface.BackBuffer);
//tracer.push_trace('video.Flush.exit');
end;
procedure DrawLine(x1,y1,x2,y2 : uint32; thickness : uint32; Color : TRGB32);
begin
VideoInterface.DrawRoutines.DrawLine(VideoInterface.DefaultBuffer,x1,y1,x2,y2,thickness,Color);
end;
procedure DrawRect(x1,y1,x2,y2 : uint32; line_thickness : uint32; Color : TRGB32);
begin
VideoInterface.DrawRoutines.DrawRect(VideoInterface.DefaultBuffer,x1,y1,x2,y2,line_thickness,color);
end;
procedure FillRect(x1,y1,x2,y2 : uint32; line_thickness : uint32; Line_Color : TRGB32; Fill_Color : TRGB32);
begin
VideoInterface.DrawRoutines.FillRect(VideoInterface.DefaultBuffer,x1,y1,x2,y2,line_thickness,Line_Color,Fill_Color);
end;
function frontBufferWidth : uint32;
begin
frontBufferWidth:= VideoInterface.FrontBuffer.Width;
end;
function frontBufferHeight : uint32;
begin
frontBufferHeight:= VideoInterface.FrontBuffer.Height;
end;
function frontBufferBpp : uint8;
begin
frontBufferBpp:= VideoInterface.FrontBuffer.BitsPerPixel;
end;
function backBufferWidth : uint32;
begin
backBufferWidth:= VideoInterface.BackBuffer.Width;
end;
function backBufferHeight : uint32;
begin
backBufferHeight:= VideoInterface.BackBuffer.Height;
end;
function backBufferBpp : uint8;
begin
backBufferBpp:= VideoInterface.BackBuffer.BitsPerPixel;
end;
end.

View File

@ -0,0 +1,92 @@
// Copyright 2021 Kieron Morris
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
{
Driver->Video->Videotypes - Provides types relating to the video framework & driver interface.
@author(Kieron Morris <kjm@kieronmorris.me>)
}
unit videotypes;
interface
uses
color;
type
//Arbitrary pointer to a raw video buffer in memory
VideoBuffer = uint32;
//Struct representing a Memory Mapped Video Buffer
TVideoBuffer = record
//Has this buffer been initialized? Has it been paged/created in memory?
Initialized : Boolean;
//Location of the video buffer in memory as a QWORD.
Location : VideoBuffer;
//How many bits per pixel?
BitsPerPixel : uint8;
//Width of the buffer.
Width : uint32;
//Height of the buffer.
Height : uint32;
end;
//Pointer to a video buffer
PVideoBuffer = ^TVideoBuffer;
//(Abstract) Draw a pixel to screenspace
FDrawPixel = procedure(Buffer : PVideoBuffer; X : uint32; Y : uint32; Pixel : TRGB32);
//(Abstract) Flush backbuffer to MMIO Buffer
FFlush = procedure(FrontBuffer : PVideoBuffer; BackBuffer : PVideoBuffer);
//(Abstract) Draw a line to the screen
FDrawLine = procedure(Buffer : PVideoBuffer; x1,y1,x2,y2 : uint32; thickness : uint32; Color : TRGB32);
//(Abstract) Draw a rect to the screen
FDrawRect = procedure(Buffer : PVideoBuffer; x1,y1,x2,y2 : uint32; line_thickness : uint32; Color : TRGB32);
//(Abstract) Draw a filled rect to the screen
FFillRect = procedure(Buffer : PVideoBuffer; x1,y1,x2,y2 : uint32; line_thickness : uint32; Line_Color : TRGB32; Fill_Color : TRGB32);
//Routines for drawing to the screen
TDrawRoutines = record
DrawPixel : FDrawPixel;
Flush : FFlush;
DrawLine : FDrawLine;
DrawRect : FDrawRect;
FillRect : FFillRect;
end;
//Pointer to drawing routines
PDrawRoutines = ^TDrawRoutines;
//Struct representing the whole video driver.
TVideoInterface = record
//Default buffer to be used when rendering, front buffer for no double buffering, back buffer otherwise.
DefaultBuffer : PVideoBuffer;
//Memory Mapped IO Buffer for raw rasterization.
FrontBuffer : TVideoBuffer;
//Back buffer used for double buffering, this is flushed to FrontBuffer with flush();
BackBuffer : TVideoBuffer;
//Drawing Routines
DrawRoutines : TDrawRoutines;
end;
//Pointer to a video interface struct.
PVideoInterface = ^TVideoInterface;
//(Abstract) Enable method for a driver, called from video to enable driver.
FEnableDriver = function(VideoInterface : PVideoInterface) : boolean;
//(Abstract) Register driver, called from a driver to register with the video interface.
FRegisterDriver = function(DriverIdentifier : pchar; EnableCallback : FEnableDriver) : boolean;
//(Abstract) Init driver, called from _somewhere_ to start the driver and register it with the video interface.
FInitDriver = procedure(Register : FRegisterDriver);
implementation
end.

63
src/include/color.pas Normal file
View File

@ -0,0 +1,63 @@
// Copyright 2021 Kieron Morris
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
{
Include->Color - Provides types relating to color/graphics.
@author(Kieron Morris <kjm@kieronmorris.me>)
}
unit color;
interface
type
TRGB32 = bitpacked record
B : uint8;
G : uint8;
R : uint8;
A : uint8;
end;
PRGB32 = ^TRGB32;
TRGB24 = bitpacked record
B : uint8;
G : uint8;
R : uint8;
end;
PRGB23 = ^TRGB24;
TRGB16 = bitpacked record
B : UBit5;
G : UBit6;
R : UBit5;
end;
PRGB16 = ^TRGB16;
TRGB8 = bitpacked record
B : UBit2;
G : UBit4;
R : UBit2;
end;
PRGB8 = ^TRGB8;
const
black : TRGB32 = (B: 000; G: 000; R: 000; A: 000);
white : TRGB32 = (B: 255; G: 255; R: 255; A: 000);
red : TRGB32 = (B: 000; G: 000; R: 255; A: 000);
green : TRGB32 = (B: 000; G: 255; R: 000; A: 000);
blue : TRGB32 = (B: 255; G: 000; R: 000; A: 000);
implementation
end.

View File

@ -16,6 +16,7 @@
Include->Strings - String Manipulation. Include->Strings - String Manipulation.
@author(Kieron Morris <kjm@kieronmorris.me>) @author(Kieron Morris <kjm@kieronmorris.me>)
@author(Aaron Hance <ah@aaronhance.me>)
} }
unit strings; unit strings;
@ -33,6 +34,10 @@ function stringCopy(str : pchar) : pchar;
function stringNew(size : uint32) : pchar; function stringNew(size : uint32) : pchar;
function stringSize(str : pchar) : uint32; function stringSize(str : pchar) : uint32;
function stringConcat(str1, str2 : pchar) : pchar; function stringConcat(str1, str2 : pchar) : pchar;
function stringTrim(str : pchar; length : uint32) : pchar;
function stringSub(str : pchar; start, size : uint32) : pchar;
function stringReplace(str, find, replace : pchar) : pchar;
function stringIndexOf(str, find : pchar) : sint32;
function stringContains(str : pchar; sub : pchar) : boolean; function stringContains(str : pchar; sub : pchar) : boolean;
function stringToInt(str : pchar) : uint32; function stringToInt(str : pchar) : uint32;
function hexStringToInt(str : pchar) : uint32; function hexStringToInt(str : pchar) : uint32;
@ -151,6 +156,94 @@ begin
stringConcat:= result; stringConcat:= result;
end; end;
// Trim the string to the specified length.
function stringTrim(str : pchar; length : uInt32) : pchar;
var
result : pchar;
begin
result:= stringNew(length);
memcpy(uint32(str), uint32(result), length);
stringTrim:= result;
end;
// Return a substring of the string.
function stringSub(str : pchar; start, size : uint32) : pchar;
var
result : pchar;
begin
result:= stringNew(size);
memcpy(uint32(str)+start, uint32(result), size);
stringSub:= result;
end;
// Replace first instance of a string with another.
function stringReplace(str, find, replace : pchar) : pchar;
var
result : pchar;
i, j, k : uint32;
found : boolean;
begin
// Find the first instance of the find string.
i:= 0;
found:= false;
while (i < stringSize(str)) and (not found) do begin
if stringEquals(str+i, find) then begin
found:= true;
end else begin
inc(i);
end;
end;
// If we found the find string, replace it.
if found then begin
result:= stringNew(stringSize(str) - stringSize(find) + stringSize(replace));
j:= 0;
k:= 0;
while i < stringSize(str) do begin
if stringEquals(str+i, find) then begin
memcpy(uint32(replace), uint32(result+j), stringSize(replace));
j:= j + stringSize(replace);
inc(i, stringSize(find));
end else begin
result[j]:= str[i];
inc(j);
inc(i);
end;
end;
stringReplace:= result;
end else begin
stringReplace:= stringCopy(str);
end;
// Return the result.
stringReplace:= result;
end;
// Find the index of the first instance of a string.
function stringIndexOf(str, find : pchar) : sint32;
var
i : uint32;
found : boolean;
begin
i:= 0;
found:= false;
while (i < stringSize(str)) and (not found) do begin
if stringEquals(str+i, find) then begin
found:= true;
end else begin
inc(i);
end;
end;
if found then begin
stringIndexOf:= i;
end else begin
stringIndexOf:= -1;
end;
end;
function stringContains(str : pchar; sub : pchar) : boolean; function stringContains(str : pchar; sub : pchar) : boolean;
var var
strEnd, subEnd, i, j, count : uint32; strEnd, subEnd, i, j, count : uint32;

View File

@ -143,6 +143,22 @@ type
PText = ^Text; PText = ^Text;
var
AK_START : uint32; external name 'kernel_start';
AK_END : uint32; external name 'kernel_end';
ASURO_KERNEL_START : uint32;
ASURO_KERNEL_END : uint32;
ASURO_KERNEL_SIZE : uint32;
procedure init();
implementation implementation
procedure init();
begin
ASURO_KERNEL_START := uint32(@AK_START);
ASURO_KERNEL_END := uint32(@AK_END);
ASURO_KERNEL_SIZE:= ASURO_KERNEL_END - ASURO_KERNEL_START;
end;
end. end.

67
src/include/targa.pas Normal file
View File

@ -0,0 +1,67 @@
unit targa;
interface
uses
lmemorymanager, texture;
type
TTARGAColor = packed record
b, g, r, a: uint8;
end;
PTARGAColor = ^TTARGAColor;
TTARGAHeader = packed record
Magic: uint8;
ColorMapType: uint8;
ImageType: uint8;
ColorMapOrigin: uint16;
ColorMapLength: uint16;
ColorMapDepth: uint8;
XOrigin: uint16;
YOrigin: uint16;
Width: uint16;
Height: uint16;
PixelDepth: uint8;
ImageDescriptor: uint8;
Data : PTARGAColor;
end;
PTARGAHeader = ^TTARGAHeader;
Function Parse(buffer : puint8; len : uint32) : PTexture;
implementation
Function Parse(buffer : puint8; len : uint32) : PTexture;
var
header : PTARGAHeader;
i, j : uint32;
data : PTARGAColor;
tex : PTexture;
begin
if (len < sizeof(TTARGAHeader)) then exit;
header := PTARGAHeader(buffer);
if (header^.Magic <> $0) or (header^.ImageType <> 2) or (header^.PixelDepth <> 32) then exit;
//Create a new texture
tex:= texture.newTexture(header^.Width, header^.Height);
tex^.Width:= header^.Width;
tex^.Height:= header^.Height;
//Copy the data
data := PTARGAColor(header^.Data);
for i := 0 to header^.Height - 1 do begin
for j := 0 to header^.Width - 1 do begin
tex^.Pixels[i * header^.Width + j].r := data^.r;
tex^.Pixels[i * header^.Width + j].g := data^.g;
tex^.Pixels[i * header^.Width + j].b := data^.b;
tex^.Pixels[i * header^.Width + j].a := data^.a;
end;
end;
Parse := tex;
end;
end.

34
src/include/texture.pas Normal file
View File

@ -0,0 +1,34 @@
unit texture;
interface
uses
lmemorymanager, color;
type
TTexture = packed record
Width : uint32;
Height : uint32;
Size : uint32;
Pixels : PRGB32;
end;
PTexture = ^TTexture;
Function newTexture(width, height: uint32): PTexture;
implementation
Function newTexture(width, height: uint32): PTexture;
var
texture: PTexture;
begin
texture:= PTexture(kalloc(sizeof(TTexture)));
texture^.Pixels:= PRGB32(kalloc(width * height * sizeof(TRGB32)));
texture^.Width:= width;
texture^.Height:= height;
texture^.Size:= width * height;
newTexture:= texture;
end;
end.

View File

@ -49,6 +49,7 @@ procedure io_wait;
procedure memset(location : uint32; value : uint8; size : uint32); procedure memset(location : uint32; value : uint8; size : uint32);
procedure memcpy(source : uint32; dest : uint32; size : uint32); procedure memcpy(source : uint32; dest : uint32; size : uint32);
procedure __SSE_128_memcpy(source : uint32; dest : uint32);
procedure printmemory(source : uint32; length : uint32; col : uint32; delim : PChar; offset_row : boolean); procedure printmemory(source : uint32; length : uint32; col : uint32; delim : PChar; offset_row : boolean);
procedure printmemoryWND(source : uint32; length : uint32; col : uint32; delim : PChar; offset_row : boolean; WND : HWND); procedure printmemoryWND(source : uint32; length : uint32; col : uint32; delim : PChar; offset_row : boolean; WND : HWND);
@ -80,6 +81,8 @@ function RorDWord(AValue : uint32; Dist : uint8) : uint32;
function MsSinceSystemBoot : uint64; function MsSinceSystemBoot : uint64;
function abs(x : sint32) : uint32;
var var
endptr : uint32; external name '__end'; endptr : uint32; external name '__end';
stack : uint32; external name 'KERNEL_STACK'; stack : uint32; external name 'KERNEL_STACK';
@ -89,6 +92,15 @@ implementation
uses uses
console, RTC, cpu, serial, strings, isr_types; console, RTC, cpu, serial, strings, isr_types;
function abs(x : sint32) : uint32;
var
y : uint32;
begin
y:= x SHR 31;
abs:= (x XOR y) - y;
end;
function MsSinceSystemBoot : uint64; function MsSinceSystemBoot : uint64;
begin begin
MsSinceSystemBoot:= div6432(getTSC, (CPUID.ClockSpeed.Hz div 1000)); MsSinceSystemBoot:= div6432(getTSC, (CPUID.ClockSpeed.Hz div 1000));
@ -116,6 +128,14 @@ begin
div6432:= (r0 SHL 32) OR r4; div6432:= (r0 SHL 32) OR r4;
end; end;
procedure __SSE_128_memcpy(source : uint32; dest : uint32); assembler;
asm
MOV EAX, Source
MOVAPS XMM1, [EAX]
MOV EAX, Dest
MOVAPS [EAX], XMM1
end;
function switchendian16(b : uint16) : uint16; function switchendian16(b : uint16) : uint16;
begin begin
switchendian16:= ((b AND $FF00) SHR 8) OR ((b AND $00FF) SHL 8); switchendian16:= ((b AND $FF00) SHR 8) OR ((b AND $00FF) SHL 8);

View File

@ -54,7 +54,8 @@ uses
base64, base64,
rand, rand,
terminal, terminal,
hashmap, vfs; hashmap, vfs,
video, vesa, doublebuffer, color;
procedure kmain(mbinfo: Pmultiboot_info_t; mbmagic: uint32); stdcall; procedure kmain(mbinfo: Pmultiboot_info_t; mbmagic: uint32); stdcall;
@ -123,8 +124,16 @@ var
ulf : pointer; ulf : pointer;
HM : PHashMap; HM : PHashMap;
colour : TRGB32;
array1 : Array[0..255] of char;
array2 : Array[0..255] of char;
begin begin
{ Init the base system unit }
System.init();
{ Serial Init } { Serial Init }
serial.init(); serial.init();
@ -132,6 +141,8 @@ begin
multibootinfo:= mbinfo; multibootinfo:= mbinfo;
multibootmagic:= mbmagic; multibootmagic:= mbmagic;
//video.init();
{ Ensure tracer is frozen } { Ensure tracer is frozen }
tracer.freeze(); tracer.freeze();
@ -198,6 +209,53 @@ begin
{ Call Tracer } { Call Tracer }
tracer.init(); tracer.init();
video.init();
vesa.init(@video.register);
doublebuffer.init(@video.register);
video.enable('VESA');
video.enable('BASIC_DOUBLE_BUFFER');
colour:= color.white;
// serial.sendHex(uint32(@array1[8]));
// serial.sendHex(uint32(@array2[8]));
// for i:=8 to 23 do begin
// array2[i]:= '?';
// end;
// array2[24]:= #0;
// array1[8]:= 'H';
// array1[9]:= 'e';
// array1[10]:= 'l';
// array1[11]:= 'l';
// array1[12]:= 'o';
// array1[13]:= 'w';
// array1[14]:= 'o';
// array1[15]:= 'r';
// array1[16]:= 'l';
// array1[17]:= 'd';
// array1[18]:= '1';
// array1[19]:= '2';
// array1[20]:= '3';
// array1[21]:= '4';
// array1[22]:= '5';
// array1[23]:= '!';
// __SSE_128_memcpy(uint32(@array1[8]), uint32(@array2[8]));
// serial.sendString(pchar(@array2[8]));
for i:=0 to video.frontBufferWidth-1 do begin
for z:=0 to video.frontBufferHeight-1 do begin
video.DrawPixel(i, z, colour);
end;
end;
video.DrawLine(50,50,100,100,1,color.black);
video.DrawRect(50,150,100,200,1,color.black);
video.FillRect(50,250,100,300,1,color.black,color.red);
video.DrawLine(50,350,100,350,1,color.black);
video.Flush();
while true do begin end;
{ VFS Init } { VFS Init }
vfs.init(); vfs.init();
@ -259,7 +317,7 @@ begin
rand.srand((getDateTime.Seconds SHL 24) OR (getDateTime.Minutes SHL 16) OR (getDateTime.Hours SHL 8) OR (getDateTime.Day)); rand.srand((getDateTime.Seconds SHL 24) OR (getDateTime.Minutes SHL 16) OR (getDateTime.Hours SHL 8) OR (getDateTime.Day));
tracer.push_trace('kmain.TICK'); tracer.push_trace('kmain.TICK');
while true do begin while true do begin
tracer.push_trace('kmain.RedrawWindows'); tracer.push_trace('kmain.RedrawWindows');
console.redrawWindows; console.redrawWindows;

View File

@ -77,9 +77,9 @@ dd 0
dd 0 dd 0
dd 0 dd 0
dd 0 dd 0
dd 1280 dd 1600
dd 1024 dd 1200
dd 16 dd 32
; ;
; Entrypoint ; Entrypoint

58
virtualbox-wrapper.ps1 Normal file
View File

@ -0,0 +1,58 @@
<#
You need a local git-ignored localenv.json file with the following content:
{
"virtualbox": {
"MachineName": "your-machine-name or guid"
}
}
#>
param (
[Parameter(Mandatory=$true)]
[ValidateSet('up', 'down')]
[String]$Command
)
$Config = Get-Content .\localenv.json | ConvertFrom-Json
$MachineName = $Config.virtualbox.MachineName
$LogLocation = $Config.virtualbox.LogLocation
$LogOutputEnabled = $LogLocation -ne $null
if ($Command -eq 'up') {
if($LogOutputEnabled) {
Clear-Content $LogLocation
}
$MonitorJob = Start-Job -ArgumentList $MachineName -ScriptBlock {
param($MachineName)
Write-Output "Starting $MachineName"
VBoxManage.exe startvm $MachineName
$running=$true
while($running) {
$status=(VBoxManage.exe list runningvms)
if($status) {
$running=$status.contains($MachineName)
} else {
$running=$false
}
}
}
if($LogOutputEnabled) {
$LogJob = Start-Job -ArgumentList $LogLocation -ScriptBlock {
param($LogLocation)
Get-Content -Path $LogLocation -Wait
}
}
while($MonitorJob.State -eq 'Running') {
if($LogOutputEnabled) {
Receive-Job $LogJob
}
Receive-Job $MonitorJob
}
} elseif ($Command -eq 'down') {
Write-Output "Stopping $MachineName"
VBoxManage.exe controlvm $MachineName poweroff
}