├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── boot └── boot.asm ├── files ├── action.rad ├── aditup.rad ├── adlib.rad ├── adlibsp.rad ├── alloyrun.rad ├── aperture.asc ├── bg.sys ├── bliss.pcx ├── c_loop.pcx ├── c_phpdev.pcx ├── c_webdev.pcx ├── castle.pcx ├── cf.bas ├── default.asc ├── eldreams.rad ├── fire.pcx ├── font.sys ├── greenhil.rad ├── hangover.rad ├── inkspill.bas ├── inkspill.dat ├── lake.pcx ├── lgins.rad ├── miketron.bas ├── mindflux.rad ├── muncher.bas ├── oblit.rad ├── ooahh.rad ├── rain.rad ├── raster.rad ├── skychase.rad ├── spiral.rad ├── src │ ├── atomino.dro │ ├── castle.dro │ ├── castle1.dro │ ├── castle2.dro │ ├── castle3.dro │ ├── crooner.dro │ ├── deadend.dro │ ├── dig_it.dro │ ├── dntshout.dro │ ├── doom.dro │ ├── hobbits.dro │ ├── jbells.mus │ ├── jbells1.mus │ ├── mdoa.dro │ ├── megaman3.dro │ ├── megarace.dro │ ├── meltdown.dro │ ├── mglvna.mus │ ├── monkey.dro │ ├── neointro.dro │ ├── phemopop.dro │ ├── px3.dro │ ├── strkfrce.dro │ ├── swinging.dro │ ├── tetris.mus │ ├── tmarch.mus │ ├── tmarch1.mus │ ├── tyrian.dro │ ├── ultima6.dro │ └── wolf3d.dro ├── streets.rad ├── whscream.rad └── zap.rad ├── include ├── constants.asm ├── kernel.inc ├── program.inc └── syscalls.asm ├── kernel ├── compressed │ ├── sub_desktop.asm │ └── sub_fatalerr.asm ├── features │ ├── basic.asm │ ├── basicerr.txt │ ├── disk.asm │ ├── disk │ │ ├── cache.asm │ │ └── lowlevel.asm │ ├── graphics.asm │ ├── icons.asm │ ├── int.asm │ ├── keyboard.asm │ ├── math.asm │ ├── misc.asm │ ├── ports.asm │ ├── screen.asm │ ├── sound.asm │ ├── string.asm │ └── zx7.asm └── main.asm ├── misc ├── LICENSE ├── MikeOS LICENSE ├── VirtualBox.md ├── dosbox.conf ├── gallery.md ├── geninclude.py ├── kerneltree.py ├── mapper.map └── zx7 │ ├── appzx7.c │ ├── build.sh │ ├── compress.c │ ├── optimize.c │ ├── rawzx7.c │ ├── zx7.c │ └── zx7.h └── programs ├── about.asm ├── asciiart.asm ├── asmtris.asm ├── calc.asm ├── check.asm ├── clock.asm ├── config.asm ├── crash.asm ├── deadpixl.asm ├── demotour.asm ├── disktest.asm ├── donkey.asm ├── dots.asm ├── edit.asm ├── fileman.asm ├── fisher.asm ├── float.asm ├── fontedit.asm ├── hangman.asm ├── hwcheck.asm ├── hwcheck ├── basic.asm ├── extended.asm ├── features.asm └── vesa.asm ├── kbdtest.asm ├── memedit.asm ├── pcmtest.asm ├── pixel.asm ├── player.asm ├── player ├── dro.asm ├── libs.asm ├── monommf.asm ├── monopian.asm ├── polymmf.asm ├── polypian.asm └── rad.asm ├── rdtsc.asm ├── rtctest.asm ├── sector.asm ├── serial.asm ├── shapes.asm ├── snake.asm ├── spaceinv.asm ├── stars.asm ├── sudoku.asm ├── terminal.asm ├── test.asm └── viewer.asm /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | programs/gitignore 3 | files/gitignore 4 | misc/zx7/segmented_zx7 5 | misc/zx7/app_zx7 6 | misc/zx7/raw_zx7 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2021, Michal Procházka 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ### MichalOS Makefile 2 | 3 | .DEFAULT_GOAL := retail 4 | 5 | # These targets aren't triggered by a change of a file. 6 | .PHONY: clean 7 | 8 | # This selects all programs and music files to be built. 9 | PROGRAMS := \ 10 | $(patsubst programs/%.asm,build/%.app,$(sort $(wildcard programs/*.asm))) \ 11 | $(patsubst programs/gitignore/%.asm,build/%.app,$(sort $(wildcard programs/gitignore/*.asm))) 12 | MMF := $(patsubst files/src/%.mus,build/%.mmf,$(sort $(wildcard files/src/*.mus))) 13 | DRO := $(patsubst files/src/%.dro,build/%.drz,$(sort $(wildcard files/src/*.dro))) 14 | 15 | # This selects all compressed kernel assets to be built and compressed 16 | CKA := $(patsubst kernel/compressed/%.asm,build/%.zx7,$(sort $(wildcard kernel/compressed/*.asm))) 17 | 18 | # This selects all files to copy to the final image. 19 | FILES := $(PROGRAMS) $(MMF) $(DRO) $(wildcard files/*.*) $(wildcard files/gitignore/*.*) 20 | 21 | VER := 3.0 22 | VERCOMMIT := 0 23 | 24 | build: 25 | mkdir -p $@ 26 | 27 | build/images: 28 | mkdir -p $@ 29 | 30 | build/images/isoroot: 31 | mkdir -p $@ 32 | 33 | build/images/iso288root: 34 | mkdir -p $@ 35 | 36 | misc/zx7/app_zx7: misc/zx7/appzx7.c misc/zx7/optimize.c misc/zx7/compress.c 37 | cc $^ -o $@ 38 | 39 | misc/zx7/raw_zx7: misc/zx7/rawzx7.c misc/zx7/optimize.c misc/zx7/compress.c 40 | cc $^ -o $@ 41 | 42 | misc/zx7/segmented_zx7: misc/zx7/zx7.c misc/zx7/optimize.c misc/zx7/compress.c 43 | cc $^ -o $@ 44 | 45 | # Default target: builds the image and boots it. 46 | retail: build/images/michalos.flp 47 | dosbox -conf misc/dosbox.conf -c "boot build/images/michalos.flp" 48 | 49 | # Development target: builds as usual, but uses dosbox-debug instead of regular DOSBox. 50 | debug: build/images/michalos.flp 51 | dosbox-debug -conf misc/dosbox.conf -c "boot build/images/michalos.flp" 52 | 53 | # Noboot target: builds as usual, but does not boot the image. 54 | noboot: build/images/michalos.flp 55 | 56 | # "Big" floppy target: builds an 2.88 image (containing a 1.44 MB FAT filesystem and a 1.44 MB binary) 57 | big: build/images/michalos288.flp 58 | dosbox -conf misc/dosbox.conf -c "boot build/images/michalos288.flp" 59 | 60 | bigdebug: build/images/michalos288.flp 61 | dosbox-debug -conf misc/dosbox.conf -c "boot build/images/michalos288.flp" 62 | 63 | bignoboot: build/images/michalos288.flp 64 | 65 | # Include header file 66 | include/syscalls.asm: misc/geninclude.py kernel/main.asm kernel/features/*.asm kernel/features/*/*.asm 67 | python3 misc/geninclude.py 68 | 69 | # Bootloader target 70 | build/boot.bin: boot/boot.asm .git/refs/heads/master | build 71 | nasm -O2 -w+all -f bin -o $@ -l build/boot.lst boot/boot.asm \ 72 | -dVERMIN="'`expr $$(git rev-list --all --count) - $(VERCOMMIT)`'" \ 73 | -dVERMAJ="'$(VER)'" 74 | 75 | # Compressed kernel asset target 76 | build/%.zx7: kernel/compressed/%.asm include/*.* .git/refs/heads/master misc/zx7/raw_zx7 | build 77 | nasm -I . $< -o $@.raw 78 | misc/zx7/raw_zx7 $@.raw $@ 79 | 80 | # Kernel target 81 | build/kernel.sys: kernel/main.asm include/*.* .git/refs/heads/master $(CKA) | build 82 | nasm -O2 -w+all -f bin -I . -I kernel/ -I build/ -o $@ -l build/kernel.lst kernel/main.asm \ 83 | -dVERMIN="'`expr $$(git rev-list --all --count) - $(VERCOMMIT)`'" \ 84 | -dVERMAJ="'$(VER)'" 85 | 86 | # Assembles all programs. 87 | # Note: % means file name prefix, $@ means output file and $< means source file. 88 | build/%.app: build/%.app.bin misc/zx7/app_zx7 89 | misc/zx7/app_zx7 $< $@ 90 | 91 | .PRECIOUS: build/%.app.bin 92 | 93 | build/%.app.bin: programs/gitignore/%.asm programs/gitignore/%/*.asm include/*.* .git/refs/heads/master | build 94 | nasm -O2 -w+all -f bin -I . -I programs/ -I programs/gitignore/ -o $@ -l $@.lst $< \ 95 | -dGIT="'(`git log -1 --format="commit %h from %cd" --date=format:"%Y/%m/%d %H:%M:%S %z"`)'" 96 | 97 | build/%.app.bin: programs/gitignore/%.asm include/*.* .git/refs/heads/master | build 98 | nasm -O2 -w+all -f bin -I . -I programs/ -I programs/gitignore/ -o $@ -l $@.lst $< \ 99 | -dGIT="'(`git log -1 --format="commit %h from %cd" --date=format:"%Y/%m/%d %H:%M:%S %z"`)'" 100 | 101 | build/%.app.bin: programs/%.asm programs/%/*.asm include/*.* .git/refs/heads/master | build 102 | nasm -O2 -w+all -f bin -I . -I programs/ -o $@ -l $@.lst $< \ 103 | -dGIT="'(`git log -1 --format="commit %h from %cd" --date=format:"%Y/%m/%d %H:%M:%S %z"`)'" 104 | 105 | build/%.app.bin: programs/%.asm include/*.* .git/refs/heads/master | build 106 | nasm -O2 -w+all -f bin -I . -I programs/ -o $@ -l $@.lst $< \ 107 | -dGIT="'(`git log -1 --format="commit %h from %cd" --date=format:"%Y/%m/%d %H:%M:%S %z"`)'" 108 | 109 | # Assembles all songs. 110 | build/%.mmf: files/src/%.mus include/constants.asm | build 111 | nasm -O2 -w+all -f bin -I . -I files/src/ -o $@ $< 112 | 113 | build/%.drz: files/src/%.dro misc/zx7/segmented_zx7 | build 114 | misc/zx7/segmented_zx7 $< $@ 115 | 116 | # Builds the image. 117 | build/images/michalos.flp: include/syscalls.asm build/boot.bin build/kernel.sys \ 118 | $(FILES) | build/images 119 | dd if=/dev/zero of=build/images/michalos.flp bs=512 count=2880 120 | dd conv=notrunc if=build/boot.bin of=build/images/michalos.flp 121 | 122 | mcopy -o -i $@ build/kernel.sys $(FILES) :: 123 | 124 | build/images/michalos288.flp: build/images/michalos.flp files/gitignore/288data 125 | cp files/gitignore/288data build/288data 126 | truncate -s 1474560 build/288data 127 | cat build/images/michalos.flp build/288data > $@ 128 | 129 | # Optional target: builds a bootable ISO image for CDs. 130 | iso: build/images/michalos.iso 131 | 132 | build/images/michalos.iso: build/images/michalos.flp | build/images/isoroot 133 | rm -f $@ 134 | cp $< build/images/isoroot/michalos.flp 135 | mkisofs -V 'MICHALOS' -input-charset iso8859-1 -o $@ -b michalos.flp build/images/isoroot/ 136 | 137 | bigiso: build/images/michalos288.iso 138 | 139 | build/images/michalos288.iso: build/images/michalos288.flp | build/images/iso288root 140 | rm -f $@ 141 | cp $< build/images/iso288root/michalos.flp 142 | mkisofs -V 'MICHALOS' -input-charset iso8859-1 -o $@ -b michalos.flp build/images/iso288root/ 143 | 144 | # Removes all of the built pieces. 145 | clean: 146 | -rm -rf build misc/zx7/*_zx7 147 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MichalOS 2 | 3 | A 16-bit keyboard controlled operating system based on MikeOS 4.5, aimed to be more advanced and lightweight on the inside, but simple and easy to use on the outside. 4 | 5 | ## New features 6 | 7 | - Many applications/kernel API calls have been improved/rewritten (both in UI and under the hood) + many new custom applications 8 | - Customizable user interface (custom background, window colors, selectable font, screensaver etc.) 9 | - On-screen clock with timezone support 10 | - AdLib synthesizer support (including primitive PWM emulation via PC speaker) - music file player included (as well as a bunch of example files) 11 | - Lots of new kernel API calls 12 | - ZX7 decompression 13 | - flexible UI elements with keyboard input callbacks 14 | - VGA graphics drawing functions (lines, boxes, polygons, circles) 15 | - interrupt handling (including a friendly timer interrupt handler) 16 | - math functions 17 | - sound abstraction layer (for both PC speaker and the AdLib) 18 | - Loading of compressed applications (ZX7 compressed) 19 | - Certain kernel modules are decompressed at runtime, saving precious memory (also ZX7 compressed) 20 | - System-wide keyboard shortcuts 21 | - etc. 22 | 23 | Please check out the [gallery](https://github.com/prochazkaml/MichalOS/blob/master/misc/gallery.md) to see the words above in action. 24 | 25 | ## System requirements 26 | 27 | - Intel 80386 or higher, Pentium recommended 28 | - At least 128-ish kB RAM, 256 kB recommended 29 | - A VGA video card 30 | - A keyboard 31 | 32 | ## Screenshots 33 | 34 | ![Login screen](https://user-images.githubusercontent.com/41787099/128972820-d9d31c96-0e88-4fcb-b216-772a4f0d1568.png) 35 | ![Desktop](https://user-images.githubusercontent.com/41787099/128972823-3aae09a0-7684-4dc7-a195-92c6e2fb33d7.png) 36 | 37 | More screenshots are available in the [gallery](https://github.com/prochazkaml/MichalOS/blob/master/misc/gallery.md). 38 | 39 | ## Building instructions 40 | 41 | For building the OS, a Unix-based system is required (Linux, BSD, WSL, macOS) with **NASM**, **mtools**, **Python 3** and **make** installed. **DOSBox** is required for testing MichalOS builds (QEMU, [VirtualBox](https://github.com/prochazkaml/MichalOS/blob/master/misc/VirtualBox.md), VMware etc. could also be used, but you will be met with limited functionality). **mkisofs** is needed only if you want to generate an ISO image for CDs by running ```make iso```. 42 | 43 | On Debian GNU/Linux (and its derivates, such as Linux Mint or Ubuntu), these requirements can be met by running ```sudo apt-get install nasm mtools make dosbox python3```. 44 | 45 | On macOS, first install [Homebrew](https://brew.sh/) and then run ```brew install nasm mtools dosbox python``` from the Terminal. 46 | 47 | Then, you can simply build the image by running ```make```. 48 | -------------------------------------------------------------------------------- /files/action.rad: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/action.rad -------------------------------------------------------------------------------- /files/aditup.rad: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/aditup.rad -------------------------------------------------------------------------------- /files/adlib.rad: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/adlib.rad -------------------------------------------------------------------------------- /files/adlibsp.rad: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/adlibsp.rad -------------------------------------------------------------------------------- /files/alloyrun.rad: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/alloyrun.rad -------------------------------------------------------------------------------- /files/aperture.asc: -------------------------------------------------------------------------------- 1 |                                                                                                                  .,-:;//;:=,                                                                  . :H@@@MM@M#H/.,+%;,                                                         ,/X+ +M@@M@MM%=,-%HMMM@X/,                                                    -+@MM; $M@@MH+-,;XMMMM@MMMM@+-                                                 ;@M@@M- XM@X;. -+XXXXXHHH@M@M#@/.                                             ,%MM@@MH ,@%=            .---=-=:=,.                                            =@#@@@MX .,              -%HX$$%%%+;                                           =-./@M@M$                  .;@MMMM@MM:                                          X@/ -$MM/                    .+MM@@@M$                                         ,@M@H: :@:                    . =X#@@@@-                                        ,@@@MMX, .                    /H- ;@M@M=                                        .H@@@@M@+,                    %MM+..%#$.                                         /MMMM@MMH/.                  XM@MH; =;                                           /%+%$XHH@$=              , .H@@@@MX,                                             .=--------.           -%H.,@@@@@MX,                                             .%MM@@@HHHXX$$$%+- .:$MMX =M@@MM%.                                                =XMMM@MM@MM#H;,-+HMM@M+ /MMMX=                                                    =%@M@M#@$-.=$@MM@@@M; %M%=                                                        ,:+$+-,/H#MMMMMMM@= =,                                                                =++%%%%+/:-.                                                                                                                                                                                                                                                                                                                                                                 -------------------------------------------------------------------------------- /files/bg.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/bg.sys -------------------------------------------------------------------------------- /files/bliss.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/bliss.pcx -------------------------------------------------------------------------------- /files/c_loop.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/c_loop.pcx -------------------------------------------------------------------------------- /files/c_phpdev.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/c_phpdev.pcx -------------------------------------------------------------------------------- /files/c_webdev.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/c_webdev.pcx -------------------------------------------------------------------------------- /files/castle.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/castle.pcx -------------------------------------------------------------------------------- /files/default.asc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/default.asc -------------------------------------------------------------------------------- /files/eldreams.rad: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/eldreams.rad -------------------------------------------------------------------------------- /files/fire.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/fire.pcx -------------------------------------------------------------------------------- /files/font.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/font.sys -------------------------------------------------------------------------------- /files/greenhil.rad: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/greenhil.rad -------------------------------------------------------------------------------- /files/hangover.rad: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/hangover.rad -------------------------------------------------------------------------------- /files/inkspill.bas: -------------------------------------------------------------------------------- 1 | rem InkSpill port for MichalOS 2 | rem Memory map: 3 | rem 20000 - 60255: tile data 4 | rem 1 - red 5 | rem 2 - orange 6 | rem 3 - yellow 7 | rem 4 - green 8 | rem 5 - blue 9 | rem 6 - purple 10 | rem multiplied by 7 if tile is active 11 | rem Used variables & strings: 12 | rem a,b,c,d,e,x,y,z: temporary variables 13 | rem g: game ended 14 | rem l: steps left 15 | rem h: reset requested 16 | rem $1: temporary string 17 | 18 | rem -----------------------------------------Resetovat hru 19 | reset: 20 | cls 21 | cursor off 22 | 23 | g = 0 24 | l = 35 25 | h = 0 26 | 27 | for x = 0 to 15 28 | for y = 0 to 15 29 | rand a 1 6 30 | c = y * 16 31 | b = 20000 + x + c 32 | poke a b 33 | next y 34 | next x 35 | 36 | rem -----------------------------------------Pozadi: svetle seda 37 | ink 112 38 | for x = 0 to 24 39 | for y = 0 to 79 40 | move y x 41 | print " "; 42 | next y 43 | next x 44 | 45 | peek a 20000 46 | a = a * 7 47 | poke a 20000 48 | 49 | rem -----------------------------------------Hlavni smycka 50 | mainloop: 51 | gosub checkforactive 52 | if h = 1 then goto reset 53 | gosub gamecheck 54 | gosub render 55 | gosub controls 56 | goto mainloop 57 | 58 | rem -----------------------------------------Zkontrolovat, zda je konec hry 59 | gamecheck: 60 | e = 0 61 | for x = 0 to 15 62 | for y = 0 to 15 63 | c = y * 16 64 | b = 20000 + x + c 65 | peek a b 66 | d = a % 7 67 | if d = 0 then e = e + 1 68 | next y 69 | next x 70 | if e = 256 then goto youwin 71 | if l = 0 then goto youlose 72 | return 73 | 74 | rem -----------------------------------------Hrac vyhral 75 | youwin: 76 | if g = 1 then goto skipwin 77 | load "inkspill.dat" 20000 78 | g = 1 79 | ink 112 80 | move 1 15 81 | print "You win!" 82 | skipwin: 83 | return 84 | 85 | rem -----------------------------------------Hrac prohral 86 | youlose: 87 | if g = 1 then goto skiplose 88 | load "inkspill.dat" 19744 89 | g = 1 90 | ink 112 91 | move 1 15 92 | print "Game over!" 93 | skiplose: 94 | return 95 | 96 | rem -----------------------------------------Render herniho planu a popisku 97 | render: 98 | rem -----------------------------------------Popisky 99 | ink 112 100 | move 1 1 101 | print "InkSpill" 102 | move 1 3 103 | print "Controls:" 104 | move 1 4 105 | ink 116 106 | print "Q - Red" 107 | move 1 5 108 | ink 118 109 | print "W - Orange/Brown" 110 | move 1 6 111 | ink 126 112 | print "E - Yellow" 113 | move 1 7 114 | ink 114 115 | print "R - Green" 116 | move 1 8 117 | ink 113 118 | print "T - Blue" 119 | move 1 9 120 | ink 117 121 | print "Y - Purple" 122 | 123 | ink 112 124 | move 1 10 125 | print "O - Reset the game" 126 | move 1 11 127 | print "P - Quit" 128 | move 1 13 129 | print "Remaining steps: "; 130 | number l $1 131 | print $1; 132 | print " " 133 | move 1 14 134 | print "Acquired tiles: "; 135 | z = 0 136 | for x = 0 to 15 137 | for y = 0 to 15 138 | e = y * 16 139 | b = 20000 + x + e 140 | peek a b 141 | c = a % 7 142 | if c = 0 then z = z + 1 143 | next y 144 | next x 145 | number z $1 146 | print $1; 147 | print " " 148 | 149 | rem -----------------------------------------Herni plan 150 | for x = 0 to 15 151 | for y = 0 to 15 152 | e = y * 16 153 | b = 20000 + x + e 154 | peek a b 155 | f = x * 2 156 | c = f + 30 157 | d = y + 1 158 | move c d 159 | e = a % 7 160 | if e = 0 then a = a / 7 161 | if a = 1 then ink 4 162 | if a = 2 then ink 6 163 | if a = 3 then ink 14 164 | if a = 4 then ink 2 165 | if a = 5 then ink 1 166 | if a = 6 then ink 5 167 | print chr 219 168 | c = c + 1 169 | move c d 170 | print chr 219 171 | next y 172 | next x 173 | 174 | return 175 | 176 | rem -----------------------------------------Ovladani 177 | controls: 178 | waitkey x 179 | if x = 'q' then goto red 180 | if x = 'w' then goto orange 181 | if x = 'e' then goto yellow 182 | if x = 'r' then goto green 183 | if x = 't' then goto blue 184 | if x = 'y' then goto purple 185 | if x = 'o' then goto resetgame 186 | if x = 'p' then goto exit 187 | h = 0 188 | return 189 | 190 | resetgame: 191 | h = 1 192 | return 193 | 194 | red: 195 | c = 1 * 7 196 | for x = 0 to 15 197 | for y = 0 to 15 198 | d = y * 16 199 | b = 20000 + x + d 200 | peek a b 201 | e = a % 7 202 | if e = 0 then poke c b 203 | next y 204 | next x 205 | l = l - 1 206 | return 207 | 208 | orange: 209 | c = 2 * 7 210 | for x = 0 to 15 211 | for y = 0 to 15 212 | d = y * 16 213 | b = 20000 + x + d 214 | peek a b 215 | e = a % 7 216 | if e = 0 then poke c b 217 | next y 218 | next x 219 | l = l - 1 220 | return 221 | 222 | yellow: 223 | c = 3 * 7 224 | for x = 0 to 15 225 | for y = 0 to 15 226 | d = y * 16 227 | b = 20000 + x + d 228 | peek a b 229 | e = a % 7 230 | if e = 0 then poke c b 231 | next y 232 | next x 233 | l = l - 1 234 | return 235 | 236 | green: 237 | c = 4 * 7 238 | for x = 0 to 15 239 | for y = 0 to 15 240 | d = y * 16 241 | b = 20000 + x + d 242 | peek a b 243 | e = a % 7 244 | if e = 0 then poke c b 245 | next y 246 | next x 247 | l = l - 1 248 | return 249 | 250 | blue: 251 | c = 5 * 7 252 | for x = 0 to 15 253 | for y = 0 to 15 254 | d = y * 16 255 | b = 20000 + x + d 256 | peek a b 257 | e = a % 7 258 | if e = 0 then poke c b 259 | next y 260 | next x 261 | l = l - 1 262 | return 263 | 264 | purple: 265 | c = 6 * 7 266 | for x = 0 to 15 267 | for y = 0 to 15 268 | d = y * 16 269 | b = 20000 + x + d 270 | peek a b 271 | e = a % 7 272 | if e = 0 then poke c b 273 | next y 274 | next x 275 | l = l - 1 276 | return 277 | 278 | rem -----------------------------------------Kontrolovani aktivnich policek 279 | checkforactive: 280 | for z = 0 to 15 281 | for x = 0 to 15 282 | for y = 0 to 15 283 | c = y * 16 284 | b = 20000 + x + c 285 | peek a b 286 | d = a % 7 287 | if d = 0 then gosub activefound 288 | next y 289 | next x 290 | next z 291 | return 292 | 293 | rem -----------------------------------------Aktivni dilek nalezen, zaktivuj 294 | rem i ty ostatni okolo neho(pokud maji stejnou barvu) 295 | activefound: 296 | c = a / 7 297 | 298 | d = y * 16 299 | 300 | right: 301 | if x = 15 then goto left 302 | b = 20000 + x + d + 1 303 | peek a b 304 | if a = c then gosub activate 305 | 306 | left: 307 | if x = 0 then goto down 308 | b = 20000 + x + d - 1 309 | peek a b 310 | if a = c then gosub activate 311 | 312 | down: 313 | if y = 15 then goto up 314 | b = 20000 + x + d + 16 315 | peek a b 316 | if a = c then gosub activate 317 | 318 | up: 319 | if y = 0 then goto activeset 320 | b = 20000 + x + d - 16 321 | peek a b 322 | if a = c then gosub activate 323 | 324 | activeset: 325 | return 326 | 327 | rem -----------------------------------------Aktivni dilek nalezen, zaktivuj 328 | activate: 329 | a = a * 7 330 | poke a b 331 | return 332 | 333 | rem -----------------------------------------Ukoncit hru 334 | exit: 335 | end 336 | -------------------------------------------------------------------------------- /files/inkspill.dat: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /files/lake.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/lake.pcx -------------------------------------------------------------------------------- /files/lgins.rad: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/lgins.rad -------------------------------------------------------------------------------- /files/miketron.bas: -------------------------------------------------------------------------------- 1 | rem MikeTron Game (MIKETRON.BAS) 2 | rem A expanded demo game 3 | rem Created by Mike Saunders 4 | rem Extended by Joshua Beck 5 | rem Version 1.1.1 6 | rem Send any bug reports or suggested features to: 7 | rem mikeosdeveloper@gmail.com 8 | 9 | cls 10 | 11 | print "You control a vehicle leaving a trail behind it." 12 | print "" 13 | print "It is always moving, and if it crosses any part" 14 | print "of the trail or border (+ characters), the game" 15 | print "is over. Use W, A, S, D to change the direction" 16 | print "See how long you can survive! Score at the end." 17 | print "" 18 | print "NOTE: May perform at wrong speed in emulators!" 19 | print "" 20 | print "Hit a key to begin..." 21 | 22 | waitkey x 23 | 24 | 25 | cls 26 | cursor off 27 | 28 | 29 | rem *** Draw border around screen *** 30 | 31 | gosub setupscreen 32 | for o = 1 to 20 33 | gosub addbonus 34 | next o 35 | 36 | rem *** Start in the middle of the screen *** 37 | 38 | x = 40 39 | y = 12 40 | 41 | move x y 42 | 43 | 44 | rem *** Movement directions: 1 - 4 = up, down, left, right *** 45 | rem *** We start the game moving right *** 46 | 47 | d = 4 48 | 49 | 50 | rem *** S = score variable *** 51 | s = 0 52 | 53 | rem *** E = tail character *** 54 | e = 197 55 | 56 | mainloop: 57 | if p = 0 then print chr e ; 58 | 59 | rem wait once, then again if traveling vertical 60 | pause 2 61 | if d = 1 then pause 2 62 | if d = 2 then pause 2 63 | 64 | rem Apple Bonus 65 | if a > 0 then move x y 66 | if a > 0 then print " " ; 67 | if a > 0 then a = a - 1 68 | 69 | rem Invisible ?Bonus? 70 | if p > 0 then p = p - 1 71 | 72 | getkey k 73 | 74 | rem New keys, WASD 75 | if k = 'w' then d = 1 76 | if k = 'W' then d = 1 77 | if k = 'a' then d = 3 78 | if k = 'A' then d = 3 79 | if k = 's' then d = 2 80 | if k = 'S' then d = 2 81 | if k = 'd' then d = 4 82 | if k = 'D' then d = 4 83 | 84 | rem if they press ESC exit game 85 | if k = 27 then goto finish 86 | 87 | if d = 1 then y = y - 1 88 | if d = 2 then y = y + 1 89 | if d = 3 then x = x - 1 90 | if d = 4 then x = x + 1 91 | 92 | move x y 93 | 94 | curschar c 95 | rem ***did we collide with wall*** 96 | if c = '+' then gosub sides 97 | rem ***if we are invisible don't register collisions*** 98 | if p > 0 then goto mainloop 99 | rem ***did we collide with tail?*** 100 | if c = e then goto finish 101 | rem ***no trail time set*** 102 | if c = 235 then a = a + 10 103 | rem ***explode*** 104 | if c = 233 then gosub explode 105 | rem ***overwrite (?)*** 106 | if c = '?' then print chr e ; 107 | if c = '?' then move x y 108 | rem ***invisible time*** 109 | if c = '?' then p = p + 4 110 | rem ***stop*** 111 | if c = 'S' then gosub stop 112 | rem ***bonus spreader*** 113 | if c = 'B' then gosub bonus 114 | 115 | s = s + 1 116 | 117 | rem a bonus for every 100 points but not over 1000 118 | r = s % 100 119 | if r > 1000 then goto mainloop 120 | if r = 0 then gosub bonus 121 | goto mainloop 122 | 123 | explode: 124 | q = 219 125 | gosub bomb 126 | pause 4 127 | q = 178 128 | gosub bomb 129 | pause 4 130 | q = 177 131 | gosub bomb 132 | pause 4 133 | q = 176 134 | gosub bomb 135 | pause 4 136 | q = 32 137 | gosub bomb 138 | return 139 | 140 | bonus: 141 | print chr e ; 142 | for o = 1 to 5 143 | gosub addbonus 144 | next o 145 | move x y 146 | return 147 | 148 | stop: 149 | waitkey k 150 | if k = 'w' then d = 1 151 | if k = 'W' then d = 1 152 | if k = 'a' then d = 3 153 | if k = 'A' then d = 3 154 | if k = 's' then d = 2 155 | if k = 'S' then d = 2 156 | if k = 'd' then d = 4 157 | if k = 'D' then d = 4 158 | return 159 | 160 | bomb: 161 | v = x - 5 162 | w = y - 2 163 | for u = 1 to 5 164 | if w > 23 then goto noprinta 165 | if w < 1 then goto noprinta 166 | for t = 1 to 10 167 | move v w 168 | if v < 2 then goto noprintb 169 | if v > 78 then goto noprintb 170 | print chr q ; 171 | noprintb: 172 | v = v + 1 173 | next t 174 | noprinta: 175 | v = x - 5 176 | w = w + 1 177 | next u 178 | move x y 179 | return 180 | 181 | sides: 182 | if x > 77 then x = 1 183 | if x < 1 then x = 77 184 | if y > 23 then y = 1 185 | if y < 1 then y = 23 186 | move x y 187 | return 188 | 189 | finish: 190 | cursor on 191 | cls 192 | 193 | print "Your score was: " ; 194 | print s 195 | print "Press Esc to finish" 196 | 197 | escloop: 198 | waitkey x 199 | if x = 27 then end 200 | goto escloop 201 | 202 | 203 | setupscreen: 204 | 205 | move 0 0 206 | for x = 0 to 78 207 | print "+" ; 208 | next x 209 | 210 | move 0 24 211 | for x = 0 to 78 212 | print "+" ; 213 | next x 214 | 215 | for y = 0 to 24 216 | move 0 y 217 | print "+" ; 218 | next y 219 | 220 | for y = 0 to 24 221 | move 78 y 222 | print "+" ; 223 | next y 224 | 225 | return 226 | 227 | addbonus: 228 | rand q 1 77 229 | rand r 1 23 230 | rand g 1 4 231 | rand f 1 20 232 | if g = 1 then g = 235 233 | if g = 2 then g = 233 234 | if g = 3 then g = 63 235 | if g = 4 then g = 83 236 | if f > 19 then g = 66 237 | move q r 238 | print chr g 239 | return 240 | 241 | 242 | -------------------------------------------------------------------------------- /files/mindflux.rad: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/mindflux.rad -------------------------------------------------------------------------------- /files/muncher.bas: -------------------------------------------------------------------------------- 1 | rem ** Muncher for MikeOS ** 2 | rem Created by Justin Tokarchuk 3 | rem ------------------------------ 4 | 5 | rem VARS 6 | rem j = score multiplier 7 | rem x, y = coords 8 | rem e = body 9 | rem s = score 10 | rem i = multipliers 11 | rem n = wallpiece counter, gets reloaded by bonus engine 12 | 13 | cursor off 14 | goto logo 15 | 16 | 17 | waitforenter: 18 | waitkey x 19 | if x = 13 then goto pregame 20 | if x = 27 then cursor on 21 | if x = 27 then END 22 | goto waitforenter 23 | 24 | logo: 25 | cls 26 | cursor off 27 | move 0 7 28 | print " ## ## ## ## ## ## ###### ## ## ######## ######## ###" 29 | print " ### ### ## ## ### ## ## ## ## ## ## ## ## ###" 30 | print " #### #### ## ## #### ## ## ## ## ## ## ## ###" 31 | print " ## ### ## ## ## ## ## ## ## ######### ###### ######## # " 32 | print " ## ## ## ## ## #### ## ## ## ## ## ## " 33 | print " ## ## ## ## ## ### ## ## ## ## ## ## ## ###" 34 | print " ## ## ####### ## ## ###### ## ## ######## ## ## ###" 35 | print "" 36 | print " ======================================================================" 37 | print "" 38 | print " Press ENTER to play, ESC to quit. " 39 | gosub changelook 40 | 41 | goto waitforenter 42 | 43 | changelook: 44 | for b = 0 to 24 45 | for a = 0 to 78 46 | move a b 47 | curschar c 48 | if c = '#' then c = 219 49 | if c = '=' then c = 220 50 | print chr c ; 51 | next a 52 | next b 53 | 54 | move 0 24 55 | return 56 | 57 | pregame: 58 | cls 59 | n = 0 60 | 61 | cls 62 | cursor off 63 | gosub setwalls 64 | 65 | 66 | rem ** Place user in middle of screen. ** 67 | x = 40 68 | y = 12 69 | move x y 70 | 71 | rem ** dirs = up (1), down (2), left (3), right (4) 72 | rem ** start moving left 73 | 74 | d = 3 75 | 76 | rem ** score 77 | s = 0 78 | 79 | rem ** Body character. 80 | e = 35 81 | 82 | 83 | gosub addapple 84 | 85 | game: 86 | print chr e ; 87 | gosub printscore 88 | pause 2 89 | if d = 1 then pause 2 90 | if d = 2 then pause 2 91 | 92 | getkey k 93 | 94 | rem ** controls 95 | if k = 'w' then d = 1 96 | if k = 'W' then d = 1 97 | if k = 'a' then d = 3 98 | if k = 'A' then d = 3 99 | if k = 's' then d = 2 100 | if k = 'S' then d = 2 101 | if k = 'd' then d = 4 102 | if k = 'D' then d = 4 103 | 104 | 105 | rem if they press ESC exit game 106 | if k = 27 then goto finish 107 | 108 | if d = 1 then gosub moveupdown 109 | if d = 2 then gosub moveupdown 110 | if d = 3 then gosub moveleft 111 | if d = 4 then gosub moveright 112 | 113 | move x y 114 | 115 | curschar c 116 | rem ***did we collide with wall*** 117 | if x = 79 then goto finish 118 | if c = 'x' then goto finish 119 | if c = 178 then goto finish 120 | if c = e then goto finish 121 | if c = '@' then gosub getbonus 122 | goto game 123 | 124 | moveupdown: 125 | move x y 126 | print " " 127 | if d = 1 then y = y - 1 128 | if d = 2 then y = y + 1 129 | return 130 | 131 | 132 | moveleft: 133 | print " " ; 134 | move x y 135 | print " " 136 | x = x - 1 137 | return 138 | 139 | moveright: 140 | if x = q AND y = r then gosub getbonus 141 | move x y 142 | print " " 143 | x = x + 1 144 | return 145 | 146 | setwalls: 147 | a = 178 148 | 149 | move 0 0 150 | for x = 0 to 78 151 | print chr a ; 152 | next x 153 | 154 | move 0 23 155 | for x = 0 to 78 156 | print chr a ; 157 | next x 158 | 159 | for y = 0 to 23 160 | move 0 y 161 | print chr a ; 162 | next y 163 | 164 | for y = 0 to 23 165 | move 78 y 166 | print chr a ; 167 | next y 168 | 169 | return 170 | 171 | printscore: 172 | move 0 24 173 | print "Score: " ; 174 | print s ; 175 | move x y 176 | return 177 | 178 | addapple: 179 | rand q 1 77 180 | rand r 1 22 181 | g = 64 182 | if q = x then goto addapple 183 | if r = y then goto addapple 184 | move q r 185 | print chr g 186 | 187 | rem generate random number of wallpieces 188 | if s < 500 then rand g 1 2 189 | if s > 499 then rand g 2 5 190 | if s > 999 then rand g 5 10 191 | if s > 1999 then rand g 10 20 192 | morewallz: 193 | if s > 0 then gosub wallpiece 194 | g = g - 1 195 | if g > 0 then goto morewallz 196 | move x y 197 | return 198 | 199 | wallpiece: 200 | rem ** now add a wall piece ** 201 | rand l 1 77 202 | rand m 1 22 203 | rem Don't put it on a character or the apple please! 204 | if l = q then goto wallpiece 205 | if l = x then goto wallpiece 206 | if m = r then goto wallpiece 207 | if m = y then goto wallpiece 208 | 209 | rem is the wall piece too close to the character? 210 | if l > x then a = l - x 211 | if l < x then a = x - l 212 | if m > y then b = m - y 213 | if m < y then b = y - m 214 | if a < 7 then goto wallpiece 215 | if b < 4 then goto wallpiece 216 | move l m 217 | if c = 'x' then gosub wallpiece 218 | print "x" ; 219 | 220 | return 221 | 222 | getbonus: 223 | move x y 224 | g = 1 225 | print chr g 226 | pause 2 227 | move x y 228 | g = 2 229 | print chr g 230 | pause 2 231 | move x y 232 | g = 1 233 | print chr g 234 | pause 2 235 | move x y 236 | print " " 237 | rem *i = intermediate number for score bonus 238 | if s > 250 then j = 2 239 | if s > 1000 then j = 3 240 | if s > 3000 then j = 5 241 | if s > 5000 then j = 10 242 | gosub addapple 243 | j = 1 244 | i = 150 * j 245 | s = s + i 246 | return 247 | 248 | finish: 249 | 250 | cls 251 | cursor off 252 | move 0 2 253 | print " ###### ### ## ## ####### " 254 | print " ## ## ## ## ### ### ## " 255 | print " ## ## ## #### #### ## " 256 | print " ## #### ## ## ## ### ## ###### " 257 | print " ## ## ######### ## ## ## " 258 | print " ## ## ## ## ## ## ## " 259 | print " ###### ## ## ## ## ####### " 260 | print "" 261 | print " ####### ## ## ######## ######## " 262 | print " ## ## ## ## ## ## ## " 263 | print " ## ## ## ## ## ## ## " 264 | print " ## ## ## ## ###### ######## " 265 | print " ## ## ## ## ## ## ## " 266 | print " ## ## ## ## ## ## ## " 267 | print " ####### ### ######## ## ## " 268 | print "" 269 | print " Your Score Was: " ; 270 | print s 271 | print "" 272 | print " Play Again? (Y/N)" 273 | gosub changelook 274 | 275 | goto escloop 276 | 277 | escloop: 278 | waitkey x 279 | cursor on 280 | if x = 'n' then end 281 | if x = 'N' then end 282 | if x = 27 then end 283 | if x = 'y' then goto logo 284 | if x = 'Y' then goto logo 285 | goto escloop 286 | 287 | -------------------------------------------------------------------------------- /files/oblit.rad: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/oblit.rad -------------------------------------------------------------------------------- /files/ooahh.rad: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/ooahh.rad -------------------------------------------------------------------------------- /files/rain.rad: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/rain.rad -------------------------------------------------------------------------------- /files/raster.rad: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/raster.rad -------------------------------------------------------------------------------- /files/skychase.rad: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/skychase.rad -------------------------------------------------------------------------------- /files/spiral.rad: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/spiral.rad -------------------------------------------------------------------------------- /files/src/atomino.dro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/src/atomino.dro -------------------------------------------------------------------------------- /files/src/castle.dro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/src/castle.dro -------------------------------------------------------------------------------- /files/src/castle1.dro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/src/castle1.dro -------------------------------------------------------------------------------- /files/src/castle2.dro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/src/castle2.dro -------------------------------------------------------------------------------- /files/src/castle3.dro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/src/castle3.dro -------------------------------------------------------------------------------- /files/src/crooner.dro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/src/crooner.dro -------------------------------------------------------------------------------- /files/src/deadend.dro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/src/deadend.dro -------------------------------------------------------------------------------- /files/src/dig_it.dro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/src/dig_it.dro -------------------------------------------------------------------------------- /files/src/dntshout.dro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/src/dntshout.dro -------------------------------------------------------------------------------- /files/src/doom.dro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/src/doom.dro -------------------------------------------------------------------------------- /files/src/hobbits.dro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/src/hobbits.dro -------------------------------------------------------------------------------- /files/src/jbells.mus: -------------------------------------------------------------------------------- 1 | ; MichalOS Music Format File 2 | 3 | %INCLUDE "include/constants.asm" 4 | 5 | start: 6 | .pit_data dw 0 7 | .song_delay db 1 8 | 9 | ; 0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 10 | .track00 dw D4, D4, D4, 0, B4, B4, B4, 0, A4, A4, A4, 0, G4, G4, G4, 0, D4, D4, D4, D4, D4, D4, D4, D4, D4, D4, D4, D4, D4, D4, D4, 0 11 | .track01 dw D4, D4, D4, 0, B4, B4, B4, 0, A4, A4, A4, 0, G4, G4, G4, 0, E4, E4, E4, E4, E4, E4, E4, E4, E4, E4, E4, E4, E4, E4, E4, 0 12 | .track02 dw E4, E4, E4, 0, C5, C5, C5, 0, B4, B4, B4, 0, A4, A4, A4, 0, FS4,FS4,FS4,FS4,FS4,FS4,FS4,FS4,FS4,FS4,FS4,FS4,FS4,FS4,FS4,0 13 | .track03 dw D5, D5, D5, 0, D5, D5, D5, 0, C5, C5, C5, 0, A4, A4, A4, 0, B4, B4, B4, B4, B4, B4, B4, B4, B4, B4, B4, B4, B4, B4, B4, 0 14 | 15 | .track04 dw D4, D4, D4, 0, B4, B4, B4, 0, A4, A4, A4, 0, G4, G4, G4, 0, D4, D4, D4, D4, D4, D4, D4, D4, D4, D4, D4, D4, D4, D4, D4, 0 16 | .track05 dw D4, D4, D4, 0, B4, B4, B4, 0, A4, A4, A4, 0, G4, G4, G4, 0, E4, E4, E4, E4, E4, E4, E4, E4, E4, E4, E4, E4, E4, E4, E4, 0 17 | .track06 dw E4, E4, E4, 0, C5, C5, C5, 0, B4, B4, B4, 0, A4, A4, A4, 0, D5, D5, D5, 0, D5, D5, D5, 0, D5, D5, D5, 0, D5, D5, D5, 0 18 | .track07 dw E5, E5, E5, 0, D5, D5, D5, 0, C5, C5, C5, 0, A4, A4, A4, 0, G4, G4, G4, G4, G4, G4, G4, 0, D5, D5, D5, D5, D5, D5, D5, 0 19 | 20 | .track08 dw B4, B5, B4, 0, B4, B5, B4, 0, B4, B5, B4, B5, B4, B5, B4, 0, B4, B5, B4, 0, B4, B5, B4, 0, B4, B5, B4, B5, B4, B5, B4, 0 21 | .track09 dw B4, B5, B4, 0, D5, D6, D5, 0, G4, G5, G4, 0, A4, A5, A4, 0, B4, B5, B4, B5, B4, B5, B4, B5, B4, B5, B4, B5, B4, B5, B4, 0 22 | .track0A dw C5, C6, C5, 0, C5, C6, C5, 0, C5, C6, C5, 0, C5, C6, C5, 0, C5, C6, C5, 0, B4, B5, B4, 0, B4, B5, B4, 0, B4, B5, B4, 0 23 | .track0B dw B4, B5, B4, 0, A4, A5, A4, 0, A4, A5, A4, 0, B4, B5, B4, 0, A4, A5, A4, A5, A4, A5, A4, 0, D5, D6, D5, D6, D5, D6, D5, 0 24 | 25 | .track0C dw B4, B5, B4, 0, B4, B5, B4, 0, B4, B5, B4, B5, B4, B5, B4, 0, B4, B5, B4, 0, B4, B5, B4, 0, B4, B5, B4, B5, B4, B5, B4, 0 26 | .track0D dw B4, B5, B4, 0, D5, D6, D5, 0, G4, G5, G4, 0, A4, A5, A4, 0, B4, B5, B4, B5, B4, B5, B4, B5, B4, B5, B4, B5, B4, B5, B4, 0 27 | .track0E dw C5, C6, C5, 0, C5, C6, C5, 0, C5, C6, C5, 0, C5, C6, C5, 0, C5, C6, C5, 0, B4, B5, B4, 0, B4, B5, B4, 0, B4, B5, B4, 0 28 | .track0F dw D5, D6, D5, 0, D5, D6, D5, 0, C5, C6, C5, 0, A4, A5, A4, 0, G4, G5, G4, G5, G4, G5, G4, G5, G4, G5, G4, G5, G4, G5, G4, 0 29 | 30 | .end dw 1 31 | -------------------------------------------------------------------------------- /files/src/jbells1.mus: -------------------------------------------------------------------------------- 1 | ; MichalOS Music Format File 2 | 3 | %INCLUDE "include/constants.asm" 4 | 5 | start: 6 | .pit_data dw 0 7 | .song_delay db 1 8 | 9 | ; 0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 10 | .track00 dw G3, B3, G3, B3, G3, B3, G3, B3, G3, B3, G3, B3, G3, B3, G3, 0, G3, B3, G3, B3, G3, B3, G3, B3, G3, B3, G3, B3, G3, B3, G3, 0 11 | .track01 dw G3, B3, G3, B3, G3, B3, G3, B3, G3, B3, G3, B3, G3, B3, G3, 0, G3, C4, G3, C4, G3, C4, G3, C4, G3, C4, G3, C4, G3, C4, G3, 0 12 | .track02 dw G3, C4, G3, C4, G3, C4, G3, C4, G3, C4, G3, C4, G3, C4, G3, 0, A3, D4, A3, D4, A3, D4, A3, D4, A3, D4, A3, D4, A3, D4, A3, 0 13 | .track03 dw A3, D4, A3, D4, A3, D4, A3, D4, A3, D4, A3, D4, A3, D4, A3, 0, B3, D4, B3, D4, B3, D4, B3, D4, B3, D4, B3, D4, B3, D4, B3, 0 14 | 15 | .track04 dw G3, B3, G3, B3, G3, B3, G3, B3, G3, B3, G3, B3, G3, B3, G3, 0, G3, B3, G3, B3, G3, B3, G3, B3, G3, B3, G3, B3, G3, B3, G3, 0 16 | .track05 dw G3, B3, G3, B3, G3, B3, G3, B3, G3, B3, G3, B3, G3, B3, G3, 0, G3, C4, G3, C4, G3, C4, G3, C4, G3, C4, G3, C4, G3, C4, G3, 0 17 | .track06 dw G3, C4, G3, C4, G3, C4, G3, C4, G3, C4, G3, C4, G3, C4, G3, 0, A3, D4, A3, D4, A3, D4, A3, D4, A3, D4, A3, D4, A3, D4, A3, 0 18 | .track07 dw A3, D4, A3, D4, A3, D4, A3, D4, A3, D4, A3, D4, A3, D4, A3, 0, B3, D4, B3, D4, B3, D4, B3, D4, B3, D4, B3, D4, B3, D4, B3, 0 19 | 20 | .track08 dw G3, G3, G3, G3, B3, B3, B3, B3, D3, D3, D3, D3, B3, B3, B3, B3, G3, G3, G3, G3, B3, B3, B3, B3, D3, D3, D3, D3, B3, B3, B3, B3 21 | .track09 dw G3, G3, G3, G3, B3, B3, B3, B3, D3, D3, D3, D3, B3, B3, B3, B3, G3, G3, G3, G3, B3, B3, B3, B3, D3, D3, D3, D3, B3, B3, B3, B3 22 | .track0A dw G3, G3, G3, G3, C4, C4, C4, C4, E3, E3, E3, E3, C4, C4, C4, C4, G3, G3, G3, G3, B3, B3, B3, B3, D3, D3, D3, D3, B3, B3, B3, B3 23 | .track0B dw E3, E3, E3, E3, A3, A3, A3, A3, CS3,CS3,CS3,CS3,A3, A3, A3, A3, FS3,FS3,FS3,FS3,B3, B3, B3, B3, D3, D3, D3, D3, B3, B3, B3, B3 24 | 25 | .track0C dw G3, G3, G3, G3, B3, B3, B3, B3, D3, D3, D3, D3, B3, B3, B3, B3, G3, G3, G3, G3, B3, B3, B3, B3, D3, D3, D3, D3, B3, B3, B3, B3 26 | .track0D dw G3, G3, G3, G3, B3, B3, B3, B3, D3, D3, D3, D3, B3, B3, B3, B3, G3, G3, G3, G3, B3, B3, B3, B3, D3, D3, D3, D3, B3, B3, B3, B3 27 | .track0E dw G3, G3, G3, G3, C4, C4, C4, C4, E3, E3, E3, E3, C4, C4, C4, C4, G3, G3, G3, G3, B3, B3, B3, B3, D3, D3, D3, D3, B3, B3, B3, B3 28 | .track0F dw FS3,FS3,FS3,FS3,B3, B3, B3, B3, D3, D3, D3, D3, B3, B3, B3, B3, G3, B3, G3, B3, G3, B3, G3, B3, G3, B3, G3, B3, G3, B3, G3, 0 29 | 30 | .end dw 1 31 | -------------------------------------------------------------------------------- /files/src/mdoa.dro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/src/mdoa.dro -------------------------------------------------------------------------------- /files/src/megaman3.dro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/src/megaman3.dro -------------------------------------------------------------------------------- /files/src/megarace.dro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/src/megarace.dro -------------------------------------------------------------------------------- /files/src/meltdown.dro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/src/meltdown.dro -------------------------------------------------------------------------------- /files/src/mglvna.mus: -------------------------------------------------------------------------------- 1 | ; MichalOS Music Format File 2 | 3 | %INCLUDE "include/constants.asm" 4 | 5 | start: 6 | .pit_data dw 0 7 | .song_delay db 1 8 | ; 0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 9 | .track00 dw D4, 0, D4, 0, D5, 0, 0, 0, A4, 0, 0, 0, 0, 0, GS4,GS4,0, 0, G4, 0, 0, 0, F4, F4, F4, F4, D4, D4, F4, F4, G4, G4 10 | .track01 dw C4, 0, C4, 0, D5, 0, 0, 0, A4, 0, 0, 0, 0, 0, GS4,GS4,0, 0, G4, 0, 0, 0, F4, F4, F4, F4, D4, D4, F4, F4, G4, G4 11 | .track02 dw B3, 0, B3, 0, D5, 0, 0, 0, A4, 0, 0, 0, 0, 0, GS4,GS4,0, 0, G4, 0, 0, 0, F4, F4, F4, F4, D4, D4, F4, F4, G4, G4 12 | .track03 dw AS3,0, AS3,0, D5, 0, 0, 0, A4, 0, 0, 0, 0, 0, GS4,GS4,0, 0, G4, 0, 0, 0, F4, F4, F4, F4, D4, D4, F4, F4, G4, G4 13 | .track04 dw D4, 0, D4, 0, D5, 0, 0, 0, A4, 0, 0, 0, 0, 0, GS4,GS4,0, 0, G4, 0, 0, 0, F4, F4, F4, F4, D4, D4, F4, F4, G4, G4 14 | .track05 dw C4, 0, C4, 0, D5, 0, 0, 0, A4, 0, 0, 0, 0, 0, GS4,GS4,0, 0, G4, 0, 0, 0, F4, F4, F4, F4, D4, D4, F4, F4, G4, G4 15 | .track06 dw B3, 0, B3, 0, D5, 0, 0, 0, A4, 0, 0, 0, 0, 0, GS4,GS4,0, 0, G4, 0, 0, 0, F4, F4, F4, F4, D4, D4, F4, F4, G4, G4 16 | .track07 dw AS3,0, AS3,0, D5, 0, 0, 0, A4, 0, 0, 0, 0, 0, GS4,GS4,0, 0, G4, 0, 0, 0, F4, F4, F4, F4, D4, D4, F4, F4, G4, G4 17 | .track08 dw D4, D5, D4, D5, D5, D6, 0, 0, A4, A5, 0, 0, 0, 0, GS4,GS5,0, 0, G4, G5, 0, 0, F4, F5, F4, F5, D4, D5, F4, F5, G4, G5 18 | .track09 dw C4, C5, C4, C5, D5, D6, 0, 0, A4, A5, 0, 0, 0, 0, GS4,GS5,0, 0, G4, G5, 0, 0, F4, F5, F4, F5, D4, D5, F4, F5, G4, G5 19 | .track0A dw B3, B4, B3, B4, D5, D6, 0, 0, A4, A5, 0, 0, 0, 0, GS4,GS5,0, 0, G4, G5, 0, 0, F4, F5, F4, F5, D4, D5, F4, F5, G4, G5 20 | .track0B dw AS3,AS4,AS3,AS4,D5, D6, 0, 0, A4, A5, 0, 0, 0, 0, GS4,GS5,0, 0, G4, G5, 0, 0, F4, F5, F4, F5, D4, D5, F4, F5, G4, G5 21 | 22 | .track0C dw D4, D5, D4, D5, D5, D6, 0, 0, A4, A5, 0, 0, 0, 0, GS4,GS5,0, 0, G4, G5, 0, 0, F4, F5, F4, F5, D4, D5, F4, F5, G4, G5 23 | .track0D dw C4, C5, C4, C5, D5, D6, 0, 0, A4, A5, 0, 0, 0, 0, GS4,GS5,0, 0, G4, G5, 0, 0, F4, F5, F4, F5, D4, D5, F4, F5, G4, G5 24 | .track0E dw B3, B4, B3, B4, D5, D6, 0, 0, A4, A5, 0, 0, 0, 0, GS4,GS5,0, 0, G4, G5, 0, 0, F4, F5, F4, F5, D4, D5, F4, F5, G4, G5 25 | .track0F dw AS3,AS4,AS3,AS4,D5, D6, 0, 0, A4, A5, 0, 0, 0, 0, GS4,GS5,0, 0, G4, G5, 0, 0, F4, F5, F4, F5, D4, D5, F4, F5, G4, G5 26 | 27 | .track10 dw F5, F5, F5, 0, F5, 0, F5, 0, 0, 0, F5, 0, 0, 0, F5, F5, F5, F5, D5, D5, D5, 0, D5, D5, D5, D5, D5, D5, D5, D5, D5, D5 28 | .track11 dw F5, F5, F5, 0, F5, 0, F5, 0, 0, 0, G5, 0, 0, 0, GS5,GS5,GS5,GS5,G5, A5, G5, F5, F5, D5, D5, F5, F5, G5, G5, 0, 0, 0 29 | .track12 dw F5, F5, F5, 0, F5, 0, F5, 0, 0, 0, G5, 0, 0, 0, GS5,GS5,0, 0, A5, A5, A5, A5, C6, C6, C6, C6, A5, A5, A5, A5, A5, A5 30 | .track13 dw D6, 0, 0, 0, D6, 0, 0, 0, D6, D6, A5, A5, D6, D6, C6, C6, C6, C6, C6, C6, C6, C6, C6, C6, 0, 0, 0, 0, 0, 0, 0, 0 31 | 32 | ; 0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 33 | .track14 dw F5, A5, F5, A5, F5, A5, F5, A5, 0, 0, F5, A5, 0, 0, F5, A5, F5, A5, D5, G5, 0, 0, D5, G5, D5, G5, D5, G5, D5, G5, D5, G5 34 | .track15 dw F5, A5, F5, A5, F5, A5, F5, A5, 0, 0, F5, A5, 0, 0, D5, G5, 0, 0, F5, A5, 0, 0, E5, D6, 0, 0, D5, A5, C5, G5, C5, G5 35 | .track16 dw B5, D6, G5, D6, D5, A5, E5, A5, F5, G5, D5, G5, B4, F5, D5, F5, 0, C6, D5, C6, B4, G5, D5, G5, B4, F5, G4, F5, B4, E5, G4, E5 36 | .track17 dw AS4,AS4,AS4,AS4,C5, C5, AS4,D5, 0, 0, D5, F5, D5, F5, E5, C6, E5, C6, E5, C6, E5, C6, E5, C6, E5, C6, E5, C6, E5, C6, E5, C6 37 | 38 | .track18 dw 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, D5, F5, AS4,D5, D5, F5, E5, G5, F5, GS5,E5, G5, D5, F5, AS4,D5 39 | .track19 dw GS5,G5, F5, D5, D5, F5, E5, G5, E5, G5, E5, G5, E5, G5, E5, G5, E5, G5, E5, G5, E5, G5, E5, G5, E5, G5, GS5,GS5,GS5,GS5,A5, A5 40 | .track1A dw C6, 0, 0, 0, GS5,0, GS5,0, G5, G5, F5, F5, D5, D5, E5, E5, F5, F5, F5, F5, G5, G5, G5, G5, A5, A5, A5, A5, C6, C6, C6, C6 41 | .track1B dw CS6,CS6,CS6,CS6,GS5,0, 0, 0, GS5,GS5,G5, G5, F5, F5, G5, G5, G5, G5, G5, G5, G5, G5, G5, G5, G5, G5, G5, G5, G5, G5, G5, G5 42 | 43 | .track1C dw D4, F4, D4, F4, E4, G4, E4, G4, F4, A4, F4, A4, D5, F5, D5, F5, C5, E5, C5, E5, C5, E5, C5, E5, A4, D5, A4, D5, A4, D5, A4, D5 44 | .track1D dw G4, E5, G4, E5, G4, E5, G4, E5, A4, F5, A4, F5, A4, F5, A4, F5, C5, G5, C5, G5, C5, G5, C5, G5, A4, E5, A4, E5, A4, E5, A4, E5 45 | .track1E dw D5, A5, D5, A5, D5, A5, D5, A5, D5, A5, D5, A5, D5, A5, D5, A5, A5, A5, GS5,GS5,G5, G5, FS5,FS5,F5, F5, E5, E5, DS5,DS5,D5, D5 46 | .track1F dw GS4,CS5,GS4,CS5,GS4,CS5,GS4,CS5,GS4,CS5,GS4,CS5,GS4,CS5,GS4,CS5,AS4,DS5,AS4,DS5,AS4,DS5,AS4,DS5,AS4,DS5,AS4,DS5,AS4,DS5,AS4,DS5 47 | 48 | .track20 dw 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, D5, F5, AS4,D5, D5, F5, E5, G5, F5, GS5,E5, G5, D5, F5, AS4,D5 49 | .track21 dw GS5,G5, F5, D5, D5, F5, E5, G5, E5, G5, E5, G5, E5, G5, E5, G5, E5, G5, E5, G5, E5, G5, E5, G5, E5, G5, GS5,GS5,GS5,GS5,A5, A5 50 | .track22 dw C6, 0, 0, 0, GS5,0, GS5,0, G5, G5, F5, F5, D5, D5, E5, E5, F5, F5, F5, F5, G5, G5, G5, G5, A5, A5, A5, A5, C6, C6, C6, C6 51 | .track23 dw CS6,CS6,CS6,CS6,GS5,0, 0, 0, GS5,GS5,G5, G5, F5, F5, G5, G5, G5, G5, G5, G5, G5, G5, G5, G5, G5, G5, G5, G5, G5, G5, G5, G5 52 | 53 | .track24 dw D4, F4, D4, F4, E4, G4, E4, G4, F4, A4, F4, A4, D5, F5, D5, F5, C5, E5, C5, E5, C5, E5, C5, E5, A4, D5, A4, D5, A4, D5, A4, D5 54 | .track25 dw G4, E5, G4, E5, G4, E5, G4, E5, A4, F5, A4, F5, A4, F5, A4, F5, C5, G5, C5, G5, C5, G5, C5, G5, A4, E5, A4, E5, A4, E5, A4, E5 55 | .track26 dw D5, A5, D5, A5, D5, A5, D5, A5, D5, A5, D5, A5, D5, A5, D5, A5, A5, A5, GS5,GS5,G5, G5, FS5,FS5,F5, F5, E5, E5, DS5,DS5,D5, D5 56 | .track27 dw GS4,CS5,GS4,CS5,GS4,CS5,GS4,CS5,GS4,CS5,GS4,CS5,GS4,CS5,GS4,CS5,AS4,DS5,AS4,DS5,AS4,DS5,AS4,DS5,AS4,DS5,AS4,DS5,AS4,DS5,AS4,DS5 57 | 58 | ; 0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 59 | .track28 dw AS3,AS3,AS3,AS3,AS3,AS3,AS3,AS3,AS3,AS3,AS3,AS3,AS3,AS3,AS3,AS3,AS3,AS3,AS3,AS3,AS3,AS3,AS3,AS3,F4, F4, F4, F4, F4, F4, F4, F4 60 | .track29 dw E4, E4, E4, E4, E4, E4, E4, E4, E4, E4, E4, E4, E4, E4, E4, E4, D4, D4, D4, D4, D4, D4, D4, D4, D4, D4, D4, D4, D4, D4, D4, D4 61 | .track2A dw F4, F4, F4, F4, F4, F4, F4, F4, F4, F4, F4, F4, F4, F4, F4, F4, F4, F4, F4, F4, F4, F4, F4, F4, F4, F4, F4, F4, F4, F4, F4, F4 62 | .track2B dw F4, F4, F4, F4, F4, F4, F4, F4, F4, F4, F4, F4, F4, F4, F4, F4, F4, F4, F4, F4, F4, F4, F4, F4, F4, F4, F4, F4, F4, F4, F4, F4 63 | 64 | .track2C dw AS3,AS3,AS3,AS3,AS3,AS3,AS3,AS3,AS3,AS3,AS3,AS3,AS3,AS3,AS3,AS3,AS3,AS3,AS3,AS3,AS3,AS3,AS3,AS3,F4, F4, F4, F4, F4, F4, F4, F4 65 | .track2D dw E4, E4, E4, E4, E4, E4, E4, E4, E4, E4, E4, E4, E4, E4, E4, E4, D4, D4, D4, D4, D4, D4, D4, D4, D4, D4, D4, D4, D4, D4, D4, 0 66 | .track2E dw D4, D4, D4, D4, D4, D4, D4, 0, D4, D4, CS4,CS4,C4, C4, B3, B3, AS3,AS3,A3, A3, GS3,GS3,G3, G3, FS3,FS3,F3, F3, E3, E3, DS3,DS3 67 | .track2F dw D3, D3, D3, D3, D3, D3, D3, D3, D3, D3, D3, D3, D3, D3, D3, D3, D3, D3, D3, D3, D3, D3, D3, D3, D3, D3, D3, D3, D3, D3, D3, D3 68 | 69 | 70 | 71 | .end dw 1 72 | -------------------------------------------------------------------------------- /files/src/monkey.dro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/src/monkey.dro -------------------------------------------------------------------------------- /files/src/neointro.dro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/src/neointro.dro -------------------------------------------------------------------------------- /files/src/phemopop.dro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/src/phemopop.dro -------------------------------------------------------------------------------- /files/src/px3.dro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/src/px3.dro -------------------------------------------------------------------------------- /files/src/strkfrce.dro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/src/strkfrce.dro -------------------------------------------------------------------------------- /files/src/swinging.dro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/src/swinging.dro -------------------------------------------------------------------------------- /files/src/tetris.mus: -------------------------------------------------------------------------------- 1 | ; MichalOS Music Format File 2 | 3 | %INCLUDE "include/constants.asm" 4 | 5 | start: 6 | .pit_data dw 0 7 | .song_delay db 2 8 | ; 0 1 2 3 4 5 6 7 8 9 A B C D E F 9 | .track00 dw E5, E5, E5, E5, B4, B4, C5, C5, D5, D5, E5, D5, C5, C5, B4, B4 10 | .track01 dw A4, A4, A4, 0, A4, A4, C5, C5, E5, E5, E5, E5, D5, D5, C5, C5 11 | .track02 dw B4, B4, B4, B4, B4, B4, C5, C5, D5, D5, D5, D5, E5, E5, E5, E5 12 | .track03 dw C5, C5, C5, C5, A4, A4, A4, 0, A4, A4, A4, 0, 0, 0, 0, 0 13 | .track04 dw 0, 0, D5, D5, D5, D5, F5, F5, A5, 0, A5, A5, G5, G5, F5, F5 14 | .track05 dw E5, E5, E5, E5, E5, E5, C5, C5, E5, E5, E5, E5, D5, D5, C5, C5 15 | .track06 dw B4, B4, B4, 0, B4, B4, C5, C5, D5, D5, D5, D5, E5, E5, E5, E5 16 | .track07 dw C5, C5, C5, C5, A4, A4, A4, 0, A4, A4, A4, A4, 0, 0, 0, 0 17 | .track08 dw E5, E5, E5, E5, B4, B4, C5, C5, D5, D5, E5, D5, C5, C5, B4, B4 18 | .track09 dw A4, A4, A4, 0, A4, A4, C5, C5, E5, E5, E5, E5, D5, D5, C5, C5 19 | .track0A dw B4, B4, B4, B4, B4, B4, C5, C5, D5, D5, D5, D5, E5, E5, E5, E5 20 | .track0B dw C5, C5, C5, C5, A4, A4, A4, 0, A4, A4, A4, 0, 0, 0, 0, 0 21 | .track0C dw 0, 0, D5, D5, D5, D5, F5, F5, A5, 0, A5, A5, G5, G5, F5, F5 22 | .track0D dw E5, E5, E5, E5, E5, E5, C5, C5, E5, E5, E5, E5, D5, D5, C5, C5 23 | .track0E dw B4, B4, B4, 0, B4, B4, C5, C5, D5, D5, D5, D5, E5, E5, E5, E5 24 | .track0F dw C5, C5, C5, C5, A4, A4, A4, 0, A4, A4, A4, A4, 0, 0, 0, 0 25 | .track10 dw E5, E5, E5, E5, E5, E5, E5, E5, C5, C5, C5, C5, C5, C5, C5, C5 26 | .track11 dw D5, D5, D5, D5, D5, D5, D5, D5, B4, B4, B4, B4, B4, B4, B4, B4 27 | .track12 dw C5, C5, C5, C5, C5, C5, C5, C5, A4, A4, A4, A4, A4, A4, A4, A4 28 | .track13 dw GS4,GS4,GS4,GS4,GS4,GS4,GS4,GS4,B4, B4, B4, B4, 0, 0, 0, 0 29 | .track14 dw E5, E5, E5, E5, E5, E5, E5, E5, C5, C5, C5, C5, C5, C5, C5, C5 30 | .track15 dw D5, D5, D5, D5, D5, D5, D5, D5, B4, B4, B4, B4, B4, B4, B4, B4 31 | .track16 dw C5, C5, C5, C5, E5, E5, E5, E5, A5, A5, A5, A5, A5, A5, A5, A5 32 | .track17 dw GS5,GS5,GS5,GS5,GS5,GS5,GS5,GS5,0, 0, 0, 0, 0, 0, 0, 0 33 | 34 | 35 | 36 | .end dw 1 37 | -------------------------------------------------------------------------------- /files/src/tmarch.mus: -------------------------------------------------------------------------------- 1 | ; MichalOS Music Format File 2 | 3 | %INCLUDE "include/constants.asm" 4 | 5 | start: 6 | .pit_data dw 0 7 | .song_delay db 2 8 | .track00 dw 0, 0, 0, 0, B4, A4, GS4, A4 9 | .track01 dw C5, C5, 0, 0, D5, C5, B4, C5 10 | .track02 dw E5, E5, 0, 0, F5, E5, DS5, E5 11 | .track03 dw B5, A5, GS5, A5, B5, A5, GS5, A5 12 | .track04 dw C6, C6, 0, 0, A5, 0, C6, 0 13 | .track05 dw B5, 0, A5, 0, G5, 0, A5, 0 14 | .track06 dw B5, 0, A5, 0, G5, 0, A5, 0 15 | .track07 dw B5, 0, A5, 0, G5, 0, FS5, 0 16 | .track08 dw E5, E5, 0, 0, B4, A4, GS4, A4 17 | .track09 dw C5, C5, 0, 0, D5, C5, B4, C5 18 | .track0A dw E5, E5, 0, 0, F5, E5, DS5, E5 19 | .track0B dw B5, A5, GS5, A5, B5, A5, GS5, A5 20 | .track0C dw C6, C6, 0, 0, A5, 0, C6, 0 21 | .track0D dw B5, 0, A5, 0, G5, 0, A5, 0 22 | .track0E dw B5, 0, A5, 0, G5, 0, A5, 0 23 | .track0F dw B5, 0, A5, 0, G5, 0, FS5, 0 24 | .track10 dw E5, E5, 0, 0, E5, 0, F5, 0 25 | .track11 dw G5, 0, G5, 0, A5, G5, F5, E5 26 | .track12 dw D5, D5, 0, 0, E5, 0, F5, 0 27 | .track13 dw G5, 0, G5, 0, A5, G5, F5, E5 28 | .track14 dw D5, D5, 0, 0, C5, 0, D5, 0 29 | .track15 dw E5, 0, E5, 0, F5, E5, D5, C5 30 | .track16 dw B4, B4, 0, 0, C5, 0, D5, 0 31 | .track17 dw E5, 0, E5, 0, F5, E5, D5, C5 32 | .track18 dw B4, B4, 0, 0, B4, A4, GS4, A4 33 | .track19 dw C5, C5, 0, 0, D5, C5, B4, C5 34 | .track1A dw E5, E5, 0, 0, F5, E5, DS5, E5 35 | .track1B dw B5, A5, GS5, A5, B5, A5, GS5, A5 36 | .track1C dw C6, C6, 0, 0, A5, 0, B5, 0 37 | .track1D dw C6, 0, B5, 0, A5, 0, GS5, 0 38 | .track1E dw A5, 0, E5, 0, F5, 0, D5, 0 39 | .track1F dw C5, C5, 0, 0, B4, A4, B4, B4 40 | .track20 dw A4, A4, A4, A4 41 | 42 | .end dw 1 43 | -------------------------------------------------------------------------------- /files/src/tmarch1.mus: -------------------------------------------------------------------------------- 1 | ; MichalOS Music Format File 2 | 3 | %INCLUDE "include/constants.asm" 4 | 5 | start: 6 | .pit_data dw 0 7 | .song_delay db 2 8 | .track00 dw 0, 0, 0, 0, 0, 0, 0, 0 9 | .track01 dw A3, 0, E4, 0, E4, 0, E4, 0 10 | .track02 dw A3, 0, E4, 0, E4, 0, E4, 0 11 | .track03 dw A3, 0, E4, 0, A3, 0, E4, 0 12 | .track04 dw A3, 0, E4, 0, E4, 0, E4, 0 13 | .track05 dw E3, 0, B3, 0, B3, 0, B3, 0 14 | .track06 dw E3, 0, B3, 0, B3, 0, B3, 0 15 | .track07 dw E3, 0, B3, 0, B2, 0, B3, 0 16 | .track08 dw E3, E3, 0, 0, 0, 0, 0, 0 17 | .track09 dw A3, 0, E4, 0, E4, 0, E4, 0 18 | .track0A dw A3, 0, E4, 0, E4, 0, E4, 0 19 | .track0B dw A3, 0, E4, 0, A3, 0, E4, 0 20 | .track0C dw A3, 0, E4, 0, E4, 0, E4, 0 21 | .track0D dw E3, 0, B3, 0, B3, 0, B3, 0 22 | .track0E dw E3, 0, B3, 0, B3, 0, B3, 0 23 | .track0F dw E3, 0, B3, 0, B2, 0, B3, 0 24 | .track10 dw E3, E3, 0, 0, 0, 0, 0, 0 25 | .track11 dw C3, 0, C4, 0, E3, 0, E4, 0 26 | .track12 dw G3, G3, 0, 0, 0, 0, 0, 0 27 | .track13 dw C3, 0, C4, 0, E3, 0, E4, 0 28 | .track14 dw G3, G3, 0, 0, 0, 0, 0, 0 29 | .track15 dw A2, 0, A3, 0, C3, 0, C4, 0 30 | .track16 dw E3, E3, 0, 0, 0, 0, 0, 0 31 | .track17 dw A2, 0, A3, 0, C3, 0, C4, 0 32 | .track18 dw E3, E3, 0, 0, 0, 0, 0, 0 33 | .track19 dw A3, 0, E4, 0, E4, 0, E4, 0 34 | .track1A dw A3, 0, E4, 0, E4, 0, E4, 0 35 | .track1B dw A3, 0, E4, 0, A3, 0, E4, 0 36 | .track1C dw F3, 0, DS4, 0, DS4, 0, DS4, 0 37 | .track1D dw F3, 0, E4, 0, D3, 0, B3, 0 38 | .track1E dw C3, 0, A3, 0, D3, 0, B3, 0 39 | .track1F dw E3, 0, A3, 0, E3, 0, GS3, 0 40 | .track20 dw A2, A2, A2, A2 41 | 42 | .end dw 1 43 | -------------------------------------------------------------------------------- /files/src/tyrian.dro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/src/tyrian.dro -------------------------------------------------------------------------------- /files/src/ultima6.dro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/src/ultima6.dro -------------------------------------------------------------------------------- /files/src/wolf3d.dro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/src/wolf3d.dro -------------------------------------------------------------------------------- /files/streets.rad: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/streets.rad -------------------------------------------------------------------------------- /files/whscream.rad: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/whscream.rad -------------------------------------------------------------------------------- /files/zap.rad: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prochazkaml/MichalOS/1dc9e80bbfeccaeaf08609a20808018d667d6ab5/files/zap.rad -------------------------------------------------------------------------------- /include/constants.asm: -------------------------------------------------------------------------------- 1 | ; ------------------------------------------------------------------ 2 | ; Include file for MichalOS kernel/program development - constants & macros 3 | ; ------------------------------------------------------------------ 4 | 5 | ; ------------------------------------------------------------------ 6 | ; COLOURS (eg for os_draw_background and os_draw_block) 7 | 8 | %DEFINE BLACK_ON_WHITE 11110000b 9 | %DEFINE WHITE_ON_BLACK 00001111b 10 | 11 | ; ------------------------------------------------------------------ 12 | ; KEYS 13 | 14 | %DEFINE KEY_UP 72 15 | %DEFINE KEY_DOWN 80 16 | %DEFINE KEY_LEFT 75 17 | %DEFINE KEY_RIGHT 77 18 | 19 | %DEFINE KEY_ESC 27 20 | %DEFINE KEY_ENTER 13 21 | 22 | ; ------------------------------------------------------------------ 23 | ; MACROS 24 | 25 | %macro syscall 1 26 | mov bp, %1 27 | call os_syscall 28 | %endmacro 29 | 30 | %macro clr 1 31 | xor %1, %1 32 | %endmacro 33 | 34 | %macro mov16 3 35 | mov %1, (%2 + %3 * 256) 36 | %endmacro 37 | 38 | %macro movs 2 39 | push %2 40 | pop %1 41 | %endmacro 42 | 43 | ; ------------------------------------------------------------------ 44 | ; MEMORY LOCATIONS 45 | 46 | %define ADLIB_BUFFER 0500h 47 | %define DESKTOP_BACKGROUND 0600h 48 | %define SYSTEM_FONT 1600h 49 | %define FILE_MANAGER 2600h 50 | %define DISK_PARAMS 2E00h 51 | 52 | %define DISK_BUFFER 0E000h 53 | %define CONFIG_FILE 57000 54 | %define CONFIG_FILE_SIZE 83 55 | 56 | ; ------------------------------------------------------------------ 57 | ; CONFIG FILE LOCATIONS 58 | 59 | %define CONFIG(x) (CONFIG_FILE + x) 60 | 61 | ; 0 = Desktop background color (BYTE) 62 | %define CONFIG_DESKTOP_BG_COLOR CONFIG(0) 63 | 64 | ; 1 = Window background color (BYTE) 65 | %define CONFIG_WINDOW_BG_COLOR CONFIG(1) 66 | 67 | ; 2 = Password enabled (BYTE) 68 | %define CONFIG_PASSWORD_ENABLED CONFIG(2) 69 | 70 | ; 3 - 35 = Password data (STRING, 32 chars + '\0') 71 | %define CONFIG_PASSWORD CONFIG(3) 72 | %define CFG_PASSWORD_MAX_INPUT_LENGTH 32 73 | %define CFG_PASSWORD_MAX_LENGTH 33 74 | 75 | ; 36 - 68 = Username (STRING, 32 chars + '\0') 76 | %define CONFIG_USERNAME CONFIG(36) 77 | %define CFG_USERNAME_MAX_INPUT_LENGTH 32 78 | %define CFG_USERNAME_MAX_LENGTH 33 79 | 80 | ; 69 - Sound enabled on startup (BYTE) 81 | %define CONFIG_SOUND_ENABLED CONFIG(69) 82 | 83 | ; 70 - Adlib driver number 84 | %define CONFIG_ADLIB_DRIVER CONFIG(70) 85 | %define CFG_ADLIB_STD_DRIVER 0 86 | %define CFG_ADLIB_PWM_DRIVER 1 87 | %define CFG_ADLIB_PWM_LOUD_DRIVER 2 88 | 89 | ; 71 - Menu screen dimming enabled (BYTE) 90 | %define CONFIG_MENU_DIMMING CONFIG(71) 91 | 92 | ; 72 - Menu color (BYTE) 93 | %define CONFIG_MENU_BG_COLOR CONFIG(72) 94 | 95 | ; 73 - "DOS" font enabled (BYTE) 96 | %define CONFIG_FONT CONFIG(73) 97 | %define CFG_FONT_MICHALOS 0 98 | %define CFG_FONT_BIOS 1 99 | 100 | ; 74 - Minutes to wait for screensaver (BYTE) 101 | %define CONFIG_SCREENSAVER_MINUTES CONFIG(74) 102 | 103 | ; 75 - System stack size in 16-byte blocks (WORD) 104 | %define CONFIG_STACKSGMT_SIZE CONFIG(75) 105 | 106 | ; 77 - 80 - Unused ******************************* 107 | 108 | ; 81 - Minute time offset (WORD) 109 | %define CONFIG_TIMEZONE_OFFSET CONFIG(81) 110 | 111 | ; ------------------------------------------------------------------ 112 | ; MUSICAL NOTE FREQUENCY LIST 113 | 114 | A2 equ 110 115 | AS2 equ 117 116 | B2 equ 124 117 | C3 equ 131 118 | CS3 equ 139 119 | D3 equ 147 120 | DS3 equ 156 121 | E3 equ 165 122 | F3 equ 175 123 | FS3 equ 185 124 | G3 equ 196 125 | GS3 equ 208 126 | A3 equ 220 127 | AS3 equ 233 128 | B3 equ 247 129 | C4 equ 262 130 | CS4 equ 277 131 | D4 equ 294 132 | DS4 equ 311 133 | E4 equ 330 134 | F4 equ 349 135 | FS4 equ 370 136 | G4 equ 392 137 | GS4 equ 415 138 | A4 equ 440 139 | AS4 equ 466 140 | B4 equ 494 141 | C5 equ 523 142 | CS5 equ 554 143 | D5 equ 587 144 | DS5 equ 622 145 | E5 equ 659 146 | F5 equ 698 147 | FS5 equ 740 148 | G5 equ 784 149 | GS5 equ 831 150 | A5 equ 880 151 | AS5 equ 932 152 | B5 equ 988 153 | C6 equ 1046 154 | CS6 equ 1109 155 | D6 equ 1175 156 | DS6 equ 1245 157 | E6 equ 1319 158 | F6 equ 1397 159 | FS6 equ 1480 160 | G6 equ 1568 161 | GS6 equ 1661 162 | A6 equ 1760 163 | AS6 equ 1865 164 | B6 equ 1976 165 | C7 equ 2093 166 | CS7 equ 2217 167 | D7 equ 2349 168 | DS7 equ 2489 169 | E7 equ 2637 170 | F7 equ 2794 171 | FS7 equ 2960 172 | G7 equ 3136 173 | GS7 equ 3322 174 | A7 equ 3520 175 | AS7 equ 3729 176 | B7 equ 3951 177 | C8 equ 4186 178 | CS8 equ 4435 179 | D8 equ 4699 180 | DS8 equ 4978 181 | E8 equ 5274 182 | F8 equ 5588 183 | FS8 equ 5920 184 | G8 equ 6272 185 | GS8 equ 6645 186 | A8 equ 7040 187 | AS8 equ 7459 188 | B8 equ 7902 189 | -------------------------------------------------------------------------------- /include/kernel.inc: -------------------------------------------------------------------------------- 1 | ; ------------------------------------------------------------------ 2 | ; Include file for MichalOS kernel development 3 | ; ------------------------------------------------------------------ 4 | 5 | %include "include/constants.asm" 6 | 7 | ; ----------------------------------------------------------------- 8 | -------------------------------------------------------------------------------- /include/program.inc: -------------------------------------------------------------------------------- 1 | ; ------------------------------------------------------------------ 2 | ; Include file for MichalOS program or kernel module development 3 | ; ------------------------------------------------------------------ 4 | 5 | BITS 16 6 | ORG 100h 7 | 8 | %include "include/constants.asm" 9 | %include "include/syscalls.asm" 10 | 11 | %macro oscall 1 12 | mov bp, %1 13 | int 40h 14 | %endmacro 15 | 16 | ; ----------------------------------------------------------------- 17 | -------------------------------------------------------------------------------- /kernel/compressed/sub_fatalerr.asm: -------------------------------------------------------------------------------- 1 | ; ================================================================== 2 | ; MichalOS Fatal error kill screen 3 | ; ================================================================== 4 | 5 | %include "include/program.inc" 6 | 7 | mov [.ax], ax ; Store string location for now, ... 8 | call os_clear_screen 9 | 10 | .main_screen: 11 | mov ax, cs 12 | mov ds, ax 13 | mov es, ax 14 | 15 | call os_init_text_mode 16 | 17 | mov ax, .title_msg 18 | mov bx, .footer_msg 19 | mov cx, 01001111b 20 | call os_draw_background 21 | 22 | mov dx, 2 * 256 23 | call os_move_cursor 24 | mov si, bomblogo 25 | call os_draw_icon 26 | 27 | mov dx, 2 * 256 + 35 28 | call os_move_cursor 29 | 30 | mov si, .msg0 31 | call os_print_string 32 | 33 | mov dx, 3 * 256 + 35 34 | call os_move_cursor 35 | 36 | mov ax, 0A2Ah ; Write a 43-character long asterisk-type line 37 | clr bh 38 | mov cx, 42 39 | int 10h 40 | 41 | mov dx, 5 * 256 + 35 42 | call os_move_cursor 43 | mov si, .msg3 44 | call os_print_string 45 | 46 | mov si, [.ax] 47 | call os_print_string 48 | 49 | call os_hide_cursor 50 | 51 | pop bx 52 | pop ax 53 | 54 | mov16 dx, 35, 7 55 | call os_move_cursor 56 | 57 | mov si, .msg 58 | call os_print_string 59 | 60 | call os_print_4hex 61 | 62 | mov al, ':' 63 | call os_putchar 64 | 65 | mov ax, bx 66 | call os_print_4hex 67 | 68 | mov16 dx, 35, 8 69 | call os_move_cursor 70 | 71 | mov si, .msg1 72 | call os_print_string 73 | 74 | mov ax, sp 75 | call os_print_4hex 76 | 77 | cli 78 | hlt 79 | 80 | .msg db 'Crash location: ', 0 81 | .msg1 db 'Stack pointer: ', 0 82 | 83 | .title_msg db 'MichalOS Fatal Error' 84 | .footer_msg db 0 85 | 86 | .msg0 db 'MichalOS has encountered a critical error.', 0 87 | .msg3 db 'Error: ', 0 88 | 89 | .ax dw 0 90 | 91 | bomblogo db 9, 16 92 | db 00000000b, 00000000b, 00000000b, 00000000b, 00000000b, 00100000b, 00000000b, 01100000b, 00000000b 93 | db 00000000b, 00000000b, 00000000b, 00000000b, 00000100b, 00000010b, 00000001b, 10000000b, 00000000b 94 | db 00000000b, 00000000b, 00000000b, 00000000b, 00000000b, 10000100b, 10000000b, 00000000b, 00000000b 95 | db 00000000b, 00000000b, 00000000b, 01101010b, 10100101b, 00000001b, 01010000b, 10001000b, 10000000b 96 | db 00000000b, 00000000b, 00000011b, 00000000b, 00000000b, 10101000b, 00000000b, 01000000b, 00000000b 97 | db 00000000b, 00000000b, 01010111b, 01010100b, 00000000b, 00011000b, 00100000b, 00100100b, 00000000b 98 | db 00000000b, 00000000b, 11111111b, 11111100b, 00000000b, 10000000b, 00100000b, 00000010b, 00000000b 99 | db 00000000b, 01011111b, 11111111b, 11111111b, 11010100b, 00000000b, 00100000b, 00000000b, 00000000b 100 | db 00000001b, 11111111b, 11111111b, 11111111b, 11111101b, 00000000b, 00000000b, 00000000b, 00000000b 101 | db 00000111b, 11111111b, 11111111b, 11111111b, 11111111b, 01000000b, 00000000b, 00000000b, 00000000b 102 | db 00001111b, 11111111b, 11111111b, 11111111b, 11111111b, 11000000b, 00000000b, 00000000b, 00000000b 103 | db 00001111b, 11111111b, 11111111b, 11111111b, 11111111b, 11000000b, 00000000b, 00000000b, 00000000b 104 | db 00001111b, 11111111b, 11111111b, 11111111b, 11111111b, 11000000b, 00000000b, 00000000b, 00000000b 105 | db 00000011b, 11111111b, 11111111b, 11111111b, 11111111b, 00000000b, 00000000b, 00000000b, 00000000b 106 | db 00000000b, 11111111b, 11111111b, 11111111b, 11111100b, 00000000b, 00000000b, 00000000b, 00000000b 107 | db 00000000b, 00001010b, 11111111b, 11111110b, 10000000b, 00000000b, 00000000b, 00000000b, 00000000b 108 | -------------------------------------------------------------------------------- /kernel/features/basicerr.txt: -------------------------------------------------------------------------------- 1 | Error 00: unexpected char in number 2 | Error 01: unknown command 3 | Error 02: attempt to divide by zero 4 | Error 03: DO/LOOP nesting limit exceeded 5 | Error 04: file not found 6 | Error 05: GOTO or GOSUB not followed by label 7 | Error 06: label not found 8 | Error 07: FOR or GOSUB nest limit exceeded 9 | Error 08: NEXT without FOR 10 | Error 09: LOOP without DO 11 | Error 10: PRINT not followed by quoted text or variable 12 | Error 11: quoted string or char not terminated correctly 13 | Error 12: RETURN without GOSUB 14 | Error 13: string location out of range 15 | Error 14: syntax error -------------------------------------------------------------------------------- /kernel/features/disk/cache.asm: -------------------------------------------------------------------------------- 1 | ; ================================================================== 2 | ; MichalOS Disk cache driver 3 | ; ================================================================== 4 | 5 | ; -------------------------------------------------------------------------- 6 | ; os_disk_cache_alloc_sector -- Allocates a free sector in the cache 7 | ; IN: DL = drive number, OUT: DS:SI = free 512 byte buffer 8 | 9 | os_disk_cache_alloc_sector: 10 | ; TODO 11 | ret 12 | 13 | ; -------------------------------------------------------------------------- 14 | ; os_disk_cache_read_sector -- Read a single sector from cache or disk, if necessary 15 | ; IN: EAX = sector ID, ES:SI = 512 byte buffer, DL = drive number, OUT: carry set if error 16 | 17 | os_disk_cache_read_sector: 18 | ret 19 | 20 | ; -------------------------------------------------------------------------- 21 | ; os_disk_cache_write_sector -- Write a single sector to cache or flush disk, if necessary 22 | ; IN: EAX = sector ID, ES:SI = 512 byte buffer, DL = drive number, OUT: carry set if error 23 | 24 | os_disk_cache_write_sector: 25 | ret 26 | -------------------------------------------------------------------------------- /kernel/features/icons.asm: -------------------------------------------------------------------------------- 1 | ; ================================================================== 2 | ; MichalOS Icons 3 | ; ================================================================== 4 | 5 | filelogo db 4, 8 6 | db 00001110b, 10101010b, 11010000b, 00000000b 7 | db 00001100b, 00000000b, 11001001b, 00000000b 8 | db 00001100b, 00000000b, 10101010b, 11000000b 9 | db 00001100b, 00000000b, 00000000b, 11000000b 10 | db 00001100b, 00000000b, 00000000b, 11000000b 11 | db 00001100b, 00000000b, 00000000b, 11000000b 12 | db 00001100b, 00000000b, 00000000b, 11000000b 13 | db 00001101b, 01010101b, 01010101b, 11000000b 14 | 15 | logo db 18, 7 16 | db 00000000b, 00000000b, 00001110b, 11101010b, 10101010b, 10101100b, 01000000b, 00000100b, 00000000b, 00000000b, 01000000b, 00000000b, 00000000b, 00010011b, 11101010b, 10111111b, 10101010b, 10110000b 17 | db 00000000b, 00000000b, 00001100b, 11101010b, 10101010b, 11101100b, 11100100b, 01101100b, 00000000b, 00000000b, 11000000b, 00000000b, 00000000b, 00110011b, 00111111b, 11001100b, 11111111b, 11110000b 18 | db 00000000b, 00000000b, 00001100b, 11000000b, 00000000b, 11001100b, 11000010b, 00001100b, 10000000b, 00000000b, 11000000b, 00000000b, 00000000b, 00110011b, 00111111b, 11001100b, 11111111b, 11110000b 19 | db 00000000b, 00000000b, 00001100b, 11000000b, 00000000b, 11001100b, 11000000b, 00001100b, 11000110b, 10101000b, 11011010b, 10010010b, 10101001b, 00110011b, 00111111b, 11001111b, 01010101b, 10110000b 20 | db 00000000b, 00000000b, 00001100b, 11000000b, 00000000b, 11001100b, 11000000b, 00001100b, 11001100b, 00000000b, 11000000b, 00110001b, 10101011b, 00110011b, 00111111b, 11001111b, 11111111b, 00110000b 21 | db 00000000b, 00000000b, 00001110b, 10101010b, 10101010b, 11001100b, 11000000b, 00001100b, 11001001b, 01010100b, 11000000b, 00110010b, 01010110b, 00110011b, 01101010b, 10011110b, 10101010b, 01110000b 22 | db 00000000b, 00000000b, 00001010b, 10101010b, 10101010b, 10101000b, 00000000b, 00000000b, 00000000b, 00000000b, 00000000b, 00000000b, 00000000b, 00000010b, 10101010b, 10101010b, 10101010b, 10100000b 23 | 24 | ; ================================================================== 25 | -------------------------------------------------------------------------------- /kernel/features/int.asm: -------------------------------------------------------------------------------- 1 | ; ================================================================== 2 | ; MichalOS Interrupt management & app timer functions 3 | ; ================================================================== 4 | 5 | ; ----------------------------------------------------------------- 6 | ; os_modify_int_handler -- Change location of interrupt handler 7 | ; IN: CL = int number, DI:SI = handler location 8 | ; OUT: None, registers preserved 9 | 10 | os_modify_int_handler: 11 | pusha 12 | 13 | .no_pusha: 14 | cli 15 | 16 | movzx bx, cl ; Move supplied int into BX 17 | shl bx, 2 ; Multiply by four to get position 18 | 19 | mov [fs:bx], si ; First store offset 20 | mov [fs:bx + 2], di ; Then segment of our handler 21 | 22 | sti 23 | popa 24 | ret 25 | 26 | ; ----------------------------------------------------------------- 27 | ; os_get_int_handler -- Change location of interrupt handler 28 | ; IN: CL = int number 29 | ; OUT: DI:SI = handler location 30 | 31 | os_get_int_handler: 32 | push bx 33 | 34 | movzx bx, cl ; Move supplied int into BX 35 | shl bx, 2 ; Multiply by four to get position 36 | 37 | mov si, [fs:bx] ; First store offset 38 | mov di, [fs:bx + 2] ; Then segment of our handler 39 | 40 | pop bx 41 | ret 42 | 43 | ; ------------------------------------------------------------------ 44 | ; os_pause -- Delay execution for a specified number of ticks (18.2 Hz by default) 45 | ; IN: AX = amount of ticks to wait 46 | ; OUT: None, registers preserved 47 | 48 | os_pause: 49 | mov [cs:pause_timer], ax 50 | 51 | .wait_loop: 52 | cmp word [cs:pause_timer], 0 53 | jne .wait_loop 54 | ret 55 | 56 | ; ----------------------------------------------------------------- 57 | ; os_attach_app_timer -- Attach a timer interrupt to an application and sets the timer speed 58 | ; Formula: speed = (105000000 / 88) / frequency 59 | ; IN: DS:SI = handler location, CX = speed 60 | ; OUT: None, registers preserved 61 | 62 | os_attach_app_timer: 63 | pusha 64 | mov byte [cs:timer_application_attached], 0 65 | 66 | test si, si 67 | jz os_set_timer_speed.no_pusha 68 | 69 | mov [cs:timer_application_offset], si 70 | mov [cs:timer_application_segment], ds 71 | mov byte [cs:timer_application_attached], 1 72 | 73 | jmp os_set_timer_speed.no_pusha 74 | 75 | ; ----------------------------------------------------------------- 76 | ; os_return_app_timer -- Returns the timer interrupt back to the system and resets the timer speed 77 | ; IN/OUT: None, registers preserved 78 | 79 | os_return_app_timer: 80 | pusha 81 | mov byte [cs:timer_application_attached], 0 82 | 83 | clr cx 84 | call os_set_timer_speed 85 | 86 | mov cl, 1Ch ; RTC handler 87 | mov si, os_compat_int1C 88 | mov di, cs 89 | jmp os_modify_int_handler.no_pusha 90 | 91 | ; ----------------------------------------------------------------- 92 | ; os_set_timer_speed -- Sets the timer's trigger speed. 93 | ; Formula: speed = (105000000 / 88) / frequency 94 | ; IN: CX = speed 95 | ; OUT: Nothing, registers preserved 96 | 97 | os_set_timer_speed: 98 | pusha 99 | 100 | .no_pusha: 101 | mov [cs:current_timer_speed], cx 102 | 103 | mov al, 00110110b ; Timer 0, square wave 104 | out 43h, al 105 | mov al, cl 106 | out 40h, al 107 | mov al, ch 108 | out 40h, al 109 | 110 | pushad 111 | clr edx 112 | mov eax, 105000000*60/88 ; Ticks per minute 113 | 114 | dec cx ; 0x0000 -> 0xFFFF 115 | movzx ecx, cx 116 | inc ecx ; 0xFFFF -> 0x10000 117 | 118 | div ecx 119 | 120 | mov [cs:current_timer_freq], eax 121 | popad 122 | 123 | popa 124 | ret 125 | 126 | ; ----------------------------------------------------------------- 127 | ; Interrupt call parsers 128 | 129 | ; Division by 0 error handler 130 | os_compat_int00: 131 | mov ax, .msg 132 | jmp os_fatal_error 133 | 134 | .msg db 'CPU: Division by zero error', 0 135 | 136 | ; Invalid opcode handler 137 | os_compat_int06: 138 | mov ax, .msg 139 | jmp os_fatal_error 140 | 141 | .msg db 'CPU: Invalid opcode', 0 142 | 143 | ; Processor extension error handler 144 | os_compat_int07: 145 | mov ax, .msg 146 | jmp os_fatal_error 147 | 148 | .msg db 'CPU: Processor extension error', 0 149 | 150 | ; System timer handler (8253/8254) 151 | os_compat_int1C: 152 | cli 153 | pushad 154 | push ds 155 | push es 156 | 157 | mov ax, cs 158 | mov ds, ax 159 | mov es, ax 160 | 161 | cmp dword [screensaver_timer], 0 162 | je .no_update_screensaver 163 | 164 | dec dword [screensaver_timer] 165 | 166 | .no_update_screensaver: 167 | cmp word [pause_timer], 0 168 | je .no_update_pause_timer 169 | 170 | dec word [pause_timer] 171 | 172 | .no_update_pause_timer: 173 | cmp byte [system_ui_state], 1 174 | je .no_update 175 | 176 | mov ah, 02h ; Get the time 177 | call os_int_1Ah 178 | cmp cx, [.tmp_time] 179 | je .no_update 180 | mov [.tmp_time], cx 181 | 182 | call os_print_clock 183 | 184 | .no_update: 185 | cmp byte [timer_application_attached], 1 186 | je .app_routine 187 | 188 | pop es 189 | pop ds 190 | popad 191 | sti 192 | iret 193 | 194 | .tmp_time dw 0 195 | 196 | .app_routine: 197 | mov ds, [timer_application_segment] 198 | movs es, ds 199 | call far [cs:timer_application_offset] 200 | 201 | pop es 202 | pop ds 203 | popad 204 | iret 205 | 206 | ; Far API call handler 207 | os_farcall_handler: 208 | sti 209 | 210 | call bp 211 | pushf 212 | pop bp 213 | 214 | push bx 215 | mov bx, sp 216 | mov [ss:bx + 6], bp 217 | pop bx 218 | 219 | clr bp 220 | iret 221 | 222 | timer_application_attached db 0 223 | timer_application_offset dw 0 224 | timer_application_segment dw 0 225 | 226 | current_timer_speed dw 0 227 | current_timer_freq dd 0 ; in Hz/64 228 | 229 | screensaver_timer dd 0 230 | pause_timer dw 0 231 | 232 | ; ================================================================== 233 | -------------------------------------------------------------------------------- /kernel/features/keyboard.asm: -------------------------------------------------------------------------------- 1 | ; ================================================================== 2 | ; MichalOS Keyboard input handling functions 3 | ; ================================================================== 4 | 5 | ; ------------------------------------------------------------------ 6 | ; os_wait_for_key -- Waits for keypress and returns key 7 | ; Also handles the screensaver. TODO: move the screensaver code to "int.asm" 8 | ; IN: None 9 | ; OUT: AX = key pressed, other regs preserved 10 | 11 | os_wait_for_key: 12 | push ds 13 | pusha 14 | movs ds, cs 15 | 16 | .try_again: 17 | clr bh 18 | call .screen_power 19 | 20 | ; Reset the screensaver tick 21 | movzx eax, byte [CONFIG_SCREENSAVER_MINUTES] 22 | mov ebx, [current_timer_freq] ; Multiply by the number of ticks per minute 23 | mul ebx 24 | mov [screensaver_timer], eax ; See "int.asm" 25 | 26 | mov byte [.scrn_active], 0 ; Reset all the screensaver variables 27 | 28 | mov al, [system_ui_state] ; Save the current screen state, for later 29 | mov [.gfx_state], al 30 | mov ah, 03h 31 | clr bh 32 | int 10h 33 | mov [.orig_crsr], cx ; Get the shape of the cursor 34 | 35 | .loop: 36 | hlt ; Halt the CPU for 1/18.2 seconds, to save the CPU usage 37 | call .screensaver 38 | call os_check_for_key 39 | 40 | test ax, ax 41 | jz .loop 42 | 43 | pusha 44 | mov ax, 0500h 45 | int 10h 46 | 47 | mov al, [.gfx_state] 48 | mov [system_ui_state], al 49 | mov cx, [.orig_crsr] 50 | mov ah, 01h 51 | int 10h 52 | popa 53 | 54 | cmp byte [.scrn_active], 1 55 | je .try_again 56 | 57 | popa 58 | mov ax, [os_check_for_key.tmp_buf] 59 | pop ds 60 | ret 61 | 62 | .screensaver: 63 | cmp dword [screensaver_timer], 0 64 | jne .good 65 | 66 | cmp byte [CONFIG_SCREENSAVER_MINUTES], 0 67 | je .good 68 | 69 | mov ah, 0Fh 70 | int 10h 71 | 72 | cmp al, 3 73 | jne .good 74 | 75 | pusha 76 | mov byte [system_ui_state], 1 77 | mov ax, 0501h 78 | int 10h 79 | call os_hide_cursor 80 | mov byte [.scrn_active], 1 81 | 82 | mov bh, 4 83 | call .screen_power 84 | popa 85 | 86 | .good: 87 | ret 88 | 89 | .screen_power: 90 | cmp bh, [.scrn_power] 91 | je .good 92 | 93 | pusha 94 | mov ax, 4F10h 95 | mov bl, 1 96 | mov [.scrn_power], bh 97 | int 10h 98 | popa 99 | ret 100 | 101 | .gfx_state db 0 102 | .orig_crsr dw 0 103 | .scrn_active db 0 104 | .scrn_power db 0 105 | 106 | ; ------------------------------------------------------------------ 107 | ; os_check_for_key -- Scans keyboard buffer for input, but doesn't wait 108 | ; Also handles special keyboard shortcuts. 109 | ; IN: None 110 | ; OUT: AX = 0 if no key pressed, otherwise scan code 111 | 112 | os_check_for_key: 113 | push ds 114 | pusha 115 | movs ds, cs 116 | 117 | mov ah, 11h ; BIOS call to check for key 118 | 119 | int 16h 120 | 121 | jz .nokey ; If no key, skip to end 122 | 123 | mov ah, 10h ; Otherwise get it from buffer 124 | int 16h 125 | 126 | call int_special_keys 127 | 128 | mov [.tmp_buf], ax ; Store resulting keypress 129 | popa ; But restore all other regs 130 | mov ax, [.tmp_buf] 131 | pop ds 132 | ret 133 | 134 | .nokey: 135 | popa 136 | pop ds 137 | clr ax ; Zero result if no key pressed 138 | ret 139 | 140 | .tmp_buf dw 0 141 | 142 | 143 | ; ================================================================== 144 | 145 | ; ------------------------------------------------------------------ 146 | ; int_special_keys -- Checks for special keys and performs their action. 147 | ; IN: AX = key 148 | ; OUT: None, registers preserved 149 | 150 | int_special_keys: 151 | pusha 152 | cmp ah, 105 153 | je .disable_sound 154 | cmp ah, 106 155 | je .enable_sound 156 | cmp ah, 107 157 | je .exit_app 158 | popa 159 | ret 160 | 161 | .exit_app: 162 | cmp byte [app_running], 0 163 | je .no_exit 164 | 165 | mov sp, [origstack] 166 | jmp finish 167 | 168 | .no_exit: 169 | popa 170 | ret 171 | 172 | .enable_sound: 173 | mov byte [speaker_unmuted], 1 174 | 175 | mov ax, [speaker_period] 176 | 177 | cmp ax, 1 178 | je .no_play_note 179 | 180 | call os_speaker_raw_period 181 | 182 | .no_play_note: 183 | jmp .display_speaker 184 | 185 | .disable_sound: 186 | mov byte [speaker_unmuted], 0 187 | call os_speaker_off 188 | 189 | .display_speaker: 190 | cmp byte [system_ui_state], 1 191 | je .no_display_spkr 192 | 193 | call os_get_cursor_pos 194 | push dx 195 | mov dx, 79 ; Print the little speaker icon 196 | call os_move_cursor 197 | 198 | mov ax, 0E17h 199 | clr bh 200 | cmp byte [speaker_unmuted], 0 201 | je .no_crossed_spkr 202 | 203 | dec al 204 | 205 | .no_crossed_spkr: 206 | int 10h 207 | pop dx 208 | call os_move_cursor 209 | 210 | .no_display_spkr: 211 | popa 212 | clr ax 213 | ret 214 | 215 | ; ================================================================== 216 | 217 | -------------------------------------------------------------------------------- /kernel/features/math.asm: -------------------------------------------------------------------------------- 1 | ; ================================================================== 2 | ; MichalOS Math functions 3 | ; ================================================================== 4 | 5 | ; ------------------------------------------------------------------ 6 | ; os_get_random -- Return a random integer between low and high (inclusive) 7 | ; IN: AX = low integer, BX = high integer 8 | ; OUT: CX = random integer 9 | 10 | os_get_random: 11 | push dx 12 | push bx 13 | push ax 14 | 15 | sub bx, ax ; We want a number between 0 and (high-low) 16 | call .generate_random 17 | mov dx, bx 18 | inc dx 19 | mul dx 20 | mov cx, dx 21 | 22 | pop ax 23 | pop bx 24 | pop dx 25 | add cx, ax ; Add the low offset back 26 | ret 27 | 28 | .generate_random: 29 | push dx 30 | 31 | mov ax, [cs:os_random_seed] 32 | mov dx, 0x7383 ; The magic number (random.org) 33 | mul dx ; DX:AX = AX * DX 34 | mov [cs:os_random_seed], ax 35 | 36 | pop dx 37 | ret 38 | 39 | os_random_seed dw 0x7384 40 | 41 | ; ------------------------------------------------------------------ 42 | ; os_bcd_to_int -- Converts a binary coded decimal number to an integer 43 | ; IN: AL = BCD number 44 | ; OUT: AX = integer value 45 | 46 | os_bcd_to_int: 47 | push cx 48 | push bx 49 | 50 | mov bl, al ; Store entire number for now 51 | 52 | and ax, 0Fh ; Zero-out high bits 53 | mov cx, ax ; CH/CL = lower BCD number, zero extended 54 | 55 | shr bl, 4 ; Move higher BCD number into lower bits, zero fill msb 56 | mov al, 10 57 | mul bl ; AX = 10 * BL 58 | 59 | add ax, cx ; Add lower BCD to 10*higher 60 | 61 | pop bx 62 | pop cx 63 | ret 64 | 65 | 66 | ; ------------------------------------------------------------------ 67 | ; os_int_to_bcd -- Converts an integer to a binary coded decimal number 68 | ; IN: AL = integer value 69 | ; OUT: AL = BCD number 70 | 71 | os_int_to_bcd: 72 | push bx 73 | push dx 74 | 75 | movzx ax, al 76 | xor dx, dx 77 | 78 | mov bx, 10 79 | div bx 80 | 81 | shl al, 4 82 | add al, dl 83 | 84 | pop dx 85 | pop bx 86 | ret 87 | 88 | 89 | ; ------------------------------------------------------------------ 90 | ; os_math_power -- Calculates EAX^EBX. 91 | ; IN: EAX^EBX = input 92 | ; OUT: EAX = result 93 | 94 | os_math_power: 95 | pushad 96 | cmp ebx, 1 97 | je .power_end 98 | 99 | test ebx, ebx 100 | jz .zero 101 | 102 | mov ecx, ebx ; Prepare the data 103 | mov ebx, eax 104 | 105 | .power_loop: 106 | mul ebx 107 | dec ecx 108 | 109 | cmp ecx, 1 110 | jnle .power_loop 111 | 112 | .power_end: 113 | mov [cs:.tmp_dword], eax 114 | popad 115 | mov eax, [cs:.tmp_dword] 116 | xor edx, edx 117 | ret 118 | 119 | .zero: 120 | popad 121 | mov eax, 1 122 | xor edx, edx 123 | ret 124 | 125 | .tmp_dword dd 0 126 | 127 | ; ------------------------------------------------------------------ 128 | ; os_math_root -- Approximates the EBXth root of EAX. 129 | ; IN: EAX = input, EBX = root 130 | ; OUT: EAX(EDX = 0) = result; EAX to EDX = range 131 | 132 | os_math_root: 133 | pushad 134 | mov ecx, eax ; Prepare the data 135 | mov esi, 2 136 | 137 | .root_loop: 138 | mov eax, esi 139 | call os_math_power 140 | 141 | cmp eax, ecx 142 | je .root_exact 143 | jg .root_range 144 | 145 | inc esi 146 | jmp .root_loop 147 | 148 | .root_exact: 149 | mov [cs:.tmp_dword], esi 150 | popad 151 | mov eax, [cs:.tmp_dword] 152 | xor edx, edx 153 | ret 154 | 155 | .root_range: 156 | mov [cs:.tmp_dword], esi 157 | popad 158 | mov edx, [cs:.tmp_dword] 159 | mov eax, edx 160 | dec eax 161 | ret 162 | 163 | .tmp_dword dd 0 164 | 165 | ; ================================================================== 166 | -------------------------------------------------------------------------------- /kernel/features/ports.asm: -------------------------------------------------------------------------------- 1 | ; ================================================================== 2 | ; MichalOS Port I/O functions 3 | ; ================================================================== 4 | 5 | ; ------------------------------------------------------------------ 6 | ; os_serial_port_enable -- Set up the serial port for transmitting data 7 | ; IN: AX = 0 for normal mode (9600 baud), or 1 for slow mode (1200 baud) 8 | ; OUT: None, registers preserved 9 | 10 | os_serial_port_enable: 11 | pusha 12 | 13 | ; TODO: Access raw ports! 14 | 15 | clr dx ; Configure serial port 1 16 | cmp ax, 1 17 | je .slow_mode 18 | 19 | mov ax, 11100011b ; 9600 baud, no parity, 8 data bits, 1 stop bit 20 | jmp .finish 21 | 22 | .slow_mode: 23 | mov ax, 10000011b ; 1200 baud, no parity, 8 data bits, 1 stop bit 24 | 25 | .finish: 26 | int 14h 27 | 28 | popa 29 | ret 30 | 31 | 32 | ; ------------------------------------------------------------------ 33 | ; os_send_via_serial -- Send a byte via the serial port 34 | ; IN: AL = byte to send via serial 35 | ; OUT: AH = Bit 7 clear on success 36 | 37 | os_send_via_serial: 38 | pusha 39 | 40 | ; TODO: Access raw ports! 41 | 42 | mov ah, 01h 43 | clr dx ; COM1 44 | 45 | int 14h 46 | 47 | mov [cs:.tmp], ah 48 | 49 | popa 50 | 51 | mov ah, [cs:.tmp] 52 | 53 | ret 54 | 55 | .tmp db 0 56 | 57 | 58 | ; ------------------------------------------------------------------ 59 | ; os_get_via_serial -- Get a byte from the serial port 60 | ; IN: None 61 | ; OUT: AL = byte that was received, AH = Bit 7 clear on success 62 | 63 | os_get_via_serial: 64 | pusha 65 | 66 | ; TODO: Access raw ports! 67 | 68 | mov ah, 02h 69 | clr dx ; COM1 70 | 71 | int 14h 72 | 73 | mov [cs:.tmp], ax 74 | 75 | popa 76 | 77 | mov ax, [cs:.tmp] 78 | 79 | ret 80 | 81 | 82 | .tmp dw 0 83 | 84 | ; ================================================================== 85 | -------------------------------------------------------------------------------- /kernel/features/zx7.asm: -------------------------------------------------------------------------------- 1 | ; ================================================================== 2 | ; MichalOS ZX7 decompression routine 3 | ; ================================================================== 4 | 5 | ; Decompresses Einar Saukas' ZX7 compressed stream data in 16-bit real mode. 6 | ; ZX7 format and original Z80 decompressor by Einar Saukas. 7 | ; Original Z80 to 8086 conversion, and size-optimized version, by Peter Ferrie. 8 | ; Speed-optimized code by Peter Ferrie and Jim Leonard. 9 | ; 20160308 10 | ; 11 | ; The source for the conversion was the original "default" Z80 decompression 12 | ; code provided by Einar. Further size optimization and unrolling were 13 | ; independently performed specifically for the 8086. 14 | ; Source is formatted for Borland Turbo Assembler IDEAL mode and NEAR calls, 15 | ; however it should be very easy to port to other assemblers if necessary. 16 | 17 | ; ------------------------------------------------------------------ 18 | ; os_decompress_zx7 -- Decompresses ZX7-packed data. 19 | ; IN: DS:SI = source, ES:DI = destination 20 | ; OUT: None, registers preserved 21 | 22 | os_decompress_zx7: 23 | pusha 24 | call int_decompress_zx7 25 | popa 26 | ret 27 | 28 | ; ================================================================== 29 | 30 | ; ------------------------------------------------------------------ 31 | ; int_decompress_zx7 -- Decompresses ZX7-packed data. 32 | ; IN: DS:SI = source, ES:DI = destination 33 | ; OUT: None, destroys every imaginable register under the sun 34 | 35 | int_decompress_zx7: 36 | mov al, 80h 37 | xor cx, cx 38 | mov bp, .next_bit 39 | 40 | .copy_byte_loop: 41 | movsb ; copy literal byte 42 | 43 | .main_loop: 44 | call bp 45 | jnc .copy_byte_loop ; next bit indicates either 46 | ; literal or sequence 47 | 48 | ; determine number of bits used for length (Elias gamma coding) 49 | 50 | xor bx, bx 51 | 52 | .len_size_loop: 53 | inc bx 54 | call bp 55 | jnc .len_size_loop 56 | db 80h ; mask call 57 | 58 | ; determine length 59 | 60 | .len_value_loop: 61 | call bp 62 | 63 | .len_value_skip: 64 | adc cx, cx 65 | jb .next_bit_ret ; check end marker 66 | dec bx 67 | jnz .len_value_loop 68 | inc cx ; adjust length 69 | 70 | ; determine offset 71 | 72 | mov bl, [si] ; load offset flag (1 bit) + 73 | ; offset value (7 bits) 74 | inc si 75 | stc 76 | adc bl, bl 77 | jnc .offset_end ; if offset flag is set, load 78 | ; 4 extra bits 79 | mov bh, 10h ; bit marker to load 4 bits 80 | .rld_next_bit: 81 | call bp 82 | adc bh, bh ; insert next bit into D 83 | jnc .rld_next_bit ; repeat 4 times, until bit 84 | ; marker is out 85 | inc bh ; add 128 to DE 86 | 87 | .offset_end: 88 | shr bx, 1 ; insert fourth bit into E 89 | 90 | ; copy previous sequence 91 | 92 | push si 93 | mov si, di 94 | sbb si, bx ; destination = destination - offset - 1 95 | 96 | es rep movsb 97 | 98 | pop si ; restore source address 99 | ; (compressed data) 100 | jmp .main_loop 101 | 102 | .next_bit: 103 | add al, al ; check next bit 104 | jnz .next_bit_ret ; no more bits left? 105 | lodsb ; load another group of 8 bits 106 | adc al, al 107 | 108 | .next_bit_ret: 109 | ret 110 | 111 | ; ================================================================== 112 | -------------------------------------------------------------------------------- /misc/LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2017-2021, Michal Prochazka 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /misc/MikeOS LICENSE: -------------------------------------------------------------------------------- 1 | ================================================================== 2 | MikeOS -- License 3 | ================================================================== 4 | 5 | 6 | Copyright (C) 2006 - 2014 MikeOS Developers -- http://mikeos.sourceforge.net 7 | 8 | All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without 11 | modification, are permitted provided that the following conditions are met: 12 | 13 | * Redistributions of source code must retain the above copyright 14 | notice, this list of conditions and the following disclaimer. 15 | 16 | * Redistributions in binary form must reproduce the above copyright 17 | notice, this list of conditions and the following disclaimer in the 18 | documentation and/or other materials provided with the distribution. 19 | 20 | * Neither the name MikeOS nor the names of any MikeOS contributors 21 | may be used to endorse or promote products derived from this software 22 | without specific prior written permission. 23 | 24 | THIS SOFTWARE IS PROVIDED BY MIKEOS DEVELOPERS AND CONTRIBUTORS "AS IS" 25 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 | ARE DISCLAIMED. IN NO EVENT SHALL MIKEOS DEVELOPERS BE LIABLE FOR ANY 28 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 29 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 30 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 31 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 32 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 33 | USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | 35 | 36 | ================================================================== 37 | 38 | -------------------------------------------------------------------------------- /misc/VirtualBox.md: -------------------------------------------------------------------------------- 1 | # Running MichalOS in VirtualBox 2 | 3 | If you aren't familiar with DOSBox (or don't have a Linux system available to build the project), this is your next best option. 4 | However, there is one big issue with using MichalOS on VirtualBox: 5 | 6 | **Sound doesn't work at all.** 7 | 8 | MichalOS uses old primitive PC sound technologies (PC speaker, AdLib FM Synthesizer), which aren't supported under VirtualBox. 9 | 10 | Anyhow, here's the guide: 11 | 12 | ## Step 1: Get VirtualBox 13 | 14 | [Here](https://www.virtualbox.org/wiki/Downloads)'s the link to the VirtualBox's Downloads page. 15 | 16 | ## Step 2: Create a new virtual machine 17 | 18 | Open VirtualBox, and you should be greeted by this window: 19 | 20 | ![fresh_vbox](https://user-images.githubusercontent.com/41787099/126858589-9d62b502-e966-4644-8f6c-ada33a4305d8.png) 21 | 22 | Click on the blue "New" button. This should pop up: 23 | 24 | ![name](https://user-images.githubusercontent.com/41787099/126858600-7c11c63e-3a38-4610-ae6e-d49a82a728a4.png) 25 | 26 | Fill it in so that your settings match the ones on the picture (except the "Machine folder"), so: 27 | 28 | - Name: "MichalOS" 29 | - Type: "Other" 30 | - Version: "Other/Unknown" 31 | 32 | Next it will ask you how much RAM you want. Keep in mind that MichalOS can only use 640 kB of RAM, so just set it to the minimum: 33 | 34 | ![memory](https://user-images.githubusercontent.com/41787099/126858650-fe752fec-448d-4c46-ac7a-9bf6f9311da4.png) 35 | 36 | Finally, it will ask you whether you want a hard disk. We don't, MichalOS doesn't support it, so select the "Do not add a virtual hard disk" option: 37 | 38 | ![hdd](https://user-images.githubusercontent.com/41787099/126858656-88df62f9-723a-4816-bf94-21297bf02581.png) 39 | 40 | It will nag you for not adding a hard disk, however, we know what we're doing, so just click "Continue": 41 | 42 | ![nag](https://user-images.githubusercontent.com/41787099/126858688-e09bc725-ebc9-442f-9673-cf62daee9eaa.png) 43 | 44 | ## Step 3: Attach a floppy disk image to the virtual machine 45 | 46 | After you've created your new virtual machine, highlight it and click on the orange "Settings" button: 47 | 48 | ![vm_created](https://user-images.githubusercontent.com/41787099/126858793-6760335a-6cec-46f1-8bef-c29becdda64a.png) 49 | 50 | A new window will pop up. From the panel on the left, select "Storage". Your window will now look like this: 51 | 52 | ![settings](https://user-images.githubusercontent.com/41787099/126858818-23d2de66-01f9-44be-81c9-b0ac17392b85.png) 53 | 54 | On the bottom, there is a little button with an icon of a weird tilted green square and a plus icon (it's the one on the left). Click on it and select "I82078 (Floppy)": 55 | 56 | ![floppy](https://user-images.githubusercontent.com/41787099/126858851-5ca2fdfd-d3ff-4085-bee4-8b4b2e5635d5.png) 57 | 58 | This will create a new floppy controller. 59 | 60 | ![floppycontroller](https://user-images.githubusercontent.com/41787099/126858889-0cd59498-6ef0-41ad-88b4-431a524f2c0b.png) 61 | 62 | Highlight it, and next to it will appear a little "floppy add" icon. Click on it, and it will take you to the Floppy Disk Selector: 63 | 64 | ![floppyadddialog](https://user-images.githubusercontent.com/41787099/126858917-7052d622-c74b-4d24-9960-fa8c1639e95c.png) 65 | 66 | Click on the "Add" button. From there, navigate to the directory where you have extracted MichalOS and find "michalos.flp" (it will be either in the "build" or "build/images" directory): 67 | 68 | ![michalosflp](https://user-images.githubusercontent.com/41787099/126858963-1241cee7-576f-464f-b462-edf260a1bc05.png) 69 | 70 | Click on "Open". That will take you back to the Floppy Disk Selector. 71 | 72 | ![yesiwantthatfloppy](https://user-images.githubusercontent.com/41787099/126859008-413c16fb-720a-400d-884c-02db57a7a20d.png) 73 | 74 | Select "michalos.flp" in the list and click "Choose". That will take you back to the settings dialog. Press "OK". 75 | 76 | ## Step 4: Run! 77 | 78 | Select "MichalOS" from the virtual machine list and press Start. 79 | -------------------------------------------------------------------------------- /misc/gallery.md: -------------------------------------------------------------------------------- 1 | # MichalOS Gallery 2 | 3 | Here are some screenshots, which may give you an idea of the feel of MichalOS. 4 | 5 | ## Demo tour 6 | 7 | ![2022-10-29-214207_640x400_scrot](https://user-images.githubusercontent.com/41787099/198850156-62d37bdf-c176-4711-b91f-32ca9784a1f0.png) 8 | 9 | ## Login screen 10 | 11 | ![2022-10-29-214214_640x400_scrot](https://user-images.githubusercontent.com/41787099/198850154-60ebd462-5e5b-475b-a6b8-3f24b7a35396.png) 12 | 13 | ## Desktop 14 | 15 | ![2022-10-29-214226_640x400_scrot](https://user-images.githubusercontent.com/41787099/198850152-d33458ef-353c-4d27-a5a1-cbebf38bed04.png) 16 | 17 | ## Main menu 18 | 19 | ![2022-10-29-214231_640x400_scrot](https://user-images.githubusercontent.com/41787099/198850151-5c12cce2-9120-4a4d-8c09-82d4a5b16a2e.png) 20 | 21 | ## File manager 22 | 23 | ![2022-10-29-214256_640x400_scrot](https://user-images.githubusercontent.com/41787099/198850150-ae437eb0-0b9b-4a70-b1a7-86132b19de0d.png) 24 | 25 | ## Clock 26 | 27 | ![2022-10-29-214305_640x400_scrot](https://user-images.githubusercontent.com/41787099/198850149-aa9348b4-137b-415f-8d39-7b9cda3cb07b.png) 28 | 29 | ## Music player - playing back a file 30 | 31 | ![2022-10-29-214322_640x400_scrot](https://user-images.githubusercontent.com/41787099/198850146-4d4fb643-5d20-44f0-93ee-bd38b92b0844.png) 32 | 33 | ## Pixel art editor 34 | 35 | ![2022-10-29-214504_640x400_scrot](https://user-images.githubusercontent.com/41787099/198850145-28f7cafc-a7d3-4b40-ae85-c69ad9af174e.png) 36 | 37 | ## Memory editor 38 | 39 | ![2022-10-29-214740_640x400_scrot](https://user-images.githubusercontent.com/41787099/198850144-53e860db-9e84-4e6d-9a3e-aac99b75fd06.png) 40 | 41 | ## Music player - keyboard piano 42 | 43 | ![2022-10-29-214751_640x400_scrot](https://user-images.githubusercontent.com/41787099/198850143-5685d196-633c-4a21-b94c-3f91780becc4.png) 44 | 45 | ## Image viewer 46 | 47 | ![2022-10-29-214805_640x400_scrot](https://user-images.githubusercontent.com/41787099/198850141-d5501ae6-a015-4f24-94b0-3a59c8e9e204.png) 48 | 49 | ## Settings 50 | 51 | ![2022-10-29-214823_640x400_scrot](https://user-images.githubusercontent.com/41787099/198850139-c113e24e-0407-4476-85d5-e597c5ba3b1c.png) 52 | 53 | ## About MichalOS 54 | 55 | ![2022-10-29-214832_640x400_scrot](https://user-images.githubusercontent.com/41787099/198850137-33f25533-0430-45cc-b9cf-df9c1664afb6.png) 56 | 57 | ## When things don't go particularly well... 58 | 59 | ![2022-10-29-220305_640x400_scrot](https://user-images.githubusercontent.com/41787099/198850727-12de36bf-e038-4d16-8f94-9793906329fd.png) 60 | -------------------------------------------------------------------------------- /misc/geninclude.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import fnmatch 4 | import os 5 | 6 | main = open("kernel/main.asm") 7 | rows = main.read().replace("\t", " ").splitlines() 8 | 9 | # Search os_call_vectors 10 | 11 | searching_vectors = False 12 | org = None 13 | found_calls = [] 14 | 15 | for row in rows: 16 | el = list(filter(None, row.split(' '))) 17 | 18 | if len(el) > 0 and el[0].upper() == "ORG": 19 | org = int(el[1]) 20 | 21 | if searching_vectors: 22 | if org == None: 23 | print("ORG not found!") 24 | searching_vectors = False 25 | break 26 | 27 | if row.startswith(" jmp "): 28 | found_calls.append([el[1], org]) 29 | org += 3 30 | 31 | else: 32 | break 33 | 34 | if row == "os_call_vectors:": 35 | searching_vectors = True 36 | 37 | if not searching_vectors: 38 | print("Error, cannot find call vectors!") 39 | exit(1) 40 | 41 | print("Discovered " + str(len(found_calls)) + " function calls.") 42 | 43 | # Go through each file in kernel/features, generate output 44 | 45 | output = open("include/syscalls.asm", "w") 46 | 47 | output.write("; ------------------------------------------------------------------\n") 48 | output.write("; Include file for MichalOS program development - syscalls\n") 49 | output.write("; ------------------------------------------------------------------\n\n") 50 | 51 | for root, dirnames, filenames in os.walk('kernel/features'): 52 | for filename in fnmatch.filter(filenames, '*.asm'): 53 | asm = open(os.path.join(root, filename)) 54 | rows = asm.read().splitlines() 55 | 56 | header_printed = False 57 | 58 | for i in range(len(rows)): 59 | row = rows[i] 60 | 61 | if rows[i].startswith("os_") and rows[i].endswith(":"): 62 | # Found a function definition, find the match 63 | 64 | fncall = rows[i][:-1] 65 | matchcall = None 66 | 67 | for call in found_calls: 68 | if call[0] == fncall: 69 | matchcall = call 70 | break 71 | 72 | if matchcall != None: 73 | # Match found, search the comments above the function call 74 | 75 | doc = [] 76 | 77 | for j in range(i - 1, -1, -1): 78 | if rows[j].startswith(";"): 79 | doc.append(rows[j]) 80 | elif len(doc) > 0: 81 | break 82 | 83 | doc.reverse() 84 | 85 | # If the file's header has not been written yet, write it 86 | 87 | if not header_printed: 88 | header_printed = True 89 | 90 | for row in rows: 91 | if row.startswith(";"): 92 | output.write(row + "\n") 93 | else: 94 | output.write("\n") 95 | break 96 | 97 | # Output the function call 98 | 99 | for docline in doc: 100 | output.write(docline + "\n") 101 | 102 | output.write("\n" + matchcall[0] + " equ " + str(matchcall[1]) + "\n\n") -------------------------------------------------------------------------------- /misc/kerneltree.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import re 4 | 5 | table = open("build/kernel.lst") 6 | rows = table.read().replace("\t", " ").splitlines() 7 | 8 | oldname = "" 9 | newname = "" 10 | oldinclude = "" 11 | newinclude = "" 12 | oldstartaddr = 0 13 | includefound = False 14 | firstaddrfound = False 15 | 16 | for row in rows: 17 | el = list(filter(None, row.split(' '))) 18 | 19 | includefound = False 20 | 21 | for e in el: 22 | if ";" in e: 23 | break 24 | 25 | match = re.findall("^[0-9a-z_]*:", e) 26 | 27 | if len(match) == 1 and (match[0].startswith("os_") or match[0].startswith("int_")): 28 | oldname = newname 29 | newname = match[0] 30 | firstaddrfound = False 31 | 32 | if "%INCLUDE" in e: 33 | includefound = True 34 | 35 | if includefound: 36 | newinclude = e 37 | 38 | try: 39 | addr = int(el[1], base=16) 40 | 41 | if not firstaddrfound: 42 | if oldname != "": 43 | print("%d %s %s" % (addr - oldstartaddr, oldname, oldinclude)) 44 | 45 | oldinclude = newinclude 46 | oldstartaddr = addr 47 | firstaddrfound = True 48 | 49 | except: 50 | pass 51 | 52 | print("%d total" % oldstartaddr) 53 | -------------------------------------------------------------------------------- /misc/mapper.map: -------------------------------------------------------------------------------- 1 | hand_shutdown "key 290 mod1" 2 | hand_capmouse "key 291 mod1" 3 | hand_fullscr "key 13 mod2" 4 | hand_mapper "key 282 mod1" 5 | hand_speedlock "key 293 mod2" 6 | hand_recwave "key 287 mod1" 7 | hand_caprawmidi "key 289 mod1 mod2" 8 | hand_scrshot "key 286 mod1" 9 | hand_video "key 286 mod1 mod2" 10 | hand_decfskip "key 288 mod1" 11 | hand_incfskip "key 289 mod1" 12 | hand_cycledown "key 292 mod1" 13 | hand_cycleup "key 293 mod1" 14 | hand_debugger "key 127 mod1" "key 282 mod1" "key 306 mod1" "key 282 mod1" "key 283" 15 | hand_caprawopl "key 288 mod1" 16 | hand_swapimg "key 285 mod1" 17 | key_esc "key 27" 18 | key_f1 "key 282" 19 | key_f2 "key 283" 20 | key_f3 "key 284" 21 | key_f4 "key 285" 22 | key_f5 "key 286" 23 | key_f6 "key 287" 24 | key_f7 "key 288" 25 | key_f8 "key 289" 26 | key_f9 "key 290" 27 | key_f10 "key 291" 28 | key_f11 "key 292" 29 | key_f12 "key 293" 30 | key_grave "key 96" 31 | key_1 "key 49" 32 | key_2 "key 50" 33 | key_3 "key 51" 34 | key_4 "key 52" 35 | key_5 "key 53" 36 | key_6 "key 54" 37 | key_7 "key 55" 38 | key_8 "key 56" 39 | key_9 "key 57" 40 | key_0 "key 48" 41 | key_minus "key 45" 42 | key_equals "key 61" 43 | key_bspace "key 8" 44 | key_tab "key 9" 45 | key_q "key 113" 46 | key_w "key 119" 47 | key_e "key 101" 48 | key_r "key 114" 49 | key_t "key 116" 50 | key_y "key 121" 51 | key_u "key 117" 52 | key_i "key 105" 53 | key_o "key 111" 54 | key_p "key 112" 55 | key_lbracket "key 91" 56 | key_rbracket "key 93" 57 | key_enter "key 13" 58 | key_capslock "key 301" 59 | key_a "key 97" 60 | key_s "key 115" 61 | key_d "key 100" 62 | key_f "key 102" 63 | key_g "key 103" 64 | key_h "key 104" 65 | key_j "key 106" 66 | key_k "key 107" 67 | key_l "key 108" 68 | key_semicolon "key 59" 69 | key_quote "key 39" 70 | key_backslash "key 92" 71 | key_lshift "key 304" 72 | key_lessthan "key 60" 73 | key_z "key 122" 74 | key_x "key 120" 75 | key_c "key 99" 76 | key_v "key 118" 77 | key_b "key 98" 78 | key_n "key 110" 79 | key_m "key 109" 80 | key_comma "key 44" 81 | key_period "key 46" 82 | key_slash "key 47" 83 | key_rshift "key 303" 84 | key_lctrl "key 306" 85 | key_lalt "key 308" 86 | key_space "key 32" 87 | key_ralt "key 307" 88 | key_rctrl "key 305" 89 | key_printscreen "key 316" 90 | key_scrolllock "key 302" 91 | key_pause "key 19" 92 | key_insert "key 277" 93 | key_home "key 278" 94 | key_pageup "key 280" 95 | key_delete "key 127" 96 | key_end "key 279" 97 | key_pagedown "key 281" 98 | key_up "key 273" 99 | key_left "key 276" 100 | key_down "key 274" 101 | key_right "key 275" 102 | key_numlock "key 300" 103 | key_kp_divide "key 267" 104 | key_kp_multiply "key 268" 105 | key_kp_minus "key 269" 106 | key_kp_7 "key 263" 107 | key_kp_8 "key 264" 108 | key_kp_9 "key 265" 109 | key_kp_plus "key 270" 110 | key_kp_4 "key 260" 111 | key_kp_5 "key 261" 112 | key_kp_6 "key 262" 113 | key_kp_1 "key 257" 114 | key_kp_2 "key 258" 115 | key_kp_3 "key 259" 116 | key_kp_enter "key 271" 117 | key_kp_0 "key 256" 118 | key_kp_period "key 266" 119 | jbutton_0_0 120 | jbutton_0_1 121 | jaxis_0_1- 122 | jaxis_0_1+ 123 | jaxis_0_0- 124 | jaxis_0_0+ 125 | jbutton_0_2 126 | jbutton_0_3 127 | jbutton_1_0 128 | jbutton_1_1 129 | jaxis_0_2- 130 | jaxis_0_2+ 131 | jaxis_0_3- 132 | jaxis_0_3+ 133 | jaxis_1_0- 134 | jaxis_1_0+ 135 | jaxis_1_1- 136 | jaxis_1_1+ 137 | jbutton_0_4 138 | jbutton_0_5 139 | jhat_0_0_0 140 | jhat_0_0_3 141 | jhat_0_0_2 142 | jhat_0_0_1 143 | mod_1 "key 305" "key 306" 144 | mod_2 "key 307" "key 308" 145 | mod_3 146 | -------------------------------------------------------------------------------- /misc/zx7/appzx7.c: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) Copyright 2012-2016 by Einar Saukas. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * * Redistributions of source code must retain the above copyright 7 | * notice, this list of conditions and the following disclaimer. 8 | * * Redistributions in binary form must reproduce the above copyright 9 | * notice, this list of conditions and the following disclaimer in the 10 | * documentation and/or other materials provided with the distribution. 11 | * * The name of its author may not be used to endorse or promote products 12 | * derived from this software without specific prior written permission. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 18 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | */ 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #include "zx7.h" 34 | 35 | int main(int argc, char *argv[]) { 36 | unsigned char *input_data; 37 | unsigned char *output_data; 38 | FILE *ifp; 39 | FILE *ofp; 40 | size_t size; 41 | size_t input_size; 42 | size_t output_size; 43 | size_t partial_counter; 44 | size_t total_counter; 45 | long delta; 46 | int i, segments, ptr; 47 | 48 | if(argc != 3) { 49 | fprintf(stderr, "Usage: %s input output\n", argv[0]); 50 | 51 | exit(1); 52 | } 53 | 54 | /* open input file */ 55 | ifp = fopen(argv[1], "rb"); 56 | if (!ifp) { 57 | fprintf(stderr, "Error: Cannot access input file %s\n", argv[1]); 58 | exit(1); 59 | } 60 | 61 | /* determine input size */ 62 | fseek(ifp, 0L, SEEK_END); 63 | input_size = ftell(ifp); 64 | fseek(ifp, 0L, SEEK_SET); 65 | if (!input_size) { 66 | fprintf(stderr, "Error: Empty input file %s\n", argv[1]); 67 | exit(1); 68 | } 69 | 70 | /* allocate input buffer */ 71 | input_data = (unsigned char *)malloc(input_size); 72 | if (!input_data) { 73 | fprintf(stderr, "Error: Insufficient memory\n"); 74 | exit(1); 75 | } 76 | 77 | /* read input file */ 78 | total_counter = 0; 79 | do { 80 | partial_counter = fread(input_data+total_counter, sizeof(char), input_size-total_counter, ifp); 81 | total_counter += partial_counter; 82 | } while (partial_counter > 0); 83 | 84 | if (total_counter != input_size) { 85 | fprintf(stderr, "Error: Cannot read input file %s\n", argv[1]); 86 | exit(1); 87 | } 88 | 89 | /* close input file */ 90 | fclose(ifp); 91 | 92 | /* create output file */ 93 | ofp = fopen(argv[2], "wb"); 94 | if (!ofp) { 95 | fprintf(stderr, "Error: Cannot create output file %s\n", argv[2]); 96 | exit(1); 97 | } 98 | 99 | /* generate output file */ 100 | output_data = compress(optimize(input_data, input_size), input_data, input_size, &output_size, &delta); 101 | 102 | fputc(0xC3, ofp); 103 | fwrite("MiOS", sizeof(char), 4, ofp); // Signature 104 | if(input_size <= output_size || (8 + 0x100 + input_size + output_size) >= 0x8000) { 105 | // Compressed output is larger or it doesn't fit in the memory space for decompression 106 | 107 | fputc(0, ofp); // Flags - not compressed 108 | fputc(input_size & 0xFF, ofp); // Uncompressed file data 109 | fputc(input_size >> 8, ofp); 110 | fwrite(input_data, sizeof(char), input_size, ofp); // Data 111 | } else { 112 | // Compressed output is better 113 | 114 | fputc(1, ofp); // Flags - compressed 115 | fputc(output_size & 0xFF, ofp); // Compressed file data 116 | fputc(output_size >> 8, ofp); 117 | fwrite(output_data, sizeof(char), output_size, ofp); // Data 118 | } 119 | 120 | /* close output file */ 121 | fclose(ofp); 122 | } 123 | -------------------------------------------------------------------------------- /misc/zx7/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cc zx7.c optimize.c compress.c -o segmented_zx7 4 | cc appzx7.c optimize.c compress.c -o app_zx7 5 | cc rawzx7.c optimize.c compress.c -o raw_zx7 6 | -------------------------------------------------------------------------------- /misc/zx7/compress.c: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) Copyright 2012-2016 by Einar Saukas. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * * Redistributions of source code must retain the above copyright 7 | * notice, this list of conditions and the following disclaimer. 8 | * * Redistributions in binary form must reproduce the above copyright 9 | * notice, this list of conditions and the following disclaimer in the 10 | * documentation and/or other materials provided with the distribution. 11 | * * The name of its author may not be used to endorse or promote products 12 | * derived from this software without specific prior written permission. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 18 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | */ 25 | 26 | #include 27 | #include 28 | 29 | #include "zx7.h" 30 | 31 | unsigned char* output_data; 32 | size_t output_index; 33 | size_t bit_index; 34 | int bit_mask; 35 | long diff; 36 | 37 | void read_bytes(int n, long *delta) { 38 | diff += n; 39 | if (diff > *delta) 40 | *delta = diff; 41 | } 42 | 43 | void write_byte(int value) { 44 | output_data[output_index++] = value; 45 | diff--; 46 | } 47 | 48 | void write_bit(int value) { 49 | if (bit_mask == 0) { 50 | bit_mask = 128; 51 | bit_index = output_index; 52 | write_byte(0); 53 | } 54 | if (value > 0) { 55 | output_data[bit_index] |= bit_mask; 56 | } 57 | bit_mask >>= 1; 58 | } 59 | 60 | void write_elias_gamma(int value) { 61 | int i; 62 | 63 | for (i = 2; i <= value; i <<= 1) { 64 | write_bit(0); 65 | } 66 | while ((i >>= 1) > 0) { 67 | write_bit(value & i); 68 | } 69 | } 70 | 71 | unsigned char *compress(Optimal *optimal, unsigned char *input_data, size_t input_size, size_t *output_size, long *delta) { 72 | size_t input_index; 73 | size_t input_prev; 74 | int offset1; 75 | int mask; 76 | int i; 77 | 78 | /* calculate and allocate output buffer */ 79 | input_index = input_size-1; 80 | *output_size = (optimal[input_index].bits+18+7)/8; 81 | output_data = (unsigned char *)malloc(*output_size); 82 | if (!output_data) { 83 | fprintf(stderr, "Error: Insufficient memory\n"); 84 | exit(1); 85 | } 86 | 87 | /* initialize delta */ 88 | diff = *output_size - input_size; 89 | *delta = 0; 90 | 91 | /* un-reverse optimal sequence */ 92 | optimal[input_index].bits = 0; 93 | while (input_index) { 94 | input_prev = input_index - (optimal[input_index].len > 0 ? optimal[input_index].len : 1); 95 | optimal[input_prev].bits = input_index; 96 | input_index = input_prev; 97 | } 98 | 99 | output_index = 0; 100 | bit_mask = 0; 101 | 102 | /* first byte is always literal */ 103 | write_byte(input_data[input_index]); 104 | read_bytes(1, delta); 105 | 106 | /* process remaining bytes */ 107 | while ((input_index = optimal[input_index].bits) > 0) { 108 | if (optimal[input_index].len == 0) { 109 | 110 | /* literal indicator */ 111 | write_bit(0); 112 | 113 | /* literal value */ 114 | write_byte(input_data[input_index]); 115 | read_bytes(1, delta); 116 | 117 | } else { 118 | 119 | /* sequence indicator */ 120 | write_bit(1); 121 | 122 | /* sequence length */ 123 | write_elias_gamma(optimal[input_index].len-1); 124 | 125 | /* sequence offset */ 126 | offset1 = optimal[input_index].offset-1; 127 | if (offset1 < 128) { 128 | write_byte(offset1); 129 | } else { 130 | offset1 -= 128; 131 | write_byte((offset1 & 127) | 128); 132 | for (mask = 1024; mask > 127; mask >>= 1) { 133 | write_bit(offset1 & mask); 134 | } 135 | } 136 | read_bytes(optimal[input_index].len, delta); 137 | } 138 | } 139 | 140 | /* sequence indicator */ 141 | write_bit(1); 142 | 143 | /* end marker > MAX_LEN */ 144 | for (i = 0; i < 16; i++) { 145 | write_bit(0); 146 | } 147 | write_bit(1); 148 | 149 | return output_data; 150 | } 151 | -------------------------------------------------------------------------------- /misc/zx7/optimize.c: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) Copyright 2012-2016 by Einar Saukas. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * * Redistributions of source code must retain the above copyright 7 | * notice, this list of conditions and the following disclaimer. 8 | * * Redistributions in binary form must reproduce the above copyright 9 | * notice, this list of conditions and the following disclaimer in the 10 | * documentation and/or other materials provided with the distribution. 11 | * * The name of its author may not be used to endorse or promote products 12 | * derived from this software without specific prior written permission. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 18 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | */ 25 | 26 | #include 27 | #include 28 | 29 | #include "zx7.h" 30 | 31 | int elias_gamma_bits(int value) { 32 | int bits; 33 | 34 | bits = 1; 35 | while (value > 1) { 36 | bits += 2; 37 | value >>= 1; 38 | } 39 | return bits; 40 | } 41 | 42 | int count_bits(int offset, int len) { 43 | return 1 + (offset > 128 ? 12 : 8) + elias_gamma_bits(len-1); 44 | } 45 | 46 | Optimal* optimize(unsigned char *input_data, size_t input_size) { 47 | size_t *min; 48 | size_t *max; 49 | size_t *matches; 50 | size_t *match_slots; 51 | Optimal *optimal; 52 | size_t *match; 53 | int match_index; 54 | int offset; 55 | size_t len; 56 | size_t best_len; 57 | size_t bits; 58 | size_t i; 59 | 60 | /* allocate all data structures at once */ 61 | min = (size_t *)calloc(MAX_OFFSET+1, sizeof(size_t)); 62 | max = (size_t *)calloc(MAX_OFFSET+1, sizeof(size_t)); 63 | matches = (size_t *)calloc(256*256, sizeof(size_t)); 64 | match_slots = (size_t *)calloc(input_size, sizeof(size_t)); 65 | optimal = (Optimal *)calloc(input_size, sizeof(Optimal)); 66 | 67 | if (!min || !max || !matches || !match_slots || !optimal) { 68 | fprintf(stderr, "Error: Insufficient memory\n"); 69 | exit(1); 70 | } 71 | 72 | /* first byte is always literal */ 73 | optimal[0].bits = 8; 74 | 75 | /* process remaining bytes */ 76 | for (i = 1; i < input_size; i++) { 77 | optimal[i].bits = optimal[i-1].bits + 9; 78 | match_index = input_data[i-1] << 8 | input_data[i]; 79 | best_len = 1; 80 | for (match = &matches[match_index]; *match != 0 && best_len < MAX_LEN; match = &match_slots[*match]) { 81 | offset = i - *match; 82 | if (offset > MAX_OFFSET) { 83 | *match = 0; 84 | break; 85 | } 86 | 87 | for (len = 2; len <= MAX_LEN && i >= len; len++) { 88 | if (len > best_len) { 89 | best_len = len; 90 | bits = optimal[i-len].bits + count_bits(offset, len); 91 | if (optimal[i].bits > bits) { 92 | optimal[i].bits = bits; 93 | optimal[i].offset = offset; 94 | optimal[i].len = len; 95 | } 96 | } else if (max[offset] != 0 && i+1 == max[offset]+len) { 97 | len = i-min[offset]; 98 | if (len > best_len) { 99 | len = best_len; 100 | } 101 | } 102 | if (i < offset+len || input_data[i-len] != input_data[i-len-offset]) { 103 | break; 104 | } 105 | } 106 | min[offset] = i+1-len; 107 | max[offset] = i; 108 | } 109 | match_slots[i] = matches[match_index]; 110 | matches[match_index] = i; 111 | } 112 | 113 | /* save time by releasing the largest block only, the O.S. will clean everything else later */ 114 | free(match_slots); 115 | 116 | return optimal; 117 | } 118 | -------------------------------------------------------------------------------- /misc/zx7/rawzx7.c: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) Copyright 2012-2016 by Einar Saukas. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * * Redistributions of source code must retain the above copyright 7 | * notice, this list of conditions and the following disclaimer. 8 | * * Redistributions in binary form must reproduce the above copyright 9 | * notice, this list of conditions and the following disclaimer in the 10 | * documentation and/or other materials provided with the distribution. 11 | * * The name of its author may not be used to endorse or promote products 12 | * derived from this software without specific prior written permission. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 18 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | */ 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #include "zx7.h" 34 | 35 | int main(int argc, char *argv[]) { 36 | unsigned char *input_data; 37 | unsigned char *output_data; 38 | FILE *ifp; 39 | FILE *ofp; 40 | size_t size; 41 | size_t input_size; 42 | size_t output_size; 43 | size_t partial_counter; 44 | size_t total_counter; 45 | long delta; 46 | int i, segments, ptr; 47 | 48 | if(argc != 3) { 49 | fprintf(stderr, "Usage: %s input output\n", argv[0]); 50 | 51 | exit(1); 52 | } 53 | 54 | /* open input file */ 55 | ifp = fopen(argv[1], "rb"); 56 | if (!ifp) { 57 | fprintf(stderr, "Error: Cannot access input file %s\n", argv[1]); 58 | exit(1); 59 | } 60 | 61 | /* determine input size */ 62 | fseek(ifp, 0L, SEEK_END); 63 | input_size = ftell(ifp); 64 | fseek(ifp, 0L, SEEK_SET); 65 | if (!input_size) { 66 | fprintf(stderr, "Error: Empty input file %s\n", argv[1]); 67 | exit(1); 68 | } 69 | 70 | /* allocate input buffer */ 71 | input_data = (unsigned char *)malloc(input_size); 72 | if (!input_data) { 73 | fprintf(stderr, "Error: Insufficient memory\n"); 74 | exit(1); 75 | } 76 | 77 | /* read input file */ 78 | total_counter = 0; 79 | do { 80 | partial_counter = fread(input_data+total_counter, sizeof(char), input_size-total_counter, ifp); 81 | total_counter += partial_counter; 82 | } while (partial_counter > 0); 83 | 84 | if (total_counter != input_size) { 85 | fprintf(stderr, "Error: Cannot read input file %s\n", argv[1]); 86 | exit(1); 87 | } 88 | 89 | /* close input file */ 90 | fclose(ifp); 91 | 92 | /* create output file */ 93 | ofp = fopen(argv[2], "wb"); 94 | if (!ofp) { 95 | fprintf(stderr, "Error: Cannot create output file %s\n", argv[2]); 96 | exit(1); 97 | } 98 | 99 | /* generate output file */ 100 | output_data = compress(optimize(input_data, input_size), input_data, input_size, &output_size, &delta); 101 | 102 | fwrite(output_data, sizeof(char), output_size, ofp); // Data 103 | 104 | /* close output file */ 105 | fclose(ofp); 106 | } 107 | -------------------------------------------------------------------------------- /misc/zx7/zx7.c: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) Copyright 2012-2016 by Einar Saukas. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * * Redistributions of source code must retain the above copyright 7 | * notice, this list of conditions and the following disclaimer. 8 | * * Redistributions in binary form must reproduce the above copyright 9 | * notice, this list of conditions and the following disclaimer in the 10 | * documentation and/or other materials provided with the distribution. 11 | * * The name of its author may not be used to endorse or promote products 12 | * derived from this software without specific prior written permission. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 18 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | */ 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | #include "zx7.h" 33 | 34 | int main(int argc, char *argv[]) { 35 | unsigned char *input_data; 36 | unsigned char *output_data; 37 | FILE *ifp; 38 | FILE *ofp; 39 | size_t size; 40 | size_t input_size; 41 | size_t output_size; 42 | size_t partial_counter; 43 | size_t total_counter; 44 | long delta; 45 | int i, segments, ptr; 46 | 47 | if(argc != 3) { 48 | fprintf(stderr, "Usage: %s input output\n", argv[0]); 49 | 50 | exit(1); 51 | } 52 | 53 | /* open input file */ 54 | ifp = fopen(argv[1], "rb"); 55 | if (!ifp) { 56 | fprintf(stderr, "Error: Cannot access input file %s\n", argv[1]); 57 | exit(1); 58 | } 59 | 60 | /* determine input size */ 61 | fseek(ifp, 0L, SEEK_END); 62 | input_size = ftell(ifp); 63 | fseek(ifp, 0L, SEEK_SET); 64 | if (!input_size) { 65 | fprintf(stderr, "Error: Empty input file %s\n", argv[1]); 66 | exit(1); 67 | } 68 | 69 | /* allocate input buffer */ 70 | input_data = (unsigned char *)malloc(input_size); 71 | if (!input_data) { 72 | fprintf(stderr, "Error: Insufficient memory\n"); 73 | exit(1); 74 | } 75 | 76 | /* read input file */ 77 | total_counter = 0; 78 | do { 79 | partial_counter = fread(input_data+total_counter, sizeof(char), input_size-total_counter, ifp); 80 | total_counter += partial_counter; 81 | } while (partial_counter > 0); 82 | 83 | if (total_counter != input_size) { 84 | fprintf(stderr, "Error: Cannot read input file %s\n", argv[1]); 85 | exit(1); 86 | } 87 | 88 | /* close input file */ 89 | fclose(ifp); 90 | 91 | /* create output file */ 92 | ofp = fopen(argv[2], "wb"); 93 | if (!ofp) { 94 | fprintf(stderr, "Error: Cannot create output file %s\n", argv[2]); 95 | exit(1); 96 | } 97 | 98 | /* generate output file */ 99 | segments = ((input_size - 1) >> 16) + 1; 100 | fputc(segments, ofp); 101 | 102 | ptr = segments * 2 + 1; 103 | 104 | for(i = 0; i < segments; i++) { 105 | size = (input_size > 0x10000) ? 0x10000 : input_size; 106 | 107 | output_data = compress(optimize(input_data + (i << 16), size), input_data + (i << 16), size, &output_size, &delta); 108 | input_size -= 0x10000; 109 | 110 | fseek(ofp, ptr, SEEK_SET); 111 | 112 | /* write output file */ 113 | if (fwrite(output_data, sizeof(char), output_size, ofp) != output_size) { 114 | fprintf(stderr, "Error: Cannot write output file %s\n", argv[2]); 115 | exit(1); 116 | } 117 | 118 | fseek(ofp, i * 2 + 1, SEEK_SET); 119 | fputc(ptr & 0xFF, ofp); 120 | fputc(ptr >> 8, ofp); 121 | 122 | ptr += output_size; 123 | } 124 | 125 | /* close output file */ 126 | fclose(ofp); 127 | } 128 | -------------------------------------------------------------------------------- /misc/zx7/zx7.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) Copyright 2012-2016 by Einar Saukas. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * * Redistributions of source code must retain the above copyright 7 | * notice, this list of conditions and the following disclaimer. 8 | * * Redistributions in binary form must reproduce the above copyright 9 | * notice, this list of conditions and the following disclaimer in the 10 | * documentation and/or other materials provided with the distribution. 11 | * * The name of its author may not be used to endorse or promote products 12 | * derived from this software without specific prior written permission. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 18 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | */ 25 | 26 | #define MAX_OFFSET 2176 /* range 1..2176 */ 27 | #define MAX_LEN 65536 /* range 2..65536 */ 28 | 29 | typedef struct optimal_t { 30 | size_t bits; 31 | int offset; 32 | int len; 33 | } Optimal; 34 | 35 | Optimal *optimize(unsigned char *input_data, size_t input_size); 36 | 37 | unsigned char *compress(Optimal *optimal, unsigned char *input_data, size_t input_size, size_t *output_size, long *delta); 38 | -------------------------------------------------------------------------------- /programs/about.asm: -------------------------------------------------------------------------------- 1 | ; ------------------------------------------------------------------ 2 | ; About MichalOS 3 | ; ------------------------------------------------------------------ 4 | 5 | %INCLUDE "include/program.inc" 6 | 7 | start: 8 | mov bx, .footer_msg 9 | call draw_background 10 | 11 | mov16 dx, 0, 2 12 | call os_move_cursor 13 | 14 | call os_draw_logo 15 | 16 | mov16 dx, 2, 10 17 | call os_move_cursor 18 | call os_get_os_name 19 | call os_print_string 20 | mov si, .commitver 21 | call os_print_string 22 | 23 | mov16 dx, 0, 12 24 | call os_move_cursor 25 | mov si, .introtext 26 | call os_print_string 27 | 28 | call os_hide_cursor 29 | 30 | call os_wait_for_key 31 | cmp al, ' ' 32 | je .hall_of_fame 33 | cmp al, 'l' 34 | je .license 35 | 36 | ret 37 | 38 | .hall_of_fame: 39 | mov bx, .footer_msg_hall 40 | call draw_background 41 | 42 | mov16 dx, 0, 2 43 | call os_move_cursor 44 | 45 | call os_draw_logo 46 | 47 | mov16 dx, 0, 10 48 | call os_move_cursor 49 | mov si, .hoftext 50 | call os_print_string 51 | 52 | call os_hide_cursor 53 | 54 | call os_wait_for_key 55 | cmp al, ' ' 56 | je start 57 | cmp al, 'l' 58 | je .license 59 | 60 | ret 61 | 62 | .license: 63 | clr cl 64 | 65 | call .draw_license 66 | 67 | .licenseloop: 68 | call os_wait_for_key 69 | 70 | cmp al, ' ' 71 | je .hall_of_fame 72 | cmp al, 'l' 73 | je start 74 | cmp ah, KEY_UP 75 | je .license_cur_up 76 | cmp ah, KEY_DOWN 77 | je .license_cur_down 78 | 79 | ret 80 | 81 | .license_cur_down: 82 | cmp cl, 6 83 | je .licenseloop 84 | 85 | inc cl 86 | call .draw_license 87 | jmp .licenseloop 88 | 89 | .license_cur_up: 90 | test cl, cl 91 | jz .licenseloop 92 | 93 | dec cl 94 | call .draw_license 95 | jmp .licenseloop 96 | 97 | .draw_license: 98 | mov bx, .footer_msg_lic 99 | push cx 100 | call draw_background 101 | pop cx 102 | 103 | mov si, .licensetext 104 | call print_text_wall 105 | ret 106 | 107 | .introtext db ' MichalOS: Copyright (C) Michal Prochazka, 2017-2022', 13, 10 108 | db ' MichalOS Font & logo: Copyright (C) Krystof Kubin, 2017-2022', 13, 10, 10 109 | db ' If you find a bug, or you just have a feature request, please leave a ticket', 13, 10 110 | db ' in the Issues section on GitHub. I welcome all kinds of feedback.', 13, 10, 10, 111 | db ' https://github.com/prochazkaml/MichalOS', 13, 10, 10 112 | db ' https://www.prochazkaml.eu/', 0 113 | 114 | .hoftext db ' Special thanks to: (in alphabetical order)', 13, 10 115 | db ' Einar Saukas for the ZX7 compression method & decompression routine', 13, 10 116 | db ' fanzyflani for porting the Reality AdLib Tracker to NASM', 13, 10 117 | db ' Ivan Ivanov for discovering and helping with fixing bugs', 13, 10 118 | db ' Jasper Ziller for making the Fisher game', 13, 10 119 | db ' Leonardo Ono for making the Snake game', 13, 10 120 | db ' MikeOS developers for making the base OS - MikeOS :)', 13, 10 121 | db ' My wonderful classmates for providing feedback (and doing bug-hunting)', 13, 10 122 | db ' REALITY for releasing the Reality AdLib Tracker source code back in 1995', 13, 10 123 | db ' Sebastian Mihai for creating & releasing the source code of aSMtris', 13, 10 124 | db ' Shoaib Jamal for making the MichalOS website', 13, 10 125 | db ' VileR for porting the original DONKEY.BAS to assembly', 13, 10 126 | db ' ZeroKelvinKeyboard for creating TachyonOS & writing apps for MikeOS', 13, 10, 0 127 | 128 | .footer_msg db '[Space] Visit the hall of fame [L] View the license', 0 129 | .footer_msg_hall db '[Space] Go back [L] View the license', 0 130 | .footer_msg_lic db '[Space] Visit the hall of fame [L] Go back [Up/Down] Scroll', 0 131 | 132 | .commitver db ' ', GIT, 0 133 | 134 | .licensetext: incbin "../misc/LICENSE" 135 | db 0 136 | 137 | print_text_wall: 138 | pusha 139 | ; mov al, cl 140 | ; call os_print_2hex 141 | 142 | test cl, cl 143 | jz .print_loop 144 | 145 | .skip_loop: 146 | lodsb 147 | 148 | test al, al 149 | jz .exit 150 | 151 | cmp al, 10 152 | jne .skip_loop 153 | 154 | loop .skip_loop 155 | 156 | .print_loop: 157 | lodsb 158 | test al, al 159 | jz .exit 160 | 161 | call os_putchar 162 | 163 | call os_get_cursor_pos 164 | cmp dh, 24 165 | jne .print_loop 166 | 167 | .exit: 168 | popa 169 | ret 170 | 171 | draw_background: 172 | mov ax, .title_msg 173 | mov cx, 7 174 | call os_draw_background 175 | ret 176 | 177 | .title_msg db 'About MichalOS', 0 178 | 179 | ; ------------------------------------------------------------------ 180 | -------------------------------------------------------------------------------- /programs/calc.asm: -------------------------------------------------------------------------------- 1 | ; ------------------------------------------------------------------ 2 | ; MichalOS Calculator (32-bit) 3 | ; ------------------------------------------------------------------ 4 | 5 | %INCLUDE "include/program.inc" 6 | 7 | start: 8 | call .draw_background 9 | 10 | mov ax, .options 11 | mov bx, .options_name 12 | mov cx, .footer_msg 13 | call os_list_dialog 14 | 15 | jc .exit 16 | 17 | cmp ax, 1 18 | je .plus 19 | 20 | cmp ax, 2 21 | je .minus 22 | 23 | cmp ax, 3 24 | je .multiply 25 | 26 | cmp ax, 4 27 | je .divide 28 | 29 | cmp ax, 5 30 | je .power 31 | 32 | cmp ax, 6 33 | je .square_root 34 | 35 | cmp ax, 7 36 | je .cube_root 37 | 38 | .plus: 39 | call .draw_background 40 | call .get_numbers 41 | 42 | clr edx 43 | add eax, ebx 44 | 45 | jmp .result 46 | 47 | .minus: 48 | call .draw_background 49 | call .get_numbers 50 | 51 | clr edx 52 | sub eax, ebx 53 | 54 | jmp .result 55 | 56 | .multiply: 57 | call .draw_background 58 | call .get_numbers 59 | 60 | clr edx 61 | mul ebx 62 | 63 | jmp .result 64 | 65 | .divide: 66 | call .draw_background 67 | call .get_numbers 68 | 69 | test ebx, ebx 70 | jz .divide_error 71 | clr edx 72 | div ebx 73 | 74 | jmp .result 75 | 76 | .power: 77 | call .draw_background 78 | call .get_numbers 79 | 80 | call os_math_power 81 | jmp .result 82 | 83 | .square_root: 84 | call .draw_background 85 | call .get_number 86 | 87 | mov ebx, 2 88 | call os_math_root 89 | 90 | test edx, edx 91 | jnz .root_result 92 | 93 | jmp .result 94 | 95 | .cube_root: 96 | call .draw_background 97 | call .get_number 98 | 99 | mov ebx, 3 100 | call os_math_root 101 | 102 | test edx, edx 103 | jnz .root_result 104 | 105 | jmp .result 106 | 107 | .get_number: 108 | mov ax, .firstnumberstring 109 | mov bx, .number_msg 110 | call os_input_dialog 111 | mov si, ax 112 | call os_string_to_32int 113 | ret 114 | 115 | .get_numbers: 116 | mov ax, .firstnumberstring 117 | mov bx, .firstnumber_msg 118 | call os_input_dialog 119 | mov si, ax 120 | call os_string_to_32int 121 | push eax 122 | 123 | mov ax, .secondnumberstring 124 | mov bx, .secondnumber_msg 125 | call os_input_dialog 126 | mov si, ax 127 | call os_string_to_32int 128 | 129 | mov ebx, eax 130 | pop eax 131 | 132 | ret 133 | 134 | .root_result: 135 | mov si, .root_msg1 136 | mov di, .resultmsg 137 | call os_string_copy 138 | 139 | call os_32int_to_string ; We already have the result in EAX 140 | mov bx, ax 141 | mov ax, .resultmsg 142 | call os_string_add 143 | 144 | mov bx, .root_msg2 145 | call os_string_add 146 | 147 | mov eax, edx 148 | call os_32int_to_string 149 | mov bx, ax 150 | mov ax, .resultmsg 151 | call os_string_add 152 | 153 | mov ax, .resultmsg 154 | clr bx 155 | clr cx 156 | clr dx 157 | call os_dialog_box 158 | 159 | jmp start 160 | 161 | .result: 162 | mov si, .result_msg 163 | mov di, .resultmsg 164 | call os_string_copy 165 | 166 | call os_32int_to_string ; We already have the result in EAX 167 | mov bx, ax 168 | mov ax, .resultmsg 169 | call os_string_add 170 | 171 | test edx, edx 172 | jz .skipremainder 173 | 174 | mov bx, .remainder_msg 175 | call os_string_add 176 | 177 | push ax 178 | mov eax, edx 179 | call os_32int_to_string 180 | 181 | mov bx, ax 182 | pop ax 183 | call os_string_add 184 | 185 | mov bx, .msg_end 186 | call os_string_add 187 | 188 | .skipremainder: 189 | clr bx 190 | clr cx 191 | clr dx 192 | call os_dialog_box 193 | 194 | jmp start 195 | 196 | .divide_error: 197 | mov ax, .divide_msg 198 | clr bx 199 | clr cx 200 | clr dx 201 | call os_dialog_box 202 | jmp start 203 | 204 | .draw_background: 205 | mov ax, .title_msg 206 | mov bx, .footer_msg 207 | mov cx, 256 208 | call os_draw_background 209 | clr ch 210 | ret 211 | 212 | .exit: 213 | ret 214 | 215 | .title_msg db 'MichalOS Calculator', 0 216 | .footer_msg db 0 217 | 218 | .options_name db 'Choose an operation...', 0 219 | .options db '+ (Add),- (Subtract),* (Multiply),/ (Divide),^ (Power),', 0FBh, ' (Square root),3', 0FBh, ' (Cube root)', 0 220 | ; 251 = root symbol 221 | 222 | .result_msg db 'Answer: ', 0 223 | .remainder_msg db ' (remainder: ', 0 224 | .msg_end db ')', 0 225 | 226 | .root_msg1 db 'Answer: between ', 0 227 | .root_msg2 db ' and ', 0 228 | 229 | .divide_msg db 'Cannot divide by zero!', 0 230 | 231 | .number_msg db 'Enter a number:', 0 232 | .firstnumber_msg db 'Enter the first number:', 0 233 | .secondnumber_msg db 'Enter the second number:', 0 234 | 235 | .resultint dd 2048 + 0 236 | .remainderint dd 2048 + 4 237 | .firstnumber dd 2048 + 8 238 | .secondnumber dd 2048 + 12 239 | 240 | .firstnumberstring equ 4096 241 | .secondnumberstring equ 6144 242 | .resultmsg equ 8192 243 | 244 | 245 | ; ------------------------------------------------------------------ 246 | -------------------------------------------------------------------------------- /programs/check.asm: -------------------------------------------------------------------------------- 1 | 2 | %INCLUDE "include/program.inc" 3 | 4 | start: 5 | mov ax, .title 6 | mov bx, .null 7 | mov cx, 256 8 | call os_draw_background 9 | 10 | mov ax, .msg1 11 | mov bx, .msg2 12 | mov cx, .msg3 13 | mov dx, 1 14 | call os_dialog_box 15 | 16 | cmp ax, 1 17 | je .exit 18 | 19 | call os_clear_screen 20 | call os_get_boot_disk 21 | 22 | clr eax 23 | 24 | .loop: 25 | call .sectorselect 26 | inc ax 27 | cmp ax, 2880 28 | jl .loop 29 | 30 | mov ax, [.bad_sectors] 31 | call os_print_int 32 | 33 | mov si, .badmsg0 34 | call os_print_string 35 | 36 | call os_wait_for_key 37 | 38 | .exit: 39 | ret 40 | 41 | .sectorselect: 42 | pusha 43 | mov si, .sectormsg 44 | call os_print_string 45 | 46 | call os_print_int 47 | popa 48 | 49 | pusha 50 | mov si, 4000h 51 | call os_get_boot_disk 52 | call os_disk_read_sector 53 | jc .error 54 | 55 | mov si, .pass_msg 56 | call os_print_string 57 | popa 58 | ret 59 | 60 | .error: 61 | mov si, .err_msg 62 | call os_print_string 63 | inc word [.bad_sectors] 64 | popa 65 | ret 66 | 67 | .drive db 0 68 | .bad_sectors dw 0 69 | 70 | .title db 'MichalOS Disk Checker', 0 71 | .null db 0 72 | .msg1 db 'This utility will scan the current drive', 0 73 | .msg2 db 'for bad sectors. On a real floppy, this', 0 74 | .msg3 db 'test takes ~2 min. Are you sure?', 0 75 | 76 | .sectormsg db 'Sector ', 0 77 | .pass_msg db ' - Passed', 13, 10, 0 78 | .err_msg db ' - Failed', 13, 10, 0 79 | .badmsg0 db ' bad sectors found.', 0 80 | 81 | ; ------------------------------------------------------------------ 82 | 83 | -------------------------------------------------------------------------------- /programs/crash.asm: -------------------------------------------------------------------------------- 1 | ; ------------------------------------------------------------------ 2 | ; MichalOS INT 00 crash test 3 | ; ------------------------------------------------------------------ 4 | 5 | %include "include/program.inc" 6 | 7 | start: 8 | mov eax, 12342123h 9 | mov ebx, 69696969h 10 | mov ecx, 44444444h 11 | mov edx, 65465465h 12 | mov esi, 87658786h 13 | mov edi, 65432123h 14 | 15 | call os_dump_registers 16 | call os_wait_for_key 17 | 18 | mov ax, 9 19 | mov bx, 0 20 | div bx 21 | 22 | ret 23 | -------------------------------------------------------------------------------- /programs/deadpixl.asm: -------------------------------------------------------------------------------- 1 | ; ------------------------------------------------------------------ 2 | ; MichalOS Dead Pixel Test 3 | ; ------------------------------------------------------------------ 4 | 5 | %INCLUDE "include/program.inc" 6 | 7 | start: 8 | mov ax, .msg1 9 | mov bx, .msg2 10 | clr cx 11 | clr dx 12 | call os_dialog_box 13 | 14 | call os_init_graphics_mode 15 | 16 | clr bx 17 | movs es, 0A000h 18 | 19 | .loop: 20 | call os_clear_graphics 21 | 22 | inc bl 23 | and bl, 7 24 | 25 | call os_wait_for_key 26 | cmp al, 27 27 | jne .loop 28 | ret 29 | 30 | .msg1 db "Press any key to change the color.", 0 31 | .msg2 db "Press Escape to quit.", 0 32 | 33 | ; ------------------------------------------------------------------ 34 | -------------------------------------------------------------------------------- /programs/disktest.asm: -------------------------------------------------------------------------------- 1 | ; ------------------------------------------------------------------ 2 | ; MichalOS Disk test 3 | ; ------------------------------------------------------------------ 4 | 5 | %INCLUDE "include/program.inc" 6 | 7 | start: 8 | mov dx, 65535 9 | .loop: 10 | inc dx 11 | cmp dx, 256 12 | je .exit 13 | 14 | mov si, disk_buffer 15 | mov eax, 0 ; Load first disk sector into RAM 16 | call os_disk_read_sector 17 | jc .loop 18 | 19 | mov al, dl 20 | call os_print_2hex 21 | call os_print_newline 22 | jmp .loop 23 | .exit: 24 | call os_wait_for_key 25 | ret 26 | 27 | disk_buffer: 28 | 29 | ; ------------------------------------------------------------------ 30 | -------------------------------------------------------------------------------- /programs/dots.asm: -------------------------------------------------------------------------------- 1 | ; ------------------------------------------------------------------ 2 | ; MichalOS Dots Test 3 | ; ------------------------------------------------------------------ 4 | 5 | %INCLUDE "include/program.inc" 6 | 7 | start: 8 | call os_init_graphics_mode 9 | 10 | mov ax, 0A000h 11 | mov es, ax 12 | 13 | clr si 14 | clr di 15 | 16 | .loop: 17 | clr ax 18 | mov bx, 255 19 | call os_get_random 20 | mov bl, cl 21 | 22 | mov cx, si 23 | mov ax, di 24 | 25 | call os_set_pixel 26 | 27 | inc si 28 | cmp si, 320 29 | jne .no_inc_y 30 | 31 | clr si 32 | inc di 33 | 34 | cmp di, 200 35 | jne .no_inc_y 36 | 37 | clr di 38 | 39 | .no_inc_y: 40 | call os_check_for_key 41 | cmp al, 27 42 | jne .loop 43 | ret 44 | 45 | .color db 0 46 | .x_pos dw 0 47 | .y_pos dw 0 48 | 49 | ; ------------------------------------------------------------------ 50 | -------------------------------------------------------------------------------- /programs/fileman.asm: -------------------------------------------------------------------------------- 1 | ; ------------------------------------------------------------------ 2 | ; MichalOS File Manager 3 | ; ------------------------------------------------------------------ 4 | 5 | %INCLUDE "include/program.inc" 6 | 7 | start: 8 | mov [.load_segment], gs 9 | mov [.params_struct + 012h], ds 10 | 11 | call .draw_background 12 | 13 | call os_file_selector 14 | jc .exit 15 | 16 | mov bx, ax 17 | mov cx, .screenstring 18 | mov ax, .root 19 | call os_string_join 20 | mov ax, bx 21 | 22 | push ax 23 | 24 | mov bx, cx 25 | 26 | .commands: 27 | mov bx, .params_struct ; Draw list of disk operations 28 | call os_list_dialog_ex 29 | 30 | jc .clearstack ; User pressed Esc? 31 | 32 | cmp ax, 1 ; Otherwise respond to choice 33 | je .launch_file 34 | 35 | cmp ax, 2 36 | je .create_file 37 | 38 | cmp ax, 3 39 | je .delete_file 40 | 41 | cmp ax, 4 42 | je .rename_file 43 | 44 | cmp ax, 5 45 | je .copy_file 46 | 47 | .clearstack: 48 | pop ax 49 | jmp start 50 | 51 | .launch_file: 52 | pop ax 53 | call os_exit 54 | 55 | .create_file: 56 | pop ax 57 | 58 | call .draw_background 59 | 60 | mov bx, .filename_msg ; Get a filename 61 | mov ax, .filename_input 62 | call os_input_dialog 63 | 64 | clr cx ; Create an empty file 65 | mov bx, 4096 66 | mov ax, .filename_input 67 | call os_write_file 68 | 69 | jc .writing_error 70 | 71 | jmp start 72 | 73 | 74 | 75 | .delete_file: 76 | call .draw_background 77 | 78 | mov ax, .delete_confirm_msg ; Confirm delete operation 79 | clr bx 80 | clr cx 81 | mov dx, 1 82 | call os_dialog_box 83 | 84 | test ax, ax 85 | jz .ok_to_delete 86 | 87 | pop ax 88 | jmp start 89 | 90 | .ok_to_delete: 91 | pop ax 92 | call os_remove_file 93 | jc .disk_error 94 | jmp start 95 | 96 | .rename_file: 97 | call .draw_background 98 | 99 | pop ax 100 | 101 | mov si, ax ; And store it 102 | mov di, .filename_tmp1 103 | call os_string_copy 104 | 105 | mov bx, .filename_msg ; Get second filename 106 | mov ax, .filename_input 107 | call os_input_dialog 108 | 109 | mov si, ax ; Store it for later 110 | mov di, .filename_tmp2 111 | call os_string_copy 112 | 113 | mov ax, di ; Does the second filename already exist? 114 | call os_file_exists 115 | jnc .rename_fail ; Quit out if so 116 | 117 | mov ax, .filename_tmp1 118 | mov bx, .filename_tmp2 119 | 120 | call os_rename_file 121 | jc .writing_error 122 | 123 | jmp start 124 | 125 | 126 | .rename_fail: 127 | mov ax, .err_file_exists 128 | clr bx 129 | clr cx 130 | clr dx 131 | call os_dialog_box 132 | jmp start 133 | 134 | 135 | .copy_file: 136 | call .draw_background 137 | 138 | pop ax 139 | 140 | mov si, ax ; And store it 141 | mov di, .filename_tmp1 142 | call os_string_copy 143 | 144 | call .draw_background 145 | 146 | mov bx, .filename_msg ; Get second filename 147 | mov ax, .filename_input 148 | call os_input_dialog 149 | 150 | mov si, ax 151 | mov di, .filename_tmp2 152 | call os_string_copy 153 | 154 | call os_file_exists 155 | jnc .file_exists 156 | 157 | mov ax, .filename_tmp1 158 | mov bx, .filename_tmp2 159 | 160 | call os_get_file_size 161 | cmp ebx, 28672 162 | jl .no_copy_change 163 | 164 | mov word [.load_segment], gs 165 | mov word [.load_offset], 0000h 166 | 167 | .no_copy_change: 168 | push es 169 | mov es, [.load_segment] 170 | mov cx, [.load_offset] 171 | call os_load_file 172 | 173 | mov cx, bx 174 | mov bx, [.load_offset] 175 | mov ax, .filename_tmp2 176 | call os_write_file 177 | pop es 178 | 179 | jc .writing_error 180 | 181 | mov word [.load_segment], cs 182 | mov word [.load_offset], 1000h 183 | 184 | jmp start 185 | 186 | .no_copy_file_selected: 187 | jmp start 188 | 189 | .writing_error: 190 | mov word [.load_segment], cs 191 | mov word [.load_offset], 1000h 192 | 193 | call .draw_background 194 | 195 | mov ax, .error_msg 196 | mov bx, .error_msg2 197 | mov cx, .error_msg3 198 | clr dx 199 | call os_dialog_box 200 | jmp start 201 | 202 | .exit: 203 | call os_clear_screen 204 | ret 205 | 206 | 207 | .draw_background: 208 | mov ax, .title_msg 209 | mov bx, .footer_msg 210 | mov cx, 256 211 | call os_draw_background 212 | ret 213 | 214 | .disk_error: 215 | mov ax, .dk_error 216 | clr bx 217 | clr cx 218 | clr dx 219 | call os_dialog_box 220 | 221 | jmp start 222 | 223 | .file_exists: 224 | mov ax, .err_file_exists 225 | clr bx 226 | clr cx 227 | clr dx 228 | call os_dialog_box 229 | 230 | jmp start 231 | 232 | .params_struct: 233 | dw 0 ; No entry display callback 234 | dw .command_list ; Comma-separated list 235 | dw 0 ; No key/entry change callback 236 | dw 0 ; Auto-calculate number of entries 237 | dw .screenstring ; First help string 238 | dw .helpmsg ; Second help string 239 | dw 0 ; No history data 240 | db 2 ; X position 241 | db 2 ; Y position 242 | db 37 ; Width 243 | db 21 ; Height 244 | dw 0 ; Segment 245 | 246 | .command_list db 'Run application,Create file,Delete file,Rename,Copy file', 0 247 | 248 | .root db 'A:/' 249 | .helpmsg db 0 250 | 251 | .title_msg db 'MichalOS File Manager', 0 252 | .footer_msg db 0 253 | 254 | .delete_confirm_msg db 'Are you sure?', 0 255 | 256 | .filename_msg db 'Enter a new filename:', 0 257 | .filename_input times 60 db 0 258 | .filename_tmp1 times 60 db 0 259 | .filename_tmp2 times 60 db 0 260 | 261 | .error_msg db 'Error writing to the disk!', 0 262 | .error_msg2 db '(Disk is read-only/file already exists/', 0 263 | .error_msg3 db 'an invalid filename was entered)?', 0 264 | 265 | .err_file_exists db 'File with this name already exists!', 0 266 | 267 | .dk_error db 'Disk error!', 0 268 | 269 | .load_segment dw 0 270 | .load_offset dw 0 271 | 272 | .screenstring times 24 db 0 273 | 274 | blank: 275 | 276 | ; ------------------------------------------------------------------ -------------------------------------------------------------------------------- /programs/float.asm: -------------------------------------------------------------------------------- 1 | %include "include/program.inc" 2 | 3 | start: 4 | finit ; Initialize the FPU 5 | 6 | fstcw [tmpword] 7 | or byte [tmpword + 1], 1100b ; Disable rounding 8 | fldcw [tmpword] 9 | 10 | fldpi ; ST0 = Pi 11 | call .print_float 12 | fdecstp 13 | fldz ; ST0 = Pi 14 | call .print_float 15 | fdecstp 16 | fld1 ; ST0 = Pi 17 | call .print_float 18 | fdecstp 19 | fldlg2 ; ST0 = Pi 20 | call .print_float 21 | fdecstp 22 | fldln2 ; ST0 = Pi 23 | call .print_float 24 | fdecstp 25 | 26 | call os_wait_for_key 27 | ret 28 | 29 | .print_float: 30 | fst qword [backup] ; Remember the test value for later 31 | 32 | ; Get the digits before the decimal point 33 | 34 | mov di, buffer + 299 35 | std ; The digits will be backwards 36 | 37 | mov cx, 300 38 | 39 | .loop: 40 | fst qword [tmp] ; ST0 = Pi 41 | 42 | fild word [mul10] ; ST0 = 10, ST1 = Pi 43 | fld qword [tmp] ; ST0 = Pi, ST1 = 10, ST2 = Pi 44 | fprem ; ST0 = Pi % 10, ST1 = 10, ST2 = Pi 45 | 46 | fistp word [tmpword]; ST0 = 10, ST1 = Pi 47 | fstp qword [tmp] ; ST0 = Pi 48 | 49 | fidiv word [mul10] ; ST0 = Pi / 10 50 | 51 | mov ax, [tmpword] 52 | stosb 53 | 54 | loop .loop 55 | 56 | ; And now after the decimal point 57 | 58 | mov di, buffer + 300 59 | cld 60 | 61 | fstp qword [tmp] 62 | fld qword [backup] 63 | 64 | mov cx, 300 65 | 66 | .loop2: 67 | fimul word [mul10] 68 | 69 | fst qword [tmp] 70 | 71 | fild word [mul10] 72 | fld qword [tmp] 73 | fprem 74 | 75 | fistp word [tmpword] 76 | fstp qword [tmp] 77 | 78 | mov ax, [tmpword] 79 | stosb 80 | 81 | loop .loop2 82 | 83 | ; And now, print the digits 84 | mov si, buffer 85 | mov cx, 600 86 | 87 | test byte [backup + 7], 80h ; Negative? 88 | jz .prefixloop 89 | 90 | mov al, '-' 91 | call os_putchar 92 | 93 | ; First, skip all of the prefix zeroes 94 | 95 | .prefixloop: 96 | lodsb 97 | test al, al 98 | jnz .print 99 | 100 | loop .prefixloop 101 | 102 | ; No digits were found, so it's zero 103 | 104 | .print: 105 | push cx 106 | 107 | ; Print the first digit 108 | 109 | add al, '0' 110 | call os_putchar 111 | 112 | mov al, '.' 113 | call os_putchar 114 | 115 | mov cx, 14 ; Print the next 14 digits 116 | 117 | .print_loop: 118 | lodsb 119 | 120 | add al, '0' 121 | call os_putchar 122 | 123 | loop .print_loop 124 | 125 | mov al, 'e' 126 | call os_putchar 127 | 128 | pop cx 129 | sub cx, 301 130 | mov ax, cx 131 | call os_sint_to_string 132 | mov si, ax 133 | call os_print_string 134 | 135 | .exit: 136 | call os_print_newline 137 | ret 138 | 139 | tmp dq 0.0 140 | backup dq 0.0 141 | tmpword dw 0 142 | mul10 dw 10 143 | 144 | buffer: 145 | -------------------------------------------------------------------------------- /programs/hwcheck.asm: -------------------------------------------------------------------------------- 1 | ; ------------------------------------------------------------------ 2 | ; MichalOS Hardware checker 3 | ; ------------------------------------------------------------------ 4 | 5 | %INCLUDE "include/program.inc" 6 | 7 | start: 8 | clr eax ; Get the maximum parameter for basic CPUID 9 | cpuid 10 | mov [basicid], eax 11 | 12 | mov eax, 80000000h ; Get the maximum parameter for extended CPUID 13 | cpuid 14 | mov [extendedid], eax 15 | 16 | main_loop: 17 | clr al 18 | mov cx, 64 19 | mov di, p1 20 | rep stosb 21 | 22 | call background 23 | mov ax, optionlist 24 | mov bx, optionmsg1 25 | mov cx, optionmsg2 26 | call os_list_dialog 27 | call background 28 | 29 | cmp ax, 1 30 | je checkvendor 31 | 32 | cmp ax, 2 33 | je checkfeatures 34 | 35 | cmp ax, 3 36 | je vesa 37 | 38 | exit: 39 | call os_clear_screen 40 | ret 41 | 42 | background: 43 | pusha 44 | call os_clear_screen 45 | mov ax, welcomemsg 46 | mov bx, footermsg 47 | mov cx, 11110000b 48 | call os_draw_background 49 | mov16 dx, 0, 2 50 | call os_move_cursor 51 | popa 52 | ret 53 | 54 | %INCLUDE "hwcheck/basic.asm" 55 | %INCLUDE "hwcheck/features.asm" 56 | %INCLUDE "hwcheck/extended.asm" 57 | %INCLUDE "hwcheck/vesa.asm" 58 | 59 | basicid dd 0 60 | extendedid dd 0 61 | 62 | unit_kb db ' kB', 0 63 | unit_mhz db ' MHz', 0 64 | unit_hex db 'h', 0 65 | 66 | noimp db '', 0 67 | enabled db 'Enabled', 0 68 | disabled db 'Disabled', 0 69 | 70 | welcomemsg db 'MichalOS Hardware Checking Utility', 0 71 | footermsg db 0 72 | 73 | optionmsg1 db 'Choose an option...', 0 74 | optionmsg2 db 0 75 | optionlist db 'Basic system specifications,Processor features,VESA specifications', 0 76 | 77 | buffer: 78 | p0 dd 0 79 | p1 dd 0 80 | p2 dd 0 81 | p3 dd 0 82 | p4 dd 0 83 | p5 dd 0 84 | p6 dd 0 85 | p7 dd 0 86 | p8 dd 0 87 | p9 dd 0 88 | p10 dd 0 89 | p11 dd 0 90 | p12 dd 0 91 | p13 dd 0 92 | p14 dd 0 93 | p15 dd 0 94 | p16 dd 0 95 | pfinal db 0 96 | 97 | ; ------------------------------------------------------------------ 98 | 99 | -------------------------------------------------------------------------------- /programs/hwcheck/basic.asm: -------------------------------------------------------------------------------- 1 | checkvendor: ; CPU vendor 2 | call background 3 | 4 | mov si, msg0 5 | call os_print_string 6 | 7 | mov eax, [basicid] ; Is the CPU compatible with this instruction? 8 | cmp eax, 1 9 | jge vendor 10 | 11 | mov si, noimp 12 | call os_print_string 13 | 14 | jmp checkfamily 15 | 16 | vendor: 17 | clr eax 18 | cpuid 19 | 20 | mov [p1], ebx 21 | mov [p2], edx 22 | mov [p3], ecx 23 | 24 | mov si, p1 25 | call os_print_string 26 | 27 | checkfamily: ; Family info 28 | call os_print_newline 29 | 30 | mov eax, [basicid] ; Is the CPU compatible with this instruction? 31 | cmp eax, 1 32 | jge steppingid ; If it is, continue to the %INCLUDEd file below... 33 | 34 | mov si, msg1 35 | call os_print_string 36 | mov si, noimp 37 | call os_print_string 38 | call os_print_newline 39 | mov si, msg2 40 | call os_print_string 41 | mov si, noimp 42 | call os_print_string 43 | call os_print_newline 44 | mov si, msg3 45 | call os_print_string 46 | mov si, noimp 47 | call os_print_string 48 | call os_print_newline 49 | mov si, msg4 50 | call os_print_string 51 | mov si, noimp 52 | call os_print_string 53 | call os_print_newline 54 | 55 | call os_wait_for_key 56 | 57 | jmp main_loop 58 | 59 | steppingid: 60 | mov eax, 1 61 | cpuid 62 | 63 | clr edx 64 | mov ecx, 16 65 | div ecx 66 | 67 | mov [p1], edx 68 | 69 | model: 70 | clr edx 71 | mov ecx, 16 72 | div ecx 73 | 74 | mov [p2], edx 75 | 76 | family: 77 | clr edx 78 | mov ecx, 16 79 | div ecx 80 | 81 | mov [p3], edx 82 | 83 | cputype: 84 | clr edx 85 | mov ecx, 4 86 | div ecx 87 | 88 | mov [p4], edx 89 | 90 | clr edx ; Skip the next 2 bits, they are reserved 91 | mov ecx, 4 92 | div ecx 93 | 94 | extmodel: 95 | clr edx 96 | mov ecx, 4 97 | div ecx 98 | 99 | mov [p5], edx 100 | 101 | extfamily: 102 | clr edx 103 | mov ecx, 4 104 | div ecx 105 | 106 | mov [p6], edx 107 | 108 | familyoutput: 109 | mov si, msg1 110 | call os_print_string 111 | mov eax, [p1] 112 | call os_print_int 113 | call os_print_newline 114 | 115 | mov si, msg2 116 | call os_print_string 117 | mov eax, [p5] ; Get the high 4 bits 118 | mov bx, 16 119 | mul bx ; Multiply them by 16 120 | mov ebx, eax ; Store the result to EBX 121 | mov eax, [p2] ; Get the low 4 bits 122 | add eax, ebx ; Add the high and low bits together 123 | call os_print_int 124 | call os_print_newline 125 | 126 | mov si, msg3 127 | call os_print_string 128 | mov eax, [p6] ; Get the high 4 bits 129 | mov bx, 16 130 | mul bx ; Multiply them by 16 131 | mov ebx, eax ; Store the result to EBX 132 | mov eax, [p3] ; Get the low 4 bits 133 | add eax, ebx ; Add the high and low bits together 134 | call os_print_int 135 | call os_print_newline 136 | 137 | mov si, msg4 138 | call os_print_string 139 | mov eax, [p4] 140 | call os_print_int 141 | call os_print_newline 142 | 143 | mov si, convmem 144 | call os_print_string 145 | call os_get_memory 146 | call os_print_int 147 | mov si, unit_kb 148 | call os_print_string 149 | call os_print_newline 150 | 151 | mov si, highmem 152 | call os_print_string 153 | call os_get_memory 154 | mov ax, bx 155 | call os_print_int 156 | mov si, unit_kb 157 | call os_print_string 158 | call os_get_memory 159 | cmp bx, 64512 160 | jne .not_more_ram 161 | 162 | mov si, or_more 163 | call os_print_string 164 | 165 | .not_more_ram: 166 | call os_print_newline 167 | 168 | jmp extendedcpu 169 | 170 | msg0 db 'Vendor ID: ', 0 171 | msg1 db 'Stepping ID: ', 0 172 | msg2 db 'Model: ', 0 173 | msg3 db 'Family: ', 0 174 | msg4 db 'CPU type: ', 0 175 | convmem db 'Conv. memory: ', 0 176 | highmem db 'Ext. memory: ', 0 177 | or_more db ' (or more)', 0 178 | -------------------------------------------------------------------------------- /programs/hwcheck/extended.asm: -------------------------------------------------------------------------------- 1 | extendedcpu: 2 | mov si, name 3 | call os_print_string 4 | cmp dword [extendedid], 0 5 | jge .error 6 | 7 | cmp eax, 80000004h 8 | jge cpuname 9 | 10 | .error: 11 | mov si, noimp 12 | call os_print_string 13 | jmp cpuidcheck 14 | 15 | cpuname: 16 | mov eax, 80000002h 17 | cpuid 18 | mov [p1], eax 19 | mov [p2], ebx 20 | mov [p3], ecx 21 | mov [p4], edx 22 | 23 | mov eax, 80000003h 24 | cpuid 25 | mov [p5], eax 26 | mov [p6], ebx 27 | mov [p7], ecx 28 | mov [p8], edx 29 | 30 | mov eax, 80000004h 31 | cpuid 32 | mov [p9], eax 33 | mov [p10], ebx 34 | mov [p11], ecx 35 | mov [p12], edx 36 | 37 | mov si, p1 38 | call os_print_string 39 | 40 | cpuidcheck: 41 | call os_print_newline 42 | mov si, cpuidbas 43 | call os_print_string 44 | mov eax, [basicid] 45 | call os_print_8hex 46 | mov si, unit_hex 47 | call os_print_string 48 | call os_print_newline 49 | 50 | mov si, cpuidext 51 | call os_print_string 52 | mov eax, [extendedid] 53 | call os_print_8hex 54 | mov si, unit_hex 55 | call os_print_string 56 | call os_print_newline 57 | 58 | ;mov ecx, 0xe7 59 | ;rdmsr 60 | ;call os_print_8hex 61 | ;mov eax, edx 62 | ;call os_print_8hex 63 | ;call os_print_newline 64 | ;mov ecx, 0xe8 65 | ;rdmsr 66 | ;call os_print_8hex 67 | ;mov eax, edx 68 | ;call os_print_8hex 69 | ;call os_print_newline 70 | 71 | 72 | extendedcpuend: 73 | call os_wait_for_key 74 | jmp main_loop 75 | 76 | name db 'Name ', 0 77 | cpuidbas db 'Basic CPUID: ', 0 78 | cpuidext db 'Ext. CPUID: ', 0 79 | -------------------------------------------------------------------------------- /programs/hwcheck/features.asm: -------------------------------------------------------------------------------- 1 | checkfeatures: 2 | mov eax, [basicid] ; Is the CPU compatible with this instruction? 3 | cmp eax, 1 4 | jge features 5 | 6 | jmp main_loop 7 | 8 | features: 9 | mov eax, 1 10 | cpuid 11 | mov di, 24000 12 | features_loop: 13 | mov al, dl 14 | and al, 1 15 | mov [di], al 16 | shr edx, 1 17 | 18 | inc di 19 | cmp di, 24032 20 | jl features_loop 21 | 22 | features_loop2: 23 | mov al, cl 24 | and al, 1 25 | mov [di], al 26 | shr ecx, 1 27 | 28 | inc di 29 | cmp di, 24064 30 | jl features_loop2 31 | 32 | features_output: 33 | mov di, 24000 34 | mov cx, feature00 35 | mov16 dx, 0, 1 36 | 37 | features_loop_output: 38 | call os_move_cursor 39 | 40 | mov si, cx 41 | call os_print_string 42 | 43 | mov al, [di] 44 | cmp al, 1 45 | je feature_enabled 46 | 47 | mov si, disabled 48 | call os_print_string 49 | 50 | feature_loop_continue: 51 | inc di 52 | inc dh 53 | add cx, 14 54 | 55 | cmp di, 24064 56 | je feature_end 57 | 58 | cmp dh, 24 59 | je feature_loop_nextcolumn 60 | 61 | jmp features_loop_output 62 | 63 | feature_enabled: 64 | mov si, enabled 65 | call os_print_string 66 | jmp feature_loop_continue 67 | 68 | feature_loop_nextcolumn: 69 | add dl, 26 70 | mov dh, 1 71 | jmp features_loop_output 72 | 73 | feature_end: 74 | call os_wait_for_key 75 | jmp main_loop 76 | 77 | feature00 db 'fpu: ', 0 78 | feature01 db 'vme: ', 0 79 | feature02 db 'de: ', 0 80 | feature03 db 'pse: ', 0 81 | feature04 db 'tsc: ', 0 82 | feature05 db 'msr: ', 0 83 | feature06 db 'pae: ', 0 84 | feature07 db 'mce: ', 0 85 | feature08 db 'cx8: ', 0 86 | feature09 db 'apic: ', 0 87 | feature10 db ' ', 0 88 | feature11 db 'sep: ', 0 89 | feature12 db 'mtrr: ', 0 90 | feature13 db 'pge: ', 0 91 | feature14 db 'mca: ', 0 92 | feature15 db 'cmov: ', 0 93 | feature16 db 'pat: ', 0 94 | feature17 db 'pse-36: ', 0 95 | feature18 db 'psn: ', 0 96 | feature19 db 'clfsh: ', 0 97 | feature20 db ' ', 0 98 | feature21 db 'ds: ', 0 99 | feature22 db 'acpi: ', 0 100 | feature23 db 'mmx: ', 0 101 | feature24 db 'fxsr: ', 0 102 | feature25 db 'sse: ', 0 103 | feature26 db 'sse2: ', 0 104 | feature27 db 'ss: ', 0 105 | feature28 db 'htt: ', 0 106 | feature29 db 'tm: ', 0 107 | feature30 db 'ia64: ', 0 108 | feature31 db 'pbe: ', 0 109 | feature32 db 'sse3: ', 0 110 | feature33 db 'pclmulqdq: ', 0 111 | feature34 db 'dtes64: ', 0 112 | feature35 db 'monitor: ', 0 113 | feature36 db 'ds-cpl: ', 0 114 | feature37 db 'vmx: ', 0 115 | feature38 db 'smx: ', 0 116 | feature39 db 'est: ', 0 117 | feature40 db 'tm2: ', 0 118 | feature41 db 'ssse3: ', 0 119 | feature42 db 'cnxt-id: ', 0 120 | feature43 db 'sdbg: ', 0 121 | feature44 db 'fma: ', 0 122 | feature45 db 'cx16: ', 0 123 | feature46 db 'xtpr: ', 0 124 | feature47 db 'pdcm: ', 0 125 | feature48 db ' ', 0 126 | feature49 db 'pcid: ', 0 127 | feature50 db 'dca: ', 0 128 | feature51 db 'sse4.1: ', 0 129 | feature52 db 'sse4.2: ', 0 130 | feature53 db 'x2apic: ', 0 131 | feature54 db 'movbe: ', 0 132 | feature55 db 'popcnt: ', 0 133 | feature56 db 'tsc-deadline:', 0 134 | feature57 db 'aes: ', 0 135 | feature58 db 'xsave: ', 0 136 | feature59 db 'osxsave: ', 0 137 | feature60 db 'avx: ', 0 138 | feature61 db 'f16c: ', 0 139 | feature62 db 'rdrnd: ', 0 140 | feature63 db 'hypervisor: ', 0 141 | -------------------------------------------------------------------------------- /programs/hwcheck/vesa.asm: -------------------------------------------------------------------------------- 1 | vesa: ; CPU vendor 2 | call background 3 | 4 | mov ax, 4F00h 5 | mov di, buffer 6 | int 10h 7 | 8 | mov si, .msg0 9 | call os_print_string 10 | 11 | mov ax, [buffer + 04h] 12 | call os_print_4hex 13 | 14 | call os_print_newline 15 | 16 | mov si, .msg1 17 | call os_print_string 18 | 19 | mov eax, [buffer + 0Ah] 20 | call os_print_8hex 21 | 22 | call os_print_newline 23 | 24 | mov si, .msg2 25 | call os_print_string 26 | 27 | clr eax 28 | mov ax, [buffer + 12h] 29 | shl eax, 6 30 | call os_print_32int 31 | mov si, unit_kb 32 | call os_print_string 33 | 34 | call os_wait_for_key 35 | 36 | jmp main_loop 37 | 38 | .msg0 db 'VESA version: ', 0 39 | .msg1 db 'Abilities: ', 0 40 | .msg2 db 'VESA memory: ', 0 41 | -------------------------------------------------------------------------------- /programs/kbdtest.asm: -------------------------------------------------------------------------------- 1 | %INCLUDE "include/program.inc" 2 | 3 | start: 4 | call .draw_background 5 | 6 | mov ax, .options 7 | mov bx, .optmsg 8 | mov cx, .blank 9 | call os_list_dialog 10 | 11 | jc .exit 12 | 13 | pusha 14 | mov ax, .exit_msg 15 | clr bx 16 | clr cx 17 | clr dx 18 | call os_dialog_box 19 | call os_clear_screen 20 | popa 21 | 22 | cmp ax, 1 23 | je .test1 24 | 25 | cmp ax, 2 26 | je .test2 27 | 28 | cmp ax, 3 29 | je .test3 30 | 31 | cmp ax, 4 32 | je .test4 33 | 34 | .test4: 35 | mov ah, 10h 36 | int 16h 37 | cmp al, "Q" 38 | je start 39 | 40 | push ax 41 | 42 | mov bx, 100h 43 | clr dx 44 | div bx 45 | call os_print_int 46 | call os_print_space 47 | mov ax, dx 48 | call os_print_int 49 | call os_print_space 50 | 51 | pop ax 52 | call os_print_4hex 53 | 54 | call os_print_newline 55 | jmp .test4 56 | 57 | .test1: 58 | clr ah 59 | int 16h 60 | cmp al, "Q" 61 | je start 62 | 63 | push ax 64 | 65 | mov bx, 100h 66 | clr dx 67 | div bx 68 | call os_print_int 69 | call os_print_space 70 | mov ax, dx 71 | call os_print_int 72 | call os_print_space 73 | 74 | pop ax 75 | call os_print_4hex 76 | 77 | call os_print_newline 78 | jmp .test1 79 | 80 | .test2: 81 | mov ah, 1 82 | int 16h 83 | 84 | jz .2nokey ; If no key, skip to end 85 | 86 | clr ax ; Otherwise get it from buffer 87 | int 16h 88 | 89 | .2nokey: 90 | cmp al, "Q" 91 | je start 92 | 93 | push ax 94 | 95 | mov bx, 100h 96 | clr dx 97 | div bx 98 | call os_print_int 99 | call os_print_space 100 | mov ax, dx 101 | call os_print_int 102 | call os_print_space 103 | 104 | pop ax 105 | call os_print_4hex 106 | 107 | call os_print_newline 108 | jmp .test2 109 | 110 | .test3: 111 | mov al, [fs:0417h] 112 | call os_print_2hex 113 | mov al, [fs:0418h] 114 | call os_print_2hex 115 | 116 | mov ah, 1 117 | int 16h 118 | jz .3nokey ; If no key, skip to end 119 | 120 | clr ax ; Otherwise get it from buffer 121 | int 16h 122 | 123 | .3nokey: 124 | cmp al, "Q" 125 | je start 126 | 127 | jmp .test3 128 | 129 | .exit: 130 | ret 131 | 132 | .draw_background: 133 | mov ax, .title 134 | mov bx, .blank 135 | mov cx, 256 136 | call os_draw_background 137 | ret 138 | 139 | .title db 'MichalOS Keyboard Diagnostic Tool', 0 140 | .optmsg db 'Choose an option...', 0 141 | .options db 'INT 16h (00h) - Slow key test,INT 16h (01h) - Fast key test,INT 16h (02h) - Modifier key test,INT 16h (10h) - Slow key test (AT)', 0 142 | .blank db 0 143 | 144 | .exit_msg db 'Press Shift+Q to quit.', 0 145 | 146 | buffer: 147 | -------------------------------------------------------------------------------- /programs/pcmtest.asm: -------------------------------------------------------------------------------- 1 | ; ------------------------------------------------------------------ 2 | ; MichalOS PC Speaker PCM Demo 3 | ; 4 | ; WARNING: This demo uses the top 1.44 MB of a 2.88 MB disk. 5 | ; To generate a compatible image, run your favorite song through 6 | ; FFmpeg to convert it to a 11025 Hz 8-bit PCM file: 7 | ; 8 | ; ffmpeg -i -f u8 -acodec pcm_u8 -ac 1 -ar 11025 9 | ; 10 | ; Then, move the output file to files/gitignore/288data. After that, 11 | ; you can generate the 2.88 MB image by running: 12 | ; 13 | ; make big 14 | ; ------------------------------------------------------------------ 15 | 16 | %include "include/program.inc" 17 | bits 16 18 | org 100h 19 | 20 | counter equ 0x1234DC / 11025 21 | 22 | start: 23 | call os_hide_cursor 24 | 25 | mov ax, .titlemsg 26 | mov bx, .footermsg 27 | mov cx, 256 28 | call os_draw_background 29 | 30 | ;; Load data sector 31 | mov eax, 2880 32 | mov si, 8192 33 | mov cx, 8 34 | call os_get_boot_disk 35 | call os_disk_read_multiple_sectors 36 | jnc .no_error 37 | 38 | mov ax, .error_msg1 39 | mov bx, .error_msg2 40 | mov cx, .error_msg3 41 | mov dx, 1 42 | call os_dialog_box 43 | 44 | test ax, ax 45 | jnz .appexit 46 | 47 | .no_error: 48 | clr si 49 | clr ax 50 | clr bx 51 | clr cx 52 | clr dx 53 | call os_temp_box 54 | 55 | ;; Replace IRQ0 with our sound code 56 | mov si, tick 57 | call os_attach_app_timer 58 | 59 | ;; Attach the PC Speaker to PIT Channel 2 60 | in al, 0x61 61 | or al, 3 62 | out 0x61, al 63 | 64 | ;; Reprogram PIT Channel 0 to fire IRQ0 at 16kHz 65 | cli 66 | mov al, 0x36 67 | out 0x43, al 68 | mov ax, counter 69 | out 0x40, al 70 | mov al, ah 71 | out 0x40, al 72 | sti 73 | 74 | ;; Keep processing interrupts until it says we're done 75 | 76 | .mainlp: 77 | hlt 78 | call os_check_for_key 79 | cmp al, "1" 80 | je .dec_volume 81 | cmp al, "2" 82 | je .inc_volume 83 | cmp al, 32 84 | je .playpause 85 | cmp al, 27 86 | je .exit 87 | 88 | ; Load new sectors if necessary 89 | 90 | mov ax, [offset] 91 | and ax, 0x1000 92 | cmp ax, [.previous_block] 93 | je .no_load 94 | 95 | mov [.previous_block], ax 96 | xor ax, 0x1000 97 | mov si, 8192 98 | add si, ax 99 | 100 | mov ax, [.current_position] 101 | cmp ax, 2880 * 2 102 | jne .no_reset 103 | 104 | mov ax, 2880 105 | mov [.current_position], ax 106 | mov word [.loadedbuffers], 0 107 | 108 | .no_reset: 109 | mov cx, 8 110 | call os_get_boot_disk 111 | call os_disk_read_multiple_sectors 112 | 113 | add word [.current_position], 8 114 | inc word [.loadedbuffers] 115 | 116 | .no_load: 117 | ; Draw the VU meter 118 | 119 | mov dl, 24 120 | mov dh, 14 121 | call os_move_cursor 122 | 123 | mov cx, 32 124 | mov bx, 7 125 | mov ax, 0920h 126 | int 10h 127 | 128 | mov si, [offset] 129 | movzx cx, byte [si] 130 | cmp cx, 80h 131 | jge .subtract 132 | 133 | mov al, 80h 134 | sub al, cl 135 | mov cl, al 136 | jmp .done 137 | 138 | .subtract: 139 | sub cl, 80h 140 | 141 | .done: 142 | shr cx, 2 143 | 144 | mov ax, 09DBh 145 | int 10h 146 | 147 | .no_display: 148 | ; Show how many samples have been read 149 | 150 | mov dl, 20 151 | mov dh, 10 152 | call os_move_cursor 153 | 154 | mov ax, [.loadedbuffers] 155 | call os_print_int 156 | 157 | mov si, .buffmsg 158 | call os_print_string 159 | 160 | mov ax, [.loadedbuffers] 161 | shl ax, 2 162 | call os_print_int 163 | 164 | mov si, .buffmsg2 165 | call os_print_string 166 | 167 | ; Show how long has the song been playing 168 | 169 | mov dl, 20 170 | mov dh, 12 171 | call os_move_cursor 172 | 173 | clr edx 174 | movzx eax, word [.loadedbuffers] 175 | shl eax, 12 176 | mov ebx, 11025 177 | div ebx 178 | 179 | call os_print_int 180 | 181 | mov si, .secondmsg 182 | call os_print_string 183 | 184 | cmp word [done], 0 185 | je .mainlp 186 | 187 | .exit: 188 | ;; Restore original IRQ0 189 | 190 | call os_return_app_timer 191 | 192 | mov al, 0x36 ; ... and slow the timer back down 193 | out 0x43, al ; to 18.2 Hz 194 | xor al, al 195 | out 0x40, al 196 | out 0x40, al 197 | 198 | ;; Turn off the PC speaker 199 | in al, 0x61 200 | and al, 0xfc 201 | out 0x61, al 202 | 203 | .appexit: 204 | ;; And quit with success 205 | ret 206 | 207 | .playpause: 208 | xor byte [pausestate], 1 209 | jmp .mainlp 210 | 211 | .inc_volume: 212 | cmp byte [shr_value], 00h 213 | je .mainlp 214 | 215 | dec byte [shr_value] 216 | jmp .mainlp 217 | 218 | .dec_volume: 219 | cmp byte [shr_value], 07h 220 | je .mainlp 221 | 222 | inc byte [shr_value] 223 | jmp .mainlp 224 | 225 | .current_position dw 2880 + 8 226 | .titlemsg db "MichalOS PCM Test", 0 227 | .footermsg db "[Space] Play/Pause [Esc] Exit", 0 228 | .secondmsg db " seconds played ", 0 229 | .buffmsg db " buffers read (", 0 230 | .buffmsg2 db " kB) ", 0 231 | .previous_block dw 1 232 | .loadedbuffers dw 1 233 | 234 | .error_msg1 db "Error reading high disk sectors.", 0 235 | .error_msg2 db "On some systems, this may be a false", 0 236 | .error_msg3 db "positive. Do you still want to continue?", 0 237 | 238 | ;; *** IRQ0 TICK ROUTINE *** 239 | tick: 240 | cmp byte [pausestate], 1 241 | je .no_update_timer 242 | 243 | mov si, [offset] 244 | 245 | mov ah, [si] ; If not, load up the value 246 | mov cl, [shr_value] 247 | shr ax, cl ; Make it a 7-bit value 248 | test ah, ah 249 | jz .no_play ; If the value is 0, the PIT thinks it's actually 0x100, so it'll clip 250 | 251 | mov al, 0xb0 ; And program PIT Channel 2 to 252 | out 0x43, al ; deliver a pulse that many 253 | mov al, ah ; microseconds long 254 | out 0x42, al 255 | clr al 256 | out 0x42, al 257 | 258 | .no_play: 259 | inc si ; Update pointer 260 | and si, 0x1FFF ; Ensure the pointer is 4096-8191 261 | or si, 0x2000 262 | mov [offset], si 263 | 264 | .no_update_timer: 265 | jmp .intend ; ... and jump to end of interrupt 266 | 267 | ;; If we get here, we're past the end of the sound. 268 | .nosnd: 269 | mov ax, [done] ; Have we already marked it done? 270 | jnz .intend ; If so, nothing left to do 271 | mov ax, 1 ; Otherwise, mark it done... 272 | mov [done], ax 273 | 274 | .intend: 275 | retf 276 | 277 | done dw 0 278 | offset dw 8192 279 | shr_value db 2 280 | pausestate db 0 281 | -------------------------------------------------------------------------------- /programs/player/dro.asm: -------------------------------------------------------------------------------- 1 | ; ------------------------------------------------------------------ 2 | ; MichalOS Music Player - DRO decoder 3 | ; ------------------------------------------------------------------ 4 | 5 | start_drz: 6 | popa 7 | 8 | push bx 9 | 10 | push es 11 | mov ax, gs 12 | add ax, 2000h ; Scratch segment 13 | mov es, ax 14 | mov ax, bx 15 | clr cx 16 | call os_load_file 17 | pop es 18 | 19 | jc start_dro.stop 20 | 21 | push ds 22 | push es 23 | 24 | mov ax, gs 25 | mov es, ax 26 | add ax, 2000h 27 | mov ds, ax 28 | clr si 29 | clr di 30 | 31 | ; The file contains several compressed 64 kB chunks, so decompress each one 32 | 33 | lodsb ; Load the number of chunks 34 | movzx cx, al 35 | 36 | .loadsegloop: 37 | lodsw ; Load the compressed chunk pointer 38 | 39 | push si 40 | mov si, ax 41 | 42 | push cx 43 | call os_decompress_zx7 ; Decompress the chunk 44 | pop cx 45 | pop si 46 | 47 | mov ax, es 48 | add ax, 1000h ; Point to the next segment 49 | mov es, ax 50 | clr di 51 | 52 | loop .loadsegloop 53 | 54 | pop es 55 | pop ds 56 | 57 | jmp start_dro.dro_post_load 58 | 59 | start_dro: 60 | popa 61 | 62 | push bx 63 | 64 | push es 65 | mov ax, gs 66 | mov es, ax 67 | mov ax, bx 68 | clr cx 69 | call os_load_file 70 | pop es 71 | 72 | jc .stop 73 | 74 | .dro_post_load: 75 | call start.draw_player_background 76 | 77 | mov si, .playmsg1 78 | mov bx, .playmsg2 79 | call create_player_box 80 | 81 | mov dx, 0A21h 82 | call os_move_cursor 83 | 84 | pop si 85 | call os_print_string 86 | 87 | .dro_decode: 88 | mov byte [.play], 0 89 | mov dword [.target_pos], 0 90 | 91 | call .clear_adlib 92 | 93 | mov eax, [gs:10h] ; Song length in miliseconds 94 | shr eax, 10 95 | mov [.song_length], ax 96 | 97 | mov al, [gs:17h] 98 | mov [cs:.short_delay], al 99 | mov al, [gs:18h] 100 | mov [cs:.long_delay], al 101 | mov al, [gs:19h] ; Codemap length 102 | 103 | movzx bx, al 104 | mov [.codemap], bx 105 | 106 | and eax, 000000FFh 107 | add eax, 1Ah ; Get the data start 108 | 109 | mov [.position_offset], ax 110 | mov word [.position_segment], 0 111 | 112 | add eax, [gs:0Ch] ; Add the song length 113 | 114 | shl eax, 1 ; Register pairs -> offset 115 | mov [.length_offset], ax 116 | 117 | shr eax, 4 ; Get the segment 118 | and ax, 0F000h 119 | mov [.length_segment], ax 120 | 121 | call os_stop_adlib 122 | 123 | mov dword [.current_pos], 0 124 | 125 | mov si, .int_handler 126 | mov cx, 132 127 | mov bl, 9 128 | call os_start_adlib 129 | 130 | jmp .noplaypause 131 | 132 | .loop: 133 | ; Check the keys 134 | 135 | call os_check_for_key 136 | cmp al, 27 137 | je .stop 138 | cmp al, 32 139 | jne .noplaypause 140 | 141 | xor byte [.play], 1 142 | 143 | cmp byte [.play], 0 144 | je .unmute 145 | jne .mute 146 | 147 | .noplaypause: 148 | ; Display the info 149 | 150 | pushad 151 | 152 | mov eax, [.current_pos] 153 | test ax, 1111111111b 154 | jnz .no_update_timer 155 | 156 | mov ebx, [gs:10h] 157 | call draw_progress_bar 158 | 159 | shr eax, 10 ; Waaay faster than dividing by 250 160 | 161 | mov dx, 0C26h 162 | call os_move_cursor 163 | 164 | call os_print_int 165 | 166 | mov al, 73h ; Print an "s" 167 | call os_putchar 168 | 169 | mov al, 2Fh ; "/" 170 | call os_putchar 171 | 172 | mov ax, [.song_length] 173 | call os_print_int 174 | 175 | mov si, .end_time_msg 176 | call os_print_string 177 | 178 | .no_update_timer: 179 | popad 180 | 181 | ; DRO parsing 182 | mov eax, [.target_pos] 183 | cmp [.current_pos], eax 184 | jl .loop 185 | 186 | mov ax, [.position_segment] 187 | cmp ax, [.length_segment] 188 | jne .no_reset 189 | 190 | mov ax, [.position_offset] 191 | cmp ax, [.length_offset] 192 | je .dro_decode 193 | 194 | .no_reset: 195 | push es 196 | mov ax, [.position_segment] 197 | mov bx, gs 198 | add ax, bx 199 | mov es, ax 200 | 201 | mov si, [.position_offset] 202 | mov ax, [es:si] 203 | pop es 204 | 205 | add word [.position_offset], 2 206 | jnc .no_segment_inc 207 | 208 | add word [.position_segment], 1000h 209 | 210 | .no_segment_inc: 211 | xchg ah, al 212 | 213 | cmp ah, [.short_delay] 214 | je .do_short 215 | 216 | cmp ah, [.long_delay] 217 | je .do_long 218 | 219 | movzx bx, ah ; Decode the command 220 | cmp bx, [.codemap] 221 | jg .loop 222 | 223 | mov ah, [gs:1Ah + bx] 224 | call os_adlib_regwrite 225 | 226 | jmp .loop 227 | 228 | .unmute: 229 | call os_adlib_unmute 230 | jmp .noplaypause 231 | 232 | .mute: 233 | call os_adlib_mute 234 | jmp .noplaypause 235 | 236 | .do_short: 237 | pusha 238 | inc al 239 | clr ebx 240 | mov bl, al 241 | add [.target_pos], ebx 242 | popa 243 | jmp .loop 244 | 245 | .do_long: 246 | pusha 247 | inc al 248 | clr ebx 249 | mov bh, al 250 | add [.target_pos], ebx 251 | popa 252 | jmp .loop 253 | 254 | .wait_stop: 255 | popa 256 | 257 | .stop: 258 | call os_stop_adlib 259 | 260 | jmp start 261 | 262 | .clear_adlib: 263 | clr ax 264 | 265 | .exit_loop: 266 | call os_adlib_regwrite 267 | inc ah 268 | jnz .exit_loop 269 | 270 | ret 271 | 272 | .int_handler: 273 | cmp byte [.play], 1 274 | je .no_dec_timer 275 | 276 | add dword [.current_pos], 4 277 | 278 | .no_dec_timer: 279 | retf 280 | 281 | .short_delay db 0 282 | .long_delay db 0 283 | .position_offset dw 0 284 | .position_segment dw 0 285 | .length_offset dw 0 286 | .length_segment dw 0 287 | 288 | .current_pos dd 0 289 | .target_pos dd 0 290 | .song_length dw 0 291 | 292 | .codemap dw 0 293 | .play db 0 294 | 295 | .millilength_msg db 'Song length (in milliseconds): ', 0 296 | .position_msg db 'Current position (milliseconds): ', 0 297 | .playmsg1 db 'Now playing:', 0 298 | .playmsg2 db 'Current position:', 0 299 | .end_time_msg db 's ', 0 300 | -------------------------------------------------------------------------------- /programs/player/libs.asm: -------------------------------------------------------------------------------- 1 | create_player_box: ; SI = top line, BX = center line 2 | clr ax 3 | clr cx 4 | clr dx 5 | call os_temp_box 6 | 7 | mov ax, 0920h 8 | mov bx, 87h 9 | mov cx, 40 10 | int 10h 11 | ret 12 | 13 | draw_progress_bar: ; EAX = current position, EBX = total 14 | pushad 15 | mov16 dx, 20, 14 16 | call os_move_cursor 17 | 18 | clr edx 19 | mov ecx, 80 20 | mul ecx 21 | div ebx 22 | 23 | cmp ax, [.lastval] 24 | jge .no_redraw 25 | 26 | pusha 27 | mov ax, 0920h 28 | mov bx, 87h 29 | mov cx, 40 30 | int 10h 31 | popa 32 | 33 | .no_redraw: 34 | mov [.lastval], ax 35 | push ax 36 | 37 | shr ax, 1 38 | 39 | test ax, ax 40 | jz .nodraw 41 | 42 | mov cx, ax 43 | 44 | .loop: 45 | mov ax, 0EDBh 46 | clr bx 47 | int 10h 48 | 49 | loop .loop 50 | 51 | .nodraw: 52 | pop ax 53 | test ax, 1 54 | jz .exit 55 | 56 | mov ax, 0EDDh 57 | clr bx 58 | int 10h 59 | 60 | .exit: 61 | popad 62 | ret 63 | 64 | .lastval dw 0 65 | -------------------------------------------------------------------------------- /programs/player/monommf.asm: -------------------------------------------------------------------------------- 1 | ; ------------------------------------------------------------------ 2 | ; MichalOS Music Player - mono MMF decoder 3 | ; ------------------------------------------------------------------ 4 | 5 | start_mono_mmf: 6 | push bx 7 | 8 | mov ax, bx 9 | mov cx, buffer 10 | call os_load_file 11 | 12 | sub bx, 3 13 | mov [.filesize], bx 14 | 15 | mov cx, [buffer] 16 | call os_set_timer_speed 17 | 18 | call start.draw_player_background 19 | mov ax, .msgstart 20 | clr bx 21 | clr cx 22 | clr dx 23 | call os_dialog_box 24 | 25 | mov si, start_dro.playmsg1 26 | mov bx, start_dro.playmsg2 27 | call create_player_box 28 | 29 | mov dx, 0A21h 30 | call os_move_cursor 31 | pop si 32 | call os_print_string 33 | 34 | .play_loop: 35 | call .int_handler 36 | call os_check_for_key 37 | 38 | cmp al, 27 39 | je .exit 40 | cmp al, 32 41 | je .pause 42 | 43 | mov ax, 1 44 | call os_pause 45 | 46 | cmp word [.pointer], .track0 47 | jne .play_loop 48 | cmp byte [.delay], 0 49 | jne .play_loop 50 | 51 | .exit: 52 | mov word [.pointer], .track0 ; Reset the values when we press Esc 53 | mov word [.previous], 0 54 | mov word [.counter], 0 55 | mov byte [.paused], 0 56 | 57 | clr cx ; 18.2 Hz 58 | call os_set_timer_speed 59 | ret 60 | 61 | .pause: 62 | xor byte [.paused], 1 63 | jmp .play_loop 64 | 65 | .int_handler: 66 | pusha 67 | cmp byte [.paused], 0 68 | jne .skip_play 69 | 70 | inc byte [.delay] 71 | mov al, [.song_delay] 72 | cmp byte [.delay], al 73 | jl .skip_play 74 | 75 | inc word [.counter] 76 | pusha 77 | mov dx, 0C26h 78 | call os_move_cursor 79 | mov ax, [.counter] 80 | call os_print_int 81 | popa 82 | 83 | movzx eax, word [.pointer] 84 | sub eax, buffer + 3 85 | movzx ebx, word [.filesize] 86 | call draw_progress_bar 87 | 88 | mov byte [.delay], 0 89 | 90 | mov si, [.pointer] 91 | lodsw 92 | mov [.pointer], si 93 | 94 | cmp ax, [.previous] 95 | je .skip_play 96 | 97 | mov [.previous], ax 98 | 99 | test ax, ax 100 | jz .notone 101 | 102 | cmp ax, 1 103 | je .end 104 | 105 | call os_speaker_tone 106 | 107 | .skip_play: 108 | popa 109 | ret 110 | 111 | .notone: 112 | call os_speaker_off 113 | popa 114 | ret 115 | 116 | .end: 117 | call os_speaker_off 118 | mov word [.pointer], .track0 119 | popa 120 | ret 121 | 122 | .previous dw 0 123 | .pointer dw .track0 124 | .filesize dw 0 125 | .counter dw 0 126 | .delay db 0 127 | .paused db 0 128 | .song_delay equ buffer + 2 129 | .track0 equ buffer + 3 130 | .msgstart db 'Press OK to start...', 0 131 | -------------------------------------------------------------------------------- /programs/player/monopian.asm: -------------------------------------------------------------------------------- 1 | piano: 2 | call start.draw_clear_background 3 | 4 | mov16 dx, 1, 9 5 | call os_move_cursor 6 | mov si, start.piano0 7 | call os_print_string 8 | call os_hide_cursor 9 | 10 | .pianoloop: 11 | mov16 dx, 1, 17 12 | call os_move_cursor 13 | 14 | mov si, start.octavemsg 15 | call os_print_string 16 | 17 | mov al, [start.octave] 18 | call os_print_1hex 19 | 20 | call os_wait_for_key 21 | 22 | cmp ah, 72 23 | je .octave_up 24 | 25 | cmp ah, 80 26 | je .octave_down 27 | 28 | cmp al, ' ' 29 | je .execstop 30 | 31 | cmp al, 27 32 | je start 33 | 34 | mov si, start.keydata1 35 | mov di, start.notedata1 36 | 37 | .decodeloop: 38 | mov bh, [si] 39 | inc si 40 | add di, 2 41 | 42 | test bh, bh 43 | jz .pianoloop 44 | 45 | cmp ah, bh 46 | jne .decodeloop 47 | 48 | sub di, 2 ; We've overflowed a bit 49 | mov ax, [di] 50 | 51 | mov bl, [start.octave] 52 | mov cl, 6 53 | sub cl, bl 54 | shr ax, cl 55 | 56 | call os_speaker_tone 57 | 58 | jmp .pianoloop 59 | 60 | .octave_down: 61 | cmp byte [start.octave], 1 62 | je .pianoloop 63 | dec byte [start.octave] 64 | jmp .pianoloop 65 | 66 | .octave_up: 67 | cmp byte [start.octave], 6 68 | je .pianoloop 69 | inc byte [start.octave] 70 | jmp .pianoloop 71 | 72 | .execstop: 73 | call os_speaker_off 74 | jmp .pianoloop 75 | 76 | -------------------------------------------------------------------------------- /programs/player/polymmf.asm: -------------------------------------------------------------------------------- 1 | ; ------------------------------------------------------------------ 2 | ; MichalOS Music Player - duo MMF decoder 3 | ; ------------------------------------------------------------------ 4 | 5 | start_poly_mmf: 6 | mov [.filesize], bx 7 | 8 | call start.draw_player_background 9 | 10 | clr dx 11 | mov ax, [buffer] 12 | test ax, ax 13 | jnz .no_18_2 14 | 15 | inc dx 16 | 17 | .no_18_2: 18 | mov bx, 36 19 | div bx 20 | 21 | mov si, .int_handler 22 | mov cx, ax 23 | mov bl, 2 24 | call os_start_adlib 25 | 26 | mov cx, 7 ; We will only read 7 registers here 27 | mov si, polypiano.adlibsquare 28 | 29 | .preparechannels: 30 | lodsw 31 | 32 | push cx 33 | clr bx 34 | mov cx, 9 35 | 36 | .channelloop: 37 | push ax 38 | add ah, [polypiano.adliboffsets + bx] 39 | inc bx 40 | 41 | call os_adlib_regwrite 42 | pop ax 43 | 44 | loop .channelloop 45 | 46 | pop cx 47 | loop .preparechannels 48 | 49 | lodsw 50 | 51 | .feedbackloop: ; Write the 8th register 52 | call os_adlib_regwrite 53 | inc ah 54 | cmp ah, 0C9h 55 | jne .feedbackloop 56 | 57 | mov si, .playmsg 58 | mov bx, start_dro.playmsg2 59 | call create_player_box 60 | 61 | mov al, [.song_delay] 62 | mov [.sdelay], al 63 | 64 | mov al, [.song_delay_2] 65 | mov [.sdelay_2], al 66 | 67 | mov word [.pointer], .track0 ; Reset the values when we press Esc 68 | mov byte [.delay], 1 69 | 70 | mov word [.pointer_2], .track0_2 71 | mov byte [.delay_2], 1 72 | 73 | mov word [.counter], 0 74 | mov byte [.paused], 0 75 | mov byte [.song_end], 0 76 | 77 | mov byte [.playreq], 0 78 | 79 | .play_loop: 80 | cmp byte [.playreq], 1 81 | jne .no_play 82 | 83 | mov byte [.playreq], 0 84 | 85 | cmp byte [.paused], 0 86 | jne .no_play 87 | 88 | clr cl ; Channel 89 | mov di, .pointer 90 | call .parse_channel 91 | 92 | inc cl 93 | mov di, .pointer_2 94 | call .parse_channel 95 | 96 | .no_play: 97 | mov dx, 0C26h 98 | call os_move_cursor 99 | 100 | mov ax, [.counter] 101 | call os_print_int 102 | 103 | movzx eax, word [.pointer_2] 104 | sub eax, buffer2 + 3 105 | movzx ebx, word [.filesize] 106 | call draw_progress_bar 107 | 108 | call os_check_for_key 109 | cmp al, 27 110 | je .exit 111 | cmp al, 32 112 | je .pause 113 | 114 | hlt 115 | 116 | cmp byte [.song_end], 1 117 | jne .play_loop 118 | 119 | .parse_channel: 120 | dec byte [di + 3] ; Delay value 121 | jnz .no_parse_channel 122 | 123 | mov al, [di + 2] ; Global song delay value 124 | mov [di + 3], al 125 | 126 | test cl, cl 127 | jnz .no_inc_ctr 128 | 129 | inc word [.counter] 130 | 131 | .no_inc_ctr: 132 | mov si, [di] ; Current pointer 133 | lodsw 134 | mov [di], si 135 | 136 | test ax, ax 137 | jz .notone 138 | 139 | cmp ax, 1 140 | je .mark_end 141 | 142 | call os_adlib_calcfreq 143 | 144 | .no_parse_channel: 145 | ret 146 | 147 | .notone: 148 | call os_adlib_noteoff 149 | ret 150 | 151 | .mark_end: 152 | mov byte [.song_end], 1 153 | ret 154 | 155 | .exit: 156 | call os_stop_adlib 157 | ret 158 | 159 | .pause: 160 | xor byte [.paused], 1 161 | 162 | call os_adlib_mute 163 | 164 | cmp byte [.paused], 1 165 | je .play_loop 166 | 167 | call os_adlib_unmute 168 | 169 | jmp .play_loop 170 | 171 | .int_handler: 172 | mov byte [.playreq], 1 173 | retf 174 | 175 | .pointer dw .track0 176 | .sdelay db 0 177 | .delay db 1 178 | 179 | .pointer_2 dw .track0_2 180 | .sdelay_2 db 0 181 | .delay_2 db 1 182 | 183 | .counter dw 0 184 | .paused db 0 185 | .song_end db 0 186 | 187 | .playreq db 0 188 | .filesize dw 0 189 | 190 | .playmsg db 'Now playing: ' 191 | .playmsg2 times 32 db 0 192 | 193 | .playmsgcct db '/', 0 194 | 195 | .song_delay equ buffer + 2 196 | .song_delay_2 equ buffer2 + 2 197 | .track0 equ buffer + 3 198 | .track0_2 equ buffer2 + 3 199 | -------------------------------------------------------------------------------- /programs/player/polypian.asm: -------------------------------------------------------------------------------- 1 | polypiano: 2 | call start.draw_background 3 | 4 | mov ax, buffer 5 | mov bx, .channelmsg 6 | call os_input_dialog 7 | 8 | mov si, buffer 9 | call os_string_to_int 10 | 11 | cmp al, 9 12 | jg .error 13 | 14 | cmp al, 1 15 | jl .error 16 | 17 | .init_adlib: 18 | mov byte [.currentchannel], 0 19 | mov [.numofchannels], al 20 | 21 | clr si 22 | mov cx, 1820 23 | mov bl, al 24 | call os_start_adlib 25 | 26 | mov cx, 7 ; We will only read 7 registers here 27 | mov si, .adlibsquare 28 | 29 | .preparechannels: 30 | lodsw 31 | 32 | push cx 33 | clr bx 34 | mov cx, 9 35 | 36 | .channelloop: 37 | push ax 38 | add ah, [.adliboffsets + bx] 39 | inc bx 40 | 41 | call os_adlib_regwrite 42 | pop ax 43 | 44 | loop .channelloop 45 | 46 | pop cx 47 | loop .preparechannels 48 | 49 | lodsw 50 | 51 | .feedbackloop: ; Write the 8th register 52 | call os_adlib_regwrite 53 | inc ah 54 | cmp ah, 0C9h 55 | jne .feedbackloop 56 | 57 | call start.draw_clear_background 58 | 59 | mov16 dx, 1, 9 60 | call os_move_cursor 61 | mov si, start.piano0 62 | call os_print_string 63 | call os_hide_cursor 64 | 65 | .pianoloop: 66 | mov16 dx, 1, 17 67 | call os_move_cursor 68 | 69 | mov si, start.octavemsg 70 | call os_print_string 71 | 72 | mov al, [start.octave] 73 | call os_print_1hex 74 | 75 | call os_wait_for_key 76 | 77 | cmp ah, 72 78 | je .octave_up 79 | 80 | cmp ah, 80 81 | je .octave_down 82 | 83 | cmp al, ' ' 84 | je .execstop 85 | 86 | cmp al, 27 87 | je .end 88 | 89 | mov si, start.keydata1 90 | mov di, start.notedata1 91 | 92 | .decodeloop: 93 | mov bh, [si] 94 | inc si 95 | add di, 2 96 | 97 | test bh, bh 98 | jz .pianoloop 99 | 100 | cmp ah, bh 101 | jne .decodeloop 102 | 103 | sub di, 2 ; We've overflowed a bit 104 | mov ax, [di] 105 | 106 | mov bl, [start.octave] 107 | mov cl, 6 108 | sub cl, bl 109 | shr ax, cl 110 | 111 | mov cl, [.currentchannel] 112 | call os_adlib_calcfreq 113 | 114 | inc cl 115 | cmp cl, [.numofchannels] 116 | jne .no_reset_counter 117 | 118 | clr cl 119 | 120 | .no_reset_counter: 121 | mov [.currentchannel], cl 122 | 123 | jmp .pianoloop 124 | 125 | .octave_down: 126 | cmp byte [start.octave], 1 127 | jle .pianoloop 128 | dec byte [start.octave] 129 | jmp .pianoloop 130 | 131 | .octave_up: 132 | cmp byte [start.octave], 6 133 | jge .pianoloop 134 | inc byte [start.octave] 135 | jmp .pianoloop 136 | 137 | .execstop: 138 | clr cl 139 | 140 | .stoploop: 141 | call os_adlib_noteoff 142 | 143 | inc cl 144 | cmp cl, 9 145 | jne .stoploop 146 | 147 | jmp .pianoloop 148 | 149 | .end: 150 | call os_stop_adlib 151 | jmp start 152 | 153 | .error: 154 | mov ax, .channelerr 155 | mov bx, .channelerr2 156 | clr cx 157 | clr dx 158 | call os_dialog_box 159 | 160 | mov al, 9 161 | jmp .init_adlib 162 | 163 | .currentchannel db 0 164 | .numofchannels db 0 165 | 166 | .adlibsquare db 02h, 20h 167 | db 01h, 23h 168 | db 19h, 40h 169 | db 0F0h,60h 170 | db 0F0h,63h 171 | db 0F0h,80h 172 | db 0FFh,83h 173 | db 0Eh, 0C0h 174 | 175 | .adliboffsets db 0, 1, 2, 8, 9, 10, 16, 17, 18 176 | 177 | .channelmsg db 'How many notes at once? (1-9)', 0 178 | .channelerr db 'Number not in range.', 0 179 | .channelerr2 db 'Defaulted to 9 notes.', 0 180 | -------------------------------------------------------------------------------- /programs/rdtsc.asm: -------------------------------------------------------------------------------- 1 | ; ------------------------------------------------------------------ 2 | ; About MichalOS 3 | ; ------------------------------------------------------------------ 4 | 5 | %INCLUDE "include/program.inc" 6 | 7 | start: 8 | mov ax, .msg1 9 | mov bx, .msg2 10 | clr cx 11 | clr dx 12 | call os_dialog_box 13 | 14 | call os_clear_screen 15 | 16 | mov si, .handler 17 | mov cx, 11932 18 | call os_attach_app_timer 19 | 20 | .loop: 21 | hlt 22 | 23 | cmp word [.timer], 100 24 | jne .loop 25 | 26 | mov word [.timer], 0 27 | 28 | mov edx, [.new_edx] 29 | sub edx, [.old_edx] 30 | 31 | mov eax, [.new_eax] 32 | sub eax, [.old_eax] 33 | 34 | jnc .no_carry 35 | 36 | dec edx 37 | 38 | .no_carry: 39 | mov ebx, 10 40 | div ebx 41 | 42 | call os_print_32int 43 | call os_print_newline 44 | 45 | call os_check_for_key 46 | cmp al, 27 47 | jne .loop 48 | 49 | call os_return_app_timer 50 | 51 | ret 52 | 53 | .handler: 54 | mov eax, [.new_eax] 55 | mov [.old_eax], eax 56 | 57 | mov eax, [.new_edx] 58 | mov [.old_edx], eax 59 | 60 | rdtsc 61 | 62 | mov [.new_eax], eax 63 | mov [.new_edx], edx 64 | 65 | inc word [.timer] 66 | retf 67 | 68 | .timer dw 0 69 | .old_eax dd 0 70 | .old_edx dd 0 71 | .new_eax dd 0 72 | .new_edx dd 0 73 | 74 | .msg1 db "This app measures the CPU clock speed", 0 75 | .msg2 db "(of core #0) in kHz. To exit, press Esc.", 0 76 | 77 | ; ------------------------------------------------------------------ 78 | -------------------------------------------------------------------------------- /programs/rtctest.asm: -------------------------------------------------------------------------------- 1 | BITS 16 2 | ORG 100h 3 | %INCLUDE "include/program.inc" 4 | 5 | start: 6 | call .draw_background 7 | 8 | mov ax, .exit_msg 9 | clr bx 10 | clr cx 11 | clr dx 12 | call os_dialog_box 13 | call os_clear_screen 14 | .test: 15 | call os_check_for_key 16 | cmp al, "Q" 17 | je .exit 18 | 19 | clr cl 20 | 21 | .loop: 22 | mov al, cl 23 | out 70h, al 24 | 25 | in al, 71h 26 | 27 | add al, 13h 28 | daa 29 | 30 | call os_print_2hex 31 | call os_print_space 32 | inc cl 33 | cmp cl, 10 34 | jne .loop 35 | 36 | call os_print_newline 37 | jmp .test 38 | 39 | .draw_background: 40 | mov ax, .title 41 | mov bx, .blank 42 | mov cx, 256 43 | call os_draw_background 44 | ret 45 | 46 | .exit: 47 | ret 48 | 49 | .title db 'MichalOS RTC Diagnostic Tool', 0 50 | .blank db 0 51 | 52 | .space db ' ', 0 53 | .exit_msg db 'Press Shift+Q to quit.', 0 54 | -------------------------------------------------------------------------------- /programs/sector.asm: -------------------------------------------------------------------------------- 1 | 2 | %INCLUDE "include/program.inc" 3 | 4 | start: 5 | call .draw_background 6 | mov16 dx, 5, 4 7 | call os_move_cursor 8 | 9 | clr eax 10 | 11 | .hex2_title_loop: 12 | call os_print_2hex 13 | call os_print_space 14 | 15 | inc al 16 | cmp al, 10h 17 | jne .hex2_title_loop 18 | 19 | clr al 20 | call os_print_space 21 | 22 | .hex_title_loop: 23 | call os_print_1hex 24 | 25 | inc al 26 | cmp al, 10h 27 | jne .hex_title_loop 28 | 29 | mov cx, 512 30 | mov di, 4000h 31 | mov al, 88 32 | rep stosb 33 | 34 | .draw_loop: 35 | call .bardraw 36 | 37 | mov16 dx, 5, 6 38 | call os_move_cursor 39 | mov si, 4000h 40 | cmp byte [.halfnum], 0 41 | je .zerohalf 42 | add si, 256 43 | 44 | .zerohalf: 45 | pusha 46 | call .datadraw 47 | popa 48 | mov16 dx, 54, 6 49 | call os_move_cursor 50 | call .asciidraw 51 | 52 | mov16 dx, 1, 2 ; Print the input label 53 | call os_move_cursor 54 | mov al, '>' 55 | call os_putchar 56 | 57 | mov ax, 0920h ; Clear the screen for the next input 58 | clr bh 59 | mov bl, [CONFIG_DESKTOP_BG_COLOR] 60 | mov cx, 60 61 | int 10h 62 | 63 | call .sectordraw 64 | 65 | mov16 dx, 2, 2 ; Print the input label 66 | call os_move_cursor 67 | call os_show_cursor ; Get a command from the user 68 | mov ax, .input_buffer 69 | call os_input_string 70 | 71 | mov si, .input_buffer ; Decode the command 72 | call os_string_uppercase 73 | lodsb 74 | cmp al, 'Q' ; 'Q' typed? 75 | je .exit 76 | cmp al, 'S' 77 | je .sectorselect 78 | cmp al, 'H' 79 | je .selecthalf 80 | jmp .draw_loop 81 | 82 | .sectordraw: 83 | mov16 dx, 40, 2 84 | call os_move_cursor 85 | mov ax, [.sectornum] 86 | call os_print_int 87 | ret 88 | 89 | .asciidraw: 90 | lodsb 91 | cmp al, 32 92 | jge .asciichar 93 | mov al, '.' 94 | .asciichar: 95 | call os_putchar 96 | 97 | call os_get_cursor_pos 98 | cmp dl, 70 99 | jl .asciidraw 100 | 101 | mov dl, 54 102 | inc dh 103 | call os_move_cursor 104 | 105 | cmp dh, 22 106 | jl .asciidraw 107 | ret 108 | 109 | .datadraw: 110 | lodsb 111 | call os_print_2hex 112 | 113 | push si 114 | mov si, .space 115 | call os_print_string 116 | pop si 117 | 118 | call os_get_cursor_pos 119 | cmp dl, 53 120 | jl .datadraw 121 | 122 | mov dl, 5 123 | inc dh 124 | call os_move_cursor 125 | 126 | cmp dh, 22 127 | jl .datadraw 128 | ret 129 | 130 | 131 | 132 | .selecthalf: 133 | lodsb 134 | cmp al, '0' 135 | je .selectfirsthalf 136 | mov byte [.halfnum], 1 137 | jmp .draw_loop 138 | .selectfirsthalf: 139 | mov byte [.halfnum], 0 140 | jmp .draw_loop 141 | 142 | .sectorselect: 143 | call os_string_to_int ; Decode the entered number 144 | mov [.sectornum], ax 145 | 146 | mov si, 4000h 147 | call os_get_boot_disk 148 | call os_disk_read_sector 149 | jc .error 150 | jmp .draw_loop 151 | 152 | .error: 153 | mov ax, .msg1 154 | mov bx, .msg2 155 | mov cx, .msg2 156 | clr dx 157 | call os_dialog_box 158 | call .draw_background 159 | jmp .draw_loop 160 | 161 | .exit: 162 | call os_clear_screen 163 | ret 164 | 165 | .draw_background: 166 | mov ax, .title_msg 167 | mov bx, .footer_msg 168 | mov cx, [CONFIG_DESKTOP_BG_COLOR] 169 | call os_draw_background 170 | ret 171 | 172 | .bardraw: 173 | mov16 dx, 1, 6 174 | clr bl 175 | 176 | .bardrawloop: 177 | call os_move_cursor 178 | 179 | mov al, [.halfnum] 180 | call os_print_1hex 181 | 182 | mov al, bl 183 | call os_print_2hex 184 | 185 | inc dh 186 | add bl, 10h 187 | jnz .bardrawloop 188 | ret 189 | 190 | 191 | 192 | .title_msg db 'MichalOS Disk Inspector', 0 193 | .footer_msg db 'q = Quit, sXYZ = Load sector XYZ, h0/h1 = Display 1st/2nd half', 0 194 | 195 | .halfnum db 0 196 | .sectornum dw 0 197 | 198 | .space db ' ', 0 199 | 200 | .msg1 db 'Disk error!' ; Termination not necessary here 201 | .msg2 db 0 202 | 203 | .input_buffer: ; Has to be at the end! 204 | ; ------------------------------------------------------------------ 205 | 206 | -------------------------------------------------------------------------------- /programs/serial.asm: -------------------------------------------------------------------------------- 1 | ; ------------------------------------------------------------------ 2 | ; MichalOS Serial Tester 3 | ; ------------------------------------------------------------------ 4 | 5 | %INCLUDE "include/program.inc" 6 | 7 | start: 8 | call .draw_background 9 | clr ax ; Set up the serial port 10 | call os_serial_port_enable 11 | 12 | call os_get_via_serial ; Is the other computer waiting for connection? 13 | cmp al, 123 14 | je .connection_request 15 | 16 | mov si, .wait_msg1 17 | mov ax, .wait_msg2 18 | mov bx, .blank 19 | mov cx, .blank 20 | mov dx, .blank 21 | call os_temp_box 22 | 23 | .loop: 24 | mov al, 123 25 | call os_send_via_serial 26 | 27 | call os_get_via_serial 28 | cmp al, 125 29 | je .request_confirm 30 | 31 | call os_check_for_key 32 | cmp al, 27 33 | je .exit 34 | 35 | jmp .loop 36 | 37 | .connection_request: 38 | mov al, 125 39 | call os_send_via_serial 40 | 41 | .request_confirm: 42 | mov ax, .connection_msg 43 | clr bx 44 | clr cx 45 | clr dx 46 | call os_dialog_box 47 | 48 | jmp .exit 49 | 50 | 51 | .draw_background: 52 | mov ax, .title_msg 53 | mov bx, .blank 54 | mov cx, 256 55 | call os_draw_background 56 | ret 57 | 58 | .exit: 59 | clr al 60 | call os_send_via_serial 61 | ret 62 | 63 | .title_msg db 'MichalOS Serial Tester', 0 64 | .blank db 0 65 | .wait_msg1 db 'Waiting for a response...', 0 66 | .wait_msg2 db 'Press Esc to quit.', 0 67 | .connection_msg db 'Successfully connected.', 0 68 | 69 | ; ------------------------------------------------------------------ 70 | -------------------------------------------------------------------------------- /programs/shapes.asm: -------------------------------------------------------------------------------- 1 | ; ------------------------------------------------------------------ 2 | ; MichalOS Shapes Test 3 | ; ------------------------------------------------------------------ 4 | 5 | %INCLUDE "include/program.inc" 6 | 7 | start: 8 | mov ax, .msg1 9 | mov bx, .msg2 10 | mov cx, .msg3 11 | mov dx, 0 12 | call os_dialog_box 13 | 14 | call os_init_graphics_mode 15 | 16 | mov ax, 0A000h 17 | mov es, ax 18 | 19 | .loop: 20 | clr ax 21 | 22 | mov bx, 15 23 | call os_get_random 24 | mov [.color], cl 25 | 26 | mov bx, 199 27 | call os_get_random 28 | mov di, cx 29 | call os_get_random 30 | mov dx, cx 31 | 32 | mov bx, 319 33 | call os_get_random 34 | mov si, cx 35 | call os_get_random 36 | 37 | mov bl, [.color] 38 | cmp byte [.shape], 0 39 | je .line 40 | cmp byte [.shape], 1 41 | je .cf_rect 42 | cmp byte [.shape], 2 43 | je .circles 44 | cmp byte [.shape], 3 45 | je .no_cf_rect 46 | 47 | call os_clear_graphics 48 | 49 | jmp .get_key 50 | 51 | .no_cf_rect: 52 | clc 53 | call os_draw_rectangle 54 | jmp .get_key 55 | 56 | .line: 57 | call os_draw_line 58 | jmp .get_key 59 | 60 | .cf_rect: 61 | stc 62 | call os_draw_rectangle 63 | jmp .get_key 64 | 65 | .circles: 66 | mov al, bl 67 | mov bx, si 68 | shr bx, 1 69 | call os_draw_circle 70 | 71 | .get_key: 72 | call os_check_for_key 73 | cmp al, 32 74 | jne .no_switch 75 | 76 | inc byte [.shape] 77 | cmp byte [.shape], 5 78 | jne .no_switch 79 | 80 | mov byte [.shape], 0 81 | 82 | .no_switch: 83 | cmp al, 27 84 | jne .loop 85 | ret 86 | 87 | .color db 0 88 | .shape db 0 89 | 90 | .msg1 db "Press Space to cycle lines, fill rects,", 0 91 | .msg2 db "circles, rects & full screen refresh", 0 92 | .msg3 db "Press Esc to exit.", 0 93 | 94 | ; ------------------------------------------------------------------ 95 | -------------------------------------------------------------------------------- /programs/stars.asm: -------------------------------------------------------------------------------- 1 | ; ------------------------------------------------------------------ 2 | ; MichalOS Starfield demo 3 | ; Backported from MichalOS 2.2 to work on standard VGA 4 | ; ------------------------------------------------------------------ 5 | 6 | %INCLUDE "include/program.inc" 7 | %DEFINE STARCOUNT 512 8 | %DEFINE MAX_DEPTH 360 9 | 10 | start: 11 | ; Set up speed limiting interrupt 12 | 13 | mov si, .int_handler 14 | mov cx, 19886 15 | call os_attach_app_timer 16 | 17 | ; Generate the stars 18 | 19 | mov cx, STARCOUNT 20 | mov di, starlist 21 | 22 | .gen_loop: 23 | call .generate_new_star 24 | add di, 4 25 | loop .gen_loop 26 | 27 | ; Initialize graphics mode 28 | 29 | call os_init_graphics_mode 30 | 31 | .loop: 32 | cmp byte [.drawframe], 1 33 | je .draw 34 | 35 | hlt 36 | jmp .loop 37 | 38 | .draw: 39 | mov byte [.drawframe], 0 40 | 41 | push gs 42 | pop es 43 | 44 | clr di 45 | clr eax 46 | mov cx, 64000 / 4 47 | rep stosd 48 | 49 | ; Process the stars! 50 | 51 | mov cx, STARCOUNT 52 | mov si, starlist 53 | 54 | .drawloop: 55 | ; Draw the star 56 | 57 | push cx 58 | 59 | ; Calculate X postition 60 | 61 | movsx eax, byte [si + 0] 62 | mov ebx, 1280 63 | imul ebx 64 | 65 | movsx ebx, word [.xoffset] 66 | sal ebx, 8 67 | sub eax, ebx 68 | 69 | movzx ebx, word [si + 2] 70 | clr edx 71 | bt eax, 31 72 | jnc .no_negative_x 73 | 74 | dec edx 75 | 76 | .no_negative_x: 77 | idiv ebx 78 | 79 | ; Is the star out of range? 80 | 81 | add ax, 160 82 | js .no_render 83 | mov cx, ax 84 | 85 | cmp cx, 320 86 | jge .no_render 87 | 88 | ; Calculate Y postition 89 | 90 | movsx eax, byte [si + 1] 91 | mov ebx, 1280 92 | imul ebx 93 | 94 | movsx ebx, word [.yoffset] 95 | sal ebx, 8 96 | sub eax, ebx 97 | 98 | movzx ebx, word [si + 2] 99 | clr edx 100 | bt eax, 31 101 | jnc .no_negative_y 102 | 103 | dec edx 104 | 105 | .no_negative_y: 106 | movzx ebx, word [si + 2] 107 | idiv ebx 108 | 109 | ; Is the star out of range? 110 | 111 | add ax, 100 112 | js .no_render 113 | mov dx, ax 114 | 115 | cmp dx, 200 116 | jge .no_render 117 | 118 | ; Calculate the pointer 119 | 120 | mov ax, dx 121 | mov bx, 320 122 | mul bx 123 | add ax, cx 124 | mov di, ax 125 | 126 | ; Calculate the color 127 | 128 | clr dx 129 | mov ax, [si + 2] 130 | mov bx, MAX_DEPTH / 15 131 | 132 | div bx 133 | 134 | mov bl, 15 135 | sub bl, al 136 | 137 | add bl, 16 138 | mov [gs:di], bl 139 | 140 | .no_render: 141 | pop cx 142 | 143 | ; Move the star closer to the camera 144 | 145 | dec word [si + 2] 146 | jnz .no_reset 147 | 148 | mov word [si + 2], MAX_DEPTH 149 | 150 | .no_reset: 151 | add si, 4 152 | dec cx 153 | jnz .drawloop 154 | 155 | ; Copy the framebuffer 156 | 157 | push ds 158 | 159 | push gs 160 | pop ds 161 | 162 | push 0xA000 163 | pop es 164 | 165 | clr si 166 | clr di 167 | mov cx, 64000 / 4 168 | rep movsd 169 | 170 | pop ds 171 | 172 | ; Check for user input 173 | 174 | call os_check_for_key 175 | 176 | cmp ah, 72 177 | je .move_up 178 | 179 | cmp ah, 75 180 | je .move_left 181 | 182 | cmp ah, 77 183 | je .move_right 184 | 185 | cmp ah, 80 186 | je .move_down 187 | 188 | cmp al, 27 189 | jne .loop 190 | ret 191 | 192 | .move_up: 193 | dec word [.yoffset] 194 | jmp .loop 195 | 196 | .move_down: 197 | inc word [.yoffset] 198 | jmp .loop 199 | 200 | .move_left: 201 | dec word [.xoffset] 202 | jmp .loop 203 | 204 | .move_right: 205 | inc word [.xoffset] 206 | jmp .loop 207 | 208 | .xoffset dw 0 209 | .yoffset dw 0 210 | 211 | ; DI = address of star entry (4 bytes) 212 | .generate_new_star: 213 | pusha 214 | 215 | ; Generate new X/Y coordinates 216 | clr ax 217 | mov bx, 99 218 | call os_get_random 219 | 220 | mov dx, cx 221 | call os_get_random 222 | 223 | mov al, cl 224 | sub al, 50 225 | stosb 226 | 227 | mov al, dl 228 | sub al, 50 229 | stosb 230 | 231 | mov ax, 1 232 | mov bx, MAX_DEPTH 233 | 234 | call os_get_random 235 | 236 | mov [di], cx 237 | 238 | popa 239 | ret 240 | 241 | .int_handler: 242 | mov byte [.drawframe], 1 243 | retf 244 | 245 | .drawframe db 1 246 | 247 | starlist: 248 | 249 | ; ------------------------------------------------------------------ 250 | -------------------------------------------------------------------------------- /programs/test.asm: -------------------------------------------------------------------------------- 1 | ; ------------------------------------------------------------------ 2 | ; MichalOS VESA mode checker 3 | ; ------------------------------------------------------------------ 4 | 5 | %INCLUDE "include/program.inc" 6 | 7 | %define one_button 0 8 | %define two_buttons 1 9 | %define empty_string 0 10 | %define exit_application ret 11 | %define string db 12 | %define endstring , 0 13 | %define default_background 256 14 | 15 | %macro dialog_box 3-4 one_button 16 | mov ax, %1 17 | mov bx, %2 18 | mov cx, %3 19 | mov dx, %4 20 | call os_dialog_box 21 | %endmacro 22 | 23 | %macro draw_background 3 24 | mov ax, %1 25 | mov bx, %2 26 | mov cx, %3 27 | call os_draw_background 28 | %endmacro 29 | 30 | 31 | start: 32 | draw_background title, empty, default_background 33 | dialog_box helloworldmsg, empty, empty 34 | exit_application 35 | 36 | title string "MichalOS Test App" endstring 37 | empty string empty_string 38 | helloworldmsg string "Hello, World!" endstring 39 | -------------------------------------------------------------------------------- /programs/viewer.asm: -------------------------------------------------------------------------------- 1 | ; ------------------------------------------------------------------ 2 | ; MichalOS Image Viewer 3 | ; ------------------------------------------------------------------ 4 | 5 | %INCLUDE "include/program.inc" 6 | 7 | start: 8 | cmp byte [0E0h], 0 ; Were we passed a filename? 9 | je .no_param_passed 10 | 11 | cmp byte [already_displayed], 1 12 | je .exit 13 | 14 | mov byte [already_displayed], 1 15 | 16 | mov ax, 0E0h 17 | jmp .check_file 18 | 19 | .no_param_passed: 20 | call .draw_background 21 | 22 | mov bx, extension_number 23 | call os_file_selector_filtered ; Get filename 24 | 25 | jc .exit 26 | 27 | .check_file: 28 | call os_file_exists 29 | jc .load_error 30 | 31 | mov bx, ax ; Save filename for now 32 | 33 | mov di, ax 34 | 35 | call os_string_length 36 | add di, ax ; DI now points to last char in filename 37 | 38 | dec di 39 | dec di 40 | dec di ; ...and now to first char of extension! 41 | 42 | pusha 43 | 44 | mov si, pcx_extension 45 | mov cx, 3 46 | rep cmpsb ; Does the extension contain 'PCX'? 47 | je .valid_pcx_extension ; Skip ahead if so 48 | 49 | popa 50 | ; Otherwise show error dialog 51 | clr dx ; One button for dialog box 52 | mov ax, err_string 53 | mov bx, err_string2 54 | clr cx 55 | call os_dialog_box 56 | 57 | jmp start ; And retry 58 | 59 | .valid_pcx_extension: 60 | popa 61 | 62 | push ds 63 | push es 64 | mov ax, gs 65 | mov es, ax 66 | mov ax, bx 67 | clr cx ; Load PCX at GS:0000h 68 | call os_load_file 69 | 70 | call os_init_graphics_mode 71 | 72 | mov ax, 0A000h ; ES = video memory 73 | mov es, ax 74 | 75 | mov ax, gs ; DS = source file 76 | mov ds, ax 77 | 78 | mov si, 80h ; Move source to start of image data (First 80h bytes is header) 79 | clr di ; Start our loop at top of video RAM 80 | 81 | .decode: 82 | mov cx, 1 83 | lodsb 84 | cmp al, 192 ; Single pixel or string? 85 | jb .single 86 | and al, 63 ; String, so 'mod 64' it 87 | mov cl, al ; Result in CL for following 'rep' 88 | lodsb ; Get byte to put on screen 89 | .single: 90 | rep stosb ; And show it (or all of them) 91 | cmp di, 64001 92 | jb .decode 93 | 94 | 95 | mov dx, 3c8h ; Palette index register 96 | clr al ; Start at colour 0 97 | out dx, al ; Tell VGA controller that... 98 | inc dx ; ...3c9h = palette data register 99 | 100 | mov cx, 768 ; 256 colours, 3 bytes each 101 | .setpal: 102 | lodsb ; Grab the next byte. 103 | shr al, 2 ; Palettes divided by 4, so undo 104 | out dx, al ; Send to VGA controller 105 | loop .setpal 106 | 107 | pop es 108 | pop ds 109 | 110 | call os_wait_for_key 111 | call os_init_text_mode 112 | jmp start 113 | 114 | .draw_background: 115 | mov ax, title_msg ; Set up screen 116 | mov bx, footer_msg 117 | mov cx, 256 118 | call os_draw_background 119 | ret 120 | 121 | .exit: 122 | mov byte [0E0h], 0 123 | ret 124 | 125 | .load_error: 126 | mov ax, err_msg 127 | clr bx 128 | clr cx 129 | clr dx 130 | call os_dialog_box 131 | jmp .exit 132 | 133 | 134 | extension_number db 1 135 | pcx_extension db 'PCX', 0 136 | 137 | err_string db 'Invalid file type!', 0 138 | err_string2 db '320x200x8bpp PCX only!', 0 139 | 140 | err_msg db 'File not found!', 0 141 | 142 | title_msg db 'MichalOS Image Viewer', 0 143 | footer_msg db '', 0 144 | 145 | already_displayed db 0 146 | 147 | ; ------------------------------------------------------------------ 148 | 149 | --------------------------------------------------------------------------------