Compare commits
5 Commits
master
...
minimal32b
Author | SHA1 | Date |
---|---|---|
|
35edf789e5 | 7 years ago |
|
dafa6183ef | 7 years ago |
|
1a3e8f7649 | 7 years ago |
|
41d4b4a7fb | 7 years ago |
|
15894ab4c6 | 7 years ago |
53 changed files with 5223 additions and 2492 deletions
@ -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 |
|
||||||
|
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -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 |
|
||||||
``` |
|
@ -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 |
@ -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 |
Binary file not shown.
@ -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 |
Binary file not shown.
@ -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(®s, 0, sizeof(regs)); /* for Watcom C */ |
||||||
|
regs.R_AX = 0x1130; |
||||||
|
regs.R_BX = 0x0300; |
||||||
|
trap(0x10, ®s); |
||||||
|
/* 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(®s, 0, sizeof(regs)); /* for Watcom C */ |
||||||
|
regs.R_AX = mode[i]; |
||||||
|
trap(0x10, ®s); |
||||||
|
/* 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(®s, 0, sizeof(regs)); /* for Watcom C */ |
||||||
|
regs.R_AX = 0x03; |
||||||
|
trap(0x10, ®s); |
||||||
|
return 0; |
||||||
|
} |
Binary file not shown.
Binary file not shown.
@ -1,235 +1,298 @@ |
|||||||
BITS 16 |
BITS 16 |
||||||
;http://www.ousob.com/ng/bios/ng1223.php |
%include "bootloader_macros.inc" |
||||||
start: |
%define STAGE1_BASE 0x7c00 |
||||||
; Set up 4K stack after this bootloader |
%define STAGE2_BASE (STAGE1_BASE + 0x200) |
||||||
; [Remember: Effective Address = Segment*16 + Offset] |
%define PROTECED_MODE_BASE (STAGE2_BASE + 0x200) |
||||||
mov ax, 0x7C0 ; Set 'ax' equal to the location of this bootloader divided by 16 |
%define GDT 0x0800 |
||||||
add ax, 0x20 ; Skip over the size of the bootloader divided by 16 |
%define GDT_CodeSegIndex 1 |
||||||
mov ss, ax ; Set 'ss' to this location (the beginning of our stack region) |
%define GDT_DataSegIndex 2 |
||||||
mov sp, 8192 ; Set 'ss:sp' to the top of our 8K stack |
%define GDT_CodeSegmentSelector GDT_Selector(GDT_CodeSegIndex, 0, 0) |
||||||
|
%define GDT_DataSegmentSelector GDT_Selector(GDT_DataSegIndex, 0, 0) |
||||||
; Set data segment to where we're loaded so we can implicitly access all 64K from here |
%if 1; TEXT MODE |
||||||
mov ax, 0x7C0 ; Set 'ax' equal to the location of this bootloader divided by 16 |
%define VIDEO 0xB8000 |
||||||
mov ds, ax ; Set 'ds' to the this location |
%else |
||||||
|
%define VIDEO 0xA0000 |
||||||
mov [disk_identifier], dl |
%endif |
||||||
; 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 |
|
||||||
|
|
||||||
|
%define STACK_POINTER_MAX STAGE1_BASE-2 ; Stack grows downwards from right under stage_1 |
||||||
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 |
segment Stage1 vstart=STAGE1_BASE |
||||||
mov al, dl |
Stage1: |
||||||
.nonzero_nopop: ; Part of the loop that prints the value. Jump to here to print without popping on first iteration. |
jmp short SkipWeirdBIOSShite |
||||||
int 0x10 |
nop ; Used later as a FLAG byte for extended INT 13 Disk Func.'s (See instruction at: 7CADh). |
||||||
loop .nonzero_loop |
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||||||
popa |
; Disk description table, to make it a valid floppy |
||||||
ret |
; Note: some of these values are hard-coded in the source! |
||||||
|
; Values are those used by IBM for 1.44 MB, 3.5" diskette |
||||||
dumpax10_rev: ; Prints ax as 16-bit decimal number in reverse |
; NOTE(jakob): From MikeOS |
||||||
pusha |
; Why do we need this... damn BIOS |
||||||
|
|
||||||
mov cx, 10 ; Divisor |
; OEMLabel db "SingOs " ; Disk label |
||||||
.loop: |
%if 1 |
||||||
xor dx, dx ; zero dx |
times 40-($-$$) db 0 |
||||||
div cx ; Divide dx:ax by 10 -> quotient in ax, remainder in dx |
%else |
||||||
|
BytesPerSector dw 512 ; Bytes per sector |
||||||
mov bx, ax ; save quotient in bx |
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 |
||||||
|
|
||||||
|
mov [BootDriveNumber], dl ; Save boot device number |
||||||
|
|
||||||
|
mov eax, 0 ; Needed for some older BIOSes |
||||||
|
|
||||||
|
mov si, FirstStageString |
||||||
|
call PrintString |
||||||
|
|
||||||
|
mov cx, 5 ; Try five times |
||||||
|
|
||||||
mov al, dl ; put remainder in al |
.TryReadLoop: |
||||||
add al, '0' ; Make ASCII |
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 ah, 0xE ; Set teletype output |
mov ax, 0x0202 ; Read one sector |
||||||
int 0x10 ; BIOS: write one char |
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 si, SecondStageString |
||||||
|
call PrintString |
||||||
|
|
||||||
|
mov si, EnablingA20Str |
||||||
|
call PrintString |
||||||
|
|
||||||
mov ax, bx |
call Enable_A20 |
||||||
;test ax, ax |
mov al, '0' >> 1 |
||||||
cmp ax, 0 |
call Check_A20 |
||||||
jnz .loop |
rcl al, 1 |
||||||
|
mov byte [A20Status.Bit], al |
||||||
popa |
|
||||||
ret |
mov si, A20Status |
||||||
|
call PrintString |
||||||
printCRLF: |
|
||||||
mov ah, 0xE |
mov ax, 0x0003 ; AH=0 (Change video mode), AL=13h (Mode) = 320x200 - 256 colors |
||||||
mov al, 13 |
mov bx, 0x0000 |
||||||
int 0x10 |
int 0x10 ; Video BIOS interrupt |
||||||
mov al, 10 |
|
||||||
int 0x10 |
%if 0 ; VESA test (Totally wrong!!!! read up!) |
||||||
ret |
; mov ax, 0x4f02 ; VESA mode |
||||||
|
; mov bx, 0x0301 ; 132 cols by 60 rows |
||||||
; Routine for outputting string in 'si' register to screen |
; int 0x10 ; Video BIOS interrupt |
||||||
print: |
%endif |
||||||
mov ah, 0xE ; Specify 'int 0x10' 'teletype output' function |
|
||||||
; [AL = Character, BH = Page Number, BL = Colour (in graphics mode)] |
;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||||||
.printchar: |
; Global Descriptor Table ; |
||||||
lodsb ; Load byte at address SI into AL, and increment SI |
;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||||||
cmp al, 0 |
%assign GDT_SIZE 0 |
||||||
je .done ; If the character is zero (NUL), stop writing the string |
|
||||||
int 0x10 ; Otherwise, print the character via 'int 0x10' |
GDT_NULL_ENTRY GDT |
||||||
jmp .printchar ; Repeat for the next character |
%assign GDT_SIZE (GDT_SIZE+8) |
||||||
.done: |
|
||||||
ret |
GDT_ENTRY (GDT + (GDT_CodeSegIndex*8)), 0x00000000, 0xffffffff, CodeRead, 0, 1 |
||||||
|
%assign GDT_SIZE (GDT_SIZE+8) |
||||||
; b_dumpmem: |
|
||||||
; push ax |
GDT_ENTRY (GDT + (GDT_DataSegIndex*8)), 0x00000000, 0xffffffff, DataMutable, 0, 1 |
||||||
; push dx |
%assign GDT_SIZE (GDT_SIZE+8) |
||||||
; call printCRLF |
|
||||||
; shr cx, 1 |
cli |
||||||
; xor dx, dx ; zero dx |
lgdt [GDT_Record] |
||||||
; .loop: |
|
||||||
; cmp dx, cx |
mov eax, cr0 |
||||||
; jae .end |
or al, 1 ; set PE (Protection Enable) bit in CR0 (Control Register 0) |
||||||
; mov ax, word [esi + 2*edx] |
mov cr0, eax |
||||||
; call dumpax |
|
||||||
; mov ax, 0xe20 |
jmp ClearPrefetchQueue |
||||||
; int 0x10 |
nop |
||||||
; inc dx |
nop |
||||||
; jmp .loop |
ClearPrefetchQueue: |
||||||
; .end: |
|
||||||
; pop dx |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||||||
; pop ax |
;; Manually assembled long jump |
||||||
; ret |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||||||
; Pad to 510 bytes (boot sector size minus 2) with 0s, and finish with the two-byte standard boot signature |
db 0x66 ; 32bit override |
||||||
times 510-($-$$) db 0 |
db 0xea ; Long jump |
||||||
dw 0xAA55 ; => 0x55 0xAA (little endian byte order) |
dd PROTECED_MODE_BASE ; Absolute address |
||||||
; bootloder debug_mode goes here |
dw GDT_CodeSegmentSelector ; Descriptor Selector |
||||||
|
|
||||||
times 8192-($-$$) db 0 |
; jmp GDT_CodeSegmentSelector:ProtectedModeBaby ; 8: is for the first descriptor in the GDT that is not the null-descriptor |
||||||
|
HALT |
||||||
; From Version 0.0.3 we are concatinate the bootloader and the kernel after compile time |
|
||||||
;%include "kernel.nasm" |
GDT_Record: |
||||||
|
dw GDT_SIZE - 1 ; Size of GDT in bytes minus 1 |
||||||
;times 8192-($-$$) db 0 |
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 |
||||||
|
xor bl, dl |
||||||
|
shl bl, 4 |
||||||
|
mov ah, bl |
||||||
|
ror bl, 1 |
||||||
|
xor ah, bl |
||||||
|
and ah, 0x70 |
||||||
|
mov al, dl |
||||||
|
add al, cl |
||||||
|
and al, 4 |
||||||
|
ror al, 1 |
||||||
|
or ah, al |
||||||
|
mov al, 0 |
||||||
|
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 |
@ -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 |
@ -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 |
@ -0,0 +1,64 @@ |
|||||||
|
%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 |
||||||
|
|
||||||
|
%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)) |
@ -1,17 +1,19 @@ |
|||||||
#!/usr/bin/bash |
#!/usr/bin/bash |
||||||
|
|
||||||
if [ "$1" == "build" ] || [ "$1" == "run" ]; then |
AsmFile=bootloader.nasm |
||||||
nasm -fbin bootloader.nasm -o bootloader.bin |
# AsmFile=write_self.nasm |
||||||
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 |
|
||||||
|
|
||||||
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 |
||||||
|
@ -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" |
|
||||||
|
|
@ -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 |
@ -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,0 +1,280 @@ |
|||||||
|
|
||||||
|
%define GDT 0xfe00 |
||||||
|
%define GDT_CodeSegIndex 1 |
||||||
|
%define GDT_DataSegIndex 2 |
||||||
|
%define GDT_Selector(DescriptorIndex, TableIndicator, RequestorPrivLevel) ((DescriptorIndex << 3) | ((TableIndicator & 1) << 2) | (RequestorPrivLevel & 0x3)) |
||||||
|
%define GDT_CodeSegmentSelector GDT_Selector(GDT_CodeSegIndex, 0, 0) |
||||||
|
%define GDT_DataSegmentSelector GDT_Selector(GDT_DataSegIndex, 0, 0) |
||||||
|
|
||||||
|
; GDT Stuff |
||||||
|
%define Data 0000b |
||||||
|
%define DataMutable 0010b |
||||||
|
%define DataShrink 0100b |
||||||
|
%define DataShrinkMutable 0110b |
||||||
|
%define Code 1000b |
||||||
|
%define CodeRead 1010b |
||||||
|
%define CodeOwnRing 1100b |
||||||
|
%define CodeOwnRingRead 1110b |
||||||
|
|
||||||
|
%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 |
||||||
|
|
||||||
|
Go32Bit: |
||||||
|
;;;;;;;;;;;;;;;;;;; |
||||||
|
; Enable A20 line ; |
||||||
|
;;;;;;;;;;;;;;;;;;; |
||||||
|
call Enable_A20 |
||||||
|
|
||||||
|
; Set screen mode |
||||||
|
mov ax, 0x0003 ; AH=0 (Change video mode), AL=13h (Mode) = 320x200 - 256 colors |
||||||
|
mov bx, 0x0000 |
||||||
|
int 0x10 ; Video BIOS interrupt |
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||||||
|
; 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 |
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||||||
|
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 |
||||||
|
|
||||||
|
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 |
||||||
|
xor bl, dl |
||||||
|
shl bl, 4 |
||||||
|
mov ah, bl |
||||||
|
ror bl, 1 |
||||||
|
xor ah, bl |
||||||
|
and ah, 0x70 |
||||||
|
mov al, dl |
||||||
|
add al, cl |
||||||
|
and al, 4 |
||||||
|
ror al, 1 |
||||||
|
or ah, al |
||||||
|
mov al, 0 |
||||||
|
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 |
@ -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. |
|
@ -1,2 +0,0 @@ |
|||||||
Folder of compiling the OS |
|
||||||
This folder has to be empty on the repository |
|
@ -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 |
|
@ -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 |
|
@ -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 |
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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 |
|
@ -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 |
|
@ -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 |
|
@ -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 |
|
@ -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 |
|
@ -1,4 +0,0 @@ |
|||||||
BITS 16 |
|
||||||
|
|
||||||
mem_get_zstack_buffer: |
|
||||||
; INPUT size of zeroed buffer ax in bytes |
|
@ -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 |
@ -0,0 +1,8 @@ |
|||||||
|
{ |
||||||
|
"folders": |
||||||
|
[ |
||||||
|
{ |
||||||
|
"path": "." |
||||||
|
} |
||||||
|
] |
||||||
|
} |
File diff suppressed because it is too large
Load Diff
@ -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 |
|
@ -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…
Reference in new issue