BIOS color, scroll

This commit is contained in:
Ciro Santilli
2015-09-20 10:59:36 +02:00
parent 7dc6e56e16
commit 3fa034d5b8
9 changed files with 219 additions and 27 deletions

View File

@@ -6,13 +6,17 @@ Hello world programs that run without an operating system.
1. [printf](printf/)
1. [min](min.S)
1. [No ld script](no-ld-script/)
1. [NASM](nasm/)
1. BIOS
1. [BIOS one char](bios_one_char.S)
1. [BIOS hello world](bios_hello_world.S)
1. [BIOS newline](bios_newline.S)
1. [BIOS carriage return](bios_carriage_return.S)
1. [BIOS clear screen](bios_clear_screen.S)
1. [one char](bios_one_char.S)
1. [hello world](bios_hello_world.S)
1. [NASM](nasm/)
1. [newline](bios_newline.S)
1. [carriage return](bios_carriage_return.S)
1. [cursor position](bios_cursor_position.S)
1. [color](bios_color.S)
1. [background](bios_background.S)
1. [scroll](bios_scroll.S)
1. [clear screen](bios_clear_screen.S)
1. APM
1. [APM shutdown](apm_shutdown.S)
1. [APM shutdown 2](apm_shutdown2.S)
@@ -64,6 +68,8 @@ Then:
- during boot, hit some special hardware dependant key, usually F12, Esc
- choose to boot from the USB
When you are done, just hit the power button to shutdown.
Tested on: ThinkPad T400.
#### Big image
@@ -77,3 +83,5 @@ Now if you do:
sudo dd if=big.img of=/dev/sdX
you can test several examples with a single USB burn, which is much faster.
You will also want to change the boot order to put the USB first from the F12 BIOS menu. This way you don't have to hit F12 like a madman every time.

View File

@@ -2,6 +2,8 @@
- Segment registers: http://stackoverflow.com/questions/30549526/c-kernel-works-fine-on-vm-but-not-actual-computer?rq=1
- 32 bit mode. Answer http://stackoverflow.com/questions/7130726/writing-a-hello-world-kernel
- BIOS
- pages
- ACPI
- reboot computer. Would put QEMU into an infinite reboot loop. Awesome.
- multithreading: http://stackoverflow.com/questions/7308391/how-is-concurrency-done-in-intel-x86-assembly || http://stackoverflow.com/questions/980999/what-does-multicore-assembly-language-look-like || http://stackoverflow.com/questions/714905/threads-in-x86-assembler-using-the-gnu-assember-as || https://github.com/cirosantilli/oszur11-operating-system-examples/tree/1af6451852887fac3d7206d4d09714c181c81d1e/Chapter_07_Threads
@@ -9,8 +11,7 @@
- test the paging circuit
- play with hardware
- set a pixel on screen
- http://stackoverflow.com/questions/5646153/how-to-write-pixels-in-a-pixel-screen
- http://stackoverflow.com/questions/27344904/how-can-i-set-pixels-of-whole-screen-with-x86-assembly-without-any-bios-interrup
- http://wiki.osdev.org/How_do_I_set_a_graphics_mode
- http://stackoverflow.com/questions/14419088/assembly-draw-a-pixel-on-the-screen-in-protected-mode
- USB
- networking

16
bios.md
View File

@@ -8,6 +8,22 @@
Can only be used in real mode.
## Documentation
Does any documentation or portability exist??
<http://www.ctyme.com/intr/int.htm> Ralf Brown's Interrupt List. Everyone says that this is the ultimate unofficial compilation.
<https://en.wikipedia.org/wiki/INT_10H> good quick summary
<http://www.scs.stanford.edu/nyu/04fa/lab/specsbbs101.pdf> says little about interrupts, I don't understand it's scope.
## Colors
## Text properties
<https://en.wikipedia.org/wiki/BIOS_color_attributes>
## Get BIOS information
## SMBIOS

11
bios_background.S Normal file
View File

@@ -0,0 +1,11 @@
#include "common.h"
BEGIN
mov $0x0B, %ah
mov $0x0034, %bx
int $0x10
PUTC(61)
hlt
END

View File

