This commit is contained in:
Tiberiu Chibici 2021-09-14 18:34:14 +03:00
parent 7cb940e485
commit 4e5c38d0ff
152 changed files with 5042 additions and 2585 deletions

486
.gitignore vendored
View File

@ -1,486 +0,0 @@
# ---> C++
# Prerequisites
*.d
# Compiled Object files
*.slo
*.lo
#*.o
*.obj
# Precompiled Headers
*.gch
*.pch
# Compiled Dynamic libraries
*.so
*.dylib
*.dll
# Fortran module files
*.mod
*.smod
# Compiled Static libraries
*.lai
*.la
*.a
*.lib
# Executables
*.exe
*.out
*.app
# ---> Eclipse
.metadata
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.settings/
.loadpath
.recommenders
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# PyDev specific (Python IDE for Eclipse)
*.pydevproject
# CDT-specific (C/C++ Development Tooling)
.cproject
# CDT- autotools
.autotools
# Java annotation processor (APT)
.factorypath
# PDT-specific (PHP Development Tools)
.buildpath
# sbteclipse plugin
.target
# Tern plugin
.tern-project
# TeXlipse plugin
.texlipse
# STS (Spring Tool Suite)
.springBeans
# Code Recommenders
.recommenders/
# Annotation Processing
.apt_generated/
.apt_generated_test/
# Scala IDE specific (Scala & Java development for Eclipse)
.cache-main
.scala_dependencies
.worksheet
# Uncomment this line if you wish to ignore the project description file.
# Typically, this file would be tracked if it contains build/dependency configurations:
#.project
# ---> VisualStudio
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ogs/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# ASP.NET Scaffolding
ScaffoldingReadMe.txt
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.tlog
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Coverlet is a free, cross platform Code Coverage Tool
coverage*.json
coverage*.xml
coverage*.info
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Nuget personal access tokens and Credentials
nuget.config
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
# Fody - auto-generated XML schema
FodyWeavers.xsd
# VS Code files for those working on multiple tools
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
*.code-workspace
# Local History for Visual Studio Code
.history/
# Windows Installer files from build outputs
*.cab
*.msi
*.msix
*.msm
*.msp
# JetBrains Rider
.idea/
*.sln.iml

16
SysBoot/makeall.bat Normal file
View File

@ -0,0 +1,16 @@
@echo off
set nasm_path=C:\nasm
set djgpp_path=C:\DJGPP\bin
@echo ***************** CTA Bootloader *****************
@echo.
:Stage1
cd stage1
call make.bat
cd..
:Stage2
cd stage2
call make.bat
cd..

23
SysBoot/stage1/make.bat Normal file
View File

@ -0,0 +1,23 @@
@echo off
set nasm_path=C:\nasm
set djgpp_path=C:\DJGPP\bin
goto build
:error
@echo.
@echo There have been build errors. Building halted.
@pause
exit
:build
@echo Compiling stage 1...
del bootload.bin
%nasm_path%\nasm.exe -f bin bootload.asm -o bootload.bin
:check
if not exist bootload.bin goto error
:copy
@echo Writing stage 1 to floppy boot sector...
debug bootload.bin <..\..\scripts\stage1d >nul

24
SysBoot/stage2/MAKE.BAT Normal file
View File

@ -0,0 +1,24 @@
@echo off
set nasm_path=C:\nasm
set djgpp_path=C:\DJGPP\bin
goto build
:error
@echo.
@echo There have been build errors. Building halted.
@pause
exit
:build
@echo Compiling stage 2...
del stage2.cta
%nasm_path%\nasm.exe -f bin stage2.asm -o stage2.cta
:test
if not exist stage2.cta goto error
:copy
@echo Copying stage 2 to floppy...
copy stage2.cta A:\stage2.cta >nul

BIN
SysBoot/stage2/STAGE2.CTA Normal file

Binary file not shown.

55
SysBoot/stage2/a20.inc Normal file
View File

@ -0,0 +1,55 @@
;********************************************
; Enable A20 address line
;
; OS Development Series
;********************************************
bits 16 ; real mode 16 bit code
_EnableA20:
cli
call a20wait
mov al,0xAD
out 0x64,al
call a20wait
mov al,0xD0
out 0x64,al
call a20wait2
in al,0x60
push eax
call a20wait
mov al,0xD1
out 0x64,al
call a20wait
pop eax
or al,2
out 0x60,al
call a20wait
mov al,0xAE
out 0x64,al
call a20wait
sti
ret
a20wait:
in al,0x64
test al,2
jnz a20wait
ret
a20wait2:
in al,0x64
test al,1
jz a20wait2
ret

View File

@ -0,0 +1,40 @@
;*******************************************************
;
; bootinfo.inc
; multiboot information structure
;
; OS Development Series
;*******************************************************
%ifndef __BOOTINFO_INC_67343546FDCC56AAB872_INCLUDED__
%define __BOOTINFO_INC_67343546FDCC56AAB872_INCLUDED__
struc multiboot_info
.flags resd 1
.memoryLo resd 1
.memoryHi resd 1
.bootDevice resd 1
.cmdLine resd 1
.mods_count resd 1
.mods_addr resd 1
.syms0 resd 1
.syms1 resd 1
.syms2 resd 1
.mmap_length resd 1
.mmap_addr resd 1
.drives_length resd 1
.drives_addr resd 1
.config_table resd 1
.bootloader_name resd 1
.apm_table resd 1
.vbe_control_info resd 1
.vbe_mode_info resd 1
.vbe_mode resw 1
.vbe_interface_seg resw 1
.vbe_interface_off resw 1
.vbe_interface_len resw 1
endstruc
%endif

View File

@ -141,41 +141,40 @@ FindFile:
; parm/ ES:SI => File to load
; parm/ EBX:BP => Buffer to load file to
; ret/ AX => -1 on error, 0 on success
; ret/ CX => number of sectors read
;*******************************************
LoadFile:
xor ecx, ecx ; size of file in sectors
xor ecx, ecx ; size of file in sectors
push ecx
.FIND_FILE:
push bx ; BX=>BP points to buffer to write to; store it for later
push bx ; BX=>BP points to buffer to write to; store it for later
push bp
call FindFile ; find our file. ES:SI contains our filename
cmp ax, -1
jne .LOAD_IMAGE_PRE
pop bp
pop bx
pop ecx
mov ax, -1
call FindFile ; find our file. ES:SI contains our filename
cmp ax, -1
jne .LOAD_IMAGE_PRE
pop bp
pop bx
pop ecx
mov ax, -1
ret
.LOAD_IMAGE_PRE:
sub edi, ROOT_OFFSET
sub eax, ROOT_OFFSET
sub edi, ROOT_OFFSET
sub eax, ROOT_OFFSET
; get starting cluster
push word ROOT_SEG ;root segment loc
pop es
mov dx, WORD [es:di + 0x001A]; DI points to file entry in root directory table. Refrence the table...
mov WORD [cluster], dx ; file's first cluster
pop bx ; get location to write to so we dont screw up the stack
pop es
push bx ; store location for later again
push word ROOT_SEG ;root segment loc
pop es
mov dx, WORD [es:di + 0x001A] ; DI points to file entry in root directory table. Refrence the table...
mov WORD [cluster], dx ; file's first cluster
pop bx ; get location to write to so we dont screw up the stack
pop es
push bx ; store location for later again
push es
call LoadFAT
@ -183,56 +182,60 @@ LoadFile:
; load the cluster
mov ax, WORD [cluster] ; cluster to read
pop es ; bx:bp=es:bx
pop bx
mov ax, WORD [cluster] ; cluster to read
pop es ; bx:bp=es:bx
pop bx
call ClusterLBA
xor cx, cx
xor cx, cx
mov cl, BYTE [bpbSectorsPerCluster]
call ReadSectors
pop ecx
inc ecx ; add one more sector to counter
pop ecx
inc ecx
push ecx
push bx
push es
mov ax, FAT_SEG ;start reading from fat
mov es, ax
xor bx, bx
mov ax, FAT_SEG ;start reading from fat
mov es, ax
xor bx, bx
; get next cluster
mov ax, WORD [cluster] ; identify current cluster
mov cx, ax ; copy current cluster
mov dx, ax
shr dx, 0x0001 ; divide by two
add cx, dx ; sum for (3/2)
mov ax, WORD [cluster] ; identify current cluster
mov cx, ax ; copy current cluster
mov dx, ax ; copy current cluster
shr dx, 0x0001 ; divide by two
add cx, dx ; sum for (3/2)
mov bx, 0 ;location of fat in memory
add bx, cx
mov dx, WORD [es:bx]
test ax, 0x0001 ; test for odd or even cluster
jnz .ODD_CLUSTER
mov bx, 0 ;location of fat in memory
add bx, cx
mov dx, WORD [es:bx]
test ax, 0x0001 ; test for odd or even cluster
jnz .ODD_CLUSTER
.EVEN_CLUSTER:
and dx, 0000111111111111b ; take low 12 bits
jmp .DONE
and dx, 0000111111111111b ; take low 12 bits
jmp .DONE
.ODD_CLUSTER:
shr dx, 0x0004 ; take high 12 bits
shr dx, 0x0004 ; take high 12 bits
.DONE:
mov WORD [cluster], dx
cmp dx, 0x0ff0 ; test for end of file marker
jb .LOAD_IMAGE
mov WORD [cluster], dx
cmp dx, 0x0ff0 ; test for end of file marker
jb .LOAD_IMAGE
.SUCCESS:
pop es
pop bx
pop ecx
xor ax, ax
pop es
pop bx
pop ecx
xor ax, ax
ret
%endif ;__FAT12_INC_67343546FDCC56AAB872_INCLUDED__

View File

@ -114,4 +114,8 @@ ReadSectors:
loop .MAIN ; read next sector
ret
%endif ;__FLOPPY16_INC_67343546FDCC56AAB872_INCLUDED__

175
SysBoot/stage2/memory.inc Normal file
View File

@ -0,0 +1,175 @@
;*************************************************
; Memory.inc
; -Basic memory routines
;
; OS Development Series
;*************************************************
%ifndef __MEMORY_INC_67343546FDCC56AAB872_INCLUDED__
%define __MEMORY_INC_67343546FDCC56AAB872_INCLUDED__
bits 16
;--------------------------------------------
; Memory map entry structure
;--------------------------------------------
struc MemoryMapEntry
.baseAddress resq 1
.length resq 1
.type resd 1
.acpi_null resd 1
endstruc
;---------------------------------------------
; Get memory map from bios
; /in es:di->destination buffer for entries
; /ret bp=entry count
;---------------------------------------------
BiosGetMemoryMap:
pushad
xor ebx, ebx
xor bp, bp ; number of entries stored here
mov edx, 'PAMS' ; 'SMAP'
mov eax, 0xe820
mov ecx, 24 ; memory map entry struct is 24 bytes
int 0x15 ; get first entry
jc .error
cmp eax, 'PAMS' ; bios returns SMAP in eax
jne .error
test ebx, ebx ; if ebx=0 then list is one entry long; bail out
je .error
jmp .start
.next_entry:
mov edx, 'PAMS' ; some bios's trash this register
mov ecx, 24 ; entry is 24 bytes
mov eax, 0xe820
int 0x15 ; get next entry
.start:
jcxz .skip_entry ; if actual returned bytes is 0, skip entry
.notext:
mov ecx, [es:di + MemoryMapEntry.length] ; get length (low dword)
test ecx, ecx ; if length is 0 skip it
jne short .good_entry
mov ecx, [es:di + MemoryMapEntry.length + 4]; get length (upper dword)
jecxz .skip_entry ; if length is 0 skip it
.good_entry:
inc bp ; increment entry count
add di, 24 ; point di to next entry in buffer
.skip_entry:
cmp ebx, 0 ; if ebx return is 0, list is done
jne .next_entry ; get next entry
jmp .done
.error:
stc
.done:
popad
ret
;---------------------------------------------
; Get memory size for >64M configuations (32 bit)
; ret\ ax=KB between 1MB and 16MB
; ret\ bx=number of 64K blocks above 16MB
; ret\ bx=0 and ax= -1 on error
;---------------------------------------------
BiosGetMemorySize64MB_32Bit:
push ecx
push edx
xor ecx, ecx
xor edx, edx
mov ax, 0xe881
int 0x15
jc .error
cmp ah, 0x86 ;unsupported function
je .error
cmp ah, 0x80 ;invalid command
je .error
jcxz .use_ax ;bios may have stored it in ax,bx or cx,dx. test if cx is 0
mov ax, cx ;its not, so it should contain mem size; store it
mov bx, dx
.use_ax:
pop edx ;mem size is in ax and bx already, return it
pop ecx
ret
.error:
mov ax, -1
mov bx, 0
pop edx
pop ecx
ret
;---------------------------------------------
; Get memory size for >64M configuations
; ret\ ax=KB between 1MB and 16MB
; ret\ bx=number of 64K blocks above 16MB
; ret\ bx=0 and ax= -1 on error
;---------------------------------------------
BiosGetMemorySize64MB:
push ecx
push edx
xor ecx, ecx
xor edx, edx
mov ax, 0xe801
int 0x15
jc .error
cmp ah, 0x86 ;unsupported function
je .error
cmp ah, 0x80 ;invalid command
je .error
jcxz .use_ax ;bios may have stored it in ax,bx or cx,dx. test if cx is 0
mov ax, cx ;its not, so it should contain mem size; store it
mov bx, dx
.use_ax:
pop edx ;mem size is in ax and bx already, return it
pop ecx
ret
.error:
mov si, msgNotSupported
call Puts16
mov ax, -1
mov bx, 0
pop edx
pop ecx
ret
;---------------------------------------------
; Get amount of contiguous KB from addr 0
; ret\ ax=KB size from address 0
;---------------------------------------------
BiosGetMemorySize:
int 0x12
ret
;---------------------------------------------
; Get contiguous exetended memory size
; ret\ ax=KB size above 1MB; ax= -1 on error
;---------------------------------------------
BiosGetExtendedMemorySize:
mov ax, 0x88
int 0x15
jc .error
test ax, ax ; if size=0
je .error
cmp ah, 0x86 ;unsupported function
je .error
cmp ah, 0x80 ;invalid command
je .error
ret
.error:
mov ax, -1
ret
msgNotSupported db 0x0A, 0x0D, "BiosGetMemorySize64MB: function not supported.",0x0A, 0x0D, 0x00
%endif

172
SysBoot/stage2/stage2.asm Normal file
View File

@ -0,0 +1,172 @@
;*******************************************************
;
; Stage2.asm
; Stage2 Bootloader
;
; OS Development Series
;*******************************************************
bits 16
org 0x500
jmp main ; go to start
;*******************************************************
; Preprocessor directives
;*******************************************************
%include "stdio.inc" ; basic i/o routines
%include "gdt.inc" ; Gdt routines
%include "a20.inc" ; A20 enabling
%include "fat12.inc" ; FAT12 driver. Kinda :)
%include "common.inc"
;%include "bootinfo.inc"
%include "memory.inc"
;*******************************************************
; Data Section
;*******************************************************
msgFailure db 0x0D, 0x0A, "FATAL ERROR: Kernel file KERNEL.CTA missing or corrupt. Press Any Key to Reboot.", 0x0D, 0x0A, 0x0A, 0x00
boot_info:
multiboot_info_flags dd 0
multiboot_info_memoryLo dd 0
multiboot_info_memoryHi dd 0
multiboot_info_bootDevice dd 0
multiboot_info_cmdLine dd 0
multiboot_info_mods_count dd 0
multiboot_info_mods_addr dd 0
multiboot_info_syms0 dd 0
multiboot_info_syms1 dd 0
multiboot_info_syms2 dd 0
multiboot_info_mmap_length dd 0
multiboot_info_mmap_addr dd 0
multiboot_info_drives_length dd 0
multiboot_info_drives_addr dd 0
multiboot_info_config_table dd 0
multiboot_info_bootloader_name dd 0
multiboot_info_apm_table dd 0
multiboot_info_vbe_control_info dd 0
multiboot_info_vbe_mode_info dw 0
multiboot_info_vbe_interface_seg dw 0
multiboot_info_vbe_interface_off dw 0
multiboot_info_vbe_interface_len dw 0
main:
;-------------------------------;
; Setup segments and stack ;
;-------------------------------;
cli ; clear interrupts
xor ax, ax ; null segments
mov ds, ax
mov es, ax
mov ax, 0x0000 ; stack begins at 0x9000-0xffff
mov ss, ax
mov sp, 0xFFFF
sti ; enable interrupts
mov [multiboot_info_bootDevice], dl
call _EnableA20
call InstallGDT
sti
xor eax, eax
xor ebx, ebx
call BiosGetMemorySize64MB
mov word [multiboot_info_memoryHi], bx
mov word [multiboot_info_memoryLo], ax
mov eax, 0x0
mov ds, ax
mov di, 0x1000
call BiosGetMemoryMap
mov dword [multiboot_info_mmap_addr], 0x1000
xor eax, eax
mov ax, bp
mov dword [multiboot_info_mmap_length], eax
call LoadRoot
mov ebx, 0
mov ebp, IMAGE_RMODE_BASE
mov esi, ImageName
call LoadFile ; load our file
mov dword [ImageSize], ecx
cmp ax, 0
je EnterStage3
mov si, msgFailure
call Puts16
mov ah, 0
int 0x16 ; await keypress
int 0x19 ; warm boot computer
;-------------------------------;
; Go into pmode ;
;-------------------------------;
EnterStage3:
cli ; clear interrupts
mov eax, cr0 ; set bit 0 in cr0--enter pmode
or eax, 1
mov cr0, eax
jmp CODE_DESC:Stage3 ; far jump to fix CS. Remember that the code selector is 0x8!
; Note: Do NOT re-enable interrupts! Doing so will triple fault!
; We will fix this in Stage 3.
;******************************************************
; ENTRY POINT FOR STAGE 3
;******************************************************
bits 32
BadImage db "FATAL ERROR: Kernel file KERNEL.CTA missing or corrupt. Press Any Key to Reboot.", 0
Stage3:
;-------------------------------;
; Set registers ;
;-------------------------------;
mov ax, DATA_DESC ; set data segments to data selector (0x10)
mov ds, ax
mov ss, ax
mov es, ax
mov esp, 90000h ; stack begins from 90000h
CopyImage:
mov eax, dword [ImageSize]
movzx ebx, word [bpbBytesPerSector]
mul ebx
mov ebx, 4
div ebx
cld
mov esi, IMAGE_RMODE_BASE
mov edi, IMAGE_PMODE_BASE
mov ecx, eax
rep movsd ; copy image to its protected mode address
mov eax, 0x2badb002 ; multiboot specs say eax should be this
mov ebx, 0
;edx=8
push dword boot_info
push dword [ImageSize]
jmp CODE_DESC:IMAGE_PMODE_BASE ; Execute Kernel
add esp, 4
cli
hlt

View File

