Compare commits

...

3 Commits

Author SHA1 Message Date
  Jakob Kjær-Kammersgaard 1a3e8f7649 godnat 5 years ago
  Jakob Kjær-Kammersgaard 41d4b4a7fb PROTECTED MODE BABY 5 years ago
  Jakob Kjær-Kammersgaard 15894ab4c6 Lets32Bit 5 years ago
52 changed files with 4966 additions and 2492 deletions
Split View
  1. +0
    -5
      .gitignore
  2. +0
    -173
      CLI/CLI.nasm
  3. BIN
      DebuggingGhostZeros/WTF_4Sectors.bin
  4. BIN
      DebuggingGhostZeros/WTF_69.bin
  5. BIN
      DebuggingGhostZeros/WTF_Folmer.bin
  6. BIN
      DebuggingGhostZeros/WTF_Folmer_1stSector.bin
  7. BIN
      DebuggingGhostZeros/WTF_Folmer_FuckedBootSector.bin
  8. BIN
      DebuggingGhostZeros/WTF_MAYBE.bin
  9. BIN
      DebuggingGhostZeros/WTF_MAYBE2.bin
  10. BIN
      DebuggingGhostZeros/WTF_MAYBE3.bin
  11. BIN
      DebuggingGhostZeros/WTF_MAYBE4.bin
  12. BIN
      DebuggingGhostZeros/WTF_MAYBE5.bin
  13. BIN
      DebuggingGhostZeros/WTF_MAYBE_OLD_ACER.bin
  14. BIN
      DebuggingGhostZeros/WTF_Overwrite_Sector1.bin
  15. +0
    -39
      README.md
  16. +226
    -0
      References/Artiskok.dissasm
  17. +493
    -0
      References/Folmer.dissasm
  18. BIN
      References/Intel 64 and IA-32 Architectures Software Developer's Manual(s) vol-1-2abcd-3abcd.pdf
  19. +781
    -0
      References/RalfBrown_VideoModes.txt
  20. BIN
      References/VESA_BIOS_Extensions_(VBE)_v3.pdf
  21. +762
    -0
      References/VGA/grdemo.c
  22. BIN
      References/X86 Assembly_Print Version - Wikibooks, open books for an open world.pdf
  23. BIN
      References/cmu-bootloader-project(2007).pdf
  24. +305
    -229
      bootloader.nasm
  25. +106
    -0
      bootloader_A20.nasm
  26. +164
    -0
      bootloader_bios_functions.inc
  27. +74
    -0
      bootloader_macros.inc
  28. +16
    -14
      build
  29. +0
    -16
      build.sh
  30. +26
    -0
      bx_enh_dbg.ini
  31. +114
    -0
      count_a_lot.nasm
  32. +0
    -305
      kernel.nasm
  33. +0
    -1
      legacy/README.md
  34. +0
    -2
      legacy/compile_folder/README.md
  35. +0
    -3
      legacy/source/build.sh
  36. +0
    -3
      legacy/source/generic_build.sh
  37. +0
    -3
      legacy/source/info.txt
  38. +0
    -76
      legacy/source/mytest.s
  39. +0
    -227
      legacy/source/mytest2.s
  40. +0
    -120
      legacy/source/sing_boot_alt.s
  41. +0
    -135
      legacy/source/sing_boot_guess.s
  42. +0
    -337
      lib/debug_tools.nasm
  43. +0
    -72
      lib/os_lib.nasm
  44. +0
    -39
      lib/std_power.nasm
  45. +0
    -57
      lib/string.nasm
  46. +0
    -290
      lib/svim.nasm
  47. +0
    -4
      mem_lib/mem_lib.nasm
  48. +134
    -0
      min.nasm
  49. +8
    -0
      proj.sublime-project
  50. +1712
    -0
      proj.sublime-workspace
  51. +0
    -342
      vsfs/vsfs.nasm
  52. +45
    -0
      write_self.nasm

+ 0
- 5
.gitignore View File

@ -1,5 +0,0 @@
.DS_Store
*.swp
*.sublime*
*.img
*.bin

+ 0
- 173
CLI/CLI.nasm View File

@ -1,173 +0,0 @@
BITS 16
;CLI
;Command syntax: <command name> <arg1>
;Argument must not contain spaces.
; Data
CLI_Command_Buffer times 256 db 0
CLI_Command_Length dw 0
; API
; args:
; ax: keyboard keycode.
CLI_ASCII_INPUT:
pusha
; Fetch command buffer offset.
; If there is no room in the buffer, then just bail on the key press.
mov bx, [CLI_Command_Length]
cmp bx, 255
je .end
inc bx ; The new last element will be located at this offset.
mov [CLI_Command_Length], bx ; Save the new counter.
dec bx ; Go back to the index the character should be written to.
; Move new ascii character into command buffer.
add bx, CLI_Command_Buffer ; address+offset = destination
mov [bx], al
inc bx
mov byte [bx], 0
; Print out the input character
mov ah, 0xe ; Teletype output
mov bl, 0x02 ; color (green)
int 0x10
.end:
popa
ret
; args:
CLI_DELETE:
pusha
; Check if at the beginning of the line.
mov bx, [CLI_Command_Length]
cmp bx, 0x00
je .end
; Move the counter one back
sub bx, 0x01
mov [CLI_Command_Length], bx
;Move NULL into the last character of the line (delete)
mov al, 0x0
add bx, CLI_Command_Buffer ; address+offset = destination
mov [bx], al
; Go back one space
mov ax, 0x0e08 ; ah=0x0e means teletype output. al=0x08 means backspace character.
int 0x10
; Place a NULL
mov al, 0x0 ; NULL
int 0x10
; Go back one space again as the above print of NULL pushes the cursor forward again.
mov ax, 0x0e08
int 0x10
.end:
popa
ret
; Probably activated with the 'Enter' button.
CLI_CONFIRM_INPUT:
call CLI_EXECUTE
mov bx, 0
mov [CLI_Command_Length], bx
mov [CLI_Command_Buffer], bx
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
print_help_message:
; Prints a list of available commands
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
push si
mov si, .command_list_string
call print
pop si
ret
.command_list_string:
db 13, 10
db "Available commands:", 13, 10
db " help: Prints this screen", 13, 10
db " dumpmem: Prints the contents of a memory region (At the moment hardcoded)", 13, 10
db " keyprint: Prints the character and keycode for a key presssd", 13, 10
db " clear: Clears the screen", 13, 10
db " formatdisk: Initialize the file system", 13, 10
db " createfile: Name a file, in the file system", 13, 10
db " fsinfo: Displays info about the file system", 13, 10
db " ls: Lists the named files", 13, 10
db " svim: SingOS' text editor", 13, 10, 0
; Executes the command.
CLI_EXECUTE:
pusha
mov bx, [CLI_Command_Length]
cmp bx, 0
je near .end ; If there are not bytes in the buffer then there is no command.
mov ax, [.Num_Commands] ; The number of commands available.
lea si, [CLI_Command_Buffer]
mov cx, 0 ; Index into the list of commands.
.Interpreter_Search_Commands_Loop:
;cmp cx, ax ; Start by comparing.
;je .end
mov bx, cx ; Move Index into bx to offset into the array of commands.
add bx, bx ; The pointers are two bytes long. This compensates for that.
mov bx, [.Command_Name_List + bx] ; Fetch the pointer for the string.
lea di, [bx]
call stringcompare
je .Interpreter_Command_Execute
inc cx ; Prepare for next iteration.
cmp ax, cx
je .end
jmp .Interpreter_Search_Commands_Loop
.Interpreter_Command_Execute:
mov bx, cx ; Move Index into bx to offset into the array of commands.
add bx, bx ; The pointers are two bytes long. This compensates for that.
pusha
call printCRLF
popa
mov dx, [.Command_Function_Pointers + bx] ; Program pointer
; Execute program.
call dx
.end:
popa
ret
.tmp dw 0
.Num_Commands dw 9
.Command_Name_List dw .CMD1, .CMD2, .CMD3, .CMD4, .CMD5, .CMD6, .CMD7, .CMD8, .CMD9
.Command_Function_Pointers dw dumpmem_hardcoded_args, keyprint, svim, vsfs_list_files_command, vsfs_create_file, vsfs_format_disk, vsfs_get_fs_info, os_clear_screen, print_help_message
.CMD1 db 'dumpmem', 0
.CMD2 db 'keyprint', 0
.CMD3 db 'svim', 0
.CMD4 db 'ls', 0
.CMD5 db 'createfile', 0
.CMD6 db 'formatdisk', 0
.CMD7 db 'fsinfo', 0
.CMD8 db 'clear', 0
.CMD9 db 'help', 0

BIN
DebuggingGhostZeros/WTF_4Sectors.bin View File


BIN
DebuggingGhostZeros/WTF_69.bin View File


BIN
DebuggingGhostZeros/WTF_Folmer.bin View File


BIN
DebuggingGhostZeros/WTF_Folmer_1stSector.bin View File


BIN
DebuggingGhostZeros/WTF_Folmer_FuckedBootSector.bin View File


BIN
DebuggingGhostZeros/WTF_MAYBE.bin View File


BIN
DebuggingGhostZeros/WTF_MAYBE2.bin View File


BIN
DebuggingGhostZeros/WTF_MAYBE3.bin View File


BIN
DebuggingGhostZeros/WTF_MAYBE4.bin View File


BIN
DebuggingGhostZeros/WTF_MAYBE5.bin View File


BIN
DebuggingGhostZeros/WTF_MAYBE_OLD_ACER.bin View File


BIN
DebuggingGhostZeros/WTF_Overwrite_Sector1.bin View File


+ 0
- 39
README.md View File

@ -1,39 +0,0 @@
SingOS is a single task operating system.
Current version 0.0.3
The goal for this project is to create a Operating System
which tries to find new better ways to handle memory adressing
It will also be posible to switch between 16, 32 and 64-bit mode
such that anything on very low level can be tested.
You can build and run the OS with following command
(Require nasm and qemu installed)
```sh
sh build.sh
```
If you only want to run SingOS:
```sh
sh build.sh run
```
If you only want to compile the binary:
```sh
sh build.sh make
```
If you want to write it to a usb device
```sh
sudo dd if=/some_dir/SingOS.img of=/dev/name_device status=progress oflag=sync
```

+ 226
- 0
References/Artiskok.dissasm View File

@ -0,0 +1,226 @@
Artiskok.bin: file format binary
Disassembly of section .data:
00000000 <.data>:
0: eb 63 jmp 0x7c65
2: 90 nop
3: 10 8e d0 bc adc BYTE PTR [bp-0x4330],cl
7: 00 b0 b8 00 add BYTE PTR [bx+si+0xb8],dh
b: 00 8e d8 8e add BYTE PTR [bp-0x7128],cl
f: c0 fb be sar bl,0xbe
12: 00 7c bf add BYTE PTR [si-0x41],bh
15: 00 06 b9 00 add BYTE PTR ds:0xb9,al
19: 02 f3 add dh,bl
1b: a4 movs BYTE PTR es:[di],BYTE PTR ds:[si]
1c: ea 21 06 00 00 jmp 0x0:0x621
21: be be 07 mov si,0x7be
24: 38 04 cmp BYTE PTR [si],al
26: 75 0b jne 0x33
28: 83 c6 10 add si,0x10
2b: 81 fe fe 07 cmp si,0x7fe
2f: 75 f3 jne 0x24
31: eb 16 jmp 0x49
33: b4 02 mov ah,0x2
35: b0 01 mov al,0x1
37: bb 00 7c mov bx,0x7c00
3a: b2 80 mov dl,0x80
3c: 8a 74 01 mov dh,BYTE PTR [si+0x1]
3f: 8b 4c 02 mov cx,WORD PTR [si+0x2]
42: cd 13 int 0x13
44: ea 00 7c 00 00 jmp 0x0:0x7c00
49: eb fe jmp 0x49
4b: 00 00 add BYTE PTR [bx+si],al
4d: 00 00 add BYTE PTR [bx+si],al
4f: 00 00 add BYTE PTR [bx+si],al
51: 00 00 add BYTE PTR [bx+si],al
53: 00 00 add BYTE PTR [bx+si],al
55: 00 00 add BYTE PTR [bx+si],al
57: 00 00 add BYTE PTR [bx+si],al
59: 00 00 add BYTE PTR [bx+si],al
5b: 80 01 00 add BYTE PTR [bx+di],0x0
5e: 00 00 add BYTE PTR [bx+si],al
60: 00 00 add BYTE PTR [bx+si],al
62: 00 00 add BYTE PTR [bx+si],al
64: ff (bad)
65: fa cli
66: 90 nop
67: 90 nop
68: f6 c2 80 test dl,0x80
6b: 74 05 je 0x72
6d: f6 c2 70 test dl,0x70
70: 74 02 je 0x74
72: b2 80 mov dl,0x80
74: ea 79 7c 00 00 jmp 0x0:0x7c79
79: 31 c0 xor ax,ax
7b: 8e d8 mov ds,ax
7d: 8e d0 mov ss,ax
7f: bc 00 20 mov sp,0x2000
82: fb sti
83: a0 64 7c mov al,ds:0x7c64
86: 3c ff cmp al,0xff
88: 74 02 je 0x8c
8a: 88 c2 mov dl,al
8c: 52 push dx
8d: be 80 7d mov si,0x7d80
90: e8 17 01 call 0x1aa
93: be 05 7c mov si,0x7c05
96: b4 41 mov ah,0x41
98: bb aa 55 mov bx,0x55aa
9b: cd 13 int 0x13
9d: 5a pop dx
9e: 52 push dx
9f: 72 3d jb 0xde
a1: 81 fb 55 aa cmp bx,0xaa55
a5: 75 37 jne 0xde
a7: 83 e1 01 and cx,0x1
aa: 74 32 je 0xde
ac: 31 c0 xor ax,ax
ae: 89 44 04 mov WORD PTR [si+0x4],ax
b1: 40 inc ax
b2: 88 44 ff mov BYTE PTR [si-0x1],al
b5: 89 44 02 mov WORD PTR [si+0x2],ax
b8: c7 04 10 00 mov WORD PTR [si],0x10
bc: 66 8b 1e 5c 7c mov ebx,DWORD PTR ds:0x7c5c
c1: 66 89 5c 08 mov DWORD PTR [si+0x8],ebx
c5: 66 8b 1e 60 7c mov ebx,DWORD PTR ds:0x7c60
ca: 66 89 5c 0c mov DWORD PTR [si+0xc],ebx
ce: c7 44 06 00 70 mov WORD PTR [si+0x6],0x7000
d3: b4 42 mov ah,0x42
d5: cd 13 int 0x13
d7: 72 05 jb 0xde
d9: bb 00 70 mov bx,0x7000
dc: eb 76 jmp 0x154
de: b4 08 mov ah,0x8
e0: cd 13 int 0x13
e2: 73 0d jae 0xf1
e4: 5a pop dx
e5: 84 d2 test dl,dl
e7: 0f 83 d8 00 jae 0x1c3
eb: be 8b 7d mov si,0x7d8b
ee: e9 82 00 jmp 0x173
f1: 66 0f b6 c6 movzx eax,dh
f5: 88 64 ff mov BYTE PTR [si-0x1],ah
f8: 40 inc ax
f9: 66 89 44 04 mov DWORD PTR [si+0x4],eax
fd: 0f b6 d1 movzx dx,cl
100: c1 e2 02 shl dx,0x2
103: 88 e8 mov al,ch
105: 88 f4 mov ah,dh
107: 40 inc ax
108: 89 44 08 mov WORD PTR [si+0x8],ax
10b: 0f b6 c2 movzx ax,dl
10e: c0 e8 02 shr al,0x2
111: 66 89 04 mov DWORD PTR [si],eax
114: 66 a1 60 7c mov eax,ds:0x7c60
118: 66 09 c0 or eax,eax
11b: 75 4e jne 0x16b
11d: 66 a1 5c 7c mov eax,ds:0x7c5c
121: 66 31 d2 xor edx,edx
124: 66 f7 34 div DWORD PTR [si]
127: 88 d1 mov cl,dl
129: 31 d2 xor dx,dx
12b: 66 f7 74 04 div DWORD PTR [si+0x4]
12f: 3b 44 08 cmp ax,WORD PTR [si+0x8]
132: 7d 37 jge 0x16b
134: fe c1 inc cl
136: 88 c5 mov ch,al
138: 30 c0 xor al,al
13a: c1 e8 02 shr ax,0x2
13d: 08 c1 or cl,al
13f: 88 d0 mov al,dl
141: 5a pop dx
142: 88 c6 mov dh,al
144: bb 00 70 mov bx,0x7000
147: 8e c3 mov es,bx
149: 31 db xor bx,bx
14b: b8 01 02 mov ax,0x201
14e: cd 13 int 0x13
150: 72 1e jb 0x170
152: 8c c3 mov bx,es
154: 60 pusha
155: 1e push ds
156: b9 00 01 mov cx,0x100
159: 8e db mov ds,bx
15b: 31 f6 xor si,si
15d: bf 00 80 mov di,0x8000
160: 8e c6 mov es,si
162: fc cld
163: f3 a5 rep movs WORD PTR es:[di],WORD PTR ds:[si]
165: 1f pop ds
166: 61 popa
167: ff 26 5a 7c jmp WORD PTR ds:0x7c5a
16b: be 86 7d mov si,0x7d86
16e: eb 03 jmp 0x173
170: be 95 7d mov si,0x7d95
173: e8 34 00 call 0x1aa
176: be 9a 7d mov si,0x7d9a
179: e8 2e 00 call 0x1aa
17c: cd 18 int 0x18
17e: eb fe jmp 0x17e
180: 47 inc di
181: 52 push dx
182: 55 push bp
183: 42 inc dx
184: 20 00 and BYTE PTR [bx+si],al
186: 47 inc di
187: 65 6f outs dx,WORD PTR gs:[si]
189: 6d ins WORD PTR es:[di],dx
18a: 00 48 61 add BYTE PTR [bx+si+0x61],cl
18d: 72 64 jb 0x1f3
18f: 20 44 69 and BYTE PTR [si+0x69],al
192: 73 6b jae 0x1ff
194: 00 52 65 add BYTE PTR [bp+si+0x65],dl
197: 61 popa
198: 64 00 20 add BYTE PTR fs:[bx+si],ah
19b: 45 inc bp
19c: 72 72 jb 0x210
19e: 6f outs dx,WORD PTR ds:[si]
19f: 72 0d jb 0x1ae
1a1: 0a 00 or al,BYTE PTR [bx+si]
1a3: bb 01 00 mov bx,0x1
1a6: b4 0e mov ah,0xe
1a8: cd 10 int 0x10
1aa: ac lods al,BYTE PTR ds:[si]
1ab: 3c 00 cmp al,0x0
1ad: 75 f4 jne 0x1a3
1af: c3 ret
1b0: 00 00 add BYTE PTR [bx+si],al
1b2: 00 00 add BYTE PTR [bx+si],al
1b4: 00 00 add BYTE PTR [bx+si],al
1b6: 00 00 add BYTE PTR [bx+si],al
1b8: 6c ins BYTE PTR es:[di],dx
1b9: 0f d1 b6 00 00 psrlw mm6,QWORD PTR [bp+0x0]
1be: 00 20 add BYTE PTR [bx+si],ah
1c0: 22 00 and al,BYTE PTR [bx+si]
1c2: 83 fe ff cmp si,0xffff
1c5: ff 01 inc WORD PTR [bx+di]
1c7: 08 00 or BYTE PTR [bx+si],al
1c9: 00 74 54 add BYTE PTR [si+0x54],dh
1cc: 3d 39 00 cmp ax,0x39
1cf: fe (bad)
1d0: ff (bad)
1d1: ff 82 fe ff inc WORD PTR [bp+si-0x2]
1d5: ff 75 5c push WORD PTR [di+0x5c]
1d8: 3d 39 cc cmp ax,0xcc39
1db: ef out dx,ax
1dc: fa cli
1dd: 00 00 add BYTE PTR [bx+si],al
1df: 00 00 add BYTE PTR [bx+si],al
1e1: 00 00 add BYTE PTR [bx+si],al
1e3: 00 00 add BYTE PTR [bx+si],al
1e5: 00 00 add BYTE PTR [bx+si],al
1e7: 00 00 add BYTE PTR [bx+si],al
1e9: 00 00 add BYTE PTR [bx+si],al
1eb: 00 00 add BYTE PTR [bx+si],al
1ed: 00 00 add BYTE PTR [bx+si],al
1ef: 00 00 add BYTE PTR [bx+si],al
1f1: 00 00 add BYTE PTR [bx+si],al
1f3: 00 00 add BYTE PTR [bx+si],al
1f5: 00 00 add BYTE PTR [bx+si],al
1f7: 00 00 add BYTE PTR [bx+si],al
1f9: 00 00 add BYTE PTR [bx+si],al
1fb: 00 00 add BYTE PTR [bx+si],al
1fd: 00 55 aa add BYTE PTR [di-0x56],dl

+ 493
- 0
References/Folmer.dissasm View File