@@ -1,29 +1,34 @@
/*
Clear screen by scrolling.
*/
/* Clear screen by scrolling. */
#include "common.h"
BEGIN
/*
Print one char to ensure that something will be claered.
Print one 'a' char to ensure that something will be claered.
On some systems, BIOS messages get automatically cleared. Not the case for QEMU 2.0.0.
*/
mov $0x0E40, %ax
PUTC(61)
mov $0x0600, %ax
mov $0xA4, %bh
/*
Act on the entire screen.
Bottom right is at (24,79) == (0x18,0x4F)
*/
mov $0x0000, %cx
mov $0X184F, %dx
int $0x10
/* Function ID. */
mov $0x06, %ah
/* nr. of lines to scroll, 00 means clear window. */
mov $0x0, %al
/* TODO: I think this is the style. */
mov $0x7, %bh
/* CH,CL: row,column upper left corner (00:00) */
mov $0x0, %cx
/* DH,DL: row,column lower right corner (24:79) */
mov $0x184f, %dx
int $0x10
/*
Print a 'b' char to see where we are now.
TODO, on ThinkPad T400, the cursor gets put back to the initial position. But QEMU 2.0.0 leaves it in the middle ofthe screen. Thus we reset the position to make them work the same way.
*/
CURSOR_POSITION(0, 0)
PUTC(62)
hlt
END

32
bios_color.S Normal file
View File

@@ -0,0 +1,32 @@
/*
Write a character N times with given color.
TODO: is this the only way? How to set the current color for ah = 0E?
Color codes: https://en.wikipedia.org/wiki/BIOS_color_attributes
*/
#include "common.h"
BEGIN
/* ID, character to print. */
mov $0x0961, %ax
/* Page, color, */
mov $0x0034, %bx
/*
How many times to write.
If too big, wraps around screen.
*/
mov $0x0001, %cx
int $0x10
/*
The new color is reused only for character that overwrite the writen region.
Cursor is not moved by the previous interrupt, so this produces a colored 'A'.
*/
PUTC(62)
PUTC(63)
hlt
END

21
bios_cursor_position.S Normal file
View File

@@ -0,0 +1,21 @@
#include "common.h"
BEGIN
CLEAR
/* Print "ab" */
PUTC(61)
PUTC(62)
/* Move back to 0, 0.*/
mov $0x02, %ah
/* page number 0. TODO what is this? */
mov $0x0, %bh
/* DH=0 row, DL=0 col */
mov $0x0, %dx
int $0x10
/* Overwrite 'a' with c'. */
PUTC(63)
hlt
END

72
bios_scroll.S Normal file
View File

@@ -0,0 +1,72 @@
/*
BIOS has a scroll function!
Very convenient, otherwise that would be hard to implement.
How it works:
Before scroll:
a
b
c
d
We then choose to act on the rectangle with corners
(1, 1) and (2, 2)} given by cx and dx:
a
XX
XX
d
and scroll that rectangle down by one line (al).
The final outcome is:
a
c
NN
d
where `N` are new squares generated by the scroll,
which gets filled with the background color in bh.
*/
#include "common.h"
BEGIN
/* Print staircase. */
CLEAR
PUTC(61)
PUTC(0A)
PUTC(62)
PUTC(0A)
PUTC(63)
PUTC(0A)
PUTC(64)
/* Function ID. */
mov $0x06, %ah
/* nr. of lines to scroll */
mov $0x01, %al
/*
BIOS color attributes.
Background is the clear color.
Foreground is set as the new foreground color.
*/
mov $0xA4, %bh
/*
CH,CL: row,column upper left corner (00:00)
TODO what does that mean?
*/
mov $0x0101, %cx
/*
DH,DL: row,column lower right corner (24:79).
TODO what does it mean?
*/
mov $0x0202, %dx
int $0x10
hlt
END

View File

@@ -1,5 +1,31 @@
#define BEGIN .code16; \
cli; \
xor %ax, %ax; \
#define BEGIN \
.code16;\
cli;\
xor %ax, %ax;\
mov %ax, %ds
#define END
#define CURSOR_POSITION(x, y) \
mov $0x02, %ah;\
mov $0x00, %bh;\
mov $0x ## x ## y, %dx;\
int $0x10
/* Clear the screen, move to position 0, 0. */
#define CLEAR \
mov $0x0600, %ax;\
mov $0x7, %bh;\
mov $0x0, %cx;\
mov $0x184f, %dx;\
int $0x10;\
CURSOR_POSITION(0, 0)
/*
Print a single character.
`c` is it's value in hex.
*/
#define PUTC(c) \
mov $0x0E ## c, %ax;\
int $0x10