@ -21,6 +21,7 @@
; -Prints a null terminated string
; DS=>SI: 0 terminated string
;************************************************;
tmpStr db " ", 0x0D, 0x0A, 0x00
bits 16
@ -38,6 +39,44 @@ Puts16Done:
ret ; we are done, so return
PutINT:
pusha ; save registers
mov cx, 0
.init:
mov bx, cx
add bx, tmpStr
mov [bx], byte ' '
inc cx
cmp cx, 31
jne .init
mov cx, 31 ; initialize counter
.loop:
mov dx, 0
mov bx, 0x0A
div bx ; ax = ax/10, dx = ax%10
mov bx, cx
add bx, tmpStr
add dl, '0'
mov [bx], dl
sub cx, 1
cmp ax, 0 ; when done, ax = 0;
je .done
jmp .loop
.done:
mov si, tmpStr
call Puts16
popa
ret
;==========================================================
;
; 32 Bit Protected Mode Routines
@ -48,7 +87,7 @@ bits 32
%define VIDMEM 0xB8000 ; video memory
%define COLS 80 ; width and height of screen
%define LINES 25
%define CHAR_ATTRIB 63 ; character attribute (White text on light blue background)
%define CHAR_ATTRIB 14 ; character attribute (White text on black background)
_CurX db 0 ; current x/y location
_CurY db 0
@ -61,85 +100,53 @@ _CurY db 0
Putch32:
pusha ; save registers
mov edi, VIDMEM ; get pointer to video memory
;-------------------------------;
; Get current position ;
;-------------------------------;
pusha
mov edi, VIDMEM
xor eax, eax ; clear eax
;--------------------------------
; Remember: currentPos = x + y * COLS! x and y are in _CurX and _CurY.
; Because there are two bytes per character, COLS=number of characters in a line.
; We have to multiply this by 2 to get number of bytes per line. This is the screen width,
; so multiply screen with * _CurY to get current line
;--------------------------------
; y * screen width
mov ecx, COLS*2 ; Mode 7 has 2 bytes per char, so its COLS*2 bytes per line
mov al, byte [_CurY] ; get y pos
mul ecx ; multiply y*COLS
push eax ; save eax--the multiplication
mov ecx, COLS*2 ; Mode 7 has 2 bytes per char, so its COLS*2 bytes per line
mov al, byte [_CurY] ; get y pos
mul ecx ; multiply y*COLS
push eax ; save eax--the multiplication
;--------------------------------
; Now y * screen width is in eax. Now, just add _CurX. But, again remember that _CurX is relative
; to the current character count, not byte count. Because there are two bytes per character, we
; have to multiply _CurX by 2 first, then add it to our screen width * y.
;--------------------------------
; now add _CurX * 2
mov al, byte [_CurX] ; multiply _CurX by 2 because it is 2 bytes per char
mov cl, 2
mul cl
pop ecx ; pop y*COLS result
add eax, ecx
mov al, byte [_CurX] ; multiply _CurX by 2 because it is 2 bytes per char
mov cl, 2
mul cl
pop ecx ; pop y*COLS result
add eax, ecx
;-------------------------------
; Now eax contains the offset address to draw the character at, so just add it to the base address
; of video memory (Stored in edi)
;-------------------------------
; add the position to draw to the base of vid memory
xor ecx, ecx
add edi, eax ; add it to the base address
xor ecx, ecx
add edi, eax ; add it to the base address
;-------------------------------;
; Watch for new line ;
;-------------------------------;
; watch for new line
cmp bl, 0x0A ; is it a newline character?
je .Row ; yep--go to next row
;-------------------------------;
; Print a character ;
;-------------------------------;
; print the character
mov dl, bl ; Get character
mov dh, CHAR_ATTRIB ; the character attribute
mov word [edi], dx ; write to video display
;-------------------------------;
; Update next position ;
;-------------------------------;
; go to next location
inc byte [_CurX] ; go to next character
; cmp byte [_CurX], COLS ; are we at the end of the line?
; je .Row ; yep-go to next row
jmp .done ; nope, bail out
;-------------------------------;
; Go to next row ;
;-------------------------------;
.Row:
mov byte [_CurX], 0 ; go back to col 0
inc byte [_CurY] ; go to next row
;-------------------------------;
; Restore registers & return ;
;-------------------------------;
.done:
popa ; restore registers and return
popa
ret
;**************************************************;
@ -150,11 +157,7 @@ Putch32:
Puts32:
;-------------------------------;
; Store registers ;
;-------------------------------;
pusha ; save registers
pusha
push ebx ; copy the string address
pop edi
@ -187,9 +190,6 @@ Puts32:
; Update hardware cursor ;
;-------------------------------;
; Its more efficiant to update the cursor after displaying
; the complete string because direct VGA is slow
mov bh, byte [_CurY] ; get current position
mov bl, byte [_CurX]
call MovCur ; update cursor
@ -203,20 +203,20 @@ Puts32:
; parm/ bh = Y pos
; parm/ bl = x pos
;**************************************************;
bits 32
MovCur:
pusha ; save registers (aren't you getting tired of this comment?)
pusha
;-------------------------------;
; Get current position ;
;-------------------------------;
; Here, _CurX and _CurY are relitave to the current position on screen, not in memory.
; That is, we don't need to worry about the byte alignment we do when displaying characters,
; so just follow the forumla: location = _CurX + _CurY * COLS
; location = _CurX + _CurY * COLS
xor eax, eax
mov ecx, COLS
@ -270,7 +270,6 @@ ClrScr32:
mov ah, CHAR_ATTRIB
mov al, ' '
rep stosw
mov byte [_CurX], 0
mov byte [_CurY], 0
popa
@ -287,12 +286,10 @@ bits 32
GotoXY:
pusha
mov [_CurX], al ; just set the current position
mov [_CurX], al
mov [_CurY], ah
popa
ret
%endif ;__STDIO_INC_67343546FDCC56AAB872_INCLUDED__

View File

@ -6,18 +6,15 @@ rem NASM and DJGPP executable paths:
set nasm_path=C:\nasm
set djgpp_path=C:\DJGPP\bin
@echo on
rem Compile loader
%nasm_path%\nasm.exe -f aout -o %loader_name%.o %loader_name%.asm
@echo on
%nasm_path%\nasm.exe -f aout -o ./objects/%loader_name%.o %loader_name%.asm
@echo off
@echo.
rem Compile main Kernel
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin -I./include -c -o main.o main.c
@echo on
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I./include -c -o ./objects/main.o main.c
@echo off
rem OTHER GCC/NASM SOURCES GO HERE
@echo on
%djgpp_path%\ld -T link.ld -o kernel.bin %loader_name%.o main.o
@echo .
@echo Done!
@pause
copy KERNEL.BIN C:\SHARE
copy KERNEL.BIN A:\KERNEL.CTA

Binary file not shown.

292
SysCore/debug/OSDev.log Normal file
View File

@ -0,0 +1,292 @@
00000000000i[ ] Bochs x86 Emulator 2.4.5
00000000000i[ ] Build from CVS snapshot, on April 25, 2010
00000000000i[ ] System configuration
00000000000i[ ] processors: 1 (cores=1, HT threads=1)
00000000000i[ ] A20 line support: yes
00000000000i[ ] CPU configuration
00000000000i[ ] level: 6
00000000000i[ ] SMP support: no
00000000000i[ ] APIC support: yes
00000000000i[ ] FPU support: yes
00000000000i[ ] MMX support: yes
00000000000i[ ] 3dnow! support: no
00000000000i[ ] SEP support: yes
00000000000i[ ] SSE support: sse2
00000000000i[ ] XSAVE support: no
00000000000i[ ] AES support: no
00000000000i[ ] MOVBE support: no
00000000000i[ ] x86-64 support: yes
00000000000i[ ] 1G paging support: no
00000000000i[ ] MWAIT support: no
00000000000i[ ] VMX support: no
00000000000i[ ] Optimization configuration
00000000000i[ ] RepeatSpeedups support: yes
00000000000i[ ] Trace cache support: yes
00000000000i[ ] Fast function calls: yes
00000000000i[ ] Devices configuration
00000000000i[ ] ACPI support: yes
00000000000i[ ] NE2000 support: yes
00000000000i[ ] PCI support: yes, enabled=yes
00000000000i[ ] SB16 support: yes
00000000000i[ ] USB support: yes
00000000000i[ ] VGA extension support: vbe cirrus
00000000000i[MEM0 ] allocated memory at 027B0020. after alignment, vector=027B1000
00000000000i[MEM0 ] 32.00MB
00000000000i[MEM0 ] mem block size = 0x00100000, blocks=32
00000000000i[MEM0 ] rom at 0xe0000/131072 ('BIOS-bochs-latest')
00000000000i[MEM0 ] rom at 0xc0000/40448 ('VGABIOS-lgpl-latest')
00000000000i[CMOS ] Using local time for initial clock
00000000000i[CMOS ] Setting initial clock to: Sat Jul 03 09:26:48 2010 (time0=1278138408)
00000000000i[DMA ] channel 4 used by cascade
00000000000i[DMA ] channel 2 used by Floppy Drive
00000000000i[FDD ] fd0: 'ctaos.img' ro=0, h=2,t=80,spt=18
00000000000i[PCI ] 440FX Host bridge present at device 0, function 0
00000000000i[PCI ] PIIX3 PCI-to-ISA bridge present at device 1, function 0
00000000000i[MEM0 ] Register memory access handlers: 0x000a0000 - 0x000bffff
00000000000i[WGUI ] Desktop Window dimensions: 1366 x 768
00000000000i[WGUI ] Number of Mouse Buttons = 5
00000000000i[WGUI ] IME disabled
00000000000i[MEM0 ] Register memory access handlers: 0xe0000000 - 0xe0ffffff
00000000000i[CLVGA] VBE Bochs Display Extension Enabled
00000000000i[CLVGA] interval=50000
00000000000i[ ] init_dev of 'unmapped' plugin device by virtual method
00000000000i[ ] init_dev of 'biosdev' plugin device by virtual method
00000000000i[ ] init_dev of 'speaker' plugin device by virtual method
00000000000i[ ] init_dev of 'extfpuirq' plugin device by virtual method
00000000000i[ ] init_dev of 'gameport' plugin device by virtual method
00000000000i[ ] init_dev of 'pci_ide' plugin device by virtual method
00000000000i[PCI ] PIIX3 PCI IDE controller present at device 1, function 1
00000000000i[ ] init_dev of 'acpi' plugin device by virtual method
00000000000i[PCI ] ACPI Controller present at device 1, function 3
00000000000i[ ] init_dev of 'ioapic' plugin device by virtual method
00000000000i[IOAP ] initializing I/O APIC
00000000000i[MEM0 ] Register memory access handlers: 0xfec00000 - 0xfec00fff
00000000000i[ ] init_dev of 'keyboard' plugin device by virtual method
00000000000i[KBD ] will paste characters every 1000 keyboard ticks
00000000000i[ ] init_dev of 'harddrv' plugin device by virtual method
00000000000i[HD ] Using boot sequence floppy, none, none
00000000000i[HD ] Floppy boot signature check is enabled
00000000000i[ ] init_dev of 'serial' plugin device by virtual method
00000000000i[SER ] com1 at 0x03f8 irq 4
00000000000i[ ] init_dev of 'parallel' plugin device by virtual method
00000000000i[PAR ] parallel port 1 at 0x0378 irq 7
00000000000i[ ] register state of 'unmapped' plugin device by virtual method
00000000000i[ ] register state of 'biosdev' plugin device by virtual method
00000000000i[ ] register state of 'speaker' plugin device by virtual method
00000000000i[ ] register state of 'extfpuirq' plugin device by virtual method
00000000000i[ ] register state of 'gameport' plugin device by virtual method
00000000000i[ ] register state of 'pci_ide' plugin device by virtual method
00000000000i[ ] register state of 'acpi' plugin device by virtual method
00000000000i[ ] register state of 'ioapic' plugin device by virtual method
00000000000i[ ] register state of 'keyboard' plugin device by virtual method
00000000000i[ ] register state of 'harddrv' plugin device by virtual method
00000000000i[ ] register state of 'serial' plugin device by virtual method
00000000000i[ ] register state of 'parallel' plugin device by virtual method
00000000000i[SYS ] bx_pc_system_c::Reset(HARDWARE) called
00000000000i[CPU0 ] cpu hardware reset
00000000000i[APIC0] allocate APIC id=0 (MMIO enabled) to 0xfee00000
00000000000i[CPU0 ] CPUID[0x00000000]: 00000003 756e6547 6c65746e 49656e69
00000000000i[CPU0 ] CPUID[0x00000001]: 00000f20 00000800 00002000 078bfbff
00000000000i[CPU0 ] CPUID[0x00000002]: 00410601 00000000 00000000 00000000
00000000000i[CPU0 ] CPUID[0x00000003]: 00000000 00000000 00000000 00000000
00000000000i[CPU0 ] CPUID[0x00000004]: 00000000 00000000 00000000 00000000
00000000000i[CPU0 ] CPUID[0x80000000]: 80000008 00000000 00000000 00000000
00000000000i[CPU0 ] CPUID[0x80000001]: 00000000 00000000 00000101 2a100800
00000000000i[CPU0 ] CPUID[0x80000002]: 20202020 20202020 20202020 6e492020
00000000000i[CPU0 ] CPUID[0x80000003]: 286c6574 50202952 69746e65 52286d75
00000000000i[CPU0 ] CPUID[0x80000004]: 20342029 20555043 20202020 00202020
00000000000i[CPU0 ] CPUID[0x80000006]: 00000000 42004200 02008140 00000000
00000000000i[CPU0 ] CPUID[0x80000007]: 00000000 00000000 00000000 00000000
00000000000i[CPU0 ] CPUID[0x80000008]: 00003020 00000000 00000000 00000000
00000000000i[ ] reset of 'unmapped' plugin device by virtual method
00000000000i[ ] reset of 'biosdev' plugin device by virtual method
00000000000i[ ] reset of 'speaker' plugin device by virtual method
00000000000i[ ] reset of 'extfpuirq' plugin device by virtual method
00000000000i[ ] reset of 'gameport' plugin device by virtual method
00000000000i[ ] reset of 'pci_ide' plugin device by virtual method
00000000000i[ ] reset of 'acpi' plugin device by virtual method
00000000000i[ ] reset of 'ioapic' plugin device by virtual method
00000000000i[ ] reset of 'keyboard' plugin device by virtual method
00000000000i[ ] reset of 'harddrv' plugin device by virtual method
00000000000i[ ] reset of 'serial' plugin device by virtual method
00000000000i[ ] reset of 'parallel' plugin device by virtual method
00000003305i[BIOS ] $Revision: 1.247 $ $Date: 2010/04/04 19:33:50 $
00000200000i[WGUI ] dimension update x=720 y=400 fontheight=16 fontwidth=9 bpp=8
00000318042i[KBD ] reset-disable command received
00000444800i[VBIOS] VGABios $Id: vgabios.c,v 1.69 2009/04/07 18:18:20 vruppert Exp $
00000444871i[CLVGA] VBE known Display Interface b0c0
00000444903i[CLVGA] VBE known Display Interface b0c5
00000447828i[VBIOS] VBE Bios $Id: vbe.c,v 1.62 2009/01/25 15:46:25 vruppert Exp $
00000760517i[BIOS ] Starting rombios32
00000761014i[BIOS ] Shutdown flag 0
00000761695i[BIOS ] ram_size=0x02000000
00000762173i[BIOS ] ram_end=32MB
00000802745i[BIOS ] Found 1 cpu(s)
00000822014i[BIOS ] bios_table_addr: 0x000fbc18 end=0x000fcc00
00000822117i[PCI ] 440FX PMC write to PAM register 59 (TLB Flush)
00001149814i[PCI ] 440FX PMC write to PAM register 59 (TLB Flush)
00001477742i[P2I ] PCI IRQ routing: PIRQA# set to 0x0b
00001477763i[P2I ] PCI IRQ routing: PIRQB# set to 0x09
00001477784i[P2I ] PCI IRQ routing: PIRQC# set to 0x0b
00001477805i[P2I ] PCI IRQ routing: PIRQD# set to 0x09
00001477815i[P2I ] write: ELCR2 = 0x0a
00001478700i[BIOS ] PIIX3/PIIX4 init: elcr=00 0a
00001486658i[BIOS ] PCI: bus=0 devfn=0x00: vendor_id=0x8086 device_id=0x1237 class=0x0600
00001489220i[BIOS ] PCI: bus=0 devfn=0x08: vendor_id=0x8086 device_id=0x7000 class=0x0601
00001491621i[BIOS ] PCI: bus=0 devfn=0x09: vendor_id=0x8086 device_id=0x7010 class=0x0101
00001491851i[PIDE ] new BM-DMA address: 0xc000
00001492555i[BIOS ] region 4: 0x0000c000
00001494865i[BIOS ] PCI: bus=0 devfn=0x0b: vendor_id=0x8086 device_id=0x7113 class=0x0680
00001495103i[ACPI ] new irq line = 11
00001495117i[ACPI ] new irq line = 9
00001495147i[ACPI ] new PM base address: 0xb000
00001495161i[ACPI ] new SM base address: 0xb100
00001495189i[PCI ] setting SMRAM control register to 0x4a
00001659283i[CPU0 ] Enter to System Management Mode
00001659293i[CPU0 ] RSM: Resuming from System Management Mode
00001823313i[PCI ] setting SMRAM control register to 0x0a
00001832484i[BIOS ] MP table addr=0x000fbcf0 MPC table addr=0x000fbc20 size=0xd0
00001834543i[BIOS ] SMBIOS table addr=0x000fbd00
00001836931i[BIOS ] ACPI tables: RSDP addr=0x000fbe20 ACPI DATA addr=0x01ff0000 size=0x988
00001840169i[BIOS ] Firmware waking vector 0x1ff00cc
00001851282i[PCI ] 440FX PMC write to PAM register 59 (TLB Flush)
00001852126i[BIOS ] bios_table_cur_addr: 0x000fbe44
00014041543i[BIOS ] Booting from 0000:7c00
00019105039i[KBD ] setting typematic info
00019105052i[KBD ] setting delay to 500 mS (unused)
00019105052i[KBD ] setting repeat rate to 10.9 cps (unused)
00019105085i[KBD ] Switched to scancode set 2
00019105160i[KBD ] keyboard: scan convert turned off
00019184168e[CPU0 ] interrupt(): gate.type(1) != {5,6,7,14,15}
00019184168e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x0d)
00019184168e[CPU0 ] interrupt(): gate.type(1) != {5,6,7,14,15}
00019184168i[CPU0 ] CPU is in protected mode (active)
00019184168i[CPU0 ] CS.d_b = 32 bit
00019184168i[CPU0 ] SS.d_b = 32 bit
00019184168i[CPU0 ] EFER = 0x00000000
00019184168i[CPU0 ] | RAX=00000000000011a5 RBX=0000000000001116
00019184168i[CPU0 ] | RCX=000000000010a977 RDX=0000000000000eea
00019184168i[CPU0 ] | RSP=000000000008ffc8 RBP=0000000000003000
00019184168i[CPU0 ] | RSI=00000000000000ff RDI=0000000000105001
00019184168i[CPU0 ] | R8=0000000000000000 R9=0000000000000000
00019184168i[CPU0 ] | R10=0000000000000000 R11=0000000000000000
00019184168i[CPU0 ] | R12=0000000000000000 R13=0000000000000000
00019184168i[CPU0 ] | R14=0000000000000000 R15=0000000000000000
00019184168i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df IF tf sf zf AF PF cf
00019184168i[CPU0 ] | SEG selector base limit G D
00019184168i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
00019184168i[CPU0 ] | CS:0008( 0001| 0| 0) 00000000 ffffffff 1 1
00019184168i[CPU0 ] | DS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
00019184168i[CPU0 ] | SS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
00019184168i[CPU0 ] | ES:0010( 0002| 0| 0) 00000000 ffffffff 1 1
00019184168i[CPU0 ] | FS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
00019184168i[CPU0 ] | GS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
00019184168i[CPU0 ] | MSR_FS_BASE:0000000000000000
00019184168i[CPU0 ] | MSR_GS_BASE:0000000000000000
00019184168i[CPU0 ] | RIP=00000000001030d7 (00000000001030d7)
00019184168i[CPU0 ] | CR0=0x60000011 CR2=0x0000000000000000
00019184168i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00019184168i[CPU0 ] 0x00000000001030d7>> jnz .-25 (0x001030c0) : 75E7
00019184168e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting
00019184168i[SYS ] bx_pc_system_c::Reset(HARDWARE) called
00019184168i[CPU0 ] cpu hardware reset
00019184168i[APIC0] allocate APIC id=0 (MMIO enabled) to 0xfee00000
00019184168i[CPU0 ] CPUID[0x00000000]: 00000003 756e6547 6c65746e 49656e69
00019184168i[CPU0 ] CPUID[0x00000001]: 00000f20 00000800 00002000 078bfbff
00019184168i[CPU0 ] CPUID[0x00000002]: 00410601 00000000 00000000 00000000
00019184168i[CPU0 ] CPUID[0x00000003]: 00000000 00000000 00000000 00000000
00019184168i[CPU0 ] CPUID[0x00000004]: 00000000 00000000 00000000 00000000
00019184168i[CPU0 ] CPUID[0x80000000]: 80000008 00000000 00000000 00000000
00019184168i[CPU0 ] CPUID[0x80000001]: 00000000 00000000 00000101 2a100800
00019184168i[CPU0 ] CPUID[0x80000002]: 20202020 20202020 20202020 6e492020
00019184168i[CPU0 ] CPUID[0x80000003]: 286c6574 50202952 69746e65 52286d75
00019184168i[CPU0 ] CPUID[0x80000004]: 20342029 20555043 20202020 00202020
00019184168i[CPU0 ] CPUID[0x80000006]: 00000000 42004200 02008140 00000000
00019184168i[CPU0 ] CPUID[0x80000007]: 00000000 00000000 00000000 00000000
00019184168i[CPU0 ] CPUID[0x80000008]: 00003020 00000000 00000000 00000000
00019184168i[ ] reset of 'unmapped' plugin device by virtual method
00019184168i[ ] reset of 'biosdev' plugin device by virtual method
00019184168i[ ] reset of 'speaker' plugin device by virtual method
00019184168i[ ] reset of 'extfpuirq' plugin device by virtual method
00019184168i[ ] reset of 'gameport' plugin device by virtual method
00019184168i[ ] reset of 'pci_ide' plugin device by virtual method
00019184168i[ ] reset of 'acpi' plugin device by virtual method
00019184168i[ ] reset of 'ioapic' plugin device by virtual method
00019184168i[ ] reset of 'keyboard' plugin device by virtual method
00019184168i[ ] reset of 'harddrv' plugin device by virtual method
00019184168i[ ] reset of 'serial' plugin device by virtual method
00019184168i[ ] reset of 'parallel' plugin device by virtual method
00019187474i[BIOS ] $Revision: 1.247 $ $Date: 2010/04/04 19:33:50 $
00019502059i[KBD ] reset-disable command received
00019628817i[VBIOS] VGABios $Id: vgabios.c,v 1.69 2009/04/07 18:18:20 vruppert Exp $
00019628888i[CLVGA] VBE known Display Interface b0c0
00019628920i[CLVGA] VBE known Display Interface b0c5
00019631845i[VBIOS] VBE Bios $Id: vbe.c,v 1.62 2009/01/25 15:46:25 vruppert Exp $
00019944534i[BIOS ] Starting rombios32
00019945031i[BIOS ] Shutdown flag 0
00019945712i[BIOS ] ram_size=0x02000000
00019946190i[BIOS ] ram_end=32MB
00019986786i[BIOS ] Found 1 cpu(s)
00020006055i[BIOS ] bios_table_addr: 0x000fbc18 end=0x000fcc00
00020006158i[PCI ] 440FX PMC write to PAM register 59 (TLB Flush)
00020333855i[PCI ] 440FX PMC write to PAM register 59 (TLB Flush)
00020661783i[P2I ] PCI IRQ routing: PIRQA# set to 0x0b
00020661804i[P2I ] PCI IRQ routing: PIRQB# set to 0x09
00020661825i[P2I ] PCI IRQ routing: PIRQC# set to 0x0b
00020661846i[P2I ] PCI IRQ routing: PIRQD# set to 0x09
00020661856i[P2I ] write: ELCR2 = 0x0a
00020662741i[BIOS ] PIIX3/PIIX4 init: elcr=00 0a
00020670699i[BIOS ] PCI: bus=0 devfn=0x00: vendor_id=0x8086 device_id=0x1237 class=0x0600
00020673261i[BIOS ] PCI: bus=0 devfn=0x08: vendor_id=0x8086 device_id=0x7000 class=0x0601
00020675662i[BIOS ] PCI: bus=0 devfn=0x09: vendor_id=0x8086 device_id=0x7010 class=0x0101
00020676596i[BIOS ] region 4: 0x0000c000
00020678906i[BIOS ] PCI: bus=0 devfn=0x0b: vendor_id=0x8086 device_id=0x7113 class=0x0680
00020679144i[ACPI ] new irq line = 11
00020679158i[ACPI ] new irq line = 9
00020679230i[PCI ] setting SMRAM control register to 0x4a
00020843324i[CPU0 ] Enter to System Management Mode
00020843334i[CPU0 ] RSM: Resuming from System Management Mode
00021007354i[PCI ] setting SMRAM control register to 0x0a
00021016525i[BIOS ] MP table addr=0x000fbcf0 MPC table addr=0x000fbc20 size=0xd0
00021018584i[BIOS ] SMBIOS table addr=0x000fbd00
00021020972i[BIOS ] ACPI tables: RSDP addr=0x000fbe20 ACPI DATA addr=0x01ff0000 size=0x988
00021024210i[BIOS ] Firmware waking vector 0x1ff00cc
00021035323i[PCI ] 440FX PMC write to PAM register 59 (TLB Flush)
00021036167i[BIOS ] bios_table_cur_addr: 0x000fbe44
00033225716i[BIOS ] Booting from 0000:7c00
00038289036i[KBD ] setting typematic info
00038289049i[KBD ] setting delay to 500 mS (unused)
00038289049i[KBD ] setting repeat rate to 10.9 cps (unused)
00038289082i[KBD ] Switched to scancode set 2
00038289157i[KBD ] keyboard: scan convert turned off
00220440000p[WGUI ] >>PANIC<< POWER button turned off.
00220440000i[CPU0 ] CPU is in protected mode (active)
00220440000i[CPU0 ] CS.d_b = 32 bit
00220440000i[CPU0 ] SS.d_b = 32 bit
00220440000i[CPU0 ] EFER = 0x00000000
00220440000i[CPU0 ] | RAX=0000000000000700 RBX=000000000008ffa0
00220440000i[CPU0 ] | RCX=00000000000b8000 RDX=00000000000bf01c
00220440000i[CPU0 ] | RSP=000000000008ff20 RBP=0000000000003000
00220440000i[CPU0 ] | RSI=0000000000008000 RDI=0000000000000028
00220440000i[CPU0 ] | R8=0000000000000000 R9=0000000000000000
00220440000i[CPU0 ] | R10=0000000000000000 R11=0000000000000000
00220440000i[CPU0 ] | R12=0000000000000000 R13=0000000000000000
00220440000i[CPU0 ] | R14=0000000000000000 R15=0000000000000000
00220440000i[CPU0 ] | IOPL=0 id vip vif ac vm rf nt of df if tf sf zf af pf cf
00220440000i[CPU0 ] | SEG selector base limit G D
00220440000i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
00220440000i[CPU0 ] | CS:0008( 0001| 0| 0) 00000000 ffffffff 1 1
00220440000i[CPU0 ] | DS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
00220440000i[CPU0 ] | SS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
00220440000i[CPU0 ] | ES:0010( 0002| 0| 0) 00000000 ffffffff 1 1
00220440000i[CPU0 ] | FS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
00220440000i[CPU0 ] | GS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
00220440000i[CPU0 ] | MSR_FS_BASE:0000000000000000
00220440000i[CPU0 ] | MSR_GS_BASE:0000000000000000
00220440000i[CPU0 ] | RIP=0000000000102a49 (0000000000102a49)
00220440000i[CPU0 ] | CR0=0x60000011 CR2=0x0000000000000000
00220440000i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00220440000i[CPU0 ] 0x0000000000102a49>> jmp .-2 (0x00102a49) : EBFE
00220440000i[CMOS ] Last time is 1278138462 (Sat Jul 03 09:27:42 2010)
00220440000i[ ] restoring default signal behavior
00220440000i[CTRL ] quit_sim called with exit code 1