@ -0,0 +1,493 @@
WTF_Folmer_FuckedBootSector.bin: file format binary
Disassembly of section .data:
00000000 <.data>:
0: e9 cb 01 jmp 0x1ce
3: ff (bad)
4: ff (bad)
5: ff (bad)
6: ff (bad)
7: ff (bad)
8: ff (bad)
9: ff (bad)
a: ff (bad)
b: ff (bad)
c: ff (bad)
d: ff (bad)
e: ff (bad)
f: ff (bad)
10: ff (bad)
11: ff (bad)
12: ff (bad)
13: ff (bad)
14: ff (bad)
15: ff (bad)
16: ff (bad)
17: ff (bad)
18: ff (bad)
19: ff (bad)
1a: ff (bad)
1b: ff 00 inc WORD PTR [bx+si]
1d: 00 00 add BYTE PTR [bx+si],al
1f: 00 ff add bh,bh
21: ff (bad)
22: ff (bad)
23: ff 00 inc WORD PTR [bx+si]
25: ff (bad)
26: ff (bad)
27: ff (bad)
28: ff (bad)
29: ff (bad)
2a: ff (bad)
2b: ff (bad)
2c: ff (bad)
2d: ff (bad)
2e: ff (bad)
2f: ff (bad)
30: ff (bad)
31: ff (bad)
32: ff (bad)
33: ff (bad)
34: ff (bad)
35: ff (bad)
36: ff (bad)
37: ff (bad)
38: ff (bad)
39: ff (bad)
3a: ff (bad)
3b: ff (bad)
3c: ff (bad)
3d: ff (bad)
3e: ff (bad)
3f: ff (bad)
40: ff (bad)
41: ff (bad)
42: ff (bad)
43: ff (bad)
44: ff (bad)
45: ff (bad)
46: ff (bad)
47: ff (bad)
48: ff (bad)
49: ff (bad)
4a: ff (bad)
4b: ff (bad)
4c: ff (bad)
4d: ff (bad)
4e: ff (bad)
4f: ff (bad)
50: ff (bad)
51: ff (bad)
52: ff (bad)
53: ff (bad)
54: ff (bad)
55: ff (bad)
56: ff (bad)
57: ff (bad)
58: ff (bad)
59: ff (bad)
5a: ff (bad)
5b: ff (bad)
5c: ff (bad)
5d: ff (bad)
5e: ff (bad)
5f: ff (bad)
60: ff (bad)
61: ff (bad)
62: ff (bad)
63: ff (bad)
64: ff (bad)
65: ff (bad)
66: ff (bad)
67: ff (bad)
68: ff (bad)
69: ff (bad)
6a: ff (bad)
6b: ff (bad)
6c: ff (bad)
6d: ff (bad)
6e: ff (bad)
6f: ff (bad)
70: ff (bad)
71: ff (bad)
72: ff (bad)
73: ff (bad)
74: ff (bad)
75: ff (bad)
76: ff (bad)
77: ff (bad)
78: ff (bad)
79: ff (bad)
7a: ff (bad)
7b: ff (bad)
7c: ff (bad)
7d: ff (bad)
7e: ff (bad)
7f: ff (bad)
80: ff (bad)
81: ff (bad)
82: ff (bad)
83: ff (bad)
84: ff (bad)
85: ff (bad)
86: ff (bad)
87: ff (bad)
88: ff (bad)
89: ff (bad)
8a: ff (bad)
8b: ff (bad)
8c: ff (bad)
8d: ff (bad)
8e: ff (bad)
8f: ff (bad)
90: ff (bad)
91: ff (bad)
92: ff (bad)
93: ff (bad)
94: ff (bad)
95: ff (bad)
96: ff (bad)
97: ff (bad)
98: ff (bad)
99: ff (bad)
9a: ff (bad)
9b: ff (bad)
9c: ff (bad)
9d: ff (bad)
9e: ff (bad)
9f: ff (bad)
a0: ff (bad)
a1: ff (bad)
a2: ff (bad)
a3: ff (bad)
a4: ff (bad)
a5: ff (bad)
a6: ff (bad)
a7: ff (bad)
a8: ff (bad)
a9: ff (bad)
aa: ff (bad)
ab: ff (bad)
ac: ff (bad)
ad: ff (bad)
ae: ff (bad)
af: ff (bad)
b0: ff (bad)
b1: ff (bad)
b2: ff (bad)
b3: ff (bad)
b4: ff (bad)
b5: ff (bad)
b6: ff (bad)
b7: ff (bad)
b8: ff (bad)
b9: ff (bad)
ba: ff (bad)
bb: ff (bad)
bc: ff (bad)
bd: ff (bad)
be: ff (bad)
bf: ff (bad)
c0: ff (bad)
c1: ff (bad)
c2: ff (bad)
c3: ff (bad)
c4: ff (bad)
c5: ff (bad)
c6: ff (bad)
c7: ff (bad)
c8: ff (bad)
c9: ff (bad)
ca: ff (bad)
cb: ff (bad)
cc: ff (bad)
cd: ff (bad)
ce: ff (bad)
cf: ff (bad)
d0: ff (bad)
d1: ff (bad)
d2: ff (bad)
d3: ff (bad)
d4: ff (bad)
d5: ff (bad)
d6: ff (bad)
d7: ff (bad)
d8: ff (bad)
d9: ff (bad)
da: ff (bad)
db: ff (bad)
dc: ff (bad)
dd: ff (bad)
de: ff (bad)
df: ff (bad)
e0: ff (bad)
e1: ff (bad)
e2: ff (bad)
e3: ff (bad)
e4: ff (bad)
e5: ff (bad)
e6: ff (bad)
e7: ff (bad)
e8: ff (bad)
e9: ff (bad)
ea: ff (bad)
eb: ff (bad)
ec: ff (bad)
ed: ff (bad)
ee: ff (bad)
ef: ff (bad)
f0: ff (bad)
f1: ff (bad)
f2: ff (bad)
f3: ff (bad)
f4: ff (bad)
f5: ff (bad)
f6: ff (bad)
f7: ff (bad)
f8: ff (bad)
f9: ff (bad)
fa: ff (bad)
fb: ff (bad)
fc: ff (bad)
fd: ff (bad)
fe: ff (bad)
ff: ff (bad)
100: ff (bad)
101: ff (bad)
102: ff (bad)
103: ff (bad)
104: ff (bad)
105: ff (bad)
106: ff (bad)
107: ff (bad)
108: ff (bad)
109: ff (bad)
10a: ff (bad)
10b: ff (bad)
10c: ff (bad)
10d: ff (bad)
10e: ff (bad)
10f: ff (bad)
110: ff (bad)
111: ff (bad)
112: ff (bad)
113: ff (bad)
114: ff (bad)
115: ff (bad)
116: ff (bad)
117: ff (bad)
118: ff (bad)
119: ff (bad)
11a: ff (bad)
11b: ff (bad)
11c: ff (bad)
11d: ff (bad)
11e: ff (bad)
11f: ff (bad)
120: ff (bad)
121: ff (bad)
122: ff (bad)
123: ff (bad)
124: ff (bad)
125: ff (bad)
126: ff (bad)
127: ff (bad)
128: ff (bad)
129: ff (bad)
12a: ff (bad)
12b: ff (bad)
12c: ff (bad)
12d: ff (bad)
12e: ff (bad)
12f: ff (bad)
130: ff (bad)
131: ff (bad)
132: ff (bad)
133: ff (bad)
134: ff (bad)
135: ff (bad)
136: ff (bad)
137: ff (bad)
138: ff (bad)
139: ff (bad)
13a: ff (bad)
13b: ff (bad)
13c: ff (bad)
13d: ff (bad)
13e: ff (bad)
13f: ff (bad)
140: ff (bad)
141: ff (bad)
142: ff (bad)
143: ff (bad)
144: ff (bad)
145: ff (bad)
146: ff (bad)
147: ff (bad)
148: ff (bad)
149: ff (bad)
14a: ff (bad)
14b: ff (bad)
14c: ff (bad)
14d: ff (bad)
14e: ff (bad)
14f: ff (bad)
150: ff (bad)
151: ff (bad)
152: ff (bad)
153: ff (bad)
154: ff (bad)
155: ff (bad)
156: ff (bad)
157: ff (bad)
158: ff (bad)
159: ff (bad)
15a: ff (bad)
15b: ff (bad)
15c: ff (bad)
15d: ff (bad)
15e: ff (bad)
15f: ff (bad)
160: ff (bad)
161: ff (bad)
162: ff (bad)
163: ff (bad)
164: ff (bad)
165: ff (bad)
166: ff (bad)
167: ff (bad)
168: ff (bad)
169: ff (bad)
16a: ff (bad)
16b: ff (bad)
16c: ff (bad)
16d: ff (bad)
16e: ff (bad)
16f: ff (bad)
170: ff (bad)
171: ff (bad)
172: ff (bad)
173: ff (bad)
174: ff (bad)
175: ff (bad)
176: ff (bad)
177: ff (bad)
178: ff (bad)
179: ff (bad)
17a: ff (bad)
17b: ff (bad)
17c: ff (bad)
17d: ff (bad)
17e: ff (bad)
17f: ff (bad)
180: ff (bad)
181: ff (bad)
182: ff (bad)
183: ff (bad)
184: ff (bad)
185: ff (bad)
186: ff (bad)
187: ff (bad)
188: ff (bad)
189: ff (bad)
18a: ff (bad)
18b: ff (bad)
18c: ff (bad)
18d: ff (bad)
18e: ff (bad)
18f: ff (bad)
190: ff (bad)
191: ff (bad)
192: ff (bad)
193: ff (bad)
194: ff (bad)
195: ff (bad)
196: ff (bad)
197: ff (bad)
198: ff (bad)
199: ff (bad)
19a: ff (bad)
19b: ff (bad)
19c: ff (bad)
19d: ff (bad)
19e: ff (bad)
19f: ff (bad)
1a0: ff (bad)
1a1: ff (bad)
1a2: ff (bad)
1a3: ff (bad)
1a4: ff (bad)
1a5: ff (bad)
1a6: ff (bad)
1a7: ff (bad)
1a8: ff (bad)
1a9: ff (bad)
1aa: ff (bad)
1ab: ff (bad)
1ac: ff (bad)
1ad: ff (bad)
1ae: ff (bad)
1af: ff (bad)
1b0: ff (bad)
1b1: ff (bad)
1b2: ff (bad)
1b3: ff (bad)
1b4: ff (bad)
1b5: ff (bad)
1b6: ff (bad)
1b7: ff (bad)
1b8: ff (bad)
1b9: ff (bad)
1ba: ff (bad)
1bb: ff (bad)
1bc: ff (bad)
1bd: ff (bad)
1be: ff (bad)
1bf: ff (bad)
1c0: ff (bad)
1c1: ff (bad)
1c2: ff (bad)
1c3: ff (bad)
1c4: ff (bad)
1c5: ff (bad)
1c6: ff (bad)
1c7: ff (bad)
1c8: ff (bad)
1c9: ff (bad)
1ca: ff (bad)
1cb: ff (bad)
1cc: ff (bad)
1cd: ff 31 push WORD PTR [bx+di]
1cf: c0 8e c0 bb 00 ror BYTE PTR [bp-0x4440],0x0
1d4: 7c b8 jl 0x18e
1d6: 01 03 add WORD PTR [bp+di],ax
1d8: b9 02 00 mov cx,0x2
1db: 30 f6 xor dh,dh
1dd: cd 13 int 0x13
1df: b9 10 00 mov cx,0x10
1e2: 93 xchg bx,ax
1e3: b8 18 0e mov ax,0xe18
1e6: d1 e3 shl bx,1
1e8: d0 d0 rcl al,1
1ea: cd 10 int 0x10
1ec: e2 f5 loop 0x1e3
1ee: fa cli
1ef: f4 hlt
1f0: eb fc jmp 0x1ee
1f2: 90 nop
1f3: 90 nop
1f4: 90 nop
1f5: 90 nop
1f6: 90 nop
1f7: 90 nop
1f8: 90 nop
1f9: 90 nop
1fa: 90 nop
1fb: 90 nop
1fc: 90 nop
1fd: 90 nop
1fe: 55 push bp
1ff: aa stos BYTE PTR es:[di],al

BIN
References/Intel 64 and IA-32 Architectures Software Developer's Manual(s) vol-1-2abcd-3abcd.pdf View File


+ 781
- 0
References/RalfBrown_VideoModes.txt View File

