diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..a8fc851 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2016 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Makefile b/Makefile index a8cce14..f2f3742 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,16 @@ +UNAME := $(shell uname) +ifeq ($(UNAME), Darwin) + STAT := gstat +else + STAT := stat +endif + all: tetros.img tetros.img: tetros.asm Makefile nasm -d DEBUG -f bin tetros.asm -o tetros.img - @echo "size is" `stat -c "%s" tetros.img` - @if [ `stat -c "%s" tetros.img` -gt 446 ]; then \ + @echo "size is" `$(STAT) -c "%s" tetros.img` + @if [ `$(STAT) -c "%s" tetros.img` -gt 446 ]; then \ bash -c 'echo -e "\e[91mOutput exceeded size of 446 bytes.\e[0m"'; \ rm -f tetros.img; exit 1; fi nasm -f bin tetros.asm -o tetros.img diff --git a/README.md b/README.md index 93dde8b..5cd45b0 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,29 @@ # TetrOS -TetrOS is a small *feature rich* Tetris clone which is written in Assembly. -It fits completely into a 512 byte boot sector and is executed during the -boot sequence before any operating system is loaded. It does not need any -existing operating system. TetrOS is its own operating system, hence the suffix -OS in its name. +TetrOS is a small *feature rich* Tetris clone which is written in Assembly. It fits completely into a 512 byte boot sector as it requires only 446 bytes (which is the maximum allowed size of the first stage boot loader in the master boot record (MBR) of a drive) and is executed during the boot sequence before any operating system is loaded. Actually, it does not need any existing operating system. TetrOS *is* an operating system, hence the suffix OS in its name. -This is how it looks like: +Video that shows TetrOS in action: -![TetrOS - Tetris in 512 byte boot sector](https://github.com/daniel-e/mbr_tetris/blob/master/tetros_tetris_screenshot.png) +[![TetrOS - Teris in 512 byte boot sector](http://img.youtube.com/vi/Hl7M7f-Hh78/0.jpg)](https://youtu.be/Hl7M7f-Hh78) And this is the complete machine code: -![TetrOS - Machine code](https://github.com/daniel-e/mbr_tetris/blob/master/code.png) +![TetrOS - Machine code](https://github.com/daniel-e/mbr_tetris/blob/master/screenshots/code.png) + +## Running TetrOS + +There are two options to run TetrOS. Either in an emulator like qemu or via an installation of TetrOS in the boot sector of a real disk, USB stick or some other media. + +### Running via qemu + +Simply run `make run`. This will execute qemu with the right parameters to run TetrOS. If you're using Ubuntu and qemu is not intalled on your system you can install it via `sudo apt-get install qemu`. + +### Running via an USB stick + +First, copy the image to an USB stick. For example, if your USB stick is on `/dev/sde` use the following command to overwrite the first sector of the USB stick with the TetrOS image: + +`sudo dd if=tetros.img of=/dev/sde` + +After that you should be able to boot the stick to play TetrOS. ## Features * Each brick shape has a unique color. @@ -21,7 +33,7 @@ And this is the complete machine code: * Down arrow to drop a brick. * Game over detection. It stops if a new brick could not be placed. * Selects the next brick at random via a linear congruential generator. -* Shows a nice playing field. +* Nice playing field. ## Features missing due to size limits * Scores and highscores. @@ -30,7 +42,21 @@ And this is the complete machine code: * Show next brick. * Increase speed. +## Compiling the sources + +The repository already contains an image which you can use for testing. However, if you want to compile the image from the sources you need nasm, a general prupose x86 assembler to be installed on your system. On Ubuntu you can can install it via the command `sudo apt-get install nasm`. On macOS you will need [homebrew](http://brew.sh/) to install `nasm` and `binutils`. + +If `nasm` is installed you can compile the sources by executing `make`. This will create the image `tetros.img`. After that you can run the image via qemu or you can copy the image via `dd` on an USB disk or a disk (see above). + +I have tested it with nasm 2.11.08 on Ubuntu 16.04. + ## Similar projects * https://github.com/dbittman/bootris * https://github.com/Shikhin/tetranglix * http://olivier.poudade.free.fr/src/BootChess.asm +* https://github.com/programble/tetrasm - Tetris for x86 in NASM but which does not fit into the boot sector. + +## Acknowledgements +I would like to thank the following persons for contributing to TetrOS. +* [DraftYeti5608](https://github.com/DraftYeti5608) +* [Ivoah](https://github.com/Ivoah) diff --git a/code.png b/screenshots/code.png similarity index 100% rename from code.png rename to screenshots/code.png diff --git a/tetros_tetris_screenshot.png b/screenshots/tetros_tetris_screenshot.png similarity index 100% rename from tetros_tetris_screenshot.png rename to screenshots/tetros_tetris_screenshot.png diff --git a/tetros.asm b/tetros.asm index 9dfbaef..d2117be 100644 --- a/tetros.asm +++ b/tetros.asm @@ -90,7 +90,7 @@ new_brick: mov byte [delay], 100 ; 3 * 100 = 300ms select_brick ; returns the selected brick in AL mov dx, start_row_col ; start at row 4 and col 38 -loop: +lp: call check_collision jne $ ; collision -> game over call print_brick @@ -154,7 +154,7 @@ no_key: call clear_brick inc dh ; increase row call check_collision - je loop ; no collision + je lp ; no collision dec dh call print_brick call check_filled @@ -253,7 +253,7 @@ check_collision_main: ; DI = 1 -> check, 0 -> print cc: push cx mov cl, 4 -dd: +zz: test ah, 10000000b jz is_zero @@ -278,7 +278,7 @@ is_zero_a: is_zero: shl ax, 1 ; move to next bit in brick mask inc dx ; move to next column - loop dd + loop zz sub dl, 4 ; reset column inc dh ; move to next row pop cx