Binary file not shown.

View File

@ -0,0 +1,14 @@
# ROM and VGA BIOS images ---------------------------------------------
romimage: file=BIOS-bochs-latest, address=0xe0000
vgaromimage: file=VGABIOS-lgpl-latest
# boot from floppy using our disk image -------------------------------
floppya: 1_44=ctaos.img, status=inserted
# logging and reporting -----------------------------------------------
log: OSDev.log # All errors and info logs will output to OSDev.log
error: action=report
info: action=report

BIN
SysCore/debug/ctaos.img Normal file

Binary file not shown.

92
SysCore/hal/cmos/cmos.c Normal file
View File

@ -0,0 +1,92 @@
#include <system.h>
#include <time.h>
#include "cmos.h"
volatile byte i86_cmos_data[128];
void i86_cmos_write ()
{
byte i;
for (i = 0; i < 128; i++) {
//asm volatile ("cli");
outportb(0x70, i);
iowait();
outportb(0x71, i86_cmos_data[i]);
//asm volatile ("sti");
}
}
void i86_cmos_read ()
{
byte i;
for (i = 0; i < 128; i++) {
//asm volatile ("cli");
outportb(0x70, i);
iowait();
i86_cmos_data[i] = inportb(0x71);
//asm volatile ("sti");
}
}
void i86_cmos_read_clock(TIME* tim)
{
i86_cmos_read();
if ((i86_cmos_data[0x0b]&4)==0) // BCD = true;
{
tim->seconds = (i86_cmos_data[0x00]%16) + 10*(i86_cmos_data[0x00]/16);
tim->minutes = (i86_cmos_data[0x02]%16) + 10*(i86_cmos_data[0x02]/16);
if ((i86_cmos_data[0x0b]&2)==0) { // AM/PM
if (i86_cmos_data[0x04]&80) { // pm
tim->hours = ((i86_cmos_data[0x04]-0x80)%16) + 10*((i86_cmos_data[0x04]-0x80)/16);
tim->am_pm = 1;
}
else { // am
tim->hours = (i86_cmos_data[0x04]%16) + 10*(i86_cmos_data[0x04]/16);
tim->am_pm = 0;
}
}
else { // 24 hours
tim->hours = (i86_cmos_data[0x04]%16) + 10*(i86_cmos_data[0x04]/16);
if (tim->hours > 12) {
tim->am_pm = 1;
tim->hours -= 12;
}
else tim->am_pm = 0;
}
tim->weekday = (i86_cmos_data[0x06]%16) + 10*(i86_cmos_data[0x06]/16);
tim->day = (i86_cmos_data[0x07]%16) + 10*(i86_cmos_data[0x07]/16);
tim->month = (i86_cmos_data[0x08]%16) + 10*(i86_cmos_data[0x08]/16);
tim->year = (i86_cmos_data[0x09]%16) + 10*(i86_cmos_data[0x09]/16);
tim->century = (i86_cmos_data[0x32]%16) + 10*(i86_cmos_data[0x32]/16);
}
else {//BCD = false;
tim->seconds = i86_cmos_data[0x00];
tim->minutes = i86_cmos_data[0x02];
if ((i86_cmos_data[0x0b]&2)==0) { // AM/PM
if (i86_cmos_data[0x04]&80) { // pm
tim->hours = i86_cmos_data[0x04]-0x80;
tim->am_pm = 1;
}
else { // am
tim->hours = i86_cmos_data[0x04];
tim->am_pm = 0;
}
}
else { // 24 hours
tim->hours = i86_cmos_data[0x02];
if (tim->hours > 12) {
tim->am_pm = 1;
tim->hours -= 12;
}
else tim->am_pm = 0;
}
tim->weekday = i86_cmos_data[0x06];
tim->day = i86_cmos_data[0x07];
tim->month = i86_cmos_data[0x08];
tim->year = i86_cmos_data[0x09];
tim->century = i86_cmos_data[0x32];
}
}

10
SysCore/hal/cmos/cmos.h Normal file
View File

@ -0,0 +1,10 @@
#ifndef __CMOS_H
#define __CMOS_H
extern volatile byte i86_cmos_data[128];
extern void i86_cmos_write ();
extern void i86_cmos_read ();
extern void i86_cmos_read_clock (TIME *tim);
#endif

View File

@ -0,0 +1,18 @@
@echo off
rem The name of the loader assembly file (without extension, must be .asm):
set loader_name=loader
rem NASM and DJGPP executable paths:
set nasm_path=C:\nasm
set djgpp_path=C:\DJGPP\bin
set objpath=../../objects
set incpath=../../include
@echo on
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/cmos.o cmos.c
@echo off
@echo .
@echo Done!
@pause

43
SysCore/hal/compile.bat Normal file
View File

@ -0,0 +1,43 @@
@echo off
set loader_name=loader
set nasm_path=C:\nasm
set djgpp_path=C:\DJGPP\bin
@echo ***************** CTA KERNEL *****************
:KernelEntry
@echo.
@echo Building Kernel entry...
@echo * Compiling kernel loader...
%nasm_path%\nasm.exe -f aout -o ./objects/%loader_name%.o %loader_name%.asm
@echo * Compiling kernel main...
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I./include -c -o ./objects/main.o main.c
:KernelSTDLIB
cd lib
call compile.bat
cd..
:KernelMemoryManager
cd memory
call compile.bat
cd..
rem here go other sources:
rem here go other sources ^
:Finish
cd objects
@echo Linking...
%djgpp_path%\ld -T link.ld
@echo.
echo Copying to floppy drive...
copy KERNEL.BIN A:\KERNEL.CTA
cd..

View File

@ -0,0 +1,18 @@
@echo off
rem The name of the loader assembly file (without extension, must be .asm):
set loader_name=loader
rem NASM and DJGPP executable paths:
set nasm_path=C:\nasm
set djgpp_path=C:\DJGPP\bin
set objpath=../../objects
set incpath=../../include
@echo on
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/cpu.o cpu.c
@echo off
@echo .
@echo Done!
@pause

35
SysCore/hal/cpu/cpu.c Normal file
View File

@ -0,0 +1,35 @@
#include <system.h>
#include "cpu.h"
#include "../gdt/gdt.h"
#include "../idt/idt.h"
#define cpuid(in, a, b, c, d) __asm__("cpuid": "=a" (a), "=b" (b), "=c" (c), "=d" (d) : "a" (in));
// initializes cpu resources
void i86_cpu_initialize()
{
// initialize processor tables
i86_gdt_install();
i86_idt_install();
}
void i86_cpu_shutdown()
{
}
char* i86_cpu_get_vender()
{
static char vender[13];
dword unused, arr[3];
int i;
cpuid(0, unused, arr[0], arr[2], arr[1]);
for (i=0; i<12; i++)
vender[i] = (arr[i/4]>>(i%4*8)) && 0xFF;
vender[12] = 0;
return vender;
}

29
SysCore/hal/cpu/cpu.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef _CPU_H_INCLUDED
#define _CPU_H_INCLUDED
//****************************************************************************
//**
//** cpu.h
//**
//** This is the processor interface. Everything outside of this module
//** must use this interface when working on processor data.
//**
//** A processor is a module that manages the very basic data structures
//** and data within the system. The processor interface provides the interface
//** for managing processors, processor cores, accessing processor structures,
//** and more
//**
//****************************************************************************
#include <stdint.h>
#include <regs.h>
//! initialize the processors
extern void i86_cpu_initialize ();
//! shutdown the processors
extern void i86_cpu_shutdown ();
//! get cpu vender
extern char* i86_cpu_get_vender ();
#endif

View File

@ -0,0 +1,19 @@
@echo off
rem The name of the loader assembly file (without extension, must be .asm):
set loader_name=loader
rem NASM and DJGPP executable paths:
set nasm_path=C:\nasm
set djgpp_path=C:\DJGPP\bin
set objpath=../../objects
set incpath=../../include
@echo on
%nasm_path%\nasm.exe -f aout -o %objpath%/gdt_asm.o gdt.asm
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/gdt.o gdt.c
@echo off
@echo .
@echo Done!
@pause

20
SysCore/hal/gdt/gdt.asm Normal file
View File

@ -0,0 +1,20 @@
bits 32
; !!! GDT !!!
; This will set up our new segment registers. We need to do
; something special in order to set CS. We do what is called a
; far jump. A jump that includes a segment as well as an offset.
; This is declared in C as 'extern void gdt_flush();'
global _i86_gdt_flush ; Allows the C code to link to this
extern _gp ; Says that '_gp' is in another file
_i86_gdt_flush:
lgdt [_gp] ; Load the GDT with our '_gp' which is a special pointer
mov ax, 0x10 ; 0x10 is the offset in the GDT to our data segment
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
jmp 0x08:flush2 ; 0x08 is the offset to our code segment: Far jump!
flush2:
ret ; Returns back to the C code!

View File

@ -1,36 +1,17 @@
#include <system.h>
/* Defines a GDT entry. We say packed, because it prevents the
* compiler from doing things that it thinks is best: Prevent
* compiler "optimization" by packing */
struct gdt_entry
{
unsigned short limit_low;
unsigned short base_low;
unsigned char base_middle;
unsigned char access;
unsigned char granularity;
unsigned char base_high;
} __attribute__((packed));
/* Special pointer which includes the limit: The max bytes
* taken up by the GDT, minus 1. Again, this NEEDS to be packed */
struct gdt_ptr
{
unsigned short limit;
unsigned int base;
} __attribute__((packed));
/******************************************************************
* gdt.c - GLOBAL DESCRIPTOR TABLE *
* Contains function prototypes for setting up the GDT *
******************************************************************/
#define MAX_DESCRIPTORS 3
#include "gdt.h"
/* Our GDT, with 3 entries, and finally our special GDT pointer */
struct gdt_entry gdt[3];
struct gdt_ptr gp;
/* This will be a function in start.asm. We use this to properly
* reload the new segment registers */
extern void gdt_flush();
/* Setup a descriptor in the Global Descriptor Table */
void gdt_set_gate(int num, unsigned long base, unsigned long limit, unsigned char access, unsigned char gran)
void i86_gdt_set_gate(int num, unsigned long base, unsigned long limit, unsigned char access, unsigned char gran)
{
/* Setup the descriptor base address */
gdt[num].base_low = (base & 0xFFFF);
@ -46,33 +27,39 @@ void gdt_set_gate(int num, unsigned long base, unsigned long limit, unsigned cha
gdt[num].access = access;
}
struct gdt_entry* i86_gdt_get_gate(int num)
{
if (num>MAX_DESCRIPTORS) return 0;
return &gdt[num];
}
/* Should be called by main. This will setup the special GDT
* pointer, set up the first 3 entries in our GDT, and then
* finally call gdt_flush() in our assembler file in order
* to tell the processor where the new GDT is and update the
* new segment registers */
void gdt_install()
void i86_gdt_install()
{
/* Setup the GDT pointer and limit */
gp.limit = (sizeof(struct gdt_entry) * 3) - 1;
gp.base = &gdt;
gp.base = (unsigned int)&gdt;
/* Our NULL descriptor */
gdt_set_gate(0, 0, 0, 0, 0);
i86_gdt_set_gate(0, 0, 0, 0, 0);
/* The second entry is our Code Segment. The base address
* is 0, the limit is 4GBytes, it uses 4KByte granularity,
* uses 32-bit opcodes, and is a Code Segment descriptor.
* Please check the table above in the tutorial in order
* to see exactly what each value means */
gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);
i86_gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);
/* The third entry is our Data Segment. It's EXACTLY the
* same as our code segment, but the descriptor type in
* this entry's access byte says it's a Data Segment */
gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);
i86_gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);
/* Flush out the old GDT and install the new changes! */
gdt_flush();
i86_gdt_flush();
}

39
SysCore/hal/gdt/gdt.h Normal file
View File

@ -0,0 +1,39 @@
/******************************************************************
* gdt.h - GLOBAL DESCRIPTOR TABLE *
* Contains structures and function declarations for GDT *
******************************************************************/
#ifndef __GDT_H
#define __GDT_H
/* Defines a GDT entry. We say packed, because it prevents the
* compiler from doing things that it thinks is best: Prevent
* compiler "optimization" by packing */
struct gdt_entry
{
unsigned short limit_low;
unsigned short base_low;
unsigned char base_middle;
unsigned char access;
unsigned char granularity;
unsigned char base_high;
} __attribute__((packed));
/* Special pointer which includes the limit: The max bytes
* taken up by the GDT, minus 1. Again, this NEEDS to be packed */
struct gdt_ptr
{
unsigned short limit;
unsigned int base;
} __attribute__((packed));
/* This will be a function in start.asm. We use this to properly
* reload the new segment registers */
extern void i86_gdt_flush();
extern void i86_gdt_set_gate(int num, unsigned long base, unsigned long limit, unsigned char access, unsigned char gran);
extern struct gdt_entry* i86_gdt_get_gate(int num);
extern void i86_gdt_install();
#endif

184
SysCore/hal/hal.c Normal file
View File

@ -0,0 +1,184 @@
#include <system.h>
#include <time.h>
#include <hal.h>
#include "cpu/cpu.h"
#include "gdt/gdt.h"
#include "idt/idt.h"
#include "pic/pic.h"
#include "pit/pit.h"
#include "cmos/cmos.h"
#include "irq/irq.h"
#include "isrs/isrs.h"
#include "keyboard/keyus.h"
// initialize hardware devices
void i86_hal_initialize () {
// initialize motherboard controllers and system timer
i86_cpu_initialize (); // (install GDT, IDT)
i86_isrs_install(); // (install ISR handler)
i86_irq_install(); // (install IRQ handler)
// install PIT and system clock; pit at 100 Hz
i86_kb_install_partone();
i86_cmos_read_clock((TIME*)&_internal_clock);
i86_pit_install (100);
i86_kb_install_parttwo();
// enable interrupts
i86_start_interrupts();
}
// shutdown hardware devices
int i86_hal_shutdown () {
i86_cpu_shutdown ();
return 0;
}
void reboot()
{
unsigned char good = 0x02;
while ((good & 0x02) != 0)
good = inportb(0x64);
outportb(0x64, 0xFE);
__asm__ __volatile__ ("hlt");
}
//! notifies hal interrupt is done
/*inline void interruptdone (unsigned int intno) {
//! insure its a valid hardware irq
if (intno > 16)
return;
//! test if we need to send end-of-interrupt to second pic
if (intno >= 8)
i86_pic_send_command (0x20, 0xA1);
//! always send end-of-interrupt to primary pic
i86_pic_send_command (0x20, 0x21);
}
*/
//! output sound to speaker
void sound (unsigned frequency) {
//! sets frequency for speaker. frequency of 0 disables speaker
outportb (0x61, 3 | (byte)(frequency<<2) );
}
//! sets new interrupt vector
/*void _cdecl setvect (int intno, void (_cdecl far &vect) ( ) ) {
//! install interrupt handler! This overwrites prev interrupt descriptor
i86_install_ir (intno, I86_IDT_DESC_PRESENT | I86_IDT_DESC_BIT32,
0x8, vect);
}
//! returns current interrupt vector
void (_cdecl far * _cdecl getvect (int intno)) ( ) {
//! get the descriptor from the idt
idt_descriptor* desc = i86_get_ir (intno);
if (!desc)
return 0;
//! get address of interrupt handler
uint32_t addr = desc->baseLo | (desc->baseHi << 16);
//! return interrupt handler
I86_IRQ_HANDLER irq = (I86_IRQ_HANDLER)addr;
return irq;
}
*/
//! returns cpu vender
const char* get_cpu_vender () {
return i86_cpu_get_vender();
}
/***************************************************************************************
* Keyboard Routines *
***************************************************************************************/
char getch()
{
kb_key alpha = getkey();
return alpha.character;
}
char scancode_to_ascii(byte scancode, byte status)
{
if ((status&1) || (status&2)) return kbdus_map_shift[scancode];
else return kbdus_map[scancode];
}
byte get_key_status (byte scancode)
{
if (scancode&0xF0) return kb_lights_status&0x0F;
else if (scancode&0x80) return kb_modifier_status&0x7F;
return i86_kb_get_key(scancode);
}
/***************************************
* Set repeat rate/delay *
***************************************
Values for inter-character delay (bits 4-0)
(characters per second; default is 10.9)
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
----+----+----+----+----+----+----+----+----
0 |30.0|26.7|24.0|21.8|20.0|18.5|17.1|16.0
8 |15.0|13.3|12.0|10.9|10.0|9.2 |8.6 |8.0
16 |7.5 |6.7 |6.0 |5.5 |5.0 |4.6 |4.3 |4.0
24 |3.7 |3.3 |3.0 |2.7 |2.5 |2.3 |2.1 |2.0
Values for delay:
(miliseconds; default is 500)
0 | 1 | 2 | 3
-----+-----+-----+-----
250 | 500 | 750 | 1000
***************************************/
void kb_set_repeat(float rate, int delay){
float rates[] = {30.0, 26.7, 24.0, 21.8, 20.0, 18.5, 17.1, 16.0, 15.0, 13.3, 12.0,
10.9, 10.0, 9.2, 8.6, 8.0, 7.5, 6.7, 6.0, 5.5, 5.0, 4.6, 4.3, 4.0,
3.7, 3.3, 3.0, 2.7, 2.5, 2.3, 2.1, 2.0} ;
byte r,d;
for (r = 0; rate != rates[r] && r < 32; r++)
if (rate==32) return;
switch(delay) {
case 250: d = 0; break;
case 500: d = 1; break;
case 750: d = 2; break;
case 1000: d = 3; break;
default: return;
}
i86_kb_set_repeat(r,d);
}
/***************************************
* Set keyboard LEDs *
***************************************
+-----------+-------+-------+--------+
| Bits 7-3 | Bit 2 | Bit 1 | Bit 0 |
| 0 | Caps | Num | Scroll |
|(reserved) | lock | lock | lock |
+-----------+-------+-------+--------+
***************************************/
void kb_set_LEDs(byte status) {
i86_kb_set_LEDs(status);
}