@ -0,0 +1,781 @@
(Table 00010)
Values for video mode:
text/ text pixel pixel colors disply scrn system
grph resol box resolution pages addr
00h = T 40x25 8x8 320x200 16gray 8 B800 CGA,PCjr,Tandy
= T 40x25 8x14 320x350 16gray 8 B800 EGA
= T 40x25 8x16 320x400 16 8 B800 MCGA
= T 40x25 9x16 360x400 16 8 B800 VGA
01h = T 40x25 8x8 320x200 16 8 B800 CGA,PCjr,Tandy
= T 40x25 8x14 320x350 16 8 B800 EGA
= T 40x25 8x16 320x400 16 8 B800 MCGA
= T 40x25 9x16 360x400 16 8 B800 VGA
02h = T 80x25 8x8 640x200 16gray 4 B800 CGA,PCjr,Tandy
= T 80x25 8x14 640x350 16gray 8 B800 EGA
= T 80x25 8x16 640x400 16 8 B800 MCGA
= T 80x25 9x16 720x400 16 8 B800 VGA
03h = T 80x25 8x8 640x200 16 4 B800 CGA,PCjr,Tandy
= T 80x25 8x14 640x350 16/64 8 B800 EGA
= T 80x25 8x16 640x400 16 8 B800 MCGA
= T 80x25 9x16 720x400 16 8 B800 VGA
= T 80x43 8x8 640x350 16 4 B800 EGA,VGA [17]
= T 80x50 8x8 640x400 16 4 B800 VGA [17]
04h = G 40x25 8x8 320x200 4 . B800 CGA,PCjr,EGA,MCGA,VGA
05h = G 40x25 8x8 320x200 4gray . B800 CGA,PCjr,EGA
= G 40x25 8x8 320x200 4 . B800 MCGA,VGA
06h = G 80x25 8x8 640x200 2 . B800 CGA,PCjr,EGA,MCGA,VGA
= G 80x25 . . mono . B000 HERCULES.COM on HGC [14]
07h = T 80x25 9x14 720x350 mono var B000 MDA,Hercules,EGA
= T 80x25 9x16 720x400 mono . B000 VGA
08h = T 132x25 8x8 1056x200 16 . B800 ATI EGA/VGA Wonder [2]
= T 132x25 8x8 1056x200 mono . B000 ATI EGA/VGA Wonder [2]
= G 20x25 8x8 160x200 16 . . PCjr, Tandy 1000
= G 80x25 8x16 640x400 color . . Tandy 2000
= G 90x43 8x8 720x348 mono . B000 Hercules + MSHERC.COM
= G 90x45 8x8 720x360 mono . B000 Hercules + HERKULES [11]
= G 90x29 8x12 720x348 mono . . Hercules + HERCBIOS [15]
09h = G 40x25 8x8 320x200 16 . . PCjr, Tandy 1000
= G 80x25 8x16 640x400 mono . . Tandy 2000
= G 90x43 8x8 720x348 mono . . Hercules + HERCBIOS [15]
0Ah = G 80x25 8x8 640x200 4 . . PCjr, Tandy 1000
0Bh = reserved (EGA BIOS internal use)
= G 80x25 8x8 640x200 16 . . Tandy 1000 SL/TL [13]
0Ch = reserved (EGA BIOS internal use)
0Dh = G 40x25 8x8 320x200 16 8 A000 EGA,VGA
0Eh = G 80x25 8x8 640x200 16 4 A000 EGA,VGA
0Fh = G 80x25 8x14 640x350 mono 2 A000 EGA,VGA
10h = G 80x25 8x14 640x350 4 2 A000 64k EGA
= G . . 640x350 16 . A000 256k EGA,VGA
11h = G 80x30 8x16 640x480 mono . A000 VGA,MCGA,ATI EGA,ATI VIP
12h = G 80x30 8x16 640x480 16/256K . A000 VGA,ATI VIP
= G 80x30 8x16 640x480 16/64 . A000 ATI EGA Wonder
= G . . 640x480 16 . . UltraVision+256K EGA
13h = G 40x25 8x8 320x200 256/256K . A000 VGA,MCGA,ATI VIP
14h = T 132x25 Nx16 . 16 . B800 XGA, IBM Enhanced VGA [3]
= T 132x25 8x16 1056x400 16/256K . . Cirrus CL-GD5420/5422/5426
= G 80x25 8x8 640x200 . . . Lava Chrome II EGA
= G . . 640x400 16 . . Tecmar VGA/AD
15h = G 80x25 8x14 640x350 . . . Lava Chrome II EGA
16h = G 80x25 8x14 640x350 . . . Lava Chrome II EGA
= G . . 800x600 16 . . Tecmar VGA/AD
17h = T 132x25 . . . . . Tecmar VGA/AD
= T 80x43 8x8 640x348 16 4 B800 Tseng ET4000 BIOS [10]
= G 80x34 8x14 640x480 . . . Lava Chrome II EGA
18h = T 80x30 9x16 720x480 16 1 A000 Realtek RTVGA [12]
= T 132x25 . . mono . B000 Cirrus 5320 chipset
= T 132x44 8x8 1056x352 mono . B000 Tseng Labs EVA
= T 132x44 9x8 1188x352 4gray 2 B000 Tseng ET3000 chipset
= T 132x44 8x8 1056x352 16/256 2 B000 Tseng ET4000 chipset
= G 80x34 8x14 640x480 . . . Lava Chrome II EGA
= G 1024x768 16 . . Tecmar VGA/AD
19h = T 80x43 9x11 720x473 16 1 A000 Realtek RTVGA [12]
= T 132x25 8x14 1056x350 mono . B000 Tseng Labs EVA
= T 132x25 9x14 1188x350 4gray 4 B000 Tseng ET3000 chipset
= T 132x25 8x14 1056x350 16/256 4 B000 Tseng ET4000 chipset
= T 132x34 . . mono . B000 Cirrus 5320 chipset
1Ah = T 80x60 9x8 720x480 16 1 A000 Realtek RTVGA [12]
= T 132x28 8x13 1056x364 mono . B000 Tseng Labs EVA
= T 132x28 9x13 1188x364 4gray 4 B000 Tseng ET3000 chipset
= T 132x28 8x13 1056x364 16/256 4 B000 Tseng ET4000 chipset
= T 132x44 . . mono . B000 Cirrus 5320 chipset
= G . . 640x350 256 . . Tecmar VGA/AD
1Bh = T 132x25 9x14 1188x350 16 1 A000 Realtek RTVGA [12]
= G . . 640x400 256 . . Tecmar VGA/AD
1Ch = T 132x25 . . . . . Cirrus 5320 chipset
= T 132x30 9x16 1188x480 16 1 A000 Realtek RTVGA [12]
= G . . 640x480 256 . . Tecmar VGA/AD
1Dh = T 132x43 . . . . . Cirrus 5320 chipset
= T 132x43 9x11 1188x473 16 1 A000 Realtek RTVGA [12]
= G . . 800x600 256 . . Tecmar VGA/AD
1Eh = T 132x44 . . . . . Cirrus 5320 chipset
= T 132x60 9x8 1188x480 16 1 A000 Realtek RTVGA [12]
1Fh = G 100x75 8x8 800x600 16 1 A000 Realtek RTVGA
20h = T 132x25 . . 16 . . Avance Logic AL2101
= G 40x16 . 240x128 mono . B000 HP 95LX/100LX/200LX
= G 80x30 8x16 640x480 16 . . C&T 64310/65530 BIOS
= G 120x45 8x16 960x720 16 1 A000 Realtek RTVGA
21h = T 80x25 . . mono . B000 HP 200LX
= T 132x30 . . 16 . . Avance Logic AL2101
= T 132x44 9x9 1188x396 16/256K . B800 WD90C
= T 132x44 9x9 1188x396 16 . B800 Diamond Speedstar 24X
= T 132x60 . . 16 2 B800 Tseng ET4000 chipset [10]
= G 80x43 8x8 720x348 mono . B000 DESQview 2.x+Hercules [4]
= G 128x48 8x16 1024x768 16 1 A000 Realtek RTVGA [12]
22h = T 132x43 . . . . . Allstar Peacock (VGA)
= T 132x43 . . 16 . . Avance Logic AL2101
= T 132x44 8x8 1056x352 . . B800 Tseng Labs EVA
= T 132x44 9x8 1188x352 16/256K 2 B800 Tseng ET3000 chipset
= T 132x44 8x8 1056x352 16/256K 2 B800 Tseng ET4000 chipset
= T 132x44 8x8 1056x352 . . . Ahead Systems EGA2001
= T 132x44 8x8 1056x352 16 2 B800 Ahead B
= T 132x44 8x9 1056x398 16 . . STB Lightspeed ET4000/W32P
= T 132x44 . . 16 . . Orchid Prodesigner VGA
= G 80x43 8x8 720x348 mono . B800 DESQview 2.x+Hercules [4]
= G 96x64 8x16 768x1024 16 1 A000 Realtek RTVGA
= G 100x37 8x16 800x600 16 . . C&T 64310/65530 BIOS
23h = T 132x25 6x14 792x350 . . B800 Tseng Labs EVA
= T 132x25 9x14 1188x350 16/256K 4 B800 Tseng ET3000 chipset
= T 132x25 8x14 1056x350 16/256 4 B800 Tseng ET4000 chipset
= T 132x25 8x14 1056x350 . . . Ahead Systems EGA2001
= T 132x25 8x14 1056x350 16 4 B800 Ahead B
= T 132x25 8x8 1056x200 16 . B800 ATI EGA Wonder,ATI VIP
= T 132x25 . . . . . Cirrus 5320 chipset
= T 132x28 . . . . . Allstar Peacock (VGA)
= T 132x28 . . 16 . . Orchid Prodesigner VGA
= T 132x60 . . 16 . . Avance Logic AL2101
= G 128x48 8x16 1024x768 4 1 A000 Realtek RTVGA
24h = T 80x30 . . 16 . . Avance Logic AL2101
= T 132x25 . . . . . Allstar Peacock (VGA)
= T 132x25 . . 16 . . Orchid Prodesigner VGA
= T 132x28 6x13 792x364 . . B800 Tseng Labs EVA
= T 132x28 9x13 1188x364 16/256K 4 B800 Tseng ET3000 chipset
= T 132x28 8x12 1056x336 16 1 B800 Ahead B
= T 132x28 8x13 1056x364 16/256K 4 B800 Tseng ET4000 chipset
= T 132x28 8x14 1056x392 16 . . STB Lightspeed ET4000/W32P
= T 132x28 . . . . . Cirrus 5320 chipset
= G 64x32 8x16 512x512 256 1 A000 Realtek RTVGA
= G 128x48 8x16 1024x768 16 . . C&T 64310/65530 BIOS
25h = T 80x43 . . 16 . . Avance Logic AL2101
= G 80x60 8x8 640x480 . . A000 Tseng Labs EVA
= G 80x60 8x8 640x480 16/256K 1 A000 Tseng ET3000/4000 chipset
= G . . 640x480 16 . . VEGA VGA
= G 80x60 8x8 640x480 16 . A000 Orchid Prodesigner VGA
= G 80x60 8x8 640x480 16 1 A000 Ahead B (same as 26h)
= G . . 640x480 16 . . NEC GB-1
= G . . 640x480 16 . . Cirrus 5320 chipset
= G . . 640x400 256 . . Realtek RTVGA
26h = T 80x60 8x8 640x480 . . . Tseng Labs EVA
= T 80x60 8x8 640x480 16/256K 3 B800 Tseng ET3000/4000 chipset
= T 80x60 . . . . . Allstar Peacock (VGA)
= T 80x60 . . 16 . . Orchid ProDesigner VGA
= T 80x60 . . 16 . . Avance Logic AL2101
= G 80x60 8x8 640x480 . . . Ahead Systems EGA2001
= G 80x60 8x8 640x480 16 1 A000 Ahead B (same as 25h)
= G . . 640x480 256 . . Realtek RTVGA
27h = T 132x25 8x8 1056x200 mono . B000 ATI EGA Wonder,ATI VIP
= G . . 720x512 16 . . VEGA VGA
= G . . 720x512 16 . . Genoa
= G 100x75 8x8 800x600 256 1 A000 Realtek RTVGA [12]
= G . . 960x720 16 . . Avance Logic AL2101
28h = T ???x??? . . . . . VEGA VGA
= G . . 512x512 256 . . Avance Logic AL2101
= G . . 1024x768 256 . . Realtek RTVGA (1meg)
= G 160x64 8x16 1280x1024 16 . . Chips&Technologies 64310 [1]
29h = G . . 640x400 256 . . Avance Logic AL2101
= G . . 800x600 16 . . VEGA VGA
= G 100x37 8x16 800x600 16 . A000 Orchid
= G . . 800x600 16 . A000 STB,Genoa,Sigma
= G . . 800x600 16 . . Allstar Peacock (VGA)
= G 100x37 8x16 800x600 16/256K 1 A000 Tseng ET3000/4000 chipset
= G . . 800x600 ??? . . EIZO MDB10
= G . . 800x600 16 . . Cirrus 5320 chipset
= G NA . 800x600 16 . . Compaq QVision 1024/1280
= G . . 1024x1024 256 . . Realtek RTVGA BIOS v3.C10
2Ah = T 100x40 . . . . . Allstar Peacock (VGA)
= T 100x40 8x16 800x640 16 . . Orchid Prodesigner VGA
= T 100x40 8x15 800x600 16/256K 4 B800 Tseng ET3000/4000 chipset
= T 100x40 8x15 800x600 16 . . STB Lightspeed ET4000/W32P
= G . . 640x480 256 . . Avance Logic AL2101
= G . . 1280x1024 16 . . Realtek RTVGA
2Bh = G . . 800x600 16 . . Avance Logic AL2101
2Ch = G . . 800x600 256 . . Avance Logic AL2101
2Dh = G . . 640x350 256 . . VEGA VGA
= G . . 640x350 256/256K . A000 Orchid, Genoa, STB
= G 80x25 8x14 640x350 256/256K 1 A000 Tseng ET3000/4000 chipset
= G . . 640x350 256 . . Cirrus 5320 chipset
= G 80x25 8x14 640x350 256 . . STB Lightspeed ET4000/W32P
= G . . 768x1024 16 . . Avance Logic AL2101
2Eh = G . . 640x480 256 . . VEGA VGA
= G 80x30 8x16 640x480 256/256K . A000 Orchid
= G . . 640x480 256/256K . A000 STB,Genoa,Sigma
= G 80x30 8x16 640x480 256/256K 1 A000 Tseng ET3000/4000 chipset
= G . . 640x480 256/256K . . Compaq QVision 1024/1280
= G . . 768x1024 256 . . Avance Logic AL2101
2Fh = T 160x50 8x8 1280x400 16 4 B800 Ahead B (Wizard/3270)
= G . . 720x512 256 . . VEGA VGA
= G . . 720x512 256 . . Genoa
= G 80x25 8x16 640x400 256/256K 1 A000 Tseng ET4000 chipset
= G . . 1024x768 4 . . Avance Logic AL2101
30h = G 80x30 8x16 640x480 256 . . C&T 64310/65530 BIOS
= G . . . . . B800 AT&T 6300
= G . . 720x350 2 . . 3270 PC
= G . . 800x600 256 . . VEGA VGA
= G 100x37 8x16 800x600 256/256K . A000 Orchid
= G . . 800x600 256/256K . A000 STB,Genoa,Sigma
= G . . 800x600 256 . . Cardinal
= G 100x37 8x16 800x600 256/256K 1 A000 Tseng ET3000/4000 chipset
= G . . 1024x768 16 . . Avance Logic AL2101
31h = G . . 1024x768 256 . . Avance Logic AL2101
32h = T 80x34 8x10 . 16 4 B800 Ahead B (Wizard/3270)
= G . . 640x480 256 . . Compaq QVision 1024/1280
= G 100x37 8x16 800x600 256 . . C&T 64310/65530 BIOS
33h = T 132x44 8x8 . 16 . B800 ATI EGA Wonder,ATI VIP
= T 80x34 8x8 . 16 4 B800 Ahead B (Wizard/3270)
34h = T 80x66 8x8 . 16 4 B800 Ahead B (Wizard/3270)
= G . . 800x600 256 . . Compaq QVision 1024/1280
= G 128x48 8x16 1024x768 256 . . Chips&Technologies 64310
36h = G . . 960x720 16 . . VEGA VGA, STB
= G . . 960x720 16 . A000 Tseng ET3000 only
= G . . 1280x1024 16 . . Avance Logic AL2101
37h = T 132x44 8x8 . mono . B800 ATI EGA Wonder,ATI VIP
= G . . 1024x768 16 . . VEGA VGA
= G 128x48 8x16 1024x768 16 . A000 Orchid
= G . . 1024x768 16 . A000 STB,Genoa,Sigma
= G . . 1024x768 16 . . Definicon
= G 128x48 8x16 1024x768 16 1 A000 Tseng ET3000/4000 chipset
= G . . 1024x768 16 . . Compaq QVision 1024/1280
= G . . 1280x1024 256 . . Avance Logic AL2101
38h = G . . 1024x768 256 . . STB VGA/EM-16 Plus (1MB)
= G 128x48 8x16 1024x768 256/256K 1 A000 Tseng ET4000 chipset
= G . . 1024x768 256 . . Orchid ProDesigner II
= G . . 1024x768 256 . . Compaq QVision 1024/1280
= G 160x64 8x16 1280x1024 256 . . Chips&Technologies 64310 [1]
39h = G . . 1280x1024 16 . . Compaq QVision 1280
3Ah = G . . 1280x1024 256 . . Compaq QVision 1280
3Bh = G . . 512x480 256 . . Compaq QVision 1024/1280
3Ch = G . . 640x400 64K . . Compaq QVision 1024/1280
3Dh = G . . 1280x1024 16 . . Definicon
= G 128x64 8x16 1280x1024 16 1 A000 Tseng ET4000 v3.00 [1,7]
3Eh = G . . 1280x961 16 . . Definicon
= G . . 640x480 64K . . Compaq QVision 1024/1280
3Fh = G . . 1280x1024 256 . . Hercules ??? (ET4000W32)
= G . . 800x600 64K . . Compaq QVision 1024/1280
40h = T 80x43 . . . . . VEGA VGA, Tecmar VGA/AD
= T 80x43 . . . . . Video7 V-RAM VGA
= T 80x43 . . . . . Tatung VGA
= T 100x30 . . 16 . . MORSE VGA
= T 100x30 . . . . . Cirrus 510/520 chipset
= T 80x25 . 720x350 mono . . Genoa SuperEGA BIOS 3.0+
= G . . 320x200 64K . . Avance Logic AL2101
= G 80x25 8x16 640x400 2 1 B800 AT&T 6300, AT&T VDC600
= G 80x25 8x16 640x400 2 1 B800 Olivetti Quaderno
= G 80x25 8x16 640x400 2 1 B800 Compaq Portable
= G 80x30 8x16 640x480 32K . . Chips&Technologies 64310
= G . . 1024x768 64K . . Compaq QVision 1280
41h = T 132x25 . . . . . VEGA VGA
= T 132x25 . . . . . Tatung VGA
= T 132x25 . . . . . Video7 V-RAM VGA
= T 100x50 . . 16 . . MORSE VGA
= T 100x50 . . . . . Cirrus 510/520 chipset
= T 80x34 9x14 720x476 16/256K . B800 WD90C
= T 80x34 9x14 . 16 . B800 Diamond Speedstar 24X
= G . . 512x512 64K . . Avance Logic AL2101
= G . . 640x200 16 1 . AT&T 6300
= G 80x30 8x16 640x480 64K . . Chips&Technologies 64310
= G 80x25 . 720x348 mono . B000 Genoa SuperEGA BIOS 3.0+
42h = T 132x43 . . . . . VEGA VGA
= T 132x43 . . . . . Tatung VGA
= T 132x43 . . . . . Video7 V-RAM VGA
= T 80x34 9x10 . 4 4 B800 Ahead B (Wizard/3270)
= T 100x60 . . 16 . . MORSE VGA
= T 100x60 . . . . . Cirrus 510/520 chipset
= G 80x25 8x16 640x400 16 . . AT&T 6300, AT&T VDC600
= G . . 640x400 64K . . Avance Logic AL2101
= G 80x25 . 720x348 mono . B800 Genoa SuperEGA BIOS 3.0+
= G 100x37 8x16 800x600 32K . . Chips&Technologies 64310
43h = T 80x60 . . . . . VEGA VGA
= T 80x60 . . . . . Tatung VGA
= T 80x60 . . . . . Video7 V-RAM VGA
= T 80x45 9x8 . 4 4 B800 Ahead B (Wizard/3270)
= T 100x75 . . 16 . . MORSE VGA
= T 80x29 . 720x348 mono . . Genoa SuperEGA BIOS 3.0+
= G . . 640x200 of 640x400 viewport AT&T 6300 (unsupported)
= G . . 640x480 64K . . Avance Logic AL2101
= G 100x37 8x16 800x600 64K . . Chips&Technologies 64310
44h = disable VDC and DEB output . AT&T 6300
= T 100x60 . . . . . VEGA VGA
= T 100x60 . . . . . Tatung VGA
= T 100x60 . . . . . Video7 V-RAM VGA
= T 80x32 . 720x352 mono . . Genoa SuperEGA BIOS 3.0+
= G . . 800x600 64K . . Avance Logic AL2101
45h = T 132x28 . . . . . Tatung VGA
= T 132x28 . . . . . Video7 V-RAM VGA
= T 80x44 . 720x352 mono . . Genoa SuperEGA BIOS 3.0+
46h = T 132x25 8x14 . mono . . Genoa 6400
= T 132x25 9x14 . mono . . Genoa SuperEGA BIOS 3.0+
= G 100x40 8x15 800x600 2 . . AT&T VDC600
47h = T 132x29 8x12 . mono . . Genoa 6400
= T 132x29 9x12 . mono . . Genoa SuperEGA BIOS 3.0+
= T 132x28 9x16 1188x448 16/256K . B800 WD90C
= T 132x28 9x16 . 16 . B800 Diamond Speedstar 24X
= G 100x37 8x16 800x600 16 . . AT&T VDC600
48h = T 132x32 8x12 . mono . . Genoa 6400
= T 132x32 9x11 . mono . . Genoa SuperEGA BIOS 3.0+
= G 80x50 8x8 640x400 2 . B800 AT&T 6300, AT&T VDC600
= G 80x50 8x8 640x400 2 . B800 Olivetti Quaderno
49h = T 132x44 8x8 . mono . . Genoa 6400
= T 132x44 9x8 . mono . . Genoa SuperEGA BIOS 3.0+
= G 80x30 8x16 640x480 . . . Lava Chrome II EGA
= G 80x30 8x16 640x480 . . A000 Diamond Stealth64 Video 2xx1
4Bh = G 100x37 8x16 800x600 . . A000 Diamond Stealth64 Video 2xx1
4Dh = T 120x25 . . . . . VEGA VGA
= G . . 512x480 16M . . Compaq QVision 1024/1280
= G 128x48 8x16 1024x768 . . A000 Diamond Stealth64 Video 2xx1
4Eh = T 120x43 . . . . . VEGA VGA
= T 80x60 8x8 . 16/256K . B800 Oak OTI-067/OTI-077 [8]
= G . . 640x400 16M . . Compaq QVision 1024/1280
= G 144x54 8x16 1152x864 . . A000 Diamond Stealth64 Video 2xx1
4Fh = T 132x25 . . . . . VEGA VGA
= T 132x60 . . . . . some Oak Tech VGA [8]
= G . . 640x480 16M . . Compaq QVision 1280
50h = T 80x30 8x16 . 16/256K . B800 Trident TVGA 8800/8900
= T 80x34 . . . . . Lava Chrome II EGA
= T 80x43 . . mono . . VEGA VGA
= T 132x25 9x14 . mono . . Ahead Systems EGA2001
= T 132x25 9x14 . 4 4 B800 Ahead B
= T 132x25 8x14 . 16 8 B800 OAK Technologies VGA-16
= T 132x25 8x14 . 16/256K . B800 Oak OTI-037/067/077 [8]
= T 132x25 8x14 1056x350 16 8 B800 UM587 chipset
= T 132x30 . . 16 . . MORSE VGA
= T 132x30 . . . . . Cirrus 510/520 chipset
= G 80x30 8x16 640x480 16 . . Paradise EGA-480
= G 80x30 8x16 640x480 16 . . NEL Electronics BIOS
= G 80x30 8x16 640x480 16M . . Chips&Technologies 64310
= G . . 640x480 mono??? . . Taxan 565 EGA
= G 40x25 8x8 320x200 . . . Genoa SuperEGA BIOS 3.0+
51h = T 80x30 8x16 . . . . Paradise EGA-480
= T 80x30 9x16 . . . . NEL Electronics BIOS
= T 80x30 . . . . . Lava Chrome II EGA
= T 80x43 8x11 . 16/256K . B800 Trident TVGA 8800/8900
= T 132x25 . . mono . . VEGA VGA
= T 132x28 9x12 . 4 4 B800 Ahead B
= T 132x43 8x8 . 16 5 B800 OAK Technologies VGA-16
= T 132x43 8x8 . 16/256K . B800 Oak OTI-037/067/077
= T 132x43 8x8 1056x344 16 5 B800 UM587 chipset
= T 132x50 . . 16 . . MORSE VGA
= T 132x50 . . . . . Cirrus 510/520 chipset
= G 80x34 8x14 640x480 16 . . ATI EGA Wonder
= G 80x25 8x8 640x200 . . . Genoa SuperEGA BIOS 3.0+
52h = T 80x60 . . . . . Lava Chrome II EGA
= T 80x60 8x8 . 16/256K . B800 Trident TVGA 8800/8900
= T 132x43 . . mono . . VEGA VGA
= T 132x44 9x8 . mono . . Ahead Systems EGA2001
= T 132x44 9x8 . 4 2 B800 Ahead B
= T 132x60 . . 16 . . MORSE VGA
= T 132x60 . . . . . Cirrus 510/520 chipset
= G 80x25 8x19 640x480 16 1 A000 AX VGA (Kanji&superimpose)
= G 94x29 8x14 752x410 16 . . ATI EGA Wonder
= G 100x75 8x8 800x600 16 1 A000 OAK Technologies VGA-16
= G 100x75 8x8 800x600 16 . A000 Oak OTI-037 chipset [8]
= G 100x37 8x16 800x600 16 . A000 Oak OTI-067/077 chips [8]
= G 100x75 8x8 800x600 16 . A000 UM587 chipset
= G 128x30 8x16 1024x480 16 . . NEL Electronics BIOS
53h = T 80x25 8x16 . . . . NEL Electronics BIOS
= T 80x60 . . 16 . . MORSE VGA
= T 80x60 . . . . . Cirrus 510/520 chipset
= T 132x25 8x14 . 16/256K . B800 Trident TVGA 8800/8900
= T 132x43 . . . . . Lava Chrome II EGA
= G 80x25 8x19 640x480 16 1 A000 AX VGA (Kanji, no superimp.)
= G . . 640x480 256 . . Oak VGA
= G 80x30 8x16 640x480 256 . A000 Oak OTI-067/OTI-077 [8]
= G 100x40 8x14 800x560 16 . . ATI EGA Wonder,ATI VIP
= G . . . . . . AX PC
54h = T 132x25 . . . . . Lava Chrome II EGA
= T 132x30 8x16 . 16/256K . B800 Trident TVGA 8800/8900
= T 132x43 8x8 . . . . Paradise EGA-480
= T 132x43 8x8 . . . . NEL Electronics BIOS
= T 132x43 7x9 . 16/256K . B800 Paradise VGA
= T 132x43 8x9 . 16/256K . B800 Paradise VGA on multisync
= T 132x43 . . . . . Taxan 565 EGA
= T 132x43 . . . . . AST VGA Plus
= T 132x43 . . . . . Hewlett-Packard D1180A
= T 132x43 7x9 . 16 . . AT&T VDC600
= T 132x43 9x9 1188x387 16/256K . B800 WD90C
= T 132x43 9x9 1188x387 16/256K . B800 Diamond Speedstar 24X
= T 132x43 9x9 1188x387 16/256K . B800 Diamond Stealth 24
= T 132x43 8x8 . . . B800 Diamond Stealth64 Video 2xx1
= T 132x43 8x8 1056x350 16/256K . . Cirrus CL-GD5420/5422/5426
= T 132x50 8x8 . 16 . A000 NCR 77C22 [9]
= G 100x42 8x14 800x600 16 . A000 ATI EGA Wonder, VGA Wonder
= G 100x42 8x14 800x600 16 . A000 ATI Ultra 8514A, ATI XL
= G . . 800x600 256 . A000 Oak VGA
= G 100x37 8x16 800x600 256 . A000 Oak OTI-067/077 chips [8]
55h = T 80x66 8x8 . 16/256K . A000 ATI VIP
= T 132x25 8x14 . . . . Paradise EGA-480
= T 132x25 8x14 . . . . NEL Electronics BIOS
= T 132x25 7x16 . 16/256K . B800 Paradise VGA
= T 132x25 8x16 . 16/256K . B800 Paradise VGA on multisync
= T 132x25 . . . . . Taxan 565 EGA
= T 132x25 . . . . . AST VGA Plus
= T 132x25 . . . . . Hewlett-Packard D1180A
= T 132x25 7x16 . 16 . . AT&T VDC600
= T 132x25 8x16 . 16 . A000 NCR 77C22 [9]
= T 132x25 9x16 1188x400 16/256K . B800 WD90C
= T 132x25 9x16 1188x400 16/256K . B800 Diamond Speedstar 24X
= T 132x25 9x16 1188x400 16/256K . B800 Diamond Stealth 24
= T 132x25 8x16 . . . B800 Diamond Stealth64 Video 2xx1
= T 132x25 8x14 1056x350 16/256K . . Cirrus CL-GD5420/5422/5426
= T 132x43 8x11 . 16/256K . B800 Trident TVGA 8800/8900
= G 94x29 8x14 752x410 . . . Lava Chrome II EGA
= G 128x48 8x16 1024x768 16/256K . A000 ATI VGA Wonder v4+ [5]
= G . . 1024x768 16/256K . . ATI VGA Wonder Plus
= G . . 1024x768 16/256K . . ATI Ultra 8514A,ATI XL
= G 128x48 8x16 1024x768 4 . A000 Oak OTI-067/077 chips [8]
56h = T 132x43 8x8 . 3??? 2 B000 NSI Smart EGA+
= T 132x43 7x9 . 4 . B000 Paradise VGA
= T 132x43 8x9 . 4 . B000 Paradise VGA on multisync
= T 132x43 . . mono . . Taxan 565 EGA
= T 132x43 7x9 . 2 . . AT&T VDC600
= T 132x43 9x8 . . . . NEL Electronics BIOS
= T 132x50 8x8 . 4 . A000 NCR 77C22 [9]
= T 132x60 8x8 . 16/256K . B800 Trident TVGA 8800/8900
= G . . 1024x768 16 . A000 Oak VGA
= G 128x48 8x16 1024x768 16 . A000 Oak OTI-067/077 chips [8]
57h = T 132x25 8x14 . 3??? 4 B000 NSI Smart EGA+
= T 132x25 7x16 . 4 . B000 Paradise VGA
= T 132x25 8x16 . 4 . B000 Paradise VGA on multisync
= T 132x25 9x14 . . . . NEL Electronics BIOS
= T 132x25 . . mono . . Taxan 565 EGA
= T 132x25 7x16 . 2 . . AT&T VDC600
= T 132x25 9x14 . 16/256K . B800 Trident TVGA 8800/8900
= T 132x25 8x16 . 4 . A000 NCR 77C22 [9]
= G 96x48 8x16 768x1024 16 . A000 Oak OTI-067/077 chips [8]
58h = T 80x33 8x14 . 16 . B800 ATI EGA Wonder,ATI VIP
= T 80x32 9x16 . 16 . . Genoa 6400
= T 80x43 8x8 . . . . NEL Electronics BIOS
= T 132x30 9x16 . 16/256K . B800 Trident TVGA 8800/8900
= G 100x75 8x8 800x600 16/256K . A000 Paradise VGA
= G 100x75 8x8 800x600 16 . . AT&T VDC600
= G 100x75 8x8 800x600 16 . A000 NCR 77C22 [9]
= G 100x75 8x8 800x600 16 . A000 Diamond Speedstar 24X
= G 100x75 8x8 800x600 16/256K . A000 Paradise VGA, WD90C
= G . . 800x600 16 . . AST VGA Plus, Compaq VGA
= G . . 800x600 16 . . Dell VGA
= G . . 800x600 16 . . Hewlett-Packard D1180A
= G . . 800x600 ??? . . ELT VGA PLUS 16
= G 100x37 8x16 800x600 16/256K . A000 Cirrus CL-GD5420/5422/5426
= G 160x64 8x16 1280x1024 16 . A000 Oak OTI-077 chipset [8]
59h = T 80x43 9x8 . . . . NEL Electronics BIOS
= T 80x66 8x8 . 16/256K . A000 ATI VIP
= T 132x43 9x11 . 16/256K . B800 Trident TVGA 8800/8900
= G 100x75 8x8 800x600 2 . A000 Paradise VGA
= G 100x75 8x8 800x600 2 . . AT&T VDC600
= G . . 800x600 2 . . AST VGA Plus, Compaq VGA
= G . . 800x600 2 . . Dell VGA
= G . . 800x600 2 . . Hewlett-Packard D1180A
= G 100x75 8x8 800x600 2 . A000 NCR 77C22 [9]
= G 128x48 8x16 1024x768 256 . A000 Oak OTI-077 chipset [8]
5Ah = T 80x60 8x8 . . . . NEL Electronics BIOS
= T 132x60 9x8 . 16/256K . B800 Trident TVGA 8800/8900
= G 128x48 8x16 1024x768 2 . A000 NCR 77C22 [9]
5Bh = T 80x30 8x16 . . . B800 ATI VGA Wonder (undoc)
= G . . 640x350 256 . . Genoa 6400
= G 80x25 8x16 640x400 32K . A000 Oak OTI-067/077 chips [8]
= G . . 800x600 16 . . Maxxon, SEFCO TVGA, Imtec
= G 100x75 8x8 800x600 16/256K . A000 Trident TVGA 8800, 8900
= G . . 800x600 ??? . . Vobis MVGA
= G 100x37 8x16 800x600 . . . NEL Electronics BIOS
= G 128x48 8x16 1024x768 16 . A000 NCR 77C22 [1,9]
5Ch = T 100x37 8x16 . . . . NEL Electronics BIOS
= G . . 640x400 256 . . Logix, ATI Prism Elite
= G . . 640x400 256 . . Maxxon, SEFCO TVGA, Imtec
= G 80x25 8x16 640x400 256/256K . A000 Zymos Poach, Hi Res 512
= G 80x25 8x16 640x400 256/256K . A000 Trident TVGA 8800/8900
= G 80x30 8x16 640x480 256 . . Genoa 6400
= G 80x30 8x16 640x480 32K . A000 Oak OTI-077 chipset [8]
= G 100x75 8x8 800x600 256 . A000 NCR 77C22 [9]
= G 100x75 8x8 800x600 256/256K . A000 WD90C
= G 100x75 8x8 800x600 256/256K . A000 Diamond Speedstar 24X
= G 100x37 8x16 800x600 256/256K . A000 Cirrus CL-GD5420/5422/5426
5Dh = T 100x75 8x8 . . . . NEL Electronics BIOS
= G 80x25 8x14 640x350 64K . . STB Lightspeed ET4000/W32P
= G . . 640x480 256 . . Logix, ATI Prism Elite
= G . . 640x480 256 . . Maxxon, SEFCO TVGA, Imtec
= G 80x30 8x16 640x480 256/256K . A000 Zymos Poach, Hi Res 512
= G 80x30 8x16 640x480 256/256K . A000 Trident TVGA 8800 (512K)
= G 128x48 8x16 1024x768 16 . A000 NCR 77C22 [9]
= G 128x48 8x16 1024x768 16/256K . A000 WD90C
= G 128x48 8x16 1024x768 16 . A000 Diamond Speedstar 24X
= G 128x48 8x16 1024x768 16/256K . A000 Cirrus CL-GD5420/5422/5426
5Eh = G . . 640x400 256 . . Paradise VGA,VEGA VGA
= G . . 640x400 256 . . AST VGA Plus, NCR 77C22
= G . . 640x400 256 . . Compaq VGA, Dell VGA
= G 80x25 8x16 640x400 256 . . AT&T VDC600
= G 80x25 8x16 640x400 256 . A000 NCR 77C22 [9]
= G 80x25 8x16 640x400 256/256K . A000 WD90C
= G 80x25 8x16 640x400 256/256K . A000 Diamond Speedstar 24X
= G . . 800x600 16 . . Logix, ATI Prism Elite
= G 100x37 8x16 800x600 16 . . NEL Electronics BIOS
= G 100x75 8x8 800x600 256 . . Genoa 6400
= G 100x75 8x8 800x600 256/256K . A000 Zymos Poach, Trident 8900
= G 100x75 8x8 800x600 256/256K . A000 Hi Res 512
5Fh = G 80x25 8x16 640x400 64K . . STB Lightspeed ET4000/W32P
= G . . 640x480 256 . . Paradise VGA
= G . . 640x480 256 . . AST VGA Plus, NCR 77C22
= G . . 640x480 256 . . Compaq VGA, Dell VGA
= G . . 640x480 256 . . Hewlett-Packard D1180A
= G 80x30 8x16 640x480 256 . . AT&T VDC600 (512K)
= G 80x30 8x16 640x480 256 . A000 NCR 77C22 [9]
= G 80x30 8x16 640x480 256/256K . A000 WD90C
= G 80x30 8x16 640x480 256/256K . A000 Diamond Speedstar 24X
= G 80x30 8x16 640x480 256/256K . A000 Cirrus CL-GD5420/5422/5426
= G . . 1024x768 16 . . Logix, ATI Prism Elite
= G . . 1024x768 16 . . Maxxon, Imtec
= G 128x48 8x16 1024x768 16 . . Genoa 6400
= G 128x48 8x16 1024x768 16/256K . A000 Zymos Poach, Hi Res 512
= G 128x48 8x16 1024x768 16/256K . A000 Trident TVGA 88/8900 512K
60h = T 132x25 8x14 . 16/64 8 B800 Quadram Ultra VGA
= T 132x25 8x14 . 16 . . Genoa 6400
= T 132x25 8x14 . 16 . . Genoa SuperEGA BIOS 3.0+
= T 132x25 . . . . . Cirrus 5320 chipset
= T 132x25 8x16 1056x400 16 . B800 Chips&Technologies chipset
= G 80x??? . ???x400 . . . Corona/Cordata BIOS 4.10+
= G 80x25 8x16 640x400 256 1 A000 Ahead A, Ahead B
= G . . 752x410 . . . VEGA VGA
= G . . 752x410 16 . . Tatung VGA
= G . . 752x410 16 . . Video7 V-RAM VGA
= G 128x48 8x16 1024x768 4/256K . A000 Trident TVGA 8900
= G 128x48 8x16 1024x768 256/256K . A000 WD90C
= G 128x48 8x16 1024x768 256/256K . A000 Diamond Speedstar 24X
= G 128x48 8x16 1024x768 256/256K . A000 Cirrus CL-GD5420/5422/5426
= G 144x54 8x16 1152x864 . . A000 Diamond Stealth64 Video 2xx1
61h = T 132x29 8x12 . 16/64 8 B800 Quadram Ultra VGA
= T 132x29 8x8 . 16 . . Genoa 6400
= T 132x29 8x8 . 16 . . Genoa SuperEGA BIOS 3.0+
= T 132x50 . . . . . Cirrus 5320 chipset
= T 132x50 8x8 1056x400 16 . B800 Chips&Technologies chipset
= T 132x50 8x16 1056x800 16 . B800 Chips&Technologies 64310
= G . . ???x400 . . . Corona/Cordata BIOS 4.10+
= G 80x25 8x16 640x400 256 . A000 ATI VGA Wonder,VGA Wonder+
= G 80x25 8x16 640x400 256 . A000 ATI Ultra 8514A,ATI XL
= G 80x25 8x16 640x400 . . A000 Diamond Stealth64 Video 2xx1
= G 80x30 8x16 640x480 256 1 A000 Ahead A, Ahead B (512K)
= G . . 720x540 . . . VEGA VGA
= G . . 720x540 16 . . Tatung VGA
= G . . 720x540 16 . . Video7 V-RAM VGA
= G 96x64 8x16 768x1024 16/256K . A000 Trident TVGA 88/8900 512K
= G 128x48 8x16 1024x768 256 . A000 NCR 77C22 [1,9]
= G 144x54 8x16 1152x864 . . A000 Diamond Stealth64 Video 2xx1
62h = T 132x32 8x11 . 16/64 6 B800 Quadram Ultra VGA
= T 132x32 8x12 . 16 . . Genoa 6400
= T 132x32 8x11 . 16 . . Genoa SuperEGA BIOS 3.0+
= T 132x43 8x8 1056x344 16 . B800 C&T 82C450 BIOS
= G . . 640x450 16 . . Cirrus 510/520 chipset
= G 80x30 8x16 640x480 256 . A000 ATI VGA Wonder,VGA Wonder+
= G 80x30 8x16 640x480 256 . A000 ATI Ultra 8514A,ATI XL
= G 80x30 8x16 640x480 32K . A000 WD90C
= G 80x30 8x16 640x480 32K . A000 Diamond Speedstar 24X
= G . . 800x600 . . . VEGA VGA
= G . . 800x600 16 . . Tatung VGA
= G . . 800x600 16 . . Video7 V-RAM VGA
= G 100x75 8x8 800x600 256 1 A000 Ahead A, Ahead B (512K)
= G 128x48 8x16 1024x768 256/256K . A000 Trident TVGA 8900, Zymos
= G 128x48 8x16 1024x768 256 . A000 NCR 77C22 [9]
63h = T 132x44 8x8 . 16/64 5 B800 Quadram Ultra VGA
= T 132x44 8x8 . 16 . . Genoa 6400
= T 132x44 8x8 . 16 . . Genoa SuperEGA BIOS 3.0+
= G . . 720x540 16 . . MORSE VGA
= G . . 720x540 16 . . Cirrus 510/520 chipset
= G 100x42 8x14 800x600 256 . A000 ATI VGA Wonder,VGA Wonder+
= G 100x42 8x14 800x600 256 . A000 ATI Ultra 8514A,ATI XL
= G . . 800x600 32K . A000 WD90C
= G . . 800x600 32K . A000 Diamond Speedstar 24X
= G 128x48 7x16 1024x768 256 1 A000 Ahead B (1MB)
= G . . 1024x768 2 . . Video7 V-RAM VGA
64h = T 132x60 8x8 . 16 . . Genoa 6400
= T 80x43 8x8 528x344 16 . B800 C&T 82C450 BIOS
= G . . 640x480 64K . A000 Cirrus CL-GD 5422/5426
= G . . 800x600 16 . . MORSE VGA
= G . . 800x600 16 . . Cirrus 510/520 chipset
= G . . 800x600 ??? . . SAMPO-Mira VGA
= G . . 1024x768 4 . . Video7 V-RAM VGA
= G 128x48 8x16 1024x768 256 . A000 ATI VGA Wonder Plus,ATI XL
= G 160x64 8x16 1280x1024 16/256K . A000 WD90C [1]
= G 160x64 8x16 1280x1024 16/256K . A000 Diamond Speedstar 24X [1]
65h = T 80x50 8x8 528x400 16 . B800 C&T 82C450 BIOS
= G . . 800x600 64K . A000 Cirrus CL-GD 5422/5426
= G . . 1024x768 16 . . Video7 V-RAM VGA
= G 128x48 8x16 1024x768 16 . A000 ATI VGA Wonder
66h = T 80x50 8x8 640x400 16/256K . B800 WD90C
= T 80x50 8x8 . 16 . B800 Diamond Speedstar 24X
= G . . 640x400 256 . . Tatung VGA
= G . . 640x400 256 . . Video7 V-RAM VGA
= G . . 640x480 32K . A000 Cirrus CL-GD 5422/5426
67h = T 80x43 8x8 640x344 16/256K . B800 WD90C
= T 80x43 8x8 . 16 . B800 Diamond Speedstar 24X
= G . . 640x480 256 . . Video7 V-RAM VGA
= G . . 800x600 32K . A000 Cirrus CL-GD 5422/5426
= G 128x48 8x16 1024x768 4 . A000 ATI VGA Wonder
= G 160x64 8x16 1280x1024 16 . A000 NCR 77C22 [1,9]
68h = G 80x25 8x16 640x400 . . A000 Diamond Stealth64 Video 2xx1
69h = T 132x50 8x8 1056x400 16/256K . B800 WD90C
= T 132x50 8x8 . 16 . B800 Diamond Speedstar 24X
= G 80x30 8x16 640x480 . . A000 Diamond Stealth64 Video 2xx1
= G . . 720x540 256 . A000 Video7 V-RAM VGA
6Ah = G . . 800x600 16 . A000 VESA standard interface
= G 100x75 8x8 800x600 16 . A000 Genoa 6400
= G 100x75 8x8 800x600 16 . A000 Diamond Speedstar 24X
= G . . 800x600 16 . A000 Ahead A
= G 100x75 8x8 800x600 16 1 A000 Ahead B (VESA) [see 71h]
= G . . 800x600 16 . . Zymos Poach, Hi Res 512
= G . . 800x600 16 . . Epson LT-386SX in CRT Mode
= G . . 800x600 16 . . Compuadd 316SL in CRT Mode
= G 100x37 8x16 800x600 16/256K . A000 Cirrus CL-GD5420/5422/5426
= G 100x37 8x16 800x600 16 . A000 Diamond Stealth64 Video 2xx1
= G 100x42 8x14 800x600 . . A000 ATI VGA Wonder (undoc)
= G . . 800x600 16 . A000 Chips&Technologies chipset
= G 160x64 8x16 1280x1024 256 . A000 NCR 77C22 [1,9]
6Bh = T 100x37 8x16 . 16 . . Genoa 6400
= T 100x37 8x16 . . . . NEL Electronics BIOS
= G 100x37 8x16 800x600 . . A000 Diamond Stealth64 Video 2xx1
6Ch = G 80x30 8x16 640x480 16M . A000 Trident 8900CL/BIOS C04
= G 100x75 8x8 800x600 256 . . Genoa 6400
= G 128x48 8x16 1024x768 2 . A000 Diamond Stealth64 Video 2xx1
= G 160x60 8x16 1280x960 16/256K . A000 WD90C [1]
= G 160x60 8x16 1280x960 16/256K . A000 Diamond Speedstar 24X [1]
= G 160x64 8x16 1280x1024 16/256K . A000 Cirrus CL-GD 5422/5426 [1]
6Dh = G 80x25 8x14 640x350 64K . A000 STB Lightspeed ET4000/W32P
= G 128x48 8x16 1024x768 . . A000 Diamond Stealth64 Video 2xx1
= G 160x64 8x16 1280x1024 256/256K . A000 Cirrus CL-GD 5422/5426 [1]
6Eh = G 40x25 8x8 320x200 64K . A000 Cirrus CL-GD 5422/5426
= G 160x64 8x16 1280x1024 2 . A000 Diamond Stealth64 Video 2xx1
6Fh = G 40x25 8x8 320x200 16M . A000 Cirrus CL-GD 5422/5426
= G 160x64 8x16 1280x1024 . . A000 Diamond Stealth64 Video 2xx1
70h = extended mode set (see AX=0070h) . Everex Micro Enhancer EGA
= T 40x25 8x8 . 16 8 B800 Quadram (CGA double scan)
= T 40x25 8x8 (CGA dblscan) . . Genoa SuperEGA BIOS 3.0+
= G . . 360x480 256 . . Cirrus 510/520/5320 chips
= G 90x28 8x14 720x392 16 1 A000 Ahead B
= G 80x30 8x16 640x480 . . A000 Diamond Stealth64 Video 2xx1
= G 100x38 8x16 800x600 16 . A000 C&T chipset, Cardinal
= G . . 1024x480 256 . A000 Trident 8900C BIOS C3.0
71h = T 80x25 8x8 . 16 8 B800 Quadram (CGA double scan)
= T 80x25 8x8 (CGA dblscan) . . Genoa SuperEGA BIOS 3.0+
= G . . 528x400 256 . . Cirrus 510/520 chipset
= G 80x30 8x16 640x480 16M . A000 Cirrus CL-GD 5422/5426
= G 80x30 8x16 640x480 . . A000 Diamond Stealth64 Video 2xx1
= G 100x35 8x16 800x600 16/64 . A000 NSI Smart EGA+
= G 100x75 8x8 800x600 16 1 A000 Ahead B (same as 6Ah)
= G . . 960x720 16 . . C&T chipset, Cardinal
= G . . 1024x480 256 . A000 Trident 8900C BIOS C3.0
72h = T 80x60 8x8 . 16 . B800 Quadram Ultra VGA
= T 80x60 8x8 . 16 . B800 Genoa 6400
= T 80x60 8x8 . 16 . B800 Genoa SuperEGA BIOS 3.0+
= G . . 528x480 256 . . Cirrus 510/520 chipset
= G 80x25 8x19 640x480 16 1 A000 DOS/V w/ any VGA
= G 80x30 8x16 640x480 . . A000 Diamond Stealth64 Video 2xx1
= G . . 640x480 32K . A000 ATI
= G . . 640x480 16M . A000 WD90C
= G . . 640x480 16M . A000 Diamond Speedstar 24X
= G . . 1024x768 16 . . C&T chipset, Cardinal
= G 128x48 8x16 1024x768i 16 . A000 C&T 82C450 BIOS
= G 128x48 8x16 1024x768 16 . A000 C&T 65530 BIOS (multisync)
73h = G 80x60 8x8 640x480 16 . A000 Quadram Ultra VGA
= G 80x60 8x8 640x480 16 . . Genoa 6400
= G 80x60 8x8 640x480 16 . . Genoa SuperEGA BIOS 3.0+
= G 100x37 8x16 800x600 . . A000 Diamond Stealth64 Video 2xx1
= T 80x25 8x19 640x475 16 1 none DOS/V, emulated in VGA graph
74h = T 80x66 8x8 . 16 . B800 Quadram Ultra VGA
= T 80x66 8x8 . 16 . B800 Genoa 6400
= T 80x66 8x8 . 16 . B800 Genoa SuperEGA BIOS 3.0+
= G . . 640x400 2 . B800 Toshiba 3100 AT&T mode
= G 80x30 8x16 640x480 32K . A000 Trident 8900C/BIOS C03
= G 100x37 8x16 800x600 . . A000 Diamond Stealth64 Video 2xx1
= G 128x48 8x16 1024x768 16 1 A000 Ahead A, Ahead B (512K)
= G . . 1024x768 64K . A000 Cirrus CL-GD 5422/5426 [1]
75h = G 80x30 8x16 640x480 64K . A000 Trident 8900C/BIOS C03
= G 80x66 . 640x528 16??? . A000 Quadram Ultra VGA
= G 80x66 . 640x528 16 . . Genoa SuperEGA BIOS 3.0+
= G 100x37 8x16 800x600 . . A000 Diamond Stealth64 Video 2xx1
= G 128x48 8x16 1024x768 4 1 A000 Ahead B
= G 128x48 8x16 1024x768 16 . A000 Chips&Technologies 64310
76h = T 94x29 8x14 . 16 . B800 Quadram Ultra VGA
= T 94x29 8x14 . . . . Genoa SuperEGA BIOS 3.0+
= G 100x75 8x8 800x600 32K . A000 Trident 8900C/BIOS C03
= G 128x48 8x16 1024x768 2 1 A000 Ahead B
= G 128x48 8x16 1024x768 . . A000 Diamond Stealth64 Video 2xx1
= G 160x64 8x16 1280x1024 16 . A000 Chips&Technologies 64310 [1]
77h = G 94x29 . 752x410 16??? . A000 Quadram Ultra VGA
= G 94x29 . 752x410 16 . . Genoa SuperEGA BIOS 3.0+
= G 100x75 8x8 800x600 64K . A000 Trident 8900C/BIOS C03
= G 128x48 8x16 1024x768 . . A000 Diamond Stealth64 Video 2xx1
78h = T 100x37 8x16 . 16 . . Genoa 6400
= T 100x75 8x8 . 16 . B800 Quadram Ultra VGA
= T 100x75 8x8 . . . . Genoa SuperEGA BIOS 3.0+
= G . . 640x400 256 . . STB VGA/EM-16 Plus
= G 80x25 8x16 640x400 256 . . Cardinal, C&T chipset
= G . . 640x400 256 . . Cirrus 5320 chipset
= G 80x25 8x16 640x400 256 . A000 Chips&Technologies 64310
79h = G 80x30 8x16 640x480 256 . . Cardinal, C&T chipset
= G 80x30 8x16 640x480 256 . A000 Chips&Technologies 64310
= G 100x75 . 800x600 16??? . A000 Quadram Ultra VGA
= G 100x75 8x8 800x600 16 . . Genoa SuperEGA BIOS 3.0+
= G 100x75 8x8 800x600 16 . . Genoa 6400
7Ah = T 114x60 8x8 . 16 . B800 Quadram Ultra VGA
= T 114x60 8x8 . . . . Genoa SuperEGA BIOS 3.0+
= G . . 720x540 256 . . C&T chipset, Cardinal
7Bh = G . . 800x600 256 . . C&T chipset, Cardinal
= G 114x60 . 912x480 16??? . A000 Quadram Ultra VGA
= G . . 912x480 16 . . Genoa SuperEGA BIOS 3.0+
7Ch = G . . 512x512 16 . . Genoa
= G 100x37 8x16 800x600 256 . . C&T 82C453/F65530 chipsets
= G 100x37 8x16 800x600 256 . A000 Chips&Technologies 64310
= G 200x75 8x16 1600x1200 . [16] . A000 Diamond Stealth64 Video 2xx1
7Dh = G 64x32 8x16 512x512 256 . . Genoa
7Eh = special mode set (see AX=007Eh) . Paradise VGA, AT&T VDC600
= G 80x25 8x16 640x400 256 . . Genoa 6400
= G . . 1024x768 256 . . C&T 82C453 chipset
= G 128x48 8x16 1024x768 256 . A000 Chips&Technologies 64310
= G 90x43 . . mono . B000 HERCULES.COM on HGC [14]
7Fh = special function set (see AX=007Fh/BH=00h) Paradise VGA, AT&T VDC600
= G 128x48 8x16 1024x768 4 . . Genoa 6400
= G 90x29 . . mono . B000 HERCULES.COM on HGC [14]
82h = T 80x25 . . B&W . . AT&T VDC overlay mode [6]
83h = T 80x25 . . . . . AT&T VDC overlay mode [6]
86h = G . . 640x200 B&W . . AT&T VDC overlay mode [6]
88h = G 90x43 8x8 720x348 mono . B000 Hercules + MSHERC.COM
C0h = G . . 640x400 2/prog palette . AT&T VDC overlay mode [6]
= G . . 640x400 2/prog palette . Olivetti Quaderno overlay
C4h = disable output . . . . AT&T VDC overlay mode [6]
C8h = G 80x50 8x8 640x400 2 . B800 Olivetti Quaderno overlay
D0h = G . . 640x400 2 . B800 DEC VAXmate AT&T mode
Notes:
[1] interlaced only
[2] for ATI EGA Wonder, mode 08h is only valid if SMS.COM is loaded resident.
SMS maps mode 08h to mode 27h if the byte at location 0040:0063 is 0B4h,
otherwise to mode 23h, thus selecting the appropriate (monochrome or
color) 132x25 character mode.
for ATI VGA Wonder, mode 08h is the same, and only valid if VCONFIG loaded
resident
[3] early XGA boards support 132-column text but do not have this BIOS mode
[4] DESQview intercepts calls to change into these two modes (21h is page 0,
22h is page 1) even if there is no Hercules graphics board installed
[5] ATI BIOS v4-1.00 has a text-scrolling bug in this mode
[6] for AT&T VDC overlay modes, BL contains the DEB mode, which may be 06h,
40h, or 44h
[7] BIOS text support is broken in this undocumented mode; scrolling moves
only about 1/3 of the screen (and does even that portion incorrectly),
while screen clears only clear about 3/4.
[8] The Oak OTI-037/067/077 modes are present in the Oak VGA BIOS, which OEMs
may choose to use only partially or not at all; thus, not all Oak boards
support all "Oak" modes listed here
[9] this card uses the full 128K A000h-BFFFh range for the video buffer,
precluding the use of a monochrome adapter in the same system
[10] mode 17h supported by Tseng ET4000 BIOS 8.01X dated 1990/09/14, but not
v8.01X dated 1992/02/28; mode 21h supported by 1992/02/28 version but not
1990/09/14 version
[11] HERKULES simulates a 90x45 text mode in Hercules graphics mode; the
installation check for HERKULES.COM is the signature "Herkules" two
bytes beyond the INT 10 handler
[12] The Realtek RTVGA BIOS v3.C10 crashes when attempting to switch into
modes 21h or 27h; this version of the BIOS also sets the BIOS data area
incorrectly for extended text modes, resulting in scrolling after only
24 lines (the VMODE.EXE utility does set the data area correctly)
[13] The Tandy 1000SL/TL BIOS does not actually support this mode
[14] HERCULES.COM is a graphics-mode BIOS extension for Hercules-compatible
graphics cards by Soft Warehouse, Inc. Its installation check is to
test whether the word preceding the INT 10 handler is 4137h.
[15] The Hercules-graphics video modes for HERCBIOS (shareware by Dave
Tutelman) may be changed by a command-line switch; the 90x43
character-cell mode's number is always one higher than the 90x29 mode
(whose default is mode 08h)
[16] Stealth64 Video 2001-series BIOS v1.03 reports 76 lines for mode 7Ch,
resulting in incorrect scrolling for TTY output (scrolling occurs only
after the end of the 76th line, which is not displayed)
[17] For 43-line text on EGA or 43/50-line text on VGA, you must load an 8x8
font using AX=1102h after switching to mode 3; VGA may also require
using INT 10/AH=12h/BL=30h

