├── LICENSE ├── README.md ├── boot ├── BOS_boot.asm └── BOS_boot.bin ├── bos.img ├── doc ├── bochsrc-osx.txt ├── bochsrc.txt ├── design.txt ├── services.txt └── shell.txt ├── kernel ├── 16bit │ ├── a20.asm │ ├── gdt.asm │ ├── idt.asm │ ├── init16bit.asm │ ├── mem.asm │ └── variables.asm ├── fat12 │ └── fat12.asm ├── fdc │ ├── dma.asm │ └── fdc.asm ├── init │ ├── bios.asm │ ├── cmos.asm │ ├── init32b.asm │ ├── pic.asm │ └── timer.asm ├── int │ ├── debug.asm │ ├── idt.asm │ └── isr.asm ├── kbd │ ├── keyboard.asm │ └── keymap.asm ├── kernel.asm ├── kernel.sys ├── ram │ └── mem.asm ├── shell │ ├── clock.asm │ ├── commands.asm │ └── shell.asm ├── sound │ └── speaker.asm ├── stdio │ └── stdio.asm ├── system │ └── services.asm ├── vars │ └── strings.asm ├── vfs │ ├── parse.asm │ └── vfs.asm └── vga │ ├── font8x16.asm │ ├── mario.asm │ ├── text.asm │ └── vga.asm ├── scripts ├── install.bat ├── install.sh ├── mac-bochs.sh └── mac-install.sh └── utils ├── FASM.EXE ├── PARTCOPY.EXE ├── fasm └── osxfasm /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | BOS 2 | === 3 | 4 | [![Gitter](https://img.shields.io/badge/Gitter-Join%20chat-brightgreen.svg)](https://gitter.im/bubach/BOS) [![GitHub Pages](https://img.shields.io/badge/GitHub-Pages-brightgreen.svg)](http://bubach.github.io/BOS/) 5 | 6 | BOS - a small x86 operating system written in Assembly 7 | -------------------------------------------------------------------------------- /boot/BOS_boot.asm: -------------------------------------------------------------------------------- 1 | ;------------------------------------------------------------; 2 | ; BOS - FAT12 bootsector ; 3 | ;------------------------------------------------------------; 4 | ; - FAT12 compatible. ; 5 | ; - Loads a binary file from the floppy. ; 6 | ; ; 7 | ; 16-bit mem map (seg:off) ; 8 | ;------------------------------------------------------------; 9 | ; 0x0000:0x0000 -> 0x0000:0x0500 BIOS stuff ; 10 | ; 0x0000:0x0500 -> 0x0000:0x2100 FAT12 rootdir ; 11 | ; 0x0000:0x2100 -> 0x0000:0x3300 FAT for FAT12 ; 12 | ; 0x0000:0x3300 -> 0x0000:0x6c00 14,25kb free space ; 13 | ; 0x0000:0x6c00 -> 0x0000:0x7400 IDT, 256 descriptors ; 14 | ; 0x0000:0x7400 -> 0x0000:0x7c00 GDT, 256 descriptors ; 15 | ; 0x0000:0x7c00 -> 0x0000:0x7e00 bootsector ; 16 | ; 0x0000:0x7e00 <- 0x0000:0x8000 512b stack for boot ; 17 | ; 0x0000:0x8000 -> 0x9000:0xffff 608kb kernel/free space ; 18 | ; 0xA000:0x0000 -> ............. VGA mem etc. ; 19 | ;------------------------------------------------------------; 20 | 21 | use16 22 | org 0x7C00 23 | 24 | boot: 25 | jmp short start 26 | nop 27 | 28 | ;------------------------------------------; 29 | ; Standard BIOS Parameter Block, "BPB". ; 30 | ;------------------------------------------; 31 | bpbOEM db 'BOS 0.04' 32 | bpbSectSize dw 512 33 | bpbClustSize db 1 34 | bpbReservedSec dw 1 35 | bpbFats db 2 36 | bpbRootSize dw 224 37 | bpbTotalSect dw 2880 38 | bpbMedia db 240 39 | bpbFatSize dw 9 40 | bpbTrackSect dw 18 41 | bpbHeads dw 2 42 | bpbHiddenSect dd 0 43 | bpbLargeSect dd 0 44 | ;---------------------------------; 45 | ; extended BPB for FAT12/FAT16 ; 46 | ;---------------------------------; 47 | bpbDriveNo db 0 48 | bpbReserved db 0 49 | bpbSignature db 41 ; 0 = end. 41 = three more. 50 | bpbID dd 1 51 | bpbVolumeLabel db 'BOOT FLOPPY' 52 | bpbFileSystem db 'FAT12 ' 53 | 54 | 55 | ;----------------------------------------; 56 | ; starting point of bootsector code ; 57 | ;----------------------------------------; 58 | start: 59 | cli 60 | 61 | xor ax, ax ; initialize all the necessary 62 | mov ds, ax ; registers. 63 | mov es, ax 64 | mov ss, ax 65 | mov sp, 0x8000 ; Stack.. 66 | 67 | mov [bpbDriveNo], dl 68 | 69 | sti 70 | 71 | 72 | ;----------------------------------; 73 | ; clear screen and print some ; 74 | ;----------------------------------; 75 | mov ax, 3 ; Set mode 0x03 76 | int 0x10 77 | 78 | mov bp, loading ; Print loading message. 79 | mov ax, 0x1301 80 | mov bx, 7 81 | mov cx, 12 82 | mov dx, 0x0102 83 | int 0x10 84 | 85 | mov bl, 2 ; Set cursor. 86 | mov ah, 2 87 | mov dx, 0x0201 88 | int 0x10 89 | 90 | mov ah, 9 ; Print 14 green dots. 91 | mov al, '.' 92 | mov cx, 14 93 | int 0x10 94 | 95 | 96 | ;---------------------------; 97 | ; load FAT and root ; 98 | ;---------------------------; 99 | mov di, 0x0050 ; Load the root to 100 | mov ax, 19 ; 0x0000:0x0500 (0x500/0x10) 101 | mov cx, 14 102 | call read_sectors 103 | 104 | mov di, 0x0210 ; Load the fat to 105 | mov ax, 1 ; 0x0000:0x2100 106 | mov cx, 9 107 | call read_sectors 108 | 109 | 110 | ;------------------------; 111 | ; search for the file ; 112 | ;------------------------; 113 | mov dx, [bpbRootSize] 114 | mov bx, 0x0500 115 | .filesearch: 116 | cld 117 | mov si, filename 118 | mov cx, 11 119 | mov di, bx 120 | repe cmpsb 121 | je found 122 | add bx, 32 123 | dec dx 124 | jz error 125 | jmp .filesearch 126 | 127 | 128 | ;-----------------------------------; 129 | ; variables & functions ; 130 | ;-----------------------------------; 131 | loading db 'Starting BOS' 132 | filename db 'KERNEL SYS' 133 | failure db 'Read error!' 134 | 135 | 136 | ;-----------------------------------------------; 137 | ; read a number of sectors (one at a time) ; 138 | ;-----------------------------------------------; 139 | ; in: ; 140 | ; di = segment to save at ; 141 | ; ax = sector to read ; 142 | ; cx = number of sectors ; 143 | ; out: ; 144 | ; di = updated (added for next read) ; 145 | ; ax = updated (added for next read) ; 146 | ;-----------------------------------------------; 147 | read_sectors: 148 | pusha 149 | mov bl, byte [bpbTrackSect] ; bl = number of sectors per track 150 | div bl ; al = ax / bl 151 | mov cl, ah ; cl = real sector number 152 | add cl, 1 153 | 154 | xor ah, ah ; del the rest of the div before 155 | mov bl, byte [bpbHeads] ; bl = number of heads 156 | div bl ; ah = rest of ( ax / bx ), al = ax / bx 157 | mov ch, al ; ch = number of track 158 | mov dh, ah ; dh = the head number 159 | 160 | mov ax, cx ; save cx in ax 161 | mov cx, 6 ; try it 6 times 162 | .next_try: 163 | push es 164 | push cx 165 | mov cx, ax ; restore cx 166 | push cx 167 | 168 | xor ax, ax 169 | mov dl, [bpbDriveNo] ; reset drive 170 | push dx 171 | int 0x13 172 | jc .failed 173 | 174 | pop dx 175 | pop cx 176 | xor bx, bx 177 | mov es, di 178 | mov ax, 0x0201 ; function 2, 1 sector 179 | int 0x13 180 | jnc .ok ; if it was ok, check next.. 181 | 182 | .failed: 183 | pop dx 184 | pop ax 185 | 186 | pop cx 187 | pop es 188 | loop .next_try ; else try once again if there is an error 189 | jmp error ; if cx = 0 and the read operation failed, halt 190 | .ok: 191 | pop cx ; from the next_try loop 192 | pop es 193 | popa 194 | add di, 32 ; add 32 (512/16) to segment 195 | inc ax ; add sector counter 196 | loop read_sectors 197 | ret 198 | 199 | 200 | ;----------------------------------------------------; 201 | ; show a message and wait for a key before reboot ; 202 | ;----------------------------------------------------; 203 | error: 204 | mov bp, failure 205 | mov ax, 0x1301 206 | mov bx, 4 207 | mov cx, 11 208 | mov dx, 0x0401 209 | int 0x10 210 | 211 | mov ah, 0 212 | int 0x16 213 | int 0x19 214 | 215 | 216 | ;-----------------------------------; 217 | ; the file is found, load it. ; 218 | ;-----------------------------------; 219 | found: 220 | mov bp, [bx+26] ; bp = cluster from dir entry 221 | mov di, 0x0800 ; 800 (segment) 222 | 223 | .next_block: 224 | xor cx, cx 225 | mov cl, [bpbClustSize] ; reset sector count to 1 cluster 226 | mov si, bp ; si = next should-be cluster for 227 | ; contiguous reads 228 | .next_contiguous: 229 | mov ax, 3 230 | mul si ; multiply cluster number by 3 231 | shr ax, 1 ; divide by two 232 | mov bx, ax 233 | mov ax, word [(0x2100+bx)] ; ax = FAT element with junk 234 | jc .odd_cluster ; jump if the value was odd 235 | and ax, 0x0FFF ; leave only lower 12 bits 236 | jmp .got_cluster ; got it 237 | .odd_cluster: 238 | shr ax, 4 ; (leave only bits 4-15) 239 | 240 | .got_cluster: 241 | inc si ; si = current cluster+1 242 | cmp ax, si ; next cluster = current cluster+1? 243 | jne .force_read ; is it still contiguous? 244 | 245 | add cl, [bpbClustSize] ; increase sector count by 1 cluster 246 | adc ch, 0 ; add cf + 0 to ch 247 | jmp .next_contiguous 248 | 249 | .force_read: 250 | xchg bp, ax ; ax = bp (base cluster), bp = new cluster 251 | dec ax ; decrease by 2 to get the actual... 252 | dec ax ; ...cluster number 253 | 254 | movzx dx, byte [bpbClustSize] 255 | mul dx ; multiply by sectors per cluster 256 | add ax, 33 ; add data-area location (33) 257 | call read_sectors 258 | 259 | cmp bp, 0x0FF8 ; is the new cluster EOF (FF8-FFF)? 260 | jb .next_block ; if not, read next block 261 | 262 | ;-----------------------; 263 | ; the file is loaded ; 264 | ;-----------------------; 265 | quit: 266 | jmp 0x0000:0x8000 ; jump to loaded file (64kb in mem) 267 | 268 | 269 | ;-------------------------------------; 270 | ; set the BOOT-signature at byte 510. ; 271 | ;-------------------------------------; 272 | rb boot+512-2-$ 273 | dw 0xAA55 -------------------------------------------------------------------------------- /boot/BOS_boot.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bubach/BOS/a2421e39f4c4ce2d834a1850c706153e5bf04af8/boot/BOS_boot.bin -------------------------------------------------------------------------------- /bos.img: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bubach/BOS/a2421e39f4c4ce2d834a1850c706153e5bf04af8/bos.img -------------------------------------------------------------------------------- /doc/bochsrc-osx.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # # 3 | # BOCHS config file for BOS # 4 | # # 5 | ####################################### 6 | 7 | #display_library: term 8 | romimage: file=/usr/local/Cellar/bochs/2.6.2/share/bochs/BIOS-bochs-latest 9 | megs: 32 10 | vgaromimage: file=/usr/local/Cellar/bochs/2.6.2/share/bochs/VGABIOS-lgpl-latest 11 | floppya: 1_44=../bos.img, status=inserted 12 | boot: a 13 | floppy_bootsig_check: disabled=0 14 | #log: bochsout.txt 15 | panic: action=ask 16 | error: action=report 17 | info: action=report 18 | debug: action=ignore 19 | #debugger_log: debugger.out 20 | keyboard_serial_delay: 250 21 | keyboard_paste_delay: 100000 22 | mouse: enabled=0 23 | keyboard_mapping: enabled=0, map= 24 | user_shortcut: keys=ctrlaltdel -------------------------------------------------------------------------------- /doc/bochsrc.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # # 3 | # BOCHS config file for BOS # 4 | # # 5 | ####################################### 6 | 7 | romimage: file=BIOS-bochs-latest, address=0xf0000 8 | megs: 32 9 | vgaromimage: VGABIOS-elpin-2.40 10 | floppya: 1_44=a:, status=inserted 11 | boot: a 12 | floppy_bootsig_check: disabled=0 13 | log: bochsout.txt 14 | panic: action=ask 15 | error: action=report 16 | info: action=report 17 | debug: action=ignore 18 | debugger_log: debugger.out 19 | vga_update_interval: 300000 20 | keyboard_serial_delay: 250 21 | keyboard_paste_delay: 100000 22 | floppy_command_delay: 50000 23 | ips: 1000000 24 | mouse: enabled=0 25 | keyboard_mapping: enabled=0, map= 26 | user_shortcut: keys=ctrlaltdel 27 | -------------------------------------------------------------------------------- /doc/design.txt: -------------------------------------------------------------------------------- 1 | BOS design 2 | ---------- 3 | 4 | The kernel will load internal system modules like STDIO, 5 | VFS and so on, by calling a dd list in "init.inc". 6 | STDIO should be the first to load, as to be able to print 7 | loading status of other parts. 8 | 9 | 10 | 11 | STDIO will use internal buffer/debug console as STDOUT at 12 | first, until textmode, VESA or serial output driver is 13 | activated, at which point the internal buffer/debug console 14 | will be flushed to new STDOUT. 15 | 16 | Module for STDOUT could even include a file handle for 17 | systems with no normal output device, so that debugging 18 | information can be read out from file. All drivers 19 | for STDIO will have to follow a common STDIO interface 20 | and can be dynamically loaded and unloaded at runtime. 21 | 22 | Keyboard/mouse drivers for PS/2 and later USB also needs 23 | to register itself to STDIO as STDIN devices in the system. 24 | 25 | 26 | 27 | Other primary services tightly connected to the BOS kernel 28 | is the VFS for all storage devices and filesystems, the 29 | interrupt and system call interface for adding new calls 30 | and groups of calls within the standard int 0x32 interrupt. 31 | 32 | Groups of calls is for primary system services to be 33 | accessed from within the same interrupt, 0x32. For 34 | example the VFS, could use AL = 0x05 for it's "group-ID" 35 | and AH = 0x?? for a specific function-call. STDIO, could 36 | have AL = 0x01 with AH = 0x?? for the function number. 37 | 38 | 39 | 40 | Another primary systemcall group will be the "loader", 41 | for applications and modules/drivers not present inside 42 | the kernel image file - kernel.sys 43 | 44 | It will initially support 2 types of applications, 45 | normal programs and drivers/modules/TSR. 46 | 47 | Loading will be handled by means of segmentation at first, 48 | as the simpler format with less overhead. Similar to 49 | DOS .COM files. Another format for relocatable programs 50 | is planned but will require modifications to fasm for 51 | native output. This will be similar to .EXE files in 52 | DOS. No limitations will be made to the formats, 53 | except the segmentated one will not have base set to zero 54 | in RAM, and will not have program headers and relocation- 55 | tables as overhead. 56 | 57 | This makes it somewhat trickier to preform certain RAM 58 | operations in higher level languages but also ideal for 59 | space constrained applications, such as scene demos - which 60 | often has very low size limits. 61 | 62 | File format exstensions is not yet decided, but might 63 | differ for the two formats. Maybe .APP for the simpler 64 | segmentated format and .PRG for the relocatable? 65 | 66 | 67 | 68 | The kernel image file will need to include some loadable 69 | drivers at the end for further access to media such as 70 | the floppy disk, and the FAT12 filesystem. With this it's 71 | possible that the file on a fat12 formatted floppy will 72 | be named kernel.img while internally it might be visible 73 | as kernel.sys, floppy.drv, fat12.drv and so on. 74 | 75 | Initially the VFS will have internal drivers for parsing 76 | this image format and deploying it as a RAM-drive with 77 | SBFS - static BOS filesystem. A very simple read-only FS 78 | in linked-list style. As simple as it gets. 79 | 80 | So the VFS needs RAM-drive and SBFS support built-in for 81 | it to be able to load additional drivers for floppy, fat12, 82 | harddrives and other media. System drive will always 83 | be this RAM-drive. Any drivers loaded at a later stage can 84 | be on any other media or drive, such as the floppy. 85 | 86 | There should be commands to load a driver like "LOAD" 87 | for one time use and "LOADPERM" for it to be permanetly 88 | inserted into the kernel image file for loading at boot. 89 | "UNLOAD" and "UNLOADPERM" could be used for unloading 90 | and removing drivers from the kernel image. 91 | 92 | 93 | 94 | Memory managment and allocation in BOS will be another 95 | primary system service with it's own group-ID in AL, 96 | for access with int 0x32. It will provide one allocation 97 | and freeing service for memory above 1mb and another 98 | service for memory below 1mb. 99 | 100 | Memory below 1mb should only be used in applications that 101 | needs to run 16-bit code or allocate DMA buffer space. It 102 | will be possible to demand 64kb align on allocations made 103 | in low memory - to properly support DMA transfers. 104 | 105 | The memory managment service group will also have functions 106 | to get RAM size, and maybe system location/size or others. 107 | 108 | 109 | 110 | Running custom 16-bit code will be possible by allocating 111 | low memory space, relocating any 16-bit code to that area 112 | and then calling a BOS system service to start execution 113 | in realmode at that address. This will allow for greater 114 | flexibility in utilizing BIOS services than a direct 115 | bridge call to for example interrupt 0x10 or 0x13. 116 | 117 | All (segment) registers can be used and BIOS interrupts 118 | demanding buffer space pointers will easily be supported by 119 | pre-allocating the necessary low memory before executing 120 | the real mode code. 121 | 122 | Direct execution of a native 16-bit executable file format 123 | is not planned, but could be supported by a third party 124 | loader written in 32-bit to take 16-bit binary filename as 125 | input, allocate low memory for it, relocate it, execute 126 | and clean up at exit. Such a program could be extended to 127 | contain interrupt 0x21 services for basic DOS compability. 128 | 129 | BOS kernel is loaded at the 64kb mark right now, but should 130 | be moved sufficently below that for internal 16-bit code 131 | to work without address fixes. The ORG offset should be 132 | below 0xFFFF for all internal 16-bit code. Now it starts 133 | at 0x10000, which means this offset has to be substracted 134 | from all 16-bit code that deals with variables. 135 | 136 | For external 16-bit code, relocated and runned by the kernel, 137 | this is no issue. 138 | 139 | 140 | 141 | BOS should include a scripting language, similar to DOS batch 142 | files for scripting and "autoexec" usage. If the extension 143 | is .RUN - the file to autostart drivers and customize the 144 | system at boot could be called "auto.run". 145 | 146 | The scripting language needs some internal commands not tied 147 | to any shell, for program control - and also for the auto.run 148 | file to be able to load the shell at boot, the LOADSH command 149 | is needed. This could be directly tied to the VFS for 150 | selecting which shell to load. The shell needs to set some 151 | system vars like %SHELLNAME% and %SHELLVERSION% for the 152 | scripts to know what other commands are available from it. 153 | 154 | Basic commands, independent of shell could be: 155 | LOADSH = "fd0:/path/shell.app" 156 | GOTO LABEL 157 | :LABEL 158 | REM comment 159 | IF [NOT] %xxx%==something GOTO LABEL 160 | ECHO %1 is first command line parameter 161 | ECHO. 162 | ECHO %SHELLNAME% is env. var for shell used. 163 | SET ENV_VARIBEL=Hi 164 | SETLOCAL LOCAL_VAR=Bye 165 | LOOP %var% 166 | ENDLOOP 167 | CALL filename.run 168 | 169 | Nothing is set in stone, but DOS batch file similarity could 170 | be good for those that know it well. It should be as easy to 171 | parse as possible. 172 | 173 | 174 | 175 | Graphics in BOS will probably be tied to the STDIO services 176 | with many additional function calls for drawing shapes and 177 | outputing sprites. Text output will be possible as in any 178 | textmode, but the cursor will be hidden by default, and if 179 | enabled, simulated with blinking and all - by BOS. 180 | 181 | With text output options even in VESA modes, a system crash 182 | will still be able to print out some facts about it with 183 | the same STDOUT functions as in textmode. Font&size will be 184 | optional, but optimized for best look and usability as default. 185 | 186 | Other graphics function will include anything that helps 187 | and eases the development of games, added as I port and 188 | develops my own game clones. 189 | 190 | 191 | 192 | The sound service group will have a unified function interface 193 | no matter what device is installed, only PC speaker, AC'97, 194 | SoundBlaster/AdLib compatible or Intel HD audio. 195 | 196 | It will be possible for the programs to detect capability of 197 | the installed driver for best utilization. 198 | 199 | 200 | 201 | A driver will be loaded in the exact same way as any other 202 | application but will install itself with the service group 203 | it belongs to, or as a new interrupt itself before quitting 204 | in a TSR way. 205 | 206 | The interrupt handling code will have functionality for drivers 207 | not only to install a completly new interrupt, but also to add 208 | itself as a new service group in the system interrupt 0x32. 209 | It will then be given a free service number (AL=0x??) for calls 210 | made to that group. It could also request to take over an 211 | existing service number. What internal function to be called is 212 | decided with the value in AH and could go to external drivers 213 | that has been loaded and added itself to the service group. 214 | 215 | A driver might use .DRV extension or something to distinguish 216 | itself from a normal executable. It's not decided how to tell 217 | if it's a .APP type segmented driver or .PRG relocatable driver 218 | with just one .DRV extension. Could probe for relocatble format 219 | header for .PRG and assume .APP format if not found. This could 220 | be done for programs as well, if I choose to use one extension 221 | on both executable formats. 222 | 223 | 224 | 225 | The End 226 | - for now. -------------------------------------------------------------------------------- /doc/services.txt: -------------------------------------------------------------------------------- 1 | SYSTEM SERVICES LAYOUT 2 | ====================== 3 | 4 | All OS functionality can be reached from one or several 5 | interfaces/services. 6 | 7 | When calling the system interrupt 0x32, you request a service 8 | number and function in AX register with AL & AH. Making 256 the max 9 | number of interfaces and available service-functions. 10 | 11 | Services numbered 0x0F and below are system reserved and will not be 12 | assigned automatically when requesting to add a new service. They can 13 | still be replaced by implicitly requesting that service number instead 14 | of getting a free one assigned. 15 | 16 | This will allow for great OS modularity when each interface/service- 17 | group can be replaced or upgraded by any user software or driver. 18 | 19 | Most service groups or interfaces can be extended with drivers for 20 | the type of device(s) that it handles, or the full service/interface 21 | can be replaced for more fundamental changes to the design. For 22 | example the 'process' and 'memory' interfaces can be replaced to 23 | allow more advanced functionality like multitasking and paging. 24 | 25 | The OS will be unable to function at all without the basic service 26 | 0x00 that performs the most crucial tasks, and without the STDIO and 27 | VFS interfaces it will be severly crippled, left with no means of 28 | communication, except perhaps a beep or two from the PC-speaker. 29 | 30 | Below is a more visual representation of the main OS services 31 | that will likely be included in the kernel. And a draft of what 32 | functions each could or would include. Some functions also have 33 | a breif example of parameters required. 34 | 35 | Possible funture service groups or interfaces that could be system 36 | default include: 37 | - network functionality 38 | - general PCI devices 39 | - special one for all things USB? 40 | - GUI specific functions 41 | - printing services 42 | - running stuff in 16 and 64 bit, with extra DOS emulation 43 | and/or other services 44 | 45 | 46 | 47 | 48 | services.asm (main service 0x00) 49 | -------------------------------------- 50 | always present in BOS, kernel 51 | -------------------------------------- 52 | - add service 53 | signature dd 'VFS ', 'IO ', 'SND ', 'PCI ' 54 | version db 1 55 | requested_no db 23 ; 0xFF or 0x00 to get assigned 56 | service_struct dd 0 ; memory address of service calltable 57 | - get servide 58 | AL = number 59 | returns all info above if service found 60 | - remove service 61 | AL = number 62 | removes / unloads a service/interface 63 | - get free number 64 | AL = free service number ; always above 0x0F (below reserved) 65 | - get BOS version (and other misc. kernel functions below) 66 | - get/set interrupts 67 | - execute kernel monitor command/script 68 | - get time/date 69 | - GDT function, create new segments 'n shit 70 | - pc-speaker beep if not even stdio is found 71 | - CMOS / PIC functions 72 | 73 | 74 | stdio.asm (service number 0x01) 75 | -------------------------------------- 76 | needs to init itself as a service, 77 | requesting servicenumber 1. 78 | internal struct with info on 79 | default in and out devices. 80 | -------------------------------------- 81 | - add device 82 | type db 1 ; 0 = output, 1 = input 83 | signature dd 'COM ', 'VGA ', 'VESA', 'FILE', 'NET ', 'USB ', 'KEYB', 'MICE' 84 | version db 1 85 | device_struct dd 0 ; address of calltable 86 | - get device 87 | AL = assigned device type ID / 0 for default? 88 | returns all info above 89 | - remove device 90 | AL = assigned device type ID 91 | removes device 92 | - set default 93 | AL = assigned device type ID 94 | AH = 1 for in, 0 for out 95 | - getc 96 | get a char from stdin or specified device 97 | - putc 98 | put a char to stdout or specified device 99 | 100 | .... other default stubs needed for STDIO .... 101 | 102 | 103 | vfs.asm (service number 0x02) 104 | -------------------------------------- 105 | needs to init itself as a service, 106 | requesting servicenumber 2. 107 | internal struct with info on 108 | devices and filesystems. 109 | add simple 'FILE' STDIO interface? 110 | -------------------------------------- 111 | - add device 112 | - remove device 113 | - get devices (list or number specified) 114 | - read sector 115 | - write sector 116 | - seek 117 | - more device specific stubs? 118 | ... 119 | - add fs 120 | - remove fs 121 | - parse path 122 | - load file 123 | - write file 124 | - seek file 125 | - close file 126 | - mount device (with auto detect fs option) 127 | - format fs (take device argument) 128 | - more fs specific stubs? 129 | 130 | 131 | proccess.asm (service number 0x03) 132 | -------------------------------------- 133 | needs to init itself as a service, 134 | requesting servicenumber 3. 135 | possible to extend/replace for 136 | multitasking. 137 | -------------------------------------- 138 | - Load process 139 | needs VFS info to load file 140 | - Exit process 141 | - Terminate and Stay Resident 142 | - Add exec. driver 143 | interface to load driver/extensions for 144 | more executable formats, possibly other 145 | execution modes: realmode, longmode 146 | - Remove driver 147 | - run 16/64 bit code - seperate services for this? (int21h included?) 148 | 149 | 150 | memory.asm (service number 0x04) 151 | -------------------------------------- 152 | needs to init itself as a service, 153 | requesting servicenumber 4. 154 | -------------------------------------- 155 | - lowalloc ? (for low mem, DMA & 16bit code) 156 | - alloc 157 | - realloc 158 | - free 159 | - DMA functions here? Possibly most related to mem? -------------------------------------------------------------------------------- /doc/shell.txt: -------------------------------------------------------------------------------- 1 | SHELL DESIGN 2 | ============ 3 | 4 | The BOS shell should operate at a minimum resolution of 80*25, but prefarably on more. 5 | It should be tile-able to allow different apps to run in different parts of the window, such 6 | as a "graphical" file browser might use up all but one line at the bottom for commands. 7 | 8 | The mouse or keyboard interrupts will be used to switch between active tile, giving that 9 | areas program full control. Simulating multitasking to some degree. 10 | 11 | The built in scripting language needs support to set up screen resolution, tile areas, 12 | and more on boot. 13 | 14 | Programs should provide minimum resolution requirements if not text based scrolling 15 | is all it needs. 16 | 17 | Pop-ups with kernel panics or dialogs could cover any area. 18 | 19 | The shell scripting language will allow a few special case script-files called in an 20 | event like fashion. If .RUN is the default script exstension, AUTO.RUN would be used 21 | at boot. EXIT.RUN when exiting/rebooting, NOTFOUND.RUN to parse commands not understood 22 | and provide shortcuts for builtin commands. Cron like functionality for other 23 | scripts to be scheduled. 24 | 25 | GUI apps using build in functions for borders, pop-ups and such will scale perfectly 26 | from 80*25 textmode all the way to some VESA mode with polished graphics, like 1024*768. -------------------------------------------------------------------------------- /kernel/16bit/a20.asm: -------------------------------------------------------------------------------- 1 | ;----------------------------------------------------------; 2 | ; BOS 0.05 Christoffer Bubach, 2005. ; 3 | ;----------------------------------------------------------; 4 | ; ; 5 | ; Realmode functions to set a20-gate. ; 6 | ; ; 7 | ;----------------------------------------------------------; 8 | 9 | ;----------------------; 10 | ; enable a20 gate ; 11 | ;----------------------; 12 | enable_a20: 13 | in al, 0x64 ; first try.. 14 | test al, 2 15 | jnz enable_a20 16 | mov al, 0xD1 17 | out 0x64, al 18 | .d6: 19 | in al, 0x64 20 | and ax, 2 21 | jnz .d6 22 | mov al, 0xDF 23 | out 0x60, al 24 | 25 | call a20_test 26 | jz .ok 27 | 28 | in al, 0x92 ; try again, diffrent method. 29 | or al, 0x02 30 | out 0x92, al 31 | 32 | call a20_test 33 | jz .ok 34 | 35 | ; ERROR! 36 | ; a20-gate not set! Do something about it here... ;) 37 | 38 | .ok: 39 | ret 40 | 41 | ;------------------------; 42 | ; test if A20 is set ; 43 | ;------------------------; 44 | a20_test: 45 | mov al, byte [fs:0] 46 | mov ah, al 47 | not al 48 | xchg al, byte [gs:0x10] 49 | cmp ah, byte [fs:0] 50 | mov [gs:0x10], al 51 | ret -------------------------------------------------------------------------------- /kernel/16bit/gdt.asm: -------------------------------------------------------------------------------- 1 | ;----------------------------------------------------------; 2 | ; BOS kernel Christoffer Bubach, 2004-2005. ; 3 | ;----------------------------------------------------------; 4 | ; ; 5 | ; Global Descriptor Table (GDT). ; 6 | ; ; 7 | ;----------------------------------------------------------; 8 | 9 | ;-------------------; 10 | ; pointer to GDT ; 11 | ;-------------------; 12 | gdtr: 13 | .size dw gdt_end - gdt - 1 14 | .address dd 0x7400 ; here we move the gdt 15 | 16 | ;-----------------------------------; 17 | ; Global Descriptor Table (GDT). ; 18 | ;-----------------------------------; 19 | gdt: 20 | .null dw 0x0000, 0x0000, 0x0000, 0x0000 ; null desc. 21 | .BOS_code: dw 0xFFFF, 0x0000, 0x9A00, 0x00CF ; 0x08 , was 9800 before. 22 | .BOS_data: dw 0xFFFF, 0x0000, 0x9200, 0x00CF ; 0x10 23 | .BOS_16code: dw 0xFFFF, 0x0000, 0x9A00, 0x0000 ; 0x18 24 | .BOS_16data: dw 0xFFFF, 0x0000, 0x9200, 0x0000 ; 0x20 25 | gdt_end: -------------------------------------------------------------------------------- /kernel/16bit/idt.asm: -------------------------------------------------------------------------------- 1 | ;----------------------------------------------------------; 2 | ; BOS kernel Christoffer Bubach, 2003-2005. ; 3 | ;----------------------------------------------------------; 4 | ; ; 5 | ; pointer to IDT (Interrupt Description Table) ; 6 | ; ; 7 | ;----------------------------------------------------------; 8 | 9 | 10 | 11 | ;-----------------; 12 | ; IDT pointer ; 13 | ;-----------------; 14 | idtr: 15 | .size dw 0x800 16 | .address dd 0x6C00 -------------------------------------------------------------------------------- /kernel/16bit/init16bit.asm: -------------------------------------------------------------------------------- 1 | ;----------------------------------------------------------; 2 | ; BOS kernel Christoffer Bubach, 2005. ; 3 | ;----------------------------------------------------------; 4 | ; ; 5 | ; Do everything related to 16-bit here... :) ; 6 | ; ; 7 | ;----------------------------------------------------------; 8 | 9 | ;---------------------; 10 | ; save info ; 11 | ;---------------------; 12 | init16bit: 13 | call getmem ; realmode/mem.inc 14 | mov [ram_amount], eax 15 | 16 | xor eax, eax ; clear mem for IDT and GDT 17 | mov edi, [idtr.address] ; IDT address 18 | mov ecx, (0x800 + 0x800)/4 19 | rep stosd 20 | 21 | mov eax, cs 22 | shl eax, 4 23 | mov [gdt.BOS_16code + 2], ax ; Prepare GDT by 24 | mov [gdt.BOS_16data + 2], ax ; setting 16-bit base. 25 | shr eax, 16 26 | mov [gdt.BOS_16code + 4], al 27 | mov [gdt.BOS_16data + 4], al 28 | mov [gdt.BOS_16code + 7], ah 29 | mov [gdt.BOS_16data + 7], ah 30 | 31 | lea esi, [gdt] 32 | mov edi, 0x7400 ; GDT address 33 | mov ecx, (gdt_end - gdt)/4 34 | rep movsd ; Move it to final pos. 35 | 36 | push dword 0 ; clear NT bit 37 | popfd 38 | ret -------------------------------------------------------------------------------- /kernel/16bit/mem.asm: -------------------------------------------------------------------------------- 1 | ;----------------------------------------------------------; 2 | ; BOS kernel Christoffer Bubach, 2003-2005. ; 3 | ;----------------------------------------------------------; 4 | ; ; 5 | ; Get memory size, only using E801 right now. ; 6 | ; ; 7 | ;----------------------------------------------------------; 8 | 9 | ;-----------------------------------------; 10 | ; get mem ; 11 | ; in: nothing ; 12 | ; out: eax = mem in bytes, 0 = error ; 13 | ;-----------------------------------------; 14 | getmem: 15 | push dx 16 | push cx 17 | push ebx 18 | 19 | xor eax, eax 20 | xor ebx, ebx 21 | mov ax, 0xE801 22 | xor dx, dx 23 | xor cx, cx 24 | int 0x15 25 | jnc .cont1 26 | xor eax, eax 27 | jmp .end ; failed! :'( 28 | 29 | .cont1: 30 | mov si, ax 31 | or si, bx 32 | jne .cont 33 | mov ax, cx 34 | mov bx, dx 35 | 36 | .cont: 37 | cmp ax, 0x3C00 38 | jb .below_16 39 | movzx eax, bx 40 | add eax, 0x100 41 | shl eax, 16 ; eax = eax * 65536 42 | jmp .end 43 | 44 | .below_16: 45 | shl eax, 10 ; eax = eax * 1024 46 | 47 | .end: 48 | pop ebx 49 | pop cx 50 | pop dx 51 | ret -------------------------------------------------------------------------------- /kernel/16bit/variables.asm: -------------------------------------------------------------------------------- 1 | ;----------------------------------------------------------; 2 | ; BOS kernel Christoffer Bubach, 2005. ; 3 | ;----------------------------------------------------------; 4 | ; ; 5 | ; Variabels for/from realmode. ; 6 | ; ; 7 | ;----------------------------------------------------------; 8 | 9 | ;---------------------------------------; 10 | ; needed to get back to 16-bit mode ; 11 | ;---------------------------------------; 12 | realmode_cs dw 0 13 | ridtr: dw 0x3FF 14 | dd 0 15 | 16 | ;----------------; 17 | ; other stuff ; 18 | ;----------------; 19 | int_number db 0 20 | realmode_error db 0 21 | realmode_ax dw 0 22 | realmode_bx dw 0 23 | realmode_cx dw 0 24 | realmode_dx dw 0 25 | 26 | ;-------------------; 27 | ; saved info ; 28 | ;-------------------; 29 | ram_amount dd 0 -------------------------------------------------------------------------------- /kernel/fat12/fat12.asm: -------------------------------------------------------------------------------- 1 | ;----------------------------------------------------------; 2 | ; BOS kernel Christoffer Bubach, 2012-2015. ; 3 | ;----------------------------------------------------------; 4 | ; ; 5 | ; FAT12 driver. ; 6 | ; ; 7 | ;----------------------------------------------------------; 8 | 9 | ;---------------------------------------------; 10 | ; FAT12 calltable and structure pointer ; 11 | ;---------------------------------------------; 12 | FAT12: 13 | .data_pointer dd 0 ; internal driver data 14 | .FSname db 'FAT12' ; 5 char filesystem name 15 | .init dd init_fat12 ; pointer to init 16 | .deinit dd 0 ; remove driver 17 | .format dd 0 ; format drive 18 | .mount dd 0 ; mount drive 19 | .unmount dd 0 ; unmount drive 20 | .find dd 0 ; find file 21 | .findnext dd 0 ; get next match 22 | .open dd 0 ; open file, get handle 23 | .close dd 0 ; close file from handle 24 | .attrib dd 0 ; get/set attrib. and time 25 | .read dd 0 ; read file from handle 26 | .write dd 0 ; write file from handle 27 | .seek dd 0 ; seek from handle 28 | .rename dd 0 ; rename file 29 | .remove dd 0 ; remove file/dir 30 | .create dd 0 ; create file/dir 31 | .ioctl dd 0 ; extra calls if exists 32 | 33 | ;---------------------------------------------; 34 | ; FAT12 main info structure ; 35 | ;---------------------------------------------; 36 | struc fat12_data 37 | { 38 | .disk_number db 0 ; which VFS disk number 39 | .root_dir dw 0 ; position of rootdir 40 | .disk_size dd 0 ; total storage size 41 | .free_space dd 0 ; free space available 42 | .fat_1 dd 0 ; position of fat1 43 | .fat_2 dd 0 ; position of fat2 44 | .data_area dw 0 ; position of dataarea 45 | .boot: times sizeof.bootsector db 0 ; copy of FAT12 bootsector 46 | .dir_entries: 47 | times 16 * sizeof.dir_entry db 0 ; 512b dir entry buffer 48 | .fat_buffer: times 512 db 0 ; 512b FAT cluster info buffer 49 | .foundfile: 50 | times 1 * sizeof.search db 0 ; "DTA" like structure 51 | .filehandles: ; "System File Table" 52 | times 32 * sizeof.filehandle db 0 ; for now, max opened files is 32 53 | } 54 | 55 | virtual at 0 ; could use "at esi" instead 56 | fat12_data fat12_data 57 | sizeof.fat12_data = $-$$ 58 | end virtual 59 | 60 | ;---------------------------------------------; 61 | ; FAT12 bootsector structure ; 62 | ;---------------------------------------------; 63 | struc bootsector ; 512 bytes 64 | { 65 | .jumper db 0,0,0 66 | .oem db 0,0,0,0,0,0,0,0 67 | .sectorsize dw 0 68 | .sect_per_clust db 0 69 | .reserved_sect dw 0 ; reserved sectors, 1 for bootsector. 70 | .fats_per_drive db 0 71 | .root_entries dw 0 72 | .small_sectors dw 0 ; total sectors on small disk 73 | .media_describtor db 0 ; 240 / 0xF0 = 1.44MB, 3.5" 74 | .sectors_per_fat dw 0 ; 9 on 1.44MB, 3,5" 75 | .sect_per_track dw 0 ; 18 on 1.44MB, 3,5" 76 | .heads dw 0 ; 2 on 1.44MB, 3,5" 77 | .hidden_sectors dd 0 ; sectors before bootsector 78 | .large_sectors dd 0 ; total sectors if large disk 79 | .drive_no db 0 80 | .reserved_field db 0 81 | .bpb_signature db 0 ; 41=3 more (win NT req.), 0=end. 82 | .disk_id dd 0 ; random ident number on format. 83 | .volume_label db 0,0,0,0,0,0,0,0,0,0,0 84 | .filesystem db 0,0,0,0,0,0,0,0 ; "FAT12 " or "FAT16 " 85 | .code: times 448 db 0 86 | .boot_signature db 0,0 ; 0x55,0xAA 87 | } 88 | 89 | virtual at 0 90 | bootsector bootsector 91 | sizeof.bootsector = $-$$ 92 | end virtual 93 | 94 | ;---------------------------------------------; 95 | ; FAT12 directory entry structure ; 96 | ;---------------------------------------------; 97 | struc dir_entry 98 | { 99 | .filename db 0,0,0,0,0,0,0,0 100 | .extension db 0,0,0 101 | .attributes db 0 ; 0x10 = dir for example. 102 | .reserved db 0,0,0,0,0,0,0,0,0,0 103 | .changed_time dw 0 104 | .changed_date dw 0 105 | .start_cluster dw 0 106 | .filesize dd 0 107 | } 108 | 109 | virtual at 0 110 | dir_entry dir_entry 111 | sizeof.dir_entry = $-$$ 112 | end virtual 113 | 114 | ;---------------------------------------------; 115 | ; FAT12 directory entry for LFN ; 116 | ;---------------------------------------------; 117 | struc lfn_entry 118 | { 119 | .order db 0 ; LFN entry in sequence, never 0x00 or 0xE5. 120 | .namefirst dw 0,0,0,0,0 ; 5 first unicode (2byte) chars 121 | .attribute db 0 ; 0x0F for Long File Name identification. 122 | .reserved db 0 123 | .checksum db 0 ; 8.3 name checksum 124 | .namemiddle dw 0,0,0,0,0,0 ; middle 6 unicode (2byte) chars 125 | .zero_cluster dw 0 ; always zero on LNF entries 126 | .namelast dw 0,0 ; last 2 unicode (2byte) characters. 127 | } 128 | 129 | virtual at 0 130 | lfn_entry lfn_entry 131 | sizeof.lfn_entry = $-$$ 132 | end virtual 133 | 134 | ;---------------------------------------------; 135 | ; FAT12 file search/DTA structure ; 136 | ;---------------------------------------------; 137 | struc search 138 | { 139 | .searchname: 140 | times 255 db 0 ; file search pattern. 141 | .attribute db 0 ; search attribute. 142 | .direntry dw 0 ; directory entry number, 0 based 143 | .dircluster dw 0 ; starting cluster of dir, 0 root 144 | .foundattrib db 0 ; attribute of matching file 145 | .foundtime dw 0 ; file time 146 | .founddate dw 0 ; file date 147 | .foundsize dw 0 ; file size 148 | } 149 | 150 | virtual at 0 151 | search search 152 | sizeof.search = $-$$ 153 | end virtual 154 | 155 | ;---------------------------------------------; 156 | ; FAT12 file-handle structure ; 157 | ;---------------------------------------------; 158 | struc filehandle 159 | { 160 | .handles db 0 ; reference count or or zero for unused 161 | .mode db 0 ; open mode. 0=read, 1=write, 2=r/w. 162 | .lfn_entry dw 0 ; file LFN directory entry position 163 | .direntry dw 0 ; file directory entry position 164 | .cluster dw 0 ; file first cluster 165 | .attribute db 0 ; file attributes 166 | .filetime dw 0 ; last modified time 167 | .filedate dw 0 ; last modified date 168 | .filesize dd 0 ; filesize 169 | .position dd 0 ; R/W position in file 170 | .clusterpos dw 0 ; cluster number of last cluster read 171 | .shortname: 172 | times 11 db 0 ; short name 173 | .fullname: 174 | times 255 db 0 ; the full LFN 175 | } 176 | 177 | virtual at 0 178 | filehandle filehandle 179 | sizeof.filehandle = $-$$ 180 | end virtual 181 | 182 | ;------------------------------------------; 183 | ; FAT cluster constants used ; 184 | ;------------------------------------------; 185 | cluster_free = 0x000 ; up for grabs. 186 | cluster_reserved = 0xFF0 ; 0xFF0-0xFF6. 0xFF7=bad. 187 | cluster_last = 0xFF8 ; 0xFF8-0xFFF last cluster. 188 | 189 | ;------------------------------------------; 190 | ; Directory entry first char constants ; 191 | ;------------------------------------------; 192 | entry_free = 0xE5 ; up for grabs. 193 | entry_last = 0x00 ; this and remaining is free 194 | entry_japan_kludge = 0x0E ; should be outputed as 0xE5. 195 | entry_dot = 0x2E ; ASCII dot, check for "." or ".." dirs 196 | 197 | ;------------------------------------------; 198 | ; Directory entry attribute masks ; 199 | ;------------------------------------------; 200 | mask_readonly = 0x01 201 | mask_hidden = 0x02 202 | mask_system = 0x04 203 | mask_volume_label = 0x08 204 | mask_subdirectory = 0x10 205 | mask_archive = 0x20 206 | 207 | ;------------------------------------------; 208 | ; Long File Name entry constants ; 209 | ;------------------------------------------; 210 | lfn_last_entry_mask = 0x40 ; LFN sequence-order mask for last 211 | attribute_lfn = 0x0F ; attrb. byte value for LFN dir entry 212 | 213 | 214 | ;--------------------------------------------------------------; 215 | ; init_fat12 - detect if drive fs is fat12 and init ; 216 | ;--------------------------------------------------------------; 217 | ; ; 218 | ; in: reg = pointer to VFS drive info ; 219 | ; ; 220 | ; out: reg = pointer to struct(s) if FAT12 found ; 221 | ; ; 222 | ;--------------------------------------------------------------; 223 | init_fat12: 224 | push eax 225 | ;... 226 | 227 | ;-----------------------------; 228 | ; calculate root location ; 229 | ;-----------------------------; 230 | xor eax, eax 231 | mov al, byte [fd0.boot.fats_per_drive] 232 | mul word [fd0.boot.sectors_per_fat] 233 | add ax, word [fd0.boot.reserved_sect] 234 | mov [fd0.root_dir], ax 235 | 236 | ; working with 237 | ;mov si, [drive] 238 | ;mov ax, [si+fat12.boot.sectorssize] 239 | 240 | ; a bit more code here 241 | pop eax 242 | ret 243 | 244 | ;--------------------------------------------------------------; 245 | ; calc_lfn_chksum - get long file name checksum ; 246 | ;--------------------------------------------------------------; 247 | ; ; 248 | ; in: esi = pointer to 11 byte 8.3 filename ; 249 | ; ; 250 | ; out: ax = checksum ; 251 | ; ; 252 | ;--------------------------------------------------------------; 253 | calc_lfn_chksum: 254 | push cx 255 | push esi 256 | 257 | mov cx, 11 258 | xor ax, ax ; return value start with null 259 | .l1: 260 | push cx 261 | movzx cx, byte [esi] ; add next char to sum 262 | add ax, cx 263 | pop cx 264 | shr ax, 1 ; shift sum right by 1 265 | inc esi ; prepare for next character 266 | loop .l1 267 | 268 | pop esi 269 | pop cx 270 | ret 271 | 272 | ;--------------------------------------------------------------; 273 | ; get_dir_entry - get a directory entry or amount ; 274 | ;--------------------------------------------------------------; 275 | ; ; 276 | ; in: esi = pointer to prev dir entry or 0 for root ; 277 | ; cx = entry no. to extract or 0 for none ; 278 | ; ; 279 | ; out: cx = number of entries or unchanged if set ; 280 | ; edi = pointer to dir entry or unchanged if cx=0 ; 281 | ;--------------------------------------------------------------; 282 | get_dir_entry: 283 | ;...... 284 | ret 285 | 286 | ;--------------------------------------------------------------; 287 | ; get_fat_entry - get a fat entry/cluster number ; 288 | ;--------------------------------------------------------------; 289 | ; ; 290 | ; in: cx = fat entry/cluster number ; 291 | ; ; 292 | ; out: cx = next fat entry/cluster no. or 0 if none ; 293 | ;--------------------------------------------------------------; 294 | get_fat_entry: 295 | ;... 296 | ret 297 | 298 | ;--------------------------------------------------------------; 299 | ; get_cluster - get a cluster ; 300 | ;--------------------------------------------------------------; 301 | ; ; 302 | ; in: cx = fat entry/cluster number ; 303 | ; ; 304 | ; out: edi = pointer to cluster or zero if none ; 305 | ;--------------------------------------------------------------; 306 | get_cluster: 307 | ;... 308 | ret -------------------------------------------------------------------------------- /kernel/fdc/dma.asm: -------------------------------------------------------------------------------- 1 | ;----------------------------------------------------------; 2 | ; BOS kernel Christoffer Bubach, 2004-2005. ; 3 | ;----------------------------------------------------------; 4 | ; ; 5 | ; DMA transfer code. ; 6 | ; ; 7 | ;----------------------------------------------------------; 8 | 9 | 10 | ;------------------------------------------; 11 | ; Lookup table for DMA controller ports ; 12 | ;------------------------------------------; 13 | dma_mask_reg dw 0x0A, 0x0A, 0x0A, 0x0A, 0xD4, 0xD4, 0xD4, 0xD4 14 | dma_mode_reg dw 0x0B, 0x0B, 0x0B, 0x0B, 0xD6, 0xD6, 0xD6, 0xD6 15 | dma_clear_reg dw 0x0C, 0x0C, 0x0C, 0x0C, 0xD8, 0xD8, 0xD8, 0xD8 16 | dma_page_port dw 0x87, 0x83, 0x81, 0x82, 0x8F, 0x8B, 0x89, 0x8A 17 | dma_addr_port dw 0x00, 0x02, 0x04, 0x06, 0xC0, 0xC4, 0xC8, 0xCC 18 | dma_count_port dw 0x01, 0x03, 0x05, 0x07, 0xC2, 0xC6, 0xCA, 0xCE 19 | 20 | 21 | ;-----------------------------------; 22 | ; dma transfer ; 23 | ; ; 24 | ; in: ecx = page:offset ; 25 | ; bl = channel ; 26 | ; bh = 1=read, 0=write ; 27 | ; esi = count ; 28 | ; ; 29 | ; out: nothing. ; 30 | ;-----------------------------------; 31 | dma_transfer: 32 | push eax 33 | push edx 34 | push esi 35 | cli 36 | or bh, bh 37 | jz .dont_read 38 | 39 | mov bh, bl 40 | add bh, 0x48 41 | jmp .read 42 | .dont_read: 43 | mov bh, bl 44 | add bh, 0x44 45 | .read: 46 | dec esi 47 | 48 | movzx eax, bl 49 | mov dx, word [(eax*2)+dma_mask_reg] 50 | mov al, bl 51 | or al, 0x04 52 | out dx, al ; disable the channel 53 | 54 | movzx eax, bl 55 | mov dx, word [(eax*2)+dma_clear_reg] 56 | mov al, 0 57 | out dx, al ; initialize flip-flop 58 | 59 | movzx eax, bl 60 | mov dx, word [(eax*2)+dma_mode_reg] 61 | mov al, bh 62 | out dx, al ; set DMA mode 63 | 64 | movzx eax, bl 65 | mov dx, word [(eax*2)+dma_addr_port] 66 | mov al, cl 67 | out dx, al ; write low offset part 68 | mov al, ch 69 | out dx, al ; and high offset part 70 | 71 | movzx eax, bl 72 | mov dx, word [(eax*2)+dma_page_port] 73 | mov eax, ecx 74 | shr eax, 16 75 | out dx, al ; write page. 76 | 77 | movzx eax, bl 78 | mov dx, word [(eax*2)+dma_count_port] 79 | mov eax, esi 80 | out dx, al ; low count 81 | mov al, ah 82 | out dx, al ; high count 83 | 84 | movzx eax, bl 85 | mov dx, word [(eax*2)+dma_mask_reg] 86 | mov al, bl 87 | out dx, al ; enable channel 88 | 89 | sti 90 | pop esi 91 | pop edx 92 | pop eax 93 | ret -------------------------------------------------------------------------------- /kernel/init/bios.asm: -------------------------------------------------------------------------------- 1 | ;----------------------------------------------------------; 2 | ; BOS kernel Christoffer Bubach, 2003-2005. ; 3 | ;----------------------------------------------------------; 4 | ; ; 5 | ; Goes back to realmode to do an INT. ; 6 | ; ; 7 | ;----------------------------------------------------------; 8 | 9 | 10 | rmode_int: 11 | pushad 12 | push eax 13 | shr eax, 16 ; move high bits to ax 14 | mov word [realmode_ax], ax ; save new ax value 15 | pop eax ; restore 16 | 17 | push ebx 18 | shr ebx, 16 ; move high bits to bx 19 | mov byte [int_number], bl ; save int number to call 20 | pop ebx 21 | 22 | mov byte [realmode_error], 0 ; all variables is in the 23 | mov word [realmode_bx], bx ; realmode/variables.inc file 24 | mov word [realmode_cx], cx 25 | mov word [realmode_dx], dx 26 | call disable_irqs 27 | jmp pword 0x18:do_16pmode ; begin our dark journey into 16bit-land 28 | 29 | use16 30 | do_16pmode: 31 | mov ax, 0x20 32 | mov ds, ax 33 | mov es, ax 34 | mov fs, ax 35 | mov gs, ax 36 | mov ss, ax 37 | 38 | cli 39 | mov eax, cr0 40 | and al, 0xFE 41 | mov cr0, eax 42 | 43 | jmp 0x0000:(do_realm) ; this should be triple checked! 44 | 45 | do_realm: 46 | mov ax, cs 47 | mov ds, ax 48 | 49 | xor ax, ax 50 | mov es, ax 51 | mov fs, ax 52 | mov gs, ax 53 | mov ss, ax 54 | 55 | lidt [ridtr] ; realmode/variables.inc 56 | sti 57 | 58 | mov ax, word [realmode_ax] 59 | mov bx, word [realmode_bx] 60 | mov cx, word [realmode_cx] 61 | mov dx, word [realmode_dx] 62 | 63 | push ax ; this is some cool shit.. ;) 64 | mov al, [int_number] ; interrupt to preform 65 | mov [$+5], al ; move it to right pos. 66 | pop ax 67 | db 0xCD ; opcode for int. 68 | db 0x00 ; move int_number here 69 | 70 | jnc .no_error 71 | mov byte [realmode_error], 1 72 | 73 | .no_error: 74 | mov word [realmode_ax], ax 75 | mov word [realmode_bx], bx 76 | mov word [realmode_cx], cx 77 | mov word [realmode_dx], dx 78 | 79 | cli 80 | 81 | lgdt [gdtr] 82 | lidt [idtr] 83 | mov eax, cr0 84 | or al, 1 85 | mov cr0, eax 86 | 87 | jmp pword 0x08:gobackto_pm 88 | 89 | 90 | use32 91 | gobackto_pm: 92 | mov ax, 0x10 ; refresh all segment registers 93 | mov ds, ax 94 | mov es, ax 95 | mov fs, ax 96 | mov gs, ax 97 | mov ss, ax 98 | call enable_irqs 99 | sti 100 | popad 101 | clc ; clear carry. 102 | cmp [realmode_error], 1 ; if error, then 103 | jne .end 104 | stc ; set carry. 105 | .end: 106 | ret -------------------------------------------------------------------------------- /kernel/init/cmos.asm: -------------------------------------------------------------------------------- 1 | ;----------------------------------------------------------; 2 | ; BOS kernel Christoffer Bubach, 2005. ; 3 | ;----------------------------------------------------------; 4 | ; ; 5 | ; To get stuff ( time & date ) from CMOS memory. ; 6 | ; ; 7 | ;----------------------------------------------------------; 8 | 9 | 10 | ;-----------------------------------; 11 | ; variables containing CMOS data ; 12 | ;-----------------------------------; 13 | century db 0 ; latest century, 14 | year db 0 ; year, 15 | month db 0 ; month, 16 | day db 0 ; day (1 = sunday), 17 | hour db 0 ; hour, 18 | minute db 0 ; minute and 19 | second db 0 ; second read in from CMOS. 20 | 21 | 22 | ;-------------------------; 23 | ; save info from CMOS ; 24 | ;-------------------------; 25 | get_cmos_data: 26 | push ax 27 | 28 | mov al, 0x00 ; get the "second" byte 29 | out 0x70, al 30 | in al, 0x71 31 | mov [second], al ; save it. 32 | 33 | mov al, 0x02 ; get the "minute" byte 34 | out 0x70, al 35 | in al, 0x71 36 | mov [minute], al 37 | 38 | mov al, 0x04 ; get the "hour" byte 39 | out 0x70, al 40 | in al, 0x71 41 | mov [hour], al 42 | 43 | mov al, 0x07 ; get the "day" byte 44 | out 0x70, al 45 | in al, 0x71 46 | mov [day], al 47 | 48 | mov al, 0x08 ; get the "month" byte 49 | out 0x70, al 50 | in al, 0x71 51 | mov [month], al 52 | 53 | mov al, 0x09 ; get the "year" byte 54 | out 0x70, al 55 | in al, 0x71 56 | mov [year], al 57 | 58 | mov al, 0x32 ; get the "century" byte 59 | out 0x70, al 60 | in al, 0x71 61 | mov [century], al 62 | 63 | pop ax 64 | ret 65 | 66 | ;------------------------------------------------; 67 | ; calculate binary from BCD ; 68 | ; in: al = BCD ; 69 | ; out: al = bin ; 70 | ;------------------------------------------------; 71 | BCD2bin: 72 | push ebx 73 | mov bl, al ; bl = al mod 16 74 | and bl, 0x0F 75 | shr al, 4 ; al = al / 16 76 | mov bh, 10 77 | mul bh ; multiply by 10 78 | add al, bl ; add in low nib 79 | pop ebx 80 | ret 81 | 82 | 83 | ;------------------------------------------------; 84 | ; calculate ASCII from BCD ; 85 | ; in: al = BCD ; 86 | ; out: ax = ASCII ; 87 | ;------------------------------------------------; 88 | BCD2ascii: 89 | push ecx 90 | mov ah, al 91 | and ax, 0xF00F ; mask bits 92 | shr ah, 4 ; right shift ah to get unpacked BCD 93 | or ax, 0x3030 ; combine with 30 to get ASCII 94 | xchg ah, al ; swap for ASCII storage convention 95 | pop ecx 96 | ret -------------------------------------------------------------------------------- /kernel/init/init32b.asm: -------------------------------------------------------------------------------- 1 | ;----------------------------------------------------------; 2 | ; BOS kernel Christoffer Bubach, 2003-2005. ; 3 | ;----------------------------------------------------------; 4 | ; ; 5 | ; Initiation function for BOS ; 6 | ; ; 7 | ;----------------------------------------------------------; 8 | 9 | 10 | bos_init: 11 | 12 | ;----------------------; 13 | ; we are in pmode.. ; 14 | ;----------------------; 15 | mov bx, 0x0193 16 | call setcursor 17 | mov esi, pmode_load 18 | mov bl, 0x07 19 | call print 20 | 21 | mov bx, 0x01C5 22 | call setcursor 23 | mov esi, pmode_load_ok 24 | mov bl, 0x02 25 | call print 26 | 27 | ;----------------------; 28 | ; kernel loaded.. ; 29 | ;----------------------; 30 | mov bx, 0x01E3 31 | call setcursor 32 | mov esi, kernel_load 33 | mov bl, 0x07 34 | call print 35 | 36 | mov bx, 0x0215 37 | call setcursor 38 | mov esi, kernel_load_ok 39 | mov bl, 0x02 40 | call print 41 | 42 | ;----------------; 43 | ; remap PICs ; 44 | ;----------------; 45 | mov cl, 0x20 ; PIC 1, irq0-irq7 -> int 0x20-27. 46 | mov ch, 0x28 ; PIC 2, irq8-irq15 -> int 0x28-30. 47 | call remap_pics 48 | call disable_irqs 49 | 50 | mov bx, 0x0233 51 | call setcursor 52 | mov esi, pic_irq 53 | mov bl, 0x07 54 | call print 55 | 56 | mov bx, 0x0265 57 | call setcursor 58 | mov esi, pic_irq_ok 59 | mov bl, 0x02 60 | call print 61 | 62 | ;--------------; 63 | ; setup IDT ; 64 | ;--------------; 65 | mov esi, u_isr ; isr.inc 66 | call init_idt ; idt.inc 67 | mov esi, idt_list ; idt.inc 68 | call set_idt_list ; idt.inc 69 | 70 | sti ; Interrupts back. 71 | 72 | mov bx, 0x0283 73 | call setcursor 74 | mov esi, idt_mess 75 | mov bl, 0x07 76 | call print 77 | 78 | mov bx, 0x02B5 79 | call setcursor 80 | mov esi, idt_ok 81 | mov bl, 0x02 82 | call print 83 | 84 | 85 | ;---------------------------------------------; 86 | ; enable IRQs (one after one as i code it) ; 87 | ;---------------------------------------------; 88 | mov cl, 1 89 | call enable_irq ; Enable IRQ 1. 90 | 91 | mov bx, 0x02D3 92 | call setcursor 93 | mov esi, kbd_load 94 | mov bl, 0x07 95 | call print 96 | 97 | mov bx, 0x0305 98 | call setcursor 99 | mov esi, kbd_ok 100 | mov bl, 0x02 101 | call print 102 | 103 | ;------------------------------------; 104 | ; get CMOS data, set PIT to 100Hz ; 105 | ; and start timer. ; 106 | ;------------------------------------; 107 | call get_cmos_data ; cmos.inc 108 | call set_pit_freq ; timer.inc 109 | mov cl, 0 110 | call enable_irq ; Enable IRQ 0. 111 | 112 | ;-------------------; 113 | ; init simple MM ; 114 | ;-------------------; 115 | mov ebx, 0x100000 ; address of first free 116 | mov ecx, [ram_amount] ; RAM. everything before 117 | call init_mem ; that is reserved. 118 | 119 | ;--------------------; 120 | ; init fdc driver ; 121 | ;--------------------; 122 | call fdc_init ; fdc.inc 123 | 124 | 125 | ;-------------------------; 126 | ; return to kernel.asm ; 127 | ;-------------------------; 128 | ret -------------------------------------------------------------------------------- /kernel/init/pic.asm: -------------------------------------------------------------------------------- 1 | ;----------------------------------------------------------; 2 | ; BOS 0.04 Christoffer Bubach, 2004. ; 3 | ;----------------------------------------------------------; 4 | ; ; 5 | ; PIC/IRQ handling. ; 6 | ; ; 7 | ;----------------------------------------------------------; 8 | 9 | 10 | ;-------------------------------------------; 11 | ; remap PICs ; 12 | ; in: cl = pic1 ; 13 | ; ch = pic2 ; 14 | ;-------------------------------------------; 15 | remap_pics: 16 | push ax 17 | push dx 18 | 19 | mov al, 0x11 ; IWC1 20 | out 0x20, al 21 | out 0xA0, al 22 | 23 | mov al, cl ; IWC2 24 | out 0x21, al 25 | mov al, ch 26 | out 0xA1, al 27 | 28 | mov al, 0x04 ; IWC3 29 | out 0x21, al 30 | mov al, 0x02 31 | out 0xA1, al 32 | 33 | mov al, 0x01 ; IWC4 34 | out 0x21, al 35 | out 0xA1, al 36 | 37 | pop dx 38 | pop ax 39 | ret 40 | 41 | 42 | ;----------------------; 43 | ; disable all IRQs. ; 44 | ;----------------------; 45 | disable_irqs: 46 | push ax 47 | 48 | mov al, 0xFF 49 | out 0x21, al 50 | out 0xA1, al 51 | 52 | pop ax 53 | ret 54 | 55 | 56 | ;---------------------; 57 | ; enable all IRQs. ; 58 | ;---------------------; 59 | enable_irqs: 60 | push ax 61 | 62 | mov al, 0x00 63 | out 0x21, al 64 | out 0xA1, al 65 | 66 | pop ax 67 | ret 68 | 69 | 70 | ;-----------------------------; 71 | ; enable an IRQ. cl = irq ; 72 | ;-----------------------------; 73 | enable_irq: 74 | push ax 75 | push cx 76 | 77 | cmp cl, 8 78 | jb .master 79 | 80 | sub cl, 8 81 | mov ah, 1 82 | shl ah, cl 83 | xor ah, 0xFF 84 | 85 | in al, 0xA1 86 | and al, ah 87 | out 0xA1, al 88 | 89 | pop cx 90 | pop ax 91 | ret 92 | .master: 93 | mov ah, 1 94 | shl ah, cl 95 | xor ah, 0xFF 96 | 97 | in al, 0x21 98 | and al, ah 99 | out 0x21, al 100 | 101 | pop cx 102 | pop ax 103 | ret 104 | 105 | 106 | ;------------------------------; 107 | ; disable an IRQ. ; 108 | ; in: cl = irq ; 109 | ;------------------------------; 110 | disable_irq: 111 | push ax 112 | push cx 113 | 114 | cmp cl, 8 115 | jb .master 116 | 117 | sub cl, 8 118 | mov ah, 1 119 | shl ah, cl 120 | 121 | in al, 0xA1 122 | or al, ah 123 | out 0xA1, al 124 | 125 | pop cx 126 | pop ax 127 | ret 128 | .master: 129 | mov ah, 1 130 | shl ah, cl 131 | 132 | in al, 0x21 133 | or al, ah 134 | out 0x21, al 135 | 136 | pop cx 137 | pop ax 138 | ret -------------------------------------------------------------------------------- /kernel/init/timer.asm: -------------------------------------------------------------------------------- 1 | ;----------------------------------------------------------; 2 | ; BOS kernel Christoffer Bubach, 2005. ; 3 | ;----------------------------------------------------------; 4 | ; ; 5 | ; Function to set up the timer IRQ. ; 6 | ; ; 7 | ;----------------------------------------------------------; 8 | 9 | ;-----------------; 10 | ; variables ; 11 | ;-----------------; 12 | timer_wait dd 0 ; time to wait 13 | timer_counter dd 0, 0 ; time since BOS started 14 | call_list dd 0, 0, 0, 0, 0 ; functions to call 15 | 16 | 17 | ;---------------------------; 18 | ; Timer IRQ(0) ; 19 | ;---------------------------; 20 | timer: 21 | add dword [timer_counter], 1 ; it's just a 64-bit 22 | adc dword [timer_counter+4], 0 ; counter since boot. 23 | 24 | cmp [timer_wait], 0 ; "delay" countdown. 25 | je .test1 26 | dec [timer_wait] 27 | 28 | .test1: ; checks for calls to 29 | cmp [call_list], dword 0 ; do before we quit. 30 | je .test2 31 | call dword [call_list] 32 | .test2: 33 | cmp [call_list+4], dword 0 34 | je .test3 35 | call dword [call_list+4] 36 | .test3: 37 | cmp [call_list+8], dword 0 38 | je .test4 39 | call dword [call_list+8] 40 | .test4: 41 | cmp [call_list+12], dword 0 42 | je .test5 43 | call dword [call_list+12] 44 | .test5: 45 | cmp [call_list+16], dword 0 46 | je .end 47 | call dword [call_list+16] 48 | 49 | .end: 50 | mov al, 0x20 51 | out 0x20, al 52 | ret 53 | 54 | 55 | 56 | ;------------------------------------------------; 57 | ; add function for the timer to call ; 58 | ; in: ebx = function address ; 59 | ; out: eax = 0 if OK ; 60 | ;------------------------------------------------; 61 | add_timercall: 62 | cmp [call_list], 0 63 | jne .test2 64 | mov [call_list], ebx 65 | jmp .end 66 | .error: 67 | mov eax, 1 68 | ret 69 | .test2: 70 | cmp [call_list+4], 0 ; since i am so lazy 71 | jne .test3 ; and a loop can be 72 | mov [call_list+4], ebx ; rather complicated 73 | jmp .end ; for this stuff, i 74 | .test3: ; check for each one.. 75 | cmp [call_list+8], 0 ; after all, it's only 5. 76 | jne .test4 77 | mov [call_list+8], ebx 78 | jmp .end 79 | .test4: 80 | cmp [call_list+12], 0 81 | jne .test5 82 | mov [call_list+12], ebx 83 | jmp .end 84 | .test5: 85 | cmp [call_list+16], 0 86 | jne .error 87 | mov [call_list+16], ebx 88 | .end: 89 | xor eax, eax 90 | ret 91 | 92 | 93 | 94 | ;-------------------------------------------------; 95 | ; remove function from the call list ; 96 | ; in: ebx = function address ; 97 | ; out: eax = 0 if OK ; 98 | ;-------------------------------------------------; 99 | remove_timercall: 100 | cmp [call_list], ebx 101 | jne .test2 102 | mov [call_list], dword 0 103 | jmp .end 104 | .error: 105 | mov eax, 1 106 | ret 107 | .test2: 108 | cmp [call_list+4], ebx 109 | jne .test3 110 | mov [call_list+4], dword 0 111 | jmp .end 112 | .test3: 113 | cmp [call_list+8], ebx 114 | jne .test4 115 | mov [call_list+8], dword 0 116 | jmp .end 117 | .test4: 118 | cmp [call_list+12], ebx 119 | jne .test5 120 | mov [call_list+12], dword 0 121 | jmp .end 122 | .test5: 123 | cmp [call_list+16], ebx 124 | jne .error 125 | mov [call_list+16], dword 0 126 | .end: 127 | xor eax, eax 128 | ret 129 | 130 | 131 | 132 | ;--------------------------------------------; 133 | ; delay function ; 134 | ; in: ecx = 100/second to wait ; 135 | ; out: nothing ; 136 | ;--------------------------------------------; 137 | delay: 138 | mov [timer_wait], ecx ; mov value to "timer" 139 | .loop: 140 | cmp [timer_wait], 0 141 | jne .loop 142 | ret 143 | 144 | 145 | 146 | ;--------------------------------------------; 147 | ; "active" delay ; 148 | ; ; 149 | ; gives the caller a pointer to the counter ; 150 | ; so that it can check for timeouts etc, ; 151 | ; itself. ; 152 | ; in: ecx = 100/second to wait ; 153 | ; out: ecx = pointer to counter ; 154 | ;--------------------------------------------; 155 | active_delay: 156 | mov [timer_wait], ecx ; mov value to "timer" 157 | mov ecx, timer_wait ; let caller check value 158 | ret 159 | 160 | 161 | 162 | ;------------------------------; 163 | ; set PIT to 100Hz ; 164 | ;------------------------------; 165 | set_pit_freq: 166 | push eax 167 | mov al, 0x34 ; set to 100Hz, 0x34 = 00110100b 168 | out 0x43, al 169 | mov al, 0x9B ; lsb 1193180 / 1193 170 | out 0x40, al 171 | mov al, 0x2E ; msb 172 | out 0x40, al 173 | pop eax 174 | ret -------------------------------------------------------------------------------- /kernel/int/debug.asm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bubach/BOS/a2421e39f4c4ce2d834a1850c706153e5bf04af8/kernel/int/debug.asm -------------------------------------------------------------------------------- /kernel/int/idt.asm: -------------------------------------------------------------------------------- 1 | ;----------------------------------------------------------; 2 | ; BOS kernel Christoffer Bubach, 2003-2015. ; 3 | ;----------------------------------------------------------; 4 | ; ; 5 | ; Set/modify IDT entries ; 6 | ; ; 7 | ;----------------------------------------------------------; 8 | 9 | ;-----------------------------------------------------; 10 | ; ; 11 | ; IDT entry structure ; 12 | ; ; 13 | ; 16bit - entry offset bits 0..15 ; 14 | ; 16bit - code segment selector in GDT or LDT ; 15 | ; 8bit - unused, set to 0 ; 16 | ; 8bit - type and attributes ; 17 | ; - 0xE = 32bit intterrupt ; 18 | ; - 0x8 = Present bit = 1 ; 19 | ; 16bit - entry offset bits 16..31 ; 20 | ; ; 21 | ; middle section for code segment 08 = 0x8E000008 ; 22 | ;-----------------------------------------------------; 23 | 24 | 25 | ;--------------------------------------------------; 26 | ; set up IDT ; 27 | ; in: esi = pointer to "unhandled int"-function. ; 28 | ;--------------------------------------------------; 29 | init_idt: 30 | push eax 31 | push ecx 32 | push edi 33 | 34 | xor edi, edi 35 | xor ecx, ecx 36 | add edi, [idtr.address] 37 | .l1: ; loop full IDT table 38 | mov eax, esi 39 | mov word [edi], ax ; set handler lower offset 40 | add edi, 2 41 | 42 | mov dword [edi], 0x8E000008 ; set IDT segment and attributes 43 | add edi, 4 44 | 45 | mov eax, esi 46 | shr eax, 16 47 | mov word [edi], ax ; set handler high offset 48 | add edi, 2 49 | 50 | add cx, 8 ; 8byte * 51 | cmp cx, word [idtr.size] ; 256 ints 52 | jb .l1 ; = done? 53 | 54 | pop edi 55 | pop ecx 56 | pop eax 57 | ret 58 | 59 | 60 | 61 | ;--------------------------------------; 62 | ; modify IDT, set any int ; 63 | ; in: cl = int number ; 64 | ; edi = int function pointer ; 65 | ;--------------------------------------; 66 | set_int: 67 | push eax 68 | push ecx 69 | 70 | mov al, 8 ; 8 bytes for each int 71 | mul cl ; cl * al = ax 72 | movzx ecx, ax ; ecx = IDT offset 73 | shr ecx, 1 ; 1/2 for dword list 74 | mov dword [(idt_list+ecx)], edi ; add to dword int list 75 | movzx ecx, ax ; ecx = IDT offset 76 | 77 | mov eax, edi 78 | mov [(0x6c00+ecx)], ax 79 | add ecx, 2 80 | 81 | mov dword [(0x6c00+ecx)], 0x8E000008 82 | add ecx, 4 83 | 84 | mov eax, edi 85 | shr eax, 16 86 | mov [(0x6c00+ecx)], ax 87 | 88 | pop ecx 89 | pop eax 90 | ret 91 | 92 | 93 | 94 | ;------------------------------------------------; 95 | ; get int address ; 96 | ; in: cl = int number ; 97 | ; out: esi = address or 0 if none present ; 98 | ;------------------------------------------------; 99 | get_int: 100 | push eax 101 | 102 | mov eax, 4 ; 4 bytes for each address 103 | mul cl ; cl * al = ax 104 | mov esi, idt_list 105 | add esi, eax 106 | 107 | pop eax 108 | ret 109 | 110 | 111 | 112 | 113 | ;----------------------------------------; 114 | ; sets ints from list ; 115 | ; in: esi = pointer to int list ; 116 | ;----------------------------------------; 117 | set_idt_list: 118 | push eax 119 | push edi 120 | 121 | xor ecx, ecx 122 | .l1: 123 | lodsd 124 | or eax, eax 125 | jz .next 126 | mov edi, eax 127 | call set_int 128 | .next: 129 | inc ecx 130 | cmp ecx, 0x100 131 | jb .l1 132 | 133 | pop edi 134 | pop eax 135 | ret 136 | 137 | 138 | 139 | ;------------------------------; 140 | ; list of idt entries. ; 141 | ; 0 = not handled ; 142 | ;------------------------------; 143 | idt_list: dd isr00 144 | dd isr01 145 | dd isr02 146 | dd isr03 147 | dd isr04 148 | dd isr05 149 | dd isr06 150 | dd isr07 151 | dd isr08 152 | dd isr09 153 | dd isr0A 154 | dd isr0B 155 | dd isr0C 156 | dd isr0D 157 | dd isr0E 158 | dd 0 159 | dd isr10 160 | dd isr11 161 | dd isr12 162 | dd isr13 163 | times 12 dd 0 ; 12 unused ints 164 | dd isr20 165 | dd isr21 166 | times 16 dd 0 ; 16 unused ints 167 | dd isr32 ; First free and BOS system interrupt. 168 | times 205 dd 0 ; 205 unused ints -------------------------------------------------------------------------------- /kernel/int/isr.asm: -------------------------------------------------------------------------------- 1 | ;----------------------------------------------------------; 2 | ; BOS 0.04 Christoffer Bubach, 2004. ; 3 | ;----------------------------------------------------------; 4 | ; ; 5 | ; ISR (Interrupt Service Rutines). ; 6 | ; ; 7 | ;----------------------------------------------------------; 8 | 9 | 10 | 11 | ;------------------------; 12 | ; Unhandled Interrupt ; 13 | ;------------------------; 14 | u_isr: 15 | mov [dbg_keypress], 0 ; in debug.inc 16 | mov [dbg_error], 'U' 17 | mov [dbg_error+1], 'n' 18 | mov [dbg_error+2], 'h' 19 | mov [dbg_error+3], 'a' 20 | mov [dbg_error+4], 'n' 21 | mov [dbg_error+5], 'd' 22 | mov [dbg_error+6], 'l' 23 | mov [dbg_error+7], 'e' 24 | mov [dbg_error+8], 'd' 25 | mov [dbg_error+9], ' ' 26 | mov [dbg_error+10], 'I' 27 | mov [dbg_error+11], 'n' 28 | mov [dbg_error+12], 't' 29 | mov [dbg_error+13], ' ' 30 | mov [dbg_error+14], 0 31 | call dump_regs 32 | 33 | 34 | ;-------------------------------; 35 | ; Exception Interrupt no. 00 ; 36 | ;-------------------------------; 37 | isr00: 38 | mov [dbg_keypress], 0 39 | mov [dbg_error], 'D' 40 | mov [dbg_error+1], 'i' 41 | mov [dbg_error+2], 'v' 42 | mov [dbg_error+3], 'i' 43 | mov [dbg_error+4], 'd' 44 | mov [dbg_error+5], 'e' 45 | mov [dbg_error+6], ' ' 46 | mov [dbg_error+7], 'e' 47 | mov [dbg_error+8], 'r' 48 | mov [dbg_error+9], 'r' 49 | mov [dbg_error+10], 'o' 50 | mov [dbg_error+11], 'r' 51 | mov [dbg_error+12], ' ' 52 | mov [dbg_error+13], ' ' 53 | mov [dbg_error+14], 0 54 | call dump_regs 55 | 56 | 57 | ;-------------------------------; 58 | ; Exception Interrupt no. 01 ; 59 | ;-------------------------------; 60 | isr01: 61 | mov [dbg_keypress], 0 62 | mov [dbg_error], 'D' 63 | mov [dbg_error+1], 'e' 64 | mov [dbg_error+2], 'b' 65 | mov [dbg_error+3], 'u' 66 | mov [dbg_error+4], 'g' 67 | mov [dbg_error+5], ' ' 68 | mov [dbg_error+6], 'f' 69 | mov [dbg_error+7], 'a' 70 | mov [dbg_error+8], 'u' 71 | mov [dbg_error+9], 'l' 72 | mov [dbg_error+10], 't' 73 | mov [dbg_error+11], ' ' 74 | mov [dbg_error+12], ' ' 75 | mov [dbg_error+13], ' ' 76 | mov [dbg_error+14], 0 77 | call dump_regs 78 | 79 | 80 | ;-------------------------------; 81 | ; Exception Interrupt no. 02 ; 82 | ;-------------------------------; 83 | isr02: 84 | mov [dbg_keypress], 0 85 | mov [dbg_error], 'N' 86 | mov [dbg_error+1], 'M' 87 | mov [dbg_error+2], 'I' 88 | mov [dbg_error+3], ' ' 89 | mov [dbg_error+4], 'i' 90 | mov [dbg_error+5], 'n' 91 | mov [dbg_error+6], 't' 92 | mov [dbg_error+7], 'e' 93 | mov [dbg_error+8], 'r' 94 | mov [dbg_error+9], 'r' 95 | mov [dbg_error+10], 'u' 96 | mov [dbg_error+11], 'p' 97 | mov [dbg_error+12], 't' 98 | mov [dbg_error+13], ' ' 99 | mov [dbg_error+14], 0 100 | call dump_regs 101 | 102 | 103 | ;-------------------------------; 104 | ; Exception Interrupt no. 03 ; 105 | ;-------------------------------; 106 | isr03: 107 | mov [dbg_keypress], 0 108 | mov [dbg_error], 'B' 109 | mov [dbg_error+1], 'r' 110 | mov [dbg_error+2], 'e' 111 | mov [dbg_error+3], 'a' 112 | mov [dbg_error+4], 'k' 113 | mov [dbg_error+5], 'p' 114 | mov [dbg_error+6], 'o' 115 | mov [dbg_error+7], 'i' 116 | mov [dbg_error+8], 'n' 117 | mov [dbg_error+9], 't' 118 | mov [dbg_error+10], ' ' 119 | mov [dbg_error+11], ' ' 120 | mov [dbg_error+12], ' ' 121 | mov [dbg_error+13], ' ' 122 | mov [dbg_error+14], 0 123 | call dump_regs 124 | 125 | 126 | ;-------------------------------; 127 | ; Exception Interrupt no. 04 ; 128 | ;-------------------------------; 129 | isr04: 130 | mov [dbg_keypress], 0 131 | mov [dbg_error], 'O' 132 | mov [dbg_error+1], 'v' 133 | mov [dbg_error+2], 'e' 134 | mov [dbg_error+3], 'r' 135 | mov [dbg_error+4], 'f' 136 | mov [dbg_error+5], 'l' 137 | mov [dbg_error+6], 'o' 138 | mov [dbg_error+7], 'w' 139 | mov [dbg_error+8], ' ' 140 | mov [dbg_error+9], 'f' 141 | mov [dbg_error+10], 'a' 142 | mov [dbg_error+11], 'u' 143 | mov [dbg_error+12], 'l' 144 | mov [dbg_error+13], 't' 145 | mov [dbg_error+14], 0 146 | call dump_regs 147 | 148 | 149 | ;-------------------------------; 150 | ; Exception Interrupt no. 05 ; 151 | ;-------------------------------; 152 | isr05: 153 | mov [dbg_keypress], 0 154 | mov [dbg_error], 'B' 155 | mov [dbg_error+1], 'o' 156 | mov [dbg_error+2], 'u' 157 | mov [dbg_error+3], 'n' 158 | mov [dbg_error+4], 'd' 159 | mov [dbg_error+5], 's' 160 | mov [dbg_error+6], ' ' 161 | mov [dbg_error+7], 'c' 162 | mov [dbg_error+8], 'h' 163 | mov [dbg_error+9], 'e' 164 | mov [dbg_error+10], 'c' 165 | mov [dbg_error+11], 'k' 166 | mov [dbg_error+12], ' ' 167 | mov [dbg_error+13], ' ' 168 | mov [dbg_error+14], 0 169 | call dump_regs 170 | 171 | 172 | ;-------------------------------; 173 | ; Exception Interrupt no. 06 ; 174 | ;-------------------------------; 175 | isr06: 176 | mov [dbg_keypress], 0 177 | mov [dbg_error], 'I' 178 | mov [dbg_error+1], 'n' 179 | mov [dbg_error+2], 'v' 180 | mov [dbg_error+3], 'a' 181 | mov [dbg_error+4], 'l' 182 | mov [dbg_error+5], 'i' 183 | mov [dbg_error+6], 'd' 184 | mov [dbg_error+7], ' ' 185 | mov [dbg_error+8], 'o' 186 | mov [dbg_error+9], 'p' 187 | mov [dbg_error+10], 'c' 188 | mov [dbg_error+11], 'o' 189 | mov [dbg_error+12], 'd' 190 | mov [dbg_error+13], 'e' 191 | mov [dbg_error+14], 0 192 | call dump_regs 193 | 194 | 195 | ;-------------------------------; 196 | ; Exception Interrupt no. 07 ; 197 | ;-------------------------------; 198 | isr07: 199 | mov [dbg_keypress], 0 200 | mov [dbg_error], 'N' 201 | mov [dbg_error+1], 'o' 202 | mov [dbg_error+2], ' ' 203 | mov [dbg_error+3], 'c' 204 | mov [dbg_error+4], 'o' 205 | mov [dbg_error+5], 'p' 206 | mov [dbg_error+6], '.' 207 | mov [dbg_error+7], ' ' 208 | mov [dbg_error+8], 'a' 209 | mov [dbg_error+9], 'v' 210 | mov [dbg_error+10], 'a' 211 | mov [dbg_error+11], 'i' 212 | mov [dbg_error+12], 'l' 213 | mov [dbg_error+13], '.' 214 | mov [dbg_error+14], 0 215 | call dump_regs 216 | 217 | 218 | ;-------------------------------; 219 | ; Exception Interrupt no. 08 ; 220 | ;-------------------------------; 221 | isr08: 222 | mov [dbg_keypress], 0 223 | mov [dbg_error], 'D' 224 | mov [dbg_error+1], 'o' 225 | mov [dbg_error+2], 'u' 226 | mov [dbg_error+3], 'b' 227 | mov [dbg_error+4], 'l' 228 | mov [dbg_error+5], 'e' 229 | mov [dbg_error+6], ' ' 230 | mov [dbg_error+7], 'f' 231 | mov [dbg_error+8], 'a' 232 | mov [dbg_error+9], 'u' 233 | mov [dbg_error+10], 'l' 234 | mov [dbg_error+11], 't' 235 | mov [dbg_error+12], ' ' 236 | mov [dbg_error+13], ' ' 237 | mov [dbg_error+14], 0 238 | call dump_regs 239 | 240 | 241 | ;-------------------------------; 242 | ; Exception Interrupt no. 09 ; 243 | ;-------------------------------; 244 | isr09: 245 | mov [dbg_keypress], 0 246 | mov [dbg_error], 'C' 247 | mov [dbg_error+1], 'o' 248 | mov [dbg_error+2], 'p' 249 | mov [dbg_error+3], 'r' 250 | mov [dbg_error+4], 'o' 251 | mov [dbg_error+5], '.' 252 | mov [dbg_error+6], ' ' 253 | mov [dbg_error+7], 's' 254 | mov [dbg_error+8], 'e' 255 | mov [dbg_error+9], 'g' 256 | mov [dbg_error+10], 'm' 257 | mov [dbg_error+11], 'e' 258 | mov [dbg_error+12], 'n' 259 | mov [dbg_error+13], 't' 260 | mov [dbg_error+14], 0 261 | call dump_regs 262 | 263 | 264 | ;-------------------------------; 265 | ; Exception Interrupt no. 10 ; 266 | ;-------------------------------; 267 | isr0A: 268 | mov [dbg_keypress], 0 269 | mov [dbg_error], 'I' 270 | mov [dbg_error+1], 'n' 271 | mov [dbg_error+2], 'v' 272 | mov [dbg_error+3], 'a' 273 | mov [dbg_error+4], 'l' 274 | mov [dbg_error+5], 'i' 275 | mov [dbg_error+6], 'd' 276 | mov [dbg_error+7], ' ' 277 | mov [dbg_error+8], 'T' 278 | mov [dbg_error+9], 'S' 279 | mov [dbg_error+10], 'S' 280 | mov [dbg_error+11], '!' 281 | mov [dbg_error+12], ' ' 282 | mov [dbg_error+13], ' ' 283 | mov [dbg_error+14], 0 284 | call dump_regs 285 | 286 | 287 | ;-------------------------------; 288 | ; Exception Interrupt no. 11 ; 289 | ;-------------------------------; 290 | isr0B: 291 | mov [dbg_keypress], 0 292 | mov [dbg_error], 'N' 293 | mov [dbg_error+1], 'o' 294 | mov [dbg_error+2], ' ' 295 | mov [dbg_error+3], 's' 296 | mov [dbg_error+4], 'e' 297 | mov [dbg_error+5], 'g' 298 | mov [dbg_error+6], 'm' 299 | mov [dbg_error+7], 'e' 300 | mov [dbg_error+8], 'n' 301 | mov [dbg_error+9], 't' 302 | mov [dbg_error+10], '!' 303 | mov [dbg_error+11], ' ' 304 | mov [dbg_error+12], ' ' 305 | mov [dbg_error+13], ' ' 306 | mov [dbg_error+14], 0 307 | call dump_regs 308 | 309 | 310 | ;-------------------------------; 311 | ; Exception Interrupt no. 12 ; 312 | ;-------------------------------; 313 | isr0C: 314 | mov [dbg_keypress], 0 315 | mov [dbg_error], 'S' 316 | mov [dbg_error+1], 't' 317 | mov [dbg_error+2], 'a' 318 | mov [dbg_error+3], 'c' 319 | mov [dbg_error+4], 'k' 320 | mov [dbg_error+5], ' ' 321 | mov [dbg_error+6], 'f' 322 | mov [dbg_error+7], 'a' 323 | mov [dbg_error+8], 'u' 324 | mov [dbg_error+9], 'l' 325 | mov [dbg_error+10], 't' 326 | mov [dbg_error+11], '!' 327 | mov [dbg_error+12], ' ' 328 | mov [dbg_error+13], ' ' 329 | mov [dbg_error+14], 0 330 | call dump_regs 331 | 332 | 333 | ;-------------------------------; 334 | ; Exception Interrupt no. 13 ; 335 | ;-------------------------------; 336 | isr0D: 337 | mov [dbg_keypress], 0 338 | mov [dbg_error], 'T' 339 | mov [dbg_error+1], 'r' 340 | mov [dbg_error+2], 'i' 341 | mov [dbg_error+3], 'p' 342 | mov [dbg_error+4], 'l' 343 | mov [dbg_error+5], 'e' 344 | mov [dbg_error+6], ' ' 345 | mov [dbg_error+7], 'f' 346 | mov [dbg_error+8], 'a' 347 | mov [dbg_error+9], 'u' 348 | mov [dbg_error+10], 'l' 349 | mov [dbg_error+11], 't' 350 | mov [dbg_error+12], '!' 351 | mov [dbg_error+13], ' ' 352 | mov [dbg_error+14], 0 353 | call dump_regs 354 | 355 | 356 | ;-------------------------------; 357 | ; Exception Interrupt no. 14 ; 358 | ;-------------------------------; 359 | isr0E: 360 | mov [dbg_keypress], 0 361 | mov [dbg_error], 'P' 362 | mov [dbg_error+1], 'a' 363 | mov [dbg_error+2], 'g' 364 | mov [dbg_error+3], 'e' 365 | mov [dbg_error+4], ' ' 366 | mov [dbg_error+5], 'f' 367 | mov [dbg_error+6], 'a' 368 | mov [dbg_error+7], 'u' 369 | mov [dbg_error+8], 'l' 370 | mov [dbg_error+9], 't' 371 | mov [dbg_error+10], '!' 372 | mov [dbg_error+11], ' ' 373 | mov [dbg_error+12], ' ' 374 | mov [dbg_error+13], ' ' 375 | mov [dbg_error+14], 0 376 | call dump_regs 377 | 378 | 379 | ;-------------------------------; 380 | ; Exception Interrupt no. 16 ; 381 | ;-------------------------------; 382 | isr10: 383 | mov [dbg_keypress], 0 384 | mov [dbg_error], 'C' 385 | mov [dbg_error+1], 'o' 386 | mov [dbg_error+2], 'p' 387 | mov [dbg_error+3], 'r' 388 | mov [dbg_error+4], 'o' 389 | mov [dbg_error+5], 'c' 390 | mov [dbg_error+6], 'e' 391 | mov [dbg_error+7], 's' 392 | mov [dbg_error+8], 's' 393 | mov [dbg_error+9], 'o' 394 | mov [dbg_error+10], 'r' 395 | mov [dbg_error+11], '!' 396 | mov [dbg_error+12], ' ' 397 | mov [dbg_error+13], ' ' 398 | mov [dbg_error+14], 0 399 | call dump_regs 400 | 401 | 402 | ;-------------------------------; 403 | ; Exception Interrupt no. 17 ; 404 | ;-------------------------------; 405 | isr11: 406 | mov [dbg_keypress], 0 407 | mov [dbg_error], 'A' 408 | mov [dbg_error+1], 'l' 409 | mov [dbg_error+2], 'i' 410 | mov [dbg_error+3], 'g' 411 | mov [dbg_error+4], 'n' 412 | mov [dbg_error+5], 'm' 413 | mov [dbg_error+6], 'e' 414 | mov [dbg_error+7], 'n' 415 | mov [dbg_error+8], 't' 416 | mov [dbg_error+9], ' ' 417 | mov [dbg_error+10], 'c' 418 | mov [dbg_error+11], 'h' 419 | mov [dbg_error+12], 'k' 420 | mov [dbg_error+13], '.' 421 | mov [dbg_error+14], 0 422 | call dump_regs 423 | 424 | 425 | ;-------------------------------; 426 | ; Exception Interrupt no. 18 ; 427 | ;-------------------------------; 428 | isr12: 429 | mov [dbg_keypress], 0 430 | mov [dbg_error], 'M' 431 | mov [dbg_error+1], 'a' 432 | mov [dbg_error+2], 'c' 433 | mov [dbg_error+3], 'h' 434 | mov [dbg_error+4], 'i' 435 | mov [dbg_error+5], 'n' 436 | mov [dbg_error+6], 'e' 437 | mov [dbg_error+7], ' ' 438 | mov [dbg_error+8], 'c' 439 | mov [dbg_error+9], 'h' 440 | mov [dbg_error+10], 'e' 441 | mov [dbg_error+11], 'c' 442 | mov [dbg_error+12], 'k' 443 | mov [dbg_error+13], '!' 444 | mov [dbg_error+14], 0 445 | call dump_regs 446 | 447 | 448 | ;-------------------------------; 449 | ; Exception Interrupt no. 19 ; 450 | ;-------------------------------; 451 | isr13: 452 | mov [dbg_keypress], 0 453 | mov [dbg_error], 'S' 454 | mov [dbg_error+1], 'I' 455 | mov [dbg_error+2], 'M' 456 | mov [dbg_error+3], 'D' 457 | mov [dbg_error+4], ' ' 458 | mov [dbg_error+5], 'f' 459 | mov [dbg_error+6], 'l' 460 | mov [dbg_error+7], 'o' 461 | mov [dbg_error+8], 'a' 462 | mov [dbg_error+9], 't' 463 | mov [dbg_error+10], '.' 464 | mov [dbg_error+11], '-' 465 | mov [dbg_error+12], 'p' 466 | mov [dbg_error+13], '.' 467 | mov [dbg_error+14], 0 468 | call dump_regs 469 | 470 | 471 | 472 | ;--------------------------; 473 | ; ISR 20. The timer. ; 474 | ;--------------------------; 475 | isr20: 476 | pusha 477 | push gs 478 | push fs 479 | push ds 480 | push es 481 | 482 | call timer ; in timer.inc 483 | 484 | pop es 485 | pop ds 486 | pop fs 487 | pop gs 488 | popa 489 | iret 490 | 491 | 492 | ;--------------------------; 493 | ; Keyboard IRQ. ISR 21. ; 494 | ;--------------------------; 495 | isr21: 496 | pusha 497 | push gs 498 | push fs 499 | push ds 500 | push es 501 | push esi 502 | 503 | call keyboard_isr ; Located in keyboard.inc 504 | 505 | pop esi 506 | pop es 507 | pop ds 508 | pop fs 509 | pop gs 510 | popa 511 | iret 512 | 513 | 514 | ;---------------------; 515 | ; Interrupt no. 50 ; 516 | ;---------------------; 517 | isr32: 518 | push gs 519 | push fs 520 | push ds 521 | push es 522 | 523 | call interrupt_32 ; Located in sys_ints.inc 524 | 525 | pop es 526 | pop ds 527 | pop fs 528 | pop gs 529 | iret -------------------------------------------------------------------------------- /kernel/kbd/keyboard.asm: -------------------------------------------------------------------------------- 1 | ;----------------------------------------------------------; 2 | ; BOS 0.04 Christoffer Bubach, 2004-2005. ; 3 | ;----------------------------------------------------------; 4 | ; ; 5 | ; Keyboard functions. IRQ, INT's and more. ; 6 | ; ; 7 | ;----------------------------------------------------------; 8 | 9 | 10 | ;--------------; 11 | ; Variabels ; 12 | ;--------------; 13 | 14 | ;--------------------------------------------------------------------------------; 15 | ; _______________________ Keyboard buffer system ; 16 | ; | | | | | | | | | | | | ; 17 | ; +---------------------+ ; 18 | ; | +----------> kbd_head, here is where we put new scan-codes. ; 19 | ; +--------------------> kbd_tail, where we last read a key. this means ; 20 | ; that we have 4 new scan-codes to read before we catch up. ; 21 | ;--------------------------------------------------------------------------------; 22 | kbd_buffer db ' A 64-byte ' 23 | db ' keyboard buffer ' 24 | kbd_head db 1 ; head must be +1 from tail 25 | kbd_tail db 0 26 | 27 | ;-------------------------------------------------------------------------; 28 | ; _________________ Flag byte: ; 29 | ; |1|1|0|0|0|1|1|1| ; 30 | ; +---------------+ 1 = True 0 = False ; 31 | ; | | | | | | | +---> shift key ; 32 | ; | | | | | | +-----> ctrl key ; 33 | ; | | | | | +-------> alt key ; 34 | ; | | | | +---------> reserved bit ; 35 | ; | | | +-----------> reserved bit ; 36 | ; | | +-------------> reserved bit ; 37 | ; | +---------------> ctrl + alt + del ; 38 | ; +-----------------> key released ; 39 | ;-------------------------------------------------------------------------; 40 | kbd_flags db 0 ; flag byte 41 | 42 | ;-------------------------------------------------------------------------; 43 | ; _________________ LED status byte: ; 44 | ; |0|0|0|0|0|1|1|1| ; 45 | ; +---------------+ 1 = True 0 = False ; 46 | ; | | +---> scroll lock ; 47 | ; | +-----> num lock ; 48 | ; +-------> caps lock ; 49 | ;-------------------------------------------------------------------------; 50 | kbd_status db 0 ; LED statusbyte 51 | 52 | 53 | ;----------------------; 54 | ; Keyboard IRQ ; 55 | ;----------------------; 56 | keyboard_isr: 57 | push eax 58 | 59 | ;-------------------------; 60 | ; get the scancode ; 61 | ;-------------------------; 62 | xor eax, eax 63 | in al, 0x60 64 | 65 | ;------------------------------; 66 | ; check if key was released ; 67 | ;------------------------------; 68 | test al, 0x80 69 | jz .key_down 70 | and byte [kbd_flags], 01111111b ; key up.. 71 | 72 | cmp al, 42+128 ; left shift up? 73 | je .shift_up 74 | cmp al, 54+128 ; right shift up? 75 | je .shift_up 76 | 77 | cmp al, 29+128 ; ctrl up? 78 | je .ctrl_up 79 | 80 | cmp al, 83+128 ; del up? 81 | je .del_up 82 | 83 | cmp al, 56+128 ; alt up? 84 | je .alt_up 85 | jmp .end 86 | 87 | ;--------------------; 88 | ; it was released ; 89 | ;--------------------; 90 | .shift_up: 91 | and byte [kbd_flags], 11111110b 92 | jmp .end 93 | 94 | .del_up: 95 | jmp .CAD_off 96 | 97 | .ctrl_up: 98 | and byte [kbd_flags], 11111101b ; ctrl off. 99 | jmp .CAD_off 100 | 101 | .alt_up: 102 | and byte [kbd_flags], 11111011b ; alt off. 103 | jmp .CAD_off 104 | 105 | .CAD_off: 106 | test byte [kbd_flags], 01000000b 107 | jz .CAD_is_off 108 | and byte [kbd_flags], 10111111b ; ctrl+alt+del bit off. 109 | .CAD_is_off: 110 | jmp .end 111 | 112 | ;----------------------------------------------; 113 | ; a key was pressed, check for special keys ; 114 | ;----------------------------------------------; 115 | .key_down: 116 | or byte [kbd_flags], 10000000b 117 | 118 | .shift: 119 | cmp al, 42 120 | jnz .check_rshift 121 | or byte [kbd_flags], 00000001b 122 | jmp .end 123 | 124 | .check_rshift: 125 | cmp al, 54 126 | jnz .check_ctrl 127 | or byte [kbd_flags], 00000001b 128 | jmp .end 129 | 130 | .check_ctrl: 131 | cmp al, 29 132 | jnz .check_alt 133 | or byte [kbd_flags], 00000010b 134 | jmp .end 135 | 136 | .check_alt: 137 | cmp al, 56 138 | jnz .ctrl_alt_del 139 | or byte [kbd_flags], 00000100b 140 | jmp .end 141 | 142 | .ctrl_alt_del: 143 | test byte [kbd_flags], 00000110b ; check for ctrl+alt 144 | jz .check_caps 145 | cmp al, 83 ; check for delete 146 | jne .check_caps 147 | or byte [kbd_flags], 01000000b ; ctrl+alt+del bit on. 148 | 149 | ;-------------------------------------; 150 | ; toggle caps, num and scroll lock ; 151 | ;-------------------------------------; 152 | .check_caps: 153 | cmp al, 58 154 | jnz .check_num 155 | xor byte [kbd_status], 4 156 | call update_leds 157 | jmp .end 158 | 159 | .check_num: 160 | cmp al, 69 161 | jnz .check_scroll 162 | xor byte [kbd_status], 2 163 | call update_leds 164 | jmp .end 165 | 166 | .check_scroll: 167 | cmp al, 70 168 | jnz .end 169 | xor byte [kbd_status], 1 170 | call update_leds 171 | jmp .end 172 | 173 | ;-----------------------------------; 174 | ; put the scancode in the buffer ; 175 | ;-----------------------------------; 176 | .end: 177 | push eax 178 | mov edi, kbd_buffer 179 | xor eax, eax 180 | mov al, [kbd_head] 181 | add edi, eax 182 | pop eax 183 | stosb 184 | cmp [kbd_head], 63 ; if we reach the buffer 185 | jne .cont1 ; end, go back to 0. 186 | cmp [kbd_tail], 0 187 | je .error 188 | mov [kbd_head], 0 189 | jmp .quit 190 | .cont1: 191 | mov ah, [kbd_tail] 192 | mov al, [kbd_head] 193 | add al, 1 194 | cmp ah, al 195 | je .error 196 | inc [kbd_head] 197 | jmp .quit 198 | .error: 199 | call beep ; pc_speaker.inc 200 | mov [kbd_head], 1 ; fix it as good 201 | mov [kbd_tail], 0 ; as possible.. :S 202 | .quit: 203 | mov al, 0x20 204 | out 0x20, al 205 | pop eax 206 | ret 207 | 208 | 209 | 210 | ;------------------------------; 211 | ; Update the keyboard LED's ; 212 | ;------------------------------; 213 | update_leds: 214 | push ax 215 | 216 | call kbd_wait 217 | mov al, 0xED 218 | out 0x60, al 219 | call kbd_wait 220 | mov al, [kbd_status] 221 | out 0x60, al 222 | call kbd_wait 223 | 224 | pop ax 225 | ret 226 | 227 | 228 | 229 | ;------------------; 230 | ; keyboard wait ; 231 | ;------------------; 232 | kbd_wait: 233 | jmp $+2 234 | in al, 0x64 235 | test al, 1 236 | jz .ok 237 | jmp $+2 238 | in al, 0x60 239 | jmp kbd_wait 240 | .ok: 241 | test al, 2 242 | jnz kbd_wait 243 | ret 244 | 245 | 246 | 247 | ;-------------------------------------------------------; 248 | ; BOS INT to get a char. ; 249 | ; out: ah = scan code, al = ascii ; 250 | ; bh = flag-byte, bl = led-byte ; 251 | ;-------------------------------------------------------; 252 | getc: 253 | push esi 254 | 255 | .no_new: 256 | mov al, [kbd_head] 257 | mov ah, [kbd_tail] 258 | cmp ah, 63 259 | jne .check2 260 | cmp al, 0 261 | je .no_new 262 | mov [kbd_tail], 0 263 | jmp .done_check 264 | .check2: 265 | mov bl, ah 266 | inc bl 267 | cmp bl, al 268 | je .no_new 269 | inc [kbd_tail] 270 | .done_check: 271 | 272 | mov esi, kbd_buffer 273 | movzx eax, [kbd_tail] 274 | add esi, eax 275 | mov ah, byte [esi] ; ah = scancode 276 | movzx esi, byte [esi] ; esi = scancode 277 | 278 | ;------------------; 279 | ; some checks.. ; 280 | ;------------------; 281 | cmp ah, 0xFA 282 | je .no_new 283 | cmp ah, 0xE0 284 | je .no_new 285 | cmp ah, 0xE1 286 | je .no_new 287 | test ah, 0x80 288 | jnz .no_new 289 | 290 | ;--------------------------------; 291 | ; check for caps, shift & alt ; 292 | ;--------------------------------; 293 | test [kbd_status], 00000100b 294 | jnz .caps 295 | test [kbd_flags], 00000001b 296 | jnz .shift 297 | 298 | ;------------------; 299 | ; normal keymap ; 300 | ;------------------; 301 | mov al, [esi+keymap] ; scancode + keymap = ascii 302 | jmp .end 303 | 304 | ;--------------------; 305 | ; capslock keymap ; 306 | ;--------------------; 307 | .caps: 308 | test [kbd_flags], 00000001b 309 | jnz .caps_and_shift 310 | 311 | mov al, [esi+keymap_caps] 312 | jmp .end 313 | 314 | ;--------------------------; 315 | ; caps and shift keymap ; 316 | ;--------------------------; 317 | .caps_and_shift: 318 | mov al, [esi+keymap_caps_shift] 319 | jmp .end 320 | 321 | ;-----------------; 322 | ; shift keymap ; 323 | ;-----------------; 324 | .shift: 325 | mov al, [esi+keymap_shift] 326 | jmp .end 327 | 328 | ;---------------------------; 329 | ; set registers and exit ; 330 | ;---------------------------; 331 | .end: 332 | mov bl, [kbd_status] 333 | mov bh, [kbd_flags] 334 | 335 | pop esi 336 | ret 337 | 338 | 339 | ;------------------------------; 340 | ; "press any key to..." ; 341 | ;------------------------------; 342 | wait_key: 343 | push eax 344 | push ebx 345 | push esi 346 | 347 | .no_new: 348 | mov al, [kbd_head] 349 | mov ah, [kbd_tail] 350 | cmp ah, 63 351 | jne .check2 352 | cmp al, 0 353 | je .no_new 354 | mov [kbd_tail], 0 355 | jmp .done_check 356 | .check2: 357 | mov bl, ah 358 | inc bl 359 | cmp bl, al 360 | je .no_new 361 | inc [kbd_tail] 362 | .done_check: 363 | 364 | mov esi, kbd_buffer 365 | movzx eax, [kbd_tail] 366 | add esi, eax 367 | mov ah, byte [esi] ; ah = scancode 368 | cmp ah, 0xFA ; check for some stuff.. 369 | je .no_new 370 | cmp ah, 0xE0 371 | je .no_new 372 | cmp ah, 0xE1 373 | je .no_new 374 | test ah, 0x80 375 | jnz .no_new 376 | 377 | pop esi 378 | pop ebx 379 | pop eax 380 | ret -------------------------------------------------------------------------------- /kernel/kbd/keymap.asm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bubach/BOS/a2421e39f4c4ce2d834a1850c706153e5bf04af8/kernel/kbd/keymap.asm -------------------------------------------------------------------------------- /kernel/kernel.asm: -------------------------------------------------------------------------------- 1 | ;-------------------------------------------------------; 2 | ; BOS kernel ; 3 | ;-------------------------------------------------------; 4 | ; BOS 32-bit kernel, expects to be loaded at 32kb ; 5 | ; in mem. Small amount of 16-bit code included. ; 6 | ; ; 7 | ; Homepage: http://bos.asmhackers.net/ ; 8 | ; Repository: http://github.com/bubach/BOS ; 9 | ; ; 10 | ; by: Christoffer Bubach, 2003-2015 ; 11 | ;-------------------------------------------------------; 12 | use16 13 | org 0x8000 14 | 15 | ;---------------------------; 16 | ; jump to starting point ; 17 | ;---------------------------; 18 | jmp start 19 | 20 | ;----------------------------------------; 21 | ; 16-bit include files ; 22 | ;----------------------------------------; 23 | include '16bit/a20.asm' ; Function to set the a20-gate. 24 | include '16bit/gdt.asm' ; Global Description Table. 25 | include '16bit/idt.asm' ; The Interrupt Description Table. 26 | include '16bit/mem.asm' ; Get memory size. 27 | include '16bit/variables.asm' ; For/from realmode. 28 | include '16bit/init16bit.asm' ; Save "go back to 16-bit"-info. 29 | 30 | 31 | 32 | ;--------------------------; 33 | ; 16-bit entry point ; 34 | ;--------------------------; 35 | start: 36 | cli 37 | mov ax, cs 38 | mov ds, ax 39 | ; fasm is more strict about 40 | xor eax, eax ; "org 0x10000" then nasm, so 41 | mov es, ax ; i have to do -0x10000 from 42 | mov fs, ax ; all variable addresses while 43 | mov gs, ax ; in realmode. 44 | sti 45 | 46 | call enable_a20 47 | call init16bit ; ... :P 48 | 49 | cli 50 | mov ax, cs ; save cs 51 | mov [realmode_cs], ax ; in variables.inc 52 | 53 | lgdt [gdtr] ; Load the GDT descriptor 54 | lidt [idtr] ; Load the IDT descriptor 55 | 56 | mov eax, cr0 57 | or al, 1 58 | mov cr0, eax 59 | 60 | jmp pword 0x08:flush ; dword in nasm 61 | 62 | 63 | 64 | ;--------------------------; 65 | ; 32-bit entry point ; 66 | ;--------------------------; 67 | use32 68 | flush: 69 | mov ax, 0x10 ; refresh all segment registers 70 | mov ds, ax 71 | mov es, ax 72 | mov fs, ax 73 | mov gs, ax 74 | mov ss, ax 75 | mov esp, 0xFFFC 76 | 77 | call bos_init ; fix everything 78 | 79 | mov bx, 0x04B1 ; start the shell 80 | call setcursor 81 | mov esi, bos_shell 82 | mov bl, 0x07 83 | call print 84 | call init_cmd 85 | jmp shell 86 | 87 | ;int 0x32 88 | 89 | .hang: 90 | cli 91 | hlt 92 | jmp .hang ; hang, just in case.. 93 | 94 | 95 | ;----------------------------------------; 96 | ; 32-bit include files ; 97 | ;----------------------------------------; 98 | include 'int/idt.asm' ; The Interrupt Description Table. 99 | include 'vga/text.asm' ; The default textmode functions. 100 | include 'init/init32b.asm' ; Function that starts up BOS 101 | include 'vars/strings.asm' ; All strings in english (soon). 102 | include 'init/bios.asm' ; Get back to realmode and do an INT. 103 | include 'init/pic.asm' ; PIC rutines. 104 | include 'system/services.asm' ; System service handler (int 0x32). 105 | include 'kbd/keyboard.asm' ; Keyboard ISR. 106 | include 'kbd/keymap.asm' ; Keymap(s). 107 | include 'shell/shell.asm' ; File with shell/kernel monitor functions. 108 | include 'shell/commands.asm' ; Command table, for valid shell commands. 109 | include 'int/isr.asm' ; Interrupt Service Rutines. 110 | include 'int/debug.asm' ; Print contents of all regs and hang. 111 | include 'init/cmos.asm' ; To get CMOS data. 112 | include 'shell/clock.asm' ; Print time and date. 113 | include 'init/timer.asm' ; Timer IRQ. 114 | include 'vga/vga.asm' ; VGA functions. 115 | ; include 'vga/font8x16.asm' ; Standard font. 116 | include 'fdc/dma.asm' ; DMA code. 117 | include 'fdc/fdc.asm' ; Floppy code. 118 | include 'vga/mario.asm' ; Mario sprite. 119 | include 'sound/speaker.asm' ; PC speaker. 120 | include 'ram/mem.asm' ; Memory allocation and freeing. 121 | include 'vfs/parse.asm' ; Path parser for VFS functions. -------------------------------------------------------------------------------- /kernel/kernel.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bubach/BOS/a2421e39f4c4ce2d834a1850c706153e5bf04af8/kernel/kernel.sys -------------------------------------------------------------------------------- /kernel/ram/mem.asm: -------------------------------------------------------------------------------- 1 | ;----------------------------------------------------------; 2 | ; BOS kernel Christoffer Bubach, 2003-2005. ; 3 | ;----------------------------------------------------------; 4 | ; ; 5 | ; functions to allocate/free mem. ; 6 | ; ; 7 | ;----------------------------------------------------------; 8 | 9 | ;----------------; 10 | ; variables ; 11 | ;----------------; 12 | first_free dd 0 13 | prev_pointer dd 0 14 | size dd 0 15 | next_pointer dd 0 16 | 17 | 18 | ;------------------------------------------------------; 19 | ; init mem ; 20 | ; in: ebx = first free memory ; 21 | ; ecx = total memory size ; 22 | ;------------------------------------------------------; 23 | init_mem: 24 | push ecx 25 | 26 | mov [first_free], ebx 27 | sub ecx, ebx 28 | mov [size], ecx 29 | mov [prev_pointer], 0 30 | mov [next_pointer], 0 31 | mov ecx, [prev_pointer] 32 | mov [ebx], ecx 33 | mov ecx, [size] 34 | mov [ebx+4], ecx 35 | mov ecx, [next_pointer] 36 | mov [ebx+8], ecx 37 | 38 | pop ecx 39 | ret 40 | 41 | 42 | 43 | ;------------------------------------------------------; 44 | ; allocate memory ; 45 | ; in: ebx = wanted size in bytes ; 46 | ; out: eax = 0 if failed ; 47 | ; ebx = pointer to memory ; 48 | ;------------------------------------------------------; 49 | allocate_mem: 50 | push ecx 51 | push edx 52 | 53 | mov eax, [first_free] 54 | 55 | .loop: 56 | mov ecx, [eax] 57 | mov [prev_pointer], ecx 58 | 59 | mov ecx, [eax+4] 60 | mov [size], ecx 61 | 62 | mov ecx, [eax+8] 63 | mov [next_pointer], ecx 64 | 65 | cmp [size], ebx 66 | jae .found 67 | cmp [next_pointer], 0 68 | je .error 69 | mov eax, [next_pointer] 70 | jmp .loop 71 | 72 | .error: 73 | xor eax, eax 74 | jmp .end 75 | 76 | .found: 77 | mov ecx, [size] 78 | sub ecx, ebx 79 | jz .equal 80 | 81 | cmp [next_pointer], 0 82 | jne .next_exists 83 | cmp [prev_pointer], 0 84 | jne .prev_but_no_next 85 | 86 | 87 | ;----------------------------------------------; 88 | ; no other block exists; add new free block ; 89 | ; with the reminding space as free, and move ; 90 | ; "first free" to that block.. ; 91 | ;----------------------------------------------; 92 | mov ecx, eax ; move address to ecx and 93 | add ecx, ebx ; add size. ecx=end requested 94 | mov dword [ecx], 0 ; set new header's prev to 0 95 | mov edx, [size] 96 | sub edx, ebx ; remaining space in edx 97 | mov [ecx+4], edx ; save it to new header 98 | mov dword [ecx+8], 0 ; no next pointer.. 99 | 100 | mov [first_free], ecx 101 | mov ebx, eax ; eax is unchanged from loop 102 | jmp .end 103 | 104 | ;----------------------------------------------; 105 | ; no next block exists, make a new header at ; 106 | ; the end of the requested size with the ; 107 | ; reminder of the free space, and update the ; 108 | ; prev header's next pointer.. ; 109 | ;----------------------------------------------; 110 | .prev_but_no_next: 111 | mov ecx, eax ; move address to ecx and 112 | add ecx, ebx ; add size. ecx=end requested 113 | mov edx, [prev_pointer] ; set prev for new header 114 | mov [ecx], edx ; set new header's prev to 0 115 | mov edx, [size] 116 | sub edx, ebx ; remaining space in edx 117 | mov [ecx+4], edx ; save it to new header 118 | mov dword [ecx+8], 0 ; no next pointer.. 119 | 120 | mov [prev_pointer+8], ecx 121 | mov ebx, eax ; eax is unchanged from loop 122 | jmp .end 123 | 124 | 125 | ;----------------------------------------------; 126 | ; both next and previous blocks exists, make a ; 127 | ; new header at the end of the requested size ; 128 | ; with the reminder of the free space, move ; 129 | ; data from next block to the new one but add ; 130 | ; size so it gets right, then update all prev/ ; 131 | ; next pointers for total 3 blocks.. puh.. ; 132 | ;----------------------------------------------; 133 | .next_exists: 134 | cmp [prev_pointer], 0 135 | je .next_but_no_prev 136 | 137 | mov ecx, eax ; move address to ecx and 138 | add ecx, ebx ; add size. ecx=end requested 139 | mov edx, [prev_pointer] ; set prev for new header 140 | mov [ecx], edx ; set new header's prev 141 | mov edx, [size] 142 | sub edx, ebx 143 | mov ebx, [next_pointer+4] 144 | add edx, ebx ; remaining space in edx 145 | mov [ecx+4], edx ; save it to new header 146 | mov edx, [next_pointer] ; address to next block 147 | cmp dword [edx], 0 148 | je .no_next_next 149 | mov dword [edx], ecx ; update next-next's prev.. 150 | mov dword [ecx+8], edx ; address to next pointer. 151 | 152 | mov [prev_pointer+8], ecx 153 | mov ebx, eax ; eax is unchanged from loop 154 | jmp .end 155 | .no_next_next: 156 | mov dword [edx], 0 157 | mov dword [ecx+8], 0 158 | mov [prev_pointer+8], ecx 159 | mov ebx, eax ; eax is unchanged from loop 160 | jmp .end 161 | 162 | 163 | ;----------------------------------------------; 164 | ; we allocated the first free block, do the ; 165 | ; same as above, except ignore the prev block ; 166 | ; part, and move the "first free". ; 167 | ;----------------------------------------------; 168 | .next_but_no_prev: 169 | mov ecx, eax ; move address to ecx and 170 | add ecx, ebx ; add size. ecx=end requested 171 | mov dword [ecx], 0 ; set new header's prev to 0 172 | mov edx, [size] 173 | sub edx, ebx 174 | mov ebx, [next_pointer+4] 175 | add edx, ebx ; remaining space in edx 176 | mov [ecx+4], edx ; save it to new header 177 | mov edx, [next_pointer] ; address to next block 178 | cmp dword [edx], 0 179 | je .no_next_next2 180 | mov dword [edx], ecx ; update next-next's prev.. 181 | mov dword [ecx+8], edx ; address to next pointer. 182 | 183 | mov [first_free], ecx ; zero and update first free. 184 | mov ebx, eax ; eax is unchanged from loop 185 | jmp .end 186 | .no_next_next2: 187 | mov dword [edx], 0 188 | mov ecx, [ecx+8] 189 | mov dword [ecx], 0 190 | mov [prev_pointer+8], ecx 191 | mov ebx, eax ; eax is unchanged from loop 192 | jmp .end 193 | 194 | 195 | ;-----------------------------------------; 196 | ; requested == size ; 197 | ; I prefered coding this one.. ;) ; 198 | ;-----------------------------------------; 199 | .equal: 200 | cmp [next_pointer], 0 201 | jne .next_exists2 202 | cmp [prev_pointer], 0 203 | jne .prev_but_no_next2 204 | mov [first_free], 0 205 | mov ebx, eax ; eax is unchanged from loop 206 | jmp .end 207 | 208 | .prev_but_no_next2: 209 | mov dword [prev_pointer+8], 0 210 | mov ebx, eax ; eax is unchanged from loop 211 | jmp .end 212 | 213 | .next_exists2: 214 | cmp [prev_pointer], 0 215 | je .next_but_no_prev2 216 | mov ecx, [prev_pointer] ; update prev and next's 217 | mov edx, [next_pointer] ; headers to bypass this 218 | mov [ecx+8], edx ; chunk. 219 | mov [edx], ecx 220 | mov ebx, eax ; eax is unchanged from loop 221 | jmp .end 222 | 223 | .next_but_no_prev2: 224 | mov ecx, [eax+8] ; get address of next header 225 | mov dword [ecx], 0 ; set prev in next header to 226 | mov [first_free], ecx ; zero and update first free. 227 | mov ebx, eax ; eax is unchanged from loop 228 | 229 | .end: 230 | pop edx 231 | pop ecx 232 | ret 233 | 234 | 235 | 236 | 237 | ;------------------------------------------------------; 238 | ; free memory ; 239 | ; in: ebx = pointer to mem ; 240 | ; ecx = size in bytes ; 241 | ;------------------------------------------------------; 242 | free_mem: 243 | push eax 244 | push ebx 245 | push ecx 246 | push edx 247 | 248 | cmp ebx, [first_free] 249 | jb .new_first_free 250 | cmp [first_free], 0 251 | je .new_first_free 252 | 253 | ;-----------------------------------------------------------; 254 | ; the block we want to free is somewhere in between ; 255 | ; two other free blocks or after the last free block. ; 256 | ; search for the "ebx"-address, so we know where the new ; 257 | ; prev/next pointers are, and then can check if we should ; 258 | ; merge blocks.. ; 259 | ;-----------------------------------------------------------; 260 | mov eax, [first_free] ; "current" free block 261 | mov edx, [eax+8] ; next free block 262 | 263 | .find_pos_loop: 264 | cmp edx, 0 ; check if the "next" 265 | je .found_end_of_ram ; free exists.. 266 | 267 | cmp ebx, edx ; is ebx "below" edx? 268 | jb .found_between ; found ebx in between 269 | 270 | mov eax, edx ; update pointers for 271 | mov edx, [eax+8] ; another loop. 272 | jmp .find_pos_loop 273 | 274 | ;------------------------------------------; 275 | ; the block is between two other blocks ; 276 | ;------------------------------------------; 277 | .found_between: 278 | mov [ebx], eax ; create header 279 | mov [ebx+4], ecx 280 | mov [ebx+8], edx 281 | 282 | mov [eax+8], ebx ; update prev header 283 | mov [edx], ebx ; update next header 284 | 285 | ; now check if we can merge blocks.... 286 | add ecx, ebx 287 | cmp edx, ecx 288 | jne .merge_only_first 289 | push eax 290 | add eax, [eax+4] 291 | cmp ebx, eax 292 | pop eax 293 | jne .merge_only_last 294 | 295 | ; we can merge with both prev & next 296 | mov ecx, [ebx+4] ; get size from "current" 297 | add [eax+4], ecx ; and add it to "prev". 298 | mov ecx, [edx+4] ; get size from "next" 299 | add [eax+4], ecx ; and add it to "prev". 300 | mov ecx, [edx+8] ; get the new next 301 | mov [eax+8], ecx ; pointer, and store it. 302 | cmp ecx, 0 303 | je .end 304 | mov [ecx], eax 305 | jmp .end 306 | 307 | .merge_only_first: 308 | cmp ebx, eax 309 | jne .end 310 | mov ecx, [ebx+4] ; get size from "current" 311 | add [eax+4], ecx ; and add it to "prev". 312 | mov [edx], eax ; update prev and next 313 | mov [eax+8], edx ; pointers for the two.. 314 | jmp .end 315 | 316 | .merge_only_last: 317 | cmp edx, ecx 318 | jne .end 319 | mov ecx, [edx+4] 320 | add [ebx+4], ecx 321 | mov ecx, [edx+8] 322 | mov [ebx+8], ecx 323 | cmp ecx, 0 324 | je .end 325 | mov [ecx], ebx 326 | jmp .end 327 | 328 | ;----------------------------------------------; 329 | ; the block is after all existing free ones ; 330 | ;----------------------------------------------; 331 | .found_end_of_ram: 332 | mov [ebx], eax ; create header 333 | mov [ebx+4], ecx 334 | mov [ebx+8], edx 335 | 336 | mov [eax+8], ebx ; update prev header 337 | 338 | ; now check if we can merge the blocks.... 339 | mov ecx, eax 340 | add ecx, [eax+4] 341 | cmp ebx, ecx 342 | jne .end 343 | mov ecx, [ebx+4] 344 | add [eax+4], ecx 345 | mov ecx, [ebx+8] 346 | mov [eax+8], ecx 347 | jmp .end 348 | 349 | ;--------------------------------------------; 350 | ; the block is before any other free ones ; 351 | ;--------------------------------------------; 352 | .new_first_free: 353 | mov dword [ebx], 0 354 | mov [ebx+4], ecx ; create the 355 | mov edx, [first_free] ; new header 356 | mov [ebx+8], edx 357 | 358 | mov edx, ebx ; check if the 359 | add edx, [ebx+4] ; first_free matches 360 | cmp edx, [first_free] ; current pos + size? 361 | je .merge_first_free ; if so, merge the two 362 | 363 | cmp [first_free], 0 ; else check if 364 | je .cont1 ; first_free exists 365 | mov edx, [ebx+8] ; if it does, update 366 | mov [edx], ebx ; it's prev pointer. 367 | .cont1: 368 | mov [first_free], ebx ; else/and set new 369 | jmp .end ; first free and quit 370 | 371 | .merge_first_free: ; merge the two first 372 | mov edx, [ebx+8] ; add the size of the 373 | mov ecx, [edx+4] ; second block to the 374 | add [ebx+4], ecx ; new one. 375 | mov ecx, [edx+8] ; get the next pointer 376 | mov [ebx+8], ecx ; from the old block, 377 | cmp ecx, 0 378 | je .cont2 379 | mov [ecx], ebx ; update this + next.. 380 | .cont2: 381 | mov [first_free], ebx ; update first_free 382 | 383 | .end: 384 | pop edx 385 | pop ecx 386 | pop ebx 387 | pop eax 388 | ret -------------------------------------------------------------------------------- /kernel/shell/clock.asm: -------------------------------------------------------------------------------- 1 | ;----------------------------------------------------------; 2 | ; BOS kernel Christoffer Bubach, 2005. ; 3 | ;----------------------------------------------------------; 4 | ; ; 5 | ; functions to print date and time. ; 6 | ; ; 7 | ;----------------------------------------------------------; 8 | 9 | ;------------------; 10 | ; variables ; 11 | ;------------------; 12 | msg_time db 13,10,' Time: ',0 13 | msg_date db 13,10,' Date: ',0 14 | 15 | 16 | ;------------------------------------------------------; 17 | ; date, prints current date and goes back to the ; 18 | ; prompt. swedish i.e. normal :) format ; 19 | ;------------------------------------------------------; 20 | print_date: 21 | push eax 22 | push ebx 23 | push esi 24 | 25 | mov esi, msg_date 26 | mov bl, 0x07 27 | call print ; text.inc 28 | call get_cmos_data ; cmos.inc 29 | 30 | mov al, [century] ; cmos.inc 31 | call BCD2ascii 32 | push eax 33 | mov bh, 0x07 34 | mov bl, al 35 | call print_char 36 | pop eax 37 | mov bl, ah 38 | call print_char 39 | 40 | mov al, [year] 41 | call BCD2ascii 42 | push eax 43 | mov bl, al 44 | call print_char 45 | pop eax 46 | mov bl, ah 47 | call print_char 48 | 49 | mov bl, ':' 50 | call print_char 51 | 52 | mov al, [month] 53 | call BCD2ascii 54 | push eax 55 | mov bl, al 56 | call print_char 57 | pop eax 58 | mov bl, ah 59 | call print_char 60 | 61 | mov bl, ':' 62 | call print_char 63 | 64 | mov al, [day] 65 | call BCD2ascii 66 | push eax 67 | mov bl, al 68 | call print_char 69 | pop eax 70 | mov bl, ah 71 | call print_char 72 | 73 | pop esi 74 | pop ebx 75 | pop eax 76 | ret 77 | 78 | 79 | ;------------------------------------------------------; 80 | ; time, prints current time and goes back to the ; 81 | ; prompt. ; 82 | ;------------------------------------------------------; 83 | print_time: 84 | push eax 85 | push ebx 86 | push esi 87 | 88 | mov esi, msg_time 89 | mov bl, 0x07 90 | call print ; text.inc 91 | call get_cmos_data ; cmos.inc 92 | mov al, [hour] ; cmos.inc 93 | call BCD2ascii 94 | push eax 95 | mov bh, 0x07 96 | mov bl, al 97 | call print_char 98 | pop eax 99 | mov bl, ah 100 | call print_char 101 | 102 | mov bl, ':' 103 | call print_char 104 | 105 | mov al, [minute] 106 | call BCD2ascii 107 | push eax 108 | mov bl, al 109 | call print_char 110 | pop eax 111 | mov bl, ah 112 | call print_char 113 | 114 | mov bl, ':' 115 | call print_char 116 | 117 | mov al, [second] 118 | call BCD2ascii 119 | push eax 120 | mov bl, al 121 | call print_char 122 | pop eax 123 | mov bl, ah 124 | call print_char 125 | 126 | pop esi 127 | pop ebx 128 | pop eax 129 | ret -------------------------------------------------------------------------------- /kernel/shell/shell.asm: -------------------------------------------------------------------------------- 1 | ;----------------------------------------------------------; 2 | ; BOS 0.04 Christoffer Bubach, 2004-2005. ; 3 | ;----------------------------------------------------------; 4 | ; ; 5 | ; Basic shell. ; 6 | ; ; 7 | ;----------------------------------------------------------; 8 | 9 | 10 | ;--------------; 11 | ; Variabels ; 12 | ;--------------; 13 | 14 | prompt db 'BOS kernel>', 0 15 | cmd_buffer: times 255 db 0 ; 255 char command buffer 16 | 17 | 18 | 19 | ;----------------------------------------------; 20 | ; print the prompt for the first time.. :-) ; 21 | ;----------------------------------------------; 22 | init_cmd: 23 | mov byte [kbd_status], 0 ; reset LEDs to 0.. 24 | call update_leds 25 | 26 | mov esi, prompt 27 | mov bl, 0x0E 28 | call print 29 | 30 | mov edi, cmd_buffer 31 | ret 32 | 33 | 34 | 35 | ;-------------------------------; 36 | ; Main shell function & loop ; 37 | ;-------------------------------; 38 | shell: 39 | mov cx, 0 ; max 254 chars in command 40 | .loop: ; no. 255 is always a 0 41 | 42 | push cx ; better be sure it´s safe.. 43 | push edi 44 | 45 | call getc ; keyboard.inc 46 | 47 | pop edi 48 | pop cx 49 | 50 | cmp ah, 28 ; enter 51 | je .enter 52 | 53 | cmp ah, 14 ; backspace 54 | je .backspace 55 | 56 | cmp al, 0 ; no normal key 57 | je .loop ; exceptions above.. 58 | 59 | cmp cx, 254 60 | jae .loop 61 | 62 | stosb ; store char in buffer 63 | inc cx 64 | 65 | mov bl, al ; print it.. 66 | mov bh, 0x07 67 | call print_char 68 | 69 | jmp .loop 70 | 71 | .enter: 72 | mov al, 0 ; the command buffer is 73 | stosb ; in ASCIIZ format.. 74 | jmp chk_cmd 75 | 76 | .backspace: 77 | cmp cx, 0 ; can´t delete the prompt.. ;-) 78 | je .loop 79 | dec edi ; "remove" one char from buffer 80 | call backspace ; do backspace on screen 81 | dec cx ; decrease buffer counter 82 | jmp .loop 83 | jmp $ 84 | ret 85 | 86 | 87 | 88 | ;---------------------------------; 89 | ; check for valid cmd ; 90 | ;---------------------------------; 91 | chk_cmd: 92 | 93 | mov esi, commands 94 | mov edi, cmd_buffer 95 | mov ebp, 0 ; command-table counter 96 | 97 | ;------------------------------------------; 98 | ; big loop, for each command in table ; 99 | ;------------------------------------------; 100 | .l1: 101 | mov ecx, 0 ; char counter 102 | 103 | cmp byte [esi], 0xFF 104 | je .no_valid_cmd 105 | 106 | ;------------------------------------------; 107 | ; smaller loop for each char in command ; 108 | ;------------------------------------------; 109 | .l2: 110 | cmp byte [edi], ' ' ; space or zero 111 | je .l_chk ; both indicate 112 | cmp byte [edi], 0 ; "end of command" 113 | je .l_chk 114 | jmp .l_cont 115 | 116 | .l_chk: 117 | cmp byte [esi], 0 ; commands are equal, but 118 | jne .new_cmd ; do not match in size.. 119 | jmp .done 120 | 121 | .l_cont: 122 | cmp byte [esi], 0 ; commands are equal, but 123 | je .new_cmd ; do not match in size.. 124 | 125 | mov al, [esi] 126 | cmp al, [edi] 127 | jne .new_cmd 128 | 129 | inc esi 130 | inc edi 131 | inc ecx ; inc char counter 132 | jmp .l2 133 | ;----------------------; 134 | ; end of small loop ; 135 | ;----------------------; 136 | 137 | .new_cmd: 138 | inc ebp ; inc command counter 139 | mov edi, cmd_buffer ; remember to point to the right place.. ;-) 140 | .l3: 141 | inc esi 142 | cmp byte [esi], 0 ; loop until end of command 143 | jne .l3 144 | 145 | inc esi 146 | jmp .l1 147 | ;----------------------; 148 | ; end of big loop ; 149 | ;----------------------; 150 | 151 | 152 | 153 | ;--------------------------; 154 | ; done. command found ; 155 | ;--------------------------; 156 | .done: 157 | cmp ecx, 0 ; make sure it´s more 158 | je .d_quit ; then 0 chars.. 159 | 160 | shl ebp, 2 161 | call dword [ebp+call_table] 162 | 163 | .d_quit: 164 | jmp .cont ; then go back to the shell 165 | 166 | 167 | ;--------------------------; 168 | ; command not found ; 169 | ;--------------------------; 170 | .no_valid_cmd: 171 | 172 | ; call search_current_directory_for_file.... :-) 173 | 174 | call no_such_cmd ; print error.. 175 | jmp .cont ; then go back to the shell 176 | 177 | ;---------------------------------; 178 | ; make the prompt appear again ; 179 | ;---------------------------------; 180 | .cont: 181 | call new_line 182 | call new_line 183 | mov esi, prompt 184 | mov bl, 0x0E 185 | call print 186 | mov edi, cmd_buffer 187 | jmp shell 188 | 189 | ret 190 | -------------------------------------------------------------------------------- /kernel/sound/speaker.asm: -------------------------------------------------------------------------------- 1 | ;----------------------------------------------------------; 2 | ; BOS kernel Christoffer Bubach, 2004-2005. ; 3 | ;----------------------------------------------------------; 4 | ; ; 5 | ; Internal PCspeaker functions. ; 6 | ; ; 7 | ;----------------------------------------------------------; 8 | 9 | ;-----------------------; 10 | ; turn on PC speaker ; 11 | ; bx = frequency ; 12 | ;-----------------------; 13 | speaker_on: 14 | mov dx, 0x12 15 | mov ax, 0x34DC 16 | div bx 17 | mov bl, al 18 | mov al, 0xB6 19 | out 0x43, al 20 | mov al, bl 21 | out 0x42, al 22 | mov al, ah 23 | out 0x42, al 24 | in al, 0x61 25 | or al, 3 26 | out 0x61, al 27 | ret 28 | 29 | 30 | ;----------------------; 31 | ; turn speaker off ; 32 | ;----------------------; 33 | speaker_off: 34 | push ax 35 | in al, 0x61 36 | and al, 0xFC ; some do 0xFD, some 0xFC... :/ 37 | out 0x61, al 38 | pop ax 39 | ret 40 | 41 | 42 | ;----------------------------------; 43 | ; PC-speaker; beep ; 44 | ;----------------------------------; 45 | beep: 46 | push eax 47 | push ecx 48 | in al, 0x61 ; turn the speaker on. 49 | or al, 3 50 | out 0x61, al 51 | mov ecx, 50 52 | call delay ; timer.inc 53 | call speaker_off 54 | pop ecx 55 | pop eax 56 | ret -------------------------------------------------------------------------------- /kernel/stdio/stdio.asm: -------------------------------------------------------------------------------- 1 | ;----------------------------------------------------------; 2 | ; BOS kernel Christoffer Bubach, 2012-2015. ; 3 | ;----------------------------------------------------------; 4 | ; ; 5 | ; STDIO interface, handling all user input/output. ; 6 | ; ; 7 | ;----------------------------------------------------------; 8 | 9 | init_stdio: 10 | push eax 11 | ; a bit more code here 12 | pop eax 13 | ret -------------------------------------------------------------------------------- /kernel/system/services.asm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bubach/BOS/a2421e39f4c4ce2d834a1850c706153e5bf04af8/kernel/system/services.asm -------------------------------------------------------------------------------- /kernel/vars/strings.asm: -------------------------------------------------------------------------------- 1 | ;----------------------------------------------------------; 2 | ; BOS 0.05 Christoffer Bubach, 2004-2015. ; 3 | ;----------------------------------------------------------; 4 | ; ; 5 | ; English strings used in BOS. ; 6 | ; ; 7 | ;----------------------------------------------------------; 8 | 9 | 10 | ;---------------; 11 | ; strings ; 12 | ;---------------; 13 | 14 | pmode_load db 'Setting up protected mode...', 0 15 | pmode_load_ok db '[ 32-bits OK ]', 0 16 | 17 | kernel_load db 'Loading kernel...', 0 18 | kernel_load_ok db '[ OK ]', 0 19 | 20 | pic_irq db 'Fixing PIC and IRQs...', 0 21 | pic_irq_ok db '[ Done ]', 0 22 | 23 | idt_mess db 'Setting up IDT...', 0 24 | idt_ok db '[ IDT OK ]', 0 25 | 26 | kbd_load db 'Enables IRQ1...', 0 27 | kbd_ok db '[ Keyboard OK ]', 0 28 | 29 | bos_shell db 'BOS shell. Type "help" for more info.', 13, 10, 0 30 | -------------------------------------------------------------------------------- /kernel/vfs/parse.asm: -------------------------------------------------------------------------------- 1 | ;--------------------------------------------------------------; 2 | ; parse_path - parse path to get info on each part ; 3 | ;--------------------------------------------------------------; 4 | ; ; 5 | ; in: esi = pointer to full ASCIIZ path ; 6 | ; cl = part no. to extract or 0 for none ; 7 | ; ; 8 | ; out: bl = drive no. (VFS assigned) or zero ; 9 | ; bh = number of elements or zero for none ; 10 | ; edi = pointer to ASCIIZ part of path in ; 11 | ; cl, or 0 on error or no input ; 12 | ;--------------------------------------------------------------; 13 | parse_path: 14 | push eax 15 | push ecx 16 | push edx 17 | push esi 18 | 19 | cmp byte [esi], 0 20 | je .error 21 | cmp byte [esi+1], 0 ; minimum 3 chars drive 22 | je .error 23 | cmp byte [esi+2], 0 24 | je .error 25 | 26 | and byte [esi], 11011111b ; (0xDF) to uppercase 27 | and byte [esi+1], 11011111b ; (0xDF) to uppercase 28 | 29 | mov bl, 0x00 ; fd base is 0x00 30 | cmp word [esi], 'FD' ; fd check 31 | je .drive_found 32 | mov bl, 0x10 ; hd base is 0x10 33 | cmp word [esi], 'HD' ; hd check 34 | je .drive_found 35 | mov bl, 0x60 ; cd base is 0x60 36 | cmp word [esi], 'CD' ; cd check 37 | je .drive_found 38 | mov bl, 0x80 ; vd base is 0x80 39 | cmp word [esi], 'VD' ; vd (virtual ram drive) check 40 | je .drive_found 41 | mov bl, 0x90 ; rd base is 0x90 42 | cmp word [esi], 'RD' ; rd (removable/usb) 43 | je .drive_found 44 | mov bl, 0xB0 ; nd base is 0xB0 45 | cmp word [esi], 'ND' ; nd (net) check 46 | je .drive_found 47 | 48 | jmp .error ; no valid drive found 49 | 50 | ;-----------------------; 51 | ; get drive number ; 52 | ;-----------------------; 53 | .drive_found: 54 | xor edx, edx ; esi offest for first / 55 | cmp byte [esi+3], 0 ; end of path 56 | je .one_number 57 | cmp byte [esi+3], '/' ; one number 58 | je .one_number 59 | 60 | mov edx, 4 ; first / after numbers 61 | xor eax, eax 62 | mov ax, word [esi+2] ; get 2 bytes number 63 | jmp .convert_cont 64 | .one_number: 65 | mov edx, 3 ; first / after numbers 66 | xor eax, eax 67 | mov al, byte [esi+2] ; 1 byte ASCII number 68 | .convert_cont: 69 | push ecx 70 | xor ecx, ecx 71 | cmp ah, 0 72 | jne .cont_convert 73 | pop ecx 74 | sub al, 0x30 ; only one ASCII char. 75 | jmp .number_found ; done. 76 | .cont_convert: 77 | mov cl, ah 78 | sub cx, 0x30 ; take care of first 79 | push ecx ; save it for later.. 80 | mov cl, al 81 | sub cx, 0x30 82 | shl cx, 1 ; multiply with 10 using 83 | mov eax, ecx ; x*8 + x*2 = 84 | shl cx, 2 85 | add ax, cx ; x*10 86 | pop ecx 87 | add ax, cx ; add first number 88 | pop ecx 89 | 90 | .number_found: 91 | add bl, al ; add number to base 92 | 93 | ;------------------------; 94 | ; parse parts of path ; 95 | ;------------------------; 96 | mov bh, 0 ; start at zero 97 | add esi, edx ; add start offset 98 | 99 | cmp byte [esi], '/' 100 | jne .end ; root, no parts 101 | xor eax, eax ; counter 102 | .parts_loop: ; loop for path parts 103 | inc esi 104 | cmp byte [esi], 0 ; end of path? 105 | je .end ; no inc in parts 106 | cmp byte [esi], '/' ; end of part? 107 | je .new_part 108 | cmp eax, 0 109 | jne .cont_parts 110 | inc bh ; inc no. of parts 111 | .cont_parts: 112 | inc eax ; char count inc 113 | 114 | cmp cl, bh ; check for part to 115 | jne .parts_loop ; save, if match: 116 | mov edi, .filename_buffer ; get buffer 117 | dec edi ; offset starts at 1, 118 | add edi, eax ; not 0 - so fixed now 119 | push eax 120 | mov al, byte [esi] 121 | mov byte [edi], al ; put the byte 122 | mov byte [edi+1], 0 ; make ASCIIZ 123 | pop eax 124 | 125 | jmp .parts_loop 126 | .new_part: 127 | xor eax, eax ; reset char count 128 | jmp .parts_loop ; loop again 129 | 130 | ;------------------------; 131 | ; cleanup and return ; 132 | ;------------------------; 133 | .end: 134 | mov edi, .filename_buffer 135 | pop esi 136 | pop edx 137 | pop ecx 138 | pop eax 139 | ret 140 | .error: 141 | pop esi 142 | pop edx 143 | pop ecx 144 | pop eax 145 | mov edi, 0 ; not a valid part 146 | mov bl, 0 ; not a valid drive 147 | mov bh, 0 ; not a valid path 148 | ret 149 | 150 | .filename_buffer: times 256 db 0 -------------------------------------------------------------------------------- /kernel/vfs/vfs.asm: -------------------------------------------------------------------------------- 1 | ;----------------------------------------------------------; 2 | ; BOS kernel Christoffer Bubach, 2012-2015. ; 3 | ;----------------------------------------------------------; 4 | ; ; 5 | ; VFS handling all devices and filesystems. ; 6 | ; ; 7 | ;----------------------------------------------------------; 8 | 9 | 10 | ;---------------------------------------------; 11 | ; VFS main structure ; 12 | ;---------------------------------------------; 13 | struc VFS 14 | { 15 | .number: times 255 db 0 ; 00=FD, 0x10=HD, 0x60=CD, 0x80=VD, 90=RD, B0=ND 16 | .storage: 17 | times 255 * sizeof.VFS_storage db 0 ; storage driver structure 18 | .filesystem: 19 | times 255 * sizeof.VFS_filesystem db 0 ; filesystem driver structure 20 | .mounted db 0 ; 1/0 switch if mounted 21 | .current_path: times 255 db 0 ; drive opened path (increase max path size?) 22 | } 23 | 24 | virtual at 0 ; could use "at esi" instead 25 | VFS VFS 26 | sizeof.VFS = $-$$ 27 | end virtual 28 | 29 | ;---------------------------------------------; 30 | ; VFS storage driver structure ; 31 | ;---------------------------------------------; 32 | struc VFS_storage 33 | { 34 | .data_pointer dd 0 ; internal driver data 35 | .init dd 0 ; pointer to init 36 | .deinit dd 0 ; remove driver 37 | .read dd 0 ; read device 38 | .write dd 0 ; write device 39 | .ioctl dd 0 ; handle device specific extras 40 | } 41 | 42 | virtual at 0 43 | VFS_storage VFS_storage 44 | sizeof.VFS_storage = $-$$ 45 | end virtual 46 | 47 | ;---------------------------------------------; 48 | ; VFS filesystem structure ; 49 | ;---------------------------------------------; 50 | struc VFS_filesystem 51 | { 52 | .data_pointer dd 0 ; internal driver data 53 | .FSname db 0,0,0,0,0 ; 5 char filesystem name 54 | .init dd 0 ; pointer to init 55 | .deinit dd 0 ; remove driver 56 | .format dd 0 ; format drive 57 | .mount dd 0 ; mount drive 58 | .unmount dd 0 ; unmount drive 59 | .find dd 0 ; find file 60 | .findnext dd 0 ; get next match 61 | .open dd 0 ; open file, get handle 62 | .close dd 0 ; close file from handle 63 | .attrib dd 0 ; get/set attrib. and time 64 | .read dd 0 ; read file from handle 65 | .write dd 0 ; write file from handle 66 | .seek dd 0 ; seek from handle 67 | .rename dd 0 ; rename file 68 | .remove dd 0 ; remove file/dir 69 | .create dd 0 ; create file/dir 70 | .ioctl dd 0 ; extra calls if exists 71 | } 72 | 73 | virtual at 0 74 | VFS_filesystem VFS_filesystem 75 | sizeof.VFS_filesystem = $-$$ 76 | end virtual 77 | 78 | ;---------------------------------------------; 79 | ; VFS structure pointer ; 80 | ;---------------------------------------------; 81 | VFS_structure dd 0 82 | 83 | 84 | ;--------------------------------------------------------------; 85 | ; init_vfs - detect connected drives ; 86 | ;--------------------------------------------------------------; 87 | ; ; 88 | ; out: cf = set if failed ; 89 | ; ; 90 | ;--------------------------------------------------------------; 91 | init_vfs: 92 | push eax 93 | push ebx 94 | 95 | mov ebx, sizeof.VFS ; allocate structure size 96 | call allocate_mem 97 | cmp eax, 0 98 | jne .ok 99 | stc ; if error, set carry 100 | mov ebx, 0 101 | 102 | .ok: 103 | mov dword [VFS_structure], ebx 104 | 105 | pop ebx 106 | pop eax 107 | ret 108 | 109 | ;--------------------------------------------------------------; 110 | ; add_media - add media driver ; 111 | ;--------------------------------------------------------------; 112 | ; ; 113 | ; in: reg = pointer to VFS drive info ; 114 | ; ; 115 | ; out: reg = pointer to struct(s) if FAT12 found ; 116 | ; ; 117 | ;--------------------------------------------------------------; 118 | add_media: 119 | push eax 120 | ;... 121 | pop eax 122 | ret 123 | 124 | ;--------------------------------------------------------------; 125 | ; add_fs - add filesystem driver ; 126 | ;--------------------------------------------------------------; 127 | ; ; 128 | ; in: reg = pointer to VFS drive info ; 129 | ; ; 130 | ; out: reg = pointer to struct(s) if FAT12 found ; 131 | ; ; 132 | ;--------------------------------------------------------------; 133 | add_fs: 134 | push eax 135 | ;... 136 | pop eax 137 | ret 138 | 139 | ;--------------------------------------------------------------; 140 | ; open_file - open file, return handle ; 141 | ;--------------------------------------------------------------; 142 | ; ; 143 | ; in: reg = ASCIIZ file name and such ; 144 | ; ; 145 | ; out: reg = dword file handle ; 146 | ; ; 147 | ;--------------------------------------------------------------; 148 | open_file: 149 | push eax 150 | ; file handles need to be dword, where the high 151 | ; word contains drive number, and the low word 152 | ; is the drive/FS specific handle. meaning no internal 153 | ; table in VFS, created dynamically with FS info. 154 | ; limits FS to a max of 65535 opened files. most use fewer 155 | ; as default. FAT12 driver has 32. 156 | ; FS reports error if handle is invalid. 157 | pop eax 158 | ret -------------------------------------------------------------------------------- /kernel/vga/mario.asm: -------------------------------------------------------------------------------- 1 | mario: 2 | db 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00 3 | db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x32, 0x05, 0x36, 0x36, 0x05, 0x05, 0x05, 0x10 4 | db 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x05, 0x36, 0x1F, 0x37 5 | db 0x36, 0x05, 0x05, 0x05, 0x05, 0x05, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10 6 | db 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x32, 0x05, 0x05, 0x05, 0x05, 0x05, 0x10, 0x00, 0x00, 0x00 7 | db 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x32, 0x05, 0x05 8 | db 0x05, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x10, 0x33, 0x10, 0x33, 0x32, 0x10 9 | db 0x10, 0x10, 0x10, 0x32, 0x34, 0x05, 0x00, 0x00, 0x00, 0x00, 0x34, 0x34, 0x34, 0x36, 0x10, 0x35 10 | db 0x10, 0x35, 0x35, 0x34, 0x32, 0x10, 0x32, 0x34, 0x37, 0x34, 0x32, 0x00, 0x00, 0x34, 0x37, 0x37 11 | db 0x37, 0x37, 0x37, 0x36, 0x36, 0x36, 0x35, 0x32, 0x10, 0x10, 0x34, 0x36, 0x36, 0x34, 0x32, 0x00 12 | db 0x00, 0x32, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x10, 0x36, 0x36, 0x32, 0x10, 0x36, 0x34 13 | db 0x34, 0x32, 0x10, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x36 14 | db 0x36, 0x36, 0x36, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10 15 | db 0x10, 0x32, 0x34, 0x34, 0x34, 0x34, 0x32, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 16 | db 0x00, 0x00, 0x6B, 0x8B, 0x8B, 0x8B, 0x8B, 0x6B, 0x32, 0x05, 0x05, 0x32, 0x00, 0x00, 0x00, 0x00 17 | db 0x00, 0x00, 0x00, 0x00, 0x00, 0x6A, 0x8C, 0x8D, 0x8D, 0x8C, 0x8B, 0x8B, 0x6B, 0x05, 0x05, 0x05 18 | db 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x8C, 0x8E, 0x8E, 0x8D, 0x8C, 0x8C, 0x8B 19 | db 0x6E, 0x1F, 0x1F, 0x6E, 0x6B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x8C, 0x8D, 0x8E 20 | db 0x8C, 0x8B, 0x8B, 0x8B, 0x10, 0x6E, 0x1F, 0x6E, 0x6B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 21 | db 0x00, 0x10, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x10, 0x6D, 0x6E, 0x6D, 0x6B, 0x00, 0x00, 0x00 22 | db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x32, 0x4B, 0x4B, 0x32 23 | db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x4E, 0x4C, 0x32, 0x4E, 0x4E, 0x4C 24 | db 0x4C, 0x4C, 0x4B, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x32, 0x32 25 | db 0x10, 0x4B, 0x4B, 0x32, 0x32, 0x32, 0x32, 0x10, 0x00, 0x00, 0x00, 0x00 26 | 27 | grass_l: 28 | db 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 29 | db 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x10, 0x10, 0x10, 0x29, 0x2C, 0x2B, 0x2C, 0x2C 30 | db 0x2B, 0x2B, 0x2D, 0x2D, 0x2C, 0x2C, 0x2B, 0x2C, 0x2C, 0x2C, 0x00, 0x10, 0x29, 0x2A, 0x2A, 0x2C 31 | db 0x2D, 0x2A, 0x2C, 0x2B, 0x2C, 0x2D, 0x2B, 0x2C, 0x2C, 0x2D, 0x2D, 0x2C, 0x2C, 0x2B, 0x10, 0x29 32 | db 0x2B, 0x2A, 0x2B, 0x2B, 0x2B, 0x2C, 0x2B, 0x2B, 0x2A, 0x2A, 0x2B, 0x2A, 0x2B, 0x2B, 0x2A, 0x2C 33 | db 0x2B, 0x2A, 0x10, 0x29, 0x2A, 0x2A, 0x2A, 0x2B, 0x2A, 0x2B, 0x2A, 0x2B, 0x2A, 0x2A, 0x2A, 0x2B 34 | db 0x2A, 0x2A, 0x2A, 0x2B, 0x2A, 0x2B, 0x10, 0x28, 0x29, 0x2A, 0x2C, 0x29, 0x2B, 0x2A, 0x29, 0x2A 35 | db 0x2B, 0x2C, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x28, 0x10, 0x29, 0x2A, 0x2A, 0x2D, 0x29 36 | db 0x2A, 0x29, 0x2A, 0x29, 0x2A, 0x2A, 0x29, 0x2A, 0x2A, 0x2C, 0x2A, 0x28, 0x29, 0x2A, 0x10, 0x28 37 | db 0x29, 0x2A, 0x2B, 0x2A, 0x2A, 0x28, 0x2A, 0x10, 0x29, 0x2A, 0x2A, 0x29, 0x10, 0x2B, 0x2A, 0x10 38 | db 0x29, 0x28, 0x10, 0x29, 0x29, 0x2B, 0x2A, 0x29, 0x2B, 0x29, 0x2B, 0x10, 0x28, 0x29, 0x10, 0x2B 39 | db 0x10, 0x29, 0x28, 0x2A, 0x28, 0x2B, 0x00, 0x28, 0x2A, 0x29, 0x10, 0x10, 0x2A, 0x10, 0x10, 0x41 40 | db 0x10, 0x10, 0x41, 0x10, 0x28, 0x10, 0x29, 0x2B, 0x29, 0x28, 0x00, 0x10, 0x28, 0x10, 0x10, 0x41 41 | db 0x10, 0x41, 0x50, 0x50, 0x41, 0x50, 0x50, 0x41, 0x10, 0x41, 0x10, 0x29, 0x28, 0x41, 0x00, 0x00 42 | db 0x10, 0x10, 0x41, 0x10, 0x50, 0x50, 0x51, 0x51, 0x51, 0x52, 0x50, 0x50, 0x51, 0x51, 0x41, 0x41 43 | db 0x10, 0x50, 0x00, 0x00, 0x10, 0x41, 0x50, 0x41, 0x51, 0x52, 0x52, 0x52, 0x52, 0x53, 0x53, 0x53 44 | db 0x54, 0x53, 0x52, 0x50, 0x50, 0x51, 0x00, 0x00, 0x10, 0x41, 0x41, 0x51, 0x52, 0x53, 0x54, 0x53 45 | db 0x53, 0x54, 0x55, 0x55, 0x55, 0x54, 0x54, 0x52, 0x52, 0x54 46 | 47 | grass_f: 48 | db 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 49 | db 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x2C, 0x2B, 0x2C, 0x2C, 0x2D, 0x2D, 0x2D, 0x2C, 0x2D, 0x2B 50 | db 0x2B, 0x2C, 0x2D, 0x2C, 0x2D, 0x2B, 0x2C, 0x2B, 0x2C, 0x2D, 0x2B, 0x2D, 0x2C, 0x2C, 0x2B, 0x2A 51 | db 0x2C, 0x2A, 0x2C, 0x2D, 0x2C, 0x2C, 0x2B, 0x2C, 0x2A, 0x2C, 0x2D, 0x2D, 0x2B, 0x2B, 0x2A, 0x2B 52 | db 0x2C, 0x2B, 0x2A, 0x2C, 0x2A, 0x2B, 0x2B, 0x2B, 0x2A, 0x2A, 0x2B, 0x2A, 0x2B, 0x2B, 0x2A, 0x2C 53 | db 0x2B, 0x2A, 0x2A, 0x2A, 0x2A, 0x2B, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2B, 0x2A, 0x2A, 0x2A, 0x2B 54 | db 0x2A, 0x2A, 0x2A, 0x2B, 0x2A, 0x2B, 0x2A, 0x2B, 0x2A, 0x2A, 0x2A, 0x29, 0x2B, 0x2A, 0x29, 0x2A 55 | db 0x2A, 0x2B, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x28, 0x2A, 0x29, 0x28, 0x29, 0x2A, 0x29 56 | db 0x2A, 0x29, 0x2A, 0x29, 0x2A, 0x2A, 0x29, 0x2A, 0x2A, 0x2B, 0x2A, 0x28, 0x29, 0x2A, 0x29, 0x29 57 | db 0x28, 0x2A, 0x29, 0x29, 0x2A, 0x28, 0x2A, 0x10, 0x29, 0x2A, 0x2A, 0x29, 0x10, 0x2B, 0x2A, 0x10 58 | db 0x29, 0x28, 0x2A, 0x28, 0x2A, 0x2B, 0x10, 0x29, 0x2B, 0x29, 0x2B, 0x10, 0x28, 0x29, 0x10, 0x2B 59 | db 0x10, 0x29, 0x28, 0x2A, 0x28, 0x2B, 0x28, 0x29, 0x2A, 0x2B, 0x10, 0x10, 0x2A, 0x10, 0x10, 0x41 60 | db 0x10, 0x10, 0x41, 0x10, 0x28, 0x10, 0x29, 0x2B, 0x29, 0x28, 0x41, 0x10, 0x28, 0x10, 0x10, 0x41 61 | db 0x10, 0x41, 0x50, 0x50, 0x41, 0x50, 0x50, 0x41, 0x10, 0x41, 0x10, 0x29, 0x28, 0x41, 0x50, 0x41 62 | db 0x10, 0x41, 0x41, 0x50, 0x51, 0x50, 0x51, 0x51, 0x51, 0x52, 0x50, 0x50, 0x51, 0x51, 0x41, 0x41 63 | db 0x10, 0x50, 0x51, 0x51, 0x50, 0x50, 0x51, 0x51, 0x52, 0x51, 0x52, 0x52, 0x52, 0x53, 0x53, 0x53 64 | db 0x54, 0x53, 0x52, 0x50, 0x50, 0x51, 0x53, 0x52, 0x51, 0x51, 0x53, 0x53, 0x52, 0x53, 0x54, 0x53 65 | db 0x53, 0x54, 0x55, 0x55, 0x55, 0x54, 0x54, 0x52, 0x52, 0x54 66 | 67 | grass_ul: 68 | db 0x10, 0x10, 0x10, 0x31, 0x51, 0x51, 0x52, 0x52, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54 69 | db 0x55, 0x55, 0x54, 0x54, 0x54, 0x54, 0x2C, 0x2C, 0x29, 0x2A, 0x31, 0x10, 0x51, 0x52, 0x52, 0x55 70 | db 0x53, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x55, 0x2B, 0x2D, 0x2D, 0x29, 0x2B, 0x2A 71 | db 0x31, 0x28, 0x53, 0x52, 0x52, 0x54, 0x54, 0x54, 0x55, 0x54, 0x54, 0x54, 0x54, 0x54, 0x2A, 0x2B 72 | db 0x2B, 0x2A, 0x2D, 0x2C, 0x2B, 0x2A, 0x42, 0x52, 0x54, 0x55, 0x54, 0x54, 0x54, 0x54, 0x55, 0x54 73 | db 0x54, 0x54, 0x2A, 0x2B, 0x2C, 0x2B, 0x2B, 0x2B, 0x2A, 0x2B, 0x28, 0x28, 0x52, 0x52, 0x54, 0x54 74 | db 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x2A, 0x2A, 0x2B, 0x2B, 0x2A, 0x2D, 0x2B, 0x2A, 0x2B, 0x28 75 | db 0x28, 0x53, 0x53, 0x54, 0x54, 0x54, 0x54, 0x55, 0x55, 0x54, 0x2B, 0x2A, 0x2B, 0x2A, 0x2A, 0x2B 76 | db 0x2A, 0x28, 0x29, 0x2A, 0x10, 0x41, 0x53, 0x53, 0x54, 0x54, 0x55, 0x55, 0x55, 0x55, 0x2C, 0x28 77 | db 0x29, 0x2A, 0x2A, 0x2A, 0x2B, 0x29, 0x28, 0x10, 0x42, 0x53, 0x53, 0x54, 0x55, 0x54, 0x55, 0x55 78 | db 0x55, 0x55, 0x28, 0x29, 0x28, 0x28, 0x10, 0x28, 0x2A, 0x28, 0x51, 0x42, 0x53, 0x52, 0x54, 0x54 79 | db 0x54, 0x54, 0x54, 0x55, 0x54, 0x54, 0x28, 0x29, 0x41, 0x41, 0x51, 0x10, 0x28, 0x41, 0x42, 0x52 80 | db 0x51, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x41, 0x10, 0x41, 0x51, 0x41, 0x51 81 | db 0x42, 0x53, 0x53, 0x54, 0x53, 0x55, 0x54, 0x54, 0x54, 0x54, 0x54, 0x55, 0x54, 0x54, 0x51, 0x41 82 | db 0x53, 0x41, 0x52, 0x52, 0x53, 0x54, 0x53, 0x53, 0x54, 0x54, 0x54, 0x54, 0x55, 0x55, 0x54, 0x54 83 | db 0x54, 0x54, 0x52, 0x52, 0x52, 0x53, 0x55, 0x53, 0x53, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x55 84 | db 0x55, 0x55, 0x55, 0x54, 0x54, 0x54, 0x54, 0x53, 0x55, 0x54, 0x53, 0x53, 0x54, 0x54, 0x55, 0x54 85 | db 0x54, 0x54, 0x54, 0x55, 0x55, 0x55, 0x55, 0x54, 0x54, 0x55 86 | 87 | g_lefts: 88 | db 0x00, 0x00, 0x10, 0x41, 0x51, 0x52, 0x52, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54 89 | db 0x55, 0x55, 0x54, 0x54, 0x54, 0x54, 0x00, 0x00, 0x10, 0x50, 0x51, 0x53, 0x54, 0x55, 0x54, 0x53 90 | db 0x54, 0x55, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x55, 0x00, 0x00, 0x10, 0x50, 0x41, 0x52 91 | db 0x54, 0x54, 0x55, 0x54, 0x53, 0x54, 0x55, 0x54, 0x55, 0x54, 0x54, 0x54, 0x54, 0x54, 0x00, 0x00 92 | db 0x10, 0x41, 0x52, 0x52, 0x54, 0x53, 0x54, 0x54, 0x54, 0x54, 0x55, 0x54, 0x54, 0x54, 0x55, 0x54 93 | db 0x54, 0x54, 0x00, 0x00, 0x10, 0x50, 0x51, 0x52, 0x52, 0x54, 0x53, 0x53, 0x54, 0x54, 0x54, 0x54 94 | db 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x00, 0x00, 0x10, 0x41, 0x51, 0x41, 0x54, 0x53, 0x54, 0x54 95 | db 0x54, 0x55, 0x54, 0x54, 0x54, 0x54, 0x55, 0x55, 0x54, 0x54, 0x00, 0x00, 0x10, 0x41, 0x51, 0x52 96 | db 0x52, 0x53, 0x54, 0x55, 0x54, 0x54, 0x54, 0x54, 0x54, 0x55, 0x55, 0x55, 0x55, 0x54, 0x00, 0x00 97 | db 0x10, 0x41, 0x50, 0x51, 0x53, 0x54, 0x54, 0x55, 0x55, 0x54, 0x55, 0x54, 0x54, 0x55, 0x55, 0x55 98 | db 0x55, 0x54, 0x00, 0x00, 0x10, 0x41, 0x50, 0x51, 0x53, 0x54, 0x54, 0x54, 0x55, 0x54, 0x54, 0x54 99 | db 0x54, 0x54, 0x55, 0x55, 0x54, 0x54, 0x00, 0x00, 0x10, 0x41, 0x50, 0x52, 0x52, 0x53, 0x54, 0x55 100 | db 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x00, 0x00, 0x10, 0x50, 0x51, 0x52 101 | db 0x50, 0x52, 0x53, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x55, 0x54, 0x54, 0x00, 0x00 102 | db 0x10, 0x41, 0x52, 0x52, 0x52, 0x55, 0x55, 0x54, 0x54, 0x54, 0x54, 0x54, 0x55, 0x55, 0x54, 0x54 103 | db 0x54, 0x54, 0x00, 0x00, 0x10, 0x41, 0x50, 0x52, 0x52, 0x53, 0x54, 0x54, 0x54, 0x54, 0x54, 0x55 104 | db 0x55, 0x55, 0x55, 0x54, 0x54, 0x54, 0x00, 0x00, 0x10, 0x50, 0x52, 0x52, 0x54, 0x53, 0x54, 0x54 105 | db 0x55, 0x54, 0x54, 0x55, 0x55, 0x55, 0x55, 0x54, 0x54, 0x55 106 | 107 | g_earth: 108 | db 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54 109 | db 0x55, 0x55, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x55, 0x55, 0x54, 0x54, 0x54, 0x54, 0x54, 0x55 110 | db 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x55, 0x54, 0x55, 0x55, 0x55, 0x55, 0x54 111 | db 0x55, 0x54, 0x54, 0x54, 0x55, 0x55, 0x54, 0x54, 0x55, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x55 112 | db 0x55, 0x55, 0x55, 0x54, 0x54, 0x54, 0x54, 0x54, 0x55, 0x55, 0x54, 0x54, 0x54, 0x54, 0x55, 0x54 113 | db 0x54, 0x54, 0x54, 0x54, 0x55, 0x55, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54 114 | db 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x55 115 | db 0x54, 0x54, 0x54, 0x55, 0x54, 0x54, 0x55, 0x55, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54 116 | db 0x55, 0x55, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x55, 0x55, 0x55, 0x55, 0x54, 0x54, 0x54 117 | db 0x54, 0x54, 0x54, 0x55, 0x55, 0x55, 0x55, 0x54, 0x55, 0x54, 0x54, 0x54, 0x54, 0x55, 0x55, 0x55 118 | db 0x55, 0x54, 0x54, 0x54, 0x55, 0x54, 0x54, 0x55, 0x55, 0x55, 0x55, 0x54, 0x54, 0x54, 0x54, 0x54 119 | db 0x54, 0x54, 0x55, 0x55, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x55, 0x55, 0x54, 0x54 120 | db 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x55, 0x54, 0x54, 0x54, 0x54 121 | db 0x54, 0x54, 0x54, 0x54, 0x54, 0x55, 0x54, 0x54, 0x54, 0x54, 0x54, 0x55, 0x54, 0x54, 0x54, 0x55 122 | db 0x55, 0x54, 0x54, 0x54, 0x55, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x55, 0x55, 0x54, 0x54 123 | db 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x55, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x55 124 | db 0x55, 0x55, 0x55, 0x54, 0x54, 0x54, 0x54, 0x54, 0x55, 0x54, 0x54, 0x54, 0x54, 0x54, 0x55, 0x54 125 | db 0x54, 0x54, 0x54, 0x55, 0x55, 0x55, 0x55, 0x54, 0x54, 0x55 -------------------------------------------------------------------------------- /kernel/vga/text.asm: -------------------------------------------------------------------------------- 1 | ;----------------------------------------------------------; 2 | ; BOS kernel Christoffer Bubach, 2003-2005. ; 3 | ;----------------------------------------------------------; 4 | ; ; 5 | ; Textmode screen functions. ; 6 | ; ; 7 | ;----------------------------------------------------------; 8 | 9 | ;-----------------; 10 | ; variables ; 11 | ;-----------------; 12 | screen_rows db 25 ; all comments assume 13 | screen_cols db 80 ; that this is 25 & 80 14 | cursor_pos dw 0 15 | 16 | 17 | ;--------------------------------------; 18 | ; change cursor attribs ; 19 | ; in: bx = cursor attribs ; 20 | ;--------------------------------------; 21 | changecursor: 22 | push ax 23 | push dx 24 | 25 | mov dx, 0x3D4 26 | mov al, 0x0A 27 | mov ah, bh 28 | out dx, ax 29 | inc ax 30 | mov ah, bl 31 | out dx, ax 32 | 33 | pop dx 34 | pop ax 35 | ret 36 | 37 | 38 | ;----------------------; 39 | ; clear the screen ; 40 | ;----------------------; 41 | cls: 42 | push bx 43 | push cx 44 | 45 | movzx cx, [screen_rows] 46 | .loop: 47 | call _scroll_up 48 | loop .loop 49 | 50 | mov bx, 0 51 | call setcursor 52 | 53 | pop cx 54 | pop bx 55 | ret 56 | 57 | 58 | ;-----------------------------------; 59 | ; get the cursor pos ; 60 | ; out: bh = x bl = y ; 61 | ;-----------------------------------; 62 | getcursorxy: 63 | push ax 64 | 65 | call getcursor 66 | mov ax, bx 67 | mov bl, [screen_cols] 68 | div bl 69 | mov bl, al 70 | mov bh, ah 71 | 72 | pop ax 73 | ret 74 | 75 | 76 | ;-------------------------------; 77 | ; get the cursor pos ; 78 | ; out: bx = offset ; 79 | ;-------------------------------; 80 | getcursor: 81 | push ax 82 | push dx 83 | 84 | mov dx, 0x3D4 85 | mov al, 0x0E 86 | out dx, al 87 | inc dx 88 | in al, dx 89 | mov bh, al 90 | mov al, 0x0F 91 | dec dx 92 | out dx, al 93 | inc dx 94 | in al, dx 95 | mov bl, al 96 | 97 | pop dx 98 | pop ax 99 | ret 100 | 101 | 102 | ;------------------------------; 103 | ; set the cursor to: ; 104 | ; bh = x bl = y ; 105 | ;------------------------------; 106 | setcursorxy: 107 | push ax 108 | push bx 109 | 110 | xor ax, ax 111 | mov al, [screen_cols] 112 | mul bl ; bl * al = ax 113 | movzx bx, bh 114 | add bx, ax 115 | call setcursor 116 | 117 | pop bx 118 | pop ax 119 | ret 120 | 121 | 122 | ;--------------------------; 123 | ; set the cursor to: ; 124 | ; bx = offset ; 125 | ;--------------------------; 126 | setcursor: 127 | push ax 128 | push bx 129 | push dx 130 | 131 | mov al, 0x0E 132 | mov ah, bh 133 | mov dx, 0x3D4 134 | out dx, ax 135 | inc ax 136 | mov ah, bl 137 | out dx, ax 138 | 139 | pop dx 140 | pop bx 141 | pop ax 142 | ret 143 | 144 | 145 | ;-----------------------; 146 | ; cursor position +1 ; 147 | ;-----------------------; 148 | inccursor: 149 | push ax 150 | push bx 151 | 152 | mov al, [screen_cols] 153 | mov bl, [screen_rows] 154 | mul bl 155 | dec ax 156 | 157 | call getcursor 158 | cmp bx, ax ; 0x7CF = (80*25)-1 159 | jne .cont 160 | call scroll_up 161 | jmp .end 162 | 163 | .cont: 164 | inc bx 165 | call setcursor 166 | 167 | .end: 168 | pop bx 169 | pop ax 170 | ret 171 | 172 | 173 | ;-----------------------; 174 | ; cursor position -1 ; 175 | ;-----------------------; 176 | deccursor: 177 | push bx 178 | 179 | call getcursor 180 | cmp bx, 0 181 | je .end 182 | 183 | dec bx 184 | call setcursor 185 | 186 | .end: 187 | pop bx 188 | ret 189 | 190 | 191 | 192 | ;---------------------------------------; 193 | ; backspace - delete last typed char ; 194 | ;---------------------------------------; 195 | backspace: 196 | push bx 197 | 198 | call getcursor 199 | cmp bx, 0 200 | je .end 201 | 202 | call deccursor 203 | 204 | mov bh, 0x07 205 | mov bl, 0 206 | call print_char 207 | 208 | call deccursor 209 | 210 | .end: 211 | pop bx 212 | ret 213 | 214 | 215 | 216 | ;-----------------------------------------; 217 | ; print char ; 218 | ; in: bl = char, bh = attrib ; 219 | ;-----------------------------------------; 220 | print_char: 221 | push eax 222 | push bx 223 | 224 | cmp bl, 13 225 | jne .cont 226 | call new_line 227 | jmp .done 228 | 229 | .cont: 230 | cmp bl, 10 ; ignore 231 | je .done 232 | 233 | push bx 234 | call getcursor 235 | movzx eax, bx 236 | pop bx 237 | 238 | mov [es:(eax*2 + 0xB8000)], bx 239 | 240 | call inccursor 241 | .done: 242 | pop bx 243 | pop eax 244 | ret 245 | 246 | 247 | 248 | ;------------------------------------------; 249 | ; print 32-bit hex value ; 250 | ; in: ebx = value, cl = color ; 251 | ;------------------------------------------; 252 | print_hex32: 253 | push eax 254 | push ebx 255 | push ecx 256 | push edx 257 | 258 | mov eax, ebx ; quick & dirty fix so 259 | mov bh, cl ; input reg != eax 260 | mov ecx, 8 261 | 262 | .print_it: 263 | rol eax, 4 264 | movzx edx, al 265 | and edx, 0x0F 266 | or edx, 0x30 267 | cmp edx, 0x39 268 | jna .cont 269 | add edx, 7 270 | .cont: 271 | mov bl, dl 272 | call print_char 273 | loop .print_it 274 | 275 | pop edx 276 | pop ecx 277 | pop ebx 278 | pop eax 279 | ret 280 | 281 | 282 | 283 | ;-------------------------------------------------; 284 | ; display a asciiz message on the screen ; 285 | ; in: esi = message, bl = color ; 286 | ;-------------------------------------------------; 287 | print: 288 | push eax 289 | push bx 290 | 291 | mov ah, bl 292 | call getcursor 293 | mov [cursor_pos], bx 294 | 295 | .displaychar: 296 | lodsb 297 | or al, al 298 | jz .done 299 | 300 | cmp al, 13 301 | jne .cont 302 | mov bx, [cursor_pos] 303 | call setcursor 304 | call new_line 305 | call getcursor 306 | mov [cursor_pos], bx 307 | jmp .displaychar 308 | 309 | .cont: 310 | cmp al, 10 ; ignore 311 | je .displaychar 312 | movzx ebx, [cursor_pos] 313 | mov [es:(ebx*2 + 0xB8000)], ax 314 | inc [cursor_pos] 315 | jmp .displaychar 316 | 317 | .done: 318 | mov bx, [cursor_pos] 319 | call setcursor ; update cursor on screen 320 | 321 | pop bx 322 | pop eax 323 | ret 324 | 325 | 326 | 327 | ;-----------------------------; 328 | ; make a new line (CR, LF) ; 329 | ;-----------------------------; 330 | new_line: 331 | push bx 332 | 333 | call getcursorxy 334 | mov bh, [screen_rows] 335 | dec bh 336 | cmp bl, bh ; 24 337 | jb .newline 338 | 339 | call scroll_up 340 | jmp .done 341 | 342 | .newline: 343 | call getcursorxy 344 | mov bh, 0 345 | inc bl 346 | call setcursorxy 347 | 348 | .done: 349 | pop bx 350 | ret 351 | 352 | 353 | 354 | ;----------------; 355 | ; scrolling.. ; 356 | ;----------------; 357 | scroll_up: 358 | call _scroll_up 359 | 360 | .mv_curs: 361 | push ax 362 | push bx 363 | 364 | xor ax, ax 365 | mov al, [screen_rows] ; mov bx, 80*24 366 | mov bl, [screen_cols] 367 | dec al 368 | mul bl 369 | mov bx, ax 370 | call setcursor 371 | 372 | pop bx 373 | pop ax 374 | ret 375 | 376 | _scroll_up: 377 | push eax 378 | push ecx 379 | push edi 380 | push esi 381 | 382 | mov edi, 0xB8000 383 | movzx esi, [screen_cols] 384 | shl esi, 1 ; 80*2 = 160 385 | mov cl, [screen_rows] 386 | dec cl 387 | mov eax, esi 388 | mul cl 389 | shr ax, 2 ; ax = (160*24)/4 390 | movzx ecx, ax ; ecx = - || - 391 | add esi, 0xB8000 ; esi = 0xB8000+160 392 | 393 | rep movsd 394 | 395 | mov cl, [screen_cols] 396 | shl cl, 1 ; 80*2 = 160 397 | mov al, [screen_rows] 398 | dec al ; al = 24 399 | mul cl 400 | movzx edi, ax 401 | add edi, 0xB8000 ; edi = 0xB8000+160*24 402 | movzx ecx, [screen_cols] 403 | shr ecx, 1 ; 80/2 404 | mov eax, 0x07000700 ; fill with zeros 405 | rep stosd 406 | 407 | pop esi 408 | pop edi 409 | pop ecx 410 | pop eax 411 | ret -------------------------------------------------------------------------------- /kernel/vga/vga.asm: -------------------------------------------------------------------------------- 1 | ;----------------------------------------------------------; 2 | ; BOS 0.04 Christoffer Bubach, 2004-2005. ; 3 | ;----------------------------------------------------------; 4 | ; ; 5 | ; VGA functions. Change video mode etc. ; 6 | ; ; 7 | ;----------------------------------------------------------; 8 | 9 | 10 | ;-------------------; 11 | ; VGA palettes ; 12 | ;-------------------; 13 | 14 | palette256: 15 | db 00, 00, 00, 00, 10, 41, 12, 28, 18, 02, 43, 22, 35 16 | db 19, 09, 58, 00, 00, 57, 35, 12, 43, 43, 47, 24, 24 17 | db 28, 20, 24, 60, 10, 60, 15, 31, 47, 63, 62, 56, 20 18 | db 60, 56, 22, 63, 61, 36, 63, 63, 63, 00, 00, 00, 05 19 | db 05, 05, 08, 08, 08, 11, 11, 11, 14, 14, 14, 17, 17 20 | db 17, 20, 20, 20, 24, 24, 24, 28, 28, 28, 32, 32, 32 21 | db 36, 36, 36, 40, 40, 40, 45, 45, 45, 50, 50, 50, 56 22 | db 56, 56, 63, 63, 63, 13, 12, 15, 15, 16, 22, 17, 20 23 | db 29, 19, 24, 36, 21, 28, 43, 23, 31, 50, 25, 34, 57 24 | db 26, 42, 63, 00, 15, 02, 01, 22, 04, 02, 29, 06, 03 25 | db 36, 08, 04, 43, 10, 05, 50, 12, 06, 57, 14, 20, 63 26 | db 40, 18, 06, 07, 25, 12, 11, 33, 17, 14, 40, 23, 18 27 | db 48, 28, 21, 55, 34, 25, 62, 39, 27, 63, 48, 36, 15 28 | db 03, 02, 22, 06, 04, 29, 09, 06, 36, 12, 08, 43, 15 29 | db 10, 50, 18, 12, 57, 21, 14, 63, 28, 20, 15, 00, 00 30 | db 22, 07, 00, 29, 15, 00, 36, 23, 00, 43, 31, 00, 50 31 | db 39, 00, 57, 47, 00, 63, 55, 00, 15, 05, 03, 22, 11 32 | db 07, 29, 17, 11, 36, 23, 15, 43, 29, 19, 50, 35, 23 33 | db 57, 41, 27, 63, 53, 34, 28, 14, 12, 33, 20, 14, 38 34 | db 26, 16, 43, 32, 18, 48, 38, 20, 53, 44, 22, 58, 50 35 | db 24, 63, 56, 30, 05, 05, 06, 10, 10, 13, 15, 15, 20 36 | db 20, 20, 27, 25, 25, 34, 30, 30, 41, 35, 35, 48, 44 37 | db 44, 63, 03, 06, 05, 05, 11, 09, 07, 16, 13, 09, 21 38 | db 17, 11, 26, 21, 13, 31, 25, 15, 36, 29, 20, 48, 38 39 | db 06, 06, 07, 13, 13, 15, 20, 20, 23, 27, 27, 31, 34 40 | db 34, 39, 41, 41, 47, 48, 48, 55, 57, 57, 63, 06, 15 41 | db 04, 12, 22, 08, 18, 29, 12, 24, 36, 16, 30, 43, 20 42 | db 36, 50, 24, 42, 57, 28, 54, 63, 35, 15, 10, 10, 22 43 | db 16, 16, 29, 21, 21, 36, 27, 27, 43, 32, 32, 50, 38 44 | db 38, 57, 43, 43, 63, 54, 54, 15, 15, 06, 22, 22, 12 45 | db 29, 29, 18, 36, 36, 24, 43, 43, 30, 50, 50, 36, 57 46 | db 57, 42, 63, 63, 54, 02, 04, 14, 06, 12, 21, 10, 20 47 | db 28, 14, 28, 35, 18, 36, 42, 22, 44, 49, 26, 52, 56 48 | db 36, 63, 63, 18, 04, 14, 24, 08, 21, 31, 12, 28, 37 49 | db 16, 35, 44, 20, 42, 50, 24, 49, 57, 28, 56, 63, 38 50 | db 63, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 51 | db 00, 00, 00, 00, 00, 00, 00, 00, 00, 53, 44, 22, 09 52 | db 08, 12, 16, 14, 16, 22, 21, 20, 29, 27, 24, 35, 34 53 | db 28, 42, 40, 32, 48, 47, 36, 57, 56, 43, 08, 12, 16 54 | db 14, 16, 22, 21, 20, 29, 27, 24, 35, 34, 28, 42, 40 55 | db 32, 48, 47, 36, 57, 56, 43, 63, 13, 09, 11, 21, 16 56 | db 15, 27, 22, 18, 36, 29, 22, 42, 35, 25, 51, 42, 29 57 | db 57, 48, 32, 63, 56, 39, 06, 14, 09, 12, 21, 14, 18 58 | db 27, 22, 24, 33, 28, 30, 39, 36, 36, 46, 42, 42, 52 59 | db 47, 50, 59, 53, 00, 00, 00, 00, 00, 00, 00, 00, 00 60 | db 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 61 | db 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 62 | db 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 63 | db 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 64 | db 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 65 | db 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 66 | db 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 67 | db 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 68 | db 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 69 | db 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 70 | db 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 71 | db 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 72 | db 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 73 | db 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 74 | db 00 75 | 76 | 77 | ;---------------------------------; 78 | ; sets the screen to mode 0x03 ; 79 | ;---------------------------------; 80 | set_mode_0x03: 81 | push eax 82 | 83 | ;mov ax, 0x0003 ; "realmode ax", move to 84 | ;shl eax, 16 ; the high part of eax 85 | ;mov ax, 0x77 ; os function number for ints 86 | ;int 0x32 87 | 88 | ;mov eax, 0x00030077 ; or it could look like this. 89 | 90 | mov eax, 0x00030000 91 | mov ebx, 0x00100000 ; int no. in high part and 92 | call rmode_int ; realmode bx in low part 93 | 94 | pop eax 95 | ret 96 | 97 | 98 | ;---------------------------------; 99 | ; sets the screen to mode 0x13 ; 100 | ;---------------------------------; 101 | set_mode_0x13: 102 | push eax 103 | push ebx 104 | 105 | mov eax, 0x00130000 ; realmode ax in high part 106 | mov ebx, 0x00100000 ; int no. in high part and 107 | call rmode_int ; realmode bx in low part 108 | 109 | mov esi, palette256 110 | call set_palette256 111 | 112 | pop ebx 113 | pop eax 114 | ret 115 | 116 | 117 | ;------------------------------------; 118 | ; put a pixel at x, y with color ; 119 | ; used only in mode 0x13 ; 120 | ; ; 121 | ; input: bx = x ; 122 | ; cx = y ; 123 | ; al = color ; 124 | ; ; 125 | ; output: none. ; 126 | ;------------------------------------; 127 | put_0x13_pixel: 128 | push ax 129 | push bx 130 | push cx 131 | push edi 132 | 133 | mov edi, 0xa0000 ; directly to mem 134 | add di, bx 135 | mov bx, cx 136 | shl cx, 8 137 | shl bx, 6 138 | add cx, bx 139 | add di, cx 140 | stosb 141 | 142 | pop edi 143 | pop cx 144 | pop bx 145 | pop ax 146 | ret 147 | 148 | 149 | ;-----------------------------------------------------; 150 | ; put a sprite at x, y. only for mode 0x13 ; 151 | ; ; 152 | ; input: ax = x, bx = y, cx = width, dx = height ; 153 | ; esi = pointer to sprite ; 154 | ; ; 155 | ; output: none. ; 156 | ;-----------------------------------------------------; 157 | put_0x13_sprite: 158 | pushad ; this was a 159 | .row_loop: ; nightmare to write. 160 | dec dx ; guess how many times 161 | push cx ; i got lost in the push 162 | push ax ; and pops here.. ;) 163 | .col_loop: ; not to mention what 164 | dec cx ; time it was when i wrote 165 | push ax ; it.. :P 166 | push bx 167 | push cx 168 | mov cx, bx 169 | mov bx, ax 170 | lodsb 171 | call put_0x13_pixel 172 | pop cx 173 | pop bx 174 | pop ax 175 | inc ax 176 | cmp cx, 0 177 | jne .col_loop 178 | pop ax 179 | pop cx 180 | inc bx 181 | cmp dx, 0 182 | jne .row_loop 183 | popad 184 | ret 185 | 186 | 187 | ;---------------------------------------------; 188 | ; sets the palette (256 colors) ; 189 | ; ; 190 | ; input: esi = palette. ; 191 | ; output: none. ; 192 | ;---------------------------------------------; 193 | set_palette256: 194 | push ax 195 | push cx 196 | push dx 197 | 198 | xor cx, cx 199 | .l1: 200 | mov dx, 0x03C8 201 | mov al, cl ; color no. = loop no. 202 | out dx, al 203 | inc dx ; port 0x3C9 204 | mov al, byte [esi] ; red 205 | out dx, al 206 | inc esi 207 | mov al, byte [esi] ; green 208 | out dx, al 209 | inc esi 210 | mov al, byte [esi] ; blue 211 | out dx, al 212 | inc esi 213 | 214 | inc cx 215 | cmp cx, 256 216 | jl .l1 217 | 218 | pop dx 219 | pop cx 220 | pop ax 221 | ret 222 | 223 | -------------------------------------------------------------------------------- /scripts/install.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | echo Put an empty floppy in drive a: and 3 | pause 4 | echo. 5 | cd ..\kernel 6 | ..\utils\fasm kernel.asm kernel.sys 7 | cd ..\boot 8 | ..\utils\fasm BOS_boot.asm BOS_boot.bin 9 | cd.. 10 | .\utils\partcopy .\boot\BOS_boot.bin 0 200 -f0 11 | copy .\kernel\kernel.sys a: 12 | echo. 13 | echo Complete. Thank you for using my crappy 14 | echo installer.. (and for testing BOS 0.04) 15 | echo. 16 | pause -------------------------------------------------------------------------------- /scripts/install.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | # BOS Linux Installer version 0.2 4 | # You must be root to run this script because of the floppy/loopback device 5 | 6 | echo 7 | echo -e "\E[33;1mBOS\E[0m - \E[32;1mLinux installer\E[0m" 8 | echo 9 | 10 | if [ `id -u` != "0" ]; then 11 | echo -e "\E[31;1mYou must be root to use this installer!\E[0m" 12 | echo 13 | fi 14 | 15 | if [ -z "$1" ]; then 16 | echo "Usage is:" 17 | echo -e "\E[31m$0 image\E[0m - Creates a floppy image called bos.img" 18 | echo -e "\E[31m$0 floppy\E[0m - Install BOS into a floppy ( must be inserted )" 19 | echo 20 | echo "Note: this installer will create a bootable image/floppy." 21 | echo "Floppy creation is not tested ( I don't have a floppy reader ) and it should be already formatted" 22 | exit 23 | fi 24 | 25 | echo -e "\E[32mCompiling BOS...\E[0m" 26 | ../utils/fasm ../kernel/kernel.asm ../kernel/kernel.sys 27 | ../utils/fasm ../boot/BOS_boot.asm ../boot/BOS_boot.bin 28 | 29 | if [ "$1" = "floppy" ]; then 30 | echo -e "\E[32mStarting floppy installation...\E[0m" 31 | 32 | #Install BOS_boot.bin as bootsector into bos.img 33 | dd if=boot/BOS_boot.bin of=/dev/fd0 bs=1 count=512 34 | mount /mnt/floppy 35 | 36 | #Insert kernel.sys into image 37 | cp ../kernel/kernel.sys /mnt/floppy 38 | 39 | #Umount & cleanup 40 | umount /mnt/floppy 41 | 42 | echo -e "\E[33mBOS installed.\E[0m" 43 | 44 | else 45 | echo -e "\E[32mStarting image creation...\E[0m" 46 | 47 | #Create empty image 48 | if [ -e ../bos.img ]; then 49 | rm -f ../bos.img 50 | fi 51 | dd if=/dev/zero of=bos.img bs=1k count=1440 52 | 53 | #Format image in MSDOS format and mount it 54 | mkdosfs ../bos.img 55 | losetup /dev/loop3 ../bos.img 56 | 57 | #Install BOS_boot.bin as bootsector into bos.img 58 | dd if=../boot/BOS_boot.bin of=/dev/loop3 bs=1 count=512 59 | if [ ! -e tmpmnt ]; then 60 | mkdir tmpmnt 61 | fi 62 | mount -tmsdos /dev/loop3 tmpmnt 63 | 64 | #Insert kernel.sys into image 65 | cp ../kernel/kernel.sys tmpmnt 66 | 67 | #Umount & cleanup 68 | umount /dev/loop3 69 | if [ -e tmpmnt ]; then 70 | rm -rf tmpmnt 71 | fi 72 | losetup -d /dev/loop3 73 | 74 | echo -e "\E[33mBOS image created! ( better do a chown on it now ;) )\E[0m" 75 | fi -------------------------------------------------------------------------------- /scripts/mac-bochs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #needs homebrew/xquartz 4 | # brew install homebrew/x11/bochs 5 | 6 | bochs -f ../doc/bochsrc-osx.txt -------------------------------------------------------------------------------- /scripts/mac-install.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | # BOS MacOS X Installer version 0.2 4 | # You must be root to run this script because of the floppy/loopback device 5 | 6 | echo 7 | echo " BOS - MacOS X installer" 8 | echo "-------------------------" 9 | echo "Requires: Homebrew mtools" 10 | echo 11 | 12 | if [ `id -u` != "0" ]; then 13 | echo "You must be root to use this installer!" 14 | echo 15 | fi 16 | 17 | if [ -z "$1" ]; then 18 | echo "Usage is:" 19 | echo "$0 image - Creates a floppy image called bos.img" 20 | echo "$0 floppy - Install BOS into a floppy ( must be inserted )" 21 | echo 22 | echo "Note: this installer will create a bootable image/floppy." 23 | echo "Floppy creation is not tested ( I don't have a floppy reader ) and it should be already formatted" 24 | exit 25 | fi 26 | 27 | echo "Compiling BOS..." 28 | ../utils/osxfasm ../kernel/kernel.asm ../kernel/kernel.sys 29 | ../utils/osxfasm ../boot/BOS_boot.asm ../boot/BOS_boot.bin 30 | 31 | if [ "$1" = "floppy" ]; then 32 | echo "Starting floppy installation..." 33 | 34 | #Install BOS_boot.bin as bootsector into bos.img 35 | dd if=../boot/BOS_boot.bin of=/dev/fd0 bs=1 count=512 36 | mount /mnt/floppy 37 | 38 | #Insert kernel.sys into image 39 | cp ../kernel/kernel.sys /mnt/floppy 40 | 41 | #Umount & cleanup 42 | umount /mnt/floppy 43 | 44 | echo "BOS installed." 45 | 46 | else 47 | echo "Starting image creation..." 48 | 49 | #Create image 50 | rm -rf ../bos.img 51 | mformat -C -f 1440 -v BOS -i ../bos.img :: 52 | 53 | #Erhm, it isn't pretty.... 54 | DISKNAME=`hdiutil attach -nomount ../bos.img` 55 | diskutil mount $DISKNAME 56 | MOUNTNAME=`diskutil info $DISKNAME | grep 'Mount Point' | cut -d : -f 2 | sed 's/^ *//g' | sed 's/ *$//g';` 57 | 58 | #Mounted, copy kernel.sys 59 | cp ../kernel/kernel.sys $MOUNTNAME 60 | 61 | #Install BOS_boot.bin as bootsector into bos.img 62 | umount $DISKNAME 63 | dd if=../boot/BOS_boot.bin of=$DISKNAME bs=1 count=512 64 | 65 | #Detach 66 | hdiutil detach $DISKNAME 67 | chmod 0777 ../bos.img 68 | 69 | echo "BOS image created!" 70 | fi -------------------------------------------------------------------------------- /utils/FASM.EXE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bubach/BOS/a2421e39f4c4ce2d834a1850c706153e5bf04af8/utils/FASM.EXE -------------------------------------------------------------------------------- /utils/PARTCOPY.EXE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bubach/BOS/a2421e39f4c4ce2d834a1850c706153e5bf04af8/utils/PARTCOPY.EXE -------------------------------------------------------------------------------- /utils/fasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bubach/BOS/a2421e39f4c4ce2d834a1850c706153e5bf04af8/utils/fasm -------------------------------------------------------------------------------- /utils/osxfasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bubach/BOS/a2421e39f4c4ce2d834a1850c706153e5bf04af8/utils/osxfasm --------------------------------------------------------------------------------