View File

@ -0,0 +1,19 @@
@echo off
rem The name of the loader assembly file (without extension, must be .asm):
set loader_name=loader
rem NASM and DJGPP executable paths:
set nasm_path=C:\nasm
set djgpp_path=C:\DJGPP\bin
set objpath=../../objects
set incpath=../../include
@echo on
%nasm_path%\nasm.exe -f aout -o %objpath%/idt_asm.o idt.asm
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/idt.o idt.c
@echo off
@echo .
@echo Done!
@pause

9
SysCore/hal/idt/idt.asm Normal file
View File

@ -0,0 +1,9 @@
bits 32
; !!! IDT !!!
; Loads the IDT defined in '_idtp'
global _i86_idt_load
extern _idtp
_i86_idt_load:
lidt [_idtp]
ret

View File

@ -1,20 +1,9 @@
/******************************************************************
* idt.h - INTERRUPT DESCRIPTOR TABLE *
* Contains structures and function declarations for IDT *
******************************************************************/
#include <system.h>
/* Defines an IDT entry */
struct idt_entry
{
unsigned short base_lo;
unsigned short sel;
unsigned char always0;
unsigned char flags;
unsigned short base_hi;
} __attribute__((packed));
struct idt_ptr
{
unsigned short limit;
unsigned int base;
} __attribute__((packed));
#include "idt.h"
/* Declare an IDT of 256 entries. Although we will only use the
* first 32 entries in this tutorial, the rest exists as a bit
@ -25,12 +14,9 @@ struct idt_ptr
struct idt_entry idt[256];
struct idt_ptr idtp;
/* This exists in 'start.asm', and is used to load our IDT */
extern void idt_load();
/* Use this function to set an entry in the IDT. Alot simpler
* than twiddling with the GDT ;) */
void idt_set_gate(unsigned char num, unsigned long base, unsigned short sel, unsigned char flags)
void i86_idt_set_gate(unsigned char num, unsigned long base, unsigned short sel, unsigned char flags)
{
/* The interrupt routine's base address */
idt[num].base_lo = (base & 0xFFFF);
@ -43,20 +29,21 @@ void idt_set_gate(unsigned char num, unsigned long base, unsigned short sel, uns
idt[num].flags = flags;
}
struct idt_entry* i86_idt_get_gate(unsigned char num)
{
return &idt[num];
}
/* Installs the IDT */
void idt_install()
void i86_idt_install()
{
/* Sets the special IDT pointer up, just like in 'gdt.c' */
idtp.limit = (sizeof (struct idt_entry) * 256) - 1;
idtp.base = &idt;
idtp.base = (unsigned int)&idt;
/* Clear out the entire IDT, initializing it to zeros */
memset(&idt, 0, sizeof(struct idt_entry) * 256);
/* Add any new ISRs to the IDT here using idt_set_gate */
memset (&idt, 0, sizeof(struct idt_entry) * 256);
/* Points the processor's internal register to the new IDT */
idt_load();
i86_idt_load();
}

32
SysCore/hal/idt/idt.h Normal file
View File

@ -0,0 +1,32 @@
/******************************************************************
* idt.h - INTERRUPT DESCRIPTOR TABLE *
* Contains structures and function declarations for IDT *
******************************************************************/
#ifndef __IDT_H
#define __IDT_H
/* Defines an IDT entry */
struct idt_entry
{
unsigned short base_lo;
unsigned short sel;
unsigned char always0;
unsigned char flags;
unsigned short base_hi;
} __attribute__((packed));
struct idt_ptr
{
unsigned short limit;
unsigned int base;
} __attribute__((packed));
/* This exists in 'start.asm', and is used to load our IDT */
extern void i86_idt_load();
extern void i86_idt_set_gate(unsigned char num, unsigned long base, unsigned short sel, unsigned char flags);
extern struct idt_entry* i86_idt_get_gate(unsigned char num);
extern void i86_idt_install();
#endif

View File

@ -0,0 +1,19 @@
@echo off
rem The name of the loader assembly file (without extension, must be .asm):
set loader_name=loader
rem NASM and DJGPP executable paths:
set nasm_path=C:\nasm
set djgpp_path=C:\DJGPP\bin
set objpath=../../objects
set incpath=../../include
@echo on
%nasm_path%\nasm.exe -f aout -o %objpath%/irq_asm.o irq.asm
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/irq.o irq.c
@echo off
@echo .
@echo Done!
@pause

159
SysCore/hal/irq/irq.asm Normal file
View File

@ -0,0 +1,159 @@
bits 32
; !!! IRQ !!!
global _i86_irq0
global _i86_irq1
global _i86_irq2
global _i86_irq3
global _i86_irq4
global _i86_irq5
global _i86_irq6
global _i86_irq7
global _i86_irq8
global _i86_irq9
global _i86_irq10
global _i86_irq11
global _i86_irq12
global _i86_irq13
global _i86_irq14
global _i86_irq15
; 32: IRQ0
_i86_irq0:
cli
push byte 0
push byte 32; Note that these don't push an error code on the stack:
; We need to push a dummy error code
jmp irq_common_stub
; 33: IRQ1
_i86_irq1:
cli
push byte 0
push byte 33
jmp irq_common_stub
; 34: IRQ2
_i86_irq2:
cli
push byte 0
push byte 34
jmp irq_common_stub
; 35: IRQ3
_i86_irq3:
cli
push byte 0
push byte 35
jmp irq_common_stub
; 36: IRQ4
_i86_irq4:
cli
push byte 0
push byte 36
jmp irq_common_stub
; 37: IRQ5
_i86_irq5:
cli
push byte 0
push byte 37
jmp irq_common_stub
; 38: IRQ6
_i86_irq6:
cli
push byte 0
push byte 38
jmp irq_common_stub
; 39: IRQ7
_i86_irq7:
cli
push byte 0
push byte 39
jmp irq_common_stub
; 40: IRQ8
_i86_irq8:
cli
push byte 0
push byte 40
jmp irq_common_stub
; 41: IRQ9
_i86_irq9:
cli
push byte 0
push byte 41
jmp irq_common_stub
; 42: IRQ10
_i86_irq10:
cli
push byte 0
push byte 42
jmp irq_common_stub
; 43: IRQ11
_i86_irq11:
cli
push byte 0
push byte 43
jmp irq_common_stub
; 44: IRQ12
_i86_irq12:
cli
push byte 0
push byte 44
jmp irq_common_stub
; 45: IRQ13
_i86_irq13:
cli
push byte 0
push byte 45
jmp irq_common_stub
; 46: IRQ14
_i86_irq14:
cli
push byte 0
push byte 46
jmp irq_common_stub
; 47: IRQ15
_i86_irq15:
cli
push byte 0
push byte 47
jmp irq_common_stub
extern _i86_irq_handler
; This is a stub that we have created for IRQ based ISRs. This calls
; '_i86_irq_handler' in our C code. We need to create this in an 'irq.c'
irq_common_stub:
pusha
push ds
push es
push fs
push gs
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov eax, esp
push eax
mov eax, _i86_irq_handler
call eax
pop eax
pop gs
pop fs
pop es
pop ds
popa
add esp, 8
iret

79
SysCore/hal/irq/irq.c Normal file
View File

@ -0,0 +1,79 @@
#include <system.h>
#include "../idt/idt.h"
#include "../pic/pic.h"
#include "irq.h"
/* This array is actually an array of function pointers. We use
* this to handle custom IRQ handlers for a given IRQ */
void *irq_routines[16] =
{
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
};
/* This installs a custom IRQ handler for the given IRQ */
void i86_irq_install_handler (int irq, void (*handler)(ISR_stack_regs *r))
{
irq_routines[irq] = handler;
}
void i86_irq_uninstall_handler (int irq)
{
irq_routines[irq] = 0;
}
/* We first remap the interrupt controllers, and then we install
* the appropriate ISRs to the correct entries in the IDT. This
* is just like installing the exception handlers */
void i86_irq_install()
{
i86_pic_remap(32,40);
i86_idt_set_gate(32, (unsigned)i86_irq0, 0x08, 0x8E);
i86_idt_set_gate(33, (unsigned)i86_irq1, 0x08, 0x8E);
i86_idt_set_gate(34, (unsigned)i86_irq2, 0x08, 0x8E);
i86_idt_set_gate(35, (unsigned)i86_irq3, 0x08, 0x8E);
i86_idt_set_gate(36, (unsigned)i86_irq4, 0x08, 0x8E);
i86_idt_set_gate(37, (unsigned)i86_irq5, 0x08, 0x8E);
i86_idt_set_gate(38, (unsigned)i86_irq6, 0x08, 0x8E);
i86_idt_set_gate(39, (unsigned)i86_irq7, 0x08, 0x8E);
i86_idt_set_gate(40, (unsigned)i86_irq8, 0x08, 0x8E);
i86_idt_set_gate(41, (unsigned)i86_irq9, 0x08, 0x8E);
i86_idt_set_gate(42, (unsigned)i86_irq10, 0x08, 0x8E);
i86_idt_set_gate(43, (unsigned)i86_irq11, 0x08, 0x8E);
i86_idt_set_gate(44, (unsigned)i86_irq12, 0x08, 0x8E);
i86_idt_set_gate(45, (unsigned)i86_irq13, 0x08, 0x8E);
i86_idt_set_gate(46, (unsigned)i86_irq14, 0x08, 0x8E);
i86_idt_set_gate(47, (unsigned)i86_irq15, 0x08, 0x8E);
}
/* Each of the IRQ ISRs point to this function, rather than
* the 'fault_handler' in 'isrs.c'. The IRQ Controllers need
* to be told when you are done servicing them, so you need
* to send them an "End of Interrupt" command (0x20). There
* are two 8259 chips: The first exists at 0x20, the second
* exists at 0xA0. If the second controller (an IRQ from 8 to
* 15) gets an interrupt, you need to acknowledge the
* interrupt at BOTH controllers, otherwise, you only send
* an EOI command to the first controller. If you don't send
* an EOI, you won't raise any more IRQs */
void i86_irq_handler (ISR_stack_regs *r)
{
/* This is a blank function pointer */
void (*handler)(ISR_stack_regs *r);
/* Find out if we have a custom handler to run for this
* IRQ, and then finally, run it */
handler = irq_routines[r->int_no - 32];
if (handler) handler(r);
/* If the IDT entry that was invoked was greater than 40
* (meaning IRQ8 - 15), then we need to send an EOI to
* the slave controller */
if (r->int_no >=40) outportb(0x0A, 0x20);
/* In either case, we need to send an EOI to the master
* interrupt controller too */
outportb(0x20, 0x20);
}

29
SysCore/hal/irq/irq.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef __IRQ_H
#define __IRQ_H
/* These are own ISRs that point to our special IRQ handler
* instead of the regular 'fault_handler' function */
extern void i86_irq0();
extern void i86_irq1();
extern void i86_irq2();
extern void i86_irq3();
extern void i86_irq4();
extern void i86_irq5();
extern void i86_irq6();
extern void i86_irq7();
extern void i86_irq8();
extern void i86_irq9();
extern void i86_irq10();
extern void i86_irq11();
extern void i86_irq12();
extern void i86_irq13();
extern void i86_irq14();
extern void i86_irq15();
extern void i86_irq_install_handler (int irq, void (*handler)(ISR_stack_regs *r));
extern void i86_irq_uninstall_handler (int irq);
extern void i86_irq_install();
extern void i86_irq_handler (ISR_stack_regs *r);
#endif

79
SysCore/hal/isrs/BSOD.c Normal file
View File

@ -0,0 +1,79 @@
#include <system.h>
#include <conio.h>
char *exception_messages[] = {
"Division By Zero Exception",
"Debug Exception",
"Non Maskable Interrupt Exception",
"Breakpoint Exception",
"Into Detected Overflow Exception",
"Out of Bounds Exception",
"Invalid Opcode Exception",
"No Coprocessor",
"Double Fault Exception",
"Coprocessor Segment Overrun Exception",
"Bad TSS Exception",
"Segment Not Present Exception",
"Stack Fault Exception",
"General Protection Fault Exception",
"Page Fault Exception",
"Unknown Interrupt Exception",
"Coprocessor Fault Exception",
"Alignment Check Exception",
"Machine Check Exception",
"Reserved Exception",
"Reserved Exception",
"Reserved Exception",
"Reserved Exception",
"Reserved Exception",
"Reserved Exception",
"Reserved Exception",
"Reserved Exception",
"Reserved Exception",
"Reserved Exception",
"Reserved Exception",
"Reserved Exception"
};
void _STOP_ERROR_SCREEN (ISR_stack_regs *r)
{
set_default_colors (0x01, 0x0F); clrscr();
puts (" Blue Screen Of Death\n");
int i; for (i = 79; i>=0; i--) putc('=');
puts_pos_font (15, 2, "A fatal error has occured, CTA OS has been halted.", 0x01, 0x0C);
puts_pos_font (10, 4, "gs", 0x01, 0x0B); put_hex_pos(15, 4, r->gs);
puts_pos_font (10, 5, "fs", 0x01, 0x0B); put_hex_pos(15, 5, r->fs);
puts_pos_font (10, 6, "es", 0x01, 0x0B); put_hex_pos(15, 6, r->es);
puts_pos_font (10, 7, "ds", 0x01, 0x0B); put_hex_pos(15, 7, r->ds);
puts_pos_font (40, 4, "edi", 0x01, 0x0B); put_hex_pos(45, 4, r->edi);
puts_pos_font (40, 5, "esi", 0x01, 0x0B); put_hex_pos(45, 5, r->esi);
puts_pos_font (40, 6, "ebp", 0x01, 0x0B); put_hex_pos(45, 6, r->ebp);
puts_pos_font (40, 7, "esp", 0x01, 0x0B); put_hex_pos(45, 7, r->esp);
puts_pos_font (10, 9, "eax", 0x01, 0x0B); put_hex_pos(15, 9, r->eax);
puts_pos_font (10, 10, "ebx", 0x01, 0x0B); put_hex_pos(15, 10, r->ebx);
puts_pos_font (40, 9, "ecx", 0x01, 0x0B); put_hex_pos(45, 9, r->ecx);
puts_pos_font (40, 10, "edx", 0x01, 0x0B); put_hex_pos(45, 10, r->edx);
puts_pos_font (10, 12, "int_no", 0x01, 0x0B); put_hex_pos(17, 12, r->int_no);
puts_pos_font (10, 14, "Error code:", 0x01, 0x0B); put_hex_pos(24, 14, r->err_code);
puts_pos_font (10, 15, "Error msg: ", 0x01, 0x0B); puts_pos(24, 15, exception_messages[r->int_no]);
puts_pos_font (10, 17, "eip", 0x01, 0x0B); put_hex_pos(17, 17, r->eip);
puts_pos_font (10, 18, "cs", 0x01, 0x0B); put_hex_pos(17, 18, r->cs);
puts_pos_font (10, 19, "eflags", 0x01, 0x0B); put_hex_pos(17, 19, r->eflags);
puts_pos_font (10, 20, "useresp", 0x01, 0x0B); put_hex_pos(17, 20, r->useresp);
puts_pos_font (10, 21, "ss", 0x01, 0x0B); put_hex_pos(17, 21, r->ss);
puts_pos_font (29, 24, "!!! System Halted !!!", 0x01, 0x0C);
}
/*void _STOP_ERROR_SCREEN (ISR_stack_regs *r)
{
puts_pos_font (30, 24, "Stop error 0x", 0x01, 0x0B); put_hex_pos(37, 24, r->int_no);
puts_pos(50, 24, exception_messages[r->int_no]);
puts_pos_font (5, 24, "!!! System Halted !!!", 0x01, 0x0C);
}*/

View File

@ -0,0 +1,20 @@
@echo off
rem The name of the loader assembly file (without extension, must be .asm):
set loader_name=loader
rem NASM and DJGPP executable paths:
set nasm_path=C:\nasm
set djgpp_path=C:\DJGPP\bin
set objpath=../../objects
set incpath=../../include
@echo on
%nasm_path%\nasm.exe -f aout -o %objpath%/isrs_asm.o isrs.asm
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/isrs.o isrs.c
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/BSOD.o BSOD.c
@echo off
@echo .
@echo Done!
@pause

217
SysCore/hal/isrs/isrs.asm Normal file
View File

@ -0,0 +1,217 @@
bits 32
; !!! ISRs !!!
global _i86_isr0
global _i86_isr1
global _i86_isr2
global _i86_isr3
global _i86_isr4
global _i86_isr5
global _i86_isr6
global _i86_isr7
global _i86_isr8
global _i86_isr9
global _i86_isr10
global _i86_isr11
global _i86_isr12
global _i86_isr13
global _i86_isr14
global _i86_isr15
global _i86_isr16
global _i86_isr17
global _i86_isr18
global _i86_isr19
global _i86_isr20
global _i86_isr21
global _i86_isr22
global _i86_isr23
global _i86_isr24
global _i86_isr25
global _i86_isr26
global _i86_isr27
global _i86_isr28
global _i86_isr29
global _i86_isr30
global _i86_isr31
_i86_isr0:
cli
push byte 0; A normal ISR stub that pops a dummy error code to keep a
; uniform stack frame
push byte 0
jmp isr_common_stub
_i86_isr1:
cli
push byte 0
push byte 1
jmp isr_common_stub
_i86_isr2:
cli
push byte 0
push byte 2
jmp isr_common_stub
_i86_isr3:
cli
push byte 0
push byte 3
jmp isr_common_stub
_i86_isr4:
cli
push byte 0
push byte 4
jmp isr_common_stub
_i86_isr5:
cli
push byte 0
push byte 5
jmp isr_common_stub
_i86_isr6:
cli
push byte 0
push byte 6
jmp isr_common_stub
_i86_isr7:
cli
push byte 0
push byte 7
jmp isr_common_stub
_i86_isr8:
cli
push byte 8
jmp isr_common_stub
_i86_isr9:
cli
push byte 0
push byte 9
jmp isr_common_stub
_i86_isr10:
cli
push byte 10
jmp isr_common_stub
_i86_isr11:
cli
push byte 11
jmp isr_common_stub
_i86_isr12:
cli
push byte 12
jmp isr_common_stub
_i86_isr13:
cli
push byte 13
jmp isr_common_stub
_i86_isr14:
cli
push byte 14
jmp isr_common_stub
_i86_isr15:
cli
push byte 0
push byte 15
jmp isr_common_stub
_i86_isr16:
cli
push byte 0
push byte 16
jmp isr_common_stub
_i86_isr17:
cli
push byte 0
push byte 17
jmp isr_common_stub
_i86_isr18:
cli
push byte 0
push byte 18
jmp isr_common_stub
_i86_isr19:
cli
push byte 0
push byte 19
jmp isr_common_stub
_i86_isr20:
cli
push byte 0
push byte 20
jmp isr_common_stub
_i86_isr21:
cli
push byte 0
push byte 21
jmp isr_common_stub
_i86_isr22:
cli
push byte 0
push byte 22
jmp isr_common_stub
_i86_isr23:
cli
push byte 0
push byte 23
jmp isr_common_stub
_i86_isr24:
cli
push byte 0
push byte 24
jmp isr_common_stub
_i86_isr25:
cli
push byte 0
push byte 25
jmp isr_common_stub
_i86_isr26:
cli
push byte 0
push byte 26
jmp isr_common_stub
_i86_isr27:
cli
push byte 0
push byte 27
jmp isr_common_stub
_i86_isr28:
cli
push byte 0
push byte 28
jmp isr_common_stub
_i86_isr29:
cli
push byte 0
push byte 29
jmp isr_common_stub
_i86_isr30:
cli
push byte 0
push byte 30
jmp isr_common_stub
_i86_isr31:
cli
push byte 0
push byte 31
jmp isr_common_stub
extern _i86_fault_handler
isr_common_stub:
pusha
push ds
push es
push fs
push gs
mov ax, 0x10 ; Load the Kernel Data Segment descriptor!
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov eax, esp ; Push us the stack
push eax
mov eax, _i86_fault_handler
call eax ; A special call, preserves the 'eip' register
pop eax
pop gs
pop fs
pop es
pop ds
popa
add esp, 8 ; Cleans up the pushed error code and pushed ISR number
iret ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP!

70
SysCore/hal/isrs/isrs.c Normal file
View File

@ -0,0 +1,70 @@
#include <system.h>
#include "isrs.h"
#include "../idt/idt.h"
extern void _STOP_ERROR_SCREEN(ISR_stack_regs *);
/* This is a very repetitive function... it's not hard, it's
* just annoying. As you can see, we set the first 32 entries
* in the IDT to the first 32 ISRs. We can't use a for loop
* for this, because there is no way to get the function names
* that correspond to that given entry. We set the access
* flags to 0x8E. This means that the entry is present, is
* running in ring 0 (kernel level), and has the lower 5 bits
* set to the required '14', which is represented by 'E' in
* hex. */
void i86_isrs_install()
{
i86_idt_set_gate(0, (unsigned)i86_isr0, 0x08, 0x8E);
i86_idt_set_gate(1, (unsigned)i86_isr1, 0x08, 0x8E);
i86_idt_set_gate(2, (unsigned)i86_isr2, 0x08, 0x8E);
i86_idt_set_gate(3, (unsigned)i86_isr3, 0x08, 0x8E);
i86_idt_set_gate(4, (unsigned)i86_isr4, 0x08, 0x8E);
i86_idt_set_gate(5, (unsigned)i86_isr5, 0x08, 0x8E);
i86_idt_set_gate(6, (unsigned)i86_isr6, 0x08, 0x8E);
i86_idt_set_gate(7, (unsigned)i86_isr7, 0x08, 0x8E);
i86_idt_set_gate(8, (unsigned)i86_isr8, 0x08, 0x8E);
i86_idt_set_gate(9, (unsigned)i86_isr9, 0x08, 0x8E);
i86_idt_set_gate(10, (unsigned)i86_isr10, 0x08, 0x8E);
i86_idt_set_gate(11, (unsigned)i86_isr11, 0x08, 0x8E);
i86_idt_set_gate(12, (unsigned)i86_isr12, 0x08, 0x8E);
i86_idt_set_gate(13, (unsigned)i86_isr13, 0x08, 0x8E);
i86_idt_set_gate(14, (unsigned)i86_isr14, 0x08, 0x8E);
i86_idt_set_gate(15, (unsigned)i86_isr15, 0x08, 0x8E);
i86_idt_set_gate(16, (unsigned)i86_isr16, 0x08, 0x8E);
i86_idt_set_gate(17, (unsigned)i86_isr17, 0x08, 0x8E);
i86_idt_set_gate(18, (unsigned)i86_isr18, 0x08, 0x8E);
i86_idt_set_gate(19, (unsigned)i86_isr19, 0x08, 0x8E);
i86_idt_set_gate(20, (unsigned)i86_isr20, 0x08, 0x8E);
i86_idt_set_gate(21, (unsigned)i86_isr21, 0x08, 0x8E);
i86_idt_set_gate(22, (unsigned)i86_isr22, 0x08, 0x8E);
i86_idt_set_gate(23, (unsigned)i86_isr23, 0x08, 0x8E);
i86_idt_set_gate(24, (unsigned)i86_isr24, 0x08, 0x8E);
i86_idt_set_gate(25, (unsigned)i86_isr25, 0x08, 0x8E);
i86_idt_set_gate(26, (unsigned)i86_isr26, 0x08, 0x8E);
i86_idt_set_gate(27, (unsigned)i86_isr27, 0x08, 0x8E);
i86_idt_set_gate(28, (unsigned)i86_isr28, 0x08, 0x8E);
i86_idt_set_gate(29, (unsigned)i86_isr29, 0x08, 0x8E);
i86_idt_set_gate(30, (unsigned)i86_isr30, 0x08, 0x8E);
i86_idt_set_gate(31, (unsigned)i86_isr31, 0x08, 0x8E);
}
/* All of our Exception handling Interrupt Service Routines will
* point to this function. This will tell us what exception has
* happened! Right now, we simply halt the system by hitting an
* endless loop. All ISRs disable interrupts while they are being
* serviced as a 'locking' mechanism to prevent an IRQ from
* happening and messing up kernel data structures */
void i86_fault_handler(ISR_stack_regs *r)
{
/* Is this a fault whose number is from 0 to 31? */
if (r->int_no < 32)
{
_STOP_ERROR_SCREEN(r);
/* Display the description for the Exception that occurred.*/
/* Put on the BSOD screen*/
for (;;);
}
}

40
SysCore/hal/isrs/isrs.h Normal file
View File

@ -0,0 +1,40 @@
#ifndef __ISRS_H
#define __ISRS_H
extern void i86_isr0();
extern void i86_isr1();
extern void i86_isr2();
extern void i86_isr3();
extern void i86_isr4();
extern void i86_isr5();
extern void i86_isr6();
extern void i86_isr7();
extern void i86_isr8();
extern void i86_isr9();
extern void i86_isr10();
extern void i86_isr11();
extern void i86_isr12();
extern void i86_isr13();
extern void i86_isr14();
extern void i86_isr15();
extern void i86_isr16();
extern void i86_isr17();
extern void i86_isr18();
extern void i86_isr19();
extern void i86_isr20();
extern void i86_isr21();
extern void i86_isr22();
extern void i86_isr23();
extern void i86_isr24();
extern void i86_isr25();
extern void i86_isr26();
extern void i86_isr27();
extern void i86_isr28();
extern void i86_isr29();
extern void i86_isr30();
extern void i86_isr31();
extern void i86_isrs_install();
extern void i86_fault_handler(ISR_stack_regs *r);
#endif

View File

@ -0,0 +1,18 @@
@echo off
rem The name of the loader assembly file (without extension, must be .asm):
set loader_name=loader
rem NASM and DJGPP executable paths:
set nasm_path=C:\nasm
set djgpp_path=C:\DJGPP\bin
set objpath=../../objects
set incpath=../../include
@echo on
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/keyus.o keyus.c
@echo off
@echo .
@echo Done!
@pause

View File

@ -0,0 +1,133 @@
#define KB_KEY_LSHIFT 0x81 // 1000 0001
#define KB_KEY_RSHIFT 0X82 // 1000 0010
#define KB_KEY_LALT 0X84 // 1000 0100
#define KB_KEY_RALT 0x88 // 1000 1000
#define KB_KEY_LCTRL 0x90 // 1001 0000
#define KB_KEY_RCTRL 0xA0 // 1010 0000
#define KB_KEY_FSHIFT 0xC0 // 1100 0000
extern volatile byte kb_modifier_status;
#define KB_PREFIX_GRAY 0x01 // Gray
#define KB_PREFIX_BREAK 0x02 // Break code
#define KB_PREFIX_PAUSE 0x04 // Pause/break key
#define KB_PREFIX_PAUSE1 0x08 // Recieved first byte from pause/break
extern volatile byte kb_prefix;
#define KB_KEY_SCROLL 0xF1 // 1111 0001
#define KB_KEY_NUM 0xF2 // 1111 0010
#define KB_KEY_CAPS 0xF4 // 1111 0100
extern volatile byte kb_lights_status;
extern byte kb_scancode_set;
#define KB_KEY_PAUSE 0x00
#define KB_KEY_F9 0x01
#define KB_KEY_F7 0x02
#define KB_KEY_F5 0X03
#define KB_KEY_F3 0x04
#define KB_KEY_F1 0x05
#define KB_KEY_F2 0x06
#define KB_KEY_F12 0x07
#define KB_KEY_PRINTSCRN 0x08
#define KB_KEY_F10 0x09
#define KB_KEY_F8 0x0A
#define KB_KEY_F6 0x0B
#define KB_KEY_F4 0x0C
#define KB_KEY_TAB 0x0D
#define KB_KEY_TILDA 0x0E
#define KB_KEY_Q 0x15
#define KB_KEY_1 0x16
#define KB_KEY_Z 0x1A
#define KB_KEY_S 0x1B
#define KB_KEY_A 0x1C
#define KB_KEY_W 0x1D
#define KB_KEY_2 0x1E
#define KB_KEY_LWIN 0x1F
#define KB_KEY_C 0x21
#define KB_KEY_X 0x22
#define KB_KEY_D 0x23
#define KB_KEY_E 0x24
#define KB_KEY_4 0x25
#define KB_KEY_3 0x26
#define KB_KEY_RWIN 0x27
#define KB_KEY_SPACE 0x29
#define KB_KEY_V 0x2A
#define KB_KEY_F 0x2B
#define KB_KEY_T 0x2C
#define KB_KEY_R 0x2D
#define KB_KEY_5 0x2E
#define KB_KEY_MENU 0x2F
#define KB_KEY_N 0x31
#define KB_KEY_B 0x32
#define KB_KEY_H 0x33
#define KB_KEY_G 0x34
#define KB_KEY_Y 0x35
#define KB_KEY_6 0x36
#define KB_KEY_M 0x3A
#define KB_KEY_J 0x3B
#define KB_KEY_U 0x3C
#define KB_KEY_7 0x3D
#define KB_KEY_8 0x3E
#define KB_KEY_COMMA 0x41
#define KB_KEY_K 0x42
#define KB_KEY_I 0x43
#define KB_KEY_O 0x44
#define KB_KEY_0 0x45
#define KB_KEY_9 0x46
#define KB_KEY_PERIOD 0x49
#define KB_KEY_SLASH 0x4A
#define KB_KEY_L 0x4B
#define KB_KEY_SEMICOLON 0x4C
#define KB_KEY_P 0x4D
#define KB_KEY_DASH 0x4E
#define KB_KEY_APOSTROPHE 0x52
#define KB_KEY_LBRACKET 0x54
#define KB_KEY_EQUAL 0x55
#define KB_KEY_NUMPAD_ENTER 0x59
#define KB_KEY_ENTER 0x5A
#define KB_KEY_RBRACKET 0x5B
#define KB_KEY_BACKSLASH 0x5D
#define KB_KEY_END 0x5E
#define KB_KEY_LEFT 0x5F
#define KB_KEY_HOME 0x60
#define KB_KEY_INSERT 0x61
#define KB_KEY_DELETE 0x62
#define KB_KEY_DOWN 0x63
#define KB_KEY_RIGHT 0x64
#define KB_KEY_UP 0x65
#define KB_KEY_BACKSPACE 0x66
#define KB_KEY_PGDOWN 0x67
#define KB_KEY_PGUP 0x68
#define KB_KEY_NUMPAD_1 0x69
#define KB_KEY_NUMPAD_SLASH 0x6A
#define KB_KEY_NUMPAD_4 0x6B
#define KB_KEY_NUMPAD_7 0x6C
#define KB_KEY_NUMPAD_0 0x70
#define KB_KEY_NUMPAD_COLON 0x71
#define KB_KEY_NUMPAD_2 0x72
#define KB_KEY_NUMPAD_5 0x73
#define KB_KEY_NUMPAD_6 0x74
#define KB_KEY_NUMPAD_8 0x75
#define KB_KEY_ESC 0x76
#define KB_KEY_F11 0x78
#define KB_KEY_NUMPAD_PLUS 0x79
#define KB_KEY_NUMPAD_3 0x7A
#define KB_KEY_NUMPAD_MINUS 0x7B
#define KB_KEY_NUMPAD_ASTERISK 0x7C
#define KB_KEY_NUMPAD_9 0x7D
typedef struct {
byte status;
byte lights;
byte scancode;
byte character;
} kb_key;
extern char getch();
extern kb_key get_key();
extern scancode_to_ascii(byte scancode);
extern byte get_key_status(byte scancode);
extern void kb_set_repeat(float rate, int delay);
extern void kb_set_LEDs(byte status);

View File

@ -1,31 +1,42 @@
#include <system.h>
#include <hal.h>
#include "keyus.h"
#include "../irq/irq.h"
// kb_key_return 4-byte structure
typedef struct {
byte status;
byte lights;
byte scancode;
byte character;
} kb_key;
extern void reboot();
byte kb_array[16];
volatile static byte kb_newdata;
const char kbdus_map[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '\t', '`', 0,
0, 0, 0, 0, 0, 'q', '1', 0, 0, 0, 'z', 's', 'a', 'w', '2', 0,
0, 'c', 'x', 'd', 'e', '4', '3', 0, 0, ' ', 'v', 'f', 't', 'r', '5', 0,
0, 'n', 'b', 'h', 'g', 'y', '6', 0, 0, 0, 'm', 'j', 'u', '7', '8', 0,
0, ',', 'k', 'i', 'o', '0', '9', 0, 0, '.', '/', 'l', ';', 'p', '-', 0,
0, 0, '\'', 0, '[', '=', 0, 0, 0, '\n', '\n', ']', 0, '\\', 0, 0,
0, 0, 0x7F, 0, 0, 0, '\b', 0, 0, '1', '/', '4', '7', 0, 0, 0,
'0', '.', '2', '5', '6', '8', 0, 0, 0, '+', '3', '-', '*', '9', 0, 0
};
/*********DEBUG**************/
void kb_print_binary(int x, int y, byte what)
{
char arr[9]; int i;
for (i = 7; i>=0; i--, what/=2)
arr[i] = (what%2) + '0';
arr[8] = 0;
puts_pos(x,y,arr);
const char kbdus_map_shift[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '\t', '~', 0,
0, 0, 0, 0, 0, 'Q', '!', 0, 0, 0, 'Z', 'S', 'A', 'W', '@', 0,
0, 'C', 'X', 'D', 'E', '$', '#', 0, 0, ' ', 'V', 'F', 'T', 'R', '%', 0,
0, 'N', 'B', 'H', 'G', 'Y', '^', 0, 0, 0, 'M', 'J', 'U', '&', '*', 0,
0, '<', 'K', 'I', 'O', ')', '(', 0, 0, '>', '?', 'L', ':', 'P', '_', 0,
0, 0, '\"', 0, '{', '+', 0, 0, 0, '\n', '\n', '}', 0, '|', 0, 0,
0, 0, 0x7F, 0, 0, 0, '\b', 0, 0, '1', '/', '4', '7', 0, 0, 0,
'0', '.', '2', '5', '6', '8', 0, 0, 0, '+', '3', '-', '*', '9', 0, 0
};
}
/*********DEBUG**************/
void kb_set_key(byte scancode, byte val)
volatile byte kb_array[16];
volatile byte kb_newdata;
volatile byte kb_modifier_status;
volatile byte kb_prefix;
volatile byte kb_lights_status;
byte kb_scancode_set;
void i86_kb_set_key(byte scancode, byte val)
{
byte pos = scancode/8;
byte offset = scancode%8;
@ -37,7 +48,7 @@ void kb_set_key(byte scancode, byte val)
else kb_array[pos] &= 0xFF - (1<<offset);
}
byte kb_get_key(byte scancode)
byte i86_kb_get_key(byte scancode)
{
byte pos = scancode/8;
byte offset = scancode%8;
@ -45,14 +56,14 @@ byte kb_get_key(byte scancode)
}
void kb_handler(regs *r) {
void i86_kb_handler(ISR_stack_regs *r) {
byte scancode = inportb(0x60);
switch (scancode) {
case 0x00: // Error 0x00
case 0xFC: // Diagnostics failed (MF kb)
case 0xFD: // Diagnostics failed (AT kb)
case 0xFF: kb_waitin(); outportb(0x60, 0xF4); // Error 0xFF
case 0xFF: i86_kb_waitin(); outportb(0x60, 0xF4); // Error 0xFF
break;
case 0xAA: // BAT test successful.
case 0xFA: // ACKnowledge
@ -84,10 +95,9 @@ void kb_handler(regs *r) {
}
kb_prefix = 0; break;
//TO ADD BELOW: pause/break byte1
case 0x14: if (kb_prefix&4) {
if ((kb_prefix&2) == 0) kb_set_key (0, 1);
else kb_set_key (0, 0);
if ((kb_prefix&2) == 0) i86_kb_set_key (0, 1);
else i86_kb_set_key (0, 0);
kb_prefix |= 8; break;
}
@ -109,17 +119,17 @@ void kb_handler(regs *r) {
// LEDs
case 0x58: if ((kb_prefix&2) == 0) {
kb_lights_status ^= 4; kb_set_LEDs(kb_lights_status);
kb_lights_status ^= 4; i86_kb_set_LEDs(kb_lights_status);
} kb_prefix = 0; break; // Caps
//TO ADD BELOW: pause/break byte2
case 0x77:
if ((kb_prefix&4) && (kb_prefix&8)) kb_prefix=0;
else if ((kb_prefix&2) == 0) {
kb_lights_status ^= 2; kb_set_LEDs(kb_lights_status);
kb_lights_status ^= 2; i86_kb_set_LEDs(kb_lights_status);
} kb_prefix = 0; break; // Num
case 0x7E: if ((kb_prefix&2) == 0) {
kb_lights_status ^= 1; kb_set_LEDs(kb_lights_status);
kb_lights_status ^= 1; i86_kb_set_LEDs(kb_lights_status);
} kb_prefix = 0; break; // Scroll
case 0x83: scancode = 0x02; // Put F7 under the 0x80 (128bit) barrier
@ -141,8 +151,8 @@ void kb_handler(regs *r) {
case 0x7A: scancode=0x67; break; // PageDown
case 0x7D: scancode=0x68; break; // PageUp
}
if ((kb_prefix&2) == 0) kb_set_key(scancode, 1);
else kb_set_key(scancode, 0);
if ((kb_prefix&2) == 0) i86_kb_set_key(scancode, 1);
else i86_kb_set_key(scancode, 0);
kb_prefix = 0; break;
}
@ -160,7 +170,7 @@ void kb_handler(regs *r) {
kb_key kb_getkey()
kb_key getkey()
{
kb_key ret;
@ -176,4 +186,141 @@ kb_key kb_getkey()
else ret.character = kbdus_map[ret.scancode]; // Shift is off
return ret; // And send it.
}
}
/***************************************
* Set repeat rate/delay *
***************************************
Values for inter-character delay (bits 4-0)
(characters per second; default is 10.9)
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
----+----+----+----+----+----+----+----+----
0 |30.0|26.7|24.0|21.8|20.0|18.5|17.1|16.0
8 |15.0|13.3|12.0|10.9|10.0|9.2 |8.6 |8.0
16 |7.5 |6.7 |6.0 |5.5 |5.0 |4.6 |4.3 |4.0
24 |3.7 |3.3 |3.0 |2.7 |2.5 |2.3 |2.1 |2.0
Values for delay:
(miliseconds; default is 500)
0 | 1 | 2 | 3
-----+-----+-----+-----
250 | 500 | 750 | 1000
***************************************/
void i86_kb_set_repeat(byte rate, byte delay)
{
if (rate>3 || delay>31) return;
byte out = rate<<5 | delay;
while ((inportb(0x64)&2) != 0);
outportb(0x60, 0xF3);
while ((inportb(0x64)&2) != 0);
outportb(0x60, out);
}
/***************************************
* Set keyboard LEDs *
***************************************
+-----------+-------+-------+--------+
| Bits 7-3 | Bit 2 | Bit 1 | Bit 0 |
| 0 | Caps | Num | Scroll |
|(reserved) | lock | lock | lock |
+-----------+-------+-------+--------+
***************************************/
void i86_kb_set_LEDs(byte status)
{
while ((inportb (0x64)&2)!=0);
outportb (0x60, 0xED);
while ((inportb (0x64)&2)!=0);
outportb (0x60, status);
}
/***************************************
* Set scancode set *
***************************************
0 Get current scancode set
1 Set to scancode set 1
2 Set to scancode set 2
3 Set to scancode set 3
***************************************/
void i86_kb_set_scancodeset(byte set)
{
if (set>3) return;
while ((inportb (0x64)&2)!=0);
outportb (0x60, 0xF0);
while ((inportb (0x64)&2)!=0);
outportb (0x60, set);
kb_scancode_set = set;
}
byte i86_kb_get_scancodeset() {
return kb_scancode_set;
}
void i86_kb_waitin()
{
int fail_safe=200000;
while ((inportb(0x64)&2)!=0 && fail_safe>0) fail_safe--;
}
void i86_kb_waitout()
{
int fail_safe=200000;
while ((inportb(0x64)&1)==0 && fail_safe>0) fail_safe--;
}
void i86_kb_install_partone()
{
i86_irq_install_handler(1, i86_kb_handler);// instali handler
i86_kb_waitin(); outportb(0x60, 0xFF); // Reset kb
// Initialize variables
kb_newdata = 0;
kb_modifier_status = 0;
kb_prefix = 0;
kb_lights_status = 0;
kb_scancode_set = 0;
}
int i86_kb_install_parttwo()
{
int ret = 0;
// Wait for BAT test results
byte temp;
do temp = inportb(0x60);
while (temp!=0xAA && temp!=0xFC);
if (temp == 0xFC) ret = -1;
// Set new repeat rate
i86_kb_set_repeat(1, 11);
// Set scancode set 2
i86_kb_set_scancodeset(2); // Set new scancode set
i86_kb_waitin();
outportb(0x64, 0x20); // Get "Command byte"
do { temp = inportb(0x60);
} while (temp==0xFA || temp==0xAA);
temp &= 0xFF - (1<<6); // Set bit6 to 0: disable conversion
i86_kb_waitin(); outportb(0x64, 0x60); // Function to write cmd byte
i86_kb_waitin(); outportb(0x60, temp); // Send it
memset((void*)kb_array, 0, 16);
return ret;
}

View File

@ -0,0 +1,28 @@
#ifndef __KEYUS_H
#define __KEYUS_H
extern const char kbdus_map[0x80];
extern const char kbdus_map_shift[0x80];
extern volatile byte kb_modifier_status;
extern volatile byte kb_prefix;
extern volatile byte kb_lights_status;
extern byte kb_scancode_set;
extern void i86_kb_set_key(byte scancode, byte val);
extern void i86_kb_set_LEDs(byte status);
extern void i86_kb_set_repeat(byte rate, byte delay);
extern void i86_kb_set_scancodeset(byte set);
extern byte i86_kb_get_key(byte scancode);
extern void i86_kb_handler(ISR_stack_regs *r);
extern kb_key getkey();
extern void i86_kb_set_repeat(byte rate, byte delay);
extern void i86_kb_set_LEDs(byte status);
extern void i86_kb_set_scancodeset(byte set);
extern byte i86_kb_get_scancodeset();
extern void i86_kb_waitin();
extern void i86_kb_waitout();
extern void i86_kb_install_partone();
extern int i86_kb_install_parttwo();
#endif

109
SysCore/hal/makeall.bat Normal file
View File

@ -0,0 +1,109 @@
@echo off
set nasm_path=C:\nasm
set djgpp_path=C:\DJGPP\bin
@echo Building Hardware Abstraction Layer...
set objpath=..\objects
set incpath=../include
del %objpath%\hal.o
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/hal.o hal.c
if not exist %objpath%\hal.o goto error
set objpath=..\..\objects
set incpath=../../include
goto cmos
:error
@echo.
@echo There have been build errors. Building halted.
@pause
exit
:cmos
cd cmos
@echo * Compiling CMOS...
del %objpath%\cmos.o
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/cmos.o cmos.c
if not exist %objpath%\cmos.o goto error
cd..
:cpu
cd cpu
@echo * Compiling Central Processing Unit...
del %objpath%\cpu.o
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/cpu.o cpu.c
if not exist %objpath%\cpu.o goto error
cd..
:gdt
cd gdt
@echo * Compiling Global Descriptor Table...
del %objpath%\gdt.o
del %objpath%\gdt_asm.o
%nasm_path%\nasm.exe -f aout -o %objpath%/gdt_asm.o gdt.asm
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/gdt.o gdt.c
if not exist %objpath%\gdt.o goto error
if not exist %objpath%\gdt_asm.o goto error
cd..
:idt
cd idt
@echo * Compiling Interrupt Descriptor Table...
del %objpath%\idt.o
del %objpath%\idt_asm.o
%nasm_path%\nasm.exe -f aout -o %objpath%/idt_asm.o idt.asm
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/idt.o idt.c
if not exist %objpath%\idt.o goto error
if not exist %objpath%\idt_asm.o goto error
cd..
:irq
cd irq
@echo * Compiling Interrupt ReQuests...
del %objpath%\irq.o
del %objpath%\irq_asm.o
%nasm_path%\nasm.exe -f aout -o %objpath%/irq_asm.o irq.asm
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/irq.o irq.c
if not exist %objpath%\irq.o goto error
if not exist %objpath%\irq_asm.o goto error
cd..
:isrs
cd isrs
@echo * Compiling Interrupt Service Routines...
del %objpath%\isrs_asm.o
del %objpath%\isrs.o
del %objpath%\BSOD.o
%nasm_path%\nasm.exe -f aout -o %objpath%/isrs_asm.o isrs.asm
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/isrs.o isrs.c
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/BSOD.o BSOD.c
if not exist %objpath%\isrs_asm.o goto error
if not exist %objpath%\isrs.o goto error
if not exist %objpath%\BSOD.o goto error
cd..
:keyboard
cd keyboard
@echo * Compiling KEYBOARD...
del %objpath%\keyus.o
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/keyus.o keyus.c
if not exist %objpath%\keyus.o goto error
cd..
:pic
cd pic
@echo * Compiling Programmable Interrupt Controller...
del %objpath%\pic.o
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/pic.o pic.c
if not exist %objpath%\pic.o goto error
cd..
:pit
cd pit
@echo * Compiling Programmable Interval Timer...
del %objpath%\pit.o
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/pit.o pit.c
if not exist %objpath%\pit.o goto error
cd..

View File

@ -0,0 +1,18 @@
@echo off
rem The name of the loader assembly file (without extension, must be .asm):
set loader_name=loader
rem NASM and DJGPP executable paths:
set nasm_path=C:\nasm
set djgpp_path=C:\DJGPP\bin
set objpath=../../objects
set incpath=../../include
@echo on
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/pic.o pic.c
@echo off
@echo .
@echo Done!
@pause

23
SysCore/hal/pic/pic.c Normal file
View File

@ -0,0 +1,23 @@
#include <system.h>
#include "pic.h"
void i86_pic_remap(int pic1, int pic2)
{
// Send ICW1
outportb(0x20, 0x11);
outportb(0xA0, 0x11);
// send ICW2
outportb(0x21, pic1); // remap pics
outportb(0xA1, pic2);
// send ICW3
outportb(0x21, 4);
outportb(0xA1, 2);
// Send ICW4
outportb(0x21, 0x01);
outportb(0xA1, 0x01);
outportb(0x21, 0x00);
}

6
SysCore/hal/pic/pic.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef _PIC_H
#define _PIC_H
extern void i86_pic_remap(int pic1, int pic2);
#endif

View File

@ -0,0 +1,18 @@
@echo off
rem The name of the loader assembly file (without extension, must be .asm):
set loader_name=loader
rem NASM and DJGPP executable paths:
set nasm_path=C:\nasm
set djgpp_path=C:\DJGPP\bin
set objpath=../../objects
set incpath=../../include
@echo on
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/pit.o pit.c
@echo off
@echo .
@echo Done!
@pause

56
SysCore/hal/pit/pit.c Normal file
View File

@ -0,0 +1,56 @@
#include <system.h>
#include <time.h>
#include "../irq/irq.h"
#include "pit.h"
volatile unsigned int _pit_ticks = 0;
volatile unsigned int _pit_frequency = 0;
unsigned char _pit_init = 0;
volatile TIME _internal_clock;
void i86_pit_set_frequency(int frequency)
{
int divisor = 1193180/frequency; // Calculate the divisor
outportb(0x43, 0x36); // Set our command byte 0x36
outportb(0x40, divisor&0xFF); // Set low byte
outportb(0x40, divisor>>8); // Set high byte
_pit_frequency = frequency;
}
void i86_pit_handler(ISR_stack_regs *r)
{
_pit_ticks++; // count tick
if (_pit_ticks % _pit_frequency == 0)
_CLOCK_INC((TIME*)&_internal_clock); // update internal clock
}
unsigned int i86_pit_set_tick_count(unsigned int i)
{
unsigned int r = _pit_ticks;
_pit_ticks = i;
return r;
}
unsigned int i86_pit_get_tick_count()
{
return _pit_ticks;
}
unsigned int i86_pit_get_frequency()
{
return _pit_frequency;
}
void i86_pit_install(int freq)
{
i86_irq_install_handler(0, i86_pit_handler);
i86_pit_set_frequency(freq);
_pit_ticks = 0;
_pit_init = 1;
}
unsigned char i86_pit_is_initialized()
{
return _pit_init;
}

17
SysCore/hal/pit/pit.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef __PIT_H
#define __PIT_H
#include<regs.h>
extern volatile unsigned int _pit_ticks;
extern volatile unsigned int _pit_frequency;
extern volatile TIME _internal_clock;
extern void i86_pit_handler(ISR_stack_regs *r);
extern void i86_pit_set_frequency(int frequency);
extern unsigned int i86_pit_set_tick_count(unsigned int i);
extern unsigned int i86_pit_get_tick_count();
extern unsigned int i86_pit_get_frequency();
extern void i86_pit_install(int freq);
extern unsigned char i86_pit_is_initialized();
#endif

30
SysCore/include/_null.h Normal file
View File

@ -0,0 +1,30 @@
#ifndef __NULL_H
#define __NULL_H
/******************************
* _null.h *
* - NULL declaration *
******************************/
#if defined (_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#ifdef NULL
#undef NULL
#endif
#ifdef __cplusplus
extern "C"
{
/* standard NULL declaration */
#define NULL 0
}
#else
/* standard NULL declaration */
#define NULL (void*)0
#endif
#endif

View File

@ -0,0 +1,39 @@
#ifndef _BOOTINFO_H
#define _BOOTINFO_H
//****************************************************************************
//** bootinfo.h
//****************************************************************************
#include <stdint.h>
//! multiboot info structure passed from boot loader
typedef struct {
uint32_t m_flags;
uint32_t m_memoryLo;
uint32_t m_memoryHi;
uint32_t m_bootDevice;
uint32_t m_cmdLine;
uint32_t m_modsCount;
uint32_t m_modsAddr;
uint32_t m_syms0;
uint32_t m_syms1;
uint32_t m_syms2;
uint32_t m_mmap_length;
uint32_t m_mmap_addr;
uint32_t m_drives_length;
uint32_t m_drives_addr;
uint32_t m_config_table;
uint32_t m_bootloader_name;
uint32_t m_apm_table;
uint32_t m_vbe_control_info;
uint32_t m_vbe_mode_info;
uint16_t m_vbe_mode;
uint32_t m_vbe_interface_addr;
uint16_t m_vbe_interface_len;
} multiboot_info ;
#endif

9
SysCore/include/cctype Normal file
View File

@ -0,0 +1,9 @@
// cerrno standard header
#ifndef _CSTDCTYPE_
#define _CSTDCTYPE_
#include <ctype.h>
#endif /* _CSTDCTYPE_ */

30
SysCore/include/conio.h Normal file
View File

@ -0,0 +1,30 @@
#ifndef __CONIO_H
#define __CONIO_H
#define _ATTRIB 0x0F
extern byte default_background, default_foreground;
extern char hex[16];
extern void itoa (int value, char *string, unsigned int radix);
extern int printf(const char* str, ...);
extern int abs(int x);
extern void graphics_init();
extern void text_mode_cursor(int x, int y);
extern void set_default_colors(byte back, byte fore);
extern void clrscr();
extern void scroll(int n);
extern void prev_line();
extern void next_line();
extern void putc_pos_font(int x, int y, char c, byte back, byte fore);
extern void putc_pos(int x, int y, char c);
extern void putc_font(char c, byte back, byte fore);
extern void putc(char c);
extern void puts_pos_font(int x, int y, const char *str, byte back, byte fore);
extern void puts_pos(int x, int y, const char *str);
extern void puts(const char *str);
extern void puts_font(const char *str, byte back, byte fore);
extern void put_hex(unsigned int alpha);
extern void put_hex_pos(int x, int y, unsigned int alpha);
extern void put_bin (int x, int y, byte xz);
#endif

50
SysCore/include/crtdefs.h Normal file
View File

@ -0,0 +1,50 @@
#ifndef _CRTDEFS_H
#define _CRTDEFS_H
/******************************
* crtdefs.h *
* - basic definitions *
******************************/
#if !defined (CRT_EXPORTS) && !defined (CRT_IMPORTS)
#define CRT_EXPORTS
#endif
#undef far
#undef near
#undef pascal
#define far
#define near
#ifdef _WIN32
#if (!defined(_MAC)) && ((_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED))
#define pascal __stdcall
#else
#define pascal
#endif
#endif
#ifdef _MAC
#ifndef _CRTLIB
#define _CRTLIB __cdecl
#endif
#ifdef _68K_
#ifndef __pascal
#define __pascal
#endif
#endif
#elif defined( _WIN32)
#if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED)
#ifndef _CRTLIB
#define _CRTLIB __stdcall
#endif
#else
#ifndef _CRTLIB
#define _CRTLIB
#endif
#endif
#endif
#endif

7
SysCore/include/cstdarg Normal file
View File

@ -0,0 +1,7 @@
// cerrno standard header
#ifndef _CSTDARG_
#define _CSTDARG_
#include <stdarg.h>
#endif /* _CSTDARG_ */

9
SysCore/include/cstdint Normal file
View File

@ -0,0 +1,9 @@
// cerrno standard header
#ifndef _CSTDINT_
#define _CSTDINT_
#include <stdint.h>
#endif /* _CSTDINT_ */

9
SysCore/include/cstring Normal file
View File

@ -0,0 +1,9 @@
// cstring standard header
#ifndef _CSTDSTRING_
#define _CSTDSTRING_
#include <string.h>
#endif /* _CSTDINT_ */

55
SysCore/include/ctype.h Normal file
View File

@ -0,0 +1,55 @@
#ifndef __CTYPE_H
#define __CTYPE_H
/******************************
* ctype.h *
* - character macros *
******************************/
#ifdef _MSC_VER
// Get rid of conversion warnings
#pragma warning (disable:4244)
#endif
#ifdef __cplusplus
extern "C"
{
#endif
extern char _ctype[];
/* Constants */
#define CT_UP 0x01 /* upper case */
#define CT_LOW 0x02 /* lower case */
#define CT_DIG 0x04 /* digit */
#define CT_CTL 0x08 /* control */
#define CT_PUN 0x10 /* punctuation */
#define CT_WHT 0x20 /* white space (space/cr/lf/tab) */
#define CT_HEX 0x40 /* hex digit */
#define CT_SP 0x80 /* hard space (0x20) */
/* Basic macros */
#define isalnum(c) ((_ctype + 1)[(unsigned)(c)] & (CT_UP | CT_LOW | CT_DIG))
#define isalpha(c) ((_ctype + 1)[(unsigned)(c)] & (CT_UP | CT_LOW))
#define iscntrl(c) ((_ctype + 1)[(unsigned)(c)] & (CT_CTL))
#define isdigit(c) ((_ctype + 1)[(unsigned)(c)] & (CT_DIG))
#define isgraph(c) ((_ctype + 1)[(unsigned)(c)] & (CT_PUN | CT_UP | CT_LOW | CT_DIG))
#define islower(c) ((_ctype + 1)[(unsigned)(c)] & (CT_LOW))
#define isprint(c) ((_ctype + 1)[(unsigned)(c)] & (CT_PUN | CT_UP | CT_LOW | CT_DIG | CT_SP))
#define ispunct(c) ((_ctype + 1)[(unsigned)(c)] & (CT_PUN))
#define isspace(c) ((_ctype + 1)[(unsigned)(c)] & (CT_WHT))
#define isupper(c) ((_ctype + 1)[(unsigned)(c)] & (CT_UP))
#define isxdigit(c) ((_ctype + 1)[(unsigned)(c)] & (CT_DIG | CT_HEX))
#define isascii(c) ((unsigned)(c) <= 0x7F)
#define toascii(c) ((unsigned)(c) & 0x7F)
#define tolower(c) (isupper(c) ? c + 'a' - 'A' : c)
#define toupper(c) (islower(c) ? c + 'A' - 'a' : c)
#ifdef __cplusplus
}
#endif
#endif

180
SysCore/include/hal.h Normal file
View File

@ -0,0 +1,180 @@
#ifndef _HAL_H
#define _HAL_H
#include <stdint.h>
#include <time.h>
#define far
#define near
#define i86_start_interrupts() __asm__ __volatile__ ("sti");
#define i86_clear_interrupts() __asm__ __volatile__ ("cli");
extern volatile TIME _internal_clock;
// initialize hardware abstraction layer
extern void i86_hal_initialize ();
// shutdown hardware abstraction layer
extern int i86_hal_shutdown ();
//! notifies hal interrupt is done
//extern void interruptdone (unsigned int intno);
//! output sound to speaker
extern void sound (unsigned frequency);
//! read byte from device using port mapped io
//extern unsigned char inportb (unsigned short _port);
//! write byte to device through port mapped io
//extern void outportb (unsigned short _port, unsigned char _data);
//! sets new interrupt vector
//extern void setvect (int intno, void ( far &vect) ( ) );
//! returns current interrupt vector
//extern void ( far * getvect (int intno)) ( );
//! returns cpu vender
extern const char* get_cpu_vender ();
extern void reboot();
/**********************************************************************
* KEYBOARD STUFF *
**********************************************************************/
#define KB_KEY_LSHIFT 0x81 // 1000 0001
#define KB_KEY_RSHIFT 0X82 // 1000 0010
#define KB_KEY_LALT 0X84 // 1000 0100
#define KB_KEY_RALT 0x88 // 1000 1000
#define KB_KEY_LCTRL 0x90 // 1001 0000
#define KB_KEY_RCTRL 0xA0 // 1010 0000
#define KB_KEY_FSHIFT 0xC0 // 1100 0000
extern volatile byte kb_modifier_status;
#define KB_PREFIX_GRAY 0x01 // Gray
#define KB_PREFIX_BREAK 0x02 // Break code
#define KB_PREFIX_PAUSE 0x04 // Pause/break key
#define KB_PREFIX_PAUSE1 0x08 // Recieved first byte from pause/break
extern volatile byte kb_prefix;
#define KB_KEY_SCROLL 0xF1 // 1111 0001
#define KB_KEY_NUM 0xF2 // 1111 0010
#define KB_KEY_CAPS 0xF4 // 1111 0100
extern volatile byte kb_lights_status;
extern byte kb_scancode_set;
#define KB_KEY_PAUSE 0x00
#define KB_KEY_F9 0x01
#define KB_KEY_F7 0x02
#define KB_KEY_F5 0X03
#define KB_KEY_F3 0x04
#define KB_KEY_F1 0x05
#define KB_KEY_F2 0x06
#define KB_KEY_F12 0x07
#define KB_KEY_PRINTSCRN 0x08
#define KB_KEY_F10 0x09
#define KB_KEY_F8 0x0A
#define KB_KEY_F6 0x0B
#define KB_KEY_F4 0x0C
#define KB_KEY_TAB 0x0D
#define KB_KEY_TILDA 0x0E
#define KB_KEY_Q 0x15
#define KB_KEY_1 0x16
#define KB_KEY_Z 0x1A
#define KB_KEY_S 0x1B
#define KB_KEY_A 0x1C
#define KB_KEY_W 0x1D
#define KB_KEY_2 0x1E
#define KB_KEY_LWIN 0x1F
#define KB_KEY_C 0x21
#define KB_KEY_X 0x22
#define KB_KEY_D 0x23
#define KB_KEY_E 0x24
#define KB_KEY_4 0x25
#define KB_KEY_3 0x26
#define KB_KEY_RWIN 0x27
#define KB_KEY_SPACE 0x29
#define KB_KEY_V 0x2A
#define KB_KEY_F 0x2B
#define KB_KEY_T 0x2C
#define KB_KEY_R 0x2D
#define KB_KEY_5 0x2E
#define KB_KEY_MENU 0x2F
#define KB_KEY_N 0x31
#define KB_KEY_B 0x32
#define KB_KEY_H 0x33
#define KB_KEY_G 0x34
#define KB_KEY_Y 0x35
#define KB_KEY_6 0x36
#define KB_KEY_M 0x3A
#define KB_KEY_J 0x3B
#define KB_KEY_U 0x3C
#define KB_KEY_7 0x3D
#define KB_KEY_8 0x3E
#define KB_KEY_COMMA 0x41
#define KB_KEY_K 0x42
#define KB_KEY_I 0x43
#define KB_KEY_O 0x44
#define KB_KEY_0 0x45
#define KB_KEY_9 0x46
#define KB_KEY_PERIOD 0x49
#define KB_KEY_SLASH 0x4A
#define KB_KEY_L 0x4B
#define KB_KEY_SEMICOLON 0x4C
#define KB_KEY_P 0x4D
#define KB_KEY_DASH 0x4E
#define KB_KEY_APOSTROPHE 0x52
#define KB_KEY_LBRACKET 0x54
#define KB_KEY_EQUAL 0x55
#define KB_KEY_NUMPAD_ENTER 0x59
#define KB_KEY_ENTER 0x5A
#define KB_KEY_RBRACKET 0x5B
#define KB_KEY_BACKSLASH 0x5D
#define KB_KEY_END 0x5E
#define KB_KEY_LEFT 0x5F
#define KB_KEY_HOME 0x60
#define KB_KEY_INSERT 0x61
#define KB_KEY_DELETE 0x62
#define KB_KEY_DOWN 0x63
#define KB_KEY_RIGHT 0x64
#define KB_KEY_UP 0x65
#define KB_KEY_BACKSPACE 0x66
#define KB_KEY_PGDOWN 0x67
#define KB_KEY_PGUP 0x68
#define KB_KEY_NUMPAD_1 0x69
#define KB_KEY_NUMPAD_SLASH 0x6A
#define KB_KEY_NUMPAD_4 0x6B
#define KB_KEY_NUMPAD_7 0x6C
#define KB_KEY_NUMPAD_0 0x70
#define KB_KEY_NUMPAD_COLON 0x71
#define KB_KEY_NUMPAD_2 0x72
#define KB_KEY_NUMPAD_5 0x73
#define KB_KEY_NUMPAD_6 0x74
#define KB_KEY_NUMPAD_8 0x75
#define KB_KEY_ESC 0x76
#define KB_KEY_F11 0x78
#define KB_KEY_NUMPAD_PLUS 0x79
#define KB_KEY_NUMPAD_3 0x7A
#define KB_KEY_NUMPAD_MINUS 0x7B
#define KB_KEY_NUMPAD_ASTERISK 0x7C
#define KB_KEY_NUMPAD_9 0x7D
typedef struct {
byte status;
byte lights;
byte scancode;
byte character;
} kb_key;
extern char getch();
extern kb_key getkey();
extern char scancode_to_ascii(byte scancode, byte status);
extern byte get_key_status(byte scancode);
extern void kb_set_repeat(float rate, int delay);
extern void kb_set_LEDs(byte status);
#endif

100
SysCore/include/regs.h Normal file
View File

@ -0,0 +1,100 @@
#ifndef _REGS_H_INCLUDED
#define _REGS_H_INCLUDED
//****************************************************************************
//**
//** regs.h
//**
//** processor register structures and declarations. This interface abstracts
//** register names behind a common, portable interface
//**
//****************************************************************************
//============================================================================
// INTERFACE REQUIRED HEADERS
//============================================================================
#include <stdint.h>
//============================================================================
// INTERFACE DEFINITIONS / ENUMERATIONS / SIMPLE TYPEDEFS
//============================================================================
//============================================================================
// INTERFACE CLASS PROTOTYPES / EXTERNAL CLASS REFERENCES
//============================================================================
//============================================================================
// INTERFACE STRUCTURES / UTILITY CLASSES
//============================================================================
//! 32 bit registers
typedef struct {
uint32_t eax, ebx, ecx, edx, esi, edi, ebp, esp, eflags;
uint8_t cflag;
} _R32BIT;
//! 16 bit registers
typedef struct {
uint16_t ax, bx, cx, dx, si, di, bp, sp, es, cs, ss, ds, flags;
uint8_t cflag;
} _R16BIT ;
//! 16 bit registers expressed in 32 bit registers
typedef struct {
uint16_t ax, axh, bx, bxh, cx, cxh, dx, dxh;
uint16_t si, di, bp, sp, es, cs, ss, ds, flags;
uint8_t cflags;
} _R16BIT32 ;
//! 8 bit registers
typedef struct {
uint8_t al, ah, bl, bh, cl, ch, dl, dh;
} _R8BIT;
//! 8 bit registers expressed in 32 bit registers
typedef struct {
uint8_t al, ah; uint16_t axh;
uint8_t bl, bh; uint16_t bxh;
uint8_t cl, ch; uint16_t cxh;
uint8_t dl, dh; uint16_t dxh;
} _R8BIT32;
//! 8 and 16 bit registers union
typedef union {
_R16BIT x;
_R8BIT h;
}_INTR16;
//! 32 bit, 16 bit and 8 bit registers union
typedef union {
_R32BIT x;
_R16BIT32 l;
_R8BIT32 h;
} _INTR32;
/* This defines what the stack looks like after an ISR was running */
typedef struct
{
unsigned int gs, fs, es, ds; /* pushed the segs last */
unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax; /* pushed by 'pusha' */
unsigned int int_no, err_code; /* our 'push byte #' and ecodes do this */
unsigned int eip, cs, eflags, useresp, ss; /* pushed by the processor automatically */
} ISR_stack_regs;
//============================================================================
// INTERFACE DATA DECLARATIONS
//============================================================================
//============================================================================
// INTERFACE FUNCTION PROTOTYPES
//============================================================================
//============================================================================
// INTERFACE OBJECT CLASS DEFINITIONS
//============================================================================
//============================================================================
// INTERFACE TRAILING HEADERS
//============================================================================
//****************************************************************************
//**
//** END regs.h
//**
//****************************************************************************
#endif

23
SysCore/include/size_t.h Normal file
View File

@ -0,0 +1,23 @@
#ifndef __SIZE_T_H
#define __SIZE_T_H
/************************************
* size_t.h *
* - Standard C/C++ size_t type *
************************************/
#ifdef __cplusplus
extern "C"
{
#endif
/* standard size_t type */
typedef unsigned size_t;
#ifdef __cplusplus
}
#endif
#endif

46
SysCore/include/stdarg.h Normal file
View File

@ -0,0 +1,46 @@
#ifndef __STDARG_H
#define __STDARG_H
/******************************
* [filename] *
* - [description] *
******************************/
// INTERFACE REQUIRED HEADERS
#include <va_list.h>
// INTERFACE DEFINITIONS / ENUMERATIONS / SIMPLE TYPEDEFS
#ifdef __cplusplus
extern "C"
{
#endif
/* width of stack == width of int */
#define STACKITEM int
/* round up width of objects pushed on stack. The expression before the
& ensures that we get 0 for objects of size 0. */
#define VA_SIZE(TYPE) \
((sizeof(TYPE) + sizeof(STACKITEM) - 1) \
& ~(sizeof(STACKITEM) - 1))
/* &(LASTARG) points to the LEFTMOST argument of the function call
(before the ...) */
#define va_start(AP, LASTARG) \
(AP=((va_list)&(LASTARG) + VA_SIZE(LASTARG)))
/* nothing for va_end */
#define va_end(AP)
#define va_arg(AP, TYPE) \
(AP += VA_SIZE(TYPE), *((TYPE *)(AP - VA_SIZE(TYPE))))
#ifdef __cplusplus
}
#endif
#endif

163
SysCore/include/stdint.h Normal file
View File

@ -0,0 +1,163 @@
#ifndef _STDINT_H
#define _STDINT_H
#define __need_wint_t
#define __need_wchar_t
/***************************************
* stdint.h *
* - Standard C++ integral types *
***************************************/
/* 7.18.1.1 Exact-width integer types */
typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef short int16_t;
typedef unsigned short uint16_t;
typedef int int32_t;
typedef unsigned uint32_t;
typedef long long int64_t;
typedef unsigned long long uint64_t;
/* 7.18.1.2 Minimum-width integer types */
typedef signed char int_least8_t;
typedef unsigned char uint_least8_t;
typedef short int_least16_t;
typedef unsigned short uint_least16_t;
typedef int int_least32_t;
typedef unsigned uint_least32_t;
typedef long long int_least64_t;
typedef unsigned long long uint_least64_t;
/* 7.18.1.3 Fastest minimum-width integer types
* Not actually guaranteed to be fastest for all purposes
* Here we use the exact-width types for 8 and 16-bit ints.
*/
typedef char int_fast8_t;
typedef unsigned char uint_fast8_t;
typedef short int_fast16_t;
typedef unsigned short uint_fast16_t;
typedef int int_fast32_t;
typedef unsigned int uint_fast32_t;
typedef long long int_fast64_t;
typedef unsigned long long uint_fast64_t;
/* 7.18.1.4 Integer types capable of holding object pointers */
typedef int intptr_t;
typedef unsigned uintptr_t;
/* 7.18.1.5 Greatest-width integer types */
typedef long long intmax_t;
typedef unsigned long long uintmax_t;
/* 7.18.2 Limits of specified-width integer types */
#if !defined ( __cplusplus) || defined (__STDC_LIMIT_MACROS)
/* 7.18.2.1 Limits of exact-width integer types */
#define INT8_MIN (-128)
#define INT16_MIN (-32768)
#define INT32_MIN (-2147483647 - 1)
#define INT64_MIN (-9223372036854775807LL - 1)
#define INT8_MAX 127
#define INT16_MAX 32767
#define INT32_MAX 2147483647
#define INT64_MAX 9223372036854775807LL
#define UINT8_MAX 0xff /* 255U */
#define UINT16_MAX 0xffff /* 65535U */
#define UINT32_MAX 0xffffffff /* 4294967295U */
#define UINT64_MAX 0xffffffffffffffffULL /* 18446744073709551615ULL */
/* 7.18.2.2 Limits of minimum-width integer types */
#define INT_LEAST8_MIN INT8_MIN
#define INT_LEAST16_MIN INT16_MIN
#define INT_LEAST32_MIN INT32_MIN
#define INT_LEAST64_MIN INT64_MIN
#define INT_LEAST8_MAX INT8_MAX
#define INT_LEAST16_MAX INT16_MAX
#define INT_LEAST32_MAX INT32_MAX
#define INT_LEAST64_MAX INT64_MAX
#define UINT_LEAST8_MAX UINT8_MAX
#define UINT_LEAST16_MAX UINT16_MAX
#define UINT_LEAST32_MAX UINT32_MAX
#define UINT_LEAST64_MAX UINT64_MAX
/* 7.18.2.3 Limits of fastest minimum-width integer types */
#define INT_FAST8_MIN INT8_MIN
#define INT_FAST16_MIN INT16_MIN
#define INT_FAST32_MIN INT32_MIN
#define INT_FAST64_MIN INT64_MIN
#define INT_FAST8_MAX INT8_MAX
#define INT_FAST16_MAX INT16_MAX
#define INT_FAST32_MAX INT32_MAX
#define INT_FAST64_MAX INT64_MAX
#define UINT_FAST8_MAX UINT8_MAX
#define UINT_FAST16_MAX UINT16_MAX
#define UINT_FAST32_MAX UINT32_MAX
#define UINT_FAST64_MAX UINT64_MAX
/* 7.18.2.4 Limits of integer types capable of holding
object pointers */
#define INTPTR_MIN INT32_MIN
#define INTPTR_MAX INT32_MAX
#define UINTPTR_MAX UINT32_MAX
/* 7.18.2.5 Limits of greatest-width integer types */
#define INTMAX_MIN INT64_MIN
#define INTMAX_MAX INT64_MAX
#define UINTMAX_MAX UINT64_MAX
/* 7.18.3 Limits of other integer types */
#define PTRDIFF_MIN INT32_MIN
#define PTRDIFF_MAX INT32_MAX
#define SIG_ATOMIC_MIN INT32_MIN
#define SIG_ATOMIC_MAX INT32_MAX
#define SIZE_MAX UINT32_MAX
#ifndef WCHAR_MIN /* also in wchar.h */
#define WCHAR_MIN 0
#define WCHAR_MAX ((wchar_t)-1) /* UINT16_MAX */
#endif
/*
* wint_t is unsigned short for compatibility with MS runtime
*/
#define WINT_MIN 0
#define WINT_MAX ((wint_t)-1) /* UINT16_MAX */
#endif /* !defined ( __cplusplus) || defined __STDC_LIMIT_MACROS */
/* 7.18.4 Macros for integer constants */
#if !defined ( __cplusplus) || defined (__STDC_CONSTANT_MACROS)
/* 7.18.4.1 Macros for minimum-width integer constants */
#define INT8_C(val) ((int8_t) + (val))
#define UINT8_C(val) ((uint8_t) + (val##U))
#define INT16_C(val) ((int16_t) + (val))
#define UINT16_C(val) ((uint16_t) + (val##U))
#define INT32_C(val) val##L
#define UINT32_C(val) val##UL
#define INT64_C(val) val##LL
#define UINT64_C(val) val##ULL
/* 7.18.4.2 Macros for greatest-width integer constants */
#define INTMAX_C(val) INT64_C(val)
#define UINTMAX_C(val) UINT64_C(val)
#endif /* !defined ( __cplusplus) || defined __STDC_CONSTANT_MACROS */
#endif

46
SysCore/include/string.h Normal file
View File

@ -0,0 +1,46 @@
#ifndef _STRING_H
#define _STRING_H
//****************************************************************************
//**
//** [string.h]
//** - Standard C String routines
//**
//****************************************************************************
//============================================================================
// INTERFACE REQUIRED HEADERS
//============================================================================
#include <size_t.h>
//============================================================================
// INTERFACE DEFINITIONS / ENUMERATIONS / SIMPLE TYPEDEFS
//============================================================================
//============================================================================
// INTERFACE CLASS PROTOTYPES / EXTERNAL CLASS REFERENCES
//============================================================================
//============================================================================
// INTERFACE STRUCTURES / UTILITY CLASSES
//============================================================================
//============================================================================
// INTERFACE DATA DECLARATIONS
//============================================================================
//============================================================================
// INTERFACE FUNCTION PROTOTYPES
//============================================================================
extern size_t strlen (const char *str);
extern int strcmp(const char *pStr1, const char *pStr2);
//============================================================================
// INTERFACE OBJECT CLASS DEFINITIONS
//============================================================================
//============================================================================
// INTERFACE TRAILING HEADERS
//============================================================================
//****************************************************************************
//**
//** END [string.h]
//**
//****************************************************************************
#endif

View File

@ -0,0 +1,21 @@
#ifndef __DECLARAT_H
#define __DECLARAT_H
// Data type declarations
typedef unsigned char byte;
typedef unsigned short word;
typedef unsigned int dword;
// Functions
void system_init();
void isrs_install();
void irq_install_handler(int irq, void (*handler)(ISR_stack_regs *r));
void irq_uninstall_handler(int irq);
void irq_install();
void kb_handler(ISR_stack_regs *r);
void reboot();
void kb_waitin();
#endif

40
SysCore/include/system.h Normal file
View File

@ -0,0 +1,40 @@
/*******************************************************************
* system.c - Basic system functions and variables declaration *
*******************************************************************/
#ifndef __SYSTEM_H
#define __SYSTEM_H
#include <regs.h>
#define true 1
#define false 0
// Data type declarations
typedef unsigned char byte;
typedef unsigned short word;
typedef unsigned int dword;
extern byte *TextVideoRam;
extern volatile int cursor_x, cursor_y;
extern int current_mode_width;
extern int current_mode_height;
extern void *memcpy(void *dest, const void *src, int count);
extern void *memset(void *dest, char val, int count);
extern unsigned short *memsetw(unsigned short *dest, unsigned short val, int count);
extern byte inportb (word _port);
extern byte inb (word _port);
static inline void outportb (word _port, byte _data) {
__asm__ __volatile__ ("outb %1, %0" : : "dN" (_port), "a" (_data));
}
static inline void outb (word _port, byte _data) {
__asm__ __volatile__ ("outb %1, %0" : : "dN" (_port), "a" (_data));
}
static inline void iowait() {
asm volatile ("outb %al, $0x80");
}
#endif

25
SysCore/include/time.h Normal file
View File

@ -0,0 +1,25 @@
#ifndef __TIME_C
#define __TIME_C
extern const char* clock_months[13];
extern const char* clock_weekdays[8];
extern byte clock_months_len[13];
typedef struct {
byte seconds;
byte minutes;
byte hours;
byte weekday;
byte day;
byte month;
byte year;
byte century;
byte am_pm;
} TIME;
extern void _CLOCK_INC(TIME *tim);
//extern char* asctime (TIME time);
#endif

52
SysCore/include/va_list.h Normal file
View File

@ -0,0 +1,52 @@
#ifndef __VA_LIST_H
#define __VA_LIST_H
//****************************************************************************
//**
//** va_list.h
//** - varable length parameter definition
//**
//****************************************************************************
//============================================================================
// INTERFACE REQUIRED HEADERS
//============================================================================
//============================================================================
// INTERFACE DEFINITIONS / ENUMERATIONS / SIMPLE TYPEDEFS
//============================================================================
#ifdef __cplusplus
extern "C"
{
#endif
/* va list parameter list */
typedef unsigned char *va_list;
#ifdef __cplusplus
}
#endif
//============================================================================
// INTERFACE CLASS PROTOTYPES / EXTERNAL CLASS REFERENCES
//============================================================================
//============================================================================
// INTERFACE STRUCTURES / UTILITY CLASSES
//============================================================================
//============================================================================
// INTERFACE DATA DECLARATIONS
//============================================================================
//============================================================================
// INTERFACE FUNCTION PROTOTYPES
//============================================================================
//============================================================================
// INTERFACE OBJECT CLASS DEFINITIONS
//============================================================================
//============================================================================
// INTERFACE TRAILING HEADERS
//============================================================================
//****************************************************************************
//**
//** END va_list.h
//**
//****************************************************************************
#endif

40
SysCore/lib/compile.bat Normal file
View File

@ -0,0 +1,40 @@
@echo off
rem NASM and DJGPP executable paths:
set nasm_path=C:\nasm
set djgpp_path=C:\DJGPP\bin
set objpath=..\objects
set incpath=../include
@echo Building Kernel Standard Libraries...
del %objpath%\system.o
del %objpath%\string.o
del %objpath%\conio.o
del %objpath%\time.o
goto build
:error
@echo.
@echo There have been build errors. Building halted.
@pause
exit
:build
@echo * Compiling SYSTEM.C ...
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/system.o system.c
@echo * Compiling STRING.C ...
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/string.o string.c
@echo * Compiling CONIO.C ...
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/conio.o conio.c
@echo * Compiling TIME.C ...
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/time.o time.c
:check
if not exist %objpath%\system.o goto error
if not exist %objpath%\string.o goto error
if not exist %objpath%\conio.o goto error
if not exist %objpath%\time.o goto error

View File

@ -1,12 +1,32 @@
#include <stdarg.h>
#include <stdint.h>
#include <string.h>
#include <system.h>
#ifndef __CONIO_H
#define __CONIO_H
#define _ATTRIB 0x0F
#include <conio.h>
byte default_background, default_foreground;
char hex[] = "0123456789ABCDEF";
const static char base_chars[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int abs(int x)
{
return (x>0) ? (x) : (x*-1);
}
void graphics_init()
{
// Detect if color/monochrome screen
char c = (*(volatile unsigned short*)0x410)&0x30;
if (c==0x30) TextVideoRam = (byte *)0xb0000;
else TextVideoRam = (byte *)0xb8000;
// Reset cursor, use 80x25 text video mode
current_mode_width = 80;
current_mode_height = 25;
cursor_x = cursor_y = 0;
}
// Change cursor position
@ -101,12 +121,55 @@ void putc(char c)
if (cursor_x >= current_mode_width) next_line();
if (c == '\n') {next_line(); return;};
if (c == '\r') {cursor_x = 0; return; };
TextVideoRam[2*(cursor_y*current_mode_width+cursor_x)] = c;
cursor_x++;
}
// Unsigned INT to ASCII
void uitoa (unsigned int value, char *string, int radix)
{
if (radix == 1 || radix>36) return;
// Calculate how much space needed for number
int len, temp = abs(value);
for (len = 0; temp > 0; len++) temp/=radix;
if (len == 0) len = 1;
string[len] = 0;
for (len--; len >=0; len-- ) {
string[len] = base_chars[value%radix];
value/=radix;
}
}
// Signed INT to ASCII
void itoa (int value, char *string, unsigned int radix)
{
if (radix < 2 || radix>36) return;
// Calculate how much space needed for number
int len, temp = abs(value);
for (len = 0; temp > 0; len++) temp/=radix;
if (len == 0) len = 1;
//Add a space for '-'
if (value<0) {
len++; string[0] = '-';
value = abs(value);
}
string[len] = 0;
for (len--; len >0; len-- ) {
string[len] = base_chars[value%radix];
value/=radix;
}
}
// Put string on screen in specified position; can use different font colors
void puts_pos_font(int x, int y, char *str, byte back, byte fore)
void puts_pos_font(int x, int y, const char *str, byte back, byte fore)
{
int i;
for (i = 0; str[i] != 0; i++)
@ -115,20 +178,20 @@ void puts_pos_font(int x, int y, char *str, byte back, byte fore)
}
// Put string on screen in specified position; use default font colors
void puts_pos(int x, int y, char *str)
void puts_pos(int x, int y, const char *str)
{
int i;
for (i = 0; str[i] != 0; i++)
putc_pos(x+i, y, str[i]);
}
void puts(char *str)
void puts(const char *str)
{
int i;
for (i = 0; str[i] != 0; i++)
putc(str[i]);
}
void puts_font(char *str, byte back, byte fore)
void puts_font(const char *str, byte back, byte fore)
{
int i;
for (i = 0; str[i] != 0; i++)
@ -167,6 +230,55 @@ void put_bin (int x, int y, byte xz)
}
puts_pos (x, y, arr);
}
int printf(const char* str, ...)
{
if (!str) return 0;
#endif
va_list args;
va_start (args, str);
size_t i, len = strlen(str);
for (i = 0; i < len; i++)
switch (str[i]) {
case '%':
switch (str[i+1]) {
// Character
case 'c': {char c = va_arg (args, char);
putc(c); i++; break;}
// String
case 's': {int* c = (int*) va_arg (args, char*);
puts((const char*)c); i++; break;}
// Integers
case 'd':
case 'i': {int c = va_arg(args, int);
char temp[32];
itoa(c, temp, 10);
puts(temp);
i++; break;}
// Integers - hex
case 'X':
case 'x': {int c = va_arg(args, int);
char temp[32];
uitoa(c, temp, 16);
puts(temp);
i++; break;}
// Integers - unsigned
case 'u': { int c = va_arg(args, unsigned int);
char temp[32];
uitoa(c, temp, 10);
puts(temp);
i++; break;
}
default: va_end(args); return 1;
};
break;
default: putc(str[i]); break;
}
va_end(args);
return i;
}

23
SysCore/lib/string.c Normal file
View File

@ -0,0 +1,23 @@
#include <string.h>
size_t strlen (const char *str)
{
size_t i;
for (i = 0; *str!=0; str++) i++;
return i;
}
int strcmp(const char *pStr1, const char *pStr2)
{
char c1, c2;
int v;
do {
c1 = *pStr1++;
c2 = *pStr2++;
/* the casts are necessary when pStr1 is shorter & char is signed */
v = (unsigned int)c1 - (unsigned int)c2;
} while ((v == 0) && (c1 != '\0'));
return v;
}

44
SysCore/lib/system.c Normal file
View File

@ -0,0 +1,44 @@
/******************************************************************
* system.c - Basic system functions *
******************************************************************/
#include <system.h>
byte *TextVideoRam;
volatile int cursor_x, cursor_y;
int current_mode_width;
int current_mode_height;
void *memcpy(void *dest, const void *src, int count)
{
const char *sp = (const char *)src;
char *dp = (char *)dest;
for(; count != 0; count--) *dp++ = *sp++;
return dest;
}
void *memset(void *dest, char val, int count)
{
char *temp = (char *)dest;
for( ; count != 0; count--) *temp++ = val;
return dest;
}
unsigned short *memsetw(unsigned short *dest, unsigned short val, int count)
{
unsigned short *temp = (unsigned short *)dest;
for( ; count != 0; count--) *temp++ = val;
return dest;
}
byte inportb (word _port) {
byte rv;
__asm__ __volatile__ ("inb %1, %0" : "=a" (rv) : "dN" (_port));
return rv;
}
byte inb (word _port) {
byte rv;
__asm__ __volatile__ ("inb %1, %0" : "=a" (rv) : "dN" (_port));
return rv;
}

80
SysCore/lib/time.c Normal file
View File

@ -0,0 +1,80 @@
#include <system.h>
#include <time.h>
const char* clock_months[] = {0,
"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"};
const char* clock_weekdays[] = {0,
"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
byte clock_months_len[] = {
0,
31, // January
28, // February
31, // March
30, // April
31, // May
30, // June
31, // July
31, // August
30, // September
31, // October
30, // November
31 // December
};
void _CLOCK_INC(TIME *tim)
{
// New minute
if (++tim->seconds > 59) {
tim->seconds = 0;
// New hour
if (++tim->minutes > 59) {
tim->minutes = 0;
tim->hours++;
if (tim->hours == 12 && tim->am_pm == 1) { // 11:59pm -> 0:00am
tim->hours = 0; tim->am_pm = 0;
// New day
tim->weekday = 1+(tim->weekday%7);
// Leap years
if ((tim->day==28) && (tim->month==2)) { tim->day++; return; }
// New month
if (++tim->day > clock_months_len[tim->month]) {
tim->day = 1;
// New year
if (++tim->month>12) {
tim->month = 1;
// New century
if (++tim->year > 99) { tim->year = 0; tim->century++;}
}
}
}
else if (tim->hours == 12 && tim->am_pm == 0) tim->am_pm = 1; // 11:59am -> 12:00pm
else if (tim->hours == 13 && tim->am_pm == 1) tim->hours = 1; // 12:59pm -> 1:59pm
}
}
}
/* ASCTIME Formats: ****************************************************************
* 1 W = weekday, M = month, D = day, H = Hour, M = Minute, S = Second, Y = year) *
* A = AM/PM *
* 2 Use capital letter for one letter/digit; else, use lower *
* *
* Example: asctime (time, "Today is: %W3 %D2 %m") *
* Result: Today is: Mon 22 June *
************************************************************************************/
/*char* asctime (TIME time, char* format)
{
char str[100];
int l = strlen(format), i;
byte special = 0;
for (i=0; i<l-1 && i<100; i++) {
if (format[i] == '%') switch (format[i+1]) {
case 'W':
}*/

26
SysCore/loader.asm Normal file
View File

@ -0,0 +1,26 @@
bits 32
global start
start: jmp stub
stub: cmp eax, 0x2badb002
jne .bad
mov ax, 10h
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
extern _k_main
call _k_main
.bad:
cli
hlt
SECTION .bss
resb 8192 ; This reserves 8KBytes of memory here

71
SysCore/main.c Normal file
View File

@ -0,0 +1,71 @@
#include <string.h>
#include <system.h>
#include <conio.h>
#include <hal.h>
#include <time.h>
#include <bootinfo.h>
#include "memory/mmngr_ph.h"
#include "shell/shell.c"
//! format of a memory region
typedef struct {
uint32_t startLo;
uint32_t startHi;
uint32_t sizeLo;
uint32_t sizeHi;
uint32_t type;
uint32_t acpi_3_0;
} memory_region ;
//! different memory regions (in memory_region.type)
char* strMemoryTypes[] = {
"",
"Available", //memory_region.type==0
"Reserved", //memory_region.type==1
"ACPI Reclaim", //memory_region.type==2
"ACPI NVS Memory" //memory_region.type==3
};
extern dword _code;
extern dword _data;
extern dword _bss;
extern dword _end;
void k_init(multiboot_info* bootinfo)
{
// Start by zero-ing the bss
memset(&_bss, 0, &_end - &_bss);
// Initialize HAL
i86_hal_initialize();
// Initialize Graphics
graphics_init();
// cleanup the console screen
set_default_colors (0x07, 0x04);
clrscr();
// Start memory manager
uint32_t memSize = 1024 + bootinfo->m_memoryLo + bootinfo->m_memoryHi*64;
memory_region* memMap = (memory_region*)0x1000;
pmmngr_init (memSize, (uint32_t)&_end);
unsigned int i;
for (i=0; (memMap[i].sizeHi != 0 || memMap[i].sizeLo != 0) && i<3; ++i)
if (memMap[i].type==1) pmmngr_init_region (memMap[i].startLo, memMap[i].sizeLo);
}
void k_main(uint32_t kernel_size, multiboot_info* bootinfo)
{
k_init(bootinfo);
apps_osver();
shell();
for(;;);
}

59
SysCore/makeall.bat Normal file
View File

@ -0,0 +1,59 @@
@echo off
set loader_name=loader
set nasm_path=C:\nasm
set djgpp_path=C:\DJGPP\bin
@echo ***************** CTA KERNEL *****************
goto KernelEntry
:error
@echo.
@echo There have been build errors. Building halted.
@pause
exit
:KernelEntry
del objects\%loader_name%.o
del objects\main.o
@echo.
@echo Building Kernel entry...
@echo * Compiling kernel loader...
%nasm_path%\nasm.exe -f aout -o ./objects/%loader_name%.o %loader_name%.asm
@echo * Compiling kernel main...
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I./include -c -o ./objects/main.o main.c
if not exist objects\%loader_name%.o goto error
if not exist objects\main.o goto error
@echo.
:KernelSTDLIB
cd lib
rem call compile.bat
cd..
:KernelMemoryManager
cd memory
call compile.bat
cd..
rem here go other sources:
rem here go other sources ^
:Finish
cd objects
@echo Linking...
del kernel.bin
%djgpp_path%\ld -T link.ld
if not exist kernel.bin goto error
@echo.
echo Copying to floppy drive...
copy KERNEL.BIN A:\KERNEL.CTA >nul
cd..

66
SysCore/makeallh.bat Normal file
View File

@ -0,0 +1,66 @@
@echo off
set loader_name=loader
set nasm_path=C:\nasm
set djgpp_path=C:\DJGPP\bin
@echo ***************** CTA KERNEL *****************
goto KernelEntry
:error
@echo.
@echo There have been build errors. Building halted.
@pause
exit
:KernelEntry
del objects\%loader_name%.o
del objects\main.o
@echo.
@echo Building Kernel entry...
@echo * Compiling kernel loader...
%nasm_path%\nasm.exe -f aout -o ./objects/%loader_name%.o %loader_name%.asm
@echo * Compiling kernel main...
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I./include -c -o ./objects/main.o main.c
if not exist objects\%loader_name%.o goto error
if not exist objects\main.o goto error
@echo.
:KernelSTDLIB
cd lib
call compile.bat
@echo.
cd..
:KernelMemoryManager
cd memory
call compile.bat
@echo.
cd..
:KernelHAL
cd hal
call makeall.bat
cd..
rem here go other sources:
rem here go other sources ^
:Finish
cd objects
@echo Linking...
del kernel.bin
%djgpp_path%\ld -T link.ld
if not exist kernel.bin goto error
@echo.
echo Copying to floppy drive...
copy KERNEL.BIN A:\KERNEL.CTA >nul
cd..

View File

@ -0,0 +1,28 @@
@echo off
rem NASM and DJGPP executable paths:
set nasm_path=C:\nasm
set djgpp_path=C:\DJGPP\bin
set objpath=..\objects
set incpath=../include
goto build
:error
@echo.
@echo There have been build errors. Building halted.
@pause
exit
:build
@echo Building Memory Manager...
del %objpath%\mmngr_cr.o
del %objpath%\mmngr_ph.o
@echo * Compiling Physical Memory Manager...
%nasm_path%\nasm.exe -f aout -o %objpath%/mmngr_cr.o mmngr_cr.asm
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/mmngr_ph.o mmngr_ph.c
:check
if not exist %objpath%\mmngr_cr.o goto error
if not exist %objpath%\mmngr_ph.o goto error

View File

@ -0,0 +1,29 @@
bits 32
global _read_cr0
_read_cr0:
mov eax, cr0
retn
global _write_cr0
_write_cr0:
push ebp
mov ebp, esp
mov eax, [ebp+8]
mov cr0, eax
pop ebp
retn
global _read_cr3
_read_cr3:
mov eax, cr3
retn
global _write_cr3
_write_cr3:
push ebp
mov ebp, esp
mov eax, [ebp+8]
mov cr3, eax
pop ebp
retn

204
SysCore/memory/mmngr_ph.c Normal file
View File

@ -0,0 +1,204 @@
/******************************************************
* Physical Memory Manager *
******************************************************/
#include <system.h>
#include <string.h>
#include "mmngr_ph.h"
#define PMMNGR_BLOCK_SIZE 4096 // block size (4k)
#define PMMNGR_BLOCK_ALIGN PMMNGR_BLOCK_SIZE // block alignment
struct memory_stack_entry{
word low;
byte high;
} __attribute__ ((__packed__));
typedef struct memory_stack_entry mstack;
static uint32_t _mmngr_memory_size=0; // size of physical memory
static uint32_t _mmngr_used_blocks=0; // number of blocks currently in use
static uint32_t _mmngr_max_blocks=0; // maximum number of available memory blocks
static uint32_t _mmngr_index = 0;
static mstack* _mmngr_memory_stack= 0; // memory stack
inline mstack mstack_pop ()
{
mstack temp;
temp.low = _mmngr_memory_stack[--_mmngr_index].low;
temp.high = _mmngr_memory_stack[_mmngr_index].high;
_mmngr_used_blocks++;
_mmngr_memory_stack[_mmngr_index].low = 0xFFFF;
_mmngr_memory_stack[_mmngr_index].high = 0xFF;
return temp;
}
inline void mstack_push (const mstack *block)
{
if (block->low == 0 && block-> high == 0) return;
_mmngr_memory_stack[_mmngr_index].low = block->low;
_mmngr_memory_stack[_mmngr_index].high = block->high;
_mmngr_index++;
_mmngr_used_blocks--;
}
inline byte mstack_test (const mstack *block)
{
uint32_t i;
for (i = 0; i < _mmngr_index; i++)
if (_mmngr_memory_stack[i].low == block->low && _mmngr_memory_stack[i].high == block->high) return 1;
return 0;
}
byte pmmngr_test_block (uint32_t block)
{
mstack temp;
temp.low = block & 0xFFFF;
temp.high = (block>>16) & 0xFF;
return mstack_test(&temp);
}
void pmmngr_free_block(void* address)
{
// Calculate block
mstack block;
uint32_t temp = (uint32_t)address / PMMNGR_BLOCK_SIZE;
block.low = temp & 0xFFFF;
block.high = (temp>>16) & 0xFF;
// Push it
mstack_push (&block);
}
void* pmmngr_alloc_block()
{
if (_mmngr_index == 0) return 0;// Out of memory
// pop a block
mstack block = mstack_pop();
// Calculate and return address;
void* address;
uint32_t temp = block.low | (block.high<<16);
address = (void *)(temp * PMMNGR_BLOCK_SIZE);
return address;
}
void pmmngr_init (size_t memSize, uint32_t stack) {
_mmngr_memory_size = memSize;
_mmngr_memory_stack = (mstack*) stack;
_mmngr_max_blocks = (_mmngr_memory_size*1024) / PMMNGR_BLOCK_SIZE;
_mmngr_used_blocks = _mmngr_max_blocks;
_mmngr_index = 0;
// By default, all of memory is in use
}
void pmmngr_init_region (physical_addr base, size_t size) {
mstack block;
unsigned int count = size / PMMNGR_BLOCK_SIZE;
unsigned int start = base / PMMNGR_BLOCK_SIZE;
for (; count!=0; count--) {
block.low = (start + count) & 0xFFFF;
block.high = ((start + count) << 16) & 0xFF;
mstack_push(&block);
}
}
void pmmngr_deinit_region (physical_addr base, size_t size) {
unsigned int start = base / PMMNGR_BLOCK_SIZE;
unsigned int count = size / PMMNGR_BLOCK_SIZE;
int temp;
unsigned int i;
unsigned int j;
// Find free blocks in the area and zero them
for (i = 0; i < _mmngr_index; i++) {
temp = (_mmngr_memory_stack[i].high << 16) | _mmngr_memory_stack[i].low;
if (temp >=start && temp < start+count)
{ _mmngr_memory_stack[i].high = 0;
_mmngr_memory_stack[i].low = 0;
}
}
// Eliminate zero blocks
for (i = 0; i<_mmngr_index; i++)
if (_mmngr_memory_stack[i].high == 0 && _mmngr_memory_stack[i].low == 0)
{
// Find next non-zero
for (j = i; _mmngr_memory_stack[j].high == 0 && _mmngr_memory_stack[j].low == 0; j++)
if (j == _mmngr_index-1) {
j = 0; break; }
if (j == 0) {
_mmngr_index = i;
break;
}
_mmngr_memory_stack[i].high = _mmngr_memory_stack[j].high;
_mmngr_memory_stack[i].low = _mmngr_memory_stack[j].low;
_mmngr_memory_stack[j].high = 0;
_mmngr_memory_stack[j].low = 0;
}
}
size_t pmmngr_get_memory_size () {
return _mmngr_memory_size;
}
uint32_t pmmngr_get_block_count () {
return _mmngr_max_blocks;
}
uint32_t pmmngr_get_use_block_count () {
return _mmngr_used_blocks;
}
uint32_t pmmngr_get_free_block_count () {
return _mmngr_index;
}
uint32_t pmmngr_get_block_size () {
return PMMNGR_BLOCK_SIZE;
}
void pmmngr_paging_enable (byte b) {
uint32_t temp;
temp = read_cr0();
// Enable
if (b) temp |= 0x80000000;
else temp &= ~0x80000000;
write_cr0(temp);
}
byte pmmngr_is_paging () {
uint32_t temp = read_cr0();
return ((temp&0x80000000)>0);
}
mstack* pmmngr_get_stack_addr()
{
return _mmngr_memory_stack;
}

33
SysCore/memory/mmngr_ph.h Normal file
View File

@ -0,0 +1,33 @@
#ifndef _MMNGR_PHYS_H
#define _MMNGR_PHYS_H
#include <stdint.h>
#include <system.h>
#define pmmngr_load_PDBR(addr) write_cr3(addr)
#define pmmngr_get_PDBR() read_cr3()
// physical address
typedef unsigned physical_addr;
extern uint32_t read_cr0();
extern uint32_t read_cr3();
extern void write_cr0(uint32_t data);
extern void write_cr3(uint32_t data);
extern void pmmngr_free_block(void* address); // releases a memory block
extern void* pmmngr_alloc_block (); // allocates a single memory block
extern void pmmngr_init (size_t memSize, uint32_t stack); // initialize the physical memory manager
extern void pmmngr_init_region (physical_addr base, size_t size); // enables a physical memory region for use
extern void pmmngr_deinit_region (physical_addr base, size_t size); // disables a physical memory region as in use (unuseable)
extern size_t pmmngr_get_memory_size (); // returns amount of physical memory the manager is set to use
extern uint32_t pmmngr_get_use_block_count (); // returns number of blocks currently in use
extern uint32_t pmmngr_get_free_block_count (); // returns number of blocks not in use
extern uint32_t pmmngr_get_block_count (); // returns number of memory blocks
extern uint32_t pmmngr_get_block_size (); // returns default memory block size in bytes
extern void pmmngr_paging_enable (byte b); // enable or disable paging
extern byte pmmngr_is_paging (); // test if paging is enabled
extern byte pmmngr_test_block (uint32_t block);
#endif

26
SysCore/memory/pde.c Normal file
View File

@ -0,0 +1,26 @@
#include <pde.h>
void pt_entry_add_attrib (pt_entry* entry, unsigned mask) {
*entry |= mask;
}
void pt_entry_del_attrib (pt_entry* entry, unsigned mask) {
*entry &= ~mask;
}
void pt_entry_set_frame (pt_entry* entry, unsigned address) {
*entry &= ~_I86_PTE_FRAME;
*entry |= address & _I86_PTE_FRAME;
}
unsigned pt_entry_get_frame (pt_entry entry) {
return entry&_I86_PTE_FRAME;
}
unsigned char pt_entry_is_present (pt_entry entry) {
return ( (entry & _I86_PTE_PRESENT) > 0 );
}
unsigned char pt_entry_is_writable (pt_entry entry) {
return ( (entry & _I86_PTE_WRITABLE) > 0 );
}

27
SysCore/memory/pde.h Normal file
View File

@ -0,0 +1,27 @@
#ifndef __PAGE_DIRECTORY_ENTRY_
#define __PAGE_DIRECTORY_ENTRY_
enum __PAGE_FLAGS {
_I86_PTE_PRESENT = 1,
_I86_PTE_WRITABLE = 2,
_I86_PTE_USER = 4,
_I86_PTE_WRITETHROUGH = 8,
_I86_PTE_NOT_CACHEABLE = 0x10,
_I86_PTE_ACCESSED = 0x20,
_I86_PTE_DIRTY = 0x40,
_I86_PTE_PAT = 0x80,
_I86_PTE_CPU_GLOBAL = 0x100,
_I86_PTE_LV4_GLOBAL = 0x200,
_I86_PTE_FRAME = 0x7FFFF000
};
typedef unsigned pt_entry;
extern void pt_entry_add_attrib (pt_entry* entry, unsigned mask);
extern void pt_entry_del_attrib (pt_entry* entry, unsigned mask);
extern void pt_entry_set_frame (pt_entry* entry, unsigned address);
extern unsigned pt_entry_get_frame (pt_entry entry);
extern unsigned char pt_entry_is_present (pt_entry entry);
extern unsigned char pt_entry_is_writable (pt_entry entry);
#endif

26
SysCore/memory/pte.c Normal file
View File

@ -0,0 +1,26 @@
#include <pte.h>
void pt_entry_add_attrib (pt_entry* entry, unsigned mask) {
*entry |= mask;
}
void pt_entry_del_attrib (pt_entry* entry, unsigned mask) {
*entry &= ~mask;
}
void pt_entry_set_frame (pt_entry* entry, unsigned address) {
*entry &= ~_I86_PTE_FRAME;
*entry |= address & _I86_PTE_FRAME;
}
unsigned pt_entry_get_frame (pt_entry entry) {
return entry&_I86_PTE_FRAME;
}
unsigned char pt_entry_is_present (pt_entry entry) {
return ( (entry & _I86_PTE_PRESENT) > 0 );
}
unsigned char pt_entry_is_writable (pt_entry entry) {
return ( (entry & _I86_PTE_WRITABLE) > 0 );
}

27
SysCore/memory/pte.h Normal file
View File

@ -0,0 +1,27 @@
#ifndef __PAGE_TABLE_ENTRY_
#define __PAGE_TABLE_ENTRY_
enum __PAGE_FLAGS {
_I86_PTE_PRESENT = 1,
_I86_PTE_WRITABLE = 2,
_I86_PTE_USER = 4,
_I86_PTE_WRITETHROUGH = 8,
_I86_PTE_NOT_CACHEABLE = 0x10,
_I86_PTE_ACCESSED = 0x20,
_I86_PTE_DIRTY = 0x40,
_I86_PTE_PAT = 0x80,
_I86_PTE_CPU_GLOBAL = 0x100,
_I86_PTE_LV4_GLOBAL = 0x200,
_I86_PTE_FRAME = 0x7FFFF000
};
typedef unsigned pt_entry;
extern void pt_entry_add_attrib (pt_entry* entry, unsigned mask);
extern void pt_entry_del_attrib (pt_entry* entry, unsigned mask);
extern void pt_entry_set_frame (pt_entry* entry, unsigned address);
extern unsigned pt_entry_get_frame (pt_entry entry);
extern unsigned char pt_entry_is_present (pt_entry entry);
extern unsigned char pt_entry_is_writable (pt_entry entry);
#endif

BIN
SysCore/objects/BSOD.O Normal file

Binary file not shown.

BIN
SysCore/objects/CMOS.O Normal file

Binary file not shown.

BIN
SysCore/objects/CONIO.O Normal file

Binary file not shown.

BIN
SysCore/objects/CPU.O Normal file

Binary file not shown.

BIN
SysCore/objects/GDT.O Normal file

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More