BIN
References/VESA_BIOS_Extensions_(VBE)_v3.pdf View File


+ 762
- 0
References/VGA/grdemo.c View File

@ -0,0 +1,762 @@
/*****************************************************************************
VGA graphics demo
Chris Giese <geezer@execpc.com> http://my.execpc.com/~geezer
Release date: ?
This code is public domain (no copyright).
You can do whatever you want with it.
This code uses the BIOS to set graphics mode, and uses the BIOS font.
Should compile cleanly with Turbo C++ 1.0, Turbo C++ 3.0, 16- or 32-bit
Watcom C, or DJGPP. DJGPP version will not work in Windows NT/2000/XP
DOS box.
Some additional things you could do with this:
- Write a function tblit1(), similar to blit1(), that uses an on-off
transparency mask. Use this function to blit non-rectangular objects
such as a mouse cursor.
- Write blit_plane(): a fast function to blit from monochrome to monochrome
or 4-plane bitmaps. Use an external shift() function, written in asm
- Support VBE 1.x banked framebuffer
- Support VBE 2.x linear framebuffer (pmode only, not at A000h:0000)
- Support greater color depths: 15 bpp, 16 bpp, 24 bpp, 32 bpp
- Color reduction, e.g. Heckbert (median-cut) algorithm
- Clipping engine that lets you draw a window that is partially
obscured by "closer" windows
- Mouse, keyboard, and timer events
- Widgets: push button, checkbox, radio buttons, listbox, dialog, etc.
*****************************************************************************/
#include <string.h> /* [_f]memset() */
/********************************* TURBO C **********************************/
#if defined(__TURBOC__)
#include <dos.h> /* struct REGPACK, intr() */
/* The framebuffer is far outside the 16-bit data segment. The only way to
make the framebuffer work like in-memory bitmaps is to use far pointers.
We still use the SMALL memory model. */
#define FAR far
#define FARPTR(S, O) MK_FP(S, O)
#define outportw(P,V) outport(P,V)
#define R_AX r_ax
#define R_BX r_bx
#define R_BP r_bp
#define R_ES r_es
#define trap(N,R)
typedef struct regs_t;
#if __TURBOC__<0x300
void vmemset(unsigned char FAR *s, unsigned c, unsigned n)
{
for(; n != 0; n--)
{
*s = c;
s++;
}
}
#else
void vmemset(unsigned char FAR *s, unsigned c, unsigned n)
{
_fmemset(s, c, n);
}
#endif
/********************************* DJGPP ************************************/
#elif defined(__DJGPP__)
#include <dpmi.h> /* __dpmi_... */
#include <dos.h> /* inportb(), outportb() */
#define FAR /* nothing */
#define FARPTR(S, O) (unsigned char *)((S) * 16L + (O) + \
__djgpp_conventional_base)
/* near pointers; not supported in Windows NT/2k/XP DOS box */
#include <sys/nearptr.h> /* __djgpp_conventional_base, __djgpp_nearptr_enable() */
#include <stdio.h> /* printf() */
#include <crt0.h> /* _CRT0_FLAG_NEARPTR, _crt0_startup_flags */
#define R_AX x.ax
#define R_BX x.bx
#define R_BP x.bp
#define R_ES x.es
#define trap(N,R) __dpmi_int(N,R)
typedef __dpmi_regs regs_t;
void vmemset(unsigned char FAR *s, unsigned c, unsigned n)
{
memset(s, c, n);
}
/******************************** WATCOM C **********************************/
#elif defined(__WATCOMC__)
#include <dos.h> /* union REGPACK, MK_FP(), intr() */
#if defined(__386__)
#define FAR /* nothing */
#define FARPTR(S, O) (unsigned char *)((S) * 16L + (O))
void vmemset(unsigned char FAR *s, unsigned c, unsigned n)
{
memset(s, c, n);
}
#else
#define FAR far
#define FARPTR(S, O) MK_FP(S, O)
void vmemset(unsigned char FAR *s, unsigned c, unsigned n)
{
_fmemset(s, c, n);
}
#endif
#define inportb(P) inp(P)
#define outportb(P,V) outp(P,V)
#define outportw(P,V) outpw(P,V)
#define R_AX w.ax
#define R_BX w.bx
#define R_BP w.bp
#define R_ES w.es
/* WARNING: for 32-bit code, unused fields of regs_t
must be zeroed before using this macro */
#define trap(N,R) intr(N,R)
typedef union REGPACK regs_t;
#else
#error Not Turbo C, not DJGPP, not Watcom C. Sorry.
#endif
#include <conio.h> /* getch() */
/* need direct access to some VGA registers to select plane,
enable Mode X, and fix screwy CGA addressing */
#define VGA_SEQ_INDEX 0x3C4
#define VGA_SEQ_DATA 0x3C5
#define VGA_GC_INDEX 0x3CE
#define VGA_GC_DATA 0x3CF
#define VGA_CRTC_INDEX 0x3D4
#define VGA_CRTC_DATA 0x3D5
/* bitmap "class" */
typedef struct
{
unsigned wd, ht;
unsigned char FAR *raster;
unsigned fore_color, back_color;
/* "member functions" */
const struct _driver *ops;
} bmp_t;
typedef struct _driver
{
/* "pure virtual functions": color drivers MUST implement these */
void (*write_pixel)(bmp_t *bmp, unsigned x, unsigned y, unsigned c);
unsigned (*read_pixel)(bmp_t *bmp, unsigned x, unsigned y);
/* "virtual functions": drivers MAY implement these, for speed
fill rectangular area with solid color */
void (*fill_rect)(bmp_t *bmp, int x, int y, int wd, int ht);
/* copy monochrome bitmap to this bitmap (used to display text) */
void (*blit1)(bmp_t *src, bmp_t *dst, unsigned dst_x, unsigned dst_y);
/* copy all or part of one bitmap to another (both of the same depth) */
void (*blit)(bmp_t *src, bmp_t *dst, unsigned dst_x, unsigned dst_y);
} ops_t;
/*============================================================================
helper functions
============================================================================*/
/*****************************************************************************
*****************************************************************************/
void set_plane(unsigned p)
{
static unsigned curr_p = -1u;
/**/
unsigned char pmask;
p &= 3;
if(p == curr_p)
return;
curr_p = p;
pmask = 1 << p;
#if 0
outportb(VGA_GC_INDEX, 4);
outportb(VGA_GC_DATA, p);
outportb(VGA_SEQ_INDEX, 2);
outportb(VGA_SEQ_DATA, pmask);
#else
/* this is a little faster... */
outportw(VGA_GC_INDEX, (p << 8) | 4);
outportw(VGA_SEQ_INDEX, (pmask << 8) | 2);
#endif
}
/*****************************************************************************
fast planar (monochrome or 16-color) rectangle fill
*****************************************************************************/
void fill_plane(bmp_t *bmp, int x, int y, int wd, int ht, unsigned c)
{
unsigned w, wd_in_bytes, off;
unsigned char lmask, rmask;
int x2, y2;
x2 = x + wd - 1;
w = (x2 >> 3) - (x >> 3) + 1;
lmask = 0x00FF >> (x & 7); /* FF 7F 3F 1F 0F 07 03 01 */
rmask = 0xFF80 >> (x2 & 7);/* 80 C0 E0 F0 F8 FC FE FF */
if(w == 1)
lmask &= rmask;
wd_in_bytes = bmp->wd / 8;
off = wd_in_bytes * y + x / 8;
if(c)
/* for each row... */
for(y2 = y; y2 < y + ht; y2++)
{
/* do partial byte on left */
bmp->raster[off] |= lmask;
/* do solid bytes in middle */
if(w > 2)
vmemset(bmp->raster + off + 1, 0xFF, w - 2);
/* do partial byte on right */
if(w > 1)
bmp->raster[off + w - 1] |= rmask;
/* next row */
off += wd_in_bytes;
}
else
{
lmask = ~lmask;
rmask = ~rmask;
for(y2 = y; y2 < y + ht; y2++)
{
bmp->raster[off] &= lmask;
if(w > 2)
vmemset(bmp->raster + off + 1, 0, w - 2);
if(w > 1)
bmp->raster[off + w - 1] &= rmask;
off += wd_in_bytes;
}
}
}
/*****************************************************************************
fast planar blit
*****************************************************************************/
void blit_plane(bmp_t *src, bmp_t *dst, unsigned dst_x, unsigned dst_y)
{
/* left as an exercise for the reader :)
You may need an external, assembly-language function to shift (left or
right) a long string of bytes. No need to shift by more than 7 bits. */
}
/*============================================================================
driver for monochrome (1-bit) graphics
============================================================================*/
/*****************************************************************************
*****************************************************************************/
static void write_pixel1(bmp_t *bmp, unsigned x, unsigned y, unsigned c)
{
unsigned wd_in_bytes;
unsigned off, mask;
c = (c & 1) * 0xFF;
wd_in_bytes = bmp->wd / 8;
off = wd_in_bytes * y + x / 8;
x = (x & 7) * 1;
mask = 0x80 >> x;
bmp->raster[off] = (bmp->raster[off] & ~mask) | (c & mask);
}
/*****************************************************************************
*****************************************************************************/
static unsigned read_pixel1(bmp_t *bmp, unsigned x, unsigned y)
{
unsigned wd_in_bytes;
unsigned off, mask;
wd_in_bytes = bmp->wd / 8;
off = wd_in_bytes * y + x / 8;
x = (x & 7) * 1;
mask = 0x80 >> x;
return (bmp->raster[off] & mask) != 0;
}
/*****************************************************************************
*****************************************************************************/
static void fill_rect1(bmp_t *bmp, int x, int y, int wd, int ht)
{
fill_plane(bmp, x, y, wd, ht, bmp->fore_color & 1);
}
/*****************************************************************************
*****************************************************************************/
const ops_t g_ops1 =
{
write_pixel1,
read_pixel1,
fill_rect1,
NULL, /* blit1 */
NULL /* blit */
};
/*============================================================================
driver for 2-bit packed pixel (4-color CGA) graphics
============================================================================*/
/*****************************************************************************
*****************************************************************************/
static void write_pixel2(bmp_t *bmp, unsigned x, unsigned y, unsigned c)
{
unsigned wd_in_bytes, off, mask;
c = (c & 3) * 0x55;
wd_in_bytes = bmp->wd / 4;
off = wd_in_bytes * y + x / 4;
x = (x & 3) * 2;
mask = 0xC0 >> x;
bmp->raster[off] = (bmp->raster[off] & ~mask) | (c & mask);
}
/*****************************************************************************
*****************************************************************************/
const ops_t g_ops2 =
{
write_pixel2,
NULL, /* read_pixel */
NULL, /* fill_rect */
NULL, /* blit1 */
NULL /* blit */
};
/*============================================================================
driver for 4-plane 16-color graphics
============================================================================*/
/*****************************************************************************
*****************************************************************************/
static void write_pixel4p(bmp_t *bmp, unsigned x, unsigned y, unsigned c)
{
unsigned wd_in_bytes, off, mask, p, pmask;
wd_in_bytes = bmp->wd / 8;
off = wd_in_bytes * y + x / 8;
x = (x & 7) * 1;
mask = 0x80 >> x;
pmask = 1;
for(p = 0; p < 4; p++)
{
set_plane(p);
if(pmask & c)
bmp->raster[off] |= mask;
else
bmp->raster[off] &= ~mask;
pmask <<= 1;
}
}
/*****************************************************************************
pixel-by-pixel fill is too slow, so use this optimized function:
*****************************************************************************/
static void fill_rect4p(bmp_t *bmp, int x, int y, int wd, int ht)
{
unsigned char p, pmask;
pmask = 1;
for(p = 0; p < 4; p++)
{
set_plane(p);
fill_plane(bmp, x, y, wd, ht, bmp->fore_color & pmask);
pmask <<= 1;
}
}
/*****************************************************************************
*****************************************************************************/
const ops_t g_ops4p =
{
write_pixel4p,
NULL, /* read_pixel */
fill_rect4p,
NULL, /* blit1 */
NULL /* blit */
};
/*============================================================================
driver for 8-bit 256-color graphics
============================================================================*/
/*****************************************************************************
*****************************************************************************/
static void write_pixel8(bmp_t *bmp, unsigned x, unsigned y, unsigned c)
{
unsigned wd_in_bytes;
unsigned off;
wd_in_bytes = bmp->wd;
off = wd_in_bytes * y + x;
bmp->raster[off] = c;
}
/*****************************************************************************
*****************************************************************************/
static void fill_rect8(bmp_t *bmp, int x, int y, int wd, int ht)
{
unsigned wd_in_bytes, off, y2;
wd_in_bytes = bmp->wd;
off = wd_in_bytes * y + x;
for(y2 = y; y2 < y + ht; y2++)
{
vmemset(bmp->raster + off, bmp->fore_color, wd);
off += wd_in_bytes;
}
}
/*****************************************************************************
*****************************************************************************/
const ops_t g_ops8 =
{
write_pixel8,
NULL, /* read_pixel */
fill_rect8,
NULL, /* blit1 */
NULL /* blit */
};
/*============================================================================
driver for 8-bit 256-color Mode-X graphics
============================================================================*/
/*****************************************************************************
*****************************************************************************/
static void write_pixel8x(bmp_t *bmp, unsigned x, unsigned y, unsigned c)
{
unsigned wd_in_bytes;
unsigned off;
wd_in_bytes = bmp->wd / 4;
off = wd_in_bytes * y + x / 4;
set_plane(x & 3);
bmp->raster[off] = c;
}
/*****************************************************************************
*****************************************************************************/
const ops_t g_ops8x =
{
write_pixel8x,
NULL, /* read_pixel */
NULL, /* fill_rect */
NULL, /* blit1 */
NULL /* blit */
};
/*============================================================================
depth-independent routines, which call the depth-dependent routines
============================================================================*/
/*****************************************************************************
*****************************************************************************/
unsigned read_pixel(bmp_t *bmp, unsigned x, unsigned y)
{
if(x >= bmp->wd || y >= bmp->ht)
return 0;
if(bmp->ops->read_pixel == NULL)
return 0; /* uh-oh */
return bmp->ops->read_pixel(bmp, x, y);
}
/*****************************************************************************
*****************************************************************************/
void write_pixel(bmp_t *bmp, unsigned x, unsigned y, unsigned c)
{
if(x >= bmp->wd || y >= bmp->ht)
return;
if(bmp->ops->write_pixel == NULL)
return; /* uh-oh */
bmp->ops->write_pixel(bmp, x, y, c);
}
/*****************************************************************************
*****************************************************************************/
void fill_rect(bmp_t *bmp, int x, int y, int wd, int ht)
{
int x2, y2;
/* clip */
if(x < 0)
{
if(wd + x < 0)
return;
wd += x;
x = 0;
}
if(x + wd >= (int)bmp->wd)
{
if(x >= (int)bmp->wd)
return;
wd = bmp->wd - x;
}
if(y < 0)
{
if(ht + y < 0)
return;
ht += y;
y = 0;
}
if(y + ht >= (int)bmp->ht)
{
if(y >= (int)bmp->ht)
return;
ht = bmp->ht - y;
}
/* use fast routine if available */
if(bmp->ops->fill_rect != NULL)
{
bmp->ops->fill_rect(bmp, x, y, wd, ht);
return;
}
for(y2 = y; y2 < y + ht; y2++)
for(x2 = x; x2 < x + wd; x2++)
write_pixel(bmp, x2, y2, bmp->fore_color);
}
/*****************************************************************************
*****************************************************************************/
void hline(bmp_t *bmp, int x, int y, unsigned wd)
{
fill_rect(bmp, x, y, wd, 1);
}
/*****************************************************************************
*****************************************************************************/
void vline(bmp_t *bmp, int x, int y, unsigned ht)
{
fill_rect(bmp, x, y, 1, ht);
}
/*****************************************************************************
blit1 = blit from monochrome bitmap to bitmap of any color depth
*****************************************************************************/
void blit1(bmp_t *src, bmp_t *dst, unsigned dst_x, unsigned dst_y)
{
unsigned x, y, c;
/* source bitmap _must_ be monochrome */
if(src->ops != &g_ops1)
return;
/* use fast routine if available */
if(src->ops->blit1 != NULL)
{
src->ops->blit1(src, dst, dst_x, dst_y);
return;
}
for(y = 0; y < src->ht; y++)
for(x = 0; x < src->wd; x++)
{
c = read_pixel(src, x, y);
/* xxx - on-off transparency?
if(c == 0)
continue; */
if(c != 0)
c = dst->fore_color;
else
c = dst->back_color;
write_pixel(dst, dst_x + x, dst_y + y, c);
}
}
/*****************************************************************************
blit = copy from one bitmap to another, both of the same color depth
*****************************************************************************/
void blit(bmp_t *src, bmp_t *dst, unsigned dst_x, unsigned dst_y)
{
unsigned x, y, c;
/* they must be the same depth */
if(src->ops != dst->ops)
return;
/* use fast routine if available */
if(src->ops->blit != NULL)
{
src->ops->blit(src, dst, dst_x, dst_y);
return;
}
for(y = 0; y < src->ht; y++)
for(x = 0; x < src->wd; x++)
{
c = read_pixel(src, x, y);
write_pixel(dst, dst_x + x, dst_y + y, c);
}
}
/*****************************************************************************
find 8x8 font in VGA BIOS ROM
*****************************************************************************/
unsigned char FAR *bios_8x8_font(void)
{
unsigned char FAR *font;
regs_t regs;
/* use BIOS INT 10h AX=1130h to find font #3 (8x8) in ROM */
memset(&regs, 0, sizeof(regs)); /* for Watcom C */
regs.R_AX = 0x1130;
regs.R_BX = 0x0300;
trap(0x10, &regs);
/* CauseWay DOS extender seems to return a selector in ES,
instead of real-mode segment value (usu. 0xC000) */
#if defined(__WATCOMC__)&&defined(__386__)
font = FARPTR(0xC000, regs.R_BP);
#else
font = FARPTR(regs.R_ES, regs.R_BP);
#endif
return font;
}
/*****************************************************************************
*****************************************************************************/
void bputs(bmp_t *bmp, unsigned x, unsigned y, const char *s)
{
unsigned char FAR *font;
bmp_t src;
font = bios_8x8_font();
src.wd = 8;
src.ht = 8;
src.ops = &g_ops1;
for(; *s != '\0'; s++)
{
src.raster = font + 8 * (*s);
blit1(&src, bmp, x, y);
x += 8;
}
}
/*============================================================================
DEMO
============================================================================*/
/*****************************************************************************
*****************************************************************************/
static void border3d(bmp_t *bmp, int x, int y, unsigned wd, unsigned ht,
char down)
{
if(down)
{
bmp->fore_color = 8;
hline(bmp, x + 0, y + 0, wd - 1);
vline(bmp, x + 0, y + 0, ht - 1);
bmp->fore_color = 0;
hline(bmp, x + 1, y + 1, wd - 3);
vline(bmp, x + 1, y + 1, ht - 3);
bmp->fore_color = 7;
hline(bmp, x + 1, y + ht - 2, wd - 2);
vline(bmp, x + wd - 2, y + 1, ht - 2);
bmp->fore_color = 15;
hline(bmp, x + 0, y + ht - 1, wd);
vline(bmp, x + wd - 1, y + 0, ht);
}
else
{
bmp->fore_color = 7;
hline(bmp, x + 0, y + 0, wd - 1);
vline(bmp, x + 0, y + 0, ht - 1);
bmp->fore_color = 15;
hline(bmp, x + 1, y + 1, wd - 3);
vline(bmp, x + 1, y + 1, ht - 3);
bmp->fore_color = 8;
hline(bmp, x + 1, y + ht - 2, wd - 2);
vline(bmp, x + wd - 2, y + 1, ht - 2);
bmp->fore_color = 0;
hline(bmp, x + 0, y + ht - 1, wd);
vline(bmp, x + wd - 1, y + 0, ht);
}
}
/*****************************************************************************
*****************************************************************************/
static void demo(bmp_t *bmp, const char *title)
{
unsigned x = 10, y = 10, wd = 180, ht = 50;
/* erase screen to blue */
bmp->fore_color = 1;
fill_rect(bmp, 0, 0, bmp->wd, bmp->ht);
/* draw gray window with 3D border */
bmp->fore_color = 7;
fill_rect(bmp, x, y, wd, ht);
border3d(bmp, x, y, wd, ht, 0);
/* draw white-on-green title bar */
bmp->fore_color = 2;
fill_rect(bmp, x + 2, y + 2, wd - 4, 10);
bmp->back_color = 2;
bmp->fore_color = 15;
bputs(bmp, x + 3, y + 3, title);
/* draw menu bar on existing gray background */
bmp->back_color = 7;
bmp->fore_color = 0;
bputs(bmp, x + 3, y + 13, "File Edit");
/* draw white inner area with 3D border */
bmp->fore_color = 15;
fill_rect(bmp, x + 3, y + 21, wd - 6, ht - 24);
border3d(bmp, x + 3, y + 21, wd - 6, ht - 24, 1);
/* await key pressed */
getch();
}
/*****************************************************************************
*****************************************************************************/
int main(void)
{
static const unsigned wd[] =
{
640, 320, 640, 320, 320
};
static const unsigned ht[] =
{
480, 200, 480, 200, 200
};
static const ops_t *ops[] =
{
&g_ops1, &g_ops2, &g_ops4p, &g_ops8, &g_ops8x
};
static const unsigned mode[] =
{
0x11, 5, 0x12, 0x13, 0x13
};
static const char *title[] =
{
"640x480x2", "320x200x4", "640x480x16", "320x200x256",
"320x200x256 ModeX"
};
/**/
regs_t regs;
unsigned i;
bmp_t bmp;
#if defined(__DJGPP__)
if(!(_crt0_startup_flags & _CRT0_FLAG_NEARPTR))
{
if(!__djgpp_nearptr_enable())
{
printf("Could not enable nearptr access "
"(Windows NT/2000/XP?)\n");
}
}
#endif
for(i = 0; i < sizeof(wd) / sizeof(wd[0]); i++)
{
bmp.raster = FARPTR(0xA000, 0);
bmp.wd = wd[i];
bmp.ht = ht[i];
bmp.ops = ops[i];
memset(&regs, 0, sizeof(regs)); /* for Watcom C */
regs.R_AX = mode[i];
trap(0x10, &regs);
/* to make CGA graphics work like other graphics modes... */
if(mode[i] == 0x05)
{
/* 1) turn off screwy CGA addressing */
outportb(VGA_CRTC_INDEX, 0x17);
outportb(VGA_CRTC_DATA, inportb(VGA_CRTC_DATA) | 1);
/* 2) turn off doublescan */
outportb(VGA_CRTC_INDEX, 9);
outportb(VGA_CRTC_DATA, inportb(VGA_CRTC_DATA) & ~0x80);
/* 3) move the framebuffer from B800:0000 to A000:0000 */
outportb(VGA_GC_INDEX, 6);
outportb(VGA_GC_DATA, inportb(VGA_GC_INDEX) & ~0x0C);
}
/* to convert mode 13h to Mode X... */
else if(i == 4)
{
/* 1) turn off Chain-4 addressing */
outportb(VGA_SEQ_INDEX, 0x04);
outportb(VGA_SEQ_DATA, inportb(VGA_SEQ_DATA) & ~0x08);
/* 2) turn off doubleword clocking */
outportb(VGA_CRTC_INDEX, 0x14);
outportb(VGA_CRTC_DATA, inportb(VGA_CRTC_DATA) & ~0x40);
/* 3) turn off word clocking in case it's on */
outportb(VGA_CRTC_INDEX, 0x17);
outportb(VGA_CRTC_DATA, inportb(VGA_CRTC_DATA) | 0x40);
}
demo(&bmp, title[i]);
}
/* return to text mode */
memset(&regs, 0, sizeof(regs)); /* for Watcom C */
regs.R_AX = 0x03;
trap(0x10, &regs);
return 0;
}

BIN
References/X86 Assembly_Print Version - Wikibooks, open books for an open world.pdf View File


BIN
References/cmu-bootloader-project(2007).pdf View File


+ 305
- 229
bootloader.nasm View File

@ -1,235 +1,311 @@
BITS 16
;http://www.ousob.com/ng/bios/ng1223.php
start:
; Set up 4K stack after this bootloader
; [Remember: Effective Address = Segment*16 + Offset]
mov ax, 0x7C0 ; Set 'ax' equal to the location of this bootloader divided by 16
add ax, 0x20 ; Skip over the size of the bootloader divided by 16
mov ss, ax ; Set 'ss' to this location (the beginning of our stack region)
mov sp, 8192 ; Set 'ss:sp' to the top of our 8K stack
; Set data segment to where we're loaded so we can implicitly access all 64K from here
mov ax, 0x7C0 ; Set 'ax' equal to the location of this bootloader divided by 16
mov ds, ax ; Set 'ds' to the this location
mov [disk_identifier], dl
; Print our message and stop execution
mov si, message ; Put address of the null-terminated string to output into 'si'
call print ; Call our string-printing routine
mov si, enter_debug_mode
call print
call printCRLF
; here goes wait call, for the user to enter debug mode.
; Wating for 2 seconds:
mov ah, 0x86 ; code for waiting interupt call
mov cx, 0x001e ; high count of microseconds
mov dx, 0x8480 ; low count
int 0x15
.busy_wait_for_key:
xor ax, ax
mov ah, 0x01 ; BIOS call to wait for key
int 0x16
jnz debug_mode
; entering system check:
mov si, enter_system_check
mov si, sys_check_ok ; Put address of the null-terminated string to output into 'si'
call print ; Call our string-printing routine
mov si, boot_system ; Put address of the null-terminated string to output into 'si'
call print ; Call our string-printing routine
;This goes first as to now overwrite %ah and %al.
mov ax, 0x0
mov es, ax ;Section to write into
mov ah, 0x2 ;Read sectors from drive
mov al, 0xf ;Number of sectors to read (15 * 512 = 7680 bytes)
mov ch, 0x0 ;Low 8 bits of cylinder
mov cl, 0x11 ;First sector to read (bits 0-5), upper bits of cylinder (bits 6-7)
mov dh, 0x0 ;Head number
mov dl, [disk_identifier] ;0x0 ;Drive number
mov bx, 0x7e00 ;Offset into section
int 0x13 ;Low level disk services
;mov [0x7000], es ; saving retult of read
;
;Debug dump of loaded memory
;mov si, 500
;mov cx, 512
;call b_dumpmem
jnc notcarry
mov si, error_str
call print
jmp endcarrycheck
;
notcarry:
mov si, success_str
call print
call printCRLF
call printCRLF
; xor ax, ax
; mov al, [disk_identifier]
; call dumpax
mov dl, [disk_identifier]
mov ax, 0x7e0
mov ds, ax
jmp 0x7e0:0x00
endcarrycheck:
cli ; Clear the Interrupt Flag (disable external interrupts)
hlt ; Halt the CPU (until the next external interrupt)
debug_mode:
mov si, .welcome_debug
call print
cli ; Clear the Interrupt Flag (disable external interrupts)
hlt
.welcome_debug db 'This is debug mode', 0
data:
message db 'Bootloader for SingOS! v0.0.3',13,10,0
enter_debug_mode db 'Press d to enter bootloader debug mode',13,10,0
enter_system_check db 'Performing system check:',13,10,0
sys_check_ok db 'System check ok', 13, 10, 0
boot_system db 'Read SingOS from disk', 13, 10, 0
error_str db 'Error', 0
success_str db 'Success', 0
disk_identifier db 0
; Routine for printing a 'ax' as hex
dumpax:
pusha ; save registers
mov bx, ax
mov ah, 0xE ; Teletype output
mov cx, 4 ; 4 nipples in a 16 bit word
.loop:
rol bx, 4 ; rotate to next nipple
mov al, bl ; we copy to al because we need to mask only the low 4 bits
and al, 1111b ; Do the masking
add al, '0' ; convert to ASCII
cmp al, '9' ; If we are greater than 9 ascii, we add 7 to make digit 10 be represented as 'A'
jbe .skip ; -|-
add al, 7 ; -|-
.skip: ; -|-
int 0x10 ; BIOS call 'output'
loop .loop
popa ; restore registers
ret
dumpax10: ; Prints ax as 16-bit decimal number
pusha
mov bx, 10 ; Divisor
mov cx, 5 ; Loop 5 times
.loop1: ; finds digits and pushes them to stack
xor dx, dx
div bx
add dl, '0'
push dx
loop .loop1
%include "bootloader_macros.inc"
%define STAGE1_BASE 0x7c00
%define STAGE2_BASE (STAGE1_BASE + 0x200)
%define PROTECED_MODE_BASE (STAGE2_BASE + 0x200)
%define GDT 0x0800
%define GDT_CodeSegIndex 1
%define GDT_DataSegIndex 2
%define GDT_CodeSegmentSelector GDT_Selector(GDT_CodeSegIndex, 0, 0)
%define GDT_DataSegmentSelector GDT_Selector(GDT_DataSegIndex, 0, 0)
%if 1; TEXT MODE
%define VIDEO 0xB8000
%else
%define VIDEO 0xA0000
%endif
mov ah, 0xE
mov cx, 5 ; Loop 5 times
mov bl, '0'
.loop2: ; Pops from stack until it hits a non-'0' value. It then jumps to nonzero_nopop to print it.
pop dx
mov al, dl
cmp al, bl
jne .nonzero_nopop
loop .loop2
.nonzero_loop: ; Pops values from the stack and prints them.
pop dx
mov al, dl
.nonzero_nopop: ; Part of the loop that prints the value. Jump to here to print without popping on first iteration.
int 0x10
loop .nonzero_loop
popa
ret
dumpax10_rev: ; Prints ax as 16-bit decimal number in reverse
pusha
mov cx, 10 ; Divisor
.loop:
xor dx, dx ; zero dx
div cx ; Divide dx:ax by 10 -> quotient in ax, remainder in dx
mov bx, ax ; save quotient in bx
%define STACK_POINTER_MAX STAGE1_BASE-2 ; Stack grows downwards from right under stage_1
; /$$$$$$ /$$ /$$
; /$$__ $$ | $$ /$$$$
; | $$ \__//$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ |_ $$
; | $$$$$$|_ $$_/ |____ $$ /$$__ $$ /$$__ $$ | $$
; \____ $$ | $$ /$$$$$$$| $$ \ $$| $$$$$$$$ | $$
; /$$ \ $$ | $$ /$$ /$$__ $$| $$ | $$| $$_____/ | $$
; | $$$$$$/ | $$$$/| $$$$$$$| $$$$$$$| $$$$$$$ /$$$$$$
; \______/ \___/ \_______/ \____ $$ \_______//$$$$$$|______/
; /$$ \ $$ |______/
; | $$$$$$/
; \______/
segment Stage1 vstart=STAGE1_BASE
Stage1:
jmp short SkipWeirdBIOSShite
nop ; Used later as a FLAG byte for extended INT 13 Disk Func.'s (See instruction at: 7CADh).
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Disk description table, to make it a valid floppy
; Note: some of these values are hard-coded in the source!
; Values are those used by IBM for 1.44 MB, 3.5" diskette
; NOTE(jakob): From MikeOS
; Why do we need this... damn BIOS
; OEMLabel db "SingOs " ; Disk label
%if 1
times 40-($-$$) db 0
%else
BytesPerSector dw 512 ; Bytes per sector
SectorsPerCluster db 1 ; Sectors per cluster
ReservedForBoot dw 1 ; Reserved sectors for boot record
NumberOfFats db 2 ; Number of copies of the FAT
RootDirEntries dw 224 ; Number of entries in root dir
; (224 * 32 = 7168 = 14 sectors to read)
LogicalSectors dw 2880 ; Number of logical sectors
MediumByte db 0xF0 ; Medium descriptor byte
SectorsPerFat dw 9 ; Sectors per FAT
SectorsPerTrack dw 18 ; Sectors per track (36/cylinder)
Sides dw 2 ; Number of sides/heads
HiddenSectors dd 0 ; Number of hidden sectors
LargeSectors dd 0 ; Number of LBA sectors
DriveNo dw 0 ; Drive No: 0
Signature db 0 ; Drive signature: 41 for floppy
VolumeID dd 0x00000000 ; Volume ID: any number
VolumeLabel db "SingOs "; Volume Label: any 11 chars
FileSystem db "VSFS " ; File system type: don't change!
%endif
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SkipWeirdBIOSShite:
cli ; Disable interrupts
; Setup segments
jmp 0x0000:CanonicalBootloaderStart ; CS:IP = 0x0000:7Cxx where xx is
; the size of the BPB + instructions
; before CanonicalBootloaderStart
CanonicalBootloaderStart:
xor ax, ax
mov ds, ax
mov es, ax
mov fs, ax
mov ss, ax
; Setup stack
mov sp, STACK_POINTER_MAX
sti ; Enable interrupts
cld
; NOTE: From MikeOS bootloader
; - A few early BIOSes are reported to improperly set DL
and dl, dl
jz NoChange
mov [BootDriveNumber], dl ; Save boot device number
; mov ah, 8 ; Get drive parameters
; int 0x13
; jc DiskReadError
; and cx, 0x3F ; Maximum sector number
; mov [SectorsPerTrack], cx ; Sector numbers start at 1
; movzx dx, dh ; Maximum head number
; add dx, 1 ; Head numbers start at 0 - add 1 for total
; mov [Sides], dx
NoChange:
mov eax, 0 ; Needed for some older BIOSes
call PrintRealAddress
CRLF
mov si, FirstStageString
call PrintString
mov cx, 3 ; Try five times
.TryReadLoop:
xor ax, ax ; Reset disk controller
mov es, ax ; Just to be damn sure! (Still canonical 0 segment)
movzx dx, byte [BootDriveNumber];
int 0x13
mov ax, 0x0202 ; Read one sector
mov cx, 0x0002 ; Cylinder 0, sector 2
movzx dx, byte [BootDriveNumber] ; Head zero, drive number
mov bx, STAGE2_BASE ; Where we put the second stage
int 0x13
jnc .BreakTryReadLoop
loop .TryReadLoop
jmp DiskReadError
.BreakTryReadLoop:
jmp STAGE2_BASE
DiskReadError:
mov si, DiskReadErrorStr
call PrintString
xor ax, ax
int 16h ; Wait for keystroke
xor ax, ax
int 19h ; Reboot the system
jmp DiskReadError
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
%include "bootloader_bios_functions.inc"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
FirstStageString: db "Loading stage 2...", 13, 10, 0
DiskReadErrorStr: db "Disk read error. Press any key to reboot.", 0
BootDriveNumber db 0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
times 512-($-$$)-2 db 0 ; Zero pad to boot signature
db 0x55, 0xAA ; Boot signature
; /$$$$$$ /$$ /$$$$$$
; /$$__ $$ | $$ /$$__ $$
; | $$ \__//$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ |__/ \ $$
; | $$$$$$|_ $$_/ |____ $$ /$$__ $$ /$$__ $$ /$$$$$$/
; \____ $$ | $$ /$$$$$$$| $$ \ $$| $$$$$$$$ /$$____/
; /$$ \ $$ | $$ /$$ /$$__ $$| $$ | $$| $$_____/ | $$
; | $$$$$$/ | $$$$/| $$$$$$$| $$$$$$$| $$$$$$$ | $$$$$$$$
; \______/ \___/ \_______/ \____ $$ \_______//$$$$$$|________/
; /$$ \ $$ |______/
; | $$$$$$/
; \______/
; org STAGE2_BASE
segment Stage2 vstart=STAGE2_BASE
Stage2:
call PrintRealAddress
CRLF
mov al, dl ; put remainder in al
add al, '0' ; Make ASCII
mov si, SecondStageString
call PrintString
mov ah, 0xE ; Set teletype output
int 0x10 ; BIOS: write one char
mov si, EnablingA20Str
call PrintString
mov ax, bx
;test ax, ax
cmp ax, 0
jnz .loop
popa
ret
printCRLF:
mov ah, 0xE
mov al, 13
int 0x10
mov al, 10
int 0x10
ret
; Routine for outputting string in 'si' register to screen
print:
mov ah, 0xE ; Specify 'int 0x10' 'teletype output' function
; [AL = Character, BH = Page Number, BL = Colour (in graphics mode)]
.printchar:
lodsb ; Load byte at address SI into AL, and increment SI
cmp al, 0
je .done ; If the character is zero (NUL), stop writing the string
int 0x10 ; Otherwise, print the character via 'int 0x10'
jmp .printchar ; Repeat for the next character
.done:
ret
; b_dumpmem:
; push ax
; push dx
; call printCRLF
; shr cx, 1
; xor dx, dx ; zero dx
; .loop:
; cmp dx, cx
; jae .end
; mov ax, word [esi + 2*edx]
; call dumpax
; mov ax, 0xe20
; int 0x10
; inc dx
; jmp .loop
; .end:
; pop dx
; pop ax
; ret
; Pad to 510 bytes (boot sector size minus 2) with 0s, and finish with the two-byte standard boot signature
times 510-($-$$) db 0
dw 0xAA55 ; => 0x55 0xAA (little endian byte order)
; bootloder debug_mode goes here
times 8192-($-$$) db 0
; From Version 0.0.3 we are concatinate the bootloader and the kernel after compile time
;%include "kernel.nasm"
;times 8192-($-$$) db 0
call Enable_A20
mov al, '0' >> 1
call Check_A20
rcl al, 1
mov byte [A20Status.Bit], al
mov si, A20Status
call PrintString
mov ax, 0x0003 ; AH=0 (Change video mode), AL=13h (Mode) = 320x200 - 256 colors
mov bx, 0x0000
int 0x10 ; Video BIOS interrupt
%if 0 ; VESA test (Totally wrong!!!! read up!)
; mov ax, 0x4f02 ; VESA mode
; mov bx, 0x0301 ; 132 cols by 60 rows
; int 0x10 ; Video BIOS interrupt
%endif
;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Global Descriptor Table ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;
%assign GDT_SIZE 0
GDT_NULL_ENTRY GDT
%assign GDT_SIZE (GDT_SIZE+8)
GDT_ENTRY (GDT + (GDT_CodeSegIndex*8)), 0x00000000, 0xffffffff, CodeRead, 0, 1
%assign GDT_SIZE (GDT_SIZE+8)
GDT_ENTRY (GDT + (GDT_DataSegIndex*8)), 0x00000000, 0xffffffff, DataMutable, 0, 1
%assign GDT_SIZE (GDT_SIZE+8)
cli
lgdt [GDT_Record]
mov eax, cr0
or al, 1 ; set PE (Protection Enable) bit in CR0 (Control Register 0)
mov cr0, eax
jmp ClearPrefetchQueue
nop
nop
ClearPrefetchQueue:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Manually assembled long jump
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
db 0x66 ; 32bit override
db 0xea ; Long jump
dd PROTECED_MODE_BASE ; Absolute address
dw GDT_CodeSegmentSelector ; Descriptor Selector
; jmp GDT_CodeSegmentSelector:ProtectedModeBaby ; 8: is for the first descriptor in the GDT that is not the null-descriptor
HALT
GDT_Record:
dw GDT_SIZE - 1 ; Size of GDT in bytes minus 1
dd GDT ; Linear address of GDT
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
%include "bootloader_A20.nasm"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SecondStageString: db "This is the second stage!", 13, 10, 0
EnablingA20Str: db "Enabling A20...", 13, 10, 0
A20Status: db "A20_Enabled="
.Bit: db '0', 13, 10, 0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
times 512-($-$$) db 0
BITS 32
segment ProtectedModeBaby vstart=PROTECED_MODE_BASE
ProtectedModeBaby:
; Code segment updated by the long jump here
; Update Other Segments
mov ax, GDT_DataSegmentSelector
mov ds, ax
mov ss, ax
mov es, ax
mov fs, ax
mov gs, ax
; Setup stack
mov esp, 0xffffffff
mov ecx, 0
mov edx, 0
lea edi, [VIDEO]
mov ax, 0x4000
LoopRows:
LoopCols:
mov bl, cl
sub bl, dl
shl bl, 4
mov ah, bl
ror bl, 1
xor ah, bl
; rol ah, 4
; xor ah, dl
; rol ah, 3
mov WORD [edi], ax
inc edi
inc edi
inc ecx
cmp ecx, 80
je BreakLoopCols
jmp LoopCols
BreakLoopCols:
mov ecx, 0
inc edx
cmp edx, 25
je BreakLoopRows
jmp LoopRows
BreakLoopRows:
WriteProtectedModeString:
cld
lea esi, [ProtectedWelcomeStr]
lea edi, [VIDEO+(80*2)*12+19*2]
.print_loop:
mov al, BYTE [esi]
test al, al
jz .break_print_loop
mov BYTE [edi], al
mov BYTE [edi+1], 0x0f
inc esi
inc edi
inc edi
jmp .print_loop
.break_print_loop:
HALT
;;;;;;;;;;;;;;;;;;;;;;;;
;; Strings
;;;;;;;;;;;;;;;;;;;;;;;;
ProtectedWelcomeStr: db " Placeholder for SingOS - 32 bit edition! ", 0

+ 106
- 0
bootloader_A20.nasm View File

@ -0,0 +1,106 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Enable_A20:
; Enables A20 gate using:the BIOS, keyboard controller, or Fast A20
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pushad ;Preserve registers
pushfd ;Preserve EFLAGS because we might disable interrupts
mov ax,0x2402 ;INT 15h AX=2402h: Query A20 status
int 0x15 ;Check to see if A20 gate is enabled
jc A20_No_BIOS ;Error? Don't use BIOS to enable gate
test al,1 ;Test Bit 0 of AL
je A20_Enabled ;A20 gate already enabled
mov ax,0x2401 ;INT 15h AX=2401h: Enable A20 gate
int 0x15 ;Use BIOS to enable A20 gate
jc A20_No_BIOS ;Error? Don't use BIOS to enable gate
or ah,ah ;Test AH
jnz A20_No_BIOS ;Non-zero? A20 gate may not be enabled
A20_Enabled:
popfd ;Restore EFLAGS
popad ;Restore registers
ret ;Return
A20_No_BIOS:
mov ax,0x2403 ;INT 15h AX=2403h: Query A20 support
int 0x15 ;Call BIOS to find out how the A20 gate can be enabled
jc A20_KBD ;Error? Assume that keyboard controller is the only option
test bx,1 ;Bit 0:Keyboard controller supported
je A20_KBD ;BIOS indicates that keyboard controller is supported
test bx,2 ;Bit 1:Fast A20 supported
je FAST_A20 ;BIOS indicated that Fast A20 is supported
call Check_A20 ;Test A20 gate manually
jc A20_Enabled ;A20 gate already enabled
A20_Fail:
lea si,[A20_ERROR] ;"Unable to enable A20 gate!"
call PrintString
call A20_OUT_Wait ;Print string
cli ;Disable interrupts
hlt ;Halt machine
FAST_A20:
in al,0x92 ;Read System Control Port A
test al,2 ;Test Fast A20 bit
jnz A20_Fail ;Bit already set, failed to enable A20 gate
or al,2 ;Set Bit 1:Enable Fast A20
and al,0xFE ;Always clear Bit 0 so that machine does not reboot
out 0x92,al ;Write to port 92h
call Check_A20 ;Check A20 gate
jc A20_Enabled ;Success?
cli ;No? something must have gone wrong
hlt ;Clear interrupts and halt machine
A20_KBD:
cli ;Disable interrupts
mov cx,50 ;Number of attempts to enable gate
Use_KBD:
call A20_OUT_Wait ;Wait for keyboard
mov al,0xAD ;Disable Keyboard
out 0x64,al ;Wait for Keyboard
mov al,0xD0 ;Read Controller Output Port
out 0x64,al
call A20_IN_Wait ;Wait for Keyboard
in al,0x60 ;Read Data Port
push ax ;Save
call A20_OUT_Wait ;Wait for Keyboard
mov al,0xD1 ;Write Controller Output Port
out 0x64,al
call A20_OUT_Wait ;Wait for Keyboard
pop ax ;Get port data back
or al,10b ;Bit 1: Enable A20 gate
out 0x60,al ;Write to data port
call A20_OUT_Wait ;Wait for Keyboard
mov al,0xAE ;Enable Keyboard
out 0x64,al
call A20_OUT_Wait ;Wait for Keyboard
call Check_A20 ;Verify that gate is enabled
jc A20_Enabled ;Yes? Return
loop Use_KBD ;No? Keep trying
jmp A20_Fail ;Could not enable gate after 50 tries
A20_OUT_Wait:
in al,0x64 ;Read status register
test al,10b ;Is port ready?
jnz A20_OUT_Wait ;Nope, wait
ret ;Yep, continue
A20_IN_Wait:
in al,0x64 ;Read status register
test al,1b ;Is port ready?
jz A20_IN_Wait ;Nope, wait
ret ;Yep, continue
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Check_A20:
; Test if A20 gate is enabled by comaparing the value in FFFF:7E0E
; with the VBR boot signature at 0000:7DFE
; Out: Carry flag set if A20 gate is enabled
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pushad ;Preserve registers
push es
mov ax, 0xFFFF
mov es, ax ;Extra segment:FFFF
cmp WORD [es:0x7DFE + 16], 0xAAFF ;See if boot signature is wrapped at FFFF:7E0E (Meaning FFFF:7E0E = 0:7DFE)
stc ; Assume we didn't wrap, yes A20
jne .End
clc ; We did wrap, no A20
.End:
pop es
popad
ret
A20_ERROR db "Unable to enable A20 gate!",0

+ 164
- 0
bootloader_bios_functions.inc View File

@ -0,0 +1,164 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PrintString:
; uses bios to print string
; IN 'si': pointer to beginning of zero terminated string
; OUT 'si': pointer to the zero terminator at the end of the string
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pushf
push ax
cld ; Ensure direction flag is cleared (for LODSB)
mov ah, 0xe
.PrintLoop:
lodsb
test al, al
jz .BreakPrintLoop
int 0x10
jmp .PrintLoop
.BreakPrintLoop:
pop ax
popf
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PrintRealAddress:
; Clobbers AX
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov ax, cs
call PrintAx
mov ax, 0xe00|':'
int 0x10
pop ax
push ax
call PrintAx
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PrintAx:
PrintAxHex:
; Prints the contens of ax as a hexadecimal number
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pusha ; save registers
mov dx, ax
mov ah, 0xE ; Teletype output
mov cx, 4 ; 4 nibbles in a 16 bit word
.PrintLoop:
rol dx, 4 ; rotate to next nibble
mov al, dl ; we copy to al because we need to mask only the low 4 bits
and al, 0xF ; Do the masking
add al, '0' ; convert to ASCII
; If we are greater than 9 ascii...
cmp al, '9'
jbe .SkipDiffToAsciiA
add al, 'A'-('9'+1) ; ...add 7 to make digits 10 to 15 be represented as 'A' to 'F'
.SkipDiffToAsciiA:
int 0x10 ; BIOS call 'output'
loop .PrintLoop
popa ; restore registers
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PrintAxDec:
; Prints the contens of ax as a decimal number
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pusha
xor cx, cx ; Digit count starts at 0
test ax, ax
jz .AlreadyZero
mov bx, 10 ; Divisor
.LoopDivide: ; finds digits and pushes them to stack
test ax, ax
jz .BreakLoopDivide
xor dx, dx
div bx ; dx = (dx:ax)%bx, ax = (dx:ax)/bx
push dx
inc cx ; Increase digit count
jmp .LoopDivide
.BreakLoopDivide:
.LoopPrint:
test cx, cx
jz .BreakLoopPrint
dec cx
pop ax
.AlreadyZero:
add al, '0' ; Convert to ascii
mov ah, 0xE
int 0x10
jmp .LoopPrint
.BreakLoopPrint:
popa
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PrintAxBin:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
push ax
push bx
push cx
xchg bx, ax
bsr cx, bx
inc cx
ror bx, cl
mov ah, 0xe
.loop:
mov al, '0'>>1
shl bx, 1
rcl al, 1
int 0x10
loop .loop
pop cx
pop bx
pop ax
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PrintMemoryRegion:
; IN: DS:SI is the address to read from
; IN: CX is the amount of 16 bit words to read
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
push cx
push ax
.Loop:
lodsw
call PrintAx
loop .Loop
pop ax
pop cx
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LoadOneSector:
; Tries to load one sector to linear address ES:BX
; IN:
; Assumes CS == DS == SS
; NOTE: No error checking on the track number
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; C = LBA / (HeadsPerCylinder * SectorsPerTrack)
; H = (LBA / SectorsPerTrack) mod HeadsPerCylinder
; S = (LBA % SectorsPerTrack) + 1
mov cx, 5 ; Try five times
.Retry:
xor ax, ax ; Reset disk controller
movzx dx, byte [BootDriveNumber];
int 0x13
mov ax, 0x0201 ; Read one sector
mov cx, 0x0002 ; Cylinder 0, sector 2
movzx dx, byte [BootDriveNumber] ; Head zero, drive number
int 0x13
jnc .BreakRetryLoop
loop .Retry
.BreakRetryLoop:
ret

+ 74
- 0
bootloader_macros.inc View File

@ -0,0 +1,74 @@
%macro HALT 0
%%h:
cli
hlt
jmp %%h
%endmacro
%macro CRLF 0
push ax
mov ax, 0xe00|13
int 0x10
mov al, 10
int 0x10
pop ax
%endmacro
; GDT Stuff
%define Data 0000b
%define DataMutable 0010b
%define DataShrink 0100b
%define DataShrinkMutable 0110b
%define Code 1000b
%define CodeRead 1010b
%define CodeOnlyOwnPriv 1100b
%define CodeOnlyOwnPrivRead 1110b
; %define DataAcc 0001b
; %define DataMutableAcc 0011b
; %define DataShrinkAcc 0101b
; %define DataShrinkMutableAcc 0111b
; %define CodeAcc 1001b
; %define CodeReadAcc 1011b
; %define CodeOnlyOwnPrivAcc 1101b
; %define CodeOnlyOwnPrivReadAcc 1111b
%macro GDT_NULL_ENTRY 1 ; address
%assign address %1
lea di, [address]
xor ax, ax
mov cx, 4
rep stosw
%endmacro
%macro GDT_ENTRY 6 ; address base limit type privilege bits32
%assign address %1
%assign base %2
%assign limit %3
%assign type (%4 & 0xf)
%assign reserved (1<<4)
%assign privilege ((%5 & 0x3) << 5)
%assign present (1<<7)
%assign access (present | privilege | reserved | type)
%assign bits32 ((%6 & 1) << 2)
%assign granularity (1<<3)
%assign flags (granularity | bits32)
%assign limit_0_15 (limit & 0xffff)
%assign limit_16_19 ((limit >> 16) & 0xf)
%assign base_0_15 (base & 0xffff)
%assign base_16_23 ((base >> 16) & 0xff)
%assign base_24_31 ((base >> 24) & 0xff)
mov WORD [address + 0], limit_0_15
mov WORD [address + 2], base_0_15
mov WORD [address + 4], base_16_23 | (access << 8)
mov WORD [address + 6], limit_16_19 | (flags << 4) | (base_24_31 << 8)
%endmacro
%define GDT_Selector(DescriptorIndex, TableIndicator, RequestorPrivLevel) ((DescriptorIndex << 3) | ((TableIndicator & 1) << 2) | (RequestorPrivLevel & 0x3))

+ 16
- 14
build View File

@ -1,17 +1,19 @@
#!/usr/bin/bash
if [ "$1" == "build" ] || [ "$1" == "run" ]; then
nasm -fbin bootloader.nasm -o bootloader.bin
nasm -fbin kernel.nasm -o kernel.bin
cat bootloader.bin kernel.bin > SingOS.img
if [ $1 == "run" ]; then
#qemu-system-x86_64 -drive format=raw,file=SingOS.img
#qemu-system-x86_64 -hda SingOS.img
qemu-system-x86_64 -drive index=0,if=floppy,format=raw,file=SingOS.img
else
bash -c "echo;echo;echo 'Press [ENTER] to exit'; read line"
fi
fi
AsmFile=bootloader.nasm
# AsmFile=write_self.nasm
echo "Done"
BuildSteps=(
"nasm ${AsmFile} -f bin -o boot.bin"
"dd bs=512 count=2880 if=/dev/zero of=./Floppy.img"
"dd conv=notrunc if=./boot.bin of=./Floppy.img"
# "gcc -O0 -o ./VGA/grdemo.o ./VGA/grdemo.c"
# "objcopy -O binary ./VGA/grdemo.o ./grdemo.bin"
"qemu-system-x86_64 -vga cirrus -drive format=raw,file=Floppy.img"
# "bochs"
)
for cmd in "${BuildSteps[@]}"; do
echo -e "\033[1;34m${cmd}\033[0m"
if ! eval $cmd ; then read line ; break; fi
done

+ 0
- 16
build.sh View File

@ -1,16 +0,0 @@
#!/bin/bash
if [ "$1" != "run" ]; then
nasm -fbin bootloader.nasm -o bootloader.bin
nasm -fbin kernel.nasm -o kernel.bin
cat bootloader.bin kernel.bin > SingOS.img
fi
if [ "$1" != "make" ]; then
#qemu-system-x86_64 -drive format=raw,file=SingOS.img
#qemu-system-x86_64 -hda SingOS.img
qemu-system-x86_64 -drive index=0,if=floppy,format=raw,file=SingOS.img
fi
echo "Done"

+ 26
- 0
bx_enh_dbg.ini View File

@ -0,0 +1,26 @@
# bx_enh_dbg_ini
SeeReg[0] = TRUE
SeeReg[1] = TRUE
SeeReg[2] = TRUE
SeeReg[3] = TRUE
SeeReg[4] = FALSE
SeeReg[5] = FALSE
SeeReg[6] = FALSE
SeeReg[7] = FALSE
SingleCPU = FALSE
ShowIOWindows = TRUE
ShowButtons = TRUE
SeeRegColors = TRUE
ignoreNxtT = TRUE
ignSSDisasm = TRUE
UprCase = 0
DumpInAsciiMode = 3
isLittleEndian = TRUE
DefaultAsmLines = 512
DumpWSIndex = 1
DockOrder = 0x132
ListWidthPix[0] = 127
ListWidthPix[1] = 95
ListWidthPix[2] = 172
MainWindow = 800, -2, 398, 878
FontName = Normal

+ 114
- 0
count_a_lot.nasm View File

@ -0,0 +1,114 @@
[bits 16]
[org 0x0600]
%define STAGE1_BASE 0x7c00
%define STAGE2_BASE 0x0600
%define STACK_POINTER_MAX 0x2000
%macro HALT 0
%%h:
cli
hlt
jmp %%h
%endmacro
%macro CRLF 0
push ax
mov ax, 0xe00|13
int 0x10
mov al, 10
int 0x10
pop ax
%endmacro
segment Stage1 vstart=STAGE1_BASE
Stage1:
; Setup segments
cli
xor ax, ax
xor bx, bx
xor cx, cx
xor dx, dx
xor si, si
xor di, di
times 32-($-$$) nop
times 7 inc ax
times 40 nop
call PrintAxHex
call PrintCRLF
HALT
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PrintAx:
PrintAxHex:
; Prints the contens of ax as a hexadecimal number
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pusha ; save registers
mov dx, ax
mov ah, 0xE ; Teletype output
mov cx, 4 ; 4 nibbles in a 16 bit word
.PrintLoop:
rol dx, 4 ; rotate to next nibble
mov al, dl ; we copy to al because we need to mask only the low 4 bits
and al, 0xF ; Do the masking
add al, '0' ; convert to ASCII
; If we are greater than 9 ascii...
cmp al, '9'
jbe .SkipDiffToAsciiA
add al, 'A'-('9'+1) ; ...add 7 to make digits 10 to 15 be represented as 'A' to 'F'
.SkipDiffToAsciiA:
int 0x10 ; BIOS call 'output'
loop .PrintLoop
popa ; restore registers
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PrintAxDec:
; Prints the contens of ax as a decimal number
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pusha
mov bx, 10 ; Divisor
xor cx, cx ; Digit count starts at 0
.LoopDivide: ; finds digits and pushes them to stack
test ax, ax
jz .BreakLoopDivide
xor dx, dx
div bx ; dx = (dx:ax)%bx, ax = (dx:ax)/bx
push dx
inc cx ; Increase digit count
jmp .LoopDivide
.BreakLoopDivide:
.LoopPrint:
pop ax
add al, '0' ; Convert to ascii
mov ah, 0xE
int 0x10
loop .LoopPrint
popa
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PrintCRLF:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pusha
mov ah, 0xE
mov al, 13
int 0x10
mov al, 10
int 0x10
popa
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
times 510-($-$$) db 0 ; Zero-pad to boot signature
db 0x55, 0xAA ; Boot signature

+ 0
- 305
kernel.nasm View File

@ -1,305 +0,0 @@
BITS 16
start_sing:
; loading essentials for SingOS to run
; VSFS is loaded:
mov [global_disk_identifier], dl ; saving disk_identifier, this is the number the disk that we are booting from.
; This number is set by the bios
jmp sing_ready
%include "mem_lib/mem_lib.nasm"
%include "lib/os_lib.nasm"
%include "lib/string.nasm"
%include "lib/debug_tools.nasm"
%include "lib/std_power.nasm"
%include "lib/svim.nasm"
%include "vsfs/vsfs.nasm"
%include "CLI/CLI.nasm"
sing_ready: ; SingOS is ready for the user:
call os_clear_screen
mov si, welcome ; Put address of the null-terminated string to output into 'si'
call print ; Call our string-printing routine
print_format example_format_string, 0xdead, 0xbeef, 0xbabe, 420
call printCRLF
call dump_general_registers
call printCRLF
call dump_segment_registers
call printCRLF
call dump_stack_registers
call printCRLF
call dump_status_flags
call printCRLF
call print_help_message
; call dump_status_flags
; call printCRLF
mov si, command_line
call print
jmp terminal
terminal:
call wait_for_key
jmp terminal
wait_for_key:
pusha
mov ax, 0
mov ah, 0x10 ; BIOS call to wait for key
int 0x16
cmp ax, 0x11b; ESC key
je near .end
cmp ax, 0x3b00 ; f1 key
je .change_one
cmp ax, 0x3c00 ; f2 key
je .change_two
cmp ax, 0x1c0d ; enter key
je .enter_hit
mov [.tmp_buf], ax ; save the key pressed befor printing it
mov cx, [.tmp_buf]
cmp cx, 0x0e08 ; backspace key
;je .backspace_handler
jne .dont_backspace
call CLI_DELETE
popa
ret
.dont_backspace:
call CLI_ASCII_INPUT
;mov ah, 0xE ; This destroy the high part of the key pressed
;mov bl, 0x02
;int 0x10
;mov bx, [.os_command_buffer_counter]
;cmp bx, 254
;je .os_buffer_full
;mov ax, bx
;add ax, .os_command_buffer
;add bx, 0x01
;mov [.os_command_buffer_counter], bx
;mov bx, ax
;mov ax, [.tmp_buf]
;mov [bx], ax
.return_enter:
mov ax, [.tmp_buf]
popa ; But restore all other regs
ret
.os_buffer_full:
mov si, .os_str_full
call print
popa
ret
.backspace_handler:
; bx already set to the current buffer count
mov bx, [.os_command_buffer_counter]
cmp bx, 0x00
je .backspace_stop
sub bx, 0x01
mov [.os_command_buffer_counter], bx
add bx, .os_command_buffer
mov ax, 0x00
mov [bx], ax
mov ax, [.tmp_buf] ; load the backpace
mov ah, 0xE ; print the backspace
int 0x10
mov al, 0
int 0x10
mov al, 0x08
int 0x10
;mov al, 0x20 ; now the curser is one back
;int 0x10 ; print null charecter
.backspace_stop:
popa ; But restore all other regs
ret
.change_one:
mov al, 0x00 ; arg: index 0
call os_change_screen
jmp terminal
.change_two:
mov al, 0x01 ; arg: index 0
call os_change_screen
jmp terminal
.enter_hit:
call CLI_CONFIRM_INPUT
jmp .command_interpreter
.no_str:
mov si, command_line
call print
jmp .return_enter
.compare_with_LIST_searchindex dw 0
.compare_with_LIST_NAMES dw .compare_with_dumpmem, .compare_with_keyprint, .compare_with_display, .compare_with_svim, .compare_with_clear, .compare_with_ls, 0
.compare_with_LIST_POINTERS dw dumpmem, keyprint, .change_display, svim, .clearcommand, vsfs_list_files_command, 0
.compare_with_dumpmem db 'dumpmem', 0
.compare_with_keyprint db 'keyprint', 0
.compare_with_display db 'display', 0 ; original this is the display command for better grapichs
.compare_with_svim db 'svim', 0 ; SingOS vim edition 'svim'
.compare_with_clear db 'clear', 0 ; Clear the screen
.compare_with_ls db 'ls', 0 ; List file table
.end:
mov si, exit_message
call print
call power_off
cli
hlt
.change_display:
mov ax, 0x4F02 ; set VBE mode
mov bx, 0x4118 ; VBE mode number; notice that bits 0-13 contain the mode number and bit 14 (LFB) is set and bit 15 (DM) is clear.
;xor bx, bx
;xor cx, cx
;xor dx, dx
;mov ah, 0x06
;mov al, 0xff
int 0x10
ret
.clearcommand:
xor bx, bx
xor cx, cx ; Upper and left coordinate
mov bh, 0x0f ; color for new screen 0 = black f = white
mov dh, 0xff ; Select all screen
mov dl, 0xff ; Select all screen
mov ah, 0x07 ; scrool down
mov al, 0x00 ; scrool 0 lines (means blank screen )
int 0x10
; move curser back to the top of the screen
mov ah, 0x02
mov bh, 0x00 ; page number 0
mov dh, 0x00 ; row zero
mov dl, 0x00 ; coloumn zero
int 0x10
ret
.tmp_buf dw 0
.os_command_buffer times 255 dw 0
.os_command_buffer_counter dw 0
.os_str_full db 13, 10, 'Buffer is full', 13, 10, 0
.command_interpreter:
mov bx, [.os_command_buffer_counter]
cmp bx, 0x00
je near .no_str ; First byte is 0 => No command
call printCRLF
add bx, .os_command_buffer ; Note addition. Sets bx to the end of the string, which should be guaranteed to be 0
mov ax, 0x00
mov [bx], ax ; Ensure that the command is null-terminated
xor bx, bx
mov [.os_command_buffer_counter], bx
mov si, .os_command_buffer
call print ; Echo the command
lea si, [.os_command_buffer]
;mov dword [.compare_with_LIST_searchindex], 0 ; Next time, start at 0
mov cx, 0 ; Index
.command_interpreter_searchloop:
;call printCRLF
;mov ax, cx
;call dumpax
;mov bx, [.compare_with_LIST_searchindex]
mov bx, cx
add bx, bx ; The pointers are 2 bytes long. Compensate here
;call printCRLF
;mov ax, cx
;call dumpax
mov dx, [.compare_with_LIST_NAMES+bx] ; Here it HAS to be bx. Otherwise it is invalid for some reason
mov bx, dx
lea di, [bx]
call stringcompare
je .command_interpreter_foundcommand
; I don't assume here that the registers contain the same values they used to after the calls
;mov bx, [.compare_with_LIST_searchindex]
;inc bx
;mov [.compare_with_LIST_searchindex], bx
inc cx
mov bx, cx
add bx, bx
mov dx, [.compare_with_LIST_NAMES+bx]
cmp dx, 0 ;Is it at the null terminator?
jne .command_interpreter_searchloop ; There is another command to check
jmp .no_str
.command_interpreter_foundcommand:
call printCRLF
;mov bx, [.compare_with_LIST_searchindex] ; Remember this thing
mov bx, cx
add bx, bx ;The pointers are 2 bytes long. Compensate here
;call printCRLF
;mov ax, cx
;call dumpax
mov dx, [.compare_with_LIST_POINTERS+bx] ; This is where the program is.
;mov ax, dx
;call printCRLF
;call dumpax
call dx
jmp .no_str
;
global_vars:
global_vsfs_master_record dw 8 ; this is the index of the start of the master table for the filesystem
; This should maby contain more information.
; and somehow be setted in a fix sector, which holds all the variabels for SingOS
; 8 is currently the magic number where the file system starts on our disk.
global_vsfs_next_index dw 0 ; This is the next index to the next file created.
; this var is set durling load of SingOS
; Changed my mind, the index is currently loaded and written back to disk under
; creation of a new file.
global_disk_identifier db 0 ; set by the bios passed by the bootloader,
; this is the bios ID
data:
welcome db "###############################################################################", 13, 10, "# Welcome to SingOS anniversary edition. #", 13, 10, "# This build marks 1 year of SingOS! #", 13, 10, "###############################################################################", 13, 10, 'Press ESC to halt.', 13, 10, 13, 10, 0
exit_message db 13, 10, 'Goodbye from SingOS',13,10,'The system has halted.', 0
command_line db 13, 10, 'groot@SingOS $ ', 0
number_one_zstring db '71', 0
example_format_string db "(%x-%x-%x){%d%%}",0
;times 131072-($-$$) db 0 ; 256 sectos
;GLOBAL_VSFS_START db 'VSFS v0.1' ; sector 257 reserved for file system information
times (1<<20)-($-$$) db 0 ; sector 258 to sector 2048 should be avaliable to the filesystem.

+ 0
- 1
legacy/README.md View File

@ -1 +0,0 @@
SingOs

+ 0
- 2
legacy/compile_folder/README.md View File

@ -1,2 +0,0 @@
Folder of compiling the OS
This folder has to be empty on the repository

+ 0
- 3
legacy/source/build.sh View File

@ -1,3 +0,0 @@
as sing_boot_alt.s -o ../compile_folder/alt.o
ld -Ttext 0x7c00 --oformat=binary ../compile_folder/alt.o -o ../compile_folder/sing.bin
dd if=../compile_folder/sing.bin of=../compile_folder/sing.img

+ 0
- 3
legacy/source/generic_build.sh View File

@ -1,3 +0,0 @@
as $1.s -o ../compile_folder/$2.o
ld -Ttext 0x7c00 --oformat=binary ../compile_folder/$2.o -o ../compile_folder/$2.bin
dd if=../compile_folder/$2.bin of=../compile_folder/$2.img

+ 0
- 3
legacy/source/info.txt View File

@ -1,3 +0,0 @@
https://www.codeproject.com/Articles/664165/Writing-a-boot-loader-in-Assembly-and-C-Part
http://www.computer-engineering.org/index.html // keyboard and mouse programming

+ 0
- 76
legacy/source/mytest.s View File

@ -1,76 +0,0 @@
#generate 16-bit code
.code16
#hint the assembler that here is the executable code located
.text
.globl _start;
#boot code entry
_start:
jmp _boot
start: .asciz "Start.\n\r"
error: .asciz "Error.\n\r"
succes: .asciz "Succes.\n\r"
ffs: .asciz "F.\n\r"
end: .asciz "End.\n\r"
.macro mWriteString str #macro which calls a function to print a string
leaw \str, %si
call .writeStringIn
.endm
# function to print the string
.writeStringIn:
lodsb
orb %al, %al
jz .writeStringOut
movb $0x0e, %ah
int $0x10
jmp .writeStringIn
.writeStringOut:
ret
_boot:
mWriteString start
#This goes first as to now overwrite %ah and %al.
mov $0x00, %ax
mov %ax, %es #Section to write into
mov $0x02, %ah # Read sectors from drive
mov $0x01, %al # Number of sectors to read
mov $0x00, %ch # Low 8 bits of cylinder
mov $0x02, %cl # First sector to read (bits 0-5), upper bits of cylinder (bits 6-7)
mov $0x00, %dh # Head number
mov $0x00, %dl # Drive number
# mov $0x00, %es
mov $0xFF, %bx #Offset into section
int $0x13 # Low level disk services
jnc notcarry
mWriteString error
jmp endcarrycheck
notcarry:
mWriteString succes
#fallthrough
endcarrycheck:
mWriteString mystr
mWriteString end
#
#move to 510th byte from the start and append boot signature
. = _start + 510
.byte 0x55
.byte 0xaa
mystr: .asciz "asdf"
. = _start + 1023
.byte 0x00

+ 0
- 227
legacy/source/mytest2.s View File

@ -1,227 +0,0 @@
#generate 16-bit code
.code16
#hint the assembler that here is the executable code located
.text
.globl _start;
#boot code entry
_start:
jmp _boot
start: .asciz "Start.\n\r"
error: .asciz "Error.\n\r"
succes: .asciz "Succes.\n\r"
ffs: .asciz "F.\n\r"
end: .asciz "End.\n\r"
derpy2str: .asciz "This is from derpy2.\n\r"
cookies: .word derpy2
.macro mWriteString str #macro which calls a function to print a string
leaw \str, %si
call .writeStringIn
.endm
# function to print the string
.writeStringIn:
lodsb
orb %al, %al
jz .writeStringOut
movb $0x0e, %ah
int $0x10
jmp .writeStringIn
.writeStringOut:
ret
_boot:
mWriteString start
movb $0x0e, %ah
movb $'X', %al
int $0x10
movb $'\n', %al
int $0x10
movb $'\r', %al
int $0x10
lgdt gdtdesc
#movb $42, %bl #NOT 'A'
#movb %bl, 0x512
#This goes first as to now overwrite %ah and %al.
mov $0x00, %ax
#mov $0x08, %ax
mov %ax, %es #Section to write into
mov $0x02, %ah # Read sectors from drive
mov $0x01, %al # Number of sectors to read
mov $0x00, %ch # Low 8 bits of cylinder
mov $0x02, %cl # First sector to read (bits 0-5), upper bits of cylinder (bits 6-7)
mov $0x00, %dh # Head number
mov $0x00, %dl # Drive number
# mov $0x00, %es
#mov $0x7e00, %bx #Offset into section
mov $(_start+0x200), %bx #Offset into section
#mov $0x0, %bx #Offset into section
int $0x13 # Low level disk services
jnc notcarry
#mWriteString error
jmp endcarrycheck
notcarry:
#mWriteString succes
#mov $0x7000, %ax
#movb (%ax), %bl
#movb %bl, ffs
#movb 0x7000, %bl
#movb %bl, ffs
#mWriteString ffs
#fallthrough
endcarrycheck:
#mWriteString mystr-block2_offset
#mWriteString 0x513
#mWriteString mystr
#ljmp $0x0, $derpy
#.byte 0, 0, 0, 0, 0, 0, 0, 0
#ljmp $0x00, $0x7e00
#ljmp $0x00, $derpy2
ljmp $0x00, $code
# movw $derpy, %ax
#
# cmp $0x7e00, %ax
# je equal
# mWriteString error
# jmp after
#
# equal:
# mWriteString succes
#
# after:
/*
movb $0x0e, %ah
movw $derpy, %cx
movb 0x0e, %ah
movb $'I', %al
int $0x10
movb 0x0e, %ah
movb $'J', %al
int $0x10
*/
#movw $0x7E00, %cx
movw $derpy2, %cx
movb $0x0e, %ah
#movb $'Y', %al
movb %ch, %al
#movb $'H', %al
#movb $0x7E, %al
int $0x10
movb $0x0e, %ah
#movb $'Z', %al
movb %cl, %al
#add $0x7E, %al
#sub $0x50, %al
#movb $0x3C, %al
int $0x10
movb $0x0e, %ah
movb $'\n', %al
int $0x10
movb $0x0e, %ah
movb $'\r', %al
int $0x10
#mWriteString mystr
#jmp derpy
derpyret:
mWriteString end
#jmp 0x7008
#endend:
#mWriteString end
cli
hlt
#
derpy:
mWriteString ffs
ljmp $0x00, $derpyret
#jmp derpyret
.p2align 2 /* force 4-byte alignment */
gdt:
.word 0, 0
.byte 0, 0, 0, 0
/* code segment */
.word 0xFFFF, 0
.byte 0, 0x9A, 0xCF, 0
/* data segment */
.word 0xFFFF, 0
.byte 0, 0x92, 0xCF, 0
/* 16 bit real mode CS */
.word 0xFFFF, 0
.byte 0, 0x9E, 0, 0
/* 16 bit real mode DS */
.word 0xFFFF, 0
.byte 0, 0x92, 0, 0
/* this is the GDT descriptor */
gdtdesc:
.word 0x27 /* limit */
.long gdt /* addr */
#move to 510th byte from the start and append boot signature
. = _start + 510
.byte 0x55
.byte 0xaa
#block2_offset:
.byte 'A' #Byte 513
#mystr: .asciz "asdf\n\r"
#derpderp:
# mwriteString 0x7001
# jmp endend
derpy2:
mWriteString derpy2str
ljmp $0x00, $derpyret
code:
mWriteString derpy2str
movb $0x0e, %ah
movb $'C', %al
int $0x10
movb $0x0e, %ah
movb $'\n', %al
int $0x10
movb $0x0e, %ah
movb $'\r', %al
int $0x10
ljmp $0x00, $derpyret
. = _start + 1021
.byte 0x00
.word derpy2

+ 0
- 120
legacy/source/sing_boot_alt.s View File

@ -1,120 +0,0 @@
#generate 16-bit code
.code16
#hint the assembler that here is the executable code located
.text
.globl _start;
#boot code entry
_start:
jmp _boot #jump to boot code
welcome: .asciz "Hello, new World\n\r" #here we define the string
enter_number: .asciz "Enter a number: \n\r"
lower_msg: .asciz "\nYour number is to low :( \n\r" # 26
higher_msg: .asciz "\nYour number is to high :( \n\r" # 27
winner_msg: .asciz "\nYour are the CAMPION, :D \n\r" # 26
.macro mWriteString str #macro which calls a function to print a string
leaw \str, %si
call .writeStringIn
.endm
# function to print the string
.writeStringIn:
lodsb
orb %al, %al
jz .writeStringOut
movb $0x0e, %ah
int $0x10
jmp .writeStringIn
.writeStringOut:
ret
.type get_number, @function
get_number:
# save state before function
push %bp
mov %sp, %bp
push %bx
push %cx
# Start of function
mWriteString enter_number
mov $0, %ah
mov $0, %al
int $0x16
mov $0x0E, %ah
int $0x10
pop %cx
pop %bx
mov %bp, %sp
pop %bp
ret
.type string_to_int, @function
string_to_int:
/* Converts a string to an integer. Returns the integer in %rax.
* %rax: Address of string to convert.
*/
push %bp
mov %sp, %bp
push %bx
push %cx
mov %ax, %dx
cmp $47, %dx
jl not_a_num
cmp $57, %dx
jg not_a_num
# I multiply by 10 to shift the number one placement to the right to add the newest integer.
sub $48, %dx
jmp convertdone # In ascii, numbers start at 0 = 48, 1 = 49, 2 = 50 and so on. So I subtract 48 to get the digit.
not_a_num:
xor %dx, %dx
convertdone:
pop %cx
pop %bx
mov %bp, %sp
pop %bp
ret
_boot:
mWriteString welcome
guess:
call get_number
xor %ah, %ah
call string_to_int
cmp $5, %dx
jl if_lower
je if_eg
jg if_higher
if_lower:
mWriteString lower_msg
jmp guess
if_higher:
mWriteString higher_msg
jmp guess
if_eg:
mWriteString winner_msg
#move to 510th byte from the start and append boot signature
. = _start + 510
.byte 0x55
.byte 0xaa

+ 0
- 135
legacy/source/sing_boot_guess.s View File

@ -1,135 +0,0 @@
#generate 16-bit code
.code16
#hint the assembler that here is the executable code located
.text
.globl _start;
#boot code entry
_start:
welcome: .asciz "Welcome to this very fine Guessing game \n\r" #here we define the string
enter_number: .asciz "Enter a number: \n"
lower_msg: .asciz "Your number is to low :( \n" # 26
higher_msg: .asciz "Your number is to high :( \n" # 27
winner_msg: .asciz "Your are the CAMPION, :D \n" # 26
.macro mWriteString str #macro which calls a function to print a string
leaw \str, %si
call .writeStringIn
.endm
#jmp _boot
# function to print the string
.writeStringIn:
lodsb
orb %al, %al
jz .writeStringOut
movb $0x0e, %ah
int $0x10
jmp .writeStringIn
.writeStringOut:
ret #jump to boot code
mWriteString welcome
/*
guess:
call get_number
xor %ah, %ah
call string_to_int
cmp $5, %dx
jl if_lower # rax less then 50
je if_eg
jg if_higher
if_lower:
mWriteString lower_msg
jmp guess
if_higher:
mWriteString higher_msg
jmp guess
if_eg:
mWriteString winner_msg #message length
hlt
*/
#_boot:
# mWriteString welcome
#.type string_to_int, @function
#string_to_int:
/* Converts a string to an integer. Returns the integer in %rax.
* %rax: Address of string to convert.
*/
/*
push %bp
mov %sp, %bp
push %bx
push %cx
mov %ax, %dx
xor %ax, %ax
cmp $47, %dx
jl not_a_num
cmp $57, %dx
jg not_a_num
# I multiply by 10 to shift the number one placement to the right to add the newest integer.
sub $48, %dx # In ascii, numbers start at 0 = 48, 1 = 49, 2 = 50 and so on. So I subtract 48 to get the digit.
not_a_num:
xor %dx, %dx
convertdone:
pop %cx
pop %bx
mov %bp, %sp
pop %bp
ret
.type get_number, @function
get_number:
# .enter_char:
# mov $0, %ah
# mov $0, %al
# int $0x16
# mov $0x0E, %ah
# int $0x10
# jmp .enter_char
# save state before function
push %bp
mov %sp, %bp
push %bx
push %cx
# Start of function
mWriteString enter_number
mov $0, %ah
mov $0, %al
int $0x16
mov $0x0E, %ah
int $0x10
pop %cx
pop %bx
mov %bp, %sp
pop %bp
ret
*/
#move to 510th byte from the start and append boot signature
. = _start + 510
.byte 0x55
.byte 0xaa

+ 0
- 337
lib/debug_tools.nasm View File

@ -1,337 +0,0 @@
%macro print_format 1
lea si, [%1]
call _print_format
%endmacro
%macro print_format 2
lea si, [%1]
push %2
call _print_format
add sp, 2
%endmacro
%macro print_format 3
lea si, [%1]
push %3
push %2
call _print_format
add sp, 4
%endmacro
%macro print_format 4
lea si, [%1]
push %4
push %3
push %2
call _print_format
add sp, 6
%endmacro
%macro print_format 5
lea si, [%1]
push %5
push %4
push %3
push %2
call _print_format
add sp, 8
%endmacro
%macro print_format 6
lea si, [%1]
push %6
push %5
push %4
push %3
push %2
call _print_format
add sp, 10
%endmacro
%macro print_format 7
lea si, [%1]
push %7
push %6
push %5
push %4
push %3
push %2
call _print_format
add sp, 12
%endmacro
BITS 16
dumpmem_hardcoded_args:
mov si, sp
mov si, [si]
mov cx, 400
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
dumpmem:
; Dumps memory
; IN 'si': Start address to dump from
; IN 'cx': Number of bytes do dump
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pusha
xor edx, edx
.loop:
mov ax, word [esi + 2*edx]
inc edx
call dumpax
mov ax, (0xE<<8)|' ' ; print space
int 0x10
loop .loop
.end:
popa
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
dumpax:
; Prints the contens of ax as a hexadecimal number
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pusha ; save registers
mov dx, ax
mov ah, 0xE ; Teletype output
mov cx, 4 ; 4 nibbles in a 16 bit word
.print_loop:
rol dx, 4 ; rotate to next nibble
mov al, dl ; we copy to al because we need to mask only the low 4 bits
and al, 0xF ; Do the masking
add al, '0' ; convert to ASCII
; If we are greater than 9 ascii...
cmp al, '9'
jbe .skip_diff_to_ascii_A
add al, 'A'-('9'+1) ; ...add 7 to make digits 10 to 15 be represented as 'A' to 'F'
.skip_diff_to_ascii_A:
int 0x10 ; BIOS call 'output'
loop .print_loop
popa ; restore registers
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
dumpax10:
; Prints the contens of ax as a decimal number
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pusha
mov bx, 10 ; Divisor
xor cx, cx ; Digit count starts at 0
.loop_divide: ; finds digits and pushes them to stack
test ax, ax
jz .break_loop_divide
xor dx, dx
div bx ; dx = (dx:ax)%bx, ax = (dx:ax)/bx
push dx
inc cx ; Increase digit count
jmp .loop_divide
.break_loop_divide:
.loop_print:
pop ax
add al, '0' ; Convert to ascii
mov ah, 0xE
int 0x10
loop .loop_print
popa
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
dumpax_char:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov ah, 0xE
int 0x10
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
keyprint:
; Enters a loop where the keycode of each pressed key is printed
; [ESC] exits the loop
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pusha
mov si, .f_info
call print
.keyprint_loop:
mov ax, 0x1000 ; BIOS call to wait for key
int 0x16
mov bx, ax ; Save KeyCode in bx
print_format .f, ax, ax
cmp bx, 0x011B ; ESC key
je .break_keyprint_loop
jmp .keyprint_loop
.break_keyprint_loop:
popa
ret
.f_info: db 13, 10, "Press keys to see their keycodes.",13,10,"Press [ESC] to exit.", 13, 10, 0
.f: db "(%c: %x)", 13, 10, 0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
dump_stack_registers:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
push si
print_format .format_string, sp, bp
pop si
ret
.format_string: db "StackRegisters(SP:%x BP:%x)", 0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
dump_general_registers:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
push si
print_format .format_string, ax, cx, dx, bx, si, di
pop si
ret
.format_string: db "GeneralRegisters(ax:%x cx:%x dx:%x bx:%x si:%x di:%x)", 0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
dump_segment_registers:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
push si
print_format .format_string, ss, cs, ds, es, fs, gs
pop si
ret
.format_string: db "SegmentRegisters(Stack:%x Code:%x Data:%x Extra:%x F:%x G:%x)", 0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
_print_format:
; IN: variable number of 16-bit numbers on stack
; IN: 'si' points to beginning of format string with the following format:
; %x in string replaced with hexadecimal representation
; %d in string replaced with decimal representation
; %% in string replaced with literal % sign
;
; EXAMPLE call:
; push word 1337
; push word 0xbeef
; push word 0xdead
; lea si, [.FORMAT]
; call print_format ; output: "(DEAD-BEEF){1337} 100%"
; add sp, 6
; (...)
; .FORMAT: db "(%x-%x){%d} 100%%",0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
push bp
mov bp, sp
pushf
pusha
lea bp, [bp+4]
.outer_loop:
mov ah, 0xE ; Specify 'int 0x10' 'teletype output' function
.print_loop:
lodsb ; al = *si++
cmp al, '%'
je .break_print
test al, al
jz .break_outer
int 0x10
jmp .print_loop
.break_print:
lodsb
cmp al, 'x'
je .format_hex
cmp al, 'd'
je .format_dec
cmp al, 'c'
je .format_char
cmp al, '%'
je .print_literal_percent
.format_hex:
lea cx, [dumpax]
jmp .print_ax
.format_dec:
lea cx, [dumpax10]
jmp .print_ax
.format_char:
lea cx, [dumpax_char]
.print_ax:
mov ax, [bp]
lea bp, [bp+2]
call cx
jmp .outer_loop
.print_literal_percent:
mov ax, (0xE<<8)|'%'
int 0x10
jmp .outer_loop
.break_outer:
popa
popf
pop bp
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
dump_dx_as_two_chars:
; IN dh: first char
; IN dl: second char
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
push ax
mov ah, 0xE
mov al, dh
int 0x10
mov al, dl
int 0x10
pop ax
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
dump_status_flags:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pushf
push si
push ax
push bx
lahf
mov bl, ah
lea si, [.flags_string]
mov ah, 0xE ; Specify 'int 0x10' 'teletype output' function
.outer_loop:
; [AL = Character, BH = Page Number, BL = Colour (in graphics mode)]
.print_loop:
lodsb ; Load byte at address SI into AL, and increment SI
cmp al, '%'
je .break_print_loop ; If the character is zero (NUL), stop writing the string
test al, al
jz .break_outer_loop
int 0x10 ; Otherwise, print the character via 'int 0x10'
jmp .print_loop ; Repeat for the next character
.break_print_loop:
ror bl, 1
mov al, bl
and al, 1
add al, '0'
int 0x10
jmp .outer_loop
.break_outer_loop:
pop bx
pop ax
pop si
popf
ret
.flags_string: db "Flags(Sign:% Zero:% ?:% Adjust:% ?:% Parity:% ?:% Carry:%)", 0

+ 0
- 72
lib/os_lib.nasm View File

@ -1,72 +0,0 @@
BITS 16
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
print:
; Prints string in si
; IN si: zero terminated string to print
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov ah, 0xE ; Specify 'int 0x10' 'teletype output' function
; [AL = Character, BH = Page Number, BL = Colour (in graphics mode)]
.printchar:
lodsb ; Load byte at address SI into AL, and increment SI
test al, al
jz .done ; If the character is zero (NUL), stop writing the string
int 0x10 ; Otherwise, print the character via 'int 0x10'
jmp .printchar ; Repeat for the next character
.done:
ret
printCRLF:
mov ah, 0xE
mov al, 13
int 0x10
mov al, 10
int 0x10
ret
printSpace:
mov ax, 0xE20
int 0x10
ret
printALChar:
mov ah, 0xE
mov bl, 0x02 ;color
int 0x10
ret
; Changing the screen the user i looking at.
; value in 'al' is the screen we want to switch to.
; starting from 0x00
os_change_screen:
; Here the addresses for the screens stack
; and base pointer has to be set.
mov ah, 0x05
int 0x10
ret
os_clear_screen:
pusha
; move cursor to the bootom
xor ax, ax
xor bx, bx
mov ah, 0x02
mov bh, 0x00 ; page number 0
mov dh, 0x18 ; row zero
mov dl, 0x00 ; coloumn zero
int 0x10
xor cx, cx
.loop:
call printCRLF
add cx, 1
cmp cx, 0x19 ; until blank screen
jne .loop
; Move curser back to the top of the screen
mov ah, 0x02
mov bh, 0x00 ; page number 0
mov dh, 0x00 ; row zero
mov dl, 0x00 ; coloumn zero
int 0x10
popa
ret

+ 0
- 39
lib/std_power.nasm View File

@ -1,39 +0,0 @@
BITS 16
; THIS LIBARY IS IN REALLY BAD SHAPE
; Power_off is okay to use
power_check:
;perform an installation check
mov ah,53h ;this is an APM command
mov al,00h ;installation check command
xor bx,bx ;device id (0 = APM BIOS)
int 15h ;call the BIOS function through interrupt 15h
call printCRLF
call dumpax
;jc APM_error ;if the carry flag is set there was an error
;the function was successful
;AX = APM version number
;AH = Major revision number (in BCD format)
;AL = Minor revision number (also BCD format)
;BX = ASCII characters "P" (in BH) and "M" (in BL)
;CX = APM flags (see the official documentation for more details)
ret
power_enable:
;Enable power management for all devices
mov ah,53h ;this is an APM command
mov al,08h ;Change the state of power management...
mov bx,0001h ;...on all devices to...
mov cx,0001h ;...power management on.
int 15h ;call the BIOS function through interrupt 15h
;jc APM_error ;if the carry flag is set there was an error
ret
power_off:
;actual shutdown command
mov ah, 0x53
mov al, 0x07
mov bx, 0x1
mov cx, 0x3
int 0x15
ret

+ 0
- 57
lib/string.nasm View File

@ -1,57 +0,0 @@
BITS 16
; Compares two strings
; IN si: the first (zero terminated) string
; IN di: the second (zero terminated) string
; OUT SF and ZF (same semantics as cmp)
stringcompare:
push bx
push si
push di
.loop:
mov bl, [si]
mov bh, [di]
cmp bl, bh
jne .end
test bl, bl ; bl and bh are the same, so bl = 0 => dl = 0
jz .end
inc si
inc di
jmp .loop
.end:
pop di
pop si
pop bx
ret
zstring_to_integer:
;IN: si Pointer to string
;OUT: ax result in binary
push bx
push si
push cx
push dx
xor ax, ax
xor bx, bx
xor cx, cx
xor dx, dx
mov bx, 10
.loop:
mov cl, [si]
cmp cl, 0
je .end
sub cl,'0'
cmp cl, 9
ja .end ; next number is not a number, or its a zero, and then we are done
; multiply by 10, and add the new number.
mul bx
add ax, cx
inc si
jmp .loop
.end:
pop dx
pop cx
pop si
pop bx
ret

+ 0
- 290
lib/svim.nasm View File

@ -1,290 +0,0 @@
BITS 16
svim:
pusha ; save state before program
;mov si, .os_clear_screen_str
;call print
xor bx, bx
call os_clear_screen
;xor cx, cx ; Upper and left coordinate
;mov bh, 0x0a ; color for new screen 0 = black a = light green
;mov dh, 0xff ; Select all screen
;mov dl, 0xff ; Select all screen
;mov ah, 0x07 ; scrool down
;mov al, 0x00 ; scrool 0 lines (means blank screen )
;int 0x10
mov ah, 0x02
mov bh, 0x00 ; page number 0
mov dh, 0x00 ; row zero
mov dl, 0x17 ; coloumn zero
int 0x10
mov si, .welcome_svim_select_file
call print
call printCRLF
mov si, .seperate_line
call print
call vsfs_list_files_command
; move cursor to the bootom
xor ax, ax
xor bx, bx
mov ah, 0x02
mov bh, 0x00 ; page number 0
mov dh, 0x17 ; row zero
mov dl, 0x00 ; coloumn zero
int 0x10
mov si, .welcome_svim
call print
call printCRLF
mov si, .welcome_svim_enter_fileindex
call print
; Ask the user for the filename
xor bx, bx
xor cx, cx ; are going to be the counter
xor dx, dx
.enter_fileindex_loop:
push cx
.loop_no_push:
mov ax, 0x10 ; BIOS call to wait for key
int 0x16
cmp ax, 0x1c0d ; enter key
je .fileindex_done
cmp ax, 0x0e08 ; backspace
jne .no_enter_fileindex
cmp cx, 0
je .loop_no_push
pop cx
sub cx, 1
mov bx, .buffer_for_svim
add bx, cx
mov BYTE [bx], 0
; Go back one space
mov ax, 0x0e08 ; ah=0x0e means teletype output. al=0x08 means backspace character.
int 0x10
; Place a NULL
mov al, 0x0 ; NULL
int 0x10
; Go back one space again as the above print of NULL pushes the cursor forward again.
mov ax, 0x0e08
int 0x10
jmp .enter_fileindex_loop
.no_enter_fileindex:
mov bh, 0x00
mov bl, 0x02
mov ah, 0x0E
int 0x10 ; print char
pop cx
mov bx, .buffer_for_svim
add bx, cx
mov [bx], al
add cx, 1
; fileindex must only be 120 chars
cmp cx, 120
jae .fileindex_done
jmp .enter_fileindex_loop
.fileindex_done:
pop cx ; Cleanup, and now contain filename size
mov ax, cx
add ax, .buffer_for_svim
mov bx, ax
mov BYTE [bx], 0
mov si, .buffer_for_svim
call zstring_to_integer ; ax now contain the interger index for the file
mov [.fileindex_for_open_file], ax ; save the file index
call os_clear_screen
; move cursor to the bootom
xor ax, ax
xor bx, bx
mov ah, 0x02
mov bh, 0x00 ; page number 0
mov dh, 0x17 ; row zero
mov dl, 0x00 ; coloumn zero
int 0x10
mov si, .seperate_line
call print
mov si, .welcome_svim
call print
; move cursor to the top
xor ax, ax
xor bx, bx
mov ah, 0x02
mov bh, 0x00 ; page number 0
mov dh, 0x00 ; row zero
mov dl, 0x00 ; coloumn zero
int 0x10
; Load from disk and, enter it, into the buffer
mov si, .welcome_svim_select_file
call print
mov ax, [.fileindex_for_open_file]
call dumpax10
call printCRLF
mov si, .seperate_line
call print
mov ax, [.fileindex_for_open_file]
mov ch, al ; move the fileindex in the ch
mov bx, ds
mov es, bx
xor bx, bx
mov bx, .buffer_for_svim
xor ax, ax
mov ah, 0x02 ;Read sectors from drive
mov al, 0x04 ;Number of sectors to read (8 * 512 = 4096 bytes)
mov cl, 0x01 ;First sector to read (bits 0-5), upper bits of cylinder (bits 6-7)
mov dh, 0x00 ;Head number
mov dl, [global_disk_identifier] ;Drive number
int 0x13
mov bx, .buffer_for_svim
add bx, 2046
mov ax, [bx]
mov [.buffer_counter_svim], ax
; print buffer
mov si, .buffer_for_svim
mov es, si
call print
.svim_loop:
xor bx, bx
xor cx, cx
xor dx, dx
mov ax, 0x1000 ; BIOS call to wait for key
int 0x16
cmp ax, 0x1c0d ; enter key
jne .no_enter
mov bx, .buffer_for_svim
add bx, [.buffer_counter_svim]
mov BYTE [bx], 13 ; put char in the buffer
mov BYTE [bx + 1], 10 ; put char in the buffer
mov bx, [.buffer_counter_svim]
add bx, 0x02
mov [.buffer_counter_svim], bx
xor bx, bx
xor cx, cx
xor dx, dx
mov ax, 0x0e0d
int 0x10
mov ax, 0x0e0a
int 0x10
jmp .svim_loop
.no_enter:
cmp ax, 0x11b ; ESC key
je .end_svim
;cmp ax, 0x3c00 ; f2 key
;je .f_key_pushed
cmp ax, 0x0e08 ; backspace
je .backspace_pushed
mov bx, ax
mov ax, 0xe20
mov al, bl
mov bx, .buffer_for_svim
add bx, [.buffer_counter_svim]
mov [bx], al ; put char in the buffer
mov bx, [.buffer_counter_svim]
add bx, 0x01
mov [.buffer_counter_svim], bx
int 0x10 ; print char
jmp .svim_loop
.end_svim:
; save the written buffer
;AH 03h
;AL Sectors To Write Count
;CH Track
;CL Sector
;DH Head
;DL Drive
;ES:BX Buffer Address Pointer
mov ax, [.buffer_counter_svim]
mov bx, .buffer_for_svim
add bx, 2046
mov [bx], ax
mov bx, ds
mov es, bx
mov bx, .buffer_for_svim
mov ax, [.fileindex_for_open_file]
mov ch, al ; move the fileindex in the ch
mov ah, 0x03 ;Write sectors to drive
mov al, 0x04 ;Number of sectors to write (8 * 512 = 4096 bytes)
mov cl, 0x01 ;First sector to read (bits 0-5), upper bits of cylinder (bits 6-7)
mov dh, 0x00 ;Head number
mov dl, [global_disk_identifier] ;Drive number
int 0x13 ;Low level disk services
; clean up swim
;xor bx, bx
;xor cx, cx ; Upper and left coordinate
;mov bh, 0x0f ; color for new screen 0 = black f = white
;mov dh, 0xff ; Select all screen
;mov dl, 0xff ; Select all screen
;mov ah, 0x07 ; scrool down
;mov al, 0x00 ; scrool 0 lines (means blank screen )
;int 0x10
call os_clear_screen
popa
ret
.backspace_pushed:
mov bx, [.buffer_counter_svim]
cmp bx, 0
je .svim_loop
;print_format .debug_buffer_counter, bx
mov cx, bx
sub cx, 1
mov bx, .buffer_for_svim
add bx, cx
mov BYTE [bx], 0
mov [.buffer_counter_svim], cx
;print_format .debug_buffer_counter, cx
; Go back one space
mov ax, 0x0e08 ; ah=0x0e means teletype output. al=0x08 means backspace character.
int 0x10
; Place a NULL
mov al, 0x0 ; NULL
int 0x10
; Go back one space again as the above print of NULL pushes the cursor forward again.
mov ax, 0x0e08
int 0x10
jmp .svim_loop
;.f_key_pushed:
;mov al, 0x01 ;arg: index 1
;call os_change_screen
;jmp .svim_loop
;.load_buffer_svim:
.debug_buffer_counter db 'Buffer count: %d', 13, 10, 0
.welcome_svim db 'Vim like text editor for SingOS, ESC to exit', 0
.welcome_svim_select_file db 'svim - Open file: ', 0
.welcome_svim_enter_fileindex db 'Enter fileindex: ', 0
.seperate_line db '________________________________________________________________________________', 0
.fileindex_for_open_file dw 0
.buffer_for_svim times 2048 db 0 ; db 'this is the buffer', 0, times 32 db 0
.buffer_counter_svim dw 0

+ 0
- 4
mem_lib/mem_lib.nasm View File

@ -1,4 +0,0 @@
BITS 16
mem_get_zstack_buffer:
; INPUT size of zeroed buffer ax in bytes

+ 134
- 0
min.nasm View File

@ -0,0 +1,134 @@
[bits 16]
[org 0x0600]
%define STAGE1_BASE 0x7c00
%define STAGE2_BASE 0x0600
%define STACK_POINTER_MAX 0x2000
%macro HALT 0
%%h:
cli
hlt
jmp %%h
%endmacro
%macro CRLF 0
push ax
mov ax, 0xe00|13
int 0x10
mov al, 10
int 0x10
pop ax
%endmacro
segment Stage1 vstart=STAGE1_BASE
Stage1:
; Setup segments
cli
xor ax, ax
xor bx, bx
xor cx, cx
xor dx, dx
xor si, si
xor di, di
times 3 inc ax
times 3 inc bx
times 3 inc cx
times 3 inc dx
times 3 inc si
times 4 nop
times 3 inc di
times 40 nop
call PrintAx
call PrintCRLF
mov ax, bx
call PrintAx
call PrintCRLF
mov ax, cx
call PrintAx
call PrintCRLF
mov ax, dx
call PrintAx
call PrintCRLF
mov ax, si
call PrintAx
call PrintCRLF
mov ax, di
call PrintAx
call PrintCRLF
HALT
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PrintAx:
PrintAxHex:
; Prints the contens of ax as a hexadecimal number
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pusha ; save registers
mov dx, ax
mov ah, 0xE ; Teletype output
mov cx, 4 ; 4 nibbles in a 16 bit word
.PrintLoop:
rol dx, 4 ; rotate to next nibble
mov al, dl ; we copy to al because we need to mask only the low 4 bits
and al, 0xF ; Do the masking
add al, '0' ; convert to ASCII
; If we are greater than 9 ascii...
cmp al, '9'
jbe .SkipDiffToAsciiA
add al, 'A'-('9'+1) ; ...add 7 to make digits 10 to 15 be represented as 'A' to 'F'
.SkipDiffToAsciiA:
int 0x10 ; BIOS call 'output'
loop .PrintLoop
popa ; restore registers
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PrintAxDec:
; Prints the contens of ax as a decimal number
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pusha
mov bx, 10 ; Divisor
xor cx, cx ; Digit count starts at 0
.LoopDivide: ; finds digits and pushes them to stack
test ax, ax
jz .BreakLoopDivide
xor dx, dx
div bx ; dx = (dx:ax)%bx, ax = (dx:ax)/bx
push dx
inc cx ; Increase digit count
jmp .LoopDivide
.BreakLoopDivide:
.LoopPrint:
pop ax
add al, '0' ; Convert to ascii
mov ah, 0xE
int 0x10
loop .LoopPrint
popa
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PrintCRLF:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pusha
mov ah, 0xE
mov al, 13
int 0x10
mov al, 10
int 0x10
popa
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
times 510-($-$$) db 0 ; Zero-pad to boot signature
db 0x55, 0xAA ; Boot signature

+ 8
- 0
proj.sublime-project View File

@ -0,0 +1,8 @@
{
"folders":
[
{
"path": "."
}
]
}

+ 1712
- 0
proj.sublime-workspace
File diff suppressed because it is too large
View File


+ 0
- 342
vsfs/vsfs.nasm View File

@ -1,342 +0,0 @@
BITS 16
vsfs_format_disk:
; When SingOS it booted for the first time,
; we have to format the disk to create the global structure
; of the VSFS.
pusha
;AH 03h
;AL Sectors To Write Count
;CH Track
;CL Sector
;DH Head
;DL Drive
; Set the es to point to the data segment,
; this is the global segment, where we calculate all
; our adresses from
; ES:BX Buffer Address Pointer
mov bx, ds
mov es, bx
; Set the bx to point to the pointer of the sector we have to write
; to the disk.
mov bx, .vsfs_format_disk_buffer
mov ah, 0x03 ;Write sectors to drive
mov al, 0x01 ;Number of sectors to write (8 * 512 = 4096 bytes)
mov cl, 0x01 ;First sector to read (bits 0-5), upper bits of cylinder (bits 6-7)
mov ch, 0x08
mov dh, 0x00 ;Head number
mov dl, [global_disk_identifier] ;Drive number
int 0x13 ;Low level disk services
popa
ret
.vsfs_format_disk_buffer db 'VSFS v0.1', 13, 10, '(VerySimpelFileSystem)', 13, 10, 'Developed to SingOS', 13, 10, 'by Jorn Guldberg', 13, 10, 0 ; 66 chars + 8 bytes
times 431 db 0
dw 8, 0, 9 ; Start index, number of files, next free index
vsfs_get_fs_info:
pusha
mov bx, ds
mov es, bx
mov bx, vsfs_loading_buffer
mov ah, 0x02 ; Read sectors from drive
mov al, 0x01 ; Number of sectors to read (8 * 512 = 4096 bytes)
mov ch, 0x08 ; cylinder
mov cl, 0x01 ; First sector to read (bits 0-5), upper bits of cylinder (bits 6-7)
mov dh, 0x00 ; Head number
mov dl, [global_disk_identifier] ; Drive number
int 0x13
mov si, vsfs_loading_buffer
call print
popa
ret
vsfs_read_file_index_in_ax:
; INPUT ax = file index
; INPUT bx = filebuffer
pusha ; save all register state
;call vsfs_convert_index_into_regs
;mov bx, .buffer_for_svim
push bx
mov bx, ds
mov es, bx
pop bx
mov ch, al ; Low 8 bits of cylinder
; the file index into ch, we need to calculatet this, if the number is larger than 16-bits
mov ah, 0x02 ; Read sectors from drive
mov al, 0x01 ; Number of sectors to read (8 * 512 = 4096 bytes)
mov cl, 0x01 ; First sector to read (bits 0-5), upper bits of cylinder (bits 6-7)
mov dh, 0x00 ; Head number
mov dl, [global_disk_identifier] ; Drive number
int 0x13
popa
ret
vsfs_write_file_to_index_in_ax:
pusha ; save all register state
;AH 03h
;AL Sectors To Write Count
;CH Track
;CL Sector
;DH Head
;DL Drive
;ES:BX Buffer Address Pointer
mov bx, ds
mov es, bx
xor bx, bx
;mov bx, .buffer_for_svim
xor cx, cx
xor ax, ax
mov ah, 0x03 ;Write sectors to drive
mov al, 0x01 ;Number of sectors to write (8 * 512 = 4096 bytes)
mov cl, 0x03 ;First sector to read (bits 0-5), upper bits of cylinder (bits 6-7)
mov ch, 0x02
mov dh, 0x01 ;Head number
mov dl, [global_disk_identifier] ;Drive number
int 0x13 ;Low level disk services
popa
ret
vsfs_convert_index_into_regs:
; This function takes a file index in ax, do the calculations
; to set the registers to the right place at the disk
; CH Track
; CL Sector
; DH Head
; The rest of the parameters is set in the read and write function.
ret
vsfs_create_file:
; ax pointer to filename
; bx size
; cx fileIndex
pusha ; save all register state
mov si, .vsfs_create_file_type_filename
call print
; Ask the user for the filename
xor bx, bx
xor cx, cx ; are going to be the counter
xor dx, dx
.enter_filename_loop:
push cx
mov ax, 0x10 ; BIOS call to wait for key
int 0x16
cmp ax, 0x1c0d ; enter key
je .filename_done
cmp ax, 0x0e08 ; backspace
jne .no_enter
pop cx
cmp cx, 0
je .enter_filename_loop
sub cx, 1
mov bx, .new_filename_buffer
add bx, cx
mov BYTE [bx], 0
; Go back one space
mov ax, 0x0e08 ; ah=0x0e means teletype output. al=0x08 means backspace character.
int 0x10
; Place a NULL
mov al, 0x0 ; NULL
int 0x10
; Go back one space again as the above print of NULL pushes the cursor forward again.
mov ax, 0x0e08
int 0x10
jmp .enter_filename_loop
.no_enter:
mov bh, 0x00
mov bl, 0x02
mov ah, 0x0E
int 0x10 ; print char
pop cx
mov bx, .new_filename_buffer
add bx, cx
mov [bx], al
add cx, 1
; filename must only be 120 chars
cmp cx, 120
jae .filename_done
jmp .enter_filename_loop
.filename_done:
pop cx ; Cleanup, and now contain filename size
mov bx, .new_filename_buffer
add bx, cx
mov BYTE [bx], 0
call printCRLF
; We first need to know the index for the file.
; The next avaliable index are we going to get from the
; FSinfo sctor of the disk:
mov bx, ds
mov es, bx
mov bx, vsfs_loading_buffer
mov ch, 0x08 ; Low 8 bits of cylinder
; the file index into ch, we need to calculatet this, if the number is larger than 16-bits
mov ah, 0x02 ; Read sectors from drive
mov al, 0x01 ; Number of sectors to read (8 * 512 = 4096 bytes)
mov cl, 0x01 ; First sector to read (bits 0-5), upper bits of cylinder (bits 6-7)
mov dh, 0x00 ; Head number
mov dl, [global_disk_identifier] ; Drive number
int 0x13
mov ax, [vsfs_loading_buffer + 510]
mov [.to_write_fileindex], ax
; We have to do modulo 4, to know where in the sector the
; file entry has to be written
add DWORD [vsfs_loading_buffer + 510], 1
add DWORD [vsfs_loading_buffer + 508], 1
mov bx, vsfs_loading_buffer
mov ah, 0x03 ;Write sectors to drive
mov al, 0x01 ;Number of sectors to write (8 * 512 = 4096 bytes)
mov cl, 0x01 ;First sector to read (bits 0-5), upper bits of cylinder (bits 6-7)
mov ch, 0x08
mov dh, 0x00 ;Head number
mov dl, [global_disk_identifier] ;Drive number
int 0x13 ;Low level disk services
; Now we have the index in ax.
;AH 03h
;AL Sectors To Write Count
;CH Track
;CL Sector
;DH Head
;DL Drive
; Set the es to point to the data segment,
; this is the global segment, where we calculate all
; our adresses from
; ES:BX Buffer Address Pointer
mov bx, ds
mov es, bx
mov bx, [.to_write_fileindex]
sub bx, 0x07 ; Det skal den bare
mov cl, bl ; First sector to write (bits 0-5), upper bits of cylinder (bits 6-7)
; Set the bx to point to the pointer of the sector we have to write
; to the disk.
mov bx, .new_filename_buffer
mov ah, 0x03 ;Write sectors to drive
mov al, 0x01 ;Number of sectors to write (8 * 512 = 4096 bytes)
mov ch, 0x08
mov dh, 0x00 ;Head number
mov dl, [global_disk_identifier] ;Drive number
int 0x13 ;Low level disk services
popa
ret
.vsfs_create_file_type_filename db 'Enter filename: ', 0
.new_filename_buffer times 122 db 0
.new_file_size dw 0, 0
.to_write_fileindex dw 0
vsfs_list_files_command:
; This function takes the adress of the first sector of the disk
; which the OS has to know
; the adress is given by ax
; Check which registers to save
pusha
; Load the master table into memory
;mov ax, 8 ; file index for master record
;mov bx, vsfs_loading_buffer ; pointer to the input buffer
;call vsfs_read_file_index_in_ax ; call the fucntion which read the master record
; TODO we might want this to be in memory at all times
; loaded already from boot
mov bx, ds
mov es, bx
mov si, .ls_header
call print
mov si, .seperate_line
call print
mov BYTE [.ls_counter], 1
.load_next_fileinfo:
add BYTE [.ls_counter], 1
mov bl, [.ls_counter]
mov cl, bl ; First sector to read (bits 0-5), upper bits of cylinder (bits 6-7)
mov bx, vsfs_loading_buffer
;mov ch, al ; Low 8 bits of cylinder
; the file index into ch, we need to calculatet this, if the number is larger than 16-bits
mov ah, 0x02 ; Read sectors from drive
mov al, 0x01 ; Number of sectors to read (8 * 512 = 4096 bytes)
mov ch, 0x08 ; cylinder
mov dh, 0x00 ; Head number
mov dl, [global_disk_identifier] ; Drive number
int 0x13
mov ax, [vsfs_loading_buffer + 126]
mov bx, ax
mov cx, ' '
mov dx, 'X'
cmp ax, 0
je .end_ls
cmp ax, 10
ja .index_over_10
mov [.fileentry_line + 3 ], cx
mov [.fileentry_line + 4 ], cx
add bx, 48 ; get ascii value
mov [.fileentry_line + 5 ], bl
jmp .stop_index
.index_over_10:
cmp ax, 10
ja .index_over_100
mov [.fileentry_line + 3 ], cx
mov [.fileentry_line + 4 ], dx
mov [.fileentry_line + 5 ], dx
jmp .stop_index
.index_over_100:
mov [.fileentry_line + 3 ], dx
mov [.fileentry_line + 4 ], dx
mov [.fileentry_line + 5 ], dx
.stop_index:
mov si, .fileentry_line ; printing the buffer
call print
mov si, vsfs_loading_buffer ; printing the buffer
call print
call printCRLF
mov si, .seperate_line
call print
jmp .load_next_fileinfo
.end_ls:
popa
ret
.ls_counter db 0
.ls_header db 'List of files:', 13, 10, 'Index | Filename ', 13, 10, 0
.seperate_line db '- - - - - - - - - - - - - - - - ', 13, 10, 0
.fileentry_line db ' 456 | ', 0
vsfs_loading_buffer times 512 db 0

+ 45
- 0
write_self.nasm View File

@ -0,0 +1,45 @@
[bits 16]
%macro HALT 0
%%h:
cli
hlt
jmp %%h
%endmacro
segment Stage1 vstart=0x7c00
Stage1:
jmp short .to
times 40-($-$$) db 0
.to:
xor ax, ax
mov es, ax
mov bx, 0x7c00
; mov ax, 0x0201
; mov cx, 0x0003
; xor dh, dh
; pusha
; int 0x13
; popa
mov ax, 0x0301
mov cx, 0x0004
xor dh, dh
int 0x13
mov cx, 16
xchg bx, ax
.loop:
mov ax, 0x0e00 | ('0'>>1)
shl bx, 1
rcl al, 1
int 0x10
loop .loop
HALT
times 510-($-$$) db 0 ; Zero-pad to boot signature
db 0x55, 0xAA ; Boot signature
times 512 db 0
times 512 db 0xff

Loading…
Cancel
Save